pkg: pass-through ABIVersion to status file
[project/opkg-lede.git] / libopkg / pkg.c
index 1a3eda8167bcaf3700cf2940fcff44627a62a4cc..51110687cc8c50368f099b1e82457666104f8655 100644 (file)
@@ -15,8 +15,6 @@
    General Public License for more details.
 */
 
-#include "config.h"
-
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
@@ -108,7 +106,7 @@ void *pkg_set_raw(pkg_t *pkg, int id, const void *val, size_t len)
        blob_for_each_attr(cur, pkg->blob.head, rem) {
                if (blob_id(cur) == id) {
                        if (blob_len(cur) < len) {
-                               fprintf(stderr, "ERROR: truncating field %d <%p> to %d byte",
+                               fprintf(stderr, "ERROR: truncating field %d <%p> to %zu byte",
                                        id, val, blob_len(cur));
                        }
                        memcpy(blob_data(cur), val, blob_len(cur));
@@ -269,7 +267,10 @@ static void compound_depend_deinit(compound_depend_t * depends)
 
 void pkg_deinit(pkg_t * pkg)
 {
+       int rem;
+       struct blob_attr *cur;
        compound_depend_t *deps, *dep;
+       void *ptr;
 
        if (pkg->name)
                free(pkg->name);
@@ -284,24 +285,57 @@ void pkg_deinit(pkg_t * pkg)
        pkg->state_flag = SF_OK;
        pkg->state_status = SS_NOT_INSTALLED;
 
-       deps = pkg_get_ptr(pkg, PKG_DEPENDS);
+       blob_for_each_attr(cur, pkg->blob.head, rem) {
+               switch (blob_id(cur)) {
+               case PKG_DEPENDS:
+               case PKG_CONFLICTS:
+                       deps = pkg_get_ptr(pkg, blob_id(cur));
 
-       if (deps) {
-               for (dep = deps; dep->type; dep++)
-                       compound_depend_deinit(dep);
+                       if (deps) {
+                               for (dep = deps; dep->type; dep++)
+                                       compound_depend_deinit(dep);
 
-               free(deps);
-               pkg_set_ptr(pkg, PKG_DEPENDS, NULL);
-       }
+                               free(deps);
+                       }
+
+                       pkg_set_ptr(pkg, blob_id(cur), NULL);
+                       break;
+
+               case PKG_REPLACES:
+               case PKG_PROVIDES:
+                       ptr = pkg_get_ptr(pkg, blob_id(cur));
+
+                       if (ptr)
+                               free(ptr);
 
-       deps = pkg_get_ptr(pkg, PKG_CONFLICTS);
+                       pkg_set_ptr(pkg, blob_id(cur), NULL);
+                       break;
+
+               case PKG_CONFFILES:
+                       ptr = pkg_get_ptr(pkg, blob_id(cur));
+
+                       if (ptr) {
+                               conffile_list_deinit(ptr);
+                               free(ptr);
+                       }
+
+                       pkg_set_ptr(pkg, blob_id(cur), NULL);
+                       break;
+               case PKG_ALTERNATIVES:
+                       ptr = pkg_get_ptr(pkg, blob_id(cur));
 
-       if (deps) {
-               for (dep = deps; dep->type; dep++)
-                       compound_depend_deinit(dep);
+                       if (ptr) {
+                               struct pkg_alternatives *pkg_alts = ptr;
 
-               free(deps);
-               pkg_set_ptr(pkg, PKG_CONFLICTS, NULL);
+                               while (pkg_alts->nalts)
+                                       free(pkg_alts->alts[--pkg_alts->nalts]);
+                               free(pkg_alts->alts);
+                               free(pkg_alts);
+                       }
+
+                       pkg_set_ptr(pkg, blob_id(cur), NULL);
+                       break;
+               }
        }
 
        //conffile_list_deinit(&pkg->conffiles);
@@ -313,7 +347,7 @@ void pkg_deinit(pkg_t * pkg)
        pkg_free_installed_files(pkg);
        pkg->essential = 0;
 
-       //blob_buf_free(&pkg->blob);
+       blob_buf_free(&pkg->blob);
 }
 
 int pkg_init_from_file(pkg_t * pkg, const char *filename)
@@ -324,6 +358,11 @@ int pkg_init_from_file(pkg_t * pkg, const char *filename)
 
        pkg_init(pkg);
 
+       if (!(pkg->state_flag & SF_NEED_DETAIL)) {
+               opkg_msg(DEBUG, "applying abpkg flag to %s\n", filename);
+               pkg->state_flag |= SF_NEED_DETAIL;
+       }
+
        pkg_set_string(pkg, PKG_LOCAL_FILENAME, filename);
 
        tmp = xstrdup(filename);
@@ -376,7 +415,6 @@ err0:
 int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
 {
        abstract_pkg_t **ab;
-       conffile_list_t *cf, head;
 
        if (oldpkg == newpkg) {
                return 0;
@@ -408,6 +446,9 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
        if (!ab || !ab[0] || !ab[1]) {
                pkg_set_ptr(oldpkg, PKG_PROVIDES, pkg_get_ptr(newpkg, PKG_PROVIDES));
                pkg_set_ptr(newpkg, PKG_PROVIDES, NULL);
+
+               if (ab)
+                       free(ab);
        }
 
        if (!pkg_get_ptr(oldpkg, PKG_CONFLICTS)) {
@@ -438,14 +479,12 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
                pkg_set_string(oldpkg, PKG_PRIORITY, pkg_get_string(newpkg, PKG_PRIORITY));
        if (!pkg_get_string(oldpkg, PKG_SOURCE))
                pkg_set_string(oldpkg, PKG_SOURCE, pkg_get_string(newpkg, PKG_SOURCE));
+       if (!pkg_get_string(oldpkg, PKG_ABIVERSION))
+               pkg_set_string(oldpkg, PKG_ABIVERSION, pkg_get_string(newpkg, PKG_ABIVERSION));
 
        if (!pkg_get_ptr(oldpkg, PKG_CONFFILES)) {
-               cf = pkg_get_ptr(newpkg, PKG_CONFFILES);
-               if (cf) {
-                       conffile_list_init(&head);
-                       list_splice_init(&cf->head, &head.head);
-                       pkg_set_raw(oldpkg, PKG_CONFFILES, &head, sizeof(head));
-               }
+               pkg_set_ptr(oldpkg, PKG_CONFFILES, pkg_get_ptr(newpkg, PKG_CONFFILES));
+               pkg_set_ptr(newpkg, PKG_CONFFILES, NULL);
        }
 
        if (!oldpkg->installed_files) {
@@ -458,6 +497,9 @@ int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
        if (!oldpkg->essential)
                oldpkg->essential = newpkg->essential;
 
+       if (!oldpkg->provided_by_hand)
+               oldpkg->provided_by_hand = newpkg->provided_by_hand;
+
        return 0;
 }
 
@@ -478,34 +520,6 @@ abstract_pkg_t *abstract_pkg_new(void)
        return ab_pkg;
 }
 
-void set_flags_from_control(pkg_t * pkg)
-{
-       char *file_name;
-       FILE *fp;
-
-       sprintf_alloc(&file_name, "%s/%s.control", pkg->dest->info_dir,
-                     pkg->name);
-
-       fp = fopen(file_name, "r");
-       if (fp == NULL) {
-               opkg_perror(ERROR, "Failed to open %s", file_name);
-               free(file_name);
-               return;
-       }
-
-       free(file_name);
-
-       if (pkg_parse_from_stream(pkg, fp, PFM_ALL ^ PFM_ESSENTIAL)) {
-               opkg_msg(DEBUG,
-                        "Unable to read control file for %s. May be empty.\n",
-                        pkg->name);
-       }
-
-       fclose(fp);
-
-       return;
-}
-
 static const char *pkg_state_want_to_str(pkg_state_want_t sw)
 {
        int i;
@@ -638,7 +652,27 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        switch (field[0]) {
        case 'a':
        case 'A':
-               if (strcasecmp(field, "Architecture") == 0) {
+               if (strcasecmp(field, "ABIVersion") == 0) {
+                       p = pkg_get_string(pkg, PKG_ABIVERSION);
+                       if (p) {
+                               fprintf(fp, "ABIVersion: %s\n", p);
+                       }
+               } else if (strcasecmp(field, "Alternatives") == 0) {
+                       struct pkg_alternatives *pkg_alts = pkg_get_ptr(pkg, PKG_ALTERNATIVES);
+
+                       if (pkg_alts && pkg_alts->nalts > 0) {
+                               int i;
+                               struct pkg_alternative *alt;
+
+                               alt = pkg_alts->alts[0];
+                               fprintf(fp, "Alternatives: %d:%s:%s", alt->prio, alt->path, alt->altpath);
+                               for (i = 1; i < pkg_alts->nalts; i++) {
+                                       alt = pkg_alts->alts[i];
+                                       fprintf(fp, ", %d:%s:%s", alt->prio, alt->path, alt->altpath);
+                               }
+                               fputs("\n", fp);
+                       }
+               } else if (strcasecmp(field, "Architecture") == 0) {
                        p = pkg_get_architecture(pkg);
                        if (p) {
                                fprintf(fp, "Architecture: %s\n",
@@ -776,10 +810,9 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                        ab_pkg = pkg_get_ptr(pkg, PKG_PROVIDES);
                        if (ab_pkg && ab_pkg[0] && ab_pkg[1]) {
                                fprintf(fp, "Provides:");
-                               for (i = 0, ab_pkg++; *ab_pkg; i++, ab_pkg++) {
-                                       fprintf(fp, "%s %s", i == 0 ? "" : ",",
-                                               (*ab_pkg)->name);
-                                       ab_pkg++;
+                               for (i = 1; ab_pkg[i]; i++) {
+                                       fprintf(fp, "%s %s", i == 1 ? "" : ",",
+                                               ab_pkg[i]->name);
                                }
                                fprintf(fp, "\n");
                        }
@@ -791,11 +824,11 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
        case 'R':
                if (strcasecmp(field, "Replaces") == 0) {
                        ab_pkg = pkg_get_ptr(pkg, PKG_REPLACES);
-                       if (ab_pkg && *ab_pkg) {
+                       if (ab_pkg && ab_pkg[0]) {
                                fprintf(fp, "Replaces:");
-                               for (i = 0; *ab_pkg; i++, ab_pkg++) {
+                               for (i = 0; ab_pkg[i]; i++) {
                                        fprintf(fp, "%s %s", i == 0 ? "" : ",",
-                                               (*ab_pkg)->name);
+                                               ab_pkg[i]->name);
                                }
                                fprintf(fp, "\n");
                        }
@@ -825,13 +858,11 @@ void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
                        if (p) {
                                fprintf(fp, "Section: %s\n", p);
                        }
-#if defined HAVE_SHA256
                } else if (strcasecmp(field, "SHA256sum") == 0) {
                        p = pkg_get_string(pkg, PKG_SHA256SUM);
                        if (p) {
                                fprintf(fp, "SHA256sum: %s\n", p);
                        }
-#endif
                } else if (strcasecmp(field, "Size") == 0) {
                        i = pkg_get_int(pkg, PKG_SIZE);
                        if (i) {
@@ -930,6 +961,7 @@ void pkg_print_status(pkg_t * pkg, FILE * file)
        }
 
        pkg_formatted_field(file, pkg, "Package");
+       pkg_formatted_field(file, pkg, "ABIVersion");
        pkg_formatted_field(file, pkg, "Version");
        pkg_formatted_field(file, pkg, "Depends");
        pkg_formatted_field(file, pkg, "Recommends");
@@ -943,6 +975,7 @@ void pkg_print_status(pkg_t * pkg, FILE * file)
        pkg_formatted_field(file, pkg, "Conffiles");
        pkg_formatted_field(file, pkg, "Installed-Time");
        pkg_formatted_field(file, pkg, "Auto-Installed");
+       pkg_formatted_field(file, pkg, "Alternatives");
        fputs("\n", file);
 }
 
@@ -1340,7 +1373,8 @@ int pkg_run_script(pkg_t * pkg, const char *script, const char *args)
        /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
           have scripts in tmp_unpack_dir. */
        if (pkg->state_status == SS_INSTALLED
-           || pkg->state_status == SS_UNPACKED) {
+           || pkg->state_status == SS_UNPACKED
+           || pkg->state_status == SS_HALF_INSTALLED) {
                if (pkg->dest == NULL) {
                        opkg_msg(ERROR, "Internal error: %s has a NULL dest.\n",
                                 pkg->name);
@@ -1378,7 +1412,7 @@ int pkg_run_script(pkg_t * pkg, const char *script, const char *args)
        sprintf_alloc(&cmd, "%s %s", path, args);
        free(path);
        {
-               const char *argv[] = { "sh", "-c", cmd, NULL };
+               const char *argv[] = { "/bin/sh", "-c", cmd, NULL };
                err = xsystem(argv);
        }
        free(cmd);