help.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. /*
  2. * dpkg - main program for package management
  3. * help.c - various helper routines
  4. *
  5. * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
  6. *
  7. * This is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation; either version 2,
  10. * or (at your option) any later version.
  11. *
  12. * This is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public
  18. * License along with dpkg; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include <config.h>
  22. #include <compat.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <sys/wait.h>
  26. #include <assert.h>
  27. #include <errno.h>
  28. #include <string.h>
  29. #include <time.h>
  30. #include <dirent.h>
  31. #include <unistd.h>
  32. #include <stdlib.h>
  33. #include <dpkg/i18n.h>
  34. #include <dpkg/dpkg.h>
  35. #include <dpkg/dpkg-db.h>
  36. #include <dpkg/path.h>
  37. #include <dpkg/subproc.h>
  38. #include "filesdb.h"
  39. #include "main.h"
  40. const char *const statusstrings[]= {
  41. N_("not installed"),
  42. N_("not installed but configs remain"),
  43. N_("broken due to failed removal or installation"),
  44. N_("unpacked but not configured"),
  45. N_("broken due to postinst failure"),
  46. N_("awaiting trigger processing by another package"),
  47. N_("triggered"),
  48. N_("installed")
  49. };
  50. struct filenamenode *namenodetouse(struct filenamenode *namenode, struct pkginfo *pkg) {
  51. struct filenamenode *r;
  52. if (!namenode->divert) {
  53. r = namenode;
  54. return r;
  55. }
  56. debug(dbg_eachfile,"namenodetouse namenode=`%s' pkg=%s",
  57. namenode->name,pkg->name);
  58. r=
  59. (namenode->divert->useinstead && namenode->divert->pkg != pkg)
  60. ? namenode->divert->useinstead : namenode;
  61. debug(dbg_eachfile,
  62. "namenodetouse ... useinstead=%s camefrom=%s pkg=%s return %s",
  63. namenode->divert->useinstead ? namenode->divert->useinstead->name : "<none>",
  64. namenode->divert->camefrom ? namenode->divert->camefrom->name : "<none>",
  65. namenode->divert->pkg ? namenode->divert->pkg->name : "<none>",
  66. r->name);
  67. return r;
  68. }
  69. void checkpath(void) {
  70. /* Verify that some programs can be found in the PATH. */
  71. static const char *const prog_list[] = {
  72. DEFAULTSHELL,
  73. RM,
  74. TAR,
  75. FIND,
  76. BACKEND,
  77. "ldconfig",
  78. #if WITH_START_STOP_DAEMON
  79. "start-stop-daemon",
  80. #endif
  81. "update-rc.d",
  82. NULL
  83. };
  84. const char *const *prog;
  85. const char *path_list;
  86. char *filename;
  87. int warned= 0;
  88. path_list = getenv("PATH");
  89. if (!path_list)
  90. ohshit(_("error: PATH is not set."));
  91. filename = m_malloc(strlen(path_list) + 2 + strlen("start-stop-daemon"));
  92. for (prog = prog_list; *prog; prog++) {
  93. struct stat stab;
  94. const char *path, *path_end;
  95. size_t path_len;
  96. path = path_list;
  97. while (path) {
  98. path_end = strchr(path, ':');
  99. path_len = path_end ? (size_t)(path_end - path) : strlen(path);
  100. memcpy(filename, path, path_len);
  101. if (path_len)
  102. filename[path_len++] = '/';
  103. strcpy(filename + path_len, *prog);
  104. if (stat(filename, &stab) == 0 && (stab.st_mode & 0111))
  105. break;
  106. path = path_end;
  107. if (path)
  108. path++;
  109. }
  110. if (!path) {
  111. warning(_("'%s' not found on PATH."), *prog);
  112. warned++;
  113. }
  114. }
  115. free(filename);
  116. if (warned)
  117. forcibleerr(fc_badpath,_("%d expected program(s) not found on PATH.\nNB: root's "
  118. "PATH should usually contain /usr/local/sbin, /usr/sbin and /sbin."),
  119. warned);
  120. }
  121. bool
  122. ignore_depends(struct pkginfo *pkg)
  123. {
  124. struct pkg_list *id;
  125. for (id= ignoredependss; id; id= id->next)
  126. if (id->pkg == pkg)
  127. return true;
  128. return false;
  129. }
  130. bool
  131. force_depends(struct deppossi *possi)
  132. {
  133. return fc_depends ||
  134. ignore_depends(possi->ed) ||
  135. ignore_depends(possi->up->up);
  136. }
  137. bool
  138. force_breaks(struct deppossi *possi)
  139. {
  140. return fc_breaks ||
  141. ignore_depends(possi->ed) ||
  142. ignore_depends(possi->up->up);
  143. }
  144. bool
  145. force_conflicts(struct deppossi *possi)
  146. {
  147. return fc_conflicts;
  148. }
  149. static const char* preexecscript(const char *path, char *const *argv) {
  150. /* returns the path to the script inside the chroot
  151. * FIXME: none of the stuff here will work if admindir isn't inside
  152. * instdir as expected.
  153. */
  154. size_t instdirl;
  155. if (*instdir) {
  156. if (chroot(instdir)) ohshite(_("failed to chroot to `%.250s'"),instdir);
  157. if (chdir("/"))
  158. ohshite(_("failed to chdir to `%.255s'"), "/");
  159. }
  160. if (f_debug & dbg_scripts) {
  161. struct varbuf args = VARBUF_INIT;
  162. while (*++argv) {
  163. varbufaddc(&args, ' ');
  164. varbufaddstr(&args, *argv);
  165. }
  166. varbufaddc(&args, '\0');
  167. debug(dbg_scripts, "fork/exec %s (%s )", path, args.buf);
  168. varbuffree(&args);
  169. }
  170. instdirl= strlen(instdir);
  171. if (!instdirl) return path;
  172. assert (strlen(path)>=instdirl);
  173. return path+instdirl;
  174. }
  175. static char *const *vbuildarglist(const char *scriptname, va_list ap) {
  176. static char *bufs[PKGSCRIPTMAXARGS+1];
  177. char *nextarg;
  178. int i;
  179. i=0;
  180. if(bufs[0]) free(bufs[0]);
  181. /* Yes, cast away const because exec wants it that way */
  182. bufs[i++] = m_strdup(scriptname);
  183. for (;;) {
  184. assert(i < PKGSCRIPTMAXARGS);
  185. nextarg= va_arg(ap,char*);
  186. if (!nextarg) break;
  187. bufs[i++]= nextarg;
  188. }
  189. bufs[i] = NULL;
  190. return bufs;
  191. }
  192. static char *const *buildarglist(const char *scriptname, ...) {
  193. char *const *arglist;
  194. va_list ap;
  195. va_start(ap,scriptname);
  196. arglist= vbuildarglist(scriptname,ap);
  197. va_end(ap);
  198. return arglist;
  199. }
  200. void
  201. post_postinst_tasks(struct pkginfo *pkg, enum pkgstatus new_status)
  202. {
  203. pkg->trigpend_head = NULL;
  204. pkg->status = pkg->trigaw.head ? stat_triggersawaited : new_status;
  205. post_postinst_tasks_core(pkg);
  206. }
  207. void
  208. post_postinst_tasks_core(struct pkginfo *pkg)
  209. {
  210. modstatdb_note(pkg);
  211. if (!f_noact) {
  212. debug(dbg_triggersdetail, "post_postinst_tasks_core - trig_incorporate");
  213. trig_incorporate(msdbrw_write, admindir);
  214. }
  215. }
  216. static void
  217. post_script_tasks(void)
  218. {
  219. ensure_diversions();
  220. debug(dbg_triggersdetail,
  221. "post_script_tasks - ensure_diversions; trig_incorporate");
  222. trig_incorporate(msdbrw_write, admindir);
  223. }
  224. static void
  225. cu_post_script_tasks(int argc, void **argv)
  226. {
  227. post_script_tasks();
  228. }
  229. static void setexecute(const char *path, struct stat *stab) {
  230. if ((stab->st_mode & 0555) == 0555) return;
  231. if (!chmod(path,0755)) return;
  232. ohshite(_("unable to set execute permissions on `%.250s'"),path);
  233. }
  234. static int
  235. do_script(struct pkginfo *pkg, struct pkginfoperfile *pif,
  236. const char *scriptname, const char *scriptpath, struct stat *stab,
  237. char *const arglist[], const char *desc, const char *name, int warn)
  238. {
  239. const char *scriptexec;
  240. int c1, r;
  241. setexecute(scriptpath,stab);
  242. push_cleanup(cu_post_script_tasks, ehflag_bombout, NULL, 0, 0);
  243. c1= m_fork();
  244. if (!c1) {
  245. const char **narglist;
  246. for (r=0; arglist[r]; r++) ;
  247. narglist=nfmalloc((r+1)*sizeof(char*));
  248. for (r=1; arglist[r-1]; r++)
  249. narglist[r]= arglist[r];
  250. scriptexec= preexecscript(scriptpath,(char * const *)narglist);
  251. narglist[0]= scriptexec;
  252. if (setenv(MAINTSCRIPTPKGENVVAR, pkg->name, 1) ||
  253. setenv(MAINTSCRIPTARCHENVVAR, pif->architecture, 1) ||
  254. setenv(MAINTSCRIPTDPKGENVVAR, PACKAGE_VERSION, 1))
  255. ohshite(_("unable to setenv for maintainer script"));
  256. execv(scriptexec,(char * const *)narglist);
  257. ohshite(desc,name);
  258. }
  259. subproc_signals_setup(name); /* This does a push_cleanup() */
  260. r = subproc_wait_check(c1, name, warn);
  261. pop_cleanup(ehflag_normaltidy);
  262. pop_cleanup(ehflag_normaltidy);
  263. return r;
  264. }
  265. static int
  266. vmaintainer_script_installed(struct pkginfo *pkg, const char *scriptname,
  267. const char *desc, va_list ap)
  268. {
  269. const char *scriptpath;
  270. char *const *arglist;
  271. struct stat stab;
  272. char buf[100];
  273. scriptpath= pkgadminfile(pkg,scriptname);
  274. arglist= vbuildarglist(scriptname,ap);
  275. sprintf(buf, _("installed %s script"), desc);
  276. if (stat(scriptpath,&stab)) {
  277. if (errno == ENOENT) {
  278. debug(dbg_scripts, "vmaintainer_script_installed nonexistent %s",
  279. scriptname);
  280. return 0;
  281. }
  282. ohshite(_("unable to stat %s `%.250s'"), buf, scriptpath);
  283. }
  284. do_script(pkg, &pkg->installed, scriptname, scriptpath, &stab,
  285. arglist, _("unable to execute %s"), buf, 0);
  286. return 1;
  287. }
  288. /* All ...'s are const char*'s. */
  289. int
  290. maintainer_script_installed(struct pkginfo *pkg, const char *scriptname,
  291. const char *desc, ...)
  292. {
  293. int r;
  294. va_list ap;
  295. va_start(ap, desc);
  296. r = vmaintainer_script_installed(pkg, scriptname, desc, ap);
  297. va_end(ap);
  298. if (r)
  299. post_script_tasks();
  300. return r;
  301. }
  302. int
  303. maintainer_script_postinst(struct pkginfo *pkg, ...)
  304. {
  305. int r;
  306. va_list ap;
  307. va_start(ap, pkg);
  308. r = vmaintainer_script_installed(pkg, POSTINSTFILE, "post-installation", ap);
  309. va_end(ap);
  310. if (r)
  311. ensure_diversions();
  312. return r;
  313. }
  314. int
  315. maintainer_script_new(struct pkginfo *pkg,
  316. const char *scriptname, const char *desc,
  317. const char *cidir, char *cidirrest, ...)
  318. {
  319. char *const *arglist;
  320. struct stat stab;
  321. va_list ap;
  322. char buf[100];
  323. va_start(ap,cidirrest);
  324. arglist= vbuildarglist(scriptname,ap);
  325. va_end(ap);
  326. sprintf(buf, _("new %s script"), desc);
  327. strcpy(cidirrest,scriptname);
  328. if (stat(cidir,&stab)) {
  329. if (errno == ENOENT) {
  330. debug(dbg_scripts,"maintainer_script_new nonexistent %s `%s'",scriptname,cidir);
  331. return 0;
  332. }
  333. ohshite(_("unable to stat %s `%.250s'"), buf, cidir);
  334. }
  335. do_script(pkg, &pkg->available, scriptname, cidir, &stab,
  336. arglist, _("unable to execute %s"), buf, 0);
  337. post_script_tasks();
  338. return 1;
  339. }
  340. int maintainer_script_alternative(struct pkginfo *pkg,
  341. const char *scriptname, const char *desc,
  342. const char *cidir, char *cidirrest,
  343. const char *ifok, const char *iffallback) {
  344. const char *oldscriptpath;
  345. char *const *arglist;
  346. struct stat stab;
  347. char buf[100];
  348. oldscriptpath= pkgadminfile(pkg,scriptname);
  349. arglist= buildarglist(scriptname,
  350. ifok,versiondescribe(&pkg->available.version,
  351. vdew_nonambig),
  352. NULL);
  353. sprintf(buf, _("old %s script"), desc);
  354. if (stat(oldscriptpath,&stab)) {
  355. if (errno == ENOENT) {
  356. debug(dbg_scripts,"maintainer_script_alternative nonexistent %s `%s'",
  357. scriptname,oldscriptpath);
  358. return 0;
  359. }
  360. warning(_("unable to stat %s '%.250s': %s"),
  361. buf,oldscriptpath,strerror(errno));
  362. } else {
  363. if (!do_script(pkg, &pkg->installed, scriptname, oldscriptpath, &stab,
  364. arglist, _("unable to execute %s"), buf, PROCWARN)) {
  365. post_script_tasks();
  366. return 1;
  367. }
  368. }
  369. fprintf(stderr, _("dpkg - trying script from the new package instead ...\n"));
  370. arglist= buildarglist(scriptname,
  371. iffallback,versiondescribe(&pkg->installed.version,
  372. vdew_nonambig),
  373. NULL);
  374. strcpy(cidirrest,scriptname);
  375. sprintf(buf, _("new %s script"), desc);
  376. if (stat(cidir,&stab)) {
  377. if (errno == ENOENT)
  378. ohshit(_("there is no script in the new version of the package - giving up"));
  379. else
  380. ohshite(_("unable to stat %s `%.250s'"),buf,cidir);
  381. }
  382. do_script(pkg, &pkg->available, scriptname, cidir, &stab,
  383. arglist, _("unable to execute %s"), buf, 0);
  384. fprintf(stderr, _("dpkg: ... it looks like that went OK.\n"));
  385. post_script_tasks();
  386. return 1;
  387. }
  388. void clear_istobes(void) {
  389. struct pkgiterator *it;
  390. struct pkginfo *pkg;
  391. it= iterpkgstart();
  392. while ((pkg = iterpkgnext(it)) != NULL) {
  393. ensure_package_clientdata(pkg);
  394. pkg->clientdata->istobe= itb_normal;
  395. pkg->clientdata->replacingfilesandsaid= 0;
  396. }
  397. iterpkgend(it);
  398. }
  399. void debug(int which, const char *fmt, ...) {
  400. va_list ap;
  401. if (!(f_debug & which)) return;
  402. fprintf(stderr,"D0%05o: ",which);
  403. va_start(ap,fmt);
  404. vfprintf(stderr,fmt,ap);
  405. va_end(ap);
  406. putc('\n',stderr);
  407. }
  408. /*
  409. * Returns true if the directory contains conffiles belonging to pkg,
  410. * false otherwise.
  411. */
  412. bool
  413. hasdirectoryconffiles(struct filenamenode *file, struct pkginfo *pkg)
  414. {
  415. struct conffile *conff;
  416. size_t namelen;
  417. debug(dbg_veryverbose, "hasdirectoryconffiles `%s' (from %s)", file->name,
  418. pkg->name);
  419. namelen = strlen(file->name);
  420. for (conff= pkg->installed.conffiles; conff; conff= conff->next) {
  421. if (!strncmp(file->name,conff->name,namelen)) {
  422. debug(dbg_veryverbose, "directory %s has conffile %s from %s",
  423. file->name, conff->name, pkg->name);
  424. return true;
  425. }
  426. }
  427. debug(dbg_veryverbose, "hasdirectoryconffiles no");
  428. return false;
  429. }
  430. /*
  431. * Returns true if the file is used by packages other than pkg,
  432. * false otherwise.
  433. */
  434. bool
  435. isdirectoryinuse(struct filenamenode *file, struct pkginfo *pkg)
  436. {
  437. struct filepackages *packageslump;
  438. int i;
  439. debug(dbg_veryverbose, "isdirectoryinuse `%s' (except %s)", file->name,
  440. pkg ? pkg->name : "<none>");
  441. for (packageslump= file->packages; packageslump; packageslump= packageslump->more) {
  442. debug(dbg_veryverbose, "isdirectoryinuse packageslump %s ...",
  443. packageslump->pkgs[0] ? packageslump->pkgs[0]->name : "<none>");
  444. for (i=0; i < PERFILEPACKAGESLUMP && packageslump->pkgs[i]; i++) {
  445. debug(dbg_veryverbose, "isdirectoryinuse considering [%d] %s ...", i,
  446. packageslump->pkgs[i]->name);
  447. if (packageslump->pkgs[i] == pkg) continue;
  448. return true;
  449. }
  450. }
  451. debug(dbg_veryverbose, "isdirectoryinuse no");
  452. return false;
  453. }
  454. void oldconffsetflags(const struct conffile *searchconff) {
  455. struct filenamenode *namenode;
  456. while (searchconff) {
  457. namenode= findnamenode(searchconff->name, 0); /* XXX */
  458. namenode->flags |= fnnf_old_conff;
  459. if (!namenode->oldhash)
  460. namenode->oldhash= searchconff->hash;
  461. debug(dbg_conffdetail, "oldconffsetflags `%s' namenode %p flags %o",
  462. searchconff->name, namenode, namenode->flags);
  463. searchconff= searchconff->next;
  464. }
  465. }
  466. /*
  467. * If the pathname to remove is:
  468. *
  469. * 1. a sticky or set-id file, or
  470. * 2. an unknown object (i.e., not a file, link, directory, fifo or socket)
  471. *
  472. * we change its mode so that a malicious user cannot use it, even if it's
  473. * linked to another file.
  474. */
  475. int
  476. secure_unlink(const char *pathname)
  477. {
  478. struct stat stab;
  479. if (lstat(pathname,&stab)) return -1;
  480. return secure_unlink_statted(pathname, &stab);
  481. }
  482. int
  483. secure_unlink_statted(const char *pathname, const struct stat *stab)
  484. {
  485. if (S_ISREG(stab->st_mode) ? (stab->st_mode & 07000) :
  486. !(S_ISLNK(stab->st_mode) || S_ISDIR(stab->st_mode) ||
  487. S_ISFIFO(stab->st_mode) || S_ISSOCK(stab->st_mode))) {
  488. if (chmod(pathname, 0600))
  489. return -1;
  490. }
  491. if (unlink(pathname)) return -1;
  492. return 0;
  493. }
  494. void ensure_pathname_nonexisting(const char *pathname) {
  495. int c1;
  496. const char *u;
  497. u = path_skip_slash_dotslash(pathname);
  498. assert(*u);
  499. debug(dbg_eachfile,"ensure_pathname_nonexisting `%s'",pathname);
  500. if (!rmdir(pathname)) return; /* Deleted it OK, it was a directory. */
  501. if (errno == ENOENT || errno == ELOOP) return;
  502. if (errno == ENOTDIR) {
  503. /* Either it's a file, or one of the path components is. If one
  504. * of the path components is this will fail again ...
  505. */
  506. if (secure_unlink(pathname) == 0)
  507. return; /* OK, it was */
  508. if (errno == ENOTDIR) return;
  509. }
  510. if (errno != ENOTEMPTY && errno != EEXIST) { /* Huh ? */
  511. ohshite(_("unable to securely remove '%.255s'"), pathname);
  512. }
  513. c1= m_fork();
  514. if (!c1) {
  515. execlp(RM, "rm", "-rf", "--", pathname, NULL);
  516. ohshite(_("failed to exec rm for cleanup"));
  517. }
  518. debug(dbg_eachfile,"ensure_pathname_nonexisting running rm -rf");
  519. subproc_wait_check(c1, "rm cleanup", 0);
  520. }
  521. void log_action(const char *action, struct pkginfo *pkg) {
  522. log_message("%s %s %s %s", action, pkg->name,
  523. versiondescribe(&pkg->installed.version, vdew_nonambig),
  524. versiondescribe(&pkg->available.version, vdew_nonambig));
  525. statusfd_send("processing: %s: %s", action, pkg->name);
  526. }