diff options
Diffstat (limited to 'dpkg.c')
-rw-r--r-- | dpkg.c | 371 |
1 files changed, 175 insertions, 196 deletions
@@ -20,7 +20,7 @@ | |||
20 | #define DODEPENDS 1 | 20 | #define DODEPENDS 1 |
21 | 21 | ||
22 | /* Should we do debugging? */ | 22 | /* Should we do debugging? */ |
23 | //#define DODEBUG 1 | 23 | #define DODEBUG 0 |
24 | 24 | ||
25 | #ifdef DODEBUG | 25 | #ifdef DODEBUG |
26 | #define SYSTEM(x) do_system(x) | 26 | #define SYSTEM(x) do_system(x) |
@@ -32,63 +32,68 @@ | |||
32 | 32 | ||
33 | /* from dpkg-deb.c */ | 33 | /* from dpkg-deb.c */ |
34 | 34 | ||
35 | static const int dpkg_deb_contents = 1; | ||
36 | static const int dpkg_deb_control = 2; | ||
37 | // const int dpkg_deb_info = 4; | ||
38 | static const int dpkg_deb_extract = 8; | ||
39 | static const int dpkg_deb_verbose_extract = 16; | ||
40 | static const int dpkg_deb_list = 32; | ||
41 | |||
42 | static const char statusfile[] = "/var/lib/dpkg/status.udeb"; | 35 | static const char statusfile[] = "/var/lib/dpkg/status.udeb"; |
43 | static const char new_statusfile[] = "/var/lib/dpkg/status.udeb.new"; | 36 | static const char new_statusfile[] = "/var/lib/dpkg/status.udeb.new"; |
44 | static const char bak_statusfile[] = "/var/lib/dpkg/status.udeb.bak"; | 37 | static const char bak_statusfile[] = "/var/lib/dpkg/status.udeb.bak"; |
45 | 38 | ||
46 | static const char dpkgcidir[] = "/var/lib/dpkg/tmp.ci/"; | ||
47 | |||
48 | static const char infodir[] = "/var/lib/dpkg/info/"; | 39 | static const char infodir[] = "/var/lib/dpkg/info/"; |
49 | static const char udpkg_quiet[] = "UDPKG_QUIET"; | 40 | static const char udpkg_quiet[] = "UDPKG_QUIET"; |
50 | 41 | ||
51 | //static const int status_want_unknown = 1; | 42 | //static const int status_want_unknown = 1; |
52 | static const int status_want_install = 2; | 43 | static const int state_want_install = 2; |
53 | //static const int status_want_hold = 3; | 44 | //static const int state_want_hold = 3; |
54 | //static const int status_want_deinstall = 4; | 45 | //static const int state_want_deinstall = 4; |
55 | //static const int status_want_purge = 5; | 46 | //static const int state_want_purge = 5; |
56 | 47 | ||
57 | static const int status_flag_ok = 1; | 48 | static const int state_flag_ok = 1; |
58 | //static const int status_flag_reinstreq = 2; | 49 | //static const int state_flag_reinstreq = 2; |
59 | //static const int status_flag_hold = 3; | 50 | //static const int state_flag_hold = 3; |
60 | //static const int status_flag_holdreinstreq = 4; | 51 | //static const int state_flag_holdreinstreq = 4; |
61 | 52 | ||
62 | //static const int status_statusnoninstalled = 1; | 53 | //static const int state_statusnoninstalled = 1; |
63 | static const int status_status_unpacked = 2; | 54 | static const int state_status_unpacked = 2; |
64 | static const int status_status_halfconfigured = 3; | 55 | static const int state_status_halfconfigured = 3; |
65 | static const int status_status_installed = 4; | 56 | static const int state_status_installed = 4; |
66 | static const int status_status_halfinstalled = 5; | 57 | static const int state_status_halfinstalled = 5; |
67 | //static const int status_statusconfigfiles = 6; | 58 | //static const int state_statusconfigfiles = 6; |
68 | //static const int status_statuspostinstfailed = 7; | 59 | //static const int state_statuspostinstfailed = 7; |
69 | //static const int status_statusremovalfailed = 8; | 60 | //static const int state_statusremovalfailed = 8; |
70 | 61 | ||
71 | static const char *status_words_want[] = { "unknown", "install", "hold", "deinstall", "purge", 0 }; | 62 | static const char *state_words_want[] = { "unknown", "install", "hold", "deinstall", "purge", 0 }; |
72 | static const char *status_words_flag[] = { "ok", "reinstreq", "hold", "hold-reinstreq", 0 }; | 63 | static const char *state_words_flag[] = { "ok", "reinstreq", "hold", "hold-reinstreq", 0 }; |
73 | static const char *status_words_status[] = { "not-installed", "unpacked", "half-configured", "installed", | 64 | static const char *state_words_status[] = { "not-installed", "unpacked", "half-configured", "installed", |
74 | "half-installed", "config-files", "post-inst-failed", "removal-failed", 0 }; | 65 | "half-installed", "config-files", "post-inst-failed", "removal-failed", 0 }; |
75 | 66 | ||
76 | static const int color_white = 0; | 67 | static const int color_white = 0; |
77 | static const int color_grey = 1; | 68 | static const int color_grey = 1; |
78 | static const int color_black = 2; | 69 | static const int color_black = 2; |
79 | 70 | ||
80 | /* data structures */ | 71 | /* data structures */ |
81 | typedef struct package_s { | 72 | typedef struct package_s { |
82 | char *file; | 73 | char *filename; |
83 | char *package; | 74 | char *package; |
84 | char *version; | 75 | unsigned char state_want; |
76 | unsigned char state_flag; | ||
77 | unsigned char state_status; | ||
85 | char *depends; | 78 | char *depends; |
86 | char *provides; | 79 | char *provides; |
87 | char *description; | 80 | char *description; |
81 | char *priority; | ||
82 | char *section; | ||
83 | char *installed_size; | ||
84 | char *maintainer; | ||
85 | char *source; | ||
86 | char *version; | ||
87 | char *pre_depends; | ||
88 | char *replaces; | ||
89 | char *recommends; | ||
90 | char *suggests; | ||
91 | char *conflicts; | ||
92 | char *conffiles; | ||
93 | char *long_description; | ||
94 | char *architecture; | ||
95 | char *md5sum; | ||
88 | int installer_menu_item; | 96 | int installer_menu_item; |
89 | unsigned char status_want; | ||
90 | unsigned char status_flag; | ||
91 | unsigned char status_status; | ||
92 | char color; /* for topo-sort */ | 97 | char color; /* for topo-sort */ |
93 | struct package_s *requiredfor[DEPENDSMAX]; | 98 | struct package_s *requiredfor[DEPENDSMAX]; |
94 | unsigned short requiredcount; | 99 | unsigned short requiredcount; |
@@ -265,8 +270,8 @@ static package_t *depends_resolve(package_t *pkgs, void *status) | |||
265 | /* Check for dependencies; first look for installed packages */ | 270 | /* Check for dependencies; first look for installed packages */ |
266 | dependpkg.package = dependsvec[i]; | 271 | dependpkg.package = dependsvec[i]; |
267 | if (((found = tfind(&dependpkg, &status, package_compare)) == 0) || | 272 | if (((found = tfind(&dependpkg, &status, package_compare)) == 0) || |
268 | ((chk = *(package_t **)found) && (chk->status_flag & status_flag_ok) && | 273 | ((chk = *(package_t **)found) && (chk->state_flag & state_flag_ok) && |
269 | (chk->status_status & status_status_installed))) { | 274 | (chk->state_status & state_status_installed))) { |
270 | 275 | ||
271 | /* if it fails, we look through the list of packages we are going to | 276 | /* if it fails, we look through the list of packages we are going to |
272 | * install */ | 277 | * install */ |
@@ -328,47 +333,100 @@ static unsigned char status_parse(const char *line, const char **status_words) | |||
328 | } | 333 | } |
329 | 334 | ||
330 | /* | 335 | /* |
331 | * Read a control file (or a stanza of a status file) and parse it, | 336 | * Read the buffered control file and parse it, |
332 | * filling parsed fields into the package structure | 337 | * filling parsed fields into the package structure |
333 | */ | 338 | */ |
334 | static int control_read(FILE *file, package_t *p) | 339 | static int fill_package_struct(package_t *package, const char *package_buffer) |
335 | { | 340 | { |
336 | char *line; | 341 | char *field = NULL; |
337 | 342 | int field_start = 0; | |
338 | while ((line = get_line_from_file(file)) != NULL) { | 343 | int field_length = 0; |
339 | line[strlen(line) - 1] = '\0'; | 344 | while ((field = read_package_field(&package_buffer[field_start])) != NULL) { |
340 | 345 | field_length = strlen(field); | |
341 | if (strlen(line) == 0) { | 346 | field_start += (field_length + 1); |
347 | |||
348 | if (strlen(field) == 0) { | ||
349 | printf("empty line: *this shouldnt happen i dont think*\n"); | ||
342 | break; | 350 | break; |
343 | } | 351 | } |
344 | else if (strstr(line, "Package: ") == line) { | 352 | |
345 | p->package = xstrdup(line + 9); | 353 | /* these are common to both installed and uninstalled packages */ |
346 | } | 354 | if (strstr(field, "Package: ") == field) { |
347 | else if (strstr(line, "Status: ") == line) { | 355 | package->package = strdup(field + 9); |
348 | char *word_pointer; | ||
349 | word_pointer = strchr(line, ' ') + 1; | ||
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 | } |
356 | else if (strstr(line, "Depends: ") == line) { | 357 | else if (strstr(field, "Depends: ") == field) { |
357 | p->depends = xstrdup(line + 9); | 358 | package->depends = strdup(field + 9); |
358 | } | 359 | } |
359 | else if (strstr(line, "Provides: ") == line) { | 360 | else if (strstr(field, "Provides: ") == field) { |
360 | p->provides = xstrdup(line + 10); | 361 | package->provides = strdup(field + 10); |
361 | } | 362 | } |
362 | else if (strstr(line, "Description: ") == line) { | ||
363 | p->description = xstrdup(line + 13); | ||
364 | /* This is specific to the Debian Installer. Ifdef? */ | 363 | /* This is specific to the Debian Installer. Ifdef? */ |
364 | else if (strstr(field, "installer-menu-item: ") == field) { | ||
365 | package->installer_menu_item = atoi(field + 21); | ||
366 | } | ||
367 | else if (strstr(field, "Description: ") == field) { | ||
368 | package->description = strdup(field + 13); | ||
369 | } | ||
370 | else if (strstr(field, "Priority: ") == field) { | ||
371 | package->priority = strdup(field + 10); | ||
372 | } | ||
373 | else if (strstr(field, "Section: ") == field) { | ||
374 | package->section = strdup(field + 9); | ||
375 | } | ||
376 | else if (strstr(field, "Installed-Size: ") == field) { | ||
377 | package->installed_size = strdup(field + 16); | ||
378 | } | ||
379 | else if (strstr(field, "Maintainer: ") == field) { | ||
380 | package->maintainer = strdup(field + 12); | ||
381 | } | ||
382 | else if (strstr(field, "Version: ") == field) { | ||
383 | package->version = strdup(field + 9); | ||
365 | } | 384 | } |
366 | else if (strstr(line, "installer-menu-item: ") == line) { | 385 | else if (strstr(field, "Suggests: ") == field) { |
367 | p->installer_menu_item = atoi(line + 21); | 386 | package->suggests = strdup(field + 10); |
368 | } | 387 | } |
369 | /* TODO: localized descriptions */ | 388 | else if (strstr(field, "Recommends: ") == field) { |
389 | package->recommends = strdup(field + 12); | ||
390 | } | ||
391 | /* else if (strstr(field, "Conffiles: ") == field) { | ||
392 | package->conffiles = read_block(file); | ||
393 | package->conffiles = xcalloc(1, 1); | ||
394 | while ((field = strtok(NULL, "\n")) != NULL) { | ||
395 | package->long_description = xrealloc(package->conffiles, | ||
396 | strlen(package->conffiles) + strlen(field) + 1); | ||
397 | strcat(package->conffiles, field); | ||
398 | } | ||
399 | } | ||
400 | */ | ||
401 | /* These are only in available file */ | ||
402 | else if (strstr(field, "Architecture: ") == field) { | ||
403 | package->architecture = strdup(field + 14); | ||
404 | } | ||
405 | else if (strstr(field, "Filename: ") == field) { | ||
406 | package->filename = strdup(field + 10); | ||
407 | } | ||
408 | else if (strstr(field, "MD5sum ") == field) { | ||
409 | package->md5sum = strdup(field + 7); | ||
410 | } | ||
411 | |||
412 | /* This is only needed for status file */ | ||
413 | if (strstr(field, "Status: ") == field) { | ||
414 | char *word_pointer; | ||
415 | |||
416 | word_pointer = strchr(field, ' ') + 1; | ||
417 | package->state_want = status_parse(word_pointer, state_words_want); | ||
418 | word_pointer = strchr(word_pointer, ' ') + 1; | ||
419 | package->state_flag = status_parse(word_pointer, state_words_flag); | ||
420 | word_pointer = strchr(word_pointer, ' ') + 1; | ||
421 | package->state_status = status_parse(word_pointer, state_words_status); | ||
422 | } else { | ||
423 | package->state_want = status_parse("purge", state_words_want); | ||
424 | package->state_flag = status_parse("ok", state_words_flag); | ||
425 | package->state_status = status_parse("not-installed", state_words_status); | ||
426 | } | ||
427 | |||
428 | free(field); | ||
370 | } | 429 | } |
371 | free(line); | ||
372 | return EXIT_SUCCESS; | 430 | return EXIT_SUCCESS; |
373 | } | 431 | } |
374 | 432 | ||
@@ -377,6 +435,7 @@ static void *status_read(void) | |||
377 | FILE *f; | 435 | FILE *f; |
378 | void *status = 0; | 436 | void *status = 0; |
379 | package_t *m = 0, *p = 0, *t = 0; | 437 | package_t *m = 0, *p = 0, *t = 0; |
438 | char *package_control_buffer = NULL; | ||
380 | 439 | ||
381 | if (getenv(udpkg_quiet) == NULL) { | 440 | if (getenv(udpkg_quiet) == NULL) { |
382 | printf("(Reading database...)\n"); | 441 | printf("(Reading database...)\n"); |
@@ -386,9 +445,11 @@ static void *status_read(void) | |||
386 | return(NULL); | 445 | return(NULL); |
387 | } | 446 | } |
388 | 447 | ||
389 | while (!feof(f)) { | 448 | while ( (package_control_buffer = read_text_file_to_buffer(f)) != NULL) { |
390 | m = (package_t *)xcalloc(1, sizeof(package_t)); | 449 | m = (package_t *)xcalloc(1, sizeof(package_t)); |
391 | control_read(f, m); | 450 | printf("read buffer [%s]\n", package_control_buffer); |
451 | fill_package_struct(m, package_control_buffer); | ||
452 | printf("package is [%s]\n", m->package); | ||
392 | if (m->package) { | 453 | if (m->package) { |
393 | /* | 454 | /* |
394 | * If there is an item in the tree by this name, | 455 | * If there is an item in the tree by this name, |
@@ -418,9 +479,9 @@ static void *status_read(void) | |||
418 | * packages of different statuses | 479 | * packages of different statuses |
419 | * provide it). | 480 | * provide it). |
420 | */ | 481 | */ |
421 | t->status_want = m->status_want; | 482 | t->state_want = m->state_want; |
422 | t->status_flag = m->status_flag; | 483 | t->state_flag = m->state_flag; |
423 | t->status_status = m->status_status; | 484 | t->state_status = m->state_status; |
424 | } | 485 | } |
425 | } | 486 | } |
426 | } | 487 | } |
@@ -428,6 +489,7 @@ static void *status_read(void) | |||
428 | free(m); | 489 | free(m); |
429 | } | 490 | } |
430 | } | 491 | } |
492 | printf("done\n"); | ||
431 | fclose(f); | 493 | fclose(f); |
432 | return status; | 494 | return status; |
433 | } | 495 | } |
@@ -479,9 +541,9 @@ static int status_merge(void *status, package_t *pkgs) | |||
479 | } | 541 | } |
480 | if (strstr(line, "Status: ") == line && statpkg != 0) { | 542 | if (strstr(line, "Status: ") == line && statpkg != 0) { |
481 | snprintf(line, sizeof(line), "Status: %s %s %s", | 543 | snprintf(line, sizeof(line), "Status: %s %s %s", |
482 | status_words_want[statpkg->status_want - 1], | 544 | state_words_want[statpkg->state_want - 1], |
483 | status_words_flag[statpkg->status_flag - 1], | 545 | state_words_flag[statpkg->state_flag - 1], |
484 | status_words_status[statpkg->status_status - 1]); | 546 | state_words_status[statpkg->state_status - 1]); |
485 | } | 547 | } |
486 | fprintf(fout, "%s\n", line); | 548 | fprintf(fout, "%s\n", line); |
487 | } | 549 | } |
@@ -492,9 +554,9 @@ static int status_merge(void *status, package_t *pkgs) | |||
492 | // Print out packages we processed. | 554 | // Print out packages we processed. |
493 | for (pkg = pkgs; pkg != 0; pkg = pkg->next) { | 555 | for (pkg = pkgs; pkg != 0; pkg = pkg->next) { |
494 | fprintf(fout, "Package: %s\nStatus: %s %s %s\n", | 556 | fprintf(fout, "Package: %s\nStatus: %s %s %s\n", |
495 | pkg->package, status_words_want[pkg->status_want - 1], | 557 | pkg->package, state_words_want[pkg->state_want - 1], |
496 | status_words_flag[pkg->status_flag - 1], | 558 | state_words_flag[pkg->state_flag - 1], |
497 | status_words_status[pkg->status_status - 1]); | 559 | state_words_status[pkg->state_status - 1]); |
498 | 560 | ||
499 | if (pkg->depends) | 561 | if (pkg->depends) |
500 | fprintf(fout, "Depends: %s\n", pkg->depends); | 562 | fprintf(fout, "Depends: %s\n", pkg->depends); |
@@ -544,144 +606,68 @@ static int dpkg_doconfigure(package_t *pkg) | |||
544 | char buf[1024]; | 606 | char buf[1024]; |
545 | 607 | ||
546 | DPRINTF("Configuring %s\n", pkg->package); | 608 | DPRINTF("Configuring %s\n", pkg->package); |
547 | pkg->status_status = 0; | 609 | pkg->state_status = 0; |
548 | snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package); | 610 | snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package); |
549 | 611 | ||
550 | if (is_file(postinst)) { | 612 | if (is_file(postinst)) { |
551 | snprintf(buf, sizeof(buf), "%s configure", postinst); | 613 | snprintf(buf, sizeof(buf), "%s configure", postinst); |
552 | if ((r = do_system(buf)) != 0) { | 614 | if ((r = do_system(buf)) != 0) { |
553 | error_msg("postinst exited with status %d\n", r); | 615 | error_msg("postinst exited with status %d\n", r); |
554 | pkg->status_status = status_status_halfconfigured; | 616 | pkg->state_status = state_status_halfconfigured; |
555 | return 1; | 617 | return 1; |
556 | } | 618 | } |
557 | } | 619 | } |
558 | pkg->status_status = status_status_installed; | 620 | pkg->state_status = state_status_installed; |
559 | 621 | ||
560 | return 0; | 622 | return 0; |
561 | } | 623 | } |
562 | 624 | ||
563 | static int dpkg_dounpack(package_t *pkg) | 625 | static int dpkg_dounpack(package_t *pkg) |
564 | { | 626 | { |
565 | int r = 0, i; | 627 | int r = 0; |
566 | int status = TRUE; | 628 | int status = TRUE; |
567 | char *cwd = xgetcwd(0); | 629 | char *lst_path; |
568 | char *src_filename = NULL; | ||
569 | char *dst_filename = NULL; | ||
570 | // char *lst_file = NULL; | ||
571 | char *adminscripts[] = { "prerm", "postrm", "preinst", "postinst", | ||
572 | "conffiles", "md5sums", "shlibs", "templates" }; | ||
573 | 630 | ||
574 | DPRINTF("Unpacking %s\n", pkg->package); | 631 | DPRINTF("Unpacking %s\n", pkg->package); |
575 | 632 | ||
576 | if(cwd==NULL) | 633 | /* extract the data file */ |
577 | exit(EXIT_FAILURE); | 634 | deb_extract(pkg->filename, extract_extract, "/", NULL); |
578 | chdir("/"); | ||
579 | deb_extract(pkg->file, dpkg_deb_extract, "/"); | ||
580 | 635 | ||
581 | /* Installs the package scripts into the info directory */ | 636 | /* extract the control files */ |
582 | for (i = 0; i < sizeof(adminscripts) / sizeof(adminscripts[0]); i++) { | 637 | deb_extract(pkg->filename, extract_control, infodir, pkg->package); |
583 | struct stat src_stat_buf; | ||
584 | FILE *src_file = NULL, *dst_file = NULL; | ||
585 | 638 | ||
586 | /* The full path of the current location of the admin file */ | 639 | /* Create the list file */ |
587 | src_filename = xrealloc(src_filename, strlen(dpkgcidir) + strlen(pkg->package) + strlen(adminscripts[i]) + 1); | 640 | lst_path = xmalloc(strlen(infodir) + strlen(pkg->package) + 6); |
588 | sprintf(src_filename, "%s%s/%s", dpkgcidir, pkg->package, adminscripts[i]); | 641 | strcpy(lst_path, infodir); |
642 | strcat(lst_path, pkg->package); | ||
643 | strcat(lst_path, ".list"); | ||
644 | deb_extract(pkg->filename, extract_contents_to_file, lst_path, NULL); | ||
589 | 645 | ||
590 | /* the full path of where we want the file to be copied to */ | 646 | pkg->state_want = state_want_install; |
591 | dst_filename = xrealloc(dst_filename, strlen(infodir) + strlen(pkg->package) + strlen(adminscripts[i]) + 1); | 647 | pkg->state_flag = state_flag_ok; |
592 | sprintf(dst_filename, "%s%s.%s", infodir, pkg->package, adminscripts[i]); | ||
593 | |||
594 | /* | ||
595 | * copy admin file to permanent home | ||
596 | * NOTE: Maybe merge this behaviour into libb/copy_file.c | ||
597 | */ | ||
598 | if (lstat(src_filename, &src_stat_buf) == 0) { | ||
599 | if ((src_file = wfopen(src_filename, "r")) != NULL) { | ||
600 | if ((dst_file = wfopen(dst_filename, "w")) == NULL) { | ||
601 | status = FALSE; | ||
602 | perror_msg("Opening %s", dst_filename); | ||
603 | } | ||
604 | copy_file_chunk(src_file, dst_file, src_stat_buf.st_size); | ||
605 | fclose(src_file); | ||
606 | fclose(dst_file); | ||
607 | } else { | ||
608 | status = FALSE; | ||
609 | error_msg("couldnt open [%s]\n", src_filename); | ||
610 | } | ||
611 | } | ||
612 | } | ||
613 | |||
614 | /* | ||
615 | * create the list file | ||
616 | * FIXME: currently this dumps the lst to stdout instead of a file | ||
617 | */ | ||
618 | /* lst_file = (char *) xmalloc(strlen(infodir) + strlen(pkg->package) + 6); | ||
619 | strcpy(lst_file, infodir); | ||
620 | strcat(lst_file, pkg->package); | ||
621 | strcat(lst_file, ".list"); | ||
622 | deb_extract(dpkg_deb_list, NULL, pkg->file); | ||
623 | */ | ||
624 | |||
625 | pkg->status_want = status_want_install; | ||
626 | pkg->status_flag = status_flag_ok; | ||
627 | 648 | ||
628 | if (status == TRUE) { | 649 | if (status == TRUE) { |
629 | pkg->status_status = status_status_unpacked; | 650 | pkg->state_status = state_status_unpacked; |
630 | } else { | 651 | } else { |
631 | pkg->status_status = status_status_halfinstalled; | 652 | pkg->state_status = state_status_halfinstalled; |
632 | } | 653 | } |
633 | 654 | ||
634 | chdir(cwd); | ||
635 | return r; | 655 | return r; |
636 | } | 656 | } |
637 | 657 | ||
638 | /* | 658 | /* |
639 | * Extract and parse the control.tar.gz from the specified package | 659 | * Extract and parse the control file from control.tar.gz |
640 | */ | 660 | */ |
641 | static int dpkg_unpackcontrol(package_t *pkg) | 661 | static int dpkg_read_control(package_t *pkg) |
642 | { | 662 | { |
643 | char *tmp_name; | 663 | FILE *pkg_file; |
644 | FILE *file; | 664 | char *control_buffer = NULL; |
645 | int length; | ||
646 | 665 | ||
647 | /* clean the temp directory (dpkgcidir) be recreating it */ | 666 | if ((pkg_file = wfopen(pkg->filename, "r")) == NULL) { |
648 | remove_dir(dpkgcidir); | ||
649 | if (create_path(dpkgcidir, S_IRWXU) == FALSE) { | ||
650 | return EXIT_FAILURE; | 667 | return EXIT_FAILURE; |
651 | } | 668 | } |
652 | 669 | control_buffer = deb_extract(pkg->filename, extract_field, NULL, NULL); | |
653 | /* | 670 | fill_package_struct(pkg, control_buffer); |
654 | * Get the package name from the file name, | ||
655 | * first remove the directories | ||
656 | */ | ||
657 | if ((tmp_name = strrchr(pkg->file, '/')) == NULL) { | ||
658 | tmp_name = pkg->file; | ||
659 | } else { | ||
660 | tmp_name++; | ||
661 | } | ||
662 | /* now remove trailing version numbers etc */ | ||
663 | length = strcspn(tmp_name, "_."); | ||
664 | pkg->package = (char *) xcalloc(1, length + 1); | ||
665 | /* store the package name */ | ||
666 | strncpy(pkg->package, tmp_name, length); | ||
667 | |||
668 | /* work out the full extraction path */ | ||
669 | tmp_name = (char *) xcalloc(1, strlen(dpkgcidir) + strlen(pkg->package) + 9); | ||
670 | strcpy(tmp_name, dpkgcidir); | ||
671 | strcat(tmp_name, pkg->package); | ||
672 | |||
673 | /* extract control.tar.gz to the full extraction path */ | ||
674 | deb_extract(pkg->file, dpkg_deb_control, tmp_name); | ||
675 | |||
676 | /* parse the extracted control file */ | ||
677 | strcat(tmp_name, "/control"); | ||
678 | if ((file = wfopen(tmp_name, "r")) == NULL) { | ||
679 | return EXIT_FAILURE; | ||
680 | } | ||
681 | if (control_read(file, pkg) == EXIT_FAILURE) { | ||
682 | return EXIT_FAILURE; | ||
683 | } | ||
684 | |||
685 | return EXIT_SUCCESS; | 671 | return EXIT_SUCCESS; |
686 | } | 672 | } |
687 | 673 | ||
@@ -691,15 +677,12 @@ static int dpkg_unpack(package_t *pkgs, void *status) | |||
691 | package_t *pkg; | 677 | package_t *pkg; |
692 | 678 | ||
693 | for (pkg = pkgs; pkg != 0; pkg = pkg->next) { | 679 | for (pkg = pkgs; pkg != 0; pkg = pkg->next) { |
694 | if (dpkg_unpackcontrol(pkg) == EXIT_FAILURE) { | 680 | dpkg_read_control(pkg); |
695 | return EXIT_FAILURE; | ||
696 | } | ||
697 | if ((r = dpkg_dounpack(pkg)) != 0 ) { | 681 | if ((r = dpkg_dounpack(pkg)) != 0 ) { |
698 | break; | 682 | break; |
699 | } | 683 | } |
700 | } | 684 | } |
701 | status_merge(status, pkgs); | 685 | status_merge(status, pkgs); |
702 | remove_dir(dpkgcidir); | ||
703 | 686 | ||
704 | return r; | 687 | return r; |
705 | } | 688 | } |
@@ -735,9 +718,7 @@ static int dpkg_install(package_t *pkgs, void *status) | |||
735 | 718 | ||
736 | /* Stage 1: parse all the control information */ | 719 | /* Stage 1: parse all the control information */ |
737 | for (p = pkgs; p != 0; p = p->next) { | 720 | for (p = pkgs; p != 0; p = p->next) { |
738 | if (dpkg_unpackcontrol(p) == EXIT_FAILURE) { | 721 | dpkg_read_control(p); |
739 | return(EXIT_FAILURE); | ||
740 | } | ||
741 | } | 722 | } |
742 | 723 | ||
743 | /* Stage 2: resolve dependencies */ | 724 | /* Stage 2: resolve dependencies */ |
@@ -749,27 +730,26 @@ static int dpkg_install(package_t *pkgs, void *status) | |||
749 | 730 | ||
750 | /* Stage 3: install */ | 731 | /* Stage 3: install */ |
751 | for (p = ordered; p != 0; p = p->next) { | 732 | for (p = ordered; p != 0; p = p->next) { |
752 | p->status_want = status_want_install; | 733 | p->state_want = state_want_install; |
753 | 734 | ||
754 | /* for now the flag is always set to ok... this is probably | 735 | /* for now the flag is always set to ok... this is probably |
755 | * not what we want | 736 | * not what we want |
756 | */ | 737 | */ |
757 | p->status_flag = status_flag_ok; | 738 | p->state_flag = state_flag_ok; |
758 | 739 | ||
759 | DPRINTF("Installing %s\n", p->package); | 740 | DPRINTF("Installing %s\n", p->package); |
760 | if (dpkg_dounpack(p) != 0) { | 741 | if (dpkg_dounpack(p) != 0) { |
761 | perror_msg(p->file); | 742 | perror_msg(p->filename); |
762 | } | 743 | } |
763 | 744 | ||
764 | if (dpkg_doconfigure(p) != 0) { | 745 | if (dpkg_doconfigure(p) != 0) { |
765 | perror_msg(p->file); | 746 | perror_msg(p->filename); |
766 | } | 747 | } |
767 | } | 748 | } |
768 | 749 | ||
769 | if (ordered != 0) { | 750 | if (ordered != 0) { |
770 | status_merge(status, pkgs); | 751 | status_merge(status, pkgs); |
771 | } | 752 | } |
772 | remove_dir(dpkgcidir); | ||
773 | 753 | ||
774 | return 0; | 754 | return 0; |
775 | } | 755 | } |
@@ -822,7 +802,7 @@ extern int dpkg_main(int argc, char **argv) | |||
822 | if (optflag & arg_configure) { | 802 | if (optflag & arg_configure) { |
823 | p->package = xstrdup(argv[optind]); | 803 | p->package = xstrdup(argv[optind]); |
824 | } else { | 804 | } else { |
825 | p->file = xstrdup(argv[optind]); | 805 | p->filename = xstrdup(argv[optind]); |
826 | } | 806 | } |
827 | p->next = packages; | 807 | p->next = packages; |
828 | packages = p; | 808 | packages = p; |
@@ -830,7 +810,6 @@ extern int dpkg_main(int argc, char **argv) | |||
830 | optind++; | 810 | optind++; |
831 | } | 811 | } |
832 | 812 | ||
833 | create_path(dpkgcidir, S_IRWXU); | ||
834 | create_path(infodir, S_IRWXU); | 813 | create_path(infodir, S_IRWXU); |
835 | 814 | ||
836 | status = status_read(); | 815 | status = status_read(); |