4
0

buffer.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584
  1. /* Buffer management for tar.
  2. Copyright (C) 1988, 1992, 1993 Free Software Foundation
  3. This file is part of GNU Tar.
  4. GNU Tar is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Tar is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Tar; see the file COPYING. If not, write to
  14. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  15. /*
  16. * Buffer management for tar.
  17. *
  18. * Written by John Gilmore, ihnp4!hoptoad!gnu, on 25 August 1985.
  19. */
  20. #include <stdio.h>
  21. #include <errno.h>
  22. #ifndef STDC_HEADERS
  23. extern int errno;
  24. #endif
  25. #include <sys/types.h> /* For non-Berkeley systems */
  26. #include <signal.h>
  27. #include <time.h>
  28. time_t time ();
  29. #ifdef HAVE_SYS_MTIO_H
  30. #include <sys/ioctl.h>
  31. #include <sys/mtio.h>
  32. #endif
  33. #ifdef BSD42
  34. #include <sys/file.h>
  35. #else
  36. #ifndef V7
  37. #include <fcntl.h>
  38. #endif
  39. #endif
  40. #ifdef __MSDOS__
  41. #include <process.h>
  42. #endif
  43. #ifdef XENIX
  44. #include <sys/inode.h>
  45. #endif
  46. #include "tar.h"
  47. #include "port.h"
  48. #include "rmt.h"
  49. #include "regex.h"
  50. /* Either stdout or stderr: The thing we write messages (standard msgs, not
  51. errors) to. Stdout unless we're writing a pipe, in which case stderr */
  52. FILE *msg_file = stdout;
  53. #define STDIN 0 /* Standard input file descriptor */
  54. #define STDOUT 1 /* Standard output file descriptor */
  55. #define PREAD 0 /* Read file descriptor from pipe() */
  56. #define PWRITE 1 /* Write file descriptor from pipe() */
  57. #define MAGIC_STAT 105 /* Magic status returned by child, if
  58. it can't exec. We hope compress/sh
  59. never return this status! */
  60. void *valloc ();
  61. void writeerror ();
  62. void readerror ();
  63. void ck_pipe ();
  64. void ck_close ();
  65. int backspace_output ();
  66. extern void finish_header ();
  67. void flush_archive ();
  68. int isfile ();
  69. int new_volume ();
  70. void verify_volume ();
  71. extern void to_oct ();
  72. #ifndef __MSDOS__
  73. /* Obnoxious test to see if dimwit is trying to dump the archive */
  74. dev_t ar_dev;
  75. ino_t ar_ino;
  76. #endif
  77. /*
  78. * The record pointed to by save_rec should not be overlaid
  79. * when reading in a new tape block. Copy it to record_save_area first, and
  80. * change the pointer in *save_rec to point to record_save_area.
  81. * Saved_recno records the record number at the time of the save.
  82. * This is used by annofile() to print the record number of a file's
  83. * header record.
  84. */
  85. static union record **save_rec;
  86. union record record_save_area;
  87. static long saved_recno;
  88. /*
  89. * PID of child program, if f_compress or remote archive access.
  90. */
  91. static int childpid = 0;
  92. /*
  93. * Record number of the start of this block of records
  94. */
  95. long baserec;
  96. /*
  97. * Error recovery stuff
  98. */
  99. static int r_error_count;
  100. /*
  101. * Have we hit EOF yet?
  102. */
  103. static int hit_eof;
  104. /* Checkpointing counter */
  105. static int checkpoint;
  106. /* JF we're reading, but we just read the last record and its time to update */
  107. extern time_to_start_writing;
  108. int file_to_switch_to = -1; /* If remote update, close archive, and use
  109. this descriptor to write to */
  110. static int volno = 1; /* JF which volume of a multi-volume tape
  111. we're on */
  112. static int global_volno = 1; /* Volume number to print in external messages. */
  113. char *save_name = 0; /* Name of the file we are currently writing */
  114. long save_totsize; /* total size of file we are writing. Only
  115. valid if save_name is non_zero */
  116. long save_sizeleft; /* Where we are in the file we are writing.
  117. Only valid if save_name is non-zero */
  118. int write_archive_to_stdout;
  119. /* Used by fl_read and fl_write to store the real info about saved names */
  120. static char real_s_name[NAMSIZ];
  121. static long real_s_totsize;
  122. static long real_s_sizeleft;
  123. /* Reset the EOF flag (if set), and re-set ar_record, etc */
  124. void
  125. reset_eof ()
  126. {
  127. if (hit_eof)
  128. {
  129. hit_eof = 0;
  130. ar_record = ar_block;
  131. ar_last = ar_block + blocking;
  132. ar_reading = 0;
  133. }
  134. }
  135. /*
  136. * Return the location of the next available input or output record.
  137. * Return NULL for EOF. Once we have returned NULL, we just keep returning
  138. * it, to avoid accidentally going on to the next file on the "tape".
  139. */
  140. union record *
  141. findrec ()
  142. {
  143. if (ar_record == ar_last)
  144. {
  145. if (hit_eof)
  146. return (union record *) NULL; /* EOF */
  147. flush_archive ();
  148. if (ar_record == ar_last)
  149. {
  150. hit_eof++;
  151. return (union record *) NULL; /* EOF */
  152. }
  153. }
  154. return ar_record;
  155. }
  156. /*
  157. * Indicate that we have used all records up thru the argument.
  158. * (should the arg have an off-by-1? XXX FIXME)
  159. */
  160. void
  161. userec (rec)
  162. union record *rec;
  163. {
  164. while (rec >= ar_record)
  165. ar_record++;
  166. /*
  167. * Do NOT flush the archive here. If we do, the same
  168. * argument to userec() could mean the next record (if the
  169. * input block is exactly one record long), which is not what
  170. * is intended.
  171. */
  172. if (ar_record > ar_last)
  173. abort ();
  174. }
  175. /*
  176. * Return a pointer to the end of the current records buffer.
  177. * All the space between findrec() and endofrecs() is available
  178. * for filling with data, or taking data from.
  179. */
  180. union record *
  181. endofrecs ()
  182. {
  183. return ar_last;
  184. }
  185. /*
  186. * Duplicate a file descriptor into a certain slot.
  187. * Equivalent to BSD "dup2" with error reporting.
  188. */
  189. void
  190. dupto (from, to, msg)
  191. int from, to;
  192. char *msg;
  193. {
  194. int err;
  195. if (from != to)
  196. {
  197. err = close (to);
  198. if (err < 0 && errno != EBADF)
  199. {
  200. msg_perror ("Cannot close descriptor %d", to);
  201. exit (EX_SYSTEM);
  202. }
  203. err = dup (from);
  204. if (err != to)
  205. {
  206. msg_perror ("cannot dup %s", msg);
  207. exit (EX_SYSTEM);
  208. }
  209. ck_close (from);
  210. }
  211. }
  212. #ifdef __MSDOS__
  213. void
  214. child_open ()
  215. {
  216. fprintf (stderr, "MS-DOS %s can't use compressed or remote archives\n", tar);
  217. exit (EX_ARGSBAD);
  218. }
  219. #else
  220. void
  221. child_open ()
  222. {
  223. int pipe[2];
  224. int err = 0;
  225. int kidpipe[2];
  226. int kidchildpid;
  227. #define READ 0
  228. #define WRITE 1
  229. ck_pipe (pipe);
  230. childpid = fork ();
  231. if (childpid < 0)
  232. {
  233. msg_perror ("cannot fork");
  234. exit (EX_SYSTEM);
  235. }
  236. if (childpid > 0)
  237. {
  238. /* We're the parent. Clean up and be happy */
  239. /* This, at least, is easy */
  240. if (ar_reading)
  241. {
  242. f_reblock++;
  243. archive = pipe[READ];
  244. ck_close (pipe[WRITE]);
  245. }
  246. else
  247. {
  248. archive = pipe[WRITE];
  249. ck_close (pipe[READ]);
  250. }
  251. return;
  252. }
  253. /* We're the kid */
  254. if (ar_reading)
  255. {
  256. dupto (pipe[WRITE], STDOUT, "(child) pipe to stdout");
  257. ck_close (pipe[READ]);
  258. }
  259. else
  260. {
  261. dupto (pipe[READ], STDIN, "(child) pipe to stdin");
  262. ck_close (pipe[WRITE]);
  263. }
  264. /* We need a child tar only if
  265. 1: we're reading/writing stdin/out (to force reblocking)
  266. 2: the file is to be accessed by rmt (compress doesn't know how)
  267. 3: the file is not a plain file */
  268. #ifdef NO_REMOTE
  269. if (!(ar_files[0][0] == '-' && ar_files[0][1] == '\0') && isfile (ar_files[0]))
  270. #else
  271. if (!(ar_files[0][0] == '-' && ar_files[0][1] == '\0') && !_remdev (ar_files[0]) && isfile (ar_files[0]))
  272. #endif
  273. {
  274. /* We don't need a child tar. Open the archive */
  275. if (ar_reading)
  276. {
  277. archive = open (ar_files[0], O_RDONLY | O_BINARY, 0666);
  278. if (archive < 0)
  279. {
  280. msg_perror ("can't open archive %s", ar_files[0]);
  281. exit (EX_BADARCH);
  282. }
  283. dupto (archive, STDIN, "archive to stdin");
  284. /* close(archive); */
  285. }
  286. else
  287. {
  288. archive = creat (ar_files[0], 0666);
  289. if (archive < 0)
  290. {
  291. msg_perror ("can't open archive %s", ar_files[0]);
  292. exit (EX_BADARCH);
  293. }
  294. dupto (archive, STDOUT, "archive to stdout");
  295. /* close(archive); */
  296. }
  297. }
  298. else
  299. {
  300. /* We need a child tar */
  301. ck_pipe (kidpipe);
  302. kidchildpid = fork ();
  303. if (kidchildpid < 0)
  304. {
  305. msg_perror ("child can't fork");
  306. exit (EX_SYSTEM);
  307. }
  308. if (kidchildpid > 0)
  309. {
  310. /* About to exec compress: set up the files */
  311. if (ar_reading)
  312. {
  313. dupto (kidpipe[READ], STDIN, "((child)) pipe to stdin");
  314. ck_close (kidpipe[WRITE]);
  315. /* dup2(pipe[WRITE],STDOUT); */
  316. }
  317. else
  318. {
  319. /* dup2(pipe[READ],STDIN); */
  320. dupto (kidpipe[WRITE], STDOUT, "((child)) pipe to stdout");
  321. ck_close (kidpipe[READ]);
  322. }
  323. /* ck_close(pipe[READ]); */
  324. /* ck_close(pipe[WRITE]); */
  325. /* ck_close(kidpipe[READ]);
  326. ck_close(kidpipe[WRITE]); */
  327. }
  328. else
  329. {
  330. /* Grandchild. Do the right thing, namely sit here and
  331. read/write the archive, and feed stuff back to compress */
  332. tar = "tar (child)";
  333. if (ar_reading)
  334. {
  335. dupto (kidpipe[WRITE], STDOUT, "[child] pipe to stdout");
  336. ck_close (kidpipe[READ]);
  337. }
  338. else
  339. {
  340. dupto (kidpipe[READ], STDIN, "[child] pipe to stdin");
  341. ck_close (kidpipe[WRITE]);
  342. }
  343. if (ar_files[0][0] == '-' && ar_files[0][1] == '\0')
  344. {
  345. if (ar_reading)
  346. archive = STDIN;
  347. else
  348. archive = STDOUT;
  349. }
  350. else /* This can't happen if (ar_reading==2)
  351. archive = rmtopen(ar_files[0], O_RDWR|O_CREAT|O_BINARY, 0666);
  352. else */ if (ar_reading)
  353. archive = rmtopen (ar_files[0], O_RDONLY | O_BINARY, 0666);
  354. else
  355. archive = rmtcreat (ar_files[0], 0666);
  356. if (archive < 0)
  357. {
  358. msg_perror ("can't open archive %s", ar_files[0]);
  359. exit (EX_BADARCH);
  360. }
  361. if (ar_reading)
  362. {
  363. for (;;)
  364. {
  365. char *ptr;
  366. int max, count;
  367. r_error_count = 0;
  368. error_loop:
  369. err = rmtread (archive, ar_block->charptr, (int) (blocksize));
  370. if (err < 0)
  371. {
  372. readerror ();
  373. goto error_loop;
  374. }
  375. if (err == 0)
  376. break;
  377. ptr = ar_block->charptr;
  378. max = err;
  379. while (max)
  380. {
  381. count = (max < RECORDSIZE) ? max : RECORDSIZE;
  382. err = write (STDOUT, ptr, count);
  383. if (err != count)
  384. {
  385. if (err < 0)
  386. {
  387. msg_perror ("can't write to compression program");
  388. exit (EX_SYSTEM);
  389. }
  390. else
  391. msg ("write to compression program short %d bytes",
  392. count - err);
  393. count = (err < 0) ? 0 : err;
  394. }
  395. ptr += count;
  396. max -= count;
  397. }
  398. }
  399. }
  400. else
  401. {
  402. for (;;)
  403. {
  404. int n;
  405. char *ptr;
  406. n = blocksize;
  407. ptr = ar_block->charptr;
  408. while (n)
  409. {
  410. err = read (STDIN, ptr, (n < RECORDSIZE) ? n : RECORDSIZE);
  411. if (err <= 0)
  412. break;
  413. n -= err;
  414. ptr += err;
  415. }
  416. /* EOF */
  417. if (err == 0)
  418. {
  419. if (!f_compress_block)
  420. blocksize -= n;
  421. else
  422. bzero (ar_block->charptr + blocksize - n, n);
  423. err = rmtwrite (archive, ar_block->charptr, blocksize);
  424. if (err != (blocksize))
  425. writeerror (err);
  426. if (!f_compress_block)
  427. blocksize += n;
  428. break;
  429. }
  430. if (n)
  431. {
  432. msg_perror ("can't read from compression program");
  433. exit (EX_SYSTEM);
  434. }
  435. err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
  436. if (err != blocksize)
  437. writeerror (err);
  438. }
  439. }
  440. /* close_archive(); */
  441. exit (0);
  442. }
  443. }
  444. /* So we should exec compress (-d) */
  445. if (ar_reading)
  446. execlp (f_compressprog, f_compressprog, "-d", (char *) 0);
  447. else
  448. execlp (f_compressprog, f_compressprog, (char *) 0);
  449. msg_perror ("can't exec %s", f_compressprog);
  450. _exit (EX_SYSTEM);
  451. }
  452. /* return non-zero if p is the name of a directory */
  453. int
  454. isfile (p)
  455. char *p;
  456. {
  457. struct stat stbuf;
  458. if (stat (p, &stbuf) < 0)
  459. return 1;
  460. if (S_ISREG (stbuf.st_mode))
  461. return 1;
  462. return 0;
  463. }
  464. #endif
  465. /*
  466. * Open an archive file. The argument specifies whether we are
  467. * reading or writing.
  468. */
  469. /* JF if the arg is 2, open for reading and writing. */
  470. void
  471. open_archive (reading)
  472. int reading;
  473. {
  474. msg_file = f_exstdout ? stderr : stdout;
  475. if (blocksize == 0)
  476. {
  477. msg ("invalid value for blocksize");
  478. exit (EX_ARGSBAD);
  479. }
  480. if (n_ar_files == 0)
  481. {
  482. msg ("No archive name given, what should I do?");
  483. exit (EX_BADARCH);
  484. }
  485. /*NOSTRICT*/
  486. if (f_multivol)
  487. {
  488. ar_block = (union record *) valloc ((unsigned) (blocksize + (2 * RECORDSIZE)));
  489. if (ar_block)
  490. ar_block += 2;
  491. }
  492. else
  493. ar_block = (union record *) valloc ((unsigned) blocksize);
  494. if (!ar_block)
  495. {
  496. msg ("could not allocate memory for blocking factor %d",
  497. blocking);
  498. exit (EX_ARGSBAD);
  499. }
  500. ar_record = ar_block;
  501. ar_last = ar_block + blocking;
  502. ar_reading = reading;
  503. if (f_multivol && f_verify)
  504. {
  505. msg ("cannot verify multi-volume archives");
  506. exit (EX_ARGSBAD);
  507. }
  508. if (f_compressprog)
  509. {
  510. if (reading == 2 || f_verify)
  511. {
  512. msg ("cannot update or verify compressed archives");
  513. exit (EX_ARGSBAD);
  514. }
  515. if (f_multivol)
  516. {
  517. msg ("cannot use multi-volume compressed archives");
  518. exit (EX_ARGSBAD);
  519. }
  520. child_open ();
  521. if (!reading && ar_files[0][0] == '-' && ar_files[0][1] == '\0')
  522. msg_file = stderr;
  523. /* child_open(rem_host, rem_file); */
  524. }
  525. else if (ar_files[0][0] == '-' && ar_files[0][1] == '\0')
  526. {
  527. f_reblock++; /* Could be a pipe, be safe */
  528. if (f_verify)
  529. {
  530. msg ("can't verify stdin/stdout archive");
  531. exit (EX_ARGSBAD);
  532. }
  533. if (reading == 2)
  534. {
  535. archive = STDIN;
  536. msg_file = stderr;
  537. write_archive_to_stdout++;
  538. }
  539. else if (reading)
  540. archive = STDIN;
  541. else
  542. {
  543. archive = STDOUT;
  544. msg_file = stderr;
  545. }
  546. }
  547. else if (reading == 2 || f_verify)
  548. {
  549. archive = rmtopen (ar_files[0], O_RDWR | O_CREAT | O_BINARY, 0666);
  550. }
  551. else if (reading)
  552. {
  553. archive = rmtopen (ar_files[0], O_RDONLY | O_BINARY, 0666);
  554. }
  555. else
  556. {
  557. archive = rmtcreat (ar_files[0], 0666);
  558. }
  559. if (archive < 0)
  560. {
  561. msg_perror ("can't open %s", ar_files[0]);
  562. exit (EX_BADARCH);
  563. }
  564. #ifndef __MSDOS__
  565. if (!_isrmt (archive))
  566. {
  567. struct stat tmp_stat;
  568. fstat (archive, &tmp_stat);
  569. if (S_ISREG (tmp_stat.st_mode))
  570. {
  571. ar_dev = tmp_stat.st_dev;
  572. ar_ino = tmp_stat.st_ino;
  573. }
  574. }
  575. #endif
  576. #ifdef __MSDOS__
  577. setmode (archive, O_BINARY);
  578. #endif
  579. if (reading)
  580. {
  581. ar_last = ar_block; /* Set up for 1st block = # 0 */
  582. (void) findrec (); /* Read it in, check for EOF */
  583. if (f_volhdr)
  584. {
  585. union record *head;
  586. #if 0
  587. char *ptr;
  588. if (f_multivol)
  589. {
  590. ptr = malloc (strlen (f_volhdr) + 20);
  591. sprintf (ptr, "%s Volume %d", f_volhdr, 1);
  592. }
  593. else
  594. ptr = f_volhdr;
  595. #endif
  596. head = findrec ();
  597. if (!head)
  598. {
  599. msg ("Archive not labelled to match %s", f_volhdr);
  600. exit (EX_BADVOL);
  601. }
  602. if (re_match (label_pattern, head->header.arch_name,
  603. strlen (head->header.arch_name), 0, 0) < 0)
  604. {
  605. msg ("Volume mismatch! %s!=%s", f_volhdr,
  606. head->header.arch_name);
  607. exit (EX_BADVOL);
  608. }
  609. #if 0
  610. if (strcmp (ptr, head->header.name))
  611. {
  612. msg ("Volume mismatch! %s!=%s", ptr, head->header.name);
  613. exit (EX_BADVOL);
  614. }
  615. if (ptr != f_volhdr)
  616. free (ptr);
  617. #endif
  618. }
  619. }
  620. else if (f_volhdr)
  621. {
  622. bzero ((void *) ar_block, RECORDSIZE);
  623. if (f_multivol)
  624. sprintf (ar_block->header.arch_name, "%s Volume 1", f_volhdr);
  625. else
  626. strcpy (ar_block->header.arch_name, f_volhdr);
  627. current_file_name = ar_block->header.arch_name;
  628. ar_block->header.linkflag = LF_VOLHDR;
  629. to_oct (time (0), 1 + 12, ar_block->header.mtime);
  630. finish_header (ar_block);
  631. /* ar_record++; */
  632. }
  633. }
  634. /*
  635. * Remember a union record * as pointing to something that we
  636. * need to keep when reading onward in the file. Only one such
  637. * thing can be remembered at once, and it only works when reading
  638. * an archive.
  639. *
  640. * We calculate "offset" then add it because some compilers end up
  641. * adding (baserec+ar_record), doing a 9-bit shift of baserec, then
  642. * subtracting ar_block from that, shifting it back, losing the top 9 bits.
  643. */
  644. void
  645. saverec (pointer)
  646. union record **pointer;
  647. {
  648. long offset;
  649. save_rec = pointer;
  650. offset = ar_record - ar_block;
  651. saved_recno = baserec + offset;
  652. }
  653. /*
  654. * Perform a write to flush the buffer.
  655. */
  656. /*send_buffer_to_file();
  657. if(new_volume) {
  658. deal_with_new_volume_stuff();
  659. send_buffer_to_file();
  660. }
  661. */
  662. void
  663. fl_write ()
  664. {
  665. int err;
  666. int copy_back;
  667. static long bytes_written = 0;
  668. if (f_checkpoint && !(++checkpoint % 10))
  669. msg ("Write checkpoint %d\n", checkpoint);
  670. if (tape_length && bytes_written >= tape_length * 1024)
  671. {
  672. errno = ENOSPC;
  673. err = 0;
  674. }
  675. else
  676. err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
  677. if (err != blocksize && !f_multivol)
  678. writeerror (err);
  679. else if (f_totals)
  680. tot_written += blocksize;
  681. if (err > 0)
  682. bytes_written += err;
  683. if (err == blocksize)
  684. {
  685. if (f_multivol)
  686. {
  687. if (!save_name)
  688. {
  689. real_s_name[0] = '\0';
  690. real_s_totsize = 0;
  691. real_s_sizeleft = 0;
  692. return;
  693. }
  694. #ifdef __MSDOS__
  695. if (save_name[1] == ':')
  696. save_name += 2;
  697. #endif
  698. while (*save_name == '/')
  699. save_name++;
  700. strcpy (real_s_name, save_name);
  701. real_s_totsize = save_totsize;
  702. real_s_sizeleft = save_sizeleft;
  703. }
  704. return;
  705. }
  706. /* We're multivol Panic if we didn't get the right kind of response */
  707. /* ENXIO is for the UNIX PC */
  708. if (err < 0 && errno != ENOSPC && errno != EIO && errno != ENXIO)
  709. writeerror (err);
  710. /* If error indicates a short write, we just move to the next tape. */
  711. if (new_volume (0) < 0)
  712. return;
  713. bytes_written = 0;
  714. if (f_volhdr && real_s_name[0])
  715. {
  716. copy_back = 2;
  717. ar_block -= 2;
  718. }
  719. else if (f_volhdr || real_s_name[0])
  720. {
  721. copy_back = 1;
  722. ar_block--;
  723. }
  724. else
  725. copy_back = 0;
  726. if (f_volhdr)
  727. {
  728. bzero ((void *) ar_block, RECORDSIZE);
  729. sprintf (ar_block->header.arch_name, "%s Volume %d", f_volhdr, volno);
  730. to_oct (time (0), 1 + 12, ar_block->header.mtime);
  731. ar_block->header.linkflag = LF_VOLHDR;
  732. finish_header (ar_block);
  733. }
  734. if (real_s_name[0])
  735. {
  736. int tmp;
  737. if (f_volhdr)
  738. ar_block++;
  739. bzero ((void *) ar_block, RECORDSIZE);
  740. strcpy (ar_block->header.arch_name, real_s_name);
  741. ar_block->header.linkflag = LF_MULTIVOL;
  742. to_oct ((long) real_s_sizeleft, 1 + 12,
  743. ar_block->header.size);
  744. to_oct ((long) real_s_totsize - real_s_sizeleft,
  745. 1 + 12, ar_block->header.offset);
  746. tmp = f_verbose;
  747. f_verbose = 0;
  748. finish_header (ar_block);
  749. f_verbose = tmp;
  750. if (f_volhdr)
  751. ar_block--;
  752. }
  753. err = rmtwrite (archive, ar_block->charptr, (int) blocksize);
  754. if (err != blocksize)
  755. writeerror (err);
  756. else if (f_totals)
  757. tot_written += blocksize;
  758. bytes_written = blocksize;
  759. if (copy_back)
  760. {
  761. ar_block += copy_back;
  762. bcopy ((void *) (ar_block + blocking - copy_back),
  763. (void *) ar_record,
  764. copy_back * RECORDSIZE);
  765. ar_record += copy_back;
  766. if (real_s_sizeleft >= copy_back * RECORDSIZE)
  767. real_s_sizeleft -= copy_back * RECORDSIZE;
  768. else if ((real_s_sizeleft + RECORDSIZE - 1) / RECORDSIZE <= copy_back)
  769. real_s_name[0] = '\0';
  770. else
  771. {
  772. #ifdef __MSDOS__
  773. if (save_name[1] == ':')
  774. save_name += 2;
  775. #endif
  776. while (*save_name == '/')
  777. save_name++;
  778. strcpy (real_s_name, save_name);
  779. real_s_sizeleft = save_sizeleft;
  780. real_s_totsize = save_totsize;
  781. }
  782. copy_back = 0;
  783. }
  784. }
  785. /* Handle write errors on the archive. Write errors are always fatal */
  786. /* Hitting the end of a volume does not cause a write error unless the write
  787. * was the first block of the volume */
  788. void
  789. writeerror (err)
  790. int err;
  791. {
  792. if (err < 0)
  793. {
  794. msg_perror ("can't write to %s", ar_files[cur_ar_file]);
  795. exit (EX_BADARCH);
  796. }
  797. else
  798. {
  799. msg ("only wrote %u of %u bytes to %s", err, blocksize, ar_files[cur_ar_file]);
  800. exit (EX_BADARCH);
  801. }
  802. }
  803. /*
  804. * Handle read errors on the archive.
  805. *
  806. * If the read should be retried, readerror() returns to the caller.
  807. */
  808. void
  809. readerror ()
  810. {
  811. # define READ_ERROR_MAX 10
  812. read_error_flag++; /* Tell callers */
  813. msg_perror ("read error on %s", ar_files[cur_ar_file]);
  814. if (baserec == 0)
  815. {
  816. /* First block of tape. Probably stupidity error */
  817. exit (EX_BADARCH);
  818. }
  819. /*
  820. * Read error in mid archive. We retry up to READ_ERROR_MAX times
  821. * and then give up on reading the archive. We set read_error_flag
  822. * for our callers, so they can cope if they want.
  823. */
  824. if (r_error_count++ > READ_ERROR_MAX)
  825. {
  826. msg ("Too many errors, quitting.");
  827. exit (EX_BADARCH);
  828. }
  829. return;
  830. }
  831. /*
  832. * Perform a read to flush the buffer.
  833. */
  834. void
  835. fl_read ()
  836. {
  837. int err; /* Result from system call */
  838. int left; /* Bytes left */
  839. char *more; /* Pointer to next byte to read */
  840. if (f_checkpoint && !(++checkpoint % 10))
  841. msg ("Read checkpoint %d\n", checkpoint);
  842. /*
  843. * Clear the count of errors. This only applies to a single
  844. * call to fl_read. We leave read_error_flag alone; it is
  845. * only turned off by higher level software.
  846. */
  847. r_error_count = 0; /* Clear error count */
  848. /*
  849. * If we are about to wipe out a record that
  850. * somebody needs to keep, copy it out to a holding
  851. * area and adjust somebody's pointer to it.
  852. */
  853. if (save_rec &&
  854. *save_rec >= ar_record &&
  855. *save_rec < ar_last)
  856. {
  857. record_save_area = **save_rec;
  858. *save_rec = &record_save_area;
  859. }
  860. if (write_archive_to_stdout && baserec != 0)
  861. {
  862. err = rmtwrite (1, ar_block->charptr, blocksize);
  863. if (err != blocksize)
  864. writeerror (err);
  865. }
  866. if (f_multivol)
  867. {
  868. if (save_name)
  869. {
  870. if (save_name != real_s_name)
  871. {
  872. #ifdef __MSDOS__
  873. if (save_name[1] == ':')
  874. save_name += 2;
  875. #endif
  876. while (*save_name == '/')
  877. save_name++;
  878. strcpy (real_s_name, save_name);
  879. save_name = real_s_name;
  880. }
  881. real_s_totsize = save_totsize;
  882. real_s_sizeleft = save_sizeleft;
  883. }
  884. else
  885. {
  886. real_s_name[0] = '\0';
  887. real_s_totsize = 0;
  888. real_s_sizeleft = 0;
  889. }
  890. }
  891. error_loop:
  892. err = rmtread (archive, ar_block->charptr, (int) blocksize);
  893. if (err == blocksize)
  894. return;
  895. if ((err == 0 || (err < 0 && errno == ENOSPC) || (err > 0 && !f_reblock)) && f_multivol)
  896. {
  897. union record *head;
  898. try_volume:
  899. if (new_volume ((cmd_mode == CMD_APPEND || cmd_mode == CMD_CAT || cmd_mode == CMD_UPDATE) ? 2 : 1) < 0)
  900. return;
  901. vol_error:
  902. err = rmtread (archive, ar_block->charptr, (int) blocksize);
  903. if (err < 0)
  904. {
  905. readerror ();
  906. goto vol_error;
  907. }
  908. if (err != blocksize)
  909. goto short_read;
  910. head = ar_block;
  911. if (head->header.linkflag == LF_VOLHDR)
  912. {
  913. if (f_volhdr)
  914. {
  915. #if 0
  916. char *ptr;
  917. ptr = (char *) malloc (strlen (f_volhdr) + 20);
  918. sprintf (ptr, "%s Volume %d", f_volhdr, volno);
  919. #endif
  920. if (re_match (label_pattern, head->header.arch_name,
  921. strlen (head->header.arch_name),
  922. 0, 0) < 0)
  923. {
  924. msg ("Volume mismatch! %s!=%s", f_volhdr,
  925. head->header.arch_name);
  926. --volno;
  927. --global_volno;
  928. goto try_volume;
  929. }
  930. #if 0
  931. if (strcmp (ptr, head->header.name))
  932. {
  933. msg ("Volume mismatch! %s!=%s", ptr, head->header.name);
  934. --volno;
  935. --global_volno;
  936. free (ptr);
  937. goto try_volume;
  938. }
  939. free (ptr);
  940. #endif
  941. }
  942. if (f_verbose)
  943. fprintf (msg_file, "Reading %s\n", head->header.arch_name);
  944. head++;
  945. }
  946. else if (f_volhdr)
  947. {
  948. msg ("Warning: No volume header!");
  949. }
  950. if (real_s_name[0])
  951. {
  952. long from_oct ();
  953. if (head->header.linkflag != LF_MULTIVOL || strcmp (head->header.arch_name, real_s_name))
  954. {
  955. msg ("%s is not continued on this volume!", real_s_name);
  956. --volno;
  957. --global_volno;
  958. goto try_volume;
  959. }
  960. if (real_s_totsize != from_oct (1 + 12, head->header.size) + from_oct (1 + 12, head->header.offset))
  961. {
  962. msg ("%s is the wrong size (%ld!=%ld+%ld)",
  963. head->header.arch_name, save_totsize,
  964. from_oct (1 + 12, head->header.size),
  965. from_oct (1 + 12, head->header.offset));
  966. --volno;
  967. --global_volno;
  968. goto try_volume;
  969. }
  970. if (real_s_totsize - real_s_sizeleft != from_oct (1 + 12, head->header.offset))
  971. {
  972. msg ("This volume is out of sequence");
  973. --volno;
  974. --global_volno;
  975. goto try_volume;
  976. }
  977. head++;
  978. }
  979. ar_record = head;
  980. return;
  981. }
  982. else if (err < 0)
  983. {
  984. readerror ();
  985. goto error_loop; /* Try again */
  986. }
  987. short_read:
  988. more = ar_block->charptr + err;
  989. left = blocksize - err;
  990. again:
  991. if (0 == (((unsigned) left) % RECORDSIZE))
  992. {
  993. /* FIXME, for size=0, multi vol support */
  994. /* On the first block, warn about the problem */
  995. if (!f_reblock && baserec == 0 && f_verbose && err > 0)
  996. {
  997. /* msg("Blocksize = %d record%s",
  998. err / RECORDSIZE, (err > RECORDSIZE)? "s": "");*/
  999. msg ("Blocksize = %d records", err / RECORDSIZE);
  1000. }
  1001. ar_last = ar_block + ((unsigned) (blocksize - left)) / RECORDSIZE;
  1002. return;
  1003. }
  1004. if (f_reblock)
  1005. {
  1006. /*
  1007. * User warned us about this. Fix up.
  1008. */
  1009. if (left > 0)
  1010. {
  1011. error2loop:
  1012. err = rmtread (archive, more, (int) left);
  1013. if (err < 0)
  1014. {
  1015. readerror ();
  1016. goto error2loop; /* Try again */
  1017. }
  1018. if (err == 0)
  1019. {
  1020. msg ("archive %s EOF not on block boundary", ar_files[cur_ar_file]);
  1021. exit (EX_BADARCH);
  1022. }
  1023. left -= err;
  1024. more += err;
  1025. goto again;
  1026. }
  1027. }
  1028. else
  1029. {
  1030. msg ("only read %d bytes from archive %s", err, ar_files[cur_ar_file]);
  1031. exit (EX_BADARCH);
  1032. }
  1033. }
  1034. /*
  1035. * Flush the current buffer to/from the archive.
  1036. */
  1037. void
  1038. flush_archive ()
  1039. {
  1040. int c;
  1041. baserec += ar_last - ar_block;/* Keep track of block #s */
  1042. ar_record = ar_block; /* Restore pointer to start */
  1043. ar_last = ar_block + blocking;/* Restore pointer to end */
  1044. if (ar_reading)
  1045. {
  1046. if (time_to_start_writing)
  1047. {
  1048. time_to_start_writing = 0;
  1049. ar_reading = 0;
  1050. if (file_to_switch_to >= 0)
  1051. {
  1052. if ((c = rmtclose (archive)) < 0)
  1053. msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
  1054. archive = file_to_switch_to;
  1055. }
  1056. else
  1057. (void) backspace_output ();
  1058. fl_write ();
  1059. }
  1060. else
  1061. fl_read ();
  1062. }
  1063. else
  1064. {
  1065. fl_write ();
  1066. }
  1067. }
  1068. /* Backspace the archive descriptor by one blocks worth.
  1069. If its a tape, MTIOCTOP will work. If its something else,
  1070. we try to seek on it. If we can't seek, we lose! */
  1071. int
  1072. backspace_output ()
  1073. {
  1074. long cur;
  1075. /* int er; */
  1076. extern char *output_start;
  1077. #ifdef MTIOCTOP
  1078. struct mtop t;
  1079. t.mt_op = MTBSR;
  1080. t.mt_count = 1;
  1081. if ((rmtioctl (archive, MTIOCTOP, &t)) >= 0)
  1082. return 1;
  1083. if (errno == EIO && (rmtioctl (archive, MTIOCTOP, &t)) >= 0)
  1084. return 1;
  1085. #endif
  1086. cur = rmtlseek (archive, 0L, 1);
  1087. cur -= blocksize;
  1088. /* Seek back to the beginning of this block and
  1089. start writing there. */
  1090. if (rmtlseek (archive, cur, 0) != cur)
  1091. {
  1092. /* Lseek failed. Try a different method */
  1093. msg ("Couldn't backspace archive file. It may be unreadable without -i.");
  1094. /* Replace the first part of the block with nulls */
  1095. if (ar_block->charptr != output_start)
  1096. bzero (ar_block->charptr, output_start - ar_block->charptr);
  1097. return 2;
  1098. }
  1099. return 3;
  1100. }
  1101. /*
  1102. * Close the archive file.
  1103. */
  1104. void
  1105. close_archive ()
  1106. {
  1107. int child;
  1108. int status;
  1109. int c;
  1110. if (time_to_start_writing || !ar_reading)
  1111. flush_archive ();
  1112. if (cmd_mode == CMD_DELETE)
  1113. {
  1114. off_t pos;
  1115. pos = rmtlseek (archive, 0L, 1);
  1116. #ifndef __MSDOS__
  1117. (void) ftruncate (archive, pos);
  1118. #else
  1119. (void) rmtwrite (archive, "", 0);
  1120. #endif
  1121. }
  1122. if (f_verify)
  1123. verify_volume ();
  1124. if ((c = rmtclose (archive)) < 0)
  1125. msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
  1126. #ifndef __MSDOS__
  1127. if (childpid)
  1128. {
  1129. /*
  1130. * Loop waiting for the right child to die, or for
  1131. * no more kids.
  1132. */
  1133. while (((child = wait (&status)) != childpid) && child != -1)
  1134. ;
  1135. if (child != -1)
  1136. {
  1137. if (WIFSIGNALED (status))
  1138. {
  1139. /* SIGPIPE is OK, everything else is a problem. */
  1140. if (WTERMSIG (status) != SIGPIPE)
  1141. msg ("child died with signal %d%s", WTERMSIG (status),
  1142. WIFCOREDUMPED (status) ? " (core dumped)" : "");
  1143. }
  1144. else
  1145. {
  1146. /* Child voluntarily terminated -- but why? */
  1147. if (WEXITSTATUS (status) == MAGIC_STAT)
  1148. {
  1149. exit (EX_SYSTEM); /* Child had trouble */
  1150. }
  1151. if (WEXITSTATUS (status) == (SIGPIPE + 128))
  1152. {
  1153. /*
  1154. * /bin/sh returns this if its child
  1155. * dies with SIGPIPE. 'Sok.
  1156. */
  1157. /* Do nothing. */
  1158. }
  1159. else if (WEXITSTATUS (status))
  1160. msg ("child returned status %d",
  1161. WEXITSTATUS (status));
  1162. }
  1163. }
  1164. }
  1165. #endif /* __MSDOS__ */
  1166. }
  1167. #ifdef DONTDEF
  1168. /*
  1169. * Message management.
  1170. *
  1171. * anno writes a message prefix on stream (eg stdout, stderr).
  1172. *
  1173. * The specified prefix is normally output followed by a colon and a space.
  1174. * However, if other command line options are set, more output can come
  1175. * out, such as the record # within the archive.
  1176. *
  1177. * If the specified prefix is NULL, no output is produced unless the
  1178. * command line option(s) are set.
  1179. *
  1180. * If the third argument is 1, the "saved" record # is used; if 0, the
  1181. * "current" record # is used.
  1182. */
  1183. void
  1184. anno (stream, prefix, savedp)
  1185. FILE *stream;
  1186. char *prefix;
  1187. int savedp;
  1188. {
  1189. # define MAXANNO 50
  1190. char buffer[MAXANNO]; /* Holds annorecment */
  1191. # define ANNOWIDTH 13
  1192. int space;
  1193. long offset;
  1194. int save_e;
  1195. save_e = errno;
  1196. /* Make sure previous output gets out in sequence */
  1197. if (stream == stderr)
  1198. fflush (stdout);
  1199. if (f_sayblock)
  1200. {
  1201. if (prefix)
  1202. {
  1203. fputs (prefix, stream);
  1204. putc (' ', stream);
  1205. }
  1206. offset = ar_record - ar_block;
  1207. (void) sprintf (buffer, "rec %d: ",
  1208. savedp ? saved_recno :
  1209. baserec + offset);
  1210. fputs (buffer, stream);
  1211. space = ANNOWIDTH - strlen (buffer);
  1212. if (space > 0)
  1213. {
  1214. fprintf (stream, "%*s", space, "");
  1215. }
  1216. }
  1217. else if (prefix)
  1218. {
  1219. fputs (prefix, stream);
  1220. fputs (": ", stream);
  1221. }
  1222. errno = save_e;
  1223. }
  1224. #endif
  1225. /* Called to initialize the global volume number. */
  1226. void
  1227. init_volume_number ()
  1228. {
  1229. FILE *vf;
  1230. vf = fopen (f_volno_file, "r");
  1231. if (!vf && errno != ENOENT)
  1232. msg_perror ("%s", f_volno_file);
  1233. if (vf)
  1234. {
  1235. fscanf (vf, "%d", &global_volno);
  1236. fclose (vf);
  1237. }
  1238. }
  1239. /* Called to write out the closing global volume number. */
  1240. void
  1241. closeout_volume_number ()
  1242. {
  1243. FILE *vf;
  1244. vf = fopen (f_volno_file, "w");
  1245. if (!vf)
  1246. msg_perror ("%s", f_volno_file);
  1247. else
  1248. {
  1249. fprintf (vf, "%d\n", global_volno);
  1250. fclose (vf);
  1251. }
  1252. }
  1253. /* We've hit the end of the old volume. Close it and open the next one */
  1254. /* Values for type: 0: writing 1: reading 2: updating */
  1255. int
  1256. new_volume (type)
  1257. int type;
  1258. {
  1259. int c;
  1260. char inbuf[80];
  1261. char *p;
  1262. static FILE *read_file = 0;
  1263. extern int now_verifying;
  1264. extern char TTY_NAME[];
  1265. static int looped = 0;
  1266. if (!read_file && !f_run_script_at_end)
  1267. read_file = (archive == 0) ? fopen (TTY_NAME, "r") : stdin;
  1268. if (now_verifying)
  1269. return -1;
  1270. if (f_verify)
  1271. verify_volume ();
  1272. if ((c = rmtclose (archive)) < 0)
  1273. msg_perror ("Warning: can't close %s(%d,%d)", ar_files[cur_ar_file], archive, c);
  1274. global_volno++;
  1275. volno++;
  1276. cur_ar_file++;
  1277. if (cur_ar_file == n_ar_files)
  1278. {
  1279. cur_ar_file = 0;
  1280. looped = 1;
  1281. }
  1282. tryagain:
  1283. if (looped)
  1284. {
  1285. /* We have to prompt from now on. */
  1286. if (f_run_script_at_end)
  1287. {
  1288. closeout_volume_number ();
  1289. system (info_script);
  1290. }
  1291. else
  1292. for (;;)
  1293. {
  1294. fprintf (msg_file, "\007Prepare volume #%d for %s and hit return: ", global_volno, ar_files[cur_ar_file]);
  1295. fflush (msg_file);
  1296. if (fgets (inbuf, sizeof (inbuf), read_file) == 0)
  1297. {
  1298. fprintf (msg_file, "EOF? What does that mean?");
  1299. if (cmd_mode != CMD_EXTRACT && cmd_mode != CMD_LIST && cmd_mode != CMD_DIFF)
  1300. msg ("Warning: Archive is INCOMPLETE!");
  1301. exit (EX_BADARCH);
  1302. }
  1303. if (inbuf[0] == '\n' || inbuf[0] == 'y' || inbuf[0] == 'Y')
  1304. break;
  1305. switch (inbuf[0])
  1306. {
  1307. case '?':
  1308. {
  1309. fprintf (msg_file, "\
  1310. n [name] Give a new filename for the next (and subsequent) volume(s)\n\
  1311. q Abort tar\n\
  1312. ! Spawn a subshell\n\
  1313. ? Print this list\n");
  1314. }
  1315. break;
  1316. case 'q': /* Quit */
  1317. fprintf (msg_file, "No new volume; exiting.\n");
  1318. if (cmd_mode != CMD_EXTRACT && cmd_mode != CMD_LIST && cmd_mode != CMD_DIFF)
  1319. msg ("Warning: Archive is INCOMPLETE!");
  1320. exit (EX_BADARCH);
  1321. case 'n': /* Get new file name */
  1322. {
  1323. char *q, *r;
  1324. static char *old_name;
  1325. for (q = &inbuf[1]; *q == ' ' || *q == '\t'; q++)
  1326. ;
  1327. for (r = q; *r; r++)
  1328. if (*r == '\n')
  1329. *r = '\0';
  1330. old_name = p = (char *) malloc ((unsigned) (strlen (q) + 2));
  1331. if (p == 0)
  1332. {
  1333. msg ("Can't allocate memory for name");
  1334. exit (EX_SYSTEM);
  1335. }
  1336. (void) strcpy (p, q);
  1337. ar_files[cur_ar_file] = p;
  1338. }
  1339. break;
  1340. case '!':
  1341. #ifdef __MSDOS__
  1342. spawnl (P_WAIT, getenv ("COMSPEC"), "-", 0);
  1343. #else
  1344. /* JF this needs work! */
  1345. switch (fork ())
  1346. {
  1347. case -1:
  1348. msg_perror ("can't fork!");
  1349. break;
  1350. case 0:
  1351. p = getenv ("SHELL");
  1352. if (p == 0)
  1353. p = "/bin/sh";
  1354. execlp (p, "-sh", "-i", 0);
  1355. msg_perror ("can't exec a shell %s", p);
  1356. _exit (55);
  1357. default:
  1358. wait (0);
  1359. break;
  1360. }
  1361. #endif
  1362. break;
  1363. }
  1364. }
  1365. }
  1366. if (type == 2 || f_verify)
  1367. archive = rmtopen (ar_files[cur_ar_file], O_RDWR | O_CREAT, 0666);
  1368. else if (type == 1)
  1369. archive = rmtopen (ar_files[cur_ar_file], O_RDONLY, 0666);
  1370. else if (type == 0)
  1371. archive = rmtcreat (ar_files[cur_ar_file], 0666);
  1372. else
  1373. archive = -1;
  1374. if (archive < 0)
  1375. {
  1376. msg_perror ("can't open %s", ar_files[cur_ar_file]);
  1377. goto tryagain;
  1378. }
  1379. #ifdef __MSDOS__
  1380. setmode (archive, O_BINARY);
  1381. #endif
  1382. return 0;
  1383. }
  1384. /* this is a useless function that takes a buffer returned by wantbytes
  1385. and does nothing with it. If the function called by wantbytes returns
  1386. an error indicator (non-zero), this function is called for the rest of
  1387. the file.
  1388. */
  1389. int
  1390. no_op (size, data)
  1391. int size;
  1392. char *data;
  1393. {
  1394. return 0;
  1395. }
  1396. /* Some other routine wants SIZE bytes in the archive. For each chunk of
  1397. the archive, call FUNC with the size of the chunk, and the address of
  1398. the chunk it can work with.
  1399. */
  1400. int
  1401. wantbytes (size, func)
  1402. long size;
  1403. int (*func) ();
  1404. {
  1405. char *data;
  1406. long data_size;
  1407. while (size)
  1408. {
  1409. data = findrec ()->charptr;
  1410. if (data == NULL)
  1411. { /* Check it... */
  1412. msg ("Unexpected EOF on archive file");
  1413. return -1;
  1414. }
  1415. data_size = endofrecs ()->charptr - data;
  1416. if (data_size > size)
  1417. data_size = size;
  1418. if ((*func) (data_size, data))
  1419. func = no_op;
  1420. userec ((union record *) (data + data_size - 1));
  1421. size -= data_size;
  1422. }
  1423. return 0;
  1424. }