tar.c 28 KB

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