rs@uunet.UU.NET (Rich Salz) (08/28/87)
Submitted-by: uiucdcs!fthood!egray Posting-number: Volume 11, Issue 23 Archive-name: mtools/Part01 [ I haven't tried this stuff, but it seems useful to those who might need it. --r$ ] This is a collection of MSDOS tools to allow you to read and write to MSDOS formatted diskettes from a Unix based system. The only requirement is that your system must have floppy drive and a device driver that can handle at lease one of the disk formats used by the IBM PC. The following MSDOS commands are emulated: Mtool MSDOS name equivalent Description ----- ---- ----------- mdel DEL/ERASE delete a MSDOS file mdir DIR display a MSDOS directory mmd MD/MKDIR make a MSDOS sub directory mrd RD/RMDIR remove a MSDOS sub directory mread COPY read (copy) a MSDOS file to Unix mren REN/RENAME rename an existing MSDOS file mtype TYPE display contents of a MSDOS file mwrite COPY write (copy) a Unix file to MSDOS * CD change working directory * by use of an environmental variable Altering your particular device driver to accept the IBM disk formats is beyond the scope of this program. This collection of programs was written under SVR2, but the only 4.2bsd inconsistencies should be strchr/strrchr vs. index/rindex. Emmet P. Gray US Army, HQ III Corps & Fort Hood ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV Directorate of Engineering & Housing Environmental Management Office Fort Hood, TX 76544-5057 #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # Readme # Makefile # Mdel.1 # Mdir.1 # Mmd.1 # Mrd.1 # Mread.1 # Mren.1 # Mtype.1 # Mwrite.1 # msdos.h # convdate.c # fixname.c # getfat.c # init.c # isdir.c # match.c # mdel.c # mdir.c # This archive created: Thu Jul 9 22:35:39 1987 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'Readme'" '(5399 characters)' if test -f 'Readme' then echo shar: "will not over-write existing file 'Readme'" else sed 's/^X//' << \SHAR_EOF > 'Readme' X MTOOLS v1.2 X XThis is a collection of MSDOS tools to allow you to read and write to XMSDOS formatted diskettes from a Unix based system. X XThe following MSDOS commands are emulated: X XMtool MSDOS Xname equivalent Description X----- ---- ----------- Xmdel DEL/ERASE delete a MSDOS file Xmdir DIR display a MSDOS directory Xmmd MD/MKDIR make a MSDOS sub directory Xmrd RD/RMDIR remove a MSDOS sub directory Xmread COPY read (copy) a MSDOS file to Unix Xmren REN/RENAME rename an existing MSDOS file Xmtype TYPE display contents of a MSDOS file Xmwrite COPY write (copy) a Unix file to MSDOS X* CD change working directory X X * by use of the environmental variable MCWD X XThe formats of IBM PC floppy disk drives are: X X bytes per sectors per tracks number total disk introduced X sector track per side of sides capacity size in MSDOS X 512 8 40 1 160k 5.25 1.0 X 512 9 40 1 180k 5.25 1.1 X 512 8 40 2 320k 5.25 2.0 X 512 9 40 2 360k 5.25 2.0 X 512 15 80 2 1.2M 5.25 3.0 X 512 9 80 2 720k 3.5 3.2 X X XThe following are typical Unix device names for the IBM formats: X X /dev/rflp 'generic' used first to test the media X /dev/rflp40t8s1s 40 track 8 sector single sided X /dev/rflp40t8s2s 40 track 8 sector double sided X /dev/rflp40t9s1s 40 track 9 sector single sided X /dev/rflp40t9s2s 40 track 9 sector double sided X /dev/rflp80t15s2s 80 track 15 sector double sided X /dev/rflp80t9s2s 3.5 inch 80 track 9 sector double sided X XThese device names are in the msdos.h file as #defines and must be edited Xto match the device names on your system. If your device driver does not Xhandle all of the formats shown, then you should leave those particular Xdevices undefined in the msdos.h file. X XThis program can be easily customized to accept non-standard disk formats. XFor example, a popular disk format for Unix machines seems to be 80 track, Xdouble sided, 8 sector. This doesn't conform to any of the IBM standard Xformats, but MSDOS 3.30 can be made to format virtually anything using the XDRIVER.SYS parameters in the CONFIG.SYS file. Let's take a hypothetical Xcase of a brand X Unix machine with a 80 track, double sided, 8 sector Xdisk drive. You could purchase an external 80 track drive for your IBM Xcompatible computer and format the drive D: under MSDOS 3.30 with the Xfollowing DRIVER.SYS parameters: X X DEVICE=DRIVER.SYS /D:2 /T:80 /S:8 /H:2 /F:2 X XThen, you would edit the init.c file to include the new non-standard Xparameters. You might need Norton Utilities, or some other program, Xto determine the statistics of the format. Using our example, the Xformat would have the following parameters: X X FAT#1 sectors 1 - 3 fat_len = 3 X FAT#2 sectors 4 - 6 dir_start = 4 X DIR sectors 7 - 13 dir_len = 7 X cluster size is 2 sectors clus_size = 2 X there are 633 clusters num_clus = 633 X XNow, the diskette formated on your PC's external drive can be used in Xboth your PC and your Unix machine. Obviously, that diskette could not Xbe used in other IBM compatibles, unless they too had an external 80 Xtrack drive. That means that you'd need to copy your data from a normal X40 track diskette to the 80 track diskette prior to moving it to your XUnix machine. Likewise, you'd need to copy the 80 track diskette to a X40 track diskette to be able to move data from the Unix machine to Xanother PC. X XThe manuals are very terse... it's assumed that the reader is already Xfamiliar with MSDOS. X XThe use of the environmental variable MCWD to keep track of the current Xworking directory is a little awkward, especially since there is no X'change directory' command. Bourne shell users will have to type two Xcommands to set their working directory, ie: X X MCWD=/TMP X export MCWD X XWildcards are only applied to filenames and not to directory names. XFor example '/usr/local/*.c' is appropriate, but '/usr/l*/main.c' is not. X XI really wanted to avoid the use of a 'text' mode and a 'data' mode Xwhen transferring files, but I couldn't find a better way. It gets rather Xconfusing and it's quite possible to mess up a file if you apply the Xtext mode when it is not appropriate (ie: to a COM or EXE file). Likewise, Xif you forget to apply the text mode (to a Unix text file) then if the Xfile is used under MSDOS, it will be missing carriage returns. However, Xif you aren't going to use the files on your Unix system (you just Xintend to hold the files and then transfer them back to MSDOS later) then Xyou shouldn't use the text mode during either mread or mwrite. This is Xbecause, the text mode is only useful if the files are gonna be used Xunder Unix. X XMwrite adds an EOF marker to every file (not just text files). Mread Xignores all EOF markers. X XThe MSDOS 'copy' command had to be broken down into two separate Unix Xcommands since the MSDOS device designations (A: or C:) would be Xclumsy to implement. X XMtools is also available in versions especially written for Masscomp Xcomputers and the AT&T Unix PC 7300. X XEmmet P. Gray US Army, HQ III Corps & Fort Hood X...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV X Directorate of Engineering & Housing X Environmental Management Office X Fort Hood, TX 76544-5057 SHAR_EOF if test 5399 -ne "`wc -c < 'Readme'`" then echo shar: "error transmitting 'Readme'" '(should have been 5399 characters)' fi fi echo shar: "extracting 'Makefile'" '(2916 characters)' if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else sed 's/^X//' << \SHAR_EOF > 'Makefile' X# X# Makefile for MSDOS tools X# X XCC = cc XCFLAGS = -O XLINT = lint -c XSHAR = shar -a XBINDIR = /usr/local/bin XPROGS = mdir mread mwrite mdel mtype mmd mrd mren X XMDIR = mdir.o getfat.o init.o search.o match.o convdate.o unixname.o subdir.o \ X isdir.o XMREAD = mread.o getfat.o init.o search.o match.o unixname.o subdir.o XMWRITE = mwrite.o getfat.o init.o search.o fixname.o unixname.o putfat.o \ X subdir.o mkentry.o isdir.o XMDEL = mdel.o getfat.o init.o search.o match.o unixname.o putfat.o subdir.o XMTYPE = mtype.o getfat.o init.o search.o match.o unixname.o subdir.o XMMD = mmd.o getfat.o init.o search.o fixname.o unixname.o putfat.o subdir.o \ X mkentry.o XMRD = mrd.o getfat.o init.o search.o unixname.o putfat.o subdir.o XMREN = mren.o getfat.o init.o search.o fixname.o unixname.o putfat.c subdir.o \ X isdir.o X Xall: $(PROGS) X Xmdir: $(MDIR) X $(CC) $(CFLAGS) $(MDIR) -o mdir X Xmread: $(MREAD) X $(CC) $(CFLAGS) $(MREAD) -o mread X Xmwrite: $(MWRITE) X $(CC) $(CFLAGS) $(MWRITE) -o mwrite X Xmdel: $(MDEL) X $(CC) $(CFLAGS) $(MDEL) -o mdel X Xmtype: $(MTYPE) X $(CC) $(CFLAGS) $(MTYPE) -o mtype X Xmmd: $(MMD) X $(CC) $(CFLAGS) $(MMD) -o mmd X Xmrd: $(MRD) X $(CC) $(CFLAGS) $(MRD) -o mrd X Xmren: $(MREN) X $(CC) $(CFLAGS) $(MREN) -o mren X Xinstall: $(PROGS) X cp mdir $(BINDIR)/mdir X strip $(BINDIR)/mdir X rm mdir X# cp Mdir.1 /usr/man/man1/mdir.1 X cp mread $(BINDIR)/mread X strip $(BINDIR)/mread X rm mread X# cp Mread.1 /usr/man/man1/mread.1 X cp mwrite $(BINDIR)/mwrite X strip $(BINDIR)/mwrite X rm mwrite X# cp Mwrite.1 /usr/man/man1/mwrite.1 X cp mdel $(BINDIR)/mdel X strip $(BINDIR)/mdel X rm mdel X# cp Mdel.1 /usr/man/man1/mdel.1 X cp mtype $(BINDIR)/mtype X strip $(BINDIR)/mtype X rm mtype X# cp Mtype.1 /usr/man/man1/mtype.1 X cp mmd $(BINDIR)/mmd X strip $(BINDIR)/mmd X rm mmd X# cp Mmd.1 /usr/man/man1/mmd.1 X cp mrd $(BINDIR)/mrd X strip $(BINDIR)/mrd X rm mrd X# cp Mrd.1 /usr/man/man1/mrd.1 X cp mren $(BINDIR)/mren X strip $(BINDIR)/mren X rm mren X# cp Mren.1 /usr/man/man1/mren.1 X Xlint: X $(LINT) mdir.c getfat.c init.c search.c match.c convdate.c subdir.c \ X unixname.c isdir.c X $(LINT) mread.c getfat.c init.c search.c match.c unixname.c subdir.c X $(LINT) mwrite.c getfat.c init.c search.c fixname.c unixname.c \ X putfat.c subdir.c mkentry.c isdir.c X $(LINT) mdel.c getfat.c init.c search.c match.c unixname.c putfat.c \ X subdir.c X $(LINT) mtype.c getfat.c init.c search.c match.c unixname.c subdir.c X $(LINT) mmd.c getfat.c init.c search.c fixname.c unixname.c putfat.c \ X subdir.c mkentry.c X $(LINT) mrd.c getfat.c init.c search.c unixname.c putfat.c subdir.c X $(LINT) mren.c getfat.c init.c search.c fixname.c unixname.c putfat.c \ X subdir.c X Xshar: X $(SHAR) Readme Makefile Mdel.1 Mdir.1 Mmd.1 Mrd.1 Mread.1 Mren.1 \ X Mtype.1 Mwrite.1 msdos.h convdate.c fixname.c getfat.c init.c \ X isdir.c match.c mdel.c mdir.c > mtools1 X $(SHAR) mkentry.c mmd.c mrd.c mread.c mren.c mtype.c mwrite.c \ X putfat.c search.c subdir.c unixname.c > mtools2 SHAR_EOF if test 2916 -ne "`wc -c < 'Makefile'`" then echo shar: "error transmitting 'Makefile'" '(should have been 2916 characters)' fi fi echo shar: "extracting 'Mdel.1'" '(673 characters)' if test -f 'Mdel.1' then echo shar: "will not over-write existing file 'Mdel.1'" else sed 's/^X//' << \SHAR_EOF > 'Mdel.1' X.TH MDEL 1 local X.SH NAME Xmdel \- delete a MSDOS file X.SH SYNOPSIS X.B mdel msdosfile X[ X.B msdosfiles... X] X.SH DESCRIPTION X.I Mdel Xdeletes a file on a MSDOS formatted diskette. Sub directories are supported Xwith either the '/' or '\e\' separator. The use of the '\e\' separator Xor wildcards will require the names to be enclosed in quotes to protect Xthem from the shell. X.PP X.I Mdel Xwill ask for verification prior to removing a read\-only file. X.PP XThe environmental variable MCWD may be used to establish a current Xworking directory (relative to the MSDOS diskette). X.SH SEE ALSO Xmdir(1) X.SH BUGS XDoes not follow the MSDOS convention of allowing only one file argument. SHAR_EOF if test 673 -ne "`wc -c < 'Mdel.1'`" then echo shar: "error transmitting 'Mdel.1'" '(should have been 673 characters)' fi fi echo shar: "extracting 'Mdir.1'" '(926 characters)' if test -f 'Mdir.1' then echo shar: "will not over-write existing file 'Mdir.1'" else sed 's/^X//' << \SHAR_EOF > 'Mdir.1' X.TH MDIR 1 local X.SH NAME Xmdir \- display a MSDOS directory X.SH SYNOPSIS X.B mdir X[ X.B -w X] X.B msdosdirectory X.PP X.B mdir X[ X.B -w X] X.B msdosfile X[ X.B msdosfiles... X] X.SH DESCRIPTION X.I Mdir Xdisplays the contents of a MSDOS formatted diskette. Sub directories Xare supported with either the '/' or '\e\' separator. The use of Xthe '\e\' separator or wildcards will require the names to be enclosed in Xquotes to protect them from the shell. X.PP X.I Mdir Xwill accept the following command line option: X.TP X.B w XWide output. This option will print the file names across the page without Xdisplaying the file size or creation date. X.PP XAn error occurs if a component of the path is not a directory. X.PP XThe environmental variable MCWD may be used to establish a current Xworking directory (relative to the MSDOS diskette). X.SH SEE ALSO Xmtype(1) X.SH BUGS XDoes not follow the MSDOS convention of allowing only one directory Xargument. SHAR_EOF if test 926 -ne "`wc -c < 'Mdir.1'`" then echo shar: "error transmitting 'Mdir.1'" '(should have been 926 characters)' fi fi echo shar: "extracting 'Mmd.1'" '(723 characters)' if test -f 'Mmd.1' then echo shar: "will not over-write existing file 'Mmd.1'" else sed 's/^X//' << \SHAR_EOF > 'Mmd.1' X.TH MMD 1 local X.SH NAME Xmmd \- make a MSDOS sub directory X.SH SYNOPSIS X.B mmd msdosdirectory X.SH DESCRIPTION X.I Mmd Xmakes a new directory on a MSDOS formatted diskette. Sub directories are Xsupported with either the '/' or '\e\' separator. The use of Xthe '\e\' separator will require the directory name to be enclosed in quotes Xto protect it from the shell. X.PP XReasonable care is taken to create a valid MSDOS directory name. If an Xinvalid name is specified, X.I mmd Xwill change the name and display the new name. X.PP XAn error occurs if the directory already exists. X.PP XThe environmental variable MCWD may be used to establish a current Xworking directory (relative to the MSDOS diskette). X.SH SEE ALSO Xmdir(1), mrd(1) SHAR_EOF if test 723 -ne "`wc -c < 'Mmd.1'`" then echo shar: "error transmitting 'Mmd.1'" '(should have been 723 characters)' fi fi echo shar: "extracting 'Mrd.1'" '(598 characters)' if test -f 'Mrd.1' then echo shar: "will not over-write existing file 'Mrd.1'" else sed 's/^X//' << \SHAR_EOF > 'Mrd.1' X.TH MRD 1 local X.SH NAME Xmrd \- remove a MSDOS sub directory X.SH SYNOPSIS X.B mrd msdosdirectory X.SH DESCRIPTION X.I Mrd Xremoves a directory from a MSDOS formatted diskette. Sub directories are Xsupported with either the '/' or '\e\' separator. The use of Xthe '\e\' separator will require the directory name to be enclosed in quotes Xto protect it from the shell. X.PP XAn error occurs if the directory is not empty. X.PP XWildcards are not supported. X.PP XThe environmental variable MCWD may be used to establish a current Xworking directory (relative to the MSDOS diskette). X.SH SEE ALSO Xmdir(1), mmd(1) SHAR_EOF if test 598 -ne "`wc -c < 'Mrd.1'`" then echo shar: "error transmitting 'Mrd.1'" '(should have been 598 characters)' fi fi echo shar: "extracting 'Mread.1'" '(1152 characters)' if test -f 'Mread.1' then echo shar: "will not over-write existing file 'Mread.1'" else sed 's/^X//' << \SHAR_EOF > 'Mread.1' X.TH MREAD 1 local X.SH NAME Xmread \- read (copy) a MSDOS file to Unix X.SH SYNOPSIS X.B mread X[ X.B -t X| X.B -n X] X.B msdosfile unixfile X.PP X.B mread X[ X.B -t X| X.B -n X] X.B msdosfile X[ X.B msdosfiles... X] X.B unixdirectory X.SH DESCRIPTION XIn the first form, X.I mread Xcopies the specified MSDOS file to the named Unix file. The second form Xof the command copies multiple MSDOS files to the named Unix directory. XMSDOS sub directories are supported with either the '/' or '\e\' separator. XThe use of the '\e\' separator or wildcards will require the names to be Xenclosed in quotes to protect them from the shell. X.PP X.I Mread Xwill accept the following command line options: X.TP X.B t XText file transfer. X.I Mread Xwill translate incoming carriage return/line feeds to line feeds. X.TP X.B n XNo warning. X.I Mread Xwill not warn the user when overwriting an existing file. X.PP XIf the target file already exists, and the X.I -n Xoption is not in effect, X.I mread Xasks whether or not to overwrite the file. X.PP XThe environmental variable MCWD may be used to establish a current Xworking directory (relative to the MSDOS diskette). X.SH SEE ALSO Xmdir(1), mtype(1), mwrite(1) SHAR_EOF if test 1152 -ne "`wc -c < 'Mread.1'`" then echo shar: "error transmitting 'Mread.1'" '(should have been 1152 characters)' fi fi echo shar: "extracting 'Mren.1'" '(938 characters)' if test -f 'Mren.1' then echo shar: "will not over-write existing file 'Mren.1'" else sed 's/^X//' << \SHAR_EOF > 'Mren.1' X.TH MREN 1 local X.SH NAME Xmren \- rename an existing MSDOS file X.SH SYNOPSIS X.B mren sourcefile targetfile X.SH DESCRIPTION X.I Mren Xrenames an existing file on a MSDOS formatted diskette. Sub directories are Xsupported with either the '/' or '\e\' separator. The use of the '\e\' Xseparator or wildcards will require the names to be enclosed in quotes to Xprotect them from the shell. X.PP XReasonable care is taken to create a valid MSDOS filename. If an invalid XMSDOS target name is specified, X.I mren Xwill change the name and prompt the user to accept or reject the new name. X.PP XThe path component of the target filename (if supplied) is ignored. In Xother words, you may not use X.I mren Xto move a file from one sub directory to another. X.PP X.I Mren Xmay also be used to rename directories. X.PP XThe environmental variable MCWD may be used to establish a current Xworking directory (relative to the MSDOS diskette). X.SH SEE ALSO Xmwrite(1) SHAR_EOF if test 938 -ne "`wc -c < 'Mren.1'`" then echo shar: "error transmitting 'Mren.1'" '(should have been 938 characters)' fi fi echo shar: "extracting 'Mtype.1'" '(928 characters)' if test -f 'Mtype.1' then echo shar: "will not over-write existing file 'Mtype.1'" else sed 's/^X//' << \SHAR_EOF > 'Mtype.1' X.TH MTYPE 1 local X.SH NAME Xmtype \- display contents of a MSDOS file X.SH SYNOPSIS X.B mtype X[ X.B -t X| X.B -s X] X.B msdosfile X[ X.B msdosfiles... X] X.SH DESCRIPTION X.I Mtype Xdisplays the specified MSDOS file on the screen. MSDOS sub directories are Xsupported with either the '/' or '\e\' separator. The use of the '\e\' Xseparator or wildcards will require the names to be enclosed in quotes to Xprotect them from the shell. X.PP X.I Mtype Xwill accept the following command line options: X.TP X.B t XText file viewing. X.I Mtype Xwill translate incoming carriage return/line feeds to line feeds. X.TP X.B s XStrip high bit. X.I Mtype Xwill strip the high bit from the data. Useful for viewing Wordstar files. X.PP XThe environmental variable MCWD may be used to establish a current Xworking directory (relative to the MSDOS diskette). X.SH SEE ALSO Xmdir(1), mread(1) X.SH BUGS XDoes not follow the MSDOS convention of allowing only one file Xargument. SHAR_EOF if test 928 -ne "`wc -c < 'Mtype.1'`" then echo shar: "error transmitting 'Mtype.1'" '(should have been 928 characters)' fi fi echo shar: "extracting 'Mwrite.1'" '(1294 characters)' if test -f 'Mwrite.1' then echo shar: "will not over-write existing file 'Mwrite.1'" else sed 's/^X//' << \SHAR_EOF > 'Mwrite.1' X.TH MWRITE 1 local X.SH NAME Xmwrite \- write (copy) a Unix file to MSDOS X.SH SYNOPSIS X.B mwrite X[ X.B -t X| X.B -n X] X.B unixfile msdosfile X.PP X.B mwrite X[ X.B -t X| X.B -n X] X.B unixfile X[ X.B unixfiles... X] X.B msdosdirectory X.SH DESCRIPTION XIn the first form, X.I mwrite Xcopies the specified Unix file to the named MSDOS file. The second form Xof the command copies multiple Unix files to the named MSDOS directory. XMSDOS sub directories are are supported with either the '/' or '\e\' separator. XThe use of the '\e\' separator will require the names to be enclosed in Xquotes to protect them from the shell. X.PP X.I Mwrite Xwill accept the following command line options: X.TP X.B t XText file transfer. X.I Mwrite Xwill translate incoming line feeds to carriage return/line feeds. X.TP X.B n XNo warning. X.I Mwrite Xwill not warn the user when overwriting an existing file. X.PP XIf the target file already exists, and the X.I -n Xoption is not in effect, X.I mwrite Xasks whether or not to overwrite the file. X.PP XReasonable care is taken to create a valid MSDOS filename. If an invalid Xname is specified, X.I mwrite Xwill change the name and display the new name. X.PP XThe environmental variable MCWD may be used to establish a current Xworking directory (relative to the MSDOS diskette). X.SH SEE ALSO Xmdir(1), mread(1) SHAR_EOF if test 1294 -ne "`wc -c < 'Mwrite.1'`" then echo shar: "error transmitting 'Mwrite.1'" '(should have been 1294 characters)' fi fi echo shar: "extracting 'msdos.h'" '(791 characters)' if test -f 'msdos.h' then echo shar: "will not over-write existing file 'msdos.h'" else sed 's/^X//' << \SHAR_EOF > 'msdos.h' X/* X * msdos common header file X */ X X#define MSECSIZ 512 X#define MDIRSIZ 32 X X/* X * If your device driver does not support any of the following formats, X * then leave those devices undefined. X */ X X#define FLOPPY "/dev/rflp" X#define FLP_40_8_1 "/dev/rflp40t8s1s" X#define FLP_40_8_2 "/dev/rflp40t8s2s" X#define FLP_40_9_1 "/dev/rflp40t9s1s" X#define FLP_40_9_2 "/dev/rflp40t9s2s" X#define FLP_80_15_2 "/dev/rflp80t15s2s" X#define FLP_80_9_2 "/dev/rflp80t9s2s" X Xstruct directory { X unsigned char name[8]; /* file name */ X unsigned char ext[3]; /* file extent */ X unsigned char attr; /* attribute byte */ X unsigned char reserved[10]; /* ?? */ X unsigned char time[2]; X unsigned char date[2]; X unsigned char start[2]; /* starting cluster number */ X unsigned char size[4]; /* size of the file */ X}; SHAR_EOF if test 791 -ne "`wc -c < 'msdos.h'`" then echo shar: "error transmitting 'msdos.h'" '(should have been 791 characters)' fi fi echo shar: "extracting 'convdate.c'" '(1314 characters)' if test -f 'convdate.c' then echo shar: "will not over-write existing file 'convdate.c'" else sed 's/^X//' << \SHAR_EOF > 'convdate.c' X/* X * convdate(), convtime() X */ X X/* X * convert MSDOS directory datestamp to ASCII X */ X Xchar * Xconvdate(date_high, date_low) Xunsigned date_high; Xunsigned date_low; X{ X/* X * hi byte | low byte X * |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7| X * | | | | | | | | | | | | | | | | | X * \ 7 bits /\4 bits/\ 5 bits / X * year +80 month day X */ X static char buffer[9]; X unsigned char year, month_hi, month_low, day; X X year = (date_high >> 1) + 80; X month_hi = (date_high & 0x1) << 3; X month_low = date_low >> 5; X day = date_low & 0x1f; X sprintf(buffer, "%2d-%02d-%02d", month_hi+month_low, day, year); X return(buffer); X} X X/* X * Convert MSDOS directory timestamp to ASCII X */ X Xchar * Xconvtime(time_high, time_low) Xunsigned time_high; Xunsigned time_low; X{ X/* X * hi byte | low byte X * |0|1|2|3|4|5|6|7|0|1|2|3|4|5|6|7| X * | | | | | | | | | | | | | | | | | X * \ 5 bits /\ 6 bits /\ 5 bits / X * hour minutes sec*2 X */ X static char buffer[7]; X char am_pm; X unsigned char hour, min_hi, min_low; X X hour = time_high >> 3; X am_pm = (hour >= 12) ? 'p' : 'a'; X if (hour > 12) X hour = hour -12; X if (hour == 0) X hour = 12; X min_hi = (time_high & 0x7) << 3; X min_low = time_low >> 5; X sprintf(buffer, "%2d:%02d%c", hour, min_hi+min_low, am_pm); X return(buffer); X} SHAR_EOF if test 1314 -ne "`wc -c < 'convdate.c'`" then echo shar: "error transmitting 'convdate.c'" '(should have been 1314 characters)' fi fi echo shar: "extracting 'fixname.c'" '(1670 characters)' if test -f 'fixname.c' then echo shar: "will not over-write existing file 'fixname.c'" else sed 's/^X//' << \SHAR_EOF > 'fixname.c' X/* X * Convert a Unix filename to a legal MSDOS name. Returns a pointer to X * the 'fixed' name. Will truncate file and extension names, will X * substitute the letter 'X' for any illegal character in the name. X */ X X#include <stdio.h> X#include <ctype.h> X Xchar * Xfixname(name) Xchar *name; X{ X static char *dev[8] = {"CON", "AUX", "COM1", "LPT1", "PRN", "LPT2", X "LPT3", "NUL"}; X char *s, *temp, *ext, *malloc(), *strcpy(), *strpbrk(), *strrchr(); X int i, dot, modified; X static char *ans; X X temp = malloc(strlen(name)+1); X strcpy(temp, name); X /* zap the leading path */ X if (s = strrchr(temp, '/')) X temp = s+1; X if (s = strrchr(temp, '\\')) X temp = s+1; X X ext = NULL; X dot = 0; X for (s = temp; *s; ++s) { X if (*s == '.' && !dot) { X dot = 1; X *s = NULL; X ext = s + 1; X } X if (islower(*s)) X *s = toupper(*s); X } X if (*temp == NULL) { X temp = "X"; X printf("'%s' Null name component, using '%s.%s'\n", name, temp, ext); X } X for (i=0; i<8; i++) { X if (!strcmp(temp, dev[i])) { X *temp = 'X'; X printf("'%s' Is a device name, using '%s.%s'\n", name, temp, ext); X } X } X if (strlen(temp) > 8) { X *(temp+8) = NULL; X printf("'%s' Name too long, using, '%s.%s'\n", name, temp, ext); X } X if (strlen(ext) > 3) { X *(ext+3) = NULL; X printf("'%s' Extension too long, using '%s.%s'\n", name, temp, ext); X } X modified = 0; X while (s = strpbrk(temp, "^+=/[]:',?*\\<>|\". ")) { X modified++; X *s = 'X'; X } X while (s = strpbrk(ext, "^+=/[]:',?*\\<>|\". ")) { X modified++; X *s = 'X'; X } X if (modified) X printf("'%s' Contains illegal character\(s\), using '%s.%s'\n", name, temp, ext); X ans = malloc(12); X sprintf(ans, "%-8.8s%-3.3s", temp, ext); X return(ans); X} SHAR_EOF if test 1670 -ne "`wc -c < 'fixname.c'`" then echo shar: "error transmitting 'fixname.c'" '(should have been 1670 characters)' fi fi echo shar: "extracting 'getfat.c'" '(1377 characters)' if test -f 'getfat.c' then echo shar: "will not over-write existing file 'getfat.c'" else sed 's/^X//' << \SHAR_EOF > 'getfat.c' X/* X * Get and decode a FAT (file allocation table) entry. The FAT entries X * are 1.5 bytes long and switch nibbles (.5 byte) according to whether X * or not the entry starts on a byte boundary. Returns the cluster X * number on success or -1 on failure. X */ X X#include "msdos.h" X Xextern int fat_len; Xextern unsigned char *fatbuf; X Xint Xgetfat(num) Xint num; X{ X/* X * | byte n | byte n+1 | byte n+2 | 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| X * | | | | | | | | | | | | | | | | | | | | | | | | | X * | n.0 | n.5 | n+1.0 | n+1.5 | n+2.0 | n+2.5 | X * \_____ \____ \______/________/_____ / X * ____\______\________/ _____/ ____\_/ X * / \ \ / / \ X * | n+1.5 | n.0 | n.5 | n+2.0 | n+2.5 | n+1.0 | X * | FAT entry k | FAT entry k+1 | X */ X unsigned int fat_hi, fat_low, byte_1, byte_2; X int start; X static int fat; X /* which bytes contain the entry */ X start = num * 3 / 2; X if (start < 0 || start+1 > (fat_len * MSECSIZ)) X return(-1); X X byte_1 = *(fatbuf + start); X byte_2 = *(fatbuf + start + 1); X /* (odd) not on byte boundary */ X if (num % 2) { X fat_hi = (byte_2 & 0xff) << 4; X fat_low = (byte_1 & 0xf0) >> 4; X } X /* (even) on byte boundary */ X else { X fat_hi = (byte_2 & 0xf) << 8; X fat_low = byte_1 & 0xff; X } X fat = (fat_hi + fat_low) & 0xfff; X return(fat); X} SHAR_EOF if test 1377 -ne "`wc -c < 'getfat.c'`" then echo shar: "error transmitting 'getfat.c'" '(should have been 1377 characters)' fi fi echo shar: "extracting 'init.c'" '(5957 characters)' if test -f 'init.c' then echo shar: "will not over-write existing file 'init.c'" else sed 's/^X//' << \SHAR_EOF > 'init.c' X/* X * Initialize a MSDOS diskette. Get the media signature (1st FAT entry) X * and switch to the proper floppy disk device to match the format X * of the disk. Sets a bunch of global variables. Returns 0 on success, X * or 1 on failure. X */ X X#include <stdio.h> X#include <ctype.h> X#include "msdos.h" X Xextern int fd, dir_len, dir_start, clus_size, fat_len, num_clus; Xextern unsigned char *fatbuf; Xextern char *mcwd; X Xint Xinit(mode) Xint mode; X{ X int code = 0, buflen; X unsigned char read_fat(), fat; X char *getenv(), *fixmcwd(), *malloc(), version, get_dos_ver(); X long lseek(); X void perror(), exit(); X X /* open the 'generic' floppy */ X if ((fd = open(FLOPPY, mode)) < 0) { X perror("init: open"); X exit(1); X } X /* read media signature (1st FAT) */ X fat = read_fat(); X switch(fat) { X case 0xfe: X#ifndef FLP_40_8_1 X fprintf(stderr, "40 track, 8 sector, single sided: not supported\n"); X code = 1; X#else FLP_40_8_1 X dir_start = 3; X dir_len = 4; X clus_size = 1; X fat_len = 1; X num_clus = 313; X close(fd); X if ((fd = open(FLP_40_8_1, mode)) < 0) { X perror("init: open"); X return(1); X } X#endif FLP_40_8_1 X break; X case 0xff: X#ifndef FLP_40_8_2 X fprintf(stderr, "40 track, 8 sector, double sided: not supported\n"); X code = 1; X#else FLP_40_8_2 X dir_start = 3; X dir_len = 7; X clus_size = 2; X fat_len = 1; X num_clus = 315; X close(fd); X if ((fd = open(FLP_40_8_2, mode)) < 0) { X perror("init: open"); X return(1); X } X#endif FLP_40_8_2 X break; X case 0xfc: X#ifndef FLP_40_9_1 X fprintf(stderr, "40 track, 9 sector, single sided: not supported\n"); X code = 1; X#else FLP_40_9_1 X dir_start = 5; X dir_len = 4; X clus_size = 1; X fat_len = 2; X num_clus = 351; X close(fd); X if ((fd = open(FLP_40_9_1, mode)) < 0) { X perror("init: open"); X return(1); X } X#endif FLP_40_9_1 X break; X case 0xfd: X#ifndef FLP_40_9_2 X fprintf(stderr, "40 track, 9 sector, double sided: not supported\n"); X code = 1; X#else FLP_40_9_2 X dir_start = 5; X dir_len = 7; X clus_size = 2; X fat_len = 2; X num_clus = 354; X close(fd); X if ((fd = open(FLP_40_9_2, mode)) < 0) { X perror("init: open"); X return(1); X } X#endif FLP_40_9_2 X break; X case 0xf9: /* all 80 track disks */ X version = get_dos_ver(); X switch (version) { X case '0': X case '1': X#ifndef FLP_80_15_2 X fprintf(stderr, "80 track, 15 sector, double sided: not supported\n"); X code = 1; X#else FLP_80_15_2 X dir_start = 15; X dir_len = 14; X clus_size = 1; X fat_len = 7; X num_clus = 1193; X close(fd); X if ((fd = open(FLP_80_15_2, mode)) < 0) { X perror("init: open"); X return(1); X } X#endif FLP_80_15_2 X break; X case '2': X#ifndef FLP_80_9_2 X fprintf(stderr, "3.5 inch 80 track, 9 sector, double sided: not supported\n"); X code = 1; X#else FLP_80_9_2 X dir_start = 7; X dir_len = 7; X clus_size = 2; X fat_len = 3; X num_clus = 713; X close(fd); X if ((fd = open(FLP_80_9_2, mode)) < 0) { X perror("init: open"); X return(1); X } X#endif FLP_80_9_2 X break; X default: X fprintf(stderr, "Unknown DOS version '%02x'\n", version); X code = 1; X break; X } X break; X default: X fprintf(stderr, "Unknown format '%02x'\n", fat); X code = 1; X break; X } X if (code) X return(1); X X buflen = fat_len * MSECSIZ; X fatbuf = (unsigned char *) malloc(buflen); X move(1); X /* read the FAT sectors */ X if (read(fd, fatbuf, buflen) != buflen) { X perror("init: read"); X exit(1); X } X /* set dir_chain to root directory */ X reset_dir(); X /* get Current Working Directory */ X mcwd = fixmcwd(getenv("MCWD")); X /* test it out.. */ X if (subdir("")) { X fprintf(stderr, "Environmental variable MCWD needs updating\n"); X exit(1); X } X return(0); X} X X/* X * Move the read/write head to the next location. Tries to optimize X * the movement by moving relative to current location. The argument X * is a logical sector number. All errors are fatal. X */ X Xmove(sector) Xint sector; X{ X long cur_loc, next, lseek(); X void exit(), perror(); X /* get current location */ X if ((cur_loc = lseek(fd, 0L, 1)) < 0) { X perror("move: lseek"); X exit(1); X } X next = (long) (MSECSIZ * sector) - cur_loc; X /* we're already there */ X if (next == 0L) X return; X /* move to next location */ X if (lseek(fd, next, 1) < 0) { X perror("move: lseek"); X exit(1); X } X return; X} X X/* X * Fix MCWD to be a proper directory name. Always has a leading separator. X * Never has a trailing separator (unless it is the path itself). X */ X Xchar * Xfixmcwd(dirname) Xchar *dirname; X{ X char *s, *malloc(), *strcpy(), *strcat(); X static char *ans; X X ans = malloc(strlen(dirname)+2); X /* add a leading separator */ X if (*dirname != '/' && *dirname != '\\') { X strcpy(ans, "/"); X strcat(ans, dirname); X } X else X strcpy(ans, dirname); X /* translate to upper case */ X for (s = ans; *s; ++s) { X if (islower(*s)) X *s = toupper(*s); X } X /* if separator alone */ X if (strlen(ans) == 1) X return(ans); X /* zap the trailing separator */ X s--; X if (*s == '/' || *s == '\\') X *s = NULL; X return(ans); X} X X/* X * Read the first byte of the FAT table. This code serves as a media X * signature for the diskette. X */ X Xunsigned char Xread_fat() X{ X unsigned char buf[MSECSIZ]; X static unsigned char ans; X /* move to boot sector */ X if (lseek(fd, (long) MSECSIZ, 0) < 0) { X perror("init: lseek"); X exit(1); X } X /* read the first FAT sector */ X if (read(fd, buf, MSECSIZ) != MSECSIZ) { X perror("init: read"); X exit(1); X } X ans = *buf; X return(ans); X} X X/* X * Read the Boot Sector to figure out the DOS version. X */ X Xchar Xget_dos_ver() X{ X unsigned char bootbuf[MSECSIZ]; X static char ans; X /* move to boot sector */ X if (lseek(fd, 0L, 0) < 0) { X perror("init: lseek"); X exit(1); X } X /* read the boot sector */ X if (read(fd, bootbuf, MSECSIZ) != MSECSIZ) { X perror("init: read"); X exit(1); X } X ans = *(bootbuf+10); X return(ans); X} SHAR_EOF if test 5957 -ne "`wc -c < 'init.c'`" then echo shar: "error transmitting 'init.c'" '(should have been 5957 characters)' fi fi echo shar: "extracting 'isdir.c'" '(917 characters)' if test -f 'isdir.c' then echo shar: "will not over-write existing file 'isdir.c'" else sed 's/^X//' << \SHAR_EOF > 'isdir.c' X/* X * Test to see if a filename is a directory. Subdir() has to be X * run first... Returns 1 if true. X */ X X#include <stdio.h> X#include "msdos.h" X Xextern int dir_entries; X Xint Xisdir(path) Xchar *path; X{ X int entry; X char *newname, *unixname(), *strncpy(), name[9], ext[4]; X struct directory *dir, *search(); X /* no path */ X if (*path == NULL) X return(0); X X for (entry=0; entry<dir_entries; entry++) { X dir = search(entry); X /* if empty */ X if (dir->name[0] == NULL) X break; X /* if erased */ X if (dir->name[0] == 0xe5) X continue; X /* skip if not a directory */ X if (!(dir->attr & 0x10)) X continue; X strncpy(name, dir->name, 8); X name[8] = NULL; X strncpy(ext, dir->ext, 3); X ext[3] = NULL; X newname = unixname(name, ext); X if (!strcmp(newname, path)) X return(1); X } X /* if "." or ".." fails, then root */ X if (!strcmp(path, ".") || !strcmp(path, "..")) X return(1); X return(0); X} SHAR_EOF if test 917 -ne "`wc -c < 'isdir.c'`" then echo shar: "error transmitting 'isdir.c'" '(should have been 917 characters)' fi fi echo shar: "extracting 'match.c'" '(1894 characters)' if test -f 'match.c' then echo shar: "will not over-write existing file 'match.c'" else sed 's/^X//' << \SHAR_EOF > 'match.c' X/* X * Do shell-style pattern matching for '?', '\', '[..]', and '*' wildcards. X * Not idiot proof! Returns 1 if match, 0 if not. X * X * Ideas for this routine were taken from a program by Rich Salz, mirror!rs X */ X X#include <stdio.h> X Xint Xmatch(s, p) Xchar *s; /* string to match */ Xchar *p; /* pattern */ X{ X int matched, reverse; X char first, last; X X for ( ; *p != NULL; s++, p++) { X switch (*p) { X /* Literal match with next character */ X case '\\': X p++; X default: X if (*s != *p) X return(0); X break; X /* match any one character */ X case '?': X if (*s == NULL) X return(0); X break; X /* match everything */ X case '*': X /* if last char in pattern */ X if (*++p == NULL) X return(1); X /* search for next char in pattern */ X matched = 0; X while (*s != NULL) { X if (*s == *p) { X matched = 1; X if (!strcmp(s+1,p+1)) X break; X } X s++; X } X if (!matched) X return(0); X s--; X p--; X break; X /* match range of characters */ X case '[': X first = NULL; X matched = 0; X reverse = 0; X while (*++p != ']') { X if (*p == '^') { X reverse = 1; X p++; X } X first = *p; X if (first == ']' || first == NULL) { X fprintf(stderr, "match: Malformed regular expression\n"); X return(0); X } X /* if 2nd char is '-' */ X if (*(p+1) == '-') { X p++; X /* set last to 3rd char ... */ X last = *++p; X if (last == ']' || last == NULL) { X fprintf(stderr, "match: Malformed regular expression\n"); X return(0); X } X /* test the range of values */ X if (*s>=first && *s<=last) { X matched = 1; X p++; X break; X } X return(0); X } X if (*s == *p) X matched = 1; X } X if (matched && reverse) X return(0); X if (!matched) X return(0); X break; X } X } X /* string ended prematurely ? */ X if (*s != NULL) X return(0); X else X return(1); X} SHAR_EOF if test 1894 -ne "`wc -c < 'match.c'`" then echo shar: "error transmitting 'match.c'" '(should have been 1894 characters)' fi fi echo shar: "extracting 'mdel.c'" '(2580 characters)' if test -f 'mdel.c' then echo shar: "will not over-write existing file 'mdel.c'" else sed 's/^X//' << \SHAR_EOF > 'mdel.c' X/* X * Delete a MSDOS file X * X * Emmet P. Gray US Army, HQ III Corps & Fort Hood X * ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV X * Directorate of Engineering & Housing X * Environmental Management Office X * Fort Hood, TX 76544-5057 X */ X X#include <stdio.h> X#include "msdos.h" X#define VERBOSE X Xint fd; /* the file descriptor for the floppy */ Xint dir_start; /* starting sector for directory */ Xint dir_len; /* length of directory (in sectors) */ Xint dir_entries; /* number of directory entries */ Xint dir_chain[25]; /* chain of sectors in directory */ Xint clus_size; /* cluster size (in sectors) */ Xint fat_len; /* length of FAT table (in sectors) */ Xint num_clus; /* number of available clusters */ Xunsigned char *fatbuf; /* the File Allocation Table */ Xchar *mcwd; /* the Current Working Directory */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int i, ismatch, entry, start, nogo, subdir(); X char *filename, *newfile, text[4], tname[9], *getname(), *unixname(); X char *strncpy(), *getpath(), *pathname, ans[10]; X void exit(); X struct directory *dir, *search(); X X if (init(2)) { X fprintf(stderr, "mdel: Cannot initialize diskette\n"); X exit(1); X } X X if (argc < 2) { X fprintf(stderr, "Usage: mdel <MSDOS file> [<MSDOS files...>]\n"); X exit(1); X } X X for (i=1; i<argc; i++) { X filename = getname(argv[i]); X pathname = getpath(argv[i]); X if (subdir(pathname)) X continue; X nogo = 0; X ismatch = 0; X for (entry=0; entry<dir_entries; entry++) { X dir = search(entry); X /* if empty */ X if (dir->name[0] == NULL) X break; X /* if erased */ X if (dir->name[0] == 0xe5) X continue; X /* if dir or volume lable */ X if ((dir->attr & 0x10) || (dir->attr & 0x08)) X continue; X strncpy(tname, dir->name, 8); X strncpy(text, dir->ext, 3); X newfile = unixname(tname, text); X /* see it if matches the pattern */ X if (match(newfile, filename)) { X#ifdef VERBOSE X printf("Removing %s\n", newfile); X#endif X ismatch = 1; X if (dir->attr & 0x01) { X while (!nogo) { X printf("mdel: '%s' is read only, erase anyway (y/n) ? ", newfile); X gets(ans); X if (ans[0] == 'y' || ans[0] == 'Y') X break; X if (ans[0] == 'n' || ans[0] == 'N') X nogo = 1; X } X if (nogo) X continue; X } X start = dir->start[1]*0x100 + dir->start[0]; X zapit(start); X dir->name[0] = 0xe5; X writedir(entry, dir); X } X } X if (!ismatch) { X fprintf(stderr, "mdel: File '%s' not found\n", filename); X continue; X } X } X /* update the FAT sectors */ X writefat(); X close(fd); X exit(0); X} SHAR_EOF if test 2580 -ne "`wc -c < 'mdel.c'`" then echo shar: "error transmitting 'mdel.c'" '(should have been 2580 characters)' fi fi echo shar: "extracting 'mdir.c'" '(4372 characters)' if test -f 'mdir.c' then echo shar: "will not over-write existing file 'mdir.c'" else sed 's/^X//' << \SHAR_EOF > 'mdir.c' X/* X * Display a MSDOS directory X * X * Emmet P. Gray US Army, HQ III Corps & Fort Hood X * ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV X * Directorate of Engineering & Housing X * Environmental Management Office X * Fort Hood, TX 76544-5057 X */ X X#include <stdio.h> X#include "msdos.h" X Xint fd; /* the file descriptor for the floppy */ Xint dir_start; /* starting sector for directory */ Xint dir_len; /* length of directory (in sectors) */ Xint dir_entries; /* number of directory entries */ Xint dir_chain[25]; /* chain of sectors in directory */ Xint clus_size; /* cluster size (in sectors) */ Xint fat_len; /* length of FAT table (in sectors) */ Xint num_clus; /* number of available clusters */ Xunsigned char *fatbuf; /* the File Allocation Table */ Xchar *mcwd; /* the current working directory */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int i, entry, files, blocks, subdir(), fargn, wide; X long size; X char name[9], ext[4], *date, *time, *convdate(), *convtime(); X char *strncpy(), *dirname, *getname(), *getpath(), *pathname, sep; X char *newfile, *filename, *malloc(), *unixname(), volume[12]; X char *strcpy(), *strcat(); X void exit(); X struct directory *dir, *search(); X X if (init(0)) { X fprintf(stderr, "mdir: Cannot initialize diskette\n"); X exit(1); X } X /* find the volume label */ X reset_dir(); X for (entry=0; entry<dir_entries; entry++) { X dir = search(entry); X strncpy(name, dir->name, 8); X strncpy(ext, dir->ext, 3); X /* if empty */ X if (dir->name[0] == NULL) X break; X /* if not volume label */ X if (!(dir->attr & 0x08)) X continue; X strcpy(volume, name); X strcat(volume, ext); X break; X } X if (volume[0] == NULL) X printf(" Volume in drive has no label\n"); X else X printf(" Volume in drive is %s\n", volume); X fargn = 1; X wide = 0; X /* first argument number */ X if (argc > 1) { X if (!strcmp(argv[1], "-w")) { X wide = 1; X fargn = 2; X } X } X /* fake an argument */ X if (argc == fargn) { X argv[argc] = "."; X argc++; X } X files = 0; X for (i=fargn; i<argc; i++) { X filename = getname(argv[i]); X pathname = getpath(argv[i]); X /* move to first guess subdirectory */ X /* required by isdir() */ X if (subdir(pathname)) X continue; X if (isdir(filename)) { X dirname = malloc(strlen(argv[i])+1); X strcpy(dirname, pathname); X if (strcmp(pathname,"/") && strcmp(pathname, "\\")) { X if (*pathname != NULL) X strcat(dirname, "/"); X } X strcat(dirname, filename); X /* move to real subdirectory */ X if (subdir(dirname)) X continue; X filename = "*"; X } X if (*filename == NULL) X filename = "*"; X if (*dirname == '/' || *dirname == '\\') X printf(" Directory for %s\n\n", dirname); X else if (!strcmp(dirname, ".")) X printf(" Directory for %s\n\n", mcwd); X else { X if (strlen(mcwd) == 1 || !strlen(dirname)) X sep = NULL; X else X sep = '/'; X printf(" Directory for %s%c%s\n\n", mcwd, sep, dirname); X } X for (entry=0; entry<dir_entries; entry++) { X dir = search(entry); X strncpy(name, dir->name, 8); X strncpy(ext, dir->ext, 3); X newfile = unixname(name, ext); X /* if empty */ X if (dir->name[0] == NULL) X break; X /* if erased */ X if (dir->name[0] == 0xe5) X continue; X /* if a volume label */ X if (dir->attr & 0x08) X continue; X if (!match(newfile, filename)) X continue; X files++; X if (wide && files != 1) { X if (!((files-1) % 5)) X putchar('\n'); X } X date = convdate(dir->date[1], dir->date[0]); X time = convtime(dir->time[1], dir->time[0]); X size = dir->size[2]*0x10000 + dir->size[1]*0x100 + dir->size[0]; X /* is a subdirectory */ X if (dir->attr & 0x10) { X if (wide) X printf("%-15.15s", name); X else X printf("%8s <DIR> %s %s\n", name, date, time); X continue; X } X if (wide) X printf("%-9.9s%-6.6s", name, ext); X else X printf("%8s %3s %8d %s %s\n", name, ext, size, date, time); X } X if (argc > 2) X putchar('\n'); X } X blocks = getfree() * MSECSIZ; X if (!files) X printf("File '%s' not found\n", filename); X else X printf(" %3d File(s) %6ld bytes free\n", files, blocks); X close(fd); X exit(0); X} X X/* X * Get the amount of free space on the diskette X */ X Xint getfree() X{ X int i; X static int total; X X total = 0; X for (i=2; i<num_clus+2; i++) { X /* if getfat returns zero */ X if (!getfat(i)) X total += clus_size; X } X return(total); X} SHAR_EOF if test 4372 -ne "`wc -c < 'mdir.c'`" then echo shar: "error transmitting 'mdir.c'" '(should have been 4372 characters)' fi fi exit 0 # End of shell archive -- Rich $alz Cronus Project, BBN Labs rsalz@bbn.com Moderator, comp.sources.unix sources@uunet.uu.net