1 /* pkg.c - the itsy package management system
5 Copyright (C) 2001 University of Southern California
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2, or (at
10 your option) any later version.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
25 #include "pkg_parse.h"
26 #include "pkg_extract.h"
27 #include "opkg_message.h"
28 #include "opkg_utils.h"
30 #include "sprintf_alloc.h"
31 #include "file_util.h"
34 #include "opkg_conf.h"
36 typedef struct enum_map enum_map_t;
43 static const enum_map_t pkg_state_want_map[] = {
44 { SW_UNKNOWN, "unknown"},
45 { SW_INSTALL, "install"},
46 { SW_DEINSTALL, "deinstall"},
50 static const enum_map_t pkg_state_flag_map[] = {
52 { SF_REINSTREQ, "reinstreq"},
54 { SF_REPLACE, "replace"},
55 { SF_NOPRUNE, "noprune"},
56 { SF_PREFER, "prefer"},
57 { SF_OBSOLETE, "obsolete"},
61 static const enum_map_t pkg_state_status_map[] = {
62 { SS_NOT_INSTALLED, "not-installed" },
63 { SS_UNPACKED, "unpacked" },
64 { SS_HALF_CONFIGURED, "half-configured" },
65 { SS_INSTALLED, "installed" },
66 { SS_HALF_INSTALLED, "half-installed" },
67 { SS_CONFIG_FILES, "config-files" },
68 { SS_POST_INST_FAILED, "post-inst-failed" },
69 { SS_REMOVAL_FAILED, "removal-failed" }
72 static int verrevcmp(const char *val, const char *ref);
79 pkg = malloc(sizeof(pkg_t));
81 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
90 int pkg_init(pkg_t *pkg)
92 memset(pkg, 0, sizeof(pkg_t));
97 pkg->familiar_revision = NULL;
100 pkg->architecture = NULL;
101 pkg->maintainer = NULL;
103 pkg->description = NULL;
104 pkg->state_want = SW_UNKNOWN;
105 pkg->state_flag = SF_OK;
106 pkg->state_status = SS_NOT_INSTALLED;
107 pkg->depends_str = NULL;
108 pkg->provides_str = NULL;
109 pkg->depends_count = 0;
111 pkg->suggests_str = NULL;
112 pkg->recommends_str = NULL;
113 pkg->suggests_count = 0;
114 pkg->recommends_count = 0;
116 /* Abhaya: added init for conflicts fields */
117 pkg->conflicts = NULL;
118 pkg->conflicts_count = 0;
120 /* added for replaces. Jamey 7/23/2002 */
121 pkg->replaces = NULL;
122 pkg->replaces_count = 0;
124 pkg->pre_depends_count = 0;
125 pkg->pre_depends_str = NULL;
126 pkg->provides_count = 0;
127 pkg->provides = NULL;
128 pkg->filename = NULL;
129 pkg->local_filename = NULL;
130 pkg->tmp_unpack_dir = NULL;
133 pkg->installed_size = NULL;
134 pkg->priority = NULL;
136 conffile_list_init(&pkg->conffiles);
137 pkg->installed_files = NULL;
138 pkg->installed_files_ref_cnt = 0;
140 pkg->provided_by_hand = 0;
145 void pkg_deinit(pkg_t *pkg)
152 /* revision and familiar_revision share storage with version, so
154 pkg->revision = NULL;
155 pkg->familiar_revision = NULL;
156 /* owned by opkg_conf_t */
158 /* owned by opkg_conf_t */
160 free(pkg->architecture);
161 pkg->architecture = NULL;
162 free(pkg->maintainer);
163 pkg->maintainer = NULL;
166 free(pkg->description);
167 pkg->description = NULL;
168 pkg->state_want = SW_UNKNOWN;
169 pkg->state_flag = SF_OK;
170 pkg->state_status = SS_NOT_INSTALLED;
171 free(pkg->depends_str);
172 pkg->depends_str = NULL;
173 free(pkg->provides_str);
174 pkg->provides_str = NULL;
175 pkg->depends_count = 0;
176 /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->depends ? */
177 pkg->pre_depends_count = 0;
178 free(pkg->pre_depends_str);
179 pkg->pre_depends_str = NULL;
180 pkg->provides_count = 0;
181 /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->provides ? */
182 /* XXX: CLEANUP: MEMORY_LEAK: how to free up pkg->suggests ? */
184 pkg->filename = NULL;
185 free(pkg->local_filename);
186 pkg->local_filename = NULL;
187 /* CLEANUP: It'd be nice to pullin the cleanup function from
188 opkg_install.c here. See comment in
189 opkg_install.c:cleanup_temporary_files */
190 free(pkg->tmp_unpack_dir);
191 pkg->tmp_unpack_dir = NULL;
196 free(pkg->installed_size);
197 pkg->installed_size = NULL;
199 pkg->priority = NULL;
202 conffile_list_deinit(&pkg->conffiles);
203 /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
204 since if they are calling deinit, they should know. Maybe do an
205 assertion here instead? */
206 pkg->installed_files_ref_cnt = 1;
207 pkg_free_installed_files(pkg);
211 int pkg_init_from_file(pkg_t *pkg, const char *filename)
218 if (err) { return err; }
220 pkg->local_filename = strdup(filename);
222 control_file = tmpfile();
223 err = pkg_extract_control_file_to_stream(pkg, control_file);
224 if (err) { return err; }
226 rewind(control_file);
227 raw = read_raw_pkgs_from_stream(control_file);
228 pkg_parse_raw(pkg, &raw, NULL, NULL);
230 fclose(control_file);
235 /* Merge any new information in newpkg into oldpkg */
236 /* XXX: CLEANUP: This function shouldn't actually modify anything in
237 newpkg, but should leave it usable. This rework is so that
238 pkg_hash_insert doesn't clobber the pkg that you pass into it. */
240 * uh, i thought that i had originally written this so that it took
241 * two pkgs and returned a new one? we can do that again... -sma
243 int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status)
245 if (oldpkg == newpkg) {
250 oldpkg->src = newpkg->src;
252 oldpkg->dest = newpkg->dest;
253 if (!oldpkg->architecture)
254 oldpkg->architecture = str_dup_safe(newpkg->architecture);
255 if (!oldpkg->arch_priority)
256 oldpkg->arch_priority = newpkg->arch_priority;
257 if (!oldpkg->section)
258 oldpkg->section = str_dup_safe(newpkg->section);
259 if(!oldpkg->maintainer)
260 oldpkg->maintainer = str_dup_safe(newpkg->maintainer);
261 if(!oldpkg->description)
262 oldpkg->description = str_dup_safe(newpkg->description);
264 /* merge the state_flags from the new package */
265 oldpkg->state_want = newpkg->state_want;
266 oldpkg->state_status = newpkg->state_status;
267 oldpkg->state_flag = newpkg->state_flag;
269 if (oldpkg->state_want == SW_UNKNOWN)
270 oldpkg->state_want = newpkg->state_want;
271 if (oldpkg->state_status == SS_NOT_INSTALLED)
272 oldpkg->state_status = newpkg->state_status;
273 oldpkg->state_flag |= newpkg->state_flag;
276 if (!oldpkg->depends_str && !oldpkg->pre_depends_str && !oldpkg->recommends_str && !oldpkg->suggests_str) {
277 oldpkg->depends_str = newpkg->depends_str;
278 newpkg->depends_str = NULL;
279 oldpkg->depends_count = newpkg->depends_count;
280 newpkg->depends_count = 0;
282 oldpkg->depends = newpkg->depends;
283 newpkg->depends = NULL;
285 oldpkg->pre_depends_str = newpkg->pre_depends_str;
286 newpkg->pre_depends_str = NULL;
287 oldpkg->pre_depends_count = newpkg->pre_depends_count;
288 newpkg->pre_depends_count = 0;
290 oldpkg->recommends_str = newpkg->recommends_str;
291 newpkg->recommends_str = NULL;
292 oldpkg->recommends_count = newpkg->recommends_count;
293 newpkg->recommends_count = 0;
295 oldpkg->suggests_str = newpkg->suggests_str;
296 newpkg->suggests_str = NULL;
297 oldpkg->suggests_count = newpkg->suggests_count;
298 newpkg->suggests_count = 0;
301 if (!oldpkg->provides_str) {
302 oldpkg->provides_str = newpkg->provides_str;
303 newpkg->provides_str = NULL;
304 oldpkg->provides_count = newpkg->provides_count;
305 newpkg->provides_count = 0;
307 oldpkg->provides = newpkg->provides;
308 newpkg->provides = NULL;
311 if (!oldpkg->conflicts_str) {
312 oldpkg->conflicts_str = newpkg->conflicts_str;
313 newpkg->conflicts_str = NULL;
314 oldpkg->conflicts_count = newpkg->conflicts_count;
315 newpkg->conflicts_count = 0;
317 oldpkg->conflicts = newpkg->conflicts;
318 newpkg->conflicts = NULL;
321 if (!oldpkg->replaces_str) {
322 oldpkg->replaces_str = newpkg->replaces_str;
323 newpkg->replaces_str = NULL;
324 oldpkg->replaces_count = newpkg->replaces_count;
325 newpkg->replaces_count = 0;
327 oldpkg->replaces = newpkg->replaces;
328 newpkg->replaces = NULL;
331 if (!oldpkg->filename)
332 oldpkg->filename = str_dup_safe(newpkg->filename);
334 fprintf(stdout, "pkg=%s old local_filename=%s new local_filename=%s\n",
335 oldpkg->name, oldpkg->local_filename, newpkg->local_filename);
336 if (!oldpkg->local_filename)
337 oldpkg->local_filename = str_dup_safe(newpkg->local_filename);
338 if (!oldpkg->tmp_unpack_dir)
339 oldpkg->tmp_unpack_dir = str_dup_safe(newpkg->tmp_unpack_dir);
341 oldpkg->md5sum = str_dup_safe(newpkg->md5sum);
343 oldpkg->size = str_dup_safe(newpkg->size);
344 if (!oldpkg->installed_size)
345 oldpkg->installed_size = str_dup_safe(newpkg->installed_size);
346 if (!oldpkg->priority)
347 oldpkg->priority = str_dup_safe(newpkg->priority);
349 oldpkg->source = str_dup_safe(newpkg->source);
350 if (oldpkg->conffiles.head == NULL){
351 oldpkg->conffiles = newpkg->conffiles;
352 conffile_list_init(&newpkg->conffiles);
354 if (!oldpkg->installed_files){
355 oldpkg->installed_files = newpkg->installed_files;
356 oldpkg->installed_files_ref_cnt = newpkg->installed_files_ref_cnt;
357 newpkg->installed_files = NULL;
359 if (!oldpkg->essential)
360 oldpkg->essential = newpkg->essential;
365 abstract_pkg_t *abstract_pkg_new(void)
367 abstract_pkg_t * ab_pkg;
369 ab_pkg = malloc(sizeof(abstract_pkg_t));
371 if (ab_pkg == NULL) {
372 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
376 if ( abstract_pkg_init(ab_pkg) < 0 )
382 int abstract_pkg_init(abstract_pkg_t *ab_pkg)
384 memset(ab_pkg, 0, sizeof(abstract_pkg_t));
386 ab_pkg->provided_by = abstract_pkg_vec_alloc();
387 if (ab_pkg->provided_by==NULL){
390 ab_pkg->dependencies_checked = 0;
391 ab_pkg->state_status = SS_NOT_INSTALLED;
396 void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){
399 char **raw_start=NULL;
401 temp_str = (char *) malloc (strlen(pkg->dest->info_dir)+strlen(pkg->name)+12);
402 if (temp_str == NULL ){
403 opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__);
406 sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name);
408 raw = raw_start = read_raw_pkgs_from_file(temp_str);
410 opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__);
415 if (!pkg_valorize_other_field(pkg, &raw ) == 0) {
416 opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name);
432 char * pkg_formatted_info(pkg_t *pkg )
439 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
445 line = pkg_formatted_field(pkg, "Package");
446 strncat(buff ,line, strlen(line));
449 line = pkg_formatted_field(pkg, "Version");
450 strncat(buff ,line, strlen(line));
453 line = pkg_formatted_field(pkg, "Depends");
454 strncat(buff ,line, strlen(line));
457 line = pkg_formatted_field(pkg, "Recommends");
458 strncat(buff ,line, strlen(line));
461 line = pkg_formatted_field(pkg, "Suggests");
462 strncat(buff ,line, strlen(line));
465 line = pkg_formatted_field(pkg, "Provides");
466 strncat(buff ,line, strlen(line));
469 line = pkg_formatted_field(pkg, "Replaces");
470 strncat(buff ,line, strlen(line));
473 line = pkg_formatted_field(pkg, "Conflicts");
474 strncat(buff ,line, strlen(line));
477 line = pkg_formatted_field(pkg, "Status");
478 strncat(buff ,line, strlen(line));
481 line = pkg_formatted_field(pkg, "Section");
482 strncat(buff ,line, strlen(line));
485 line = pkg_formatted_field(pkg, "Essential"); /* @@@@ should be removed in future release. *//* I do not agree with this Pigi*/
486 strncat(buff ,line, strlen(line));
489 line = pkg_formatted_field(pkg, "Architecture");
490 strncat(buff ,line, strlen(line));
493 line = pkg_formatted_field(pkg, "Maintainer");
494 strncat(buff ,line, strlen(line));
497 line = pkg_formatted_field(pkg, "MD5sum");
498 strncat(buff ,line, strlen(line));
501 line = pkg_formatted_field(pkg, "Size");
502 strncat(buff ,line, strlen(line));
505 line = pkg_formatted_field(pkg, "Filename");
506 strncat(buff ,line, strlen(line));
509 line = pkg_formatted_field(pkg, "Conffiles");
510 strncat(buff ,line, strlen(line));
513 line = pkg_formatted_field(pkg, "Source");
514 strncat(buff ,line, strlen(line));
517 line = pkg_formatted_field(pkg, "Description");
518 strncat(buff ,line, strlen(line));
521 line = pkg_formatted_field(pkg, "Installed-Time");
522 strncat(buff ,line, strlen(line));
528 char * pkg_formatted_field(pkg_t *pkg, const char *field )
530 static size_t LINE_LEN = 128;
531 char * temp = (char *)malloc(1);
533 int flag_provide_false = 0;
536 Pigi: After some discussion with Florian we decided to modify the full procedure in
537 dynamic memory allocation. This should avoid any other segv in this area ( except for bugs )
540 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
541 goto UNKNOWN_FMT_FIELD;
550 if (strcasecmp(field, "Architecture") == 0) {
552 if (pkg->architecture) {
553 temp = (char *)realloc(temp,strlen(pkg->architecture)+17);
555 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
559 snprintf(temp, (strlen(pkg->architecture)+17), "Architecture: %s\n", pkg->architecture);
561 } else if (strcasecmp(field, "Auto-Installed") == 0) {
562 /* Auto-Installed flag */
563 if (pkg->auto_installed) {
564 char * s = "Auto-Installed: yes\n";
565 temp = (char *)realloc(temp, strlen(s) + 1);
569 goto UNKNOWN_FMT_FIELD;
574 if (strcasecmp(field, "Conffiles") == 0) {
576 conffile_list_elt_t *iter;
577 char confstr[LINE_LEN];
579 if (pkg->conffiles.head == NULL) {
584 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
585 if (iter->data->name && iter->data->value) {
586 len = len + (strlen(iter->data->name)+strlen(iter->data->value)+5);
589 temp = (char *)realloc(temp,len);
591 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
595 strncpy(temp, "Conffiles:\n", 12);
596 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
597 if (iter->data->name && iter->data->value) {
598 snprintf(confstr, LINE_LEN, "%s %s\n", iter->data->name, iter->data->value);
599 strncat(temp, confstr, strlen(confstr));
602 } else if (strcasecmp(field, "Conflicts") == 0) {
605 if (pkg->conflicts_count) {
606 char conflictstr[LINE_LEN];
608 for(i = 0; i < pkg->conflicts_count; i++) {
609 len = len + (strlen(pkg->conflicts_str[i])+5);
611 temp = (char *)realloc(temp,len);
613 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
617 strncpy(temp, "Conflicts:", 11);
618 for(i = 0; i < pkg->conflicts_count; i++) {
619 snprintf(conflictstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]);
620 strncat(temp, conflictstr, strlen(conflictstr));
622 strncat(temp, "\n", strlen("\n"));
625 goto UNKNOWN_FMT_FIELD;
630 if (strcasecmp(field, "Depends") == 0) {
634 if (pkg->depends_count) {
635 char depstr[LINE_LEN];
637 for(i = 0; i < pkg->depends_count; i++) {
638 len = len + (strlen(pkg->depends_str[i])+4);
640 temp = (char *)realloc(temp,len);
642 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
646 strncpy(temp, "Depends:", 10);
647 for(i = 0; i < pkg->depends_count; i++) {
648 snprintf(depstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->depends_str[i]);
649 strncat(temp, depstr, strlen(depstr));
651 strncat(temp, "\n", strlen("\n"));
653 } else if (strcasecmp(field, "Description") == 0) {
655 if (pkg->description) {
656 temp = (char *)realloc(temp,strlen(pkg->description)+16);
658 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
662 snprintf(temp, (strlen(pkg->description)+16), "Description: %s\n", pkg->description);
665 goto UNKNOWN_FMT_FIELD;
671 if (pkg->essential) {
672 temp = (char *)realloc(temp,16);
674 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
678 snprintf(temp, (16), "Essential: yes\n");
686 temp = (char *)realloc(temp,strlen(pkg->filename)+12);
688 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
692 snprintf(temp, (strlen(pkg->filename)+12), "Filename: %s\n", pkg->filename);
698 if (strcasecmp(field, "Installed-Size") == 0) {
700 temp = (char *)realloc(temp,strlen(pkg->installed_size)+17);
702 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
706 snprintf(temp, (strlen(pkg->installed_size)+17), "Installed-Size: %s\n", pkg->installed_size);
707 } else if (strcasecmp(field, "Installed-Time") == 0 && pkg->installed_time) {
708 temp = (char *)realloc(temp,29);
710 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
714 snprintf(temp, 29, "Installed-Time: %lu\n", pkg->installed_time);
720 /* Maintainer | MD5sum */
721 if (strcasecmp(field, "Maintainer") == 0) {
723 if (pkg->maintainer) {
724 temp = (char *)realloc(temp,strlen(pkg->maintainer)+14);
726 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
730 snprintf(temp, (strlen(pkg->maintainer)+14), "maintainer: %s\n", pkg->maintainer);
732 } else if (strcasecmp(field, "MD5sum") == 0) {
735 temp = (char *)realloc(temp,strlen(pkg->md5sum)+11);
737 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
741 snprintf(temp, (strlen(pkg->md5sum)+11), "MD5Sum: %s\n", pkg->md5sum);
744 goto UNKNOWN_FMT_FIELD;
750 if (strcasecmp(field, "Package") == 0) {
752 temp = (char *)realloc(temp,strlen(pkg->name)+11);
754 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
758 snprintf(temp, (strlen(pkg->name)+11), "Package: %s\n", pkg->name);
759 } else if (strcasecmp(field, "Priority") == 0) {
761 temp = (char *)realloc(temp,strlen(pkg->priority)+12);
763 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
767 snprintf(temp, (strlen(pkg->priority)+12), "Priority: %s\n", pkg->priority);
768 } else if (strcasecmp(field, "Provides") == 0) {
772 if (pkg->provides_count) {
773 /* Here we check if the opkg_internal_use_only is used, and we discard it.*/
774 for ( i=0; i < pkg->provides_count; i++ ){
775 if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) {
776 memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */
777 flag_provide_false = 1;
780 if ( !flag_provide_false || /* Pigi there is not my trick flag */
781 ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */
782 char provstr[LINE_LEN];
784 for(i = 0; i < pkg->provides_count; i++) {
785 len = len + (strlen(pkg->provides_str[i])+5);
787 temp = (char *)realloc(temp,len);
789 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
793 strncpy(temp, "Provides:", 12);
794 for(i = 0; i < pkg->provides_count; i++) {
795 if (strlen(pkg->provides_str[i])>0){;
796 snprintf(provstr, LINE_LEN, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]);
797 strncat(temp, provstr, strlen(provstr));
800 strncat(temp, "\n", strlen("\n"));
804 goto UNKNOWN_FMT_FIELD;
811 /* Replaces | Recommends*/
812 if (strcasecmp (field, "Replaces") == 0) {
813 if (pkg->replaces_count) {
814 char replstr[LINE_LEN];
816 for (i = 0; i < pkg->replaces_count; i++) {
817 len = len + (strlen(pkg->replaces_str[i])+5);
819 temp = (char *)realloc(temp,len);
821 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
825 strncpy(temp, "Replaces:", 12);
826 for (i = 0; i < pkg->replaces_count; i++) {
827 snprintf(replstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]);
828 strncat(temp, replstr, strlen(replstr));
830 strncat(temp, "\n", strlen("\n"));
832 } else if (strcasecmp (field, "Recommends") == 0) {
833 if (pkg->recommends_count) {
834 char recstr[LINE_LEN];
836 for(i = 0; i < pkg->recommends_count; i++) {
837 len = len + (strlen( pkg->recommends_str[i])+5);
839 temp = (char *)realloc(temp,len);
841 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
845 strncpy(temp, "Recommends:", 13);
846 for(i = 0; i < pkg->recommends_count; i++) {
847 snprintf(recstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->recommends_str[i]);
848 strncat(temp, recstr, strlen(recstr));
850 strncat(temp, "\n", strlen("\n"));
853 goto UNKNOWN_FMT_FIELD;
859 /* Section | Size | Source | Status | Suggests */
860 if (strcasecmp(field, "Section") == 0) {
863 temp = (char *)realloc(temp,strlen(pkg->section)+11);
865 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
869 snprintf(temp, (strlen(pkg->section)+11), "Section: %s\n", pkg->section);
871 } else if (strcasecmp(field, "Size") == 0) {
874 temp = (char *)realloc(temp,strlen(pkg->size)+8);
876 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
880 snprintf(temp, (strlen(pkg->size)+8), "Size: %s\n", pkg->size);
882 } else if (strcasecmp(field, "Source") == 0) {
885 temp = (char *)realloc(temp,strlen(pkg->source)+10);
887 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
891 snprintf(temp, (strlen(pkg->source)+10), "Source: %s\n", pkg->source);
893 } else if (strcasecmp(field, "Status") == 0) {
895 /* Benjamin Pineau note: we should avoid direct usage of
896 * strlen(arg) without keeping "arg" for later free()
898 char *pflag=pkg_state_flag_to_str(pkg->state_flag);
899 char *pstat=pkg_state_status_to_str(pkg->state_status);
900 char *pwant=pkg_state_want_to_str(pkg->state_want);
902 size_t sum_of_sizes = (size_t) ( strlen(pwant)+ strlen(pflag)+ strlen(pstat) + 12 );
903 temp = (char *)realloc(temp,sum_of_sizes);
905 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
909 snprintf(temp, sum_of_sizes , "Status: %s %s %s\n", pwant, pflag, pstat);
912 if(pstat) /* pfstat can be NULL if ENOMEM */
914 } else if (strcasecmp(field, "Suggests") == 0) {
915 if (pkg->suggests_count) {
917 char sugstr[LINE_LEN];
919 for(i = 0; i < pkg->suggests_count; i++) {
920 len = len + (strlen(pkg->suggests_str[i])+5);
922 temp = (char *)realloc(temp,len);
924 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
928 strncpy(temp, "Suggests:", 10);
929 for(i = 0; i < pkg->suggests_count; i++) {
930 snprintf(sugstr, LINE_LEN, "%s %s", i == 0 ? "" : ",", pkg->suggests_str[i]);
931 strncat(temp, sugstr, strlen(sugstr));
933 strncat(temp, "\n", strlen("\n"));
936 goto UNKNOWN_FMT_FIELD;
943 char *version = pkg_version_str_alloc(pkg);
944 temp = (char *)realloc(temp,strlen(version)+14);
946 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
950 snprintf(temp, (strlen(version)+12), "Version: %s\n", version);
955 goto UNKNOWN_FMT_FIELD;
958 if ( strlen(temp)<2 ) {
964 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n", __FUNCTION__, field);
965 if ( strlen(temp)<2 ) {
972 void pkg_print_info(pkg_t *pkg, FILE *file)
979 buff = pkg_formatted_info(pkg);
983 fwrite(buff, 1, strlen(buff), file);
988 void pkg_print_status(pkg_t * pkg, FILE * file)
994 /* XXX: QUESTION: Do we actually want more fields here? The
995 original idea was to save space by installing only what was
996 needed for actual computation, (package, version, status,
997 essential, conffiles). The assumption is that all other fields
998 can be found in th available file.
1000 But, someone proposed the idea to make it possible to
1001 reconstruct a .ipk from an installed package, (ie. for beaming
1002 from one handheld to another). So, maybe we actually want a few
1003 more fields here, (depends, suggests, etc.), so that that would
1004 be guaranteed to work even in the absence of more information
1005 from the available file.
1007 28-MAR-03: kergoth and I discussed this yesterday. We think
1008 the essential info needs to be here for all installed packages
1009 because they may not appear in the Packages files on various
1010 feeds. Furthermore, one should be able to install from URL or
1011 local storage without requiring a Packages file from any feed.
1014 pkg_print_field(pkg, file, "Package");
1015 pkg_print_field(pkg, file, "Version");
1016 pkg_print_field(pkg, file, "Depends");
1017 pkg_print_field(pkg, file, "Recommends");
1018 pkg_print_field(pkg, file, "Suggests");
1019 pkg_print_field(pkg, file, "Provides");
1020 pkg_print_field(pkg, file, "Replaces");
1021 pkg_print_field(pkg, file, "Conflicts");
1022 pkg_print_field(pkg, file, "Status");
1023 pkg_print_field(pkg, file, "Essential"); /* @@@@ should be removed in future release. */
1024 pkg_print_field(pkg, file, "Architecture");
1025 pkg_print_field(pkg, file, "Conffiles");
1026 pkg_print_field(pkg, file, "Installed-Time");
1027 pkg_print_field(pkg, file, "Auto-Installed");
1031 void pkg_print_field(pkg_t *pkg, FILE *file, const char *field)
1034 if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
1035 fprintf(stderr, "%s: ERROR: Unknown field name: %s\n",
1036 __FUNCTION__, field);
1038 buff = pkg_formatted_field(pkg, field);
1039 if (strlen(buff)>2) {
1040 fprintf(file, "%s", buff);
1048 * libdpkg - Debian packaging suite library routines
1049 * vercmp.c - comparison of version numbers
1051 * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
1053 int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg)
1057 if (pkg->epoch > ref_pkg->epoch) {
1061 if (pkg->epoch < ref_pkg->epoch) {
1065 r = verrevcmp(pkg->version, ref_pkg->version);
1070 r = verrevcmp(pkg->revision, ref_pkg->revision);
1078 /* assume ascii; warning: evaluates x multiple times! */
1079 #define order(x) ((x) == '~' ? -1 \
1080 : isdigit((x)) ? 0 \
1082 : isalpha((x)) ? (x) \
1085 static int verrevcmp(const char *val, const char *ref) {
1089 while (*val || *ref) {
1092 while ( (*val && !isdigit(*val)) || (*ref && !isdigit(*ref)) ) {
1093 int vc= order(*val), rc= order(*ref);
1094 if (vc != rc) return vc - rc;
1098 while ( *val == '0' ) val++;
1099 while ( *ref == '0' ) ref++;
1100 while (isdigit(*val) && isdigit(*ref)) {
1101 if (!first_diff) first_diff= *val - *ref;
1104 if (isdigit(*val)) return 1;
1105 if (isdigit(*ref)) return -1;
1106 if (first_diff) return first_diff;
1111 int pkg_version_satisfied(pkg_t *it, pkg_t *ref, const char *op)
1115 r = pkg_compare_versions(it, ref);
1117 if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
1121 if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
1125 if (strcmp(op, "<<") == 0) {
1129 if (strcmp(op, ">>") == 0) {
1133 if (strcmp(op, "=") == 0) {
1137 fprintf(stderr, "unknown operator: %s", op);
1141 int pkg_name_version_and_architecture_compare(void *p1, void *p2)
1143 const pkg_t *a = *(const pkg_t **)p1;
1144 const pkg_t *b = *(const pkg_t **)p2;
1147 if (!a->name || !b->name) {
1148 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->name=%p b=%p b->name=%p\n",
1149 a, a->name, b, b->name);
1153 namecmp = strcmp(a->name, b->name);
1156 vercmp = pkg_compare_versions(a, b);
1159 if (!a->arch_priority || !b->arch_priority) {
1160 fprintf(stderr, "pkg_name_version_and_architecture_compare: a=%p a->arch_priority=%i b=%p b->arch_priority=%i\n",
1161 a, a->arch_priority, b, b->arch_priority);
1164 if (a->arch_priority > b->arch_priority)
1166 if (a->arch_priority < b->arch_priority)
1171 int abstract_pkg_name_compare(void *p1, void *p2)
1173 const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
1174 const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
1175 if (!a->name || !b->name) {
1176 fprintf(stderr, "abstract_pkg_name_compare: a=%p a->name=%p b=%p b->name=%p\n",
1177 a, a->name, b, b->name);
1180 return strcmp(a->name, b->name);
1184 char *pkg_version_str_alloc(pkg_t *pkg)
1186 char *complete_version;
1191 sprintf_alloc(&epoch_str, "%d:", pkg->epoch);
1193 epoch_str = strdup("");
1196 if (pkg->revision && strlen(pkg->revision)) {
1197 sprintf_alloc(&revision_str, "-%s", pkg->revision);
1199 revision_str = strdup("");
1203 sprintf_alloc(&complete_version, "%s%s%s",
1204 epoch_str, pkg->version, revision_str);
1209 return complete_version;
1212 str_list_t *pkg_get_installed_files(pkg_t *pkg)
1215 char *list_file_name = NULL;
1216 FILE *list_file = NULL;
1218 char *installed_file_name;
1221 pkg->installed_files_ref_cnt++;
1223 if (pkg->installed_files) {
1224 return pkg->installed_files;
1227 pkg->installed_files = str_list_alloc();
1228 if (pkg->installed_files == NULL) {
1229 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1233 /* For uninstalled packages, get the file list firectly from the package.
1234 For installed packages, look at the package.list file in the database.
1236 if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) {
1237 if (pkg->local_filename == NULL) {
1238 return pkg->installed_files;
1240 /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
1241 file. In other words, change deb_extract so that it can
1242 simply return the file list as a char *[] rather than
1243 insisting on writing in to a FILE * as it does now. */
1244 list_file = tmpfile();
1245 err = pkg_extract_data_file_names_to_stream(pkg, list_file);
1248 fprintf(stderr, "%s: Error extracting file list from %s: %s\n",
1249 __FUNCTION__, pkg->local_filename, strerror(err));
1250 return pkg->installed_files;
1254 sprintf_alloc(&list_file_name, "%s/%s.list",
1255 pkg->dest->info_dir, pkg->name);
1256 if (! file_exists(list_file_name)) {
1257 free(list_file_name);
1258 return pkg->installed_files;
1261 list_file = fopen(list_file_name, "r");
1262 if (list_file == NULL) {
1263 fprintf(stderr, "WARNING: Cannot open %s: %s\n",
1264 list_file_name, strerror(errno));
1265 free(list_file_name);
1266 return pkg->installed_files;
1268 free(list_file_name);
1271 rootdirlen = strlen( pkg->dest->root_dir );
1275 line = file_read_line_alloc(list_file);
1282 /* Take pains to avoid uglies like "/./" in the middle of file_name. */
1283 if( strncmp( pkg->dest->root_dir,
1286 if (*file_name == '.') {
1289 if (*file_name == '/') {
1293 /* Freed in pkg_free_installed_files */
1294 sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name);
1296 // already contains root_dir as header -> ABSOLUTE
1297 sprintf_alloc(&installed_file_name, "%s", file_name);
1299 str_list_append(pkg->installed_files, installed_file_name);
1305 return pkg->installed_files;
1308 /* XXX: CLEANUP: This function and it's counterpart,
1309 (pkg_get_installed_files), do not match our init/deinit naming
1310 convention. Nor the alloc/free convention. But, then again, neither
1311 of these conventions currrently fit the way these two functions
1313 int pkg_free_installed_files(pkg_t *pkg)
1315 str_list_elt_t *iter;
1317 pkg->installed_files_ref_cnt--;
1318 if (pkg->installed_files_ref_cnt > 0) {
1322 if (pkg->installed_files) {
1324 for (iter = pkg->installed_files->head; iter; iter = iter->next) {
1325 /* malloced in pkg_get_installed_files */
1330 str_list_deinit(pkg->installed_files);
1333 pkg->installed_files = NULL;
1338 int pkg_remove_installed_files_list(opkg_conf_t *conf, pkg_t *pkg)
1341 char *list_file_name;
1343 //I don't think pkg_free_installed_files should be called here. Jamey
1344 //pkg_free_installed_files(pkg);
1346 sprintf_alloc(&list_file_name, "%s/%s.list",
1347 pkg->dest->info_dir, pkg->name);
1348 if (!conf->noaction) {
1349 err = unlink(list_file_name);
1350 free(list_file_name);
1359 conffile_t *pkg_get_conffile(pkg_t *pkg, const char *file_name)
1361 conffile_list_elt_t *iter;
1362 conffile_t *conffile;
1368 for (iter = pkg->conffiles.head; iter; iter = iter->next) {
1369 conffile = iter->data;
1371 if (strcmp(conffile->name, file_name) == 0) {
1379 int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg,
1380 const char *script, const char *args)
1386 /* XXX: FEATURE: When conf->offline_root is set, we should run the
1387 maintainer script within a chroot environment. */
1389 /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
1390 have scripts in pkg->tmp_unpack_dir. */
1391 if (pkg->state_status == SS_INSTALLED || pkg->state_status == SS_UNPACKED) {
1392 if (pkg->dest == NULL) {
1393 fprintf(stderr, "%s: ERROR: installed package %s has a NULL dest\n",
1394 __FUNCTION__, pkg->name);
1397 sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name, script);
1399 if (pkg->tmp_unpack_dir == NULL) {
1400 fprintf(stderr, "%s: ERROR: uninstalled package %s has a NULL tmp_unpack_dir\n",
1401 __FUNCTION__, pkg->name);
1404 sprintf_alloc(&path, "%s/%s", pkg->tmp_unpack_dir, script);
1407 opkg_message(conf, OPKG_INFO, "Running script %s\n", path);
1408 if (conf->noaction) return 0;
1410 /* XXX: CLEANUP: There must be a better way to handle maintainer
1411 scripts when running with offline_root mode and/or a dest other
1412 than '/'. I've been playing around with some clever chroot
1413 tricks and I might come up with something workable. */
1414 if (conf->offline_root) {
1415 setenv("OPKG_OFFLINE_ROOT", conf->offline_root, 1);
1419 pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir, 1);
1421 if (! file_exists(path)) {
1426 if (conf->offline_root) {
1427 fprintf(stderr, "(offline root mode: not running %s.%s)\n", pkg->name, script);
1432 sprintf_alloc(&cmd, "%s %s", path, args);
1439 fprintf(stderr, "%s script returned status %d\n", script, err);
1446 char *pkg_state_want_to_str(pkg_state_want_t sw)
1450 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1451 if (pkg_state_want_map[i].value == sw) {
1452 return strdup(pkg_state_want_map[i].str);
1456 fprintf(stderr, "%s: ERROR: Illegal value for state_want: %d\n",
1458 return strdup("<STATE_WANT_UNKNOWN>");
1461 pkg_state_want_t pkg_state_want_from_str(char *str)
1465 for (i=0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
1466 if (strcmp(str, pkg_state_want_map[i].str) == 0) {
1467 return pkg_state_want_map[i].value;
1471 fprintf(stderr, "%s: ERROR: Illegal value for state_want string: %s\n",
1476 char *pkg_state_flag_to_str(pkg_state_flag_t sf)
1479 int len = 3; /* ok\000 is minimum */
1482 /* clear the temporary flags before converting to string */
1483 sf &= SF_NONVOLATILE_FLAGS;
1486 return strdup("ok");
1489 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1490 if (sf & pkg_state_flag_map[i].value) {
1491 len += strlen(pkg_state_flag_map[i].str) + 1;
1495 if ( str == NULL ) {
1496 fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
1500 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1501 if (sf & pkg_state_flag_map[i].value) {
1502 strcat(str, pkg_state_flag_map[i].str);
1507 str[len-1] = 0; /* squash last comma */
1512 pkg_state_flag_t pkg_state_flag_from_str(const char *str)
1517 if (strcmp(str, "ok") == 0) {
1520 for (i=0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
1521 const char *sfname = pkg_state_flag_map[i].str;
1522 int sfname_len = strlen(sfname);
1523 if (strncmp(str, sfname, sfname_len) == 0) {
1524 sf |= pkg_state_flag_map[i].value;
1526 if (str[0] == ',') {
1537 char *pkg_state_status_to_str(pkg_state_status_t ss)
1541 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1542 if (pkg_state_status_map[i].value == ss) {
1543 return strdup(pkg_state_status_map[i].str);
1547 fprintf(stderr, "%s: ERROR: Illegal value for state_status: %d\n",
1549 return strdup("<STATE_STATUS_UNKNOWN>");
1552 pkg_state_status_t pkg_state_status_from_str(const char *str)
1556 for (i=0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
1557 if (strcmp(str, pkg_state_status_map[i].str) == 0) {
1558 return pkg_state_status_map[i].value;
1562 fprintf(stderr, "%s: ERROR: Illegal value for state_status string: %s\n",
1564 return SS_NOT_INSTALLED;
1567 int pkg_arch_supported(opkg_conf_t *conf, pkg_t *pkg)
1569 nv_pair_list_elt_t *l;
1571 if (!pkg->architecture)
1574 l = conf->arch_list.head;
1577 nv_pair_t *nv = l->data;
1578 if (strcmp(nv->name, pkg->architecture) == 0) {
1579 opkg_message(conf, OPKG_DEBUG, "arch %s (priority %s) supported for pkg %s\n", nv->name, nv->value, pkg->name);
1585 opkg_message(conf, OPKG_DEBUG, "arch %s unsupported for pkg %s\n", pkg->architecture, pkg->name);
1589 int pkg_get_arch_priority(opkg_conf_t *conf, const char *archname)
1591 nv_pair_list_elt_t *l;
1593 l = conf->arch_list.head;
1596 nv_pair_t *nv = l->data;
1597 if (strcmp(nv->name, archname) == 0) {
1598 int priority = strtol(nv->value, NULL, 0);
1606 int pkg_info_preinstall_check(opkg_conf_t *conf)
1609 hash_table_t *pkg_hash = &conf->pkg_hash;
1610 pkg_vec_t *available_pkgs = pkg_vec_alloc();
1611 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1613 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: updating arch priority for each package\n");
1614 pkg_hash_fetch_available(pkg_hash, available_pkgs);
1615 /* update arch_priority for each package */
1616 for (i = 0; i < available_pkgs->len; i++) {
1617 pkg_t *pkg = available_pkgs->pkgs[i];
1618 int arch_priority = 1;
1621 // opkg_message(conf, OPKG_DEBUG2, " package %s version=%s arch=%p:", pkg->name, pkg->version, pkg->architecture);
1622 if (pkg->architecture)
1623 arch_priority = pkg_get_arch_priority(conf, pkg->architecture);
1625 opkg_message(conf, OPKG_ERROR, "pkg_info_preinstall_check: no architecture for package %s\n", pkg->name);
1626 // opkg_message(conf, OPKG_DEBUG2, "%s arch_priority=%d\n", pkg->architecture, arch_priority);
1627 pkg->arch_priority = arch_priority;
1630 for (i = 0; i < available_pkgs->len; i++) {
1631 pkg_t *pkg = available_pkgs->pkgs[i];
1632 if (!pkg->arch_priority && (pkg->state_flag || (pkg->state_want != SW_UNKNOWN))) {
1633 /* clear flags and want for any uninstallable package */
1634 opkg_message(conf, OPKG_NOTICE, "Clearing state_want and state_flag for pkg=%s (arch_priority=%d flag=%d want=%d)\n",
1635 pkg->name, pkg->arch_priority, pkg->state_flag, pkg->state_want);
1636 pkg->state_want = SW_UNKNOWN;
1637 pkg->state_flag = 0;
1640 pkg_vec_free(available_pkgs);
1642 /* update the file owner data structure */
1643 opkg_message(conf, OPKG_INFO, "pkg_info_preinstall_check: update file owner list\n");
1644 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1645 for (i = 0; i < installed_pkgs->len; i++) {
1646 pkg_t *pkg = installed_pkgs->pkgs[i];
1647 str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
1648 str_list_elt_t *iter;
1649 if (installed_files == NULL) {
1650 opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);
1653 for (iter = installed_files->head; iter; iter = iter->next) {
1654 char *installed_file = iter->data;
1655 // opkg_message(conf, OPKG_DEBUG2, "pkg %s: file=%s\n", pkg->name, installed_file);
1656 file_hash_set_file_owner(conf, installed_file, pkg);
1659 pkg_vec_free(installed_pkgs);
1664 struct pkg_write_filelist_data {
1670 void pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
1672 struct pkg_write_filelist_data *data = data_;
1673 pkg_t *entry = entry_;
1674 if (entry == data->pkg) {
1675 fprintf(data->stream, "%s\n", key);
1679 int pkg_write_filelist(opkg_conf_t *conf, pkg_t *pkg)
1681 struct pkg_write_filelist_data data;
1682 char *list_file_name = NULL;
1686 opkg_message(conf, OPKG_ERROR, "Null pkg\n");
1689 opkg_message(conf, OPKG_INFO,
1690 " creating %s.list file\n", pkg->name);
1691 sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name);
1692 if (!list_file_name) {
1693 opkg_message(conf, OPKG_ERROR, "Failed to alloc list_file_name\n");
1696 opkg_message(conf, OPKG_INFO,
1697 " creating %s file for pkg %s\n", list_file_name, pkg->name);
1698 data.stream = fopen(list_file_name, "w");
1700 opkg_message(conf, OPKG_ERROR, "Could not open %s for writing: %s\n",
1701 list_file_name, strerror(errno));
1706 hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
1707 fclose(data.stream);
1708 free(list_file_name);
1713 int pkg_write_changed_filelists(opkg_conf_t *conf)
1715 pkg_vec_t *installed_pkgs = pkg_vec_alloc();
1716 hash_table_t *pkg_hash = &conf->pkg_hash;
1722 opkg_message(conf, OPKG_INFO, "%s: saving changed filelists\n", __FUNCTION__);
1723 pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs);
1724 for (i = 0; i < installed_pkgs->len; i++) {
1725 pkg_t *pkg = installed_pkgs->pkgs[i];
1726 if (pkg->state_flag & SF_FILELIST_CHANGED) {
1727 opkg_message(conf, OPKG_DEBUG, "Calling pkg_write_filelist for pkg=%s from %s\n", pkg->name, __FUNCTION__);
1728 err = pkg_write_filelist(conf, pkg);
1730 opkg_message(conf, OPKG_NOTICE, "pkg_write_filelist pkg=%s returned %d\n", pkg->name, err);