aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277>2001-02-11 01:40:23 +0000
committerbug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277>2001-02-11 01:40:23 +0000
commita1be2a16353409fc9a8c4d7b6eb413d68e2e2f8c (patch)
tree5a8904022795d758ac94619cf385d46452526cf2
parentd1765981299d968f187d53555469d11ac2614f43 (diff)
downloadbusybox-w32-a1be2a16353409fc9a8c4d7b6eb413d68e2e2f8c.tar.gz
busybox-w32-a1be2a16353409fc9a8c4d7b6eb413d68e2e2f8c.tar.bz2
busybox-w32-a1be2a16353409fc9a8c4d7b6eb413d68e2e2f8c.zip
More style changes
git-svn-id: svn://busybox.net/trunk/busybox@1790 69ca8d6d-28ef-0310-b511-8ec308f3f277
-rw-r--r--archival/dpkg.c325
-rw-r--r--dpkg.c325
2 files changed, 350 insertions, 300 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c
index ef120a115..7b4c74d7d 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -35,9 +35,13 @@
35#define BUFSIZE 4096 35#define BUFSIZE 4096
36#define DEPENDSMAX 64 /* maximum number of depends we can handle */ 36#define DEPENDSMAX 64 /* maximum number of depends we can handle */
37 37
38#define ADMINDIR "/var/lib/dpkg" 38static const char statusfile[] = "/var/lib/dpkg/status.udeb";
39#define STATUSFILE ADMINDIR ## "/status.udeb" 39static const char new_statusfile[] = "/var/lib/dpkg/status.udeb.new";
40#define DPKGCIDIR ADMINDIR ## "/tmp.ci/" 40static const char bak_statusfile[] = "/var/lib/dpkg/status.udeb.bak";
41
42static const char dpkgcidir[] = "/var/lib/dpkg/tmp.ci/";
43static const char rm_dpkgcidir[] = "rm -rf /var/lib/dpkg/tmp.ci/";
44
41static const char infodir[] = "/var/lib/dpkg/info/"; 45static const char infodir[] = "/var/lib/dpkg/info/";
42static const char udpkg_quiet[] = "UDPKG_QUIET"; 46static const char udpkg_quiet[] = "UDPKG_QUIET";
43 47
@@ -95,6 +99,16 @@ typedef struct package_s {
95 struct package_s *next; 99 struct package_s *next;
96} package_t; 100} package_t;
97 101
102#ifdef DODEBUG
103static int do_system(const char *cmd)
104{
105 DPRINTF("cmd is %s\n", cmd);
106 return system(cmd);
107}
108#else
109#define do_system(cmd) system(cmd)
110#endif
111
98static int package_compare(const void *p1, const void *p2) 112static int package_compare(const void *p1, const void *p2)
99{ 113{
100 return strcmp(((package_t *)p1)->package, 114 return strcmp(((package_t *)p1)->package,
@@ -111,41 +125,46 @@ static char **depends_split(const char *dependsstr)
111 int i = 0; 125 int i = 0;
112 126
113 dependsvec[0] = 0; 127 dependsvec[0] = 0;
128 if (dependsstr == 0) {
129 goto end;
130 }
114 131
115 if (dependsstr != 0) { 132 p = strdup(dependsstr);
116 p = strdup(dependsstr); 133 while (*p != 0 && *p != '\n') {
117 while (*p != 0 && *p != '\n') { 134 if (*p != ' ') {
118 if (*p != ' ') { 135 if (*p == ',') {
119 if (*p == ',') { 136 *p = 0;
120 *p = 0; 137 dependsvec[++i] = 0;
121 dependsvec[++i] = 0;
122 } else
123 if (dependsvec[i] == 0)
124 dependsvec[i] = p;
125 } else { 138 } else {
126 *p = 0; /* eat the space... */ 139 if (dependsvec[i] == 0) {
140 dependsvec[i] = p;
141 }
127 } 142 }
128 p++; 143 } else {
144 *p = 0; /* eat the space... */
129 } 145 }
130 *p = 0; 146 p++;
131 } 147 }
148 *p = 0;
149
150end:
132 dependsvec[i+1] = 0; 151 dependsvec[i+1] = 0;
133 return dependsvec; 152 return dependsvec;
134} 153}
135 154
155/* Topological sort algorithm:
156 * ordered is the output list, pkgs is the dependency graph, pkg is
157 * the current node
158 *
159 * recursively add all the adjacent nodes to the ordered list, marking
160 * each one as visited along the way
161 *
162 * yes, this algorithm looks a bit odd when all the params have the
163 * same type :-)
164 */
136static void depends_sort_visit(package_t **ordered, package_t *pkgs, 165static void depends_sort_visit(package_t **ordered, package_t *pkgs,
137 package_t *pkg) 166 package_t *pkg)
138{ 167{
139 /* Topological sort algorithm:
140 * ordered is the output list, pkgs is the dependency graph, pkg is
141 * the current node
142 *
143 * recursively add all the adjacent nodes to the ordered list, marking
144 * each one as visited along the way
145 *
146 * yes, this algorithm looks a bit odd when all the params have the
147 * same type :-)
148 */
149 unsigned short i; 168 unsigned short i;
150 169
151 /* mark node as processing */ 170 /* mark node as processing */
@@ -164,6 +183,7 @@ static void depends_sort_visit(package_t **ordered, package_t *pkgs,
164 newnode->next = *ordered; 183 newnode->next = *ordered;
165 *ordered = newnode; 184 *ordered = newnode;
166#endif 185#endif
186
167 pkg->next = *ordered; 187 pkg->next = *ordered;
168 *ordered = pkg; 188 *ordered = pkg;
169 189
@@ -178,12 +198,14 @@ static package_t *depends_sort(package_t *pkgs)
178 package_t *ordered = NULL; 198 package_t *ordered = NULL;
179 package_t *pkg; 199 package_t *pkg;
180 200
181 for (pkg = pkgs; pkg != 0; pkg = pkg->next) 201 for (pkg = pkgs; pkg != 0; pkg = pkg->next) {
182 pkg->color = color_white; 202 pkg->color = color_white;
183 203 }
184 for (pkg = pkgs; pkg != 0; pkg = pkg->next) 204 for (pkg = pkgs; pkg != 0; pkg = pkg->next) {
185 if (pkg->color == color_white) 205 if (pkg->color == color_white) {
186 depends_sort_visit(&ordered, pkgs, pkg); 206 depends_sort_visit(&ordered, pkgs, pkg);
207 }
208 }
187 209
188 /* Leaks the old list... return the new one... */ 210 /* Leaks the old list... return the new one... */
189 return ordered; 211 return ordered;
@@ -218,17 +240,15 @@ static package_t *depends_resolve(package_t *pkgs, void *status)
218 if ((found = tfind(&dependpkg, &status, package_compare)) == 0 || 240 if ((found = tfind(&dependpkg, &status, package_compare)) == 0 ||
219 ((chk = *(package_t **)found) && 241 ((chk = *(package_t **)found) &&
220 (chk->status & (status_flagok | status_statusinstalled)) != 242 (chk->status & (status_flagok | status_statusinstalled)) !=
221 (status_flagok | status_statusinstalled))) 243 (status_flagok | status_statusinstalled))) {
222 { 244
223 /* if it fails, we look through the list of packages we are going to 245 /* if it fails, we look through the list of packages we are going to
224 * install */ 246 * install */
225 for (chk = pkgs; chk != 0; chk = chk->next) { 247 for (chk = pkgs; chk != 0; chk = chk->next) {
226 if (strcmp(chk->package, dependsvec[i]) == 0 || 248 if (strcmp(chk->package, dependsvec[i]) == 0 || (chk->provides &&
227 (chk->provides &&
228 strncmp(chk->provides, dependsvec[i], strlen(dependsvec[i])) == 0)) { 249 strncmp(chk->provides, dependsvec[i], strlen(dependsvec[i])) == 0)) {
229 if (chk->requiredcount >= DEPENDSMAX) { 250 if (chk->requiredcount >= DEPENDSMAX) {
230 fprintf(stderr, "Too many dependencies for %s\n", 251 fprintf(stderr, "Too many dependencies for %s\n", chk->package);
231 chk->package);
232 return 0; 252 return 0;
233 } 253 }
234 if (chk != pkg) { 254 if (chk != pkg) {
@@ -264,16 +284,16 @@ static package_t *depends_resolve(package_t *pkgs, void *status)
264 * replacing any pre-existing entries. when a merge happens, status info 284 * replacing any pre-existing entries. when a merge happens, status info
265 * read using the status_read function is written back to the status file 285 * read using the status_read function is written back to the status file
266 */ 286 */
267
268static unsigned long status_parse(const char *line) 287static unsigned long status_parse(const char *line)
269{ 288{
270 char *p; 289 char *p;
271 int i, j; 290 int i, j;
272 unsigned long l = 0; 291 unsigned long l = 0;
273 for (i = 0; i < 3; i++) 292
274 { 293 for (i = 0; i < 3; i++) {
275 p = strchr(line, ' '); 294 if ((p = strchr(line, ' ')) != NULL) {
276 if (p) *p = 0; 295 *p = 0;
296 }
277 j = 1; 297 j = 1;
278 while (statuswords[i][j] != 0) { 298 while (statuswords[i][j] != 0) {
279 if (strcmp(line, statuswords[i][j]) == 0) { 299 if (strcmp(line, statuswords[i][j]) == 0) {
@@ -288,6 +308,7 @@ static unsigned long status_parse(const char *line)
288 } 308 }
289 line = p+1; 309 line = p+1;
290 } 310 }
311
291 return l; 312 return l;
292} 313}
293 314
@@ -313,6 +334,7 @@ static const char *status_print(unsigned long flags)
313 return NULL; 334 return NULL;
314 } 335 }
315 } 336 }
337
316 return buf; 338 return buf;
317} 339}
318 340
@@ -326,6 +348,7 @@ static void control_read(FILE *file, package_t *p)
326 348
327 while ((line = get_line_from_file(file)) != NULL) { 349 while ((line = get_line_from_file(file)) != NULL) {
328 line[strlen(line)] = 0; 350 line[strlen(line)] = 0;
351
329 if (strlen(line) == 0) { 352 if (strlen(line) == 0) {
330 break; 353 break;
331 } else 354 } else
@@ -359,13 +382,15 @@ static void *status_read(void)
359 void *status = 0; 382 void *status = 0;
360 package_t *m = 0, *p = 0, *t = 0; 383 package_t *m = 0, *p = 0, *t = 0;
361 384
362 if ((f = fopen(STATUSFILE, "r")) == NULL) { 385 if ((f = fopen(statusfile, "r")) == NULL) {
363 perror(STATUSFILE); 386 perror(statusfile);
364 return 0; 387 return 0;
365 } 388 }
389
366 if (getenv(udpkg_quiet) == NULL) { 390 if (getenv(udpkg_quiet) == NULL) {
367 printf("(Reading database...)\n"); 391 printf("(Reading database...)\n");
368 } 392 }
393
369 while (!feof(f)) { 394 while (!feof(f)) {
370 m = (package_t *)xmalloc(sizeof(package_t)); 395 m = (package_t *)xmalloc(sizeof(package_t));
371 memset(m, 0, sizeof(package_t)); 396 memset(m, 0, sizeof(package_t));
@@ -389,7 +414,7 @@ static void *status_read(void)
389 p->package = strdup(m->provides); 414 p->package = strdup(m->provides);
390 415
391 t = *(package_t **)tsearch(p, &status, package_compare); 416 t = *(package_t **)tsearch(p, &status, package_compare);
392 if (!(t == p)) { 417 if (t != p) {
393 free(p->package); 418 free(p->package);
394 free(p); 419 free(p);
395 } 420 }
@@ -422,18 +447,19 @@ static int status_merge(void *status, package_t *pkgs)
422 package_t locpkg; 447 package_t locpkg;
423 int r = 0; 448 int r = 0;
424 449
425 if ((fin = fopen(STATUSFILE, "r")) == NULL) { 450 if ((fin = fopen(statusfile, "r")) == NULL) {
426 perror(STATUSFILE); 451 perror(statusfile);
427 return 0; 452 return 0;
428 } 453 }
429 if ((fout = fopen(STATUSFILE ".new", "w")) == NULL) { 454 if ((fout = fopen(new_statusfile, "w")) == NULL) {
430 perror(STATUSFILE ".new"); 455 perror(new_statusfile);
431 return 0; 456 return 0;
432 } 457 }
433 if (getenv(udpkg_quiet) == NULL) { 458 if (getenv(udpkg_quiet) == NULL) {
434 printf("(Updating database...)\n"); 459 printf("(Updating database...)\n");
435 } 460 }
436 while (((line = get_line_from_file(fin)) != NULL) && (feof(fin) != 0)) { 461
462 while (((line = get_line_from_file(fin)) != NULL) && !feof(fin)) {
437 line[strlen(line)] = 0; /* trim newline */ 463 line[strlen(line)] = 0; /* trim newline */
438 /* If we see a package header, find out if it's a package 464 /* If we see a package header, find out if it's a package
439 * that we have processed. if so, we skip that block for 465 * that we have processed. if so, we skip that block for
@@ -488,26 +514,13 @@ static int status_merge(void *status, package_t *pkgs)
488 fclose(fin); 514 fclose(fin);
489 fclose(fout); 515 fclose(fout);
490 516
491 r = rename(STATUSFILE, STATUSFILE ".bak"); 517 r = rename(statusfile, bak_statusfile);
492 if (r == 0) { 518 if (r == 0) {
493 r = rename(STATUSFILE ".new", STATUSFILE); 519 r = rename(new_statusfile, statusfile);
494 } 520 }
495 return 0;
496}
497
498/*
499 * Main udpkg implementation routines
500 */
501 521
502#ifdef DODEBUG 522 return 0;
503static int do_system(const char *cmd)
504{
505 DPRINTF("cmd is %s\n", cmd);
506 return system(cmd);
507} 523}
508#else
509#define do_system(cmd) system(cmd)
510#endif
511 524
512static int is_file(const char *fn) 525static int is_file(const char *fn)
513{ 526{
@@ -524,9 +537,11 @@ static int dpkg_doconfigure(package_t *pkg)
524 int r; 537 int r;
525 char postinst[1024]; 538 char postinst[1024];
526 char buf[1024]; 539 char buf[1024];
540
527 DPRINTF("Configuring %s\n", pkg->package); 541 DPRINTF("Configuring %s\n", pkg->package);
528 pkg->status &= status_statusmask; 542 pkg->status &= status_statusmask;
529 snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package); 543 snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package);
544
530 if (is_file(postinst)) { 545 if (is_file(postinst)) {
531 snprintf(buf, sizeof(buf), "%s configure", postinst); 546 snprintf(buf, sizeof(buf), "%s configure", postinst);
532 if ((r = do_system(buf)) != 0) { 547 if ((r = do_system(buf)) != 0) {
@@ -535,7 +550,6 @@ static int dpkg_doconfigure(package_t *pkg)
535 return 1; 550 return 1;
536 } 551 }
537 } 552 }
538
539 pkg->status |= status_statusinstalled; 553 pkg->status |= status_statusinstalled;
540 554
541 return 0; 555 return 0;
@@ -543,80 +557,78 @@ static int dpkg_doconfigure(package_t *pkg)
543 557
544static int dpkg_dounpack(package_t *pkg) 558static int dpkg_dounpack(package_t *pkg)
545{ 559{
546 int r = 0; 560 int r = 0, i;
547 char *cwd, *p; 561 char *cwd, *p;
548 FILE *infp, *outfp; 562 FILE *infp, *outfp;
549 char buf[1024], buf2[1024]; 563 char buf[1024], buf2[1024];
550 int i;
551 char *adminscripts[] = { "prerm", "postrm", "preinst", "postinst", 564 char *adminscripts[] = { "prerm", "postrm", "preinst", "postinst",
552 "conffiles", "md5sums", "shlibs", 565 "conffiles", "md5sums", "shlibs", "templates" };
553 "templates" };
554 566
555 DPRINTF("Unpacking %s\n", pkg->package); 567 DPRINTF("Unpacking %s\n", pkg->package);
556 568
557 cwd = getcwd(0, 0); 569 cwd = getcwd(0, 0);
558 chdir("/"); 570 chdir("/");
559 snprintf(buf, sizeof(buf), "ar -p %s data.tar.gz|zcat|tar -xf -", pkg->file); 571 snprintf(buf, sizeof(buf), "ar -p %s data.tar.gz|zcat|tar -xf -", pkg->file);
560 if (SYSTEM(buf) == 0) { 572 if (SYSTEM(buf) != 0) {
561 /* Installs the package scripts into the info directory */ 573 goto end;
562 for (i = 0; i < sizeof(adminscripts) / sizeof(adminscripts[0]); i++) { 574 }
563 snprintf(buf, sizeof(buf), "%s%s/%s", 575 /* Installs the package scripts into the info directory */
564 DPKGCIDIR, pkg->package, adminscripts[i]); 576 for (i = 0; i < sizeof(adminscripts) / sizeof(adminscripts[0]); i++) {
565 snprintf(buf2, sizeof(buf), "%s%s.%s", 577 snprintf(buf, sizeof(buf), "%s%s/%s",
566 infodir, pkg->package, adminscripts[i]); 578 dpkgcidir, pkg->package, adminscripts[i]);
567 if (copy_file(buf, buf2, TRUE, FALSE, FALSE) < 0) { 579 snprintf(buf2, sizeof(buf), "%s%s.%s",
568 fprintf(stderr, "Cannot copy %s to %s: %s\n", 580 infodir, pkg->package, adminscripts[i]);
569 buf, buf2, strerror(errno)); 581 if (copy_file(buf, buf2, TRUE, FALSE, FALSE) < 0) {
570 r = 1; 582 fprintf(stderr, "Cannot copy %s to %s: %s\n",
571 break; 583 buf, buf2, strerror(errno));
572 } else { 584 r = 1;
573 /* ugly hack to create the list file; should 585 break;
574 * probably do something more elegant 586 }
575 * 587 /* ugly hack to create the list file; should
576 * why oh why does dpkg create the list file 588 * probably do something more elegant
577 * so oddly... 589 *
578 */ 590 * why oh why does dpkg create the list file
579 snprintf(buf, sizeof(buf), 591 * so oddly...
580 "ar -p %s data.tar.gz|zcat|tar -tf -", 592 */
581 pkg->file); 593 snprintf(buf, sizeof(buf), "ar -p %s data.tar.gz|zcat|tar -tf -", pkg->file);
582 snprintf(buf2, sizeof(buf2), 594 snprintf(buf2, sizeof(buf2), "%s%s.list", infodir, pkg->package);
583 "%s%s.list", infodir, pkg->package); 595 if ((infp = popen(buf, "r")) == NULL || (outfp = fopen(buf2, "w")) == NULL) {
584 if ((infp = popen(buf, "r")) == NULL || 596 fprintf(stderr, "Cannot create %s\n", buf2);
585 (outfp = fopen(buf2, "w")) == NULL) { 597 r = 1;
586 fprintf(stderr, "Cannot create %s\n", 598 break;
587 buf2); 599 }
588 r = 1; 600 while (fgets(buf, sizeof(buf), infp) && !feof(infp)) {
589 break; 601 p = buf;
590 } 602 if (*p == '.') {
591 while (fgets(buf, sizeof(buf), infp) && 603 p++;
592 !feof(infp)) { 604 }
593 p = buf; 605 if ((*p == '/') && (*(p + 1) == '\n')) {
594 if (*p == '.') p++; 606 *(p + 1) = '.';
595 if (*p == '/' && *(p+1) == '\n') { 607 *(p + 2) = '\n';
596 *(p+1) = '.'; 608 *(p + 3) = 0;
597 *(p+2) = '\n';
598 *(p+3) = 0;
599 }
600 if (p[strlen(p)-2] == '/') {
601 p[strlen(p)-2] = '\n';
602 p[strlen(p)-1] = 0;
603 }
604 fputs(p, outfp);
605 }
606 fclose(infp);
607 fclose(outfp);
608 } 609 }
610 if (p[strlen(p) - 2] == '/') {
611 p[strlen(p) - 2] = '\n';
612 p[strlen(p) - 1] = 0;
613 }
614 fputs(p, outfp);
609 } 615 }
610 pkg->status &= status_wantmask; 616 fclose(infp);
611 pkg->status |= status_wantinstall; 617 fclose(outfp);
612 pkg->status &= status_flagmask; 618 }
613 pkg->status |= status_flagok; 619
614 pkg->status &= status_statusmask; 620 pkg->status &= status_wantmask;
615 if (r == 0) 621 pkg->status |= status_wantinstall;
616 pkg->status |= status_statusunpacked; 622 pkg->status &= status_flagmask;
617 else 623 pkg->status |= status_flagok;
618 pkg->status |= status_statushalfinstalled; 624 pkg->status &= status_statusmask;
625
626 if (r == 0) {
627 pkg->status |= status_statusunpacked;
628 } else {
629 pkg->status |= status_statushalfinstalled;
619 } 630 }
631end:
620 chdir(cwd); 632 chdir(cwd);
621 return r; 633 return r;
622} 634}
@@ -638,15 +650,17 @@ static int dpkg_unpackcontrol(package_t *pkg)
638 p = strrchr(pkg->file, '/'); 650 p = strrchr(pkg->file, '/');
639 if (p) p++; else p = pkg->file; 651 if (p) p++; else p = pkg->file;
640 p = pkg->package = strdup(p); 652 p = pkg->package = strdup(p);
641 while (*p != 0 && *p != '_' && *p != '.') p++; 653 while (*p != 0 && *p != '_' && *p != '.') {
654 p++;
655 }
642 *p = 0; 656 *p = 0;
643 657
644 cwd = getcwd(0, 0); 658 cwd = getcwd(0, 0);
645 snprintf(buf, sizeof(buf), "%s%s", DPKGCIDIR, pkg->package); 659 snprintf(buf, sizeof(buf), "%s%s", dpkgcidir, pkg->package);
646 DPRINTF("dir = %s\n", buf); 660 DPRINTF("dir = %s\n", buf);
661
647 if (mkdir(buf, S_IRWXU) == 0 && chdir(buf) == 0) { 662 if (mkdir(buf, S_IRWXU) == 0 && chdir(buf) == 0) {
648 snprintf(buf, sizeof(buf), "ar -p %s control.tar.gz|zcat|tar -xf -", 663 snprintf(buf, sizeof(buf), "ar -p %s control.tar.gz|zcat|tar -xf -", pkg->file);
649 pkg->file);
650 if (SYSTEM(buf) == 0) { 664 if (SYSTEM(buf) == 0) {
651 if ((f = fopen("control", "r")) != NULL) { 665 if ((f = fopen("control", "r")) != NULL) {
652 control_read(f, pkg); 666 control_read(f, pkg);
@@ -654,9 +668,9 @@ static int dpkg_unpackcontrol(package_t *pkg)
654 } 668 }
655 } 669 }
656 } 670 }
657
658 chdir(cwd); 671 chdir(cwd);
659 free(cwd); 672 free(cwd);
673
660 return r; 674 return r;
661} 675}
662 676
@@ -666,19 +680,19 @@ static int dpkg_unpack(package_t *pkgs)
666 package_t *pkg; 680 package_t *pkg;
667 void *status = status_read(); 681 void *status = status_read();
668 682
669 if (SYSTEM("rm -rf -- " DPKGCIDIR) != 0 || 683 if (SYSTEM(rm_dpkgcidir) != 0 ||
670 mkdir(DPKGCIDIR, S_IRWXU) != 0) { 684 mkdir(dpkgcidir, S_IRWXU) != 0) {
671 perror("mkdir"); 685 perror("mkdir");
672 return 1; 686 return 1;
673 } 687 }
674
675 for (pkg = pkgs; pkg != 0; pkg = pkg->next) { 688 for (pkg = pkgs; pkg != 0; pkg = pkg->next) {
676 dpkg_unpackcontrol(pkg); 689 dpkg_unpackcontrol(pkg);
677 r = dpkg_dounpack(pkg); 690 r = dpkg_dounpack(pkg);
678 if (r != 0) break; 691 if (r != 0) break;
679 } 692 }
680 status_merge(status, pkgs); 693 status_merge(status, pkgs);
681 SYSTEM("rm -rf -- " DPKGCIDIR); 694 SYSTEM(rm_dpkgcidir);
695
682 return r; 696 return r;
683} 697}
684 698
@@ -688,18 +702,23 @@ static int dpkg_configure(package_t *pkgs)
688 void *found; 702 void *found;
689 package_t *pkg; 703 package_t *pkg;
690 void *status = status_read(); 704 void *status = status_read();
705
691 for (pkg = pkgs; pkg != 0 && r == 0; pkg = pkg->next) { 706 for (pkg = pkgs; pkg != 0 && r == 0; pkg = pkg->next) {
692 found = tfind(pkg, &status, package_compare); 707 found = tfind(pkg, &status, package_compare);
708
693 if (found == 0) { 709 if (found == 0) {
694 fprintf(stderr, "Trying to configure %s, but it is not installed\n", pkg->package); 710 fprintf(stderr, "Trying to configure %s, but it is not installed\n", pkg->package);
695 r = 1; 711 r = 1;
696 } else { 712 }
697 /* configure the package listed in the status file; 713 /* configure the package listed in the status file;
698 * not pkg, as we have info only for the latter */ 714 * not pkg, as we have info only for the latter
715 */
716 else {
699 r = dpkg_doconfigure(*(package_t **)found); 717 r = dpkg_doconfigure(*(package_t **)found);
700 } 718 }
701 } 719 }
702 status_merge(status, 0); 720 status_merge(status, 0);
721
703 return r; 722 return r;
704} 723}
705 724
@@ -707,8 +726,9 @@ static int dpkg_install(package_t *pkgs)
707{ 726{
708 package_t *p, *ordered = 0; 727 package_t *p, *ordered = 0;
709 void *status = status_read(); 728 void *status = status_read();
710 if (SYSTEM("rm -rf -- " DPKGCIDIR) != 0 || 729
711 mkdir(DPKGCIDIR, S_IRWXU) != 0) { 730 if (SYSTEM(rm_dpkgcidir) != 0 ||
731 mkdir(dpkgcidir, S_IRWXU) != 0) {
712 perror("mkdir"); 732 perror("mkdir");
713 return 1; 733 return 1;
714 } 734 }
@@ -747,7 +767,8 @@ static int dpkg_install(package_t *pkgs)
747 if (ordered != 0) { 767 if (ordered != 0) {
748 status_merge(status, pkgs); 768 status_merge(status, pkgs);
749 } 769 }
750 SYSTEM("rm -rf -- " DPKGCIDIR); 770 SYSTEM(rm_dpkgcidir);
771
751 return 0; 772 return 0;
752} 773}
753 774
@@ -755,10 +776,12 @@ static int dpkg_remove(package_t *pkgs)
755{ 776{
756 package_t *p; 777 package_t *p;
757 void *status = status_read(); 778 void *status = status_read();
779
758 for (p = pkgs; p != 0; p = p->next) 780 for (p = pkgs; p != 0; p = p->next)
759 { 781 {
760 } 782 }
761 status_merge(status, 0); 783 status_merge(status, 0);
784
762 return 0; 785 return 0;
763} 786}
764 787
@@ -768,16 +791,19 @@ extern int dpkg_main(int argc, char **argv)
768 char *s; 791 char *s;
769 package_t *p, *packages = NULL; 792 package_t *p, *packages = NULL;
770 char *cwd = getcwd(0, 0); 793 char *cwd = getcwd(0, 0);
794
771 while (*++argv) { 795 while (*++argv) {
772 if (**argv == '-') { 796 if (**argv == '-') {
773 /* Nasty little hack to "parse" long options. */ 797 /* Nasty little hack to "parse" long options. */
774 s = *argv; 798 s = *argv;
775 while (*s == '-') 799 while (*s == '-') {
776 s++; 800 s++;
801 }
777 opt=s[0]; 802 opt=s[0];
778 } else { 803 } else {
779 p = (package_t *)xmalloc(sizeof(package_t)); 804 p = (package_t *)xmalloc(sizeof(package_t));
780 memset(p, 0, sizeof(package_t)); 805 memset(p, 0, sizeof(package_t));
806
781 if (**argv == '/') { 807 if (**argv == '/') {
782 p->file = *argv; 808 p->file = *argv;
783 } else 809 } else
@@ -787,11 +813,12 @@ extern int dpkg_main(int argc, char **argv)
787 } else { 813 } else {
788 p->package = strdup(*argv); 814 p->package = strdup(*argv);
789 } 815 }
816
790 p->next = packages; 817 p->next = packages;
791 packages = p; 818 packages = p;
792 } 819 }
793
794 } 820 }
821
795 switch (opt) { 822 switch (opt) {
796 case 'i': 823 case 'i':
797 return dpkg_install(packages); 824 return dpkg_install(packages);
@@ -801,10 +828,8 @@ extern int dpkg_main(int argc, char **argv)
801 return dpkg_unpack(packages); 828 return dpkg_unpack(packages);
802 case 'c': 829 case 'c':
803 return dpkg_configure(packages); 830 return dpkg_configure(packages);
831 default :
832 usage(dpkg_usage);
833 return 0;
804 } 834 }
805
806 /* if it falls through to here, some of the command line options were
807 wrong */
808 usage(dpkg_usage);
809 return 0;
810} \ No newline at end of file 835} \ No newline at end of file
diff --git a/dpkg.c b/dpkg.c
index ef120a115..7b4c74d7d 100644
--- a/dpkg.c
+++ b/dpkg.c
@@ -35,9 +35,13 @@
35#define BUFSIZE 4096 35#define BUFSIZE 4096
36#define DEPENDSMAX 64 /* maximum number of depends we can handle */ 36#define DEPENDSMAX 64 /* maximum number of depends we can handle */
37 37
38#define ADMINDIR "/var/lib/dpkg" 38static const char statusfile[] = "/var/lib/dpkg/status.udeb";
39#define STATUSFILE ADMINDIR ## "/status.udeb" 39static const char new_statusfile[] = "/var/lib/dpkg/status.udeb.new";
40#define DPKGCIDIR ADMINDIR ## "/tmp.ci/" 40static const char bak_statusfile[] = "/var/lib/dpkg/status.udeb.bak";
41
42static const char dpkgcidir[] = "/var/lib/dpkg/tmp.ci/";
43static const char rm_dpkgcidir[] = "rm -rf /var/lib/dpkg/tmp.ci/";
44
41static const char infodir[] = "/var/lib/dpkg/info/"; 45static const char infodir[] = "/var/lib/dpkg/info/";
42static const char udpkg_quiet[] = "UDPKG_QUIET"; 46static const char udpkg_quiet[] = "UDPKG_QUIET";
43 47
@@ -95,6 +99,16 @@ typedef struct package_s {
95 struct package_s *next; 99 struct package_s *next;
96} package_t; 100} package_t;
97 101
102#ifdef DODEBUG
103static int do_system(const char *cmd)
104{
105 DPRINTF("cmd is %s\n", cmd);
106 return system(cmd);
107}
108#else
109#define do_system(cmd) system(cmd)
110#endif
111
98static int package_compare(const void *p1, const void *p2) 112static int package_compare(const void *p1, const void *p2)
99{ 113{
100 return strcmp(((package_t *)p1)->package, 114 return strcmp(((package_t *)p1)->package,
@@ -111,41 +125,46 @@ static char **depends_split(const char *dependsstr)
111 int i = 0; 125 int i = 0;
112 126
113 dependsvec[0] = 0; 127 dependsvec[0] = 0;
128 if (dependsstr == 0) {
129 goto end;
130 }
114 131
115 if (dependsstr != 0) { 132 p = strdup(dependsstr);
116 p = strdup(dependsstr); 133 while (*p != 0 && *p != '\n') {
117 while (*p != 0 && *p != '\n') { 134 if (*p != ' ') {
118 if (*p != ' ') { 135 if (*p == ',') {
119 if (*p == ',') { 136 *p = 0;
120 *p = 0; 137 dependsvec[++i] = 0;
121 dependsvec[++i] = 0;
122 } else
123 if (dependsvec[i] == 0)
124 dependsvec[i] = p;
125 } else { 138 } else {
126 *p = 0; /* eat the space... */ 139 if (dependsvec[i] == 0) {
140 dependsvec[i] = p;
141 }
127 } 142 }
128 p++; 143 } else {
144 *p = 0; /* eat the space... */
129 } 145 }
130 *p = 0; 146 p++;
131 } 147 }
148 *p = 0;
149
150end:
132 dependsvec[i+1] = 0; 151 dependsvec[i+1] = 0;
133 return dependsvec; 152 return dependsvec;
134} 153}
135 154
155/* Topological sort algorithm:
156 * ordered is the output list, pkgs is the dependency graph, pkg is
157 * the current node
158 *
159 * recursively add all the adjacent nodes to the ordered list, marking
160 * each one as visited along the way
161 *
162 * yes, this algorithm looks a bit odd when all the params have the
163 * same type :-)
164 */
136static void depends_sort_visit(package_t **ordered, package_t *pkgs, 165static void depends_sort_visit(package_t **ordered, package_t *pkgs,
137 package_t *pkg) 166 package_t *pkg)
138{ 167{
139 /* Topological sort algorithm:
140 * ordered is the output list, pkgs is the dependency graph, pkg is
141 * the current node
142 *
143 * recursively add all the adjacent nodes to the ordered list, marking
144 * each one as visited along the way
145 *
146 * yes, this algorithm looks a bit odd when all the params have the
147 * same type :-)
148 */
149 unsigned short i; 168 unsigned short i;
150 169
151 /* mark node as processing */ 170 /* mark node as processing */
@@ -164,6 +183,7 @@ static void depends_sort_visit(package_t **ordered, package_t *pkgs,
164 newnode->next = *ordered; 183 newnode->next = *ordered;
165 *ordered = newnode; 184 *ordered = newnode;
166#endif 185#endif
186
167 pkg->next = *ordered; 187 pkg->next = *ordered;
168 *ordered = pkg; 188 *ordered = pkg;
169 189
@@ -178,12 +198,14 @@ static package_t *depends_sort(package_t *pkgs)
178 package_t *ordered = NULL; 198 package_t *ordered = NULL;
179 package_t *pkg; 199 package_t *pkg;
180 200
181 for (pkg = pkgs; pkg != 0; pkg = pkg->next) 201 for (pkg = pkgs; pkg != 0; pkg = pkg->next) {
182 pkg->color = color_white; 202 pkg->color = color_white;
183 203 }
184 for (pkg = pkgs; pkg != 0; pkg = pkg->next) 204 for (pkg = pkgs; pkg != 0; pkg = pkg->next) {
185 if (pkg->color == color_white) 205 if (pkg->color == color_white) {
186 depends_sort_visit(&ordered, pkgs, pkg); 206 depends_sort_visit(&ordered, pkgs, pkg);
207 }
208 }
187 209
188 /* Leaks the old list... return the new one... */ 210 /* Leaks the old list... return the new one... */
189 return ordered; 211 return ordered;
@@ -218,17 +240,15 @@ static package_t *depends_resolve(package_t *pkgs, void *status)
218 if ((found = tfind(&dependpkg, &status, package_compare)) == 0 || 240 if ((found = tfind(&dependpkg, &status, package_compare)) == 0 ||
219 ((chk = *(package_t **)found) && 241 ((chk = *(package_t **)found) &&
220 (chk->status & (status_flagok | status_statusinstalled)) != 242 (chk->status & (status_flagok | status_statusinstalled)) !=
221 (status_flagok | status_statusinstalled))) 243 (status_flagok | status_statusinstalled))) {
222 { 244
223 /* if it fails, we look through the list of packages we are going to 245 /* if it fails, we look through the list of packages we are going to
224 * install */ 246 * install */
225 for (chk = pkgs; chk != 0; chk = chk->next) { 247 for (chk = pkgs; chk != 0; chk = chk->next) {
226 if (strcmp(chk->package, dependsvec[i]) == 0 || 248 if (strcmp(chk->package, dependsvec[i]) == 0 || (chk->provides &&
227 (chk->provides &&
228 strncmp(chk->provides, dependsvec[i], strlen(dependsvec[i])) == 0)) { 249 strncmp(chk->provides, dependsvec[i], strlen(dependsvec[i])) == 0)) {
229 if (chk->requiredcount >= DEPENDSMAX) { 250 if (chk->requiredcount >= DEPENDSMAX) {
230 fprintf(stderr, "Too many dependencies for %s\n", 251 fprintf(stderr, "Too many dependencies for %s\n", chk->package);
231 chk->package);
232 return 0; 252 return 0;
233 } 253 }
234 if (chk != pkg) { 254 if (chk != pkg) {
@@ -264,16 +284,16 @@ static package_t *depends_resolve(package_t *pkgs, void *status)
264 * replacing any pre-existing entries. when a merge happens, status info 284 * replacing any pre-existing entries. when a merge happens, status info
265 * read using the status_read function is written back to the status file 285 * read using the status_read function is written back to the status file
266 */ 286 */
267
268static unsigned long status_parse(const char *line) 287static unsigned long status_parse(const char *line)
269{ 288{
270 char *p; 289 char *p;
271 int i, j; 290 int i, j;
272 unsigned long l = 0; 291 unsigned long l = 0;
273 for (i = 0; i < 3; i++) 292
274 { 293 for (i = 0; i < 3; i++) {
275 p = strchr(line, ' '); 294 if ((p = strchr(line, ' ')) != NULL) {
276 if (p) *p = 0; 295 *p = 0;
296 }
277 j = 1; 297 j = 1;
278 while (statuswords[i][j] != 0) { 298 while (statuswords[i][j] != 0) {
279 if (strcmp(line, statuswords[i][j]) == 0) { 299 if (strcmp(line, statuswords[i][j]) == 0) {
@@ -288,6 +308,7 @@ static unsigned long status_parse(const char *line)
288 } 308 }
289 line = p+1; 309 line = p+1;
290 } 310 }
311
291 return l; 312 return l;
292} 313}
293 314
@@ -313,6 +334,7 @@ static const char *status_print(unsigned long flags)
313 return NULL; 334 return NULL;
314 } 335 }
315 } 336 }
337
316 return buf; 338 return buf;
317} 339}
318 340
@@ -326,6 +348,7 @@ static void control_read(FILE *file, package_t *p)
326 348
327 while ((line = get_line_from_file(file)) != NULL) { 349 while ((line = get_line_from_file(file)) != NULL) {
328 line[strlen(line)] = 0; 350 line[strlen(line)] = 0;
351
329 if (strlen(line) == 0) { 352 if (strlen(line) == 0) {
330 break; 353 break;
331 } else 354 } else
@@ -359,13 +382,15 @@ static void *status_read(void)
359 void *status = 0; 382 void *status = 0;
360 package_t *m = 0, *p = 0, *t = 0; 383 package_t *m = 0, *p = 0, *t = 0;
361 384
362 if ((f = fopen(STATUSFILE, "r")) == NULL) { 385 if ((f = fopen(statusfile, "r")) == NULL) {
363 perror(STATUSFILE); 386 perror(statusfile);
364 return 0; 387 return 0;
365 } 388 }
389
366 if (getenv(udpkg_quiet) == NULL) { 390 if (getenv(udpkg_quiet) == NULL) {
367 printf("(Reading database...)\n"); 391 printf("(Reading database...)\n");
368 } 392 }
393
369 while (!feof(f)) { 394 while (!feof(f)) {
370 m = (package_t *)xmalloc(sizeof(package_t)); 395 m = (package_t *)xmalloc(sizeof(package_t));
371 memset(m, 0, sizeof(package_t)); 396 memset(m, 0, sizeof(package_t));
@@ -389,7 +414,7 @@ static void *status_read(void)
389 p->package = strdup(m->provides); 414 p->package = strdup(m->provides);
390 415
391 t = *(package_t **)tsearch(p, &status, package_compare); 416 t = *(package_t **)tsearch(p, &status, package_compare);
392 if (!(t == p)) { 417 if (t != p) {
393 free(p->package); 418 free(p->package);
394 free(p); 419 free(p);
395 } 420 }
@@ -422,18 +447,19 @@ static int status_merge(void *status, package_t *pkgs)
422 package_t locpkg; 447 package_t locpkg;
423 int r = 0; 448 int r = 0;
424 449
425 if ((fin = fopen(STATUSFILE, "r")) == NULL) { 450 if ((fin = fopen(statusfile, "r")) == NULL) {
426 perror(STATUSFILE); 451 perror(statusfile);
427 return 0; 452 return 0;
428 } 453 }
429 if ((fout = fopen(STATUSFILE ".new", "w")) == NULL) { 454 if ((fout = fopen(new_statusfile, "w")) == NULL) {
430 perror(STATUSFILE ".new"); 455 perror(new_statusfile);
431 return 0; 456 return 0;
432 } 457 }
433 if (getenv(udpkg_quiet) == NULL) { 458 if (getenv(udpkg_quiet) == NULL) {
434 printf("(Updating database...)\n"); 459 printf("(Updating database...)\n");
435 } 460 }
436 while (((line = get_line_from_file(fin)) != NULL) && (feof(fin) != 0)) { 461
462 while (((line = get_line_from_file(fin)) != NULL) && !feof(fin)) {
437 line[strlen(line)] = 0; /* trim newline */ 463 line[strlen(line)] = 0; /* trim newline */
438 /* If we see a package header, find out if it's a package 464 /* If we see a package header, find out if it's a package
439 * that we have processed. if so, we skip that block for 465 * that we have processed. if so, we skip that block for
@@ -488,26 +514,13 @@ static int status_merge(void *status, package_t *pkgs)
488 fclose(fin); 514 fclose(fin);
489 fclose(fout); 515 fclose(fout);
490 516
491 r = rename(STATUSFILE, STATUSFILE ".bak"); 517 r = rename(statusfile, bak_statusfile);
492 if (r == 0) { 518 if (r == 0) {
493 r = rename(STATUSFILE ".new", STATUSFILE); 519 r = rename(new_statusfile, statusfile);
494 } 520 }
495 return 0;
496}
497
498/*
499 * Main udpkg implementation routines
500 */
501 521
502#ifdef DODEBUG 522 return 0;
503static int do_system(const char *cmd)
504{
505 DPRINTF("cmd is %s\n", cmd);
506 return system(cmd);
507} 523}
508#else
509#define do_system(cmd) system(cmd)
510#endif
511 524
512static int is_file(const char *fn) 525static int is_file(const char *fn)
513{ 526{
@@ -524,9 +537,11 @@ static int dpkg_doconfigure(package_t *pkg)
524 int r; 537 int r;
525 char postinst[1024]; 538 char postinst[1024];
526 char buf[1024]; 539 char buf[1024];
540
527 DPRINTF("Configuring %s\n", pkg->package); 541 DPRINTF("Configuring %s\n", pkg->package);
528 pkg->status &= status_statusmask; 542 pkg->status &= status_statusmask;
529 snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package); 543 snprintf(postinst, sizeof(postinst), "%s%s.postinst", infodir, pkg->package);
544
530 if (is_file(postinst)) { 545 if (is_file(postinst)) {
531 snprintf(buf, sizeof(buf), "%s configure", postinst); 546 snprintf(buf, sizeof(buf), "%s configure", postinst);
532 if ((r = do_system(buf)) != 0) { 547 if ((r = do_system(buf)) != 0) {
@@ -535,7 +550,6 @@ static int dpkg_doconfigure(package_t *pkg)
535 return 1; 550 return 1;
536 } 551 }
537 } 552 }
538
539 pkg->status |= status_statusinstalled; 553 pkg->status |= status_statusinstalled;
540 554
541 return 0; 555 return 0;
@@ -543,80 +557,78 @@ static int dpkg_doconfigure(package_t *pkg)
543 557
544static int dpkg_dounpack(package_t *pkg) 558static int dpkg_dounpack(package_t *pkg)
545{ 559{
546 int r = 0; 560 int r = 0, i;
547 char *cwd, *p; 561 char *cwd, *p;
548 FILE *infp, *outfp; 562 FILE *infp, *outfp;
549 char buf[1024], buf2[1024]; 563 char buf[1024], buf2[1024];
550 int i;
551 char *adminscripts[] = { "prerm", "postrm", "preinst", "postinst", 564 char *adminscripts[] = { "prerm", "postrm", "preinst", "postinst",
552 "conffiles", "md5sums", "shlibs", 565 "conffiles", "md5sums", "shlibs", "templates" };
553 "templates" };
554 566
555 DPRINTF("Unpacking %s\n", pkg->package); 567 DPRINTF("Unpacking %s\n", pkg->package);
556 568
557 cwd = getcwd(0, 0); 569 cwd = getcwd(0, 0);
558 chdir("/"); 570 chdir("/");
559 snprintf(buf, sizeof(buf), "ar -p %s data.tar.gz|zcat|tar -xf -", pkg->file); 571 snprintf(buf, sizeof(buf), "ar -p %s data.tar.gz|zcat|tar -xf -", pkg->file);
560 if (SYSTEM(buf) == 0) { 572 if (SYSTEM(buf) != 0) {
561 /* Installs the package scripts into the info directory */ 573 goto end;
562 for (i = 0; i < sizeof(adminscripts) / sizeof(adminscripts[0]); i++) { 574 }
563 snprintf(buf, sizeof(buf), "%s%s/%s", 575 /* Installs the package scripts into the info directory */
564 DPKGCIDIR, pkg->package, adminscripts[i]); 576 for (i = 0; i < sizeof(adminscripts) / sizeof(adminscripts[0]); i++) {
565 snprintf(buf2, sizeof(buf), "%s%s.%s", 577 snprintf(buf, sizeof(buf), "%s%s/%s",
566 infodir, pkg->package, adminscripts[i]); 578 dpkgcidir, pkg->package, adminscripts[i]);
567 if (copy_file(buf, buf2, TRUE, FALSE, FALSE) < 0) { 579 snprintf(buf2, sizeof(buf), "%s%s.%s",
568 fprintf(stderr, "Cannot copy %s to %s: %s\n", 580 infodir, pkg->package, adminscripts[i]);
569 buf, buf2, strerror(errno)); 581 if (copy_file(buf, buf2, TRUE, FALSE, FALSE) < 0) {
570 r = 1; 582 fprintf(stderr, "Cannot copy %s to %s: %s\n",
571 break; 583 buf, buf2, strerror(errno));
572 } else { 584 r = 1;
573 /* ugly hack to create the list file; should 585 break;
574 * probably do something more elegant 586 }
575 * 587 /* ugly hack to create the list file; should
576 * why oh why does dpkg create the list file 588 * probably do something more elegant
577 * so oddly... 589 *
578 */ 590 * why oh why does dpkg create the list file
579 snprintf(buf, sizeof(buf), 591 * so oddly...
580 "ar -p %s data.tar.gz|zcat|tar -tf -", 592 */
581 pkg->file); 593 snprintf(buf, sizeof(buf), "ar -p %s data.tar.gz|zcat|tar -tf -", pkg->file);
582 snprintf(buf2, sizeof(buf2), 594 snprintf(buf2, sizeof(buf2), "%s%s.list", infodir, pkg->package);
583 "%s%s.list", infodir, pkg->package); 595 if ((infp = popen(buf, "r")) == NULL || (outfp = fopen(buf2, "w")) == NULL) {
584 if ((infp = popen(buf, "r")) == NULL || 596 fprintf(stderr, "Cannot create %s\n", buf2);
585 (outfp = fopen(buf2, "w")) == NULL) { 597 r = 1;
586 fprintf(stderr, "Cannot create %s\n", 598 break;
587 buf2); 599 }
588 r = 1; 600 while (fgets(buf, sizeof(buf), infp) && !feof(infp)) {
589 break; 601 p = buf;
590 } 602 if (*p == '.') {
591 while (fgets(buf, sizeof(buf), infp) && 603 p++;
592 !feof(infp)) { 604 }
593 p = buf; 605 if ((*p == '/') && (*(p + 1) == '\n')) {
594 if (*p == '.') p++; 606 *(p + 1) = '.';
595 if (*p == '/' && *(p+1) == '\n') { 607 *(p + 2) = '\n';
596 *(p+1) = '.'; 608 *(p + 3) = 0;
597 *(p+2) = '\n';
598 *(p+3) = 0;
599 }
600 if (p[strlen(p)-2] == '/') {
601 p[strlen(p)-2] = '\n';
602 p[strlen(p)-1] = 0;
603 }
604 fputs(p, outfp);
605 }
606 fclose(infp);
607 fclose(outfp);
608 } 609 }
610 if (p[strlen(p) - 2] == '/') {
611 p[strlen(p) - 2] = '\n';
612 p[strlen(p) - 1] = 0;
613 }
614 fputs(p, outfp);
609 } 615 }
610 pkg->status &= status_wantmask; 616 fclose(infp);
611 pkg->status |= status_wantinstall; 617 fclose(outfp);
612 pkg->status &= status_flagmask; 618 }
613 pkg->status |= status_flagok; 619
614 pkg->status &= status_statusmask; 620 pkg->status &= status_wantmask;
615 if (r == 0) 621 pkg->status |= status_wantinstall;
616 pkg->status |= status_statusunpacked; 622 pkg->status &= status_flagmask;
617 else 623 pkg->status |= status_flagok;
618 pkg->status |= status_statushalfinstalled; 624 pkg->status &= status_statusmask;
625
626 if (r == 0) {
627 pkg->status |= status_statusunpacked;
628 } else {
629 pkg->status |= status_statushalfinstalled;
619 } 630 }
631end:
620 chdir(cwd); 632 chdir(cwd);
621 return r; 633 return r;
622} 634}
@@ -638,15 +650,17 @@ static int dpkg_unpackcontrol(package_t *pkg)
638 p = strrchr(pkg->file, '/'); 650 p = strrchr(pkg->file, '/');
639 if (p) p++; else p = pkg->file; 651 if (p) p++; else p = pkg->file;
640 p = pkg->package = strdup(p); 652 p = pkg->package = strdup(p);
641 while (*p != 0 && *p != '_' && *p != '.') p++; 653 while (*p != 0 && *p != '_' && *p != '.') {
654 p++;
655 }
642 *p = 0; 656 *p = 0;
643 657
644 cwd = getcwd(0, 0); 658 cwd = getcwd(0, 0);
645 snprintf(buf, sizeof(buf), "%s%s", DPKGCIDIR, pkg->package); 659 snprintf(buf, sizeof(buf), "%s%s", dpkgcidir, pkg->package);
646 DPRINTF("dir = %s\n", buf); 660 DPRINTF("dir = %s\n", buf);
661
647 if (mkdir(buf, S_IRWXU) == 0 && chdir(buf) == 0) { 662 if (mkdir(buf, S_IRWXU) == 0 && chdir(buf) == 0) {
648 snprintf(buf, sizeof(buf), "ar -p %s control.tar.gz|zcat|tar -xf -", 663 snprintf(buf, sizeof(buf), "ar -p %s control.tar.gz|zcat|tar -xf -", pkg->file);
649 pkg->file);
650 if (SYSTEM(buf) == 0) { 664 if (SYSTEM(buf) == 0) {
651 if ((f = fopen("control", "r")) != NULL) { 665 if ((f = fopen("control", "r")) != NULL) {
652 control_read(f, pkg); 666 control_read(f, pkg);
@@ -654,9 +668,9 @@ static int dpkg_unpackcontrol(package_t *pkg)
654 } 668 }
655 } 669 }
656 } 670 }
657
658 chdir(cwd); 671 chdir(cwd);
659 free(cwd); 672 free(cwd);
673
660 return r; 674 return r;
661} 675}
662 676
@@ -666,19 +680,19 @@ static int dpkg_unpack(package_t *pkgs)
666 package_t *pkg; 680 package_t *pkg;
667 void *status = status_read(); 681 void *status = status_read();
668 682
669 if (SYSTEM("rm -rf -- " DPKGCIDIR) != 0 || 683 if (SYSTEM(rm_dpkgcidir) != 0 ||
670 mkdir(DPKGCIDIR, S_IRWXU) != 0) { 684 mkdir(dpkgcidir, S_IRWXU) != 0) {
671 perror("mkdir"); 685 perror("mkdir");
672 return 1; 686 return 1;
673 } 687 }
674
675 for (pkg = pkgs; pkg != 0; pkg = pkg->next) { 688 for (pkg = pkgs; pkg != 0; pkg = pkg->next) {
676 dpkg_unpackcontrol(pkg); 689 dpkg_unpackcontrol(pkg);
677 r = dpkg_dounpack(pkg); 690 r = dpkg_dounpack(pkg);
678 if (r != 0) break; 691 if (r != 0) break;
679 } 692 }
680 status_merge(status, pkgs); 693 status_merge(status, pkgs);
681 SYSTEM("rm -rf -- " DPKGCIDIR); 694 SYSTEM(rm_dpkgcidir);
695
682 return r; 696 return r;
683} 697}
684 698
@@ -688,18 +702,23 @@ static int dpkg_configure(package_t *pkgs)
688 void *found; 702 void *found;
689 package_t *pkg; 703 package_t *pkg;
690 void *status = status_read(); 704 void *status = status_read();
705
691 for (pkg = pkgs; pkg != 0 && r == 0; pkg = pkg->next) { 706 for (pkg = pkgs; pkg != 0 && r == 0; pkg = pkg->next) {
692 found = tfind(pkg, &status, package_compare); 707 found = tfind(pkg, &status, package_compare);
708
693 if (found == 0) { 709 if (found == 0) {
694 fprintf(stderr, "Trying to configure %s, but it is not installed\n", pkg->package); 710 fprintf(stderr, "Trying to configure %s, but it is not installed\n", pkg->package);
695 r = 1; 711 r = 1;
696 } else { 712 }
697 /* configure the package listed in the status file; 713 /* configure the package listed in the status file;
698 * not pkg, as we have info only for the latter */ 714 * not pkg, as we have info only for the latter
715 */
716 else {
699 r = dpkg_doconfigure(*(package_t **)found); 717 r = dpkg_doconfigure(*(package_t **)found);
700 } 718 }
701 } 719 }
702 status_merge(status, 0); 720 status_merge(status, 0);
721
703 return r; 722 return r;
704} 723}
705 724
@@ -707,8 +726,9 @@ static int dpkg_install(package_t *pkgs)
707{ 726{
708 package_t *p, *ordered = 0; 727 package_t *p, *ordered = 0;
709 void *status = status_read(); 728 void *status = status_read();
710 if (SYSTEM("rm -rf -- " DPKGCIDIR) != 0 || 729
711 mkdir(DPKGCIDIR, S_IRWXU) != 0) { 730 if (SYSTEM(rm_dpkgcidir) != 0 ||
731 mkdir(dpkgcidir, S_IRWXU) != 0) {
712 perror("mkdir"); 732 perror("mkdir");
713 return 1; 733 return 1;
714 } 734 }
@@ -747,7 +767,8 @@ static int dpkg_install(package_t *pkgs)
747 if (ordered != 0) { 767 if (ordered != 0) {
748 status_merge(status, pkgs); 768 status_merge(status, pkgs);
749 } 769 }
750 SYSTEM("rm -rf -- " DPKGCIDIR); 770 SYSTEM(rm_dpkgcidir);
771
751 return 0; 772 return 0;
752} 773}
753 774
@@ -755,10 +776,12 @@ static int dpkg_remove(package_t *pkgs)
755{ 776{
756 package_t *p; 777 package_t *p;
757 void *status = status_read(); 778 void *status = status_read();
779
758 for (p = pkgs; p != 0; p = p->next) 780 for (p = pkgs; p != 0; p = p->next)
759 { 781 {
760 } 782 }
761 status_merge(status, 0); 783 status_merge(status, 0);
784
762 return 0; 785 return 0;
763} 786}
764 787
@@ -768,16 +791,19 @@ extern int dpkg_main(int argc, char **argv)
768 char *s; 791 char *s;
769 package_t *p, *packages = NULL; 792 package_t *p, *packages = NULL;
770 char *cwd = getcwd(0, 0); 793 char *cwd = getcwd(0, 0);
794
771 while (*++argv) { 795 while (*++argv) {
772 if (**argv == '-') { 796 if (**argv == '-') {
773 /* Nasty little hack to "parse" long options. */ 797 /* Nasty little hack to "parse" long options. */
774 s = *argv; 798 s = *argv;
775 while (*s == '-') 799 while (*s == '-') {
776 s++; 800 s++;
801 }
777 opt=s[0]; 802 opt=s[0];
778 } else { 803 } else {
779 p = (package_t *)xmalloc(sizeof(package_t)); 804 p = (package_t *)xmalloc(sizeof(package_t));
780 memset(p, 0, sizeof(package_t)); 805 memset(p, 0, sizeof(package_t));
806
781 if (**argv == '/') { 807 if (**argv == '/') {
782 p->file = *argv; 808 p->file = *argv;
783 } else 809 } else
@@ -787,11 +813,12 @@ extern int dpkg_main(int argc, char **argv)
787 } else { 813 } else {
788 p->package = strdup(*argv); 814 p->package = strdup(*argv);
789 } 815 }
816
790 p->next = packages; 817 p->next = packages;
791 packages = p; 818 packages = p;
792 } 819 }
793
794 } 820 }
821
795 switch (opt) { 822 switch (opt) {
796 case 'i': 823 case 'i':
797 return dpkg_install(packages); 824 return dpkg_install(packages);
@@ -801,10 +828,8 @@ extern int dpkg_main(int argc, char **argv)
801 return dpkg_unpack(packages); 828 return dpkg_unpack(packages);
802 case 'c': 829 case 'c':
803 return dpkg_configure(packages); 830 return dpkg_configure(packages);
831 default :
832 usage(dpkg_usage);
833 return 0;
804 } 834 }
805
806 /* if it falls through to here, some of the command line options were
807 wrong */
808 usage(dpkg_usage);
809 return 0;
810} \ No newline at end of file 835} \ No newline at end of file