1 /* pkg.c - the opkg package management system 2 3 Carl D. Worth 4 5 Copyright (C) 2001 University of Southern California 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2, or (at 10 your option) any later version. 11 12 This program is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 */ 17 18 #include <stdio.h> 19 #include <string.h> 20 #include <ctype.h> 21 #include <unistd.h> 22 #include <libgen.h> 23 24 #include "pkg.h" 25 26 #include "pkg_parse.h" 27 #include "pkg_extract.h" 28 #include "opkg_message.h" 29 #include "opkg_utils.h" 30 31 #include "libbb/libbb.h" 32 #include "sprintf_alloc.h" 33 #include "file_util.h" 34 #include "xsystem.h" 35 #include "opkg_conf.h" 36 37 typedef struct enum_map enum_map_t; 38 struct enum_map { 39 unsigned int value; 40 const char *str; 41 }; 42 43 static const enum_map_t pkg_state_want_map[] = { 44 {SW_UNKNOWN, "unknown"}, 45 {SW_INSTALL, "install"}, 46 {SW_DEINSTALL, "deinstall"}, 47 {SW_PURGE, "purge"} 48 }; 49 50 static const enum_map_t pkg_state_flag_map[] = { 51 {SF_OK, "ok"}, 52 {SF_REINSTREQ, "reinstreq"}, 53 {SF_HOLD, "hold"}, 54 {SF_REPLACE, "replace"}, 55 {SF_NOPRUNE, "noprune"}, 56 {SF_PREFER, "prefer"}, 57 {SF_OBSOLETE, "obsolete"}, 58 {SF_USER, "user"}, 59 }; 60 61 static const enum_map_t pkg_state_status_map[] = { 62 {SS_NOT_INSTALLED, "not-installed"}, 63 {SS_UNPACKED, "unpacked"}, 64 {SS_HALF_CONFIGURED, "half-configured"}, 65 {SS_INSTALLED, "installed"}, 66 {SS_HALF_INSTALLED, "half-installed"}, 67 {SS_CONFIG_FILES, "config-files"}, 68 {SS_POST_INST_FAILED, "post-inst-failed"}, 69 {SS_REMOVAL_FAILED, "removal-failed"} 70 }; 71 72 static void pkg_init(pkg_t * pkg) 73 { 74 pkg->name = NULL; 75 pkg->dest = NULL; 76 pkg->src = NULL; 77 pkg->state_want = SW_UNKNOWN; 78 pkg->state_flag = SF_OK; 79 pkg->state_status = SS_NOT_INSTALLED; 80 81 pkg->installed_files = NULL; 82 pkg->installed_files_ref_cnt = 0; 83 pkg->essential = 0; 84 pkg->provided_by_hand = 0; 85 86 pkg->arch_index = 0; 87 88 blob_buf_init(&pkg->blob, 0); 89 } 90 91 pkg_t *pkg_new(void) 92 { 93 pkg_t *pkg; 94 95 pkg = xcalloc(1, sizeof(pkg_t)); 96 pkg_init(pkg); 97 98 return pkg; 99 } 100 101 void *pkg_set_raw(pkg_t *pkg, int id, const void *val, size_t len) 102 { 103 int rem; 104 struct blob_attr *cur; 105 106 blob_for_each_attr(cur, pkg->blob.head, rem) { 107 if (blob_id(cur) == id) { 108 if (blob_len(cur) < len) { 109 fprintf(stderr, "ERROR: truncating field %d <%p> to %zu byte", 110 id, val, blob_len(cur)); 111 } 112 memcpy(blob_data(cur), val, blob_len(cur)); 113 return blob_data(cur); 114 } 115 } 116 117 cur = blob_put(&pkg->blob, id, val, len); 118 return cur ? blob_data(cur) : NULL; 119 } 120 121 void *pkg_get_raw(const pkg_t * pkg, int id) 122 { 123 int rem; 124 struct blob_attr *cur; 125 126 blob_for_each_attr(cur, pkg->blob.head, rem) 127 if (blob_id(cur) == id) 128 return blob_data(cur); 129 130 return NULL; 131 } 132 133 char *pkg_set_string(pkg_t *pkg, int id, const char *s) 134 { 135 size_t len; 136 char *p; 137 138 if (!s) 139 return NULL; 140 141 len = strlen(s); 142 143 while (isspace(*s)) { 144 s++; 145 len--; 146 } 147 148 while (len > 0 && isspace(s[len - 1])) 149 len--; 150 151 if (!len) 152 return NULL; 153 154 p = pkg_set_raw(pkg, id, s, len + 1); 155 p[len] = 0; 156 157 return p; 158 } 159 160 char *pkg_get_architecture(const pkg_t *pkg) 161 { 162 nv_pair_list_elt_t *l; 163 int n = 1; 164 165 list_for_each_entry(l, &conf->arch_list.head, node) { 166 nv_pair_t *nv = (nv_pair_t *) l->data; 167 if (n++ == pkg->arch_index) 168 return nv->name; 169 } 170 171 return NULL; 172 } 173 174 char *pkg_set_architecture(pkg_t *pkg, const char *architecture, ssize_t len) 175 { 176 nv_pair_list_elt_t *l; 177 int n = 1; 178 179 list_for_each_entry(l, &conf->arch_list.head, node) { 180 nv_pair_t *nv = (nv_pair_t *) l->data; 181 182 if (!strncmp(nv->name, architecture, len) && nv->name[len] == '\0') { 183 if (n >= 8) { 184 opkg_msg(ERROR, "Internal error: too many different architectures\n"); 185 break; 186 } 187 188 pkg->arch_index = n; 189 return nv->name; 190 } 191 192 n++; 193 } 194 195 pkg->arch_index = 0; 196 return NULL; 197 } 198 199 int pkg_get_arch_priority(const pkg_t *pkg) 200 { 201 nv_pair_list_elt_t *l; 202 int n = 1; 203 204 list_for_each_entry(l, &conf->arch_list.head, node) { 205 nv_pair_t *nv = (nv_pair_t *) l->data; 206 if (n++ == pkg->arch_index) 207 return strtol(nv->value, NULL, 0); 208 } 209 210 return 0; 211 } 212 213 char *pkg_get_md5(const pkg_t *pkg) 214 { 215 char *p = pkg_get_raw(pkg, PKG_MD5SUM); 216 217 if (!p) 218 return NULL; 219 220 return checksum_bin2hex(p, 16); 221 } 222 223 char *pkg_set_md5(pkg_t *pkg, const char *cksum) 224 { 225 size_t len; 226 char *p = checksum_hex2bin(cksum, &len); 227 228 if (!p || len != 16) 229 return NULL; 230 231 return pkg_set_raw(pkg, PKG_MD5SUM, p, len); 232 } 233 234 char *pkg_get_sha256(const pkg_t *pkg) 235 { 236 char *p = pkg_get_raw(pkg, PKG_SHA256SUM); 237 238 if (!p) 239 return NULL; 240 241 return checksum_bin2hex(p, 32); 242 } 243 244 char *pkg_set_sha256(pkg_t *pkg, const char *cksum) 245 { 246 size_t len; 247 char *p = checksum_hex2bin(cksum, &len); 248 249 if (!p || len != 32) 250 return NULL; 251 252 return pkg_set_raw(pkg, PKG_SHA256SUM, p, len); 253 } 254 255 256 static void compound_depend_deinit(compound_depend_t * depends) 257 { 258 int i; 259 for (i = 0; i < depends->possibility_count; i++) { 260 depend_t *d; 261 d = depends->possibilities[i]; 262 free(d->version); 263 free(d); 264 } 265 free(depends->possibilities); 266 } 267 268 void pkg_deinit(pkg_t * pkg) 269 { 270 int rem; 271 struct blob_attr *cur; 272 compound_depend_t *deps, *dep; 273 void *ptr; 274 275 if (pkg->name) 276 free(pkg->name); 277 pkg->name = NULL; 278 279 /* owned by opkg_conf_t */ 280 pkg->dest = NULL; 281 /* owned by opkg_conf_t */ 282 pkg->src = NULL; 283 284 pkg->state_want = SW_UNKNOWN; 285 pkg->state_flag = SF_OK; 286 pkg->state_status = SS_NOT_INSTALLED; 287 288 blob_for_each_attr(cur, pkg->blob.head, rem) { 289 switch (blob_id(cur)) { 290 case PKG_DEPENDS: 291 case PKG_CONFLICTS: 292 deps = pkg_get_ptr(pkg, blob_id(cur)); 293 294 if (deps) { 295 for (dep = deps; dep->type; dep++) 296 compound_depend_deinit(dep); 297 298 free(deps); 299 } 300 301 pkg_set_ptr(pkg, blob_id(cur), NULL); 302 break; 303 304 case PKG_REPLACES: 305 case PKG_PROVIDES: 306 ptr = pkg_get_ptr(pkg, blob_id(cur)); 307 308 if (ptr) 309 free(ptr); 310 311 pkg_set_ptr(pkg, blob_id(cur), NULL); 312 break; 313 314 case PKG_CONFFILES: 315 ptr = pkg_get_ptr(pkg, blob_id(cur)); 316 317 if (ptr) { 318 conffile_list_deinit(ptr); 319 free(ptr); 320 } 321 322 pkg_set_ptr(pkg, blob_id(cur), NULL); 323 break; 324 case PKG_ALTERNATIVES: 325 ptr = pkg_get_ptr(pkg, blob_id(cur)); 326 327 if (ptr) { 328 struct pkg_alternatives *pkg_alts = ptr; 329 330 while (pkg_alts->nalts) 331 free(pkg_alts->alts[--pkg_alts->nalts]); 332 free(pkg_alts->alts); 333 free(pkg_alts); 334 } 335 336 pkg_set_ptr(pkg, blob_id(cur), NULL); 337 break; 338 } 339 } 340 341 //conffile_list_deinit(&pkg->conffiles); 342 343 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so, 344 since if they are calling deinit, they should know. Maybe do an 345 assertion here instead? */ 346 pkg->installed_files_ref_cnt = 1; 347 pkg_free_installed_files(pkg); 348 pkg->essential = 0; 349 350 blob_buf_free(&pkg->blob); 351 } 352 353 int pkg_init_from_file(pkg_t * pkg, const char *filename) 354 { 355 int fd, err = 0; 356 FILE *control_file; 357 char *control_path, *tmp; 358 359 pkg_init(pkg); 360 361 if (!(pkg->state_flag & SF_NEED_DETAIL)) { 362 opkg_msg(DEBUG, "applying abpkg flag to %s\n", filename); 363 pkg->state_flag |= SF_NEED_DETAIL; 364 } 365 366 pkg_set_string(pkg, PKG_LOCAL_FILENAME, filename); 367 368 tmp = xstrdup(filename); 369 sprintf_alloc(&control_path, "%s/%s.control.XXXXXX", 370 conf->tmp_dir, basename(tmp)); 371 free(tmp); 372 fd = mkstemp(control_path); 373 if (fd == -1) { 374 opkg_perror(ERROR, "Failed to make temp file %s", control_path); 375 err = -1; 376 goto err0; 377 } 378 379 control_file = fdopen(fd, "r+"); 380 if (control_file == NULL) { 381 opkg_perror(ERROR, "Failed to fdopen %s", control_path); 382 close(fd); 383 err = -1; 384 goto err1; 385 } 386 387 err = pkg_extract_control_file_to_stream(pkg, control_file); 388 if (err) { 389 opkg_msg(ERROR, "Failed to extract control file from %s.\n", 390 filename); 391 goto err2; 392 } 393 394 rewind(control_file); 395 396 if ((err = pkg_parse_from_stream(pkg, control_file, 0))) { 397 if (err == 1) { 398 opkg_msg(ERROR, "Malformed package file %s.\n", 399 filename); 400 } 401 err = -1; 402 } 403 404 err2: 405 fclose(control_file); 406 err1: 407 unlink(control_path); 408 err0: 409 free(control_path); 410 411 return err; 412 } 413 414 /* Merge any new information in newpkg into oldpkg */ 415 int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg) 416 { 417 abstract_pkg_t **ab; 418 419 if (oldpkg == newpkg) { 420 return 0; 421 } 422 423 if (!oldpkg->auto_installed) 424 oldpkg->auto_installed = newpkg->auto_installed; 425 426 if (!oldpkg->src) 427 oldpkg->src = newpkg->src; 428 if (!oldpkg->dest) 429 oldpkg->dest = newpkg->dest; 430 if (!oldpkg->arch_index) 431 oldpkg->arch_index = newpkg->arch_index; 432 if (!pkg_get_string(oldpkg, PKG_SECTION)) 433 pkg_set_string(oldpkg, PKG_SECTION, pkg_get_string(newpkg, PKG_SECTION)); 434 if (!pkg_get_string(oldpkg, PKG_MAINTAINER)) 435 pkg_set_string(oldpkg, PKG_MAINTAINER, pkg_get_string(newpkg, PKG_MAINTAINER)); 436 if (!pkg_get_string(oldpkg, PKG_DESCRIPTION)) 437 pkg_set_string(oldpkg, PKG_DESCRIPTION, pkg_get_string(newpkg, PKG_DESCRIPTION)); 438 439 if (!pkg_get_ptr(oldpkg, PKG_DEPENDS)) { 440 pkg_set_ptr(oldpkg, PKG_DEPENDS, pkg_get_ptr(newpkg, PKG_DEPENDS)); 441 pkg_set_ptr(newpkg, PKG_DEPENDS, NULL); 442 } 443 444 ab = pkg_get_ptr(oldpkg, PKG_PROVIDES); 445 446 if (!ab || !ab[0] || !ab[1]) { 447 pkg_set_ptr(oldpkg, PKG_PROVIDES, pkg_get_ptr(newpkg, PKG_PROVIDES)); 448 pkg_set_ptr(newpkg, PKG_PROVIDES, NULL); 449 450 if (ab) 451 free(ab); 452 } 453 454 if (!pkg_get_ptr(oldpkg, PKG_CONFLICTS)) { 455 pkg_set_ptr(oldpkg, PKG_CONFLICTS, pkg_get_ptr(newpkg, PKG_CONFLICTS)); 456 pkg_set_ptr(newpkg, PKG_CONFLICTS, NULL); 457 } 458 459 if (!pkg_get_ptr(oldpkg, PKG_REPLACES)) { 460 pkg_set_ptr(oldpkg, PKG_REPLACES, pkg_get_ptr(newpkg, PKG_REPLACES)); 461 pkg_set_ptr(newpkg, PKG_REPLACES, NULL); 462 } 463 464 if (!pkg_get_string(oldpkg, PKG_FILENAME)) 465 pkg_set_string(oldpkg, PKG_FILENAME, pkg_get_string(newpkg, PKG_FILENAME)); 466 if (!pkg_get_string(oldpkg, PKG_LOCAL_FILENAME)) 467 pkg_set_string(oldpkg, PKG_LOCAL_FILENAME, pkg_get_string(newpkg, PKG_LOCAL_FILENAME)); 468 if (!pkg_get_string(oldpkg, PKG_TMP_UNPACK_DIR)) 469 pkg_set_string(oldpkg, PKG_TMP_UNPACK_DIR, pkg_get_string(newpkg, PKG_TMP_UNPACK_DIR)); 470 if (!pkg_get_md5(oldpkg)) 471 pkg_set_md5(oldpkg, pkg_get_md5(newpkg)); 472 if (!pkg_get_sha256(oldpkg)) 473 pkg_set_sha256(oldpkg, pkg_get_sha256(newpkg)); 474 if (!pkg_get_int(oldpkg, PKG_SIZE)) 475 pkg_set_int(oldpkg, PKG_SIZE, pkg_get_int(newpkg, PKG_SIZE)); 476 if (!pkg_get_int(oldpkg, PKG_INSTALLED_SIZE)) 477 pkg_set_int(oldpkg, PKG_INSTALLED_SIZE, pkg_get_int(newpkg, PKG_INSTALLED_SIZE)); 478 if (!pkg_get_string(oldpkg, PKG_PRIORITY)) 479 pkg_set_string(oldpkg, PKG_PRIORITY, pkg_get_string(newpkg, PKG_PRIORITY)); 480 if (!pkg_get_string(oldpkg, PKG_SOURCE)) 481 pkg_set_string(oldpkg, PKG_SOURCE, pkg_get_string(newpkg, PKG_SOURCE)); 482 if (!pkg_get_string(oldpkg, PKG_ABIVERSION)) 483 pkg_set_string(oldpkg, PKG_ABIVERSION, pkg_get_string(newpkg, PKG_ABIVERSION)); 484 485 if (!pkg_get_ptr(oldpkg, PKG_CONFFILES)) { 486 pkg_set_ptr(oldpkg, PKG_CONFFILES, pkg_get_ptr(newpkg, PKG_CONFFILES)); 487 pkg_set_ptr(newpkg, PKG_CONFFILES, NULL); 488 } 489 490 if (!oldpkg->installed_files) { 491 oldpkg->installed_files = newpkg->installed_files; 492 oldpkg->installed_files_ref_cnt = 493 newpkg->installed_files_ref_cnt; 494 newpkg->installed_files = NULL; 495 } 496 497 if (!oldpkg->essential) 498 oldpkg->essential = newpkg->essential; 499 500 if (!oldpkg->provided_by_hand) 501 oldpkg->provided_by_hand = newpkg->provided_by_hand; 502 503 return 0; 504 } 505 506 static void abstract_pkg_init(abstract_pkg_t * ab_pkg) 507 { 508 ab_pkg->provided_by = abstract_pkg_vec_alloc(); 509 ab_pkg->dependencies_checked = 0; 510 ab_pkg->state_status = SS_NOT_INSTALLED; 511 } 512 513 abstract_pkg_t *abstract_pkg_new(void) 514 { 515 abstract_pkg_t *ab_pkg; 516 517 ab_pkg = xcalloc(1, sizeof(abstract_pkg_t)); 518 abstract_pkg_init(ab_pkg); 519 520 return ab_pkg; 521 } 522 523 static const char *pkg_state_want_to_str(pkg_state_want_t sw) 524 { 525 int i; 526 527 for (i = 0; i < ARRAY_SIZE(pkg_state_want_map); i++) { 528 if (pkg_state_want_map[i].value == sw) { 529 return pkg_state_want_map[i].str; 530 } 531 } 532 533 opkg_msg(ERROR, "Internal error: state_want=%d\n", sw); 534 return "<STATE_WANT_UNKNOWN>"; 535 } 536 537 pkg_state_want_t pkg_state_want_from_str(char *str) 538 { 539 int i; 540 541 for (i = 0; i < ARRAY_SIZE(pkg_state_want_map); i++) { 542 if (strcmp(str, pkg_state_want_map[i].str) == 0) { 543 return pkg_state_want_map[i].value; 544 } 545 } 546 547 opkg_msg(ERROR, "Internal error: state_want=%s\n", str); 548 return SW_UNKNOWN; 549 } 550 551 static char *pkg_state_flag_to_str(pkg_state_flag_t sf) 552 { 553 int i; 554 unsigned int len; 555 char *str; 556 557 /* clear the temporary flags before converting to string */ 558 sf &= SF_NONVOLATILE_FLAGS; 559 560 if (sf == 0) 561 return xstrdup("ok"); 562 563 len = 0; 564 for (i = 0; i < ARRAY_SIZE(pkg_state_flag_map); i++) { 565 if (sf & pkg_state_flag_map[i].value) 566 len += strlen(pkg_state_flag_map[i].str) + 1; 567 } 568 569 str = xmalloc(len + 1); 570 str[0] = '\0'; 571 572 for (i = 0; i < ARRAY_SIZE(pkg_state_flag_map); i++) { 573 if (sf & pkg_state_flag_map[i].value) { 574 strncat(str, pkg_state_flag_map[i].str, len); 575 strncat(str, ",", len); 576 } 577 } 578 579 len = strlen(str); 580 str[len - 1] = '\0'; /* squash last comma */ 581 582 return str; 583 } 584 585 pkg_state_flag_t pkg_state_flag_from_str(const char *str) 586 { 587 int i; 588 int sf = SF_OK; 589 const char *sfname; 590 unsigned int sfname_len; 591 592 if (strcmp(str, "ok") == 0) { 593 return SF_OK; 594 } 595 for (i = 0; i < ARRAY_SIZE(pkg_state_flag_map); i++) { 596 sfname = pkg_state_flag_map[i].str; 597 sfname_len = strlen(sfname); 598 if (strncmp(str, sfname, sfname_len) == 0) { 599 sf |= pkg_state_flag_map[i].value; 600 str += sfname_len; 601 if (str[0] == ',') { 602 str++; 603 } else { 604 break; 605 } 606 } 607 } 608 609 return sf; 610 } 611 612 static const char *pkg_state_status_to_str(pkg_state_status_t ss) 613 { 614 int i; 615 616 for (i = 0; i < ARRAY_SIZE(pkg_state_status_map); i++) { 617 if (pkg_state_status_map[i].value == ss) { 618 return pkg_state_status_map[i].str; 619 } 620 } 621 622 opkg_msg(ERROR, "Internal error: state_status=%d\n", ss); 623 return "<STATE_STATUS_UNKNOWN>"; 624 } 625 626 pkg_state_status_t pkg_state_status_from_str(const char *str) 627 { 628 int i; 629 630 for (i = 0; i < ARRAY_SIZE(pkg_state_status_map); i++) { 631 if (strcmp(str, pkg_state_status_map[i].str) == 0) { 632 return pkg_state_status_map[i].value; 633 } 634 } 635 636 opkg_msg(ERROR, "Internal error: state_status=%s\n", str); 637 return SS_NOT_INSTALLED; 638 } 639 640 void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field) 641 { 642 int i, j; 643 char *str; 644 const char *p; 645 compound_depend_t *dep; 646 abstract_pkg_t **ab_pkg; 647 648 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) { 649 goto UNKNOWN_FMT_FIELD; 650 } 651 652 switch (field[0]) { 653 case 'a': 654 case 'A': 655 if (strcasecmp(field, "ABIVersion") == 0) { 656 p = pkg_get_string(pkg, PKG_ABIVERSION); 657 if (p) { 658 fprintf(fp, "ABIVersion: %s\n", p); 659 } 660 } else if (strcasecmp(field, "Alternatives") == 0) { 661 struct pkg_alternatives *pkg_alts = pkg_get_ptr(pkg, PKG_ALTERNATIVES); 662 663 if (pkg_alts && pkg_alts->nalts > 0) { 664 int i; 665 struct pkg_alternative *alt; 666 667 alt = pkg_alts->alts[0]; 668 fprintf(fp, "Alternatives: %d:%s:%s", alt->prio, alt->path, alt->altpath); 669 for (i = 1; i < pkg_alts->nalts; i++) { 670 alt = pkg_alts->alts[i]; 671 fprintf(fp, ", %d:%s:%s", alt->prio, alt->path, alt->altpath); 672 } 673 fputs("\n", fp); 674 } 675 } else if (strcasecmp(field, "Architecture") == 0) { 676 p = pkg_get_architecture(pkg); 677 if (p) { 678 fprintf(fp, "Architecture: %s\n", 679 p); 680 } 681 } else if (strcasecmp(field, "Auto-Installed") == 0) { 682 if (pkg->auto_installed) 683 fprintf(fp, "Auto-Installed: yes\n"); 684 } else { 685 goto UNKNOWN_FMT_FIELD; 686 } 687 break; 688 case 'c': 689 case 'C': 690 if (strcasecmp(field, "Conffiles") == 0) { 691 conffile_list_t *cl; 692 conffile_list_elt_t *iter; 693 694 cl = pkg_get_ptr(pkg, PKG_CONFFILES); 695 696 if (!cl || nv_pair_list_empty(cl)) 697 return; 698 699 fprintf(fp, "Conffiles:\n"); 700 for (iter = nv_pair_list_first(cl); iter; 701 iter = nv_pair_list_next(cl, iter)) { 702 if (((conffile_t *) iter->data)->name 703 && ((conffile_t *) iter->data)->value) { 704 fprintf(fp, " %s %s\n", 705 ((conffile_t *) iter->data)-> 706 name, 707 ((conffile_t *) iter->data)-> 708 value); 709 } 710 } 711 } else if (strcasecmp(field, "Conflicts") == 0) { 712 struct depend *cdep; 713 compound_depend_t *deps, *dep; 714 deps = pkg_get_ptr(pkg, PKG_CONFLICTS); 715 if (deps) { 716 fprintf(fp, "Conflicts:"); 717 for (i = 0, dep = deps; dep->type; dep++, i++) { 718 cdep = dep->possibilities[0]; 719 fprintf(fp, "%s %s", i == 0 ? "" : ",", 720 cdep->pkg->name); 721 if (cdep->version) { 722 fprintf(fp, " (%s%s)", 723 constraint_to_str(cdep-> 724 constraint), 725 cdep->version); 726 } 727 } 728 fprintf(fp, "\n"); 729 } 730 } else { 731 goto UNKNOWN_FMT_FIELD; 732 } 733 break; 734 case 'd': 735 case 'D': 736 if (strcasecmp(field, "Depends") == 0) { 737 dep = pkg_get_depends(pkg, DEPEND); 738 if (dep) { 739 fprintf(fp, "Depends:"); 740 for (i = 0, j = 0; dep && dep->type; i++, dep++) { 741 if (dep->type != DEPEND) 742 continue; 743 str = pkg_depend_str(pkg, i); 744 fprintf(fp, "%s %s", j == 0 ? "" : ",", 745 str); 746 free(str); 747 j++; 748 } 749 fprintf(fp, "\n"); 750 } 751 } else if (strcasecmp(field, "Description") == 0) { 752 p = pkg_get_string(pkg, PKG_DESCRIPTION); 753 if (p) { 754 fprintf(fp, "Description: %s\n", 755 p); 756 } 757 } else { 758 goto UNKNOWN_FMT_FIELD; 759 } 760 break; 761 case 'e': 762 case 'E': 763 if (pkg->essential) { 764 fprintf(fp, "Essential: yes\n"); 765 } 766 break; 767 case 'f': 768 case 'F': 769 p = pkg_get_string(pkg, PKG_FILENAME); 770 if (p) { 771 fprintf(fp, "Filename: %s\n", p); 772 } 773 break; 774 case 'i': 775 case 'I': 776 if (strcasecmp(field, "Installed-Size") == 0) { 777 fprintf(fp, "Installed-Size: %lu\n", 778 (unsigned long) pkg_get_int(pkg, PKG_INSTALLED_SIZE)); 779 } else if (strcasecmp(field, "Installed-Time") == 0) { 780 i = pkg_get_int(pkg, PKG_INSTALLED_TIME); 781 if (i) { 782 fprintf(fp, "Installed-Time: %lu\n", 783 (unsigned long) i); 784 } 785 } 786 break; 787 case 'm': 788 case 'M': 789 if (strcasecmp(field, "Maintainer") == 0) { 790 p = pkg_get_string(pkg, PKG_MAINTAINER); 791 if (p) { 792 fprintf(fp, "Maintainer: %s\n", p); 793 } 794 } else if (strcasecmp(field, "MD5sum") == 0) { 795 p = pkg_get_md5(pkg); 796 if (p) { 797 fprintf(fp, "MD5Sum: %s\n", p); 798 } 799 } else { 800 goto UNKNOWN_FMT_FIELD; 801 } 802 break; 803 case 'p': 804 case 'P': 805 if (strcasecmp(field, "Package") == 0) { 806 fprintf(fp, "Package: %s\n", pkg->name); 807 } else if (strcasecmp(field, "Priority") == 0) { 808 fprintf(fp, "Priority: %s\n", pkg_get_string(pkg, PKG_PRIORITY)); 809 } else if (strcasecmp(field, "Provides") == 0) { 810 ab_pkg = pkg_get_ptr(pkg, PKG_PROVIDES); 811 if (ab_pkg && ab_pkg[0] && ab_pkg[1]) { 812 fprintf(fp, "Provides:"); 813 for (i = 1; ab_pkg[i]; i++) { 814 fprintf(fp, "%s %s", i == 1 ? "" : ",", 815 ab_pkg[i]->name); 816 } 817 fprintf(fp, "\n"); 818 } 819 } else { 820 goto UNKNOWN_FMT_FIELD; 821 } 822 break; 823 case 'r': 824 case 'R': 825 if (strcasecmp(field, "Replaces") == 0) { 826 ab_pkg = pkg_get_ptr(pkg, PKG_REPLACES); 827 if (ab_pkg && ab_pkg[0]) { 828 fprintf(fp, "Replaces:"); 829 for (i = 0; ab_pkg[i]; i++) { 830 fprintf(fp, "%s %s", i == 0 ? "" : ",", 831 ab_pkg[i]->name); 832 } 833 fprintf(fp, "\n"); 834 } 835 } else if (strcasecmp(field, "Recommends") == 0) { 836 dep = pkg_get_depends(pkg, RECOMMEND); 837 if (dep) { 838 fprintf(fp, "Recommends:"); 839 for (j = 0, i = 0; dep && dep->type; i++, dep++) { 840 if (dep->type != RECOMMEND) 841 continue; 842 str = pkg_depend_str(pkg, i); 843 fprintf(fp, "%s %s", j == 0 ? "" : ",", 844 str); 845 free(str); 846 j++; 847 } 848 fprintf(fp, "\n"); 849 } 850 } else { 851 goto UNKNOWN_FMT_FIELD; 852 } 853 break; 854 case 's': 855 case 'S': 856 if (strcasecmp(field, "Section") == 0) { 857 p = pkg_get_string(pkg, PKG_SECTION); 858 if (p) { 859 fprintf(fp, "Section: %s\n", p); 860 } 861 } else if (strcasecmp(field, "SHA256sum") == 0) { 862 p = pkg_get_string(pkg, PKG_SHA256SUM); 863 if (p) { 864 fprintf(fp, "SHA256sum: %s\n", p); 865 } 866 } else if (strcasecmp(field, "Size") == 0) { 867 i = pkg_get_int(pkg, PKG_SIZE); 868 if (i) { 869 fprintf(fp, "Size: %lu\n", (unsigned long) i); 870 } 871 } else if (strcasecmp(field, "Source") == 0) { 872 p = pkg_get_string(pkg, PKG_SOURCE); 873 if (p) { 874 fprintf(fp, "Source: %s\n", p); 875 } 876 } else if (strcasecmp(field, "Status") == 0) { 877 char *pflag = pkg_state_flag_to_str(pkg->state_flag); 878 fprintf(fp, "Status: %s %s %s\n", 879 pkg_state_want_to_str(pkg->state_want), 880 pflag, 881 pkg_state_status_to_str(pkg->state_status)); 882 free(pflag); 883 } else if (strcasecmp(field, "Suggests") == 0) { 884 dep = pkg_get_depends(pkg, SUGGEST); 885 if (dep) { 886 fprintf(fp, "Suggests:"); 887 for (j = 0, i = 0; dep && dep->type; i++, dep++) { 888 if (dep->type != SUGGEST) 889 continue; 890 str = pkg_depend_str(pkg, i); 891 fprintf(fp, "%s %s", j == 0 ? "" : ",", 892 str); 893 free(str); 894 j++; 895 } 896 fprintf(fp, "\n"); 897 } 898 } else { 899 goto UNKNOWN_FMT_FIELD; 900 } 901 break; 902 case 't': 903 case 'T': 904 if (strcasecmp(field, "Tags") == 0) { 905 p = pkg_get_string(pkg, PKG_TAGS); 906 if (p) { 907 fprintf(fp, "Tags: %s\n", p); 908 } 909 } 910 break; 911 case 'v': 912 case 'V': 913 { 914 char *version = pkg_version_str_alloc(pkg); 915 if (version == NULL) 916 return; 917 fprintf(fp, "Version: %s\n", version); 918 free(version); 919 } 920 break; 921 default: 922 goto UNKNOWN_FMT_FIELD; 923 } 924 925 return; 926 927 UNKNOWN_FMT_FIELD: 928 opkg_msg(ERROR, "Internal error: field=%s\n", field); 929 } 930 931 void pkg_formatted_info(FILE * fp, pkg_t * pkg) 932 { 933 pkg_formatted_field(fp, pkg, "Package"); 934 pkg_formatted_field(fp, pkg, "Version"); 935 pkg_formatted_field(fp, pkg, "Depends"); 936 pkg_formatted_field(fp, pkg, "Recommends"); 937 pkg_formatted_field(fp, pkg, "Suggests"); 938 pkg_formatted_field(fp, pkg, "Provides"); 939 pkg_formatted_field(fp, pkg, "Replaces"); 940 pkg_formatted_field(fp, pkg, "Conflicts"); 941 pkg_formatted_field(fp, pkg, "Status"); 942 pkg_formatted_field(fp, pkg, "Section"); 943 pkg_formatted_field(fp, pkg, "Essential"); 944 pkg_formatted_field(fp, pkg, "Architecture"); 945 pkg_formatted_field(fp, pkg, "Maintainer"); 946 pkg_formatted_field(fp, pkg, "MD5sum"); 947 pkg_formatted_field(fp, pkg, "Size"); 948 pkg_formatted_field(fp, pkg, "Filename"); 949 pkg_formatted_field(fp, pkg, "Conffiles"); 950 pkg_formatted_field(fp, pkg, "Source"); 951 pkg_formatted_field(fp, pkg, "Description"); 952 pkg_formatted_field(fp, pkg, "Installed-Time"); 953 pkg_formatted_field(fp, pkg, "Tags"); 954 fputs("\n", fp); 955 } 956 957 void pkg_print_status(pkg_t * pkg, FILE * file) 958 { 959 if (pkg == NULL) { 960 return; 961 } 962 963 pkg_formatted_field(file, pkg, "Package"); 964 pkg_formatted_field(file, pkg, "ABIVersion"); 965 pkg_formatted_field(file, pkg, "Version"); 966 pkg_formatted_field(file, pkg, "Depends"); 967 pkg_formatted_field(file, pkg, "Recommends"); 968 pkg_formatted_field(file, pkg, "Suggests"); 969 pkg_formatted_field(file, pkg, "Provides"); 970 pkg_formatted_field(file, pkg, "Replaces"); 971 pkg_formatted_field(file, pkg, "Conflicts"); 972 pkg_formatted_field(file, pkg, "Status"); 973 pkg_formatted_field(file, pkg, "Essential"); 974 pkg_formatted_field(file, pkg, "Architecture"); 975 pkg_formatted_field(file, pkg, "Conffiles"); 976 pkg_formatted_field(file, pkg, "Installed-Time"); 977 pkg_formatted_field(file, pkg, "Auto-Installed"); 978 pkg_formatted_field(file, pkg, "Alternatives"); 979 fputs("\n", file); 980 } 981 982 /* 983 * libdpkg - Debian packaging suite library routines 984 * vercmp.c - comparison of version numbers 985 * 986 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk> 987 */ 988 989 /* assume ascii; warning: evaluates x multiple times! */ 990 #define order(x) ((x) == '~' ? -1 \ 991 : isdigit((x)) ? 0 \ 992 : !(x) ? 0 \ 993 : isalpha((x)) ? (x) \ 994 : (x) + 256) 995 996 static int verrevcmp(const char *val, const char *ref) 997 { 998 if (!val) 999 val = ""; 1000 if (!ref) 1001 ref = ""; 1002 1003 while (*val || *ref) { 1004 int first_diff = 0; 1005 1006 while ((*val && !isdigit(*val)) || (*ref && !isdigit(*ref))) { 1007 int vc = order(*val), rc = order(*ref); 1008 if (vc != rc) 1009 return vc - rc; 1010 val++; 1011 ref++; 1012 } 1013 1014 while (*val == '') 1015 val++; 1016 while (*ref == '') 1017 ref++; 1018 while (isdigit(*val) && isdigit(*ref)) { 1019 if (!first_diff) 1020 first_diff = *val - *ref; 1021 val++; 1022 ref++; 1023 } 1024 if (isdigit(*val)) 1025 return 1; 1026 if (isdigit(*ref)) 1027 return -1; 1028 if (first_diff) 1029 return first_diff; 1030 } 1031 return 0; 1032 } 1033 1034 int pkg_compare_versions(const pkg_t * pkg, const pkg_t * ref_pkg) 1035 { 1036 unsigned int epoch1 = (unsigned int) pkg_get_int(pkg, PKG_EPOCH); 1037 unsigned int epoch2 = (unsigned int) pkg_get_int(ref_pkg, PKG_EPOCH); 1038 char *revision1 = pkg_get_string(pkg, PKG_REVISION); 1039 char *revision2 = pkg_get_string(ref_pkg, PKG_REVISION); 1040 const char *version1 = pkg_get_string(pkg, PKG_VERSION); 1041 const char *version2 = pkg_get_string(ref_pkg, PKG_VERSION); 1042 int r; 1043 1044 if (epoch1 > epoch2) { 1045 return 1; 1046 } 1047 1048 if (epoch1 < epoch2) { 1049 return -1; 1050 } 1051 1052 r = verrevcmp(version1, version2); 1053 if (r) { 1054 return r; 1055 } 1056 1057 r = verrevcmp(revision1, revision2); 1058 if (r) { 1059 return r; 1060 } 1061 1062 return r; 1063 } 1064 1065 int pkg_version_satisfied(pkg_t * it, pkg_t * ref, const char *op) 1066 { 1067 int r; 1068 1069 r = pkg_compare_versions(it, ref); 1070 1071 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) { 1072 return r <= 0; 1073 } 1074 1075 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) { 1076 return r >= 0; 1077 } 1078 1079 if (strcmp(op, "<<") == 0) { 1080 return r < 0; 1081 } 1082 1083 if (strcmp(op, ">>") == 0) { 1084 return r > 0; 1085 } 1086 1087 if (strcmp(op, "=") == 0) { 1088 return r == 0; 1089 } 1090 1091 opkg_msg(ERROR, "Unknown operator: %s.\n", op); 1092 return 0; 1093 } 1094 1095 int pkg_name_version_and_architecture_compare(const void *p1, const void *p2) 1096 { 1097 const pkg_t * a = *(const pkg_t **)p1; 1098 const pkg_t * b = *(const pkg_t **)p2; 1099 int namecmp; 1100 int vercmp; 1101 int arch_prio1, arch_prio2; 1102 if (!a->name || !b->name) { 1103 opkg_msg(ERROR, "Internal error: a->name=%p, b->name=%p.\n", 1104 a->name, b->name); 1105 return 0; 1106 } 1107 1108 namecmp = strcmp(a->name, b->name); 1109 if (namecmp) 1110 return namecmp; 1111 vercmp = pkg_compare_versions(a, b); 1112 if (vercmp) 1113 return vercmp; 1114 arch_prio1 = pkg_get_arch_priority(a); 1115 arch_prio2 = pkg_get_arch_priority(b); 1116 if (!arch_prio1 || !arch_prio2) { 1117 opkg_msg(ERROR, 1118 "Internal error: a->arch_priority=%i b->arch_priority=%i.\n", 1119 arch_prio1, arch_prio2); 1120 return 0; 1121 } 1122 if (arch_prio1 > arch_prio2) 1123 return 1; 1124 if (arch_prio1 < arch_prio2) 1125 return -1; 1126 return 0; 1127 } 1128 1129 int abstract_pkg_name_compare(const void *p1, const void *p2) 1130 { 1131 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1; 1132 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2; 1133 if (!a->name || !b->name) { 1134 opkg_msg(ERROR, "Internal error: a->name=%p b->name=%p.\n", 1135 a->name, b->name); 1136 return 0; 1137 } 1138 return strcmp(a->name, b->name); 1139 } 1140 1141 char *pkg_version_str_alloc(pkg_t * pkg) 1142 { 1143 const char *verstr; 1144 char *version, *revptr; 1145 unsigned int epoch = (unsigned int) pkg_get_int(pkg, PKG_EPOCH); 1146 1147 revptr = pkg_get_string(pkg, PKG_REVISION); 1148 verstr = pkg_get_string(pkg, PKG_VERSION); 1149 1150 if (epoch) { 1151 if (revptr) 1152 sprintf_alloc(&version, "%d:%s-%s", 1153 epoch, verstr, revptr); 1154 else 1155 sprintf_alloc(&version, "%d:%s", 1156 epoch, verstr); 1157 } else { 1158 if (revptr) 1159 sprintf_alloc(&version, "%s-%s", 1160 verstr, revptr); 1161 else 1162 version = xstrdup(verstr); 1163 } 1164 1165 return version; 1166 } 1167 1168 /* 1169 * XXX: this should be broken into two functions 1170 */ 1171 str_list_t *pkg_get_installed_files(pkg_t * pkg) 1172 { 1173 int err, fd; 1174 char *list_file_name = NULL; 1175 FILE *list_file = NULL; 1176 char *line; 1177 char *installed_file_name; 1178 unsigned int rootdirlen = 0; 1179 int list_from_package; 1180 const char *local_filename; 1181 1182 pkg->installed_files_ref_cnt++; 1183 1184 if (pkg->installed_files) { 1185 return pkg->installed_files; 1186 } 1187 1188 pkg->installed_files = str_list_alloc(); 1189 1190 /* 1191 * For installed packages, look at the package.list file in the database. 1192 * For uninstalled packages, get the file list directly from the package. 1193 */ 1194 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) 1195 list_from_package = 1; 1196 else 1197 list_from_package = 0; 1198 1199 if (list_from_package) { 1200 local_filename = pkg_get_string(pkg, PKG_LOCAL_FILENAME); 1201 1202 if (!local_filename) { 1203 return pkg->installed_files; 1204 } 1205 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary 1206 file. In other words, change deb_extract so that it can 1207 simply return the file list as a char *[] rather than 1208 insisting on writing it to a FILE * as it does now. */ 1209 sprintf_alloc(&list_file_name, "%s/%s.list.XXXXXX", 1210 conf->tmp_dir, pkg->name); 1211 fd = mkstemp(list_file_name); 1212 if (fd == -1) { 1213 opkg_perror(ERROR, "Failed to make temp file %s.", 1214 list_file_name); 1215 free(list_file_name); 1216 return pkg->installed_files; 1217 } 1218 list_file = fdopen(fd, "r+"); 1219 if (list_file == NULL) { 1220 opkg_perror(ERROR, "Failed to fdopen temp file %s.", 1221 list_file_name); 1222 close(fd); 1223 unlink(list_file_name); 1224 free(list_file_name); 1225 return pkg->installed_files; 1226 } 1227 err = pkg_extract_data_file_names_to_stream(pkg, list_file); 1228 if (err) { 1229 opkg_msg(ERROR, "Error extracting file list from %s.\n", 1230 local_filename); 1231 fclose(list_file); 1232 unlink(list_file_name); 1233 free(list_file_name); 1234 str_list_deinit(pkg->installed_files); 1235 pkg->installed_files = NULL; 1236 return NULL; 1237 } 1238 rewind(list_file); 1239 } else { 1240 sprintf_alloc(&list_file_name, "%s/%s.list", 1241 pkg->dest->info_dir, pkg->name); 1242 list_file = fopen(list_file_name, "r"); 1243 if (list_file == NULL) { 1244 opkg_perror(ERROR, "Failed to open %s", list_file_name); 1245 free(list_file_name); 1246 return pkg->installed_files; 1247 } 1248 free(list_file_name); 1249 } 1250 1251 if (conf->offline_root) 1252 rootdirlen = strlen(conf->offline_root); 1253 1254 while (1) { 1255 char *file_name; 1256 1257 line = file_read_line_alloc(list_file); 1258 if (line == NULL) { 1259 break; 1260 } 1261 file_name = line; 1262 1263 if (list_from_package) { 1264 if (*file_name == '.') { 1265 file_name++; 1266 } 1267 if (*file_name == '/') { 1268 file_name++; 1269 } 1270 sprintf_alloc(&installed_file_name, "%s%s", 1271 pkg->dest->root_dir, file_name); 1272 } else { 1273 if (conf->offline_root && 1274 strncmp(conf->offline_root, file_name, 1275 rootdirlen)) { 1276 sprintf_alloc(&installed_file_name, "%s%s", 1277 conf->offline_root, file_name); 1278 } else { 1279 // already contains root_dir as header -> ABSOLUTE 1280 sprintf_alloc(&installed_file_name, "%s", 1281 file_name); 1282 } 1283 } 1284 str_list_append(pkg->installed_files, installed_file_name); 1285 free(installed_file_name); 1286 free(line); 1287 } 1288 1289 fclose(list_file); 1290 1291 if (list_from_package) { 1292 unlink(list_file_name); 1293 free(list_file_name); 1294 } 1295 1296 return pkg->installed_files; 1297 } 1298 1299 /* XXX: CLEANUP: This function and it's counterpart, 1300 (pkg_get_installed_files), do not match our init/deinit naming 1301 convention. Nor the alloc/free convention. But, then again, neither 1302 of these conventions currrently fit the way these two functions 1303 work. */ 1304 void pkg_free_installed_files(pkg_t * pkg) 1305 { 1306 pkg->installed_files_ref_cnt--; 1307 1308 if (pkg->installed_files_ref_cnt > 0) 1309 return; 1310 1311 if (pkg->installed_files) { 1312 str_list_purge(pkg->installed_files); 1313 } 1314 1315 pkg->installed_files = NULL; 1316 } 1317 1318 void pkg_remove_installed_files_list(pkg_t * pkg) 1319 { 1320 char *list_file_name; 1321 1322 sprintf_alloc(&list_file_name, "%s/%s.list", 1323 pkg->dest->info_dir, pkg->name); 1324 1325 if (!conf->noaction) 1326 (void)unlink(list_file_name); 1327 1328 free(list_file_name); 1329 } 1330 1331 conffile_t *pkg_get_conffile(pkg_t * pkg, const char *file_name) 1332 { 1333 conffile_list_elt_t *iter; 1334 conffile_list_t *cl; 1335 conffile_t *conffile; 1336 1337 if (pkg == NULL) { 1338 return NULL; 1339 } 1340 1341 cl = pkg_get_ptr(pkg, PKG_CONFFILES); 1342 1343 for (iter = cl ? nv_pair_list_first(cl) : NULL; iter; 1344 iter = nv_pair_list_next(cl, iter)) { 1345 conffile = (conffile_t *) iter->data; 1346 1347 if (strcmp(conffile->name, file_name) == 0) { 1348 return conffile; 1349 } 1350 } 1351 1352 return NULL; 1353 } 1354 1355 int pkg_run_script(pkg_t * pkg, const char *script, const char *args) 1356 { 1357 int err; 1358 char *path; 1359 char *cmd; 1360 char *tmp_unpack_dir; 1361 1362 if (conf->noaction) 1363 return 0; 1364 1365 /* XXX: FEATURE: When conf->offline_root is set, we should run the 1366 maintainer script within a chroot environment. */ 1367 if (conf->offline_root && !conf->force_postinstall) { 1368 opkg_msg(INFO, "Offline root mode: not running %s.%s.\n", 1369 pkg->name, script); 1370 return 0; 1371 } 1372 1373 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages 1374 have scripts in tmp_unpack_dir. */ 1375 if (pkg->state_status == SS_INSTALLED 1376 || pkg->state_status == SS_UNPACKED 1377 || pkg->state_status == SS_HALF_INSTALLED) { 1378 if (pkg->dest == NULL) { 1379 opkg_msg(ERROR, "Internal error: %s has a NULL dest.\n", 1380 pkg->name); 1381 return -1; 1382 } 1383 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, 1384 script); 1385 } else { 1386 tmp_unpack_dir = pkg_get_string(pkg, PKG_TMP_UNPACK_DIR); 1387 if (tmp_unpack_dir == NULL) { 1388 opkg_msg(ERROR, 1389 "Internal error: %s has a NULL tmp_unpack_dir.\n", 1390 pkg->name); 1391 return -1; 1392 } 1393 sprintf_alloc(&path, "%s/%s", tmp_unpack_dir, script); 1394 } 1395 1396 opkg_msg(INFO, "Running script %s.\n", path); 1397 1398 setenv("PKG_ROOT", 1399 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1400 1); 1401 1402 if (pkg->is_upgrade) 1403 setenv("PKG_UPGRADE", "1", 1); 1404 else 1405 setenv("PKG_UPGRADE", "", 1); 1406 1407 if (!file_exists(path)) { 1408 free(path); 1409 return 0; 1410 } 1411 1412 sprintf_alloc(&cmd, "%s %s", path, args); 1413 free(path); 1414 { 1415 const char *argv[] = { "/bin/sh", "-c", cmd, NULL }; 1416 err = xsystem(argv); 1417 } 1418 free(cmd); 1419 1420 if (err) { 1421 opkg_msg(ERROR, 1422 "package \"%s\" %s script returned status %d.\n", 1423 pkg->name, script, err); 1424 return err; 1425 } 1426 1427 return 0; 1428 } 1429 1430 int pkg_arch_supported(pkg_t * pkg) 1431 { 1432 nv_pair_list_elt_t *l; 1433 char *architecture = pkg_get_architecture(pkg); 1434 1435 if (!architecture) 1436 return 1; 1437 1438 list_for_each_entry(l, &conf->arch_list.head, node) { 1439 nv_pair_t *nv = (nv_pair_t *) l->data; 1440 if (strcmp(nv->name, architecture) == 0) { 1441 opkg_msg(DEBUG, 1442 "Arch %s (priority %s) supported for pkg %s.\n", 1443 nv->name, nv->value, pkg->name); 1444 return 1; 1445 } 1446 } 1447 1448 opkg_msg(DEBUG, "Arch %s unsupported for pkg %s.\n", 1449 architecture, pkg->name); 1450 return 0; 1451 } 1452 1453 void pkg_info_preinstall_check(void) 1454 { 1455 int i; 1456 pkg_vec_t *installed_pkgs = pkg_vec_alloc(); 1457 1458 /* update the file owner data structure */ 1459 opkg_msg(INFO, "Updating file owner list.\n"); 1460 pkg_hash_fetch_all_installed(installed_pkgs); 1461 for (i = 0; i < installed_pkgs->len; i++) { 1462 pkg_t *pkg = installed_pkgs->pkgs[i]; 1463 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */ 1464 str_list_elt_t *iter, *niter; 1465 if (installed_files == NULL) { 1466 opkg_msg(ERROR, "Failed to determine installed " 1467 "files for pkg %s.\n", pkg->name); 1468 break; 1469 } 1470 for (iter = str_list_first(installed_files), niter = 1471 str_list_next(installed_files, iter); iter; 1472 iter = niter, niter = 1473 str_list_next(installed_files, iter)) { 1474 char *installed_file = (char *)iter->data; 1475 file_hash_set_file_owner(installed_file, pkg); 1476 } 1477 pkg_free_installed_files(pkg); 1478 } 1479 pkg_vec_free(installed_pkgs); 1480 } 1481 1482 struct pkg_write_filelist_data { 1483 pkg_t *pkg; 1484 FILE *stream; 1485 }; 1486 1487 static void 1488 pkg_write_filelist_helper(const char *key, void *entry_, void *data_) 1489 { 1490 struct pkg_write_filelist_data *data = data_; 1491 pkg_t *entry = entry_; 1492 if (entry == data->pkg) { 1493 fprintf(data->stream, "%s\n", key); 1494 } 1495 } 1496 1497 int pkg_write_filelist(pkg_t * pkg) 1498 { 1499 struct pkg_write_filelist_data data; 1500 char *list_file_name; 1501 1502 sprintf_alloc(&list_file_name, "%s/%s.list", 1503 pkg->dest->info_dir, pkg->name); 1504 1505 opkg_msg(INFO, "Creating %s file for pkg %s.\n", 1506 list_file_name, pkg->name); 1507 1508 data.stream = fopen(list_file_name, "w"); 1509 if (!data.stream) { 1510 opkg_perror(ERROR, "Failed to open %s", list_file_name); 1511 free(list_file_name); 1512 return -1; 1513 } 1514 1515 data.pkg = pkg; 1516 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data); 1517 fclose(data.stream); 1518 free(list_file_name); 1519 1520 pkg->state_flag &= ~SF_FILELIST_CHANGED; 1521 1522 return 0; 1523 } 1524 1525 int pkg_write_changed_filelists(void) 1526 { 1527 pkg_vec_t *installed_pkgs = pkg_vec_alloc(); 1528 int i, err, ret = 0; 1529 1530 if (conf->noaction) 1531 return 0; 1532 1533 opkg_msg(INFO, "Saving changed filelists.\n"); 1534 1535 pkg_hash_fetch_all_installed(installed_pkgs); 1536 for (i = 0; i < installed_pkgs->len; i++) { 1537 pkg_t *pkg = installed_pkgs->pkgs[i]; 1538 if (pkg->state_flag & SF_FILELIST_CHANGED) { 1539 err = pkg_write_filelist(pkg); 1540 if (err) 1541 ret = -1; 1542 } 1543 } 1544 1545 pkg_vec_free(installed_pkgs); 1546 1547 return ret; 1548 } 1549
This page was automatically generated by LXR 0.3.1. • OpenWrt