2 * Copyright (c) 2007, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
17 #include "repo_write.h"
18 #include "common_write.h"
20 static Id verticals[] = {
31 static char *languagetags[] = {
33 "solvable:description:",
34 "solvable:messageins:",
35 "solvable:messagedel:",
40 static int test_separate = 0;
42 struct keyfilter_data {
45 int haveaddedfileprovides;
50 keyfilter_solv(Repo *data, Repokey *key, void *kfdata)
52 struct keyfilter_data *kd = kfdata;
56 if (test_separate && key->storage != KEY_STORAGE_SOLVABLE)
57 return KEY_STORAGE_DROPPED;
58 if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES)
59 return KEY_STORAGE_DROPPED;
60 if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL)
61 return KEY_STORAGE_DROPPED;
62 for (i = 0; verticals[i]; i++)
63 if (key->name == verticals[i])
64 return KEY_STORAGE_VERTICAL_OFFSET;
65 keyname = id2str(data->pool, key->name);
66 for (i = 0; languagetags[i] != 0; i++)
67 if (!strncmp(keyname, languagetags[i], strlen(languagetags[i])))
68 return KEY_STORAGE_VERTICAL_OFFSET;
69 return KEY_STORAGE_INCORE;
73 keyfilter_attr(Repo *data, Repokey *key, void *kfdata)
77 if (key->storage == KEY_STORAGE_SOLVABLE)
78 return KEY_STORAGE_DROPPED;
79 /* those two must only be in the main solv file */
80 if (key->name == REPOSITORY_EXTERNAL || key->name == REPOSITORY_ADDEDFILEPROVIDES)
81 return KEY_STORAGE_DROPPED;
82 for (i = 0; verticals[i]; i++)
83 if (key->name == verticals[i])
84 return KEY_STORAGE_VERTICAL_OFFSET;
85 keyname = id2str(data->pool, key->name);
86 for (i = 0; languagetags[i] != 0; i++)
87 if (!strncmp(keyname, languagetags[i], strlen(languagetags[i])))
88 return KEY_STORAGE_VERTICAL_OFFSET;
89 return KEY_STORAGE_INCORE;
93 keyfilter_language(Repo *repo, Repokey *key, void *kfdata)
95 Pool *pool = repo->pool;
100 name = id2str(repo->pool, key->name);
101 p = strrchr(name, ':');
102 if (!p || strcmp(p + 1, lang) != 0)
103 return KEY_STORAGE_DROPPED;
104 for (i = 0; verticals[i]; i++)
106 const char *vname = id2str(pool, verticals[i]);
107 if (!strncmp(name, vname, p - name) && vname[p - name] == 0)
108 return KEY_STORAGE_VERTICAL_OFFSET;
110 return KEY_STORAGE_INCORE;
114 keyfilter_DU(Repo *repo, Repokey *key, void *kfdata)
117 if (key->name != SOLVABLE_DISKUSAGE)
118 return KEY_STORAGE_DROPPED;
119 for (i = 0; verticals[i]; i++)
120 if (key->name == verticals[i])
121 return KEY_STORAGE_VERTICAL_OFFSET;
122 return KEY_STORAGE_INCORE;
126 keyfilter_FL(Repo *repo, Repokey *key, void *kfdata)
129 if (key->name != SOLVABLE_FILELIST)
130 return KEY_STORAGE_DROPPED;
131 for (i = 0; verticals[i]; i++)
132 if (key->name == verticals[i])
133 return KEY_STORAGE_VERTICAL_OFFSET;
134 return KEY_STORAGE_INCORE;
138 keyfilter_other(Repo *repo, Repokey *key, void *kfdata)
140 const char *name, *p;
141 struct keyfilter_data *kd = kfdata;
144 if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES)
145 return KEY_STORAGE_DROPPED;
146 if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL)
147 return KEY_STORAGE_DROPPED;
149 if (key->name == SOLVABLE_FILELIST || key->name == SOLVABLE_DISKUSAGE)
150 return KEY_STORAGE_DROPPED;
152 name = id2str(repo->pool, key->name);
153 p = strrchr(name, ':');
156 for (i = 0; i < kd->nlanguages; i++)
157 if (!strcmp(p + 1, kd->languages[i]))
158 return KEY_STORAGE_DROPPED;
160 for (i = 0; verticals[i]; i++)
161 if (key->name == verticals[i])
162 return KEY_STORAGE_VERTICAL_OFFSET;
163 return KEY_STORAGE_INCORE;
167 * Write <repo> to stdout
168 * If <attrname> is given, write attributes to <attrname>
169 * If <basename> is given, split attributes
172 #define REPODATAFILE_BLOCK 15
175 write_info(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodata *info, const char *location)
180 repo_write(repo, fp, keyfilter, kfdata, &keyarray);
181 h = repodata_new_handle(info);
184 for (i = 0; keyarray[i]; i++)
185 repodata_add_idarray(info, h, REPOSITORY_KEYS, keyarray[i]);
188 repodata_set_str(info, h, REPOSITORY_LOCATION, location);
189 repodata_add_flexarray(info, SOLVID_META, REPOSITORY_EXTERNAL, h);
193 tool_write(Repo *repo, const char *basename, const char *attrname)
198 char **languages = 0;
201 Id *addedfileprovides = 0;
202 struct keyfilter_data kd;
204 memset(&kd, 0, sizeof(kd));
205 info = repo_add_repodata(repo, 0);
206 pool_addfileprovides_ids(repo->pool, 0, &addedfileprovides);
207 if (addedfileprovides && *addedfileprovides)
209 kd.haveaddedfileprovides = 1;
210 for (i = 0; addedfileprovides[i]; i++)
211 repodata_add_idarray(info, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, addedfileprovides[i]);
213 sat_free(addedfileprovides);
215 pool_freeidhashes(repo->pool); /* free some mem */
224 /* find languages and other info */
225 for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
227 for (j = 1, key = data->keys + j; j < data->nkeys; j++, key++)
229 const char *keyname = id2str(repo->pool, key->name);
230 if (key->name == SOLVABLE_DISKUSAGE)
232 if (key->name == SOLVABLE_FILELIST)
234 for (k = 0; languagetags[k] != 0; k++)
235 if (!strncmp(keyname, languagetags[k], strlen(languagetags[k])))
237 if (!languagetags[k])
239 l = strlen(languagetags[k]);
240 if (strlen(keyname + l) > 5)
242 for (k = 0; k < nlanguages; k++)
243 if (!strcmp(languages[k], keyname + l))
247 languages = sat_realloc2(languages, nlanguages + 1, sizeof(char *));
248 languages[nlanguages++] = strdup(keyname + l);
251 /* write language subfiles */
252 for (i = 0; i < nlanguages; i++)
254 sprintf(fn, "%s.%s.solv", basename, languages[i]);
255 if (!(fp = fopen(fn, "w")))
260 write_info(repo, fp, keyfilter_language, languages[i], info, fn);
264 /* write DU subfile */
267 sprintf(fn, "%s.DU.solv", basename);
268 if (!(fp = fopen(fn, "w")))
273 write_info(repo, fp, keyfilter_DU, 0, info, fn);
280 sprintf(fn, "%s.FL.solv", basename);
281 if (!(fp = fopen(fn, "w")))
286 write_info(repo, fp, keyfilter_FL, 0, info, fn);
290 /* write everything else */
291 sprintf(fn, "%s.solv", basename);
292 if (!(fp = fopen(fn, "w")))
297 kd.languages = languages;
298 kd.nlanguages = nlanguages;
299 repodata_internalize(info);
300 repo_write(repo, fp, keyfilter_other, &kd, 0);
302 for (i = 0; i < nlanguages; i++)
311 FILE *fp = fopen(attrname, "w");
312 write_info(repo, fp, keyfilter_attr, 0, info, attrname);
316 repodata_internalize(info);
317 repo_write(repo, stdout, keyfilter_solv, &kd, 0);