mirror of
https://github.com/sheumann/hush.git
synced 2025-01-03 00:31:16 +00:00
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:
parent
37849f3320
commit
305fdfa755
223
archival/dpkg.c
223
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 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
223
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 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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user