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[] = {
33 static char *languagetags[] = {
35 "solvable:description:",
36 "solvable:messageins:",
37 "solvable:messagedel:",
42 static int test_separate = 0;
44 struct keyfilter_data {
47 int haveaddedfileprovides;
52 keyfilter_solv(Repo *data, Repokey *key, void *kfdata)
54 struct keyfilter_data *kd = kfdata;
58 if (test_separate && key->storage != KEY_STORAGE_SOLVABLE)
59 return KEY_STORAGE_DROPPED;
60 if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES)
61 return KEY_STORAGE_DROPPED;
62 if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL)
63 return KEY_STORAGE_DROPPED;
64 for (i = 0; verticals[i]; i++)
65 if (key->name == verticals[i])
66 return KEY_STORAGE_VERTICAL_OFFSET;
67 keyname = pool_id2str(data->pool, key->name);
68 for (i = 0; languagetags[i] != 0; i++)
69 if (!strncmp(keyname, languagetags[i], strlen(languagetags[i])))
70 return KEY_STORAGE_VERTICAL_OFFSET;
71 return KEY_STORAGE_INCORE;
75 keyfilter_attr(Repo *data, Repokey *key, void *kfdata)
79 if (key->storage == KEY_STORAGE_SOLVABLE)
80 return KEY_STORAGE_DROPPED;
81 /* those must only be in the main solv file */
82 if (key->name == REPOSITORY_EXTERNAL || key->name == REPOSITORY_ADDEDFILEPROVIDES || key->name == REPOSITORY_TOOLVERSION)
83 return KEY_STORAGE_DROPPED;
84 for (i = 0; verticals[i]; i++)
85 if (key->name == verticals[i])
86 return KEY_STORAGE_VERTICAL_OFFSET;
87 keyname = pool_id2str(data->pool, key->name);
88 for (i = 0; languagetags[i] != 0; i++)
89 if (!strncmp(keyname, languagetags[i], strlen(languagetags[i])))
90 return KEY_STORAGE_VERTICAL_OFFSET;
91 return KEY_STORAGE_INCORE;
95 keyfilter_language(Repo *repo, Repokey *key, void *kfdata)
97 Pool *pool = repo->pool;
102 name = pool_id2str(repo->pool, key->name);
103 p = strrchr(name, ':');
104 if (!p || strcmp(p + 1, lang) != 0)
105 return KEY_STORAGE_DROPPED;
106 for (i = 0; verticals[i]; i++)
108 const char *vname = pool_id2str(pool, verticals[i]);
109 if (!strncmp(name, vname, p - name) && vname[p - name] == 0)
110 return KEY_STORAGE_VERTICAL_OFFSET;
112 return KEY_STORAGE_INCORE;
116 keyfilter_DU(Repo *repo, Repokey *key, void *kfdata)
119 if (key->name != SOLVABLE_DISKUSAGE)
120 return KEY_STORAGE_DROPPED;
121 for (i = 0; verticals[i]; i++)
122 if (key->name == verticals[i])
123 return KEY_STORAGE_VERTICAL_OFFSET;
124 return KEY_STORAGE_INCORE;
128 keyfilter_FL(Repo *repo, Repokey *key, void *kfdata)
131 if (key->name != SOLVABLE_FILELIST)
132 return KEY_STORAGE_DROPPED;
133 for (i = 0; verticals[i]; i++)
134 if (key->name == verticals[i])
135 return KEY_STORAGE_VERTICAL_OFFSET;
136 return KEY_STORAGE_INCORE;
140 keyfilter_other(Repo *repo, Repokey *key, void *kfdata)
142 const char *name, *p;
143 struct keyfilter_data *kd = kfdata;
146 if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES)
147 return KEY_STORAGE_DROPPED;
148 if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL)
149 return KEY_STORAGE_DROPPED;
151 if (key->name == SOLVABLE_FILELIST || key->name == SOLVABLE_DISKUSAGE)
152 return KEY_STORAGE_DROPPED;
154 name = pool_id2str(repo->pool, key->name);
155 p = strrchr(name, ':');
158 for (i = 0; i < kd->nlanguages; i++)
159 if (!strcmp(p + 1, kd->languages[i]))
160 return KEY_STORAGE_DROPPED;
162 for (i = 0; verticals[i]; i++)
163 if (key->name == verticals[i])
164 return KEY_STORAGE_VERTICAL_OFFSET;
165 return KEY_STORAGE_INCORE;
169 * Write <repo> to stdout
170 * If <attrname> is given, write attributes to <attrname>
171 * If <basename> is given, split attributes
174 #define REPODATAFILE_BLOCK 15
177 write_info(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodata *info, const char *location)
183 if (repo_write_filtered(repo, fp, keyfilter, kfdata, &keyq) != 0)
185 fprintf(stderr, "repo_write failed\n");
188 h = repodata_new_handle(info);
190 repodata_set_idarray(info, h, REPOSITORY_KEYS, &keyq);
192 repodata_set_str(info, h, REPOSITORY_LOCATION, location);
193 repodata_add_flexarray(info, SOLVID_META, REPOSITORY_EXTERNAL, h);
197 tool_write(Repo *repo, const char *basename, const char *attrname)
202 char **languages = 0;
205 struct keyfilter_data kd;
206 Queue addedfileprovides;
208 memset(&kd, 0, sizeof(kd));
209 info = repo_add_repodata(repo, 0);
210 repodata_set_str(info, SOLVID_META, REPOSITORY_TOOLVERSION, LIBSOLV_TOOLVERSION);
211 queue_init(&addedfileprovides);
212 pool_addfileprovides_queue(repo->pool, &addedfileprovides, 0);
213 if (addedfileprovides.count)
215 kd.haveaddedfileprovides = 1;
216 repodata_set_idarray(info, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &addedfileprovides);
218 queue_free(&addedfileprovides);
220 pool_freeidhashes(repo->pool); /* free some mem */
229 /* find languages and other info */
230 FOR_REPODATAS(repo, i, data)
232 for (j = 1, key = data->keys + j; j < data->nkeys; j++, key++)
234 const char *keyname = pool_id2str(repo->pool, key->name);
235 if (key->name == SOLVABLE_DISKUSAGE)
237 if (key->name == SOLVABLE_FILELIST)
239 for (k = 0; languagetags[k] != 0; k++)
240 if (!strncmp(keyname, languagetags[k], strlen(languagetags[k])))
242 if (!languagetags[k])
244 l = strlen(languagetags[k]);
245 if (strlen(keyname + l) > 5)
247 for (k = 0; k < nlanguages; k++)
248 if (!strcmp(languages[k], keyname + l))
252 languages = solv_realloc2(languages, nlanguages + 1, sizeof(char *));
253 languages[nlanguages++] = strdup(keyname + l);
256 /* write language subfiles */
257 for (i = 0; i < nlanguages; i++)
259 sprintf(fn, "%s.%s.solv", basename, languages[i]);
260 if (!(fp = fopen(fn, "w")))
265 write_info(repo, fp, keyfilter_language, languages[i], info, fn);
269 /* write DU subfile */
272 sprintf(fn, "%s.DU.solv", basename);
273 if (!(fp = fopen(fn, "w")))
278 write_info(repo, fp, keyfilter_DU, 0, info, fn);
285 sprintf(fn, "%s.FL.solv", basename);
286 if (!(fp = fopen(fn, "w")))
291 write_info(repo, fp, keyfilter_FL, 0, info, fn);
295 /* write everything else */
296 sprintf(fn, "%s.solv", basename);
297 if (!(fp = fopen(fn, "w")))
302 kd.languages = languages;
303 kd.nlanguages = nlanguages;
304 repodata_internalize(info);
305 if (repo_write_filtered(repo, fp, keyfilter_other, &kd, 0) != 0)
307 fprintf(stderr, "repo_write failed\n");
315 for (i = 0; i < nlanguages; i++)
317 solv_free(languages);
325 fp = fopen(attrname, "w");
326 write_info(repo, fp, keyfilter_attr, 0, info, attrname);
330 repodata_internalize(info);
331 if (repo_write_filtered(repo, stdout, keyfilter_solv, &kd, 0) != 0)
333 fprintf(stderr, "repo_write failed\n");