X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libopkg%2Fpkg_parse.c;h=5d08177bf9fcce8a25b31fe3f2d5e7c3ae5376b3;hb=7486bf366c05312e7d50d5f969a539a6a581fcac;hp=fb479c36bd7a43840f84eeb673f0ce6423c2beed;hpb=99be91a0fdb86a6826a0cdcf8bede14b7d01c9a8;p=oweals%2Fopkg-lede.git diff --git a/libopkg/pkg_parse.c b/libopkg/pkg_parse.c index fb479c3..5d08177 100644 --- a/libopkg/pkg_parse.c +++ b/libopkg/pkg_parse.c @@ -1,7 +1,8 @@ /* pkg_parse.c - the opkg package management system + Copyright (C) 2009 Ubiq Technologies + Steven M. Ayer - Copyright (C) 2002 Compaq Computer Corporation This program is free software; you can redistribute it and/or @@ -15,17 +16,18 @@ General Public License for more details. */ -#include "includes.h" -#include +#include "config.h" + +#include #include - + #include "pkg.h" #include "opkg_utils.h" #include "pkg_parse.h" #include "libbb/libbb.h" static int -is_field(char *type, const char *line) +is_field(const char *type, const char *line) { if (!strncmp(line, type, strlen(type))) return 1; @@ -33,7 +35,7 @@ is_field(char *type, const char *line) } static char * -parse_simple(char *type, const char *line) +parse_simple(const char *type, const char *line) { return trim_xstrdup(line + strlen(type) + 1); } @@ -42,7 +44,7 @@ parse_simple(char *type, const char *line) * Parse a comma separated string into an array. */ static char ** -parse_comma_separated(const char *raw, int *count) +parse_comma_separated(const char *raw, unsigned int *count) { char **depends = NULL; const char *start, *end; @@ -60,7 +62,7 @@ parse_comma_separated(const char *raw, int *count) while (*raw) { depends = xrealloc(depends, sizeof(char *) * (line_count + 1)); - + while (isspace(*raw)) raw++; @@ -90,8 +92,8 @@ parse_status(pkg_t *pkg, const char *sstr) if (sscanf(sstr, "Status: %63s %63s %63s", sw_str, sf_str, ss_str) != 3) { - fprintf(stderr, "%s: failed to parse Conffiles line for %s\n", - __FUNCTION__, pkg->name); + opkg_msg(ERROR, "Failed to parse Status line for %s\n", + pkg->name); return; } @@ -106,8 +108,8 @@ parse_conffiles(pkg_t *pkg, const char *cstr) char file_name[1024], md5sum[35]; if (sscanf(cstr, "%1023s %34s", file_name, md5sum) != 2) { - fprintf(stderr, "%s: failed to parse Conffiles line for %s\n", - __FUNCTION__, pkg->name); + opkg_msg(ERROR, "Failed to parse Conffiles line for %s\n", + pkg->name); return; } @@ -130,8 +132,7 @@ parse_version(pkg_t *pkg, const char *vstr) errno = 0; pkg->epoch = strtoul(vstr, NULL, 10); if (errno) { - fprintf(stderr, "%s: %s: invalid epoch: %s\n", - __FUNCTION__, pkg->name, strerror(errno)); + opkg_perror(ERROR, "%s: invalid epoch", pkg->name); } vstr = ++colon; } else { @@ -147,17 +148,38 @@ parse_version(pkg_t *pkg, const char *vstr) return 0; } +static int +get_arch_priority(const char *arch) +{ + nv_pair_list_elt_t *l; + + list_for_each_entry(l , &conf->arch_list.head, node) { + nv_pair_t *nv = (nv_pair_t *)l->data; + if (strcmp(nv->name, arch) == 0) + return strtol(nv->value, NULL, 0); + } + return 0; +} + static int pkg_parse_line(pkg_t *pkg, const char *line, uint mask) { /* these flags are a bit hackish... */ static int reading_conffiles = 0, reading_description = 0; + int ret = 0; + + /* Exclude globally masked fields. */ + mask |= conf->pfm; + + /* Flip the semantics of the mask. */ + mask ^= PFM_ALL; switch (*line) { case 'A': - if ((mask & PFM_ARCHITECTURE ) && is_field("Architecture", line)) + if ((mask & PFM_ARCHITECTURE ) && is_field("Architecture", line)) { pkg->architecture = parse_simple("Architecture", line); - else if ((mask & PFM_AUTO_INSTALLED) && is_field("Auto-Installed", line)) { + pkg->arch_priority = get_arch_priority(pkg->architecture); + } else if ((mask & PFM_AUTO_INSTALLED) && is_field("Auto-Installed", line)) { char *tmp = parse_simple("Auto-Installed", line); if (strcmp(tmp, "yes") == 0) pkg->auto_installed = 1; @@ -200,29 +222,30 @@ pkg_parse_line(pkg_t *pkg, const char *line, uint mask) break; case 'I': - if ((mask && PFM_INSTALLED_SIZE) && is_field("Installed-Size", line)) - pkg->installed_size = parse_simple("Installed-Size", line); - else if ((mask && PFM_INSTALLED_TIME) && is_field("Installed-Time", line)) { + if ((mask & PFM_INSTALLED_SIZE) && is_field("Installed-Size", line)) { + char *tmp = parse_simple("Installed-Size", line); + pkg->installed_size = strtoul(tmp, NULL, 0); + free (tmp); + } else if ((mask & PFM_INSTALLED_TIME) && is_field("Installed-Time", line)) { char *tmp = parse_simple("Installed-Time", line); pkg->installed_time = strtoul(tmp, NULL, 0); free (tmp); - } + } break; case 'M': - if (mask && PFM_MD5SUM) { - if (is_field("MD5sum:", line)) - pkg->md5sum = parse_simple("MD5sum", line); + if ((mask & PFM_MD5SUM) && is_field("MD5sum:", line)) + pkg->md5sum = parse_simple("MD5sum", line); /* The old opkg wrote out status files with the wrong * case for MD5sum, let's parse it either way */ - else if (is_field("MD5Sum:", line)) - pkg->md5sum = parse_simple("MD5Sum", line); - } else if((mask & PFM_MAINTAINER) && is_field("Maintainer", line)) + else if ((mask & PFM_MD5SUM) && is_field("MD5Sum:", line)) + pkg->md5sum = parse_simple("MD5Sum", line); + else if((mask & PFM_MAINTAINER) && is_field("Maintainer", line)) pkg->maintainer = parse_simple("Maintainer", line); break; case 'P': - if ((mask & PFM_PACKAGE) && is_field("Package", line)) + if ((mask & PFM_PACKAGE) && is_field("Package", line)) pkg->name = parse_simple("Package", line); else if ((mask & PFM_PRIORITY) && is_field("Priority", line)) pkg->priority = parse_simple("Priority", line); @@ -247,9 +270,11 @@ pkg_parse_line(pkg_t *pkg, const char *line, uint mask) else if ((mask & PFM_SHA256SUM) && is_field("SHA256sum", line)) pkg->sha256sum = parse_simple("SHA256sum", line); #endif - else if ((mask & PFM_SIZE) && is_field("Size", line)) - pkg->size = parse_simple("Size", line); - else if ((mask & PFM_SOURCE) && is_field("Source", line)) + else if ((mask & PFM_SIZE) && is_field("Size", line)) { + char *tmp = parse_simple("Size", line); + pkg->size = strtoul(tmp, NULL, 0); + free (tmp); + } else if ((mask & PFM_SOURCE) && is_field("Source", line)) pkg->source = parse_simple("Source", line); else if ((mask & PFM_STATUS) && is_field("Status", line)) parse_status(pkg, line); @@ -275,16 +300,18 @@ pkg_parse_line(pkg_t *pkg, const char *line, uint mask) strcat(pkg->description, "\n"); strcat(pkg->description, (line)); goto dont_reset_flags; - } else if ((mask && PFM_CONFFILES) && reading_conffiles) { + } else if ((mask & PFM_CONFFILES) && reading_conffiles) { parse_conffiles(pkg, line); goto dont_reset_flags; } - break; + /* FALLTHROUGH */ default: /* For package lists, signifies end of package. */ - if(line_is_blank(line)) - return 1; + if(line_is_blank(line)) { + ret = 1; + break; + } } reading_description = 0; @@ -292,7 +319,7 @@ pkg_parse_line(pkg_t *pkg, const char *line, uint mask) dont_reset_flags: - return 0; + return ret; } int @@ -311,15 +338,13 @@ pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask, buf[0] = '\0'; while (1) { - if (fgets(buf, buflen, fp) == NULL) { + if (fgets(buf, (int)buflen, fp) == NULL) { if (ferror(fp)) { - fprintf(stderr, "%s: fgets: %s\n", - __FUNCTION__, strerror(errno)); + opkg_perror(ERROR, "fgets"); ret = -1; - } else if (strlen(*buf0) == buflen-1) { - fprintf(stderr, "%s: missing new line character" - " at end of file!\n", - __FUNCTION__); + } else if (strlen(*buf0) == buf0len-1) { + opkg_msg(ERROR, "Missing new line character" + " at end of file!\n"); pkg_parse_line(pkg, *buf0, mask); } break; @@ -333,31 +358,31 @@ pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask, * missing a newline, but we won't know until * fgets fails to read more data. */ - fprintf(stderr, "%s: missing new line character" - " at end of file!\n", - __FUNCTION__); + opkg_msg(ERROR, "Missing new line character" + " at end of file!\n"); pkg_parse_line(pkg, *buf0, mask); break; } if (buf0len >= EXCESSIVE_LINE_LEN) { - fprintf(stderr, "%s: excessively long line at " + opkg_msg(ERROR, "Excessively long line at " "%d. Corrupt file?\n", - __FUNCTION__, lineno); + lineno); ret = -1; break; } /* - * Realloc and move buf past the data already read. + * Realloc and point buf past the data already read, + * at the NULL terminator inserted by fgets. * |<--------------- buf0len ----------------->| * | |<------- buflen ---->| * |---------------------|---------------------| * buf0 buf */ - buflen = buf0len; + buflen = buf0len +1; buf0len *= 2; *buf0 = xrealloc(*buf0, buf0len); - buf = *buf0 + buflen -1; + buf = *buf0 + buflen -2; continue; } @@ -372,11 +397,11 @@ pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask, buf = *buf0; buflen = buf0len; buf[0] = '\0'; - }; + } if (pkg->name == NULL) { /* probably just a blank line */ - ret = EINVAL; + ret = 1; } return ret;