tar.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332
  1. /*
  2. * tar - `tape archiver', actually usable on any medium.
  3. * POSIX "ustar" compliant when extracting, and by default when creating.
  4. * this tar attempts to read and write multiple Tblock-byte blocks
  5. * at once to and from the filesystem, and does not copy blocks
  6. * around internally.
  7. */
  8. #include <u.h>
  9. #include <libc.h>
  10. #include <ctype.h>
  11. #include <fcall.h> /* for %M */
  12. #include <String.h>
  13. /*
  14. * modified versions of those in libc.h; scans only the first arg for
  15. * keyletters and options.
  16. */
  17. #define TARGBEGIN {\
  18. (argv0 || (argv0 = *argv)), argv++, argc--;\
  19. if (argv[0]) {\
  20. char *_args, *_argt;\
  21. Rune _argc;\
  22. _args = &argv[0][0];\
  23. _argc = 0;\
  24. while(*_args && (_args += chartorune(&_argc, _args)))\
  25. switch(_argc)
  26. #define TARGEND SET(_argt); USED(_argt);USED(_argc);USED(_args); \
  27. argc--, argv++; } \
  28. USED(argv); USED(argc); }
  29. #define TARGC() (_argc)
  30. #define HOWMANY(a, size) (((a) + (size) - 1) / (size))
  31. #define BYTES2TBLKS(bytes) HOWMANY(bytes, Tblock)
  32. /* read big-endian binary integers; args must be (uchar *) */
  33. #define G2BEBYTE(x) (((x)[0]<<8) | (x)[1])
  34. #define G3BEBYTE(x) (((x)[0]<<16) | ((x)[1]<<8) | (x)[2])
  35. #define G4BEBYTE(x) (((x)[0]<<24) | ((x)[1]<<16) | ((x)[2]<<8) | (x)[3])
  36. #define G8BEBYTE(x) (((vlong)G4BEBYTE(x)<<32) | (u32int)G4BEBYTE((x)+4))
  37. typedef vlong Off;
  38. typedef char *(*Refill)(int ar, char *bufs, int justhdr);
  39. enum { Stdin, Stdout, Stderr };
  40. enum { Rd, Wr }; /* pipe fd-array indices */
  41. enum { Output, Input };
  42. enum { None, Toc, Xtract, Replace };
  43. enum { Alldata, Justnxthdr };
  44. enum {
  45. Tblock = 512,
  46. Namsiz = 100,
  47. Maxpfx = 155, /* from POSIX */
  48. Maxname = Namsiz + 1 + Maxpfx,
  49. Binsize = 0x80, /* flag in size[0], from gnu: positive binary size */
  50. Binnegsz = 0xff, /* flag in size[0]: negative binary size */
  51. Nblock = 40, /* maximum blocksize */
  52. Dblock = 20, /* default blocksize */
  53. Debug = 0,
  54. };
  55. /* POSIX link flags */
  56. enum {
  57. LF_PLAIN1 = '\0',
  58. LF_PLAIN2 = '0',
  59. LF_LINK = '1',
  60. LF_SYMLINK1 = '2',
  61. LF_SYMLINK2 = 's', /* 4BSD used this */
  62. LF_CHR = '3',
  63. LF_BLK = '4',
  64. LF_DIR = '5',
  65. LF_FIFO = '6',
  66. LF_CONTIG = '7',
  67. /* 'A' - 'Z' are reserved for custom implementations */
  68. };
  69. #define islink(lf) (isreallink(lf) || issymlink(lf))
  70. #define isreallink(lf) ((lf) == LF_LINK)
  71. #define issymlink(lf) ((lf) == LF_SYMLINK1 || (lf) == LF_SYMLINK2)
  72. typedef union {
  73. uchar data[Tblock];
  74. struct {
  75. char name[Namsiz];
  76. char mode[8];
  77. char uid[8];
  78. char gid[8];
  79. char size[12];
  80. char mtime[12];
  81. char chksum[8];
  82. char linkflag;
  83. char linkname[Namsiz];
  84. /* rest are defined by POSIX's ustar format; see p1003.2b */
  85. char magic[6]; /* "ustar" */
  86. char version[2];
  87. char uname[32];
  88. char gname[32];
  89. char devmajor[8];
  90. char devminor[8];
  91. char prefix[Maxpfx]; /* if non-null, path= prefix "/" name */
  92. };
  93. } Hdr;
  94. typedef struct {
  95. char *comp;
  96. char *decomp;
  97. char *sfx[4];
  98. } Compress;
  99. static Compress comps[] = {
  100. "gzip", "gunzip", { ".tar.gz", ".tgz" }, /* default */
  101. "compress", "uncompress", { ".tar.Z", ".tz" },
  102. "bzip2", "bunzip2", { ".tar.bz", ".tbz",
  103. ".tar.bz2",".tbz2" },
  104. };
  105. typedef struct {
  106. int kid;
  107. int fd; /* original fd */
  108. int rfd; /* replacement fd */
  109. int input;
  110. int open;
  111. } Pushstate;
  112. #define OTHER(rdwr) ((rdwr) == Rd? Wr: Rd)
  113. static int debug;
  114. static int fixednblock;
  115. static int verb;
  116. static int posix = 1;
  117. static int docreate;
  118. static int aruid;
  119. static int argid;
  120. static int relative = 1;
  121. static int settime;
  122. static int verbose;
  123. static int docompress;
  124. static int keepexisting;
  125. static int ignerrs; /* flag: ignore i/o errors if possible */
  126. static Off blkoff; /* offset of the current archive block (not Tblock) */
  127. static Off nexthdr;
  128. static int nblock = Dblock;
  129. static int resync;
  130. static char *usefile, *arname = "archive";
  131. static char origdir[Maxname*2];
  132. static Hdr *tpblk, *endblk;
  133. static Hdr *curblk;
  134. static void
  135. usage(void)
  136. {
  137. fprint(2, "usage: %s {crtx}[PRTfgikmpsuvz] [archive] [file1 file2...]\n",
  138. argv0);
  139. exits("usage");
  140. }
  141. /* I/O, with error retry or exit */
  142. static int
  143. cope(char *name, int fd, void *buf, long len, Off off)
  144. {
  145. fprint(2, "%s: %serror reading %s: %r\n", argv0,
  146. (ignerrs? "ignoring ": ""), name);
  147. if (!ignerrs)
  148. exits("read error");
  149. /* pretend we read len bytes of zeroes */
  150. memset(buf, 0, len);
  151. if (off >= 0) /* seekable? */
  152. seek(fd, off + len, 0);
  153. return len;
  154. }
  155. static int
  156. eread(char *name, int fd, void *buf, long len)
  157. {
  158. int rd;
  159. Off off;
  160. off = seek(fd, 0, 1); /* for coping with errors */
  161. rd = read(fd, buf, len);
  162. if (rd < 0)
  163. rd = cope(name, fd, buf, len, off);
  164. return rd;
  165. }
  166. static int
  167. ereadn(char *name, int fd, void *buf, long len)
  168. {
  169. int rd;
  170. Off off;
  171. off = seek(fd, 0, 1);
  172. rd = readn(fd, buf, len);
  173. if (rd < 0)
  174. rd = cope(name, fd, buf, len, off);
  175. return rd;
  176. }
  177. static int
  178. ewrite(char *name, int fd, void *buf, long len)
  179. {
  180. int rd;
  181. werrstr("");
  182. rd = write(fd, buf, len);
  183. if (rd != len)
  184. sysfatal("error writing %s: %r", name);
  185. return rd;
  186. }
  187. /* compression */
  188. static Compress *
  189. compmethod(char *name)
  190. {
  191. int i, nmlen = strlen(name), sfxlen;
  192. Compress *cp;
  193. for (cp = comps; cp < comps + nelem(comps); cp++)
  194. for (i = 0; i < nelem(cp->sfx) && cp->sfx[i]; i++) {
  195. sfxlen = strlen(cp->sfx[i]);
  196. if (nmlen > sfxlen &&
  197. strcmp(cp->sfx[i], name + nmlen - sfxlen) == 0)
  198. return cp;
  199. }
  200. return docompress? comps: nil;
  201. }
  202. /*
  203. * push a filter, cmd, onto fd. if input, it's an input descriptor.
  204. * returns a descriptor to replace fd, or -1 on error.
  205. */
  206. static int
  207. push(int fd, char *cmd, int input, Pushstate *ps)
  208. {
  209. int nfd, pifds[2];
  210. String *s;
  211. ps->open = 0;
  212. ps->fd = fd;
  213. ps->input = input;
  214. if (fd < 0 || pipe(pifds) < 0)
  215. return -1;
  216. ps->kid = fork();
  217. switch (ps->kid) {
  218. case -1:
  219. return -1;
  220. case 0:
  221. if (input)
  222. dup(pifds[Wr], Stdout);
  223. else
  224. dup(pifds[Rd], Stdin);
  225. close(pifds[input? Rd: Wr]);
  226. dup(fd, (input? Stdin: Stdout));
  227. s = s_new();
  228. if (cmd[0] != '/')
  229. s_append(s, "/bin/");
  230. s_append(s, cmd);
  231. execl(s_to_c(s), cmd, nil);
  232. sysfatal("can't exec %s: %r", cmd);
  233. default:
  234. nfd = pifds[input? Rd: Wr];
  235. close(pifds[input? Wr: Rd]);
  236. break;
  237. }
  238. ps->rfd = nfd;
  239. ps->open = 1;
  240. return nfd;
  241. }
  242. static char *
  243. pushclose(Pushstate *ps)
  244. {
  245. Waitmsg *wm;
  246. if (ps->fd < 0 || ps->rfd < 0 || !ps->open)
  247. return "not open";
  248. close(ps->rfd);
  249. ps->rfd = -1;
  250. ps->open = 0;
  251. while ((wm = wait()) != nil && wm->pid != ps->kid)
  252. continue;
  253. return wm? wm->msg: nil;
  254. }
  255. /*
  256. * block-buffer management
  257. */
  258. static void
  259. initblks(void)
  260. {
  261. free(tpblk);
  262. tpblk = malloc(Tblock * nblock);
  263. assert(tpblk != nil);
  264. endblk = tpblk + nblock;
  265. }
  266. /*
  267. * (re)fill block buffers from archive. `justhdr' means we don't care
  268. * about the data before the next header block.
  269. */
  270. static char *
  271. refill(int ar, char *bufs, int justhdr)
  272. {
  273. int i, n;
  274. unsigned bytes = Tblock * nblock;
  275. static int done, first = 1, seekable;
  276. if (done)
  277. return nil;
  278. blkoff = seek(ar, 0, 1); /* note position for `tar r' */
  279. if (first)
  280. seekable = blkoff >= 0;
  281. /* try to size non-pipe input at first read */
  282. if (first && usefile && !fixednblock) {
  283. n = eread(arname, ar, bufs, bytes);
  284. if (n == 0)
  285. sysfatal("EOF reading archive %s: %r", arname);
  286. i = n;
  287. if (i % Tblock != 0)
  288. sysfatal("%s: archive block size (%d) error", arname, i);
  289. i /= Tblock;
  290. if (i != nblock) {
  291. nblock = i;
  292. fprint(2, "%s: blocking = %d\n", argv0, nblock);
  293. endblk = (Hdr *)bufs + nblock;
  294. bytes = n;
  295. }
  296. } else if (justhdr && seekable && nexthdr - blkoff >= bytes) {
  297. /* optimisation for huge archive members on seekable media */
  298. if (seek(ar, bytes, 1) < 0)
  299. sysfatal("can't seek on archive %s: %r", arname);
  300. n = bytes;
  301. } else
  302. n = ereadn(arname, ar, bufs, bytes);
  303. first = 0;
  304. if (n == 0)
  305. sysfatal("unexpected EOF reading archive %s", arname);
  306. if (n % Tblock != 0)
  307. sysfatal("partial block read from archive %s", arname);
  308. if (n != bytes) {
  309. done = 1;
  310. memset(bufs + n, 0, bytes - n);
  311. }
  312. return bufs;
  313. }
  314. static Hdr *
  315. getblk(int ar, Refill rfp, int justhdr)
  316. {
  317. if (curblk == nil || curblk >= endblk) { /* input block exhausted? */
  318. if (rfp != nil && (*rfp)(ar, (char *)tpblk, justhdr) == nil)
  319. return nil;
  320. curblk = tpblk;
  321. }
  322. return curblk++;
  323. }
  324. static Hdr *
  325. getblkrd(int ar, int justhdr)
  326. {
  327. return getblk(ar, refill, justhdr);
  328. }
  329. static Hdr *
  330. getblke(int ar)
  331. {
  332. return getblk(ar, nil, Alldata);
  333. }
  334. static Hdr *
  335. getblkz(int ar)
  336. {
  337. Hdr *hp = getblke(ar);
  338. if (hp != nil)
  339. memset(hp->data, 0, Tblock);
  340. return hp;
  341. }
  342. /*
  343. * how many block buffers are available, starting at the address
  344. * just returned by getblk*?
  345. */
  346. static int
  347. gothowmany(int max)
  348. {
  349. int n = endblk - (curblk - 1);
  350. return n > max? max: n;
  351. }
  352. /*
  353. * indicate that one is done with the last block obtained from getblke
  354. * and it is now available to be written into the archive.
  355. */
  356. static void
  357. putlastblk(int ar)
  358. {
  359. unsigned bytes = Tblock * nblock;
  360. /* if writing end-of-archive, aid compression (good hygiene too) */
  361. if (curblk < endblk)
  362. memset(curblk, 0, (char *)endblk - (char *)curblk);
  363. ewrite(arname, ar, tpblk, bytes);
  364. }
  365. static void
  366. putblk(int ar)
  367. {
  368. if (curblk >= endblk)
  369. putlastblk(ar);
  370. }
  371. static void
  372. putbackblk(int ar)
  373. {
  374. curblk--;
  375. USED(ar);
  376. }
  377. static void
  378. putreadblks(int ar, int blks)
  379. {
  380. curblk += blks - 1;
  381. USED(ar);
  382. }
  383. static void
  384. putblkmany(int ar, int blks)
  385. {
  386. assert(blks > 0);
  387. curblk += blks - 1;
  388. putblk(ar);
  389. }
  390. /*
  391. * common routines
  392. */
  393. /*
  394. * modifies hp->chksum but restores it; important for the last block of the
  395. * old archive when updating with `tar rf archive'
  396. */
  397. static long
  398. chksum(Hdr *hp)
  399. {
  400. int n = Tblock;
  401. long i = 0;
  402. uchar *cp = hp->data;
  403. char oldsum[sizeof hp->chksum];
  404. memmove(oldsum, hp->chksum, sizeof oldsum);
  405. memset(hp->chksum, ' ', sizeof hp->chksum);
  406. while (n-- > 0)
  407. i += *cp++;
  408. memmove(hp->chksum, oldsum, sizeof oldsum);
  409. return i;
  410. }
  411. static int
  412. isustar(Hdr *hp)
  413. {
  414. return strcmp(hp->magic, "ustar") == 0;
  415. }
  416. /*
  417. * s is at most n bytes long, but need not be NUL-terminated.
  418. * if shorter than n bytes, all bytes after the first NUL must also
  419. * be NUL.
  420. */
  421. static int
  422. strnlen(char *s, int n)
  423. {
  424. return s[n - 1] != '\0'? n: strlen(s);
  425. }
  426. /* set fullname from header */
  427. static char *
  428. name(Hdr *hp)
  429. {
  430. int pfxlen, namlen;
  431. char *fullname;
  432. static char fullnamebuf[2+Maxname+1]; /* 2+ for ./ on relative names */
  433. fullname = fullnamebuf+2;
  434. namlen = strnlen(hp->name, sizeof hp->name);
  435. if (hp->prefix[0] == '\0' || !isustar(hp)) { /* old-style name? */
  436. memmove(fullname, hp->name, namlen);
  437. fullname[namlen] = '\0';
  438. return fullname;
  439. }
  440. /* name is in two pieces */
  441. pfxlen = strnlen(hp->prefix, sizeof hp->prefix);
  442. memmove(fullname, hp->prefix, pfxlen);
  443. fullname[pfxlen] = '/';
  444. memmove(fullname + pfxlen + 1, hp->name, namlen);
  445. fullname[pfxlen + 1 + namlen] = '\0';
  446. return fullname;
  447. }
  448. static int
  449. isdir(Hdr *hp)
  450. {
  451. /* the mode test is ugly but sometimes necessary */
  452. return hp->linkflag == LF_DIR ||
  453. strrchr(name(hp), '\0')[-1] == '/' ||
  454. (strtoul(hp->mode, nil, 8)&0170000) == 040000;
  455. }
  456. static int
  457. eotar(Hdr *hp)
  458. {
  459. return name(hp)[0] == '\0';
  460. }
  461. /*
  462. static uvlong
  463. getbe(uchar *src, int size)
  464. {
  465. uvlong vl = 0;
  466. while (size-- > 0) {
  467. vl <<= 8;
  468. vl |= *src++;
  469. }
  470. return vl;
  471. }
  472. */
  473. static void
  474. putbe(uchar *dest, uvlong vl, int size)
  475. {
  476. for (dest += size; size-- > 0; vl >>= 8)
  477. *--dest = vl;
  478. }
  479. /*
  480. * cautious parsing of octal numbers as ascii strings in
  481. * a tar header block. this is particularly important for
  482. * trusting the checksum when trying to resync.
  483. */
  484. static uvlong
  485. hdrotoull(char *st, char *end, uvlong errval, char *name, char *field)
  486. {
  487. char *numb;
  488. for (numb = st; (*numb == ' ' || *numb == '\0') && numb < end; numb++)
  489. ;
  490. if (numb < end && isascii(*numb) && isdigit(*numb))
  491. return strtoull(numb, nil, 8);
  492. else if (numb >= end)
  493. fprint(2, "%s: %s: empty %s in header\n", argv0, name, field);
  494. else
  495. fprint(2, "%s: %s: %s: non-numeric %s in header\n",
  496. argv0, name, numb, field);
  497. return errval;
  498. }
  499. /*
  500. * return the nominal size from the header block, which is not always the
  501. * size in the archive (the archive size may be zero for some file types
  502. * regardless of the nominal size).
  503. *
  504. * gnu and freebsd tars are now recording vlongs as big-endian binary
  505. * with a flag in byte 0 to indicate this, which permits file sizes up to
  506. * 2^64-1 (actually 2^80-1 but our file sizes are vlongs) rather than 2^33-1.
  507. */
  508. static Off
  509. hdrsize(Hdr *hp)
  510. {
  511. uchar *p;
  512. if((uchar)hp->size[0] == Binnegsz) {
  513. fprint(2, "%s: %s: negative length, which is insane\n",
  514. argv0, name(hp));
  515. return 0;
  516. } else if((uchar)hp->size[0] == Binsize) {
  517. p = (uchar *)hp->size + sizeof hp->size - 1 -
  518. sizeof(vlong); /* -1 for terminating space */
  519. return G8BEBYTE(p);
  520. }
  521. return hdrotoull(hp->size, hp->size + sizeof hp->size, 0,
  522. name(hp), "size");
  523. }
  524. /*
  525. * return the number of bytes recorded in the archive.
  526. */
  527. static Off
  528. arsize(Hdr *hp)
  529. {
  530. if(isdir(hp) || islink(hp->linkflag))
  531. return 0;
  532. return hdrsize(hp);
  533. }
  534. static long
  535. parsecksum(char *cksum, char *name)
  536. {
  537. Hdr *hp;
  538. return hdrotoull(cksum, cksum + sizeof hp->chksum, (uvlong)-1LL,
  539. name, "checksum");
  540. }
  541. static Hdr *
  542. readhdr(int ar)
  543. {
  544. long hdrcksum;
  545. Hdr *hp;
  546. hp = getblkrd(ar, Alldata);
  547. if (hp == nil)
  548. sysfatal("unexpected EOF instead of archive header in %s",
  549. arname);
  550. if (eotar(hp)) /* end-of-archive block? */
  551. return nil;
  552. hdrcksum = parsecksum(hp->chksum, name(hp));
  553. if (hdrcksum == -1 || chksum(hp) != hdrcksum) {
  554. if (!resync)
  555. sysfatal("bad archive header checksum in %s: "
  556. "name %.100s...; expected %#luo got %#luo",
  557. arname, hp->name, hdrcksum, chksum(hp));
  558. fprint(2, "%s: skipping past archive header with bad checksum in %s...",
  559. argv0, arname);
  560. do {
  561. hp = getblkrd(ar, Alldata);
  562. if (hp == nil)
  563. sysfatal("unexpected EOF looking for archive header in %s",
  564. arname);
  565. hdrcksum = parsecksum(hp->chksum, name(hp));
  566. } while (hdrcksum == -1 || chksum(hp) != hdrcksum);
  567. fprint(2, "found %s\n", name(hp));
  568. }
  569. nexthdr += Tblock*(1 + BYTES2TBLKS(arsize(hp)));
  570. return hp;
  571. }
  572. /*
  573. * tar r[c]
  574. */
  575. /*
  576. * if name is longer than Namsiz bytes, try to split it at a slash and fit the
  577. * pieces into hp->prefix and hp->name.
  578. */
  579. static int
  580. putfullname(Hdr *hp, char *name)
  581. {
  582. int namlen, pfxlen;
  583. char *sl, *osl;
  584. String *slname = nil;
  585. if (isdir(hp)) {
  586. slname = s_new();
  587. s_append(slname, name);
  588. s_append(slname, "/"); /* posix requires this */
  589. name = s_to_c(slname);
  590. }
  591. namlen = strlen(name);
  592. if (namlen <= Namsiz) {
  593. strncpy(hp->name, name, Namsiz);
  594. hp->prefix[0] = '\0'; /* ustar paranoia */
  595. return 0;
  596. }
  597. if (!posix || namlen > Maxname) {
  598. fprint(2, "%s: name too long for tar header: %s\n",
  599. argv0, name);
  600. return -1;
  601. }
  602. /*
  603. * try various splits until one results in pieces that fit into the
  604. * appropriate fields of the header. look for slashes from right
  605. * to left, in the hopes of putting the largest part of the name into
  606. * hp->prefix, which is larger than hp->name.
  607. */
  608. sl = strrchr(name, '/');
  609. while (sl != nil) {
  610. pfxlen = sl - name;
  611. if (pfxlen <= sizeof hp->prefix && namlen-1 - pfxlen <= Namsiz)
  612. break;
  613. osl = sl;
  614. *osl = '\0';
  615. sl = strrchr(name, '/');
  616. *osl = '/';
  617. }
  618. if (sl == nil) {
  619. fprint(2, "%s: name can't be split to fit tar header: %s\n",
  620. argv0, name);
  621. return -1;
  622. }
  623. *sl = '\0';
  624. strncpy(hp->prefix, name, sizeof hp->prefix);
  625. *sl++ = '/';
  626. strncpy(hp->name, sl, sizeof hp->name);
  627. if (slname)
  628. s_free(slname);
  629. return 0;
  630. }
  631. static int
  632. mkhdr(Hdr *hp, Dir *dir, char *file)
  633. {
  634. int r;
  635. /*
  636. * some of these fields run together, so we format them left-to-right
  637. * and don't use snprint.
  638. */
  639. sprint(hp->mode, "%6lo ", dir->mode & 0777);
  640. sprint(hp->uid, "%6o ", aruid);
  641. sprint(hp->gid, "%6o ", argid);
  642. if (dir->length >= (Off)1<<32) {
  643. static int printed;
  644. if (!printed) {
  645. printed = 1;
  646. fprint(2, "%s: storing large sizes in \"base 256\"\n", argv0);
  647. }
  648. hp->size[0] = Binsize;
  649. /* emit so-called `base 256' representation of size */
  650. putbe((uchar *)hp->size+1, dir->length, sizeof hp->size - 2);
  651. hp->size[sizeof hp->size - 1] = ' ';
  652. } else
  653. sprint(hp->size, "%11lluo ", dir->length);
  654. sprint(hp->mtime, "%11luo ", dir->mtime);
  655. hp->linkflag = (dir->mode&DMDIR? LF_DIR: LF_PLAIN1);
  656. r = putfullname(hp, file);
  657. if (posix) {
  658. strncpy(hp->magic, "ustar", sizeof hp->magic);
  659. strncpy(hp->version, "00", sizeof hp->version);
  660. strncpy(hp->uname, dir->uid, sizeof hp->uname);
  661. strncpy(hp->gname, dir->gid, sizeof hp->gname);
  662. }
  663. sprint(hp->chksum, "%6luo", chksum(hp));
  664. return r;
  665. }
  666. static void addtoar(int ar, char *file, char *shortf);
  667. static void
  668. addtreetoar(int ar, char *file, char *shortf, int fd)
  669. {
  670. int n;
  671. Dir *dent, *dirents;
  672. String *name = s_new();
  673. n = dirreadall(fd, &dirents);
  674. if (n < 0)
  675. fprint(2, "%s: dirreadall %s: %r\n", argv0, file);
  676. close(fd);
  677. if (n <= 0)
  678. return;
  679. if (chdir(shortf) < 0)
  680. sysfatal("chdir %s: %r", file);
  681. if (Debug)
  682. fprint(2, "chdir %s\t# %s\n", shortf, file);
  683. for (dent = dirents; dent < dirents + n; dent++) {
  684. s_reset(name);
  685. s_append(name, file);
  686. s_append(name, "/");
  687. s_append(name, dent->name);
  688. addtoar(ar, s_to_c(name), dent->name);
  689. }
  690. s_free(name);
  691. free(dirents);
  692. /*
  693. * this assumes that shortf is just one component, which is true
  694. * during directory descent, but not necessarily true of command-line
  695. * arguments. Our caller (or addtoar's) must reset the working
  696. * directory if necessary.
  697. */
  698. if (chdir("..") < 0)
  699. sysfatal("chdir %s/..: %r", file);
  700. if (Debug)
  701. fprint(2, "chdir ..\n");
  702. }
  703. static void
  704. addtoar(int ar, char *file, char *shortf)
  705. {
  706. int n, fd, isdir;
  707. long bytes, blksread;
  708. ulong blksleft;
  709. Hdr *hbp;
  710. Dir *dir;
  711. String *name = nil;
  712. if (shortf[0] == '#') {
  713. name = s_new();
  714. s_append(name, "./");
  715. s_append(name, shortf);
  716. shortf = s_to_c(name);
  717. }
  718. if (Debug)
  719. fprint(2, "opening %s # %s\n", shortf, file);
  720. fd = open(shortf, OREAD);
  721. if (fd < 0) {
  722. fprint(2, "%s: can't open %s: %r\n", argv0, file);
  723. if (name)
  724. s_free(name);
  725. return;
  726. }
  727. dir = dirfstat(fd);
  728. if (dir == nil)
  729. sysfatal("can't fstat %s: %r", file);
  730. hbp = getblkz(ar);
  731. isdir = (dir->qid.type & QTDIR) != 0;
  732. if (mkhdr(hbp, dir, file) < 0) {
  733. putbackblk(ar);
  734. free(dir);
  735. close(fd);
  736. if (name)
  737. s_free(name);
  738. return;
  739. }
  740. putblk(ar);
  741. blksleft = BYTES2TBLKS(dir->length);
  742. free(dir);
  743. if (isdir)
  744. addtreetoar(ar, file, shortf, fd);
  745. else {
  746. for (; blksleft > 0; blksleft -= blksread) {
  747. hbp = getblke(ar);
  748. blksread = gothowmany(blksleft);
  749. assert(blksread >= 0);
  750. bytes = blksread * Tblock;
  751. n = ereadn(file, fd, hbp->data, bytes);
  752. assert(n >= 0);
  753. /*
  754. * ignore EOF. zero any partial block to aid
  755. * compression and emergency recovery of data.
  756. */
  757. if (n < Tblock)
  758. memset(hbp->data + n, 0, bytes - n);
  759. putblkmany(ar, blksread);
  760. }
  761. close(fd);
  762. if (verbose)
  763. fprint(2, "%s\n", file);
  764. }
  765. if (name)
  766. s_free(name);
  767. }
  768. static char *
  769. replace(char **argv)
  770. {
  771. int i, ar;
  772. ulong blksleft, blksread;
  773. Off bytes;
  774. char *arg;
  775. Hdr *hp;
  776. Compress *comp = nil;
  777. Pushstate ps;
  778. if (usefile && docreate) {
  779. ar = create(usefile, OWRITE, 0666);
  780. if (docompress)
  781. comp = compmethod(usefile);
  782. } else if (usefile)
  783. ar = open(usefile, ORDWR);
  784. else
  785. ar = Stdout;
  786. if (comp)
  787. ar = push(ar, comp->comp, Output, &ps);
  788. if (ar < 0)
  789. sysfatal("can't open archive %s: %r", usefile);
  790. if (usefile && !docreate) {
  791. /* skip quickly to the end */
  792. while ((hp = readhdr(ar)) != nil) {
  793. bytes = arsize(hp);
  794. for (blksleft = BYTES2TBLKS(bytes);
  795. blksleft > 0 && getblkrd(ar, Justnxthdr) != nil;
  796. blksleft -= blksread) {
  797. blksread = gothowmany(blksleft);
  798. putreadblks(ar, blksread);
  799. }
  800. }
  801. /*
  802. * we have just read the end-of-archive Tblock.
  803. * now seek back over the (big) archive block containing it,
  804. * and back up curblk ptr over end-of-archive Tblock in memory.
  805. */
  806. if (seek(ar, blkoff, 0) < 0)
  807. sysfatal("can't seek back over end-of-archive in %s: %r",
  808. arname);
  809. curblk--;
  810. }
  811. for (i = 0; argv[i] != nil; i++) {
  812. arg = argv[i];
  813. cleanname(arg);
  814. if (strcmp(arg, "..") == 0 || strncmp(arg, "../", 3) == 0)
  815. fprint(2, "%s: name starting with .. is a bad idea\n",
  816. argv0);
  817. addtoar(ar, arg, arg);
  818. chdir(origdir); /* for correctness & profiling */
  819. }
  820. /* write end-of-archive marker */
  821. getblkz(ar);
  822. putblk(ar);
  823. getblkz(ar);
  824. putlastblk(ar);
  825. if (comp)
  826. return pushclose(&ps);
  827. if (ar > Stderr)
  828. close(ar);
  829. return nil;
  830. }
  831. /*
  832. * tar [xt]
  833. */
  834. /* is pfx a file-name prefix of name? */
  835. static int
  836. prefix(char *name, char *pfx)
  837. {
  838. int pfxlen = strlen(pfx);
  839. char clpfx[Maxname+1];
  840. if (pfxlen > Maxname)
  841. return 0;
  842. strcpy(clpfx, pfx);
  843. cleanname(clpfx);
  844. return strncmp(clpfx, name, pfxlen) == 0 &&
  845. (name[pfxlen] == '\0' || name[pfxlen] == '/');
  846. }
  847. static int
  848. match(char *name, char **argv)
  849. {
  850. int i;
  851. char clname[Maxname+1];
  852. if (argv[0] == nil)
  853. return 1;
  854. strcpy(clname, name);
  855. cleanname(clname);
  856. for (i = 0; argv[i] != nil; i++)
  857. if (prefix(clname, argv[i]))
  858. return 1;
  859. return 0;
  860. }
  861. static void
  862. cantcreate(char *s, int mode)
  863. {
  864. int len;
  865. static char *last;
  866. /*
  867. * Always print about files. Only print about directories
  868. * we haven't printed about. (Assumes archive is ordered
  869. * nicely.)
  870. */
  871. if(mode&DMDIR){
  872. if(last){
  873. /* already printed this directory */
  874. if(strcmp(s, last) == 0)
  875. return;
  876. /* printed a higher directory, so printed this one */
  877. len = strlen(s);
  878. if(memcmp(s, last, len) == 0 && last[len] == '/')
  879. return;
  880. }
  881. /* save */
  882. free(last);
  883. last = strdup(s);
  884. }
  885. fprint(2, "%s: can't create %s: %r\n", argv0, s);
  886. }
  887. static int
  888. makedir(char *s)
  889. {
  890. int f;
  891. if (access(s, AEXIST) == 0)
  892. return -1;
  893. f = create(s, OREAD, DMDIR | 0777);
  894. if (f >= 0)
  895. close(f);
  896. else
  897. cantcreate(s, DMDIR);
  898. return f;
  899. }
  900. static int
  901. mkpdirs(char *s)
  902. {
  903. int err;
  904. char *p;
  905. p = s;
  906. err = 0;
  907. while (!err && (p = strchr(p+1, '/')) != nil) {
  908. *p = '\0';
  909. err = (access(s, AEXIST) < 0 && makedir(s) < 0);
  910. *p = '/';
  911. }
  912. return -err;
  913. }
  914. /* Call access but preserve the error string. */
  915. static int
  916. xaccess(char *name, int mode)
  917. {
  918. char err[ERRMAX];
  919. int rv;
  920. err[0] = 0;
  921. errstr(err, sizeof err);
  922. rv = access(name, mode);
  923. errstr(err, sizeof err);
  924. return rv;
  925. }
  926. static int
  927. openfname(Hdr *hp, char *fname, int dir, int mode)
  928. {
  929. int fd;
  930. fd = -1;
  931. cleanname(fname);
  932. switch (hp->linkflag) {
  933. case LF_LINK:
  934. case LF_SYMLINK1:
  935. case LF_SYMLINK2:
  936. fprint(2, "%s: can't make (sym)link %s\n",
  937. argv0, fname);
  938. break;
  939. case LF_FIFO:
  940. fprint(2, "%s: can't make fifo %s\n", argv0, fname);
  941. break;
  942. default:
  943. if (!keepexisting || access(fname, AEXIST) < 0) {
  944. int rw = (dir? OREAD: OWRITE);
  945. fd = create(fname, rw, mode);
  946. if (fd < 0) {
  947. mkpdirs(fname);
  948. fd = create(fname, rw, mode);
  949. }
  950. if (fd < 0 && (!dir || xaccess(fname, AEXIST) < 0))
  951. cantcreate(fname, mode);
  952. }
  953. if (fd >= 0 && verbose)
  954. fprint(2, "%s\n", fname);
  955. break;
  956. }
  957. return fd;
  958. }
  959. /* copy from archive to file system (or nowhere for table-of-contents) */
  960. static void
  961. copyfromar(int ar, int fd, char *fname, ulong blksleft, Off bytes)
  962. {
  963. int wrbytes;
  964. ulong blksread;
  965. Hdr *hbp;
  966. if (blksleft == 0 || bytes < 0)
  967. bytes = 0;
  968. for (; blksleft > 0; blksleft -= blksread) {
  969. hbp = getblkrd(ar, (fd >= 0? Alldata: Justnxthdr));
  970. if (hbp == nil)
  971. sysfatal("unexpected EOF on archive extracting %s from %s",
  972. fname, arname);
  973. blksread = gothowmany(blksleft);
  974. if (blksread <= 0) {
  975. fprint(2, "%s: got %ld blocks reading %s!\n",
  976. argv0, blksread, fname);
  977. blksread = 0;
  978. }
  979. wrbytes = Tblock*blksread;
  980. assert(bytes >= 0);
  981. if(wrbytes > bytes)
  982. wrbytes = bytes;
  983. assert(wrbytes >= 0);
  984. if (fd >= 0)
  985. ewrite(fname, fd, hbp->data, wrbytes);
  986. putreadblks(ar, blksread);
  987. bytes -= wrbytes;
  988. assert(bytes >= 0);
  989. }
  990. if (bytes > 0)
  991. fprint(2, "%s: %lld bytes uncopied at EOF on archive %s; "
  992. "%s not fully extracted\n", argv0, bytes, arname, fname);
  993. }
  994. static void
  995. wrmeta(int fd, Hdr *hp, long mtime, int mode) /* update metadata */
  996. {
  997. Dir nd;
  998. nulldir(&nd);
  999. nd.mtime = mtime;
  1000. nd.mode = mode;
  1001. dirfwstat(fd, &nd);
  1002. if (isustar(hp)) {
  1003. nulldir(&nd);
  1004. nd.gid = hp->gname;
  1005. dirfwstat(fd, &nd);
  1006. nulldir(&nd);
  1007. nd.uid = hp->uname;
  1008. dirfwstat(fd, &nd);
  1009. }
  1010. }
  1011. /*
  1012. * copy a file from the archive into the filesystem.
  1013. * fname is result of name(), so has two extra bytes at beginning.
  1014. */
  1015. static void
  1016. extract1(int ar, Hdr *hp, char *fname)
  1017. {
  1018. int fd = -1, dir = 0;
  1019. long mtime = strtol(hp->mtime, nil, 8);
  1020. ulong mode = strtoul(hp->mode, nil, 8) & 0777;
  1021. Off bytes = hdrsize(hp); /* for printing */
  1022. ulong blksleft = BYTES2TBLKS(arsize(hp));
  1023. /* fiddle name, figure out mode and blocks */
  1024. if (isdir(hp)) {
  1025. mode |= DMDIR|0700;
  1026. dir = 1;
  1027. }
  1028. switch (hp->linkflag) {
  1029. case LF_LINK:
  1030. case LF_SYMLINK1:
  1031. case LF_SYMLINK2:
  1032. case LF_FIFO:
  1033. blksleft = 0;
  1034. break;
  1035. }
  1036. if (relative)
  1037. if(fname[0] == '/')
  1038. *--fname = '.';
  1039. else if(fname[0] == '#'){
  1040. *--fname = '/';
  1041. *--fname = '.';
  1042. }
  1043. if (verb == Xtract)
  1044. fd = openfname(hp, fname, dir, mode);
  1045. else if (verbose) {
  1046. char *cp = ctime(mtime);
  1047. print("%M %8lld %-12.12s %-4.4s %s\n",
  1048. mode, bytes, cp+4, cp+24, fname);
  1049. } else
  1050. print("%s\n", fname);
  1051. copyfromar(ar, fd, fname, blksleft, bytes);
  1052. /* touch up meta data and close */
  1053. if (fd >= 0) {
  1054. /*
  1055. * directories should be wstated *after* we're done
  1056. * creating files in them, but we don't do that.
  1057. */
  1058. if (settime)
  1059. wrmeta(fd, hp, mtime, mode);
  1060. close(fd);
  1061. }
  1062. }
  1063. static void
  1064. skip(int ar, Hdr *hp, char *fname)
  1065. {
  1066. ulong blksleft, blksread;
  1067. Hdr *hbp;
  1068. for (blksleft = BYTES2TBLKS(arsize(hp)); blksleft > 0;
  1069. blksleft -= blksread) {
  1070. hbp = getblkrd(ar, Justnxthdr);
  1071. if (hbp == nil)
  1072. sysfatal("unexpected EOF on archive extracting %s from %s",
  1073. fname, arname);
  1074. blksread = gothowmany(blksleft);
  1075. putreadblks(ar, blksread);
  1076. }
  1077. }
  1078. static char *
  1079. extract(char **argv)
  1080. {
  1081. int ar;
  1082. char *longname;
  1083. Hdr *hp;
  1084. Compress *comp = nil;
  1085. Pushstate ps;
  1086. if (usefile) {
  1087. ar = open(usefile, OREAD);
  1088. comp = compmethod(usefile);
  1089. } else
  1090. ar = Stdin;
  1091. if (comp)
  1092. ar = push(ar, comp->decomp, Input, &ps);
  1093. if (ar < 0)
  1094. sysfatal("can't open archive %s: %r", usefile);
  1095. while ((hp = readhdr(ar)) != nil) {
  1096. longname = name(hp);
  1097. if (match(longname, argv))
  1098. extract1(ar, hp, longname);
  1099. else
  1100. skip(ar, hp, longname);
  1101. }
  1102. if (comp)
  1103. return pushclose(&ps);
  1104. if (ar > Stderr)
  1105. close(ar);
  1106. return nil;
  1107. }
  1108. void
  1109. main(int argc, char *argv[])
  1110. {
  1111. int errflg = 0;
  1112. char *ret = nil;
  1113. fmtinstall('M', dirmodefmt);
  1114. TARGBEGIN {
  1115. case 'c':
  1116. docreate++;
  1117. verb = Replace;
  1118. break;
  1119. case 'f':
  1120. usefile = arname = EARGF(usage());
  1121. break;
  1122. case 'g':
  1123. argid = strtoul(EARGF(usage()), 0, 0);
  1124. break;
  1125. case 'i':
  1126. ignerrs = 1;
  1127. break;
  1128. case 'k':
  1129. keepexisting++;
  1130. break;
  1131. case 'm': /* compatibility */
  1132. settime = 0;
  1133. break;
  1134. case 'p':
  1135. posix++;
  1136. break;
  1137. case 'P':
  1138. posix = 0;
  1139. break;
  1140. case 'r':
  1141. verb = Replace;
  1142. break;
  1143. case 'R':
  1144. relative = 0;
  1145. break;
  1146. case 's':
  1147. resync++;
  1148. break;
  1149. case 't':
  1150. verb = Toc;
  1151. break;
  1152. case 'T':
  1153. settime++;
  1154. break;
  1155. case 'u':
  1156. aruid = strtoul(EARGF(usage()), 0, 0);
  1157. break;
  1158. case 'v':
  1159. verbose++;
  1160. break;
  1161. case 'x':
  1162. verb = Xtract;
  1163. break;
  1164. case 'z':
  1165. docompress++;
  1166. break;
  1167. case '-':
  1168. break;
  1169. default:
  1170. fprint(2, "tar: unknown letter %C\n", TARGC());
  1171. errflg++;
  1172. break;
  1173. } TARGEND
  1174. if (argc < 0 || errflg)
  1175. usage();
  1176. initblks();
  1177. switch (verb) {
  1178. case Toc:
  1179. case Xtract:
  1180. ret = extract(argv);
  1181. break;
  1182. case Replace:
  1183. if (getwd(origdir, sizeof origdir) == nil)
  1184. strcpy(origdir, "/tmp");
  1185. ret = replace(argv);
  1186. break;
  1187. default:
  1188. usage();
  1189. break;
  1190. }
  1191. exits(ret);
  1192. }