2 * Copyright (c) 2007, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
15 #include "repo_write.h"
16 #include "common_write.h"
17 #include "solvversion.h"
19 /* toolversion history
20 * 1.0: initial tool version
21 * 1.1: changed PRODUCT_ENDOFLIFE parsing
24 static Id verticals[] = {
32 SOLVABLE_CHANGELOG_AUTHOR,
33 SOLVABLE_CHANGELOG_TEXT,
37 static char *languagetags[] = {
39 "solvable:description:",
40 "solvable:messageins:",
41 "solvable:messagedel:",
46 static int test_separate = 0;
48 struct keyfilter_data {
51 int haveaddedfileprovides;
56 keyfilter_solv(Repo *data, Repokey *key, void *kfdata)
58 struct keyfilter_data *kd = kfdata;
62 if (test_separate && key->storage != KEY_STORAGE_SOLVABLE)
63 return KEY_STORAGE_DROPPED;
64 if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES)
65 return KEY_STORAGE_DROPPED;
66 if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL)
67 return KEY_STORAGE_DROPPED;
68 if (key->name == SUSETAGS_SHARE_NAME || key->name == SUSETAGS_SHARE_EVR || key->name == SUSETAGS_SHARE_ARCH)
69 return KEY_STORAGE_DROPPED;
70 for (i = 0; verticals[i]; i++)
71 if (key->name == verticals[i])
72 return KEY_STORAGE_VERTICAL_OFFSET;
73 keyname = pool_id2str(data->pool, key->name);
74 for (i = 0; languagetags[i] != 0; i++)
75 if (!strncmp(keyname, languagetags[i], strlen(languagetags[i])))
76 return KEY_STORAGE_VERTICAL_OFFSET;
77 return KEY_STORAGE_INCORE;
81 keyfilter_attr(Repo *data, Repokey *key, void *kfdata)
85 if (key->storage == KEY_STORAGE_SOLVABLE)
86 return KEY_STORAGE_DROPPED;
87 /* those must only be in the main solv file */
88 if (key->name == REPOSITORY_EXTERNAL || key->name == REPOSITORY_ADDEDFILEPROVIDES || key->name == REPOSITORY_TOOLVERSION)
89 return KEY_STORAGE_DROPPED;
90 for (i = 0; verticals[i]; i++)
91 if (key->name == verticals[i])
92 return KEY_STORAGE_VERTICAL_OFFSET;
93 keyname = pool_id2str(data->pool, key->name);
94 for (i = 0; languagetags[i] != 0; i++)
95 if (!strncmp(keyname, languagetags[i], strlen(languagetags[i])))
96 return KEY_STORAGE_VERTICAL_OFFSET;
97 return KEY_STORAGE_INCORE;
101 keyfilter_language(Repo *repo, Repokey *key, void *kfdata)
103 Pool *pool = repo->pool;
104 const char *name, *p;
108 name = pool_id2str(repo->pool, key->name);
109 p = strrchr(name, ':');
110 if (!p || strcmp(p + 1, lang) != 0)
111 return KEY_STORAGE_DROPPED;
112 for (i = 0; verticals[i]; i++)
114 const char *vname = pool_id2str(pool, verticals[i]);
115 if (!strncmp(name, vname, p - name) && vname[p - name] == 0)
116 return KEY_STORAGE_VERTICAL_OFFSET;
118 return KEY_STORAGE_INCORE;
122 keyfilter_DU(Repo *repo, Repokey *key, void *kfdata)
125 if (key->name != SOLVABLE_DISKUSAGE)
126 return KEY_STORAGE_DROPPED;
127 for (i = 0; verticals[i]; i++)
128 if (key->name == verticals[i])
129 return KEY_STORAGE_VERTICAL_OFFSET;
130 return KEY_STORAGE_INCORE;
134 keyfilter_FL(Repo *repo, Repokey *key, void *kfdata)
137 if (key->name != SOLVABLE_FILELIST)
138 return KEY_STORAGE_DROPPED;
139 for (i = 0; verticals[i]; i++)
140 if (key->name == verticals[i])
141 return KEY_STORAGE_VERTICAL_OFFSET;
142 return KEY_STORAGE_INCORE;
146 keyfilter_other(Repo *repo, Repokey *key, void *kfdata)
148 const char *name, *p;
149 struct keyfilter_data *kd = kfdata;
152 if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES)
153 return KEY_STORAGE_DROPPED;
154 if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL)
155 return KEY_STORAGE_DROPPED;
157 if (key->name == SOLVABLE_FILELIST || key->name == SOLVABLE_DISKUSAGE)
158 return KEY_STORAGE_DROPPED;
160 name = pool_id2str(repo->pool, key->name);
161 p = strrchr(name, ':');
164 for (i = 0; i < kd->nlanguages; i++)
165 if (!strcmp(p + 1, kd->languages[i]))
166 return KEY_STORAGE_DROPPED;
168 for (i = 0; verticals[i]; i++)
169 if (key->name == verticals[i])
170 return KEY_STORAGE_VERTICAL_OFFSET;
171 return KEY_STORAGE_INCORE;
175 * Write <repo> to stdout
176 * If <attrname> is given, write attributes to <attrname>
177 * If <basename> is given, split attributes
180 #define REPODATAFILE_BLOCK 15
183 write_info(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodata *info, const char *location)
189 if (repo_write_filtered(repo, fp, keyfilter, kfdata, &keyq) != 0)
191 fprintf(stderr, "repo_write failed\n");
194 h = repodata_new_handle(info);
196 repodata_set_idarray(info, h, REPOSITORY_KEYS, &keyq);
198 repodata_set_str(info, h, REPOSITORY_LOCATION, location);
199 repodata_add_flexarray(info, SOLVID_META, REPOSITORY_EXTERNAL, h);
203 tool_write(Repo *repo, const char *basename, const char *attrname)
208 char **languages = 0;
211 struct keyfilter_data kd;
212 Queue addedfileprovides;
214 memset(&kd, 0, sizeof(kd));
215 info = repo_add_repodata(repo, 0);
216 repodata_set_str(info, SOLVID_META, REPOSITORY_TOOLVERSION, LIBSOLV_TOOLVERSION);
217 queue_init(&addedfileprovides);
218 pool_addfileprovides_queue(repo->pool, &addedfileprovides, 0);
219 if (addedfileprovides.count)
221 kd.haveaddedfileprovides = 1;
222 repodata_set_idarray(info, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, &addedfileprovides);
224 queue_free(&addedfileprovides);
226 pool_freeidhashes(repo->pool); /* free some mem */
235 /* find languages and other info */
236 FOR_REPODATAS(repo, i, data)
238 for (j = 1, key = data->keys + j; j < data->nkeys; j++, key++)
240 const char *keyname = pool_id2str(repo->pool, key->name);
241 if (key->name == SOLVABLE_DISKUSAGE)
243 if (key->name == SOLVABLE_FILELIST)
245 for (k = 0; languagetags[k] != 0; k++)
246 if (!strncmp(keyname, languagetags[k], strlen(languagetags[k])))
248 if (!languagetags[k])
250 l = strlen(languagetags[k]);
251 if (strlen(keyname + l) > 5)
253 for (k = 0; k < nlanguages; k++)
254 if (!strcmp(languages[k], keyname + l))
258 languages = solv_realloc2(languages, nlanguages + 1, sizeof(char *));
259 languages[nlanguages++] = strdup(keyname + l);
262 /* write language subfiles */
263 for (i = 0; i < nlanguages; i++)
265 sprintf(fn, "%s.%s.solv", basename, languages[i]);
266 if (!(fp = fopen(fn, "w")))
271 write_info(repo, fp, keyfilter_language, languages[i], info, fn);
275 /* write DU subfile */
278 sprintf(fn, "%s.DU.solv", basename);
279 if (!(fp = fopen(fn, "w")))
284 write_info(repo, fp, keyfilter_DU, 0, info, fn);
291 sprintf(fn, "%s.FL.solv", basename);
292 if (!(fp = fopen(fn, "w")))
297 write_info(repo, fp, keyfilter_FL, 0, info, fn);
301 /* write everything else */
302 sprintf(fn, "%s.solv", basename);
303 if (!(fp = fopen(fn, "w")))
308 kd.languages = languages;
309 kd.nlanguages = nlanguages;
310 repodata_internalize(info);
311 if (repo_write_filtered(repo, fp, keyfilter_other, &kd, 0) != 0)
313 fprintf(stderr, "repo_write failed\n");
321 for (i = 0; i < nlanguages; i++)
323 solv_free(languages);
330 fp = fopen(attrname, "w");
331 write_info(repo, fp, keyfilter_attr, 0, info, attrname);
335 repodata_internalize(info);
336 if (repo_write_filtered(repo, stdout, keyfilter_solv, &kd, 0) != 0)
338 fprintf(stderr, "repo_write failed\n");