diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2001-04-08 13:27:39 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2001-04-08 13:27:39 +0000 |
commit | 305fdfa755c94bdbe54fb9bd3db2f51086f9f2d3 (patch) | |
tree | 4aeb507ee3c04c609dd84049622138c5b284d2cc | |
parent | 37849f3320e3ca3d998ea249594d80f79e4083e2 (diff) | |
download | busybox-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.c | 229 | ||||
-rw-r--r-- | dpkg.c | 229 |
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/"; | |||
48 | static const char infodir[] = "/var/lib/dpkg/info/"; | 48 | static const char infodir[] = "/var/lib/dpkg/info/"; |
49 | static const char udpkg_quiet[] = "UDPKG_QUIET"; | 49 | static 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); | 52 | static const int status_want_install = 2; |
53 | static 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 | |
57 | static const int status_wantmask = 31; | 57 | static 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; |
60 | static 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); | 63 | static const int status_status_unpacked = 2; |
64 | static const int status_flagmask = 480; | 64 | static const int status_status_halfconfigured = 3; |
65 | 65 | static const int status_status_installed = 4; | |
66 | //static const int status_statusstart = 9; | 66 | static const int status_status_halfinstalled = 5; |
67 | //static const int status_statusnoninstalled = (1 << 9); /* 512 */ | 67 | //static const int status_statusconfigfiles = 6; |
68 | static const int status_statusunpacked = (1 << 10); | 68 | //static const int status_statuspostinstfailed = 7; |
69 | static const int status_statushalfconfigured = (1 << 11); | 69 | //static const int status_statusremovalfailed = 8; |
70 | static const int status_statusinstalled = (1 << 12); | 70 | |
71 | static const int status_statushalfinstalled = (1 << 13); | 71 | static const char *status_words_want[] = { "unknown", "install", "hold", "deinstall", "purge", 0 }; |
72 | //static const int status_statusconfigfiles = (1 << 14); | 72 | static const char *status_words_flag[] = { "ok", "reinstreq", "hold", "hold-reinstreq", 0 }; |
73 | //static const int status_statuspostinstfailed = (1 << 15); | 73 | static 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 }; |
75 | static const int status_statusmask = 130560; /* i assume status_statusinstalled is supposed to be included */ | ||
76 | |||
77 | static 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 | ||
85 | static const int color_white = 0; | 76 | static const int color_white = 0; |
86 | static const int color_grey = 1; | 77 | static 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 | */ |
321 | static unsigned long status_parse(const char *line) | 313 | static 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 | ||
349 | static 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) | |||
597 | static int dpkg_dounpack(package_t *pkg) | 564 | static 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 | } |
@@ -48,39 +48,30 @@ static const char dpkgcidir[] = "/var/lib/dpkg/tmp.ci/"; | |||
48 | static const char infodir[] = "/var/lib/dpkg/info/"; | 48 | static const char infodir[] = "/var/lib/dpkg/info/"; |
49 | static const char udpkg_quiet[] = "UDPKG_QUIET"; | 49 | static 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); | 52 | static const int status_want_install = 2; |
53 | static 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 | |
57 | static const int status_wantmask = 31; | 57 | static 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; |
60 | static 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); | 63 | static const int status_status_unpacked = 2; |
64 | static const int status_flagmask = 480; | 64 | static const int status_status_halfconfigured = 3; |
65 | 65 | static const int status_status_installed = 4; | |
66 | //static const int status_statusstart = 9; | 66 | static const int status_status_halfinstalled = 5; |
67 | //static const int status_statusnoninstalled = (1 << 9); /* 512 */ | 67 | //static const int status_statusconfigfiles = 6; |
68 | static const int status_statusunpacked = (1 << 10); | 68 | //static const int status_statuspostinstfailed = 7; |
69 | static const int status_statushalfconfigured = (1 << 11); | 69 | //static const int status_statusremovalfailed = 8; |
70 | static const int status_statusinstalled = (1 << 12); | 70 | |
71 | static const int status_statushalfinstalled = (1 << 13); | 71 | static const char *status_words_want[] = { "unknown", "install", "hold", "deinstall", "purge", 0 }; |
72 | //static const int status_statusconfigfiles = (1 << 14); | 72 | static const char *status_words_flag[] = { "ok", "reinstreq", "hold", "hold-reinstreq", 0 }; |
73 | //static const int status_statuspostinstfailed = (1 << 15); | 73 | static 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 }; |
75 | static const int status_statusmask = 130560; /* i assume status_statusinstalled is supposed to be included */ | ||
76 | |||
77 | static 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 | ||
85 | static const int color_white = 0; | 76 | static const int color_white = 0; |
86 | static const int color_grey = 1; | 77 | static 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 | */ |
321 | static unsigned long status_parse(const char *line) | 313 | static 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 | ||
349 | static 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) | |||
597 | static int dpkg_dounpack(package_t *pkg) | 564 | static 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 | } |