system.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926
  1. /* System-dependent calls for tar.
  2. Copyright 2003-2023 Free Software Foundation, Inc.
  3. This program is free software; you can redistribute it and/or modify it
  4. under the terms of the GNU General Public License as published by the
  5. Free Software Foundation; either version 3, or (at your option) any later
  6. version.
  7. This program is distributed in the hope that it will be useful, but
  8. WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
  10. Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #include <system.h>
  14. #include <system-ioctl.h>
  15. #include "common.h"
  16. #include <priv-set.h>
  17. #include <rmt.h>
  18. #include <signal.h>
  19. #include <wordsplit.h>
  20. static _Noreturn void
  21. xexec (const char *cmd)
  22. {
  23. char *argv[4];
  24. argv[0] = (char *) "/bin/sh";
  25. argv[1] = (char *) "-c";
  26. argv[2] = (char *) cmd;
  27. argv[3] = NULL;
  28. execv ("/bin/sh", argv);
  29. exec_fatal (cmd);
  30. }
  31. /* True if the archive is seekable via ioctl and MTIOCTOP,
  32. or if it is not known whether it is seekable.
  33. False if it is known to be not seekable. */
  34. static bool mtioseekable_archive;
  35. bool
  36. mtioseek (bool count_files, off_t count)
  37. {
  38. if (mtioseekable_archive)
  39. {
  40. #ifdef MTIOCTOP
  41. struct mtop operation;
  42. operation.mt_op = (count_files
  43. ? (count < 0 ? MTBSF : MTFSF)
  44. : (count < 0 ? MTBSR : MTFSR));
  45. if (! (count < 0
  46. ? INT_SUBTRACT_WRAPV (0, count, &operation.mt_count)
  47. : INT_ADD_WRAPV (count, 0, &operation.mt_count))
  48. && (0 <= rmtioctl (archive, MTIOCTOP, &operation)
  49. || (errno == EIO
  50. && 0 <= rmtioctl (archive, MTIOCTOP, &operation))))
  51. return true;
  52. #endif
  53. mtioseekable_archive = false;
  54. }
  55. return false;
  56. }
  57. #if MSDOS
  58. bool
  59. sys_get_archive_stat (void)
  60. {
  61. return 0;
  62. }
  63. bool
  64. sys_file_is_archive (struct tar_stat_info *p)
  65. {
  66. return false;
  67. }
  68. void
  69. sys_detect_dev_null_output (void)
  70. {
  71. static char const dev_null[] = "nul";
  72. dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
  73. || (! _isrmt (archive)));
  74. }
  75. void
  76. sys_wait_for_child (pid_t child_pid, bool eof)
  77. {
  78. }
  79. void
  80. sys_spawn_shell (void)
  81. {
  82. spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
  83. }
  84. /* stat() in djgpp's C library gives a constant number of 42 as the
  85. uid and gid of a file. So, comparing an FTP'ed archive just after
  86. unpack would fail on MSDOS. */
  87. bool
  88. sys_compare_uid (struct stat *a, struct stat *b)
  89. {
  90. return true;
  91. }
  92. bool
  93. sys_compare_gid (struct stat *a, struct stat *b)
  94. {
  95. return true;
  96. }
  97. void
  98. sys_compare_links (struct stat *link_data, struct stat *stat_data)
  99. {
  100. return true;
  101. }
  102. int
  103. sys_truncate (int fd)
  104. {
  105. return write (fd, "", 0);
  106. }
  107. size_t
  108. sys_write_archive_buffer (void)
  109. {
  110. return full_write (archive, record_start->buffer, record_size);
  111. }
  112. /* Set ARCHIVE for writing, then compressing an archive. */
  113. void
  114. sys_child_open_for_compress (void)
  115. {
  116. FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
  117. }
  118. /* Set ARCHIVE for uncompressing, then reading an archive. */
  119. void
  120. sys_child_open_for_uncompress (void)
  121. {
  122. FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
  123. }
  124. #else
  125. extern union block *record_start; /* FIXME */
  126. bool
  127. sys_get_archive_stat (void)
  128. {
  129. bool remote = _isrmt (archive);
  130. mtioseekable_archive = true;
  131. if (!remote && 0 <= archive && fstat (archive, &archive_stat) == 0)
  132. {
  133. if (!S_ISCHR (archive_stat.st_mode))
  134. mtioseekable_archive = false;
  135. return true;
  136. }
  137. else
  138. {
  139. /* FIXME: This memset should not be needed. It is present only
  140. because other parts of tar may incorrectly access
  141. archive_stat even if it's not the archive status. */
  142. memset (&archive_stat, 0, sizeof archive_stat);
  143. return remote;
  144. }
  145. }
  146. bool
  147. sys_file_is_archive (struct tar_stat_info *p)
  148. {
  149. return (!dev_null_output && !_isrmt (archive)
  150. && p->stat.st_dev == archive_stat.st_dev
  151. && p->stat.st_ino == archive_stat.st_ino);
  152. }
  153. /* Detect if outputting to "/dev/null". */
  154. void
  155. sys_detect_dev_null_output (void)
  156. {
  157. static char const dev_null[] = "/dev/null";
  158. static struct stat dev_null_stat;
  159. dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
  160. || (! _isrmt (archive)
  161. && S_ISCHR (archive_stat.st_mode)
  162. && (dev_null_stat.st_ino != 0
  163. || stat (dev_null, &dev_null_stat) == 0)
  164. && archive_stat.st_ino == dev_null_stat.st_ino
  165. && archive_stat.st_dev == dev_null_stat.st_dev));
  166. }
  167. void
  168. sys_wait_for_child (pid_t child_pid, bool eof)
  169. {
  170. if (child_pid)
  171. {
  172. int wait_status;
  173. while (waitpid (child_pid, &wait_status, 0) == -1)
  174. if (errno != EINTR)
  175. {
  176. waitpid_error (use_compress_program_option);
  177. break;
  178. }
  179. if (WIFSIGNALED (wait_status))
  180. {
  181. int sig = WTERMSIG (wait_status);
  182. if (!(!eof && sig == SIGPIPE))
  183. FATAL_ERROR ((0, 0, _("Child died with signal %d"), sig));
  184. }
  185. else if (WEXITSTATUS (wait_status) != 0)
  186. FATAL_ERROR ((0, 0, _("Child returned status %d"),
  187. WEXITSTATUS (wait_status)));
  188. }
  189. }
  190. void
  191. sys_spawn_shell (void)
  192. {
  193. pid_t child;
  194. const char *shell = getenv ("SHELL");
  195. if (! shell)
  196. shell = "/bin/sh";
  197. child = xfork ();
  198. if (child == 0)
  199. {
  200. priv_set_restore_linkdir ();
  201. execlp (shell, "-sh", "-i", NULL);
  202. exec_fatal (shell);
  203. }
  204. else
  205. {
  206. int wait_status;
  207. while (waitpid (child, &wait_status, 0) == -1)
  208. if (errno != EINTR)
  209. {
  210. waitpid_error (shell);
  211. break;
  212. }
  213. }
  214. }
  215. bool
  216. sys_compare_uid (struct stat *a, struct stat *b)
  217. {
  218. return a->st_uid == b->st_uid;
  219. }
  220. bool
  221. sys_compare_gid (struct stat *a, struct stat *b)
  222. {
  223. return a->st_gid == b->st_gid;
  224. }
  225. bool
  226. sys_compare_links (struct stat *link_data, struct stat *stat_data)
  227. {
  228. return stat_data->st_dev == link_data->st_dev
  229. && stat_data->st_ino == link_data->st_ino;
  230. }
  231. int
  232. sys_truncate (int fd)
  233. {
  234. off_t pos = lseek (fd, (off_t) 0, SEEK_CUR);
  235. return pos < 0 ? -1 : ftruncate (fd, pos);
  236. }
  237. /* Return nonzero if NAME is the name of a regular file, or if the file
  238. does not exist (so it would be created as a regular file). */
  239. static int
  240. is_regular_file (const char *name)
  241. {
  242. struct stat stbuf;
  243. if (stat (name, &stbuf) == 0)
  244. return S_ISREG (stbuf.st_mode);
  245. else
  246. return errno == ENOENT;
  247. }
  248. size_t
  249. sys_write_archive_buffer (void)
  250. {
  251. return rmtwrite (archive, record_start->buffer, record_size);
  252. }
  253. #define PREAD 0 /* read file descriptor from pipe() */
  254. #define PWRITE 1 /* write file descriptor from pipe() */
  255. /* Duplicate file descriptor FROM into becoming INTO.
  256. INTO is closed first and has to be the next available slot. */
  257. static void
  258. xdup2 (int from, int into)
  259. {
  260. if (from != into)
  261. {
  262. int status = close (into);
  263. if (status != 0 && errno != EBADF)
  264. {
  265. int e = errno;
  266. FATAL_ERROR ((0, e, _("Cannot close")));
  267. }
  268. status = dup (from);
  269. if (status != into)
  270. {
  271. if (status < 0)
  272. {
  273. int e = errno;
  274. FATAL_ERROR ((0, e, _("Cannot dup")));
  275. }
  276. abort ();
  277. }
  278. xclose (from);
  279. }
  280. }
  281. /* Propagate any failure of the grandchild back to the parent. */
  282. static _Noreturn void
  283. wait_for_grandchild (pid_t pid)
  284. {
  285. int wait_status;
  286. int exit_code = 0;
  287. while (waitpid (pid, &wait_status, 0) == -1)
  288. if (errno != EINTR)
  289. {
  290. waitpid_error (use_compress_program_option);
  291. break;
  292. }
  293. if (WIFSIGNALED (wait_status))
  294. raise (WTERMSIG (wait_status));
  295. else if (WEXITSTATUS (wait_status) != 0)
  296. exit_code = WEXITSTATUS (wait_status);
  297. exit (exit_code);
  298. }
  299. /* Set ARCHIVE for writing, then compressing an archive. */
  300. pid_t
  301. sys_child_open_for_compress (void)
  302. {
  303. int parent_pipe[2];
  304. int child_pipe[2];
  305. pid_t grandchild_pid;
  306. pid_t child_pid;
  307. signal (SIGPIPE, SIG_IGN);
  308. xpipe (parent_pipe);
  309. child_pid = xfork ();
  310. if (child_pid > 0)
  311. {
  312. /* The parent tar is still here! Just clean up. */
  313. archive = parent_pipe[PWRITE];
  314. xclose (parent_pipe[PREAD]);
  315. return child_pid;
  316. }
  317. /* The new born child tar is here! */
  318. set_program_name (_("tar (child)"));
  319. signal (SIGPIPE, SIG_DFL);
  320. xdup2 (parent_pipe[PREAD], STDIN_FILENO);
  321. xclose (parent_pipe[PWRITE]);
  322. /* Check if we need a grandchild tar. This happens only if either:
  323. a) the file is to be accessed by rmt: compressor doesn't know how;
  324. b) the file is not a plain file. */
  325. if (!_remdev (archive_name_array[0])
  326. && is_regular_file (archive_name_array[0]))
  327. {
  328. if (backup_option)
  329. maybe_backup_file (archive_name_array[0], 1);
  330. /* We don't need a grandchild tar. Open the archive and launch the
  331. compressor. */
  332. if (strcmp (archive_name_array[0], "-"))
  333. {
  334. archive = creat (archive_name_array[0], MODE_RW);
  335. if (archive < 0)
  336. {
  337. int saved_errno = errno;
  338. if (backup_option)
  339. undo_last_backup ();
  340. errno = saved_errno;
  341. open_fatal (archive_name_array[0]);
  342. }
  343. xdup2 (archive, STDOUT_FILENO);
  344. }
  345. priv_set_restore_linkdir ();
  346. xexec (use_compress_program_option);
  347. }
  348. /* We do need a grandchild tar. */
  349. xpipe (child_pipe);
  350. grandchild_pid = xfork ();
  351. if (grandchild_pid == 0)
  352. {
  353. /* The newborn grandchild tar is here! Launch the compressor. */
  354. set_program_name (_("tar (grandchild)"));
  355. xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
  356. xclose (child_pipe[PREAD]);
  357. priv_set_restore_linkdir ();
  358. xexec (use_compress_program_option);
  359. }
  360. /* The child tar is still here! */
  361. /* Prepare for reblocking the data from the compressor into the archive. */
  362. xdup2 (child_pipe[PREAD], STDIN_FILENO);
  363. xclose (child_pipe[PWRITE]);
  364. if (strcmp (archive_name_array[0], "-") == 0)
  365. archive = STDOUT_FILENO;
  366. else
  367. {
  368. archive = rmtcreat (archive_name_array[0], MODE_RW, rsh_command_option);
  369. if (archive < 0)
  370. open_fatal (archive_name_array[0]);
  371. }
  372. /* Let's read out of the stdin pipe and write an archive. */
  373. while (1)
  374. {
  375. size_t status = 0;
  376. char *cursor;
  377. size_t length;
  378. /* Assemble a record. */
  379. for (length = 0, cursor = record_start->buffer;
  380. length < record_size;
  381. length += status, cursor += status)
  382. {
  383. size_t size = record_size - length;
  384. status = safe_read (STDIN_FILENO, cursor, size);
  385. if (status == SAFE_READ_ERROR)
  386. read_fatal (use_compress_program_option);
  387. if (status == 0)
  388. break;
  389. }
  390. /* Copy the record. */
  391. if (status == 0)
  392. {
  393. /* We hit the end of the file. Write last record at
  394. full length, as the only role of the grandchild is
  395. doing proper reblocking. */
  396. if (length > 0)
  397. {
  398. memset (record_start->buffer + length, 0, record_size - length);
  399. status = sys_write_archive_buffer ();
  400. if (status != record_size)
  401. archive_write_error (status);
  402. }
  403. /* There is nothing else to read, break out. */
  404. break;
  405. }
  406. status = sys_write_archive_buffer ();
  407. if (status != record_size)
  408. archive_write_error (status);
  409. }
  410. wait_for_grandchild (grandchild_pid);
  411. }
  412. static void
  413. run_decompress_program (void)
  414. {
  415. int i;
  416. const char *p, *prog = NULL;
  417. struct wordsplit ws;
  418. int wsflags = (WRDSF_DEFFLAGS | WRDSF_ENV | WRDSF_DOOFFS) & ~WRDSF_NOVAR;
  419. ws.ws_env = (const char **) environ;
  420. ws.ws_offs = 1;
  421. for (p = first_decompress_program (&i); p; p = next_decompress_program (&i))
  422. {
  423. if (prog)
  424. {
  425. WARNOPT (WARN_DECOMPRESS_PROGRAM,
  426. (0, errno, _("cannot run %s"), prog));
  427. WARNOPT (WARN_DECOMPRESS_PROGRAM,
  428. (0, 0, _("trying %s"), p));
  429. }
  430. if (wordsplit (p, &ws, wsflags))
  431. FATAL_ERROR ((0, 0, _("cannot split string '%s': %s"),
  432. p, wordsplit_strerror (&ws)));
  433. wsflags |= WRDSF_REUSE;
  434. memmove(ws.ws_wordv, ws.ws_wordv + ws.ws_offs,
  435. sizeof(ws.ws_wordv[0])*ws.ws_wordc);
  436. ws.ws_wordv[ws.ws_wordc] = (char *) "-d";
  437. prog = p;
  438. execvp (ws.ws_wordv[0], ws.ws_wordv);
  439. ws.ws_wordv[ws.ws_wordc] = NULL;
  440. }
  441. if (!prog)
  442. FATAL_ERROR ((0, 0, _("unable to run decompression program")));
  443. exec_fatal (prog);
  444. }
  445. /* Set ARCHIVE for uncompressing, then reading an archive. */
  446. pid_t
  447. sys_child_open_for_uncompress (void)
  448. {
  449. int parent_pipe[2];
  450. int child_pipe[2];
  451. pid_t grandchild_pid;
  452. pid_t child_pid;
  453. xpipe (parent_pipe);
  454. child_pid = xfork ();
  455. if (child_pid > 0)
  456. {
  457. /* The parent tar is still here! Just clean up. */
  458. archive = parent_pipe[PREAD];
  459. xclose (parent_pipe[PWRITE]);
  460. return child_pid;
  461. }
  462. /* The newborn child tar is here! */
  463. set_program_name (_("tar (child)"));
  464. signal (SIGPIPE, SIG_DFL);
  465. xdup2 (parent_pipe[PWRITE], STDOUT_FILENO);
  466. xclose (parent_pipe[PREAD]);
  467. /* Check if we need a grandchild tar. This happens only if either:
  468. a) we're reading stdin: to force unblocking;
  469. b) the file is to be accessed by rmt: compressor doesn't know how;
  470. c) the file is not a plain file. */
  471. if (strcmp (archive_name_array[0], "-") != 0
  472. && !_remdev (archive_name_array[0])
  473. && is_regular_file (archive_name_array[0]))
  474. {
  475. /* We don't need a grandchild tar. Open the archive and launch the
  476. uncompressor. */
  477. archive = open (archive_name_array[0], O_RDONLY | O_BINARY, MODE_RW);
  478. if (archive < 0)
  479. open_fatal (archive_name_array[0]);
  480. xdup2 (archive, STDIN_FILENO);
  481. priv_set_restore_linkdir ();
  482. run_decompress_program ();
  483. }
  484. /* We do need a grandchild tar. */
  485. xpipe (child_pipe);
  486. grandchild_pid = xfork ();
  487. if (grandchild_pid == 0)
  488. {
  489. /* The newborn grandchild tar is here! Launch the uncompressor. */
  490. set_program_name (_("tar (grandchild)"));
  491. xdup2 (child_pipe[PREAD], STDIN_FILENO);
  492. xclose (child_pipe[PWRITE]);
  493. priv_set_restore_linkdir ();
  494. run_decompress_program ();
  495. }
  496. /* The child tar is still here! */
  497. /* Prepare for unblocking the data from the archive into the
  498. uncompressor. */
  499. xdup2 (child_pipe[PWRITE], STDOUT_FILENO);
  500. xclose (child_pipe[PREAD]);
  501. if (strcmp (archive_name_array[0], "-") == 0)
  502. archive = STDIN_FILENO;
  503. else
  504. archive = rmtopen (archive_name_array[0], O_RDONLY | O_BINARY,
  505. MODE_RW, rsh_command_option);
  506. if (archive < 0)
  507. open_fatal (archive_name_array[0]);
  508. /* Let's read the archive and pipe it into stdout. */
  509. while (1)
  510. {
  511. char *cursor;
  512. size_t maximum;
  513. size_t count;
  514. size_t status;
  515. clear_read_error_count ();
  516. error_loop:
  517. status = rmtread (archive, record_start->buffer, record_size);
  518. if (status == SAFE_READ_ERROR)
  519. {
  520. archive_read_error ();
  521. goto error_loop;
  522. }
  523. if (status == 0)
  524. break;
  525. cursor = record_start->buffer;
  526. maximum = status;
  527. while (maximum)
  528. {
  529. count = maximum < BLOCKSIZE ? maximum : BLOCKSIZE;
  530. if (full_write (STDOUT_FILENO, cursor, count) != count)
  531. write_error (use_compress_program_option);
  532. cursor += count;
  533. maximum -= count;
  534. }
  535. }
  536. xclose (STDOUT_FILENO);
  537. wait_for_grandchild (grandchild_pid);
  538. }
  539. static void
  540. dec_to_env (char const *envar, uintmax_t num)
  541. {
  542. char buf[UINTMAX_STRSIZE_BOUND];
  543. char *numstr;
  544. numstr = STRINGIFY_BIGINT (num, buf);
  545. if (setenv (envar, numstr, 1) != 0)
  546. xalloc_die ();
  547. }
  548. static void
  549. time_to_env (char const *envar, struct timespec t)
  550. {
  551. char buf[TIMESPEC_STRSIZE_BOUND];
  552. if (setenv (envar, code_timespec (t, buf), 1) != 0)
  553. xalloc_die ();
  554. }
  555. static void
  556. oct_to_env (char const *envar, unsigned long num)
  557. {
  558. char buf[1+1+(sizeof(unsigned long)*CHAR_BIT+2)/3];
  559. snprintf (buf, sizeof buf, "0%lo", num);
  560. if (setenv (envar, buf, 1) != 0)
  561. xalloc_die ();
  562. }
  563. static void
  564. str_to_env (char const *envar, char const *str)
  565. {
  566. if (str)
  567. {
  568. if (setenv (envar, str, 1) != 0)
  569. xalloc_die ();
  570. }
  571. else
  572. unsetenv (envar);
  573. }
  574. static void
  575. chr_to_env (char const *envar, char c)
  576. {
  577. char buf[2];
  578. buf[0] = c;
  579. buf[1] = 0;
  580. if (setenv (envar, buf, 1) != 0)
  581. xalloc_die ();
  582. }
  583. static void
  584. stat_to_env (char *name, char type, struct tar_stat_info *st)
  585. {
  586. str_to_env ("TAR_VERSION", PACKAGE_VERSION);
  587. str_to_env ("TAR_ARCHIVE", *archive_name_cursor);
  588. dec_to_env ("TAR_VOLUME", archive_name_cursor - archive_name_array + 1);
  589. dec_to_env ("TAR_BLOCKING_FACTOR", blocking_factor);
  590. str_to_env ("TAR_FORMAT",
  591. archive_format_string (current_format == DEFAULT_FORMAT ?
  592. archive_format : current_format));
  593. chr_to_env ("TAR_FILETYPE", type);
  594. oct_to_env ("TAR_MODE", st->stat.st_mode);
  595. str_to_env ("TAR_FILENAME", name);
  596. str_to_env ("TAR_REALNAME", st->file_name);
  597. str_to_env ("TAR_UNAME", st->uname);
  598. str_to_env ("TAR_GNAME", st->gname);
  599. time_to_env ("TAR_ATIME", st->atime);
  600. time_to_env ("TAR_MTIME", st->mtime);
  601. time_to_env ("TAR_CTIME", st->ctime);
  602. dec_to_env ("TAR_SIZE", st->stat.st_size);
  603. dec_to_env ("TAR_UID", st->stat.st_uid);
  604. dec_to_env ("TAR_GID", st->stat.st_gid);
  605. switch (type)
  606. {
  607. case 'b':
  608. case 'c':
  609. dec_to_env ("TAR_MINOR", minor (st->stat.st_rdev));
  610. dec_to_env ("TAR_MAJOR", major (st->stat.st_rdev));
  611. unsetenv ("TAR_LINKNAME");
  612. break;
  613. case 'l':
  614. case 'h':
  615. unsetenv ("TAR_MINOR");
  616. unsetenv ("TAR_MAJOR");
  617. str_to_env ("TAR_LINKNAME", st->link_name);
  618. break;
  619. default:
  620. unsetenv ("TAR_MINOR");
  621. unsetenv ("TAR_MAJOR");
  622. unsetenv ("TAR_LINKNAME");
  623. break;
  624. }
  625. }
  626. static pid_t global_pid;
  627. static void (*pipe_handler) (int sig);
  628. int
  629. sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
  630. {
  631. int p[2];
  632. xpipe (p);
  633. pipe_handler = signal (SIGPIPE, SIG_IGN);
  634. global_pid = xfork ();
  635. if (global_pid != 0)
  636. {
  637. xclose (p[PREAD]);
  638. return p[PWRITE];
  639. }
  640. /* Child */
  641. xdup2 (p[PREAD], STDIN_FILENO);
  642. xclose (p[PWRITE]);
  643. stat_to_env (file_name, typechar, st);
  644. priv_set_restore_linkdir ();
  645. xexec (to_command_option);
  646. }
  647. void
  648. sys_wait_command (void)
  649. {
  650. int status;
  651. if (global_pid < 0)
  652. return;
  653. signal (SIGPIPE, pipe_handler);
  654. while (waitpid (global_pid, &status, 0) == -1)
  655. if (errno != EINTR)
  656. {
  657. global_pid = -1;
  658. waitpid_error (to_command_option);
  659. return;
  660. }
  661. if (WIFEXITED (status))
  662. {
  663. if (!ignore_command_error_option && WEXITSTATUS (status))
  664. ERROR ((0, 0, _("%lu: Child returned status %d"),
  665. (unsigned long) global_pid, WEXITSTATUS (status)));
  666. }
  667. else if (WIFSIGNALED (status))
  668. {
  669. WARN ((0, 0, _("%lu: Child terminated on signal %d"),
  670. (unsigned long) global_pid, WTERMSIG (status)));
  671. }
  672. else
  673. ERROR ((0, 0, _("%lu: Child terminated on unknown reason"),
  674. (unsigned long) global_pid));
  675. global_pid = -1;
  676. }
  677. int
  678. sys_exec_info_script (const char **archive_name, int volume_number)
  679. {
  680. pid_t pid;
  681. char uintbuf[UINTMAX_STRSIZE_BOUND];
  682. int p[2];
  683. static void (*saved_handler) (int sig);
  684. xpipe (p);
  685. saved_handler = signal (SIGPIPE, SIG_IGN);
  686. pid = xfork ();
  687. if (pid != 0)
  688. {
  689. /* Master */
  690. int rc;
  691. int status;
  692. char *buf = NULL;
  693. size_t size = 0;
  694. FILE *fp;
  695. xclose (p[PWRITE]);
  696. fp = fdopen (p[PREAD], "r");
  697. rc = getline (&buf, &size, fp);
  698. fclose (fp);
  699. if (rc > 0 && buf[rc-1] == '\n')
  700. buf[--rc] = 0;
  701. while (waitpid (pid, &status, 0) == -1)
  702. if (errno != EINTR)
  703. {
  704. signal (SIGPIPE, saved_handler);
  705. waitpid_error (info_script_option);
  706. return -1;
  707. }
  708. signal (SIGPIPE, saved_handler);
  709. if (WIFEXITED (status))
  710. {
  711. if (WEXITSTATUS (status) == 0 && rc > 0)
  712. *archive_name = buf;
  713. else
  714. free (buf);
  715. return WEXITSTATUS (status);
  716. }
  717. free (buf);
  718. return -1;
  719. }
  720. /* Child */
  721. setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
  722. setenv ("TAR_ARCHIVE", *archive_name, 1);
  723. setenv ("TAR_VOLUME", STRINGIFY_BIGINT (volume_number, uintbuf), 1);
  724. setenv ("TAR_BLOCKING_FACTOR",
  725. STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
  726. setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
  727. setenv ("TAR_FORMAT",
  728. archive_format_string (current_format == DEFAULT_FORMAT ?
  729. archive_format : current_format), 1);
  730. setenv ("TAR_FD", STRINGIFY_BIGINT (p[PWRITE], uintbuf), 1);
  731. xclose (p[PREAD]);
  732. priv_set_restore_linkdir ();
  733. xexec (info_script_option);
  734. }
  735. void
  736. sys_exec_checkpoint_script (const char *script_name,
  737. const char *archive_name,
  738. int checkpoint_number)
  739. {
  740. pid_t pid;
  741. char uintbuf[UINTMAX_STRSIZE_BOUND];
  742. pid = xfork ();
  743. if (pid != 0)
  744. {
  745. /* Master */
  746. int status;
  747. while (waitpid (pid, &status, 0) == -1)
  748. if (errno != EINTR)
  749. {
  750. waitpid_error (script_name);
  751. break;
  752. }
  753. return;
  754. }
  755. /* Child */
  756. setenv ("TAR_VERSION", PACKAGE_VERSION, 1);
  757. setenv ("TAR_ARCHIVE", archive_name, 1);
  758. setenv ("TAR_CHECKPOINT", STRINGIFY_BIGINT (checkpoint_number, uintbuf), 1);
  759. setenv ("TAR_BLOCKING_FACTOR",
  760. STRINGIFY_BIGINT (blocking_factor, uintbuf), 1);
  761. setenv ("TAR_SUBCOMMAND", subcommand_string (subcommand_option), 1);
  762. setenv ("TAR_FORMAT",
  763. archive_format_string (current_format == DEFAULT_FORMAT ?
  764. archive_format : current_format), 1);
  765. priv_set_restore_linkdir ();
  766. xexec (script_name);
  767. }
  768. #endif /* not MSDOS */