pkg_depends.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102
  1. /* pkg_depends.c - the opkg package management system
  2. Steven M. Ayer
  3. Copyright (C) 2002 Compaq Computer Corporation
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License as
  6. published by the Free Software Foundation; either version 2, or (at
  7. your option) any later version.
  8. This program is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. */
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include "pkg.h"
  16. #include "opkg_utils.h"
  17. #include "pkg_hash.h"
  18. #include "opkg_message.h"
  19. #include "pkg_parse.h"
  20. #include "hash_table.h"
  21. #include "libbb/libbb.h"
  22. static int parseDepends(compound_depend_t * compound_depend, char *depend_str, enum depend_type type);
  23. static depend_t *depend_init(void);
  24. static char **add_unresolved_dep(pkg_t * pkg, char **the_lost, int ref_ndx);
  25. static char **merge_unresolved(char **oldstuff, char **newstuff);
  26. static int is_pkg_in_pkg_vec(pkg_vec_t * vec, pkg_t * pkg);
  27. static int pkg_installed_and_constraint_satisfied(pkg_t * pkg, void *cdata)
  28. {
  29. depend_t *depend = (depend_t *) cdata;
  30. if ((pkg->state_status == SS_INSTALLED
  31. || pkg->state_status == SS_UNPACKED)
  32. && version_constraints_satisfied(depend, pkg))
  33. return 1;
  34. else
  35. return 0;
  36. }
  37. static int pkg_constraint_satisfied(pkg_t * pkg, void *cdata)
  38. {
  39. depend_t *depend = (depend_t *) cdata;
  40. if (version_constraints_satisfied(depend, pkg))
  41. return 1;
  42. else
  43. return 0;
  44. }
  45. /* returns ndependencies or negative error value */
  46. int
  47. pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * unsatisfied,
  48. char ***unresolved, int pre_check)
  49. {
  50. pkg_t *satisfier_entry_pkg;
  51. int i, j, k;
  52. int found;
  53. char **the_lost;
  54. abstract_pkg_t *ab_pkg;
  55. compound_depend_t *compound_depend;
  56. char *check;
  57. /*
  58. * this is a setup to check for redundant/cyclic dependency checks,
  59. * which are marked at the abstract_pkg level
  60. */
  61. if (!(ab_pkg = pkg->parent)) {
  62. opkg_msg(ERROR, "Internal error, with pkg %s.\n", pkg->name);
  63. *unresolved = NULL;
  64. return 0;
  65. }
  66. if(pre_check) {
  67. check = &ab_pkg->pre_dependencies_checked;
  68. } else {
  69. check = &ab_pkg->dependencies_checked;
  70. }
  71. if (*check) { /* avoid duplicate or cyclic checks */
  72. *unresolved = NULL;
  73. return 0;
  74. } else {
  75. /* mark it for subsequent visits */
  76. *check = 1;
  77. }
  78. compound_depend = pkg_get_ptr(pkg, PKG_DEPENDS);
  79. if (!compound_depend || !compound_depend->type) {
  80. *unresolved = NULL;
  81. return 0;
  82. }
  83. the_lost = NULL;
  84. /* foreach dependency */
  85. for (i = 0; compound_depend && compound_depend->type; compound_depend++, i++) {
  86. depend_t **possible_satisfiers =
  87. compound_depend->possibilities;;
  88. found = 0;
  89. satisfier_entry_pkg = NULL;
  90. if (compound_depend->type == GREEDY_DEPEND) {
  91. /* foreach possible satisfier */
  92. for (j = 0; j < compound_depend->possibility_count; j++) {
  93. /* foreach provided_by, which includes the abstract_pkg itself */
  94. abstract_pkg_t *abpkg = possible_satisfiers[j]->pkg;
  95. abstract_pkg_vec_t *ab_provider_vec = abpkg->provided_by;
  96. int nposs = ab_provider_vec->len;
  97. abstract_pkg_t **ab_providers = ab_provider_vec->pkgs;
  98. int l;
  99. for (l = 0; l < nposs; l++) {
  100. pkg_vec_t *test_vec = ab_providers[l]->pkgs;
  101. /* if no depends on this one, try the first package that Provides this one */
  102. if (!test_vec) { /* no pkg_vec hooked up to the abstract_pkg! (need another feed?) */
  103. continue;
  104. }
  105. /* cruise this possiblity's pkg_vec looking for an installed version */
  106. for (k = 0; k < test_vec->len; k++) {
  107. pkg_t *pkg_scout = test_vec->pkgs[k];
  108. /* not installed, and not already known about? */
  109. if ((pkg_scout->state_want != SW_INSTALL)
  110. && !(pre_check ? pkg_scout->parent->pre_dependencies_checked : pkg_scout->parent->dependencies_checked)
  111. && !is_pkg_in_pkg_vec(unsatisfied, pkg_scout)) {
  112. char **newstuff = NULL;
  113. int rc;
  114. pkg_vec_t *tmp_vec = pkg_vec_alloc();
  115. /* check for not-already-installed dependencies */
  116. rc = pkg_hash_fetch_unsatisfied_dependencies(
  117. pkg_scout, tmp_vec, &newstuff, pre_check);
  118. if (newstuff == NULL) {
  119. int m;
  120. int ok = 1;
  121. for (m = 0; m < rc; m++) {
  122. pkg_t *p = tmp_vec->pkgs[m];
  123. if (p->state_want == SW_INSTALL)
  124. continue;
  125. opkg_msg(DEBUG,
  126. "Not installing %s due"
  127. " to requirement for %s.\n",
  128. pkg_scout->name, p->name);
  129. ok = 0;
  130. break;
  131. }
  132. pkg_vec_free(tmp_vec);
  133. if (ok) {
  134. /* mark this one for installation */
  135. opkg_msg(NOTICE,
  136. "Adding satisfier for greedy"
  137. " dependence %s.\n",
  138. pkg_scout->name);
  139. pkg_vec_insert(unsatisfied, pkg_scout);
  140. }
  141. } else {
  142. opkg_msg(DEBUG,
  143. "Not installing %s due to "
  144. "broken depends.\n",
  145. pkg_scout->name);
  146. free(newstuff);
  147. }
  148. }
  149. }
  150. }
  151. }
  152. continue;
  153. }
  154. /* foreach possible satisfier, look for installed package */
  155. for (j = 0; j < compound_depend->possibility_count; j++) {
  156. /* foreach provided_by, which includes the abstract_pkg itself */
  157. depend_t *dependence_to_satisfy = possible_satisfiers[j];
  158. abstract_pkg_t *satisfying_apkg = possible_satisfiers[j]->pkg;
  159. pkg_t *satisfying_pkg =
  160. pkg_hash_fetch_best_installation_candidate(satisfying_apkg,
  161. pkg_installed_and_constraint_satisfied,
  162. dependence_to_satisfy, 1);
  163. /* Being that I can't test constraing in pkg_hash, I will test it here */
  164. if (satisfying_pkg != NULL) {
  165. if (!pkg_installed_and_constraint_satisfied
  166. (satisfying_pkg, dependence_to_satisfy)) {
  167. satisfying_pkg = NULL;
  168. }
  169. }
  170. opkg_msg(DEBUG, "satisfying_pkg=%p\n", satisfying_pkg);
  171. if (satisfying_pkg != NULL) {
  172. found = 1;
  173. break;
  174. }
  175. }
  176. /* if nothing installed matches, then look for uninstalled satisfier */
  177. if (!found) {
  178. /* foreach possible satisfier, look for installed package */
  179. for (j = 0; j < compound_depend->possibility_count; j++) {
  180. /* foreach provided_by, which includes the abstract_pkg itself */
  181. depend_t *dependence_to_satisfy = possible_satisfiers[j];
  182. abstract_pkg_t *satisfying_apkg = possible_satisfiers[j]->pkg;
  183. pkg_t *satisfying_pkg =
  184. pkg_hash_fetch_best_installation_candidate(satisfying_apkg,
  185. pkg_constraint_satisfied, dependence_to_satisfy, 1);
  186. /* Being that I can't test constraing in pkg_hash, I will test it here too */
  187. if (satisfying_pkg != NULL) {
  188. if (!pkg_constraint_satisfied(satisfying_pkg,
  189. dependence_to_satisfy)) {
  190. satisfying_pkg = NULL;
  191. }
  192. }
  193. /* user request overrides package recommendation */
  194. if (satisfying_pkg != NULL
  195. && (compound_depend->type == RECOMMEND
  196. || compound_depend->type == SUGGEST)
  197. && (satisfying_pkg->state_want == SW_DEINSTALL
  198. || satisfying_pkg->state_want == SW_PURGE)) {
  199. opkg_msg(NOTICE,
  200. "%s: ignoring recommendation for "
  201. "%s at user request\n",
  202. pkg->name, satisfying_pkg->name);
  203. continue;
  204. }
  205. opkg_msg(DEBUG, "satisfying_pkg=%p\n",
  206. satisfying_pkg);
  207. if (satisfying_pkg != NULL) {
  208. satisfier_entry_pkg = satisfying_pkg;
  209. break;
  210. }
  211. }
  212. }
  213. /* we didn't find one, add something to the unsatisfied vector */
  214. if (!found) {
  215. if (!satisfier_entry_pkg) {
  216. /* failure to meet recommendations is not an error */
  217. if (compound_depend->type != RECOMMEND
  218. && compound_depend->type != SUGGEST)
  219. the_lost = add_unresolved_dep(pkg, the_lost, i);
  220. else
  221. opkg_msg(NOTICE,
  222. "%s: unsatisfied recommendation for %s\n",
  223. pkg->name,
  224. compound_depend->possibilities[0]->pkg->name);
  225. } else {
  226. if (compound_depend->type == SUGGEST) {
  227. /* just mention it politely */
  228. opkg_msg(NOTICE,
  229. "package %s suggests installing %s\n",
  230. pkg->name, satisfier_entry_pkg->name);
  231. } else {
  232. char **newstuff = NULL;
  233. if (satisfier_entry_pkg != pkg &&
  234. !is_pkg_in_pkg_vec(unsatisfied, satisfier_entry_pkg))
  235. {
  236. pkg_hash_fetch_unsatisfied_dependencies(
  237. satisfier_entry_pkg, unsatisfied, &newstuff, pre_check);
  238. pkg_vec_insert(unsatisfied, satisfier_entry_pkg);
  239. the_lost = merge_unresolved(the_lost, newstuff);
  240. if (newstuff)
  241. free(newstuff);
  242. }
  243. }
  244. }
  245. }
  246. }
  247. *unresolved = the_lost;
  248. return unsatisfied->len;
  249. }
  250. /*checking for conflicts !in replaces
  251. If a packages conflicts with another but is also replacing it, I should not consider it a
  252. really conflicts
  253. returns 0 if conflicts <> replaces or 1 if conflicts == replaces
  254. */
  255. static int is_pkg_a_replaces(pkg_t * pkg_scout, pkg_t * pkg)
  256. {
  257. abstract_pkg_t **replaces = pkg_get_ptr(pkg, PKG_REPLACES);
  258. if (!replaces || !*replaces)
  259. return 0;
  260. while (*replaces) {
  261. if (strcmp(pkg_scout->name, (*replaces)->name) == 0) { // Found
  262. opkg_msg(DEBUG2, "Seems I've found a replace %s %s\n",
  263. pkg_scout->name, (*replaces)->name);
  264. return 1;
  265. }
  266. replaces++;
  267. }
  268. return 0;
  269. }
  270. pkg_vec_t *pkg_hash_fetch_conflicts(pkg_t * pkg)
  271. {
  272. pkg_vec_t *installed_conflicts, *test_vec;
  273. compound_depend_t *conflicts, *conflict;
  274. depend_t **possible_satisfiers;
  275. depend_t *possible_satisfier;
  276. int j, k;
  277. abstract_pkg_t *ab_pkg;
  278. pkg_t **pkg_scouts;
  279. pkg_t *pkg_scout;
  280. /*
  281. * this is a setup to check for redundant/cyclic dependency checks,
  282. * which are marked at the abstract_pkg level
  283. */
  284. if (!(ab_pkg = pkg->parent)) {
  285. opkg_msg(ERROR, "Internal error: %s not in hash table\n",
  286. pkg->name);
  287. return (pkg_vec_t *) NULL;
  288. }
  289. conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS);
  290. if (!conflicts) {
  291. return (pkg_vec_t *) NULL;
  292. }
  293. installed_conflicts = pkg_vec_alloc();
  294. /* foreach conflict */
  295. for (conflict = conflicts; conflict->type; conflict++ ) {
  296. possible_satisfiers = conflicts->possibilities;
  297. /* foreach possible satisfier */
  298. for (j = 0; j < conflicts->possibility_count; j++) {
  299. possible_satisfier = possible_satisfiers[j];
  300. if (!possible_satisfier)
  301. opkg_msg(ERROR,
  302. "Internal error: possible_satisfier=NULL\n");
  303. if (!possible_satisfier->pkg)
  304. opkg_msg(ERROR,
  305. "Internal error: possible_satisfier->pkg=NULL\n");
  306. test_vec = possible_satisfier->pkg->pkgs;
  307. if (test_vec) {
  308. /* pkg_vec found, it is an actual package conflict
  309. * cruise this possiblity's pkg_vec looking for an installed version */
  310. pkg_scouts = test_vec->pkgs;
  311. for (k = 0; k < test_vec->len; k++) {
  312. pkg_scout = pkg_scouts[k];
  313. if (!pkg_scout) {
  314. opkg_msg(ERROR,
  315. "Internal error: pkg_scout=NULL\n");
  316. continue;
  317. }
  318. if ((pkg_scout->state_status == SS_INSTALLED
  319. || pkg_scout->state_want == SW_INSTALL)
  320. && version_constraints_satisfied(possible_satisfier,
  321. pkg_scout)
  322. && !is_pkg_a_replaces(pkg_scout, pkg)) {
  323. if (!is_pkg_in_pkg_vec(installed_conflicts,
  324. pkg_scout)) {
  325. pkg_vec_insert(installed_conflicts, pkg_scout);
  326. }
  327. }
  328. }
  329. }
  330. }
  331. conflicts++;
  332. }
  333. if (installed_conflicts->len)
  334. return installed_conflicts;
  335. pkg_vec_free(installed_conflicts);
  336. return (pkg_vec_t *) NULL;
  337. }
  338. int version_constraints_satisfied(depend_t * depends, pkg_t * pkg)
  339. {
  340. pkg_t *temp;
  341. int comparison;
  342. if (depends->constraint == NONE)
  343. return 1;
  344. temp = pkg_new();
  345. parse_version(temp, depends->version);
  346. comparison = pkg_compare_versions(pkg, temp);
  347. pkg_deinit(temp);
  348. free(temp);
  349. if ((depends->constraint == EARLIER) && (comparison < 0))
  350. return 1;
  351. else if ((depends->constraint == LATER) && (comparison > 0))
  352. return 1;
  353. else if (comparison == 0)
  354. return 1;
  355. else if ((depends->constraint == LATER_EQUAL) && (comparison >= 0))
  356. return 1;
  357. else if ((depends->constraint == EARLIER_EQUAL) && (comparison <= 0))
  358. return 1;
  359. return 0;
  360. }
  361. int pkg_dependence_satisfiable(depend_t * depend)
  362. {
  363. abstract_pkg_t *apkg = depend->pkg;
  364. abstract_pkg_vec_t *provider_apkgs = apkg->provided_by;
  365. int n_providers = provider_apkgs->len;
  366. abstract_pkg_t **apkgs = provider_apkgs->pkgs;
  367. pkg_vec_t *pkg_vec;
  368. int n_pkgs;
  369. int i;
  370. int j;
  371. for (i = 0; i < n_providers; i++) {
  372. abstract_pkg_t *papkg = apkgs[i];
  373. pkg_vec = papkg->pkgs;
  374. if (pkg_vec) {
  375. n_pkgs = pkg_vec->len;
  376. for (j = 0; j < n_pkgs; j++) {
  377. pkg_t *pkg = pkg_vec->pkgs[j];
  378. if (version_constraints_satisfied(depend, pkg)) {
  379. return 1;
  380. }
  381. }
  382. }
  383. }
  384. return 0;
  385. }
  386. static int is_pkg_in_pkg_vec(pkg_vec_t * vec, pkg_t * pkg)
  387. {
  388. int i;
  389. char *arch1, *arch2;
  390. pkg_t **pkgs = vec->pkgs;
  391. arch1 = pkg_get_architecture(pkg);
  392. for (i = 0; i < vec->len; i++) {
  393. arch2 = pkg_get_architecture(*(pkgs + i));
  394. if ((strcmp(pkg->name, (*(pkgs + i))->name) == 0)
  395. && (pkg_compare_versions(pkg, *(pkgs + i)) == 0)
  396. && (strcmp(arch1, arch2) == 0))
  397. return 1;
  398. }
  399. return 0;
  400. }
  401. /**
  402. * pkg_replaces returns 1 if pkg->replaces contains one of replacee's provides and 0
  403. * otherwise.
  404. */
  405. int pkg_replaces(pkg_t * pkg, pkg_t * replacee)
  406. {
  407. abstract_pkg_t **replaces = pkg_get_ptr(pkg, PKG_REPLACES);
  408. abstract_pkg_t **provides = pkg_get_ptr(replacee, PKG_PROVIDES);
  409. abstract_pkg_t **r, **p;
  410. for (r = replaces; r && *r; r++)
  411. for (p = provides; p && *p; p++)
  412. if (*r == *p)
  413. return 1;
  414. return 0;
  415. }
  416. /**
  417. * pkg_conflicts_abstract returns 1 if pkg->conflicts contains conflictee and 0
  418. * otherwise.
  419. */
  420. int pkg_conflicts_abstract(pkg_t * pkg, abstract_pkg_t * conflictee)
  421. {
  422. int i, j;
  423. compound_depend_t *conflicts;
  424. for (conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS), i = 0; conflicts && conflicts[i].type; i++)
  425. for (j = 0; j < conflicts[i].possibility_count; j++)
  426. if (conflicts[i].possibilities[j]->pkg == conflictee)
  427. return 1;
  428. return 0;
  429. }
  430. /**
  431. * pkg_conflicts returns 1 if pkg->conflicts contains one of
  432. * conflictee's provides and 0 otherwise.
  433. */
  434. int pkg_conflicts(pkg_t * pkg, pkg_t * conflictee)
  435. {
  436. int i, j;
  437. compound_depend_t *conflicts;
  438. abstract_pkg_t **provider;
  439. for (conflicts = pkg_get_ptr(pkg, PKG_CONFLICTS), i = 0; conflicts && conflicts[i].type; i++)
  440. for (j = 0; j < conflicts[i].possibility_count; j++)
  441. for (provider = pkg_get_ptr(conflictee, PKG_PROVIDES); provider && *provider; provider++)
  442. if (conflicts[i].possibilities[j]->pkg == *provider)
  443. return 1;
  444. return 0;
  445. }
  446. static char **merge_unresolved(char **oldstuff, char **newstuff)
  447. {
  448. int oldlen = 0, newlen = 0;
  449. char **result;
  450. int i, j;
  451. if (!newstuff)
  452. return oldstuff;
  453. while (oldstuff && oldstuff[oldlen])
  454. oldlen++;
  455. while (newstuff && newstuff[newlen])
  456. newlen++;
  457. result = xrealloc(oldstuff, sizeof(char *) * (oldlen + newlen + 1));
  458. for (i = oldlen, j = 0; i < (oldlen + newlen); i++, j++)
  459. *(result + i) = *(newstuff + j);
  460. *(result + i) = NULL;
  461. return result;
  462. }
  463. /*
  464. * a kinda kludgy way to back out depends str from two different arrays (reg'l'r 'n pre)
  465. * this is null terminated, no count is carried around
  466. */
  467. char **add_unresolved_dep(pkg_t * pkg, char **the_lost, int ref_ndx)
  468. {
  469. int count;
  470. char **resized;
  471. count = 0;
  472. while (the_lost && the_lost[count])
  473. count++;
  474. count++; /* need one to hold the null */
  475. resized = xrealloc(the_lost, sizeof(char *) * (count + 1));
  476. resized[count - 1] = pkg_depend_str(pkg, ref_ndx);
  477. resized[count] = NULL;
  478. return resized;
  479. }
  480. static void flag_related_packages(pkg_t *pkg, int state_flags)
  481. {
  482. int i, j;
  483. compound_depend_t *deps;
  484. for (deps = pkg_get_ptr(pkg, PKG_DEPENDS), i = 0; deps && deps[i].type; i++)
  485. for (j = 0; j < deps[i].possibility_count; j++) {
  486. if ((deps[i].possibilities[j]->pkg->state_flag & state_flags) != state_flags) {
  487. opkg_msg(DEBUG, "propagating pkg flag to dependent abpkg %s\n",
  488. deps[i].possibilities[j]->pkg->name);
  489. deps[i].possibilities[j]->pkg->state_flag |= state_flags;
  490. }
  491. }
  492. for (deps = pkg_get_ptr(pkg, PKG_CONFLICTS), i = 0; deps && deps[i].type; i++)
  493. for (j = 0; j < deps[i].possibility_count; j++) {
  494. if ((deps[i].possibilities[j]->pkg->state_flag & state_flags) != state_flags) {
  495. opkg_msg(DEBUG, "propagating pkg flag to conflicting abpkg %s\n",
  496. deps[i].possibilities[j]->pkg->name);
  497. deps[i].possibilities[j]->pkg->state_flag |= state_flags;
  498. }
  499. }
  500. }
  501. abstract_pkg_t **init_providelist(pkg_t *pkg, int *count)
  502. {
  503. abstract_pkg_t *ab_pkg;
  504. abstract_pkg_t **provides = pkg_get_ptr(pkg, PKG_PROVIDES);
  505. if (!provides) {
  506. provides = calloc(2, sizeof(abstract_pkg_t *));
  507. if (!provides) {
  508. if (count)
  509. *count = 0;
  510. return NULL;
  511. }
  512. ab_pkg = ensure_abstract_pkg_by_name(pkg->name);
  513. if (!ab_pkg->pkgs)
  514. ab_pkg->pkgs = pkg_vec_alloc();
  515. if (!abstract_pkg_vec_contains(ab_pkg->provided_by, ab_pkg))
  516. abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
  517. provides[0] = ab_pkg;
  518. provides[1] = NULL;
  519. if (count)
  520. *count = 2;
  521. pkg_set_ptr(pkg, PKG_PROVIDES, provides);
  522. }
  523. else if (count) {
  524. for (*count = 1; *provides; provides++) {
  525. if (pkg->state_flag & SF_NEED_DETAIL) {
  526. if (!((*provides)->state_flag & SF_NEED_DETAIL)) {
  527. opkg_msg(DEBUG, "propagating pkg flag to provided abpkg %s\n",
  528. (*provides)->name);
  529. (*provides)->state_flag |= SF_NEED_DETAIL;
  530. }
  531. }
  532. (*count)++;
  533. }
  534. }
  535. flag_related_packages(pkg, SF_NEED_DETAIL);
  536. return provides;
  537. }
  538. void parse_providelist(pkg_t *pkg, char *list)
  539. {
  540. int count = 0;
  541. char *item, *tok;
  542. abstract_pkg_t *ab_pkg, *provided_abpkg, **tmp, **provides;
  543. provides = init_providelist(pkg, &count);
  544. ab_pkg = ensure_abstract_pkg_by_name(pkg->name);
  545. if (!provides || !ab_pkg)
  546. return;
  547. for (item = strtok_r(list, ", ", &tok); item;
  548. count++, item = strtok_r(NULL, ", ", &tok)) {
  549. tmp = realloc(provides, sizeof(abstract_pkg_t *) * (count + 1));
  550. if (!tmp)
  551. break;
  552. provided_abpkg = ensure_abstract_pkg_by_name(item);
  553. if (provided_abpkg->state_flag & SF_NEED_DETAIL) {
  554. if (!(ab_pkg->state_flag & SF_NEED_DETAIL)) {
  555. opkg_msg(DEBUG, "propagating provided abpkg flag to "
  556. "provider abpkg %s\n", ab_pkg->name);
  557. ab_pkg->state_flag |= SF_NEED_DETAIL;
  558. }
  559. }
  560. if (!abstract_pkg_vec_contains(provided_abpkg->provided_by, ab_pkg))
  561. abstract_pkg_vec_insert(provided_abpkg->provided_by, ab_pkg);
  562. provides = tmp;
  563. provides[count - 1] = provided_abpkg;
  564. }
  565. provides[count - 1] = NULL;
  566. pkg_set_ptr(pkg, PKG_PROVIDES, provides);
  567. }
  568. void parse_replacelist(pkg_t *pkg, char *list)
  569. {
  570. int count;
  571. char *item, *tok;
  572. abstract_pkg_t *ab_pkg, *old_abpkg, **tmp, **replaces = NULL;
  573. ab_pkg = ensure_abstract_pkg_by_name(pkg->name);
  574. if (!ab_pkg->pkgs)
  575. ab_pkg->pkgs = pkg_vec_alloc();
  576. abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
  577. for (count = 1, item = strtok_r(list, ", ", &tok); item;
  578. count++, item = strtok_r(NULL, ", ", &tok)) {
  579. tmp = realloc(replaces, sizeof(abstract_pkg_t *) * (count + 1));
  580. if (!tmp)
  581. break;
  582. old_abpkg = ensure_abstract_pkg_by_name(item);
  583. if (pkg->state_flag & SF_NEED_DETAIL) {
  584. if (!(old_abpkg->state_flag & SF_NEED_DETAIL)) {
  585. opkg_msg(DEBUG, "propagating pkg flag to replaced abpkg %s\n",
  586. old_abpkg->name);
  587. old_abpkg->state_flag |= SF_NEED_DETAIL;
  588. }
  589. }
  590. if (!old_abpkg->replaced_by)
  591. old_abpkg->replaced_by = abstract_pkg_vec_alloc();
  592. /* if a package pkg both replaces and conflicts old_abpkg,
  593. * then add it to the replaced_by vector so that old_abpkg
  594. * will be upgraded to ab_pkg automatically */
  595. if (pkg_conflicts_abstract(pkg, old_abpkg)) {
  596. if (!abstract_pkg_vec_contains(old_abpkg->replaced_by, ab_pkg))
  597. abstract_pkg_vec_insert(old_abpkg->replaced_by, ab_pkg);
  598. }
  599. replaces = tmp;
  600. replaces[count - 1] = old_abpkg;
  601. }
  602. if (!replaces)
  603. return;
  604. replaces[count - 1] = NULL;
  605. pkg_set_ptr(pkg, PKG_REPLACES, replaces);
  606. }
  607. void buildProvides(abstract_pkg_t * ab_pkg, pkg_t * pkg)
  608. {
  609. #if 0
  610. int i;
  611. /* every pkg provides itself */
  612. pkg->provides_count++;
  613. abstract_pkg_vec_insert(ab_pkg->provided_by, ab_pkg);
  614. pkg->provides = xcalloc(pkg->provides_count, sizeof(abstract_pkg_t *));
  615. pkg->provides[0] = ab_pkg;
  616. for (i = 1; i < pkg->provides_count; i++) {
  617. abstract_pkg_t *provided_abpkg =
  618. ensure_abstract_pkg_by_name(pkg->provides_str[i - 1]);
  619. free(pkg->provides_str[i - 1]);
  620. pkg->provides[i] = provided_abpkg;
  621. abstract_pkg_vec_insert(provided_abpkg->provided_by, ab_pkg);
  622. }
  623. if (pkg->provides_str)
  624. free(pkg->provides_str);
  625. #endif
  626. }
  627. void buildConflicts(pkg_t * pkg)
  628. {
  629. /*
  630. int i;
  631. compound_depend_t *conflicts, *conflict;
  632. if (!pkg->conflicts_count)
  633. return;
  634. conflicts = pkg->conflicts =
  635. xcalloc(pkg->conflicts_count, sizeof(compound_depend_t));
  636. for (i = 0; i < pkg->conflicts_count; i++) {
  637. conflicts->type = CONFLICTS;
  638. parseDepends(conflicts, pkg->conflicts_str[i]);
  639. free(pkg->conflicts_str[i]);
  640. conflicts++;
  641. }
  642. if (pkg->conflicts_str)
  643. free(pkg->conflicts_str);
  644. */
  645. }
  646. void buildReplaces(abstract_pkg_t * ab_pkg, pkg_t * pkg)
  647. {
  648. #if 0
  649. int i;
  650. if (!pkg->replaces_count)
  651. return;
  652. pkg->replaces = xcalloc(pkg->replaces_count, sizeof(abstract_pkg_t *));
  653. for (i = 0; i < pkg->replaces_count; i++) {
  654. abstract_pkg_t *old_abpkg =
  655. ensure_abstract_pkg_by_name(pkg->replaces_str[i]);
  656. pkg->replaces[i] = old_abpkg;
  657. free(pkg->replaces_str[i]);
  658. if (!old_abpkg->replaced_by)
  659. old_abpkg->replaced_by = abstract_pkg_vec_alloc();
  660. /* if a package pkg both replaces and conflicts old_abpkg,
  661. * then add it to the replaced_by vector so that old_abpkg
  662. * will be upgraded to ab_pkg automatically */
  663. if (pkg_conflicts_abstract(pkg, old_abpkg))
  664. abstract_pkg_vec_insert(old_abpkg->replaced_by, ab_pkg);
  665. }
  666. if (pkg->replaces_str)
  667. free(pkg->replaces_str);
  668. #endif
  669. }
  670. void parse_deplist(pkg_t *pkg, enum depend_type type, char *list)
  671. {
  672. int id, count;
  673. char *item, *tok;
  674. compound_depend_t *tmp, *deps;
  675. switch (type)
  676. {
  677. case DEPEND:
  678. case PREDEPEND:
  679. case RECOMMEND:
  680. case SUGGEST:
  681. case GREEDY_DEPEND:
  682. id = PKG_DEPENDS;
  683. break;
  684. case CONFLICTS:
  685. id = PKG_CONFLICTS;
  686. break;
  687. default:
  688. return;
  689. }
  690. deps = pkg_get_ptr(pkg, id);
  691. for (tmp = deps, count = 1; tmp && tmp->type; tmp++)
  692. count++;
  693. for (item = strtok_r(list, ",", &tok); item; item = strtok_r(NULL, ",", &tok), count++) {
  694. tmp = realloc(deps, sizeof(compound_depend_t) * (count + 1));
  695. if (!tmp)
  696. break;
  697. deps = tmp;
  698. memset(deps + count - 1, 0, sizeof(compound_depend_t));
  699. parseDepends(deps + count - 1, item, type);
  700. }
  701. if (!deps)
  702. return;
  703. memset(deps + count - 1, 0, sizeof(compound_depend_t));
  704. pkg_set_ptr(pkg, id, deps);
  705. }
  706. void buildDepends(pkg_t * pkg)
  707. {
  708. #if 0
  709. unsigned int count;
  710. int i;
  711. compound_depend_t *depends;
  712. if (!
  713. (count =
  714. pkg->pre_depends_count + pkg->depends_count +
  715. pkg->recommends_count + pkg->suggests_count))
  716. return;
  717. depends = pkg->depends = xcalloc(count, sizeof(compound_depend_t));
  718. for (i = 0; i < pkg->pre_depends_count; i++) {
  719. parseDepends(depends, pkg->pre_depends_str[i]);
  720. free(pkg->pre_depends_str[i]);
  721. depends->type = PREDEPEND;
  722. depends++;
  723. }
  724. if (pkg->pre_depends_str)
  725. free(pkg->pre_depends_str);
  726. for (i = 0; i < pkg->depends_count; i++) {
  727. parseDepends(depends, pkg->depends_str[i]);
  728. free(pkg->depends_str[i]);
  729. depends++;
  730. }
  731. if (pkg->depends_str)
  732. free(pkg->depends_str);
  733. for (i = 0; i < pkg->recommends_count; i++) {
  734. parseDepends(depends, pkg->recommends_str[i]);
  735. free(pkg->recommends_str[i]);
  736. depends->type = RECOMMEND;
  737. depends++;
  738. }
  739. if (pkg->recommends_str)
  740. free(pkg->recommends_str);
  741. for (i = 0; i < pkg->suggests_count; i++) {
  742. parseDepends(depends, pkg->suggests_str[i]);
  743. free(pkg->suggests_str[i]);
  744. depends->type = SUGGEST;
  745. depends++;
  746. }
  747. if (pkg->suggests_str)
  748. free(pkg->suggests_str);
  749. #endif
  750. }
  751. const char *constraint_to_str(enum version_constraint c)
  752. {
  753. switch (c) {
  754. case NONE:
  755. return "";
  756. case EARLIER:
  757. return "< ";
  758. case EARLIER_EQUAL:
  759. return "<= ";
  760. case EQUAL:
  761. return "= ";
  762. case LATER_EQUAL:
  763. return ">= ";
  764. case LATER:
  765. return "> ";
  766. }
  767. return "";
  768. }
  769. /*
  770. * Returns a printable string for pkg's dependency at the specified idx. The
  771. * resultant string must be passed to free() by the caller.
  772. */
  773. char *pkg_depend_str(pkg_t * pkg, int idx)
  774. {
  775. int i;
  776. unsigned int len;
  777. char *str;
  778. compound_depend_t *cdep = NULL, *p;
  779. depend_t *dep;
  780. for (i = 0, p = pkg_get_ptr(pkg, PKG_DEPENDS); p && p->type; i++, p++)
  781. if (i == idx) {
  782. cdep = p;
  783. break;
  784. }
  785. if (!cdep)
  786. return NULL;
  787. len = 0;
  788. /* calculate string length */
  789. for (i = 0; i < cdep->possibility_count; i++) {
  790. dep = cdep->possibilities[i];
  791. if (i != 0)
  792. len += 3; /* space, pipe, space */
  793. len += strlen(dep->pkg->name);
  794. if (dep->version) {
  795. len += 2; /* space, left parenthesis */
  796. len += 3; /* constraint string (<=, >=, etc), space */
  797. len += strlen(dep->version);
  798. len += 1; /* right parenthesis */
  799. }
  800. }
  801. str = xmalloc(len + 1); /* +1 for the NULL terminator */
  802. str[0] = '\0';
  803. for (i = 0; i < cdep->possibility_count; i++) {
  804. dep = cdep->possibilities[i];
  805. if (i != 0)
  806. strncat(str, " | ", len);
  807. strncat(str, dep->pkg->name, len);
  808. if (dep->version) {
  809. strncat(str, " (", len);
  810. strncat(str, constraint_to_str(dep->constraint), len);
  811. strncat(str, dep->version, len);
  812. strncat(str, ")", len);
  813. }
  814. }
  815. return str;
  816. }
  817. void buildDependedUponBy(pkg_t * pkg, abstract_pkg_t * ab_pkg)
  818. {
  819. compound_depend_t *depends;
  820. int othercount;
  821. int j;
  822. abstract_pkg_t *ab_depend;
  823. abstract_pkg_t **temp;
  824. for (depends = pkg_get_ptr(pkg, PKG_DEPENDS); depends && depends->type; depends++) {
  825. if (depends->type != PREDEPEND
  826. && depends->type != DEPEND && depends->type != RECOMMEND)
  827. continue;
  828. for (j = 0; j < depends->possibility_count; j++) {
  829. ab_depend = depends->possibilities[j]->pkg;
  830. if (!ab_depend->depended_upon_by) {
  831. ab_depend->depended_upon_by =
  832. xcalloc(1, sizeof(abstract_pkg_t *));
  833. }
  834. temp = ab_depend->depended_upon_by;
  835. othercount = 1;
  836. while (*temp) {
  837. temp++;
  838. othercount++;
  839. }
  840. *temp = ab_pkg;
  841. ab_depend->depended_upon_by =
  842. xrealloc(ab_depend->depended_upon_by,
  843. (othercount +
  844. 1) * sizeof(abstract_pkg_t *));
  845. /* the array may have been moved by realloc */
  846. temp = ab_depend->depended_upon_by + othercount;
  847. *temp = NULL;
  848. }
  849. }
  850. }
  851. static depend_t *depend_init(void)
  852. {
  853. depend_t *d = xcalloc(1, sizeof(depend_t));
  854. d->constraint = NONE;
  855. d->version = NULL;
  856. d->pkg = NULL;
  857. return d;
  858. }
  859. static int parseDepends(compound_depend_t * compound_depend, char *depend_str, enum depend_type type)
  860. {
  861. int i;
  862. char *depend, *name, *vstr, *rest, *tok = NULL;
  863. depend_t **possibilities = NULL, **tmp;
  864. compound_depend->type = type;
  865. for (i = 0, depend = strtok_r(depend_str, "|", &tok); depend; i++, depend = strtok_r(NULL, "|", &tok)) {
  866. name = strtok(depend, " ");
  867. rest = strtok(NULL, "\n");
  868. tmp = realloc(possibilities, sizeof(tmp) * (i + 1));
  869. if (!tmp)
  870. return -1;
  871. possibilities = tmp;
  872. possibilities[i] = depend_init();
  873. possibilities[i]->pkg = ensure_abstract_pkg_by_name(name);
  874. if (rest && *rest == '(') {
  875. vstr = strtok(rest + 1, ")");
  876. if (!strncmp(vstr, "<<", 2)) {
  877. possibilities[i]->constraint = EARLIER;
  878. vstr += 2;
  879. } else if (!strncmp(vstr, "<=", 2)) {
  880. possibilities[i]->constraint = EARLIER_EQUAL;
  881. vstr += 2;
  882. } else if (!strncmp(vstr, ">=", 2)) {
  883. possibilities[i]->constraint = LATER_EQUAL;
  884. vstr += 2;
  885. } else if (!strncmp(vstr, ">>", 2)) {
  886. possibilities[i]->constraint = LATER;
  887. vstr += 2;
  888. } else if (!strncmp(vstr, "=", 1)) {
  889. possibilities[i]->constraint = EQUAL;
  890. vstr++;
  891. }
  892. /* should these be here to support deprecated designations; dpkg does */
  893. else if (!strncmp(vstr, "<", 1)) {
  894. possibilities[i]->constraint = EARLIER_EQUAL;
  895. vstr++;
  896. } else if (!strncmp(vstr, ">", 1)) {
  897. possibilities[i]->constraint = LATER_EQUAL;
  898. vstr++;
  899. }
  900. possibilities[i]->version = trim_xstrdup(vstr);
  901. rest = strtok(NULL, " ");
  902. }
  903. else {
  904. rest = strtok(rest, " ");
  905. }
  906. if (rest && *rest == '*')
  907. compound_depend->type = GREEDY_DEPEND;
  908. }
  909. compound_depend->possibility_count = i;
  910. compound_depend->possibilities = possibilities;
  911. return 0;
  912. }
  913. compound_depend_t *pkg_get_depends(pkg_t *pkg, enum depend_type type)
  914. {
  915. compound_depend_t *dep;
  916. for (dep = pkg_get_ptr(pkg, PKG_DEPENDS); dep && dep->type; dep++)
  917. if (type == UNSPEC || dep->type == type)
  918. return dep;
  919. return NULL;
  920. }