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 #define LIBSOLV_TOOLVERSION "1.0"
22 static Id verticals[] = {
30 SOLVABLE_CHANGELOG_AUTHOR,
31 SOLVABLE_CHANGELOG_TEXT,
35 static char *languagetags[] = {
37 "solvable:description:",
38 "solvable:messageins:",
39 "solvable:messagedel:",
44 static int test_separate = 0;
46 struct keyfilter_data {
49 int haveaddedfileprovides;
54 keyfilter_solv(Repo *data, Repokey *key, void *kfdata)
56 struct keyfilter_data *kd = kfdata;
60 if (test_separate && key->storage != KEY_STORAGE_SOLVABLE)
61 return KEY_STORAGE_DROPPED;
62 if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES)
63 return KEY_STORAGE_DROPPED;
64 if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL)
65 return KEY_STORAGE_DROPPED;
66 for (i = 0; verticals[i]; i++)
67 if (key->name == verticals[i])
68 return KEY_STORAGE_VERTICAL_OFFSET;
69 keyname = pool_id2str(data->pool, key->name);
70 for (i = 0; languagetags[i] != 0; i++)
71 if (!strncmp(keyname, languagetags[i], strlen(languagetags[i])))
72 return KEY_STORAGE_VERTICAL_OFFSET;
73 return KEY_STORAGE_INCORE;
77 keyfilter_attr(Repo *data, Repokey *key, void *kfdata)
81 if (key->storage == KEY_STORAGE_SOLVABLE)
82 return KEY_STORAGE_DROPPED;
83 /* those must only be in the main solv file */
84 if (key->name == REPOSITORY_EXTERNAL || key->name == REPOSITORY_ADDEDFILEPROVIDES || key->name == REPOSITORY_TOOLVERSION)
85 return KEY_STORAGE_DROPPED;
86 for (i = 0; verticals[i]; i++)
87 if (key->name == verticals[i])
88 return KEY_STORAGE_VERTICAL_OFFSET;
89 keyname = pool_id2str(data->pool, key->name);
90 for (i = 0; languagetags[i] != 0; i++)
91 if (!strncmp(keyname, languagetags[i], strlen(languagetags[i])))
92 return KEY_STORAGE_VERTICAL_OFFSET;
93 return KEY_STORAGE_INCORE;
97 keyfilter_language(Repo *repo, Repokey *key, void *kfdata)
99 Pool *pool = repo->pool;
100 const char *name, *p;
104 name = pool_id2str(repo->pool, key->name);
105 p = strrchr(name, ':');
106 if (!p || strcmp(p + 1, lang) != 0)
107 return KEY_STORAGE_DROPPED;
108 for (i = 0; verticals[i]; i++)
110 const char *vname = pool_id2str(pool, verticals[i]);
111 if (!strncmp(name, vname, p - name) && vname[p - name] == 0)
112 return KEY_STORAGE_VERTICAL_OFFSET;
114 return KEY_STORAGE_INCORE;
118 keyfilter_DU(Repo *repo, Repokey *key, void *kfdata)
121 if (key->name != SOLVABLE_DISKUSAGE)
122 return KEY_STORAGE_DROPPED;
123 for (i = 0; verticals[i]; i++)
124 if (key->name == verticals[i])
125 return KEY_STORAGE_VERTICAL_OFFSET;
126 return KEY_STORAGE_INCORE;
130 keyfilter_FL(Repo *repo, Repokey *key, void *kfdata)
133 if (key->name != SOLVABLE_FILELIST)
134 return KEY_STORAGE_DROPPED;
135 for (i = 0; verticals[i]; i++)
136 if (key->name == verticals[i])
137 return KEY_STORAGE_VERTICAL_OFFSET;
138 return KEY_STORAGE_INCORE;
142 keyfilter_other(Repo *repo, Repokey *key, void *kfdata)
144 const char *name, *p;
145 struct keyfilter_data *kd = kfdata;
148 if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES)
149 return KEY_STORAGE_DROPPED;
150 if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL)
151 return KEY_STORAGE_DROPPED;
153 if (key->name == SOLVABLE_FILELIST || key->name == SOLVABLE_DISKUSAGE)
154 return KEY_STORAGE_DROPPED;
156 name = pool_id2str(repo->pool, key->name);
157 p = strrchr(name, ':');
160 for (i = 0; i < kd->nlanguages; i++)
161 if (!strcmp(p + 1, kd->languages[i]))
162 return KEY_STORAGE_DROPPED;
164 for (i = 0; verticals[i]; i++)
165 if (key->name == verticals[i])
166 return KEY_STORAGE_VERTICAL_OFFSET;
167 return KEY_STORAGE_INCORE;
171 * Write <repo> to stdout
172 * If <attrname> is given, write attributes to <attrname>
173 * If <basename> is given, split attributes
176 #define REPODATAFILE_BLOCK 15
179 write_info(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodata *info, const char *location)
185 if (repo_write_filtered(repo, fp, keyfilter, kfdata, &keyq) != 0)
187 fprintf(stderr, "repo_write failed\n");
190 h = repodata_new_handle(info);
192 repodata_set_idarray(info, h, REPOSITORY_KEYS, &keyq);
194 repodata_set_str(info, h, REPOSITORY_LOCATION, location);
195 repodata_add_flexarray(info, SOLVID_META, REPOSITORY_EXTERNAL, h);
199 tool_write(Repo *repo, const char *basename, const char *attrname)
204 char **languages = 0;
207 struct keyfilter_data kd;
208 Queue addedfileprovides;
210 memset(&kd, 0, sizeof(kd));
211 info = repo_add_repodata(repo, 0);
212 repodata_set_str(info, SOLVID_META, REPOSITORY_TOOLVERSION, LIBSOLV_TOOLVERSION);
213 queue_init(&addedfileprovides);
214 pool_addfileprovides_queue(repo->pool, &addedfileprovides, 0);
215 if (addedfileprovides.count)
217 kd.haveaddedfileprovides = 1;
218 repodata_set_idarray(info, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &addedfileprovides);
220 queue_free(&addedfileprovides);
222 pool_freeidhashes(repo->pool); /* free some mem */
231 /* find languages and other info */
232 FOR_REPODATAS(repo, i, data)
234 for (j = 1, key = data->keys + j; j < data->nkeys; j++, key++)
236 const char *keyname = pool_id2str(repo->pool, key->name);
237 if (key->name == SOLVABLE_DISKUSAGE)
239 if (key->name == SOLVABLE_FILELIST)
241 for (k = 0; languagetags[k] != 0; k++)
242 if (!strncmp(keyname, languagetags[k], strlen(languagetags[k])))
244 if (!languagetags[k])
246 l = strlen(languagetags[k]);
247 if (strlen(keyname + l) > 5)
249 for (k = 0; k < nlanguages; k++)
250 if (!strcmp(languages[k], keyname + l))
254 languages = solv_realloc2(languages, nlanguages + 1, sizeof(char *));
255 languages[nlanguages++] = strdup(keyname + l);
258 /* write language subfiles */
259 for (i = 0; i < nlanguages; i++)
261 sprintf(fn, "%s.%s.solv", basename, languages[i]);
262 if (!(fp = fopen(fn, "w")))
267 write_info(repo, fp, keyfilter_language, languages[i], info, fn);
271 /* write DU subfile */
274 sprintf(fn, "%s.DU.solv", basename);
275 if (!(fp = fopen(fn, "w")))
280 write_info(repo, fp, keyfilter_DU, 0, info, fn);
287 sprintf(fn, "%s.FL.solv", basename);
288 if (!(fp = fopen(fn, "w")))
293 write_info(repo, fp, keyfilter_FL, 0, info, fn);
297 /* write everything else */
298 sprintf(fn, "%s.solv", basename);
299 if (!(fp = fopen(fn, "w")))
304 kd.languages = languages;
305 kd.nlanguages = nlanguages;
306 repodata_internalize(info);
307 if (repo_write_filtered(repo, fp, keyfilter_other, &kd, 0) != 0)
309 fprintf(stderr, "repo_write failed\n");
317 for (i = 0; i < nlanguages; i++)
319 solv_free(languages);
326 fp = fopen(attrname, "w");
327 write_info(repo, fp, keyfilter_attr, 0, info, attrname);
331 repodata_internalize(info);
332 if (repo_write_filtered(repo, stdout, keyfilter_solv, &kd, 0) != 0)
334 fprintf(stderr, "repo_write failed\n");