• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/opkg-lede/libopkg/pkg_hash.c

  1 /* opkg_hash.c - the opkg package management system
  2 
  3    Steven M. Ayer
  4 
  5    Copyright (C) 2002 Compaq Computer Corporation
  6 
  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.
 11 
 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.
 16 */
 17 
 18 #include <stdio.h>
 19 
 20 #include "hash_table.h"
 21 #include "pkg.h"
 22 #include "opkg_message.h"
 23 #include "pkg_depends.h"
 24 #include "pkg_vec.h"
 25 #include "pkg_hash.h"
 26 #include "parse_util.h"
 27 #include "pkg_parse.h"
 28 #include "opkg_utils.h"
 29 #include "opkg_cmd.h"
 30 #include "sprintf_alloc.h"
 31 #include "file_util.h"
 32 #include "libbb/libbb.h"
 33 #include "libbb/gzip.h"
 34 
 35 void pkg_hash_init(void)
 36 {
 37         hash_table_init("pkg-hash", &conf->pkg_hash,
 38                         OPKG_CONF_DEFAULT_HASH_LEN);
 39 }
 40 
 41 static void free_pkgs(const char *key, void *entry, void *data)
 42 {
 43         int i;
 44         abstract_pkg_t *ab_pkg;
 45 
 46         /* Each entry in the hash table is an abstract package, which contains
 47          * a list of packages that provide the abstract package.
 48          */
 49 
 50         ab_pkg = (abstract_pkg_t *) entry;
 51 
 52         if (ab_pkg->pkgs) {
 53                 for (i = 0; i < ab_pkg->pkgs->len; i++) {
 54                         pkg_deinit(ab_pkg->pkgs->pkgs[i]);
 55                         free(ab_pkg->pkgs->pkgs[i]);
 56                 }
 57         }
 58 
 59         abstract_pkg_vec_free(ab_pkg->provided_by);
 60         abstract_pkg_vec_free(ab_pkg->replaced_by);
 61         pkg_vec_free(ab_pkg->pkgs);
 62         free(ab_pkg->depended_upon_by);
 63         free(ab_pkg->name);
 64         free(ab_pkg);
 65 }
 66 
 67 void pkg_hash_deinit(void)
 68 {
 69         hash_table_foreach(&conf->pkg_hash, free_pkgs, NULL);
 70         hash_table_deinit(&conf->pkg_hash);
 71 }
 72 
 73 int
 74 pkg_hash_add_from_file(const char *file_name,
 75                        pkg_src_t * src, pkg_dest_t * dest, int is_status_file, int state_flags,
 76                        void (*cb)(pkg_t *, void *), void *priv)
 77 {
 78         pkg_t *pkg;
 79         FILE *fp;
 80         char *buf;
 81         const size_t len = 4096;
 82         int ret = 0;
 83         struct gzip_handle zh;
 84 
 85         if (src && src->gzip) {
 86                 fp = gzip_fdopen(&zh, file_name);
 87         } else {
 88                 fp = fopen(file_name, "r");
 89         }
 90 
 91         if (fp == NULL) {
 92                 opkg_perror(ERROR, "Failed to open %s", file_name);
 93                 return -1;
 94         }
 95 
 96         buf = xmalloc(len);
 97 
 98         do {
 99                 pkg = pkg_new();
100                 pkg->src = src;
101                 pkg->dest = dest;
102                 pkg->state_flag |= state_flags;
103 
104                 ret = parse_from_stream_nomalloc(pkg_parse_line, pkg, fp, 0,
105                                                  &buf, len);
106 
107                 if (pkg->name == NULL) {
108                         /* probably just a blank line */
109                         ret = 1;
110                 }
111 
112                 if (ret) {
113                         pkg_deinit(pkg);
114                         free(pkg);
115                         if (ret == -1)
116                                 break;
117                         if (ret == 1)
118                                 /* Probably a blank line, continue parsing. */
119                                 ret = 0;
120                         continue;
121                 }
122 
123                 if (!(pkg->state_flag & SF_NEED_DETAIL)) {
124                         //opkg_msg(DEBUG, "Package %s is unrelated, ignoring.\n", pkg->name);
125                         pkg_deinit(pkg);
126                         free(pkg);
127                         continue;
128                 }
129 
130                 if (!pkg_get_architecture(pkg) || !pkg_get_arch_priority(pkg)) {
131                         char *version_str = pkg_version_str_alloc(pkg);
132                         opkg_msg(NOTICE, "Package %s version %s has no "
133                                  "valid architecture, ignoring.\n",
134                                  pkg->name, version_str);
135                         free(version_str);
136                         continue;
137                 }
138 
139                 if (cb)
140                         cb(pkg, priv);
141                 else
142                         hash_insert_pkg(pkg, is_status_file);
143 
144         } while (!feof(fp));
145 
146         free(buf);
147         fclose(fp);
148 
149         if (src && src->gzip)
150                 gzip_close(&zh);
151 
152         return ret;
153 }
154 
155 /*
156  * Load in feed files from the cached "src" and/or "src/gz" locations.
157  */
158 int pkg_hash_load_feeds(int state_flags, void (*cb)(pkg_t *, void *), void *priv)
159 {
160         pkg_src_list_elt_t *iter;
161         pkg_src_t *src;
162         char *list_file, *lists_dir;
163 
164         opkg_msg(INFO, "\n");
165 
166         lists_dir = conf->restrict_to_default_dest ?
167             conf->default_dest->lists_dir : conf->lists_dir;
168 
169         for (iter = void_list_first(&conf->pkg_src_list); iter;
170              iter = void_list_next(&conf->pkg_src_list, iter)) {
171 
172                 src = (pkg_src_t *) iter->data;
173 
174                 sprintf_alloc(&list_file, "%s/%s", lists_dir, src->name);
175 
176                 if (file_exists(list_file)) {
177                         if (pkg_hash_add_from_file(list_file, src, NULL, 0, state_flags, cb, priv)) {
178                                 free(list_file);
179                                 return -1;
180                         }
181                 }
182                 free(list_file);
183         }
184 
185         return 0;
186 }
187 
188 /*
189  * Load in status files from the configured "dest"s.
190  */
191 int pkg_hash_load_status_files(void (*cb)(pkg_t *, void *), void *priv)
192 {
193         pkg_dest_list_elt_t *iter;
194         pkg_dest_t *dest;
195 
196         opkg_msg(INFO, "\n");
197 
198         for (iter = void_list_first(&conf->pkg_dest_list); iter;
199              iter = void_list_next(&conf->pkg_dest_list, iter)) {
200 
201                 dest = (pkg_dest_t *) iter->data;
202 
203                 if (file_exists(dest->status_file_name)) {
204                         if (pkg_hash_add_from_file
205                             (dest->status_file_name, NULL, dest, 1, SF_NEED_DETAIL, cb, priv))
206                                 return -1;
207                 }
208         }
209 
210         return 0;
211 }
212 
213 static void
214 pkg_hash_load_package_details_helper(const char *pkg_name, void *entry, void *data)
215 {
216         int *count = data;
217         abstract_pkg_t *ab_pkg = (abstract_pkg_t *) entry;
218 
219         if (ab_pkg->state_flag & SF_NEED_DETAIL) {
220                 if (ab_pkg->state_flag & SF_MARKED) {
221                         opkg_msg(DEBUG, "skipping already seen flagged abpkg %s\n",
222                                  ab_pkg->name);
223                         return;
224                 }
225 
226                 opkg_msg(DEBUG, "found yet incomplete flagged abpkg %s\n",
227                          ab_pkg->name);
228 
229                 (*count)++;
230                 ab_pkg->state_flag |= SF_MARKED;
231         }
232 }
233 
234 int pkg_hash_load_package_details(void)
235 {
236         int n_need_detail;
237 
238         while (1) {
239                 pkg_hash_load_feeds(0, NULL, NULL);
240 
241                 n_need_detail = 0;
242                 hash_table_foreach(&conf->pkg_hash, pkg_hash_load_package_details_helper, &n_need_detail);
243 
244                 if (n_need_detail > 0)
245                         opkg_msg(DEBUG, "Found %d packages requiring details, reloading feeds\n", n_need_detail);
246                 else
247                         break;
248         }
249 
250         return 0;
251 }
252 
253 static int
254 pkg_hash_check_unresolved(pkg_t *maybe)
255 {
256         char **unresolved = NULL;
257         char **tmp;
258         pkg_vec_t *depends;
259         int res = 0;
260 
261         depends = pkg_vec_alloc();
262         pkg_hash_fetch_unsatisfied_dependencies(maybe, depends, &unresolved, 1);
263 
264         if (unresolved) {
265                 res = 1;
266                 tmp = unresolved;
267                 while (*tmp) {
268                         opkg_msg(ERROR, "cannot find dependency %s for %s\n", *tmp, maybe->name);
269                         free(*(tmp++));
270                 }
271                 free(unresolved);
272         }
273         pkg_vec_free(depends);
274 
275         return res;
276 }
277 
278 pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg,
279                                                   int (*constraint_fcn) (pkg_t *
280                                                                          pkg,
281                                                                          void
282                                                                          *cdata),
283                                                   void *cdata, int quiet)
284 {
285         int i, j;
286         int nprovides = 0;
287         int nmatching = 0;
288         int wrong_arch_found = 0;
289         int arch_priority;
290         int good_pkg_score = 0;
291         pkg_vec_t *matching_pkgs;
292         abstract_pkg_vec_t *matching_apkgs;
293         abstract_pkg_vec_t *provided_apkg_vec;
294         abstract_pkg_t **provided_apkgs;
295         abstract_pkg_vec_t *providers;
296         pkg_t *latest_installed_parent = NULL;
297         pkg_t *latest_matching = NULL;
298         pkg_t *priorized_matching = NULL;
299         pkg_t *held_pkg = NULL;
300         pkg_t *good_pkg_by_name = NULL;
301 
302         if (apkg == NULL || apkg->provided_by == NULL
303             || (apkg->provided_by->len == 0))
304                 return NULL;
305 
306         matching_pkgs = pkg_vec_alloc();
307         matching_apkgs = abstract_pkg_vec_alloc();
308         providers = abstract_pkg_vec_alloc();
309 
310         opkg_msg(DEBUG, "Best installation candidate for %s:\n", apkg->name);
311 
312         provided_apkg_vec = apkg->provided_by;
313         nprovides = provided_apkg_vec->len;
314         provided_apkgs = provided_apkg_vec->pkgs;
315         if (nprovides > 1)
316                 opkg_msg(DEBUG, "apkg=%s nprovides=%d.\n", apkg->name,
317                          nprovides);
318 
319         /* accumulate all the providers */
320         for (i = 0; i < nprovides; i++) {
321                 abstract_pkg_t *provider_apkg = provided_apkgs[i];
322                 opkg_msg(DEBUG, "Adding %s to providers.\n",
323                          provider_apkg->name);
324                 abstract_pkg_vec_insert(providers, provider_apkg);
325         }
326         nprovides = providers->len;
327 
328         for (i = 0; i < nprovides; i++) {
329                 abstract_pkg_t *provider_apkg =
330                     abstract_pkg_vec_get(providers, i);
331                 abstract_pkg_t *replacement_apkg = NULL;
332                 pkg_vec_t *vec;
333 
334                 if (provider_apkg->replaced_by
335                     && provider_apkg->replaced_by->len) {
336                         replacement_apkg = provider_apkg->replaced_by->pkgs[0];
337                         if (provider_apkg->replaced_by->len > 1) {
338                                 opkg_msg(NOTICE, "Multiple replacers for %s, "
339                                          "using first one (%s).\n",
340                                          provider_apkg->name,
341                                          replacement_apkg->name);
342                         }
343                 }
344 
345                 if (replacement_apkg)
346                         opkg_msg(DEBUG,
347                                  "replacement_apkg=%s for provider_apkg=%s.\n",
348                                  replacement_apkg->name, provider_apkg->name);
349 
350                 if (replacement_apkg && (replacement_apkg != provider_apkg)) {
351                         if (abstract_pkg_vec_contains
352                             (providers, replacement_apkg))
353                                 continue;
354                         else
355                                 provider_apkg = replacement_apkg;
356                 }
357 
358                 if (!(vec = provider_apkg->pkgs)) {
359                         opkg_msg(DEBUG, "No pkgs for provider_apkg %s.\n",
360                                  provider_apkg->name);
361                         continue;
362                 }
363 
364                 /* now check for supported architecture */
365                 {
366                         int max_count = 0;
367 
368                         /* count packages matching max arch priority and keep track of last one */
369                         for (j = 0; j < vec->len; j++) {
370                                 pkg_t *maybe = vec->pkgs[j];
371                                 arch_priority = pkg_get_arch_priority(maybe);
372 
373                                 opkg_msg(DEBUG,
374                                          "%s arch=%s arch_priority=%d version=%s.\n",
375                                          maybe->name, pkg_get_architecture(maybe),
376                                          arch_priority, pkg_get_string(maybe, PKG_VERSION));
377                                 /* We make sure not to add the same package twice. Need to search for the reason why
378                                    they show up twice sometimes. */
379                                 if ((arch_priority > 0)
380                                     &&
381                                     (!pkg_vec_contains(matching_pkgs, maybe))) {
382                                         if (!pkg_hash_check_unresolved(maybe)) {
383                                                 max_count++;
384                                                 abstract_pkg_vec_insert(matching_apkgs,
385                                                                         maybe->parent);
386                                                 pkg_vec_insert(matching_pkgs, maybe);
387                                         }
388                                 }
389                         }
390 
391                         if (vec->len > 0 && matching_pkgs->len < 1)
392                                 wrong_arch_found = 1;
393                 }
394         }
395 
396         if (matching_pkgs->len < 1) {
397                 if (wrong_arch_found)
398                         opkg_msg(ERROR, "Packages for %s found, but"
399                                  " incompatible with the architectures configured\n",
400                                  apkg->name);
401                 pkg_vec_free(matching_pkgs);
402                 abstract_pkg_vec_free(matching_apkgs);
403                 abstract_pkg_vec_free(providers);
404                 return NULL;
405         }
406 
407         if (matching_pkgs->len > 1)
408                 pkg_vec_sort(matching_pkgs,
409                              pkg_name_version_and_architecture_compare);
410         if (matching_apkgs->len > 1)
411                 abstract_pkg_vec_sort(matching_apkgs, abstract_pkg_name_compare);
412 
413         for (i = 0; i < matching_pkgs->len; i++) {
414                 pkg_t *matching = matching_pkgs->pkgs[i];
415                 if (constraint_fcn(matching, cdata)) {
416                         int score = 1;
417                         if (strcmp(matching->name, apkg->name) == 0)
418                                 score++;
419 
420                         for (j = 0; j < opkg_cli_argc; ++j) {
421                                 if (!strcmp(matching->name, opkg_cli_argv[j])) {
422                                         score++;
423                                         break;
424                                 }
425                         }
426 
427                         opkg_msg(DEBUG, "Candidate: %s %s (score %d).\n",
428                                  matching->name, pkg_get_string(matching, PKG_VERSION),
429                                  score);
430                         if (score < good_pkg_score)
431                                 continue;
432 
433                         good_pkg_by_name = matching;
434                         good_pkg_score = score;
435                         /* It has been provided by hand, so it is what user want */
436                         if (matching->provided_by_hand == 1)
437                                 break;
438                 }
439         }
440 
441         for (i = 0; i < matching_pkgs->len; i++) {
442                 pkg_t *matching = matching_pkgs->pkgs[i];
443                 latest_matching = matching;
444                 if (matching->parent->state_status == SS_INSTALLED
445                     || matching->parent->state_status == SS_UNPACKED)
446                         latest_installed_parent = matching;
447                 if (matching->state_flag & (SF_HOLD | SF_PREFER)) {
448                         if (held_pkg)
449                                 opkg_msg(NOTICE,
450                                          "Multiple packages (%s and %s) providing"
451                                          " same name marked HOLD or PREFER. "
452                                          "Using latest.\n", held_pkg->name,
453                                          matching->name);
454                         held_pkg = matching;
455                 }
456         }
457 
458         if (!good_pkg_by_name && !held_pkg && !latest_installed_parent
459             && matching_apkgs->len > 1 && !quiet) {
460                 int prio = 0;
461                 for (i = 0; i < matching_pkgs->len; i++) {
462                         pkg_t *matching = matching_pkgs->pkgs[i];
463                         arch_priority = pkg_get_arch_priority(matching);
464                         if (arch_priority > prio) {
465                                 priorized_matching = matching;
466                                 prio = arch_priority;
467                                 opkg_msg(DEBUG, "Match %s with priority %i.\n",
468                                          matching->name, prio);
469                         }
470                 }
471 
472         }
473 
474         if (conf->verbosity >= INFO && matching_apkgs->len > 1) {
475                 opkg_msg(INFO, "%d matching pkgs for apkg=%s:\n",
476                          matching_pkgs->len, apkg->name);
477                 for (i = 0; i < matching_pkgs->len; i++) {
478                         pkg_t *matching = matching_pkgs->pkgs[i];
479                         opkg_msg(INFO, "%s %s %s\n",
480                                  matching->name, pkg_get_string(matching, PKG_VERSION),
481                                  pkg_get_architecture(matching));
482                 }
483         }
484 
485         nmatching = matching_apkgs->len;
486 
487         pkg_vec_free(matching_pkgs);
488         abstract_pkg_vec_free(matching_apkgs);
489         abstract_pkg_vec_free(providers);
490 
491         if (good_pkg_by_name) { /* We found a good candidate, we will install it */
492                 return good_pkg_by_name;
493         }
494         if (held_pkg) {
495                 opkg_msg(INFO, "Using held package %s.\n", held_pkg->name);
496                 return held_pkg;
497         }
498         if (latest_installed_parent) {
499                 opkg_msg(INFO,
500                          "Using latest version of installed package %s.\n",
501                          latest_installed_parent->name);
502                 return latest_installed_parent;
503         }
504         if (priorized_matching) {
505                 opkg_msg(INFO, "Using priorized matching %s %s %s.\n",
506                          priorized_matching->name, pkg_get_string(priorized_matching, PKG_VERSION),
507                          pkg_get_architecture(priorized_matching));
508                 return priorized_matching;
509         }
510         if (nmatching > 1) {
511                 opkg_msg(INFO, "No matching pkg out of %d matching_apkgs.\n",
512                          nmatching);
513                 return NULL;
514         }
515         if (latest_matching) {
516                 opkg_msg(INFO, "Using latest matching %s %s %s.\n",
517                          latest_matching->name, pkg_get_string(latest_matching, PKG_VERSION),
518                          pkg_get_architecture(latest_matching));
519                 return latest_matching;
520         }
521         return NULL;
522 }
523 
524 static int pkg_name_constraint_fcn(pkg_t * pkg, void *cdata)
525 {
526         const char *name = (const char *)cdata;
527 
528         if (strcmp(pkg->name, name) == 0)
529                 return 1;
530         else
531                 return 0;
532 }
533 
534 static pkg_vec_t *pkg_vec_fetch_by_name(const char *pkg_name)
535 {
536         abstract_pkg_t *ab_pkg;
537 
538         if (!(ab_pkg = abstract_pkg_fetch_by_name(pkg_name)))
539                 return NULL;
540 
541         if (ab_pkg->pkgs)
542                 return ab_pkg->pkgs;
543 
544         if (ab_pkg->provided_by) {
545                 abstract_pkg_t *abpkg =
546                     abstract_pkg_vec_get(ab_pkg->provided_by, 0);
547                 if (abpkg != NULL)
548                         return abpkg->pkgs;
549                 else
550                         return ab_pkg->pkgs;
551         }
552 
553         return NULL;
554 }
555 
556 pkg_t *pkg_hash_fetch_best_installation_candidate_by_name(const char *name)
557 {
558         abstract_pkg_t *apkg = NULL;
559 
560         if (!(apkg = abstract_pkg_fetch_by_name(name)))
561                 return NULL;
562 
563         return pkg_hash_fetch_best_installation_candidate(apkg,
564                                                           pkg_name_constraint_fcn,
565                                                           apkg->name, 0);
566 }
567 
568 pkg_t *pkg_hash_fetch_by_name_version(const char *pkg_name, const char *version)
569 {
570         pkg_vec_t *vec;
571         int i;
572         char *version_str = NULL;
573 
574         if (!(vec = pkg_vec_fetch_by_name(pkg_name)))
575                 return NULL;
576 
577         for (i = 0; i < vec->len; i++) {
578                 version_str = pkg_version_str_alloc(vec->pkgs[i]);
579                 if (!strcmp(version_str, version)) {
580                         free(version_str);
581                         break;
582                 }
583                 free(version_str);
584         }
585 
586         if (i == vec->len)
587                 return NULL;
588 
589         return vec->pkgs[i];
590 }
591 
592 pkg_t *pkg_hash_fetch_installed_by_name_dest(const char *pkg_name,
593                                              pkg_dest_t * dest)
594 {
595         pkg_vec_t *vec;
596         int i;
597 
598         if (!(vec = pkg_vec_fetch_by_name(pkg_name))) {
599                 return NULL;
600         }
601 
602         for (i = 0; i < vec->len; i++)
603                 if ((vec->pkgs[i]->state_status == SS_INSTALLED
604                      || vec->pkgs[i]->state_status == SS_UNPACKED)
605                     && vec->pkgs[i]->dest == dest) {
606                         return vec->pkgs[i];
607                 }
608 
609         return NULL;
610 }
611 
612 pkg_t *pkg_hash_fetch_installed_by_name(const char *pkg_name)
613 {
614         pkg_vec_t *vec;
615         int i;
616 
617         if (!(vec = pkg_vec_fetch_by_name(pkg_name))) {
618                 return NULL;
619         }
620 
621         for (i = 0; i < vec->len; i++) {
622                 if (vec->pkgs[i]->state_status == SS_INSTALLED
623                     || vec->pkgs[i]->state_status == SS_UNPACKED) {
624                         return vec->pkgs[i];
625                 }
626         }
627 
628         return NULL;
629 }
630 
631 static void
632 pkg_hash_fetch_available_helper(const char *pkg_name, void *entry, void *data)
633 {
634         int j;
635         abstract_pkg_t *ab_pkg = (abstract_pkg_t *) entry;
636         pkg_vec_t *all = (pkg_vec_t *) data;
637         pkg_vec_t *pkg_vec = ab_pkg->pkgs;
638 
639         if (!pkg_vec)
640                 return;
641 
642         for (j = 0; j < pkg_vec->len; j++) {
643                 pkg_t *pkg = pkg_vec->pkgs[j];
644                 pkg_vec_insert(all, pkg);
645         }
646 }
647 
648 void pkg_hash_fetch_available(pkg_vec_t * all)
649 {
650         hash_table_foreach(&conf->pkg_hash, pkg_hash_fetch_available_helper,
651                            all);
652 }
653 
654 static void
655 pkg_hash_fetch_all_installed_helper(const char *pkg_name, void *entry,
656                                     void *data)
657 {
658         abstract_pkg_t *ab_pkg = (abstract_pkg_t *) entry;
659         pkg_vec_t *all = (pkg_vec_t *) data;
660         pkg_vec_t *pkg_vec = ab_pkg->pkgs;
661         int j;
662 
663         if (!pkg_vec)
664                 return;
665 
666         for (j = 0; j < pkg_vec->len; j++) {
667                 pkg_t *pkg = pkg_vec->pkgs[j];
668                 if (pkg->state_status == SS_INSTALLED
669                     || pkg->state_status == SS_UNPACKED)
670                         pkg_vec_insert(all, pkg);
671         }
672 }
673 
674 void pkg_hash_fetch_all_installed(pkg_vec_t * all)
675 {
676         hash_table_foreach(&conf->pkg_hash, pkg_hash_fetch_all_installed_helper,
677                            all);
678 }
679 
680 /*
681  * This assumes that the abstract pkg doesn't exist.
682  */
683 static abstract_pkg_t *add_new_abstract_pkg_by_name(const char *pkg_name)
684 {
685         abstract_pkg_t *ab_pkg;
686 
687         ab_pkg = abstract_pkg_new();
688 
689         ab_pkg->name = xstrdup(pkg_name);
690         hash_table_insert(&conf->pkg_hash, pkg_name, ab_pkg);
691 
692         return ab_pkg;
693 }
694 
695 abstract_pkg_t *ensure_abstract_pkg_by_name(const char *pkg_name)
696 {
697         abstract_pkg_t *ab_pkg;
698 
699         if (!(ab_pkg = abstract_pkg_fetch_by_name(pkg_name)))
700                 ab_pkg = add_new_abstract_pkg_by_name(pkg_name);
701 
702         return ab_pkg;
703 }
704 
705 void hash_insert_pkg(pkg_t * pkg, int set_status)
706 {
707         abstract_pkg_t *ab_pkg;
708 
709         ab_pkg = ensure_abstract_pkg_by_name(pkg->name);
710         if (!ab_pkg->pkgs)
711                 ab_pkg->pkgs = pkg_vec_alloc();
712 
713         if (pkg->state_status == SS_INSTALLED) {
714                 ab_pkg->state_status = SS_INSTALLED;
715         } else if (pkg->state_status == SS_UNPACKED) {
716                 ab_pkg->state_status = SS_UNPACKED;
717         }
718 
719         buildDepends(pkg);
720 
721         buildProvides(ab_pkg, pkg);
722 
723         init_providelist(pkg, NULL);
724 
725         /* Need to build the conflicts graph before replaces for correct
726          * calculation of replaced_by relation.
727          */
728         buildConflicts(pkg);
729 
730         buildReplaces(ab_pkg, pkg);
731 
732         buildDependedUponBy(pkg, ab_pkg);
733 
734         pkg_vec_insert_merge(ab_pkg->pkgs, pkg, set_status);
735         pkg->parent = ab_pkg;
736 }
737 
738 static const char *strip_offline_root(const char *file_name)
739 {
740         unsigned int len;
741 
742         if (conf->offline_root) {
743                 len = strlen(conf->offline_root);
744                 if (strncmp(file_name, conf->offline_root, len) == 0)
745                         file_name += len;
746         }
747 
748         return file_name;
749 }
750 
751 void file_hash_remove(const char *file_name)
752 {
753         file_name = strip_offline_root(file_name);
754         hash_table_remove(&conf->file_hash, file_name);
755 }
756 
757 pkg_t *file_hash_get_file_owner(const char *file_name)
758 {
759         file_name = strip_offline_root(file_name);
760         return hash_table_get(&conf->file_hash, file_name);
761 }
762 
763 void file_hash_set_file_owner(const char *file_name, pkg_t * owning_pkg)
764 {
765         pkg_t *old_owning_pkg;
766         int file_name_len = strlen(file_name);
767 
768         if (file_name[file_name_len - 1] == '/')
769                 return;
770 
771         file_name = strip_offline_root(file_name);
772 
773         old_owning_pkg = hash_table_get(&conf->file_hash, file_name);
774         hash_table_insert(&conf->file_hash, file_name, owning_pkg);
775 
776         if (old_owning_pkg) {
777                 pkg_get_installed_files(old_owning_pkg);
778                 str_list_remove_elt(old_owning_pkg->installed_files, file_name);
779                 pkg_free_installed_files(old_owning_pkg);
780 
781                 /* mark this package to have its filelist written */
782                 old_owning_pkg->state_flag |= SF_FILELIST_CHANGED;
783                 owning_pkg->state_flag |= SF_FILELIST_CHANGED;
784         }
785 }
786 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt