pkg_depends.c 29 KB

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