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