1 /* pkg_parse.c - the opkg package management system
5 Copyright (C) 2002 Compaq Computer Corporation
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
23 #include "opkg_utils.h"
24 #include "pkg_parse.h"
25 #include "libbb/libbb.h"
27 int isGenericFieldType(char * type, char * line)
29 if(!strncmp(line, type, strlen(type)))
34 char * parseGenericFieldType(char * type, char * raw)
36 char * field_value = raw + (strlen(type) + 1);
37 return trim_alloc(field_value);
40 void parseStatus(pkg_t *pkg, char * raw)
42 char sw_str[64], sf_str[64], ss_str[64];
44 sscanf(raw, "Status: %s %s %s", sw_str, sf_str, ss_str);
45 pkg->state_want = pkg_state_want_from_str(sw_str);
46 pkg->state_flag = pkg_state_flag_from_str(sf_str);
47 pkg->state_status = pkg_state_status_from_str(ss_str);
50 char ** parseDependsString(char * raw, int * depends_count)
52 char ** depends = NULL;
54 char buff[2048], * dest;
56 while(raw && *raw && !isspace(*raw)) {
60 if(line_is_blank(raw)){
61 *depends_count = line_count;
65 depends = xrealloc(depends, sizeof(char *) * (line_count + 1));
67 while(isspace(*raw)) raw++;
70 while((*raw != ',') && *raw)
74 depends[line_count] = trim_alloc(buff);
75 if(depends[line_count] ==NULL)
81 *depends_count = line_count;
85 void parseConffiles(pkg_t * pkg, char * raw)
87 char file_name[1048], md5sum[1048]; /* please tell me there aren't any longer that 1k */
89 if(!strncmp(raw, "Conffiles:", 10))
90 raw += strlen("Conffiles:");
92 while(*raw && (sscanf(raw, "%s%s", file_name, md5sum) == 2)){
93 conffile_list_append(&pkg->conffiles, file_name, md5sum);
94 /* fprintf(stderr, "%s %s ", file_name, md5sum);*/
95 while (*raw && isspace(*raw)) {
98 raw += strlen(file_name);
99 while (*raw && isspace(*raw)) {
102 raw += strlen(md5sum);
106 int parseVersion(pkg_t *pkg, char *raw)
108 char *colon, *eepochcolon;
113 fprintf(stderr, "%s: ERROR: version string is empty", __FUNCTION__);
117 if (strncmp(raw, "Version:", 8) == 0) {
120 while (*raw && isspace(*raw)) {
124 colon= strchr(raw,':');
126 epoch= strtoul(raw,&eepochcolon,10);
127 if (colon != eepochcolon) {
128 fprintf(stderr, "%s: ERROR: epoch in version is not number", __FUNCTION__);
132 fprintf(stderr, "%s: ERROR: nothing after colon in version number", __FUNCTION__);
145 pkg->version= xcalloc(1, strlen(raw)+1);
146 strcpy(pkg->version, raw);
149 hyphen= strrchr(pkg->version,'-');
153 pkg->revision = hyphen;
159 /* Some random thoughts from Carl:
161 This function could be considerably simplified if we just kept
162 an array of all the generic string-valued field names, and looped
163 through those looking for a match. Also, these fields could perhaps
164 be stored in the package as an array as well, (or, probably better,
165 as an nv_pair_list_t).
167 Fields which require special parsing or storage, (such as Depends:
168 and Status:) could be handled as they are now.
170 /* XXX: FEATURE: The Suggests: field needs to be changed from a string
171 to a dependency list. And, since we already have
172 Depends/Pre-Depends and need to add Conflicts, Recommends, and
173 Enhances, perhaps we could generalize all of these and save some
176 int pkg_parse_raw(pkg_t *pkg, char ***raw, pkg_src_t *src, pkg_dest_t *dest)
178 int reading_conffiles, reading_description;
184 reading_conffiles = reading_description = 0;
186 for (lines = *raw; *lines; lines++) {
187 /* fprintf(stderr, "PARSING %s\n", *lines);*/
190 if(isGenericFieldType("Package:", *lines))
191 pkg->name = parseGenericFieldType("Package", *lines);
192 else if(isGenericFieldType("Priority:", *lines))
193 pkg->priority = parseGenericFieldType("Priority", *lines);
194 else if(isGenericFieldType("Provides", *lines)){
195 pkg->provides_str = parseDependsString(*lines, &pkg->provides_count);
197 else if(isGenericFieldType("Pre-Depends", *lines))
198 pkg->pre_depends_str = parseDependsString(*lines, &pkg->pre_depends_count);
202 if(isGenericFieldType("Architecture:", *lines))
203 pkg->architecture = parseGenericFieldType("Architecture", *lines);
204 else if(isGenericFieldType("Auto-Installed:", *lines)) {
205 char *auto_installed_value;
206 auto_installed_value = parseGenericFieldType("Auto-Installed:", *lines);
207 if (strcmp(auto_installed_value, "yes") == 0) {
208 pkg->auto_installed = 1;
210 free(auto_installed_value);
215 if(isGenericFieldType("Filename:", *lines))
216 pkg->filename = parseGenericFieldType("Filename", *lines);
220 if(isGenericFieldType("Section:", *lines))
221 pkg->section = parseGenericFieldType("Section", *lines);
223 else if(isGenericFieldType("SHA256sum:", *lines))
224 pkg->sha256sum = parseGenericFieldType("SHA256sum", *lines);
226 else if(isGenericFieldType("Size:", *lines))
227 pkg->size = parseGenericFieldType("Size", *lines);
228 else if(isGenericFieldType("Source:", *lines))
229 pkg->source = parseGenericFieldType("Source", *lines);
230 else if(isGenericFieldType("Status", *lines))
231 parseStatus(pkg, *lines);
232 else if(isGenericFieldType("Suggests", *lines))
233 pkg->suggests_str = parseDependsString(*lines, &pkg->suggests_count);
237 if(isGenericFieldType("Tags:", *lines))
238 pkg->tags = parseGenericFieldType("Tags", *lines);
242 if(isGenericFieldType("MD5sum:", *lines))
243 pkg->md5sum = parseGenericFieldType("MD5sum", *lines);
244 /* The old opkg wrote out status files with the wrong case for MD5sum,
245 let's parse it either way */
246 else if(isGenericFieldType("MD5Sum:", *lines))
247 pkg->md5sum = parseGenericFieldType("MD5Sum", *lines);
248 else if(isGenericFieldType("Maintainer", *lines))
249 pkg->maintainer = parseGenericFieldType("Maintainer", *lines);
253 if(isGenericFieldType("Installed-Size:", *lines))
254 pkg->installed_size = parseGenericFieldType("Installed-Size", *lines);
255 else if(isGenericFieldType("Installed-Time:", *lines)) {
256 char *time_str = parseGenericFieldType("Installed-Time", *lines);
257 pkg->installed_time = strtoul(time_str, NULL, 0);
263 if(isGenericFieldType("Essential:", *lines)) {
264 char *essential_value;
265 essential_value = parseGenericFieldType("Essential", *lines);
266 if (strcmp(essential_value, "yes") == 0) {
269 free(essential_value);
274 if(isGenericFieldType("Version", *lines))
275 parseVersion(pkg, *lines);
279 if(isGenericFieldType("Conffiles", *lines)){
280 parseConffiles(pkg, *lines);
281 reading_conffiles = 1;
283 else if(isGenericFieldType("Conflicts", *lines))
284 pkg->conflicts_str = parseDependsString(*lines, &pkg->conflicts_count);
288 if(isGenericFieldType("Description", *lines)) {
289 pkg->description = parseGenericFieldType("Description", *lines);
290 reading_conffiles = 0;
291 reading_description = 1;
293 else if(isGenericFieldType("Depends", *lines))
294 pkg->depends_str = parseDependsString(*lines, &pkg->depends_count);
298 if(isGenericFieldType("Recommends", *lines))
299 pkg->recommends_str = parseDependsString(*lines, &pkg->recommends_count);
300 else if(isGenericFieldType("Replaces", *lines))
301 pkg->replaces_str = parseDependsString(*lines, &pkg->replaces_count);
306 if(reading_description) {
307 /* we already know it's not blank, so the rest of description */
308 pkg->description = xrealloc(pkg->description,
309 strlen(pkg->description)
310 + 1 + strlen(*lines) + 1);
311 strcat(pkg->description, "\n");
312 strcat(pkg->description, (*lines));
314 else if(reading_conffiles)
315 parseConffiles(pkg, *lines);
320 if(line_is_blank(*lines)) {
337 int pkg_valorize_other_field(pkg_t *pkg, char ***raw)
341 for (lines = *raw; *lines; lines++) {
342 if(isGenericFieldType("Essential:", *lines)) {
343 char *essential_value;
344 essential_value = parseGenericFieldType("Essential", *lines);
345 if (strcmp(essential_value, "yes") == 0) {
348 free(essential_value);