aboutsummaryrefslogtreecommitdiff
path: root/archival/dpkg.c
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2006-08-03 15:41:12 +0000
committerRob Landley <rob@landley.net>2006-08-03 15:41:12 +0000
commitd921b2ecc0d294ad4bf8c7458fc52a60c28727d2 (patch)
treee4a2769349867c441cf2983d83097bb66701a733 /archival/dpkg.c
parent6dce0b6fa79f2d4bb7e9d90e1fbc0f6beb25f855 (diff)
downloadbusybox-w32-d921b2ecc0d294ad4bf8c7458fc52a60c28727d2.tar.gz
busybox-w32-d921b2ecc0d294ad4bf8c7458fc52a60c28727d2.tar.bz2
busybox-w32-d921b2ecc0d294ad4bf8c7458fc52a60c28727d2.zip
Remove bb_ prefixes from xfuncs.c (and a few other places), consolidate
things like xasprintf() into xfuncs.c, remove xprint_file_by_name() (it only had one user), clean up lots of #includes... General cleanup pass. What I've been doing for the last couple days. And it conflicts! I've removed httpd.c from this checkin due to somebody else touching that file. It builds for me. I have to catch a bus. (Now you know why I'm looking forward to Mercurial.)
Diffstat (limited to 'archival/dpkg.c')
-rw-r--r--archival/dpkg.c184
1 files changed, 133 insertions, 51 deletions
diff --git a/archival/dpkg.c b/archival/dpkg.c
index 558e3cd48..0e5772062 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -1,44 +1,39 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* 2/*
3 * Mini dpkg implementation for busybox. 3 * mini dpkg implementation for busybox.
4 * This is not meant as a replacement for dpkg 4 * this is not meant as a replacement for dpkg
5 * 5 *
6 * Written By Glenn McGrath with the help of others 6 * written by glenn mcgrath with the help of others
7 * Copyright (C) 2001 by Glenn McGrath 7 * copyright (c) 2001 by glenn mcgrath
8 * 8 *
9 * Started life as a busybox implementation of udpkg 9 * started life as a busybox implementation of udpkg
10 * 10 *
11 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 11 * licensed under gplv2 or later, see file license in this tarball for details.
12 */ 12 */
13 13
14/* 14/*
15 * Known difference between busybox dpkg and the official dpkg that i don't 15 * known difference between busybox dpkg and the official dpkg that i don't
16 * consider important, its worth keeping a note of differences anyway, just to 16 * consider important, its worth keeping a note of differences anyway, just to
17 * make it easier to maintain. 17 * make it easier to maintain.
18 * - The first value for the Confflile: field isnt placed on a new line. 18 * - the first value for the confflile: field isnt placed on a new line.
19 * - When installing a package the Status: field is placed at the end of the 19 * - when installing a package the status: field is placed at the end of the
20 * section, rather than just after the Package: field. 20 * section, rather than just after the package: field.
21 * 21 *
22 * Bugs that need to be fixed 22 * bugs that need to be fixed
23 * - (unknown, please let me know when you find any) 23 * - (unknown, please let me know when you find any)
24 * 24 *
25 */ 25 */
26 26
27#include <fcntl.h>
28#include <getopt.h>
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
32#include "unarchive.h"
33#include "busybox.h" 27#include "busybox.h"
28#include "unarchive.h"
34 29
35/* NOTE: If you vary HASH_PRIME sizes be aware, 30/* note: if you vary hash_prime sizes be aware,
36 * 1) Tweaking these will have a big effect on how much memory this program uses. 31 * 1) tweaking these will have a big effect on how much memory this program uses.
37 * 2) For computational efficiency these hash tables should be at least 20% 32 * 2) for computational efficiency these hash tables should be at least 20%
38 * larger than the maximum number of elements stored in it. 33 * larger than the maximum number of elements stored in it.
39 * 3) All _HASH_PRIME's must be a prime number or chaos is assured, if your looking 34 * 3) all _hash_prime's must be a prime number or chaos is assured, if your looking
40 * for a prime, try http://www.utm.edu/research/primes/lists/small/10000.txt 35 * for a prime, try http://www.utm.edu/research/primes/lists/small/10000.txt
41 * 4) If you go bigger than 15 bits you may get into trouble (untested) as its 36 * 4) if you go bigger than 15 bits you may get into trouble (untested) as its
42 * sometimes cast to an unsigned int, if you go to 16 bit you will overlap 37 * sometimes cast to an unsigned int, if you go to 16 bit you will overlap
43 * int's and chaos is assured, 16381 is the max prime for 14 bit field 38 * int's and chaos is assured, 16381 is the max prime for 14 bit field
44 */ 39 */
@@ -163,7 +158,7 @@ static int search_name_hashtable(const char *key)
163 } 158 }
164 } 159 }
165 } 160 }
166 name_hashtable[probe_address] = bb_xstrdup(key); 161 name_hashtable[probe_address] = xstrdup(key);
167 return(probe_address); 162 return(probe_address);
168} 163}
169 164
@@ -204,10 +199,10 @@ static int version_compare_part(const char *version1, const char *version2)
204 int ret; 199 int ret;
205 200
206 if (version1 == NULL) { 201 if (version1 == NULL) {
207 version1 = bb_xstrdup(""); 202 version1 = xstrdup("");
208 } 203 }
209 if (version2 == NULL) { 204 if (version2 == NULL) {
210 version2 = bb_xstrdup(""); 205 version2 = xstrdup("");
211 } 206 }
212 upstream_len1 = strlen(version1); 207 upstream_len1 = strlen(version1);
213 upstream_len2 = strlen(version2); 208 upstream_len2 = strlen(version2);
@@ -215,10 +210,10 @@ static int version_compare_part(const char *version1, const char *version2)
215 while ((len1 < upstream_len1) || (len2 < upstream_len2)) { 210 while ((len1 < upstream_len1) || (len2 < upstream_len2)) {
216 /* Compare non-digit section */ 211 /* Compare non-digit section */
217 tmp_int = strcspn(&version1[len1], "0123456789"); 212 tmp_int = strcspn(&version1[len1], "0123456789");
218 name1_char = bb_xstrndup(&version1[len1], tmp_int); 213 name1_char = xstrndup(&version1[len1], tmp_int);
219 len1 += tmp_int; 214 len1 += tmp_int;
220 tmp_int = strcspn(&version2[len2], "0123456789"); 215 tmp_int = strcspn(&version2[len2], "0123456789");
221 name2_char = bb_xstrndup(&version2[len2], tmp_int); 216 name2_char = xstrndup(&version2[len2], tmp_int);
222 len2 += tmp_int; 217 len2 += tmp_int;
223 tmp_int = strcmp(name1_char, name2_char); 218 tmp_int = strcmp(name1_char, name2_char);
224 free(name1_char); 219 free(name1_char);
@@ -230,10 +225,10 @@ static int version_compare_part(const char *version1, const char *version2)
230 225
231 /* Compare digits */ 226 /* Compare digits */
232 tmp_int = strspn(&version1[len1], "0123456789"); 227 tmp_int = strspn(&version1[len1], "0123456789");
233 name1_char = bb_xstrndup(&version1[len1], tmp_int); 228 name1_char = xstrndup(&version1[len1], tmp_int);
234 len1 += tmp_int; 229 len1 += tmp_int;
235 tmp_int = strspn(&version2[len2], "0123456789"); 230 tmp_int = strspn(&version2[len2], "0123456789");
236 name2_char = bb_xstrndup(&version2[len2], tmp_int); 231 name2_char = xstrndup(&version2[len2], tmp_int);
237 len2 += tmp_int; 232 len2 += tmp_int;
238 ver_num1 = atoi(name1_char); 233 ver_num1 = atoi(name1_char);
239 ver_num2 = atoi(name2_char); 234 ver_num2 = atoi(name2_char);
@@ -292,8 +287,8 @@ static int version_compare(const unsigned int ver1, const unsigned int ver2)
292 } 287 }
293 288
294 /* Compare upstream version */ 289 /* Compare upstream version */
295 upstream_ver1 = bb_xstrdup(ver1_ptr); 290 upstream_ver1 = xstrdup(ver1_ptr);
296 upstream_ver2 = bb_xstrdup(ver2_ptr); 291 upstream_ver2 = xstrdup(ver2_ptr);
297 292
298 /* Chop off debian version, and store for later use */ 293 /* Chop off debian version, and store for later use */
299 deb_ver1 = strrchr(upstream_ver1, '-'); 294 deb_ver1 = strrchr(upstream_ver1, '-');
@@ -429,7 +424,7 @@ static void add_edge_to_node(common_node_t *node, edge_t *edge)
429 */ 424 */
430static void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned int edge_type) 425static void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned int edge_type)
431{ 426{
432 char *line = bb_xstrdup(whole_line); 427 char *line = xstrdup(whole_line);
433 char *line2; 428 char *line2;
434 char *line_ptr1 = NULL; 429 char *line_ptr1 = NULL;
435 char *line_ptr2 = NULL; 430 char *line_ptr2 = NULL;
@@ -444,7 +439,7 @@ static void add_split_dependencies(common_node_t *parent_node, const char *whole
444 do { 439 do {
445 /* skip leading spaces */ 440 /* skip leading spaces */
446 field += strspn(field, " "); 441 field += strspn(field, " ");
447 line2 = bb_xstrdup(field); 442 line2 = xstrdup(field);
448 field2 = strtok_r(line2, "|", &line_ptr2); 443 field2 = strtok_r(line2, "|", &line_ptr2);
449 if ( (edge_type == EDGE_DEPENDS || edge_type == EDGE_PRE_DEPENDS) && 444 if ( (edge_type == EDGE_DEPENDS || edge_type == EDGE_PRE_DEPENDS) &&
450 (strcmp(field, field2) != 0)) { 445 (strcmp(field, field2) != 0)) {
@@ -538,6 +533,93 @@ static void free_package(common_node_t *node)
538 } 533 }
539} 534}
540 535
536/*
537 * Gets the next package field from package_buffer, seperated into the field name
538 * and field value, it returns the int offset to the first character of the next field
539 */
540static int read_package_field(const char *package_buffer, char **field_name, char **field_value)
541{
542 int offset_name_start = 0;
543 int offset_name_end = 0;
544 int offset_value_start = 0;
545 int offset_value_end = 0;
546 int offset = 0;
547 int next_offset;
548 int name_length;
549 int value_length;
550 int exit_flag = FALSE;
551
552 if (package_buffer == NULL) {
553 *field_name = NULL;
554 *field_value = NULL;
555 return(-1);
556 }
557 while (1) {
558 next_offset = offset + 1;
559 switch (package_buffer[offset]) {
560 case('\0'):
561 exit_flag = TRUE;
562 break;
563 case(':'):
564 if (offset_name_end == 0) {
565 offset_name_end = offset;
566 offset_value_start = next_offset;
567 }
568 /* TODO: Name might still have trailing spaces if ':' isnt
569 * immediately after name */
570 break;
571 case('\n'):
572 /* TODO: The char next_offset may be out of bounds */
573 if (package_buffer[next_offset] != ' ') {
574 exit_flag = TRUE;
575 break;
576 }
577 case('\t'):
578 case(' '):
579 /* increment the value start point if its a just filler */
580 if (offset_name_start == offset) {
581 offset_name_start++;
582 }
583 if (offset_value_start == offset) {
584 offset_value_start++;
585 }
586 break;
587 }
588 if (exit_flag) {
589 /* Check that the names are valid */
590 offset_value_end = offset;
591 name_length = offset_name_end - offset_name_start;
592 value_length = offset_value_end - offset_value_start;
593 if (name_length == 0) {
594 break;
595 }
596 if ((name_length > 0) && (value_length > 0)) {
597 break;
598 }
599
600 /* If not valid, start fresh with next field */
601 exit_flag = FALSE;
602 offset_name_start = offset + 1;
603 offset_name_end = 0;
604 offset_value_start = offset + 1;
605 offset_value_end = offset + 1;
606 offset++;
607 }
608 offset++;
609 }
610 if (name_length == 0) {
611 *field_name = NULL;
612 } else {
613 *field_name = xstrndup(&package_buffer[offset_name_start], name_length);
614 }
615 if (value_length > 0) {
616 *field_value = xstrndup(&package_buffer[offset_value_start], value_length);
617 } else {
618 *field_value = NULL;
619 }
620 return(next_offset);
621}
622
541static unsigned int fill_package_struct(char *control_buffer) 623static unsigned int fill_package_struct(char *control_buffer)
542{ 624{
543 static const char *const field_names[] = { "Package", "Version", 625 static const char *const field_names[] = { "Package", "Version",
@@ -631,7 +713,7 @@ static unsigned int get_status(const unsigned int status_node, const int num)
631 status_string += strspn(status_string, " "); 713 status_string += strspn(status_string, " ");
632 } 714 }
633 len = strcspn(status_string, " \n\0"); 715 len = strcspn(status_string, " \n\0");
634 state_sub_string = bb_xstrndup(status_string, len); 716 state_sub_string = xstrndup(status_string, len);
635 state_sub_num = search_name_hashtable(state_sub_string); 717 state_sub_num = search_name_hashtable(state_sub_string);
636 free(state_sub_string); 718 free(state_sub_string);
637 return(state_sub_num); 719 return(state_sub_num);
@@ -666,7 +748,7 @@ static void set_status(const unsigned int status_node_num, const char *new_value
666 bb_error_msg_and_die("DEBUG ONLY: this shouldnt happen"); 748 bb_error_msg_and_die("DEBUG ONLY: this shouldnt happen");
667 } 749 }
668 750
669 new_status = bb_xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]); 751 new_status = xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]);
670 status_hashtable[status_node_num]->status = search_name_hashtable(new_status); 752 status_hashtable[status_node_num]->status = search_name_hashtable(new_status);
671 free(new_status); 753 free(new_status);
672 return; 754 return;
@@ -705,7 +787,7 @@ static void index_status_file(const char *filename)
705 status_node_t *status_node = NULL; 787 status_node_t *status_node = NULL;
706 unsigned int status_num; 788 unsigned int status_num;
707 789
708 status_file = bb_xfopen(filename, "r"); 790 status_file = xfopen(filename, "r");
709 while ((control_buffer = fgets_str(status_file, "\n\n")) != NULL) { 791 while ((control_buffer = fgets_str(status_file, "\n\n")) != NULL) {
710 const unsigned int package_num = fill_package_struct(control_buffer); 792 const unsigned int package_num = fill_package_struct(control_buffer);
711 if (package_num != -1) { 793 if (package_num != -1) {
@@ -715,7 +797,7 @@ static void index_status_file(const char *filename)
715 if (status_line != NULL) { 797 if (status_line != NULL) {
716 status_line += 7; 798 status_line += 7;
717 status_line += strspn(status_line, " \n\t"); 799 status_line += strspn(status_line, " \n\t");
718 status_line = bb_xstrndup(status_line, strcspn(status_line, "\n\0")); 800 status_line = xstrndup(status_line, strcspn(status_line, "\n\0"));
719 status_node->status = search_name_hashtable(status_line); 801 status_node->status = search_name_hashtable(status_line);
720 free(status_line); 802 free(status_line);
721 } 803 }
@@ -749,8 +831,8 @@ static void write_buffer_no_status(FILE *new_status_file, const char *control_bu
749/* This could do with a cleanup */ 831/* This could do with a cleanup */
750static void write_status_file(deb_file_t **deb_file) 832static void write_status_file(deb_file_t **deb_file)
751{ 833{
752 FILE *old_status_file = bb_xfopen("/var/lib/dpkg/status", "r"); 834 FILE *old_status_file = xfopen("/var/lib/dpkg/status", "r");
753 FILE *new_status_file = bb_xfopen("/var/lib/dpkg/status.udeb", "w"); 835 FILE *new_status_file = xfopen("/var/lib/dpkg/status.udeb", "w");
754 char *package_name; 836 char *package_name;
755 char *status_from_file; 837 char *status_from_file;
756 char *control_buffer = NULL; 838 char *control_buffer = NULL;
@@ -768,14 +850,14 @@ static void write_status_file(deb_file_t **deb_file)
768 850
769 tmp_string += 8; 851 tmp_string += 8;
770 tmp_string += strspn(tmp_string, " \n\t"); 852 tmp_string += strspn(tmp_string, " \n\t");
771 package_name = bb_xstrndup(tmp_string, strcspn(tmp_string, "\n\0")); 853 package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n\0"));
772 write_flag = FALSE; 854 write_flag = FALSE;
773 tmp_string = strstr(control_buffer, "Status:"); 855 tmp_string = strstr(control_buffer, "Status:");
774 if (tmp_string != NULL) { 856 if (tmp_string != NULL) {
775 /* Seperate the status value from the control buffer */ 857 /* Seperate the status value from the control buffer */
776 tmp_string += 7; 858 tmp_string += 7;
777 tmp_string += strspn(tmp_string, " \n\t"); 859 tmp_string += strspn(tmp_string, " \n\t");
778 status_from_file = bb_xstrndup(tmp_string, strcspn(tmp_string, "\n")); 860 status_from_file = xstrndup(tmp_string, strcspn(tmp_string, "\n"));
779 } else { 861 } else {
780 status_from_file = NULL; 862 status_from_file = NULL;
781 } 863 }
@@ -1181,7 +1263,7 @@ static int run_package_script(const char *package_name, const char *script_type)
1181 char *script_path; 1263 char *script_path;
1182 int result; 1264 int result;
1183 1265
1184 script_path = bb_xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type); 1266 script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type);
1185 1267
1186 /* If the file doesnt exist is isnt a fatal */ 1268 /* If the file doesnt exist is isnt a fatal */
1187 result = lstat(script_path, &path_stat) < 0 ? EXIT_SUCCESS : system(script_path); 1269 result = lstat(script_path, &path_stat) < 0 ? EXIT_SUCCESS : system(script_path);
@@ -1200,7 +1282,7 @@ static char **all_control_list(const char *package_name)
1200 /* Create a list of all /var/lib/dpkg/info/<package> files */ 1282 /* Create a list of all /var/lib/dpkg/info/<package> files */
1201 remove_files = xzalloc(sizeof(all_control_files)); 1283 remove_files = xzalloc(sizeof(all_control_files));
1202 while (all_control_files[i]) { 1284 while (all_control_files[i]) {
1203 remove_files[i] = bb_xasprintf("/var/lib/dpkg/info/%s.%s", package_name, all_control_files[i]); 1285 remove_files[i] = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, all_control_files[i]);
1204 i++; 1286 i++;
1205 } 1287 }
1206 1288
@@ -1296,8 +1378,8 @@ static void remove_package(const unsigned int package_num, int noisy)
1296 1378
1297 /* Create a list of files in /var/lib/dpkg/info/<package>.* to keep */ 1379 /* Create a list of files in /var/lib/dpkg/info/<package>.* to keep */
1298 exclude_files = xzalloc(sizeof(char*) * 3); 1380 exclude_files = xzalloc(sizeof(char*) * 3);
1299 exclude_files[0] = bb_xstrdup(conffile_name); 1381 exclude_files[0] = xstrdup(conffile_name);
1300 exclude_files[1] = bb_xasprintf("/var/lib/dpkg/info/%s.postrm", package_name); 1382 exclude_files[1] = xasprintf("/var/lib/dpkg/info/%s.postrm", package_name);
1301 1383
1302 /* Create a list of all /var/lib/dpkg/info/<package> files */ 1384 /* Create a list of all /var/lib/dpkg/info/<package> files */
1303 remove_files = all_control_list(package_name); 1385 remove_files = all_control_list(package_name);
@@ -1361,7 +1443,7 @@ static archive_handle_t *init_archive_deb_ar(const char *filename)
1361 /* Setup an ar archive handle that refers to the gzip sub archive */ 1443 /* Setup an ar archive handle that refers to the gzip sub archive */
1362 ar_handle = init_handle(); 1444 ar_handle = init_handle();
1363 ar_handle->filter = filter_accept_list_reassign; 1445 ar_handle->filter = filter_accept_list_reassign;
1364 ar_handle->src_fd = bb_xopen(filename, O_RDONLY); 1446 ar_handle->src_fd = xopen(filename, O_RDONLY);
1365 1447
1366 return(ar_handle); 1448 return(ar_handle);
1367} 1449}
@@ -1428,7 +1510,7 @@ static void data_extract_all_prefix(archive_handle_t *archive_handle)
1428 1510
1429 name_ptr += strspn(name_ptr, "./"); 1511 name_ptr += strspn(name_ptr, "./");
1430 if (name_ptr[0] != '\0') { 1512 if (name_ptr[0] != '\0') {
1431 archive_handle->file_header->name = bb_xasprintf("%s%s", archive_handle->buffer, name_ptr); 1513 archive_handle->file_header->name = xasprintf("%s%s", archive_handle->buffer, name_ptr);
1432 data_extract_all(archive_handle); 1514 data_extract_all(archive_handle);
1433 } 1515 }
1434 return; 1516 return;
@@ -1457,12 +1539,12 @@ static void unpack_package(deb_file_t *deb_file)
1457 } 1539 }
1458 1540
1459 /* Extract control.tar.gz to /var/lib/dpkg/info/<package>.filename */ 1541 /* Extract control.tar.gz to /var/lib/dpkg/info/<package>.filename */
1460 info_prefix = bb_xasprintf("/var/lib/dpkg/info/%s.", package_name); 1542 info_prefix = xasprintf("/var/lib/dpkg/info/%s.", package_name);
1461 archive_handle = init_archive_deb_ar(deb_file->filename); 1543 archive_handle = init_archive_deb_ar(deb_file->filename);
1462 init_archive_deb_control(archive_handle); 1544 init_archive_deb_control(archive_handle);
1463 1545
1464 while(all_control_files[i]) { 1546 while(all_control_files[i]) {
1465 char *c = bb_xasprintf("./%s", all_control_files[i]); 1547 char *c = xasprintf("./%s", all_control_files[i]);
1466 llist_add_to(&accept_list, c); 1548 llist_add_to(&accept_list, c);
1467 i++; 1549 i++;
1468 } 1550 }
@@ -1489,7 +1571,7 @@ static void unpack_package(deb_file_t *deb_file)
1489 1571
1490 /* Create the list file */ 1572 /* Create the list file */
1491 strcat(info_prefix, "list"); 1573 strcat(info_prefix, "list");
1492 out_stream = bb_xfopen(info_prefix, "w"); 1574 out_stream = xfopen(info_prefix, "w");
1493 while (archive_handle->sub_archive->passed) { 1575 while (archive_handle->sub_archive->passed) {
1494 /* the leading . has been stripped by data_extract_all_prefix already */ 1576 /* the leading . has been stripped by data_extract_all_prefix already */
1495 fputs(archive_handle->sub_archive->passed->data, out_stream); 1577 fputs(archive_handle->sub_archive->passed->data, out_stream);
@@ -1600,7 +1682,7 @@ int dpkg_main(int argc, char **argv)
1600 if (deb_file[deb_count]->control_file == NULL) { 1682 if (deb_file[deb_count]->control_file == NULL) {
1601 bb_error_msg_and_die("Couldnt extract control file"); 1683 bb_error_msg_and_die("Couldnt extract control file");
1602 } 1684 }
1603 deb_file[deb_count]->filename = bb_xstrdup(argv[optind]); 1685 deb_file[deb_count]->filename = xstrdup(argv[optind]);
1604 package_num = fill_package_struct(deb_file[deb_count]->control_file); 1686 package_num = fill_package_struct(deb_file[deb_count]->control_file);
1605 1687
1606 if (package_num == -1) { 1688 if (package_num == -1) {