Reorganise status field to use 3 chars instead of one bit shifted long int.

Generates status file properly now, not compatable with full dpkg yet.
This commit is contained in:
Glenn L McGrath 2001-04-08 13:27:39 +00:00
parent 37849f3320
commit 305fdfa755
2 changed files with 190 additions and 256 deletions

View File

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

223
dpkg.c
View File

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