#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
+#include <ctype.h>
#include "sprintf_alloc.h"
#include "file_util.h"
#endif
+char *checksum_bin2hex(const char *src, size_t len)
+{
+ char *p;
+ static char buf[65];
+ static const unsigned char bin2hex[16] = {
+ '0', '1', '2', '3',
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+ 'c', 'd', 'e', 'f'
+ };
+
+ if (len > 32)
+ return NULL;
+
+ for (p = buf; len > 0; src++, len--) {
+ *p++ = bin2hex[*src / 16];
+ *p++ = bin2hex[*src % 16];
+ }
+
+ *p = 0;
+
+ return buf;
+}
+
+char *checksum_hex2bin(const char *src, size_t *len)
+{
+ char *p;
+ size_t slen;
+ static char buf[32];
+
+ while (isspace(*src))
+ src++;
+
+ slen = strlen(src);
+
+ if (slen > 64) {
+ *len = 0;
+ return NULL;
+ }
+
+#define hex(c) \
+ (c >= 'a' ? (c - 'a') : (c >= 'A' ? (c - 'A') : (c - '0')))
+
+ for (p = buf, *len = 0;
+ slen > 0 && isxdigit(src[0]) && isxdigit(src[1]);
+ slen--, src += 2, (*len)++)
+ *p++ = hex(src[0]) * 16 + hex(src[1]);
+
+ return buf;
+}
+
int rm_r(const char *path)
{
int ret = 0;
char *file_sha256sum_alloc(const char *file_name);
int rm_r(const char *path);
+char *checksum_bin2hex(const char *src, size_t len);
+char *checksum_hex2bin(const char *src, size_t *len);
+
#endif
/* check architecture */
if (arch) {
- if (sstrcmp(pkg_get_string(pkg, PKG_ARCHITECTURE), arch))
+ if (sstrcmp(pkg_get_architecture(pkg), arch))
continue;
}
if (!pkg_arch_supported(pkg)) {
opkg_msg(ERROR,
"INTERNAL ERROR: architecture %s for pkg %s is unsupported.\n",
- pkg_get_string(pkg, PKG_ARCHITECTURE), pkg->name);
+ pkg_get_architecture(pkg), pkg->name);
return -1;
}
if (pkg->state_status == SS_INSTALLED && conf->nodeps == 0) {
pkg->essential = 0;
pkg->provided_by_hand = 0;
+ pkg->arch_index = 0;
+
blob_buf_init(&pkg->blob, 0);
}
return p;
}
+char *pkg_get_architecture(const pkg_t *pkg)
+{
+ nv_pair_list_elt_t *l;
+ int n = 1;
+
+ list_for_each_entry(l, &conf->arch_list.head, node) {
+ nv_pair_t *nv = (nv_pair_t *) l->data;
+ if (n++ == pkg->arch_index)
+ return nv->name;
+ }
+
+ return NULL;
+}
+
+char *pkg_set_architecture(pkg_t *pkg, const char *architecture, ssize_t len)
+{
+ nv_pair_list_elt_t *l;
+ int n = 1;
+
+ list_for_each_entry(l, &conf->arch_list.head, node) {
+ nv_pair_t *nv = (nv_pair_t *) l->data;
+
+ if (!strncmp(nv->name, architecture, len) && nv->name[len] == '\0') {
+ if (n >= 8) {
+ opkg_msg(ERROR, "Internal error: too many different architectures\n");
+ break;
+ }
+
+ pkg->arch_index = n;
+ return nv->name;
+ }
+
+ n++;
+ }
+
+ pkg->arch_index = 0;
+ return NULL;
+}
+
+int pkg_get_arch_priority(const pkg_t *pkg)
+{
+ nv_pair_list_elt_t *l;
+ int n = 1;
+
+ list_for_each_entry(l, &conf->arch_list.head, node) {
+ nv_pair_t *nv = (nv_pair_t *) l->data;
+ if (n++ == pkg->arch_index)
+ return strtol(nv->value, NULL, 0);
+ }
+
+ return 0;
+}
+
static void compound_depend_deinit(compound_depend_t * depends)
{
oldpkg->src = newpkg->src;
if (!oldpkg->dest)
oldpkg->dest = newpkg->dest;
- if (!pkg_get_string(oldpkg, PKG_ARCHITECTURE))
- pkg_set_string(oldpkg, PKG_ARCHITECTURE, pkg_get_string(newpkg, PKG_ARCHITECTURE));
- if (!pkg_get_int(oldpkg, PKG_ARCH_PRIORITY))
- pkg_set_int(oldpkg, PKG_ARCH_PRIORITY, pkg_get_int(newpkg, PKG_ARCH_PRIORITY));
+ if (!oldpkg->arch_index)
+ oldpkg->arch_index = newpkg->arch_index;
if (!pkg_get_string(oldpkg, PKG_SECTION))
pkg_set_string(oldpkg, PKG_SECTION, pkg_get_string(newpkg, PKG_SECTION));
if (!pkg_get_string(oldpkg, PKG_MAINTAINER))
case 'a':
case 'A':
if (strcasecmp(field, "Architecture") == 0) {
- p = pkg_get_string(pkg, PKG_ARCHITECTURE);
+ p = pkg_get_architecture(pkg);
if (p) {
fprintf(fp, "Architecture: %s\n",
p);
vercmp = pkg_compare_versions(a, b);
if (vercmp)
return vercmp;
- arch_prio1 = pkg_get_int(a, PKG_ARCH_PRIORITY);
- arch_prio2 = pkg_get_int(b, PKG_ARCH_PRIORITY);
+ arch_prio1 = pkg_get_arch_priority(a);
+ arch_prio2 = pkg_get_arch_priority(b);
if (!arch_prio1 || !arch_prio2) {
opkg_msg(ERROR,
"Internal error: a->arch_priority=%i b->arch_priority=%i.\n",
int pkg_arch_supported(pkg_t * pkg)
{
nv_pair_list_elt_t *l;
- char *architecture = pkg_get_string(pkg, PKG_ARCHITECTURE);
+ char *architecture = pkg_get_architecture(pkg);
if (!architecture)
return 1;
PKG_LOCAL_FILENAME,
PKG_VERSION,
PKG_REVISION,
- PKG_ARCHITECTURE,
- PKG_ARCH_PRIORITY,
PKG_DESCRIPTION,
PKG_MD5SUM,
PKG_SHA256SUM,
int auto_installed:1;
int is_upgrade:1;
+ int arch_index:3;
+
struct blob_buf blob;
};
return ptr ? *ptr : NULL;
}
+char *pkg_set_architecture(pkg_t *pkg, const char *architecture, ssize_t len);
+char *pkg_get_architecture(const pkg_t *pkg);
+int pkg_get_arch_priority(const pkg_t *pkg);
+
+
abstract_pkg_t *abstract_pkg_new(void);
/*
int i;
char *arch1, *arch2;
pkg_t **pkgs = vec->pkgs;
- arch1 = pkg_get_string(pkg, PKG_ARCHITECTURE);
+ arch1 = pkg_get_architecture(pkg);
for (i = 0; i < vec->len; i++) {
- arch2 = pkg_get_string(*(pkgs + i), PKG_ARCHITECTURE);
+ arch2 = pkg_get_architecture(*(pkgs + i));
if ((strcmp(pkg->name, (*(pkgs + i))->name) == 0)
&& (pkg_compare_versions(pkg, *(pkgs + i)) == 0)
continue;
}
- if (!pkg_get_string(pkg, PKG_ARCHITECTURE) ||
- !pkg_get_int(pkg, PKG_ARCH_PRIORITY)) {
+ if (!pkg_get_architecture(pkg) || !pkg_get_arch_priority(pkg)) {
char *version_str = pkg_version_str_alloc(pkg);
opkg_msg(NOTICE, "Package %s version %s has no "
"valid architecture, ignoring.\n",
/* count packages matching max arch priority and keep track of last one */
for (j = 0; j < vec->len; j++) {
pkg_t *maybe = vec->pkgs[j];
- arch_priority = pkg_get_int(maybe, PKG_ARCH_PRIORITY);
+ arch_priority = pkg_get_arch_priority(maybe);
opkg_msg(DEBUG,
"%s arch=%s arch_priority=%d version=%s.\n",
- maybe->name, pkg_get_string(maybe, PKG_ARCHITECTURE),
+ maybe->name, pkg_get_architecture(maybe),
arch_priority, pkg_get_string(maybe, PKG_VERSION));
/* We make sure not to add the same package twice. Need to search for the reason why
they show up twice sometimes. */
int prio = 0;
for (i = 0; i < matching_pkgs->len; i++) {
pkg_t *matching = matching_pkgs->pkgs[i];
- arch_priority = pkg_get_int(matching, PKG_ARCH_PRIORITY);
+ arch_priority = pkg_get_arch_priority(matching);
if (arch_priority > prio) {
priorized_matching = matching;
prio = arch_priority;
pkg_t *matching = matching_pkgs->pkgs[i];
opkg_msg(INFO, "%s %s %s\n",
matching->name, pkg_get_string(matching, PKG_VERSION),
- pkg_get_string(matching, PKG_ARCHITECTURE));
+ pkg_get_architecture(matching));
}
}
if (priorized_matching) {
opkg_msg(INFO, "Using priorized matching %s %s %s.\n",
priorized_matching->name, pkg_get_string(priorized_matching, PKG_VERSION),
- pkg_get_string(priorized_matching, PKG_ARCHITECTURE));
+ pkg_get_architecture(priorized_matching));
return priorized_matching;
}
if (nmatching > 1) {
if (latest_matching) {
opkg_msg(INFO, "Using latest matching %s %s %s.\n",
latest_matching->name, pkg_get_string(latest_matching, PKG_VERSION),
- pkg_get_string(latest_matching, PKG_ARCHITECTURE));
+ pkg_get_architecture(latest_matching));
return latest_matching;
}
return NULL;
#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)
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)
/* 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. */
switch (*line) {
case 'A':
- if ((mask & PFM_ARCHITECTURE) && is_field("Architecture", line)) {
- pkg_set_int(pkg, 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)
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))) {
+ size_t len;
+ char *cksum = checksum_hex2bin(line + strlen("MD5sum") + 1, &len);
+ if (cksum && len == 16)
+ pkg_set_raw(pkg, PKG_MD5SUM, cksum, len);
+ }
else if ((mask & PFM_MAINTAINER)
&& is_field("Maintainer", line))
pkg_set_string(pkg, PKG_MAINTAINER, line + strlen("Maintainer") + 1);
if ((mask & PFM_SECTION) && is_field("Section", line))
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);
+ else if ((mask & PFM_SHA256SUM) && is_field("SHA256sum", line)) {
+ size_t len;
+ char *cksum = checksum_hex2bin(line + strlen("SHA256sum") + 1, &len);
+ if (cksum && len == 32)
+ pkg_set_raw(pkg, PKG_SHA256SUM, cksum, len);
+ }
#endif
else if ((mask & PFM_SIZE) && is_field("Size", line)) {
pkg_set_int(pkg, PKG_SIZE, strtoul(line + strlen("Size") + 1, NULL, 0));
int i;
int found = 0;
char *pkg_version = pkg_get_string(pkg, PKG_VERSION);
- char *pkg_architecture = pkg_get_string(pkg, PKG_ARCHITECTURE);
+ char *pkg_architecture = pkg_get_architecture(pkg);
char *vec_architecture;
/* look for a duplicate pkg by name, version, and architecture */
for (i = 0; i < vec->len; i++) {
- vec_architecture = pkg_get_string(vec->pkgs[i], PKG_ARCHITECTURE);
+ vec_architecture = pkg_get_architecture(vec->pkgs[i]);
opkg_msg(DEBUG2, "%s %s arch=%s vs. %s %s arch=%s.\n",
pkg->name, pkg_version, pkg_architecture,
pkg->name,
v,
pkg->src->name,
- pkg_get_string(pkg, PKG_ARCHITECTURE),
+ pkg_get_architecture(pkg),
pkg_get_string(pkg, PKG_DESCRIPTION),
tags ? tags : "",
(unsigned long) pkg_get_int(pkg, PKG_SIZE), pkg->state_status);
pkg =
opkg_find_package(find_pkg->name,
pkg_get_string(find_pkg, PKG_VERSION),
- pkg_get_string(find_pkg, PKG_ARCHITECTURE),
+ pkg_get_architecture(find_pkg),
find_pkg->src->name);
if (pkg) {
print_package(pkg);