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