home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / utils / unix / pdtar / part0~ae < prev    next >
Encoding:
Text File  |  1988-09-11  |  45.2 KB  |  1,312 lines

  1. Subject:  v12i068:  Public domain TAR, Part01/03
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: John Gilmore <hoptoad!gnu@UUNET.UU.NET>
  7. Posting-number: Volume 12, Issue 68
  8. Archive-name: pdtar/part01
  9.  
  10. [  See the first two paragraphs of the README for information on
  11.    what this fine program does.  --r$  ]
  12.  
  13. : To unbundle, sh this file
  14. echo README
  15. cat >README <<'@@@ Fin de README'
  16. This is the Nov87 release of a public domain tar(1) replacement.  It
  17. implements the 'c', 'x', and 't' commands of Unix tar, and many of the
  18. options.  It creates P1003 "Unix Standard" [draft 6] tapes by default,
  19. and can read and write both old and new formats.  It can compress or
  20. decompress tar archives "on the fly" (using the 'z' option) as well as
  21. accessing remote tape drives or files by specifying
  22. "host:/dev/tapedrive".  It lets you set the default tape drive by
  23. setting TAPE in your environment.  Its verbose output looks more like
  24. "ls -l" than the Unix tar, the columns line up, and you can get verbose
  25. listings from the 'cvv' option as well as from 'xvv' and 'tv'.  It does
  26. shell-globbing (regular expressions) for listing and extraction.  It is
  27. a little better at reading damaged tapes than Unix tar.  There is a
  28. half-baked "diff" option for comparing a tape against the file system.
  29. And it's free.
  30.  
  31. It is designed to be a lot more efficient than the standard Unix tar;
  32. it does as little bcopy-ing as possible, and does file I/O in large
  33. blocks.  On the other hand, it has not been timed or performance-tuned;
  34. it's just *designed* to be faster.
  35.  
  36. On SunOS 3.3, the tar archives it creates under the 'old' option are
  37. byte-for-byte the same as those created by /bin/tar, except the trash
  38. at the end of each file and at the end of the archive has been replaced
  39. by zeroes.
  40.  
  41. It was written and initially debugged on a Sun Workstation running
  42. 4.2BSD.  It has been run on Xenix, Unisoft, Vax 4.2BSD, utzoonix, USG,
  43. Masscomp, Minix, and MSDOS systems.  I'm interested in finding people
  44. who will port it to other types of (Unix and non-Unix) systems, use it,
  45. and send back the changes; and people who will add the obscure tar
  46. options that they happen to use and I don't.  In particular, VMS, Mac,
  47. Atari and Amiga versions would be handy.
  48.  
  49. It still has a number of loose ends, marked by "FIXME" comments in the
  50. source.  Fixes to these things are also welcome.
  51.  
  52. I am the author of all the code in this program, except some of the
  53. subroutines, which are from contributors listed below.  I hereby place
  54. it in the public domain.  If you modify it, or port it to another
  55. system, please send me back a copy, so I can keep a master source.
  56.  
  57. This program is much better than it started, due to the effort and care
  58. put in by Henry Spencer, Fred Fish, Ian Darwin, Geoff Collyer, Stan
  59. Barber, Guy Harris, Dave Brower, Richard Todd, Michael Rendell, Stu
  60. Heiss, and Rich $alz.  Thank you, one and all.
  61.  
  62.     John Gilmore
  63.     Nebula Consultants
  64.     PO Box 170608
  65.     San Francisco, California, USA  94117-0608
  66.     hoptoad!gnu    or   gnu@toad.com
  67.     Hoptoad talks to sun, ptsfa, ihnp4, utzoo, ucsfcgl.
  68.  
  69. @(#)README 1.14    87/11/11
  70. @@@ Fin de README
  71. echo PORTING
  72. cat >PORTING <<'@@@ Fin de PORTING'
  73.         Porting hints for public domain tar
  74.           John Gilmore, ihnp4!hoptoad!gnu
  75.              @(#)PORTING 1.13    87/11/11
  76.  
  77. The Makefile should be edited to comment out all the undesired
  78. versions, and create the following configuration lines for the system
  79. you are compiling it on:
  80.  
  81. DEFS = the proper #define's to conditionally compile for your system.
  82. LIBS = the system libraries and/or object modules to link with the program.
  83. LINT = the lint program (or the compiler with extra checking turned on)
  84. LINTFLAGS = a good strong way to invoke 'lint' on your system.
  85. DEF_AR_FILE = the name of the default archive file on your system.
  86.     It should be enclosed in quoted quotes, e.g. \"/dev/foo\" .
  87. DEFBLOCKING = the default blocking factor on your system.
  88. O = the suffix for object files ('o', except 'obj' for MSDOS).
  89.  
  90. A copy of "getopt", the standard argument parser, is required.  It's in
  91. libc on Missed'em V systems and 4.3BSD; on most other systems, you'll
  92. need a copy of a public domain getopt, available through the
  93. comp.sources.unix archives, or from the AT&T Toolchest if you can't
  94. find it elsewhere.
  95.  
  96. A copy of the Berkeley directory access routines is also required.
  97. These are in libc and <sys/dir.h> on Berkeley systems.  A public domain
  98. version is available through comp.sources.unix.  There is an #include
  99. you have to change in create.c for this, to set the name of the include
  100. file you have.  Some systems have the include file in <sys/ndir.h>.
  101. You'll have to find it on your system, or get the public domain one and
  102. place it somewhere.  For MSDOS, I have supplied these directory
  103. routines in msd_dir.c and msd_dir.h, since it's likely that your system
  104. doesn't have them.  To permanently install these into your MSC 3.0
  105. library, do the following:
  106.     copy msd_dir.h c:\c\include\sys\dir.h
  107.     cl -A$(MODEL) -c msd_dir.c
  108.     lib $(MODEL)dir.lib msd_dir.obj;
  109. Change c:\c\include to wherever your standard include directory is.
  110. You might have to modify this procedure if you aren't using MSC 3.0. 
  111.  
  112. Grep for FIXME to find places that aren't finished or which have
  113. portability problems.  Also see the file TODO.
  114.  
  115. The MSDOS port was done under the Microsoft C 3.0 compiler and
  116. libraries.  In the Makefile, COPTS should be changed to -Zi or nothing;
  117. and there is a special link command for making tar.exe, which you will
  118. have to uncomment, since MSDOS can't handle command lines longer than
  119. 128 bytes.  Also, clean and install will not work unless you change
  120. / in path names to \.
  121.  
  122. On Minix, there are a bunch of problems.  "V7 compatible" my ass.
  123.  * "make" doesn't expand macros in the Makefile properly.  You will
  124. probably have to expand them by hand.  Better to go in and fix Minix
  125. "make" though...
  126.  * The directory access library is nonexistent.  It wasn't in V7 but
  127. anybody who writes code without it, even on V7 systems, is a fool.
  128.  * Various other library routines are broken, e.g. printf() doesn't take
  129. "%*s" or "%.*s"; no <sys/types.h> which Unix requires, ctime(), getopt().
  130. @@@ Fin de PORTING
  131. echo Makefile
  132. cat >Makefile <<'@@@ Fin de Makefile'
  133. # Makefile for public domain tar program.
  134. # @(#)Makefile 1.30    87/11/11
  135.  
  136. # Berserkeley version
  137. DEFS = -DBSD42
  138. LDFLAGS =
  139. LIBS = 
  140. LINT = lint
  141. LINTFLAGS = -abchx
  142. DEF_AR_FILE = \"/dev/rmt8\"
  143. DEFBLOCKING = 20
  144. O = o
  145.  
  146. # USG version
  147. #DEFS = -DUSG
  148. #LDFLAGS =
  149. #LIBS = -lndir
  150. #LINT = lint
  151. #LINTFLAGS = -p
  152. #DEF_AR_FILE = \"/dev/rmt8\"
  153. #DEFBLOCKING = 20
  154. #O = o
  155.  
  156. # UniSoft's Uniplus SVR2 with NFS
  157. #DEFS = -DUSG -DUNIPLUS -DNFS -DSVR2
  158. #LDFLAGS =
  159. #LIBS = -lndir
  160. #LINT = lint
  161. #LINTFLAGS = -bx
  162. #DEF_AR_FILE = \"/dev/rmt8\"
  163. #DEFBLOCKING = 20
  164. #O = o
  165.  
  166. # MASSCOMP version
  167. #CC = ucb cc
  168. #DEFS = -DBSD42
  169. #LDFLAGS =
  170. #LIBS = 
  171. #LINT = lint
  172. #LINTFLAGS = -bx
  173. #DEF_AR_FILE = \"/dev/rmt0\"
  174. #DEFBLOCKING = 20
  175. #O = o
  176.  
  177. # (yuk) MS-DOS (Microsoft C) version
  178. #MODEL = S
  179. #DEFS = -DNONAMES -A$(MODEL) -nologo
  180. #LDFLAGS =
  181. #LIBS = $(MODEL)dir.lib
  182. #LINT =    $(CC)
  183. #LINTFLAGS = -W3
  184. #DEF_AR_FILE = \"tar.out\"
  185. #DEFBLOCKING = 20
  186. #O = obj
  187.  
  188. # V7 version
  189. # Pick open3 emulation or nonexistence.  See open3.h, port.c.
  190. ##DEFS = -DV7 -DEMUL_OPEN3 -Dvoid=int
  191. ##DEFS = -DV7 -DNO_OPEN3 -Dvoid=int
  192. #LDFLAGS =
  193. #LIBS = -lndir
  194. #LINT = lint
  195. #LINTFLAGS = -abchx
  196. #DEF_AR_FILE = \"/dev/rmt8\"
  197. #DEFBLOCKING = 20
  198. #O = o
  199.  
  200. # Minix version
  201. # No lint, so no lintflags.  Default file is stdin/out.  (Minix "tar"
  202. # doesn't even take an "f" flag, it assumes argv[2] is the archive name!)
  203. # Minix "make" doesn't expand macros right, so Minix users will have
  204. # to expand CFLAGS, SRCS, O, etc by hand, or fix your make.  Not my problem!
  205. # You'll also need to come up with getopt() and ctime(), the directory
  206. # library, and a fixed doprintf() that handles %*s.  Put this stuff in
  207. # the "SUBSRC/SUBOBJ" macro below if you didn't put it in your C library.
  208. # Note that Minix "cc" produces ".s" files, not .o's, so O = s has been set.
  209. #
  210. # Pick open3 emulation or nonexistence.  See open3.h, port.c.
  211. ##DEFS = -DV7 -DMINIX -DEMUL_OPEN3
  212. ##DEFS = -DV7 -DMINIX -DNO_OPEN3
  213. #LDFLAGS =
  214. #LIBS =
  215. #DEF_AR_FILE = \"-\"
  216. #DEFBLOCKING = 8    /* No good reason for this, change at will */
  217. #O = s
  218.  
  219. # Xenix version
  220. #DEFS = -DUSG -DXENIX
  221. #LDFLAGS = 
  222. #LIBS = -lx
  223. #LINT = lint
  224. #LINTFLAGS = -p
  225. #DEF_AR_FILE = \"/dev/rmt8\"
  226. #DEFBLOCKING = 20
  227. #O = o
  228.  
  229.  
  230. CFLAGS = $(COPTS) $(ALLDEFS)
  231. ALLDEFS = $(DEFS) \
  232.     -DDEF_AR_FILE=$(DEF_AR_FILE) \
  233.     -DDEFBLOCKING=$(DEFBLOCKING)
  234. # next line for Debugging
  235. COPTS = -g
  236. # next line for Production
  237. #COPTS = -O
  238.  
  239. # Add things here like getopt, readdir, etc that aren't in your
  240. # standard libraries.  (E.g. MSDOS needs getopt, msd_dir.c, msd_dir.obj)
  241. SUBSRC=    
  242. SUBOBJ=    
  243.  
  244. # Destination directory and installation program for make install
  245. DESTDIR = /usr/pd
  246. INSTALL = cp
  247. RM = rm -f
  248.  
  249. SRC1 =    tar.c create.c extract.c buffer.c getoldopt.c
  250. SRC2 =    list.c names.c diffarch.c port.c wildmat.c $(SUBSRC)
  251. SRCS =    $(SRC1) $(SRC2)
  252. OBJ1 =    tar.$O create.$O extract.$O buffer.$O getoldopt.$O list.$O
  253. OBJ2 =    names.$O diffarch.$O port.$O wildmat.$O $(SUBOBJ)
  254. OBJS =    $(OBJ1) $(OBJ2)
  255. AUX =    README PORTING Makefile TODO tar.1 tar.5 tar.h port.h open3.h \
  256.     msd_dir.h msd_dir.c
  257.  
  258. all:    tar
  259.  
  260. tar:    $(OBJS)
  261.     $(CC) $(LDFLAGS) -o tar $(COPTS) $(OBJS) $(LIBS)
  262. # command is too long for Messy-Dos (128 char line length limit) so
  263. # this kludge is used...
  264. #    @echo $(OBJ1) + > command
  265. #    @echo $(OBJ2) >> command
  266. #    link @command, $@,,$(LIBS) /NOI;
  267. #    @$(RM) command
  268.  
  269. install: all
  270.     $(RM) $(DESTDIR)/tar $(DESTDIR)/.man/tar.[15]
  271.     $(INSTALL) tar   $(DESTDIR)/tar
  272.     $(INSTALL) tar.1 $(DESTDIR)/.man/tar.1
  273.     $(INSTALL) tar.5 $(DESTDIR)/.man/tar.5
  274.  
  275. lint:    $(SRCS)
  276.     $(LINT) $(LINTFLAGS) $(ALLDEFS) $(SRCS)
  277.  
  278. clean:
  279.     $(RM) errs $(OBJS) tar
  280.  
  281. tar.shar: $(SRCS) $(AUX)
  282.     shar >tar.shar1 $(AUX)
  283.     shar >tar.shar2 $(SRC1)
  284.     shar >tar.shar3 $(SRC2)
  285.  
  286. tar.tar.Z: $(SRCS) $(AUX)
  287.     /bin/tar cf - $(AUX) $(SRCS) | compress -v >tar.tar.Z
  288.  
  289. $(OBJS): tar.h port.h
  290. @@@ Fin de Makefile
  291. echo TODO
  292. cat >TODO <<'@@@ Fin de TODO'
  293. @(#) TODO 1.15 87/11/06
  294.  
  295. Test owner/group on extraction better.
  296.  
  297. creation of links, symlinks, nodes doesn't follow the -k (f_keep) guidelines;
  298. if the file already exists, it is not replaced, even though no -k.
  299.  
  300. Check stderr and stdout for errors after writing, and quit if so.
  301.  
  302. Preliminary design of Multifile option to handle EOFs on input and
  303. output.  Multifile can just close the archive when it hits end of
  304. archive, and ask for archive to be changed.  It has no choice on some
  305. media, e.g. floppies and cartridge tapes, where there is no room for an
  306. EOF block there.  Start off 2nd archive medium with odd header block,
  307. duplicating original, but with offset to start of data spec'd.  Reading
  308. such a header causes tar non-'M' to complain while extracting (but to
  309. seek there and do it anyway!)  Big win -- this works on cartridge
  310. tapes, should work on floppies, might work on magtape.  It would
  311. encourage the *&%#$ systems programmers to fix their drivers, too!
  312.  
  313. Profile it and see where the time, call counts, etc are going.
  314.  
  315. Fix directory timestamps after inserting files into them.  Wait til next
  316. file that's not in the directory.  Need a stack of them.
  317.  
  318. Option to seek the input file (in skip_file) rather than reading
  319. and tossing it?  (Could just jump in buffer if stuff is in core.)
  320. Could misalign archive reads versus filesys and slow it down, who knows?
  321.  
  322. Add -C option for creating from odd directories a la 4.2BSD?
  323.  
  324. Break out odd bits of code into separate support modules.
  325.  
  326. Add the r, u, X, l, F, C, and digit options of Unix tar.
  327.  
  328. V8 tar does something that is quite handy when reading tapes written on
  329. 4.2 system into non-4.2 systems: it reduces file name components to
  330. 14 bytes or less and ensures that they are unique (I think it truncates
  331. to 10 bytes and appends "..aa" where aa are two unique letters) and puts
  332. out a file containing the mapping between long names on tape and short
  333. names on disk.
  334.  
  335. Clean up 'd' (diff) option.  Currently it works for regular files
  336. and symlinks, needs work for dirs and links.  Ideally, output should
  337. look like "diff -r" or -rl after an extract of the tape and a real diff.
  338. Right now it's very messy.  To do the above, we'd need to read the
  339. directories that we touch and check all the file names against what's
  340. on the tape.  All we do now is check the file contents and stats.
  341.  
  342. Check "int" variables to see if they really need to be long (file sizes,
  343. record counts, etc).  Sizes of in-core buffers should be int; since
  344. malloc() takes an int argument we can never allocate one any bigger.
  345. Maybe unsigned int would be better, though.  Little system people,
  346. help me out here!  (E.g. run lint on it on your system and send me
  347. the result if it shows anything fixable.)
  348. @@@ Fin de TODO
  349. echo tar.1
  350. cat >tar.1 <<'@@@ Fin de tar.1'
  351. .TH TAR 1 "5 November 1987"
  352. .\" @(#)tar.1 1.12 11/6/87 Public Domain - gnu
  353. .SH NAME
  354. tar \- tape (or other media) file archiver
  355. .SH SYNOPSIS
  356. \fBtar\fP \-[\fBBcdDhiklmopRstvxzZ\fP]
  357. [\fB\-b\fP \fIN\fP]
  358. [\fB\-f\fP \fIF\fP]
  359. [\fB\-T\fP \fIF\fP]
  360. [ \fIfilename or regexp\fP\| .\|.\|.  ]
  361. .SH DESCRIPTION
  362. \fItar\fP provides a way to store many files into a single archive,
  363. which can be kept in another Unix file, stored on an I/O device
  364. such as tape, floppy, cartridge, or disk, sent over a network, or piped to
  365. another program.
  366. It is useful for making backup copies, or for packaging up a set of
  367. files to move them to another system.
  368. .LP
  369. \fItar\fP has existed since Version 7 Unix with very little change.
  370. It has been proposed as the standard format for interchange of files
  371. among systems that conform to the IEEE P1003 ``Portable Operating System''
  372. standard.
  373. .LP
  374. This version of \fItar\fP supports some of the extensions which
  375. were proposed in the P1003 draft standards, including owner and group
  376. names, and support for named pipes, fifos, contiguous files,
  377. and block and character devices.
  378. .LP
  379. When reading an archive, this version of \fItar\fP continues after
  380. finding an error.  Previous versions required the `i' option to ignore
  381. checksum errors.
  382. .SH OPTIONS
  383. \fItar\fP options can be specified in either of two ways.  The usual
  384. Unix conventions can be used: each option is preceded by `\-'; arguments
  385. directly follow each option; multiple options can be combined behind one `\-'
  386. as long as they take no arguments.  For compatability with the Unix
  387. \fItar\fP program, the options may also be specified as ``keyletters,''
  388. wherein all the option letters occur in the first argument to \fItar\fP,
  389. with no `\-', and their arguments, if any, occur in the second, third, ...
  390. arguments.  Examples:
  391. .LP
  392. Normal:  tar -f arcname -cv file1 file2
  393. .LP
  394. Old:  tar fcv arcname file1 file2
  395. .LP
  396. At least one of the \fB\-c\fP, \fB\-t\fP, \fB-d\fP, or \fB\-x\fP options
  397. must be included.  The rest are optional.
  398. .LP
  399. Files to be operated upon are specified by a list of file names, which
  400. follows the option specifications (or can be read from a file by the
  401. \fB\-T\fP option).  Specifying a directory name causes that directory
  402. and all the files it contains to be (recursively) processed.  If a
  403. full path name is specified when creating an archive, it will be written
  404. to the archive without the initial "/", to allow the files to be later
  405. read into a different place than where they were
  406. dumped from, and a warning will be printed.  If
  407. files are extracted from an archive which contains 
  408. full path names, they will be extracted relative to the current directory
  409. and a warning message printed.
  410. .LP
  411. When extracting or listing files, the ``file names'' are treated as
  412. regular expressions, using mostly the same syntax as the shell.  The
  413. shell actually matches each substring between ``/''s separately, while
  414. \fItar\fP matches the entire string at once, so some anomalies will
  415. occur; e.g. ``*'' or ``?'' can match a ``/''.  To specify a regular
  416. expression as an argument to \fItar\fP, quote it so the shell will not
  417. expand it.
  418. .IP "\fB\-b\fP \fIN\fP"
  419. Specify a blocking factor for the archive.  The block size will be
  420. \fIN\fP x 512 bytes.  Larger blocks typically run faster and let you
  421. fit more data on a tape.  The default blocking factor is set when
  422. \fItar\fP is compiled, and is typically 20.  There is no limit to the
  423. maximum block size, as long as enough memory can be allocated for it,
  424. and as long as the device containing the archive can read or write
  425. that block size.
  426. .IP \fB\-B\fP
  427. When reading an archive, reblock it as we read it.
  428. Normally, \fItar\fP reads each
  429. block with a single \fIread(2)\fP system call.  This does not work
  430. when reading from a pipe or network socket under Berkeley Unix;
  431. \fIread(2)\fP only gives as much data as has arrived at the moment.
  432. With this option, it
  433. will do multiple \fIread(2)\fPs to fill out to a record boundary,
  434. rather than reporting an error.
  435. This option is default when reading an archive from standard input,
  436. or over a network.
  437. .IP \fB\-c\fP
  438. Create an archive from a list of files.
  439. .IP \fB\-d\fP
  440. Diff an archive against the files in the file system.  Reports
  441. differences in file size, mode, uid, gid, and contents.  If a file
  442. exists on the tape, but not in the file system, that is reported.
  443. This option needs further work to be really useful.
  444. .IP \fB\-D\fP
  445. When creating an archive, only dump each directory itself; don't dump
  446. all the files inside the directory.  In conjunction with \fIfind\fP(1),
  447. this is useful in creating incremental dumps for archival backups,
  448. similar to those produced by \fIdump\fP(8).
  449. .IP "\fB\-f\fP \fIF\fP"
  450. Specify the filename of the archive.  If the specified filename is ``\-'',
  451. the archive is read from the standard input or written to the standard output.
  452. If the \fB-f\fP option is not used, and the environment variable \fBTAPE\fP
  453. exists, its value will be used; otherwise,
  454. a default archive name (which was picked when tar was compiled) is used.
  455. The default is normally set to the ``first'' tape drive or other transportable
  456. I/O medium on the system.
  457. .IP
  458. If the filename contains a colon before a slash, it is interpreted
  459. as a ``hostname:/file/name'' pair.  \fItar\fP will invoke the commands
  460. \fIrsh\fP and \fIdd\fP to access the specified file or device on the
  461. system \fIhostname\fP.  If you need to do something unusual like rsh with
  462. a different user name, use ``\fB\-f \-\fP'' and pipe it to rsh manually.
  463. .IP \fB\-h\fP
  464. When creating an archive, if a symbolic link is encountered, dump
  465. the file or directory to which it points, rather than
  466. dumping it as a symbolic link.
  467. .IP \fB\-i\fP
  468. When reading an archive, ignore blocks of zeros in the archive.  Normally
  469. a block of zeros indicates the end of the archive,
  470. but in a damaged archive, or one which was
  471. created by appending several archives, this option allows \fItar\fP to 
  472. continue.  It is not on by default because there is garbage written after the
  473. zeroed blocks by the Unix \fItar\fP program.  Note that with this option
  474. set, \fItar\fP will read all the way to the end of the file, eliminating
  475. problems with multi-file tapes.
  476. .IP \fB\-k\fP
  477. When extracting files from an archive, keep existing files, rather than
  478. overwriting them with the version from the archive.
  479. .IP \fB\-l\fP
  480. When dumping the contents of a directory to an archive, stay within the
  481. local file system of that directory.  This option
  482. only affects the files dumped because
  483. they are in a dumped directory; files named on the command line are
  484. always dumped, and they can be from various file systems.
  485. This is useful for making ``full dump'' archival backups of a file system,
  486. as with the \fIdump\fP(8) command.  Files which are skipped due to this
  487. option are mentioned on the standard error.
  488. .IP \fB\-m\fP
  489. When extracting files from an archive, set each file's modified timestamp
  490. to the current time, rather than extracting each file's modified
  491. timestamp from the archive.
  492. .IP \fB\-o\fP
  493. When creating an archive, write an old format archive, which does not
  494. include information about directories, pipes, fifos, 
  495. contiguous files, or device files, and 
  496. specifies file ownership by uid's and gid's rather than by
  497. user names and group names.  In most cases, a ``new'' format archive
  498. can be read by an ``old'' tar program without serious trouble, so this
  499. option should seldom be needed.
  500. .IP \fB\-p\fP
  501. When extracting files from an archive, restore them to the same permissions
  502. that they had in the archive.  If \fB\-p\fP is not specified, the current
  503. umask limits the permissions of the extracted files.  See \fIumask(2)\fP.
  504. .IP \fB\-R\fP
  505. With each message that \fItar\fP produces, print the record number
  506. within the archive where the message occurred.  This option is especially
  507. useful when reading damaged archives, since it helps to pinpoint the damaged
  508. section.
  509. .IP \fB\-s\fP
  510. When specifying a list of filenames to be listed
  511. or extracted from an archive,
  512. the \fB\-s\fP flag specifies that the list
  513. is sorted into the same order as the tape.  This allows a large list
  514. to be used, even on small machines, because
  515. the entire list need not be read into memory at once.  Such a sorted
  516. list can easily be created by running ``tar \-t'' on the archive and
  517. editing its output.
  518. .IP \fB\-t\fP
  519. List a table of contents of an existing archive.  If file names are
  520. specified, just list files matching the specified names.  The listing
  521. appears on the standard output.
  522. .IP "\fB\-T\fP \fIF\fP"
  523. Rather than specifying file names or regular expressions as arguments to
  524. the \fItar\fP command, this option specifies that they should
  525. be read from the file \fIF\fP, one per line.
  526. If the file name specified is ``\-'',
  527. the list is read from the standard input.
  528. This option, in conjunction with the \fB\-s\fP option,
  529. allows an arbitrarily large list of files to be processed, 
  530. and allows the list to be piped to \fItar\fP.
  531. .IP \fB\-v\fP
  532. Be verbose about the files that are being processed or listed.  Normally,
  533. archive creation, file extraction, and differencing are silent,
  534. and archive listing just
  535. gives file names.  The \fB\-v\fP option causes an ``ls \-l''\-like listing
  536. to be produced.  The output from -v appears on the standard output except
  537. when creating an archive (since the new archive might be on standard output),
  538. where it goes to the standard error output.
  539. .IP \fB\-x\fP
  540. Extract files from an existing archive.  If file names are
  541. specified, just extract files matching the specified names, otherwise extract
  542. all the files in the archive.
  543. .IP "\fB\-z\fP or \fB\-Z\fP"
  544. The archive should be compressed as it is written, or decompressed as it
  545. is read, using the \fIcompress(1)\fP program.  This option works on I/O
  546. devices and over the network, as well as on disk files; data to or from
  547. such devices is reblocked using a ``dd'' command
  548. to enforce the specified (or default) block size.  The default compression
  549. parameters are used; if you need to override them, avoid the ``z'' option
  550. and compress it yourself.
  551. .SH "SEE ALSO"
  552. shar(1), tar(5), compress(1), ar(1), arc(1), cpio(1), dump(8), restore(8),
  553. restor(8), rsh(1), dd(1), find(1)
  554. .SH BUGS
  555. The \fBr, u, w, X, l, F, C\fP, and \fIdigit\fP options of Unix \fItar\fP
  556. are not supported.
  557. .LP
  558. Multiple-tape (or floppy) archives should be supported, but so far no
  559. clean way has been implemented.
  560. .LP
  561. A bug in the Bourne Shell usually causes an extra newline to be written
  562. to the standard error when using compressed or remote archives.
  563. .LP
  564. A bug in ``dd'' prevents turning off the ``x+y records in/out'' messages
  565. on the standard error when ``dd'' is used to reblock or transport an archive.
  566. @@@ Fin de tar.1
  567. echo tar.5
  568. cat >tar.5 <<'@@@ Fin de tar.5'
  569. .TH TAR 5 "15 October 1987"
  570. .\" @(#)tar.5 1.4 11/6/87 Public Domain - gnu
  571. .SH NAME
  572. tar \- tape (or other media) archive file format
  573. .SH DESCRIPTION
  574. A ``tar tape'' or file contains a series of records.  Each record contains
  575. TRECORDSIZE bytes (see below).  Although this format may be thought of as
  576. being on magnetic tape, other media are often used.
  577. Each file archived is represented by a header record
  578. which describes the file, followed by zero or more records which give the
  579. contents of the file.  At the end of the archive file there may be a record
  580. filled with binary zeros as an end-of-file indicator.  A reasonable
  581. system should write a record of zeros at the end, but must not assume that
  582. an end-of-file record exists when reading an archive.
  583.  
  584. The records may be blocked for physical I/O operations.  Each block of
  585. \fIN\fP records (where \fIN\fP is set by the \fB\-b\fP option to \fItar\fP)
  586. is written with a single write() operation.  On
  587. magnetic tapes, the result of such a write is a single tape record.
  588. When writing an archive, the last block of records should be written
  589. at the full size, with records after the zero record containing
  590. all zeroes.  When reading an archive, a reasonable system should
  591. properly handle an archive whose last block is shorter than the rest, or
  592. which contains garbage records after a zero record.
  593.  
  594. The header record is defined in the header file <tar.h> as follows:
  595. .nf
  596. .sp .5v
  597. .DT
  598. /*
  599.  * Standard Archive Format - Standard TAR - USTAR
  600.  */
  601. #define    RECORDSIZE    512
  602. #define    NAMSIZ    100
  603. #define    TUNMLEN    32
  604. #define    TGNMLEN    32
  605.  
  606. union record {
  607.     char        charptr[RECORDSIZE];
  608.     struct header {
  609.         char    name[NAMSIZ];
  610.         char    mode[8];
  611.         char    uid[8];
  612.         char    gid[8];
  613.         char    size[12];
  614.         char    mtime[12];
  615.         char    chksum[8];
  616.         char    linkflag;
  617.         char    linkname[NAMSIZ];
  618.         char    magic[8];
  619.         char    uname[TUNMLEN];
  620.         char    gname[TGNMLEN];
  621.         char    devmajor[8];
  622.         char    devminor[8];
  623.     } header;
  624. };
  625.  
  626. /* The checksum field is filled with this while the checksum is computed. */
  627. #define    CHKBLANKS    "        "        /* 8 blanks, no null */
  628.  
  629. /* The magic field is filled with this if uname and gname are valid. */
  630. #define    TMAGIC    "ustar  "        /* 7 chars and a null */
  631.  
  632. /* The linkflag defines the type of file */
  633. #define    LF_OLDNORMAL '\\0'        /* Normal disk file, Unix compatible */
  634. #define    LF_NORMAL    '0'        /* Normal disk file */
  635. #define    LF_LINK    '1'        /* Link to previously dumped file */
  636. #define    LF_SYMLINK    '2'        /* Symbolic link */
  637. #define    LF_CHR    '3'        /* Character special file */
  638. #define    LF_BLK    '4'        /* Block special file */
  639. #define    LF_DIR        '5'        /* Directory */
  640. #define    LF_FIFO    '6'        /* FIFO special file */
  641. #define    LF_CONTIG    '7'        /* Contiguous file */
  642. /* Further link types may be defined later. */
  643.  
  644. /* Bits used in the mode field - values in octal */
  645. #define    TSUID        04000        /* Set UID on execution */
  646. #define    TSGID        02000        /* Set GID on execution */
  647. #define    TSVTX        01000        /* Save text (sticky bit) */
  648.  
  649. /* File permissions */
  650. #define    TUREAD    00400        /* read by owner */
  651. #define    TUWRITE    00200        /* write by owner */
  652. #define    TUEXEC    00100        /* execute/search by owner */
  653. #define    TGREAD    00040        /* read by group */
  654. #define    TGWRITE    00020        /* write by group */
  655. #define    TGEXEC    00010        /* execute/search by group */
  656. #define    TOREAD    00004        /* read by other */
  657. #define    TOWRITE    00002        /* write by other */
  658. #define    TOEXEC    00001        /* execute/search by other */
  659. .fi
  660. .LP
  661. All characters in header records
  662. are represented using 8-bit characters in the local
  663. variant of ASCII.
  664. Each field within the structure is contiguous; that is, there is
  665. no padding used within the structure.  Each character on the archive medium
  666. is stored contiguously.
  667.  
  668. Bytes representing the contents of files (after the header record
  669. of each file) are not translated in any way and
  670. are not constrained to represent characters or to be in any character set.
  671. The \fItar\fP(5) format does not distinguish text files from binary
  672. files, and no translation of file contents should be performed.
  673.  
  674. The fields \fIname, linkname, magic, uname\fP, and \fIgname\fP are
  675. null-terminated
  676. character strings.  All other fields are zero-filled octal numbers in
  677. ASCII.  Each numeric field (of width \fIw\fP) contains \fIw\fP-2 digits, a space, and
  678. a null, except \fIsize\fP and \fImtime\fP,
  679. which do not contain the trailing null.
  680.  
  681. The \fIname\fP field is the pathname of the file, with directory names
  682. (if any) preceding the file name, separated by slashes.
  683.  
  684. The \fImode\fP field provides nine bits specifying file permissions and three
  685. bits to specify the Set UID, Set GID and Save Text (TSVTX) modes.  Values
  686. for these bits are defined above.  When special permissions are required
  687. to create a file with a given mode, and the user restoring files from the
  688. archive does not hold such permissions, the mode bit(s) specifying those
  689. special permissions are ignored.  Modes which are not supported by the
  690. operating system restoring files from the archive will be ignored.
  691. Unsupported modes should be faked up when creating an archive; e.g.
  692. the group permission could be copied from the `other' permission.
  693.  
  694. The \fIuid\fP and \fIgid\fP fields are the user and group ID of the file owners,
  695. respectively.
  696.  
  697. The \fIsize\fP field is the size of the file in bytes; linked files are archived
  698. with this field specified as zero.
  699.  
  700. The \fImtime\fP field is the modification time of the file at the time it was
  701. archived.  It is the ASCII representation of the octal value of the
  702. last time the file was modified, represented as in integer number of
  703. seconds since January 1, 1970, 00:00 Coordinated Universal Time.
  704.  
  705. The \fIchksum\fP field is the ASCII representaion of the octal value of the
  706. simple sum of all bytes in the header record.  Each 8-bit byte in the
  707. header is treated as an unsigned value.  These values are added to an
  708. unsigned integer, initialized to zero, the precision of which shall be no
  709. less than seventeen bits.  When calculating the checksum, the \fIchksum\fP
  710. field is treated as if it were all blanks.
  711.  
  712. The \fItypeflag\fP field specifies the type of file archived.  If a particular
  713. implementation does not recognize or permit the specified type, the file
  714. will be extracted as if it were a regular file.  As this action occurs,
  715. \fItar\fP issues a warning to the standard error.
  716. .IP "LF_NORMAL or LF_OLDNORMAL"
  717. represents a regular file.
  718. For backward compatibility, a \fItypeflag\fP value of LF_OLDNORMAL
  719. should be silently recognized as a regular file.  New archives should
  720. be created using LF_NORMAL.
  721. Also, for backward
  722. compatability, \fItar\fP treats a regular file whose name ends
  723. with a slash as a directory.
  724. .IP LF_LINK
  725. represents a file linked to another file, of any type,
  726. previously archived.  Such files are identified in Unix by each file
  727. having the same device and inode number.  The linked-to
  728. name is specified in the \fIlinkname\fP field with a trailing null.
  729. .IP LF_SYMLINK
  730. represents a symbolic link to another file.  The linked-to
  731. name is specified in the \fIlinkname\fP field with a trailing null.
  732. .IP "LF_CHR or LF_BLK"
  733. represent character special files and block
  734. special files respectively.
  735. In this case the \fIdevmajor\fP and \fIdevminor\fP
  736. fields will contain the
  737. major and minor device numbers respectively.  Operating
  738. systems may map the device specifications to their own local
  739. specification, or may ignore the entry.
  740. .IP LF_DIR
  741. specifies a directory or sub-directory.  The directory name
  742. in the \fIname\fP field should end with a slash.
  743. On systems where
  744. disk allocation is performed on a directory basis the \fIsize\fP
  745. field will contain the maximum number of bytes (which may be
  746. rounded to the nearest disk block allocation unit) which the
  747. directory may hold.  A \fIsize\fP field of zero indicates no such
  748. limiting.  Systems which do not support limiting in this
  749. manner should ignore the \fIsize\fP field.
  750. .IP LF_FIFO
  751. specifies a FIFO special file.  Note that the archiving of
  752. a FIFO file archives the existence of this file and not its
  753. contents.
  754. .IP LF_CONTIG
  755. specifies a contiguous file, which is the same as a normal
  756. file except that, in operating systems which support it,
  757. all its space is allocated contiguously on the disk.  Operating
  758. systems which do not allow contiguous allocation should silently treat
  759. this type as a normal file.
  760. .IP "`A' \- `Z'"
  761. are reserved for custom implementations.  None are used by this
  762. version of the \fItar\fP program.
  763. .IP \fIother\fP
  764. values are reserved for specification in future revisions of the
  765. P1003 standard, and should not be used by any \fItar\fP program.
  766. .LP
  767. The \fImagic\fP field indicates that this archive was output in the P1003
  768. archive format.  If this field contains TMAGIC, then the
  769. \fIuname\fP and \fIgname\fP
  770. fields will contain the ASCII representation of the owner and group of the
  771. file respectively.  If found, the user and group ID represented by these
  772. names
  773. will be used rather than the values contained
  774. within the \fIuid\fP and \fIgid\fP fields.
  775. User names longer than TUNMLEN-1 or group
  776. names longer than TGNMLEN-1 characters will be truncated.
  777. .SH "SEE ALSO"
  778. tar(1), ar(5), cpio(5), dump(8), restor(8), restore(8)
  779. .SH BUGS
  780. Names or link names longer than NAMSIZ-1 characters cannot be archived.
  781.  
  782. This format does not yet address multi-volume archives.
  783. .SH NOTES
  784. This manual page was adapted by John Gilmore
  785. from Draft 6 of the P1003 specification
  786. @@@ Fin de tar.5
  787. echo tar.h
  788. cat >tar.h <<'@@@ Fin de tar.h'
  789. /*
  790.  * Header file for public domain tar (tape archive) program.
  791.  *
  792.  * @(#)tar.h 1.24 87/11/06    Public Domain.
  793.  *
  794.  * Created 25 August 1985 by John Gilmore, ihnp4!hoptoad!gnu.
  795.  */
  796.  
  797. /*
  798.  * Kludge for handling systems that can't cope with multiple
  799.  * external definitions of a variable.  In ONE routine (tar.c),
  800.  * we #define TAR_EXTERN to null; here, we set it to "extern" if
  801.  * it is not already set.
  802.  */
  803. #ifndef TAR_EXTERN
  804. #define TAR_EXTERN extern
  805. #endif
  806.  
  807. /*
  808.  * Header block on tape.
  809.  *
  810.  * I'm going to use traditional DP naming conventions here.
  811.  * A "block" is a big chunk of stuff that we do I/O on.
  812.  * A "record" is a piece of info that we care about.
  813.  * Typically many "record"s fit into a "block".
  814.  */
  815. #define    RECORDSIZE    512
  816. #define    NAMSIZ    100
  817. #define    TUNMLEN    32
  818. #define    TGNMLEN    32
  819.  
  820. union record {
  821.     char        charptr[RECORDSIZE];
  822.     struct header {
  823.         char    name[NAMSIZ];
  824.         char    mode[8];
  825.         char    uid[8];
  826.         char    gid[8];
  827.         char    size[12];
  828.         char    mtime[12];
  829.         char    chksum[8];
  830.         char    linkflag;
  831.         char    linkname[NAMSIZ];
  832.         char    magic[8];
  833.         char    uname[TUNMLEN];
  834.         char    gname[TGNMLEN];
  835.         char    devmajor[8];
  836.         char    devminor[8];
  837.     } header;
  838. };
  839.  
  840. /* The checksum field is filled with this while the checksum is computed. */
  841. #define    CHKBLANKS    "        "    /* 8 blanks, no null */
  842.  
  843. /* The magic field is filled with this if uname and gname are valid. */
  844. #define    TMAGIC        "ustar  "    /* 7 chars and a null */
  845.  
  846. /* The linkflag defines the type of file */
  847. #define    LF_OLDNORMAL    '\0'        /* Normal disk file, Unix compat */
  848. #define    LF_NORMAL    '0'        /* Normal disk file */
  849. #define    LF_LINK        '1'        /* Link to previously dumped file */
  850. #define    LF_SYMLINK    '2'        /* Symbolic link */
  851. #define    LF_CHR        '3'        /* Character special file */
  852. #define    LF_BLK        '4'        /* Block special file */
  853. #define    LF_DIR        '5'        /* Directory */
  854. #define    LF_FIFO        '6'        /* FIFO special file */
  855. #define    LF_CONTIG    '7'        /* Contiguous file */
  856. /* Further link types may be defined later. */
  857.  
  858. /*
  859.  * Exit codes from the "tar" program
  860.  */
  861. #define    EX_SUCCESS    0        /* success! */
  862. #define    EX_ARGSBAD    1        /* invalid args */
  863. #define    EX_BADFILE    2        /* invalid filename */
  864. #define    EX_BADARCH    3        /* bad archive */
  865. #define    EX_SYSTEM    4        /* system gave unexpected error */
  866.  
  867.  
  868. /*
  869.  * Global variables
  870.  */
  871. TAR_EXTERN union record    *ar_block;    /* Start of block of archive */
  872. TAR_EXTERN union record    *ar_record;    /* Current record of archive */
  873. TAR_EXTERN union record    *ar_last;    /* Last+1 record of archive block */
  874. TAR_EXTERN char        ar_reading;    /* 0 writing, !0 reading archive */
  875. TAR_EXTERN int        blocking;    /* Size of each block, in records */
  876. TAR_EXTERN int        blocksize;    /* Size of each block, in bytes */
  877. TAR_EXTERN char        *ar_file;    /* File containing archive */
  878. TAR_EXTERN char        *name_file;    /* File containing names to work on */
  879. TAR_EXTERN char        *tar;        /* Name of this program */
  880.  
  881. /*
  882.  * Flags from the command line
  883.  */
  884. TAR_EXTERN char    f_reblock;        /* -B */
  885. TAR_EXTERN char    f_create;        /* -c */
  886. TAR_EXTERN char    f_diff;            /* -d */
  887. TAR_EXTERN char    f_dironly;        /* -D */
  888. TAR_EXTERN char    f_follow_links;        /* -h */
  889. TAR_EXTERN char    f_ignorez;        /* -i */
  890. TAR_EXTERN char    f_keep;            /* -k */
  891. TAR_EXTERN char f_local_filesys;    /* -l */
  892. TAR_EXTERN char    f_modified;        /* -m */
  893. TAR_EXTERN char    f_oldarch;        /* -o */
  894. TAR_EXTERN char    f_use_protection;    /* -p */
  895. TAR_EXTERN char    f_sayblock;        /* -R */
  896. TAR_EXTERN char    f_sorted_names;        /* -s */
  897. TAR_EXTERN char    f_list;            /* -t */
  898. TAR_EXTERN char    f_namefile;        /* -T */
  899. TAR_EXTERN char    f_verbose;        /* -v */
  900. TAR_EXTERN char    f_extract;        /* -x */
  901. TAR_EXTERN char    f_compress;        /* -z */
  902.  
  903. /*
  904.  * We now default to Unix Standard format rather than 4.2BSD tar format.
  905.  * The code can actually produce all three:
  906.  *    f_standard    ANSI standard
  907.  *    f_oldarch    V7
  908.  *    neither        4.2BSD
  909.  * but we don't bother, since 4.2BSD can read ANSI standard format anyway.
  910.  * The only advantage to the "neither" option is that we can cmp(1) our
  911.  * output to the output of 4.2BSD tar, for debugging.
  912.  */
  913. #define        f_standard        (!f_oldarch)
  914.  
  915. /*
  916.  * Structure for keeping track of filenames and lists thereof.
  917.  */
  918. struct name {
  919.     struct name    *next;
  920.     short        length;        /* cached strlen(name) */
  921.     char        found;        /* A matching file has been found */
  922.     char        firstch;    /* First char is literally matched */
  923.     char        regexp;        /* This name is a regexp, not literal */
  924.     char        name[NAMSIZ+1];
  925. };
  926.  
  927. TAR_EXTERN struct name    *namelist;    /* Points to first name in list */
  928. TAR_EXTERN struct name    *namelast;    /* Points to last name in list */
  929.  
  930. TAR_EXTERN int        archive;    /* File descriptor for archive file */
  931. TAR_EXTERN int        errors;        /* # of files in error */
  932.  
  933. /*
  934.  *
  935.  * Due to the next struct declaration, each routine that includes
  936.  * "tar.h" must also include <sys/types.h>.  I tried to make it automatic,
  937.  * but System V has no defines in <sys/types.h>, so there is no way of
  938.  * knowing when it has been included.  In addition, it cannot be included
  939.  * twice, but must be included exactly once.  Argghh!
  940.  *
  941.  * Thanks, typedef.  Thanks, USG.
  942.  */
  943. struct link {
  944.     struct link    *next;
  945.     dev_t        dev;
  946.     ino_t        ino;
  947.     short        linkcount;
  948.     char        name[NAMSIZ+1];
  949. };
  950.  
  951. TAR_EXTERN struct link    *linklist;    /* Points to first link in list */
  952.  
  953.  
  954. /*
  955.  * Error recovery stuff
  956.  */
  957. TAR_EXTERN char        read_error_flag;
  958.  
  959.  
  960. /*
  961.  * Declarations of functions available to the world.
  962.  */
  963. union record *findrec();
  964. void userec();
  965. union record *endofrecs();
  966. void anno();
  967. #define     annorec(stream, msg)    anno(stream, msg, 0)    /* Cur rec */
  968. #define    annofile(stream, msg)    anno(stream, msg, 1)    /* Saved rec */
  969. @@@ Fin de tar.h
  970. echo port.h
  971. cat >port.h <<'@@@ Fin de port.h'
  972. /*
  973.  * Portability declarations for public domain tar.
  974.  *
  975.  * @(#)port.h 1.3    87/11/11    Public Domain by John Gilmore, 1986
  976.  */
  977.  
  978. /*
  979.  * Everybody does wait() differently.  There seem to be no definitions
  980.  * for this in V7 (e.g. you are supposed to shift and mask things out
  981.  * using constant shifts and masks.)  So fuck 'em all -- my own non
  982.  * standard but portable macros.  Don't change to a "union wait"
  983.  * based approach -- the ordering of the elements of the struct 
  984.  * depends on the byte-sex of the machine.  Foo!
  985.  */
  986. #define    TERM_SIGNAL(status)    ((status) & 0x7F)
  987. #define TERM_COREDUMP(status)    (((status) & 0x80) != 0)
  988. #define TERM_VALUE(status)    ((status) >> 8)
  989.  
  990. #ifdef    MSDOS
  991. /* missing things from sys/stat.h */
  992. #define    S_ISUID        0
  993. #define    S_ISGID        0
  994. #define    S_ISVTX        0
  995.  
  996. /* device stuff */
  997. #define    makedev(ma, mi)        ((ma << 8) | mi)
  998. #define    major(dev)        (dev)
  999. #define    minor(dev)        (dev)
  1000. #endif    /* MSDOS */
  1001. @@@ Fin de port.h
  1002. echo open3.h
  1003. cat >open3.h <<'@@@ Fin de open3.h'
  1004. /*
  1005.  * @(#)open3.h 1.4 87/11/11    Public Domain.
  1006.  *
  1007.  * open3.h -- #defines for the various flags for the Sys V style 3-argument
  1008.  * open() call.  On BSD or System 5, the system already has this in an
  1009.  * include file.  This file is needed for V7 and MINIX systems for the
  1010.  * benefit of open3() in port.c, a routine that emulates the 3-argument
  1011.  * call using system calls available on V7/MINIX. 
  1012.  *
  1013.  * This file is needed by PD tar even if we aren't using the
  1014.  * emulator, since the #defines for O_WRONLY, etc. are used in
  1015.  * a couple of places besides the open() calls, (e.g. in the assignment
  1016.  * to openflag in extract.c).  We just #include this rather than
  1017.  * #ifdef them out.
  1018.  *
  1019.  * Written 6/10/87 by rmtodd@uokmax (Richard Todd).
  1020.  *
  1021.  * The names have been changed by John Gilmore, 31 July 1987, since
  1022.  * Richard called it "bsdopen", and really this change was introduced in
  1023.  * AT&T Unix systems before BSD picked it up.
  1024.  */
  1025.  
  1026. /* Only one of the next three should be specified */
  1027. #define O_RDONLY     0 /* only allow read */
  1028. #define    O_WRONLY     1 /* only allow write */
  1029. #define    O_RDWR         2 /* both are allowed */
  1030.  
  1031. /* The rest of these can be OR-ed in to the above. */
  1032. /*
  1033.  * O_NDELAY isn't implemented by the emulator.  It's only useful (to tar) on
  1034.  * systems that have named pipes anyway; it prevents tar's hanging by
  1035.  * opening a named pipe.  We #ifndef it because some systems already have
  1036.  * it defined.
  1037.  */
  1038. #ifndef O_NDELAY
  1039. #define O_NDELAY     4 /* don't block on opening devices that would
  1040.                 * block on open -- ignored by emulator. */
  1041. #endif
  1042. #define O_CREAT         8 /* create file if needed */
  1043. #define O_EXCL        16 /* file cannot already exist */
  1044. #define O_TRUNC        32 /* truncate file on open */
  1045. #define O_APPEND    64 /* always write at end of file -- ignored by emul */
  1046.  
  1047. #ifdef EMUL_OPEN3
  1048. /*
  1049.  * make emulation transparent to rest of file -- redirect all open() calls
  1050.  * to our routine
  1051.  */
  1052. #define open    open3
  1053. #endif
  1054. @@@ Fin de open3.h
  1055. echo msd_dir.h
  1056. cat >msd_dir.h <<'@@@ Fin de msd_dir.h'
  1057. /*
  1058.  * @(#)msd_dir.h 1.4 87/11/06    Public Domain.
  1059.  *
  1060.  *  A public domain implementation of BSD directory routines for
  1061.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  1062.  *  August 1897
  1063.  */
  1064.  
  1065. #define    rewinddir(dirp)    seekdir(dirp, 0L)
  1066.  
  1067. #define    MAXNAMLEN    12
  1068.  
  1069. struct direct {
  1070.     ino_t    d_ino;            /* a bit of a farce */
  1071.     int    d_reclen;        /* more farce */
  1072.     int    d_namlen;        /* length of d_name */
  1073.     char    d_name[MAXNAMLEN + 1];        /* garentee null termination */
  1074. };
  1075.  
  1076. struct _dircontents {
  1077.     char    *_d_entry;
  1078.     struct _dircontents    *_d_next;
  1079. };
  1080.  
  1081. typedef struct _dirdesc {
  1082.     int        dd_id;    /* uniquely identify each open directory */
  1083.     long        dd_loc;    /* where we are in directory entry is this */
  1084.     struct _dircontents    *dd_contents;    /* pointer to contents of dir */
  1085.     struct _dircontents    *dd_cp;    /* pointer to current position */
  1086. } DIR;
  1087.  
  1088. extern    DIR        *opendir();
  1089. extern    struct direct    *readdir();
  1090. extern    void        seekdir();
  1091. extern    long        telldir();
  1092. extern    void        closedir();
  1093. @@@ Fin de msd_dir.h
  1094. echo msd_dir.c
  1095. cat >msd_dir.c <<'@@@ Fin de msd_dir.c'
  1096. /*
  1097.  * @(#)msd_dir.c 1.4 87/11/06    Public Domain.
  1098.  *
  1099.  *  A public domain implementation of BSD directory routines for
  1100.  *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  1101.  *  August 1897
  1102.  */
  1103.  
  1104. #include    <sys/types.h>
  1105. #include    <sys/stat.h>
  1106. #include    <sys/dir.h>
  1107. #include    <malloc.h>
  1108. #include    <string.h>
  1109. #include    <dos.h>
  1110.  
  1111. #ifndef    NULL
  1112. # define    NULL    0
  1113. #endif    /* NULL */
  1114.  
  1115. #ifndef    MAXPATHLEN
  1116. # define    MAXPATHLEN    255
  1117. #endif    /* MAXPATHLEN */
  1118.  
  1119. /* attribute stuff */
  1120. #define    A_RONLY        0x01
  1121. #define    A_HIDDEN    0x02
  1122. #define    A_SYSTEM    0x04
  1123. #define    A_LABEL        0x08
  1124. #define    A_DIR        0x10
  1125. #define    A_ARCHIVE    0x20
  1126.  
  1127. /* dos call values */
  1128. #define    DOSI_FINDF    0x4e
  1129. #define    DOSI_FINDN    0x4f
  1130. #define    DOSI_SDTA    0x1a
  1131.  
  1132. #define    Newisnull(a, t)        ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  1133. #define    ATTRIBUTES        (A_DIR | A_HIDDEN | A_SYSTEM)
  1134.  
  1135. /* what find first/next calls look use */
  1136. typedef struct {
  1137.     char        d_buf[21];
  1138.     char        d_attribute;
  1139.     unsigned short    d_time;
  1140.     unsigned short    d_date;
  1141.     long        d_size;
  1142.     char        d_name[13];
  1143. } Dta_buf;
  1144.  
  1145. static    char    *getdirent();
  1146. static    void    setdta();
  1147. static    void    free_dircontents();
  1148.  
  1149. static    Dta_buf        dtabuf;
  1150. static    Dta_buf        *dtapnt = &dtabuf;
  1151. static    union REGS    reg, nreg;
  1152.  
  1153. #if    defined(M_I86LM)
  1154. static    struct SREGS    sreg;
  1155. #endif
  1156.  
  1157. DIR    *
  1158. opendir(name)
  1159.     char    *name;
  1160. {
  1161.     struct    stat        statb;
  1162.     DIR            *dirp;
  1163.     char            c;
  1164.     char            *s;
  1165.     struct _dircontents    *dp;
  1166.     char            nbuf[MAXPATHLEN + 1];
  1167.     
  1168.     if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  1169.         return (DIR *) NULL;
  1170.     if (Newisnull(dirp, DIR))
  1171.         return (DIR *) NULL;
  1172.     if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  1173.         (void) strcat(strcpy(nbuf, name), "\\*.*");
  1174.     else
  1175.         (void) strcat(strcpy(nbuf, name), "*.*");
  1176.     dirp->dd_loc = 0;
  1177.     setdta();
  1178.     dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  1179.     if ((s = getdirent(nbuf)) == (char *) NULL)
  1180.         return dirp;
  1181.     do {
  1182.         if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  1183.             malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  1184.         {
  1185.             if (dp)
  1186.                 free((char *) dp);
  1187.             free_dircontents(dirp->dd_contents);
  1188.             return (DIR *) NULL;
  1189.         }
  1190.         if (dirp->dd_contents)
  1191.             dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  1192.         else
  1193.             dirp->dd_contents = dirp->dd_cp = dp;
  1194.         (void) strcpy(dp->_d_entry, s);
  1195.         dp->_d_next = (struct _dircontents *) NULL;
  1196.     } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  1197.     dirp->dd_cp = dirp->dd_contents;
  1198.  
  1199.     return dirp;
  1200. }
  1201.  
  1202. void
  1203. closedir(dirp)
  1204.     DIR    *dirp;
  1205. {
  1206.     free_dircontents(dirp->dd_contents);
  1207.     free((char *) dirp);
  1208. }
  1209.  
  1210. struct direct    *
  1211. readdir(dirp)
  1212.     DIR    *dirp;
  1213. {
  1214.     static    struct direct    dp;
  1215.     
  1216.     if (dirp->dd_cp == (struct _dircontents *) NULL)
  1217.         return (struct direct *) NULL;
  1218.     dp.d_namlen = dp.d_reclen =
  1219.         strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  1220.     dp.d_ino = 0;
  1221.     dirp->dd_cp = dirp->dd_cp->_d_next;
  1222.     dirp->dd_loc++;
  1223.  
  1224.     return &dp;
  1225. }
  1226.  
  1227. void
  1228. seekdir(dirp, off)
  1229.     DIR    *dirp;
  1230.     long    off;
  1231. {
  1232.     long            i = off;
  1233.     struct _dircontents    *dp;
  1234.  
  1235.     if (off < 0)
  1236.         return;
  1237.     for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  1238.         ;
  1239.     dirp->dd_loc = off - (i + 1);
  1240.     dirp->dd_cp = dp;
  1241. }
  1242.  
  1243. long
  1244. telldir(dirp)
  1245.     DIR    *dirp;
  1246. {
  1247.     return dirp->dd_loc;
  1248. }
  1249.  
  1250. static    void
  1251. free_dircontents(dp)
  1252.     struct    _dircontents    *dp;
  1253. {
  1254.     struct _dircontents    *odp;
  1255.  
  1256.     while (dp) {
  1257.         if (dp->_d_entry)
  1258.             free(dp->_d_entry);
  1259.         dp = (odp = dp)->_d_next;
  1260.         free((char *) odp);
  1261.     }
  1262. }
  1263.  
  1264. static    char    *
  1265. getdirent(dir)
  1266.     char    *dir;
  1267. {
  1268.     if (dir != (char *) NULL) {        /* get first entry */
  1269.         reg.h.ah = DOSI_FINDF;
  1270.         reg.h.cl = ATTRIBUTES;
  1271. #if    defined(M_I86LM)
  1272.         reg.x.dx = FP_OFF(dir);
  1273.         sreg.ds = FP_SEG(dir);
  1274. #else
  1275.         reg.x.dx = (unsigned) dir;
  1276. #endif
  1277.     } else {                /* get next entry */
  1278.         reg.h.ah = DOSI_FINDN;
  1279. #if    defined(M_I86LM)
  1280.         reg.x.dx = FP_OFF(dtapnt);
  1281.         sreg.ds = FP_SEG(dtapnt);
  1282. #else
  1283.         reg.x.dx = (unsigned) dtapnt;
  1284. #endif
  1285.     }
  1286. #if    defined(M_I86LM)
  1287.     intdosx(®, &nreg, &sreg);
  1288. #else
  1289.     intdos(®, &nreg);
  1290. #endif
  1291.     if (nreg.x.cflag)
  1292.         return (char *) NULL;
  1293.  
  1294.     return dtabuf.d_name;
  1295. }
  1296.  
  1297. static    void
  1298. setdta()
  1299. {
  1300.     reg.h.ah = DOSI_SDTA;
  1301. #if    defined(M_I86LM)
  1302.     reg.x.dx = FP_OFF(dtapnt);
  1303.     sreg.ds = FP_SEG(dtapnt);
  1304.     intdosx(®, &nreg, &sreg);
  1305. #else
  1306.     reg.x.dx = (int) dtapnt;
  1307.     intdos(®, &nreg);
  1308. #endif
  1309. }
  1310. @@@ Fin de msd_dir.c
  1311. exit 0
  1312.