aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2001-04-08 13:27:39 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2001-04-08 13:27:39 +0000
commit305fdfa755c94bdbe54fb9bd3db2f51086f9f2d3 (patch)
tree4aeb507ee3c04c609dd84049622138c5b284d2cc
parent37849f3320e3ca3d998ea249594d80f79e4083e2 (diff)
downloadbusybox-w32-305fdfa755c94bdbe54fb9bd3db2f51086f9f2d3.tar.gz
busybox-w32-305fdfa755c94bdbe54fb9bd3db2f51086f9f2d3.tar.bz2
busybox-w32-305fdfa755c94bdbe54fb9bd3db2f51086f9f2d3.zip
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.
-rw-r--r--archival/dpkg.c229
-rw-r--r--dpkg.c229
2 files changed, 196 insertions, 262 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/";
48static const char infodir[] = "/var/lib/dpkg/info/"; 48static const char infodir[] = "/var/lib/dpkg/info/";
49static const char udpkg_quiet[] = "UDPKG_QUIET"; 49static const char udpkg_quiet[] = "UDPKG_QUIET";
50 50
51//static const int status_wantstart = 0; 51//static const int status_want_unknown = 1;
52//static const int status_wantunknown = (1 << 0); 52static const int status_want_install = 2;
53static const int status_wantinstall = (1 << 1); 53//static const int status_want_hold = 3;
54//static const int status_wanthold = (1 << 2); 54//static const int status_want_deinstall = 4;
55//static const int status_wantdeinstall = (1 << 3); 55//static const int status_want_purge = 5;
56//static const int status_wantpurge = (1 << 4); 56
57static const int status_wantmask = 31; 57static const int status_flag_ok = 1;
58 58//static const int status_flag_reinstreq = 2;
59//static const int status_flagstart = 5; 59//static const int status_flag_hold = 3;
60static const int status_flagok = (1 << 5); /* 32 */ 60//static const int status_flag_holdreinstreq = 4;
61//static const int status_flagreinstreq = (1 << 6); 61
62//static const int status_flaghold = (1 << 7); 62//static const int status_statusnoninstalled = 1;
63//static const int status_flagholdreinstreq = (1 << 8); 63static const int status_status_unpacked = 2;
64static const int status_flagmask = 480; 64static const int status_status_halfconfigured = 3;
65 65static const int status_status_installed = 4;
66//static const int status_statusstart = 9; 66static const int status_status_halfinstalled = 5;
67//static const int status_statusnoninstalled = (1 << 9); /* 512 */ 67//static const int status_statusconfigfiles = 6;
68static const int status_statusunpacked = (1 << 10); 68//static const int status_statuspostinstfailed = 7;
69static const int status_statushalfconfigured = (1 << 11); 69//static const int status_statusremovalfailed = 8;
70static const int status_statusinstalled = (1 << 12); 70
71static const int status_statushalfinstalled = (1 << 13); 71static const char *status_words_want[] = { "unknown", "install", "hold", "deinstall", "purge", 0 };
72//static const int status_statusconfigfiles = (1 << 14); 72static const char *status_words_flag[] = { "ok", "reinstreq", "hold", "hold-reinstreq", 0 };
73//static const int status_statuspostinstfailed = (1 << 15); 73static const char *status_words_status[] = { "not-installed", "unpacked", "half-configured", "installed",
74//static const int status_statusremovalfailed = (1 << 16); 74 "half-installed", "config-files", "post-inst-failed", "removal-failed", 0 };
75static const int status_statusmask = 130560; /* i assume status_statusinstalled is supposed to be included */
76
77static const char *statuswords[][10] = {
78 { (char *) 0, "unknown", "install", "hold", "deinstall", "purge", 0 },
79 { (char *) 5, "ok", "reinstreq", "hold", "hold-reinstreq", 0 },
80 { (char *) 9, "not-installed", "unpacked", "half-configured",
81 "installed", "half-installed", "config-files",
82 "post-inst-failed", "removal-failed", 0 }
83};
84 75
85static const int color_white = 0; 76static const int color_white = 0;
86static const int color_grey = 1; 77static const int color_grey = 1;
@@ -95,7 +86,9 @@ typedef struct package_s {
95 char *provides; 86 char *provides;
96 char *description; 87 char *description;
97 int installer_menu_item; 88 int installer_menu_item;
98 unsigned long status; 89 unsigned char status_want;
90 unsigned char status_flag;
91 unsigned char status_status;
99 char color; /* for topo-sort */ 92 char color; /* for topo-sort */
100 struct package_s *requiredfor[DEPENDSMAX]; 93 struct package_s *requiredfor[DEPENDSMAX];
101 unsigned short requiredcount; 94 unsigned short requiredcount;
@@ -271,10 +264,9 @@ static package_t *depends_resolve(package_t *pkgs, void *status)
271 while (dependsvec[i] != 0) { 264 while (dependsvec[i] != 0) {
272 /* Check for dependencies; first look for installed packages */ 265 /* Check for dependencies; first look for installed packages */
273 dependpkg.package = dependsvec[i]; 266 dependpkg.package = dependsvec[i];
274 if ((found = tfind(&dependpkg, &status, package_compare)) == 0 || 267 if (((found = tfind(&dependpkg, &status, package_compare)) == 0) ||
275 ((chk = *(package_t **)found) && 268 ((chk = *(package_t **)found) && (chk->status_flag & status_flag_ok) &&
276 (chk->status & (status_flagok | status_statusinstalled)) != 269 (chk->status_status & status_status_installed))) {
277 (status_flagok | status_statusinstalled))) {
278 270
279 /* if it fails, we look through the list of packages we are going to 271 /* if it fails, we look through the list of packages we are going to
280 * install */ 272 * install */
@@ -318,58 +310,21 @@ static package_t *depends_resolve(package_t *pkgs, void *status)
318 * replacing any pre-existing entries. when a merge happens, status info 310 * replacing any pre-existing entries. when a merge happens, status info
319 * read using the status_read function is written back to the status file 311 * read using the status_read function is written back to the status file
320 */ 312 */
321static unsigned long status_parse(const char *line) 313static unsigned char status_parse(const char *line, const char **status_words)
322{ 314{
323 char *p; 315 unsigned char status_num;
324 int i, j; 316 int i = 0;
325 unsigned long l = 0;
326
327 for (i = 0; i < 3; i++) {
328 if ((p = strchr(line, ' ')) != NULL) {
329 *p = 0;
330 }
331 j = 1;
332 while (statuswords[i][j] != 0) {
333 if (strcmp(line, statuswords[i][j]) == 0) {
334 l |= (1 << ((int)statuswords[i][0] + j - 1));
335 break;
336 }
337 j++;
338 }
339 /* parse error */
340 if (statuswords[i][j] == 0) {
341 return 0;
342 }
343 line = p+1;
344 }
345
346 return l;
347}
348 317
349static const char *status_print(unsigned long flags) 318 while (status_words[i] != 0) {
350{ 319 if (strncmp(line, status_words[i], strlen(status_words[i])) == 0) {
351 /* this function returns a static buffer... */ 320 status_num = (char)i;
352 static char buf[256]; 321 return(status_num);
353 int i, j;
354
355 buf[0] = 0;
356 for (i = 0; i < 3; i++) {
357 j = 1;
358 while (statuswords[i][j] != 0) {
359 if ((flags & (1 << ((int)statuswords[i][0] + j - 1))) != 0) {
360 strcat(buf, statuswords[i][j]);
361 if (i < 2) strcat(buf, " ");
362 break;
363 }
364 j++;
365 }
366 if (statuswords[i][j] == 0) {
367 fprintf(stderr, "corrupted status flag!!\n");
368 return NULL;
369 } 322 }
323 i++;
370 } 324 }
371 325 /* parse error */
372 return buf; 326 error_msg("Invalid status word");
327 return(0);
373} 328}
374 329
375/* 330/*
@@ -385,24 +340,30 @@ static int control_read(FILE *file, package_t *p)
385 340
386 if (strlen(line) == 0) { 341 if (strlen(line) == 0) {
387 break; 342 break;
388 } else 343 }
389 if (strstr(line, "Package: ") == line) { 344 else if (strstr(line, "Package: ") == line) {
390 p->package = xstrdup(line + 9); 345 p->package = xstrdup(line + 9);
391 } else 346 }
392 if (strstr(line, "Status: ") == line) { 347 else if (strstr(line, "Status: ") == line) {
393 p->status = status_parse(line + 8); 348 char *word_pointer;
394 } else 349 word_pointer = strchr(line, ' ') + 1;
395 if (strstr(line, "Depends: ") == line) { 350 p->status_want = status_parse(word_pointer, status_words_want);
351 word_pointer = strchr(word_pointer, ' ') + 1;
352 p->status_flag = status_parse(word_pointer, status_words_flag);
353 word_pointer = strchr(word_pointer, ' ') + 1;
354 p->status_status = status_parse(word_pointer, status_words_status);
355 }
356 else if (strstr(line, "Depends: ") == line) {
396 p->depends = xstrdup(line + 9); 357 p->depends = xstrdup(line + 9);
397 } else 358 }
398 if (strstr(line, "Provides: ") == line) { 359 else if (strstr(line, "Provides: ") == line) {
399 p->provides = xstrdup(line + 10); 360 p->provides = xstrdup(line + 10);
400 } else 361 }
401 if (strstr(line, "Description: ") == line) { 362 else if (strstr(line, "Description: ") == line) {
402 p->description = xstrdup(line + 13); 363 p->description = xstrdup(line + 13);
403 /* This is specific to the Debian Installer. Ifdef? */ 364 /* This is specific to the Debian Installer. Ifdef? */
404 } else 365 }
405 if (strstr(line, "installer-menu-item: ") == line) { 366 else if (strstr(line, "installer-menu-item: ") == line) {
406 p->installer_menu_item = atoi(line + 21); 367 p->installer_menu_item = atoi(line + 21);
407 } 368 }
408 /* TODO: localized descriptions */ 369 /* TODO: localized descriptions */
@@ -417,15 +378,14 @@ static void *status_read(void)
417 void *status = 0; 378 void *status = 0;
418 package_t *m = 0, *p = 0, *t = 0; 379 package_t *m = 0, *p = 0, *t = 0;
419 380
420 if ((f = fopen(statusfile, "r")) == NULL) {
421 perror_msg(statusfile);
422 return 0;
423 }
424
425 if (getenv(udpkg_quiet) == NULL) { 381 if (getenv(udpkg_quiet) == NULL) {
426 printf("(Reading database...)\n"); 382 printf("(Reading database...)\n");
427 } 383 }
428 384
385 if ((f = fopen(statusfile, "r")) == NULL) {
386 return(NULL);
387 }
388
429 while (!feof(f)) { 389 while (!feof(f)) {
430 m = (package_t *)xcalloc(1, sizeof(package_t)); 390 m = (package_t *)xcalloc(1, sizeof(package_t));
431 control_read(f, m); 391 control_read(f, m);
@@ -445,22 +405,22 @@ static void *status_read(void)
445 */ 405 */
446 p = (package_t *)xcalloc(1, sizeof(package_t)); 406 p = (package_t *)xcalloc(1, sizeof(package_t));
447 p->package = xstrdup(m->provides); 407 p->package = xstrdup(m->provides);
448
449 t = *(package_t **)tsearch(p, &status, package_compare); 408 t = *(package_t **)tsearch(p, &status, package_compare);
450 if (t != p) { 409 if (t != p) {
451 free(p->package); 410 free(p->package);
452 free(p); 411 free(p);
453 } 412 } else {
454 else {
455 /* 413 /*
456 * Pseudo package status is the 414 * Pseudo package status is the
457 * same as the status of the 415 * same as the status of the
458 * package providing it 416 * package providing it
459 * FIXME: (not quite right, if 2 417 * FIXME: (not quite right, if 2
460 * packages of different statuses 418 * packages of different statuses
461 * provide it). 419 * provide it).
462 */ 420 */
463 t->status = m->status; 421 t->status_want = m->status_want;
422 t->status_flag = m->status_flag;
423 t->status_status = m->status_status;
464 } 424 }
465 } 425 }
466 } 426 }
@@ -485,6 +445,7 @@ static int status_merge(void *status, package_t *pkgs)
485 if (getenv(udpkg_quiet) == NULL) { 445 if (getenv(udpkg_quiet) == NULL) {
486 printf("(Updating database...)\n"); 446 printf("(Updating database...)\n");
487 } 447 }
448
488 /* 449 /*
489 * Dont use wfopen here, handle errors ourself 450 * Dont use wfopen here, handle errors ourself
490 */ 451 */
@@ -517,8 +478,10 @@ static int status_merge(void *status, package_t *pkgs)
517 continue; 478 continue;
518 } 479 }
519 if (strstr(line, "Status: ") == line && statpkg != 0) { 480 if (strstr(line, "Status: ") == line && statpkg != 0) {
520 snprintf(line, sizeof(line), "Status: %s", 481 snprintf(line, sizeof(line), "Status: %s %s %s",
521 status_print(statpkg->status)); 482 status_words_want[statpkg->status_want - 1],
483 status_words_flag[statpkg->status_flag - 1],
484 status_words_status[statpkg->status_status - 1]);
522 } 485 }
523 fputs(line, fout); 486 fputs(line, fout);
524 fputc('\n', fout); 487 fputc('\n', fout);
@@ -529,8 +492,11 @@ static int status_merge(void *status, package_t *pkgs)
529 492
530 // Print out packages we processed. 493 // Print out packages we processed.
531 for (pkg = pkgs; pkg != 0; pkg = pkg->next) { 494 for (pkg = pkgs; pkg != 0; pkg = pkg->next) {
532 fprintf(fout, "Package: %s\nStatus: %s\n", 495 fprintf(fout, "Package: %s\nStatus: %s %s %s\n",
533 pkg->package, status_print(pkg->status)); 496 pkg->package, status_words_want[pkg->status_want - 1],
497 status_words_flag[pkg->status_flag - 1],
498 status_words_status[pkg->status_status - 1]);
499
534 if (pkg->depends) 500 if (pkg->depends)
535 fprintf(fout, "Depends: %s\n", pkg->depends); 501 fprintf(fout, "Depends: %s\n", pkg->depends);
536 if (pkg->provides) 502 if (pkg->provides)
@@ -548,10 +514,11 @@ static int status_merge(void *status, package_t *pkgs)
548 */ 514 */
549 if (rename(statusfile, bak_statusfile) == -1) { 515 if (rename(statusfile, bak_statusfile) == -1) {
550 struct stat stat_buf; 516 struct stat stat_buf;
551 error_msg("Couldnt create backup status file");
552 if (stat(statusfile, &stat_buf) == 0) { 517 if (stat(statusfile, &stat_buf) == 0) {
518 error_msg("Couldnt create backup status file");
553 return(EXIT_FAILURE); 519 return(EXIT_FAILURE);
554 } 520 }
521 error_msg("No status file found, creating new one");
555 } 522 }
556 523
557 if (rename(new_statusfile, statusfile) == -1) { 524 if (rename(new_statusfile, statusfile) == -1) {
@@ -578,18 +545,18 @@ static int dpkg_doconfigure(package_t *pkg)
578 char buf[1024]; 545 char buf[1024];
579 546
580 DPRINTF("Configuring %s\n", pkg->package); 547 DPRINTF("Configuring %s\n", pkg->package);
581 pkg->status &= status_statusmask; 548 pkg->status_status = 0;
582 snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package); 549 snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package);
583 550
584 if (is_file(postinst)) { 551 if (is_file(postinst)) {
585 snprintf(buf, sizeof(buf), "%s configure", postinst); 552 snprintf(buf, sizeof(buf), "%s configure", postinst);
586 if ((r = do_system(buf)) != 0) { 553 if ((r = do_system(buf)) != 0) {
587 fprintf(stderr, "postinst exited with status %d\n", r); 554 fprintf(stderr, "postinst exited with status %d\n", r);
588 pkg->status |= status_statushalfconfigured; 555 pkg->status_status = status_status_halfconfigured;
589 return 1; 556 return 1;
590 } 557 }
591 } 558 }
592 pkg->status |= status_statusinstalled; 559 pkg->status_status = status_status_installed;
593 560
594 return 0; 561 return 0;
595} 562}
@@ -597,6 +564,7 @@ static int dpkg_doconfigure(package_t *pkg)
597static int dpkg_dounpack(package_t *pkg) 564static int dpkg_dounpack(package_t *pkg)
598{ 565{
599 int r = 0, i; 566 int r = 0, i;
567 int status = TRUE;
600 char *cwd; 568 char *cwd;
601 char *src_file = NULL; 569 char *src_file = NULL;
602 char *dst_file = NULL; 570 char *dst_file = NULL;
@@ -630,12 +598,14 @@ static int dpkg_dounpack(package_t *pkg)
630 if (lstat(src_file, &src_stat_buf) == 0) { 598 if (lstat(src_file, &src_stat_buf) == 0) {
631 if ((src_fd = open(src_file, O_RDONLY)) != -1) { 599 if ((src_fd = open(src_file, O_RDONLY)) != -1) {
632 if ((dst_fd = open(dst_file, O_WRONLY | O_CREAT, 0644)) == -1) { 600 if ((dst_fd = open(dst_file, O_WRONLY | O_CREAT, 0644)) == -1) {
601 status = FALSE;
633 perror_msg("Opening %s", dst_file); 602 perror_msg("Opening %s", dst_file);
634 } 603 }
635 copy_file_chunk(src_fd, dst_fd, src_stat_buf.st_size); 604 copy_file_chunk(src_fd, dst_fd, src_stat_buf.st_size);
636 close(src_fd); 605 close(src_fd);
637 close(dst_fd); 606 close(dst_fd);
638 } else { 607 } else {
608 status = FALSE;
639 error_msg("couldnt open [%s]\n", src_file); 609 error_msg("couldnt open [%s]\n", src_file);
640 } 610 }
641 } 611 }
@@ -652,17 +622,15 @@ static int dpkg_dounpack(package_t *pkg)
652 deb_extract(dpkg_deb_list, NULL, pkg->file); 622 deb_extract(dpkg_deb_list, NULL, pkg->file);
653*/ 623*/
654 624
655 pkg->status &= status_wantmask; 625 pkg->status_want = status_want_install;
656 pkg->status |= status_wantinstall; 626 pkg->status_flag = status_flag_ok;
657 pkg->status &= status_flagmask; 627
658 pkg->status |= status_flagok; 628 if (status == TRUE) {
659 pkg->status &= status_statusmask; 629 pkg->status_status = status_status_unpacked;
660
661 if (r == 0) {
662 pkg->status |= status_statusunpacked;
663 } else { 630 } else {
664 pkg->status |= status_statushalfinstalled; 631 pkg->status_status = status_status_halfinstalled;
665 } 632 }
633
666 chdir(cwd); 634 chdir(cwd);
667 return r; 635 return r;
668} 636}
@@ -781,19 +749,18 @@ static int dpkg_install(package_t *pkgs, void *status)
781 749
782 /* Stage 3: install */ 750 /* Stage 3: install */
783 for (p = ordered; p != 0; p = p->next) { 751 for (p = ordered; p != 0; p = p->next) {
784 p->status &= status_wantmask; 752 p->status_want = status_want_install;
785 p->status |= status_wantinstall;
786 753
787 /* for now the flag is always set to ok... this is probably 754 /* for now the flag is always set to ok... this is probably
788 * not what we want 755 * not what we want
789 */ 756 */
790 p->status &= status_flagmask; 757 p->status_flag = status_flag_ok;
791 p->status |= status_flagok;
792 758
793 DPRINTF("Installing %s\n", p->package); 759 DPRINTF("Installing %s\n", p->package);
794 if (dpkg_dounpack(p) != 0) { 760 if (dpkg_dounpack(p) != 0) {
795 perror_msg(p->file); 761 perror_msg(p->file);
796 } 762 }
763
797 if (dpkg_doconfigure(p) != 0) { 764 if (dpkg_doconfigure(p) != 0) {
798 perror_msg(p->file); 765 perror_msg(p->file);
799 } 766 }
diff --git a/dpkg.c b/dpkg.c
index c992f5338..57b31697b 100644
--- a/dpkg.c
+++ b/dpkg.c
@@ -48,39 +48,30 @@ static const char dpkgcidir[] = "/var/lib/dpkg/tmp.ci/";
48static const char infodir[] = "/var/lib/dpkg/info/"; 48static const char infodir[] = "/var/lib/dpkg/info/";
49static const char udpkg_quiet[] = "UDPKG_QUIET"; 49static const char udpkg_quiet[] = "UDPKG_QUIET";
50 50
51//static const int status_wantstart = 0; 51//static const int status_want_unknown = 1;
52//static const int status_wantunknown = (1 << 0); 52static const int status_want_install = 2;
53static const int status_wantinstall = (1 << 1); 53//static const int status_want_hold = 3;
54//static const int status_wanthold = (1 << 2); 54//static const int status_want_deinstall = 4;
55//static const int status_wantdeinstall = (1 << 3); 55//static const int status_want_purge = 5;
56//static const int status_wantpurge = (1 << 4); 56
57static const int status_wantmask = 31; 57static const int status_flag_ok = 1;
58 58//static const int status_flag_reinstreq = 2;
59//static const int status_flagstart = 5; 59//static const int status_flag_hold = 3;
60static const int status_flagok = (1 << 5); /* 32 */ 60//static const int status_flag_holdreinstreq = 4;
61//static const int status_flagreinstreq = (1 << 6); 61
62//static const int status_flaghold = (1 << 7); 62//static const int status_statusnoninstalled = 1;
63//static const int status_flagholdreinstreq = (1 << 8); 63static const int status_status_unpacked = 2;
64static const int status_flagmask = 480; 64static const int status_status_halfconfigured = 3;
65 65static const int status_status_installed = 4;
66//static const int status_statusstart = 9; 66static const int status_status_halfinstalled = 5;
67//static const int status_statusnoninstalled = (1 << 9); /* 512 */ 67//static const int status_statusconfigfiles = 6;
68static const int status_statusunpacked = (1 << 10); 68//static const int status_statuspostinstfailed = 7;
69static const int status_statushalfconfigured = (1 << 11); 69//static const int status_statusremovalfailed = 8;
70static const int status_statusinstalled = (1 << 12); 70
71static const int status_statushalfinstalled = (1 << 13); 71static const char *status_words_want[] = { "unknown", "install", "hold", "deinstall", "purge", 0 };
72//static const int status_statusconfigfiles = (1 << 14); 72static const char *status_words_flag[] = { "ok", "reinstreq", "hold", "hold-reinstreq", 0 };
73//static const int status_statuspostinstfailed = (1 << 15); 73static const char *status_words_status[] = { "not-installed", "unpacked", "half-configured", "installed",
74//static const int status_statusremovalfailed = (1 << 16); 74 "half-installed", "config-files", "post-inst-failed", "removal-failed", 0 };
75static const int status_statusmask = 130560; /* i assume status_statusinstalled is supposed to be included */
76
77static const char *statuswords[][10] = {
78 { (char *) 0, "unknown", "install", "hold", "deinstall", "purge", 0 },
79 { (char *) 5, "ok", "reinstreq", "hold", "hold-reinstreq", 0 },
80 { (char *) 9, "not-installed", "unpacked", "half-configured",
81 "installed", "half-installed", "config-files",
82 "post-inst-failed", "removal-failed", 0 }
83};
84 75
85static const int color_white = 0; 76static const int color_white = 0;
86static const int color_grey = 1; 77static const int color_grey = 1;
@@ -95,7 +86,9 @@ typedef struct package_s {
95 char *provides; 86 char *provides;
96 char *description; 87 char *description;
97 int installer_menu_item; 88 int installer_menu_item;
98 unsigned long status; 89 unsigned char status_want;
90 unsigned char status_flag;
91 unsigned char status_status;
99 char color; /* for topo-sort */ 92 char color; /* for topo-sort */
100 struct package_s *requiredfor[DEPENDSMAX]; 93 struct package_s *requiredfor[DEPENDSMAX];
101 unsigned short requiredcount; 94 unsigned short requiredcount;
@@ -271,10 +264,9 @@ static package_t *depends_resolve(package_t *pkgs, void *status)
271 while (dependsvec[i] != 0) { 264 while (dependsvec[i] != 0) {
272 /* Check for dependencies; first look for installed packages */ 265 /* Check for dependencies; first look for installed packages */
273 dependpkg.package = dependsvec[i]; 266 dependpkg.package = dependsvec[i];
274 if ((found = tfind(&dependpkg, &status, package_compare)) == 0 || 267 if (((found = tfind(&dependpkg, &status, package_compare)) == 0) ||
275 ((chk = *(package_t **)found) && 268 ((chk = *(package_t **)found) && (chk->status_flag & status_flag_ok) &&
276 (chk->status & (status_flagok | status_statusinstalled)) != 269 (chk->status_status & status_status_installed))) {
277 (status_flagok | status_statusinstalled))) {
278 270
279 /* if it fails, we look through the list of packages we are going to 271 /* if it fails, we look through the list of packages we are going to
280 * install */ 272 * install */
@@ -318,58 +310,21 @@ static package_t *depends_resolve(package_t *pkgs, void *status)
318 * replacing any pre-existing entries. when a merge happens, status info 310 * replacing any pre-existing entries. when a merge happens, status info
319 * read using the status_read function is written back to the status file 311 * read using the status_read function is written back to the status file
320 */ 312 */
321static unsigned long status_parse(const char *line) 313static unsigned char status_parse(const char *line, const char **status_words)
322{ 314{
323 char *p; 315 unsigned char status_num;
324 int i, j; 316 int i = 0;
325 unsigned long l = 0;
326
327 for (i = 0; i < 3; i++) {
328 if ((p = strchr(line, ' ')) != NULL) {
329 *p = 0;
330 }
331 j = 1;
332 while (statuswords[i][j] != 0) {
333 if (strcmp(line, statuswords[i][j]) == 0) {
334 l |= (1 << ((int)statuswords[i][0] + j - 1));
335 break;
336 }
337 j++;
338 }
339 /* parse error */
340 if (statuswords[i][j] == 0) {
341 return 0;
342 }
343 line = p+1;
344 }
345
346 return l;
347}
348 317
349static const char *status_print(unsigned long flags) 318 while (status_words[i] != 0) {
350{ 319 if (strncmp(line, status_words[i], strlen(status_words[i])) == 0) {
351 /* this function returns a static buffer... */ 320 status_num = (char)i;
352 static char buf[256]; 321 return(status_num);
353 int i, j;
354
355 buf[0] = 0;
356 for (i = 0; i < 3; i++) {
357 j = 1;
358 while (statuswords[i][j] != 0) {
359 if ((flags & (1 << ((int)statuswords[i][0] + j - 1))) != 0) {
360 strcat(buf, statuswords[i][j]);
361 if (i < 2) strcat(buf, " ");
362 break;
363 }
364 j++;
365 }
366 if (statuswords[i][j] == 0) {
367 fprintf(stderr, "corrupted status flag!!\n");
368 return NULL;
369 } 322 }
323 i++;
370 } 324 }
371 325 /* parse error */
372 return buf; 326 error_msg("Invalid status word");
327 return(0);
373} 328}
374 329
375/* 330/*
@@ -385,24 +340,30 @@ static int control_read(FILE *file, package_t *p)
385 340
386 if (strlen(line) == 0) { 341 if (strlen(line) == 0) {
387 break; 342 break;
388 } else 343 }
389 if (strstr(line, "Package: ") == line) { 344 else if (strstr(line, "Package: ") == line) {
390 p->package = xstrdup(line + 9); 345 p->package = xstrdup(line + 9);
391 } else 346 }
392 if (strstr(line, "Status: ") == line) { 347 else if (strstr(line, "Status: ") == line) {
393 p->status = status_parse(line + 8); 348 char *word_pointer;
394 } else 349 word_pointer = strchr(line, ' ') + 1;
395 if (strstr(line, "Depends: ") == line) { 350 p->status_want = status_parse(word_pointer, status_words_want);
351 word_pointer = strchr(word_pointer, ' ') + 1;
352 p->status_flag = status_parse(word_pointer, status_words_flag);
353 word_pointer = strchr(word_pointer, ' ') + 1;
354 p->status_status = status_parse(word_pointer, status_words_status);
355 }
356 else if (strstr(line, "Depends: ") == line) {
396 p->depends = xstrdup(line + 9); 357 p->depends = xstrdup(line + 9);
397 } else 358 }
398 if (strstr(line, "Provides: ") == line) { 359 else if (strstr(line, "Provides: ") == line) {
399 p->provides = xstrdup(line + 10); 360 p->provides = xstrdup(line + 10);
400 } else 361 }
401 if (strstr(line, "Description: ") == line) { 362 else if (strstr(line, "Description: ") == line) {
402 p->description = xstrdup(line + 13); 363 p->description = xstrdup(line + 13);
403 /* This is specific to the Debian Installer. Ifdef? */ 364 /* This is specific to the Debian Installer. Ifdef? */
404 } else 365 }
405 if (strstr(line, "installer-menu-item: ") == line) { 366 else if (strstr(line, "installer-menu-item: ") == line) {
406 p->installer_menu_item = atoi(line + 21); 367 p->installer_menu_item = atoi(line + 21);
407 } 368 }
408 /* TODO: localized descriptions */ 369 /* TODO: localized descriptions */
@@ -417,15 +378,14 @@ static void *status_read(void)
417 void *status = 0; 378 void *status = 0;
418 package_t *m = 0, *p = 0, *t = 0; 379 package_t *m = 0, *p = 0, *t = 0;
419 380
420 if ((f = fopen(statusfile, "r")) == NULL) {
421 perror_msg(statusfile);
422 return 0;
423 }
424
425 if (getenv(udpkg_quiet) == NULL) { 381 if (getenv(udpkg_quiet) == NULL) {
426 printf("(Reading database...)\n"); 382 printf("(Reading database...)\n");
427 } 383 }
428 384
385 if ((f = fopen(statusfile, "r")) == NULL) {
386 return(NULL);
387 }
388
429 while (!feof(f)) { 389 while (!feof(f)) {
430 m = (package_t *)xcalloc(1, sizeof(package_t)); 390 m = (package_t *)xcalloc(1, sizeof(package_t));
431 control_read(f, m); 391 control_read(f, m);
@@ -445,22 +405,22 @@ static void *status_read(void)
445 */ 405 */
446 p = (package_t *)xcalloc(1, sizeof(package_t)); 406 p = (package_t *)xcalloc(1, sizeof(package_t));
447 p->package = xstrdup(m->provides); 407 p->package = xstrdup(m->provides);
448
449 t = *(package_t **)tsearch(p, &status, package_compare); 408 t = *(package_t **)tsearch(p, &status, package_compare);
450 if (t != p) { 409 if (t != p) {
451 free(p->package); 410 free(p->package);
452 free(p); 411 free(p);
453 } 412 } else {
454 else {
455 /* 413 /*
456 * Pseudo package status is the 414 * Pseudo package status is the
457 * same as the status of the 415 * same as the status of the
458 * package providing it 416 * package providing it
459 * FIXME: (not quite right, if 2 417 * FIXME: (not quite right, if 2
460 * packages of different statuses 418 * packages of different statuses
461 * provide it). 419 * provide it).
462 */ 420 */
463 t->status = m->status; 421 t->status_want = m->status_want;
422 t->status_flag = m->status_flag;
423 t->status_status = m->status_status;
464 } 424 }
465 } 425 }
466 } 426 }
@@ -485,6 +445,7 @@ static int status_merge(void *status, package_t *pkgs)
485 if (getenv(udpkg_quiet) == NULL) { 445 if (getenv(udpkg_quiet) == NULL) {
486 printf("(Updating database...)\n"); 446 printf("(Updating database...)\n");
487 } 447 }
448
488 /* 449 /*
489 * Dont use wfopen here, handle errors ourself 450 * Dont use wfopen here, handle errors ourself
490 */ 451 */
@@ -517,8 +478,10 @@ static int status_merge(void *status, package_t *pkgs)
517 continue; 478 continue;
518 } 479 }
519 if (strstr(line, "Status: ") == line && statpkg != 0) { 480 if (strstr(line, "Status: ") == line && statpkg != 0) {
520 snprintf(line, sizeof(line), "Status: %s", 481 snprintf(line, sizeof(line), "Status: %s %s %s",
521 status_print(statpkg->status)); 482 status_words_want[statpkg->status_want - 1],
483 status_words_flag[statpkg->status_flag - 1],
484 status_words_status[statpkg->status_status - 1]);
522 } 485 }
523 fputs(line, fout); 486 fputs(line, fout);
524 fputc('\n', fout); 487 fputc('\n', fout);
@@ -529,8 +492,11 @@ static int status_merge(void *status, package_t *pkgs)
529 492
530 // Print out packages we processed. 493 // Print out packages we processed.
531 for (pkg = pkgs; pkg != 0; pkg = pkg->next) { 494 for (pkg = pkgs; pkg != 0; pkg = pkg->next) {
532 fprintf(fout, "Package: %s\nStatus: %s\n", 495 fprintf(fout, "Package: %s\nStatus: %s %s %s\n",
533 pkg->package, status_print(pkg->status)); 496 pkg->package, status_words_want[pkg->status_want - 1],
497 status_words_flag[pkg->status_flag - 1],
498 status_words_status[pkg->status_status - 1]);
499
534 if (pkg->depends) 500 if (pkg->depends)
535 fprintf(fout, "Depends: %s\n", pkg->depends); 501 fprintf(fout, "Depends: %s\n", pkg->depends);
536 if (pkg->provides) 502 if (pkg->provides)
@@ -548,10 +514,11 @@ static int status_merge(void *status, package_t *pkgs)
548 */ 514 */
549 if (rename(statusfile, bak_statusfile) == -1) { 515 if (rename(statusfile, bak_statusfile) == -1) {
550 struct stat stat_buf; 516 struct stat stat_buf;
551 error_msg("Couldnt create backup status file");
552 if (stat(statusfile, &stat_buf) == 0) { 517 if (stat(statusfile, &stat_buf) == 0) {
518 error_msg("Couldnt create backup status file");
553 return(EXIT_FAILURE); 519 return(EXIT_FAILURE);
554 } 520 }
521 error_msg("No status file found, creating new one");
555 } 522 }
556 523
557 if (rename(new_statusfile, statusfile) == -1) { 524 if (rename(new_statusfile, statusfile) == -1) {
@@ -578,18 +545,18 @@ static int dpkg_doconfigure(package_t *pkg)
578 char buf[1024]; 545 char buf[1024];
579 546
580 DPRINTF("Configuring %s\n", pkg->package); 547 DPRINTF("Configuring %s\n", pkg->package);
581 pkg->status &= status_statusmask; 548 pkg->status_status = 0;
582 snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package); 549 snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package);
583 550
584 if (is_file(postinst)) { 551 if (is_file(postinst)) {
585 snprintf(buf, sizeof(buf), "%s configure", postinst); 552 snprintf(buf, sizeof(buf), "%s configure", postinst);
586 if ((r = do_system(buf)) != 0) { 553 if ((r = do_system(buf)) != 0) {
587 fprintf(stderr, "postinst exited with status %d\n", r); 554 fprintf(stderr, "postinst exited with status %d\n", r);
588 pkg->status |= status_statushalfconfigured; 555 pkg->status_status = status_status_halfconfigured;
589 return 1; 556 return 1;
590 } 557 }
591 } 558 }
592 pkg->status |= status_statusinstalled; 559 pkg->status_status = status_status_installed;
593 560
594 return 0; 561 return 0;
595} 562}
@@ -597,6 +564,7 @@ static int dpkg_doconfigure(package_t *pkg)
597static int dpkg_dounpack(package_t *pkg) 564static int dpkg_dounpack(package_t *pkg)
598{ 565{
599 int r = 0, i; 566 int r = 0, i;
567 int status = TRUE;
600 char *cwd; 568 char *cwd;
601 char *src_file = NULL; 569 char *src_file = NULL;
602 char *dst_file = NULL; 570 char *dst_file = NULL;
@@ -630,12 +598,14 @@ static int dpkg_dounpack(package_t *pkg)
630 if (lstat(src_file, &src_stat_buf) == 0) { 598 if (lstat(src_file, &src_stat_buf) == 0) {
631 if ((src_fd = open(src_file, O_RDONLY)) != -1) { 599 if ((src_fd = open(src_file, O_RDONLY)) != -1) {
632 if ((dst_fd = open(dst_file, O_WRONLY | O_CREAT, 0644)) == -1) { 600 if ((dst_fd = open(dst_file, O_WRONLY | O_CREAT, 0644)) == -1) {
601 status = FALSE;
633 perror_msg("Opening %s", dst_file); 602 perror_msg("Opening %s", dst_file);
634 } 603 }
635 copy_file_chunk(src_fd, dst_fd, src_stat_buf.st_size); 604 copy_file_chunk(src_fd, dst_fd, src_stat_buf.st_size);
636 close(src_fd); 605 close(src_fd);
637 close(dst_fd); 606 close(dst_fd);
638 } else { 607 } else {
608 status = FALSE;
639 error_msg("couldnt open [%s]\n", src_file); 609 error_msg("couldnt open [%s]\n", src_file);
640 } 610 }
641 } 611 }
@@ -652,17 +622,15 @@ static int dpkg_dounpack(package_t *pkg)
652 deb_extract(dpkg_deb_list, NULL, pkg->file); 622 deb_extract(dpkg_deb_list, NULL, pkg->file);
653*/ 623*/
654 624
655 pkg->status &= status_wantmask; 625 pkg->status_want = status_want_install;
656 pkg->status |= status_wantinstall; 626 pkg->status_flag = status_flag_ok;
657 pkg->status &= status_flagmask; 627
658 pkg->status |= status_flagok; 628 if (status == TRUE) {
659 pkg->status &= status_statusmask; 629 pkg->status_status = status_status_unpacked;
660
661 if (r == 0) {
662 pkg->status |= status_statusunpacked;
663 } else { 630 } else {
664 pkg->status |= status_statushalfinstalled; 631 pkg->status_status = status_status_halfinstalled;
665 } 632 }
633
666 chdir(cwd); 634 chdir(cwd);
667 return r; 635 return r;
668} 636}
@@ -781,19 +749,18 @@ static int dpkg_install(package_t *pkgs, void *status)
781 749
782 /* Stage 3: install */ 750 /* Stage 3: install */
783 for (p = ordered; p != 0; p = p->next) { 751 for (p = ordered; p != 0; p = p->next) {
784 p->status &= status_wantmask; 752 p->status_want = status_want_install;
785 p->status |= status_wantinstall;
786 753
787 /* for now the flag is always set to ok... this is probably 754 /* for now the flag is always set to ok... this is probably
788 * not what we want 755 * not what we want
789 */ 756 */
790 p->status &= status_flagmask; 757 p->status_flag = status_flag_ok;
791 p->status |= status_flagok;
792 758
793 DPRINTF("Installing %s\n", p->package); 759 DPRINTF("Installing %s\n", p->package);
794 if (dpkg_dounpack(p) != 0) { 760 if (dpkg_dounpack(p) != 0) {
795 perror_msg(p->file); 761 perror_msg(p->file);
796 } 762 }
763
797 if (dpkg_doconfigure(p) != 0) { 764 if (dpkg_doconfigure(p) != 0) {
798 perror_msg(p->file); 765 perror_msg(p->file);
799 } 766 }