home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume11 / sparc-mtools / part01 next >
Encoding:
Text File  |  1990-03-25  |  58.5 KB  |  2,167 lines

  1. Newsgroups: comp.sources.misc
  2. keywords: DOS, floppy
  3. subject: v11i081: Fast mtools,  + mkdfs for SparcStation1 or Sun-3/80 Part 1
  4. from: viktor@melon.princeton.edu (Viktor Dukhovni)
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 11, Issue 81
  8. Submitted-by: viktor@melon.princeton.edu (Viktor Dukhovni)
  9. Archive-name: sparc-mtools/part01
  10.  
  11.     By permission of Emmet Gray I am reposting "mtools"
  12.  
  13. The comp.sources.unix archives are out of date wrt Emmet's latest version
  14. and I have added a somewhat more general driver support mechanism,   so
  15. that the Unix PC and other machines that can read DOS disks only after
  16. various parameters are changed with disk ioctls can be supported more easily.
  17.  
  18.     Included is "mkdfs" an "mkfs" for dos disks,  currently this
  19. works only with 3.5", 80 track disks, and knows the path of the low level format
  20. program only on the SparcStation 1 or Sun 3/80.  A more general program
  21. based on an external table (/etc/dosformat.dat?) should be written one day.
  22.  
  23.     The mread and mwrite are considerably faster on fresh disks,
  24. up to a factor of 12 for large files on high density disks.  The algorithm
  25. degrades to the original speed once files get substantially fragemented,
  26. A more robust algorithm is possible,  but this is quite good enough for
  27. moving files around,  which is the main application I would expect to see
  28. for this package.  
  29.  
  30.     Enjoy!  And please send those bug fixes or improvements,  the
  31. package is still 90% Emmet's code,  so I would much have preferred for him
  32. to resubmit it,  but there is a lot of demand for it now with the desktop
  33. Suns selling in unprecedented numbers,  and Emmet did not have much time
  34. to devote to this.  The only bug I am aware of now is that globbing DOS
  35. file names does not work entirely as expected.  This should either be fixed
  36. or documented.
  37.  
  38.     Viktor Dukhovni <viktor@math.princeton.edu>    : ARPA
  39.         <...!uunet!princeton!math!viktor>    : UUCP
  40.     Fine Hall, Washington Rd., Princeton, NJ 08544  : US-Post
  41.         +1-(609)-258-5792             : VOICE
  42.  
  43. #! /bin/sh
  44. # This is a shell archive.  Remove anything before this line, then unpack
  45. # it by saving it into a file and typing "sh file".  To overwrite existing
  46. # files, type "sh file -c".  You can also feed this as standard input via
  47. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  48. # will see the following message at the end:
  49. #        "End of archive 1 (of 3)."
  50. # Contents:  Customize MANIFEST Makefile Mcopy.1 Mdel.1 Mdir.1 Mkdfs.1
  51. #   Mmd.1 Mrd.1 Mread.1 Mren.1 Mtype.1 Mwrite.1 bootblk.h convdate.c
  52. #   devices.c devices.h fixname.c getfat.c isdir.c match.c mcopy.c
  53. #   mdel.c mkentry.c msdos.h putfat.c search.c unixname.c
  54. # Wrapped by viktor@cucumber on Fri Mar 16 20:50:05 1990
  55. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  56. if test -f 'Customize' -a "${1}" != "-c" ; then 
  57.   echo shar: Will not clobber existing file \"'Customize'\"
  58. else
  59. echo shar: Extracting \"'Customize'\" \(2654 characters\)
  60. sed "s/^X//" >'Customize' <<'END_OF_FILE'
  61. XHow to configure Mtools for non-standard disk formats...
  62. X
  63. XThere are three approaches to the problem of trying to read and write
  64. XMSDOS formatted diskettes in a Unix box doesn't have a floppy drive
  65. Xthat meets the physical drive requirements.  For example, if your
  66. XUnix box only has a 80 track floppy, you can:
  67. X
  68. X    1) Get a device driver to "double step" the 80 track drive
  69. X    to read and write to 40 track diskettes.
  70. X
  71. X        Pros: No new hardware costs.
  72. X        Cons: Device drivers are a bitch to write (or
  73. X                    expensive to buy).
  74. X              Success rates are low when using 80 track
  75. X            drives to write 40 tracks.
  76. X
  77. X    2) Get a conventional device driver and purchase a 40 track
  78. X    drive.  You'll still need the device driver unless your 
  79. X    Unix vendor was thoughtful enough to leave you some "extras".
  80. X
  81. X        Pros: High success rates (40 track to 40 track)
  82. X        Cons: The "foriegn" drive may cause trouble with
  83. X            maintenance contracts
  84. X
  85. X    3) Purchase a 80 track drive for your PC.  This exploits the
  86. X    fact that MSDOS already has a configurable device driver
  87. X    feature.
  88. X
  89. X        Pros: You don't alter your Unix box in any way.
  90. X        Cons: You'll have to process all MSDOS diskettes
  91. X            thru the one PC before using Mtools.
  92. X
  93. X               +--------+          +-----------+
  94. X          +--> | Unix   |          |  IBM PC   |
  95. X          |    | box    |          |  clone    |
  96. X        mtools +--------+          +-----+-----+
  97. X          |    | 80 trk |          | 80  | 40  |        MSDOS
  98. X          +--> | track  | <------> | trk | trk | <----> world
  99. X               +--------+          +-----+-----+
  100. X                                    ^         ^
  101. X                                    |  MSDOS  |
  102. X                                    +- COPY --+
  103. X
  104. XHow to customize Mtools...
  105. X
  106. XThe program can be easily customized to accept non-standard disk
  107. Xformats.  For example, a popular disk format for Unix machines seems to
  108. Xbe 80 track, double sided, 8 sector.  This doesn't conform to any of the
  109. XIBM standard formats, but MSDOS 3.2 (or greater) can be made to format
  110. Xvirtually anything using DRIVPARM (or DRIVER.SYS) in the CONFIG.SYS
  111. Xfile.  Let's take a hypothetical case of a brand X Unix machine with a
  112. X80 track, double sided, 8 sector disk drive.  You could purchase an
  113. Xexternal 80 track drive for your IBM compatible computer and format the
  114. Xnew drive D: under MSDOS with the following in your CONFIG.SYS file
  115. X
  116. X    DRIVPARM=/D:2 /T:80 /S:8 /H:2 /F:2
  117. X        or
  118. X    DEVICE=DRIVER.SYS /D:2 /T:80 /S:8 /H:2 /F:2
  119. X
  120. X
  121. XEmmet P. Gray                US Army, HQ III Corps & Fort Hood
  122. X...!unnet!uiucuxc!fthood!egray        Attn: AFZF-DE-ENV
  123. X                    Directorate of Engineering & Housing
  124. X                    Environmental Management Office
  125. X                    Fort Hood, TX 76544-5057
  126. END_OF_FILE
  127. if test 2654 -ne `wc -c <'Customize'`; then
  128.     echo shar: \"'Customize'\" unpacked with wrong size!
  129. fi
  130. # end of 'Customize'
  131. fi
  132. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  133.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  134. else
  135. echo shar: Extracting \"'MANIFEST'\" \(1305 characters\)
  136. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  137. X   File Name        Archive #    Description
  138. X-----------------------------------------------------------
  139. X Customize                  1    
  140. X MANIFEST                   1    
  141. X Makefile                   1    
  142. X Mcopy.1                    1    
  143. X Mdel.1                     1    
  144. X Mdir.1                     1    
  145. X Mkdfs.1                    1    
  146. X Mmd.1                      1    
  147. X Mrd.1                      1    
  148. X Mread.1                    1    
  149. X Mren.1                     1    
  150. X Mtype.1                    1    
  151. X Mwrite.1                   1    
  152. X Readme                     2    
  153. X bootblk.h                  1    
  154. X convdate.c                 1    
  155. X devices.c                  1    
  156. X devices.h                  1    
  157. X fixname.c                  1    
  158. X getfat.c                   1    
  159. X init.c                     2    
  160. X isdir.c                    1    
  161. X match.c                    1    
  162. X mcopy.c                    1    
  163. X mdel.c                     1    
  164. X mdir.c                     2    
  165. X mkdfs.c                    2    
  166. X mkentry.c                  1    
  167. X mmd.c                      2    
  168. X mrd.c                      2    
  169. X mread.c                    2    
  170. X mren.c                     2    
  171. X msdos.h                    1    
  172. X mtype.c                    2    
  173. X mwrite.c                   3    
  174. X putfat.c                   1    
  175. X search.c                   1    
  176. X subdir.c                   2    
  177. X unixname.c                 1    
  178. END_OF_FILE
  179. if test 1305 -ne `wc -c <'MANIFEST'`; then
  180.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  181. fi
  182. # end of 'MANIFEST'
  183. fi
  184. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  185.   echo shar: Will not clobber existing file \"'Makefile'\"
  186. else
  187. echo shar: Extracting \"'Makefile'\" \(2592 characters\)
  188. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  189. X#
  190. X#       Makefile for MSDOS tools
  191. X#
  192. X
  193. XCFLAGS    = -g
  194. XLDFLAGS    = 
  195. XLINT    = lint -p
  196. X#
  197. X# Rich Salz's excelent cshar package.
  198. X# Available from comp.sources.unix archives.
  199. X#
  200. XSHAR    = makekit -m
  201. XBINDIR    = /u/viktor/bin/sun4
  202. XMANDIR  = /u/viktor/man/man1
  203. XPROGS    = mdir mread mwrite mdel mtype mmd mrd mren mcopy mkdfs
  204. XCMNOBJ = init.o search.o unixname.o subdir.o getfat.o devices.o
  205. X
  206. XMKDFS   = mkdfs.o
  207. XMDIR    = mdir.o match.o convdate.o isdir.o $(CMNOBJ)
  208. XMREAD    = mread.o match.o convdate.o $(CMNOBJ)
  209. XMWRITE    = mwrite.o fixname.o putfat.o mkentry.o isdir.o $(CMNOBJ)
  210. XMDEL    = mdel.o match.o putfat.o $(CMNOBJ)
  211. XMTYPE    = mtype.o match.o $(CMNOBJ)
  212. XMMD    = mmd.o fixname.o putfat.o mkentry.o $(CMNOBJ)
  213. XMRD    = mrd.o putfat.o $(CMNOBJ)
  214. XMREN    = mren.o fixname.o putfat.c isdir.o $(CMNOBJ)
  215. XMCOPY    = mcopy.o
  216. X
  217. Xall:    $(PROGS)
  218. X
  219. Xmkdfs:  $(MKDFS)
  220. X    $(CC) $(LDFLAGS) $(MKDFS) -o mkdfs
  221. X
  222. Xmdir:    $(MDIR)
  223. X    $(CC) $(LDFLAGS) $(MDIR) -o mdir
  224. X
  225. Xmread:    $(MREAD)
  226. X    $(CC) $(LDFLAGS) $(MREAD) -o mread
  227. X
  228. Xmwrite:    $(MWRITE)
  229. X    $(CC) $(LDFLAGS) $(MWRITE) -o mwrite
  230. X
  231. Xmdel:    $(MDEL)
  232. X    $(CC) $(LDFLAGS) $(MDEL) -o mdel
  233. X
  234. Xmtype:    $(MTYPE)
  235. X    $(CC) $(LDFLAGS) $(MTYPE) -o mtype
  236. X
  237. Xmmd:    $(MMD)
  238. X    $(CC) $(LDFLAGS) $(MMD) -o mmd
  239. X
  240. Xmrd:    $(MRD)
  241. X    $(CC) $(LDFLAGS) $(MRD) -o mrd
  242. X
  243. Xmren:    $(MREN)
  244. X    $(CC) $(LDFLAGS) $(MREN) -o mren
  245. X
  246. Xmcopy:    $(MCOPY)
  247. X    $(CC) $(LDFLAGS) $(MCOPY) -o mcopy
  248. X
  249. Xinstall: all
  250. X    cp mdir $(BINDIR)/mdir
  251. X    cp mread $(BINDIR)/mread
  252. X    cp mwrite $(BINDIR)/mwrite
  253. X    cp mdel $(BINDIR)/mdel
  254. X    cp mtype $(BINDIR)/mtype
  255. X    cp mmd $(BINDIR)/mmd
  256. X    cp mrd $(BINDIR)/mrd
  257. X    cp mren $(BINDIR)/mren
  258. X    cp mcopy $(BINDIR)/mcopy
  259. X
  260. Xinstall-man:
  261. X    cp Mread.1 $(MANDIR)/mread.1
  262. X    cp Mdir.1 $(MANDIR)/mdir.1
  263. X    cp Mwrite.1 $(MANDIR)/mwrite.1
  264. X    cp Mdel.1 $(MANDIR)/mdel.1
  265. X    cp Mtype.1 $(MANDIR)/mtype.1
  266. X    cp Mmd.1 $(MANDIR)/mmd.1
  267. X    cp Mrd.1 $(MANDIR)/mrd.1
  268. X    cp Mren.1 $(MANDIR)/mren.1
  269. X    cp Mcopy.1 $(MANDIR)/mcopy.1
  270. X
  271. Xclean:
  272. X    rm $(PROGS) *.o
  273. X
  274. Xlint:
  275. X    $(LINT) mdir.c getfat.c init.c search.c match.c convdate.c subdir.c \
  276. X    unixname.c isdir.c
  277. X    $(LINT) mread.c getfat.c init.c search.c match.c unixname.c subdir.c
  278. X    $(LINT) mwrite.c getfat.c init.c search.c fixname.c unixname.c \
  279. X    putfat.c subdir.c mkentry.c isdir.c
  280. X    $(LINT) mdel.c getfat.c init.c search.c match.c unixname.c putfat.c \
  281. X    subdir.c
  282. X    $(LINT) mtype.c getfat.c init.c search.c match.c unixname.c subdir.c
  283. X    $(LINT) mmd.c getfat.c init.c search.c fixname.c unixname.c putfat.c \
  284. X    subdir.c mkentry.c
  285. X    $(LINT) mrd.c getfat.c init.c search.c unixname.c putfat.c subdir.c
  286. X    $(LINT) mren.c getfat.c init.c search.c fixname.c unixname.c putfat.c \
  287. X    subdir.c
  288. X    $(LINT) mcopy.c
  289. X
  290. Xshar:
  291. X    $(SHAR) MANIFEST Customize Makefile Readme *.[1ch]
  292. X
  293. Xinit.o:    msdos.h devices.h
  294. END_OF_FILE
  295. if test 2592 -ne `wc -c <'Makefile'`; then
  296.     echo shar: \"'Makefile'\" unpacked with wrong size!
  297. fi
  298. # end of 'Makefile'
  299. fi
  300. if test -f 'Mcopy.1' -a "${1}" != "-c" ; then 
  301.   echo shar: Will not clobber existing file \"'Mcopy.1'\"
  302. else
  303. echo shar: Extracting \"'Mcopy.1'\" \(1676 characters\)
  304. sed "s/^X//" >'Mcopy.1' <<'END_OF_FILE'
  305. X.TH MCOPY 1 local
  306. X.SH NAME
  307. Xmcopy \- copy MSDOS files to/from Unix
  308. X.SH SYNOPSIS
  309. X.B mcopy
  310. X[
  311. X.B -tnvm
  312. X] unixfile a:msdosfile
  313. X.PP
  314. X.B mcopy
  315. X[
  316. X.B -tnvm
  317. X] unixfile [ unixfiles... ] a:msdosdirectory
  318. X.PP
  319. X.B mcopy
  320. X[
  321. X.B -tnm
  322. X] a:msdosfile unixfile
  323. X.PP
  324. X.B mcopy
  325. X[
  326. X.B -tnm
  327. X] a:msdosfile [ a:msdosfiles... ] unixdirectory
  328. X.SH DESCRIPTION
  329. XIn the first two forms,
  330. X.I mcopy
  331. Xcopies the specified Unix file to the named MSDOS file or copies
  332. Xmultiple Unix files to the named MSDOS directory.  The last two forms
  333. Xcopy MSDOS files to Unix.  MSDOS sub directories are supported with
  334. Xeither the '/' or '\e\' separator.  The use of the '\e\' separator or
  335. Xwildcards will require the names to be enclosed in quotes to protect
  336. Xthem from the shell.
  337. X.PP
  338. XThe use of the 'a:' drive designation on the MSDOS files determines the
  339. Xdirection of the transfer.  A missing drive designation implies a Unix
  340. Xfile whose path starts in the current directory 
  341. X.PP
  342. X.I Mcopy
  343. Xwill allow the following command line options:
  344. X.TP
  345. X.B t
  346. XText file transfer.
  347. X.I Mcopy
  348. Xwill translate incoming carriage return/line feeds to line feeds.
  349. X.TP
  350. X.B n
  351. XNo warning.
  352. X.I Mcopy
  353. Xwill not warn the user when overwriting an existing file.
  354. X.TP
  355. X.B v
  356. Xverbose mode.
  357. X.TP
  358. X.B m
  359. XPreserve the file modification time.
  360. X.PP
  361. XIf the target file already exists, and the
  362. X.I -n
  363. Xoption is not in effect,
  364. X.I mcopy
  365. Xasks whether or not to overwrite the file.
  366. X.PP
  367. XThe environmental variable MCWD may be used to establish a current
  368. Xworking directory (relative to the MSDOS diskette).
  369. X.SH SEE ALSO
  370. Xmdir(1), mtype(1), mread(1), mwrite(1)
  371. X.SH BUGS
  372. XWildcards are only applied to filenames, not to directory names.
  373. XUnlike MSDOS, the destination directory may not be omitted.
  374. END_OF_FILE
  375. if test 1676 -ne `wc -c <'Mcopy.1'`; then
  376.     echo shar: \"'Mcopy.1'\" unpacked with wrong size!
  377. fi
  378. # end of 'Mcopy.1'
  379. fi
  380. if test -f 'Mdel.1' -a "${1}" != "-c" ; then 
  381.   echo shar: Will not clobber existing file \"'Mdel.1'\"
  382. else
  383. echo shar: Extracting \"'Mdel.1'\" \(869 characters\)
  384. sed "s/^X//" >'Mdel.1' <<'END_OF_FILE'
  385. X.TH MDEL 1 local
  386. X.SH NAME
  387. Xmdel \- delete a MSDOS file
  388. X.SH SYNOPSIS
  389. X.B mdel
  390. X[
  391. X.B -v
  392. X] msdosfile [ msdosfiles...  ]
  393. X.SH DESCRIPTION
  394. X.I Mdel
  395. Xdeletes a file on a MSDOS formatted diskette.  Sub directories are supported
  396. Xwith either the '/' or '\e\' separator.  The use of the '\e\' separator
  397. Xor wildcards will require the names to be enclosed in quotes to protect
  398. Xthem from the shell.
  399. X.PP
  400. X.I Mdel
  401. Xwill allow the following command line option:
  402. X.TP
  403. X.B v
  404. XVerbose mode.  Echo the file names as they are processed.
  405. X.PP
  406. X.I Mdel
  407. Xwill ask for verification prior to removing a read\-only file.
  408. X.PP
  409. XThe environmental variable MCWD may be used to establish a current
  410. Xworking directory (relative to the MSDOS diskette).
  411. X.SH SEE ALSO
  412. Xmdir(1)
  413. X.SH BUGS
  414. XAllows multiple arguments, which does not follow the MSDOS convention.
  415. XWildcards are only applied to filenames, not to directory names.
  416. END_OF_FILE
  417. if test 869 -ne `wc -c <'Mdel.1'`; then
  418.     echo shar: \"'Mdel.1'\" unpacked with wrong size!
  419. fi
  420. # end of 'Mdel.1'
  421. fi
  422. if test -f 'Mdir.1' -a "${1}" != "-c" ; then 
  423.   echo shar: Will not clobber existing file \"'Mdir.1'\"
  424. else
  425. echo shar: Extracting \"'Mdir.1'\" \(975 characters\)
  426. sed "s/^X//" >'Mdir.1' <<'END_OF_FILE'
  427. X.TH MDIR 1 local
  428. X.SH NAME
  429. Xmdir \- display a MSDOS directory
  430. X.SH SYNOPSIS
  431. X.B mdir
  432. X[
  433. X.B -w
  434. X] msdosdirectory
  435. X.PP
  436. X.B mdir
  437. X[
  438. X.B -w
  439. X] msdosfile [ msdosfiles...  ] 
  440. X.SH DESCRIPTION
  441. X.I Mdir
  442. Xdisplays the contents of a MSDOS formatted diskette.  Sub directories
  443. Xare supported with either the '/' or '\e\' separator.  The use of 
  444. Xthe '\e\' separator or wildcards will require the names to be enclosed
  445. Xin quotes to protect them from the shell.
  446. X.PP
  447. X.I Mdir
  448. Xwill allow the following command line option:
  449. X.TP
  450. X.B w
  451. XWide output.  This option will print the file names across the page
  452. Xwithout displaying the file size or creation date.
  453. X.PP
  454. XAn error occurs if a component of the path is not a directory.
  455. X.PP
  456. XThe environmental variable MCWD may be used to establish a current
  457. Xworking directory (relative to the MSDOS diskette).
  458. X.SH SEE ALSO
  459. Xmtype(1)
  460. X.SH BUGS
  461. XAllows multiple arguments, which does not follow the MSDOS convention.
  462. XWildcards are only applied to filenames, not to directory names.
  463. END_OF_FILE
  464. if test 975 -ne `wc -c <'Mdir.1'`; then
  465.     echo shar: \"'Mdir.1'\" unpacked with wrong size!
  466. fi
  467. # end of 'Mdir.1'
  468. fi
  469. if test -f 'Mkdfs.1' -a "${1}" != "-c" ; then 
  470.   echo shar: Will not clobber existing file \"'Mkdfs.1'\"
  471. else
  472. echo shar: Extracting \"'Mkdfs.1'\" \(862 characters\)
  473. sed "s/^X//" >'Mkdfs.1' <<'END_OF_FILE'
  474. X.TH MKDFS 1 local
  475. X.SH NAME
  476. Xmkdfs \- Initialize an MSDOS disk.
  477. X.SH SYNOPSIS
  478. X.B mkdfs
  479. X[
  480. X.B -h
  481. X]
  482. X[
  483. X.B -f
  484. X]
  485. X.SH DESCRIPTION
  486. X.I Mkdfs
  487. XMkdfs formats and initializes a DOS file system on a 3.5 inch Sun 4/60 or
  488. X3/80 internal floppy.  It first calls the standard Sun format utility and 
  489. Xthen lays out an empty filesystem.
  490. X.PP
  491. X.I Mkdfs
  492. Xaccepts the following options:
  493. X.TP
  494. X.B h
  495. XHigh density switch.
  496. XSince 720K disks are far more common in the DOS world,  the lower
  497. Xdensity is the default,  use this option for the high density 1.44MB disks.
  498. X.TP
  499. X.B f
  500. XFirst reformat the drive,  useful for new or abused drives.  (Using the drive
  501. Xin a Mac counts in the last category)
  502. X.SH SEE ALSO
  503. Xmdir(1), mread(1), mtype(1), mren(1), mkd(1), mrd(1), mdel(1), mcopy(1)
  504. X.SH AUTHOR
  505. XViktor Dukhovni, <viktor@math.princeton.edu>
  506. X.SH BUGS
  507. XShould detect high density disks obsoleting the h option.
  508. END_OF_FILE
  509. if test 862 -ne `wc -c <'Mkdfs.1'`; then
  510.     echo shar: \"'Mkdfs.1'\" unpacked with wrong size!
  511. fi
  512. # end of 'Mkdfs.1'
  513. fi
  514. if test -f 'Mmd.1' -a "${1}" != "-c" ; then 
  515.   echo shar: Will not clobber existing file \"'Mmd.1'\"
  516. else
  517. echo shar: Extracting \"'Mmd.1'\" \(906 characters\)
  518. sed "s/^X//" >'Mmd.1' <<'END_OF_FILE'
  519. X.TH MMD 1 local
  520. X.SH NAME
  521. Xmmd \- make a MSDOS sub directory
  522. X.SH SYNOPSIS
  523. X.B mmd
  524. X[
  525. X.B -v
  526. X] msdosdirectory
  527. X.SH DESCRIPTION
  528. X.I Mmd
  529. Xmakes a new directory on a MSDOS formatted diskette.  Sub directories
  530. Xare supported with either the '/' or '\e\' separator.  The use of
  531. Xthe '\e\' separator will require the directory name to be enclosed in
  532. Xquotes to protect it from the shell.
  533. X.PP
  534. X.I Mmd
  535. Xwill allow the following command line option:
  536. X.TP
  537. X.B v
  538. XVerbose mode.  Display the new directory name if the name supplied is
  539. Xinvalid.
  540. X.PP
  541. XReasonable care is taken to create a valid MSDOS directory name.  If an
  542. Xinvalid name is specified,
  543. X.I mmd
  544. Xwill change the name (and display the new name if the verbose mode is
  545. Xset).
  546. X.PP
  547. XAn error occurs if the directory already exists.
  548. X.PP
  549. XThe environmental variable MCWD may be used to establish a current
  550. Xworking directory (relative to the MSDOS diskette).
  551. X.SH SEE ALSO
  552. Xmdir(1), mrd(1)
  553. END_OF_FILE
  554. if test 906 -ne `wc -c <'Mmd.1'`; then
  555.     echo shar: \"'Mmd.1'\" unpacked with wrong size!
  556. fi
  557. # end of 'Mmd.1'
  558. fi
  559. if test -f 'Mrd.1' -a "${1}" != "-c" ; then 
  560.   echo shar: Will not clobber existing file \"'Mrd.1'\"
  561. else
  562. echo shar: Extracting \"'Mrd.1'\" \(598 characters\)
  563. sed "s/^X//" >'Mrd.1' <<'END_OF_FILE'
  564. X.TH MRD 1 local
  565. X.SH NAME
  566. Xmrd \- remove a MSDOS sub directory
  567. X.SH SYNOPSIS
  568. X.B mrd
  569. Xmsdosdirectory
  570. X.SH DESCRIPTION
  571. X.I Mrd
  572. Xremoves a directory from a MSDOS formatted diskette.  Sub directories
  573. Xare supported with either the '/' or '\e\' separator.  The use of
  574. Xthe '\e\' separator will require the directory name to be enclosed in
  575. Xquotes to protect it from the shell.
  576. X.PP
  577. XAn error occurs if the directory is not empty.
  578. X.PP
  579. XWildcards are not supported.
  580. X.PP
  581. XThe environmental variable MCWD may be used to establish a current
  582. Xworking directory (relative to the MSDOS diskette).
  583. X.SH SEE ALSO
  584. Xmdir(1), mmd(1)
  585. END_OF_FILE
  586. if test 598 -ne `wc -c <'Mrd.1'`; then
  587.     echo shar: \"'Mrd.1'\" unpacked with wrong size!
  588. fi
  589. # end of 'Mrd.1'
  590. fi
  591. if test -f 'Mread.1' -a "${1}" != "-c" ; then 
  592.   echo shar: Will not clobber existing file \"'Mread.1'\"
  593. else
  594. echo shar: Extracting \"'Mread.1'\" \(1327 characters\)
  595. sed "s/^X//" >'Mread.1' <<'END_OF_FILE'
  596. X.TH MREAD 1 local
  597. X.SH NAME
  598. Xmread \- low level read (copy) a MSDOS file to Unix
  599. X.SH SYNOPSIS
  600. X.B mread
  601. X[
  602. X.B -tnm
  603. X] msdosfile unixfile
  604. X.PP
  605. X.B mread
  606. X[
  607. X.B -tnm
  608. X] msdosfile [ msdosfiles... ] unixdirectory
  609. X.SH DESCRIPTION
  610. XIn the first form,
  611. X.I mread
  612. Xcopies the specified MSDOS file to the named Unix file.  The second form
  613. Xof the command copies multiple MSDOS files to the named Unix directory.
  614. XMSDOS sub directories are supported with either the '/' or '\e\'
  615. Xseparator.  The use of the '\e\' separator or wildcards will require the
  616. Xnames to be enclosed in quotes to protect them from the shell.
  617. X.PP
  618. X.I Mread
  619. Xwill allow the following command line options:
  620. X.TP
  621. X.B t
  622. XText file transfer.
  623. X.I Mread
  624. Xwill translate incoming carriage return/line feeds to line feeds.
  625. X.TP
  626. X.B n
  627. XNo warning.
  628. X.I Mread
  629. Xwill not warn the user when overwriting an existing file.
  630. X.TP
  631. X.B m
  632. XPreserve the file modification times.
  633. X.PP
  634. XIf the target file already exists, and the
  635. X.I -n
  636. Xoption is not in effect,
  637. X.I mread
  638. Xasks whether or not to overwrite the file.
  639. X.PP
  640. XThe environmental variable MCWD may be used to establish a current
  641. Xworking directory (relative to the MSDOS diskette).
  642. X.SH SEE ALSO
  643. Xmcopy(1), mdir(1), mtype(1), mwrite(1)
  644. X.SH BUGS
  645. XWildcards are only applied to filenames, not to directory names.
  646. XUnlike MSDOS, the destination directory may not be omitted.
  647. END_OF_FILE
  648. if test 1327 -ne `wc -c <'Mread.1'`; then
  649.     echo shar: \"'Mread.1'\" unpacked with wrong size!
  650. fi
  651. # end of 'Mread.1'
  652. fi
  653. if test -f 'Mren.1' -a "${1}" != "-c" ; then 
  654.   echo shar: Will not clobber existing file \"'Mren.1'\"
  655. else
  656. echo shar: Extracting \"'Mren.1'\" \(1237 characters\)
  657. sed "s/^X//" >'Mren.1' <<'END_OF_FILE'
  658. X.TH MREN 1 local
  659. X.SH NAME
  660. Xmren \- rename an existing MSDOS file
  661. X.SH SYNOPSIS
  662. X.B mren
  663. X[
  664. X.B -v
  665. X] sourcefile targetfile
  666. X.SH DESCRIPTION
  667. X.I Mren
  668. Xrenames an existing file on a MSDOS formatted diskette.  Sub directories
  669. Xare supported with either the '/' or '\e\' separator.  The use of
  670. Xthe '\e\' separator or wildcards will require the names to be enclosed
  671. Xin quotes to protect them from the shell.
  672. X.PP
  673. X.I Mren
  674. Xwill allow the following command line option:
  675. X.TP
  676. X.B v
  677. XVerbose mode.  Display the new file name if the name supplied is
  678. Xinvalid.
  679. X.PP
  680. XReasonable care is taken to create a valid MSDOS filename.  If an invalid
  681. XMSDOS target name is specified,
  682. X.I mren
  683. Xwill change the name (and prompt the user to accept or reject the new name
  684. Xif the verbose mode is set).
  685. X.PP
  686. XThe path component of the target filename (if supplied) is ignored.  In
  687. Xother words, you may not use
  688. X.I mren
  689. Xto move a file from one sub directory to another.
  690. X.PP 
  691. X.I Mren
  692. Xmay also be used to rename directories.
  693. X.PP
  694. XThe environmental variable MCWD may be used to establish a current
  695. Xworking directory (relative to the MSDOS diskette).
  696. X.SH SEE ALSO
  697. Xmwrite(1)
  698. X.SH BUGS
  699. XWildcards are only applied to filenames, not to directory names.
  700. XMSDOS doesn't use ren to rename directories.
  701. END_OF_FILE
  702. if test 1237 -ne `wc -c <'Mren.1'`; then
  703.     echo shar: \"'Mren.1'\" unpacked with wrong size!
  704. fi
  705. # end of 'Mren.1'
  706. fi
  707. if test -f 'Mtype.1' -a "${1}" != "-c" ; then 
  708.   echo shar: Will not clobber existing file \"'Mtype.1'\"
  709. else
  710. echo shar: Extracting \"'Mtype.1'\" \(978 characters\)
  711. sed "s/^X//" >'Mtype.1' <<'END_OF_FILE'
  712. X.TH MTYPE 1 local
  713. X.SH NAME
  714. Xmtype \- display contents of a MSDOS file
  715. X.SH SYNOPSIS
  716. X.B mtype
  717. X[
  718. X.B -ts
  719. X] msdosfile [ msdosfiles... ]
  720. X.SH DESCRIPTION
  721. X.I Mtype
  722. Xdisplays the specified MSDOS file on the screen.  MSDOS sub directories
  723. Xare supported with either the '/' or '\e\' separator.  The use of 
  724. Xthe '\e\' separator or wildcards will require the names to be enclosed
  725. Xin quotes to protect them from the shell.
  726. X.PP
  727. X.I Mtype
  728. Xwill allow the following command line options:
  729. X.TP
  730. X.B t
  731. XText file viewing.
  732. X.I Mtype
  733. Xwill translate incoming carriage return/line feeds to line feeds.
  734. X.TP
  735. X.B s
  736. XStrip high bit.
  737. X.I Mtype
  738. Xwill strip the high bit from the data.  Useful for viewing Wordstar files.
  739. X.PP
  740. XThe environmental variable MCWD may be used to establish a current
  741. Xworking directory (relative to the MSDOS diskette).
  742. X.SH SEE ALSO
  743. Xmdir(1), mread(1)
  744. X.SH BUGS
  745. XAllows multiple arguments, which does not follow the MSDOS convention.
  746. XWildcards are only applied to filenames, not to directory names.
  747. END_OF_FILE
  748. if test 978 -ne `wc -c <'Mtype.1'`; then
  749.     echo shar: \"'Mtype.1'\" unpacked with wrong size!
  750. fi
  751. # end of 'Mtype.1'
  752. fi
  753. if test -f 'Mwrite.1' -a "${1}" != "-c" ; then 
  754.   echo shar: Will not clobber existing file \"'Mwrite.1'\"
  755. else
  756. echo shar: Extracting \"'Mwrite.1'\" \(1594 characters\)
  757. sed "s/^X//" >'Mwrite.1' <<'END_OF_FILE'
  758. X.TH MWRITE 1 local
  759. X.SH NAME
  760. Xmwrite \- low level write (copy) a Unix file to MSDOS
  761. X.SH SYNOPSIS
  762. X.B mwrite
  763. X[
  764. X.B -tnvm
  765. X] unixfile msdosfile
  766. X.PP
  767. X.B mwrite
  768. X[
  769. X.B -tnvm
  770. X] unixfile [ unixfiles... ] msdosdirectory
  771. X.SH DESCRIPTION
  772. XIn the first form,
  773. X.I mwrite
  774. Xcopies the specified Unix file to the named MSDOS file.  The second form
  775. Xof the command copies multiple Unix files to the named MSDOS directory.
  776. XMSDOS sub directories are are supported with either the '/' or '\e\'
  777. Xseparator.  The use of the '\e\' separator will require the names to be
  778. Xenclosed in quotes to protect them from the shell.
  779. X.PP
  780. X.I Mwrite
  781. Xwill allow the following command line options:
  782. X.TP
  783. X.B t
  784. XText file transfer.
  785. X.I Mwrite
  786. Xwill translate incoming line feeds to carriage return/line feeds.
  787. X.TP
  788. X.B n
  789. XNo warning.
  790. X.I Mwrite
  791. Xwill not warn the user when overwriting an existing file.
  792. X.TP
  793. X.B v
  794. XVerbose mode.  Display the new file name if the Unix file name requires
  795. Xconversion.
  796. X.TP
  797. X.B m
  798. XPreserve the file modification times.
  799. X.PP
  800. XIf the target file already exists, and the
  801. X.I -n
  802. Xoption is not in effect,
  803. X.I mwrite
  804. Xasks whether or not to overwrite the file.
  805. X.PP
  806. XReasonable care is taken to create a valid MSDOS filename.  If an
  807. Xinvalid name is specified,
  808. X.I mwrite
  809. Xwill change the name (and display the new name if the verbose mode is
  810. Xset).
  811. X.PP
  812. XThe environmental variable MCWD may be used to establish a current
  813. Xworking directory (relative to the MSDOS diskette).
  814. X.SH SEE ALSO
  815. Xmcopy(1), mdir(1), mread(1)
  816. X.SH BUGS
  817. XWildcards are only applied to filenames, not to directory names.
  818. XUnlike MSDOS, the destination directory may not be omitted.
  819. END_OF_FILE
  820. if test 1594 -ne `wc -c <'Mwrite.1'`; then
  821.     echo shar: \"'Mwrite.1'\" unpacked with wrong size!
  822. fi
  823. # end of 'Mwrite.1'
  824. fi
  825. if test -f 'bootblk.h' -a "${1}" != "-c" ; then 
  826.   echo shar: Will not clobber existing file \"'bootblk.h'\"
  827. else
  828. echo shar: Extracting \"'bootblk.h'\" \(625 characters\)
  829. sed "s/^X//" >'bootblk.h' <<'END_OF_FILE'
  830. X/*
  831. X * Just enough of a high/low density 3.5" DOS boot block
  832. X * to define the FS parameters,  should keep us out of Copyright
  833. X * trouble!  If someone wants DOS bootable filesystems,
  834. X * include the complete boot block for your machine,
  835. X * and make sure to create the "hidden" files in mkdfs.c
  836. X * (this is not easy!)
  837. X */
  838. Xstatic unsigned short hdboot[] = {
  839. X0xeb34,0x9020,0x2020,0x2020,0x2020,0x2000,0x0201,0x0100,
  840. X0x02e0,0x0040,0x0bf0,0x0900,0x1200,0x0200,0x0000,0x0000,
  841. X} ;
  842. X
  843. Xstatic unsigned short ldboot[] = {
  844. X0xeb34,0x9020,0x2020,0x2020,0x2020,0x2000,0x0202,0x0100,
  845. X0x0270,0x00a0,0x05f9,0x0300,0x0900,0x0200,0x0000,0x0000,
  846. X} ;
  847. END_OF_FILE
  848. if test 625 -ne `wc -c <'bootblk.h'`; then
  849.     echo shar: \"'bootblk.h'\" unpacked with wrong size!
  850. fi
  851. # end of 'bootblk.h'
  852. fi
  853. if test -f 'convdate.c' -a "${1}" != "-c" ; then 
  854.   echo shar: Will not clobber existing file \"'convdate.c'\"
  855. else
  856. echo shar: Extracting \"'convdate.c'\" \(2461 characters\)
  857. sed "s/^X//" >'convdate.c' <<'END_OF_FILE'
  858. X/*
  859. X * convdate(), convtime(), convstamp()
  860. X */
  861. X#include <stdio.h>
  862. X/*
  863. X * convert MSDOS directory datestamp to ASCII.
  864. X */
  865. X
  866. Xchar *
  867. Xconvdate(date_high, date_low)
  868. Xunsigned date_high, date_low;
  869. X{
  870. X/*
  871. X *        hi byte     |    low byte
  872. X *    |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
  873. X *      | | | | | | | | | | | | | | | | |
  874. X *      \   7 bits    /\4 bits/\ 5 bits /
  875. X *         year +80      month     day
  876. X */
  877. X    static char ans[9];
  878. X    unsigned char year, month_hi, month_low, day;
  879. X
  880. X    year = (date_high >> 1) + 80;
  881. X    month_hi = (date_high & 0x1) << 3;
  882. X    month_low = date_low >> 5;
  883. X    day = date_low & 0x1f;
  884. X    sprintf(ans, "%2d-%02d-%02d", month_hi+month_low, day, year);
  885. X    return(ans);
  886. X}
  887. X
  888. X/*
  889. X * Convert MSDOS directory timestamp to ASCII.
  890. X */
  891. X
  892. Xchar *
  893. Xconvtime(time_high, time_low)
  894. Xunsigned time_high, time_low;
  895. X{
  896. X/*
  897. X *        hi byte     |    low byte
  898. X *    |7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
  899. X *      | | | | | | | | | | | | | | | | |
  900. X *      \  5 bits /\  6 bits  /\ 5 bits /
  901. X *         hour      minutes     sec*2
  902. X */
  903. X    static char ans[7];
  904. X    char am_pm;
  905. X    unsigned char hour, min_hi, min_low;
  906. X
  907. X    hour = time_high >> 3;
  908. X    am_pm = (hour >= 12) ? 'p' : 'a';
  909. X    if (hour > 12)
  910. X        hour = hour -12;
  911. X    if (hour == 0)
  912. X        hour = 12;
  913. X    min_hi = (time_high & 0x7) << 3;
  914. X    min_low = time_low >> 5;
  915. X    sprintf(ans, "%2d:%02d%c", hour, min_hi+min_low, am_pm);
  916. X    return(ans);
  917. X}
  918. X
  919. X/*
  920. X * Convert a MSDOS time & date stamp to the Unix time() format
  921. X */
  922. X
  923. Xlong
  924. Xconvstamp(time_field, date_field)
  925. Xunsigned char *time_field, *date_field;
  926. X{
  927. X    extern long timezone;
  928. X    int year, mon, mday, hour, min, sec, old_leaps;
  929. X    long answer, sec_year, sec_mon, sec_mday, sec_hour, sec_min, sec_leap;
  930. X    static int month[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304,
  931. X    334};
  932. X                    /* disect the parts */
  933. X    year = (date_field[1] >> 1) + 1980;
  934. X    mon = (((date_field[1] & 0x1) << 3) + (date_field[0] >> 5));
  935. X    mday = date_field[0] & 0x1f;
  936. X    hour = time_field[1] >> 3;
  937. X    min = (((time_field[1] & 0x7) << 3) + (time_field[0] >> 5));
  938. X    sec = (time_field[0] & 0x1f) * 2;
  939. X                    /* how many previous leap years */
  940. X    old_leaps = (year -1972) / 4;
  941. X    sec_leap = old_leaps * 24 * 60 * 60;
  942. X                    /* back off 1 day if before 29 Feb */
  943. X    if (!(year % 4) && mon < 3)
  944. X        sec_leap -= 24 * 60 * 60;
  945. X    sec_year = (year - 1970) * 365 * 24 * 60 * 60;
  946. X    sec_mon = month[mon -1] * 24 * 60 * 60;
  947. X    sec_mday = mday * 24 * 60 * 60;
  948. X    sec_hour = hour * 60 * 60;
  949. X    sec_min = min * 60;
  950. X    
  951. X    answer = sec_leap + sec_year + sec_mon + sec_mday + sec_hour + sec_min + sec + timezone;
  952. X    return(answer);
  953. X}
  954. END_OF_FILE
  955. if test 2461 -ne `wc -c <'convdate.c'`; then
  956.     echo shar: \"'convdate.c'\" unpacked with wrong size!
  957. fi
  958. # end of 'convdate.c'
  959. fi
  960. if test -f 'devices.c' -a "${1}" != "-c" ; then 
  961.   echo shar: Will not clobber existing file \"'devices.c'\"
  962. else
  963. echo shar: Extracting \"'devices.c'\" \(1936 characters\)
  964. sed "s/^X//" >'devices.c' <<'END_OF_FILE'
  965. X#ifndef lint
  966. Xstatic char RCSid[]="$Header: /auto/n/melon/b/viktor/src/nmt/RCS/devices.c,v 1.3 90/03/16 02:52:20 viktor Exp Locker: viktor $" ;
  967. X#endif
  968. X/*
  969. X *  Device switch for "mtools",  each driver defines a device name,
  970. X *  an initialization function, and extra "open" flags,  typically to allow
  971. X *  NDELAY for opening floppies with non-default sectoring,  which otherwise
  972. X *  yield EIO
  973. X *
  974. X * $Log:    devices.c,v $
  975. X * Revision 1.3  90/03/16  02:52:20  viktor
  976. X * *** empty log message ***
  977. X * 
  978. X * Revision 1.2  90/03/08  20:29:59  viktor
  979. X * Added unixpc support.
  980. X * 
  981. X */
  982. X#include "devices.h"
  983. X
  984. X#ifdef sun
  985. X#include <fcntl.h>
  986. X#endif
  987. X
  988. X#ifdef unixpc
  989. X#include <sys/gdioctl.h>
  990. X#include <fcntl.h>
  991. Xint unixpc_fd_init() ;
  992. X#endif
  993. X
  994. Xstruct device fd_devices[] = {
  995. X
  996. X#ifdef sun
  997. X  {"/dev/rfd0c", (int (*)())0, 0 },
  998. X#endif
  999. X#ifdef unixpc
  1000. X  {"/dev/rfp020", unixpc_fd_init, O_NDELAY},
  1001. X#endif
  1002. X  {(char*)0, (int (*)())0, 0}
  1003. X} ;
  1004. X
  1005. X#ifdef unixpc
  1006. Xunixpc_fd_init(fd,ncyl,ntrack,nsect)
  1007. X     int fd,ncyl,ntrack,nsect;
  1008. X{
  1009. X  struct gdctl gdbuf;
  1010. X
  1011. X  if( ! ncyl && ! nsect && ! ntrack ) {
  1012. X    ncyl = 40;
  1013. X    /* Default to 1 track, will reset to 2 later if needed */
  1014. X    ntrack = 1;
  1015. X    nsect = 8;
  1016. X  }
  1017. X
  1018. X  if ( ioctl(fd,GDGETA,&gdbuf) == -1 ) {
  1019. X    perror("init: ioctl: GDGETA") ;
  1020. X    dismount(fd) ;
  1021. X  }
  1022. X
  1023. X  if (ncyl) gdbuf.params.cyls = ncyl;
  1024. X  if (ntrack) gdbuf.params.heads = ntrack;
  1025. X  if (nsect) gdbuf.params.psectrk = nsect;
  1026. X
  1027. X  gdbuf.params.pseccyl = gdbuf.params.psectrk * gdbuf.params.heads ;
  1028. X  gdbuf.params.flags = 1;        /* disk type flag */
  1029. X  gdbuf.params.step = 0;        /* step rate for controller */
  1030. X  gdbuf.params.sectorsz = 512;        /* sector size */
  1031. X
  1032. X  if (ioctl(fd, GDSETA, &gdbuf) < 0) {
  1033. X    perror("init: ioctl: GDSETA");
  1034. X    dismount(fd);
  1035. X  }
  1036. X}
  1037. X
  1038. X/*
  1039. X * Dismount the floppy.  Useful only if one of the above ioctls fail
  1040. X * and leaves the drive light turned on.
  1041. X */
  1042. Xvoid
  1043. Xdismount(fd)
  1044. X{
  1045. X    struct gdctl gdbuf;
  1046. X    void exit();
  1047. X
  1048. X    ioctl(fd, GDDISMNT, &gdbuf);
  1049. X    exit(1);
  1050. X}
  1051. X#endif
  1052. END_OF_FILE
  1053. if test 1936 -ne `wc -c <'devices.c'`; then
  1054.     echo shar: \"'devices.c'\" unpacked with wrong size!
  1055. fi
  1056. # end of 'devices.c'
  1057. fi
  1058. if test -f 'devices.h' -a "${1}" != "-c" ; then 
  1059.   echo shar: Will not clobber existing file \"'devices.h'\"
  1060. else
  1061. echo shar: Extracting \"'devices.h'\" \(76 characters\)
  1062. sed "s/^X//" >'devices.h' <<'END_OF_FILE'
  1063. Xstruct device {
  1064. X  char *drv_dev;
  1065. X  int (*drv_ifunc)() ;
  1066. X  int drv_mode;
  1067. X} ;
  1068. END_OF_FILE
  1069. if test 76 -ne `wc -c <'devices.h'`; then
  1070.     echo shar: \"'devices.h'\" unpacked with wrong size!
  1071. fi
  1072. # end of 'devices.h'
  1073. fi
  1074. if test -f 'fixname.c' -a "${1}" != "-c" ; then 
  1075.   echo shar: Will not clobber existing file \"'fixname.c'\"
  1076. else
  1077. echo shar: Extracting \"'fixname.c'\" \(1871 characters\)
  1078. sed "s/^X//" >'fixname.c' <<'END_OF_FILE'
  1079. X/*
  1080. X * Convert a Unix filename to a legal MSDOS name.  Returns a pointer to
  1081. X * the 'fixed' name.  Will truncate file and extension names, will
  1082. X * substitute the letter 'X' for any illegal character in the name.
  1083. X */
  1084. X
  1085. X#include <stdio.h>
  1086. X#include <ctype.h>
  1087. X#include "msdos.h"
  1088. X
  1089. Xchar *
  1090. Xfixname(filename, verbose)
  1091. Xchar *filename;
  1092. Xint verbose;
  1093. X{
  1094. X    static char *dev[8] = {"CON", "AUX", "COM1", "LPT1", "PRN", "LPT2",
  1095. X    "LPT3", "NUL"};
  1096. X    char *s, *ans, *name, *ext, *strcpy(), *strpbrk(), *strrchr();
  1097. X    char buf[MAX_PATH], *malloc();
  1098. X    int dot, modified;
  1099. X    register int i;
  1100. X
  1101. X    strcpy(buf, filename);
  1102. X    name = buf;
  1103. X                    /* zap the leading path */
  1104. X    if (s = strrchr(name, '/'))
  1105. X        name = s+1;
  1106. X    if (s = strrchr(name, '\\'))
  1107. X        name = s+1;
  1108. X
  1109. X    ext = "";
  1110. X    dot = 0;
  1111. X    for (i=strlen(buf)-1; i>=0; i--) {
  1112. X        if (buf[i] == '.' && !dot) {
  1113. X            dot = 1;
  1114. X            buf[i] = '\0';
  1115. X            ext = &buf[i+1];
  1116. X        }
  1117. X        if (islower(buf[i]))
  1118. X            buf[i] = toupper(buf[i]);
  1119. X    }
  1120. X    if (*name == '\0') {
  1121. X        name = "X";
  1122. X        if (verbose)
  1123. X            printf("\"%s\" Null name component, using \"%s.%s\"\n", filename, name, ext);
  1124. X    }
  1125. X    for (i=0; i<8; i++) {
  1126. X        if (!strcmp(name, dev[i])) {
  1127. X            *name = 'X';
  1128. X            if (verbose)
  1129. X                printf("\"%s\" Is a device name, using \"%s.%s\"\n", filename, name, ext);
  1130. X        }
  1131. X    }
  1132. X    if (strlen(name) > 8) {
  1133. X        *(name+8) = '\0';
  1134. X        if (verbose)
  1135. X            printf("\"%s\" Name too long, using, \"%s.%s\"\n", filename, name, ext);
  1136. X    }
  1137. X    if (strlen(ext) > 3) {
  1138. X        *(ext+3) = '\0';
  1139. X        if (verbose)
  1140. X            printf("\"%s\" Extension too long, using \"%s.%s\"\n", filename, name, ext);
  1141. X    }
  1142. X    modified = 0;
  1143. X    while (s = strpbrk(name, "^+=/[]:',?*\\<>|\". ")) {
  1144. X        modified++;
  1145. X        *s = 'X';
  1146. X    }
  1147. X    while (s = strpbrk(ext, "^+=/[]:',?*\\<>|\". ")) {
  1148. X        modified++;
  1149. X        *s = 'X';
  1150. X    }
  1151. X    if (modified && verbose)
  1152. X        printf("\"%s\" Contains illegal character(s), using \"%s.%s\"\n", filename, name, ext);
  1153. X
  1154. X    ans = malloc(12);
  1155. X    sprintf(ans, "%-8.8s%-3.3s", name, ext);
  1156. X    return(ans);
  1157. X}
  1158. END_OF_FILE
  1159. if test 1871 -ne `wc -c <'fixname.c'`; then
  1160.     echo shar: \"'fixname.c'\" unpacked with wrong size!
  1161. fi
  1162. # end of 'fixname.c'
  1163. fi
  1164. if test -f 'getfat.c' -a "${1}" != "-c" ; then 
  1165.   echo shar: Will not clobber existing file \"'getfat.c'\"
  1166. else
  1167. echo shar: Extracting \"'getfat.c'\" \(1365 characters\)
  1168. sed "s/^X//" >'getfat.c' <<'END_OF_FILE'
  1169. X/*
  1170. X * Get and decode a FAT (file allocation table) entry.  The FAT entries
  1171. X * are 1.5 bytes long and switch nibbles (.5 byte) according to whether
  1172. X * or not the entry starts on a byte boundary.  Returns the cluster 
  1173. X * number on success or -1 on failure.
  1174. X */
  1175. X
  1176. X#include "msdos.h"
  1177. X
  1178. Xextern int fat_len;
  1179. Xextern unsigned char *fatbuf;
  1180. X
  1181. Xint
  1182. Xgetfat(num)
  1183. Xint num;
  1184. X{
  1185. X/*
  1186. X *    |    byte n     |   byte n+1    |   byte n+2    |
  1187. X *    |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
  1188. X *    | | | | | | | | | | | | | | | | | | | | | | | | |
  1189. X *    |  n.0  |  n.5  | n+1.0 | n+1.5 | n+2.0 | n+2.5 |
  1190. X *        \_____  \____   \______/________/_____   /
  1191. X *          ____\______\________/   _____/  ____\_/
  1192. X *         /     \      \          /       /     \
  1193. X *    | n+1.5 |  n.0  |  n.5  | n+2.0 | n+2.5 | n+1.0 |
  1194. X *    |      FAT entry k      |    FAT entry k+1      |
  1195. X */
  1196. X    unsigned int fat_hi, fat_low, byte_1, byte_2;
  1197. X    int start, fat;
  1198. X                    /* which bytes contain the entry */
  1199. X    start = num * 3 / 2;
  1200. X    if (start < 0 || start+1 > (fat_len * MSECSIZ))
  1201. X        return(-1);
  1202. X
  1203. X    byte_1 = *(fatbuf + start);
  1204. X    byte_2 = *(fatbuf + start + 1);
  1205. X                    /* (odd) not on byte boundary */
  1206. X    if (num % 2) {
  1207. X        fat_hi = (byte_2 & 0xff) << 4;
  1208. X        fat_low  = (byte_1 & 0xf0) >> 4;
  1209. X    }
  1210. X                    /* (even) on byte boundary */
  1211. X    else {
  1212. X        fat_hi = (byte_2 & 0xf) << 8;
  1213. X        fat_low  = byte_1 & 0xff;
  1214. X    }
  1215. X    fat = (fat_hi + fat_low) & 0xfff;
  1216. X    return(fat);
  1217. X}
  1218. END_OF_FILE
  1219. if test 1365 -ne `wc -c <'getfat.c'`; then
  1220.     echo shar: \"'getfat.c'\" unpacked with wrong size!
  1221. fi
  1222. # end of 'getfat.c'
  1223. fi
  1224. if test -f 'isdir.c' -a "${1}" != "-c" ; then 
  1225.   echo shar: Will not clobber existing file \"'isdir.c'\"
  1226. else
  1227. echo shar: Extracting \"'isdir.c'\" \(1001 characters\)
  1228. sed "s/^X//" >'isdir.c' <<'END_OF_FILE'
  1229. X/*
  1230. X * Test to see if a filename is a directory.  Subdir() has to be
  1231. X * run first...  Returns 1 if true.
  1232. X */
  1233. X
  1234. X#include <stdio.h>
  1235. X#include "msdos.h"
  1236. X
  1237. Xextern int dir_entries;
  1238. X
  1239. Xint
  1240. Xisdir(path)
  1241. Xchar *path;
  1242. X{
  1243. X    register int entry;
  1244. X    char *newname, *unixname(), *strncpy(), name[9], ext[4];
  1245. X    struct directory *dir, *search();
  1246. X    void free();
  1247. X                    /* no path */
  1248. X    if (*path == '\0')
  1249. X        return(0);
  1250. X
  1251. X    for (entry=0; entry<dir_entries; entry++) {
  1252. X        dir = search(entry);
  1253. X                    /* if empty */
  1254. X        if (dir->name[0] == 0x0)
  1255. X            break;
  1256. X                    /* if erased */
  1257. X        if (dir->name[0] == 0xe5)
  1258. X            continue;
  1259. X                    /* skip if not a directory */
  1260. X        if (!(dir->attr & 0x10))
  1261. X            continue;
  1262. X
  1263. X        strncpy(name, (char *) dir->name, 8);
  1264. X        strncpy(ext, (char *) dir->ext, 3);
  1265. X        name[8] = '\0';
  1266. X        ext[3] = '\0';
  1267. X
  1268. X        newname = unixname(name, ext);
  1269. X        if (!strcmp(newname, path)) {
  1270. X            free(newname);
  1271. X            return(1);
  1272. X        }
  1273. X        free(newname);
  1274. X    }
  1275. X                    /* if "." or ".." fails, then root */
  1276. X    if (!strcmp(path, ".") || !strcmp(path, ".."))
  1277. X        return(1);
  1278. X
  1279. X    return(0);
  1280. X}
  1281. END_OF_FILE
  1282. if test 1001 -ne `wc -c <'isdir.c'`; then
  1283.     echo shar: \"'isdir.c'\" unpacked with wrong size!
  1284. fi
  1285. # end of 'isdir.c'
  1286. fi
  1287. if test -f 'match.c' -a "${1}" != "-c" ; then 
  1288.   echo shar: Will not clobber existing file \"'match.c'\"
  1289. else
  1290. echo shar: Extracting \"'match.c'\" \(1894 characters\)
  1291. sed "s/^X//" >'match.c' <<'END_OF_FILE'
  1292. X/*
  1293. X * Do shell-style pattern matching for '?', '\', '[..]', and '*' wildcards.
  1294. X * Not idiot proof!  Returns 1 if match, 0 if not.
  1295. X *
  1296. X * Ideas for this routine were taken from a program by Rich Salz, mirror!rs
  1297. X */
  1298. X
  1299. X#include <stdio.h>
  1300. X
  1301. Xint
  1302. Xmatch(s, p)
  1303. Xchar *s;                /* string to match */
  1304. Xchar *p;                /* pattern */
  1305. X{
  1306. X    int matched, reverse;
  1307. X    char first, last;
  1308. X
  1309. X    for ( ; *p != '\0'; s++, p++) {
  1310. X        switch (*p) {
  1311. X                    /* Literal match with next character */
  1312. X        case '\\':
  1313. X            p++;
  1314. X        default:
  1315. X            if (*s != *p)
  1316. X                return(0);
  1317. X            break;
  1318. X                    /* match any one character */
  1319. X        case '?':
  1320. X            if (*s == '\0')
  1321. X                return(0);
  1322. X            break;
  1323. X                    /* match everything */
  1324. X        case '*':
  1325. X                    /* if last char in pattern */
  1326. X            if (*++p == '\0')
  1327. X                return(1);
  1328. X                    /* search for next char in pattern */
  1329. X            matched = 0;
  1330. X            while (*s != '\0') {
  1331. X                if (*s == *p) {
  1332. X                    matched = 1;
  1333. X                    if (!strcmp(s+1,p+1))
  1334. X                        break;
  1335. X                }
  1336. X                s++;
  1337. X            }
  1338. X            if (!matched)
  1339. X                return(0);
  1340. X            s--;
  1341. X            p--;
  1342. X            break;
  1343. X                    /* match range of characters */
  1344. X        case '[':
  1345. X            first = '\0';
  1346. X            matched = 0;
  1347. X            reverse = 0;
  1348. X            while (*++p != ']') {
  1349. X                if (*p == '^') {
  1350. X                    reverse = 1;
  1351. X                    p++;
  1352. X                }
  1353. X                first = *p;
  1354. X                if (first == ']' || first == '\0') {
  1355. X                    fprintf(stderr, "match: Malformed regular expression\n");
  1356. X                    return(0);
  1357. X                }
  1358. X                    /* if 2nd char is '-' */
  1359. X                if (*(p+1) == '-') {
  1360. X                    p++;
  1361. X                    /* set last to 3rd char ... */
  1362. X                    last = *++p;
  1363. X                    if (last == ']' || last == '\0') {
  1364. X                        fprintf(stderr, "match: Malformed regular expression\n");
  1365. X                        return(0);
  1366. X                    }
  1367. X                    /* test the range of values */
  1368. X                    if (*s>=first && *s<=last) {
  1369. X                        matched = 1;
  1370. X                        p++;
  1371. X                        break;
  1372. X                    }
  1373. X                    return(0);
  1374. X                }
  1375. X                if (*s == *p)
  1376. X                    matched = 1;
  1377. X            }
  1378. X            if (matched && reverse)
  1379. X                return(0);
  1380. X            if (!matched)
  1381. X                return(0);
  1382. X            break;
  1383. X        }
  1384. X    }
  1385. X                    /* string ended prematurely ? */
  1386. X    if (*s != '\0')
  1387. X        return(0);
  1388. X    else
  1389. X        return(1);
  1390. X}
  1391. END_OF_FILE
  1392. if test 1894 -ne `wc -c <'match.c'`; then
  1393.     echo shar: \"'match.c'\" unpacked with wrong size!
  1394. fi
  1395. # end of 'match.c'
  1396. fi
  1397. if test -f 'mcopy.c' -a "${1}" != "-c" ; then 
  1398.   echo shar: Will not clobber existing file \"'mcopy.c'\"
  1399. else
  1400. echo shar: Extracting \"'mcopy.c'\" \(2912 characters\)
  1401. sed "s/^X//" >'mcopy.c' <<'END_OF_FILE'
  1402. X/*
  1403. X * A front-end to the mread/mwrite commands.
  1404. X *
  1405. X * Emmet P. Gray            US Army, HQ III Corps & Fort Hood
  1406. X * ...!uunet!uiucuxc!fthood!egray    Attn: AFZF-DE-ENV
  1407. X *                     Directorate of Engineering & Housing
  1408. X *                     Environmental Management Office
  1409. X *                     Fort Hood, TX 76544-5057
  1410. X */
  1411. X
  1412. X#include <stdio.h>
  1413. X
  1414. X#define NONE    0
  1415. X#define MREAD    1
  1416. X#define MWRITE    2
  1417. X
  1418. Xmain(argc, argv)
  1419. Xint argc;
  1420. Xchar *argv[];
  1421. X{
  1422. X    extern int optind;
  1423. X    extern char *optarg;
  1424. X    int i, oops, msdos_args, unix_args, destination;
  1425. X    char **nargv, *strcpy();
  1426. X    void exit();
  1427. X                    /* get command line options */
  1428. X    msdos_args = 0;
  1429. X    unix_args = 0;
  1430. X    oops = 0;
  1431. X    while ((i = getopt(argc, argv, "tnvm")) != EOF) {
  1432. X        switch(i) {
  1433. X            case 't':
  1434. X            case 'n':
  1435. X            case 'v':
  1436. X            case 'm':
  1437. X                break;
  1438. X            default:
  1439. X                oops = 1;
  1440. X                break;
  1441. X        }
  1442. X    }
  1443. X
  1444. X    if (oops || (argc - optind) < 2) {
  1445. X        fprintf(stderr, "Usage: mcopy [-tnvm] a:msdosfile unixfile\n");
  1446. X        fprintf(stderr, "       mcopy [-tnvm] a:msdosfile [a:msdosfiles...] unixdirectory\n");
  1447. X        fprintf(stderr, "       mcopy [-tnm] unixfile a:msdosfile\n");
  1448. X        fprintf(stderr, "       mcopy [-tnm] unixfile [unixfiles...] a:msdosdirectory\n");
  1449. X        exit(1);
  1450. X    }
  1451. X                    /* what is the destination drive? */
  1452. X    destination = NONE;
  1453. X                    /* first file */
  1454. X    if (argv[optind][1] == ':') {
  1455. X        if (argv[optind][0] == 'a' || argv[optind][0] == 'A')
  1456. X            destination = MREAD;
  1457. X    }
  1458. X                    /* last file */
  1459. X    if (destination == NONE && argv[argc-1][1] == ':') {
  1460. X        if (argv[argc-1][0] == 'a' || argv[argc-1][0] == 'A')
  1461. X            destination = MWRITE;
  1462. X    }
  1463. X    if (destination == NONE) {
  1464. X        fprintf(stderr, "mcopy: no 'a:' designation specified\n");
  1465. X        exit(1);
  1466. X    }
  1467. X                    /* strip out the fake "drive code" */
  1468. X    for (i=optind; i<argc; i++) {
  1469. X        if (argv[i][1] == ':') {
  1470. X            switch(argv[i][0]) {
  1471. X                case 'a':
  1472. X                case 'A':
  1473. X                    if (argv[i][2] == '\0')
  1474. X                        strcpy(argv[i], ".");
  1475. X                    else
  1476. X                        strcpy(argv[i], &argv[i][2]);
  1477. X                    msdos_args++;
  1478. X                    break;
  1479. X                case 'c':
  1480. X                case 'C':
  1481. X                    fprintf(stderr, "mcopy: 'c:' is not used to designate Unix files\n");
  1482. X                    exit(1);
  1483. X                default:
  1484. X                    fprintf(stderr, "mcopy: unknown drive '%c:'\n", argv[i][0]);
  1485. X                    exit(1);
  1486. X            }
  1487. X            continue;
  1488. X        }
  1489. X                    /* if no drive code, its a unix file */
  1490. X        unix_args++;
  1491. X    }
  1492. X                    /* sanity checking */
  1493. X    if (!msdos_args || !unix_args) {
  1494. X        fprintf(stderr, "mcopy: unresloved destination\n");
  1495. X        exit(1);
  1496. X    }
  1497. X    if ((destination == MWRITE && msdos_args > 1) || (destination == MREAD && unix_args > 1)) {
  1498. X        fprintf(stderr, "mcopy: duplicate destination files\n");
  1499. X        exit(1);
  1500. X    }
  1501. X    /*
  1502. X     * Copy the *argv[] array in case your Unix doesn't end the array
  1503. X     * with a null when it passes it to main()
  1504. X     */
  1505. X    nargv = (char **) malloc((argc+1) * sizeof(*argv));
  1506. X    nargv[argc] = NULL;
  1507. X    for(;--argc>=0;)
  1508. X        nargv[argc] = argv[argc];
  1509. X
  1510. X    if (destination == MWRITE) {
  1511. X        nargv[0] = "mwrite";
  1512. X        execvp("mwrite", nargv);
  1513. X        perror("execvp: mwrite") ;
  1514. X    }
  1515. X    else {
  1516. X        nargv[0] = "mread";
  1517. X        execvp("mread", nargv);
  1518. X        perror("execvp: mmread") ;
  1519. X    }
  1520. X}
  1521. END_OF_FILE
  1522. if test 2912 -ne `wc -c <'mcopy.c'`; then
  1523.     echo shar: \"'mcopy.c'\" unpacked with wrong size!
  1524. fi
  1525. # end of 'mcopy.c'
  1526. fi
  1527. if test -f 'mdel.c' -a "${1}" != "-c" ; then 
  1528.   echo shar: Will not clobber existing file \"'mdel.c'\"
  1529. else
  1530. echo shar: Extracting \"'mdel.c'\" \(2881 characters\)
  1531. sed "s/^X//" >'mdel.c' <<'END_OF_FILE'
  1532. X/*
  1533. X * Delete a MSDOS file
  1534. X *
  1535. X * Emmet P. Gray            US Army, HQ III Corps & Fort Hood
  1536. X * ...!uunet!uiucuxc!fthood!egray    Attn: AFZF-DE-ENV
  1537. X *                     Directorate of Engineering & Housing
  1538. X *                     Environmental Management Office
  1539. X *                     Fort Hood, TX 76544-5057
  1540. X */
  1541. X
  1542. X#include <stdio.h>
  1543. X#include "msdos.h"
  1544. X
  1545. Xint fd;                /* the file descriptor for the floppy */
  1546. Xint dir_start;            /* starting sector for directory */
  1547. Xint dir_len;            /* length of directory (in sectors) */
  1548. Xint dir_entries;        /* number of directory entries */
  1549. Xint dir_chain[25];        /* chain of sectors in directory */
  1550. Xint clus_size;            /* cluster size (in sectors) */
  1551. Xint fat_len;            /* length of FAT table (in sectors) */
  1552. Xint num_clus;            /* number of available clusters */
  1553. Xunsigned char *fatbuf;        /* the File Allocation Table */
  1554. Xchar *mcwd;            /* the Current Working Directory */
  1555. X
  1556. Xmain(argc, argv)
  1557. Xint argc;
  1558. Xchar *argv[];
  1559. X{
  1560. X    int i, ismatch, entry, start, nogo, verbose, fargn;
  1561. X    char *filename, *newfile, text[4], tname[9], *getname(), *unixname();
  1562. X    char *strncpy(), *getpath(), *pathname, ans[10];
  1563. X    void exit(), zapit(), writefat(), writedir(), free();
  1564. X    struct directory *dir, *search();
  1565. X
  1566. X    if (init(2)) {
  1567. X        fprintf(stderr, "mdel: Cannot initialize diskette\n");
  1568. X        exit(1);
  1569. X    }
  1570. X
  1571. X    if (argc < 2) {
  1572. X        fprintf(stderr, "Usage: mdel [-v] msdosfile [msdosfiles...]\n");
  1573. X        exit(1);
  1574. X    }
  1575. X    if (!strcmp(argv[1], "-v")) {
  1576. X        verbose = 1;
  1577. X        fargn = 2;
  1578. X    }
  1579. X    else {
  1580. X        verbose = 0;
  1581. X        fargn = 1;
  1582. X    }
  1583. X    for (i=fargn; i<argc; i++) {
  1584. X        filename = getname(argv[i]);
  1585. X        pathname = getpath(argv[i]);
  1586. X        if (subdir(pathname)) {
  1587. X            free(filename);
  1588. X            free(pathname);
  1589. X            continue;
  1590. X        }
  1591. X        nogo = 0;
  1592. X        ismatch = 0;
  1593. X        for (entry=0; entry<dir_entries; entry++) {
  1594. X            dir = search(entry);
  1595. X                    /* if empty */
  1596. X            if (dir->name[0] == 0x0)
  1597. X                break;
  1598. X                    /* if erased */
  1599. X            if (dir->name[0] == 0xe5)
  1600. X                continue;
  1601. X                    /* if dir or volume lable */
  1602. X            if ((dir->attr & 0x10) || (dir->attr & 0x08))
  1603. X                continue;
  1604. X
  1605. X            strncpy(tname, (char *) dir->name, 8);
  1606. X            strncpy(text, (char *) dir->ext, 3);
  1607. X            tname[8] = '\0';
  1608. X            text[3] = '\0';
  1609. X
  1610. X            newfile = unixname(tname, text);
  1611. X                    /* see it if matches the pattern */
  1612. X            if (match(newfile, filename)) {
  1613. X                if (verbose)
  1614. X                    printf("Removing %s\n", newfile);
  1615. X                ismatch = 1;
  1616. X                if (dir->attr & 0x01) {
  1617. X                    while (!nogo) {
  1618. X                        printf("mdel: \"%s\" is read only, erase anyway (y/n) ? ", newfile);
  1619. X                        gets(ans);
  1620. X                        if (ans[0] == 'y' || ans[0] == 'Y')
  1621. X                            break;
  1622. X                        if (ans[0] == 'n' || ans[0] == 'N')
  1623. X                            nogo = 1;
  1624. X                    }
  1625. X                    if (nogo) {
  1626. X                        free(newfile);
  1627. X                        continue;
  1628. X                    }
  1629. X                }
  1630. X                start = dir->start[1]*0x100 + dir->start[0];
  1631. X                zapit(start);
  1632. X                dir->name[0] = 0xe5;
  1633. X                writedir(entry, dir);
  1634. X            }
  1635. X            free(newfile);
  1636. X        }
  1637. X        if (!ismatch)
  1638. X            fprintf(stderr, "mdel: File \"%s\" not found\n", filename);
  1639. X        free(filename);
  1640. X        free(pathname);
  1641. X    }
  1642. X                    /* update the FAT sectors */
  1643. X    writefat();
  1644. X    close(fd);
  1645. X    exit(0);
  1646. X}
  1647. END_OF_FILE
  1648. if test 2881 -ne `wc -c <'mdel.c'`; then
  1649.     echo shar: \"'mdel.c'\" unpacked with wrong size!
  1650. fi
  1651. # end of 'mdel.c'
  1652. fi
  1653. if test -f 'mkentry.c' -a "${1}" != "-c" ; then 
  1654.   echo shar: Will not clobber existing file \"'mkentry.c'\"
  1655. else
  1656. echo shar: Extracting \"'mkentry.c'\" \(2539 characters\)
  1657. sed "s/^X//" >'mkentry.c' <<'END_OF_FILE'
  1658. X/*
  1659. X * mk_entry(), grow()
  1660. X */
  1661. X
  1662. X#include <stdio.h>
  1663. X#include <time.h>
  1664. X#include "msdos.h"
  1665. X
  1666. Xextern int fd, dir_start, dir_len, clus_size, dir_entries;
  1667. Xextern int dir_chain[25];
  1668. X
  1669. X/*
  1670. X * Make a directory entry.  Builds a directory entry based on the
  1671. X * name, attribute, starting cluster number, and size.  Returns a pointer
  1672. X * to the static directory structure.
  1673. X */
  1674. X
  1675. Xstruct directory *
  1676. Xmk_entry(filename, attr, fat, size, date)
  1677. Xchar *filename;
  1678. Xunsigned char attr;
  1679. Xint fat;
  1680. Xlong size, date;
  1681. X{
  1682. X    int i;
  1683. X    char *strncpy();
  1684. X    static struct directory ndir;
  1685. X    struct tm *now, *localtime();
  1686. X    unsigned char hour, min_hi, min_low, sec;
  1687. X    unsigned char year, month_hi, month_low, day;
  1688. X
  1689. X    now = localtime(&date);
  1690. X    strncpy((char *) ndir.name, filename, 8);
  1691. X    strncpy((char *) ndir.ext, filename+8, 3);
  1692. X    ndir.attr = attr;
  1693. X    for (i=0; i<10; i++)
  1694. X        ndir.reserved[i] = '\0';
  1695. X    hour = now->tm_hour << 3;
  1696. X    min_hi = now->tm_min >> 3;
  1697. X    min_low = now->tm_min << 5;
  1698. X    sec = now->tm_sec / 2;
  1699. X    ndir.time[1] = hour + min_hi;
  1700. X    ndir.time[0] = min_low + sec;
  1701. X    year = (now->tm_year - 80) << 1;
  1702. X    month_hi = (now->tm_mon+1) >> 3;
  1703. X    month_low = (now->tm_mon+1) << 5;
  1704. X    day = now->tm_mday;
  1705. X    ndir.date[1] = year + month_hi;
  1706. X    ndir.date[0] = month_low + day;
  1707. X    ndir.start[1] = fat / 0x100;
  1708. X    ndir.start[0] = fat % 0x100;
  1709. X    ndir.size[3] = 0;        /* can't be THAT large */
  1710. X    ndir.size[2] = size / 0x10000L;
  1711. X    ndir.size[1] = (size % 0x10000L) / 0x100;
  1712. X    ndir.size[0] = (size % 0x10000L) % 0x100;
  1713. X    return(&ndir);
  1714. X}
  1715. X
  1716. X/*
  1717. X * Make a subdirectory grow in length.  Only subdirectories (not root) 
  1718. X * may grow.  Returns a 0 on success or 1 on failure (disk full).
  1719. X */
  1720. X
  1721. Xint
  1722. Xgrow(fat)
  1723. Xint fat;
  1724. X{
  1725. X    int i, next, last, num, sector, buflen;
  1726. X    unsigned char tbuf[CLSTRBUF];
  1727. X    void perror(), exit(), move();
  1728. X
  1729. X    last = nextfat(0);
  1730. X    if (last == -1)
  1731. X        return(1);
  1732. X
  1733. X    while (1) {
  1734. X        next = getfat(fat);
  1735. X        if (next == -1) {
  1736. X            fprintf(stderr, "grow: FAT problem\n");
  1737. X            exit(1);
  1738. X        }
  1739. X                    /* end of cluster chain */
  1740. X        if (next >= 0xff8)
  1741. X            break;
  1742. X        fat = next;
  1743. X    }
  1744. X                    /* mark the end of the chain */
  1745. X    putfat(fat, (unsigned int) last);
  1746. X    putfat(last, 0xfff);
  1747. X                    /* zero the buffer */
  1748. X    buflen = clus_size * MSECSIZ;
  1749. X    for (i=0; i<buflen; i++)
  1750. X        tbuf[i] = '\0';
  1751. X
  1752. X                    /* write the cluster */
  1753. X    sector = (last - 2) * clus_size + dir_start + dir_len;
  1754. X    move(sector);
  1755. X    if (write(fd, (char *) tbuf, buflen) != buflen) {
  1756. X        perror("grow: write");
  1757. X        exit(1);
  1758. X    }
  1759. X                    /* fix up the globals.... */
  1760. X    num = dir_entries / 16;
  1761. X    dir_entries += clus_size * 16;
  1762. X    dir_chain[num] = sector;
  1763. X    if (clus_size == 2)
  1764. X        dir_chain[num+1] = sector +1;
  1765. X    return(0);
  1766. X}
  1767. END_OF_FILE
  1768. if test 2539 -ne `wc -c <'mkentry.c'`; then
  1769.     echo shar: \"'mkentry.c'\" unpacked with wrong size!
  1770. fi
  1771. # end of 'mkentry.c'
  1772. fi
  1773. if test -f 'msdos.h' -a "${1}" != "-c" ; then 
  1774.   echo shar: Will not clobber existing file \"'msdos.h'\"
  1775. else
  1776. echo shar: Extracting \"'msdos.h'\" \(2113 characters\)
  1777. sed "s/^X//" >'msdos.h' <<'END_OF_FILE'
  1778. X/*
  1779. X * msdos common header file
  1780. X */
  1781. X
  1782. X#define MSECSIZ    512            /* sector size */
  1783. X#define MDIRSIZ    32            /* directory size */
  1784. X#define CLSTRBUF 1024            /* largest cluster size */
  1785. X#define MAX_PATH 128
  1786. X
  1787. Xstruct directory {
  1788. X    unsigned char    name[8];    /* file name */
  1789. X    unsigned char    ext[3];        /* file extent */
  1790. X    unsigned char    attr;        /* attribute byte */
  1791. X    unsigned char    reserved[10];    /* ?? */
  1792. X    unsigned char    time[2];        
  1793. X    unsigned char    date[2];
  1794. X    unsigned char    start[2];    /* starting cluster number */
  1795. X    unsigned char    size[4];    /* size of the file */
  1796. X};
  1797. X
  1798. Xstruct dos_word {
  1799. X  unsigned char dw_low ;        /* LSB */
  1800. X  unsigned char dw_high ;        /* MSB */
  1801. X} ;
  1802. X
  1803. Xstruct superblock {
  1804. X  unsigned char jump[3] ;       /* Jump to boot code */
  1805. X  unsigned char banner[8];      /* OEM name & version */
  1806. X  struct dos_word secsiz;       /* Bytes per sector hopefully 512 */
  1807. X  unsigned char clsiz ;         /* Cluster size in sectors */
  1808. X  struct dos_word nrsvsect;     /* Number of reserved (boot) sectors */
  1809. X  unsigned char nfat;           /* Number of FAT tables hopefully 2 */
  1810. X  struct dos_word dirents;      /* Number of directory slots */
  1811. X  struct dos_word psect;        /* Total sectors on disk */
  1812. X  unsigned char descr;          /* Media descriptor=first byte of FAT */
  1813. X  struct dos_word fatlen;       /* Sectors in FAT */
  1814. X  struct dos_word nsect;        /* Sectors/track */
  1815. X  struct dos_word ntrack;       /* tracks/cyl */
  1816. X  struct dos_word nhs;          /* number of hidden sectors ? */
  1817. X} ;
  1818. X
  1819. Xunion bootblock {
  1820. X  char dummy[MSECSIZ] ;
  1821. X  struct superblock sb ;
  1822. X} ;
  1823. X
  1824. X#define WORD_VAL(x) (x.dw_low + (x.dw_high <<8))
  1825. X
  1826. X#define SECSIZ(x)    WORD_VAL(x.secsiz)
  1827. X#define CLSIZ(x)    (x.clsiz)
  1828. X#define FSSIZ(x)    WORD_VAL(x.psect)
  1829. X#define DIRENTS(x)    WORD_VAL(x.dirents)
  1830. X#define FATLEN(x)    WORD_VAL(x.fatlen)
  1831. X#define DIRLEN(x)    ((DIRENTS(x)*MDIRSIZ-1)/MSECSIZ+1)
  1832. X#define FATOFF(x)    WORD_VAL(x.nrsvsect)
  1833. X#define DIROFF(x)    (FATOFF(x)+FATLEN(x)*x.nfat)
  1834. X#define NCLUST(x)    (FSSIZ(x)-DIROFF(x)-DIRLEN(x)-WORD_VAL(x.nhs))/CLSIZ(x)
  1835. X#define NSECT(x)    WORD_VAL(x.nsect)
  1836. X#define NTRACK(x)    WORD_VAL(x.ntrack)
  1837. X#define NCYL(x)        (FSSIZ(x)/(NTRACK(x)*NSECT(x)))
  1838. X#define FATCODE(x)    (x.descr)
  1839. END_OF_FILE
  1840. if test 2113 -ne `wc -c <'msdos.h'`; then
  1841.     echo shar: \"'msdos.h'\" unpacked with wrong size!
  1842. fi
  1843. # end of 'msdos.h'
  1844. fi
  1845. if test -f 'putfat.c' -a "${1}" != "-c" ; then 
  1846.   echo shar: Will not clobber existing file \"'putfat.c'\"
  1847. else
  1848. echo shar: Extracting \"'putfat.c'\" \(2561 characters\)
  1849. sed "s/^X//" >'putfat.c' <<'END_OF_FILE'
  1850. X/*
  1851. X * putfat(), writedir(), zapit()
  1852. X */
  1853. X
  1854. X#include <stdio.h>
  1855. X#include "msdos.h"
  1856. X
  1857. Xextern int fd, fat_len, dir_chain[25];
  1858. Xextern unsigned char *fatbuf;
  1859. X
  1860. X/*
  1861. X * Puts a code into the FAT table.  Is the opposite of getfat().  No
  1862. X * sanity checking is done on the code.  Returns a 1 on error.
  1863. X */
  1864. X
  1865. Xint
  1866. Xputfat(num, code)
  1867. Xint num;
  1868. Xunsigned int code;
  1869. X{
  1870. X/*
  1871. X *    |    byte n     |   byte n+1    |   byte n+2    |
  1872. X *    |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7|
  1873. X *    | | | | | | | | | | | | | | | | | | | | | | | | |
  1874. X *    |  n.0  |  n.5  | n+1.0 | n+1.5 | n+2.0 | n+2.5 |
  1875. X *        \_____  \____   \______/________/_____   /
  1876. X *          ____\______\________/   _____/  ____\_/
  1877. X *         /     \      \          /       /     \
  1878. X *    | n+1.5 |  n.0  |  n.5  | n+2.0 | n+2.5 | n+1.0 |
  1879. X *    |      FAT entry k      |    FAT entry k+1      |
  1880. X */
  1881. X    int start;
  1882. X                    /* which bytes contain the entry */
  1883. X    start = num * 3 / 2;
  1884. X    if (start < 0 || start+1 > (fat_len * MSECSIZ))
  1885. X        return(1);
  1886. X                    /* (odd) not on byte boundary */
  1887. X    if (num % 2) {
  1888. X        *(fatbuf+start) = (*(fatbuf+start) & 0x0f) + ((code << 4) & 0xf0);
  1889. X        *(fatbuf+start+1) = (code >> 4) & 0xff;
  1890. X    }
  1891. X                    /* (even) on byte boundary */
  1892. X    else {
  1893. X        *(fatbuf+start) = code & 0xff;
  1894. X        *(fatbuf+start+1) = (*(fatbuf+start+1) & 0xf0) + ((code >> 8) & 0x0f);
  1895. X    }
  1896. X    return(0);
  1897. X}
  1898. X
  1899. X/*
  1900. X * Write a directory entry.  The first argument is the directory entry
  1901. X * number to write to.  The second is a pointer to the directory itself.
  1902. X * All errors are fatal.
  1903. X */
  1904. X
  1905. Xvoid
  1906. Xwritedir(num, dir)
  1907. Xint num;
  1908. Xstruct directory *dir;
  1909. X{
  1910. X    int skip, entry;
  1911. X    struct directory dirs[16];
  1912. X    void exit(), perror(), move();
  1913. X                    /* which sector */
  1914. X    skip = dir_chain[num / 16];
  1915. X
  1916. X    move(skip);
  1917. X                    /* read the sector */
  1918. X    if (read(fd, (char *) &dirs[0], MSECSIZ) != MSECSIZ) {
  1919. X        perror("writedir: read");
  1920. X        exit(1);
  1921. X    }
  1922. X                    /* which entry in sector */
  1923. X    entry = num % 16;
  1924. X                    /* copy the structure */
  1925. X    dirs[entry] = *dir;
  1926. X    move(skip);
  1927. X                    /* write the sector */
  1928. X    if (write(fd, (char *) &dirs[0], MSECSIZ) != MSECSIZ) {
  1929. X        perror("writedir: write");
  1930. X        exit(1);
  1931. X    }
  1932. X    return;
  1933. X}
  1934. X
  1935. X/*
  1936. X * Remove a string of FAT entries (delete the file).  The argument is
  1937. X * the beginning of the string.  Does not consider the file length, so
  1938. X * if FAT is corrupted, watch out!  All errors are fatal.
  1939. X */
  1940. X
  1941. Xvoid
  1942. Xzapit(fat)
  1943. Xint fat;
  1944. X{
  1945. X    int next;
  1946. X
  1947. X    while (1) {
  1948. X                    /* get next cluster number */
  1949. X        next = getfat(fat);
  1950. X                    /* mark current cluster as empty */
  1951. X        if (putfat(fat, 0) || next == -1) {
  1952. X            fprintf(stderr, "zapit: FAT problem\n");
  1953. X            exit(1);
  1954. X        }
  1955. X        if (next >= 0xff8)
  1956. X            break;
  1957. X        fat = next;
  1958. X    }
  1959. X    return;
  1960. X}
  1961. END_OF_FILE
  1962. if test 2561 -ne `wc -c <'putfat.c'`; then
  1963.     echo shar: \"'putfat.c'\" unpacked with wrong size!
  1964. fi
  1965. # end of 'putfat.c'
  1966. fi
  1967. if test -f 'search.c' -a "${1}" != "-c" ; then 
  1968.   echo shar: Will not clobber existing file \"'search.c'\"
  1969. else
  1970. echo shar: Extracting \"'search.c'\" \(1083 characters\)
  1971. sed "s/^X//" >'search.c' <<'END_OF_FILE'
  1972. X/*
  1973. X * Search and extract a directory structure.  The argument is the
  1974. X * relative directory entry number (no sanity checking).  It returns a
  1975. X * pointer to the directory structure at that location.  Attempts to
  1976. X * optimize by trying to determine if the buffer needs to be re-read.
  1977. X * A call to writedir() will scribble on the real buffer, so watch out!
  1978. X */
  1979. X
  1980. X#include <stdio.h>
  1981. X#include "msdos.h"
  1982. X                /* dir_chain contains the list of sectors */
  1983. X                /* that make up the current directory */
  1984. Xextern int fd, dir_chain[25];
  1985. X
  1986. Xstruct directory *
  1987. Xsearch(num)
  1988. Xint num;
  1989. X{
  1990. X    int skip, entry;
  1991. X    static int last;
  1992. X    static struct directory dirs[16];
  1993. X    void exit(), perror(), move();
  1994. X
  1995. X                    /* first call disables optimzation */
  1996. X    if (num == 0)
  1997. X        last = 0;
  1998. X                    /* which sector */
  1999. X    skip = dir_chain[num / 16];
  2000. X                    /* don't read it if same sector */
  2001. X    if (skip != last) {
  2002. X        move(skip);
  2003. X                    /* read the sector */
  2004. X        if (read(fd, (char *) &dirs[0], MSECSIZ) != MSECSIZ) {
  2005. X            perror("mread: read");
  2006. X            exit(1);
  2007. X        }
  2008. X    }
  2009. X    last = skip;
  2010. X                    /* which entry in sector */
  2011. X    entry = num % 16;
  2012. X    return(&dirs[entry]);
  2013. X}
  2014. END_OF_FILE
  2015. if test 1083 -ne `wc -c <'search.c'`; then
  2016.     echo shar: \"'search.c'\" unpacked with wrong size!
  2017. fi
  2018. # end of 'search.c'
  2019. fi
  2020. if test -f 'unixname.c' -a "${1}" != "-c" ; then 
  2021.   echo shar: Will not clobber existing file \"'unixname.c'\"
  2022. else
  2023. echo shar: Extracting \"'unixname.c'\" \(2215 characters\)
  2024. sed "s/^X//" >'unixname.c' <<'END_OF_FILE'
  2025. X/*
  2026. X * unixname(), getname(), getpath()
  2027. X */
  2028. X
  2029. X#include <stdio.h>
  2030. X#include <ctype.h>
  2031. X#include "msdos.h"
  2032. X
  2033. X/*
  2034. X * Get rid of spaces in a MSDOS 'raw' name (one that has come from the
  2035. X * directory structure) so that it can be used for regular expression
  2036. X * matching with a unix file name.  Also used to 'unfix' a name that has
  2037. X * been altered by fixname().  Returns a pointer to the unix style name.
  2038. X */
  2039. X
  2040. Xchar *
  2041. Xunixname(name, ext)
  2042. Xchar *name, *ext;
  2043. X{
  2044. X    char *s, tname[9], text[4], *strcpy(), *strcat(), *strchr();
  2045. X    char *ans, *malloc();
  2046. X
  2047. X    strcpy(tname, name);
  2048. X    if (s = strchr(tname, ' '))
  2049. X        *s = '\0';
  2050. X
  2051. X    strcpy(text, ext);
  2052. X    if (s = strchr(text, ' '))
  2053. X        *s = '\0';
  2054. X
  2055. X    ans = malloc(13);
  2056. X
  2057. X    if (*text) {
  2058. X        strcpy(ans, tname);
  2059. X        strcat(ans, ".");
  2060. X        strcat(ans, text);
  2061. X    }
  2062. X    else
  2063. X        strcpy(ans, tname);
  2064. X    return(ans);
  2065. X}
  2066. X
  2067. X/*
  2068. X * Get name component of filename.  Translates name to upper case.  Returns
  2069. X * pointer to new name.
  2070. X */
  2071. X
  2072. Xchar *
  2073. Xgetname(filename)
  2074. Xchar *filename;
  2075. X{
  2076. X    char *s, *ans, *malloc(), *temp, *strcpy(), *strrchr();
  2077. X    char buf[MAX_PATH];
  2078. X
  2079. X    strcpy(buf, filename);
  2080. X    temp = buf;
  2081. X                    /* find the last separator */
  2082. X    if (s = strrchr(temp, '/'))
  2083. X        temp = s+1;
  2084. X    if (s = strrchr(temp, '\\'))
  2085. X        temp = s+1;
  2086. X                    /* xlate to upper case */
  2087. X    for (s = temp; *s; ++s) {
  2088. X        if (islower(*s))
  2089. X            *s = toupper(*s);
  2090. X    }
  2091. X
  2092. X    ans = malloc((unsigned int) strlen(temp)+1);
  2093. X    strcpy(ans, temp);
  2094. X    return(ans);
  2095. X}
  2096. X
  2097. X/*
  2098. X * Get the path component of the filename.  Translates to upper case.
  2099. X * Returns pointer to path.  Doesn't alter leading separator, always
  2100. X * strips trailing separator (unless it is the path itself).
  2101. X */
  2102. X
  2103. Xchar *
  2104. Xgetpath(filename)
  2105. Xchar *filename;
  2106. X{
  2107. X    char *s, *temp, *ans, *malloc(), *strcpy(), *strrchr();
  2108. X    char buf[MAX_PATH];
  2109. X    int has_sep;
  2110. X
  2111. X    strcpy(buf, filename);
  2112. X    temp = buf;
  2113. X                    /* find last separator */
  2114. X    has_sep = 0;
  2115. X    if (s = strrchr(temp, '/')) {
  2116. X        has_sep++;
  2117. X        temp = s;
  2118. X    }
  2119. X    if (s = strrchr(temp, '\\')) {
  2120. X        has_sep++;
  2121. X        temp = s;
  2122. X    }
  2123. X
  2124. X    *temp = '\0';
  2125. X                    /* translate to upper case */
  2126. X    for (s = buf; *s; ++s) {
  2127. X        if (islower(*s))
  2128. X            *s = toupper(*s);
  2129. X    }
  2130. X                    /* if separator alone, put it back */
  2131. X    if (!strlen(buf) && has_sep)
  2132. X        strcpy(buf, "/");
  2133. X
  2134. X    ans = malloc((unsigned int) strlen(buf)+1);
  2135. X    strcpy(ans, buf);
  2136. X    return(ans);
  2137. X}
  2138. END_OF_FILE
  2139. if test 2215 -ne `wc -c <'unixname.c'`; then
  2140.     echo shar: \"'unixname.c'\" unpacked with wrong size!
  2141. fi
  2142. # end of 'unixname.c'
  2143. fi
  2144. echo shar: End of archive 1 \(of 3\).
  2145. cp /dev/null ark1isdone
  2146. MISSING=""
  2147. for I in 1 2 3 ; do
  2148.     if test ! -f ark${I}isdone ; then
  2149.     MISSING="${MISSING} ${I}"
  2150.     fi
  2151. done
  2152. if test "${MISSING}" = "" ; then
  2153.     echo You have unpacked all 3 archives.
  2154.     rm -f ark[1-9]isdone
  2155. else
  2156.     echo You still need to unpack the following archives:
  2157.     echo "        " ${MISSING}
  2158. fi
  2159. ##  End of shell archive.
  2160. exit 0
  2161.  
  2162.     Viktor Dukhovni <viktor@math.princeton.edu>    : ARPA
  2163.         <...!uunet!princeton!math!viktor>    : UUCP
  2164.     Fine Hall, Washington Rd., Princeton, NJ 08544  : US-Post
  2165.         +1-(609)-258-5792             : VOICE
  2166.  
  2167.