aboutsummaryrefslogtreecommitdiff
path: root/archival/dpkg.c
diff options
context:
space:
mode:
Diffstat (limited to 'archival/dpkg.c')
-rw-r--r--archival/dpkg.c229
1 files changed, 98 insertions, 131 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c
index c992f5338..57b31697b 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -48,39 +48,30 @@ static const char dpkgcidir[] = "/var/lib/dpkg/tmp.ci/";
static const char infodir[] = "/var/lib/dpkg/info/";
static const char udpkg_quiet[] = "UDPKG_QUIET";
-//static const int status_wantstart = 0;
-//static const int status_wantunknown = (1 << 0);
-static const int status_wantinstall = (1 << 1);
-//static const int status_wanthold = (1 << 2);
-//static const int status_wantdeinstall = (1 << 3);
-//static const int status_wantpurge = (1 << 4);
-static const int status_wantmask = 31;
-
-//static const int status_flagstart = 5;
-static const int status_flagok = (1 << 5); /* 32 */
-//static const int status_flagreinstreq = (1 << 6);
-//static const int status_flaghold = (1 << 7);
-//static const int status_flagholdreinstreq = (1 << 8);
-static const int status_flagmask = 480;
-
-//static const int status_statusstart = 9;
-//static const int status_statusnoninstalled = (1 << 9); /* 512 */
-static const int status_statusunpacked = (1 << 10);
-static const int status_statushalfconfigured = (1 << 11);
-static const int status_statusinstalled = (1 << 12);
-static const int status_statushalfinstalled = (1 << 13);
-//static const int status_statusconfigfiles = (1 << 14);
-//static const int status_statuspostinstfailed = (1 << 15);
-//static const int status_statusremovalfailed = (1 << 16);
-static const int status_statusmask = 130560; /* i assume status_statusinstalled is supposed to be included */
-
-static const char *statuswords[][10] = {
- { (char *) 0, "unknown", "install", "hold", "deinstall", "purge", 0 },
- { (char *) 5, "ok", "reinstreq", "hold", "hold-reinstreq", 0 },
- { (char *) 9, "not-installed", "unpacked", "half-configured",
- "installed", "half-installed", "config-files",
- "post-inst-failed", "removal-failed", 0 }
-};
+//static const int status_want_unknown = 1;
+static const int status_want_install = 2;
+//static const int status_want_hold = 3;
+//static const int status_want_deinstall = 4;
+//static const int status_want_purge = 5;
+
+static const int status_flag_ok = 1;
+//static const int status_flag_reinstreq = 2;
+//static const int status_flag_hold = 3;
+//static const int status_flag_holdreinstreq = 4;
+
+//static const int status_statusnoninstalled = 1;
+static const int status_status_unpacked = 2;
+static const int status_status_halfconfigured = 3;
+static const int status_status_installed = 4;
+static const int status_status_halfinstalled = 5;
+//static const int status_statusconfigfiles = 6;
+//static const int status_statuspostinstfailed = 7;
+//static const int status_statusremovalfailed = 8;
+
+static const char *status_words_want[] = { "unknown", "install", "hold", "deinstall", "purge", 0 };
+static const char *status_words_flag[] = { "ok", "reinstreq", "hold", "hold-reinstreq", 0 };
+static const char *status_words_status[] = { "not-installed", "unpacked", "half-configured", "installed",
+ "half-installed", "config-files", "post-inst-failed", "removal-failed", 0 };
static const int color_white = 0;
static const int color_grey = 1;
@@ -95,7 +86,9 @@ typedef struct package_s {
char *provides;
char *description;
int installer_menu_item;
- unsigned long status;
+ unsigned char status_want;
+ unsigned char status_flag;
+ unsigned char status_status;
char color; /* for topo-sort */
struct package_s *requiredfor[DEPENDSMAX];
unsigned short requiredcount;
@@ -271,10 +264,9 @@ static package_t *depends_resolve(package_t *pkgs, void *status)
while (dependsvec[i] != 0) {
/* Check for dependencies; first look for installed packages */
dependpkg.package = dependsvec[i];
- if ((found = tfind(&dependpkg, &status, package_compare)) == 0 ||
- ((chk = *(package_t **)found) &&
- (chk->status & (status_flagok | status_statusinstalled)) !=
- (status_flagok | status_statusinstalled))) {
+ if (((found = tfind(&dependpkg, &status, package_compare)) == 0) ||
+ ((chk = *(package_t **)found) && (chk->status_flag & status_flag_ok) &&
+ (chk->status_status & status_status_installed))) {
/* if it fails, we look through the list of packages we are going to
* install */
@@ -318,58 +310,21 @@ static package_t *depends_resolve(package_t *pkgs, void *status)
* replacing any pre-existing entries. when a merge happens, status info
* read using the status_read function is written back to the status file
*/
-static unsigned long status_parse(const char *line)
+static unsigned char status_parse(const char *line, const char **status_words)
{
- char *p;
- int i, j;
- unsigned long l = 0;
-
- for (i = 0; i < 3; i++) {
- if ((p = strchr(line, ' ')) != NULL) {
- *p = 0;
- }
- j = 1;
- while (statuswords[i][j] != 0) {
- if (strcmp(line, statuswords[i][j]) == 0) {
- l |= (1 << ((int)statuswords[i][0] + j - 1));
- break;
- }
- j++;
- }
- /* parse error */
- if (statuswords[i][j] == 0) {
- return 0;
- }
- line = p+1;
- }
-
- return l;
-}
+ unsigned char status_num;
+ int i = 0;
-static const char *status_print(unsigned long flags)
-{
- /* this function returns a static buffer... */
- static char buf[256];
- int i, j;
-
- buf[0] = 0;
- for (i = 0; i < 3; i++) {
- j = 1;
- while (statuswords[i][j] != 0) {
- if ((flags & (1 << ((int)statuswords[i][0] + j - 1))) != 0) {
- strcat(buf, statuswords[i][j]);
- if (i < 2) strcat(buf, " ");
- break;
- }
- j++;
- }
- if (statuswords[i][j] == 0) {
- fprintf(stderr, "corrupted status flag!!\n");
- return NULL;
+ while (status_words[i] != 0) {
+ if (strncmp(line, status_words[i], strlen(status_words[i])) == 0) {
+ status_num = (char)i;
+ return(status_num);
}
+ i++;
}
-
- return buf;
+ /* parse error */
+ error_msg("Invalid status word");
+ return(0);
}
/*
@@ -385,24 +340,30 @@ static int control_read(FILE *file, package_t *p)
if (strlen(line) == 0) {
break;
- } else
- if (strstr(line, "Package: ") == line) {
+ }
+ else if (strstr(line, "Package: ") == line) {
p->package = xstrdup(line + 9);
- } else
- if (strstr(line, "Status: ") == line) {
- p->status = status_parse(line + 8);
- } else
- if (strstr(line, "Depends: ") == line) {
+ }
+ else if (strstr(line, "Status: ") == line) {
+ char *word_pointer;
+ word_pointer = strchr(line, ' ') + 1;
+ p->status_want = status_parse(word_pointer, status_words_want);
+ word_pointer = strchr(word_pointer, ' ') + 1;
+ p->status_flag = status_parse(word_pointer, status_words_flag);
+ word_pointer = strchr(word_pointer, ' ') + 1;
+ p->status_status = status_parse(word_pointer, status_words_status);
+ }
+ else if (strstr(line, "Depends: ") == line) {
p->depends = xstrdup(line + 9);
- } else
- if (strstr(line, "Provides: ") == line) {
+ }
+ else if (strstr(line, "Provides: ") == line) {
p->provides = xstrdup(line + 10);
- } else
- if (strstr(line, "Description: ") == line) {
+ }
+ else if (strstr(line, "Description: ") == line) {
p->description = xstrdup(line + 13);
/* This is specific to the Debian Installer. Ifdef? */
- } else
- if (strstr(line, "installer-menu-item: ") == line) {
+ }
+ else if (strstr(line, "installer-menu-item: ") == line) {
p->installer_menu_item = atoi(line + 21);
}
/* TODO: localized descriptions */
@@ -417,15 +378,14 @@ static void *status_read(void)
void *status = 0;
package_t *m = 0, *p = 0, *t = 0;
- if ((f = fopen(statusfile, "r")) == NULL) {
- perror_msg(statusfile);
- return 0;
- }
-
if (getenv(udpkg_quiet) == NULL) {
printf("(Reading database...)\n");
}
+ if ((f = fopen(statusfile, "r")) == NULL) {
+ return(NULL);
+ }
+
while (!feof(f)) {
m = (package_t *)xcalloc(1, sizeof(package_t));
control_read(f, m);
@@ -445,22 +405,22 @@ static void *status_read(void)
*/
p = (package_t *)xcalloc(1, sizeof(package_t));
p->package = xstrdup(m->provides);
-
t = *(package_t **)tsearch(p, &status, package_compare);
if (t != p) {
free(p->package);
free(p);
- }
- else {
+ } else {
/*
* Pseudo package status is the
* same as the status of the
* package providing it
* FIXME: (not quite right, if 2
* packages of different statuses
- * provide it).
- */
- t->status = m->status;
+ * provide it).
+ */
+ t->status_want = m->status_want;
+ t->status_flag = m->status_flag;
+ t->status_status = m->status_status;
}
}
}
@@ -485,6 +445,7 @@ static int status_merge(void *status, package_t *pkgs)
if (getenv(udpkg_quiet) == NULL) {
printf("(Updating database...)\n");
}
+
/*
* Dont use wfopen here, handle errors ourself
*/
@@ -517,8 +478,10 @@ static int status_merge(void *status, package_t *pkgs)
continue;
}
if (strstr(line, "Status: ") == line && statpkg != 0) {
- snprintf(line, sizeof(line), "Status: %s",
- status_print(statpkg->status));
+ snprintf(line, sizeof(line), "Status: %s %s %s",
+ status_words_want[statpkg->status_want - 1],
+ status_words_flag[statpkg->status_flag - 1],
+ status_words_status[statpkg->status_status - 1]);
}
fputs(line, fout);
fputc('\n', fout);
@@ -529,8 +492,11 @@ static int status_merge(void *status, package_t *pkgs)
// Print out packages we processed.
for (pkg = pkgs; pkg != 0; pkg = pkg->next) {
- fprintf(fout, "Package: %s\nStatus: %s\n",
- pkg->package, status_print(pkg->status));
+ fprintf(fout, "Package: %s\nStatus: %s %s %s\n",
+ pkg->package, status_words_want[pkg->status_want - 1],
+ status_words_flag[pkg->status_flag - 1],
+ status_words_status[pkg->status_status - 1]);
+
if (pkg->depends)
fprintf(fout, "Depends: %s\n", pkg->depends);
if (pkg->provides)
@@ -548,10 +514,11 @@ static int status_merge(void *status, package_t *pkgs)
*/
if (rename(statusfile, bak_statusfile) == -1) {
struct stat stat_buf;
- error_msg("Couldnt create backup status file");
if (stat(statusfile, &stat_buf) == 0) {
+ error_msg("Couldnt create backup status file");
return(EXIT_FAILURE);
}
+ error_msg("No status file found, creating new one");
}
if (rename(new_statusfile, statusfile) == -1) {
@@ -578,18 +545,18 @@ static int dpkg_doconfigure(package_t *pkg)
char buf[1024];
DPRINTF("Configuring %s\n", pkg->package);
- pkg->status &= status_statusmask;
+ pkg->status_status = 0;
snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package);
if (is_file(postinst)) {
snprintf(buf, sizeof(buf), "%s configure", postinst);
if ((r = do_system(buf)) != 0) {
fprintf(stderr, "postinst exited with status %d\n", r);
- pkg->status |= status_statushalfconfigured;
+ pkg->status_status = status_status_halfconfigured;
return 1;
}
}
- pkg->status |= status_statusinstalled;
+ pkg->status_status = status_status_installed;
return 0;
}
@@ -597,6 +564,7 @@ static int dpkg_doconfigure(package_t *pkg)
static int dpkg_dounpack(package_t *pkg)
{
int r = 0, i;
+ int status = TRUE;
char *cwd;
char *src_file = NULL;
char *dst_file = NULL;
@@ -630,12 +598,14 @@ static int dpkg_dounpack(package_t *pkg)
if (lstat(src_file, &src_stat_buf) == 0) {
if ((src_fd = open(src_file, O_RDONLY)) != -1) {
if ((dst_fd = open(dst_file, O_WRONLY | O_CREAT, 0644)) == -1) {
+ status = FALSE;
perror_msg("Opening %s", dst_file);
}
copy_file_chunk(src_fd, dst_fd, src_stat_buf.st_size);
close(src_fd);
close(dst_fd);
} else {
+ status = FALSE;
error_msg("couldnt open [%s]\n", src_file);
}
}
@@ -652,17 +622,15 @@ static int dpkg_dounpack(package_t *pkg)
deb_extract(dpkg_deb_list, NULL, pkg->file);
*/
- pkg->status &= status_wantmask;
- pkg->status |= status_wantinstall;
- pkg->status &= status_flagmask;
- pkg->status |= status_flagok;
- pkg->status &= status_statusmask;
-
- if (r == 0) {
- pkg->status |= status_statusunpacked;
+ pkg->status_want = status_want_install;
+ pkg->status_flag = status_flag_ok;
+
+ if (status == TRUE) {
+ pkg->status_status = status_status_unpacked;
} else {
- pkg->status |= status_statushalfinstalled;
+ pkg->status_status = status_status_halfinstalled;
}
+
chdir(cwd);
return r;
}
@@ -781,19 +749,18 @@ static int dpkg_install(package_t *pkgs, void *status)
/* Stage 3: install */
for (p = ordered; p != 0; p = p->next) {
- p->status &= status_wantmask;
- p->status |= status_wantinstall;
+ p->status_want = status_want_install;
/* for now the flag is always set to ok... this is probably
* not what we want
*/
- p->status &= status_flagmask;
- p->status |= status_flagok;
+ p->status_flag = status_flag_ok;
DPRINTF("Installing %s\n", p->package);
if (dpkg_dounpack(p) != 0) {
perror_msg(p->file);
}
+
if (dpkg_doconfigure(p) != 0) {
perror_msg(p->file);
}