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)
96 char *lang = kfdata, *bname;
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 /* find base name id */
105 bname = strdup(name);
107 id = str2id(repo->pool, bname, 1);
108 for (i = 0; verticals[i]; i++)
109 if (id == verticals[i])
110 return KEY_STORAGE_VERTICAL_OFFSET;
111 return KEY_STORAGE_INCORE;
115 keyfilter_DU(Repo *repo, Repokey *key, void *kfdata)
118 if (key->name != SOLVABLE_DISKUSAGE)
119 return KEY_STORAGE_DROPPED;
120 for (i = 0; verticals[i]; i++)
121 if (key->name == verticals[i])
122 return KEY_STORAGE_VERTICAL_OFFSET;
123 return KEY_STORAGE_INCORE;
127 keyfilter_FL(Repo *repo, Repokey *key, void *kfdata)
130 if (key->name != SOLVABLE_FILELIST)
131 return KEY_STORAGE_DROPPED;
132 for (i = 0; verticals[i]; i++)
133 if (key->name == verticals[i])
134 return KEY_STORAGE_VERTICAL_OFFSET;
135 return KEY_STORAGE_INCORE;
139 keyfilter_other(Repo *repo, Repokey *key, void *kfdata)
141 const char *name, *p;
142 struct keyfilter_data *kd = kfdata;
145 if (!kd->haveaddedfileprovides && key->name == REPOSITORY_ADDEDFILEPROVIDES)
146 return KEY_STORAGE_DROPPED;
147 if (!kd->haveexternal && key->name == REPOSITORY_EXTERNAL)
148 return KEY_STORAGE_DROPPED;
150 if (key->name == SOLVABLE_FILELIST || key->name == SOLVABLE_DISKUSAGE)
151 return KEY_STORAGE_DROPPED;
153 name = id2str(repo->pool, key->name);
154 p = strrchr(name, ':');
157 for (i = 0; i < kd->nlanguages; i++)
158 if (!strcmp(p + 1, kd->languages[i]))
159 return KEY_STORAGE_DROPPED;
161 for (i = 0; verticals[i]; i++)
162 if (key->name == verticals[i])
163 return KEY_STORAGE_VERTICAL_OFFSET;
164 return KEY_STORAGE_INCORE;
168 * Write <repo> to stdout
169 * If <attrname> is given, write attributes to <attrname>
170 * If <basename> is given, split attributes
173 #define REPODATAFILE_BLOCK 15
176 write_info(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *key, void *kfdata), void *kfdata, Repodata *info, const char *location)
181 repo_write(repo, fp, keyfilter, kfdata, &keyarray);
182 h = repodata_new_handle(info);
185 for (i = 0; keyarray[i]; i++)
186 repodata_add_idarray(info, h, REPOSITORY_KEYS, keyarray[i]);
189 repodata_set_str(info, h, REPOSITORY_LOCATION, location);
190 repodata_add_flexarray(info, SOLVID_META, REPOSITORY_EXTERNAL, h);
194 tool_write(Repo *repo, const char *basename, const char *attrname)
199 char **languages = 0;
202 Id *addedfileprovides = 0;
203 struct keyfilter_data kd;
205 memset(&kd, 0, sizeof(kd));
206 info = repo_add_repodata(repo, 0);
207 pool_addfileprovides_ids(repo->pool, 0, &addedfileprovides);
208 if (addedfileprovides && *addedfileprovides)
210 kd.haveaddedfileprovides = 1;
211 for (i = 0; addedfileprovides[i]; i++)
212 repodata_add_idarray(info, SOLVID_META, REPOSITORY_ADDEDFILEPROVIDES, addedfileprovides[i]);
214 sat_free(addedfileprovides);
223 /* find languages and other info */
224 for (i = 0, data = repo->repodata; i < repo->nrepodata; i++, data++)
226 for (j = 1, key = data->keys + j; j < data->nkeys; j++, key++)
228 const char *keyname = id2str(repo->pool, key->name);
229 if (key->name == SOLVABLE_DISKUSAGE)
231 if (key->name == SOLVABLE_FILELIST)
233 for (k = 0; languagetags[k] != 0; k++)
234 if (!strncmp(keyname, languagetags[k], strlen(languagetags[k])))
236 if (!languagetags[k])
238 l = strlen(languagetags[k]);
239 if (strlen(keyname + l) > 5)
241 for (k = 0; k < nlanguages; k++)
242 if (!strcmp(languages[k], keyname + l))
246 languages = sat_realloc2(languages, nlanguages + 1, sizeof(char *));
247 languages[nlanguages++] = strdup(keyname + l);
250 /* write language subfiles */
251 for (i = 0; i < nlanguages; i++)
253 sprintf(fn, "%s.%s.solv", basename, languages[i]);
254 if (!(fp = fopen(fn, "w")))
259 write_info(repo, fp, keyfilter_language, languages[i], info, fn);
263 /* write DU subfile */
266 sprintf(fn, "%s.DU.solv", basename);
267 if (!(fp = fopen(fn, "w")))
272 write_info(repo, fp, keyfilter_DU, 0, info, fn);
279 sprintf(fn, "%s.FL.solv", basename);
280 if (!(fp = fopen(fn, "w")))
285 write_info(repo, fp, keyfilter_FL, 0, info, fn);
289 /* write everything else */
290 sprintf(fn, "%s.solv", basename);
291 if (!(fp = fopen(fn, "w")))
296 kd.languages = languages;
297 kd.nlanguages = nlanguages;
298 repodata_internalize(info);
299 repo_write(repo, fp, keyfilter_other, &kd, 0);
301 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);