pkg.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548
  1. /* pkg.c - the opkg package management system
  2. Carl D. Worth
  3. Copyright (C) 2001 University of Southern California
  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 <string.h>
  15. #include <ctype.h>
  16. #include <unistd.h>
  17. #include <libgen.h>
  18. #include "pkg.h"
  19. #include "pkg_parse.h"
  20. #include "pkg_extract.h"
  21. #include "opkg_message.h"
  22. #include "opkg_utils.h"
  23. #include "libbb/libbb.h"
  24. #include "sprintf_alloc.h"
  25. #include "file_util.h"
  26. #include "xsystem.h"
  27. #include "opkg_conf.h"
  28. typedef struct enum_map enum_map_t;
  29. struct enum_map {
  30. unsigned int value;
  31. const char *str;
  32. };
  33. static const enum_map_t pkg_state_want_map[] = {
  34. {SW_UNKNOWN, "unknown"},
  35. {SW_INSTALL, "install"},
  36. {SW_DEINSTALL, "deinstall"},
  37. {SW_PURGE, "purge"}
  38. };
  39. static const enum_map_t pkg_state_flag_map[] = {
  40. {SF_OK, "ok"},
  41. {SF_REINSTREQ, "reinstreq"},
  42. {SF_HOLD, "hold"},
  43. {SF_REPLACE, "replace"},
  44. {SF_NOPRUNE, "noprune"},
  45. {SF_PREFER, "prefer"},
  46. {SF_OBSOLETE, "obsolete"},
  47. {SF_USER, "user"},
  48. };
  49. static const enum_map_t pkg_state_status_map[] = {
  50. {SS_NOT_INSTALLED, "not-installed"},
  51. {SS_UNPACKED, "unpacked"},
  52. {SS_HALF_CONFIGURED, "half-configured"},
  53. {SS_INSTALLED, "installed"},
  54. {SS_HALF_INSTALLED, "half-installed"},
  55. {SS_CONFIG_FILES, "config-files"},
  56. {SS_POST_INST_FAILED, "post-inst-failed"},
  57. {SS_REMOVAL_FAILED, "removal-failed"}
  58. };
  59. static void pkg_init(pkg_t * pkg)
  60. {
  61. pkg->name = NULL;
  62. pkg->dest = NULL;
  63. pkg->src = NULL;
  64. pkg->state_want = SW_UNKNOWN;
  65. pkg->state_flag = SF_OK;
  66. pkg->state_status = SS_NOT_INSTALLED;
  67. pkg->installed_files = NULL;
  68. pkg->installed_files_ref_cnt = 0;
  69. pkg->essential = 0;
  70. pkg->provided_by_hand = 0;
  71. pkg->arch_index = 0;
  72. blob_buf_init(&pkg->blob, 0);
  73. }
  74. pkg_t *pkg_new(void)
  75. {
  76. pkg_t *pkg;
  77. pkg = xcalloc(1, sizeof(pkg_t));
  78. pkg_init(pkg);
  79. return pkg;
  80. }
  81. void *pkg_set_raw(pkg_t *pkg, int id, const void *val, size_t len)
  82. {
  83. int rem;
  84. struct blob_attr *cur;
  85. blob_for_each_attr(cur, pkg->blob.head, rem) {
  86. if (blob_id(cur) == id) {
  87. if (blob_len(cur) < len) {
  88. fprintf(stderr, "ERROR: truncating field %d <%p> to %zu byte",
  89. id, val, blob_len(cur));
  90. }
  91. memcpy(blob_data(cur), val, blob_len(cur));
  92. return blob_data(cur);
  93. }
  94. }
  95. cur = blob_put(&pkg->blob, id, val, len);
  96. return cur ? blob_data(cur) : NULL;
  97. }
  98. void *pkg_get_raw(const pkg_t * pkg, int id)
  99. {
  100. int rem;
  101. struct blob_attr *cur;
  102. blob_for_each_attr(cur, pkg->blob.head, rem)
  103. if (blob_id(cur) == id)
  104. return blob_data(cur);
  105. return NULL;
  106. }
  107. char *pkg_set_string(pkg_t *pkg, int id, const char *s)
  108. {
  109. size_t len;
  110. char *p;
  111. if (!s)
  112. return NULL;
  113. len = strlen(s);
  114. while (isspace(*s)) {
  115. s++;
  116. len--;
  117. }
  118. while (len > 0 && isspace(s[len - 1]))
  119. len--;
  120. if (!len)
  121. return NULL;
  122. p = pkg_set_raw(pkg, id, s, len + 1);
  123. p[len] = 0;
  124. return p;
  125. }
  126. char *pkg_get_architecture(const pkg_t *pkg)
  127. {
  128. nv_pair_list_elt_t *l;
  129. int n = 1;
  130. list_for_each_entry(l, &conf->arch_list.head, node) {
  131. nv_pair_t *nv = (nv_pair_t *) l->data;
  132. if (n++ == pkg->arch_index)
  133. return nv->name;
  134. }
  135. return NULL;
  136. }
  137. char *pkg_set_architecture(pkg_t *pkg, const char *architecture, ssize_t len)
  138. {
  139. nv_pair_list_elt_t *l;
  140. int n = 1;
  141. list_for_each_entry(l, &conf->arch_list.head, node) {
  142. nv_pair_t *nv = (nv_pair_t *) l->data;
  143. if (!strncmp(nv->name, architecture, len) && nv->name[len] == '\0') {
  144. if (n >= 8) {
  145. opkg_msg(ERROR, "Internal error: too many different architectures\n");
  146. break;
  147. }
  148. pkg->arch_index = n;
  149. return nv->name;
  150. }
  151. n++;
  152. }
  153. pkg->arch_index = 0;
  154. return NULL;
  155. }
  156. int pkg_get_arch_priority(const pkg_t *pkg)
  157. {
  158. nv_pair_list_elt_t *l;
  159. int n = 1;
  160. list_for_each_entry(l, &conf->arch_list.head, node) {
  161. nv_pair_t *nv = (nv_pair_t *) l->data;
  162. if (n++ == pkg->arch_index)
  163. return strtol(nv->value, NULL, 0);
  164. }
  165. return 0;
  166. }
  167. char *pkg_get_md5(const pkg_t *pkg)
  168. {
  169. char *p = pkg_get_raw(pkg, PKG_MD5SUM);
  170. if (!p)
  171. return NULL;
  172. return checksum_bin2hex(p, 16);
  173. }
  174. char *pkg_set_md5(pkg_t *pkg, const char *cksum)
  175. {
  176. size_t len;
  177. char *p = checksum_hex2bin(cksum, &len);
  178. if (!p || len != 16)
  179. return NULL;
  180. return pkg_set_raw(pkg, PKG_MD5SUM, p, len);
  181. }
  182. char *pkg_get_sha256(const pkg_t *pkg)
  183. {
  184. char *p = pkg_get_raw(pkg, PKG_SHA256SUM);
  185. if (!p)
  186. return NULL;
  187. return checksum_bin2hex(p, 32);
  188. }
  189. char *pkg_set_sha256(pkg_t *pkg, const char *cksum)
  190. {
  191. size_t len;
  192. char *p = checksum_hex2bin(cksum, &len);
  193. if (!p || len != 32)
  194. return NULL;
  195. return pkg_set_raw(pkg, PKG_SHA256SUM, p, len);
  196. }
  197. static void compound_depend_deinit(compound_depend_t * depends)
  198. {
  199. int i;
  200. for (i = 0; i < depends->possibility_count; i++) {
  201. depend_t *d;
  202. d = depends->possibilities[i];
  203. free(d->version);
  204. free(d);
  205. }
  206. free(depends->possibilities);
  207. }
  208. void pkg_deinit(pkg_t * pkg)
  209. {
  210. int rem;
  211. struct blob_attr *cur;
  212. compound_depend_t *deps, *dep;
  213. void *ptr;
  214. if (pkg->name)
  215. free(pkg->name);
  216. pkg->name = NULL;
  217. /* owned by opkg_conf_t */
  218. pkg->dest = NULL;
  219. /* owned by opkg_conf_t */
  220. pkg->src = NULL;
  221. pkg->state_want = SW_UNKNOWN;
  222. pkg->state_flag = SF_OK;
  223. pkg->state_status = SS_NOT_INSTALLED;
  224. blob_for_each_attr(cur, pkg->blob.head, rem) {
  225. switch (blob_id(cur)) {
  226. case PKG_DEPENDS:
  227. case PKG_CONFLICTS:
  228. deps = pkg_get_ptr(pkg, blob_id(cur));
  229. if (deps) {
  230. for (dep = deps; dep->type; dep++)
  231. compound_depend_deinit(dep);
  232. free(deps);
  233. }
  234. pkg_set_ptr(pkg, blob_id(cur), NULL);
  235. break;
  236. case PKG_REPLACES:
  237. case PKG_PROVIDES:
  238. ptr = pkg_get_ptr(pkg, blob_id(cur));
  239. if (ptr)
  240. free(ptr);
  241. pkg_set_ptr(pkg, blob_id(cur), NULL);
  242. break;
  243. case PKG_CONFFILES:
  244. ptr = pkg_get_ptr(pkg, blob_id(cur));
  245. if (ptr) {
  246. conffile_list_deinit(ptr);
  247. free(ptr);
  248. }
  249. pkg_set_ptr(pkg, blob_id(cur), NULL);
  250. break;
  251. case PKG_ALTERNATIVES:
  252. ptr = pkg_get_ptr(pkg, blob_id(cur));
  253. if (ptr) {
  254. struct pkg_alternatives *pkg_alts = ptr;
  255. while (pkg_alts->nalts)
  256. free(pkg_alts->alts[--pkg_alts->nalts]);
  257. free(pkg_alts->alts);
  258. free(pkg_alts);
  259. }
  260. pkg_set_ptr(pkg, blob_id(cur), NULL);
  261. break;
  262. }
  263. }
  264. //conffile_list_deinit(&pkg->conffiles);
  265. /* XXX: QUESTION: Is forcing this to 1 correct? I suppose so,
  266. since if they are calling deinit, they should know. Maybe do an
  267. assertion here instead? */
  268. pkg->installed_files_ref_cnt = 1;
  269. pkg_free_installed_files(pkg);
  270. pkg->essential = 0;
  271. blob_buf_free(&pkg->blob);
  272. }
  273. int pkg_init_from_file(pkg_t * pkg, const char *filename)
  274. {
  275. int fd, err = 0;
  276. FILE *control_file;
  277. char *control_path, *tmp;
  278. pkg_init(pkg);
  279. if (!(pkg->state_flag & SF_NEED_DETAIL)) {
  280. opkg_msg(DEBUG, "applying abpkg flag to %s\n", filename);
  281. pkg->state_flag |= SF_NEED_DETAIL;
  282. }
  283. pkg_set_string(pkg, PKG_LOCAL_FILENAME, filename);
  284. tmp = xstrdup(filename);
  285. sprintf_alloc(&control_path, "%s/%s.control.XXXXXX",
  286. conf->tmp_dir, basename(tmp));
  287. free(tmp);
  288. fd = mkstemp(control_path);
  289. if (fd == -1) {
  290. opkg_perror(ERROR, "Failed to make temp file %s", control_path);
  291. err = -1;
  292. goto err0;
  293. }
  294. control_file = fdopen(fd, "r+");
  295. if (control_file == NULL) {
  296. opkg_perror(ERROR, "Failed to fdopen %s", control_path);
  297. close(fd);
  298. err = -1;
  299. goto err1;
  300. }
  301. err = pkg_extract_control_file_to_stream(pkg, control_file);
  302. if (err) {
  303. opkg_msg(ERROR, "Failed to extract control file from %s.\n",
  304. filename);
  305. goto err2;
  306. }
  307. rewind(control_file);
  308. if ((err = pkg_parse_from_stream(pkg, control_file, 0))) {
  309. if (err == 1) {
  310. opkg_msg(ERROR, "Malformed package file %s.\n",
  311. filename);
  312. }
  313. err = -1;
  314. }
  315. err2:
  316. fclose(control_file);
  317. err1:
  318. unlink(control_path);
  319. err0:
  320. free(control_path);
  321. return err;
  322. }
  323. /* Merge any new information in newpkg into oldpkg */
  324. int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg)
  325. {
  326. abstract_pkg_t **ab;
  327. if (oldpkg == newpkg) {
  328. return 0;
  329. }
  330. if (!oldpkg->auto_installed)
  331. oldpkg->auto_installed = newpkg->auto_installed;
  332. if (!oldpkg->src)
  333. oldpkg->src = newpkg->src;
  334. if (!oldpkg->dest)
  335. oldpkg->dest = newpkg->dest;
  336. if (!oldpkg->arch_index)
  337. oldpkg->arch_index = newpkg->arch_index;
  338. if (!pkg_get_string(oldpkg, PKG_SECTION))
  339. pkg_set_string(oldpkg, PKG_SECTION, pkg_get_string(newpkg, PKG_SECTION));
  340. if (!pkg_get_string(oldpkg, PKG_MAINTAINER))
  341. pkg_set_string(oldpkg, PKG_MAINTAINER, pkg_get_string(newpkg, PKG_MAINTAINER));
  342. if (!pkg_get_string(oldpkg, PKG_DESCRIPTION))
  343. pkg_set_string(oldpkg, PKG_DESCRIPTION, pkg_get_string(newpkg, PKG_DESCRIPTION));
  344. if (!pkg_get_ptr(oldpkg, PKG_DEPENDS)) {
  345. pkg_set_ptr(oldpkg, PKG_DEPENDS, pkg_get_ptr(newpkg, PKG_DEPENDS));
  346. pkg_set_ptr(newpkg, PKG_DEPENDS, NULL);
  347. }
  348. ab = pkg_get_ptr(oldpkg, PKG_PROVIDES);
  349. if (!ab || !ab[0] || !ab[1]) {
  350. pkg_set_ptr(oldpkg, PKG_PROVIDES, pkg_get_ptr(newpkg, PKG_PROVIDES));
  351. pkg_set_ptr(newpkg, PKG_PROVIDES, NULL);
  352. if (ab)
  353. free(ab);
  354. }
  355. if (!pkg_get_ptr(oldpkg, PKG_CONFLICTS)) {
  356. pkg_set_ptr(oldpkg, PKG_CONFLICTS, pkg_get_ptr(newpkg, PKG_CONFLICTS));
  357. pkg_set_ptr(newpkg, PKG_CONFLICTS, NULL);
  358. }
  359. if (!pkg_get_ptr(oldpkg, PKG_REPLACES)) {
  360. pkg_set_ptr(oldpkg, PKG_REPLACES, pkg_get_ptr(newpkg, PKG_REPLACES));
  361. pkg_set_ptr(newpkg, PKG_REPLACES, NULL);
  362. }
  363. if (!pkg_get_string(oldpkg, PKG_FILENAME))
  364. pkg_set_string(oldpkg, PKG_FILENAME, pkg_get_string(newpkg, PKG_FILENAME));
  365. if (!pkg_get_string(oldpkg, PKG_LOCAL_FILENAME))
  366. pkg_set_string(oldpkg, PKG_LOCAL_FILENAME, pkg_get_string(newpkg, PKG_LOCAL_FILENAME));
  367. if (!pkg_get_string(oldpkg, PKG_TMP_UNPACK_DIR))
  368. pkg_set_string(oldpkg, PKG_TMP_UNPACK_DIR, pkg_get_string(newpkg, PKG_TMP_UNPACK_DIR));
  369. if (!pkg_get_md5(oldpkg))
  370. pkg_set_md5(oldpkg, pkg_get_md5(newpkg));
  371. if (!pkg_get_sha256(oldpkg))
  372. pkg_set_sha256(oldpkg, pkg_get_sha256(newpkg));
  373. if (!pkg_get_int(oldpkg, PKG_SIZE))
  374. pkg_set_int(oldpkg, PKG_SIZE, pkg_get_int(newpkg, PKG_SIZE));
  375. if (!pkg_get_int(oldpkg, PKG_INSTALLED_SIZE))
  376. pkg_set_int(oldpkg, PKG_INSTALLED_SIZE, pkg_get_int(newpkg, PKG_INSTALLED_SIZE));
  377. if (!pkg_get_string(oldpkg, PKG_PRIORITY))
  378. pkg_set_string(oldpkg, PKG_PRIORITY, pkg_get_string(newpkg, PKG_PRIORITY));
  379. if (!pkg_get_string(oldpkg, PKG_SOURCE))
  380. pkg_set_string(oldpkg, PKG_SOURCE, pkg_get_string(newpkg, PKG_SOURCE));
  381. if (!pkg_get_string(oldpkg, PKG_ABIVERSION))
  382. pkg_set_string(oldpkg, PKG_ABIVERSION, pkg_get_string(newpkg, PKG_ABIVERSION));
  383. if (!pkg_get_ptr(oldpkg, PKG_CONFFILES)) {
  384. pkg_set_ptr(oldpkg, PKG_CONFFILES, pkg_get_ptr(newpkg, PKG_CONFFILES));
  385. pkg_set_ptr(newpkg, PKG_CONFFILES, NULL);
  386. }
  387. if (!oldpkg->installed_files) {
  388. oldpkg->installed_files = newpkg->installed_files;
  389. oldpkg->installed_files_ref_cnt =
  390. newpkg->installed_files_ref_cnt;
  391. newpkg->installed_files = NULL;
  392. }
  393. if (!oldpkg->essential)
  394. oldpkg->essential = newpkg->essential;
  395. if (!oldpkg->provided_by_hand)
  396. oldpkg->provided_by_hand = newpkg->provided_by_hand;
  397. return 0;
  398. }
  399. static void abstract_pkg_init(abstract_pkg_t * ab_pkg)
  400. {
  401. ab_pkg->provided_by = abstract_pkg_vec_alloc();
  402. ab_pkg->dependencies_checked = 0;
  403. ab_pkg->state_status = SS_NOT_INSTALLED;
  404. }
  405. abstract_pkg_t *abstract_pkg_new(void)
  406. {
  407. abstract_pkg_t *ab_pkg;
  408. ab_pkg = xcalloc(1, sizeof(abstract_pkg_t));
  409. abstract_pkg_init(ab_pkg);
  410. return ab_pkg;
  411. }
  412. static const char *pkg_state_want_to_str(pkg_state_want_t sw)
  413. {
  414. int i;
  415. for (i = 0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
  416. if (pkg_state_want_map[i].value == sw) {
  417. return pkg_state_want_map[i].str;
  418. }
  419. }
  420. opkg_msg(ERROR, "Internal error: state_want=%d\n", sw);
  421. return "<STATE_WANT_UNKNOWN>";
  422. }
  423. pkg_state_want_t pkg_state_want_from_str(char *str)
  424. {
  425. int i;
  426. for (i = 0; i < ARRAY_SIZE(pkg_state_want_map); i++) {
  427. if (strcmp(str, pkg_state_want_map[i].str) == 0) {
  428. return pkg_state_want_map[i].value;
  429. }
  430. }
  431. opkg_msg(ERROR, "Internal error: state_want=%s\n", str);
  432. return SW_UNKNOWN;
  433. }
  434. static char *pkg_state_flag_to_str(pkg_state_flag_t sf)
  435. {
  436. int i;
  437. unsigned int len;
  438. char *str;
  439. /* clear the temporary flags before converting to string */
  440. sf &= SF_NONVOLATILE_FLAGS;
  441. if (sf == 0)
  442. return xstrdup("ok");
  443. len = 0;
  444. for (i = 0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
  445. if (sf & pkg_state_flag_map[i].value)
  446. len += strlen(pkg_state_flag_map[i].str) + 1;
  447. }
  448. str = xmalloc(len + 1);
  449. str[0] = '\0';
  450. for (i = 0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
  451. if (sf & pkg_state_flag_map[i].value) {
  452. strncat(str, pkg_state_flag_map[i].str, len);
  453. strncat(str, ",", len);
  454. }
  455. }
  456. len = strlen(str);
  457. str[len - 1] = '\0'; /* squash last comma */
  458. return str;
  459. }
  460. pkg_state_flag_t pkg_state_flag_from_str(const char *str)
  461. {
  462. int i;
  463. int sf = SF_OK;
  464. const char *sfname;
  465. unsigned int sfname_len;
  466. if (strcmp(str, "ok") == 0) {
  467. return SF_OK;
  468. }
  469. for (i = 0; i < ARRAY_SIZE(pkg_state_flag_map); i++) {
  470. sfname = pkg_state_flag_map[i].str;
  471. sfname_len = strlen(sfname);
  472. if (strncmp(str, sfname, sfname_len) == 0) {
  473. sf |= pkg_state_flag_map[i].value;
  474. str += sfname_len;
  475. if (str[0] == ',') {
  476. str++;
  477. } else {
  478. break;
  479. }
  480. }
  481. }
  482. return sf;
  483. }
  484. static const char *pkg_state_status_to_str(pkg_state_status_t ss)
  485. {
  486. int i;
  487. for (i = 0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
  488. if (pkg_state_status_map[i].value == ss) {
  489. return pkg_state_status_map[i].str;
  490. }
  491. }
  492. opkg_msg(ERROR, "Internal error: state_status=%d\n", ss);
  493. return "<STATE_STATUS_UNKNOWN>";
  494. }
  495. pkg_state_status_t pkg_state_status_from_str(const char *str)
  496. {
  497. int i;
  498. for (i = 0; i < ARRAY_SIZE(pkg_state_status_map); i++) {
  499. if (strcmp(str, pkg_state_status_map[i].str) == 0) {
  500. return pkg_state_status_map[i].value;
  501. }
  502. }
  503. opkg_msg(ERROR, "Internal error: state_status=%s\n", str);
  504. return SS_NOT_INSTALLED;
  505. }
  506. void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field)
  507. {
  508. int i, j;
  509. char *str;
  510. const char *p;
  511. compound_depend_t *dep;
  512. abstract_pkg_t **ab_pkg;
  513. if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) {
  514. goto UNKNOWN_FMT_FIELD;
  515. }
  516. switch (field[0]) {
  517. case 'a':
  518. case 'A':
  519. if (strcasecmp(field, "ABIVersion") == 0) {
  520. p = pkg_get_string(pkg, PKG_ABIVERSION);
  521. if (p) {
  522. fprintf(fp, "ABIVersion: %s\n", p);
  523. }
  524. } else if (strcasecmp(field, "Alternatives") == 0) {
  525. struct pkg_alternatives *pkg_alts = pkg_get_ptr(pkg, PKG_ALTERNATIVES);
  526. if (pkg_alts && pkg_alts->nalts > 0) {
  527. int i;
  528. struct pkg_alternative *alt;
  529. alt = pkg_alts->alts[0];
  530. fprintf(fp, "Alternatives: %d:%s:%s", alt->prio, alt->path, alt->altpath);
  531. for (i = 1; i < pkg_alts->nalts; i++) {
  532. alt = pkg_alts->alts[i];
  533. fprintf(fp, ", %d:%s:%s", alt->prio, alt->path, alt->altpath);
  534. }
  535. fputs("\n", fp);
  536. }
  537. } else if (strcasecmp(field, "Architecture") == 0) {
  538. p = pkg_get_architecture(pkg);
  539. if (p) {
  540. fprintf(fp, "Architecture: %s\n",
  541. p);
  542. }
  543. } else if (strcasecmp(field, "Auto-Installed") == 0) {
  544. if (pkg->auto_installed)
  545. fprintf(fp, "Auto-Installed: yes\n");
  546. } else {
  547. goto UNKNOWN_FMT_FIELD;
  548. }
  549. break;
  550. case 'c':
  551. case 'C':
  552. if (strcasecmp(field, "Conffiles") == 0) {
  553. conffile_list_t *cl;
  554. conffile_list_elt_t *iter;
  555. cl = pkg_get_ptr(pkg, PKG_CONFFILES);
  556. if (!cl || nv_pair_list_empty(cl))
  557. return;
  558. fprintf(fp, "Conffiles:\n");
  559. for (iter = nv_pair_list_first(cl); iter;
  560. iter = nv_pair_list_next(cl, iter)) {
  561. if (((conffile_t *) iter->data)->name
  562. && ((conffile_t *) iter->data)->value) {
  563. fprintf(fp, " %s %s\n",
  564. ((conffile_t *) iter->data)->
  565. name,
  566. ((conffile_t *) iter->data)->
  567. value);
  568. }
  569. }
  570. } else if (strcasecmp(field, "Conflicts") == 0) {
  571. struct depend *cdep;
  572. compound_depend_t *deps, *dep;
  573. deps = pkg_get_ptr(pkg, PKG_CONFLICTS);
  574. if (deps) {
  575. fprintf(fp, "Conflicts:");
  576. for (i = 0, dep = deps; dep->type; dep++, i++) {
  577. cdep = dep->possibilities[0];
  578. fprintf(fp, "%s %s", i == 0 ? "" : ",",
  579. cdep->pkg->name);
  580. if (cdep->version) {
  581. fprintf(fp, " (%s%s)",
  582. constraint_to_str(cdep->
  583. constraint),
  584. cdep->version);
  585. }
  586. }
  587. fprintf(fp, "\n");
  588. }
  589. } else {
  590. goto UNKNOWN_FMT_FIELD;
  591. }
  592. break;
  593. case 'd':
  594. case 'D':
  595. if (strcasecmp(field, "Depends") == 0) {
  596. dep = pkg_get_depends(pkg, DEPEND);
  597. if (dep) {
  598. fprintf(fp, "Depends:");
  599. for (i = 0, j = 0; dep && dep->type; i++, dep++) {
  600. if (dep->type != DEPEND)
  601. continue;
  602. str = pkg_depend_str(pkg, i);
  603. fprintf(fp, "%s %s", j == 0 ? "" : ",",
  604. str);
  605. free(str);
  606. j++;
  607. }
  608. fprintf(fp, "\n");
  609. }
  610. } else if (strcasecmp(field, "Description") == 0) {
  611. p = pkg_get_string(pkg, PKG_DESCRIPTION);
  612. if (p) {
  613. fprintf(fp, "Description: %s\n",
  614. p);
  615. }
  616. } else {
  617. goto UNKNOWN_FMT_FIELD;
  618. }
  619. break;
  620. case 'e':
  621. case 'E':
  622. if (pkg->essential) {
  623. fprintf(fp, "Essential: yes\n");
  624. }
  625. break;
  626. case 'f':
  627. case 'F':
  628. p = pkg_get_string(pkg, PKG_FILENAME);
  629. if (p) {
  630. fprintf(fp, "Filename: %s\n", p);
  631. }
  632. break;
  633. case 'i':
  634. case 'I':
  635. if (strcasecmp(field, "Installed-Size") == 0) {
  636. fprintf(fp, "Installed-Size: %lu\n",
  637. (unsigned long) pkg_get_int(pkg, PKG_INSTALLED_SIZE));
  638. } else if (strcasecmp(field, "Installed-Time") == 0) {
  639. i = pkg_get_int(pkg, PKG_INSTALLED_TIME);
  640. if (i) {
  641. fprintf(fp, "Installed-Time: %lu\n",
  642. (unsigned long) i);
  643. }
  644. }
  645. break;
  646. case 'm':
  647. case 'M':
  648. if (strcasecmp(field, "Maintainer") == 0) {
  649. p = pkg_get_string(pkg, PKG_MAINTAINER);
  650. if (p) {
  651. fprintf(fp, "Maintainer: %s\n", p);
  652. }
  653. } else if (strcasecmp(field, "MD5sum") == 0) {
  654. p = pkg_get_md5(pkg);
  655. if (p) {
  656. fprintf(fp, "MD5Sum: %s\n", p);
  657. }
  658. } else {
  659. goto UNKNOWN_FMT_FIELD;
  660. }
  661. break;
  662. case 'p':
  663. case 'P':
  664. if (strcasecmp(field, "Package") == 0) {
  665. fprintf(fp, "Package: %s\n", pkg->name);
  666. } else if (strcasecmp(field, "Priority") == 0) {
  667. fprintf(fp, "Priority: %s\n", pkg_get_string(pkg, PKG_PRIORITY));
  668. } else if (strcasecmp(field, "Provides") == 0) {
  669. ab_pkg = pkg_get_ptr(pkg, PKG_PROVIDES);
  670. if (ab_pkg && ab_pkg[0] && ab_pkg[1]) {
  671. fprintf(fp, "Provides:");
  672. for (i = 1; ab_pkg[i]; i++) {
  673. fprintf(fp, "%s %s", i == 1 ? "" : ",",
  674. ab_pkg[i]->name);
  675. }
  676. fprintf(fp, "\n");
  677. }
  678. } else {
  679. goto UNKNOWN_FMT_FIELD;
  680. }
  681. break;
  682. case 'r':
  683. case 'R':
  684. if (strcasecmp(field, "Replaces") == 0) {
  685. ab_pkg = pkg_get_ptr(pkg, PKG_REPLACES);
  686. if (ab_pkg && ab_pkg[0]) {
  687. fprintf(fp, "Replaces:");
  688. for (i = 0; ab_pkg[i]; i++) {
  689. fprintf(fp, "%s %s", i == 0 ? "" : ",",
  690. ab_pkg[i]->name);
  691. }
  692. fprintf(fp, "\n");
  693. }
  694. } else if (strcasecmp(field, "Recommends") == 0) {
  695. dep = pkg_get_depends(pkg, RECOMMEND);
  696. if (dep) {
  697. fprintf(fp, "Recommends:");
  698. for (j = 0, i = 0; dep && dep->type; i++, dep++) {
  699. if (dep->type != RECOMMEND)
  700. continue;
  701. str = pkg_depend_str(pkg, i);
  702. fprintf(fp, "%s %s", j == 0 ? "" : ",",
  703. str);
  704. free(str);
  705. j++;
  706. }
  707. fprintf(fp, "\n");
  708. }
  709. } else {
  710. goto UNKNOWN_FMT_FIELD;
  711. }
  712. break;
  713. case 's':
  714. case 'S':
  715. if (strcasecmp(field, "Section") == 0) {
  716. p = pkg_get_string(pkg, PKG_SECTION);
  717. if (p) {
  718. fprintf(fp, "Section: %s\n", p);
  719. }
  720. } else if (strcasecmp(field, "SHA256sum") == 0) {
  721. p = pkg_get_string(pkg, PKG_SHA256SUM);
  722. if (p) {
  723. fprintf(fp, "SHA256sum: %s\n", p);
  724. }
  725. } else if (strcasecmp(field, "Size") == 0) {
  726. i = pkg_get_int(pkg, PKG_SIZE);
  727. if (i) {
  728. fprintf(fp, "Size: %lu\n", (unsigned long) i);
  729. }
  730. } else if (strcasecmp(field, "Source") == 0) {
  731. p = pkg_get_string(pkg, PKG_SOURCE);
  732. if (p) {
  733. fprintf(fp, "Source: %s\n", p);
  734. }
  735. } else if (strcasecmp(field, "Status") == 0) {
  736. char *pflag = pkg_state_flag_to_str(pkg->state_flag);
  737. fprintf(fp, "Status: %s %s %s\n",
  738. pkg_state_want_to_str(pkg->state_want),
  739. pflag,
  740. pkg_state_status_to_str(pkg->state_status));
  741. free(pflag);
  742. } else if (strcasecmp(field, "Suggests") == 0) {
  743. dep = pkg_get_depends(pkg, SUGGEST);
  744. if (dep) {
  745. fprintf(fp, "Suggests:");
  746. for (j = 0, i = 0; dep && dep->type; i++, dep++) {
  747. if (dep->type != SUGGEST)
  748. continue;
  749. str = pkg_depend_str(pkg, i);
  750. fprintf(fp, "%s %s", j == 0 ? "" : ",",
  751. str);
  752. free(str);
  753. j++;
  754. }
  755. fprintf(fp, "\n");
  756. }
  757. } else {
  758. goto UNKNOWN_FMT_FIELD;
  759. }
  760. break;
  761. case 't':
  762. case 'T':
  763. if (strcasecmp(field, "Tags") == 0) {
  764. p = pkg_get_string(pkg, PKG_TAGS);
  765. if (p) {
  766. fprintf(fp, "Tags: %s\n", p);
  767. }
  768. }
  769. break;
  770. case 'v':
  771. case 'V':
  772. {
  773. char *version = pkg_version_str_alloc(pkg);
  774. if (version == NULL)
  775. return;
  776. fprintf(fp, "Version: %s\n", version);
  777. free(version);
  778. }
  779. break;
  780. default:
  781. goto UNKNOWN_FMT_FIELD;
  782. }
  783. return;
  784. UNKNOWN_FMT_FIELD:
  785. opkg_msg(ERROR, "Internal error: field=%s\n", field);
  786. }
  787. void pkg_formatted_info(FILE * fp, pkg_t * pkg)
  788. {
  789. pkg_formatted_field(fp, pkg, "Package");
  790. pkg_formatted_field(fp, pkg, "Version");
  791. pkg_formatted_field(fp, pkg, "Depends");
  792. pkg_formatted_field(fp, pkg, "Recommends");
  793. pkg_formatted_field(fp, pkg, "Suggests");
  794. pkg_formatted_field(fp, pkg, "Provides");
  795. pkg_formatted_field(fp, pkg, "Replaces");
  796. pkg_formatted_field(fp, pkg, "Conflicts");
  797. pkg_formatted_field(fp, pkg, "Status");
  798. pkg_formatted_field(fp, pkg, "Section");
  799. pkg_formatted_field(fp, pkg, "Essential");
  800. pkg_formatted_field(fp, pkg, "Architecture");
  801. pkg_formatted_field(fp, pkg, "Maintainer");
  802. pkg_formatted_field(fp, pkg, "MD5sum");
  803. pkg_formatted_field(fp, pkg, "Size");
  804. pkg_formatted_field(fp, pkg, "Filename");
  805. pkg_formatted_field(fp, pkg, "Conffiles");
  806. pkg_formatted_field(fp, pkg, "Source");
  807. pkg_formatted_field(fp, pkg, "Description");
  808. pkg_formatted_field(fp, pkg, "Installed-Time");
  809. pkg_formatted_field(fp, pkg, "Tags");
  810. fputs("\n", fp);
  811. }
  812. void pkg_print_status(pkg_t * pkg, FILE * file)
  813. {
  814. if (pkg == NULL) {
  815. return;
  816. }
  817. pkg_formatted_field(file, pkg, "Package");
  818. pkg_formatted_field(file, pkg, "ABIVersion");
  819. pkg_formatted_field(file, pkg, "Version");
  820. pkg_formatted_field(file, pkg, "Depends");
  821. pkg_formatted_field(file, pkg, "Recommends");
  822. pkg_formatted_field(file, pkg, "Suggests");
  823. pkg_formatted_field(file, pkg, "Provides");
  824. pkg_formatted_field(file, pkg, "Replaces");
  825. pkg_formatted_field(file, pkg, "Conflicts");
  826. pkg_formatted_field(file, pkg, "Status");
  827. pkg_formatted_field(file, pkg, "Essential");
  828. pkg_formatted_field(file, pkg, "Architecture");
  829. pkg_formatted_field(file, pkg, "Conffiles");
  830. pkg_formatted_field(file, pkg, "Installed-Time");
  831. pkg_formatted_field(file, pkg, "Auto-Installed");
  832. pkg_formatted_field(file, pkg, "Alternatives");
  833. fputs("\n", file);
  834. }
  835. /*
  836. * libdpkg - Debian packaging suite library routines
  837. * vercmp.c - comparison of version numbers
  838. *
  839. * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
  840. */
  841. /* assume ascii; warning: evaluates x multiple times! */
  842. #define order(x) ((x) == '~' ? -1 \
  843. : isdigit((x)) ? 0 \
  844. : !(x) ? 0 \
  845. : isalpha((x)) ? (x) \
  846. : (x) + 256)
  847. static int verrevcmp(const char *val, const char *ref)
  848. {
  849. if (!val)
  850. val = "";
  851. if (!ref)
  852. ref = "";
  853. while (*val || *ref) {
  854. int first_diff = 0;
  855. while ((*val && !isdigit(*val)) || (*ref && !isdigit(*ref))) {
  856. int vc = order(*val), rc = order(*ref);
  857. if (vc != rc)
  858. return vc - rc;
  859. val++;
  860. ref++;
  861. }
  862. while (*val == '0')
  863. val++;
  864. while (*ref == '0')
  865. ref++;
  866. while (isdigit(*val) && isdigit(*ref)) {
  867. if (!first_diff)
  868. first_diff = *val - *ref;
  869. val++;
  870. ref++;
  871. }
  872. if (isdigit(*val))
  873. return 1;
  874. if (isdigit(*ref))
  875. return -1;
  876. if (first_diff)
  877. return first_diff;
  878. }
  879. return 0;
  880. }
  881. int pkg_compare_versions(const pkg_t * pkg, const pkg_t * ref_pkg)
  882. {
  883. unsigned int epoch1 = (unsigned int) pkg_get_int(pkg, PKG_EPOCH);
  884. unsigned int epoch2 = (unsigned int) pkg_get_int(ref_pkg, PKG_EPOCH);
  885. char *revision1 = pkg_get_string(pkg, PKG_REVISION);
  886. char *revision2 = pkg_get_string(ref_pkg, PKG_REVISION);
  887. const char *version1 = pkg_get_string(pkg, PKG_VERSION);
  888. const char *version2 = pkg_get_string(ref_pkg, PKG_VERSION);
  889. int r;
  890. if (epoch1 > epoch2) {
  891. return 1;
  892. }
  893. if (epoch1 < epoch2) {
  894. return -1;
  895. }
  896. r = verrevcmp(version1, version2);
  897. if (r) {
  898. return r;
  899. }
  900. r = verrevcmp(revision1, revision2);
  901. if (r) {
  902. return r;
  903. }
  904. return r;
  905. }
  906. int pkg_version_satisfied(pkg_t * it, pkg_t * ref, const char *op)
  907. {
  908. int r;
  909. r = pkg_compare_versions(it, ref);
  910. if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0) {
  911. return r <= 0;
  912. }
  913. if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0) {
  914. return r >= 0;
  915. }
  916. if (strcmp(op, "<<") == 0) {
  917. return r < 0;
  918. }
  919. if (strcmp(op, ">>") == 0) {
  920. return r > 0;
  921. }
  922. if (strcmp(op, "=") == 0) {
  923. return r == 0;
  924. }
  925. opkg_msg(ERROR, "Unknown operator: %s.\n", op);
  926. return 0;
  927. }
  928. int pkg_name_version_and_architecture_compare(const void *p1, const void *p2)
  929. {
  930. const pkg_t * a = *(const pkg_t **)p1;
  931. const pkg_t * b = *(const pkg_t **)p2;
  932. int namecmp;
  933. int vercmp;
  934. int arch_prio1, arch_prio2;
  935. if (!a->name || !b->name) {
  936. opkg_msg(ERROR, "Internal error: a->name=%p, b->name=%p.\n",
  937. a->name, b->name);
  938. return 0;
  939. }
  940. namecmp = strcmp(a->name, b->name);
  941. if (namecmp)
  942. return namecmp;
  943. vercmp = pkg_compare_versions(a, b);
  944. if (vercmp)
  945. return vercmp;
  946. arch_prio1 = pkg_get_arch_priority(a);
  947. arch_prio2 = pkg_get_arch_priority(b);
  948. if (!arch_prio1 || !arch_prio2) {
  949. opkg_msg(ERROR,
  950. "Internal error: a->arch_priority=%i b->arch_priority=%i.\n",
  951. arch_prio1, arch_prio2);
  952. return 0;
  953. }
  954. if (arch_prio1 > arch_prio2)
  955. return 1;
  956. if (arch_prio1 < arch_prio2)
  957. return -1;
  958. return 0;
  959. }
  960. int abstract_pkg_name_compare(const void *p1, const void *p2)
  961. {
  962. const abstract_pkg_t *a = *(const abstract_pkg_t **)p1;
  963. const abstract_pkg_t *b = *(const abstract_pkg_t **)p2;
  964. if (!a->name || !b->name) {
  965. opkg_msg(ERROR, "Internal error: a->name=%p b->name=%p.\n",
  966. a->name, b->name);
  967. return 0;
  968. }
  969. return strcmp(a->name, b->name);
  970. }
  971. char *pkg_version_str_alloc(pkg_t * pkg)
  972. {
  973. const char *verstr;
  974. char *version, *revptr;
  975. unsigned int epoch = (unsigned int) pkg_get_int(pkg, PKG_EPOCH);
  976. revptr = pkg_get_string(pkg, PKG_REVISION);
  977. verstr = pkg_get_string(pkg, PKG_VERSION);
  978. if (epoch) {
  979. if (revptr)
  980. sprintf_alloc(&version, "%d:%s-%s",
  981. epoch, verstr, revptr);
  982. else
  983. sprintf_alloc(&version, "%d:%s",
  984. epoch, verstr);
  985. } else {
  986. if (revptr)
  987. sprintf_alloc(&version, "%s-%s",
  988. verstr, revptr);
  989. else
  990. version = xstrdup(verstr);
  991. }
  992. return version;
  993. }
  994. /*
  995. * XXX: this should be broken into two functions
  996. */
  997. str_list_t *pkg_get_installed_files(pkg_t * pkg)
  998. {
  999. int err, fd;
  1000. char *list_file_name = NULL;
  1001. FILE *list_file = NULL;
  1002. char *line;
  1003. char *installed_file_name;
  1004. unsigned int rootdirlen = 0;
  1005. int list_from_package;
  1006. const char *local_filename;
  1007. pkg->installed_files_ref_cnt++;
  1008. if (pkg->installed_files) {
  1009. return pkg->installed_files;
  1010. }
  1011. pkg->installed_files = str_list_alloc();
  1012. /*
  1013. * For installed packages, look at the package.list file in the database.
  1014. * For uninstalled packages, get the file list directly from the package.
  1015. */
  1016. if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL)
  1017. list_from_package = 1;
  1018. else
  1019. list_from_package = 0;
  1020. if (list_from_package) {
  1021. local_filename = pkg_get_string(pkg, PKG_LOCAL_FILENAME);
  1022. if (!local_filename) {
  1023. return pkg->installed_files;
  1024. }
  1025. /* XXX: CLEANUP: Maybe rewrite this to avoid using a temporary
  1026. file. In other words, change deb_extract so that it can
  1027. simply return the file list as a char *[] rather than
  1028. insisting on writing it to a FILE * as it does now. */
  1029. sprintf_alloc(&list_file_name, "%s/%s.list.XXXXXX",
  1030. conf->tmp_dir, pkg->name);
  1031. fd = mkstemp(list_file_name);
  1032. if (fd == -1) {
  1033. opkg_perror(ERROR, "Failed to make temp file %s.",
  1034. list_file_name);
  1035. free(list_file_name);
  1036. return pkg->installed_files;
  1037. }
  1038. list_file = fdopen(fd, "r+");
  1039. if (list_file == NULL) {
  1040. opkg_perror(ERROR, "Failed to fdopen temp file %s.",
  1041. list_file_name);
  1042. close(fd);
  1043. unlink(list_file_name);
  1044. free(list_file_name);
  1045. return pkg->installed_files;
  1046. }
  1047. err = pkg_extract_data_file_names_to_stream(pkg, list_file);
  1048. if (err) {
  1049. opkg_msg(ERROR, "Error extracting file list from %s.\n",
  1050. local_filename);
  1051. fclose(list_file);
  1052. unlink(list_file_name);
  1053. free(list_file_name);
  1054. str_list_deinit(pkg->installed_files);
  1055. pkg->installed_files = NULL;
  1056. return NULL;
  1057. }
  1058. rewind(list_file);
  1059. } else {
  1060. sprintf_alloc(&list_file_name, "%s/%s.list",
  1061. pkg->dest->info_dir, pkg->name);
  1062. list_file = fopen(list_file_name, "r");
  1063. if (list_file == NULL) {
  1064. opkg_perror(ERROR, "Failed to open %s", list_file_name);
  1065. free(list_file_name);
  1066. return pkg->installed_files;
  1067. }
  1068. free(list_file_name);
  1069. }
  1070. if (conf->offline_root)
  1071. rootdirlen = strlen(conf->offline_root);
  1072. while (1) {
  1073. char *file_name;
  1074. line = file_read_line_alloc(list_file);
  1075. if (line == NULL) {
  1076. break;
  1077. }
  1078. file_name = line;
  1079. if (list_from_package) {
  1080. if (*file_name == '.') {
  1081. file_name++;
  1082. }
  1083. if (*file_name == '/') {
  1084. file_name++;
  1085. }
  1086. sprintf_alloc(&installed_file_name, "%s%s",
  1087. pkg->dest->root_dir, file_name);
  1088. } else {
  1089. if (conf->offline_root &&
  1090. strncmp(conf->offline_root, file_name,
  1091. rootdirlen)) {
  1092. sprintf_alloc(&installed_file_name, "%s%s",
  1093. conf->offline_root, file_name);
  1094. } else {
  1095. // already contains root_dir as header -> ABSOLUTE
  1096. sprintf_alloc(&installed_file_name, "%s",
  1097. file_name);
  1098. }
  1099. }
  1100. str_list_append(pkg->installed_files, installed_file_name);
  1101. free(installed_file_name);
  1102. free(line);
  1103. }
  1104. fclose(list_file);
  1105. if (list_from_package) {
  1106. unlink(list_file_name);
  1107. free(list_file_name);
  1108. }
  1109. return pkg->installed_files;
  1110. }
  1111. /* XXX: CLEANUP: This function and it's counterpart,
  1112. (pkg_get_installed_files), do not match our init/deinit naming
  1113. convention. Nor the alloc/free convention. But, then again, neither
  1114. of these conventions currrently fit the way these two functions
  1115. work. */
  1116. void pkg_free_installed_files(pkg_t * pkg)
  1117. {
  1118. pkg->installed_files_ref_cnt--;
  1119. if (pkg->installed_files_ref_cnt > 0)
  1120. return;
  1121. if (pkg->installed_files) {
  1122. str_list_purge(pkg->installed_files);
  1123. }
  1124. pkg->installed_files = NULL;
  1125. }
  1126. void pkg_remove_installed_files_list(pkg_t * pkg)
  1127. {
  1128. char *list_file_name;
  1129. sprintf_alloc(&list_file_name, "%s/%s.list",
  1130. pkg->dest->info_dir, pkg->name);
  1131. if (!conf->noaction)
  1132. (void)unlink(list_file_name);
  1133. free(list_file_name);
  1134. }
  1135. conffile_t *pkg_get_conffile(pkg_t * pkg, const char *file_name)
  1136. {
  1137. conffile_list_elt_t *iter;
  1138. conffile_list_t *cl;
  1139. conffile_t *conffile;
  1140. if (pkg == NULL) {
  1141. return NULL;
  1142. }
  1143. cl = pkg_get_ptr(pkg, PKG_CONFFILES);
  1144. for (iter = cl ? nv_pair_list_first(cl) : NULL; iter;
  1145. iter = nv_pair_list_next(cl, iter)) {
  1146. conffile = (conffile_t *) iter->data;
  1147. if (strcmp(conffile->name, file_name) == 0) {
  1148. return conffile;
  1149. }
  1150. }
  1151. return NULL;
  1152. }
  1153. int pkg_run_script(pkg_t * pkg, const char *script, const char *args)
  1154. {
  1155. int err;
  1156. char *path;
  1157. char *cmd;
  1158. char *tmp_unpack_dir;
  1159. if (conf->noaction)
  1160. return 0;
  1161. /* XXX: FEATURE: When conf->offline_root is set, we should run the
  1162. maintainer script within a chroot environment. */
  1163. if (conf->offline_root && !conf->force_postinstall) {
  1164. opkg_msg(INFO, "Offline root mode: not running %s.%s.\n",
  1165. pkg->name, script);
  1166. return 0;
  1167. }
  1168. /* Installed packages have scripts in pkg->dest->info_dir, uninstalled packages
  1169. have scripts in tmp_unpack_dir. */
  1170. if (pkg->state_status == SS_INSTALLED
  1171. || pkg->state_status == SS_UNPACKED
  1172. || pkg->state_status == SS_HALF_INSTALLED) {
  1173. if (pkg->dest == NULL) {
  1174. opkg_msg(ERROR, "Internal error: %s has a NULL dest.\n",
  1175. pkg->name);
  1176. return -1;
  1177. }
  1178. sprintf_alloc(&path, "%s/%s.%s", pkg->dest->info_dir, pkg->name,
  1179. script);
  1180. } else {
  1181. tmp_unpack_dir = pkg_get_string(pkg, PKG_TMP_UNPACK_DIR);
  1182. if (tmp_unpack_dir == NULL) {
  1183. opkg_msg(ERROR,
  1184. "Internal error: %s has a NULL tmp_unpack_dir.\n",
  1185. pkg->name);
  1186. return -1;
  1187. }
  1188. sprintf_alloc(&path, "%s/%s", tmp_unpack_dir, script);
  1189. }
  1190. opkg_msg(INFO, "Running script %s.\n", path);
  1191. setenv("PKG_ROOT",
  1192. pkg->dest ? pkg->dest->root_dir : conf->default_dest->root_dir,
  1193. 1);
  1194. if (pkg->is_upgrade)
  1195. setenv("PKG_UPGRADE", "1", 1);
  1196. else
  1197. setenv("PKG_UPGRADE", "0", 1);
  1198. if (!file_exists(path)) {
  1199. free(path);
  1200. return 0;
  1201. }
  1202. sprintf_alloc(&cmd, "%s %s", path, args);
  1203. free(path);
  1204. {
  1205. const char *argv[] = { "/bin/sh", "-c", cmd, NULL };
  1206. err = xsystem(argv);
  1207. }
  1208. free(cmd);
  1209. if (err) {
  1210. opkg_msg(ERROR,
  1211. "package \"%s\" %s script returned status %d.\n",
  1212. pkg->name, script, err);
  1213. return err;
  1214. }
  1215. return 0;
  1216. }
  1217. int pkg_arch_supported(pkg_t * pkg)
  1218. {
  1219. nv_pair_list_elt_t *l;
  1220. char *architecture = pkg_get_architecture(pkg);
  1221. if (!architecture)
  1222. return 1;
  1223. list_for_each_entry(l, &conf->arch_list.head, node) {
  1224. nv_pair_t *nv = (nv_pair_t *) l->data;
  1225. if (strcmp(nv->name, architecture) == 0) {
  1226. opkg_msg(DEBUG,
  1227. "Arch %s (priority %s) supported for pkg %s.\n",
  1228. nv->name, nv->value, pkg->name);
  1229. return 1;
  1230. }
  1231. }
  1232. opkg_msg(DEBUG, "Arch %s unsupported for pkg %s.\n",
  1233. architecture, pkg->name);
  1234. return 0;
  1235. }
  1236. void pkg_info_preinstall_check(void)
  1237. {
  1238. int i;
  1239. pkg_vec_t *installed_pkgs = pkg_vec_alloc();
  1240. /* update the file owner data structure */
  1241. opkg_msg(INFO, "Updating file owner list.\n");
  1242. pkg_hash_fetch_all_installed(installed_pkgs);
  1243. for (i = 0; i < installed_pkgs->len; i++) {
  1244. pkg_t *pkg = installed_pkgs->pkgs[i];
  1245. str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */
  1246. str_list_elt_t *iter, *niter;
  1247. if (installed_files == NULL) {
  1248. opkg_msg(ERROR, "Failed to determine installed "
  1249. "files for pkg %s.\n", pkg->name);
  1250. break;
  1251. }
  1252. for (iter = str_list_first(installed_files), niter =
  1253. str_list_next(installed_files, iter); iter;
  1254. iter = niter, niter =
  1255. str_list_next(installed_files, iter)) {
  1256. char *installed_file = (char *)iter->data;
  1257. file_hash_set_file_owner(installed_file, pkg);
  1258. }
  1259. pkg_free_installed_files(pkg);
  1260. }
  1261. pkg_vec_free(installed_pkgs);
  1262. }
  1263. struct pkg_write_filelist_data {
  1264. pkg_t *pkg;
  1265. FILE *stream;
  1266. };
  1267. static void
  1268. pkg_write_filelist_helper(const char *key, void *entry_, void *data_)
  1269. {
  1270. struct pkg_write_filelist_data *data = data_;
  1271. pkg_t *entry = entry_;
  1272. if (entry == data->pkg) {
  1273. fprintf(data->stream, "%s\n", key);
  1274. }
  1275. }
  1276. int pkg_write_filelist(pkg_t * pkg)
  1277. {
  1278. struct pkg_write_filelist_data data;
  1279. char *list_file_name;
  1280. sprintf_alloc(&list_file_name, "%s/%s.list",
  1281. pkg->dest->info_dir, pkg->name);
  1282. opkg_msg(INFO, "Creating %s file for pkg %s.\n",
  1283. list_file_name, pkg->name);
  1284. data.stream = fopen(list_file_name, "w");
  1285. if (!data.stream) {
  1286. opkg_perror(ERROR, "Failed to open %s", list_file_name);
  1287. free(list_file_name);
  1288. return -1;
  1289. }
  1290. data.pkg = pkg;
  1291. hash_table_foreach(&conf->file_hash, pkg_write_filelist_helper, &data);
  1292. fclose(data.stream);
  1293. free(list_file_name);
  1294. pkg->state_flag &= ~SF_FILELIST_CHANGED;
  1295. return 0;
  1296. }
  1297. int pkg_write_changed_filelists(void)
  1298. {
  1299. pkg_vec_t *installed_pkgs = pkg_vec_alloc();
  1300. int i, err, ret = 0;
  1301. if (conf->noaction)
  1302. return 0;
  1303. opkg_msg(INFO, "Saving changed filelists.\n");
  1304. pkg_hash_fetch_all_installed(installed_pkgs);
  1305. for (i = 0; i < installed_pkgs->len; i++) {
  1306. pkg_t *pkg = installed_pkgs->pkgs[i];
  1307. if (pkg->state_flag & SF_FILELIST_CHANGED) {
  1308. err = pkg_write_filelist(pkg);
  1309. if (err)
  1310. ret = -1;
  1311. }
  1312. }
  1313. pkg_vec_free(installed_pkgs);
  1314. return ret;
  1315. }