diff options
author | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2001-02-11 01:40:23 +0000 |
---|---|---|
committer | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2001-02-11 01:40:23 +0000 |
commit | a1be2a16353409fc9a8c4d7b6eb413d68e2e2f8c (patch) | |
tree | 5a8904022795d758ac94619cf385d46452526cf2 | |
parent | d1765981299d968f187d53555469d11ac2614f43 (diff) | |
download | busybox-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.c | 325 | ||||
-rw-r--r-- | dpkg.c | 325 |
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" | 38 | static const char statusfile[] = "/var/lib/dpkg/status.udeb"; |
39 | #define STATUSFILE ADMINDIR ## "/status.udeb" | 39 | static const char new_statusfile[] = "/var/lib/dpkg/status.udeb.new"; |
40 | #define DPKGCIDIR ADMINDIR ## "/tmp.ci/" | 40 | static const char bak_statusfile[] = "/var/lib/dpkg/status.udeb.bak"; |
41 | |||
42 | static const char dpkgcidir[] = "/var/lib/dpkg/tmp.ci/"; | ||
43 | static const char rm_dpkgcidir[] = "rm -rf /var/lib/dpkg/tmp.ci/"; | ||
44 | |||
41 | static const char infodir[] = "/var/lib/dpkg/info/"; | 45 | static const char infodir[] = "/var/lib/dpkg/info/"; |
42 | static const char udpkg_quiet[] = "UDPKG_QUIET"; | 46 | static 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 | ||
103 | static 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 | |||
98 | static int package_compare(const void *p1, const void *p2) | 112 | static 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 | |||
150 | end: | ||
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 | */ | ||
136 | static void depends_sort_visit(package_t **ordered, package_t *pkgs, | 165 | static 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 | |||
268 | static unsigned long status_parse(const char *line) | 287 | static 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; |
503 | static 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 | ||
512 | static int is_file(const char *fn) | 525 | static 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 | ||
544 | static int dpkg_dounpack(package_t *pkg) | 558 | static 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 | } |
631 | end: | ||
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 |
@@ -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" | 38 | static const char statusfile[] = "/var/lib/dpkg/status.udeb"; |
39 | #define STATUSFILE ADMINDIR ## "/status.udeb" | 39 | static const char new_statusfile[] = "/var/lib/dpkg/status.udeb.new"; |
40 | #define DPKGCIDIR ADMINDIR ## "/tmp.ci/" | 40 | static const char bak_statusfile[] = "/var/lib/dpkg/status.udeb.bak"; |
41 | |||
42 | static const char dpkgcidir[] = "/var/lib/dpkg/tmp.ci/"; | ||
43 | static const char rm_dpkgcidir[] = "rm -rf /var/lib/dpkg/tmp.ci/"; | ||
44 | |||
41 | static const char infodir[] = "/var/lib/dpkg/info/"; | 45 | static const char infodir[] = "/var/lib/dpkg/info/"; |
42 | static const char udpkg_quiet[] = "UDPKG_QUIET"; | 46 | static 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 | ||
103 | static 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 | |||
98 | static int package_compare(const void *p1, const void *p2) | 112 | static 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 | |||
150 | end: | ||
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 | */ | ||
136 | static void depends_sort_visit(package_t **ordered, package_t *pkgs, | 165 | static 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 | |||
268 | static unsigned long status_parse(const char *line) | 287 | static 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; |
503 | static 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 | ||
512 | static int is_file(const char *fn) | 525 | static 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 | ||
544 | static int dpkg_dounpack(package_t *pkg) | 558 | static 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 | } |
631 | end: | ||
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 |