update busybox to v1.3.1, i was too lazy to update patch 320, feel free to do so
[openwrt/svn-archive/archive.git] / package / busybox / patches / 911-ipkg.patch
1 # Copyright (C) 2006 OpenWrt.org
2 #
3 # This is free software, licensed under the GNU General Public License v2.
4 # See /LICENSE for more information.
5 #
6 # add ipkg support to busybox
7 #
8 diff -ruN busybox-1.3.1-orig/archival/Config.in busybox-1.3.1-911/archival/Config.in
9 --- busybox-1.3.1-orig/archival/Config.in 2006-12-27 05:53:54.000000000 +0100
10 +++ busybox-1.3.1-911/archival/Config.in 2006-12-28 02:41:16.000000000 +0100
11 @@ -121,6 +121,14 @@
12 gzip is used to compress files.
13 It's probably the most widely used UNIX compression program.
14
15 +config IPKG
16 + bool "ipkg"
17 + default n
18 + select MD5SUM
19 + select WGET
20 + help
21 + ipkg is the itsy package management system.
22 +
23 config RPM2CPIO
24 bool "rpm2cpio"
25 default n
26 diff -ruN busybox-1.3.1-orig/archival/dpkg.c busybox-1.3.1-911/archival/dpkg.c
27 --- busybox-1.3.1-orig/archival/dpkg.c 2006-12-27 05:53:54.000000000 +0100
28 +++ busybox-1.3.1-911/archival/dpkg.c 2006-12-27 19:41:04.000000000 +0100
29 @@ -1507,6 +1507,10 @@
30 return ar_handle->sub_archive->buffer;
31 }
32
33 +/*
34 +
35 +// moved to data_extract_all.c
36 +
37 static void data_extract_all_prefix(archive_handle_t *archive_handle)
38 {
39 char *name_ptr = archive_handle->file_header->name;
40 @@ -1519,6 +1523,8 @@
41 return;
42 }
43
44 +*/
45 +
46 static void unpack_package(deb_file_t *deb_file)
47 {
48 const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];
49 diff -ruN busybox-1.3.1-orig/archival/ipkg.c busybox-1.3.1-911/archival/ipkg.c
50 --- busybox-1.3.1-orig/archival/ipkg.c 1970-01-01 01:00:00.000000000 +0100
51 +++ busybox-1.3.1-911/archival/ipkg.c 2006-12-27 19:41:04.000000000 +0100
52 @@ -0,0 +1,26 @@
53 +/* ipkg.c - the itsy package management system
54 +
55 + Florina Boor
56 +
57 + Copyright (C) 2003 kernel concepts
58 +
59 + This program is free software; you can redistribute it and/or
60 + modify it under the terms of the GNU General Public License as
61 + published by the Free Software Foundation; either version 2, or (at
62 + your option) any later version.
63 +
64 + This program is distributed in the hope that it will be useful, but
65 + WITHOUT ANY WARRANTY; without even the implied warranty of
66 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
67 + General Public License for more details.
68 +
69 + ipkg command line frontend using libipkg
70 +
71 +*/
72 +
73 +#include "libipkg/libipkg.h"
74 +
75 +int ipkg_main(int argc, char **argv)
76 +{
77 + return ipkg_op(argc, argv);
78 +}
79 diff -ruN busybox-1.3.1-orig/archival/Kbuild busybox-1.3.1-911/archival/Kbuild
80 --- busybox-1.3.1-orig/archival/Kbuild 2006-12-27 05:53:54.000000000 +0100
81 +++ busybox-1.3.1-911/archival/Kbuild 2006-12-27 19:51:09.000000000 +0100
82 @@ -15,6 +15,7 @@
83 lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o
84 lib-$(CONFIG_GUNZIP) += gunzip.o
85 lib-$(CONFIG_GZIP) += gzip.o
86 +lib-$(CONFIG_IPKG) += ipkg.o
87 lib-$(CONFIG_RPM2CPIO) += rpm2cpio.o
88 lib-$(CONFIG_RPM) += rpm.o
89 lib-$(CONFIG_TAR) += tar.o
90 diff -ruN busybox-1.3.1-orig/archival/libipkg/args.c busybox-1.3.1-911/archival/libipkg/args.c
91 --- busybox-1.3.1-orig/archival/libipkg/args.c 1970-01-01 01:00:00.000000000 +0100
92 +++ busybox-1.3.1-911/archival/libipkg/args.c 2006-12-27 19:41:04.000000000 +0100
93 @@ -0,0 +1,242 @@
94 +/* args.c - parse command-line args
95 +
96 + Carl D. Worth
97 +
98 + Copyright 2001 University of Southern California
99 +
100 + This program is free software; you can redistribute it and/or modify
101 + it under the terms of the GNU General Public License as published by
102 + the Free Software Foundation; either version 2, or (at your option)
103 + any later version.
104 +
105 + This program is distributed in the hope that it will be useful,
106 + but WITHOUT ANY WARRANTY; without even the implied warranty of
107 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108 + GNU General Public License for more details.
109 + */
110 +
111 +#include <getopt.h>
112 +#include <stdlib.h>
113 +#include <string.h>
114 +#include <unistd.h>
115 +
116 +#include "ipkg.h"
117 +#include "ipkg_message.h"
118 +
119 +#include "args.h"
120 +#include "sprintf_alloc.h"
121 +
122 +#include "libbb.h"
123 +
124 +
125 +static void print_version(void);
126 +
127 +enum long_args_opt
128 +{
129 + ARGS_OPT_FORCE_DEFAULTS = 129,
130 + ARGS_OPT_FORCE_DEPENDS,
131 + ARGS_OPT_FORCE_OVERWRITE,
132 + ARGS_OPT_FORCE_DOWNGRADE,
133 + ARGS_OPT_FORCE_REINSTALL,
134 + ARGS_OPT_FORCE_REMOVAL_OF_DEPENDENT_PACKAGES,
135 + ARGS_OPT_FORCE_REMOVAL_OF_ESSENTIAL_PACKAGES,
136 + ARGS_OPT_FORCE_SPACE,
137 + ARGS_OPT_NOACTION,
138 + ARGS_OPT_NODEPS,
139 + ARGS_OPT_VERBOSE_WGET,
140 + ARGS_OPT_VERBOSITY,
141 + ARGS_OPT_MULTIPLE_PROVIDERS
142 +};
143 +
144 +int args_init(args_t *args)
145 +{
146 + char *conf_file_dir;
147 +
148 + memset(args, 0, sizeof(args_t));
149 +
150 + args->dest = ARGS_DEFAULT_DEST;
151 +
152 + conf_file_dir = getenv("IPKG_CONF_DIR");
153 + if (conf_file_dir == NULL || conf_file_dir[0] == '\0') {
154 + conf_file_dir = ARGS_DEFAULT_CONF_FILE_DIR;
155 + }
156 + sprintf_alloc(&args->conf_file, "%s/%s", conf_file_dir,
157 + ARGS_DEFAULT_CONF_FILE_NAME);
158 +
159 + args->force_defaults = ARGS_DEFAULT_FORCE_DEFAULTS;
160 + args->force_depends = ARGS_DEFAULT_FORCE_DEPENDS;
161 + args->force_overwrite = ARGS_DEFAULT_FORCE_OVERWRITE;
162 + args->force_downgrade = ARGS_DEFAULT_FORCE_DOWNGRADE;
163 + args->force_reinstall = ARGS_DEFAULT_FORCE_REINSTALL;
164 + args->force_removal_of_dependent_packages = ARGS_DEFAULT_FORCE_REMOVAL_OF_DEPENDENT_PACKAGES;
165 + args->force_removal_of_essential_packages = ARGS_DEFAULT_FORCE_REMOVAL_OF_ESSENTIAL_PACKAGES;
166 + args->noaction = ARGS_DEFAULT_NOACTION;
167 + args->nodeps = ARGS_DEFAULT_NODEPS;
168 + args->verbose_wget = ARGS_DEFAULT_VERBOSE_WGET;
169 + args->verbosity = ARGS_DEFAULT_VERBOSITY;
170 + args->offline_root = ARGS_DEFAULT_OFFLINE_ROOT;
171 + args->offline_root_pre_script_cmd = ARGS_DEFAULT_OFFLINE_ROOT_PRE_SCRIPT_CMD;
172 + args->offline_root_post_script_cmd = ARGS_DEFAULT_OFFLINE_ROOT_POST_SCRIPT_CMD;
173 + args->multiple_providers = 0;
174 + args->nocheckfordirorfile = 0;
175 + args->noreadfeedsfile = 0;
176 +
177 + return 1;
178 +}
179 +
180 +void args_deinit(args_t *args)
181 +{
182 + free(args->conf_file);
183 + args->conf_file = NULL;
184 +}
185 +
186 +int args_parse(args_t *args, int argc, char *argv[])
187 +{
188 + int c;
189 + int option_index = 0;
190 + int parse_err = 0;
191 + static struct option long_options[] = {
192 + {"query-all", 0, 0, 'A'},
193 + {"conf-file", 1, 0, 'f'},
194 + {"conf", 1, 0, 'f'},
195 + {"dest", 1, 0, 'd'},
196 + {"force-defaults", 0, 0, ARGS_OPT_FORCE_DEFAULTS},
197 + {"force_defaults", 0, 0, ARGS_OPT_FORCE_DEFAULTS},
198 + {"force-depends", 0, 0, ARGS_OPT_FORCE_DEPENDS},
199 + {"force_depends", 0, 0, ARGS_OPT_FORCE_DEPENDS},
200 + {"force-overwrite", 0, 0, ARGS_OPT_FORCE_OVERWRITE},
201 + {"force_overwrite", 0, 0, ARGS_OPT_FORCE_OVERWRITE},
202 + {"force_downgrade", 0, 0, ARGS_OPT_FORCE_DOWNGRADE},
203 + {"force-downgrade", 0, 0, ARGS_OPT_FORCE_DOWNGRADE},
204 + {"force-reinstall", 0, 0, ARGS_OPT_FORCE_REINSTALL},
205 + {"force_reinstall", 0, 0, ARGS_OPT_FORCE_REINSTALL},
206 + {"force-space", 0, 0, ARGS_OPT_FORCE_SPACE},
207 + {"force_space", 0, 0, ARGS_OPT_FORCE_SPACE},
208 + {"recursive", 0, 0,
209 + ARGS_OPT_FORCE_REMOVAL_OF_DEPENDENT_PACKAGES},
210 + {"force-removal-of-dependent-packages", 0, 0,
211 + ARGS_OPT_FORCE_REMOVAL_OF_DEPENDENT_PACKAGES},
212 + {"force_removal_of_dependent_packages", 0, 0,
213 + ARGS_OPT_FORCE_REMOVAL_OF_DEPENDENT_PACKAGES},
214 + {"force-removal-of-essential-packages", 0, 0,
215 + ARGS_OPT_FORCE_REMOVAL_OF_ESSENTIAL_PACKAGES},
216 + {"force_removal_of_essential_packages", 0, 0,
217 + ARGS_OPT_FORCE_REMOVAL_OF_ESSENTIAL_PACKAGES},
218 + {"multiple-providers", 0, 0, ARGS_OPT_MULTIPLE_PROVIDERS},
219 + {"multiple_providers", 0, 0, ARGS_OPT_MULTIPLE_PROVIDERS},
220 + {"noaction", 0, 0, ARGS_OPT_NOACTION},
221 + {"nodeps", 0, 0, ARGS_OPT_NODEPS},
222 + {"offline", 1, 0, 'o'},
223 + {"offline-root", 1, 0, 'o'},
224 + {"test", 0, 0, ARGS_OPT_NOACTION},
225 + {"tmp-dir", 1, 0, 't'},
226 + {"verbose-wget", 0, 0, ARGS_OPT_VERBOSE_WGET},
227 + {"verbose_wget", 0, 0, ARGS_OPT_VERBOSE_WGET},
228 + {"verbosity", 2, 0, 'V'},
229 + {"version", 0, 0, 'v'},
230 + {0, 0, 0, 0}
231 + };
232 +
233 + while (1) {
234 + c = getopt_long_only(argc, argv, "Ad:f:no:t:vV:", long_options, &option_index);
235 + if (c == -1)
236 + break;
237 +
238 + switch (c) {
239 + case 'A':
240 + args->query_all = 1;
241 + break;
242 + case 'd':
243 + args->dest = optarg;
244 + break;
245 + case 'f':
246 + free(args->conf_file);
247 + args->conf_file = strdup(optarg);
248 + break;
249 + case 'o':
250 + args->offline_root = optarg;
251 + break;
252 + case 'n':
253 + args->noaction = 1;
254 + break;
255 + case 't':
256 + args->tmp_dir = strdup(optarg);
257 + break;
258 + case 'v':
259 + print_version();
260 + exit(0);
261 + case 'V':
262 + case ARGS_OPT_VERBOSITY:
263 + if (optarg)
264 + args->verbosity = atoi(optarg);
265 + else
266 + args->verbosity += 1;
267 + break;
268 + case ARGS_OPT_FORCE_DEFAULTS:
269 + args->force_defaults = 1;
270 + break;
271 + case ARGS_OPT_FORCE_DEPENDS:
272 + args->force_depends = 1;
273 + break;
274 + case ARGS_OPT_FORCE_OVERWRITE:
275 + args->force_overwrite = 1;
276 + break;
277 + case ARGS_OPT_FORCE_DOWNGRADE:
278 + args->force_downgrade = 1;
279 + break;
280 + case ARGS_OPT_FORCE_REINSTALL:
281 + args->force_reinstall = 1;
282 + break;
283 + case ARGS_OPT_FORCE_REMOVAL_OF_ESSENTIAL_PACKAGES:
284 + args->force_removal_of_essential_packages = 1;
285 + break;
286 + case ARGS_OPT_FORCE_REMOVAL_OF_DEPENDENT_PACKAGES:
287 + args->force_removal_of_dependent_packages = 1;
288 + break;
289 + case ARGS_OPT_FORCE_SPACE:
290 + args->force_space = 1;
291 + break;
292 + case ARGS_OPT_VERBOSE_WGET:
293 + args->verbose_wget = 1;
294 + break;
295 + case ARGS_OPT_MULTIPLE_PROVIDERS:
296 + args->multiple_providers = 1;
297 + break;
298 + case ARGS_OPT_NODEPS:
299 + args->nodeps = 1;
300 + break;
301 + case ARGS_OPT_NOACTION:
302 + args->noaction = 1;
303 + break;
304 + case ':':
305 + parse_err++;
306 + break;
307 + case '?':
308 + parse_err++;
309 + break;
310 + default:
311 + bb_error_msg("Confusion: getopt_long returned %d\n", c);
312 + }
313 + }
314 +
315 + if (parse_err) {
316 + return -parse_err;
317 + } else {
318 + return optind;
319 + }
320 +}
321 +
322 +void args_usage(char *complaint)
323 +{
324 + if (complaint) {
325 + bb_error_msg("%s\n", complaint);
326 + }
327 + print_version();
328 + bb_show_usage();
329 + exit(1);
330 +}
331 +
332 +static void print_version(void)
333 +{
334 + bb_error_msg("version %s\n", IPKG_VERSION);
335 +}
336 diff -ruN busybox-1.3.1-orig/archival/libipkg/args.h busybox-1.3.1-911/archival/libipkg/args.h
337 --- busybox-1.3.1-orig/archival/libipkg/args.h 1970-01-01 01:00:00.000000000 +0100
338 +++ busybox-1.3.1-911/archival/libipkg/args.h 2006-12-27 19:41:04.000000000 +0100
339 @@ -0,0 +1,72 @@
340 +/* args.h - parse command-line args
341 +
342 + Carl D. Worth
343 +
344 + Copyright 2001 University of Southern California
345 +
346 + This program is free software; you can redistribute it and/or modify
347 + it under the terms of the GNU General Public License as published by
348 + the Free Software Foundation; either version 2, or (at your option)
349 + any later version.
350 +
351 + This program is distributed in the hope that it will be useful,
352 + but WITHOUT ANY WARRANTY; without even the implied warranty of
353 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
354 + GNU General Public License for more details.
355 +*/
356 +
357 +#ifndef ARGS_H
358 +#define ARGS_H
359 +
360 +struct args
361 +{
362 + char *conf_file;
363 + char *dest;
364 + char *tmp_dir;
365 + int force_defaults;
366 + int force_depends;
367 + int force_overwrite;
368 + int force_downgrade;
369 + int force_reinstall;
370 + int force_removal_of_essential_packages;
371 + int force_removal_of_dependent_packages;
372 + int force_space;
373 + int noaction;
374 + int nodeps;
375 + int multiple_providers;
376 + int query_all;
377 + int verbose_wget;
378 + int verbosity;
379 + int nocheckfordirorfile;
380 + int noreadfeedsfile;
381 + char *offline_root;
382 + char *offline_root_pre_script_cmd;
383 + char *offline_root_post_script_cmd;
384 +};
385 +typedef struct args args_t;
386 +
387 +#define ARGS_DEFAULT_CONF_FILE_DIR "/etc"
388 +#define ARGS_DEFAULT_CONF_FILE_NAME "ipkg.conf"
389 +#define ARGS_DEFAULT_DEST NULL
390 +#define ARGS_DEFAULT_FORCE_DEFAULTS 0
391 +#define ARGS_DEFAULT_FORCE_DEPENDS 0
392 +#define ARGS_DEFAULT_FORCE_OVERWRITE 0
393 +#define ARGS_DEFAULT_FORCE_DOWNGRADE 0
394 +#define ARGS_DEFAULT_FORCE_REINSTALL 0
395 +#define ARGS_DEFAULT_FORCE_REMOVAL_OF_ESSENTIAL_PACKAGES 0
396 +#define ARGS_DEFAULT_FORCE_REMOVAL_OF_DEPENDENT_PACKAGES 0
397 +#define ARGS_DEFAULT_FORCE_SPACE 0
398 +#define ARGS_DEFAULT_OFFLINE_ROOT NULL
399 +#define ARGS_DEFAULT_OFFLINE_ROOT_PRE_SCRIPT_CMD NULL
400 +#define ARGS_DEFAULT_OFFLINE_ROOT_POST_SCRIPT_CMD NULL
401 +#define ARGS_DEFAULT_NOACTION 0
402 +#define ARGS_DEFAULT_NODEPS 0
403 +#define ARGS_DEFAULT_VERBOSE_WGET 0
404 +#define ARGS_DEFAULT_VERBOSITY 1
405 +
406 +int args_init(args_t *args);
407 +void args_deinit(args_t *args);
408 +int args_parse(args_t *args, int argc, char *argv[]);
409 +void args_usage(char *complaint);
410 +
411 +#endif
412 diff -ruN busybox-1.3.1-orig/archival/libipkg/conffile.c busybox-1.3.1-911/archival/libipkg/conffile.c
413 --- busybox-1.3.1-orig/archival/libipkg/conffile.c 1970-01-01 01:00:00.000000000 +0100
414 +++ busybox-1.3.1-911/archival/libipkg/conffile.c 2006-12-27 19:41:04.000000000 +0100
415 @@ -0,0 +1,64 @@
416 +/* conffile.c - the itsy package management system
417 +
418 + Carl D. Worth
419 +
420 + Copyright (C) 2001 University of Southern California
421 +
422 + This program is free software; you can redistribute it and/or
423 + modify it under the terms of the GNU General Public License as
424 + published by the Free Software Foundation; either version 2, or (at
425 + your option) any later version.
426 +
427 + This program is distributed in the hope that it will be useful, but
428 + WITHOUT ANY WARRANTY; without even the implied warranty of
429 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
430 + General Public License for more details.
431 +*/
432 +
433 +#include <string.h>
434 +#include <stdlib.h>
435 +
436 +#include "ipkg.h"
437 +#include "ipkg_message.h"
438 +
439 +#include "conffile.h"
440 +#include "file_util.h"
441 +#include "sprintf_alloc.h"
442 +
443 +int conffile_init(conffile_t *conffile, const char *file_name, const char *md5sum)
444 +{
445 + return nv_pair_init(conffile, file_name, md5sum);
446 +}
447 +
448 +void conffile_deinit(conffile_t *conffile)
449 +{
450 + nv_pair_deinit(conffile);
451 +}
452 +
453 +int conffile_has_been_modified(ipkg_conf_t *conf, conffile_t *conffile)
454 +{
455 + char *md5sum;
456 + char *filename = conffile->name;
457 + char *root_filename;
458 + int ret;
459 +
460 + if (conffile->value == NULL) {
461 + ipkg_message(conf, IPKG_NOTICE, "%s: conffile %s has no md5sum\n", __FUNCTION__, conffile->name);
462 + return 1;
463 + }
464 +
465 + root_filename = root_filename_alloc(conf, filename);
466 +
467 + md5sum = file_md5sum_alloc(root_filename);
468 +
469 + ret = strcmp(md5sum, conffile->value);
470 + if (ret) {
471 + ipkg_message(conf, IPKG_NOTICE, "%s: conffile %s: \t\nold md5=%s \t\nnew md5=%s\n", __FUNCTION__,
472 + conffile->name, md5sum, conffile->value);
473 + }
474 +
475 + free(root_filename);
476 + free(md5sum);
477 +
478 + return ret;
479 +}
480 diff -ruN busybox-1.3.1-orig/archival/libipkg/conffile.h busybox-1.3.1-911/archival/libipkg/conffile.h
481 --- busybox-1.3.1-orig/archival/libipkg/conffile.h 1970-01-01 01:00:00.000000000 +0100
482 +++ busybox-1.3.1-911/archival/libipkg/conffile.h 2006-12-27 19:41:04.000000000 +0100
483 @@ -0,0 +1,30 @@
484 +/* conffile.h - the itsy package management system
485 +
486 + Carl D. Worth
487 +
488 + Copyright (C) 2001 University of Southern California
489 +
490 + This program is free software; you can redistribute it and/or
491 + modify it under the terms of the GNU General Public License as
492 + published by the Free Software Foundation; either version 2, or (at
493 + your option) any later version.
494 +
495 + This program is distributed in the hope that it will be useful, but
496 + WITHOUT ANY WARRANTY; without even the implied warranty of
497 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
498 + General Public License for more details.
499 +*/
500 +
501 +#ifndef CONFFILE_H
502 +#define CONFFILE_H
503 +
504 +#include "nv_pair.h"
505 +
506 +typedef struct nv_pair conffile_t;
507 +
508 +int conffile_init(conffile_t *conffile, const char *file_name, const char *md5sum);
509 +void conffile_deinit(conffile_t *conffile);
510 +int conffile_has_been_modified(struct ipkg_conf *conf, conffile_t *conffile);
511 +
512 +#endif
513 +
514 diff -ruN busybox-1.3.1-orig/archival/libipkg/conffile_list.c busybox-1.3.1-911/archival/libipkg/conffile_list.c
515 --- busybox-1.3.1-orig/archival/libipkg/conffile_list.c 1970-01-01 01:00:00.000000000 +0100
516 +++ busybox-1.3.1-911/archival/libipkg/conffile_list.c 2006-12-27 19:41:04.000000000 +0100
517 @@ -0,0 +1,47 @@
518 +/* conffile_list.c - the itsy package management system
519 +
520 + Carl D. Worth
521 +
522 + Copyright (C) 2001 University of Southern California
523 +
524 + This program is free software; you can redistribute it and/or
525 + modify it under the terms of the GNU General Public License as
526 + published by the Free Software Foundation; either version 2, or (at
527 + your option) any later version.
528 +
529 + This program is distributed in the hope that it will be useful, but
530 + WITHOUT ANY WARRANTY; without even the implied warranty of
531 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
532 + General Public License for more details.
533 +*/
534 +
535 +#include "ipkg.h"
536 +
537 +#include "conffile_list.h"
538 +
539 +int conffile_list_init(conffile_list_t *list)
540 +{
541 + return nv_pair_list_init(list);
542 +}
543 +
544 +void conffile_list_deinit(conffile_list_t *list)
545 +{
546 + nv_pair_list_deinit(list);
547 +}
548 +
549 +conffile_t *conffile_list_append(conffile_list_t *list, const char *file_name,
550 + const char *md5sum)
551 +{
552 + return nv_pair_list_append(list, file_name, md5sum);
553 +}
554 +
555 +int conffile_list_push(conffile_list_t *list, conffile_t *data)
556 +{
557 + return nv_pair_list_push(list, data);
558 +}
559 +
560 +conffile_list_elt_t *conffile_list_pop(conffile_list_t *list)
561 +{
562 + return nv_pair_list_pop(list);
563 +}
564 +
565 diff -ruN busybox-1.3.1-orig/archival/libipkg/conffile_list.h busybox-1.3.1-911/archival/libipkg/conffile_list.h
566 --- busybox-1.3.1-orig/archival/libipkg/conffile_list.h 1970-01-01 01:00:00.000000000 +0100
567 +++ busybox-1.3.1-911/archival/libipkg/conffile_list.h 2006-12-27 19:41:04.000000000 +0100
568 @@ -0,0 +1,36 @@
569 +/* conffile_list.h - the itsy package management system
570 +
571 + Carl D. Worth
572 +
573 + Copyright (C) 2001 University of Southern California
574 +
575 + This program is free software; you can redistribute it and/or
576 + modify it under the terms of the GNU General Public License as
577 + published by the Free Software Foundation; either version 2, or (at
578 + your option) any later version.
579 +
580 + This program is distributed in the hope that it will be useful, but
581 + WITHOUT ANY WARRANTY; without even the implied warranty of
582 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
583 + General Public License for more details.
584 +*/
585 +
586 +#ifndef CONFFILE_LIST_H
587 +#define CONFFILE_LIST_H
588 +
589 +#include "conffile.h"
590 +#include "nv_pair_list.h"
591 +
592 +typedef struct nv_pair_list_elt conffile_list_elt_t;
593 +typedef struct nv_pair_list conffile_list_t;
594 +
595 +int conffile_list_init(conffile_list_t *list);
596 +void conffile_list_deinit(conffile_list_t *list);
597 +
598 +conffile_t *conffile_list_append(conffile_list_t *list, const char *name,
599 + const char *root_dir);
600 +int conffile_list_push(conffile_list_t *list, conffile_t *data);
601 +conffile_list_elt_t *conffile_list_pop(conffile_list_t *list);
602 +
603 +#endif
604 +
605 diff -ruN busybox-1.3.1-orig/archival/libipkg/file_util.c busybox-1.3.1-911/archival/libipkg/file_util.c
606 --- busybox-1.3.1-orig/archival/libipkg/file_util.c 1970-01-01 01:00:00.000000000 +0100
607 +++ busybox-1.3.1-911/archival/libipkg/file_util.c 2006-12-27 19:41:04.000000000 +0100
608 @@ -0,0 +1,177 @@
609 +/* file_util.c - convenience routines for common stat operations
610 +
611 + Carl D. Worth
612 +
613 + Copyright (C) 2001 University of Southern California
614 +
615 + This program is free software; you can redistribute it and/or
616 + modify it under the terms of the GNU General Public License as
617 + published by the Free Software Foundation; either version 2, or (at
618 + your option) any later version.
619 +
620 + This program is distributed in the hope that it will be useful, but
621 + WITHOUT ANY WARRANTY; without even the implied warranty of
622 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
623 + General Public License for more details.
624 +*/
625 +
626 +#include "ipkg.h"
627 +#include <sys/types.h>
628 +#include <sys/stat.h>
629 +
630 +#include "sprintf_alloc.h"
631 +#include "file_util.h"
632 +#include "md5.h"
633 +#include "libbb.h"
634 +#undef strlen
635 +
636 +int file_exists(const char *file_name)
637 +{
638 + int err;
639 + struct stat stat_buf;
640 +
641 + err = stat(file_name, &stat_buf);
642 + if (err == 0) {
643 + return 1;
644 + } else {
645 + return 0;
646 + }
647 +}
648 +
649 +int file_is_dir(const char *file_name)
650 +{
651 + int err;
652 + struct stat stat_buf;
653 +
654 + err = stat(file_name, &stat_buf);
655 + if (err) {
656 + return 0;
657 + }
658 +
659 + return S_ISDIR(stat_buf.st_mode);
660 +}
661 +
662 +/* read a single line from a file, stopping at a newline or EOF.
663 + If a newline is read, it will appear in the resulting string.
664 + Return value is a malloc'ed char * which should be freed at
665 + some point by the caller.
666 +
667 + Return value is NULL if the file is at EOF when called.
668 +*/
669 +#define FILE_READ_LINE_BUF_SIZE 1024
670 +char *file_read_line_alloc(FILE *file)
671 +{
672 + char buf[FILE_READ_LINE_BUF_SIZE];
673 + int buf_len;
674 + char *line = NULL;
675 + int line_size = 0;
676 +
677 + memset(buf, 0, FILE_READ_LINE_BUF_SIZE);
678 + while (fgets(buf, FILE_READ_LINE_BUF_SIZE, file)) {
679 + buf_len = strlen(buf);
680 + if (line) {
681 + line_size += buf_len;
682 + line = realloc(line, line_size);
683 + if (line == NULL) {
684 + fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
685 + break;
686 + }
687 + strcat(line, buf);
688 + } else {
689 + line_size = buf_len + 1;
690 + line = strdup(buf);
691 + }
692 + if (buf[buf_len - 1] == '\n') {
693 + break;
694 + }
695 + }
696 +
697 + return line;
698 +}
699 +
700 +int file_move(const char *src, const char *dest)
701 +{
702 + int err;
703 +
704 + err = rename(src, dest);
705 +
706 + if (err && errno == EXDEV) {
707 + err = file_copy(src, dest);
708 + unlink(src);
709 + } else if (err) {
710 + fprintf(stderr, "%s: ERROR: failed to rename %s to %s: %s\n",
711 + __FUNCTION__, src, dest, strerror(errno));
712 + }
713 +
714 + return err;
715 +}
716 +
717 +/* I put these here to keep libbb dependencies from creeping all over
718 + the ipkg code */
719 +int file_copy(const char *src, const char *dest)
720 +{
721 + int err;
722 +
723 + err = copy_file(src, dest, FILEUTILS_FORCE | FILEUTILS_PRESERVE_STATUS);
724 + if (err) {
725 + fprintf(stderr, "%s: ERROR: failed to copy %s to %s\n",
726 + __FUNCTION__, src, dest);
727 + }
728 +
729 + return err;
730 +}
731 +
732 +int file_mkdir_hier(const char *path, long mode)
733 +{
734 + return bb_make_directory(path, mode, FILEUTILS_RECUR);
735 +}
736 +
737 +char *file_md5sum_alloc(const char *file_name)
738 +{
739 + static const int md5sum_bin_len = 16;
740 + static const int md5sum_hex_len = 32;
741 +
742 + static const unsigned char bin2hex[16] = {
743 + '0', '1', '2', '3',
744 + '4', '5', '6', '7',
745 + '8', '9', 'a', 'b',
746 + 'c', 'd', 'e', 'f'
747 + };
748 +
749 + int i, err;
750 + FILE *file;
751 + unsigned char *md5sum_hex;
752 + unsigned char md5sum_bin[md5sum_bin_len];
753 +
754 + md5sum_hex = malloc(md5sum_hex_len + 1);
755 + if (md5sum_hex == NULL) {
756 + fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
757 + return strdup("");
758 + }
759 +
760 + file = fopen(file_name, "r");
761 + if (file == NULL) {
762 + fprintf(stderr, "%s: Failed to open file %s: %s\n",
763 + __FUNCTION__, file_name, strerror(errno));
764 + return strdup("");
765 + }
766 +
767 + err = md5_stream(file, md5sum_bin);
768 + if (err) {
769 + fprintf(stderr, "%s: ERROR computing md5sum for %s: %s\n",
770 + __FUNCTION__, file_name, strerror(err));
771 + return strdup("");
772 + }
773 +
774 + fclose(file);
775 +
776 + for (i=0; i < md5sum_bin_len; i++) {
777 + md5sum_hex[i*2] = bin2hex[md5sum_bin[i] >> 4];
778 + md5sum_hex[i*2+1] = bin2hex[md5sum_bin[i] & 0xf];
779 + }
780 +
781 + md5sum_hex[md5sum_hex_len] = '\0';
782 +
783 + return md5sum_hex;
784 +}
785 +
786 diff -ruN busybox-1.3.1-orig/archival/libipkg/file_util.h busybox-1.3.1-911/archival/libipkg/file_util.h
787 --- busybox-1.3.1-orig/archival/libipkg/file_util.h 1970-01-01 01:00:00.000000000 +0100
788 +++ busybox-1.3.1-911/archival/libipkg/file_util.h 2006-12-27 19:41:04.000000000 +0100
789 @@ -0,0 +1,29 @@
790 +/* file_util.h - convenience routines for common file operations
791 +
792 + Carl D. Worth
793 +
794 + Copyright (C) 2001 University of Southern California
795 +
796 + This program is free software; you can redistribute it and/or
797 + modify it under the terms of the GNU General Public License as
798 + published by the Free Software Foundation; either version 2, or (at
799 + your option) any later version.
800 +
801 + This program is distributed in the hope that it will be useful, but
802 + WITHOUT ANY WARRANTY; without even the implied warranty of
803 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
804 + General Public License for more details.
805 +*/
806 +
807 +#ifndef FILE_UTIL_H
808 +#define FILE_UTIL_H
809 +
810 +int file_exists(const char *file_name);
811 +int file_is_dir(const char *file_name);
812 +char *file_read_line_alloc(FILE *file);
813 +int file_move(const char *src, const char *dest);
814 +int file_copy(const char *src, const char *dest);
815 +int file_mkdir_hier(const char *path, long mode);
816 +char *file_md5sum_alloc(const char *file_name);
817 +
818 +#endif
819 diff -ruN busybox-1.3.1-orig/archival/libipkg/hash_table.c busybox-1.3.1-911/archival/libipkg/hash_table.c
820 --- busybox-1.3.1-orig/archival/libipkg/hash_table.c 1970-01-01 01:00:00.000000000 +0100
821 +++ busybox-1.3.1-911/archival/libipkg/hash_table.c 2006-12-27 19:41:04.000000000 +0100
822 @@ -0,0 +1,155 @@
823 +/* hash.c - hash tables for ipkg
824 +
825 + Steven M. Ayer, Jamey Hicks
826 +
827 + Copyright (C) 2002 Compaq Computer Corporation
828 +
829 + This program is free software; you can redistribute it and/or
830 + modify it under the terms of the GNU General Public License as
831 + published by the Free Software Foundation; either version 2, or (at
832 + your option) any later version.
833 +
834 + This program is distributed in the hope that it will be useful, but
835 + WITHOUT ANY WARRANTY; without even the implied warranty of
836 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
837 + General Public License for more details.
838 +*/
839 +
840 +#include <errno.h>
841 +#include <stdio.h>
842 +#include <stdlib.h>
843 +#include <string.h>
844 +#include "hash_table.h"
845 +#include "ipkg_message.h"
846 +
847 +
848 +static int hash_index(hash_table_t *hash, const char *pkg_name);
849 +static int rotating(const char *key, int len, int prime);
850 +
851 +static int hash_index(hash_table_t *hash, const char *pkg_name)
852 +{
853 + return rotating(pkg_name, strlen(pkg_name), hash->n_entries);
854 +}
855 +
856 +static int rotating(const char *key, int len, int prime)
857 +{
858 + unsigned int hash, i;
859 + for (hash=len, i=0; i<len; ++i)
860 + hash = (hash<<4)^(hash>>28)^key[i];
861 + return (hash % prime);
862 +}
863 +
864 +
865 +/*
866 + * this is an open table keyed by strings
867 + */
868 +int hash_table_init(const char *name, hash_table_t *hash, int len)
869 +{
870 + static int primes_table[] = {
871 + 379, 761, 983, 1423, 2711, 3361, 3931, 4679, 5519, 6701, 9587,
872 + 19471, 23143, 33961, 46499, 49727, 99529, 0
873 + };
874 + int *picker;
875 +
876 + if (hash->entries != NULL) {
877 + /* we have been here already */
878 + return 0;
879 + }
880 +
881 + hash->name = name;
882 + hash->entries = NULL;
883 + hash->n_entries = 0;
884 + hash->hash_entry_key = NULL;
885 +
886 + picker = primes_table;
887 + while(*picker && (*picker++ < len));
888 + if(!*picker)
889 + fprintf(stderr, "%s: primes table might not be big enough (! << %d)\n", __FUNCTION__, len);
890 + --picker;
891 +
892 + hash->n_entries = *picker;
893 + hash->entries = (hash_entry_t *)calloc(hash->n_entries, sizeof(hash_entry_t));
894 + if (hash->entries == NULL) {
895 + fprintf(stderr, "%s: Out of memory.\n", __FUNCTION__);
896 + return ENOMEM;
897 + }
898 + return 0;
899 +}
900 +
901 +void hash_table_deinit(hash_table_t *hash)
902 +{
903 + free(hash->entries);
904 + hash->entries = NULL;
905 + hash->n_entries = 0;
906 +}
907 +
908 +void *hash_table_get(hash_table_t *hash, const char *key)
909 +{
910 + int ndx= hash_index(hash, key);
911 + hash_entry_t *hash_entry = hash->entries + ndx;
912 + while (hash_entry)
913 + {
914 + if (hash_entry->key)
915 + {
916 + if (strcmp(key, hash_entry->key) == 0) {
917 + // ipkg_message(NULL, IPKG_DEBUG, "Function: %s. Key found for '%s' \n", __FUNCTION__, key);
918 + return hash_entry->data;
919 + }
920 + }
921 + hash_entry = hash_entry->next;
922 + }
923 + return NULL;
924 +}
925 +
926 +int hash_table_insert(hash_table_t *hash, const char *key, void *value)
927 +{
928 + int ndx= hash_index(hash, key);
929 + hash_entry_t *hash_entry = hash->entries + ndx;
930 + if (0) ipkg_message(NULL, IPKG_DEBUG2, "Function: %s. Inserting in hash for '%s' \n", __FUNCTION__, key);
931 + if (hash_entry->key) {
932 + if (strcmp(hash_entry->key, key) == 0) {
933 + /* alread in table, update the value */
934 + if (0) ipkg_message(NULL, IPKG_DEBUG2, "Function: %s. Value already in hash for '%s' \n", __FUNCTION__, key);
935 + hash_entry->data = value;
936 + return 0;
937 + } else {
938 + /*
939 + * if this is a collision, we have to go to the end of the ll,
940 + * then add a new entry
941 + * before we can hook up the value
942 + */
943 + if (0) ipkg_message(NULL, IPKG_DEBUG2, "Function: %s. Value already in hash by collision for '%s' \n", __FUNCTION__, key);
944 + while (hash_entry->next)
945 + hash_entry = hash_entry->next;
946 + hash_entry->next = (hash_entry_t *)malloc(sizeof(hash_entry_t));
947 + if (!hash_entry->next) {
948 + return -ENOMEM;
949 + }
950 + hash_entry = hash_entry->next;
951 + hash_entry->next = NULL;
952 + }
953 + }
954 + hash->n_elements++;
955 + hash_entry->key = strdup(key);
956 + hash_entry->data = value;
957 +
958 + return 0;
959 +}
960 +
961 +
962 +void hash_table_foreach(hash_table_t *hash, void (*f)(const char *key, void *entry, void *data), void *data)
963 +{
964 + int i;
965 + if (!hash || !f)
966 + return;
967 +
968 + for (i = 0; i < hash->n_entries; i++) {
969 + hash_entry_t *hash_entry = (hash->entries + i);
970 + do {
971 + if(hash_entry->key) {
972 + f(hash_entry->key, hash_entry->data, data);
973 + }
974 + } while((hash_entry = hash_entry->next));
975 + }
976 +}
977 +
978 diff -ruN busybox-1.3.1-orig/archival/libipkg/hash_table.h busybox-1.3.1-911/archival/libipkg/hash_table.h
979 --- busybox-1.3.1-orig/archival/libipkg/hash_table.h 1970-01-01 01:00:00.000000000 +0100
980 +++ busybox-1.3.1-911/archival/libipkg/hash_table.h 2006-12-27 19:41:04.000000000 +0100
981 @@ -0,0 +1,44 @@
982 +/* hash.h - hash tables for ipkg
983 +
984 + Steven M. Ayer, Jamey Hicks
985 +
986 + Copyright (C) 2002 Compaq Computer Corporation
987 +
988 + This program is free software; you can redistribute it and/or
989 + modify it under the terms of the GNU General Public License as
990 + published by the Free Software Foundation; either version 2, or (at
991 + your option) any later version.
992 +
993 + This program is distributed in the hope that it will be useful, but
994 + WITHOUT ANY WARRANTY; without even the implied warranty of
995 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
996 + General Public License for more details.
997 +*/
998 +
999 +#ifndef _HASH_TABLE_H_
1000 +#define _HASH_TABLE_H_
1001 +
1002 +typedef struct hash_entry hash_entry_t;
1003 +typedef struct hash_table hash_table_t;
1004 +
1005 +struct hash_entry {
1006 + const char * key;
1007 + void * data;
1008 + struct hash_entry * next;
1009 +};
1010 +
1011 +struct hash_table {
1012 + const char *name;
1013 + hash_entry_t * entries;
1014 + int n_entries; /* number of buckets */
1015 + int n_elements;
1016 + const char * (*hash_entry_key)(void * data);
1017 +};
1018 +
1019 +int hash_table_init(const char *name, hash_table_t *hash, int len);
1020 +void hash_table_deinit(hash_table_t *hash);
1021 +void *hash_table_get(hash_table_t *hash, const char *key);
1022 +int hash_table_insert(hash_table_t *hash, const char *key, void *value);
1023 +void hash_table_foreach(hash_table_t *hash, void (*f)(const char *key, void *entry, void *data), void *data);
1024 +
1025 +#endif /* _HASH_TABLE_H_ */
1026 diff -ruN busybox-1.3.1-orig/archival/libipkg/ipkg_cmd.c busybox-1.3.1-911/archival/libipkg/ipkg_cmd.c
1027 --- busybox-1.3.1-orig/archival/libipkg/ipkg_cmd.c 1970-01-01 01:00:00.000000000 +0100
1028 +++ busybox-1.3.1-911/archival/libipkg/ipkg_cmd.c 2006-12-27 19:41:04.000000000 +0100
1029 @@ -0,0 +1,1431 @@
1030 +/* ipkg_cmd.c - the itsy package management system
1031 +
1032 + Carl D. Worth
1033 +
1034 + Copyright (C) 2001 University of Southern California
1035 +
1036 + This program is free software; you can redistribute it and/or
1037 + modify it under the terms of the GNU General Public License as
1038 + published by the Free Software Foundation; either version 2, or (at
1039 + your option) any later version.
1040 +
1041 + This program is distributed in the hope that it will be useful, but
1042 + WITHOUT ANY WARRANTY; without even the implied warranty of
1043 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1044 + General Public License for more details.
1045 +*/
1046 +
1047 +#include <string.h>
1048 +
1049 +#include "ipkg.h"
1050 +#include <libgen.h>
1051 +#include <glob.h>
1052 +#include <errno.h>
1053 +#include <stdlib.h>
1054 +#include <unistd.h>
1055 +#include <signal.h>
1056 +#include <stdio.h>
1057 +#include <dirent.h>
1058 +
1059 +#include "ipkg_conf.h"
1060 +#include "ipkg_cmd.h"
1061 +#include "ipkg_message.h"
1062 +#include "pkg.h"
1063 +#include "pkg_dest.h"
1064 +#include "pkg_parse.h"
1065 +#include "sprintf_alloc.h"
1066 +#include "pkg.h"
1067 +#include "file_util.h"
1068 +#include "str_util.h"
1069 +#include "libbb.h"
1070 +#include "unarchive.h"
1071 +
1072 +#include <fnmatch.h>
1073 +
1074 +
1075 +#include "ipkg_download.h"
1076 +#include "ipkg_install.h"
1077 +#include "ipkg_upgrade.h"
1078 +#include "ipkg_remove.h"
1079 +#include "ipkg_configure.h"
1080 +#include "ipkg_message.h"
1081 +
1082 +#ifdef IPKG_LIB
1083 +#include "libipkg.h"
1084 +static void *p_userdata = NULL;
1085 +#endif
1086 +
1087 +static int ipkg_update_cmd(ipkg_conf_t *conf, int argc, char **argv);
1088 +static int ipkg_upgrade_cmd(ipkg_conf_t *conf, int argc, char **argv);
1089 +static int ipkg_list_cmd(ipkg_conf_t *conf, int argc, char **argv);
1090 +static int ipkg_info_cmd(ipkg_conf_t *conf, int argc, char **argv);
1091 +static int ipkg_status_cmd(ipkg_conf_t *conf, int argc, char **argv);
1092 +static int ipkg_install_pending_cmd(ipkg_conf_t *conf, int argc, char **argv);
1093 +static int ipkg_install_cmd(ipkg_conf_t *conf, int argc, char **argv);
1094 +static int ipkg_list_installed_cmd(ipkg_conf_t *conf, int argc, char **argv);
1095 +static int ipkg_remove_cmd(ipkg_conf_t *conf, int argc, char **argv);
1096 +static int ipkg_purge_cmd(ipkg_conf_t *conf, int argc, char **argv);
1097 +static int ipkg_flag_cmd(ipkg_conf_t *conf, int argc, char **argv);
1098 +static int ipkg_files_cmd(ipkg_conf_t *conf, int argc, char **argv);
1099 +static int ipkg_search_cmd(ipkg_conf_t *conf, int argc, char **argv);
1100 +static int ipkg_download_cmd(ipkg_conf_t *conf, int argc, char **argv);
1101 +static int ipkg_depends_cmd(ipkg_conf_t *conf, int argc, char **argv);
1102 +static int ipkg_whatdepends_cmd(ipkg_conf_t *conf, int argc, char **argv);
1103 +static int ipkg_whatdepends_recursively_cmd(ipkg_conf_t *conf, int argc, char **argv);
1104 +static int ipkg_whatsuggests_cmd(ipkg_conf_t *conf, int argc, char **argv);
1105 +static int ipkg_whatrecommends_cmd(ipkg_conf_t *conf, int argc, char **argv);
1106 +static int ipkg_whatprovides_cmd(ipkg_conf_t *conf, int argc, char **argv);
1107 +static int ipkg_whatconflicts_cmd(ipkg_conf_t *conf, int argc, char **argv);
1108 +static int ipkg_whatreplaces_cmd(ipkg_conf_t *conf, int argc, char **argv);
1109 +static int ipkg_compare_versions_cmd(ipkg_conf_t *conf, int argc, char **argv);
1110 +static int ipkg_print_architecture_cmd(ipkg_conf_t *conf, int argc, char **argv);
1111 +static int ipkg_configure_cmd(ipkg_conf_t *conf, int argc, char **argv);
1112 +
1113 +/* XXX: CLEANUP: The usage strings should be incorporated into this
1114 + array for easier maintenance */
1115 +static ipkg_cmd_t cmds[] = {
1116 + {"update", 0, (ipkg_cmd_fun_t)ipkg_update_cmd},
1117 + {"upgrade", 0, (ipkg_cmd_fun_t)ipkg_upgrade_cmd},
1118 + {"list", 0, (ipkg_cmd_fun_t)ipkg_list_cmd},
1119 + {"list_installed", 0, (ipkg_cmd_fun_t)ipkg_list_installed_cmd},
1120 + {"info", 0, (ipkg_cmd_fun_t)ipkg_info_cmd},
1121 + {"flag", 1, (ipkg_cmd_fun_t)ipkg_flag_cmd},
1122 + {"status", 0, (ipkg_cmd_fun_t)ipkg_status_cmd},
1123 + {"install_pending", 0, (ipkg_cmd_fun_t)ipkg_install_pending_cmd},
1124 + {"install", 1, (ipkg_cmd_fun_t)ipkg_install_cmd},
1125 + {"remove", 1, (ipkg_cmd_fun_t)ipkg_remove_cmd},
1126 + {"purge", 1, (ipkg_cmd_fun_t)ipkg_purge_cmd},
1127 + {"configure", 0, (ipkg_cmd_fun_t)ipkg_configure_cmd},
1128 + {"files", 1, (ipkg_cmd_fun_t)ipkg_files_cmd},
1129 + {"search", 1, (ipkg_cmd_fun_t)ipkg_search_cmd},
1130 + {"download", 1, (ipkg_cmd_fun_t)ipkg_download_cmd},
1131 + {"compare_versions", 1, (ipkg_cmd_fun_t)ipkg_compare_versions_cmd},
1132 + {"compare-versions", 1, (ipkg_cmd_fun_t)ipkg_compare_versions_cmd},
1133 + {"print-architecture", 0, (ipkg_cmd_fun_t)ipkg_print_architecture_cmd},
1134 + {"print_architecture", 0, (ipkg_cmd_fun_t)ipkg_print_architecture_cmd},
1135 + {"print-installation-architecture", 0, (ipkg_cmd_fun_t)ipkg_print_architecture_cmd},
1136 + {"print_installation_architecture", 0, (ipkg_cmd_fun_t)ipkg_print_architecture_cmd},
1137 + {"depends", 1, (ipkg_cmd_fun_t)ipkg_depends_cmd},
1138 + {"whatdepends", 1, (ipkg_cmd_fun_t)ipkg_whatdepends_cmd},
1139 + {"whatdependsrec", 1, (ipkg_cmd_fun_t)ipkg_whatdepends_recursively_cmd},
1140 + {"whatrecommends", 1, (ipkg_cmd_fun_t)ipkg_whatrecommends_cmd},
1141 + {"whatsuggests", 1, (ipkg_cmd_fun_t)ipkg_whatsuggests_cmd},
1142 + {"whatprovides", 1, (ipkg_cmd_fun_t)ipkg_whatprovides_cmd},
1143 + {"whatreplaces", 1, (ipkg_cmd_fun_t)ipkg_whatreplaces_cmd},
1144 + {"whatconflicts", 1, (ipkg_cmd_fun_t)ipkg_whatconflicts_cmd},
1145 +};
1146 +
1147 +int ipkg_state_changed;
1148 +static void write_status_files_if_changed(ipkg_conf_t *conf)
1149 +{
1150 + if (ipkg_state_changed && !conf->noaction) {
1151 + ipkg_message(conf, IPKG_INFO,
1152 + " writing status file\n");
1153 + ipkg_conf_write_status_files(conf);
1154 + pkg_write_changed_filelists(conf);
1155 + } else {
1156 + ipkg_message(conf, IPKG_NOTICE, "Nothing to be done\n");
1157 + }
1158 +}
1159 +
1160 +
1161 +static int num_cmds = sizeof(cmds) / sizeof(ipkg_cmd_t);
1162 +
1163 +ipkg_cmd_t *ipkg_cmd_find(const char *name)
1164 +{
1165 + int i;
1166 + ipkg_cmd_t *cmd;
1167 +
1168 + for (i=0; i < num_cmds; i++) {
1169 + cmd = &cmds[i];
1170 + if (strcmp(name, cmd->name) == 0) {
1171 + return cmd;
1172 + }
1173 + }
1174 +
1175 + return NULL;
1176 +}
1177 +
1178 +#ifdef IPKG_LIB
1179 +int ipkg_cmd_exec(ipkg_cmd_t *cmd, ipkg_conf_t *conf, int argc, const char **argv, void *userdata)
1180 +{
1181 + int result;
1182 + p_userdata = userdata;
1183 +
1184 +
1185 + result = (cmd->fun)(conf, argc, argv);
1186 + if ( result == 0 ) {
1187 + ipkg_message(conf, IPKG_NOTICE, "Done.\n");
1188 + } else {
1189 + ipkg_message(conf, IPKG_NOTICE, "An error ocurred, return value: %d.\n", result);
1190 +
1191 + }
1192 + if ( error_list ) {
1193 + reverse_error_list(&error_list);
1194 +
1195 + ipkg_message(conf, IPKG_NOTICE, "Collected errors:\n");
1196 + /* Here we print the errors collected and free the list */
1197 + while (error_list != NULL) {
1198 + ipkg_message(conf, IPKG_NOTICE, "%s",error_list->errmsg);
1199 + error_list = error_list->next;
1200 +
1201 + }
1202 + free_error_list(&error_list);
1203 +
1204 + }
1205 +
1206 + p_userdata = NULL;
1207 + return result;
1208 +}
1209 +#else
1210 +int ipkg_cmd_exec(ipkg_cmd_t *cmd, ipkg_conf_t *conf, int argc, const char **argv)
1211 +{
1212 + return (cmd->fun)(conf, argc, argv);
1213 +}
1214 +#endif
1215 +
1216 +static int ipkg_update_cmd(ipkg_conf_t *conf, int argc, char **argv)
1217 +{
1218 + int err;
1219 + int failures;
1220 + char *lists_dir;
1221 + pkg_src_list_elt_t *iter;
1222 + pkg_src_t *src;
1223 +
1224 +
1225 + sprintf_alloc(&lists_dir, "%s", conf->restrict_to_default_dest ? conf->default_dest->lists_dir : conf->lists_dir);
1226 +
1227 + if (! file_is_dir(lists_dir)) {
1228 + if (file_exists(lists_dir)) {
1229 + ipkg_message(conf, IPKG_ERROR,
1230 + "%s: ERROR: %s exists, but is not a directory\n",
1231 + __FUNCTION__, lists_dir);
1232 + free(lists_dir);
1233 + return EINVAL;
1234 + }
1235 + err = file_mkdir_hier(lists_dir, 0755);
1236 + if (err) {
1237 + ipkg_message(conf, IPKG_ERROR,
1238 + "%s: ERROR: failed to make directory %s: %s\n",
1239 + __FUNCTION__, lists_dir, strerror(errno));
1240 + free(lists_dir);
1241 + return EINVAL;
1242 + }
1243 + }
1244 +
1245 + failures = 0;
1246 + for (iter = conf->pkg_src_list.head; iter; iter = iter->next) {
1247 + char *url, *list_file_name;
1248 +
1249 + src = iter->data;
1250 +
1251 + if (src->extra_data) /* debian style? */
1252 + sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data,
1253 + src->gzip ? "Packages.gz" : "Packages");
1254 + else
1255 + sprintf_alloc(&url, "%s/%s", src->value, src->gzip ? "Packages.gz" : "Packages");
1256 +
1257 + sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name);
1258 + if (src->gzip) {
1259 + char *tmp;
1260 + char *tmp_file_name;
1261 + FILE *in, *out;
1262 +
1263 + tmp = strdup ("/tmp/ipkg.XXXXXX");
1264 +
1265 + if (mkdtemp (tmp) == NULL) {
1266 + perror ("mkdtemp");
1267 + failures++;
1268 + continue;
1269 + }
1270 +
1271 + sprintf_alloc (&tmp_file_name, "%s/%s.gz", tmp, src->name);
1272 + err = ipkg_download(conf, url, tmp_file_name);
1273 + if (err == 0) {
1274 + ipkg_message (conf, IPKG_NOTICE, "Inflating %s\n", url);
1275 + in = fopen (tmp_file_name, "r");
1276 + out = fopen (list_file_name, "w");
1277 + if (in && out)
1278 + inflate_unzip (in, out);
1279 + else
1280 + err = 1;
1281 + if (in)
1282 + fclose (in);
1283 + if (out)
1284 + fclose (out);
1285 + unlink (tmp_file_name);
1286 + rmdir (tmp);
1287 + free (tmp);
1288 + }
1289 + } else
1290 + err = ipkg_download(conf, url, list_file_name);
1291 + if (err) {
1292 + failures++;
1293 + } else {
1294 + ipkg_message(conf, IPKG_NOTICE,
1295 + "Updated list of available packages in %s\n",
1296 + list_file_name);
1297 + }
1298 + free(url);
1299 + free(list_file_name);
1300 + }
1301 + free(lists_dir);
1302 +
1303 +#ifdef CONFIG_CLEAR_SW_INSTALL_FLAG
1304 +#warning here
1305 + /* clear SW_INSTALL on any package where state is SS_NOT_INSTALLED.
1306 + * this is a hack to work around poor bookkeeping in old ipkg upgrade code
1307 + * -Jamey 3/1/03
1308 + */
1309 + {
1310 + int i;
1311 + int changed = 0;
1312 + pkg_vec_t *available = pkg_vec_alloc();
1313 + pkg_hash_fetch_available(&conf->pkg_hash, available);
1314 + ipkg_message(conf, IPKG_DEBUG, "Clearing SW_INSTALL for SS_NOT_INSTALLED packages.\n");
1315 + for (i = 0; i < available->len; i++) {
1316 + pkg_t *pkg = available->pkgs[i];
1317 + if (pkg->state_want == SW_INSTALL && pkg->state_status == SS_NOT_INSTALLED) {
1318 + ipkg_message(conf, IPKG_DEBUG, "Clearing SW_INSTALL on package %s.\n", pkg->name);
1319 + pkg->state_want = SW_UNKNOWN;
1320 + changed = 1;
1321 + }
1322 + }
1323 + pkg_vec_free(available);
1324 + if (changed) {
1325 + write_status_files_if_changed(conf);
1326 + }
1327 + }
1328 +#endif
1329 +
1330 + return failures;
1331 +}
1332 +
1333 +
1334 +/* scan the args passed and cache the local filenames of the packages */
1335 +int ipkg_multiple_files_scan(ipkg_conf_t *conf, int argc, char **argv)
1336 +{
1337 + int i;
1338 + int err;
1339 +
1340 + /*
1341 + * First scan through package names/urls
1342 + * For any urls, download the packages and install in database.
1343 + * For any files, install package info in database.
1344 + */
1345 + for (i = 0; i < argc; i ++) {
1346 + char *filename = argv [i];
1347 + //char *tmp = basename (tmp);
1348 + //int tmplen = strlen (tmp);
1349 +
1350 + //if (strcmp (tmp + (tmplen - strlen (IPKG_PKG_EXTENSION)), IPKG_PKG_EXTENSION) != 0)
1351 + // continue;
1352 + //if (strcmp (tmp + (tmplen - strlen (DPKG_PKG_EXTENSION)), DPKG_PKG_EXTENSION) != 0)
1353 + // continue;
1354 +
1355 + ipkg_message(conf, IPKG_DEBUG2, "Debug mfs: %s \n",filename );
1356 +
1357 + err = ipkg_prepare_url_for_install(conf, filename, &argv[i]);
1358 + if (err)
1359 + return err;
1360 + }
1361 + return 0;
1362 +}
1363 +
1364 +struct ipkg_intercept
1365 +{
1366 + char *oldpath;
1367 + char *statedir;
1368 +};
1369 +
1370 +typedef struct ipkg_intercept *ipkg_intercept_t;
1371 +
1372 +ipkg_intercept_t ipkg_prep_intercepts(ipkg_conf_t *conf)
1373 +{
1374 + ipkg_intercept_t ctx;
1375 + char *newpath;
1376 + int gen;
1377 +
1378 + ctx = malloc (sizeof (*ctx));
1379 + ctx->oldpath = strdup (getenv ("PATH"));
1380 +
1381 + sprintf_alloc (&newpath, "%s/ipkg/intercept:%s", IPKGLIBDIR, ctx->oldpath);
1382 + setenv ("PATH", newpath, 1);
1383 + free (newpath);
1384 +
1385 + gen = 0;
1386 + retry:
1387 + sprintf_alloc (&ctx->statedir, "/tmp/ipkg-intercept-%d-%d", getpid (), gen);
1388 + if (mkdir (ctx->statedir, 0770) < 0) {
1389 + if (errno == EEXIST) {
1390 + free (ctx->statedir);
1391 + gen++;
1392 + goto retry;
1393 + }
1394 + perror (ctx->statedir);
1395 + return NULL;
1396 + }
1397 + setenv ("IPKG_INTERCEPT_DIR", ctx->statedir, 1);
1398 + return ctx;
1399 +}
1400 +
1401 +int ipkg_finalize_intercepts(ipkg_intercept_t ctx)
1402 +{
1403 + char *cmd;
1404 + DIR *dir;
1405 + int err = 0;
1406 +
1407 + setenv ("PATH", ctx->oldpath, 1);
1408 + free (ctx->oldpath);
1409 +
1410 + dir = opendir (ctx->statedir);
1411 + if (dir) {
1412 + struct dirent *de;
1413 + while (de = readdir (dir), de != NULL) {
1414 + char *path;
1415 +
1416 + if (de->d_name[0] == '.')
1417 + continue;
1418 +
1419 + sprintf_alloc (&path, "%s/%s", ctx->statedir, de->d_name);
1420 + if (access (path, X_OK) == 0) {
1421 + if (system (path)) {
1422 + err = errno;
1423 + perror (de->d_name);
1424 + }
1425 + }
1426 + free (path);
1427 + }
1428 + } else
1429 + perror (ctx->statedir);
1430 +
1431 + sprintf_alloc (&cmd, "rm -rf %s", ctx->statedir);
1432 + system (cmd);
1433 + free (cmd);
1434 +
1435 + free (ctx->statedir);
1436 + free (ctx);
1437 +
1438 + return err;
1439 +}
1440 +
1441 +int ipkg_configure_packages(ipkg_conf_t *conf, char *pkg_name)
1442 +{
1443 + pkg_vec_t *all;
1444 + int i;
1445 + pkg_t *pkg;
1446 + ipkg_intercept_t ic;
1447 + int r, err = 0;
1448 +
1449 + ipkg_message(conf, IPKG_INFO,
1450 + "Configuring unpacked packages\n");
1451 + fflush( stdout );
1452 +
1453 + all = pkg_vec_alloc();
1454 + pkg_hash_fetch_available(&conf->pkg_hash, all);
1455 +
1456 + ic = ipkg_prep_intercepts (conf);
1457 +
1458 + for(i = 0; i < all->len; i++) {
1459 + pkg = all->pkgs[i];
1460 +
1461 + if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
1462 + continue;
1463 +
1464 + if (pkg->state_status == SS_UNPACKED) {
1465 + ipkg_message(conf, IPKG_NOTICE,
1466 + "Configuring %s\n", pkg->name);
1467 + fflush( stdout );
1468 + r = ipkg_configure(conf, pkg);
1469 + if (r == 0) {
1470 + pkg->state_status = SS_INSTALLED;
1471 + pkg->parent->state_status = SS_INSTALLED;
1472 + pkg->state_flag &= ~SF_PREFER;
1473 + } else {
1474 + if (!err)
1475 + err = r;
1476 + }
1477 + }
1478 + }
1479 +
1480 + r = ipkg_finalize_intercepts (ic);
1481 + if (r && !err)
1482 + err = r;
1483 +
1484 + pkg_vec_free(all);
1485 + return err;
1486 +}
1487 +
1488 +static void sigint_handler(int sig)
1489 +{
1490 + signal(sig, SIG_DFL);
1491 + ipkg_message(NULL, IPKG_NOTICE,
1492 + "ipkg: interrupted. writing out status database\n");
1493 + write_status_files_if_changed(global_conf);
1494 + exit(128 + sig);
1495 +}
1496 +
1497 +static int ipkg_install_cmd(ipkg_conf_t *conf, int argc, char **argv)
1498 +{
1499 + int i;
1500 + char *arg;
1501 + int err=0;
1502 +
1503 + global_conf = conf;
1504 + signal(SIGINT, sigint_handler);
1505 +
1506 + /*
1507 + * Now scan through package names and install
1508 + */
1509 + for (i=0; i < argc; i++) {
1510 + arg = argv[i];
1511 +
1512 + ipkg_message(conf, IPKG_DEBUG2, "Debug install_cmd: %s \n",arg );
1513 + err = ipkg_prepare_url_for_install(conf, arg, &argv[i]);
1514 + if (err != EINVAL && err != 0)
1515 + return err;
1516 + }
1517 + pkg_info_preinstall_check(conf);
1518 +
1519 + for (i=0; i < argc; i++) {
1520 + arg = argv[i];
1521 + if (conf->multiple_providers)
1522 + err = ipkg_install_multi_by_name(conf, arg);
1523 + else{
1524 + err = ipkg_install_by_name(conf, arg);
1525 + }
1526 + if (err == IPKG_PKG_HAS_NO_CANDIDATE) {
1527 + ipkg_message(conf, IPKG_ERROR,
1528 + "Cannot find package %s.\n"
1529 + "Check the spelling or perhaps run 'ipkg update'\n",
1530 + arg);
1531 + }
1532 + }
1533 +
1534 + /* recheck to verify that all dependences are satisfied */
1535 + if (0) ipkg_satisfy_all_dependences(conf);
1536 +
1537 + ipkg_configure_packages(conf, NULL);
1538 +
1539 + write_status_files_if_changed(conf);
1540 +
1541 + return err;
1542 +}
1543 +
1544 +static int ipkg_upgrade_cmd(ipkg_conf_t *conf, int argc, char **argv)
1545 +{
1546 + int i;
1547 + pkg_t *pkg;
1548 + int err;
1549 +
1550 + global_conf = conf;
1551 + signal(SIGINT, sigint_handler);
1552 +
1553 + if (argc) {
1554 + for (i=0; i < argc; i++) {
1555 + char *arg = argv[i];
1556 +
1557 + err = ipkg_prepare_url_for_install(conf, arg, &arg);
1558 + if (err != EINVAL && err != 0)
1559 + return err;
1560 + }
1561 + pkg_info_preinstall_check(conf);
1562 +
1563 + for (i=0; i < argc; i++) {
1564 + char *arg = argv[i];
1565 + if (conf->restrict_to_default_dest) {
1566 + pkg = pkg_hash_fetch_installed_by_name_dest(&conf->pkg_hash,
1567 + argv[i],
1568 + conf->default_dest);
1569 + if (pkg == NULL) {
1570 + ipkg_message(conf, IPKG_NOTICE,
1571 + "Package %s not installed in %s\n",
1572 + argv[i], conf->default_dest->name);
1573 + continue;
1574 + }
1575 + } else {
1576 + pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash,
1577 + argv[i]);
1578 + }
1579 + if (pkg)
1580 + ipkg_upgrade_pkg(conf, pkg);
1581 + else {
1582 + ipkg_install_by_name(conf, arg);
1583 + }
1584 + }
1585 + } else {
1586 + pkg_vec_t *installed = pkg_vec_alloc();
1587 +
1588 + pkg_info_preinstall_check(conf);
1589 +
1590 + pkg_hash_fetch_all_installed(&conf->pkg_hash, installed);
1591 + for (i = 0; i < installed->len; i++) {
1592 + pkg = installed->pkgs[i];
1593 + ipkg_upgrade_pkg(conf, pkg);
1594 + }
1595 + pkg_vec_free(installed);
1596 + }
1597 +
1598 + /* recheck to verify that all dependences are satisfied */
1599 + if (0) ipkg_satisfy_all_dependences(conf);
1600 +
1601 + ipkg_configure_packages(conf, NULL);
1602 +
1603 + write_status_files_if_changed(conf);
1604 +
1605 + return 0;
1606 +}
1607 +
1608 +static int ipkg_download_cmd(ipkg_conf_t *conf, int argc, char **argv)
1609 +{
1610 + int i, err;
1611 + char *arg;
1612 + pkg_t *pkg;
1613 +
1614 + pkg_info_preinstall_check(conf);
1615 + for (i = 0; i < argc; i++) {
1616 + arg = argv[i];
1617 +
1618 + pkg = pkg_hash_fetch_best_installation_candidate_by_name(conf, arg);
1619 + if (pkg == NULL) {
1620 + ipkg_message(conf, IPKG_ERROR,
1621 + "Cannot find package %s.\n"
1622 + "Check the spelling or perhaps run 'ipkg update'\n",
1623 + arg);
1624 + continue;
1625 + }
1626 +
1627 + err = ipkg_download_pkg(conf, pkg, ".");
1628 +
1629 + if (err) {
1630 + ipkg_message(conf, IPKG_ERROR,
1631 + "Failed to download %s\n", pkg->name);
1632 + } else {
1633 + ipkg_message(conf, IPKG_NOTICE,
1634 + "Downloaded %s as %s\n",
1635 + pkg->name, pkg->local_filename);
1636 + }
1637 + }
1638 +
1639 + return 0;
1640 +}
1641 +
1642 +
1643 +static int ipkg_list_cmd(ipkg_conf_t *conf, int argc, char **argv)
1644 +{
1645 + int i ;
1646 + pkg_vec_t *available;
1647 + pkg_t *pkg;
1648 + char desc_short[IPKG_LIST_DESCRIPTION_LENGTH];
1649 + char *newline;
1650 + char *pkg_name = NULL;
1651 + char *version_str;
1652 +
1653 + if (argc > 0) {
1654 + pkg_name = argv[0];
1655 + }
1656 + available = pkg_vec_alloc();
1657 + pkg_hash_fetch_available(&conf->pkg_hash, available);
1658 + for (i=0; i < available->len; i++) {
1659 + pkg = available->pkgs[i];
1660 + /* if we have package name or pattern and pkg does not match, then skip it */
1661 + if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
1662 + continue;
1663 + if (pkg->description) {
1664 + strncpy(desc_short, pkg->description, IPKG_LIST_DESCRIPTION_LENGTH);
1665 + } else {
1666 + desc_short[0] = '\0';
1667 + }
1668 + desc_short[IPKG_LIST_DESCRIPTION_LENGTH - 1] = '\0';
1669 + newline = strchr(desc_short, '\n');
1670 + if (newline) {
1671 + *newline = '\0';
1672 + }
1673 +#ifndef IPKG_LIB
1674 + printf("%s - %s\n", pkg->name, desc_short);
1675 +#else
1676 + if (ipkg_cb_list) {
1677 + version_str = pkg_version_str_alloc(pkg);
1678 + ipkg_cb_list(pkg->name,desc_short,
1679 + version_str,
1680 + pkg->state_status,
1681 + p_userdata);
1682 + free(version_str);
1683 + }
1684 +#endif
1685 + }
1686 + pkg_vec_free(available);
1687 +
1688 + return 0;
1689 +}
1690 +
1691 +
1692 +static int ipkg_list_installed_cmd(ipkg_conf_t *conf, int argc, char **argv)
1693 +{
1694 + int i ;
1695 + pkg_vec_t *available;
1696 + pkg_t *pkg;
1697 + char desc_short[IPKG_LIST_DESCRIPTION_LENGTH];
1698 + char *newline;
1699 + char *pkg_name = NULL;
1700 + char *version_str;
1701 +
1702 + if (argc > 0) {
1703 + pkg_name = argv[0];
1704 + }
1705 + available = pkg_vec_alloc();
1706 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available);
1707 + for (i=0; i < available->len; i++) {
1708 + pkg = available->pkgs[i];
1709 + /* if we have package name or pattern and pkg does not match, then skip it */
1710 + if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
1711 + continue;
1712 + if (pkg->description) {
1713 + strncpy(desc_short, pkg->description, IPKG_LIST_DESCRIPTION_LENGTH);
1714 + } else {
1715 + desc_short[0] = '\0';
1716 + }
1717 + desc_short[IPKG_LIST_DESCRIPTION_LENGTH - 1] = '\0';
1718 + newline = strchr(desc_short, '\n');
1719 + if (newline) {
1720 + *newline = '\0';
1721 + }
1722 +#ifndef IPKG_LIB
1723 + printf("%s - %s\n", pkg->name, desc_short);
1724 +#else
1725 + if (ipkg_cb_list) {
1726 + version_str = pkg_version_str_alloc(pkg);
1727 + ipkg_cb_list(pkg->name,desc_short,
1728 + version_str,
1729 + pkg->state_status,
1730 + p_userdata);
1731 + free(version_str);
1732 + }
1733 +#endif
1734 + }
1735 +
1736 + return 0;
1737 +}
1738 +
1739 +static int ipkg_info_status_cmd(ipkg_conf_t *conf, int argc, char **argv, int installed_only)
1740 +{
1741 + int i;
1742 + pkg_vec_t *available;
1743 + pkg_t *pkg;
1744 + char *pkg_name = NULL;
1745 + char **pkg_fields = NULL;
1746 + int n_fields = 0;
1747 + char *buff ; // = (char *)malloc(1);
1748 +
1749 + if (argc > 0) {
1750 + pkg_name = argv[0];
1751 + }
1752 + if (argc > 1) {
1753 + pkg_fields = &argv[1];
1754 + n_fields = argc - 1;
1755 + }
1756 +
1757 + available = pkg_vec_alloc();
1758 + if (installed_only)
1759 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available);
1760 + else
1761 + pkg_hash_fetch_available(&conf->pkg_hash, available);
1762 + for (i=0; i < available->len; i++) {
1763 + pkg = available->pkgs[i];
1764 + if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
1765 + continue;
1766 + }
1767 +#ifndef IPKG_LIB
1768 + if (n_fields) {
1769 + for (j = 0; j < n_fields; j++)
1770 + pkg_print_field(pkg, stdout, pkg_fields[j]);
1771 + } else {
1772 + pkg_print_info(pkg, stdout);
1773 + }
1774 +#else
1775 +
1776 + buff = pkg_formatted_info(pkg);
1777 + if ( buff ) {
1778 + if (ipkg_cb_status) ipkg_cb_status(pkg->name,
1779 + pkg->state_status,
1780 + buff,
1781 + p_userdata);
1782 +/*
1783 + We should not forget that actually the pointer is allocated.
1784 + We need to free it :) ( Thanks florian for seeing the error )
1785 +*/
1786 + free(buff);
1787 + }
1788 +#endif
1789 + if (conf->verbosity > 1) {
1790 + conffile_list_elt_t *iter;
1791 + for (iter = pkg->conffiles.head; iter; iter = iter->next) {
1792 + conffile_t *cf = iter->data;
1793 + int modified = conffile_has_been_modified(conf, cf);
1794 + ipkg_message(conf, IPKG_NOTICE, "conffile=%s md5sum=%s modified=%d\n",
1795 + cf->name, cf->value, modified);
1796 + }
1797 + }
1798 + }
1799 +#ifndef IPKG_LIB
1800 + if (buff)
1801 + free(buff);
1802 +#endif
1803 + pkg_vec_free(available);
1804 +
1805 + return 0;
1806 +}
1807 +
1808 +static int ipkg_info_cmd(ipkg_conf_t *conf, int argc, char **argv)
1809 +{
1810 + return ipkg_info_status_cmd(conf, argc, argv, 0);
1811 +}
1812 +
1813 +static int ipkg_status_cmd(ipkg_conf_t *conf, int argc, char **argv)
1814 +{
1815 + return ipkg_info_status_cmd(conf, argc, argv, 1);
1816 +}
1817 +
1818 +static int ipkg_configure_cmd(ipkg_conf_t *conf, int argc, char **argv)
1819 +{
1820 +
1821 + int err;
1822 + if (argc > 0) {
1823 + char *pkg_name = NULL;
1824 +
1825 + pkg_name = argv[0];
1826 +
1827 + err = ipkg_configure_packages (conf, pkg_name);
1828 +
1829 + } else {
1830 + err = ipkg_configure_packages (conf, NULL);
1831 + }
1832 +
1833 + write_status_files_if_changed(conf);
1834 +
1835 + return err;
1836 +}
1837 +
1838 +static int ipkg_install_pending_cmd(ipkg_conf_t *conf, int argc, char **argv)
1839 +{
1840 + int i, err;
1841 + char *globpattern;
1842 + glob_t globbuf;
1843 +
1844 + sprintf_alloc(&globpattern, "%s/*" IPKG_PKG_EXTENSION, conf->pending_dir);
1845 + err = glob(globpattern, 0, NULL, &globbuf);
1846 + free(globpattern);
1847 + if (err) {
1848 + return 0;
1849 + }
1850 +
1851 + ipkg_message(conf, IPKG_NOTICE,
1852 + "The following packages in %s will now be installed.\n",
1853 + conf->pending_dir);
1854 + for (i = 0; i < globbuf.gl_pathc; i++) {
1855 + ipkg_message(conf, IPKG_NOTICE,
1856 + "%s%s", i == 0 ? "" : " ", globbuf.gl_pathv[i]);
1857 + }
1858 + ipkg_message(conf, IPKG_NOTICE, "\n");
1859 + for (i = 0; i < globbuf.gl_pathc; i++) {
1860 + err = ipkg_install_from_file(conf, globbuf.gl_pathv[i]);
1861 + if (err == 0) {
1862 + err = unlink(globbuf.gl_pathv[i]);
1863 + if (err) {
1864 + ipkg_message(conf, IPKG_ERROR,
1865 + "%s: ERROR: failed to unlink %s: %s\n",
1866 + __FUNCTION__, globbuf.gl_pathv[i], strerror(err));
1867 + return err;
1868 + }
1869 + }
1870 + }
1871 + globfree(&globbuf);
1872 +
1873 + return err;
1874 +}
1875 +
1876 +static int ipkg_remove_cmd(ipkg_conf_t *conf, int argc, char **argv)
1877 +{
1878 + int i,a,done;
1879 + pkg_t *pkg;
1880 + pkg_t *pkg_to_remove;
1881 + pkg_vec_t *available;
1882 + char *pkg_name = NULL;
1883 + global_conf = conf;
1884 + signal(SIGINT, sigint_handler);
1885 +
1886 +// ENH: Add the "no pkg removed" just in case.
1887 +
1888 + done = 0;
1889 +
1890 + available = pkg_vec_alloc();
1891 + pkg_info_preinstall_check(conf);
1892 + if ( argc > 0 ) {
1893 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available);
1894 + for (i=0; i < argc; i++) {
1895 + pkg_name = malloc(strlen(argv[i])+2);
1896 + strcpy(pkg_name,argv[i]);
1897 + for (a=0; a < available->len; a++) {
1898 + pkg = available->pkgs[a];
1899 + if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
1900 + continue;
1901 + }
1902 + if (conf->restrict_to_default_dest) {
1903 + pkg_to_remove = pkg_hash_fetch_installed_by_name_dest(&conf->pkg_hash,
1904 + pkg->name,
1905 + conf->default_dest);
1906 + } else {
1907 + pkg_to_remove = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name );
1908 + }
1909 +
1910 + if (pkg == NULL) {
1911 + ipkg_message(conf, IPKG_ERROR, "Package %s is not installed.\n", pkg->name);
1912 + continue;
1913 + }
1914 + if (pkg->state_status == SS_NOT_INSTALLED) { // Added the control, so every already removed package could be skipped
1915 + ipkg_message(conf, IPKG_ERROR, "Package seems to be %s not installed (STATUS = NOT_INSTALLED).\n", pkg->name);
1916 + continue;
1917 + }
1918 + ipkg_remove_pkg(conf, pkg_to_remove,0);
1919 + done = 1;
1920 + }
1921 + free (pkg_name);
1922 + }
1923 + pkg_vec_free(available);
1924 + } else {
1925 + pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1926 + int i;
1927 + int flagged_pkg_count = 0;
1928 + int removed;
1929 +
1930 + pkg_hash_fetch_all_installed(&conf->pkg_hash, installed_pkgs);
1931 +
1932 + for (i = 0; i < installed_pkgs->len; i++) {
1933 + pkg_t *pkg = installed_pkgs->pkgs[i];
1934 + if (pkg->state_flag & SF_USER) {
1935 + flagged_pkg_count++;
1936 + } else {
1937 + if (!pkg_has_installed_dependents(conf, pkg->parent, pkg, NULL))
1938 + ipkg_message(conf, IPKG_NOTICE, "Non-user leaf package: %s\n", pkg->name);
1939 + }
1940 + }
1941 + if (!flagged_pkg_count) {
1942 + ipkg_message(conf, IPKG_NOTICE, "No packages flagged as installed by user, \n"
1943 + "so refusing to uninstall unflagged non-leaf packages\n");
1944 + return 0;
1945 + }
1946 +
1947 + /* find packages not flagged SF_USER (i.e., installed to
1948 + * satisfy a dependence) and not having any dependents, and
1949 + * remove them */
1950 + do {
1951 + removed = 0;
1952 + for (i = 0; i < installed_pkgs->len; i++) {
1953 + pkg_t *pkg = installed_pkgs->pkgs[i];
1954 + if (!(pkg->state_flag & SF_USER)
1955 + && !pkg_has_installed_dependents(conf, pkg->parent, pkg, NULL)) {
1956 + removed++;
1957 + ipkg_message(conf, IPKG_NOTICE, "Removing non-user leaf package %s\n");
1958 + ipkg_remove_pkg(conf, pkg,0);
1959 + done = 1;
1960 + }
1961 + }
1962 + } while (removed);
1963 + pkg_vec_free(installed_pkgs);
1964 + }
1965 +
1966 + if ( done == 0 )
1967 + ipkg_message(conf, IPKG_NOTICE, "No packages removed.\n");
1968 +
1969 + write_status_files_if_changed(conf);
1970 + return 0;
1971 +}
1972 +
1973 +static int ipkg_purge_cmd(ipkg_conf_t *conf, int argc, char **argv)
1974 +{
1975 + int i;
1976 + pkg_t *pkg;
1977 +
1978 + global_conf = conf;
1979 + signal(SIGINT, sigint_handler);
1980 +
1981 + pkg_info_preinstall_check(conf);
1982 +
1983 + for (i=0; i < argc; i++) {
1984 + if (conf->restrict_to_default_dest) {
1985 + pkg = pkg_hash_fetch_installed_by_name_dest(&conf->pkg_hash,
1986 + argv[i],
1987 + conf->default_dest);
1988 + } else {
1989 + pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, argv[i]);
1990 + }
1991 +
1992 + if (pkg == NULL) {
1993 + ipkg_message(conf, IPKG_ERROR,
1994 + "Package %s is not installed.\n", argv[i]);
1995 + continue;
1996 + }
1997 + ipkg_purge_pkg(conf, pkg);
1998 + }
1999 +
2000 + write_status_files_if_changed(conf);
2001 + return 0;
2002 +}
2003 +
2004 +static int ipkg_flag_cmd(ipkg_conf_t *conf, int argc, char **argv)
2005 +{
2006 + int i;
2007 + pkg_t *pkg;
2008 + const char *flags = argv[0];
2009 +
2010 + global_conf = conf;
2011 + signal(SIGINT, sigint_handler);
2012 +
2013 + for (i=1; i < argc; i++) {
2014 + if (conf->restrict_to_default_dest) {
2015 + pkg = pkg_hash_fetch_installed_by_name_dest(&conf->pkg_hash,
2016 + argv[i],
2017 + conf->default_dest);
2018 + } else {
2019 + pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, argv[i]);
2020 + }
2021 +
2022 + if (pkg == NULL) {
2023 + ipkg_message(conf, IPKG_ERROR,
2024 + "Package %s is not installed.\n", argv[i]);
2025 + continue;
2026 + }
2027 + if (( strcmp(flags,"hold")==0)||( strcmp(flags,"noprune")==0)||
2028 + ( strcmp(flags,"user")==0)||( strcmp(flags,"ok")==0)) {
2029 + pkg->state_flag = pkg_state_flag_from_str(flags);
2030 + }
2031 +/* pb_ asked this feature 03292004 */
2032 +/* Actually I will use only this two, but this is an open for various status */
2033 + if (( strcmp(flags,"installed")==0)||( strcmp(flags,"unpacked")==0)){
2034 + pkg->state_status = pkg_state_status_from_str(flags);
2035 + }
2036 + ipkg_state_changed++;
2037 + ipkg_message(conf, IPKG_NOTICE,
2038 + "Setting flags for package %s to %s\n",
2039 + pkg->name, flags);
2040 + }
2041 +
2042 + write_status_files_if_changed(conf);
2043 + return 0;
2044 +}
2045 +
2046 +static int ipkg_files_cmd(ipkg_conf_t *conf, int argc, char **argv)
2047 +{
2048 + pkg_t *pkg;
2049 + str_list_t *installed_files;
2050 + str_list_elt_t *iter;
2051 + char *pkg_version;
2052 + size_t buff_len = 8192;
2053 + size_t used_len;
2054 + char *buff ;
2055 +
2056 + buff = (char *)malloc(buff_len);
2057 + if ( buff == NULL ) {
2058 + fprintf( stderr,"%s: Unable to allocate memory \n",__FUNCTION__);
2059 + return ENOMEM;
2060 + }
2061 +
2062 + if (argc < 1) {
2063 + return EINVAL;
2064 + }
2065 +
2066 + pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash,
2067 + argv[0]);
2068 + if (pkg == NULL) {
2069 + ipkg_message(conf, IPKG_ERROR,
2070 + "Package %s not installed.\n", argv[0]);
2071 + return 0;
2072 + }
2073 +
2074 + installed_files = pkg_get_installed_files(pkg);
2075 + pkg_version = pkg_version_str_alloc(pkg);
2076 +
2077 +#ifndef IPKG_LIB
2078 + printf("Package %s (%s) is installed on %s and has the following files:\n",
2079 + pkg->name, pkg_version, pkg->dest->name);
2080 + for (iter = installed_files->head; iter; iter = iter->next) {
2081 + puts(iter->data);
2082 + }
2083 +#else
2084 + if (buff) {
2085 + try_again:
2086 + used_len = snprintf(buff, buff_len, "Package %s (%s) is installed on %s and has the following files:\n",
2087 + pkg->name, pkg_version, pkg->dest->name) + 1;
2088 + if (used_len > buff_len) {
2089 + buff_len *= 2;
2090 + buff = realloc (buff, buff_len);
2091 + goto try_again;
2092 + }
2093 + for (iter = installed_files->head; iter; iter = iter->next) {
2094 + used_len += strlen (iter->data) + 1;
2095 + while (buff_len <= used_len) {
2096 + buff_len *= 2;
2097 + buff = realloc (buff, buff_len);
2098 + }
2099 + strncat(buff, iter->data, buff_len);
2100 + strncat(buff, "\n", buff_len);
2101 + }
2102 + if (ipkg_cb_list) ipkg_cb_list(pkg->name,
2103 + buff,
2104 + pkg_version_str_alloc(pkg),
2105 + pkg->state_status,
2106 + p_userdata);
2107 + free(buff);
2108 + }
2109 +#endif
2110 +
2111 + free(pkg_version);
2112 + pkg_free_installed_files(pkg);
2113 +
2114 + return 0;
2115 +}
2116 +
2117 +static int ipkg_depends_cmd(ipkg_conf_t *conf, int argc, char **argv)
2118 +{
2119 +
2120 + if (argc > 0) {
2121 + pkg_vec_t *available_pkgs = pkg_vec_alloc();
2122 + const char *rel_str = "depends on";
2123 + int i;
2124 +
2125 + pkg_info_preinstall_check(conf);
2126 +
2127 + if (conf->query_all)
2128 + pkg_hash_fetch_available(&conf->pkg_hash, available_pkgs);
2129 + else
2130 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available_pkgs);
2131 + for (i = 0; i < argc; i++) {
2132 + const char *target = argv[i];
2133 + int j;
2134 +
2135 + ipkg_message(conf, IPKG_ERROR, "target=%s\n", target);
2136 +
2137 + for (j = 0; j < available_pkgs->len; j++) {
2138 + pkg_t *pkg = available_pkgs->pkgs[j];
2139 + if (fnmatch(target, pkg->name, 0) == 0) {
2140 + int k;
2141 + int count = pkg->depends_count + pkg->pre_depends_count;
2142 + ipkg_message(conf, IPKG_ERROR, "What %s (arch=%s) %s\n",
2143 + target, pkg->architecture, rel_str);
2144 + for (k = 0; k < count; k++) {
2145 + compound_depend_t *cdepend = &pkg->depends[k];
2146 + int l;
2147 + for (l = 0; l < cdepend->possibility_count; l++) {
2148 + depend_t *possibility = cdepend->possibilities[l];
2149 + ipkg_message(conf, IPKG_ERROR, " %s", possibility->pkg->name);
2150 + if (conf->verbosity > 0) {
2151 + // char *ver = abstract_pkg_version_str_alloc(possibility->pkg);
2152 + ipkg_message(conf, IPKG_NOTICE, " %s", possibility->version);
2153 + if (possibility->version) {
2154 + char *typestr = NULL;
2155 + switch (possibility->constraint) {
2156 + case NONE: typestr = "none"; break;
2157 + case EARLIER: typestr = "<"; break;
2158 + case EARLIER_EQUAL: typestr = "<="; break;
2159 + case EQUAL: typestr = "="; break;
2160 + case LATER_EQUAL: typestr = ">="; break;
2161 + case LATER: typestr = ">"; break;
2162 + }
2163 + ipkg_message(conf, IPKG_NOTICE, " (%s %s)", typestr, possibility->version);
2164 + }
2165 + // free(ver);
2166 + }
2167 + ipkg_message(conf, IPKG_ERROR, "\n");
2168 + }
2169 + }
2170 + }
2171 + }
2172 + }
2173 + pkg_vec_free(available_pkgs);
2174 + }
2175 + return 0;
2176 +}
2177 +
2178 +enum what_field_type {
2179 + WHATDEPENDS,
2180 + WHATCONFLICTS,
2181 + WHATPROVIDES,
2182 + WHATREPLACES,
2183 + WHATRECOMMENDS,
2184 + WHATSUGGESTS
2185 +};
2186 +
2187 +static int ipkg_what_depends_conflicts_cmd(ipkg_conf_t *conf, enum what_field_type what_field_type, int recursive, int argc, char **argv)
2188 +{
2189 +
2190 + if (argc > 0) {
2191 + pkg_vec_t *available_pkgs = pkg_vec_alloc();
2192 + const char *rel_str = NULL;
2193 + int i;
2194 + int changed;
2195 +
2196 + switch (what_field_type) {
2197 + case WHATDEPENDS: rel_str = "depends on"; break;
2198 + case WHATCONFLICTS: rel_str = "conflicts with"; break;
2199 + case WHATSUGGESTS: rel_str = "suggests"; break;
2200 + case WHATRECOMMENDS: rel_str = "recommends"; break;
2201 + case WHATPROVIDES: rel_str = "provides"; break;
2202 + case WHATREPLACES: rel_str = "replaces"; break;
2203 + }
2204 +
2205 + if (conf->query_all)
2206 + pkg_hash_fetch_available(&conf->pkg_hash, available_pkgs);
2207 + else
2208 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available_pkgs);
2209 +
2210 + /* mark the root set */
2211 + pkg_vec_clear_marks(available_pkgs);
2212 + ipkg_message(conf, IPKG_NOTICE, "Root set:\n");
2213 + for (i = 0; i < argc; i++) {
2214 + const char *dependee_pattern = argv[i];
2215 + pkg_vec_mark_if_matches(available_pkgs, dependee_pattern);
2216 + }
2217 + for (i = 0; i < available_pkgs->len; i++) {
2218 + pkg_t *pkg = available_pkgs->pkgs[i];
2219 + if (pkg->state_flag & SF_MARKED) {
2220 + /* mark the parent (abstract) package */
2221 + pkg_mark_provides(pkg);
2222 + ipkg_message(conf, IPKG_NOTICE, " %s\n", pkg->name);
2223 + }
2224 + }
2225 +
2226 + ipkg_message(conf, IPKG_NOTICE, "What %s root set\n", rel_str);
2227 + do {
2228 + int j;
2229 + changed = 0;
2230 +
2231 + for (j = 0; j < available_pkgs->len; j++) {
2232 + pkg_t *pkg = available_pkgs->pkgs[j];
2233 + int k;
2234 + int count = ((what_field_type == WHATCONFLICTS)
2235 + ? pkg->conflicts_count
2236 + : pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count);
2237 + /* skip this package if it is already marked */
2238 + if (pkg->parent->state_flag & SF_MARKED) {
2239 + continue;
2240 + }
2241 + for (k = 0; k < count; k++) {
2242 + compound_depend_t *cdepend =
2243 + (what_field_type == WHATCONFLICTS) ? &pkg->conflicts[k] : &pkg->depends[k];
2244 + int l;
2245 + for (l = 0; l < cdepend->possibility_count; l++) {
2246 + depend_t *possibility = cdepend->possibilities[l];
2247 + if (possibility->pkg->state_flag & SF_MARKED) {
2248 + /* mark the depending package so we won't visit it again */
2249 + pkg->state_flag |= SF_MARKED;
2250 + pkg_mark_provides(pkg);
2251 + changed++;
2252 +
2253 + ipkg_message(conf, IPKG_NOTICE, " %s", pkg->name);
2254 + if (conf->verbosity > 0) {
2255 + char *ver = pkg_version_str_alloc(pkg);
2256 + ipkg_message(conf, IPKG_NOTICE, " %s", ver);
2257 + ipkg_message(conf, IPKG_NOTICE, "\t%s %s", rel_str, possibility->pkg->name);
2258 + if (possibility->version) {
2259 + char *typestr = NULL;
2260 + switch (possibility->constraint) {
2261 + case NONE: typestr = "none"; break;
2262 + case EARLIER: typestr = "<"; break;
2263 + case EARLIER_EQUAL: typestr = "<="; break;
2264 + case EQUAL: typestr = "="; break;
2265 + case LATER_EQUAL: typestr = ">="; break;
2266 + case LATER: typestr = ">"; break;
2267 + }
2268 + ipkg_message(conf, IPKG_NOTICE, " (%s %s)", typestr, possibility->version);
2269 + }
2270 + free(ver);
2271 + if (!pkg_dependence_satisfiable(conf, possibility))
2272 + ipkg_message(conf, IPKG_NOTICE, " unsatisfiable");
2273 + }
2274 + ipkg_message(conf, IPKG_NOTICE, "\n");
2275 + goto next_package;
2276 + }
2277 + }
2278 + }
2279 + next_package:
2280 + ;
2281 + }
2282 + } while (changed && recursive);
2283 + pkg_vec_free(available_pkgs);
2284 + }
2285 +
2286 + return 0;
2287 +}
2288 +
2289 +int pkg_mark_provides(pkg_t *pkg)
2290 +{
2291 + int provides_count = pkg->provides_count;
2292 + abstract_pkg_t **provides = pkg->provides;
2293 + int i;
2294 + pkg->parent->state_flag |= SF_MARKED;
2295 + for (i = 0; i < provides_count; i++) {
2296 + provides[i]->state_flag |= SF_MARKED;
2297 + }
2298 + return 0;
2299 +}
2300 +
2301 +static int ipkg_whatdepends_recursively_cmd(ipkg_conf_t *conf, int argc, char **argv)
2302 +{
2303 + return ipkg_what_depends_conflicts_cmd(conf, WHATDEPENDS, 1, argc, argv);
2304 +}
2305 +static int ipkg_whatdepends_cmd(ipkg_conf_t *conf, int argc, char **argv)
2306 +{
2307 + return ipkg_what_depends_conflicts_cmd(conf, WHATDEPENDS, 0, argc, argv);
2308 +}
2309 +
2310 +static int ipkg_whatsuggests_cmd(ipkg_conf_t *conf, int argc, char **argv)
2311 +{
2312 + return ipkg_what_depends_conflicts_cmd(conf, WHATSUGGESTS, 0, argc, argv);
2313 +}
2314 +
2315 +static int ipkg_whatrecommends_cmd(ipkg_conf_t *conf, int argc, char **argv)
2316 +{
2317 + return ipkg_what_depends_conflicts_cmd(conf, WHATRECOMMENDS, 0, argc, argv);
2318 +}
2319 +
2320 +static int ipkg_whatconflicts_cmd(ipkg_conf_t *conf, int argc, char **argv)
2321 +{
2322 + return ipkg_what_depends_conflicts_cmd(conf, WHATCONFLICTS, 0, argc, argv);
2323 +}
2324 +
2325 +static int ipkg_what_provides_replaces_cmd(ipkg_conf_t *conf, enum what_field_type what_field_type, int argc, char **argv)
2326 +{
2327 +
2328 + if (argc > 0) {
2329 + pkg_vec_t *available_pkgs = pkg_vec_alloc();
2330 + const char *rel_str = (what_field_type == WHATPROVIDES ? "provides" : "replaces");
2331 + int i;
2332 +
2333 + pkg_info_preinstall_check(conf);
2334 +
2335 + if (conf->query_all)
2336 + pkg_hash_fetch_available(&conf->pkg_hash, available_pkgs);
2337 + else
2338 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available_pkgs);
2339 + for (i = 0; i < argc; i++) {
2340 + const char *target = argv[i];
2341 + int j;
2342 +
2343 + ipkg_message(conf, IPKG_ERROR, "What %s %s\n",
2344 + rel_str, target);
2345 + for (j = 0; j < available_pkgs->len; j++) {
2346 + pkg_t *pkg = available_pkgs->pkgs[j];
2347 + int k;
2348 + int count = (what_field_type == WHATPROVIDES) ? pkg->provides_count : pkg->replaces_count;
2349 + for (k = 0; k < count; k++) {
2350 + abstract_pkg_t *apkg =
2351 + ((what_field_type == WHATPROVIDES)
2352 + ? pkg->provides[k]
2353 + : pkg->replaces[k]);
2354 + if (fnmatch(target, apkg->name, 0) == 0) {
2355 + ipkg_message(conf, IPKG_ERROR, " %s", pkg->name);
2356 + if (strcmp(target, apkg->name) != 0)
2357 + ipkg_message(conf, IPKG_ERROR, "\t%s %s\n", rel_str, apkg->name);
2358 + ipkg_message(conf, IPKG_ERROR, "\n");
2359 + }
2360 + }
2361 + }
2362 + }
2363 + pkg_vec_free(available_pkgs);
2364 + }
2365 + return 0;
2366 +}
2367 +
2368 +static int ipkg_whatprovides_cmd(ipkg_conf_t *conf, int argc, char **argv)
2369 +{
2370 + return ipkg_what_provides_replaces_cmd(conf, WHATPROVIDES, argc, argv);
2371 +}
2372 +
2373 +static int ipkg_whatreplaces_cmd(ipkg_conf_t *conf, int argc, char **argv)
2374 +{
2375 + return ipkg_what_provides_replaces_cmd(conf, WHATREPLACES, argc, argv);
2376 +}
2377 +
2378 +static int ipkg_search_cmd(ipkg_conf_t *conf, int argc, char **argv)
2379 +{
2380 + int i;
2381 +
2382 + pkg_vec_t *installed;
2383 + pkg_t *pkg;
2384 + str_list_t *installed_files;
2385 + str_list_elt_t *iter;
2386 + char *installed_file;
2387 +
2388 + if (argc < 1) {
2389 + return EINVAL;
2390 + }
2391 +
2392 + installed = pkg_vec_alloc();
2393 + pkg_hash_fetch_all_installed(&conf->pkg_hash, installed);
2394 +
2395 + for (i=0; i < installed->len; i++) {
2396 + pkg = installed->pkgs[i];
2397 +
2398 + installed_files = pkg_get_installed_files(pkg);
2399 +
2400 + for (iter = installed_files->head; iter; iter = iter->next) {
2401 + installed_file = iter->data;
2402 + if (fnmatch(argv[0], installed_file, 0)==0) {
2403 +#ifndef IPKG_LIB
2404 + printf("%s: %s\n", pkg->name, installed_file);
2405 +#else
2406 + if (ipkg_cb_list) ipkg_cb_list(pkg->name,
2407 + installed_file,
2408 + pkg_version_str_alloc(pkg),
2409 + pkg->state_status, p_userdata);
2410 +#endif
2411 + }
2412 + }
2413 +
2414 + pkg_free_installed_files(pkg);
2415 + }
2416 +
2417 + /* XXX: CLEANUP: It's not obvious from the name of
2418 + pkg_hash_fetch_all_installed that we need to call
2419 + pkg_vec_free to avoid a memory leak. */
2420 + pkg_vec_free(installed);
2421 +
2422 + return 0;
2423 +}
2424 +
2425 +static int ipkg_compare_versions_cmd(ipkg_conf_t *conf, int argc, char **argv)
2426 +{
2427 + if (argc == 3) {
2428 + /* this is a bit gross */
2429 + struct pkg p1, p2;
2430 + parseVersion(&p1, argv[0]);
2431 + parseVersion(&p2, argv[2]);
2432 + return pkg_version_satisfied(&p1, &p2, argv[1]);
2433 + } else {
2434 + ipkg_message(conf, IPKG_ERROR,
2435 + "ipkg compare_versions <v1> <op> <v2>\n"
2436 + "<op> is one of <= >= << >> =\n");
2437 + return -1;
2438 + }
2439 +}
2440 +
2441 +#ifndef HOST_CPU_STR
2442 +#define HOST_CPU_STR__(X) #X
2443 +#define HOST_CPU_STR_(X) HOST_CPU_STR__(X)
2444 +#define HOST_CPU_STR HOST_CPU_STR_(HOST_CPU_FOO)
2445 +#endif
2446 +
2447 +static int ipkg_print_architecture_cmd(ipkg_conf_t *conf, int argc, char **argv)
2448 +{
2449 + nv_pair_list_elt_t *l;
2450 +
2451 + l = conf->arch_list.head;
2452 + while (l) {
2453 + nv_pair_t *nv = l->data;
2454 + printf("arch %s %s\n", nv->name, nv->value);
2455 + l = l->next;
2456 + }
2457 + return 0;
2458 +}
2459 +
2460 +
2461 diff -ruN busybox-1.3.1-orig/archival/libipkg/ipkg_cmd.h busybox-1.3.1-911/archival/libipkg/ipkg_cmd.h
2462 --- busybox-1.3.1-orig/archival/libipkg/ipkg_cmd.h 1970-01-01 01:00:00.000000000 +0100
2463 +++ busybox-1.3.1-911/archival/libipkg/ipkg_cmd.h 2006-12-27 19:41:04.000000000 +0100
2464 @@ -0,0 +1,46 @@
2465 +/* ipkg_cmd.h - the itsy package management system
2466 +
2467 + Carl D. Worth
2468 +
2469 + Copyright (C) 2001 University of Southern California
2470 +
2471 + This program is free software; you can redistribute it and/or
2472 + modify it under the terms of the GNU General Public License as
2473 + published by the Free Software Foundation; either version 2, or (at
2474 + your option) any later version.
2475 +
2476 + This program is distributed in the hope that it will be useful, but
2477 + WITHOUT ANY WARRANTY; without even the implied warranty of
2478 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2479 + General Public License for more details.
2480 +*/
2481 +
2482 +#ifndef IPKG_CMD_H
2483 +#define IPKG_CMD_H
2484 +
2485 +typedef int (*ipkg_cmd_fun_t)(ipkg_conf_t *conf, int argc, const char **argv);
2486 +
2487 +struct ipkg_cmd
2488 +{
2489 + char *name;
2490 + int requires_args;
2491 + ipkg_cmd_fun_t fun;
2492 +};
2493 +typedef struct ipkg_cmd ipkg_cmd_t;
2494 +
2495 +ipkg_cmd_t *ipkg_cmd_find(const char *name);
2496 +#ifdef IPKG_LIB
2497 +int ipkg_cmd_exec(ipkg_cmd_t *cmd, ipkg_conf_t *conf, int argc,
2498 + const char **argv, void *userdata);
2499 +#else
2500 +int ipkg_cmd_exec(ipkg_cmd_t *cmd, ipkg_conf_t *conf, int argc, const char **argv);
2501 +#endif
2502 +int ipkg_multiple_files_scan (ipkg_conf_t *conf, int argc, char *argv[]);
2503 +/* install any packges with state_want == SW_INSTALL */
2504 +int ipkg_install_wanted_packages(ipkg_conf_t *conf);
2505 +/* ensure that all dependences are satisfied */
2506 +int ipkg_configure_packages(ipkg_conf_t *conf, char *pkg_name);
2507 +
2508 +int pkg_mark_provides(pkg_t *pkg);
2509 +
2510 +#endif
2511 diff -ruN busybox-1.3.1-orig/archival/libipkg/ipkg_conf.c busybox-1.3.1-911/archival/libipkg/ipkg_conf.c
2512 --- busybox-1.3.1-orig/archival/libipkg/ipkg_conf.c 1970-01-01 01:00:00.000000000 +0100
2513 +++ busybox-1.3.1-911/archival/libipkg/ipkg_conf.c 2006-12-27 19:41:04.000000000 +0100
2514 @@ -0,0 +1,711 @@
2515 +/* ipkg_conf.c - the itsy package management system
2516 +
2517 + Carl D. Worth
2518 +
2519 + Copyright (C) 2001 University of Southern California
2520 +
2521 + This program is free software; you can redistribute it and/or
2522 + modify it under the terms of the GNU General Public License as
2523 + published by the Free Software Foundation; either version 2, or (at
2524 + your option) any later version.
2525 +
2526 + This program is distributed in the hope that it will be useful, but
2527 + WITHOUT ANY WARRANTY; without even the implied warranty of
2528 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2529 + General Public License for more details.
2530 +*/
2531 +
2532 +#include <glob.h>
2533 +
2534 +#include "ipkg.h"
2535 +#include "ipkg_conf.h"
2536 +
2537 +#include "xregex.h"
2538 +#include "sprintf_alloc.h"
2539 +#include "ipkg_conf.h"
2540 +#include "ipkg_message.h"
2541 +#include "file_util.h"
2542 +#include "str_util.h"
2543 +#include "xsystem.h"
2544 +
2545 +
2546 +ipkg_conf_t *global_conf;
2547 +
2548 +static int ipkg_conf_parse_file(ipkg_conf_t *conf, const char *filename,
2549 + pkg_src_list_t *pkg_src_list,
2550 + nv_pair_list_t *tmp_dest_nv_pair_list,
2551 + char **tmp_lists_dir);
2552 +static int ipkg_init_options_array(const ipkg_conf_t *conf, ipkg_option_t **options);
2553 +static int ipkg_conf_set_option(const ipkg_option_t *options,
2554 + const char *name, const char *value);
2555 +static int ipkg_conf_set_default_dest(ipkg_conf_t *conf,
2556 + const char *default_dest_name);
2557 +static int set_and_load_pkg_src_list(ipkg_conf_t *conf,
2558 + pkg_src_list_t *nv_pair_list);
2559 +static int set_and_load_pkg_dest_list(ipkg_conf_t *conf,
2560 + nv_pair_list_t *nv_pair_list, char * lists_dir);
2561 +
2562 +int ipkg_init_options_array(const ipkg_conf_t *conf, ipkg_option_t **options)
2563 +{
2564 + ipkg_option_t tmp[] = {
2565 + { "force_defaults", IPKG_OPT_TYPE_BOOL, &conf->force_defaults },
2566 + { "force_depends", IPKG_OPT_TYPE_BOOL, &conf->force_depends },
2567 + { "force_overwrite", IPKG_OPT_TYPE_BOOL, &conf->force_overwrite },
2568 + { "force_downgrade", IPKG_OPT_TYPE_BOOL, &conf->force_downgrade },
2569 + { "force_reinstall", IPKG_OPT_TYPE_BOOL, &conf->force_reinstall },
2570 + { "force_space", IPKG_OPT_TYPE_BOOL, &conf->force_space },
2571 + { "ftp_proxy", IPKG_OPT_TYPE_STRING, &conf->ftp_proxy },
2572 + { "http_proxy", IPKG_OPT_TYPE_STRING, &conf->http_proxy },
2573 + { "multiple_providers", IPKG_OPT_TYPE_BOOL, &conf->multiple_providers },
2574 + { "no_proxy", IPKG_OPT_TYPE_STRING, &conf->no_proxy },
2575 + { "test", IPKG_OPT_TYPE_INT, &conf->noaction },
2576 + { "noaction", IPKG_OPT_TYPE_INT, &conf->noaction },
2577 + { "nodeps", IPKG_OPT_TYPE_BOOL, &conf->nodeps },
2578 + { "offline_root", IPKG_OPT_TYPE_STRING, &conf->offline_root },
2579 + { "offline_root_post_script_cmd", IPKG_OPT_TYPE_STRING, &conf->offline_root_post_script_cmd },
2580 + { "offline_root_pre_script_cmd", IPKG_OPT_TYPE_STRING, &conf->offline_root_pre_script_cmd },
2581 + { "proxy_passwd", IPKG_OPT_TYPE_STRING, &conf->proxy_passwd },
2582 + { "proxy_user", IPKG_OPT_TYPE_STRING, &conf->proxy_user },
2583 + { "query-all", IPKG_OPT_TYPE_BOOL, &conf->query_all },
2584 + { "verbose-wget", IPKG_OPT_TYPE_BOOL, &conf->verbose_wget },
2585 + { "verbosity", IPKG_OPT_TYPE_BOOL, &conf->verbosity },
2586 + { NULL }
2587 + };
2588 +
2589 + *options = (ipkg_option_t *)malloc(sizeof(tmp));
2590 + if ( options == NULL ){
2591 + fprintf(stderr,"%s: Unable to allocate memory\n",__FUNCTION__);
2592 + return -1;
2593 + }
2594 +
2595 + memcpy(*options, tmp, sizeof(tmp));
2596 + return 0;
2597 +};
2598 +
2599 +static void ipkg_conf_override_string(char **conf_str, char *arg_str)
2600 +{
2601 + if (arg_str) {
2602 + if (*conf_str) {
2603 + free(*conf_str);
2604 + }
2605 + *conf_str = strdup(arg_str);
2606 + }
2607 +}
2608 +
2609 +static void ipkg_conf_free_string(char **conf_str)
2610 +{
2611 + if (*conf_str) {
2612 + free(*conf_str);
2613 + *conf_str = NULL;
2614 + }
2615 +}
2616 +
2617 +int ipkg_conf_init(ipkg_conf_t *conf, const args_t *args)
2618 +{
2619 + int err;
2620 + char *tmp_dir_base;
2621 + nv_pair_list_t tmp_dest_nv_pair_list;
2622 + char * lists_dir =NULL;
2623 + glob_t globbuf;
2624 + char *etc_ipkg_conf_pattern = "/etc/ipkg/*.conf";
2625 + char *pending_dir =NULL;
2626 +
2627 + memset(conf, 0, sizeof(ipkg_conf_t));
2628 +
2629 + pkg_src_list_init(&conf->pkg_src_list);
2630 +
2631 + nv_pair_list_init(&tmp_dest_nv_pair_list);
2632 + pkg_dest_list_init(&conf->pkg_dest_list);
2633 +
2634 + nv_pair_list_init(&conf->arch_list);
2635 +
2636 + conf->restrict_to_default_dest = 0;
2637 + conf->default_dest = NULL;
2638 +
2639 +
2640 + if (args->tmp_dir)
2641 + tmp_dir_base = args->tmp_dir;
2642 + else
2643 + tmp_dir_base = getenv("TMPDIR");
2644 + sprintf_alloc(&conf->tmp_dir, "%s/%s",
2645 + tmp_dir_base ? tmp_dir_base : IPKG_CONF_DEFAULT_TMP_DIR_BASE,
2646 + IPKG_CONF_TMP_DIR_SUFFIX);
2647 + conf->tmp_dir = mkdtemp(conf->tmp_dir);
2648 + if (conf->tmp_dir == NULL) {
2649 + fprintf(stderr, "%s: Failed to create temporary directory `%s': %s\n",
2650 + __FUNCTION__, conf->tmp_dir, strerror(errno));
2651 + return errno;
2652 + }
2653 +
2654 + conf->force_depends = 0;
2655 + conf->force_defaults = 0;
2656 + conf->force_overwrite = 0;
2657 + conf->force_downgrade = 0;
2658 + conf->force_reinstall = 0;
2659 + conf->force_space = 0;
2660 + conf->force_removal_of_essential_packages = 0;
2661 + conf->force_removal_of_dependent_packages = 0;
2662 + conf->nodeps = 0;
2663 + conf->verbose_wget = 0;
2664 + conf->offline_root = NULL;
2665 + conf->offline_root_pre_script_cmd = NULL;
2666 + conf->offline_root_post_script_cmd = NULL;
2667 + conf->multiple_providers = 0;
2668 + conf->verbosity = 1;
2669 + conf->noaction = 0;
2670 +
2671 + conf->http_proxy = NULL;
2672 + conf->ftp_proxy = NULL;
2673 + conf->no_proxy = NULL;
2674 + conf->proxy_user = NULL;
2675 + conf->proxy_passwd = NULL;
2676 +
2677 + pkg_hash_init("pkg-hash", &conf->pkg_hash, IPKG_CONF_DEFAULT_HASH_LEN);
2678 + hash_table_init("file-hash", &conf->file_hash, IPKG_CONF_DEFAULT_HASH_LEN);
2679 + hash_table_init("obs-file-hash", &conf->obs_file_hash, IPKG_CONF_DEFAULT_HASH_LEN);
2680 + lists_dir=(char *)malloc(1);
2681 + lists_dir[0]='\0';
2682 + if (args->conf_file) {
2683 + struct stat stat_buf;
2684 + err = stat(args->conf_file, &stat_buf);
2685 + if (err == 0)
2686 + if (ipkg_conf_parse_file(conf, args->conf_file,
2687 + &conf->pkg_src_list, &tmp_dest_nv_pair_list,&lists_dir)<0) {
2688 + /* Memory leakage from ipkg_conf_parse-file */
2689 + return -1;
2690 + }
2691 +
2692 + }
2693 +
2694 + /* if (!lists_dir ){*/
2695 + if (strlen(lists_dir)<=1 ){
2696 + lists_dir = realloc(lists_dir,strlen(IPKG_CONF_LISTS_DIR)+2);
2697 + sprintf (lists_dir,"%s",IPKG_CONF_LISTS_DIR);
2698 + }
2699 +
2700 + if (args->offline_root) {
2701 + char *tmp = malloc(strlen(lists_dir) + strlen(args->offline_root) + 1);
2702 + sprintf_alloc(&tmp, "%s/%s",args->offline_root,lists_dir);
2703 + free(lists_dir);
2704 + lists_dir = tmp;
2705 + }
2706 +
2707 + pending_dir = malloc(strlen(lists_dir)+strlen("/pending")+5);
2708 + snprintf(pending_dir,strlen(lists_dir)+strlen("/pending") ,"%s%s",lists_dir,"/pending");
2709 +
2710 + conf->lists_dir = strdup(lists_dir);
2711 + conf->pending_dir = strdup(pending_dir);
2712 +
2713 + if (args->offline_root)
2714 + sprintf_alloc(&etc_ipkg_conf_pattern, "%s/etc/ipkg/*.conf", args->offline_root);
2715 + memset(&globbuf, 0, sizeof(globbuf));
2716 + err = glob(etc_ipkg_conf_pattern, 0, NULL, &globbuf);
2717 + if (!err) {
2718 + int i;
2719 + for (i = 0; i < globbuf.gl_pathc; i++) {
2720 + if (globbuf.gl_pathv[i])
2721 + if ( ipkg_conf_parse_file(conf, globbuf.gl_pathv[i],
2722 + &conf->pkg_src_list, &tmp_dest_nv_pair_list,&lists_dir)<0) {
2723 + /* Memory leakage from ipkg_conf_parse-file */
2724 + return -1;
2725 + }
2726 + }
2727 + }
2728 + globfree(&globbuf);
2729 +
2730 + /* if no architectures were defined, then default all, noarch, and host architecture */
2731 + if (nv_pair_list_empty(&conf->arch_list)) {
2732 + nv_pair_list_append(&conf->arch_list, "all", "1");
2733 + nv_pair_list_append(&conf->arch_list, "noarch", "1");
2734 + nv_pair_list_append(&conf->arch_list, HOST_CPU_STR, "10");
2735 + }
2736 +
2737 + /* Even if there is no conf file, we'll need at least one dest. */
2738 + if (tmp_dest_nv_pair_list.head == NULL) {
2739 + nv_pair_list_append(&tmp_dest_nv_pair_list,
2740 + IPKG_CONF_DEFAULT_DEST_NAME,
2741 + IPKG_CONF_DEFAULT_DEST_ROOT_DIR);
2742 + }
2743 +
2744 + /* After parsing the file, set options from command-line, (so that
2745 + command-line arguments take precedence) */
2746 + /* XXX: CLEANUP: The interaction between args.c and ipkg_conf.c
2747 + really needs to be cleaned up. There is so much duplication
2748 + right now it is ridiculous. Maybe ipkg_conf_t should just save
2749 + a pointer to args_t (which could then not be freed), rather
2750 + than duplicating every field here? */
2751 + if (args->force_depends) {
2752 + conf->force_depends = 1;
2753 + }
2754 + if (args->force_defaults) {
2755 + conf->force_defaults = 1;
2756 + }
2757 + if (args->force_overwrite) {
2758 + conf->force_overwrite = 1;
2759 + }
2760 + if (args->force_downgrade) {
2761 + conf->force_downgrade = 1;
2762 + }
2763 + if (args->force_reinstall) {
2764 + conf->force_reinstall = 1;
2765 + }
2766 + if (args->force_removal_of_dependent_packages) {
2767 + conf->force_removal_of_dependent_packages = 1;
2768 + }
2769 + if (args->force_removal_of_essential_packages) {
2770 + conf->force_removal_of_essential_packages = 1;
2771 + }
2772 + if (args->nodeps) {
2773 + conf->nodeps = 1;
2774 + }
2775 + if (args->noaction) {
2776 + conf->noaction = 1;
2777 + }
2778 + if (args->query_all) {
2779 + conf->query_all = 1;
2780 + }
2781 + if (args->verbose_wget) {
2782 + conf->verbose_wget = 1;
2783 + }
2784 + if (args->multiple_providers) {
2785 + conf->multiple_providers = 1;
2786 + }
2787 + if (args->verbosity != conf->verbosity) {
2788 + conf->verbosity = args->verbosity;
2789 + }
2790 +
2791 + ipkg_conf_override_string(&conf->offline_root,
2792 + args->offline_root);
2793 + ipkg_conf_override_string(&conf->offline_root_pre_script_cmd,
2794 + args->offline_root_pre_script_cmd);
2795 + ipkg_conf_override_string(&conf->offline_root_post_script_cmd,
2796 + args->offline_root_post_script_cmd);
2797 +
2798 +/* Pigi: added a flag to disable the checking of structures if the command does not need to
2799 + read anything from there.
2800 +*/
2801 + if ( !(args->nocheckfordirorfile)){
2802 + /* need to run load the source list before dest list -Jamey */
2803 + if ( !(args->noreadfeedsfile))
2804 + set_and_load_pkg_src_list(conf, &conf->pkg_src_list);
2805 +
2806 + /* Now that we have resolved conf->offline_root, we can commit to
2807 + the directory names for the dests and load in all the package
2808 + lists. */
2809 + set_and_load_pkg_dest_list(conf, &tmp_dest_nv_pair_list,lists_dir);
2810 +
2811 + if (args->dest) {
2812 + err = ipkg_conf_set_default_dest(conf, args->dest);
2813 + if (err) {
2814 + return err;
2815 + }
2816 + }
2817 + }
2818 + nv_pair_list_deinit(&tmp_dest_nv_pair_list);
2819 + free(lists_dir);
2820 + free(pending_dir);
2821 +
2822 + return 0;
2823 +}
2824 +
2825 +void ipkg_conf_deinit(ipkg_conf_t *conf)
2826 +{
2827 +#ifdef IPKG_DEBUG_NO_TMP_CLEANUP
2828 +#error
2829 + fprintf(stderr, "%s: Not cleaning up %s since ipkg compiled "
2830 + "with IPKG_DEBUG_NO_TMP_CLEANUP\n",
2831 + __FUNCTION__, conf->tmp_dir);
2832 +#else
2833 + int err;
2834 +
2835 + err = rmdir(conf->tmp_dir);
2836 + if (err) {
2837 + if (errno == ENOTEMPTY) {
2838 + char *cmd;
2839 + sprintf_alloc(&cmd, "rm -fr %s\n", conf->tmp_dir);
2840 + err = xsystem(cmd);
2841 + free(cmd);
2842 + }
2843 + if (err)
2844 + fprintf(stderr, "WARNING: Unable to remove temporary directory: %s: %s\n", conf->tmp_dir, strerror(errno));
2845 + }
2846 +#endif /* IPKG_DEBUG_NO_TMP_CLEANUP */
2847 +
2848 + free(conf->tmp_dir); /*XXX*/
2849 +
2850 + pkg_src_list_deinit(&conf->pkg_src_list);
2851 + pkg_dest_list_deinit(&conf->pkg_dest_list);
2852 + nv_pair_list_deinit(&conf->arch_list);
2853 + if (&conf->pkg_hash)
2854 + pkg_hash_deinit(&conf->pkg_hash);
2855 + if (&conf->file_hash)
2856 + hash_table_deinit(&conf->file_hash);
2857 + if (&conf->obs_file_hash)
2858 + hash_table_deinit(&conf->obs_file_hash);
2859 +
2860 + ipkg_conf_free_string(&conf->offline_root);
2861 + ipkg_conf_free_string(&conf->offline_root_pre_script_cmd);
2862 + ipkg_conf_free_string(&conf->offline_root_post_script_cmd);
2863 +
2864 + if (conf->verbosity > 1) {
2865 + int i;
2866 + hash_table_t *hashes[] = {
2867 + &conf->pkg_hash,
2868 + &conf->file_hash,
2869 + &conf->obs_file_hash };
2870 + for (i = 0; i < 3; i++) {
2871 + hash_table_t *hash = hashes[i];
2872 + int c = 0;
2873 + int n_conflicts = 0;
2874 + int j;
2875 + for (j = 0; j < hash->n_entries; j++) {
2876 + int len = 0;
2877 + hash_entry_t *e = &hash->entries[j];
2878 + if (e->next)
2879 + n_conflicts++;
2880 + while (e && e->key) {
2881 + len++;
2882 + e = e->next;
2883 + }
2884 + if (len > c)
2885 + c = len;
2886 + }
2887 + ipkg_message(conf, IPKG_DEBUG, "hash_table[%s] n_buckets=%d n_elements=%d max_conflicts=%d n_conflicts=%d\n",
2888 + hash->name, hash->n_entries, hash->n_elements, c, n_conflicts);
2889 + hash_table_deinit(hash);
2890 + }
2891 + }
2892 +}
2893 +
2894 +static int ipkg_conf_set_default_dest(ipkg_conf_t *conf,
2895 + const char *default_dest_name)
2896 +{
2897 + pkg_dest_list_elt_t *iter;
2898 + pkg_dest_t *dest;
2899 +
2900 + for (iter = conf->pkg_dest_list.head; iter; iter = iter->next) {
2901 + dest = iter->data;
2902 + if (strcmp(dest->name, default_dest_name) == 0) {
2903 + conf->default_dest = dest;
2904 + conf->restrict_to_default_dest = 1;
2905 + return 0;
2906 + }
2907 + }
2908 +
2909 + fprintf(stderr, "ERROR: Unknown dest name: `%s'\n", default_dest_name);
2910 +
2911 + return 1;
2912 +}
2913 +
2914 +static int set_and_load_pkg_src_list(ipkg_conf_t *conf, pkg_src_list_t *pkg_src_list)
2915 +{
2916 + pkg_src_list_elt_t *iter;
2917 + pkg_src_t *src;
2918 + char *list_file;
2919 +
2920 + for (iter = pkg_src_list->head; iter; iter = iter->next) {
2921 + src = iter->data;
2922 + if (src == NULL) {
2923 + continue;
2924 + }
2925 +
2926 + sprintf_alloc(&list_file, "%s/%s",
2927 + conf->restrict_to_default_dest ? conf->default_dest->lists_dir : conf->lists_dir,
2928 + src->name);
2929 +
2930 + if (file_exists(list_file)) {
2931 + pkg_hash_add_from_file(conf, list_file, src, NULL, 0);
2932 + }
2933 + free(list_file);
2934 + }
2935 +
2936 + return 0;
2937 +}
2938 +
2939 +static int set_and_load_pkg_dest_list(ipkg_conf_t *conf, nv_pair_list_t *nv_pair_list, char *lists_dir )
2940 +{
2941 + nv_pair_list_elt_t *iter;
2942 + nv_pair_t *nv_pair;
2943 + pkg_dest_t *dest;
2944 + char *root_dir;
2945 +
2946 + for (iter = nv_pair_list->head; iter; iter = iter->next) {
2947 + nv_pair = iter->data;
2948 +
2949 + if (conf->offline_root) {
2950 + sprintf_alloc(&root_dir, "%s%s", conf->offline_root, nv_pair->value);
2951 + } else {
2952 + root_dir = strdup(nv_pair->value);
2953 + }
2954 + dest = pkg_dest_list_append(&conf->pkg_dest_list, nv_pair->name, root_dir, lists_dir);
2955 + free(root_dir);
2956 + if (dest == NULL) {
2957 + continue;
2958 + }
2959 + if (conf->default_dest == NULL) {
2960 + conf->default_dest = dest;
2961 + }
2962 + if (file_exists(dest->status_file_name)) {
2963 + pkg_hash_add_from_file(conf, dest->status_file_name,
2964 + NULL, dest, 1);
2965 + }
2966 + }
2967 +
2968 + return 0;
2969 +}
2970 +
2971 +static int ipkg_conf_parse_file(ipkg_conf_t *conf, const char *filename,
2972 + pkg_src_list_t *pkg_src_list,
2973 + nv_pair_list_t *tmp_dest_nv_pair_list,
2974 + char **lists_dir)
2975 +{
2976 + ipkg_option_t * options;
2977 + FILE *file = fopen(filename, "r");
2978 + regex_t valid_line_re, comment_re;
2979 +#define regmatch_size 12
2980 + regmatch_t regmatch[regmatch_size];
2981 +
2982 + if (ipkg_init_options_array(conf, &options)<0)
2983 + return ENOMEM;
2984 +
2985 + if (file == NULL) {
2986 + fprintf(stderr, "%s: failed to open %s: %s\n",
2987 + __FUNCTION__, filename, strerror(errno));
2988 + free(options);
2989 + return errno;
2990 + }
2991 + ipkg_message(conf, IPKG_NOTICE, "loading conf file %s\n", filename);
2992 +
2993 + xregcomp(&comment_re,
2994 + "^[[:space:]]*(#.*|[[:space:]]*)$",
2995 + REG_EXTENDED);
2996 + xregcomp(&valid_line_re, "^[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))([[:space:]]+([^[:space:]]+))?[[:space:]]*$", REG_EXTENDED);
2997 +
2998 + while(1) {
2999 + int line_num = 0;
3000 + char *line;
3001 + char *type, *name, *value, *extra;
3002 +
3003 + line = file_read_line_alloc(file);
3004 + line_num++;
3005 + if (line == NULL) {
3006 + break;
3007 + }
3008 +
3009 + str_chomp(line);
3010 +
3011 + if (regexec(&comment_re, line, 0, 0, 0) == 0) {
3012 + goto NEXT_LINE;
3013 + }
3014 +
3015 + if (regexec(&valid_line_re, line, regmatch_size, regmatch, 0) == REG_NOMATCH) {
3016 + str_chomp(line);
3017 + fprintf(stderr, "%s:%d: Ignoring invalid line: `%s'\n",
3018 + filename, line_num, line);
3019 + goto NEXT_LINE;
3020 + }
3021 +
3022 + /* This has to be so ugly to deal with optional quotation marks */
3023 + if (regmatch[2].rm_so > 0) {
3024 + type = strndup(line + regmatch[2].rm_so,
3025 + regmatch[2].rm_eo - regmatch[2].rm_so);
3026 + } else {
3027 + type = strndup(line + regmatch[3].rm_so,
3028 + regmatch[3].rm_eo - regmatch[3].rm_so);
3029 + }
3030 + if (regmatch[5].rm_so > 0) {
3031 + name = strndup(line + regmatch[5].rm_so,
3032 + regmatch[5].rm_eo - regmatch[5].rm_so);
3033 + } else {
3034 + name = strndup(line + regmatch[6].rm_so,
3035 + regmatch[6].rm_eo - regmatch[6].rm_so);
3036 + }
3037 + if (regmatch[8].rm_so > 0) {
3038 + value = strndup(line + regmatch[8].rm_so,
3039 + regmatch[8].rm_eo - regmatch[8].rm_so);
3040 + } else {
3041 + value = strndup(line + regmatch[9].rm_so,
3042 + regmatch[9].rm_eo - regmatch[9].rm_so);
3043 + }
3044 + extra = NULL;
3045 + if (regmatch[11].rm_so > 0) {
3046 + extra = strndup (line + regmatch[11].rm_so,
3047 + regmatch[11].rm_eo - regmatch[11].rm_so);
3048 + }
3049 +
3050 + /* We use the tmp_dest_nv_pair_list below instead of
3051 + conf->pkg_dest_list because we might encounter an
3052 + offline_root option later and that would invalidate the
3053 + directories we would have computed in
3054 + pkg_dest_list_init. (We do a similar thing with
3055 + tmp_src_nv_pair_list for sake of symmetry.) */
3056 + if (strcmp(type, "option") == 0) {
3057 + ipkg_conf_set_option(options, name, value);
3058 + } else if (strcmp(type, "src") == 0) {
3059 + if (!nv_pair_list_find(pkg_src_list, name)) {
3060 + pkg_src_list_append (pkg_src_list, name, value, extra, 0);
3061 + } else {
3062 + ipkg_message(conf, IPKG_ERROR, "ERROR: duplicate src declaration. Skipping:\n\t src %s %s\n",
3063 + name, value);
3064 + }
3065 + } else if (strcmp(type, "src/gz") == 0) {
3066 + if (!nv_pair_list_find(pkg_src_list, name)) {
3067 + pkg_src_list_append (pkg_src_list, name, value, extra, 1);
3068 + } else {
3069 + ipkg_message(conf, IPKG_ERROR, "ERROR: duplicate src declaration. Skipping:\n\t src %s %s\n",
3070 + name, value);
3071 + }
3072 + } else if (strcmp(type, "dest") == 0) {
3073 + nv_pair_list_append(tmp_dest_nv_pair_list, name, value);
3074 + } else if (strcmp(type, "lists_dir") == 0) {
3075 + *lists_dir = realloc(*lists_dir,strlen(value)+1);
3076 + if (*lists_dir == NULL) {
3077 + ipkg_message(conf, IPKG_ERROR, "ERROR: Not enough memory\n");
3078 + free(options);
3079 + return EINVAL;
3080 + }
3081 + sprintf (*lists_dir,"%s",value);
3082 + } else if (strcmp(type, "arch") == 0) {
3083 + ipkg_message(conf, IPKG_INFO, "supported arch %s priority (%s)\n", name, value);
3084 + if (!value) {
3085 + ipkg_message(conf, IPKG_NOTICE, "defaulting architecture %s priority to 10\n", name);
3086 + value = strdup("10");
3087 + }
3088 + nv_pair_list_append(&conf->arch_list, strdup(name), strdup(value));
3089 + } else {
3090 + fprintf(stderr, "WARNING: Ignoring unknown configuration "
3091 + "parameter: %s %s %s\n", type, name, value);
3092 + free(options);
3093 + return EINVAL;
3094 + }
3095 +
3096 + free(type);
3097 + free(name);
3098 + free(value);
3099 + if (extra)
3100 + free (extra);
3101 +
3102 + NEXT_LINE:
3103 + free(line);
3104 + }
3105 +
3106 + free(options);
3107 + regfree(&comment_re);
3108 + regfree(&valid_line_re);
3109 + fclose(file);
3110 +
3111 + return 0;
3112 +}
3113 +
3114 +static int ipkg_conf_set_option(const ipkg_option_t *options,
3115 + const char *name, const char *value)
3116 +{
3117 + int i = 0;
3118 + while (options[i].name) {
3119 + if (strcmp(options[i].name, name) == 0) {
3120 + switch (options[i].type) {
3121 + case IPKG_OPT_TYPE_BOOL:
3122 + *((int *)options[i].value) = 1;
3123 + return 0;
3124 + case IPKG_OPT_TYPE_INT:
3125 + if (value) {
3126 + *((int *)options[i].value) = atoi(value);
3127 + return 0;
3128 + } else {
3129 + printf("%s: Option %s need an argument\n",
3130 + __FUNCTION__, name);
3131 + return EINVAL;
3132 + }
3133 + case IPKG_OPT_TYPE_STRING:
3134 + if (value) {
3135 + *((char **)options[i].value) = strdup(value);
3136 + return 0;
3137 + } else {
3138 + printf("%s: Option %s need an argument\n",
3139 + __FUNCTION__, name);
3140 + return EINVAL;
3141 + }
3142 + }
3143 + }
3144 + i++;
3145 + }
3146 +
3147 + fprintf(stderr, "%s: Unrecognized option: %s=%s\n",
3148 + __FUNCTION__, name, value);
3149 + return EINVAL;
3150 +}
3151 +
3152 +int ipkg_conf_write_status_files(ipkg_conf_t *conf)
3153 +{
3154 + pkg_dest_list_elt_t *iter;
3155 + pkg_dest_t *dest;
3156 + pkg_vec_t *all;
3157 + pkg_t *pkg;
3158 + register int i;
3159 + int err;
3160 +
3161 + if (conf->noaction)
3162 + return 0;
3163 + for (iter = conf->pkg_dest_list.head; iter; iter = iter->next) {
3164 + dest = iter->data;
3165 + dest->status_file = fopen(dest->status_file_tmp_name, "w");
3166 + if (dest->status_file == NULL) {
3167 + fprintf(stderr, "%s: Can't open status file: %s for writing: %s\n",
3168 + __FUNCTION__, dest->status_file_name, strerror(errno));
3169 + }
3170 + }
3171 +
3172 + all = pkg_vec_alloc();
3173 + pkg_hash_fetch_available(&conf->pkg_hash, all);
3174 +
3175 + for(i = 0; i < all->len; i++) {
3176 + pkg = all->pkgs[i];
3177 + /* We don't need most uninstalled packages in the status file */
3178 + if (pkg->state_status == SS_NOT_INSTALLED
3179 + && (pkg->state_want == SW_UNKNOWN
3180 + || pkg->state_want == SW_DEINSTALL
3181 + || pkg->state_want == SW_PURGE)) {
3182 + continue;
3183 + }
3184 + if (!pkg) {
3185 + fprintf(stderr, "Null package\n");
3186 + }
3187 + if (pkg->dest == NULL) {
3188 + fprintf(stderr, "%s: ERROR: Can't write status for "
3189 + "package %s since it has a NULL dest\n",
3190 + __FUNCTION__, pkg->name);
3191 + continue;
3192 + }
3193 + if (pkg->dest->status_file) {
3194 + pkg_print_status(pkg, pkg->dest->status_file);
3195 + }
3196 + }
3197 +
3198 + pkg_vec_free(all);
3199 +
3200 + for (iter = conf->pkg_dest_list.head; iter; iter = iter->next) {
3201 + dest = iter->data;
3202 + if (dest->status_file) {
3203 + err = ferror(dest->status_file);
3204 + fclose(dest->status_file);
3205 + dest->status_file = NULL;
3206 + if (!err) {
3207 + file_move(dest->status_file_tmp_name, dest->status_file_name);
3208 + } else {
3209 + fprintf(stderr, "%s: ERROR: An error has occurred writing %s, "
3210 + "retaining old %s\n", __FUNCTION__,
3211 + dest->status_file_tmp_name, dest->status_file_name);
3212 + }
3213 + }
3214 + }
3215 +
3216 + return 0;
3217 +}
3218 +
3219 +
3220 +char *root_filename_alloc(ipkg_conf_t *conf, char *filename)
3221 +{
3222 + char *root_filename;
3223 + sprintf_alloc(&root_filename, "%s%s", (conf->offline_root ? conf->offline_root : ""), filename);
3224 + return root_filename;
3225 +}
3226 diff -ruN busybox-1.3.1-orig/archival/libipkg/ipkg_conf.h busybox-1.3.1-911/archival/libipkg/ipkg_conf.h
3227 --- busybox-1.3.1-orig/archival/libipkg/ipkg_conf.h 1970-01-01 01:00:00.000000000 +0100
3228 +++ busybox-1.3.1-911/archival/libipkg/ipkg_conf.h 2006-12-27 19:41:04.000000000 +0100
3229 @@ -0,0 +1,107 @@
3230 +/* ipkg_conf.h - the itsy package management system
3231 +
3232 + Carl D. Worth
3233 +
3234 + Copyright (C) 2001 University of Southern California
3235 +
3236 + This program is free software; you can redistribute it and/or
3237 + modify it under the terms of the GNU General Public License as
3238 + published by the Free Software Foundation; either version 2, or (at
3239 + your option) any later version.
3240 +
3241 + This program is distributed in the hope that it will be useful, but
3242 + WITHOUT ANY WARRANTY; without even the implied warranty of
3243 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3244 + General Public License for more details.
3245 +*/
3246 +
3247 +#ifndef IPKG_CONF_H
3248 +#define IPKG_CONF_H
3249 +
3250 +typedef struct ipkg_conf ipkg_conf_t;
3251 +
3252 +#include "hash_table.h"
3253 +#include "ipkg.h"
3254 +#include "args.h"
3255 +#include "pkg.h"
3256 +#include "pkg_hash.h"
3257 +#include "pkg_src_list.h"
3258 +#include "pkg_dest_list.h"
3259 +#include "nv_pair_list.h"
3260 +
3261 +#define IPKG_CONF_DEFAULT_TMP_DIR_BASE "/tmp"
3262 +#define IPKG_CONF_TMP_DIR_SUFFIX "ipkg-XXXXXX"
3263 +#define IPKG_CONF_LISTS_DIR IPKG_STATE_DIR_PREFIX "/lists"
3264 +#define IPKG_CONF_PENDING_DIR IPKG_STATE_DIR_PREFIX "/pending"
3265 +
3266 +/* In case the config file defines no dest */
3267 +#define IPKG_CONF_DEFAULT_DEST_NAME "root"
3268 +#define IPKG_CONF_DEFAULT_DEST_ROOT_DIR "/"
3269 +
3270 +#define IPKG_CONF_DEFAULT_HASH_LEN 1024
3271 +
3272 +struct ipkg_conf
3273 +{
3274 + pkg_src_list_t pkg_src_list;
3275 + pkg_dest_list_t pkg_dest_list;
3276 + nv_pair_list_t arch_list;
3277 +
3278 + int restrict_to_default_dest;
3279 + pkg_dest_t *default_dest;
3280 +
3281 + char *tmp_dir;
3282 + const char *lists_dir;
3283 + const char *pending_dir;
3284 +
3285 + /* options */
3286 + int force_depends;
3287 + int force_defaults;
3288 + int force_overwrite;
3289 + int force_downgrade;
3290 + int force_reinstall;
3291 + int force_space;
3292 + int force_removal_of_dependent_packages;
3293 + int force_removal_of_essential_packages;
3294 + int nodeps; /* do not follow dependences */
3295 + int verbose_wget;
3296 + int multiple_providers;
3297 + char *offline_root;
3298 + char *offline_root_pre_script_cmd;
3299 + char *offline_root_post_script_cmd;
3300 + int query_all;
3301 + int verbosity;
3302 + int noaction;
3303 +
3304 + /* proxy options */
3305 + char *http_proxy;
3306 + char *ftp_proxy;
3307 + char *no_proxy;
3308 + char *proxy_user;
3309 + char *proxy_passwd;
3310 +
3311 + hash_table_t pkg_hash;
3312 + hash_table_t file_hash;
3313 + hash_table_t obs_file_hash;
3314 +};
3315 +
3316 +enum ipkg_option_type {
3317 + IPKG_OPT_TYPE_BOOL,
3318 + IPKG_OPT_TYPE_INT,
3319 + IPKG_OPT_TYPE_STRING
3320 +};
3321 +typedef enum ipkg_option_type ipkg_option_type_t;
3322 +
3323 +typedef struct ipkg_option ipkg_option_t;
3324 +struct ipkg_option {
3325 + const char *name;
3326 + const ipkg_option_type_t type;
3327 + const void *value;
3328 +};
3329 +
3330 +int ipkg_conf_init(ipkg_conf_t *conf, const args_t *args);
3331 +void ipkg_conf_deinit(ipkg_conf_t *conf);
3332 +
3333 +int ipkg_conf_write_status_files(ipkg_conf_t *conf);
3334 +char *root_filename_alloc(ipkg_conf_t *conf, char *filename);
3335 +
3336 +#endif
3337 diff -ruN busybox-1.3.1-orig/archival/libipkg/ipkg_configure.c busybox-1.3.1-911/archival/libipkg/ipkg_configure.c
3338 --- busybox-1.3.1-orig/archival/libipkg/ipkg_configure.c 1970-01-01 01:00:00.000000000 +0100
3339 +++ busybox-1.3.1-911/archival/libipkg/ipkg_configure.c 2006-12-27 19:41:04.000000000 +0100
3340 @@ -0,0 +1,40 @@
3341 +/* ipkg_configure.c - the itsy package management system
3342 +
3343 + Carl D. Worth
3344 +
3345 + Copyright (C) 2001 University of Southern California
3346 +
3347 + This program is free software; you can redistribute it and/or
3348 + modify it under the terms of the GNU General Public License as
3349 + published by the Free Software Foundation; either version 2, or (at
3350 + your option) any later version.
3351 +
3352 + This program is distributed in the hope that it will be useful, but
3353 + WITHOUT ANY WARRANTY; without even the implied warranty of
3354 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3355 + General Public License for more details.
3356 +*/
3357 +
3358 +#include "ipkg.h"
3359 +
3360 +#include "ipkg_configure.h"
3361 +
3362 +int ipkg_configure(ipkg_conf_t *conf, pkg_t *pkg)
3363 +{
3364 + int err;
3365 +
3366 + /* DPKG_INCOMPATIBILITY:
3367 + dpkg actually does some conffile handling here, rather than at the
3368 + end of ipkg_install(). Do we care? */
3369 + /* DPKG_INCOMPATIBILITY:
3370 + dpkg actually includes a version number to this script call */
3371 + err = pkg_run_script(conf, pkg, "postinst", "configure");
3372 + if (err) {
3373 + printf("ERROR: %s.postinst returned %d\n", pkg->name, err);
3374 + return err;
3375 + }
3376 +
3377 + ipkg_state_changed++;
3378 + return 0;
3379 +}
3380 +
3381 diff -ruN busybox-1.3.1-orig/archival/libipkg/ipkg_configure.h busybox-1.3.1-911/archival/libipkg/ipkg_configure.h
3382 --- busybox-1.3.1-orig/archival/libipkg/ipkg_configure.h 1970-01-01 01:00:00.000000000 +0100
3383 +++ busybox-1.3.1-911/archival/libipkg/ipkg_configure.h 2006-12-27 19:41:04.000000000 +0100
3384 @@ -0,0 +1,25 @@
3385 +/* ipkg_configure.h - the itsy package management system
3386 +
3387 + Carl D. Worth
3388 +
3389 + Copyright (C) 2001 University of Southern California
3390 +
3391 + This program is free software; you can redistribute it and/or
3392 + modify it under the terms of the GNU General Public License as
3393 + published by the Free Software Foundation; either version 2, or (at
3394 + your option) any later version.
3395 +
3396 + This program is distributed in the hope that it will be useful, but
3397 + WITHOUT ANY WARRANTY; without even the implied warranty of
3398 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3399 + General Public License for more details.
3400 +*/
3401 +
3402 +#ifndef IPKG_CONFIGURE_H
3403 +#define IPKG_CONFIGURE_H
3404 +
3405 +#include "ipkg_conf.h"
3406 +
3407 +int ipkg_configure(ipkg_conf_t *ipkg_conf, pkg_t *pkg);
3408 +
3409 +#endif
3410 diff -ruN busybox-1.3.1-orig/archival/libipkg/ipkg_download.c busybox-1.3.1-911/archival/libipkg/ipkg_download.c
3411 --- busybox-1.3.1-orig/archival/libipkg/ipkg_download.c 1970-01-01 01:00:00.000000000 +0100
3412 +++ busybox-1.3.1-911/archival/libipkg/ipkg_download.c 2006-12-27 19:41:04.000000000 +0100
3413 @@ -0,0 +1,195 @@
3414 +/* ipkg_download.c - the itsy package management system
3415 +
3416 + Carl D. Worth
3417 +
3418 + Copyright (C) 2001 University of Southern California
3419 +
3420 + This program is free software; you can redistribute it and/or
3421 + modify it under the terms of the GNU General Public License as
3422 + published by the Free Software Foundation; either version 2, or (at
3423 + your option) any later version.
3424 +
3425 + This program is distributed in the hope that it will be useful, but
3426 + WITHOUT ANY WARRANTY; without even the implied warranty of
3427 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3428 + General Public License for more details.
3429 +*/
3430 +
3431 +#include "ipkg.h"
3432 +#include "ipkg_download.h"
3433 +#include "ipkg_message.h"
3434 +
3435 +#include "sprintf_alloc.h"
3436 +#include "xsystem.h"
3437 +#include "file_util.h"
3438 +#include "str_util.h"
3439 +
3440 +int ipkg_download(ipkg_conf_t *conf, const char *src, const char *dest_file_name)
3441 +{
3442 + int err = 0;
3443 +
3444 + char *src_basec = strdup(src);
3445 + char *src_base = basename(src_basec);
3446 + char *tmp_file_location;
3447 + char *cmd;
3448 +
3449 + ipkg_message(conf,IPKG_NOTICE,"Downloading %s\n", src);
3450 +
3451 + fflush(stdout);
3452 +
3453 + if (str_starts_with(src, "file:")) {
3454 + int ret;
3455 + const char *file_src = src + 5;
3456 + ipkg_message(conf,IPKG_INFO,"Copying %s to %s...", file_src, dest_file_name);
3457 + ret = file_copy(src + 5, dest_file_name);
3458 + ipkg_message(conf,IPKG_INFO,"Done.\n");
3459 + return ret;
3460 + }
3461 +
3462 + sprintf_alloc(&tmp_file_location, "%s/%s", conf->tmp_dir, src_base);
3463 + err = unlink(tmp_file_location);
3464 + if (err && errno != ENOENT) {
3465 + ipkg_message(conf,IPKG_ERROR, "%s: ERROR: failed to unlink %s: %s\n",
3466 + __FUNCTION__, tmp_file_location, strerror(errno));
3467 + free(tmp_file_location);
3468 + return errno;
3469 + }
3470 +
3471 + if (conf->http_proxy) {
3472 + ipkg_message(conf,IPKG_DEBUG,"Setting environment variable: http_proxy = %s\n", conf->http_proxy);
3473 + setenv("http_proxy", conf->http_proxy, 1);
3474 + }
3475 + if (conf->ftp_proxy) {
3476 + ipkg_message(conf,IPKG_DEBUG,"Setting environment variable: ftp_proxy = %s\n", conf->ftp_proxy);
3477 + setenv("ftp_proxy", conf->ftp_proxy, 1);
3478 + }
3479 + if (conf->no_proxy) {
3480 + ipkg_message(conf,IPKG_DEBUG,"Setting environment variable: no_proxy = %s\n", conf->no_proxy);
3481 + setenv("no_proxy", conf->no_proxy, 1);
3482 + }
3483 +
3484 + /* XXX: BUG rewrite to use execvp or else busybox's internal wget -Jamey 7/23/2002 */
3485 + sprintf_alloc(&cmd, "wget --passive-ftp %s %s%s %s%s %s -P %s %s",
3486 + (conf->http_proxy || conf->ftp_proxy) ? "--proxy=on" : "",
3487 + conf->proxy_user ? "--proxy-user=" : "",
3488 + conf->proxy_user ? conf->proxy_user : "",
3489 + conf->proxy_passwd ? "--proxy-passwd=" : "",
3490 + conf->proxy_passwd ? conf->proxy_passwd : "",
3491 + conf->verbose_wget ? "" : "-q",
3492 + conf->tmp_dir,
3493 + src);
3494 + err = xsystem(cmd);
3495 + if (err) {
3496 + if (err != -1) {
3497 + ipkg_message(conf,IPKG_ERROR, "%s: ERROR: Command failed with return value %d: `%s'\n",
3498 + __FUNCTION__, err, cmd);
3499 + }
3500 + unlink(tmp_file_location);
3501 + free(tmp_file_location);
3502 + free(src_basec);
3503 + free(cmd);
3504 + return EINVAL;
3505 + }
3506 + free(cmd);
3507 +
3508 + err = file_move(tmp_file_location, dest_file_name);
3509 +
3510 + free(tmp_file_location);
3511 + free(src_basec);
3512 +
3513 + if (err) {
3514 + return err;
3515 + }
3516 +
3517 + return 0;
3518 +}
3519 +
3520 +int ipkg_download_pkg(ipkg_conf_t *conf, pkg_t *pkg, const char *dir)
3521 +{
3522 + int err;
3523 + char *url;
3524 +
3525 + if (pkg->src == NULL) {
3526 + ipkg_message(conf,IPKG_ERROR, "ERROR: Package %s (parent %s) is not available from any configured src.\n",
3527 + pkg->name, pkg->parent->name);
3528 + return -1;
3529 + }
3530 +
3531 + sprintf_alloc(&url, "%s/%s", pkg->src->value, pkg->filename);
3532 +
3533 + /* XXX: BUG: The pkg->filename might be something like
3534 + "../../foo.ipk". While this is correct, and exactly what we
3535 + want to use to construct url above, here we actually need to
3536 + use just the filename part, without any directory. */
3537 + sprintf_alloc(&pkg->local_filename, "%s/%s", dir, pkg->filename);
3538 +
3539 + err = ipkg_download(conf, url, pkg->local_filename);
3540 + free(url);
3541 +
3542 + return err;
3543 +}
3544 +
3545 +/*
3546 + * Downloads file from url, installs in package database, return package name.
3547 + */
3548 +int ipkg_prepare_url_for_install(ipkg_conf_t *conf, const char *url, char **namep)
3549 +{
3550 + int err = 0;
3551 + pkg_t *pkg;
3552 + pkg = pkg_new();
3553 + if (pkg == NULL)
3554 + return ENOMEM;
3555 +
3556 + if (str_starts_with(url, "http://")
3557 + || str_starts_with(url, "ftp://")) {
3558 + char *tmp_file;
3559 + char *file_basec = strdup(url);
3560 + char *file_base = basename(file_basec);
3561 +
3562 + sprintf_alloc(&tmp_file, "%s/%s", conf->tmp_dir, file_base);
3563 + err = ipkg_download(conf, url, tmp_file);
3564 + if (err)
3565 + return err;
3566 +
3567 + err = pkg_init_from_file(pkg, tmp_file);
3568 + if (err)
3569 + return err;
3570 + pkg->local_filename = strdup(tmp_file);
3571 +
3572 + free(tmp_file);
3573 + free(file_basec);
3574 +
3575 + } else if (strcmp(&url[strlen(url) - 4], IPKG_PKG_EXTENSION) == 0
3576 + || strcmp(&url[strlen(url) - 4], DPKG_PKG_EXTENSION) == 0) {
3577 +
3578 + err = pkg_init_from_file(pkg, url);
3579 + if (err)
3580 + return err;
3581 + pkg->local_filename = strdup(url);
3582 + ipkg_message(conf, IPKG_DEBUG2, "Package %s provided by hand \(%s\).\n", pkg->name,pkg->local_filename);
3583 + pkg->provided_by_hand = 1;
3584 +
3585 + } else {
3586 + pkg_deinit(pkg);
3587 + free(pkg);
3588 + return 0;
3589 + }
3590 +
3591 + if (!pkg->architecture) {
3592 + ipkg_message(conf, IPKG_ERROR, "Package %s has no Architecture defined.\n", pkg->name);
3593 + return -EINVAL;
3594 + }
3595 +
3596 + pkg->dest = conf->default_dest;
3597 + pkg->state_want = SW_INSTALL;
3598 + pkg->state_flag |= SF_PREFER;
3599 + pkg = hash_insert_pkg(&conf->pkg_hash, pkg, 1,conf);
3600 + if ( pkg == NULL ){
3601 + fprintf(stderr, "%s : This should never happen. Report this Bug in bugzilla please \n ",__FUNCTION__);
3602 + return 0;
3603 + }
3604 + if (namep) {
3605 + *namep = strdup(pkg->name);
3606 + }
3607 + return 0;
3608 +}
3609 diff -ruN busybox-1.3.1-orig/archival/libipkg/ipkg_download.h busybox-1.3.1-911/archival/libipkg/ipkg_download.h
3610 --- busybox-1.3.1-orig/archival/libipkg/ipkg_download.h 1970-01-01 01:00:00.000000000 +0100
3611 +++ busybox-1.3.1-911/archival/libipkg/ipkg_download.h 2006-12-27 19:41:04.000000000 +0100
3612 @@ -0,0 +1,30 @@
3613 +/* ipkg_download.h - the itsy package management system
3614 +
3615 + Carl D. Worth
3616 +
3617 + Copyright (C) 2001 University of Southern California
3618 +
3619 + This program is free software; you can redistribute it and/or
3620 + modify it under the terms of the GNU General Public License as
3621 + published by the Free Software Foundation; either version 2, or (at
3622 + your option) any later version.
3623 +
3624 + This program is distributed in the hope that it will be useful, but
3625 + WITHOUT ANY WARRANTY; without even the implied warranty of
3626 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3627 + General Public License for more details.
3628 +*/
3629 +
3630 +#ifndef IPKG_DOWNLOAD_H
3631 +#define IPKG_DOWNLOAD_H
3632 +
3633 +#include "ipkg_conf.h"
3634 +
3635 +int ipkg_download(ipkg_conf_t *conf, const char *src, const char *dest_file_name);
3636 +int ipkg_download_pkg(ipkg_conf_t *conf, pkg_t *pkg, const char *dir);
3637 +/*
3638 + * Downloads file from url, installs in package database, return package name.
3639 + */
3640 +int ipkg_prepare_url_for_install(ipkg_conf_t *conf, const char *url, char **namep);
3641 +
3642 +#endif
3643 diff -ruN busybox-1.3.1-orig/archival/libipkg/ipkg.h busybox-1.3.1-911/archival/libipkg/ipkg.h
3644 --- busybox-1.3.1-orig/archival/libipkg/ipkg.h 1970-01-01 01:00:00.000000000 +0100
3645 +++ busybox-1.3.1-911/archival/libipkg/ipkg.h 2006-12-27 19:41:04.000000000 +0100
3646 @@ -0,0 +1,74 @@
3647 +/* ipkg.h - the itsy package management system
3648 +
3649 + Carl D. Worth
3650 +
3651 + Copyright (C) 2001 University of Southern California
3652 +
3653 + This program is free software; you can redistribute it and/or
3654 + modify it under the terms of the GNU General Public License as
3655 + published by the Free Software Foundation; either version 2, or (at
3656 + your option) any later version.
3657 +
3658 + This program is distributed in the hope that it will be useful, but
3659 + WITHOUT ANY WARRANTY; without even the implied warranty of
3660 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3661 + General Public License for more details.
3662 +*/
3663 +
3664 +#ifndef IPKG_H
3665 +#define IPKG_H
3666 +
3667 +/*
3668 +#ifdef HAVE_CONFIG_H
3669 +#include "config.h"
3670 +#endif
3671 +*/
3672 +
3673 +#if 0
3674 +#define IPKG_DEBUG_NO_TMP_CLEANUP
3675 +#endif
3676 +
3677 +#include "ipkg_includes.h"
3678 +#include "ipkg_conf.h"
3679 +#include "ipkg_message.h"
3680 +
3681 +#define IPKG_PKG_EXTENSION ".ipk"
3682 +#define DPKG_PKG_EXTENSION ".deb"
3683 +
3684 +#define IPKG_LEGAL_PKG_NAME_CHARS "abcdefghijklmnopqrstuvwxyz0123456789.+-"
3685 +#define IPKG_PKG_VERSION_SEP_CHAR '_'
3686 +
3687 +#define IPKG_STATE_DIR_PREFIX IPKGLIBDIR"/ipkg"
3688 +#define IPKG_LISTS_DIR_SUFFIX "lists"
3689 +#define IPKG_INFO_DIR_SUFFIX "info"
3690 +#define IPKG_STATUS_FILE_SUFFIX "status"
3691 +
3692 +#define IPKG_BACKUP_SUFFIX "-ipkg.backup"
3693 +
3694 +#define IPKG_LIST_DESCRIPTION_LENGTH 128
3695 +
3696 +#define IPKG_VERSION "0.99.162"
3697 +
3698 +
3699 +enum ipkg_error {
3700 + IPKG_SUCCESS = 0,
3701 + IPKG_PKG_DEPS_UNSATISFIED,
3702 + IPKG_PKG_IS_ESSENTIAL,
3703 + IPKG_PKG_HAS_DEPENDENTS,
3704 + IPKG_PKG_HAS_NO_CANDIDATE
3705 +};
3706 +typedef enum ipkg_error ipkg_error_t;
3707 +
3708 +extern int ipkg_state_changed;
3709 +
3710 +
3711 +struct errlist {
3712 + char * errmsg;
3713 + struct errlist * next;
3714 +} ;
3715 +
3716 +extern struct errlist* error_list;
3717 +
3718 +extern ipkg_conf_t *global_conf;
3719 +
3720 +#endif
3721 diff -ruN busybox-1.3.1-orig/archival/libipkg/ipkg_includes.h busybox-1.3.1-911/archival/libipkg/ipkg_includes.h
3722 --- busybox-1.3.1-orig/archival/libipkg/ipkg_includes.h 1970-01-01 01:00:00.000000000 +0100
3723 +++ busybox-1.3.1-911/archival/libipkg/ipkg_includes.h 2006-12-27 19:41:04.000000000 +0100
3724 @@ -0,0 +1,79 @@
3725 +#ifndef IPKG_INCLUDES_H
3726 +#define IPKG_INCLUDES_H
3727 +