libopkg: fix hex encoding/decoding, add checksum getter/setter
[oweals/opkg-lede.git] / libopkg / pkg_parse.c
index b7b2fe3f395f00c2839f213447220a289bee3d43..eca0b027c56121a46b2eb4289fd6a83945fcf48e 100644 (file)
 #include "pkg.h"
 #include "opkg_utils.h"
 #include "pkg_parse.h"
+#include "pkg_depends.h"
 #include "libbb/libbb.h"
 
+#include "file_util.h"
 #include "parse_util.h"
 
 static void parse_status(pkg_t * pkg, const char *sstr)
@@ -46,6 +48,7 @@ static void parse_status(pkg_t * pkg, const char *sstr)
 
 static void parse_conffiles(pkg_t * pkg, const char *cstr)
 {
+       conffile_list_t *cl;
        char file_name[1024], md5sum[85];
 
        if (sscanf(cstr, "%1023s %84s", file_name, md5sum) != 2) {
@@ -54,7 +57,10 @@ static void parse_conffiles(pkg_t * pkg, const char *cstr)
                return;
        }
 
-       conffile_list_append(&pkg->conffiles, file_name, md5sum);
+       cl = pkg_get_ptr(pkg, PKG_CONFFILES);
+
+       if (cl)
+               conffile_list_append(cl, file_name, md5sum);
 }
 
 int parse_version(pkg_t * pkg, const char *vstr)
@@ -77,35 +83,43 @@ int parse_version(pkg_t * pkg, const char *vstr)
                vstr = ++colon;
        }
 
-       rev = strrchr(pkg_set_string(pkg, PKG_VERSION, vstr), '-');
+       rev = strrchr(vstr, '-');
 
        if (rev) {
                *rev++ = '\0';
-               pkg_set_ptr(pkg, PKG_REVISION, rev);
+               pkg_set_string(pkg, PKG_REVISION, rev);
        }
 
+       pkg_set_string(pkg, PKG_VERSION, vstr);
+
        return 0;
 }
 
-static int get_arch_priority(const char *arch)
+static char *parse_architecture(pkg_t *pkg, const char *str)
 {
-       nv_pair_list_elt_t *l;
+       const char *s = str;
+       const char *e;
 
-       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;
+       while (isspace(*s))
+               s++;
+
+       e = s + strlen(s);
+
+       while (e > s && isspace(*e))
+               e--;
+
+       return pkg_set_architecture(pkg, s, e - s);
 }
 
 int pkg_parse_line(void *ptr, const char *line, uint mask)
 {
        pkg_t *pkg = (pkg_t *) ptr;
+       abstract_pkg_t *ab_pkg = NULL;
 
        /* these flags are a bit hackish... */
        static int reading_conffiles = 0, reading_description = 0;
        static char *description = NULL;
+       char *s;
        int ret = 0;
 
        /* Exclude globally masked fields. */
@@ -116,11 +130,9 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
 
        switch (*line) {
        case 'A':
-               if ((mask & PFM_ARCHITECTURE) && is_field("Architecture", line)) {
-                       pkg->arch_priority = get_arch_priority(
-                               pkg_set_string(pkg, PKG_ARCHITECTURE, line + strlen("Architecture") + 1));
-
-               } else if ((mask & PFM_AUTO_INSTALLED)
+               if ((mask & PFM_ARCHITECTURE) && is_field("Architecture", line))
+                       parse_architecture(pkg, line + strlen("Architecture") + 1);
+               else if ((mask & PFM_AUTO_INSTALLED)
                           && is_field("Auto-Installed", line)) {
                        char *tmp = parse_simple("Auto-Installed", line);
                        if (strcmp(tmp, "yes") == 0)
@@ -136,8 +148,7 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                        goto dont_reset_flags;
                } else if ((mask & PFM_CONFLICTS)
                           && is_field("Conflicts", line))
-                       pkg->conflicts_str =
-                           parse_list(line, &pkg->conflicts_count, ',', 0);
+                       parse_deplist(pkg, CONFLICTS, line + strlen("Conflicts") + 1);
                break;
 
        case 'D':
@@ -147,8 +158,7 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                        reading_description = 1;
                        goto dont_reset_flags;
                } else if ((mask & PFM_DEPENDS) && is_field("Depends", line))
-                       pkg->depends_str =
-                           parse_list(line, &pkg->depends_count, ',', 0);
+                       parse_deplist(pkg, DEPEND, line + strlen("Depends") + 1);
                break;
 
        case 'E':
@@ -168,24 +178,16 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
        case 'I':
                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);
+                       pkg_set_int(pkg, PKG_INSTALLED_SIZE, strtoul(line + strlen("Installed-Size") + 1, NULL, 0));
                } 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);
+                       pkg_set_int(pkg, PKG_INSTALLED_TIME, strtoul(line + strlen("Installed-Time") + 1, NULL, 0));
                }
                break;
 
        case 'M':
-               if ((mask & PFM_MD5SUM) && is_field("MD5sum:", line))
-                       pkg_set_string(pkg, PKG_MD5SUM, line + strlen("MD5sum") + 1);
-               /* The old opkg wrote out status files with the wrong
-                * case for MD5sum, let's parse it either way */
-               else if ((mask & PFM_MD5SUM) && is_field("MD5Sum:", line))
-                       pkg_set_string(pkg, PKG_MD5SUM, line + strlen("MD5Sum") + 1);
+               if ((mask & PFM_MD5SUM) && (is_field("MD5sum:", line) || is_field("MD5Sum:", line)))
+                       pkg_set_md5(pkg, line + strlen("MD5sum") + 1);
                else if ((mask & PFM_MAINTAINER)
                         && is_field("Maintainer", line))
                        pkg_set_string(pkg, PKG_MAINTAINER, line + strlen("Maintainer") + 1);
@@ -197,22 +199,17 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                else if ((mask & PFM_PRIORITY) && is_field("Priority", line))
                        pkg_set_string(pkg, PKG_PRIORITY, line + strlen("Priority") + 1);
                else if ((mask & PFM_PROVIDES) && is_field("Provides", line))
-                       pkg->provides_str =
-                           parse_list(line, &pkg->provides_count, ',', 0);
+                       parse_providelist(pkg, line + strlen("Provides") + 1);
                else if ((mask & PFM_PRE_DEPENDS)
                         && is_field("Pre-Depends", line))
-                       pkg->pre_depends_str =
-                           parse_list(line, &pkg->pre_depends_count, ',', 0);
+                       parse_deplist(pkg, PREDEPEND, line + strlen("Pre-Depends") + 1);
                break;
 
        case 'R':
                if ((mask & PFM_RECOMMENDS) && is_field("Recommends", line))
-                       pkg->recommends_str =
-                           parse_list(line, &pkg->recommends_count, ',', 0);
+                       parse_deplist(pkg, RECOMMEND, line + strlen("Recommends") + 1);
                else if ((mask & PFM_REPLACES) && is_field("Replaces", line))
-                       pkg->replaces_str =
-                           parse_list(line, &pkg->replaces_count, ',', 0);
-
+                       parse_replacelist(pkg, line + strlen("Replaces") + 1);
                break;
 
        case 'S':
@@ -220,19 +217,16 @@ int pkg_parse_line(void *ptr, const char *line, uint mask)
                        pkg_set_string(pkg, PKG_SECTION, line + strlen("Section") + 1);
 #ifdef HAVE_SHA256
                else if ((mask & PFM_SHA256SUM) && is_field("SHA256sum", line))
-                       pkg_set_string(pkg, PKG_SHA256SUM, line + strlen("SHA256sum") + 1);
+                       pkg_set_sha256(pkg, line + strlen("SHA256sum") + 1);
 #endif
                else if ((mask & PFM_SIZE) && is_field("Size", line)) {
-                       char *tmp = parse_simple("Size", line);
-                       pkg->size = strtoul(tmp, NULL, 0);
-                       free(tmp);
+                       pkg_set_int(pkg, PKG_SIZE, strtoul(line + strlen("Size") + 1, NULL, 0));
                } else if ((mask & PFM_SOURCE) && is_field("Source", line))
                        pkg_set_string(pkg, PKG_SOURCE, line + strlen("Source") + 1);
                else if ((mask & PFM_STATUS) && is_field("Status", line))
                        parse_status(pkg, line);
                else if ((mask & PFM_SUGGESTS) && is_field("Suggests", line))
-                       pkg->suggests_str =
-                           parse_list(line, &pkg->suggests_count, ',', 0);
+                       parse_deplist(pkg, SUGGEST, line + strlen("Suggests") + 1);
                break;
 
        case 'T':