7867634fd2e19cc145c859db395fba62051f0b2c
[openwrt/svn-archive/archive.git] / package / busybox / patches / 500-ipkg.patch
1 Index: busybox-1.8.1/archival/Config.in
2 ===================================================================
3 --- busybox-1.8.1.orig/archival/Config.in 2007-11-10 17:39:21.063504932 +0100
4 +++ busybox-1.8.1/archival/Config.in 2007-11-10 17:40:53.320762376 +0100
5 @@ -131,6 +131,15 @@
6 gzip is used to compress files.
7 It's probably the most widely used UNIX compression program.
8
9 +config IPKG
10 + bool "ipkg"
11 + default n
12 + select MD5SUM
13 + select WGET
14 + select DIFF
15 + help
16 + ipkg is the itsy package management system.
17 +
18 config RPM2CPIO
19 bool "rpm2cpio"
20 default n
21 Index: busybox-1.8.1/archival/dpkg.c
22 ===================================================================
23 --- busybox-1.8.1.orig/archival/dpkg.c 2007-11-10 17:39:21.071505389 +0100
24 +++ busybox-1.8.1/archival/dpkg.c 2007-11-10 17:40:53.320762376 +0100
25 @@ -1455,6 +1455,10 @@
26 return ar_handle->sub_archive->buffer;
27 }
28
29 +/*
30 +
31 +// moved to data_extract_all.c
32 +
33 static void data_extract_all_prefix(archive_handle_t *archive_handle)
34 {
35 char *name_ptr = archive_handle->file_header->name;
36 @@ -1466,6 +1470,8 @@
37 }
38 }
39
40 +*/
41 +
42 static void unpack_package(deb_file_t *deb_file)
43 {
44 const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];
45 Index: busybox-1.8.1/archival/ipkg.c
46 ===================================================================
47 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
48 +++ busybox-1.8.1/archival/ipkg.c 2007-11-10 17:41:16.866104145 +0100
49 @@ -0,0 +1,27 @@
50 +/* ipkg.c - the itsy package management system
51 +
52 + Florina Boor
53 +
54 + Copyright (C) 2003 kernel concepts
55 +
56 + This program is free software; you can redistribute it and/or
57 + modify it under the terms of the GNU General Public License as
58 + published by the Free Software Foundation; either version 2, or (at
59 + your option) any later version.
60 +
61 + This program is distributed in the hope that it will be useful, but
62 + WITHOUT ANY WARRANTY; without even the implied warranty of
63 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
64 + General Public License for more details.
65 +
66 + ipkg command line frontend using libipkg
67 +
68 +*/
69 +#include "libipkg/libipkg.h"
70 +#include "busybox.h"
71 +
72 +int ipkg_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
73 +int ipkg_main(int argc, char **argv)
74 +{
75 + return ipkg_op(argc, argv);
76 +}
77 Index: busybox-1.8.1/archival/Kbuild
78 ===================================================================
79 --- busybox-1.8.1.orig/archival/Kbuild 2007-11-10 17:39:21.083506071 +0100
80 +++ busybox-1.8.1/archival/Kbuild 2007-11-10 17:40:53.332763058 +0100
81 @@ -16,6 +16,7 @@
82 lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o
83 lib-$(CONFIG_GUNZIP) += bbunzip.o
84 lib-$(CONFIG_GZIP) += gzip.o bbunzip.o
85 +lib-$(CONFIG_IPKG) += ipkg.o
86 lib-$(CONFIG_RPM2CPIO) += rpm2cpio.o
87 lib-$(CONFIG_RPM) += rpm.o
88 lib-$(CONFIG_TAR) += tar.o
89 Index: busybox-1.8.1/archival/libipkg/args.c
90 ===================================================================
91 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
92 +++ busybox-1.8.1/archival/libipkg/args.c 2007-11-10 17:40:53.336763287 +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 Index: busybox-1.8.1/archival/libipkg/args.h
337 ===================================================================
338 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
339 +++ busybox-1.8.1/archival/libipkg/args.h 2007-11-10 17:40:53.340763516 +0100
340 @@ -0,0 +1,72 @@
341 +/* args.h - parse command-line args
342 +
343 + Carl D. Worth
344 +
345 + Copyright 2001 University of Southern California
346 +
347 + This program is free software; you can redistribute it and/or modify
348 + it under the terms of the GNU General Public License as published by
349 + the Free Software Foundation; either version 2, or (at your option)
350 + any later version.
351 +
352 + This program is distributed in the hope that it will be useful,
353 + but WITHOUT ANY WARRANTY; without even the implied warranty of
354 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
355 + GNU General Public License for more details.
356 +*/
357 +
358 +#ifndef ARGS_H
359 +#define ARGS_H
360 +
361 +struct args
362 +{
363 + char *conf_file;
364 + char *dest;
365 + char *tmp_dir;
366 + int force_defaults;
367 + int force_depends;
368 + int force_overwrite;
369 + int force_downgrade;
370 + int force_reinstall;
371 + int force_removal_of_essential_packages;
372 + int force_removal_of_dependent_packages;
373 + int force_space;
374 + int noaction;
375 + int nodeps;
376 + int multiple_providers;
377 + int query_all;
378 + int verbose_wget;
379 + int verbosity;
380 + int nocheckfordirorfile;
381 + int noreadfeedsfile;
382 + char *offline_root;
383 + char *offline_root_pre_script_cmd;
384 + char *offline_root_post_script_cmd;
385 +};
386 +typedef struct args args_t;
387 +
388 +#define ARGS_DEFAULT_CONF_FILE_DIR "/etc"
389 +#define ARGS_DEFAULT_CONF_FILE_NAME "ipkg.conf"
390 +#define ARGS_DEFAULT_DEST NULL
391 +#define ARGS_DEFAULT_FORCE_DEFAULTS 0
392 +#define ARGS_DEFAULT_FORCE_DEPENDS 0
393 +#define ARGS_DEFAULT_FORCE_OVERWRITE 0
394 +#define ARGS_DEFAULT_FORCE_DOWNGRADE 0
395 +#define ARGS_DEFAULT_FORCE_REINSTALL 0
396 +#define ARGS_DEFAULT_FORCE_REMOVAL_OF_ESSENTIAL_PACKAGES 0
397 +#define ARGS_DEFAULT_FORCE_REMOVAL_OF_DEPENDENT_PACKAGES 0
398 +#define ARGS_DEFAULT_FORCE_SPACE 0
399 +#define ARGS_DEFAULT_OFFLINE_ROOT NULL
400 +#define ARGS_DEFAULT_OFFLINE_ROOT_PRE_SCRIPT_CMD NULL
401 +#define ARGS_DEFAULT_OFFLINE_ROOT_POST_SCRIPT_CMD NULL
402 +#define ARGS_DEFAULT_NOACTION 0
403 +#define ARGS_DEFAULT_NODEPS 0
404 +#define ARGS_DEFAULT_VERBOSE_WGET 0
405 +#define ARGS_DEFAULT_VERBOSITY 1
406 +
407 +int args_init(args_t *args);
408 +void args_deinit(args_t *args);
409 +int args_parse(args_t *args, int argc, char *argv[]);
410 +void args_usage(char *complaint);
411 +
412 +#endif
413 Index: busybox-1.8.1/archival/libipkg/conffile.c
414 ===================================================================
415 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
416 +++ busybox-1.8.1/archival/libipkg/conffile.c 2007-11-10 17:40:53.340763516 +0100
417 @@ -0,0 +1,64 @@
418 +/* conffile.c - the itsy package management system
419 +
420 + Carl D. Worth
421 +
422 + Copyright (C) 2001 University of Southern California
423 +
424 + This program is free software; you can redistribute it and/or
425 + modify it under the terms of the GNU General Public License as
426 + published by the Free Software Foundation; either version 2, or (at
427 + your option) any later version.
428 +
429 + This program is distributed in the hope that it will be useful, but
430 + WITHOUT ANY WARRANTY; without even the implied warranty of
431 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
432 + General Public License for more details.
433 +*/
434 +
435 +#include <string.h>
436 +#include <stdlib.h>
437 +
438 +#include "ipkg.h"
439 +#include "ipkg_message.h"
440 +
441 +#include "conffile.h"
442 +#include "file_util.h"
443 +#include "sprintf_alloc.h"
444 +
445 +int conffile_init(conffile_t *conffile, const char *file_name, const char *md5sum)
446 +{
447 + return nv_pair_init(conffile, file_name, md5sum);
448 +}
449 +
450 +void conffile_deinit(conffile_t *conffile)
451 +{
452 + nv_pair_deinit(conffile);
453 +}
454 +
455 +int conffile_has_been_modified(ipkg_conf_t *conf, conffile_t *conffile)
456 +{
457 + char *md5sum;
458 + char *filename = conffile->name;
459 + char *root_filename;
460 + int ret;
461 +
462 + if (conffile->value == NULL) {
463 + ipkg_message(conf, IPKG_NOTICE, "%s: conffile %s has no md5sum\n", __FUNCTION__, conffile->name);
464 + return 1;
465 + }
466 +
467 + root_filename = root_filename_alloc(conf, filename);
468 +
469 + md5sum = file_md5sum_alloc(root_filename);
470 +
471 + ret = strcmp(md5sum, conffile->value);
472 + if (ret) {
473 + ipkg_message(conf, IPKG_NOTICE, "%s: conffile %s: \t\nold md5=%s \t\nnew md5=%s\n", __FUNCTION__,
474 + conffile->name, md5sum, conffile->value);
475 + }
476 +
477 + free(root_filename);
478 + free(md5sum);
479 +
480 + return ret;
481 +}
482 Index: busybox-1.8.1/archival/libipkg/conffile.h
483 ===================================================================
484 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
485 +++ busybox-1.8.1/archival/libipkg/conffile.h 2007-11-10 17:40:53.340763516 +0100
486 @@ -0,0 +1,30 @@
487 +/* conffile.h - the itsy package management system
488 +
489 + Carl D. Worth
490 +
491 + Copyright (C) 2001 University of Southern California
492 +
493 + This program is free software; you can redistribute it and/or
494 + modify it under the terms of the GNU General Public License as
495 + published by the Free Software Foundation; either version 2, or (at
496 + your option) any later version.
497 +
498 + This program is distributed in the hope that it will be useful, but
499 + WITHOUT ANY WARRANTY; without even the implied warranty of
500 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
501 + General Public License for more details.
502 +*/
503 +
504 +#ifndef CONFFILE_H
505 +#define CONFFILE_H
506 +
507 +#include "nv_pair.h"
508 +
509 +typedef struct nv_pair conffile_t;
510 +
511 +int conffile_init(conffile_t *conffile, const char *file_name, const char *md5sum);
512 +void conffile_deinit(conffile_t *conffile);
513 +int conffile_has_been_modified(struct ipkg_conf *conf, conffile_t *conffile);
514 +
515 +#endif
516 +
517 Index: busybox-1.8.1/archival/libipkg/conffile_list.c
518 ===================================================================
519 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
520 +++ busybox-1.8.1/archival/libipkg/conffile_list.c 2007-11-10 17:40:53.340763516 +0100
521 @@ -0,0 +1,47 @@
522 +/* conffile_list.c - the itsy package management system
523 +
524 + Carl D. Worth
525 +
526 + Copyright (C) 2001 University of Southern California
527 +
528 + This program is free software; you can redistribute it and/or
529 + modify it under the terms of the GNU General Public License as
530 + published by the Free Software Foundation; either version 2, or (at
531 + your option) any later version.
532 +
533 + This program is distributed in the hope that it will be useful, but
534 + WITHOUT ANY WARRANTY; without even the implied warranty of
535 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
536 + General Public License for more details.
537 +*/
538 +
539 +#include "ipkg.h"
540 +
541 +#include "conffile_list.h"
542 +
543 +int conffile_list_init(conffile_list_t *list)
544 +{
545 + return nv_pair_list_init(list);
546 +}
547 +
548 +void conffile_list_deinit(conffile_list_t *list)
549 +{
550 + nv_pair_list_deinit(list);
551 +}
552 +
553 +conffile_t *conffile_list_append(conffile_list_t *list, const char *file_name,
554 + const char *md5sum)
555 +{
556 + return nv_pair_list_append(list, file_name, md5sum);
557 +}
558 +
559 +int conffile_list_push(conffile_list_t *list, conffile_t *data)
560 +{
561 + return nv_pair_list_push(list, data);
562 +}
563 +
564 +conffile_list_elt_t *conffile_list_pop(conffile_list_t *list)
565 +{
566 + return nv_pair_list_pop(list);
567 +}
568 +
569 Index: busybox-1.8.1/archival/libipkg/conffile_list.h
570 ===================================================================
571 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
572 +++ busybox-1.8.1/archival/libipkg/conffile_list.h 2007-11-10 17:40:53.340763516 +0100
573 @@ -0,0 +1,36 @@
574 +/* conffile_list.h - the itsy package management system
575 +
576 + Carl D. Worth
577 +
578 + Copyright (C) 2001 University of Southern California
579 +
580 + This program is free software; you can redistribute it and/or
581 + modify it under the terms of the GNU General Public License as
582 + published by the Free Software Foundation; either version 2, or (at
583 + your option) any later version.
584 +
585 + This program is distributed in the hope that it will be useful, but
586 + WITHOUT ANY WARRANTY; without even the implied warranty of
587 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
588 + General Public License for more details.
589 +*/
590 +
591 +#ifndef CONFFILE_LIST_H
592 +#define CONFFILE_LIST_H
593 +
594 +#include "conffile.h"
595 +#include "nv_pair_list.h"
596 +
597 +typedef struct nv_pair_list_elt conffile_list_elt_t;
598 +typedef struct nv_pair_list conffile_list_t;
599 +
600 +int conffile_list_init(conffile_list_t *list);
601 +void conffile_list_deinit(conffile_list_t *list);
602 +
603 +conffile_t *conffile_list_append(conffile_list_t *list, const char *name,
604 + const char *root_dir);
605 +int conffile_list_push(conffile_list_t *list, conffile_t *data);
606 +conffile_list_elt_t *conffile_list_pop(conffile_list_t *list);
607 +
608 +#endif
609 +
610 Index: busybox-1.8.1/archival/libipkg/file_util.c
611 ===================================================================
612 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
613 +++ busybox-1.8.1/archival/libipkg/file_util.c 2007-11-10 17:40:53.340763516 +0100
614 @@ -0,0 +1,132 @@
615 +/* file_util.c - convenience routines for common stat operations
616 +
617 + Carl D. Worth
618 +
619 + Copyright (C) 2001 University of Southern California
620 +
621 + This program is free software; you can redistribute it and/or
622 + modify it under the terms of the GNU General Public License as
623 + published by the Free Software Foundation; either version 2, or (at
624 + your option) any later version.
625 +
626 + This program is distributed in the hope that it will be useful, but
627 + WITHOUT ANY WARRANTY; without even the implied warranty of
628 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
629 + General Public License for more details.
630 +*/
631 +
632 +#include "ipkg.h"
633 +#include <sys/types.h>
634 +#include <sys/stat.h>
635 +
636 +#include "sprintf_alloc.h"
637 +#include "file_util.h"
638 +#include "libbb.h"
639 +#undef strlen
640 +
641 +int file_exists(const char *file_name)
642 +{
643 + int err;
644 + struct stat stat_buf;
645 +
646 + err = stat(file_name, &stat_buf);
647 + if (err == 0) {
648 + return 1;
649 + } else {
650 + return 0;
651 + }
652 +}
653 +
654 +int file_is_dir(const char *file_name)
655 +{
656 + int err;
657 + struct stat stat_buf;
658 +
659 + err = stat(file_name, &stat_buf);
660 + if (err) {
661 + return 0;
662 + }
663 +
664 + return S_ISDIR(stat_buf.st_mode);
665 +}
666 +
667 +/* read a single line from a file, stopping at a newline or EOF.
668 + If a newline is read, it will appear in the resulting string.
669 + Return value is a malloc'ed char * which should be freed at
670 + some point by the caller.
671 +
672 + Return value is NULL if the file is at EOF when called.
673 +*/
674 +#define FILE_READ_LINE_BUF_SIZE 1024
675 +char *file_read_line_alloc(FILE *file)
676 +{
677 + char buf[FILE_READ_LINE_BUF_SIZE];
678 + int buf_len;
679 + char *line = NULL;
680 + int line_size = 0;
681 +
682 + memset(buf, 0, FILE_READ_LINE_BUF_SIZE);
683 + while (fgets(buf, FILE_READ_LINE_BUF_SIZE, file)) {
684 + buf_len = strlen(buf);
685 + if (line) {
686 + line_size += buf_len;
687 + line = realloc(line, line_size);
688 + if (line == NULL) {
689 + fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
690 + break;
691 + }
692 + strcat(line, buf);
693 + } else {
694 + line_size = buf_len + 1;
695 + line = strdup(buf);
696 + }
697 + if (buf[buf_len - 1] == '\n') {
698 + break;
699 + }
700 + }
701 +
702 + return line;
703 +}
704 +
705 +int file_move(const char *src, const char *dest)
706 +{
707 + int err;
708 +
709 + err = rename(src, dest);
710 +
711 + if (err && errno == EXDEV) {
712 + err = file_copy(src, dest);
713 + unlink(src);
714 + } else if (err) {
715 + fprintf(stderr, "%s: ERROR: failed to rename %s to %s: %s\n",
716 + __FUNCTION__, src, dest, strerror(errno));
717 + }
718 +
719 + return err;
720 +}
721 +
722 +/* I put these here to keep libbb dependencies from creeping all over
723 + the ipkg code */
724 +int file_copy(const char *src, const char *dest)
725 +{
726 + int err;
727 +
728 + err = copy_file(src, dest, FILEUTILS_FORCE | FILEUTILS_PRESERVE_STATUS);
729 + if (err) {
730 + fprintf(stderr, "%s: ERROR: failed to copy %s to %s\n",
731 + __FUNCTION__, src, dest);
732 + }
733 +
734 + return err;
735 +}
736 +
737 +int file_mkdir_hier(const char *path, long mode)
738 +{
739 + return bb_make_directory((char *)path, mode, FILEUTILS_RECUR);
740 +}
741 +
742 +char *file_md5sum_alloc(const char *file_name)
743 +{
744 + return hash_file(file_name, HASH_MD5);
745 +}
746 +
747 Index: busybox-1.8.1/archival/libipkg/file_util.h
748 ===================================================================
749 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
750 +++ busybox-1.8.1/archival/libipkg/file_util.h 2007-11-10 17:40:53.344763742 +0100
751 @@ -0,0 +1,29 @@
752 +/* file_util.h - convenience routines for common file operations
753 +
754 + Carl D. Worth
755 +
756 + Copyright (C) 2001 University of Southern California
757 +
758 + This program is free software; you can redistribute it and/or
759 + modify it under the terms of the GNU General Public License as
760 + published by the Free Software Foundation; either version 2, or (at
761 + your option) any later version.
762 +
763 + This program is distributed in the hope that it will be useful, but
764 + WITHOUT ANY WARRANTY; without even the implied warranty of
765 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
766 + General Public License for more details.
767 +*/
768 +
769 +#ifndef FILE_UTIL_H
770 +#define FILE_UTIL_H
771 +
772 +int file_exists(const char *file_name);
773 +int file_is_dir(const char *file_name);
774 +char *file_read_line_alloc(FILE *file);
775 +int file_move(const char *src, const char *dest);
776 +int file_copy(const char *src, const char *dest);
777 +int file_mkdir_hier(const char *path, long mode);
778 +char *file_md5sum_alloc(const char *file_name);
779 +
780 +#endif
781 Index: busybox-1.8.1/archival/libipkg/hash_table.c
782 ===================================================================
783 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
784 +++ busybox-1.8.1/archival/libipkg/hash_table.c 2007-11-10 17:40:53.344763742 +0100
785 @@ -0,0 +1,155 @@
786 +/* hash.c - hash tables for ipkg
787 +
788 + Steven M. Ayer, Jamey Hicks
789 +
790 + Copyright (C) 2002 Compaq Computer Corporation
791 +
792 + This program is free software; you can redistribute it and/or
793 + modify it under the terms of the GNU General Public License as
794 + published by the Free Software Foundation; either version 2, or (at
795 + your option) any later version.
796 +
797 + This program is distributed in the hope that it will be useful, but
798 + WITHOUT ANY WARRANTY; without even the implied warranty of
799 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
800 + General Public License for more details.
801 +*/
802 +
803 +#include <errno.h>
804 +#include <stdio.h>
805 +#include <stdlib.h>
806 +#include <string.h>
807 +#include "hash_table.h"
808 +#include "ipkg_message.h"
809 +
810 +
811 +static int hash_index(hash_table_t *hash, const char *pkg_name);
812 +static int rotating(const char *key, int len, int prime);
813 +
814 +static int hash_index(hash_table_t *hash, const char *pkg_name)
815 +{
816 + return rotating(pkg_name, strlen(pkg_name), hash->n_entries);
817 +}
818 +
819 +static int rotating(const char *key, int len, int prime)
820 +{
821 + unsigned int hash, i;
822 + for (hash=len, i=0; i<len; ++i)
823 + hash = (hash<<4)^(hash>>28)^key[i];
824 + return (hash % prime);
825 +}
826 +
827 +
828 +/*
829 + * this is an open table keyed by strings
830 + */
831 +int hash_table_init(const char *name, hash_table_t *hash, int len)
832 +{
833 + static int primes_table[] = {
834 + 379, 761, 983, 1423, 2711, 3361, 3931, 4679, 5519, 6701, 9587,
835 + 19471, 23143, 33961, 46499, 49727, 99529, 0
836 + };
837 + int *picker;
838 +
839 + if (hash->entries != NULL) {
840 + /* we have been here already */
841 + return 0;
842 + }
843 +
844 + hash->name = name;
845 + hash->entries = NULL;
846 + hash->n_entries = 0;
847 + hash->hash_entry_key = NULL;
848 +
849 + picker = primes_table;
850 + while(*picker && (*picker++ < len));
851 + if(!*picker)
852 + fprintf(stderr, "%s: primes table might not be big enough (! << %d)\n", __FUNCTION__, len);
853 + --picker;
854 +
855 + hash->n_entries = *picker;
856 + hash->entries = (hash_entry_t *)calloc(hash->n_entries, sizeof(hash_entry_t));
857 + if (hash->entries == NULL) {
858 + fprintf(stderr, "%s: Out of memory.\n", __FUNCTION__);
859 + return ENOMEM;
860 + }
861 + return 0;
862 +}
863 +
864 +void hash_table_deinit(hash_table_t *hash)
865 +{
866 + free(hash->entries);
867 + hash->entries = NULL;
868 + hash->n_entries = 0;
869 +}
870 +
871 +void *hash_table_get(hash_table_t *hash, const char *key)
872 +{
873 + int ndx= hash_index(hash, key);
874 + hash_entry_t *hash_entry = hash->entries + ndx;
875 + while (hash_entry)
876 + {
877 + if (hash_entry->key)
878 + {
879 + if (strcmp(key, hash_entry->key) == 0) {
880 + // ipkg_message(NULL, IPKG_DEBUG, "Function: %s. Key found for '%s' \n", __FUNCTION__, key);
881 + return hash_entry->data;
882 + }
883 + }
884 + hash_entry = hash_entry->next;
885 + }
886 + return NULL;
887 +}
888 +
889 +int hash_table_insert(hash_table_t *hash, const char *key, void *value)
890 +{
891 + int ndx= hash_index(hash, key);
892 + hash_entry_t *hash_entry = hash->entries + ndx;
893 + if (0) ipkg_message(NULL, IPKG_DEBUG2, "Function: %s. Inserting in hash for '%s' \n", __FUNCTION__, key);
894 + if (hash_entry->key) {
895 + if (strcmp(hash_entry->key, key) == 0) {
896 + /* alread in table, update the value */
897 + if (0) ipkg_message(NULL, IPKG_DEBUG2, "Function: %s. Value already in hash for '%s' \n", __FUNCTION__, key);
898 + hash_entry->data = value;
899 + return 0;
900 + } else {
901 + /*
902 + * if this is a collision, we have to go to the end of the ll,
903 + * then add a new entry
904 + * before we can hook up the value
905 + */
906 + if (0) ipkg_message(NULL, IPKG_DEBUG2, "Function: %s. Value already in hash by collision for '%s' \n", __FUNCTION__, key);
907 + while (hash_entry->next)
908 + hash_entry = hash_entry->next;
909 + hash_entry->next = (hash_entry_t *)malloc(sizeof(hash_entry_t));
910 + if (!hash_entry->next) {
911 + return -ENOMEM;
912 + }
913 + hash_entry = hash_entry->next;
914 + hash_entry->next = NULL;
915 + }
916 + }
917 + hash->n_elements++;
918 + hash_entry->key = strdup(key);
919 + hash_entry->data = value;
920 +
921 + return 0;
922 +}
923 +
924 +
925 +void hash_table_foreach(hash_table_t *hash, void (*f)(const char *key, void *entry, void *data), void *data)
926 +{
927 + int i;
928 + if (!hash || !f)
929 + return;
930 +
931 + for (i = 0; i < hash->n_entries; i++) {
932 + hash_entry_t *hash_entry = (hash->entries + i);
933 + do {
934 + if(hash_entry->key) {
935 + f(hash_entry->key, hash_entry->data, data);
936 + }
937 + } while((hash_entry = hash_entry->next));
938 + }
939 +}
940 +
941 Index: busybox-1.8.1/archival/libipkg/hash_table.h
942 ===================================================================
943 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
944 +++ busybox-1.8.1/archival/libipkg/hash_table.h 2007-11-10 17:40:53.344763742 +0100
945 @@ -0,0 +1,44 @@
946 +/* hash.h - hash tables for ipkg
947 +
948 + Steven M. Ayer, Jamey Hicks
949 +
950 + Copyright (C) 2002 Compaq Computer Corporation
951 +
952 + This program is free software; you can redistribute it and/or
953 + modify it under the terms of the GNU General Public License as
954 + published by the Free Software Foundation; either version 2, or (at
955 + your option) any later version.
956 +
957 + This program is distributed in the hope that it will be useful, but
958 + WITHOUT ANY WARRANTY; without even the implied warranty of
959 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
960 + General Public License for more details.
961 +*/
962 +
963 +#ifndef _HASH_TABLE_H_
964 +#define _HASH_TABLE_H_
965 +
966 +typedef struct hash_entry hash_entry_t;
967 +typedef struct hash_table hash_table_t;
968 +
969 +struct hash_entry {
970 + const char * key;
971 + void * data;
972 + struct hash_entry * next;
973 +};
974 +
975 +struct hash_table {
976 + const char *name;
977 + hash_entry_t * entries;
978 + int n_entries; /* number of buckets */
979 + int n_elements;
980 + const char * (*hash_entry_key)(void * data);
981 +};
982 +
983 +int hash_table_init(const char *name, hash_table_t *hash, int len);
984 +void hash_table_deinit(hash_table_t *hash);
985 +void *hash_table_get(hash_table_t *hash, const char *key);
986 +int hash_table_insert(hash_table_t *hash, const char *key, void *value);
987 +void hash_table_foreach(hash_table_t *hash, void (*f)(const char *key, void *entry, void *data), void *data);
988 +
989 +#endif /* _HASH_TABLE_H_ */
990 Index: busybox-1.8.1/archival/libipkg/ipkg_cmd.c
991 ===================================================================
992 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
993 +++ busybox-1.8.1/archival/libipkg/ipkg_cmd.c 2007-11-10 17:40:53.344763742 +0100
994 @@ -0,0 +1,1431 @@
995 +/* ipkg_cmd.c - the itsy package management system
996 +
997 + Carl D. Worth
998 +
999 + Copyright (C) 2001 University of Southern California
1000 +
1001 + This program is free software; you can redistribute it and/or
1002 + modify it under the terms of the GNU General Public License as
1003 + published by the Free Software Foundation; either version 2, or (at
1004 + your option) any later version.
1005 +
1006 + This program is distributed in the hope that it will be useful, but
1007 + WITHOUT ANY WARRANTY; without even the implied warranty of
1008 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1009 + General Public License for more details.
1010 +*/
1011 +
1012 +#include <string.h>
1013 +
1014 +#include "ipkg.h"
1015 +#include <libgen.h>
1016 +#include <glob.h>
1017 +#include <errno.h>
1018 +#include <stdlib.h>
1019 +#include <unistd.h>
1020 +#include <signal.h>
1021 +#include <stdio.h>
1022 +#include <dirent.h>
1023 +
1024 +#include "ipkg_conf.h"
1025 +#include "ipkg_cmd.h"
1026 +#include "ipkg_message.h"
1027 +#include "pkg.h"
1028 +#include "pkg_dest.h"
1029 +#include "pkg_parse.h"
1030 +#include "sprintf_alloc.h"
1031 +#include "pkg.h"
1032 +#include "file_util.h"
1033 +#include "str_util.h"
1034 +#include "libbb.h"
1035 +#include "unarchive.h"
1036 +
1037 +#include <fnmatch.h>
1038 +
1039 +
1040 +#include "ipkg_download.h"
1041 +#include "ipkg_install.h"
1042 +#include "ipkg_upgrade.h"
1043 +#include "ipkg_remove.h"
1044 +#include "ipkg_configure.h"
1045 +#include "ipkg_message.h"
1046 +
1047 +#ifdef IPKG_LIB
1048 +#include "libipkg.h"
1049 +static void *p_userdata = NULL;
1050 +#endif
1051 +
1052 +static int ipkg_update_cmd(ipkg_conf_t *conf, int argc, char **argv);
1053 +static int ipkg_upgrade_cmd(ipkg_conf_t *conf, int argc, char **argv);
1054 +static int ipkg_list_cmd(ipkg_conf_t *conf, int argc, char **argv);
1055 +static int ipkg_info_cmd(ipkg_conf_t *conf, int argc, char **argv);
1056 +static int ipkg_status_cmd(ipkg_conf_t *conf, int argc, char **argv);
1057 +static int ipkg_install_pending_cmd(ipkg_conf_t *conf, int argc, char **argv);
1058 +static int ipkg_install_cmd(ipkg_conf_t *conf, int argc, char **argv);
1059 +static int ipkg_list_installed_cmd(ipkg_conf_t *conf, int argc, char **argv);
1060 +static int ipkg_remove_cmd(ipkg_conf_t *conf, int argc, char **argv);
1061 +static int ipkg_purge_cmd(ipkg_conf_t *conf, int argc, char **argv);
1062 +static int ipkg_flag_cmd(ipkg_conf_t *conf, int argc, char **argv);
1063 +static int ipkg_files_cmd(ipkg_conf_t *conf, int argc, char **argv);
1064 +static int ipkg_search_cmd(ipkg_conf_t *conf, int argc, char **argv);
1065 +static int ipkg_download_cmd(ipkg_conf_t *conf, int argc, char **argv);
1066 +static int ipkg_depends_cmd(ipkg_conf_t *conf, int argc, char **argv);
1067 +static int ipkg_whatdepends_cmd(ipkg_conf_t *conf, int argc, char **argv);
1068 +static int ipkg_whatdepends_recursively_cmd(ipkg_conf_t *conf, int argc, char **argv);
1069 +static int ipkg_whatsuggests_cmd(ipkg_conf_t *conf, int argc, char **argv);
1070 +static int ipkg_whatrecommends_cmd(ipkg_conf_t *conf, int argc, char **argv);
1071 +static int ipkg_whatprovides_cmd(ipkg_conf_t *conf, int argc, char **argv);
1072 +static int ipkg_whatconflicts_cmd(ipkg_conf_t *conf, int argc, char **argv);
1073 +static int ipkg_whatreplaces_cmd(ipkg_conf_t *conf, int argc, char **argv);
1074 +static int ipkg_compare_versions_cmd(ipkg_conf_t *conf, int argc, char **argv);
1075 +static int ipkg_print_architecture_cmd(ipkg_conf_t *conf, int argc, char **argv);
1076 +static int ipkg_configure_cmd(ipkg_conf_t *conf, int argc, char **argv);
1077 +
1078 +/* XXX: CLEANUP: The usage strings should be incorporated into this
1079 + array for easier maintenance */
1080 +static ipkg_cmd_t cmds[] = {
1081 + {"update", 0, (ipkg_cmd_fun_t)ipkg_update_cmd},
1082 + {"upgrade", 0, (ipkg_cmd_fun_t)ipkg_upgrade_cmd},
1083 + {"list", 0, (ipkg_cmd_fun_t)ipkg_list_cmd},
1084 + {"list_installed", 0, (ipkg_cmd_fun_t)ipkg_list_installed_cmd},
1085 + {"info", 0, (ipkg_cmd_fun_t)ipkg_info_cmd},
1086 + {"flag", 1, (ipkg_cmd_fun_t)ipkg_flag_cmd},
1087 + {"status", 0, (ipkg_cmd_fun_t)ipkg_status_cmd},
1088 + {"install_pending", 0, (ipkg_cmd_fun_t)ipkg_install_pending_cmd},
1089 + {"install", 1, (ipkg_cmd_fun_t)ipkg_install_cmd},
1090 + {"remove", 1, (ipkg_cmd_fun_t)ipkg_remove_cmd},
1091 + {"purge", 1, (ipkg_cmd_fun_t)ipkg_purge_cmd},
1092 + {"configure", 0, (ipkg_cmd_fun_t)ipkg_configure_cmd},
1093 + {"files", 1, (ipkg_cmd_fun_t)ipkg_files_cmd},
1094 + {"search", 1, (ipkg_cmd_fun_t)ipkg_search_cmd},
1095 + {"download", 1, (ipkg_cmd_fun_t)ipkg_download_cmd},
1096 + {"compare_versions", 1, (ipkg_cmd_fun_t)ipkg_compare_versions_cmd},
1097 + {"compare-versions", 1, (ipkg_cmd_fun_t)ipkg_compare_versions_cmd},
1098 + {"print-architecture", 0, (ipkg_cmd_fun_t)ipkg_print_architecture_cmd},
1099 + {"print_architecture", 0, (ipkg_cmd_fun_t)ipkg_print_architecture_cmd},
1100 + {"print-installation-architecture", 0, (ipkg_cmd_fun_t)ipkg_print_architecture_cmd},
1101 + {"print_installation_architecture", 0, (ipkg_cmd_fun_t)ipkg_print_architecture_cmd},
1102 + {"depends", 1, (ipkg_cmd_fun_t)ipkg_depends_cmd},
1103 + {"whatdepends", 1, (ipkg_cmd_fun_t)ipkg_whatdepends_cmd},
1104 + {"whatdependsrec", 1, (ipkg_cmd_fun_t)ipkg_whatdepends_recursively_cmd},
1105 + {"whatrecommends", 1, (ipkg_cmd_fun_t)ipkg_whatrecommends_cmd},
1106 + {"whatsuggests", 1, (ipkg_cmd_fun_t)ipkg_whatsuggests_cmd},
1107 + {"whatprovides", 1, (ipkg_cmd_fun_t)ipkg_whatprovides_cmd},
1108 + {"whatreplaces", 1, (ipkg_cmd_fun_t)ipkg_whatreplaces_cmd},
1109 + {"whatconflicts", 1, (ipkg_cmd_fun_t)ipkg_whatconflicts_cmd},
1110 +};
1111 +
1112 +int ipkg_state_changed;
1113 +static void write_status_files_if_changed(ipkg_conf_t *conf)
1114 +{
1115 + if (ipkg_state_changed && !conf->noaction) {
1116 + ipkg_message(conf, IPKG_INFO,
1117 + " writing status file\n");
1118 + ipkg_conf_write_status_files(conf);
1119 + pkg_write_changed_filelists(conf);
1120 + } else {
1121 + ipkg_message(conf, IPKG_NOTICE, "Nothing to be done\n");
1122 + }
1123 +}
1124 +
1125 +
1126 +static int num_cmds = sizeof(cmds) / sizeof(ipkg_cmd_t);
1127 +
1128 +ipkg_cmd_t *ipkg_cmd_find(const char *name)
1129 +{
1130 + int i;
1131 + ipkg_cmd_t *cmd;
1132 +
1133 + for (i=0; i < num_cmds; i++) {
1134 + cmd = &cmds[i];
1135 + if (strcmp(name, cmd->name) == 0) {
1136 + return cmd;
1137 + }
1138 + }
1139 +
1140 + return NULL;
1141 +}
1142 +
1143 +#ifdef IPKG_LIB
1144 +int ipkg_cmd_exec(ipkg_cmd_t *cmd, ipkg_conf_t *conf, int argc, const char **argv, void *userdata)
1145 +{
1146 + int result;
1147 + p_userdata = userdata;
1148 +
1149 +
1150 + result = (cmd->fun)(conf, argc, argv);
1151 + if ( result == 0 ) {
1152 + ipkg_message(conf, IPKG_NOTICE, "Done.\n");
1153 + } else {
1154 + ipkg_message(conf, IPKG_NOTICE, "An error ocurred, return value: %d.\n", result);
1155 +
1156 + }
1157 + if ( error_list ) {
1158 + reverse_error_list(&error_list);
1159 +
1160 + ipkg_message(conf, IPKG_NOTICE, "Collected errors:\n");
1161 + /* Here we print the errors collected and free the list */
1162 + while (error_list != NULL) {
1163 + ipkg_message(conf, IPKG_NOTICE, "%s",error_list->errmsg);
1164 + error_list = error_list->next;
1165 +
1166 + }
1167 + free_error_list(&error_list);
1168 +
1169 + }
1170 +
1171 + p_userdata = NULL;
1172 + return result;
1173 +}
1174 +#else
1175 +int ipkg_cmd_exec(ipkg_cmd_t *cmd, ipkg_conf_t *conf, int argc, const char **argv)
1176 +{
1177 + return (cmd->fun)(conf, argc, argv);
1178 +}
1179 +#endif
1180 +
1181 +static int ipkg_update_cmd(ipkg_conf_t *conf, int argc, char **argv)
1182 +{
1183 + int err;
1184 + int failures;
1185 + char *lists_dir;
1186 + pkg_src_list_elt_t *iter;
1187 + pkg_src_t *src;
1188 +
1189 +
1190 + sprintf_alloc(&lists_dir, "%s", conf->restrict_to_default_dest ? conf->default_dest->lists_dir : conf->lists_dir);
1191 +
1192 + if (! file_is_dir(lists_dir)) {
1193 + if (file_exists(lists_dir)) {
1194 + ipkg_message(conf, IPKG_ERROR,
1195 + "%s: ERROR: %s exists, but is not a directory\n",
1196 + __FUNCTION__, lists_dir);
1197 + free(lists_dir);
1198 + return EINVAL;
1199 + }
1200 + err = file_mkdir_hier(lists_dir, 0755);
1201 + if (err) {
1202 + ipkg_message(conf, IPKG_ERROR,
1203 + "%s: ERROR: failed to make directory %s: %s\n",
1204 + __FUNCTION__, lists_dir, strerror(errno));
1205 + free(lists_dir);
1206 + return EINVAL;
1207 + }
1208 + }
1209 +
1210 + failures = 0;
1211 + for (iter = conf->pkg_src_list.head; iter; iter = iter->next) {
1212 + char *url, *list_file_name;
1213 +
1214 + src = iter->data;
1215 +
1216 + if (src->extra_data) /* debian style? */
1217 + sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data,
1218 + src->gzip ? "Packages.gz" : "Packages");
1219 + else
1220 + sprintf_alloc(&url, "%s/%s", src->value, src->gzip ? "Packages.gz" : "Packages");
1221 +
1222 + sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name);
1223 + if (src->gzip) {
1224 + char *tmp;
1225 + char *tmp_file_name;
1226 + FILE *in, *out;
1227 +
1228 + tmp = strdup ("/tmp/ipkg.XXXXXX");
1229 +
1230 + if (mkdtemp (tmp) == NULL) {
1231 + perror ("mkdtemp");
1232 + failures++;
1233 + continue;
1234 + }
1235 +
1236 + sprintf_alloc (&tmp_file_name, "%s/%s.gz", tmp, src->name);
1237 + err = ipkg_download(conf, url, tmp_file_name);
1238 + if (err == 0) {
1239 + ipkg_message (conf, IPKG_NOTICE, "Inflating %s\n", url);
1240 + in = fopen (tmp_file_name, "r");
1241 + out = fopen (list_file_name, "w");
1242 + if (in && out) {
1243 + inflate_unzip_result res;
1244 + inflate_unzip (&res, 0x8000, fileno(in), fileno(out));
1245 + } else
1246 + err = 1;
1247 + if (in)
1248 + fclose (in);
1249 + if (out)
1250 + fclose (out);
1251 + unlink (tmp_file_name);
1252 + rmdir (tmp);
1253 + free (tmp);
1254 + }
1255 + } else
1256 + err = ipkg_download(conf, url, list_file_name);
1257 + if (err) {
1258 + failures++;
1259 + } else {
1260 + ipkg_message(conf, IPKG_NOTICE,
1261 + "Updated list of available packages in %s\n",
1262 + list_file_name);
1263 + }
1264 + free(url);
1265 + free(list_file_name);
1266 + }
1267 + free(lists_dir);
1268 +
1269 +#ifdef CONFIG_CLEAR_SW_INSTALL_FLAG
1270 +#warning here
1271 + /* clear SW_INSTALL on any package where state is SS_NOT_INSTALLED.
1272 + * this is a hack to work around poor bookkeeping in old ipkg upgrade code
1273 + * -Jamey 3/1/03
1274 + */
1275 + {
1276 + int i;
1277 + int changed = 0;
1278 + pkg_vec_t *available = pkg_vec_alloc();
1279 + pkg_hash_fetch_available(&conf->pkg_hash, available);
1280 + ipkg_message(conf, IPKG_DEBUG, "Clearing SW_INSTALL for SS_NOT_INSTALLED packages.\n");
1281 + for (i = 0; i < available->len; i++) {
1282 + pkg_t *pkg = available->pkgs[i];
1283 + if (pkg->state_want == SW_INSTALL && pkg->state_status == SS_NOT_INSTALLED) {
1284 + ipkg_message(conf, IPKG_DEBUG, "Clearing SW_INSTALL on package %s.\n", pkg->name);
1285 + pkg->state_want = SW_UNKNOWN;
1286 + changed = 1;
1287 + }
1288 + }
1289 + pkg_vec_free(available);
1290 + if (changed) {
1291 + write_status_files_if_changed(conf);
1292 + }
1293 + }
1294 +#endif
1295 +
1296 + return failures;
1297 +}
1298 +
1299 +
1300 +/* scan the args passed and cache the local filenames of the packages */
1301 +int ipkg_multiple_files_scan(ipkg_conf_t *conf, int argc, char **argv)
1302 +{
1303 + int i;
1304 + int err;
1305 +
1306 + /*
1307 + * First scan through package names/urls
1308 + * For any urls, download the packages and install in database.
1309 + * For any files, install package info in database.
1310 + */
1311 + for (i = 0; i < argc; i ++) {
1312 + char *filename = argv [i];
1313 + //char *tmp = basename (tmp);
1314 + //int tmplen = strlen (tmp);
1315 +
1316 + //if (strcmp (tmp + (tmplen - strlen (IPKG_PKG_EXTENSION)), IPKG_PKG_EXTENSION) != 0)
1317 + // continue;
1318 + //if (strcmp (tmp + (tmplen - strlen (DPKG_PKG_EXTENSION)), DPKG_PKG_EXTENSION) != 0)
1319 + // continue;
1320 +
1321 + ipkg_message(conf, IPKG_DEBUG2, "Debug mfs: %s \n",filename );
1322 +
1323 + err = ipkg_prepare_url_for_install(conf, filename, &argv[i]);
1324 + if (err)
1325 + return err;
1326 + }
1327 + return 0;
1328 +}
1329 +
1330 +struct ipkg_intercept
1331 +{
1332 + char *oldpath;
1333 + char *statedir;
1334 +};
1335 +
1336 +typedef struct ipkg_intercept *ipkg_intercept_t;
1337 +
1338 +ipkg_intercept_t ipkg_prep_intercepts(ipkg_conf_t *conf)
1339 +{
1340 + ipkg_intercept_t ctx;
1341 + char *newpath;
1342 + int gen;
1343 +
1344 + ctx = malloc (sizeof (*ctx));
1345 + ctx->oldpath = strdup (getenv ("PATH"));
1346 +
1347 + sprintf_alloc (&newpath, "%s/ipkg/intercept:%s", IPKGLIBDIR, ctx->oldpath);
1348 + setenv ("PATH", newpath, 1);
1349 + free (newpath);
1350 +
1351 + gen = 0;
1352 + retry:
1353 + sprintf_alloc (&ctx->statedir, "/tmp/ipkg-intercept-%d-%d", getpid (), gen);
1354 + if (mkdir (ctx->statedir, 0770) < 0) {
1355 + if (errno == EEXIST) {
1356 + free (ctx->statedir);
1357 + gen++;
1358 + goto retry;
1359 + }
1360 + perror (ctx->statedir);
1361 + return NULL;
1362 + }
1363 + setenv ("IPKG_INTERCEPT_DIR", ctx->statedir, 1);
1364 + return ctx;
1365 +}
1366 +
1367 +int ipkg_finalize_intercepts(ipkg_intercept_t ctx)
1368 +{
1369 + char *cmd;
1370 + DIR *dir;
1371 + int err = 0;
1372 +
1373 + setenv ("PATH", ctx->oldpath, 1);
1374 + free (ctx->oldpath);
1375 +
1376 + dir = opendir (ctx->statedir);
1377 + if (dir) {
1378 + struct dirent *de;
1379 + while (de = readdir (dir), de != NULL) {
1380 + char *path;
1381 +
1382 + if (de->d_name[0] == '.')
1383 + continue;
1384 +
1385 + sprintf_alloc (&path, "%s/%s", ctx->statedir, de->d_name);
1386 + if (access (path, X_OK) == 0) {
1387 + if (system (path)) {
1388 + err = errno;
1389 + perror (de->d_name);
1390 + }
1391 + }
1392 + free (path);
1393 + }
1394 + } else
1395 + perror (ctx->statedir);
1396 +
1397 + sprintf_alloc (&cmd, "rm -rf %s", ctx->statedir);
1398 + system (cmd);
1399 + free (cmd);
1400 +
1401 + free (ctx->statedir);
1402 + free (ctx);
1403 +
1404 + return err;
1405 +}
1406 +
1407 +int ipkg_configure_packages(ipkg_conf_t *conf, char *pkg_name)
1408 +{
1409 + pkg_vec_t *all;
1410 + int i;
1411 + pkg_t *pkg;
1412 + ipkg_intercept_t ic;
1413 + int r, err = 0;
1414 +
1415 + ipkg_message(conf, IPKG_INFO,
1416 + "Configuring unpacked packages\n");
1417 + fflush( stdout );
1418 +
1419 + all = pkg_vec_alloc();
1420 + pkg_hash_fetch_available(&conf->pkg_hash, all);
1421 +
1422 + ic = ipkg_prep_intercepts (conf);
1423 +
1424 + for(i = 0; i < all->len; i++) {
1425 + pkg = all->pkgs[i];
1426 +
1427 + if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
1428 + continue;
1429 +
1430 + if (pkg->state_status == SS_UNPACKED) {
1431 + ipkg_message(conf, IPKG_NOTICE,
1432 + "Configuring %s\n", pkg->name);
1433 + fflush( stdout );
1434 + r = ipkg_configure(conf, pkg);
1435 + if (r == 0) {
1436 + pkg->state_status = SS_INSTALLED;
1437 + pkg->parent->state_status = SS_INSTALLED;
1438 + pkg->state_flag &= ~SF_PREFER;
1439 + } else {
1440 + if (!err)
1441 + err = r;
1442 + }
1443 + }
1444 + }
1445 +
1446 + r = ipkg_finalize_intercepts (ic);
1447 + if (r && !err)
1448 + err = r;
1449 +
1450 + pkg_vec_free(all);
1451 + return err;
1452 +}
1453 +
1454 +static void sigint_handler(int sig)
1455 +{
1456 + signal(sig, SIG_DFL);
1457 + ipkg_message(NULL, IPKG_NOTICE,
1458 + "ipkg: interrupted. writing out status database\n");
1459 + write_status_files_if_changed(global_conf);
1460 + exit(128 + sig);
1461 +}
1462 +
1463 +static int ipkg_install_cmd(ipkg_conf_t *conf, int argc, char **argv)
1464 +{
1465 + int i;
1466 + char *arg;
1467 + int err=0;
1468 +
1469 + global_conf = conf;
1470 + signal(SIGINT, sigint_handler);
1471 +
1472 + /*
1473 + * Now scan through package names and install
1474 + */
1475 + for (i=0; i < argc; i++) {
1476 + arg = argv[i];
1477 +
1478 + ipkg_message(conf, IPKG_DEBUG2, "Debug install_cmd: %s \n",arg );
1479 + err = ipkg_prepare_url_for_install(conf, arg, &argv[i]);
1480 + if (err != EINVAL && err != 0)
1481 + return err;
1482 + }
1483 + pkg_info_preinstall_check(conf);
1484 +
1485 + for (i=0; i < argc; i++) {
1486 + arg = argv[i];
1487 + if (conf->multiple_providers)
1488 + err = ipkg_install_multi_by_name(conf, arg);
1489 + else{
1490 + err = ipkg_install_by_name(conf, arg);
1491 + }
1492 + if (err == IPKG_PKG_HAS_NO_CANDIDATE) {
1493 + ipkg_message(conf, IPKG_ERROR,
1494 + "Cannot find package %s.\n"
1495 + "Check the spelling or perhaps run 'ipkg update'\n",
1496 + arg);
1497 + }
1498 + }
1499 +
1500 + /* recheck to verify that all dependences are satisfied */
1501 + if (0) ipkg_satisfy_all_dependences(conf);
1502 +
1503 + ipkg_configure_packages(conf, NULL);
1504 +
1505 + write_status_files_if_changed(conf);
1506 +
1507 + return err;
1508 +}
1509 +
1510 +static int ipkg_upgrade_cmd(ipkg_conf_t *conf, int argc, char **argv)
1511 +{
1512 + int i;
1513 + pkg_t *pkg;
1514 + int err;
1515 +
1516 + global_conf = conf;
1517 + signal(SIGINT, sigint_handler);
1518 +
1519 + if (argc) {
1520 + for (i=0; i < argc; i++) {
1521 + char *arg = argv[i];
1522 +
1523 + err = ipkg_prepare_url_for_install(conf, arg, &arg);
1524 + if (err != EINVAL && err != 0)
1525 + return err;
1526 + }
1527 + pkg_info_preinstall_check(conf);
1528 +
1529 + for (i=0; i < argc; i++) {
1530 + char *arg = argv[i];
1531 + if (conf->restrict_to_default_dest) {
1532 + pkg = pkg_hash_fetch_installed_by_name_dest(&conf->pkg_hash,
1533 + argv[i],
1534 + conf->default_dest);
1535 + if (pkg == NULL) {
1536 + ipkg_message(conf, IPKG_NOTICE,
1537 + "Package %s not installed in %s\n",
1538 + argv[i], conf->default_dest->name);
1539 + continue;
1540 + }
1541 + } else {
1542 + pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash,
1543 + argv[i]);
1544 + }
1545 + if (pkg)
1546 + ipkg_upgrade_pkg(conf, pkg);
1547 + else {
1548 + ipkg_install_by_name(conf, arg);
1549 + }
1550 + }
1551 + } else {
1552 + pkg_vec_t *installed = pkg_vec_alloc();
1553 +
1554 + pkg_info_preinstall_check(conf);
1555 +
1556 + pkg_hash_fetch_all_installed(&conf->pkg_hash, installed);
1557 + for (i = 0; i < installed->len; i++) {
1558 + pkg = installed->pkgs[i];
1559 + ipkg_upgrade_pkg(conf, pkg);
1560 + }
1561 + pkg_vec_free(installed);
1562 + }
1563 +
1564 + /* recheck to verify that all dependences are satisfied */
1565 + if (0) ipkg_satisfy_all_dependences(conf);
1566 +
1567 + ipkg_configure_packages(conf, NULL);
1568 +
1569 + write_status_files_if_changed(conf);
1570 +
1571 + return 0;
1572 +}
1573 +
1574 +static int ipkg_download_cmd(ipkg_conf_t *conf, int argc, char **argv)
1575 +{
1576 + int i, err;
1577 + char *arg;
1578 + pkg_t *pkg;
1579 +
1580 + pkg_info_preinstall_check(conf);
1581 + for (i = 0; i < argc; i++) {
1582 + arg = argv[i];
1583 +
1584 + pkg = pkg_hash_fetch_best_installation_candidate_by_name(conf, arg);
1585 + if (pkg == NULL) {
1586 + ipkg_message(conf, IPKG_ERROR,
1587 + "Cannot find package %s.\n"
1588 + "Check the spelling or perhaps run 'ipkg update'\n",
1589 + arg);
1590 + continue;
1591 + }
1592 +
1593 + err = ipkg_download_pkg(conf, pkg, ".");
1594 +
1595 + if (err) {
1596 + ipkg_message(conf, IPKG_ERROR,
1597 + "Failed to download %s\n", pkg->name);
1598 + } else {
1599 + ipkg_message(conf, IPKG_NOTICE,
1600 + "Downloaded %s as %s\n",
1601 + pkg->name, pkg->local_filename);
1602 + }
1603 + }
1604 +
1605 + return 0;
1606 +}
1607 +
1608 +
1609 +static int ipkg_list_cmd(ipkg_conf_t *conf, int argc, char **argv)
1610 +{
1611 + int i ;
1612 + pkg_vec_t *available;
1613 + pkg_t *pkg;
1614 + char desc_short[IPKG_LIST_DESCRIPTION_LENGTH];
1615 + char *newline;
1616 + char *pkg_name = NULL;
1617 + char *version_str;
1618 +
1619 + if (argc > 0) {
1620 + pkg_name = argv[0];
1621 + }
1622 + available = pkg_vec_alloc();
1623 + pkg_hash_fetch_available(&conf->pkg_hash, available);
1624 + for (i=0; i < available->len; i++) {
1625 + pkg = available->pkgs[i];
1626 + /* if we have package name or pattern and pkg does not match, then skip it */
1627 + if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
1628 + continue;
1629 + if (pkg->description) {
1630 + strncpy(desc_short, pkg->description, IPKG_LIST_DESCRIPTION_LENGTH);
1631 + } else {
1632 + desc_short[0] = '\0';
1633 + }
1634 + desc_short[IPKG_LIST_DESCRIPTION_LENGTH - 1] = '\0';
1635 + newline = strchr(desc_short, '\n');
1636 + if (newline) {
1637 + *newline = '\0';
1638 + }
1639 +#ifndef IPKG_LIB
1640 + printf("%s - %s\n", pkg->name, desc_short);
1641 +#else
1642 + if (ipkg_cb_list) {
1643 + version_str = pkg_version_str_alloc(pkg);
1644 + ipkg_cb_list(pkg->name,desc_short,
1645 + version_str,
1646 + pkg->state_status,
1647 + p_userdata);
1648 + free(version_str);
1649 + }
1650 +#endif
1651 + }
1652 + pkg_vec_free(available);
1653 +
1654 + return 0;
1655 +}
1656 +
1657 +
1658 +static int ipkg_list_installed_cmd(ipkg_conf_t *conf, int argc, char **argv)
1659 +{
1660 + int i ;
1661 + pkg_vec_t *available;
1662 + pkg_t *pkg;
1663 + char desc_short[IPKG_LIST_DESCRIPTION_LENGTH];
1664 + char *newline;
1665 + char *pkg_name = NULL;
1666 + char *version_str;
1667 +
1668 + if (argc > 0) {
1669 + pkg_name = argv[0];
1670 + }
1671 + available = pkg_vec_alloc();
1672 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available);
1673 + for (i=0; i < available->len; i++) {
1674 + pkg = available->pkgs[i];
1675 + /* if we have package name or pattern and pkg does not match, then skip it */
1676 + if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
1677 + continue;
1678 + if (pkg->description) {
1679 + strncpy(desc_short, pkg->description, IPKG_LIST_DESCRIPTION_LENGTH);
1680 + } else {
1681 + desc_short[0] = '\0';
1682 + }
1683 + desc_short[IPKG_LIST_DESCRIPTION_LENGTH - 1] = '\0';
1684 + newline = strchr(desc_short, '\n');
1685 + if (newline) {
1686 + *newline = '\0';
1687 + }
1688 +#ifndef IPKG_LIB
1689 + printf("%s - %s\n", pkg->name, desc_short);
1690 +#else
1691 + if (ipkg_cb_list) {
1692 + version_str = pkg_version_str_alloc(pkg);
1693 + ipkg_cb_list(pkg->name,desc_short,
1694 + version_str,
1695 + pkg->state_status,
1696 + p_userdata);
1697 + free(version_str);
1698 + }
1699 +#endif
1700 + }
1701 +
1702 + return 0;
1703 +}
1704 +
1705 +static int ipkg_info_status_cmd(ipkg_conf_t *conf, int argc, char **argv, int installed_only)
1706 +{
1707 + int i;
1708 + pkg_vec_t *available;
1709 + pkg_t *pkg;
1710 + char *pkg_name = NULL;
1711 + char **pkg_fields = NULL;
1712 + int n_fields = 0;
1713 + char *buff ; // = (char *)malloc(1);
1714 +
1715 + if (argc > 0) {
1716 + pkg_name = argv[0];
1717 + }
1718 + if (argc > 1) {
1719 + pkg_fields = &argv[1];
1720 + n_fields = argc - 1;
1721 + }
1722 +
1723 + available = pkg_vec_alloc();
1724 + if (installed_only)
1725 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available);
1726 + else
1727 + pkg_hash_fetch_available(&conf->pkg_hash, available);
1728 + for (i=0; i < available->len; i++) {
1729 + pkg = available->pkgs[i];
1730 + if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
1731 + continue;
1732 + }
1733 +#ifndef IPKG_LIB
1734 + if (n_fields) {
1735 + for (j = 0; j < n_fields; j++)
1736 + pkg_print_field(pkg, stdout, pkg_fields[j]);
1737 + } else {
1738 + pkg_print_info(pkg, stdout);
1739 + }
1740 +#else
1741 +
1742 + buff = pkg_formatted_info(pkg);
1743 + if ( buff ) {
1744 + if (ipkg_cb_status) ipkg_cb_status(pkg->name,
1745 + pkg->state_status,
1746 + buff,
1747 + p_userdata);
1748 +/*
1749 + We should not forget that actually the pointer is allocated.
1750 + We need to free it :) ( Thanks florian for seeing the error )
1751 +*/
1752 + free(buff);
1753 + }
1754 +#endif
1755 + if (conf->verbosity > 1) {
1756 + conffile_list_elt_t *iter;
1757 + for (iter = pkg->conffiles.head; iter; iter = iter->next) {
1758 + conffile_t *cf = iter->data;
1759 + int modified = conffile_has_been_modified(conf, cf);
1760 + ipkg_message(conf, IPKG_NOTICE, "conffile=%s md5sum=%s modified=%d\n",
1761 + cf->name, cf->value, modified);
1762 + }
1763 + }
1764 + }
1765 +#ifndef IPKG_LIB
1766 + if (buff)
1767 + free(buff);
1768 +#endif
1769 + pkg_vec_free(available);
1770 +
1771 + return 0;
1772 +}
1773 +
1774 +static int ipkg_info_cmd(ipkg_conf_t *conf, int argc, char **argv)
1775 +{
1776 + return ipkg_info_status_cmd(conf, argc, argv, 0);
1777 +}
1778 +
1779 +static int ipkg_status_cmd(ipkg_conf_t *conf, int argc, char **argv)
1780 +{
1781 + return ipkg_info_status_cmd(conf, argc, argv, 1);
1782 +}
1783 +
1784 +static int ipkg_configure_cmd(ipkg_conf_t *conf, int argc, char **argv)
1785 +{
1786 +
1787 + int err;
1788 + if (argc > 0) {
1789 + char *pkg_name = NULL;
1790 +
1791 + pkg_name = argv[0];
1792 +
1793 + err = ipkg_configure_packages (conf, pkg_name);
1794 +
1795 + } else {
1796 + err = ipkg_configure_packages (conf, NULL);
1797 + }
1798 +
1799 + write_status_files_if_changed(conf);
1800 +
1801 + return err;
1802 +}
1803 +
1804 +static int ipkg_install_pending_cmd(ipkg_conf_t *conf, int argc, char **argv)
1805 +{
1806 + int i, err;
1807 + char *globpattern;
1808 + glob_t globbuf;
1809 +
1810 + sprintf_alloc(&globpattern, "%s/*" IPKG_PKG_EXTENSION, conf->pending_dir);
1811 + err = glob(globpattern, 0, NULL, &globbuf);
1812 + free(globpattern);
1813 + if (err) {
1814 + return 0;
1815 + }
1816 +
1817 + ipkg_message(conf, IPKG_NOTICE,
1818 + "The following packages in %s will now be installed.\n",
1819 + conf->pending_dir);
1820 + for (i = 0; i < globbuf.gl_pathc; i++) {
1821 + ipkg_message(conf, IPKG_NOTICE,
1822 + "%s%s", i == 0 ? "" : " ", globbuf.gl_pathv[i]);
1823 + }
1824 + ipkg_message(conf, IPKG_NOTICE, "\n");
1825 + for (i = 0; i < globbuf.gl_pathc; i++) {
1826 + err = ipkg_install_from_file(conf, globbuf.gl_pathv[i]);
1827 + if (err == 0) {
1828 + err = unlink(globbuf.gl_pathv[i]);
1829 + if (err) {
1830 + ipkg_message(conf, IPKG_ERROR,
1831 + "%s: ERROR: failed to unlink %s: %s\n",
1832 + __FUNCTION__, globbuf.gl_pathv[i], strerror(err));
1833 + return err;
1834 + }
1835 + }
1836 + }
1837 + globfree(&globbuf);
1838 +
1839 + return err;
1840 +}
1841 +
1842 +static int ipkg_remove_cmd(ipkg_conf_t *conf, int argc, char **argv)
1843 +{
1844 + int i,a,done;
1845 + pkg_t *pkg;
1846 + pkg_t *pkg_to_remove;
1847 + pkg_vec_t *available;
1848 + char *pkg_name = NULL;
1849 + global_conf = conf;
1850 + signal(SIGINT, sigint_handler);
1851 +
1852 +// ENH: Add the "no pkg removed" just in case.
1853 +
1854 + done = 0;
1855 +
1856 + available = pkg_vec_alloc();
1857 + pkg_info_preinstall_check(conf);
1858 + if ( argc > 0 ) {
1859 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available);
1860 + for (i=0; i < argc; i++) {
1861 + pkg_name = malloc(strlen(argv[i])+2);
1862 + strcpy(pkg_name,argv[i]);
1863 + for (a=0; a < available->len; a++) {
1864 + pkg = available->pkgs[a];
1865 + if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
1866 + continue;
1867 + }
1868 + if (conf->restrict_to_default_dest) {
1869 + pkg_to_remove = pkg_hash_fetch_installed_by_name_dest(&conf->pkg_hash,
1870 + pkg->name,
1871 + conf->default_dest);
1872 + } else {
1873 + pkg_to_remove = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name );
1874 + }
1875 +
1876 + if (pkg == NULL) {
1877 + ipkg_message(conf, IPKG_ERROR, "Package %s is not installed.\n", pkg->name);
1878 + continue;
1879 + }
1880 + if (pkg->state_status == SS_NOT_INSTALLED) { // Added the control, so every already removed package could be skipped
1881 + ipkg_message(conf, IPKG_ERROR, "Package seems to be %s not installed (STATUS = NOT_INSTALLED).\n", pkg->name);
1882 + continue;
1883 + }
1884 + ipkg_remove_pkg(conf, pkg_to_remove,0);
1885 + done = 1;
1886 + }
1887 + free (pkg_name);
1888 + }
1889 + pkg_vec_free(available);
1890 + } else {
1891 + pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1892 + int flagged_pkg_count = 0;
1893 + int removed;
1894 +
1895 + pkg_hash_fetch_all_installed(&conf->pkg_hash, installed_pkgs);
1896 +
1897 + for (i = 0; i < installed_pkgs->len; i++) {
1898 + pkg = installed_pkgs->pkgs[i];
1899 + if (pkg->state_flag & SF_USER) {
1900 + flagged_pkg_count++;
1901 + } else {
1902 + if (!pkg_has_installed_dependents(conf, pkg->parent, pkg, NULL))
1903 + ipkg_message(conf, IPKG_NOTICE, "Non-user leaf package: %s\n", pkg->name);
1904 + }
1905 + }
1906 + if (!flagged_pkg_count) {
1907 + ipkg_message(conf, IPKG_NOTICE, "No packages flagged as installed by user, \n"
1908 + "so refusing to uninstall unflagged non-leaf packages\n");
1909 + return 0;
1910 + }
1911 +
1912 + /* find packages not flagged SF_USER (i.e., installed to
1913 + * satisfy a dependence) and not having any dependents, and
1914 + * remove them */
1915 + do {
1916 + removed = 0;
1917 + for (i = 0; i < installed_pkgs->len; i++) {
1918 + pkg = installed_pkgs->pkgs[i];
1919 + if (!(pkg->state_flag & SF_USER)
1920 + && !pkg_has_installed_dependents(conf, pkg->parent, pkg, NULL)) {
1921 + removed++;
1922 + ipkg_message(conf, IPKG_NOTICE, "Removing non-user leaf package %s\n");
1923 + ipkg_remove_pkg(conf, pkg,0);
1924 + done = 1;
1925 + }
1926 + }
1927 + } while (removed);
1928 + pkg_vec_free(installed_pkgs);
1929 + }
1930 +
1931 + if ( done == 0 )
1932 + ipkg_message(conf, IPKG_NOTICE, "No packages removed.\n");
1933 +
1934 + write_status_files_if_changed(conf);
1935 + return 0;
1936 +}
1937 +
1938 +static int ipkg_purge_cmd(ipkg_conf_t *conf, int argc, char **argv)
1939 +{
1940 + int i;
1941 + pkg_t *pkg;
1942 +
1943 + global_conf = conf;
1944 + signal(SIGINT, sigint_handler);
1945 +
1946 + pkg_info_preinstall_check(conf);
1947 +
1948 + for (i=0; i < argc; i++) {
1949 + if (conf->restrict_to_default_dest) {
1950 + pkg = pkg_hash_fetch_installed_by_name_dest(&conf->pkg_hash,
1951 + argv[i],
1952 + conf->default_dest);
1953 + } else {
1954 + pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, argv[i]);
1955 + }
1956 +
1957 + if (pkg == NULL) {
1958 + ipkg_message(conf, IPKG_ERROR,
1959 + "Package %s is not installed.\n", argv[i]);
1960 + continue;
1961 + }
1962 + ipkg_purge_pkg(conf, pkg);
1963 + }
1964 +
1965 + write_status_files_if_changed(conf);
1966 + return 0;
1967 +}
1968 +
1969 +static int ipkg_flag_cmd(ipkg_conf_t *conf, int argc, char **argv)
1970 +{
1971 + int i;
1972 + pkg_t *pkg;
1973 + char *flags = argv[0];
1974 +
1975 + global_conf = conf;
1976 + signal(SIGINT, sigint_handler);
1977 +
1978 + for (i=1; i < argc; i++) {
1979 + if (conf->restrict_to_default_dest) {
1980 + pkg = pkg_hash_fetch_installed_by_name_dest(&conf->pkg_hash,
1981 + argv[i],
1982 + conf->default_dest);
1983 + } else {
1984 + pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, argv[i]);
1985 + }
1986 +
1987 + if (pkg == NULL) {
1988 + ipkg_message(conf, IPKG_ERROR,
1989 + "Package %s is not installed.\n", argv[i]);
1990 + continue;
1991 + }
1992 + if (( strcmp(flags,"hold")==0)||( strcmp(flags,"noprune")==0)||
1993 + ( strcmp(flags,"user")==0)||( strcmp(flags,"ok")==0)) {
1994 + pkg->state_flag = pkg_state_flag_from_str(flags);
1995 + }
1996 +/* pb_ asked this feature 03292004 */
1997 +/* Actually I will use only this two, but this is an open for various status */
1998 + if (( strcmp(flags,"installed")==0)||( strcmp(flags,"unpacked")==0)){
1999 + pkg->state_status = pkg_state_status_from_str(flags);
2000 + }
2001 + ipkg_state_changed++;
2002 + ipkg_message(conf, IPKG_NOTICE,
2003 + "Setting flags for package %s to %s\n",
2004 + pkg->name, flags);
2005 + }
2006 +
2007 + write_status_files_if_changed(conf);
2008 + return 0;
2009 +}
2010 +
2011 +static int ipkg_files_cmd(ipkg_conf_t *conf, int argc, char **argv)
2012 +{
2013 + pkg_t *pkg;
2014 + str_list_t *installed_files;
2015 + str_list_elt_t *iter;
2016 + char *pkg_version;
2017 + size_t buff_len = 8192;
2018 + size_t used_len;
2019 + char *buff ;
2020 +
2021 + buff = (char *)malloc(buff_len);
2022 + if ( buff == NULL ) {
2023 + fprintf( stderr,"%s: Unable to allocate memory \n",__FUNCTION__);
2024 + return ENOMEM;
2025 + }
2026 +
2027 + if (argc < 1) {
2028 + return EINVAL;
2029 + }
2030 +
2031 + pkg = pkg_hash_fetch_installed_by_name(&conf->pkg_hash,
2032 + argv[0]);
2033 + if (pkg == NULL) {
2034 + ipkg_message(conf, IPKG_ERROR,
2035 + "Package %s not installed.\n", argv[0]);
2036 + return 0;
2037 + }
2038 +
2039 + installed_files = pkg_get_installed_files(pkg);
2040 + pkg_version = pkg_version_str_alloc(pkg);
2041 +
2042 +#ifndef IPKG_LIB
2043 + printf("Package %s (%s) is installed on %s and has the following files:\n",
2044 + pkg->name, pkg_version, pkg->dest->name);
2045 + for (iter = installed_files->head; iter; iter = iter->next) {
2046 + puts(iter->data);
2047 + }
2048 +#else
2049 + if (buff) {
2050 + try_again:
2051 + used_len = snprintf(buff, buff_len, "Package %s (%s) is installed on %s and has the following files:\n",
2052 + pkg->name, pkg_version, pkg->dest->name) + 1;
2053 + if (used_len > buff_len) {
2054 + buff_len *= 2;
2055 + buff = realloc (buff, buff_len);
2056 + goto try_again;
2057 + }
2058 + for (iter = installed_files->head; iter; iter = iter->next) {
2059 + used_len += strlen (iter->data) + 1;
2060 + while (buff_len <= used_len) {
2061 + buff_len *= 2;
2062 + buff = realloc (buff, buff_len);
2063 + }
2064 + strncat(buff, iter->data, buff_len);
2065 + strncat(buff, "\n", buff_len);
2066 + }
2067 + if (ipkg_cb_list) ipkg_cb_list(pkg->name,
2068 + buff,
2069 + pkg_version_str_alloc(pkg),
2070 + pkg->state_status,
2071 + p_userdata);
2072 + free(buff);
2073 + }
2074 +#endif
2075 +
2076 + free(pkg_version);
2077 + pkg_free_installed_files(pkg);
2078 +
2079 + return 0;
2080 +}
2081 +
2082 +static int ipkg_depends_cmd(ipkg_conf_t *conf, int argc, char **argv)
2083 +{
2084 +
2085 + if (argc > 0) {
2086 + pkg_vec_t *available_pkgs = pkg_vec_alloc();
2087 + const char *rel_str = "depends on";
2088 + int i;
2089 +
2090 + pkg_info_preinstall_check(conf);
2091 +
2092 + if (conf->query_all)
2093 + pkg_hash_fetch_available(&conf->pkg_hash, available_pkgs);
2094 + else
2095 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available_pkgs);
2096 + for (i = 0; i < argc; i++) {
2097 + const char *target = argv[i];
2098 + int j;
2099 +
2100 + ipkg_message(conf, IPKG_ERROR, "target=%s\n", target);
2101 +
2102 + for (j = 0; j < available_pkgs->len; j++) {
2103 + pkg_t *pkg = available_pkgs->pkgs[j];
2104 + if (fnmatch(target, pkg->name, 0) == 0) {
2105 + int k;
2106 + int count = pkg->depends_count + pkg->pre_depends_count;
2107 + ipkg_message(conf, IPKG_ERROR, "What %s (arch=%s) %s\n",
2108 + target, pkg->architecture, rel_str);
2109 + for (k = 0; k < count; k++) {
2110 + compound_depend_t *cdepend = &pkg->depends[k];
2111 + int l;
2112 + for (l = 0; l < cdepend->possibility_count; l++) {
2113 + depend_t *possibility = cdepend->possibilities[l];
2114 + ipkg_message(conf, IPKG_ERROR, " %s", possibility->pkg->name);
2115 + if (conf->verbosity > 0) {
2116 + // char *ver = abstract_pkg_version_str_alloc(possibility->pkg);
2117 + ipkg_message(conf, IPKG_NOTICE, " %s", possibility->version);
2118 + if (possibility->version) {
2119 + char *typestr = NULL;
2120 + switch (possibility->constraint) {
2121 + case NONE: typestr = "none"; break;
2122 + case EARLIER: typestr = "<"; break;
2123 + case EARLIER_EQUAL: typestr = "<="; break;
2124 + case EQUAL: typestr = "="; break;
2125 + case LATER_EQUAL: typestr = ">="; break;
2126 + case LATER: typestr = ">"; break;
2127 + }
2128 + ipkg_message(conf, IPKG_NOTICE, " (%s %s)", typestr, possibility->version);
2129 + }
2130 + // free(ver);
2131 + }
2132 + ipkg_message(conf, IPKG_ERROR, "\n");
2133 + }
2134 + }
2135 + }
2136 + }
2137 + }
2138 + pkg_vec_free(available_pkgs);
2139 + }
2140 + return 0;
2141 +}
2142 +
2143 +enum what_field_type {
2144 + WHATDEPENDS,
2145 + WHATCONFLICTS,
2146 + WHATPROVIDES,
2147 + WHATREPLACES,
2148 + WHATRECOMMENDS,
2149 + WHATSUGGESTS
2150 +};
2151 +
2152 +static int ipkg_what_depends_conflicts_cmd(ipkg_conf_t *conf, enum what_field_type what_field_type, int recursive, int argc, char **argv)
2153 +{
2154 +
2155 + if (argc > 0) {
2156 + pkg_vec_t *available_pkgs = pkg_vec_alloc();
2157 + const char *rel_str = NULL;
2158 + int i;
2159 + int changed;
2160 +
2161 + switch (what_field_type) {
2162 + case WHATDEPENDS: rel_str = "depends on"; break;
2163 + case WHATCONFLICTS: rel_str = "conflicts with"; break;
2164 + case WHATSUGGESTS: rel_str = "suggests"; break;
2165 + case WHATRECOMMENDS: rel_str = "recommends"; break;
2166 + case WHATPROVIDES: rel_str = "provides"; break;
2167 + case WHATREPLACES: rel_str = "replaces"; break;
2168 + }
2169 +
2170 + if (conf->query_all)
2171 + pkg_hash_fetch_available(&conf->pkg_hash, available_pkgs);
2172 + else
2173 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available_pkgs);
2174 +
2175 + /* mark the root set */
2176 + pkg_vec_clear_marks(available_pkgs);
2177 + ipkg_message(conf, IPKG_NOTICE, "Root set:\n");
2178 + for (i = 0; i < argc; i++) {
2179 + const char *dependee_pattern = argv[i];
2180 + pkg_vec_mark_if_matches(available_pkgs, dependee_pattern);
2181 + }
2182 + for (i = 0; i < available_pkgs->len; i++) {
2183 + pkg_t *pkg = available_pkgs->pkgs[i];
2184 + if (pkg->state_flag & SF_MARKED) {
2185 + /* mark the parent (abstract) package */
2186 + pkg_mark_provides(pkg);
2187 + ipkg_message(conf, IPKG_NOTICE, " %s\n", pkg->name);
2188 + }
2189 + }
2190 +
2191 + ipkg_message(conf, IPKG_NOTICE, "What %s root set\n", rel_str);
2192 + do {
2193 + int j;
2194 + changed = 0;
2195 +
2196 + for (j = 0; j < available_pkgs->len; j++) {
2197 + pkg_t *pkg = available_pkgs->pkgs[j];
2198 + int k;
2199 + int count = ((what_field_type == WHATCONFLICTS)
2200 + ? pkg->conflicts_count
2201 + : pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count);
2202 + /* skip this package if it is already marked */
2203 + if (pkg->parent->state_flag & SF_MARKED) {
2204 + continue;
2205 + }
2206 + for (k = 0; k < count; k++) {
2207 + compound_depend_t *cdepend =
2208 + (what_field_type == WHATCONFLICTS) ? &pkg->conflicts[k] : &pkg->depends[k];
2209 + int l;
2210 + for (l = 0; l < cdepend->possibility_count; l++) {
2211 + depend_t *possibility = cdepend->possibilities[l];
2212 + if (possibility->pkg->state_flag & SF_MARKED) {
2213 + /* mark the depending package so we won't visit it again */
2214 + pkg->state_flag |= SF_MARKED;
2215 + pkg_mark_provides(pkg);
2216 + changed++;
2217 +
2218 + ipkg_message(conf, IPKG_NOTICE, " %s", pkg->name);
2219 + if (conf->verbosity > 0) {
2220 + char *ver = pkg_version_str_alloc(pkg);
2221 + ipkg_message(conf, IPKG_NOTICE, " %s", ver);
2222 + ipkg_message(conf, IPKG_NOTICE, "\t%s %s", rel_str, possibility->pkg->name);
2223 + if (possibility->version) {
2224 + char *typestr = NULL;
2225 + switch (possibility->constraint) {
2226 + case NONE: typestr = "none"; break;
2227 + case EARLIER: typestr = "<"; break;
2228 + case EARLIER_EQUAL: typestr = "<="; break;
2229 + case EQUAL: typestr = "="; break;
2230 + case LATER_EQUAL: typestr = ">="; break;
2231 + case LATER: typestr = ">"; break;
2232 + }
2233 + ipkg_message(conf, IPKG_NOTICE, " (%s %s)", typestr, possibility->version);
2234 + }
2235 + free(ver);
2236 + if (!pkg_dependence_satisfiable(conf, possibility))
2237 + ipkg_message(conf, IPKG_NOTICE, " unsatisfiable");
2238 + }
2239 + ipkg_message(conf, IPKG_NOTICE, "\n");
2240 + goto next_package;
2241 + }
2242 + }
2243 + }
2244 + next_package:
2245 + ;
2246 + }
2247 + } while (changed && recursive);
2248 + pkg_vec_free(available_pkgs);
2249 + }
2250 +
2251 + return 0;
2252 +}
2253 +
2254 +int pkg_mark_provides(pkg_t *pkg)
2255 +{
2256 + int provides_count = pkg->provides_count;
2257 + abstract_pkg_t **provides = pkg->provides;
2258 + int i;
2259 + pkg->parent->state_flag |= SF_MARKED;
2260 + for (i = 0; i < provides_count; i++) {
2261 + provides[i]->state_flag |= SF_MARKED;
2262 + }
2263 + return 0;
2264 +}
2265 +
2266 +static int ipkg_whatdepends_recursively_cmd(ipkg_conf_t *conf, int argc, char **argv)
2267 +{
2268 + return ipkg_what_depends_conflicts_cmd(conf, WHATDEPENDS, 1, argc, argv);
2269 +}
2270 +static int ipkg_whatdepends_cmd(ipkg_conf_t *conf, int argc, char **argv)
2271 +{
2272 + return ipkg_what_depends_conflicts_cmd(conf, WHATDEPENDS, 0, argc, argv);
2273 +}
2274 +
2275 +static int ipkg_whatsuggests_cmd(ipkg_conf_t *conf, int argc, char **argv)
2276 +{
2277 + return ipkg_what_depends_conflicts_cmd(conf, WHATSUGGESTS, 0, argc, argv);
2278 +}
2279 +
2280 +static int ipkg_whatrecommends_cmd(ipkg_conf_t *conf, int argc, char **argv)
2281 +{
2282 + return ipkg_what_depends_conflicts_cmd(conf, WHATRECOMMENDS, 0, argc, argv);
2283 +}
2284 +
2285 +static int ipkg_whatconflicts_cmd(ipkg_conf_t *conf, int argc, char **argv)
2286 +{
2287 + return ipkg_what_depends_conflicts_cmd(conf, WHATCONFLICTS, 0, argc, argv);
2288 +}
2289 +
2290 +static int ipkg_what_provides_replaces_cmd(ipkg_conf_t *conf, enum what_field_type what_field_type, int argc, char **argv)
2291 +{
2292 +
2293 + if (argc > 0) {
2294 + pkg_vec_t *available_pkgs = pkg_vec_alloc();
2295 + const char *rel_str = (what_field_type == WHATPROVIDES ? "provides" : "replaces");
2296 + int i;
2297 +
2298 + pkg_info_preinstall_check(conf);
2299 +
2300 + if (conf->query_all)
2301 + pkg_hash_fetch_available(&conf->pkg_hash, available_pkgs);
2302 + else
2303 + pkg_hash_fetch_all_installed(&conf->pkg_hash, available_pkgs);
2304 + for (i = 0; i < argc; i++) {
2305 + const char *target = argv[i];
2306 + int j;
2307 +
2308 + ipkg_message(conf, IPKG_ERROR, "What %s %s\n",
2309 + rel_str, target);
2310 + for (j = 0; j < available_pkgs->len; j++) {
2311 + pkg_t *pkg = available_pkgs->pkgs[j];
2312 + int k;
2313 + int count = (what_field_type == WHATPROVIDES) ? pkg->provides_count : pkg->replaces_count;
2314 + for (k = 0; k < count; k++) {
2315 + abstract_pkg_t *apkg =
2316 + ((what_field_type == WHATPROVIDES)
2317 + ? pkg->provides[k]
2318 + : pkg->replaces[k]);
2319 + if (fnmatch(target, apkg->name, 0) == 0) {
2320 + ipkg_message(conf, IPKG_ERROR, " %s", pkg->name);
2321 + if (strcmp(target, apkg->name) != 0)
2322 + ipkg_message(conf, IPKG_ERROR, "\t%s %s\n", rel_str, apkg->name);
2323 + ipkg_message(conf, IPKG_ERROR, "\n");
2324 + }
2325 + }
2326 + }
2327 + }
2328 + pkg_vec_free(available_pkgs);
2329 + }
2330 + return 0;
2331 +}
2332 +
2333 +static int ipkg_whatprovides_cmd(ipkg_conf_t *conf, int argc, char **argv)
2334 +{
2335 + return ipkg_what_provides_replaces_cmd(conf, WHATPROVIDES, argc, argv);
2336 +}
2337 +
2338 +static int ipkg_whatreplaces_cmd(ipkg_conf_t *conf, int argc, char **argv)
2339 +{
2340 + return ipkg_what_provides_replaces_cmd(conf, WHATREPLACES, argc, argv);
2341 +}
2342 +
2343 +static int ipkg_search_cmd(ipkg_conf_t *conf, int argc, char **argv)
2344 +{
2345 + int i;
2346 +
2347 + pkg_vec_t *installed;
2348 + pkg_t *pkg;
2349 + str_list_t *installed_files;
2350 + str_list_elt_t *iter;
2351 + char *installed_file;
2352 +
2353 + if (argc < 1) {
2354 + return EINVAL;
2355 + }
2356 +
2357 + installed = pkg_vec_alloc();
2358 + pkg_hash_fetch_all_installed(&conf->pkg_hash, installed);
2359 +
2360 + for (i=0; i < installed->len; i++) {
2361 + pkg = installed->pkgs[i];
2362 +
2363 + installed_files = pkg_get_installed_files(pkg);
2364 +
2365 + for (iter = installed_files->head; iter; iter = iter->next) {
2366 + installed_file = iter->data;
2367 + if (fnmatch(argv[0], installed_file, 0)==0) {
2368 +#ifndef IPKG_LIB
2369 + printf("%s: %s\n", pkg->name, installed_file);
2370 +#else
2371 + if (ipkg_cb_list) ipkg_cb_list(pkg->name,
2372 + installed_file,
2373 + pkg_version_str_alloc(pkg),
2374 + pkg->state_status, p_userdata);
2375 +#endif
2376 + }
2377 + }
2378 +
2379 + pkg_free_installed_files(pkg);
2380 + }
2381 +
2382 + /* XXX: CLEANUP: It's not obvious from the name of
2383 + pkg_hash_fetch_all_installed that we need to call
2384 + pkg_vec_free to avoid a memory leak. */
2385 + pkg_vec_free(installed);
2386 +
2387 + return 0;
2388 +}
2389 +
2390 +static int ipkg_compare_versions_cmd(ipkg_conf_t *conf, int argc, char **argv)
2391 +{
2392 + if (argc == 3) {
2393 + /* this is a bit gross */
2394 + struct pkg p1, p2;
2395 + parseVersion(&p1, argv[0]);
2396 + parseVersion(&p2, argv[2]);
2397 + return pkg_version_satisfied(&p1, &p2, argv[1]);
2398 + } else {
2399 + ipkg_message(conf, IPKG_ERROR,
2400 + "ipkg compare_versions <v1> <op> <v2>\n"
2401 + "<op> is one of <= >= << >> =\n");
2402 + return -1;
2403 + }
2404 +}
2405 +
2406 +#ifndef HOST_CPU_STR
2407 +#define HOST_CPU_STR__(X) #X
2408 +#define HOST_CPU_STR_(X) HOST_CPU_STR__(X)
2409 +#define HOST_CPU_STR HOST_CPU_STR_(HOST_CPU_FOO)
2410 +#endif
2411 +
2412 +static int ipkg_print_architecture_cmd(ipkg_conf_t *conf, int argc, char **argv)
2413 +{
2414 + nv_pair_list_elt_t *l;
2415 +
2416 + l = conf->arch_list.head;
2417 + while (l) {
2418 + nv_pair_t *nv = l->data;
2419 + printf("arch %s %s\n", nv->name, nv->value);
2420 + l = l->next;
2421 + }
2422 + return 0;
2423 +}
2424 +
2425 +
2426 Index: busybox-1.8.1/archival/libipkg/ipkg_cmd.h
2427 ===================================================================
2428 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2429 +++ busybox-1.8.1/archival/libipkg/ipkg_cmd.h 2007-11-10 17:40:53.348763971 +0100
2430 @@ -0,0 +1,46 @@
2431 +/* ipkg_cmd.h - the itsy package management system
2432 +
2433 + Carl D. Worth
2434 +
2435 + Copyright (C) 2001 University of Southern California
2436 +
2437 + This program is free software; you can redistribute it and/or
2438 + modify it under the terms of the GNU General Public License as
2439 + published by the Free Software Foundation; either version 2, or (at
2440 + your option) any later version.
2441 +
2442 + This program is distributed in the hope that it will be useful, but
2443 + WITHOUT ANY WARRANTY; without even the implied warranty of
2444 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2445 + General Public License for more details.
2446 +*/
2447 +
2448 +#ifndef IPKG_CMD_H
2449 +#define IPKG_CMD_H
2450 +
2451 +typedef int (*ipkg_cmd_fun_t)(ipkg_conf_t *conf, int argc, const char **argv);
2452 +
2453 +struct ipkg_cmd
2454 +{
2455 + char *name;
2456 + int requires_args;
2457 + ipkg_cmd_fun_t fun;
2458 +};
2459 +typedef struct ipkg_cmd ipkg_cmd_t;
2460 +
2461 +ipkg_cmd_t *ipkg_cmd_find(const char *name);
2462 +#ifdef IPKG_LIB
2463 +int ipkg_cmd_exec(ipkg_cmd_t *cmd, ipkg_conf_t *conf, int argc,
2464 + const char **argv, void *userdata);
2465 +#else
2466 +int ipkg_cmd_exec(ipkg_cmd_t *cmd, ipkg_conf_t *conf, int argc, const char **argv);
2467 +#endif
2468 +int ipkg_multiple_files_scan (ipkg_conf_t *conf, int argc, char *argv[]);
2469 +/* install any packges with state_want == SW_INSTALL */
2470 +int ipkg_install_wanted_packages(ipkg_conf_t *conf);
2471 +/* ensure that all dependences are satisfied */
2472 +int ipkg_configure_packages(ipkg_conf_t *conf, char *pkg_name);
2473 +
2474 +int pkg_mark_provides(pkg_t *pkg);
2475 +
2476 +#endif
2477 Index: busybox-1.8.1/archival/libipkg/ipkg_conf.c
2478 ===================================================================
2479 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
2480 +++ busybox-1.8.1/archival/libipkg/ipkg_conf.c 2007-11-10 17:40:53.348763971 +0100
2481 @@ -0,0 +1,711 @@
2482 +/* ipkg_conf.c - the itsy package management system
2483 +
2484 + Carl D. Worth
2485 +
2486 + Copyright (C) 2001 University of Southern California
2487 +
2488 + This program is free software; you can redistribute it and/or
2489 + modify it under the terms of the GNU General Public License as
2490 + published by the Free Software Foundation; either version 2, or (at
2491 + your option) any later version.
2492 +
2493 + This program is distributed in the hope that it will be useful, but
2494 + WITHOUT ANY WARRANTY; without even the implied warranty of
2495 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2496 + General Public License for more details.
2497 +*/
2498 +
2499 +#include <glob.h>
2500 +
2501 +#include "ipkg.h"
2502 +#include "ipkg_conf.h"
2503 +
2504 +#include "xregex.h"
2505 +#include "sprintf_alloc.h"
2506 +#include "ipkg_conf.h"
2507 +#include "ipkg_message.h"
2508 +#include "file_util.h"
2509 +#include "str_util.h"
2510 +#include "xsystem.h"
2511 +
2512 +
2513 +ipkg_conf_t *global_conf;
2514 +
2515 +static int ipkg_conf_parse_file(ipkg_conf_t *conf, const char *filename,
2516 + pkg_src_list_t *pkg_src_list,
2517 + nv_pair_list_t *tmp_dest_nv_pair_list,
2518 + char **tmp_lists_dir);
2519 +static int ipkg_init_options_array(const ipkg_conf_t *conf, ipkg_option_t **options);
2520 +static int ipkg_conf_set_option(const ipkg_option_t *options,
2521 + const char *name, const char *value);
2522 +static int ipkg_conf_set_default_dest(ipkg_conf_t *conf,
2523 + const char *default_dest_name);
2524 +static int set_and_load_pkg_src_list(ipkg_conf_t *conf,
2525 + pkg_src_list_t *nv_pair_list);
2526 +static int set_and_load_pkg_dest_list(ipkg_conf_t *conf,
2527 + nv_pair_list_t *nv_pair_list, char * lists_dir);
2528 +
2529 +int ipkg_init_options_array(const ipkg_conf_t *conf, ipkg_option_t **options)
2530 +{
2531 + ipkg_option_t tmp[] = {
2532 + { "force_defaults", IPKG_OPT_TYPE_BOOL, &conf->force_defaults },
2533 + { "force_depends", IPKG_OPT_TYPE_BOOL, &conf->force_depends },
2534 + { "force_overwrite", IPKG_OPT_TYPE_BOOL, &conf->force_overwrite },
2535 + { "force_downgrade", IPKG_OPT_TYPE_BOOL, &conf->force_downgrade },
2536 + { "force_reinstall", IPKG_OPT_TYPE_BOOL, &conf->force_reinstall },
2537 + { "force_space", IPKG_OPT_TYPE_BOOL, &conf->force_space },
2538 + { "ftp_proxy", IPKG_OPT_TYPE_STRING, &conf->ftp_proxy },
2539 + { "http_proxy", IPKG_OPT_TYPE_STRING, &conf->http_proxy },
2540 + { "multiple_providers", IPKG_OPT_TYPE_BOOL, &conf->multiple_providers },
2541 + { "no_proxy", IPKG_OPT_TYPE_STRING, &conf->no_proxy },
2542 + { "test", IPKG_OPT_TYPE_INT, &conf->noaction },
2543 + { "noaction", IPKG_OPT_TYPE_INT, &conf->noaction },
2544 + { "nodeps", IPKG_OPT_TYPE_BOOL, &conf->nodeps },
2545 + { "offline_root", IPKG_OPT_TYPE_STRING, &conf->offline_root },
2546 + { "offline_root_post_script_cmd", IPKG_OPT_TYPE_STRING, &conf->offline_root_post_script_cmd },
2547 + { "offline_root_pre_script_cmd", IPKG_OPT_TYPE_STRING, &conf->offline_root_pre_script_cmd },
2548 + { "proxy_passwd", IPKG_OPT_TYPE_STRING, &conf->proxy_passwd },
2549 + { "proxy_user", IPKG_OPT_TYPE_STRING, &conf->proxy_user },
2550 + { "query-all", IPKG_OPT_TYPE_BOOL, &conf->query_all },
2551 + { "verbose-wget", IPKG_OPT_TYPE_BOOL, &conf->verbose_wget },
2552 + { "verbosity", IPKG_OPT_TYPE_BOOL, &conf->verbosity },
2553 + { NULL }
2554 + };
2555 +
2556 + *options = (ipkg_option_t *)malloc(sizeof(tmp));
2557 + if ( options == NULL ){
2558 + fprintf(stderr,"%s: Unable to allocate memory\n",__FUNCTION__);
2559 + return -1;
2560 + }
2561 +
2562 + memcpy(*options, tmp, sizeof(tmp));
2563 + return 0;
2564 +};
2565 +
2566 +static void ipkg_conf_override_string(char **conf_str, char *arg_str)
2567 +{
2568 + if (arg_str) {
2569 + if (*conf_str) {
2570 + free(*conf_str);
2571 + }
2572 + *conf_str = strdup(arg_str);
2573 + }
2574 +}
2575 +
2576 +static void ipkg_conf_free_string(char **conf_str)
2577 +{
2578 + if (*conf_str) {
2579 + free(*conf_str);
2580 + *conf_str = NULL;
2581 + }
2582 +}
2583 +
2584 +int ipkg_conf_init(ipkg_conf_t *conf, const args_t *args)
2585 +{
2586 + int err;
2587 + char *tmp_dir_base;
2588 + nv_pair_list_t tmp_dest_nv_pair_list;
2589 + char * lists_dir =NULL;
2590 + glob_t globbuf;
2591 + char *etc_ipkg_conf_pattern = "/etc/ipkg/*.conf";
2592 + char *pending_dir =NULL;
2593 +
2594 + memset(conf, 0, sizeof(ipkg_conf_t));
2595 +
2596 + pkg_src_list_init(&conf->pkg_src_list);
2597 +
2598 + nv_pair_list_init(&tmp_dest_nv_pair_list);
2599 + pkg_dest_list_init(&conf->pkg_dest_list);
2600 +
2601 + nv_pair_list_init(&conf->arch_list);
2602 +
2603 + conf->restrict_to_default_dest = 0;
2604 + conf->default_dest = NULL;
2605 +
2606 +
2607 + if (args->tmp_dir)
2608 + tmp_dir_base = args->tmp_dir;
2609 + else
2610 + tmp_dir_base = getenv("TMPDIR");
2611 + sprintf_alloc(&conf->tmp_dir, "%s/%s",
2612 + tmp_dir_base ? tmp_dir_base : IPKG_CONF_DEFAULT_TMP_DIR_BASE,
2613 + IPKG_CONF_TMP_DIR_SUFFIX);
2614 + conf->tmp_dir = mkdtemp(conf->tmp_dir);
2615 + if (conf->tmp_dir == NULL) {
2616 + fprintf(stderr, "%s: Failed to create temporary directory `%s': %s\n",
2617 + __FUNCTION__, conf->tmp_dir, strerror(errno));
2618 + return errno;
2619 + }
2620 +
2621 + conf->force_depends = 0;
2622 + conf->force_defaults = 0;
2623 + conf->force_overwrite = 0;
2624 + conf->force_downgrade = 0;
2625 + conf->force_reinstall = 0;
2626 + conf->force_space = 0;
2627 + conf->force_removal_of_essential_packages = 0;
2628 + conf->force_removal_of_dependent_packages = 0;
2629 + conf->nodeps = 0;
2630 + conf->verbose_wget = 0;
2631 + conf->offline_root = NULL;
2632 + conf->offline_root_pre_script_cmd = NULL;
2633 + conf->offline_root_post_script_cmd = NULL;
2634 + conf->multiple_providers = 0;
2635 + conf->verbosity = 1;
2636 + conf->noaction = 0;
2637 +
2638 + conf->http_proxy = NULL;
2639 + conf->ftp_proxy = NULL;
2640 + conf->no_proxy = NULL;
2641 + conf->proxy_user = NULL;
2642 + conf->proxy_passwd = NULL;
2643 +
2644 + pkg_hash_init("pkg-hash", &conf->pkg_hash, IPKG_CONF_DEFAULT_HASH_LEN);
2645 + hash_table_init("file-hash", &conf->file_hash, IPKG_CONF_DEFAULT_HASH_LEN);
2646 + hash_table_init("obs-file-hash", &conf->obs_file_hash, IPKG_CONF_DEFAULT_HASH_LEN);
2647 + lists_dir=(char *)malloc(1);
2648 + lists_dir[0]='\0';
2649 + if (args->conf_file) {
2650 + struct stat stat_buf;
2651 + err = stat(args->conf_file, &stat_buf);
2652 + if (err == 0)
2653 + if (ipkg_conf_parse_file(conf, args->conf_file,
2654 + &conf->pkg_src_list, &tmp_dest_nv_pair_list,&lists_dir)<0) {
2655 + /* Memory leakage from ipkg_conf_parse-file */
2656 + return -1;
2657 + }
2658 +
2659 + }
2660 +
2661 + /* if (!lists_dir ){*/
2662 + if (strlen(lists_dir)<=1 ){
2663 + lists_dir = realloc(lists_dir,strlen(IPKG_CONF_LISTS_DIR)+2);
2664 + sprintf (lists_dir,"%s",IPKG_CONF_LISTS_DIR);
2665 + }
2666 +
2667 + if (args->offline_root) {
2668 + char *tmp = malloc(strlen(lists_dir) + strlen(args->offline_root) + 1);
2669 + sprintf_alloc(&tmp, "%s/%s",args->offline_root,lists_dir);
2670 + free(lists_dir);
2671 + lists_dir = tmp;
2672 + }
2673 +
2674 + pending_dir = malloc(strlen(lists_dir)+strlen("/pending")+5);
2675 + snprintf(pending_dir,strlen(lists_dir)+strlen("/pending") ,"%s%s",lists_dir,"/pending");
2676 +
2677 + conf->lists_dir = strdup(lists_dir);
2678 + conf->pending_dir = strdup(pending_dir);
2679 +
2680 + if (args->offline_root)
2681 + sprintf_alloc(&etc_ipkg_conf_pattern, "%s/etc/ipkg/*.conf", args->offline_root);
2682 + memset(&globbuf, 0, sizeof(globbuf));
2683 + err = glob(etc_ipkg_conf_pattern, 0, NULL, &globbuf);
2684 + if (!err) {
2685 + int i;
2686 + for (i = 0; i < globbuf.gl_pathc; i++) {
2687 + if (globbuf.gl_pathv[i])
2688 + if ( ipkg_conf_parse_file(conf, globbuf.gl_pathv[i],
2689 + &conf->pkg_src_list, &tmp_dest_nv_pair_list,&lists_dir)<0) {
2690 + /* Memory leakage from ipkg_conf_parse-file */
2691 + return -1;
2692 + }
2693 + }
2694 + }
2695 + globfree(&globbuf);
2696 +
2697 + /* if no architectures were defined, then default all, noarch, and host architecture */
2698 + if (nv_pair_list_empty(&conf->arch_list)) {
2699 + nv_pair_list_append(&conf->arch_list, "all", "1");
2700 + nv_pair_list_append(&conf->arch_list, "noarch", "1");
2701 + nv_pair_list_append(&conf->arch_list, HOST_CPU_STR, "10");
2702 + }
2703 +
2704 + /* Even if there is no conf file, we'll need at least one dest. */
2705 + if (tmp_dest_nv_pair_list.head == NULL) {
2706 + nv_pair_list_append(&tmp_dest_nv_pair_list,
2707 + IPKG_CONF_DEFAULT_DEST_NAME,
2708 + IPKG_CONF_DEFAULT_DEST_ROOT_DIR);
2709 + }
2710 +
2711 + /* After parsing the file, set options from command-line, (so that
2712 + command-line arguments take precedence) */
2713 + /* XXX: CLEANUP: The interaction between args.c and ipkg_conf.c
2714 + really needs to be cleaned up. There is so much duplication
2715 + right now it is ridiculous. Maybe ipkg_conf_t should just save
2716 + a pointer to args_t (which could then not be freed), rather
2717 + than duplicating every field here? */
2718 + if (args->force_depends) {
2719 + conf->force_depends = 1;
2720 + }
2721 + if (args->force_defaults) {
2722 + conf->force_defaults = 1;
2723 + }
2724 + if (args->force_overwrite) {
2725 + conf->force_overwrite = 1;
2726 + }
2727 + if (args->force_downgrade) {
2728 + conf->force_downgrade = 1;
2729 + }
2730 + if (args->force_reinstall) {
2731 + conf->force_reinstall = 1;
2732 + }
2733 + if (args->force_removal_of_dependent_packages) {
2734 + conf->force_removal_of_dependent_packages = 1;
2735 + }
2736 + if (args->force_removal_of_essential_packages) {
2737 + conf->force_removal_of_essential_packages = 1;
2738 + }
2739 + if (args->nodeps) {
2740 + conf->nodeps = 1;
2741 + }
2742 + if (args->noaction) {
2743 + conf->noaction = 1;
2744 + }
2745 + if (args->query_all) {
2746 + conf->query_all = 1;
2747 + }
2748 + if (args->verbose_wget) {
2749 + conf->verbose_wget = 1;
2750 + }
2751 + if (args->multiple_providers) {
2752 + conf->multiple_providers = 1;
2753 + }
2754 + if (args->verbosity != conf->verbosity) {
2755 + conf->verbosity = args->verbosity;
2756 + }
2757 +
2758 + ipkg_conf_override_string(&conf->offline_root,
2759 + args->offline_root);
2760 + ipkg_conf_override_string(&conf->offline_root_pre_script_cmd,
2761 + args->offline_root_pre_script_cmd);
2762 + ipkg_conf_override_string(&conf->offline_root_post_script_cmd,
2763 + args->offline_root_post_script_cmd);
2764 +
2765 +/* Pigi: added a flag to disable the checking of structures if the command does not need to
2766 + read anything from there.
2767 +*/
2768 + if ( !(args->nocheckfordirorfile)){
2769 + /* need to run load the source list before dest list -Jamey */
2770 + if ( !(args->noreadfeedsfile))
2771 + set_and_load_pkg_src_list(conf, &conf->pkg_src_list);
2772 +
2773 + /* Now that we have resolved conf->offline_root, we can commit to
2774 + the directory names for the dests and load in all the package
2775 + lists. */
2776 + set_and_load_pkg_dest_list(conf, &tmp_dest_nv_pair_list,lists_dir);
2777 +
2778 + if (args->dest) {
2779 + err = ipkg_conf_set_default_dest(conf, args->dest);
2780 + if (err) {
2781 + return err;
2782 + }
2783 + }
2784 + }
2785 + nv_pair_list_deinit(&tmp_dest_nv_pair_list);
2786 + free(lists_dir);
2787 + free(pending_dir);
2788 +
2789 + return 0;
2790 +}
2791 +
2792 +void ipkg_conf_deinit(ipkg_conf_t *conf)
2793 +{
2794 +#ifdef IPKG_DEBUG_NO_TMP_CLEANUP
2795 +#error
2796 + fprintf(stderr, "%s: Not cleaning up %s since ipkg compiled "
2797 + "with IPKG_DEBUG_NO_TMP_CLEANUP\n",
2798 + __FUNCTION__, conf->tmp_dir);
2799 +#else
2800 + int err;
2801 +
2802 + err = rmdir(conf->tmp_dir);
2803 + if (err) {
2804 + if (errno == ENOTEMPTY) {
2805 + char *cmd;
2806 + sprintf_alloc(&cmd, "rm -fr %s\n", conf->tmp_dir);
2807 + err = xsystem(cmd);
2808 + free(cmd);
2809 + }
2810 + if (err)
2811 + fprintf(stderr, "WARNING: Unable to remove temporary directory: %s: %s\n", conf->tmp_dir, strerror(errno));
2812 + }
2813 +#endif /* IPKG_DEBUG_NO_TMP_CLEANUP */
2814 +
2815 + free(conf->tmp_dir); /*XXX*/
2816 +
2817 + pkg_src_list_deinit(&conf->pkg_src_list);
2818 + pkg_dest_list_deinit(&conf->pkg_dest_list);
2819 + nv_pair_list_deinit(&conf->arch_list);
2820 + if (&conf->pkg_hash)
2821 + pkg_hash_deinit(&conf->pkg_hash);
2822 + if (&conf->file_hash)
2823 + hash_table_deinit(&conf->file_hash);
2824 + if (&conf->obs_file_hash)
2825 + hash_table_deinit(&conf->obs_file_hash);
2826 +
2827 + ipkg_conf_free_string(&conf->offline_root);
2828 + ipkg_conf_free_string(&conf->offline_root_pre_script_cmd);
2829 + ipkg_conf_free_string(&conf->offline_root_post_script_cmd);
2830 +
2831 + if (conf->verbosity > 1) {
2832 + int i;
2833 + hash_table_t *hashes[] = {
2834 + &conf->pkg_hash,
2835 + &conf->file_hash,
2836 + &conf->obs_file_hash };
2837 + for (i = 0; i < 3; i++) {
2838 + hash_table_t *hash = hashes[i];
2839 + int c = 0;
2840 + int n_conflicts = 0;
2841 + int j;
2842 + for (j = 0; j < hash->n_entries; j++) {
2843 + int len = 0;
2844 + hash_entry_t *e = &hash->entries[j];
2845 + if (e->next)
2846 + n_conflicts++;
2847 + while (e && e->key) {
2848 + len++;
2849 + e = e->next;
2850 + }
2851 + if (len > c)
2852 + c = len;
2853 + }
2854 + ipkg_message(conf, IPKG_DEBUG, "hash_table[%s] n_buckets=%d n_elements=%d max_conflicts=%d n_conflicts=%d\n",
2855 + hash->name, hash->n_entries, hash->n_elements, c, n_conflicts);
2856 + hash_table_deinit(hash);
2857 + }
2858 + }
2859 +}
2860 +
2861 +static int ipkg_conf_set_default_dest(ipkg_conf_t *conf,
2862 + const char *default_dest_name)
2863 +{
2864 + pkg_dest_list_elt_t *iter;
2865 + pkg_dest_t *dest;
2866 +
2867 + for (iter = conf->pkg_dest_list.head; iter; iter = iter->next) {
2868 + dest = iter->data;
2869 + if (strcmp(dest->name, default_dest_name) == 0) {
2870 + conf->default_dest = dest;
2871 + conf->restrict_to_default_dest = 1;
2872 + return 0;
2873 + }
2874 + }
2875 +
2876 + fprintf(stderr, "ERROR: Unknown dest name: `%s'\n", default_dest_name);
2877 +
2878 + return 1;
2879 +}
2880 +
2881 +static int set_and_load_pkg_src_list(ipkg_conf_t *conf, pkg_src_list_t *pkg_src_list)
2882 +{
2883 + pkg_src_list_elt_t *iter;
2884 + pkg_src_t *src;
2885 + char *list_file;
2886 +
2887 + for (iter = pkg_src_list->head; iter; iter = iter->next) {
2888 + src = iter->data;
2889 + if (src == NULL) {
2890 + continue;
2891 + }
2892 +
2893 + sprintf_alloc(&list_file, "%s/%s",
2894 + conf->restrict_to_default_dest ? conf->default_dest->lists_dir : conf->lists_dir,
2895 + src->name);
2896 +
2897 + if (file_exists(list_file)) {
2898 + pkg_hash_add_from_file(conf, list_file, src, NULL, 0);
2899 + }
2900 + free(list_file);
2901 + }
2902 +
2903 + return 0;
2904 +}
2905 +
2906 +static int set_and_load_pkg_dest_list(ipkg_conf_t *conf, nv_pair_list_t *nv_pair_list, char *lists_dir )
2907 +{
2908 + nv_pair_list_elt_t *iter;
2909 + nv_pair_t *nv_pair;
2910 + pkg_dest_t *dest;
2911 + char *root_dir;
2912 +
2913 + for (iter = nv_pair_list->head; iter; iter = iter->next) {
2914 + nv_pair = iter->data;
2915 +
2916 + if (conf->offline_root) {
2917 + sprintf_alloc(&root_dir, "%s%s", conf->offline_root, nv_pair->value);
2918 + } else {
2919 + root_dir = strdup(nv_pair->value);
2920 + }
2921 + dest = pkg_dest_list_append(&conf->pkg_dest_list, nv_pair->name, root_dir, lists_dir);
2922 + free(root_dir);
2923 + if (dest == NULL) {
2924 + continue;
2925 + }
2926 + if (conf->default_dest == NULL) {
2927 + conf->default_dest = dest;
2928 + }
2929 + if (file_exists(dest->status_file_name)) {
2930 + pkg_hash_add_from_file(conf, dest->status_file_name,
2931 + NULL, dest, 1);
2932 + }
2933 + }
2934 +
2935 + return 0;
2936 +}
2937 +
2938 +static int ipkg_conf_parse_file(ipkg_conf_t *conf, const char *filename,
2939 + pkg_src_list_t *pkg_src_list,
2940 + nv_pair_list_t *tmp_dest_nv_pair_list,
2941 + char **lists_dir)
2942 +{
2943 + ipkg_option_t * options;
2944 + FILE *file = fopen(filename, "r");
2945 + regex_t valid_line_re, comment_re;
2946 +#define regmatch_size 12
2947 + regmatch_t regmatch[regmatch_size];
2948 +
2949 + if (ipkg_init_options_array(conf, &options)<0)
2950 + return ENOMEM;
2951 +
2952 + if (file == NULL) {
2953 + fprintf(stderr, "%s: failed to open %s: %s\n",
2954 + __FUNCTION__, filename, strerror(errno));
2955 + free(options);
2956 + return errno;
2957 + }
2958 + ipkg_message(conf, IPKG_NOTICE, "loading conf file %s\n", filename);
2959 +
2960 + xregcomp(&comment_re,
2961 + "^[[:space:]]*(#.*|[[:space:]]*)$",
2962 + REG_EXTENDED);
2963 + xregcomp(&valid_line_re, "^[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))[[:space:]]*(\"([^\"]*)\"|([^[:space:]]*))([[:space:]]+([^[:space:]]+))?[[:space:]]*$", REG_EXTENDED);
2964 +
2965 + while(1) {
2966 + int line_num = 0;
2967 + char *line;
2968 + char *type, *name, *value, *extra;
2969 +
2970 + line = file_read_line_alloc(file);
2971 + line_num++;
2972 + if (line == NULL) {
2973 + break;
2974 + }
2975 +
2976 + str_chomp(line);
2977 +
2978 + if (regexec(&comment_re, line, 0, 0, 0) == 0) {
2979 + goto NEXT_LINE;
2980 + }
2981 +
2982 + if (regexec(&valid_line_re, line, regmatch_size, regmatch, 0) == REG_NOMATCH) {
2983 + str_chomp(line);
2984 + fprintf(stderr, "%s:%d: Ignoring invalid line: `%s'\n",
2985 + filename, line_num, line);
2986 + goto NEXT_LINE;
2987 + }
2988 +
2989 + /* This has to be so ugly to deal with optional quotation marks */
2990 + if (regmatch[2].rm_so > 0) {
2991 + type = strndup(line + regmatch[2].rm_so,
2992 + regmatch[2].rm_eo - regmatch[2].rm_so);
2993 + } else {
2994 + type = strndup(line + regmatch[3].rm_so,
2995 + regmatch[3].rm_eo - regmatch[3].rm_so);
2996 + }
2997 + if (regmatch[5].rm_so > 0) {
2998 + name = strndup(line + regmatch[5].rm_so,
2999 + regmatch[5].rm_eo - regmatch[5].rm_so);
3000 + } else {
3001 + name = strndup(line + regmatch[6].rm_so,
3002 + regmatch[6].rm_eo - regmatch[6].rm_so);
3003 + }
3004 + if (regmatch[8].rm_so > 0) {
3005 + value = strndup(line + regmatch[8].rm_so,
3006 + regmatch[8].rm_eo - regmatch[8].rm_so);
3007 + } else {
3008 + value = strndup(line + regmatch[9].rm_so,
3009 + regmatch[9].rm_eo - regmatch[9].rm_so);
3010 + }
3011 + extra = NULL;
3012 + if (regmatch[11].rm_so > 0) {
3013 + extra = strndup (line + regmatch[11].rm_so,
3014 + regmatch[11].rm_eo - regmatch[11].rm_so);
3015 + }
3016 +
3017 + /* We use the tmp_dest_nv_pair_list below instead of
3018 + conf->pkg_dest_list because we might encounter an
3019 + offline_root option later and that would invalidate the
3020 + directories we would have computed in
3021 + pkg_dest_list_init. (We do a similar thing with
3022 + tmp_src_nv_pair_list for sake of symmetry.) */
3023 + if (strcmp(type, "option") == 0) {
3024 + ipkg_conf_set_option(options, name, value);
3025 + } else if (strcmp(type, "src") == 0) {
3026 + if (!nv_pair_list_find((nv_pair_list_t *)pkg_src_list, name)) {
3027 + pkg_src_list_append (pkg_src_list, name, value, extra, 0);
3028 + } else {
3029 + ipkg_message(conf, IPKG_ERROR, "ERROR: duplicate src declaration. Skipping:\n\t src %s %s\n",
3030 + name, value);
3031 + }
3032 + } else if (strcmp(type, "src/gz") == 0) {
3033 + if (!nv_pair_list_find((nv_pair_list_t *)pkg_src_list, name)) {
3034 + pkg_src_list_append (pkg_src_list, name, value, extra, 1);
3035 + } else {
3036 + ipkg_message(conf, IPKG_ERROR, "ERROR: duplicate src declaration. Skipping:\n\t src %s %s\n",
3037 + name, value);
3038 + }
3039 + } else if (strcmp(type, "dest") == 0) {
3040 + nv_pair_list_append(tmp_dest_nv_pair_list, name, value);
3041 + } else if (strcmp(type, "lists_dir") == 0) {
3042 + *lists_dir = realloc(*lists_dir,strlen(value)+1);
3043 + if (*lists_dir == NULL) {
3044 + ipkg_message(conf, IPKG_ERROR, "ERROR: Not enough memory\n");
3045 + free(options);
3046 + return EINVAL;
3047 + }
3048 + sprintf (*lists_dir,"%s",value);
3049 + } else if (strcmp(type, "arch") == 0) {
3050 + ipkg_message(conf, IPKG_INFO, "supported arch %s priority (%s)\n", name, value);
3051 + if (!value) {
3052 + ipkg_message(conf, IPKG_NOTICE, "defaulting architecture %s priority to 10\n", name);
3053 + value = strdup("10");
3054 + }
3055 + nv_pair_list_append(&conf->arch_list, strdup(name), strdup(value));
3056 + } else {
3057 + fprintf(stderr, "WARNING: Ignoring unknown configuration "
3058 + "parameter: %s %s %s\n", type, name, value);
3059 + free(options);
3060 + return EINVAL;
3061 + }
3062 +
3063 + free(type);
3064 + free(name);
3065 + free(value);
3066 + if (extra)
3067 + free (extra);
3068 +
3069 + NEXT_LINE:
3070 + free(line);
3071 + }
3072 +
3073 + free(options);
3074 + regfree(&comment_re);
3075 + regfree(&valid_line_re);
3076 + fclose(file);
3077 +
3078 + return 0;
3079 +}
3080 +
3081 +static int ipkg_conf_set_option(const ipkg_option_t *options,
3082 + const char *name, const char *value)
3083 +{
3084 + int i = 0;
3085 + while (options[i].name) {
3086 + if (strcmp(options[i].name, name) == 0) {
3087 + switch (options[i].type) {
3088 + case IPKG_OPT_TYPE_BOOL:
3089 + *((int *)options[i].value) = 1;
3090 + return 0;
3091 + case IPKG_OPT_TYPE_INT:
3092 + if (value) {
3093 + *((int *)options[i].value) = atoi(value);
3094 + return 0;
3095 + } else {
3096 + printf("%s: Option %s need an argument\n",
3097 + __FUNCTION__, name);
3098 + return EINVAL;
3099 + }
3100 + case IPKG_OPT_TYPE_STRING:
3101 + if (value) {
3102 + *((char **)options[i].value) = strdup(value);
3103 + return 0;
3104 + } else {
3105 + printf("%s: Option %s need an argument\n",
3106 + __FUNCTION__, name);
3107 + return EINVAL;
3108 + }
3109 + }
3110 + }
3111 + i++;
3112 + }
3113 +
3114 + fprintf(stderr, "%s: Unrecognized option: %s=%s\n",
3115 + __FUNCTION__, name, value);
3116 + return EINVAL;
3117 +}
3118 +
3119 +int ipkg_conf_write_status_files(ipkg_conf_t *conf)
3120 +{
3121 + pkg_dest_list_elt_t *iter;
3122 + pkg_dest_t *dest;
3123 + pkg_vec_t *all;
3124 + pkg_t *pkg;
3125 + register int i;
3126 + int err;
3127 +
3128 + if (conf->noaction)
3129 + return 0;
3130 + for (iter = conf->pkg_dest_list.head; iter; iter = iter->next) {
3131 + dest = iter->data;
3132 + dest->status_file = fopen(dest->status_file_tmp_name, "w");
3133 + if (dest->status_file == NULL) {
3134 + fprintf(stderr, "%s: Can't open status file: %s for writing: %s\n",
3135 + __FUNCTION__, dest->status_file_name, strerror(errno));
3136 + }
3137 + }
3138 +
3139 + all = pkg_vec_alloc();
3140 + pkg_hash_fetch_available(&conf->pkg_hash, all);
3141 +
3142 + for(i = 0; i < all->len; i++) {
3143 + pkg = all->pkgs[i];
3144 + /* We don't need most uninstalled packages in the status file */
3145 + if (pkg->state_status == SS_NOT_INSTALLED
3146 + && (pkg->state_want == SW_UNKNOWN
3147 + || pkg->state_want == SW_DEINSTALL
3148 + || pkg->state_want == SW_PURGE)) {
3149 + continue;
3150 + }
3151 + if (!pkg) {
3152 + fprintf(stderr, "Null package\n");
3153 + }
3154 + if (pkg->dest == NULL) {
3155 + fprintf(stderr, "%s: ERROR: Can't write status for "
3156 + "package %s since it has a NULL dest\n",
3157 + __FUNCTION__, pkg->name);
3158 + continue;
3159 + }
3160 + if (pkg->dest->status_file) {
3161 + pkg_print_status(pkg, pkg->dest->status_file);
3162 + }
3163 + }
3164 +
3165 + pkg_vec_free(all);
3166 +
3167 + for (iter = conf->pkg_dest_list.head; iter; iter = iter->next) {
3168 + dest = iter->data;
3169 + if (dest->status_file) {
3170 + err = ferror(dest->status_file);
3171 + fclose(dest->status_file);
3172 + dest->status_file = NULL;
3173 + if (!err) {
3174 + file_move(dest->status_file_tmp_name, dest->status_file_name);
3175 + } else {
3176 + fprintf(stderr, "%s: ERROR: An error has occurred writing %s, "
3177 + "retaining old %s\n", __FUNCTION__,
3178 + dest->status_file_tmp_name, dest->status_file_name);
3179 + }
3180 + }
3181 + }
3182 +
3183 + return 0;
3184 +}
3185 +
3186 +
3187 +char *root_filename_alloc(ipkg_conf_t *conf, char *filename)
3188 +{
3189 + char *root_filename;
3190 + sprintf_alloc(&root_filename, "%s%s", (conf->offline_root ? conf->offline_root : ""), filename);
3191 + return root_filename;
3192 +}
3193 Index: busybox-1.8.1/archival/libipkg/ipkg_conf.h
3194 ===================================================================
3195 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3196 +++ busybox-1.8.1/archival/libipkg/ipkg_conf.h 2007-11-10 17:40:53.348763971 +0100
3197 @@ -0,0 +1,107 @@
3198 +/* ipkg_conf.h - the itsy package management system
3199 +
3200 + Carl D. Worth
3201 +
3202 + Copyright (C) 2001 University of Southern California
3203 +
3204 + This program is free software; you can redistribute it and/or
3205 + modify it under the terms of the GNU General Public License as
3206 + published by the Free Software Foundation; either version 2, or (at
3207 + your option) any later version.
3208 +
3209 + This program is distributed in the hope that it will be useful, but
3210 + WITHOUT ANY WARRANTY; without even the implied warranty of
3211 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3212 + General Public License for more details.
3213 +*/
3214 +
3215 +#ifndef IPKG_CONF_H
3216 +#define IPKG_CONF_H
3217 +
3218 +typedef struct ipkg_conf ipkg_conf_t;
3219 +
3220 +#include "hash_table.h"
3221 +#include "ipkg.h"
3222 +#include "args.h"
3223 +#include "pkg.h"
3224 +#include "pkg_hash.h"
3225 +#include "pkg_src_list.h"
3226 +#include "pkg_dest_list.h"
3227 +#include "nv_pair_list.h"
3228 +
3229 +#define IPKG_CONF_DEFAULT_TMP_DIR_BASE "/tmp"
3230 +#define IPKG_CONF_TMP_DIR_SUFFIX "ipkg-XXXXXX"
3231 +#define IPKG_CONF_LISTS_DIR IPKG_STATE_DIR_PREFIX "/lists"
3232 +#define IPKG_CONF_PENDING_DIR IPKG_STATE_DIR_PREFIX "/pending"
3233 +
3234 +/* In case the config file defines no dest */
3235 +#define IPKG_CONF_DEFAULT_DEST_NAME "root"
3236 +#define IPKG_CONF_DEFAULT_DEST_ROOT_DIR "/"
3237 +
3238 +#define IPKG_CONF_DEFAULT_HASH_LEN 1024
3239 +
3240 +struct ipkg_conf
3241 +{
3242 + pkg_src_list_t pkg_src_list;
3243 + pkg_dest_list_t pkg_dest_list;
3244 + nv_pair_list_t arch_list;
3245 +
3246 + int restrict_to_default_dest;
3247 + pkg_dest_t *default_dest;
3248 +
3249 + char *tmp_dir;
3250 + const char *lists_dir;
3251 + const char *pending_dir;
3252 +
3253 + /* options */
3254 + int force_depends;
3255 + int force_defaults;
3256 + int force_overwrite;
3257 + int force_downgrade;
3258 + int force_reinstall;
3259 + int force_space;
3260 + int force_removal_of_dependent_packages;
3261 + int force_removal_of_essential_packages;
3262 + int nodeps; /* do not follow dependences */
3263 + int verbose_wget;
3264 + int multiple_providers;
3265 + char *offline_root;
3266 + char *offline_root_pre_script_cmd;
3267 + char *offline_root_post_script_cmd;
3268 + int query_all;
3269 + int verbosity;
3270 + int noaction;
3271 +
3272 + /* proxy options */
3273 + char *http_proxy;
3274 + char *ftp_proxy;
3275 + char *no_proxy;
3276 + char *proxy_user;
3277 + char *proxy_passwd;
3278 +
3279 + hash_table_t pkg_hash;
3280 + hash_table_t file_hash;
3281 + hash_table_t obs_file_hash;
3282 +};
3283 +
3284 +enum ipkg_option_type {
3285 + IPKG_OPT_TYPE_BOOL,
3286 + IPKG_OPT_TYPE_INT,
3287 + IPKG_OPT_TYPE_STRING
3288 +};
3289 +typedef enum ipkg_option_type ipkg_option_type_t;
3290 +
3291 +typedef struct ipkg_option ipkg_option_t;
3292 +struct ipkg_option {
3293 + const char *name;
3294 + const ipkg_option_type_t type;
3295 + const void *value;
3296 +};
3297 +
3298 +int ipkg_conf_init(ipkg_conf_t *conf, const args_t *args);
3299 +void ipkg_conf_deinit(ipkg_conf_t *conf);
3300 +
3301 +int ipkg_conf_write_status_files(ipkg_conf_t *conf);
3302 +char *root_filename_alloc(ipkg_conf_t *conf, char *filename);
3303 +
3304 +#endif
3305 Index: busybox-1.8.1/archival/libipkg/ipkg_configure.c
3306 ===================================================================
3307 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3308 +++ busybox-1.8.1/archival/libipkg/ipkg_configure.c 2007-11-10 17:40:53.348763971 +0100
3309 @@ -0,0 +1,40 @@
3310 +/* ipkg_configure.c - the itsy package management system
3311 +
3312 + Carl D. Worth
3313 +
3314 + Copyright (C) 2001 University of Southern California
3315 +
3316 + This program is free software; you can redistribute it and/or
3317 + modify it under the terms of the GNU General Public License as
3318 + published by the Free Software Foundation; either version 2, or (at
3319 + your option) any later version.
3320 +
3321 + This program is distributed in the hope that it will be useful, but
3322 + WITHOUT ANY WARRANTY; without even the implied warranty of
3323 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3324 + General Public License for more details.
3325 +*/
3326 +
3327 +#include "ipkg.h"
3328 +
3329 +#include "ipkg_configure.h"
3330 +
3331 +int ipkg_configure(ipkg_conf_t *conf, pkg_t *pkg)
3332 +{
3333 + int err;
3334 +
3335 + /* DPKG_INCOMPATIBILITY:
3336 + dpkg actually does some conffile handling here, rather than at the
3337 + end of ipkg_install(). Do we care? */
3338 + /* DPKG_INCOMPATIBILITY:
3339 + dpkg actually includes a version number to this script call */
3340 + err = pkg_run_script(conf, pkg, "postinst", "configure");
3341 + if (err) {
3342 + printf("ERROR: %s.postinst returned %d\n", pkg->name, err);
3343 + return err;
3344 + }
3345 +
3346 + ipkg_state_changed++;
3347 + return 0;
3348 +}
3349 +
3350 Index: busybox-1.8.1/archival/libipkg/ipkg_configure.h
3351 ===================================================================
3352 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3353 +++ busybox-1.8.1/archival/libipkg/ipkg_configure.h 2007-11-10 17:40:53.348763971 +0100
3354 @@ -0,0 +1,25 @@
3355 +/* ipkg_configure.h - the itsy package management system
3356 +
3357 + Carl D. Worth
3358 +
3359 + Copyright (C) 2001 University of Southern California
3360 +
3361 + This program is free software; you can redistribute it and/or
3362 + modify it under the terms of the GNU General Public License as
3363 + published by the Free Software Foundation; either version 2, or (at
3364 + your option) any later version.
3365 +
3366 + This program is distributed in the hope that it will be useful, but
3367 + WITHOUT ANY WARRANTY; without even the implied warranty of
3368 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3369 + General Public License for more details.
3370 +*/
3371 +
3372 +#ifndef IPKG_CONFIGURE_H
3373 +#define IPKG_CONFIGURE_H
3374 +
3375 +#include "ipkg_conf.h"
3376 +
3377 +int ipkg_configure(ipkg_conf_t *ipkg_conf, pkg_t *pkg);
3378 +
3379 +#endif
3380 Index: busybox-1.8.1/archival/libipkg/ipkg_download.c
3381 ===================================================================
3382 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3383 +++ busybox-1.8.1/archival/libipkg/ipkg_download.c 2007-11-10 17:40:53.352764197 +0100
3384 @@ -0,0 +1,195 @@
3385 +/* ipkg_download.c - 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 +#include "ipkg.h"
3403 +#include "ipkg_download.h"
3404 +#include "ipkg_message.h"
3405 +
3406 +#include "sprintf_alloc.h"
3407 +#include "xsystem.h"
3408 +#include "file_util.h"
3409 +#include "str_util.h"
3410 +
3411 +int ipkg_download(ipkg_conf_t *conf, const char *src, const char *dest_file_name)
3412 +{
3413 + int err = 0;
3414 +
3415 + char *src_basec = strdup(src);
3416 + char *src_base = basename(src_basec);
3417 + char *tmp_file_location;
3418 + char *cmd;
3419 +
3420 + ipkg_message(conf,IPKG_NOTICE,"Downloading %s\n", src);
3421 +
3422 + fflush(stdout);
3423 +
3424 + if (str_starts_with(src, "file:")) {
3425 + int ret;
3426 + const char *file_src = src + 5;
3427 + ipkg_message(conf,IPKG_INFO,"Copying %s to %s...", file_src, dest_file_name);
3428 + ret = file_copy(src + 5, dest_file_name);
3429 + ipkg_message(conf,IPKG_INFO,"Done.\n");
3430 + return ret;
3431 + }
3432 +
3433 + sprintf_alloc(&tmp_file_location, "%s/%s", conf->tmp_dir, src_base);
3434 + err = unlink(tmp_file_location);
3435 + if (err && errno != ENOENT) {
3436 + ipkg_message(conf,IPKG_ERROR, "%s: ERROR: failed to unlink %s: %s\n",
3437 + __FUNCTION__, tmp_file_location, strerror(errno));
3438 + free(tmp_file_location);
3439 + return errno;
3440 + }
3441 +
3442 + if (conf->http_proxy) {
3443 + ipkg_message(conf,IPKG_DEBUG,"Setting environment variable: http_proxy = %s\n", conf->http_proxy);
3444 + setenv("http_proxy", conf->http_proxy, 1);
3445 + }
3446 + if (conf->ftp_proxy) {
3447 + ipkg_message(conf,IPKG_DEBUG,"Setting environment variable: ftp_proxy = %s\n", conf->ftp_proxy);
3448 + setenv("ftp_proxy", conf->ftp_proxy, 1);
3449 + }
3450 + if (conf->no_proxy) {
3451 + ipkg_message(conf,IPKG_DEBUG,"Setting environment variable: no_proxy = %s\n", conf->no_proxy);
3452 + setenv("no_proxy", conf->no_proxy, 1);
3453 + }
3454 +
3455 + /* XXX: BUG rewrite to use execvp or else busybox's internal wget -Jamey 7/23/2002 */
3456 + sprintf_alloc(&cmd, "wget --passive-ftp %s %s%s %s%s %s -P %s %s",
3457 + (conf->http_proxy || conf->ftp_proxy) ? "--proxy=on" : "",
3458 + conf->proxy_user ? "--proxy-user=" : "",
3459 + conf->proxy_user ? conf->proxy_user : "",
3460 + conf->proxy_passwd ? "--proxy-passwd=" : "",
3461 + conf->proxy_passwd ? conf->proxy_passwd : "",
3462 + conf->verbose_wget ? "" : "-q",
3463 + conf->tmp_dir,
3464 + src);
3465 + err = xsystem(cmd);
3466 + if (err) {
3467 + if (err != -1) {
3468 + ipkg_message(conf,IPKG_ERROR, "%s: ERROR: Command failed with return value %d: `%s'\n",
3469 + __FUNCTION__, err, cmd);
3470 + }
3471 + unlink(tmp_file_location);
3472 + free(tmp_file_location);
3473 + free(src_basec);
3474 + free(cmd);
3475 + return EINVAL;
3476 + }
3477 + free(cmd);
3478 +
3479 + err = file_move(tmp_file_location, dest_file_name);
3480 +
3481 + free(tmp_file_location);
3482 + free(src_basec);
3483 +
3484 + if (err) {
3485 + return err;
3486 + }
3487 +
3488 + return 0;
3489 +}
3490 +
3491 +int ipkg_download_pkg(ipkg_conf_t *conf, pkg_t *pkg, const char *dir)
3492 +{
3493 + int err;
3494 + char *url;
3495 +
3496 + if (pkg->src == NULL) {
3497 + ipkg_message(conf,IPKG_ERROR, "ERROR: Package %s (parent %s) is not available from any configured src.\n",
3498 + pkg->name, pkg->parent->name);
3499 + return -1;
3500 + }
3501 +
3502 + sprintf_alloc(&url, "%s/%s", pkg->src->value, pkg->filename);
3503 +
3504 + /* XXX: BUG: The pkg->filename might be something like
3505 + "../../foo.ipk". While this is correct, and exactly what we
3506 + want to use to construct url above, here we actually need to
3507 + use just the filename part, without any directory. */
3508 + sprintf_alloc(&pkg->local_filename, "%s/%s", dir, pkg->filename);
3509 +
3510 + err = ipkg_download(conf, url, pkg->local_filename);
3511 + free(url);
3512 +
3513 + return err;
3514 +}
3515 +
3516 +/*
3517 + * Downloads file from url, installs in package database, return package name.
3518 + */
3519 +int ipkg_prepare_url_for_install(ipkg_conf_t *conf, const char *url, char **namep)
3520 +{
3521 + int err = 0;
3522 + pkg_t *pkg;
3523 + pkg = pkg_new();
3524 + if (pkg == NULL)
3525 + return ENOMEM;
3526 +
3527 + if (str_starts_with(url, "http://")
3528 + || str_starts_with(url, "ftp://")) {
3529 + char *tmp_file;
3530 + char *file_basec = strdup(url);
3531 + char *file_base = basename(file_basec);
3532 +
3533 + sprintf_alloc(&tmp_file, "%s/%s", conf->tmp_dir, file_base);
3534 + err = ipkg_download(conf, url, tmp_file);
3535 + if (err)
3536 + return err;
3537 +
3538 + err = pkg_init_from_file(pkg, tmp_file);
3539 + if (err)
3540 + return err;
3541 + pkg->local_filename = strdup(tmp_file);
3542 +
3543 + free(tmp_file);
3544 + free(file_basec);
3545 +
3546 + } else if (strcmp(&url[strlen(url) - 4], IPKG_PKG_EXTENSION) == 0
3547 + || strcmp(&url[strlen(url) - 4], DPKG_PKG_EXTENSION) == 0) {
3548 +
3549 + err = pkg_init_from_file(pkg, url);
3550 + if (err)
3551 + return err;
3552 + pkg->local_filename = strdup(url);
3553 + ipkg_message(conf, IPKG_DEBUG2, "Package %s provided by hand (%s).\n", pkg->name,pkg->local_filename);
3554 + pkg->provided_by_hand = 1;
3555 +
3556 + } else {
3557 + pkg_deinit(pkg);
3558 + free(pkg);
3559 + return 0;
3560 + }
3561 +
3562 + if (!pkg->architecture) {
3563 + ipkg_message(conf, IPKG_ERROR, "Package %s has no Architecture defined.\n", pkg->name);
3564 + return -EINVAL;
3565 + }
3566 +
3567 + pkg->dest = conf->default_dest;
3568 + pkg->state_want = SW_INSTALL;
3569 + pkg->state_flag |= SF_PREFER;
3570 + pkg = hash_insert_pkg(&conf->pkg_hash, pkg, 1,conf);
3571 + if ( pkg == NULL ){
3572 + fprintf(stderr, "%s : This should never happen. Report this Bug in bugzilla please \n ",__FUNCTION__);
3573 + return 0;
3574 + }
3575 + if (namep) {
3576 + *namep = strdup(pkg->name);
3577 + }
3578 + return 0;
3579 +}
3580 Index: busybox-1.8.1/archival/libipkg/ipkg_download.h
3581 ===================================================================
3582 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3583 +++ busybox-1.8.1/archival/libipkg/ipkg_download.h 2007-11-10 17:40:53.352764197 +0100
3584 @@ -0,0 +1,30 @@
3585 +/* ipkg_download.h - the itsy package management system
3586 +
3587 + Carl D. Worth
3588 +
3589 + Copyright (C) 2001 University of Southern California
3590 +
3591 + This program is free software; you can redistribute it and/or
3592 + modify it under the terms of the GNU General Public License as
3593 + published by the Free Software Foundation; either version 2, or (at
3594 + your option) any later version.
3595 +
3596 + This program is distributed in the hope that it will be useful, but
3597 + WITHOUT ANY WARRANTY; without even the implied warranty of
3598 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3599 + General Public License for more details.
3600 +*/
3601 +
3602 +#ifndef IPKG_DOWNLOAD_H
3603 +#define IPKG_DOWNLOAD_H
3604 +
3605 +#include "ipkg_conf.h"
3606 +
3607 +int ipkg_download(ipkg_conf_t *conf, const char *src, const char *dest_file_name);
3608 +int ipkg_download_pkg(ipkg_conf_t *conf, pkg_t *pkg, const char *dir);
3609 +/*
3610 + * Downloads file from url, installs in package database, return package name.
3611 + */
3612 +int ipkg_prepare_url_for_install(ipkg_conf_t *conf, const char *url, char **namep);
3613 +
3614 +#endif
3615 Index: busybox-1.8.1/archival/libipkg/ipkg.h
3616 ===================================================================
3617 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3618 +++ busybox-1.8.1/archival/libipkg/ipkg.h 2007-11-10 17:40:53.352764197 +0100
3619 @@ -0,0 +1,74 @@
3620 +/* ipkg.h - the itsy package management system
3621 +
3622 + Carl D. Worth
3623 +
3624 + Copyright (C) 2001 University of Southern California
3625 +
3626 + This program is free software; you can redistribute it and/or
3627 + modify it under the terms of the GNU General Public License as
3628 + published by the Free Software Foundation; either version 2, or (at
3629 + your option) any later version.
3630 +
3631 + This program is distributed in the hope that it will be useful, but
3632 + WITHOUT ANY WARRANTY; without even the implied warranty of
3633 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3634 + General Public License for more details.
3635 +*/
3636 +
3637 +#ifndef IPKG_H
3638 +#define IPKG_H
3639 +
3640 +/*
3641 +#ifdef HAVE_CONFIG_H
3642 +#include "config.h"
3643 +#endif
3644 +*/
3645 +
3646 +#if 0
3647 +#define IPKG_DEBUG_NO_TMP_CLEANUP
3648 +#endif
3649 +
3650 +#include "ipkg_includes.h"
3651 +#include "ipkg_conf.h"
3652 +#include "ipkg_message.h"
3653 +
3654 +#define IPKG_PKG_EXTENSION ".ipk"
3655 +#define DPKG_PKG_EXTENSION ".deb"
3656 +
3657 +#define IPKG_LEGAL_PKG_NAME_CHARS "abcdefghijklmnopqrstuvwxyz0123456789.+-"
3658 +#define IPKG_PKG_VERSION_SEP_CHAR '_'
3659 +
3660 +#define IPKG_STATE_DIR_PREFIX IPKGLIBDIR"/ipkg"
3661 +#define IPKG_LISTS_DIR_SUFFIX "lists"
3662 +#define IPKG_INFO_DIR_SUFFIX "info"
3663 +#define IPKG_STATUS_FILE_SUFFIX "status"
3664 +
3665 +#define IPKG_BACKUP_SUFFIX "-ipkg.backup"
3666 +
3667 +#define IPKG_LIST_DESCRIPTION_LENGTH 128
3668 +
3669 +#define IPKG_VERSION "0.99.162"
3670 +
3671 +
3672 +enum ipkg_error {
3673 + IPKG_SUCCESS = 0,
3674 + IPKG_PKG_DEPS_UNSATISFIED,
3675 + IPKG_PKG_IS_ESSENTIAL,
3676 + IPKG_PKG_HAS_DEPENDENTS,
3677 + IPKG_PKG_HAS_NO_CANDIDATE
3678 +};
3679 +typedef enum ipkg_error ipkg_error_t;
3680 +
3681 +extern int ipkg_state_changed;
3682 +
3683 +
3684 +struct errlist {
3685 + char * errmsg;
3686 + struct errlist * next;
3687 +} ;
3688 +
3689 +extern struct errlist* error_list;
3690 +
3691 +extern ipkg_conf_t *global_conf;
3692 +
3693 +#endif
3694 Index: busybox-1.8.1/archival/libipkg/ipkg_includes.h
3695 ===================================================================
3696 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3697 +++ busybox-1.8.1/archival/libipkg/ipkg_includes.h 2007-11-10 17:40:53.352764197 +0100
3698 @@ -0,0 +1,79 @@
3699 +#ifndef IPKG_INCLUDES_H
3700 +#define IPKG_INCLUDES_H
3701 +
3702 +/* Define to 1 if you have the <memory.h> header file. */
3703 +#define HAVE_MEMORY_H 1
3704 +
3705 +/* Define to 1 if you have the <regex.h> header file. */
3706 +#define HAVE_REGEX_H 1
3707 +
3708 +/* Define to 1 if you have the <stdlib.h> header file. */
3709 +#define HAVE_STDLIB_H 1
3710 +
3711 +/* Define to 1 if you have the <strings.h> header file. */
3712 +#define HAVE_STRINGS_H 1
3713 +
3714 +/* Define to 1 if you have the <string.h> header file. */
3715 +#define HAVE_STRING_H 1
3716 +
3717 +/* Define to 1 if you have the <sys/stat.h> header file. */
3718 +#define HAVE_SYS_STAT_H 1
3719 +
3720 +/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
3721 +#define HAVE_SYS_WAIT_H 1
3722 +
3723 +/* Define to 1 if you have the <unistd.h> header file. */
3724 +#define HAVE_UNISTD_H 1
3725 +
3726 +/* Define to 1 if you have the ANSI C header files. */
3727 +#define STDC_HEADERS 1
3728 +
3729 +
3730 +#include <stdio.h>
3731 +
3732 +#if STDC_HEADERS
3733 +# include <stdlib.h>
3734 +# include <stdarg.h>
3735 +# include <stddef.h>
3736 +# include <ctype.h>
3737 +# include <errno.h>
3738 +#else
3739 +# if HAVE_STDLIB_H
3740 +# include <stdlib.h>
3741 +# endif
3742 +#endif
3743 +
3744 +#if HAVE_REGEX_H
3745 +# include <regex.h>
3746 +#endif
3747 +
3748 +#if HAVE_STRING_H
3749 +# if !STDC_HEADERS && HAVE_MEMORY_H
3750 +# include <memory.h>
3751 +# endif
3752 +/* XXX: What's the right way to pick up GNU's strndup declaration? */
3753 +# if __GNUC__
3754 +# define __USE_GNU 1
3755 +# endif
3756 +# include <string.h>
3757 +# undef __USE_GNU
3758 +#endif
3759 +
3760 +#if HAVE_STRINGS_H
3761 +# include <strings.h>
3762 +#endif
3763 +
3764 +#if HAVE_SYS_STAT_H
3765 +# include <sys/stat.h>
3766 +#endif
3767 +
3768 +#if HAVE_SYS_WAIT_H
3769 +# include <sys/wait.h>
3770 +#endif
3771 +
3772 +#if HAVE_UNISTD_H
3773 +# include <sys/types.h>
3774 +# include <unistd.h>
3775 +#endif
3776 +
3777 +#endif /* IPKG_INCLUDES_H */
3778 Index: busybox-1.8.1/archival/libipkg/ipkg_install.c
3779 ===================================================================
3780 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
3781 +++ busybox-1.8.1/archival/libipkg/ipkg_install.c 2007-11-10 17:40:53.356764426 +0100
3782 @@ -0,0 +1,1942 @@
3783 +/* ipkg_install.c - the itsy package management system
3784 +
3785 + Carl D. Worth
3786 +
3787 + Copyright (C) 2001 University of Southern California
3788 +
3789 + This program is free software; you can redistribute it and/or
3790 + modify it under the terms of the GNU General Public License as
3791 + published by the Free Software Foundation; either version 2, or (at
3792 + your option) any later version.
3793 +
3794 + This program is distributed in the hope that it will be useful, but
3795 + WITHOUT ANY WARRANTY; without even the implied warranty of
3796 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3797 + General Public License for more details.
3798 +*/
3799 +
3800 +#include "ipkg.h"
3801 +#include <errno.h>
3802 +#include <dirent.h>
3803 +#include <glob.h>
3804 +#include <time.h>
3805 +#include <signal.h>
3806 +typedef void (*sighandler_t)(int);
3807 +
3808 +#include "pkg.h"
3809 +#include "pkg_hash.h"
3810 +#include "pkg_extract.h"
3811 +
3812 +#include "ipkg_install.h"
3813 +#include "ipkg_configure.h"
3814 +#include "ipkg_download.h"
3815 +#include "ipkg_remove.h"
3816 +
3817 +#include "ipkg_utils.h"
3818 +#include "ipkg_message.h"
3819 +
3820 +#include "sprintf_alloc.h"
3821 +#include "file_util.h"
3822 +#include "str_util.h"
3823 +#include "xsystem.h"
3824 +#include "user.h"
3825 +
3826 +int satisfy_dependencies_for(ipkg_conf_t *conf, pkg_t *pkg);
3827 +static int verify_pkg_installable(ipkg_conf_t *conf, pkg_t *pkg);
3828 +static int unpack_pkg_control_files(ipkg_conf_t *conf, pkg_t *pkg);
3829 +
3830 +static int prerm_upgrade_old_pkg(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3831 +static int prerm_upgrade_old_pkg_unwind(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3832 +static int prerm_deconfigure_conflictors(ipkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors);
3833 +static int prerm_deconfigure_conflictors_unwind(ipkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *conflictors);
3834 +static int preinst_configure(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3835 +static int preinst_configure_unwind(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3836 +static int check_data_file_clashes(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3837 +static int check_data_file_clashes_change(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3838 +static int check_data_file_clashes_unwind(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3839 +static int backup_modified_conffiles(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3840 +static int backup_modified_conffiles_unwind(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3841 +static int postrm_upgrade_old_pkg(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3842 +static int postrm_upgrade_old_pkg_unwind(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3843 +
3844 +static int remove_obsolesced_files(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3845 +static int install_maintainer_scripts(ipkg_conf_t *conf, pkg_t *pkg, pkg_t *old_pkg);
3846 +static int remove_disappeared(ipkg_conf_t *conf, pkg_t *pkg);
3847 +static int install_data_files(ipkg_conf_t *conf, pkg_t *pkg);
3848 +static int resolve_conffiles(ipkg_conf_t *conf, pkg_t *pkg);
3849 +
3850 +static int cleanup_temporary_files(ipkg_conf_t *conf, pkg_t *pkg);
3851 +
3852 +static int user_prefers_old_conffile(const char *file, const char *backup);
3853 +
3854 +static char *backup_filename_alloc(const char *file_name);
3855 +static int backup_make_backup(ipkg_conf_t *conf, const char *file_name);
3856 +static int backup_exists_for(const char *file_name);
3857 +static int backup_remove(const char *file_name);
3858 +
3859 +
3860 +int ipkg_install_from_file(ipkg_conf_t *conf, const char *filename)
3861 +{
3862 + int err, cmp;
3863 + pkg_t *pkg, *old;
3864 + char *old_version, *new_version;
3865 +
3866 + pkg = pkg_new();
3867 + if (pkg == NULL) {
3868 + return ENOMEM;
3869 + }
3870 +
3871 + err = pkg_init_from_file(pkg, filename);
3872 + if (err) {
3873 + return err;
3874 + }
3875 +
3876 + if (!pkg->architecture) {
3877 + ipkg_message(conf, IPKG_ERROR, "Package %s has no Architecture defined.\n", pkg->name);
3878 + return -EINVAL;
3879 + }
3880 +
3881 + /* XXX: CLEANUP: hash_insert_pkg has a nasty side effect of possibly
3882 + freeing the pkg that we pass in. It might be nice to clean this up
3883 + if possible. */
3884 + pkg = hash_insert_pkg(&conf->pkg_hash, pkg, 1,conf);
3885 + old = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg->name);
3886 +
3887 + pkg->local_filename = strdup(filename);
3888 +
3889 + if (old) {
3890 + old_version = pkg_version_str_alloc(old);
3891 + new_version = pkg_version_str_alloc(pkg);
3892 +
3893 + cmp = pkg_compare_versions(old, pkg);
3894 + if ( (conf->force_downgrade==1) && (cmp > 0) ){ /* We've been asked to allow downgrade and version is precedent */
3895 + cmp = -1 ; /* then we force ipkg to downgrade */
3896 + /* We need to use a value < 0 because in the 0 case we are asking to */
3897 + /* reinstall, and some check could fail asking the "force-reinstall" option */
3898 + }
3899 + if (cmp > 0) {
3900 + ipkg_message(conf, IPKG_NOTICE,
3901 + "Not downgrading package %s on %s from %s to %s.\n",
3902 + old->name, old->dest->name, old_version, new_version);
3903 + pkg->state_want = SW_DEINSTALL;
3904 + pkg->state_flag |= SF_OBSOLETE;
3905 + free(old_version);
3906 + free(new_version);
3907 + return 0;
3908 + } else {
3909 + free(old_version);
3910 + free(new_version);
3911 + }
3912 + }
3913 +
3914 + ipkg_message(conf, IPKG_DEBUG2,"Function: %s calling ipkg_install_pkg \n",__FUNCTION__);
3915 + return ipkg_install_pkg(conf, pkg,0);
3916 +}
3917 +
3918 +ipkg_error_t ipkg_install_by_name(ipkg_conf_t *conf, const char *pkg_name)
3919 +{
3920 + int cmp;
3921 + pkg_t *old, *new;
3922 + char *old_version, *new_version;
3923 +
3924 + ipkg_message(conf, IPKG_DEBUG2, " Getting old from pkg_hash_fetch \n" );
3925 + old = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg_name);
3926 + if ( old )
3927 + ipkg_message(conf, IPKG_DEBUG2, " Old versions from pkg_hash_fetch %s \n", old->version );
3928 +
3929 + ipkg_message(conf, IPKG_DEBUG2, " Getting new from pkg_hash_fetch \n" );
3930 + new = pkg_hash_fetch_best_installation_candidate_by_name(conf, pkg_name);
3931 + if ( new )
3932 + ipkg_message(conf, IPKG_DEBUG2, " New versions from pkg_hash_fetch %s \n", new->version );
3933 +
3934 +/* Pigi Basically here is broken the version stuff.
3935 + What's happening is that nothing provide the version to differents
3936 + functions, so the returned struct is always the latest.
3937 + That's why the install by name don't work.
3938 +*/
3939 + ipkg_message(conf, IPKG_DEBUG2, " Versions from pkg_hash_fetch in %s ", __FUNCTION__ );
3940 +
3941 + if ( old )
3942 + ipkg_message(conf, IPKG_DEBUG2, " old %s ", old->version );
3943 + if ( new )
3944 + ipkg_message(conf, IPKG_DEBUG2, " new %s ", new->version );
3945 + ipkg_message(conf, IPKG_DEBUG2, " \n");
3946 +
3947 + if (new == NULL) {
3948 + return IPKG_PKG_HAS_NO_CANDIDATE;
3949 + }
3950 +
3951 + new->state_flag |= SF_USER;
3952 + if (old) {
3953 + old_version = pkg_version_str_alloc(old);
3954 + new_version = pkg_version_str_alloc(new);
3955 +
3956 + cmp = pkg_compare_versions(old, new);
3957 + if ( (conf->force_downgrade==1) && (cmp > 0) ){ /* We've been asked to allow downgrade and version is precedent */
3958 + ipkg_message(conf, IPKG_DEBUG, " Forcing downgrade \n");
3959 + cmp = -1 ; /* then we force ipkg to downgrade */
3960 + /* We need to use a value < 0 because in the 0 case we are asking to */
3961 + /* reinstall, and some check could fail asking the "force-reinstall" option */
3962 + }
3963 + ipkg_message(conf, IPKG_DEBUG,
3964 + "Comparing visible versions of pkg %s:"
3965 + "\n\t%s is installed "
3966 + "\n\t%s is available "
3967 + "\n\t%d was comparison result\n",
3968 + pkg_name, old_version, new_version, cmp);
3969 + if (cmp == 0 && !conf->force_reinstall) {
3970 + ipkg_message(conf, IPKG_NOTICE,
3971 + "Package %s (%s) installed in %s is up to date.\n",
3972 + old->name, old_version, old->dest->name);
3973 + free(old_version);
3974 + free(new_version);
3975 + return 0;
3976 + } else if (cmp > 0) {
3977 + ipkg_message(conf, IPKG_NOTICE,
3978 + "Not downgrading package %s on %s from %s to %s.\n",
3979 + old->name, old->dest->name, old_version, new_version);
3980 + free(old_version);
3981 + free(new_version);
3982 + return 0;
3983 + } else if (cmp < 0) {
3984 + new->dest = old->dest;
3985 + old->state_want = SW_DEINSTALL; /* Here probably the problem for bug 1277 */
3986 + }
3987 + }
3988 +
3989 + /* XXX: CLEANUP: The error code of ipkg_install_by_name is really
3990 + supposed to be an ipkg_error_t, but ipkg_install_pkg could
3991 + return any kind of integer, (might be errno from a syscall,
3992 + etc.). This is a real mess and will need to be cleaned up if
3993 + anyone ever wants to make a nice libipkg. */
3994 +
3995 + ipkg_message(conf, IPKG_DEBUG2,"Function: %s calling ipkg_install_pkg \n",__FUNCTION__);
3996 + return ipkg_install_pkg(conf, new,0);
3997 +}
3998 +
3999 +ipkg_error_t ipkg_install_multi_by_name(ipkg_conf_t *conf, const char *pkg_name)
4000 +{
4001 + abstract_pkg_vec_t *providers = pkg_hash_fetch_all_installation_candidates (&conf->pkg_hash, pkg_name);
4002 + int i;
4003 + ipkg_error_t err;
4004 + abstract_pkg_t *ppkg ;
4005 +
4006 + if (providers == NULL)
4007 + return IPKG_PKG_HAS_NO_CANDIDATE;
4008 +
4009 + for (i = 0; i < providers->len; i++) {
4010 + ppkg = abstract_pkg_vec_get(providers, i);
4011 + ipkg_message(conf, IPKG_DEBUG2,"Function: %s calling ipkg_install_by_name %d \n",__FUNCTION__, i);
4012 + err = ipkg_install_by_name(conf, ppkg->name);
4013 + if (err)
4014 + return err;
4015 +/* XXX Maybe ppkg should be freed ? */
4016 + }
4017 + return 0;
4018 +}
4019 +
4020 +/*
4021 + * Walk dependence graph starting with pkg, collect packages to be
4022 + * installed into pkgs_needed, in dependence order.
4023 + */
4024 +int pkg_mark_dependencies_for_installation(ipkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *pkgs_needed)
4025 +{
4026 + int i, err;
4027 + pkg_vec_t *depends = pkg_vec_alloc();
4028 + char **unresolved = NULL;
4029 + int ndepends;
4030 +
4031 + ndepends = pkg_hash_fetch_unsatisfied_dependencies(conf,
4032 + pkg, depends,
4033 + &unresolved);
4034 +
4035 + if (unresolved) {
4036 + ipkg_message(conf, IPKG_ERROR,
4037 + "%s: Cannot satisfy the following dependencies for %s:\n\t",
4038 + conf->force_depends ? "Warning" : "ERROR", pkg->name);
4039 + while (*unresolved) {
4040 + ipkg_message(conf, IPKG_ERROR, " %s", *unresolved);
4041 + unresolved++;
4042 + }
4043 + ipkg_message(conf, IPKG_ERROR, "\n");
4044 + if (! conf->force_depends) {
4045 + ipkg_message(conf, IPKG_INFO,
4046 + "This could mean that your package list is out of date or that the packages\n"
4047 + "mentioned above do not yet exist (try 'ipkg update'). To proceed in spite\n"
4048 + "of this problem try again with the '-force-depends' option.\n");
4049 + pkg_vec_free(depends);
4050 + return IPKG_PKG_DEPS_UNSATISFIED;
4051 + }
4052 + }
4053 +
4054 + if (ndepends <= 0) {
4055 + pkg_vec_free(depends);
4056 + return 0;
4057 + }
4058 +
4059 + for (i = 0; i < depends->len; i++) {
4060 + pkg_t *dep = depends->pkgs[i];
4061 + /* The package was uninstalled when we started, but another
4062 + dep earlier in this loop may have depended on it and pulled
4063 + it in, so check first. */
4064 + if ((dep->state_status != SS_INSTALLED)
4065 + && (dep->state_status != SS_UNPACKED)
4066 + && (dep->state_want != SW_INSTALL)) {
4067 +
4068 + /* Mark packages as to-be-installed */
4069 + dep->state_want = SW_INSTALL;
4070 +
4071 + /* Dependencies should be installed the same place as pkg */
4072 + if (dep->dest == NULL) {
4073 + dep->dest = pkg->dest;
4074 + }
4075 +
4076 + err = pkg_mark_dependencies_for_installation(conf, dep, pkgs_needed);
4077 + if (err) {
4078 + pkg_vec_free(depends);
4079 + return err;
4080 + }
4081 + }
4082 + }
4083 + if (pkgs_needed)
4084 + pkg_vec_insert(pkgs_needed, pkg);
4085 +
4086 + pkg_vec_free(depends);
4087 +
4088 + return 0;
4089 +}
4090 +
4091 +int name_mark_dependencies_for_installation(ipkg_conf_t *conf, const char *pkg_name, pkg_vec_t *pkgs_needed)
4092 +{
4093 + int cmp;
4094 + pkg_t *old, *new;
4095 + char *old_version, *new_version;
4096 +
4097 + old = pkg_hash_fetch_installed_by_name(&conf->pkg_hash, pkg_name);
4098 +
4099 + new = pkg_hash_fetch_best_installation_candidate_by_name(conf, pkg_name);
4100 + if (new == NULL) {
4101 + return IPKG_PKG_HAS_NO_CANDIDATE;
4102 + }
4103 + if (old) {
4104 + old_version = pkg_version_str_alloc(old);
4105 + new_version = pkg_version_str_alloc(new);
4106 +
4107 + cmp = pkg_compare_versions(old, new);
4108 + if ( (conf->force_downgrade==1) && (cmp > 0) ){ /* We've been asked to allow downgrade and version is precedent */
4109 + ipkg_message(conf, IPKG_DEBUG, " Forcing downgrade ");
4110 + cmp = -1 ; /* then we force ipkg to downgrade */
4111 + /* We need to use a value < 0 because in the 0 case we are asking to */
4112 + /* reinstall, and some check could fail asking the "force-reinstall" option */
4113 + }
4114 + ipkg_message(conf, IPKG_DEBUG,
4115 + "comparing visible versions of pkg %s:"
4116 + "\n\t%s is installed "
4117 + "\n\t%s is available "
4118 + "\n\t%d was comparison result\n",
4119 + pkg_name, old_version, new_version, cmp);
4120 + if (cmp == 0 && !conf->force_reinstall) {
4121 + ipkg_message(conf, IPKG_NOTICE,
4122 + "Package %s (%s) installed in %s is up to date.\n",
4123 + old->name, old_version, old->dest->name);
4124 + free(old_version);
4125 + free(new_version);
4126 + return 0;
4127 + } else if (cmp > 0) {
4128 + ipkg_message(conf, IPKG_NOTICE,
4129 + "Not downgrading package %s on %s from %s to %s.\n",
4130 + old->name, old->dest->name, old_version, new_version);
4131 + free(old_version);
4132 + free(new_version);
4133 + return 0;
4134 + } else if (cmp < 0) {
4135 + new->dest = old->dest;
4136 + old->state_want = SW_DEINSTALL;
4137 + old->state_flag |= SF_OBSOLETE;
4138 + }
4139 + }
4140 + return pkg_mark_dependencies_for_installation(conf, new, pkgs_needed);
4141 +}
4142 +
4143 +\f
4144 +
4145 +int satisfy_dependencies_for(ipkg_conf_t *conf, pkg_t *pkg)
4146 +{
4147 + int i, err;
4148 + pkg_vec_t *depends = pkg_vec_alloc();
4149 + pkg_t *dep;
4150 + char **unresolved = NULL;
4151 + int ndepends;
4152 +
4153 + ndepends = pkg_hash_fetch_unsatisfied_dependencies(conf,
4154 + pkg, depends,
4155 + &unresolved);
4156 +
4157 + if (unresolved) {
4158 + ipkg_message(conf, IPKG_ERROR,
4159 + "%s: Cannot satisfy the following dependencies for %s:\n\t",
4160 + conf->force_depends ? "Warning" : "ERROR", pkg->name);
4161 + while (*unresolved) {
4162 + ipkg_message(conf, IPKG_ERROR, " %s", *unresolved);
4163 + unresolved++;
4164 + }
4165 + ipkg_message(conf, IPKG_ERROR, "\n");
4166 + if (! conf->force_depends) {
4167 + ipkg_message(conf, IPKG_INFO,
4168 + "This could mean that your package list is out of date or that the packages\n"
4169 + "mentioned above do not yet exist (try 'ipkg update'). To proceed in spite\n"
4170 + "of this problem try again with the '-force-depends' option.\n");
4171 + pkg_vec_free(depends);
4172 + return IPKG_PKG_DEPS_UNSATISFIED;
4173 + }
4174 + }
4175 +
4176 + if (ndepends <= 0) {
4177 + return 0;
4178 + }
4179 +
4180 + /* Mark packages as to-be-installed */
4181 + for (i=0; i < depends->len; i++) {
4182 + /* Dependencies should be installed the same place as pkg */
4183 + if (depends->pkgs[i]->dest == NULL) {
4184 + depends->pkgs[i]->dest = pkg->dest;
4185 + }
4186 + depends->pkgs[i]->state_want = SW_INSTALL;
4187 + }
4188 +
4189 + for (i = 0; i < depends->len; i++) {
4190 + dep = depends->pkgs[i];
4191 + /* The package was uninstalled when we started, but another
4192 + dep earlier in this loop may have depended on it and pulled
4193 + it in, so check first. */
4194 + if ((dep->state_status != SS_INSTALLED)
4195 + && (dep->state_status != SS_UNPACKED)) {
4196 + ipkg_message(conf, IPKG_DEBUG2,"Function: %s calling ipkg_install_pkg \n",__FUNCTION__);
4197 + err = ipkg_install_pkg(conf, dep,0);
4198 + if (err) {
4199 + pkg_vec_free(depends);
4200 + return err;
4201 + }
4202 + }
4203 + }
4204 +
4205 + pkg_vec_free(depends);
4206 +
4207 + return 0;
4208 +}
4209 +
4210 +
4211 +/* check all packages have their dependences satisfied, e.g., in case an upgraded package split */
4212 +int ipkg_satisfy_all_dependences(ipkg_conf_t *conf)
4213 +{
4214 + if (conf->nodeps == 0) {
4215 + int i;
4216 + pkg_vec_t *installed = pkg_vec_alloc();
4217 + pkg_hash_fetch_all_installed(&conf->pkg_hash, installed);
4218 + for (i = 0; i < installed->len; i++) {
4219 + pkg_t *pkg = installed->pkgs[i];
4220 + satisfy_dependencies_for(conf, pkg);
4221 + }
4222 + pkg_vec_free(installed);
4223 + }
4224 + return 0;
4225 +}
4226 +
4227 +\f
4228 +
4229 +static int check_conflicts_for(ipkg_conf_t *conf, pkg_t *pkg)
4230 +{
4231 + int i;
4232 + pkg_vec_t *conflicts = NULL;
4233 + int level;
4234 + const char *prefix;
4235 + if (conf->force_depends) {
4236 + level = IPKG_NOTICE;
4237 + prefix = "Warning";
4238 + } else {
4239 + level = IPKG_ERROR;
4240 + prefix = "ERROR";
4241 + }
4242 +
4243 + if (!conf->force_depends)
4244 + conflicts = (pkg_vec_t *)pkg_hash_fetch_conflicts(&conf->pkg_hash, pkg);
4245 +
4246 + if (conflicts) {
4247 + ipkg_message(conf, level,
4248 + "%s: The following packages conflict with %s:\n\t", prefix, pkg->name);
4249 + i = 0;
4250 + while (i < conflicts->len)
4251 + ipkg_message(conf, level, " %s", conflicts->pkgs[i++]->name);
4252 + ipkg_message(conf, level, "\n");
4253 + pkg_vec_free(conflicts);
4254 + return IPKG_PKG_DEPS_UNSATISFIED;
4255 + }
4256 + return 0;
4257 +}
4258 +
4259 +static int update_file_ownership(ipkg_conf_t *conf, pkg_t *new_pkg, pkg_t *old_pkg)
4260 +{
4261 + str_list_t *new_list = pkg_get_installed_files(new_pkg);
4262 + str_list_elt_t *iter;
4263 +
4264 + for (iter = new_list->head; iter; iter = iter->next) {
4265 + char *new_file = iter->data;
4266 + pkg_t *owner = file_hash_get_file_owner(conf, new_file);
4267 + if (!new_file)
4268 + ipkg_message(conf, IPKG_ERROR, "Null new_file for new_pkg=%s\n", new_pkg->name);
4269 + if (!owner || (owner == old_pkg))
4270 + file_hash_set_file_owner(conf, new_file, new_pkg);
4271 + }
4272 + if (old_pkg) {
4273 + str_list_t *old_list = pkg_get_installed_files(old_pkg);
4274 + for (iter = old_list->head; iter; iter = iter->next) {
4275 + char *old_file = iter->data;
4276 + pkg_t *owner = file_hash_get_file_owner(conf, old_file);
4277 + if (owner == old_pkg) {
4278 + /* obsolete */
4279 + hash_table_insert(&conf->obs_file_hash, old_file, old_pkg);
4280 + }
4281 + }
4282 + }
4283 + return 0;
4284 +}
4285 +
4286 +static int verify_pkg_installable(ipkg_conf_t *conf, pkg_t *pkg)
4287 +{
4288 + /* XXX: FEATURE: Anything else needed here? Maybe a check on free space? */
4289 +
4290 + /* sma 6.20.02: yup; here's the first bit */
4291 + /*
4292 + * XXX: BUG easy for cworth
4293 + * 1) please point the call below to the correct current root destination
4294 + * 2) we need to resolve how to check the required space for a pending pkg,
4295 + * my diddling with the .ipk file size below isn't going to cut it.
4296 + * 3) return a proper error code instead of 1
4297 + */
4298 + int comp_size, blocks_available;
4299 +
4300 + if (!conf->force_space && pkg->installed_size != NULL) {
4301 + blocks_available = get_available_blocks(conf->default_dest->root_dir);
4302 +
4303 + comp_size = strtoul(pkg->installed_size, NULL, 0);
4304 + /* round up a blocks count without doing fancy-but-slow casting jazz */
4305 + comp_size = (int)((comp_size + 1023) / 1024);
4306 +
4307 + if (comp_size >= blocks_available) {
4308 + ipkg_message(conf, IPKG_ERROR,
4309 + "Only have %d available blocks on filesystem %s, pkg %s needs %d\n",
4310 + blocks_available, conf->default_dest->root_dir, pkg->name, comp_size);
4311 + return ENOSPC;
4312 + }
4313 + }
4314 + return 0;
4315 +}
4316 +
4317 +static int unpack_pkg_control_files(ipkg_conf_t *conf, pkg_t *pkg)
4318 +{
4319 + int err;
4320 + char *conffiles_file_name;
4321 + char *root_dir;
4322 + FILE *conffiles_file;
4323 +
4324 + sprintf_alloc(&pkg->tmp_unpack_dir, "%s/%s-XXXXXX", conf->tmp_dir, pkg->name);
4325 +
4326 + pkg->tmp_unpack_dir = mkdtemp(pkg->tmp_unpack_dir);
4327 + if (pkg->tmp_unpack_dir == NULL) {
4328 + ipkg_message(conf, IPKG_ERROR,
4329 + "%s: Failed to create temporary directory '%s': %s\n",
4330 + __FUNCTION__, pkg->tmp_unpack_dir, strerror(errno));
4331 + return errno;
4332 + }
4333 +
4334 + err = pkg_extract_control_files_to_dir(pkg, pkg->tmp_unpack_dir);
4335 + if (err) {
4336 + return err;
4337 + }
4338 +
4339 + /* XXX: CLEANUP: There might be a cleaner place to read in the
4340 + conffiles. Seems like I should be able to get everything to go
4341 + through pkg_init_from_file. If so, maybe it would make sense to
4342 + move all of unpack_pkg_control_files to that function. */
4343 +
4344 + /* Don't need to re-read conffiles if we already have it */
4345 + if (pkg->conffiles.head) {
4346 + return 0;
4347 + }
4348 +
4349 + sprintf_alloc(&conffiles_file_name, "%s/conffiles", pkg->tmp_unpack_dir);
4350 + if (! file_exists(conffiles_file_name)) {
4351 + free(conffiles_file_name);
4352 + return 0;
4353 + }
4354 +
4355 + conffiles_file = fopen(conffiles_file_name, "r");
4356 + if (conffiles_file == NULL) {
4357 + fprintf(stderr, "%s: failed to open %s: %s\n",
4358 + __FUNCTION__, conffiles_file_name, strerror(errno));
4359 + free(conffiles_file_name);
4360 + return errno;
4361 + }
4362 + free(conffiles_file_name);
4363 +
4364 + while (1) {
4365 + char *cf_name;
4366 + char *cf_name_in_dest;
4367 +
4368 + cf_name = file_read_line_alloc(conffiles_file);
4369 + if (cf_name == NULL) {
4370 + break;
4371 + }
4372 + str_chomp(cf_name);
4373 + if (cf_name[0] == '\0') {
4374 + continue;
4375 + }
4376 +
4377 + /* Prepend dest->root_dir to conffile name.
4378 + Take pains to avoid multiple slashes. */
4379 + root_dir = pkg->dest->root_dir;
4380 + if (conf->offline_root)
4381 + /* skip the offline_root prefix */
4382 + root_dir = pkg->dest->root_dir + strlen(conf->offline_root);
4383 + sprintf_alloc(&cf_name_in_dest, "%s%s", root_dir,
4384 + cf_name[0] == '/' ? (cf_name + 1) : cf_name);
4385 +
4386 + /* Can't get an md5sum now, (file isn't extracted yet).
4387 + We'll wait until resolve_conffiles */
4388 + conffile_list_append(&pkg->conffiles, cf_name_in_dest, NULL);
4389 +
4390 + free(cf_name);
4391 + free(cf_name_in_dest);
4392 + }
4393 +
4394 + fclose(conffiles_file);
4395 +
4396 + return 0;
4397 +}
4398 +
4399 +/* returns number of installed replacees */
4400 +int pkg_get_installed_replacees(ipkg_conf_t *conf, pkg_t *pkg, pkg_vec_t *installed_replacees)
4401 +{
4402 + abstract_pkg_t **replaces = pkg->replaces;
4403 + int replaces_count = pkg->replaces_count;
4404 + int i, j;
4405 + for (i = 0; i < replaces_count; i++) {
4406 + abstract_pkg_t *ab_pkg = replaces[i];
4407 + pkg_vec_t *pkg_vec = ab_pkg->pkgs;
4408 + if (pkg_vec) {
4409 + for (j = 0; j < pkg_vec->len; j++) {
4410 + pkg_t *replacee = pkg_vec->pkgs[j];
4411 + if (!pkg_conflicts(pkg, replacee))
4412 + continue;
4413 + if (replacee->state_status == SS_INSTALLED) {
4414 + pkg_vec_insert(installed_replacees, replacee);
4415 + }
4416 + }
4417 + }
4418 + }
4419 + return installed_replacees->len;
4420 +}
4421 +
4422 +int pkg_remove_installed_replacees(ipkg_conf_t *conf, pkg_vec_t *replacees)