Path: utzoo!utgpu!watmath!uunet!lll-winken!xanth!galaxia!lazlo!gizzmo!fthood!egray From: egray@fthood.UUCP Newsgroups: unix-pc.sources Subject: REPOST Mtools v1.6 (2 of 2) Message-ID: <6800125@fthood> Date: 16 Jul 89 15:13:00 GMT Lines: 2376 Nf-ID: #N:fthood:6800125:000:56684 Nf-From: fthood.UUCP!egray Jul 16 10:13:00 1989 This is part 2 (of 2) to the Mtools v1.6 distribution package. Emmet P. Gray US Army, HQ III Corps & Fort Hood ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV fthood!egray@uxc.cso.uiuc.edu 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: # mdel.c # mdir.c # mkentry.c # mmd.c # mrd.c # mread.c # mren.c # msdos.h # mtype.c # mwrite.c # putfat.c # search.c # subdir.c # unixname.c # This archive created: Thu Jul 6 08:08:53 1989 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'mdel.c'" '(2881 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 * ...!uunet!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 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, ismatch, entry, start, nogo, verbose, fargn; X char *filename, *newfile, text[4], tname[9], *getname(), *unixname(); X char *strncpy(), *getpath(), *pathname, ans[10]; X void exit(), zapit(), writefat(), writedir(), free(); 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 [-v] msdosfile [msdosfiles...]\n"); X exit(1); X } X if (!strcmp(argv[1], "-v")) { X verbose = 1; X fargn = 2; X } X else { X verbose = 0; X fargn = 1; X } X for (i=fargn; iname[0] == 0x0) 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 X strncpy(tname, (char *) dir->name, 8); X strncpy(text, (char *) dir->ext, 3); X tname[8] = '\0'; X text[3] = '\0'; X X newfile = unixname(tname, text); X /* see it if matches the pattern */ X if (match(newfile, filename)) { X if (verbose) X printf("Removing %s\n", newfile); 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 free(newfile); X continue; X } X } X start = dir->start[1]*0x100 + dir->start[0]; X zapit(start); X dir->name[0] = 0xe5; X writedir(entry, dir); X } X free(newfile); X } X if (!ismatch) X fprintf(stderr, "mdel: File \"%s\" not found\n", filename); X free(filename); X free(pathname); X } X /* update the FAT sectors */ X writefat(); X close(fd); X exit(0); X} SHAR_EOF if test 2881 -ne "`wc -c < 'mdel.c'`" then echo shar: "error transmitting 'mdel.c'" '(should have been 2881 characters)' fi fi echo shar: "extracting 'mdir.c'" '(4882 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 * ...!uunet!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 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, fargn, wide, faked; X long size; X char name[9], ext[4], *date, *time, *convdate(), *convtime(); X char *strncpy(), newpath[MAX_PATH], *getname(), *getpath(), *pathname; X char *newfile, *filename, *unixname(), volume[12], *sep; X char *strcpy(), *strcat(), newname[MAX_PATH], *strncat(); X void exit(), reset_dir(), free(); 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 volume[0] = '\0'; X for (entry=0; entryname[0] == 0x0) X break; X /* if not volume label */ X if (!(dir->attr & 0x08)) X continue; X X strncpy(volume, (char *) dir->name, 8); X volume[8] = '\0'; X strncat(volume, (char *) dir->ext, 3); X volume[11] = '\0'; X break; X } X if (volume[0] == '\0') 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 faked = 0; X if (argc == fargn) { X faked++; X argc++; X } X files = 0; X for (i=fargn; iname[0] == 0x0) 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 X strncpy(name, (char *) dir->name, 8); X strncpy(ext, (char *) dir->ext, 3); X name[8] = '\0'; X ext[3] = '\0'; X X newfile = unixname(name, ext); X if (!match(newfile, newname)) { X free(newfile); X continue; X } X free(newfile); X 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]*0x10000L + dir->size[1]*0x100 + dir->size[0]; X /* is a subdirectory */ X if (dir->attr & 0x10) { X if (wide) X printf("%-9.9s%-6.6s", name, ext); X else X printf("%8s %3s %s %s\n", name, ext, 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 free(filename); X free(pathname); X } X X blocks = getfree() * MSECSIZ; X if (!files) X printf("File \"%s\" not found\n", newname); 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 Xgetfree() X{ X register int i, total; X X total = 0; X for (i=2; i 'mkentry.c' X/* X * mk_entry(), grow() X */ X X#include X#include X#include "msdos.h" X Xextern int fd, dir_start, dir_len, clus_size, dir_entries; Xextern int dir_chain[25]; X X/* X * Make a directory entry. Builds a directory entry based on the X * name, attribute, starting cluster number, and size. Returns a pointer X * to the static directory structure. X */ X Xstruct directory * Xmk_entry(filename, attr, fat, size, date) Xchar *filename; Xunsigned char attr; Xint fat; Xlong size, date; X{ X int i; X char *strncpy(); X static struct directory ndir; X struct tm *now, *localtime(); X unsigned char hour, min_hi, min_low, sec; X unsigned char year, month_hi, month_low, day; X X now = localtime(&date); X strncpy((char *) ndir.name, filename, 8); X strncpy((char *) ndir.ext, filename+8, 3); X ndir.attr = attr; X for (i=0; i<10; i++) X ndir.reserved[i] = '\0'; X hour = now->tm_hour << 3; X min_hi = now->tm_min >> 3; X min_low = now->tm_min << 5; X sec = now->tm_sec / 2; X ndir.time[1] = hour + min_hi; X ndir.time[0] = min_low + sec; X year = (now->tm_year - 80) << 1; X month_hi = (now->tm_mon+1) >> 3; X month_low = (now->tm_mon+1) << 5; X day = now->tm_mday; X ndir.date[1] = year + month_hi; X ndir.date[0] = month_low + day; X ndir.start[1] = fat / 0x100; X ndir.start[0] = fat % 0x100; X ndir.size[3] = 0; /* can't be THAT large */ X ndir.size[2] = size / 0x10000L; X ndir.size[1] = (size % 0x10000L) / 0x100; X ndir.size[0] = (size % 0x10000L) % 0x100; X return(&ndir); X} X X/* X * Make a subdirectory grow in length. Only subdirectories (not root) X * may grow. Returns a 0 on success or 1 on failure (disk full). X */ X Xint Xgrow(fat) Xint fat; X{ X int i, next, last, num, sector, buflen; X unsigned char tbuf[CLSTRBUF]; X void perror(), exit(), move(); X X last = nextfat(0); X if (last == -1) X return(1); X X while (1) { X next = getfat(fat); X if (next == -1) { X fprintf(stderr, "grow: FAT problem\n"); X exit(1); X } X /* end of cluster chain */ X if (next >= 0xff8) X break; X fat = next; X } X /* mark the end of the chain */ X putfat(fat, (unsigned int) last); X putfat(last, 0xfff); X /* zero the buffer */ X buflen = clus_size * MSECSIZ; X for (i=0; i 'mmd.c' X/* X * Make a MSDOS sub directory X * X * Emmet P. Gray US Army, HQ III Corps & Fort Hood X * ...!uunet!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 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 entry, slot, fat, dot, fargn, verbose; X char *filename, *newfile, *fixname(), *strncpy(); X char *getpath(), *pathname, tname[9], text[4], *fixed, *unixname(); X void exit(), putcluster(), writefat(), writedir(), free(); X struct directory *dir, *search(), *mk_entry(); X long time(), now; X X if (init(2)) { X fprintf(stderr, "mmd: Cannot initialize diskette\n"); X exit(1); X } X X fargn = 1; X verbose = 0; X if (argc > 1) { X if (!strcmp(argv[1], "-v")) { X fargn = 2; X verbose = 1; X } X } X /* only 1 directory ! */ X if (argc != fargn+1) { X fprintf(stderr, "Usage: mmd [-v] msdosdirectory\n"); X exit(1); X } X fixed = fixname(argv[fargn], verbose); X X strncpy(tname, fixed, 8); X strncpy(text, fixed+8, 3); X tname[8] = '\0'; X text[3] = '\0'; X X filename = unixname(tname, text); X pathname = getpath(argv[fargn]); X X if (subdir(pathname)) X exit(1); X /* see if exists and get slot */ X slot = -1; X dot = 0; X for (entry=0; entryname[0] == 0x0) { X if (slot < 0) X slot = entry; X break; X } X /* if erased */ X if (dir->name[0] == 0xe5) { X if (slot < 0) X slot = entry; X continue; X } X /* if not a directory */ X if (!(dir->attr & 0x10)) X continue; X X strncpy(tname, (char *) dir->name, 8); X strncpy(text, (char *) dir->ext, 3); X tname[8] = '\0'; X text[3] = '\0'; X X newfile = unixname(tname, text); X /* save the 'dot' directory info */ X if (!strcmp(".", newfile)) X dot = dir->start[1]*0x100 + dir->start[0]; X X if (!strcmp(filename, newfile)) { X fprintf(stderr, "mmd: Directory \"%s\" already exists\n", filename); X exit(1); X } X free(newfile); X } X /* no '.' entry means root directory */ X if (dot == 0 && slot < 0) { X fprintf(stderr, "mmd: No directory slots\n"); X exit(1); X } X /* make the directory grow */ X if (dot && slot < 0) { X if (grow(dot)) { X fprintf(stderr, "mmd: Disk full\n"); X exit(1); X } X /* first slot in 'new' directory */ X slot = entry; X } X if ((fat = nextfat(0)) == -1) { X fprintf(stderr, "mmd: Disk full\n"); X exit(1); X } X /* make directory entry */ X time(&now); X dir = mk_entry(fixed, 0x10, fat, 0L, now); X writedir(slot, dir); X /* write the cluster */ X putfat(fat, 0xfff); X putcluster(fat, dot); X /* write FAT sectors */ X writefat(); X close(fd); X exit(0); X} X X/* X * Write a blank directory 'template' to the cluster starting at 'dot'. X */ X Xvoid Xputcluster(dot, dot_dot) Xint dot, dot_dot; X{ X int buflen, start; X static struct directory dirs[32]; X struct directory *mk_entry(); X void exit(), perror(), move(); X long time(), now; X X start = (dot - 2)*clus_size + dir_start + dir_len; X move(start); X X buflen = clus_size * MSECSIZ; X /* make the '.' and '..' entries */ X time(&now); X dirs[0] = *mk_entry(". ", 0x10, dot, 0L, now); X dirs[1] = *mk_entry(".. ", 0x10, dot_dot, 0L, now); X X if (write(fd, (char *) &dirs[0], buflen) != buflen) { X perror("putcluster: write"); X exit(1); X } X return; X} X X/* X * Returns next free cluster or -1 if none are available. X */ X Xint Xnextfat(last) Xint last; X{ X register int i; X X for (i=last+1; i 'mrd.c' X/* X * Delete a MSDOS sub directory X * X * Emmet P. Gray US Army, HQ III Corps & Fort Hood X * ...!uunet!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 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 ismatch, entry, start; X char *filename, *newfile, text[4], tname[9], *getname(); X char *strncpy(), *pathname, *getpath(), *unixname(); X void exit(), zapit(), writefat(), writedir(), free(); X struct directory *dir, *search(); X X if (init(2)) { X fprintf(stderr, "mrd: Cannot initialize diskette\n"); X exit(1); X } X /* only 1 directory ! */ X if (argc != 2) { X fprintf(stderr, "Usage: mrd mdsosdirectory\n"); X exit(1); X } X X filename = getname(argv[1]); X pathname = getpath(argv[1]); X if (subdir(pathname)) X exit(1); X X ismatch = 0; X for (entry=0; entryname[0] == 0x0) X break; X /* if erased */ X if (dir->name[0] == 0xe5) X continue; X /* if not dir */ X if (!(dir->attr & 0x10)) X continue; X X strncpy(tname, (char *) dir->name, 8); X strncpy(text, (char *) dir->ext, 3); X tname[8] = '\0'; X text[3] = '\0'; X X newfile = unixname(tname, text); X if (!strcmp(newfile, filename)) { X start = dir->start[1]*0x100 + dir->start[0]; X if (!isempty(start)) { X fprintf(stderr, "mrd: Directory \"%s\" is not empty\n", filename); X exit(1); X } X if (!start) { X fprintf(stderr, "mrd: Can't remove root directory\n"); X exit(1); X } X zapit(start); X dir->name[0] = 0xe5; X writedir(entry, dir); X ismatch = 1; X } X free(newfile); X } X if (!ismatch) { X fprintf(stderr, "mrd: Directory \"%s\" not found\n", filename); X exit(1); X } X /* update the FAT sectors */ X writefat(); X close(fd); X exit(0); X} X X/* X * See if directory is empty. Returns 1 if empty, 0 if not. Can't use X * subdir() and search() as it would clobber the globals. X */ X Xint Xisempty(fat) Xint fat; X{ X register int i; X int next, buflen, sector; X unsigned char tbuf[CLSTRBUF]; X void perror(), exit(), move(); X X while (1) { X sector = (fat-2)*clus_size + dir_start + dir_len; X move(sector); X buflen = clus_size * MSECSIZ; X if (read(fd, (char *) tbuf, buflen) != buflen) { X perror("isempty: read"); X exit(1); X } X /* check first character of name */ X for (i=0; i= 0xff8) X break; X fat = next; X } X return(1); X} SHAR_EOF if test 3277 -ne "`wc -c < 'mrd.c'`" then echo shar: "error transmitting 'mrd.c'" '(should have been 3277 characters)' fi fi echo shar: "extracting 'mread.c'" '(5880 characters)' if test -f 'mread.c' then echo shar: "will not over-write existing file 'mread.c'" else sed 's/^X//' << \SHAR_EOF > 'mread.c' X/* X * Read (copy) a MSDOS file to Unix X * X * Emmet P. Gray US Army, HQ III Corps & Fort Hood X * ...!uunet!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 X#include X#include X#include X#include "msdos.h" X X#define LOWERCASE 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 Xlong size; Xlong current; Xint textmode = 0; Xint nowarn = 0; X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X extern int optind; X extern char *optarg; X int fat, i, ismatch, entry, single, c, oops, mod_time; X long mod_date, convstamp(); X char *filename, *newfile, text[4], tname[9], *getname(), *unixname(); X char *strncpy(), *pathname, *getpath(), *target, tmp[MAX_PATH]; X char *strcat(), *strcpy(); X void perror(), exit(), free(); X struct directory *dir, *search(); X struct stat stbuf; X X if (init(0)) { X fprintf(stderr, "mread: Cannot initialize diskette\n"); X exit(1); X } X /* get command line options */ X oops = 0; X mod_time = 0; X while ((c = getopt(argc, argv, "tnm")) != EOF) { X switch(c) { X case 't': X textmode = 1; X break; X case 'n': X nowarn = 1; X break; X case 'm': X mod_time = 1; X break; X default: X oops = 1; X break; X } X } X X if (oops || (argc - optind) < 2) { X fprintf(stderr, "Usage: mread [-tn] msdosfile unixfile\n"); X fprintf(stderr, " or mread [-tn] msdosfile [msdosfiles...] unixdirectory\n"); X exit(1); X } X /* only 1 file to copy... */ X single = 1; X target = argv[argc-1]; X /* ...unless last arg is a directory */ X if (!stat(target, &stbuf)) { X if ((stbuf.st_mode & S_IFMT) == S_IFDIR) X single = 0; X } X /* too many arguments */ X if (single && (argc - optind) != 2) { X fprintf(stderr, "mread: too many arguments or destination directory omitted\n"); X exit(1); X } X X for (i=optind; iname[0] == 0x0) 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 X strncpy(tname, (char *) dir->name, 8); X strncpy(text, (char *) dir->ext, 3); X tname[8] = '\0'; X text[3] = '\0'; X X newfile = unixname(tname, text); X fat = dir->start[1]*0x100 + dir->start[0]; X size = dir->size[2]*0x10000L + dir->size[1]*0x100 + dir->size[0]; X if (mod_time) X mod_date = convstamp(dir->time, dir->date); X else X mod_date = 0L; X X /* if single file */ X if (single) { X if (!strcmp(newfile, filename)) { X readit(fat, target, mod_date); X ismatch = 1; X break; X } X } X /* if multiple files */ X else { X if (match(newfile, filename)) { X printf("Copying %s\n", newfile); X strcpy(tmp, target); X strcat(tmp, "/"); X strcat(tmp, newfile); X readit(fat, tmp, mod_date); X ismatch = 1; X } X } X free(newfile); X } X if (!ismatch) X fprintf(stderr, "mread: File \"%s\" not found\n", filename); X free(filename); X free(pathname); X } X close(fd); X exit(0); X} X X/* X * Decode the FAT chain given the begining FAT entry, open the named Unix X * file for write. X */ X Xint Xreadit(fat, target, mod_date) Xint fat; Xchar *target; Xlong mod_date; X{ X char ans[10]; X void exit(), getcluster(); X FILE *fp; X struct stat stbuf; X struct utimbuf { X time_t actime; X time_t modtime; X } utbuf; X X#ifdef LOWERCASE X char *c; X c = target; X while(*c) { X if (isupper(*c)) X *c = tolower(*c); X c++; X } X#endif /* LOWERCASE */ X X current = 0L; X if (!nowarn) { X if (!access(target, 0)) { X while (1) { X printf("File \"%s\" exists, overwrite (y/n) ? ", target); X gets(ans); X if (ans[0] == 'n' || ans[0] == 'N') X return; X if (ans[0] == 'y' || ans[0] == 'Y') X break; X } X /* sanity checking */ X if (!stat(target, &stbuf)) { X if ((stbuf.st_mode & S_IFREG) != S_IFREG) { X fprintf(stderr, "mread: \"%s\" is not a regular file\n", target); X return; X } X } X } X } X X if (!(fp = fopen(target, "w"))) { X fprintf(stderr, "mread: Can't open \"%s\" for write\n", target); X return; X } X X while (1) { X getcluster(fat, fp); X /* get next cluster number */ X fat = getfat(fat); X if (fat == -1) { X fprintf(stderr, "mread: FAT problem\n"); X exit(1); X } X /* end of cluster chain */ X if (fat >= 0xff8) X break; X } X fclose(fp); X /* preserve mod times ? */ X if (mod_date != 0L) { X utbuf.actime = mod_date; X utbuf.modtime = mod_date; X utime(target, &utbuf); X } X return; X} X X/* X * Read the named cluster, write to the Unix file descriptor. X */ X Xvoid Xgetcluster(num, fp) Xint num; XFILE *fp; X{ X register int i; X int buflen, start; X unsigned char buf[CLSTRBUF]; X void exit(), perror(), move(); X X start = (num - 2)*clus_size + dir_start + dir_len; X move(start); X X buflen = clus_size * MSECSIZ; X if (read(fd, (char *) buf, buflen) != buflen) { X perror("getcluster: read"); X exit(1); X } X /* stop at size not EOF marker */ X for (i=0; i size) X break; X if (textmode && buf[i] == '\r') X continue; X if (textmode && current == size && buf[i] == 0x1a) X continue; X fputc((char) buf[i], fp); X } X return; X} SHAR_EOF if test 5880 -ne "`wc -c < 'mread.c'`" then echo shar: "error transmitting 'mread.c'" '(should have been 5880 characters)' fi fi echo shar: "extracting 'mren.c'" '(3153 characters)' if test -f 'mren.c' then echo shar: "will not over-write existing file 'mren.c'" else sed 's/^X//' << \SHAR_EOF > 'mren.c' X/* X * Rename an existing MSDOS file X * X * Emmet P. Gray US Army, HQ III Corps & Fort Hood X * ...!uunet!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 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 entry, ismatch, nogo, fargn, verbose, got_it; X char *filename, *newfile, *fixname(), *strncpy(), *unixname(); X char *getpath(), *pathname, tname[9], text[4], *getname(), *target; X char *new, ans[10], *temp, *strcpy(); X void exit(), writedir(), free(); X struct directory *dir, *search(); X X if (init(2)) { X fprintf(stderr, "mren: Cannot initialize diskette\n"); X exit(1); X } X fargn = 1; X verbose = 0; X if (argc > 1) { X if (!strcmp(argv[1], "-v")) { X fargn = 2; X verbose = 1; X } X } X if (argc != fargn+2) { X fprintf(stderr, "Usage: mren [-v] sourcefile targetfile\n"); X exit(1); X } X filename = getname(argv[fargn]); X pathname = getpath(argv[fargn]); X if (subdir(pathname)) X exit(1); X X temp = getname(argv[fargn+1]); X target = fixname(argv[fargn+1], verbose); X X strncpy(tname, target, 8); X strncpy(text, target+8, 3); X tname[8] = '\0'; X text[3] = '\0'; X X new = unixname(tname, text); X nogo = 0; X /* the name supplied may be altered */ X if (strcmp(temp, new) && verbose) { X while (!nogo) { X printf("Do you accept \"%s\" as the new file name (y/n) ? ", new); 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 } X if (nogo) X exit(0); X /* see if exists and do it */ X ismatch = 0; X for (entry=0; entryname[0] == 0x0) X break; X /* if erased */ X if (dir->name[0] == 0xe5) X continue; X /* if volume label */ X if (dir->attr == 0x08) X continue; X /* you may rename a directory */ X strncpy(tname, (char *) dir->name, 8); X strncpy(text, (char *) dir->ext, 3); X tname[8] = '\0'; X text[3] = '\0'; X X newfile = unixname(tname, text); X X /* if the new name already exists */ X if (!strcmp(new, newfile)) { X fprintf(stderr, "mren: File \"%s\" already exists\n", new); X exit(1); X } X /* if the old name exists */ X if (!strcmp(filename, newfile)) { X ismatch = 1; X got_it = entry; X } X free(newfile); X } X if (!ismatch) { X fprintf(stderr, "mren: File \"%s\" not found\n", filename); X exit(1); X } X /* so go ahead and do it */ X dir = search(got_it); X strncpy((char *) dir->name, target, 8); X strncpy((char *) dir->ext, target+8, 3); X writedir(got_it, dir); X X close(fd); X exit(0); X} SHAR_EOF if test 3153 -ne "`wc -c < 'mren.c'`" then echo shar: "error transmitting 'mren.c'" '(should have been 3153 characters)' fi fi echo shar: "extracting 'msdos.h'" '(868 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 /* sector size */ X#define MDIRSIZ 32 /* directory size */ X#define CLSTRBUF 1024 /* largest cluster size */ X#define MAX_PATH 128 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 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 868 -ne "`wc -c < 'msdos.h'`" then echo shar: "error transmitting 'msdos.h'" '(should have been 868 characters)' fi fi echo shar: "extracting 'mtype.c'" '(3748 characters)' if test -f 'mtype.c' then echo shar: "will not over-write existing file 'mtype.c'" else sed 's/^X//' << \SHAR_EOF > 'mtype.c' X/* X * Display contents of a MSDOS file X * X * Emmet P. Gray US Army, HQ III Corps & Fort Hood X * ...!uunet!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 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 Xlong size; Xlong current; Xint stripmode = 0; Xint textmode = 0; X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X extern int optind; X extern char *optarg; X int fat, i, ismatch, entry, c, oops; X char *filename, *newfile, text[4], tname[9], *getname(), *unixname(); X char *strncpy(), *pathname, *getpath(); X void exit(), readit(), free(); X struct directory *dir, *search(); X X if (init(0)) { X fprintf(stderr, "mtype: Cannot initialize diskette\n"); X exit(1); X } X /* get command line options */ X oops = 0; X while ((c = getopt(argc, argv, "st")) != EOF) { X switch(c) { X case 's': X stripmode = 1; X break; X case 't': X textmode = 1; X break; X default: X oops = 1; X break; X } X } X X if (oops || (argc - optind) < 1) { X fprintf(stderr, "Usage: mtype [-st] msdosfile [msdosfiles...]\n"); X exit(1); X } X X for (i=optind; iname[0] == 0x0) X break; X /* if erased */ X if (dir->name[0] == 0xe5) X continue; X /* if dir or volume label */ X if ((dir->attr & 0x10) || (dir->attr & 0x08)) X continue; X X strncpy(tname, (char *) dir->name, 8); X strncpy(text, (char *) dir->ext, 3); X tname[8] = '\0'; X text[3] = '\0'; X X newfile = unixname(tname, text); X /* see it if matches the pattern */ X if (match(newfile, filename)) { X fat = dir->start[1]*0x100 + dir->start[0]; X size = dir->size[2]*0x10000L + dir->size[1]*0x100 + dir->size[0]; X readit(fat); X ismatch = 1; X } X free(newfile); X } X if (!ismatch) X fprintf(stderr, "mtype: File \"%s\" not found\n", filename); X free(filename); X free(pathname); X } X close(fd); X exit(0); X} X X/* X * Decode the FAT chain given the begining FAT entry. X */ X Xvoid Xreadit(fat) Xint fat; X{ X void getcluster(); X X current = 0L; X while (1) { X getcluster(fat); X /* get next cluster number */ X fat = getfat(fat); X if (fat == -1) { X fprintf(stderr, "mtype: FAT problem\n"); X exit(1); X } X /* end of cluster chain */ X if (fat >= 0xff8) X break; X } X return; X} X X/* X * Read the named cluster, output to the stdout. X */ X Xvoid Xgetcluster(num) Xint num; X{ X register int i; X int buflen, start; X unsigned char buf[CLSTRBUF]; X void exit(), perror(), move(); X X start = (num - 2)*clus_size + dir_start + dir_len; X move(start); X X buflen = clus_size * MSECSIZ; X if (read(fd, (char *) buf, buflen) != buflen) { X perror("getcluster: read"); X exit(1); X } X /* stop at size not EOF marker */ X for (i=0; i size) X break; X if (textmode && buf[i] == '\r') X continue; X if (textmode && current == size && buf[i] == 0x1a) X continue; X if (stripmode) X putchar(buf[i] & 0x7f); X else X putchar(buf[i]); X } X return; X} SHAR_EOF if test 3748 -ne "`wc -c < 'mtype.c'`" then echo shar: "error transmitting 'mtype.c'" '(should have been 3748 characters)' fi fi echo shar: "extracting 'mwrite.c'" '(8266 characters)' if test -f 'mwrite.c' then echo shar: "will not over-write existing file 'mwrite.c'" else sed 's/^X//' << \SHAR_EOF > 'mwrite.c' X/* X * Write (copy) a Unix file to MSDOS X * X * Emmet P. Gray US Army, HQ III Corps & Fort Hood X * ...!uunet!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 X#include X#include 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 Xint full = 0; Xint textmode = 0; Xint nowarn = 0; Xlong filesize; Xint need_nl = 0; X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X extern int optind; X extern char *optarg; X int i, entry, ismatch, nogo, slot, start, dot, single; X int root, c, oops, verbose, first, mod_time; X char *filename, *newfile, tname[9], text[4], *fixname(), *getname(); X char *unixname(), ans[10], *strncpy(), *pathname, *getpath(), *fixed; X char tmp[MAX_PATH], *target, *strcat(), *strcpy(); X void exit(), zapit(), writefat(), writedir(), free(); X struct directory *dir, *search(), *writeit(); X X if (init(2)) { X fprintf(stderr, "mwrite: Cannot initialize diskette\n"); X exit(1); X } X /* get command line options */ X oops = 0; X verbose = 0; X mod_time = 0; X while ((c = getopt(argc, argv, "tnvm")) != EOF) { X switch(c) { X case 't': X textmode = 1; X break; X case 'n': X nowarn = 1; X break; X case 'v': X verbose = 1; X break; X case 'm': X mod_time = 1; X break; X default: X oops = 1; X break; X } X } X X if (oops || (argc - optind) < 2) { X fprintf(stderr, "Usage: mwrite [-tnv] unixfile msdosfile\n"); X fprintf(stderr, " or mwrite [-tnv] unixfile [unixfiles...] msdosdirectory\n"); X exit(1); X } X root = 0; X if (!strcmp(argv[argc-1], "/") || !strcmp(argv[argc-1], "\\")) X root = 1; X X filename = getname(argv[argc-1]); X pathname = getpath(argv[argc-1]); X /* test if path is ok first */ X if (subdir(pathname)) X exit(1); X /* test if last argv is a dir */ X if (isdir(filename) || root) { X if (!strlen(pathname)) { X /* don't alter the presence or */ X /* absence of a leading separator */ X strcpy(tmp, filename); X } X else { X strcpy(tmp, pathname); X strcat(tmp, "/"); X strcat(tmp, filename); X } X /* subdir is not recursive */ X subdir(tmp); X single = 0; X } X else { X single = 1; X /* too many arguments */ X if ((argc - optind) != 2) { X fprintf(stderr, "mwrite: too many arguments or destination directory omitted\n"); X exit(1); X } X } X X for (i=optind; iattr & 0x10) && dir->name[0] == '.') { X dot = dir->start[1]*0x100 + dir->start[0]; X continue; X } X } X /* is empty */ X if (dir->name[0] == 0x0) { X if (slot < 0) X slot = entry; X break; X } X /* is erased */ X if (dir->name[0] == 0xe5) { X if (slot < 0) X slot = entry; X continue; X } X /* is dir or volume lable */ X if ((dir->attr & 0x10) || (dir->attr & 0x08)) X continue; X X strncpy(tname, (char *) dir->name, 8); X strncpy(text, (char *) dir->ext, 3); X tname[8] = '\0'; X text[3] = '\0'; X X newfile = unixname(tname, text); X /* if file exists, delete it first */ X if (!strcmp(target, newfile)) { X ismatch = 1; X start = dir->start[1]*0x100 + dir->start[0]; X if (nowarn) { X zapit(start); X dir->name[0] = 0xe5; X writedir(entry, dir); X if (slot < 0) X slot = entry; X } else { X while (1) { X printf("File \"%s\" exists, overwrite (y/n) ? ", target); X gets(ans); X if (ans[0] == 'n' || ans[0] == 'N') { X nogo = 1; X break; X } X if (ans[0] == 'y' || ans[0] == 'Y') { X zapit(start); X dir->name[0] = 0xe5; X writedir(entry, dir); X if (slot < 0) X slot = entry; X break; X } X } X } X } X free(newfile); X if (ismatch) X break; X } X if (nogo) { /* chickened out... */ X free(fixed); X free(target); X continue; X } X /* no '.' entry means root directory */ X if (dot == 0 && slot < 0) { X fprintf(stderr, "mwrite: No directory slots\n"); X exit(1); X } X /* make the directory grow */ X if (dot && slot < 0) { X if (grow(dot)) { X fprintf(stderr, "mwrite: Disk full\n"); X exit(1); X } X /* first entry in 'new' directory */ X slot = entry; X } X if (!single) X printf("Copying %s\n", target); X /* write the file */ X if (dir = writeit(fixed, argv[i], verbose, mod_time)) X writedir(slot, dir); X X free(fixed); X free(target); X X if (full) { X fprintf(stderr, "mwrite: Disk Full\n"); X break; X } X if (single) X break; X } X /* write FAT sectors */ X writefat(); X close(fd); X exit(0); X} X X/* X * Open the named file for write, create the cluster chain, return the X * directory structure or NULL on error. X */ X Xstruct directory * Xwriteit(fixed, path, verbose, mod_time) Xchar *fixed, *path; Xint verbose, mod_time; X{ X FILE *fp; X int fat, firstfat, oldfat; X long size, time(), now; X struct directory *dir, *mk_entry(); X struct stat stbuf; X X if (stat(path, &stbuf) < 0) { X fprintf(stderr, "mwrite: Can't stat \"%s\"\n", path); X return(NULL); X } X X if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { X if (verbose) X fprintf(stderr, "mwrite: \"%s\" is a directory\n", path); X return(NULL); X } X X if ((stbuf.st_mode & S_IFREG) != S_IFREG) { X fprintf(stderr, "mwrite: \"%s\" is not a regular file\n", path); X return(NULL); X } X filesize = stbuf.st_size; X /* preserve mod time? */ X if (mod_time) X now = stbuf.st_mtime; X else X time(&now); X X if (!(fp = fopen(path, "r"))) { X fprintf(stderr, "mwrite: Can't open \"%s\" for read\n", path); X return(NULL); X } X size = 0L; X firstfat = nextfat(0); X if (firstfat == -1) { X full = 1; X return(NULL); X } X fat = firstfat; X while (1) { X size += putcluster(fat, fp); X if (size >= filesize) { X putfat(fat, 0xfff); X break; X } X oldfat = fat; X /* get next free cluster */ X fat = nextfat(oldfat); X if (fat == -1) { X putfat(oldfat, 0xfff); X zapit(firstfat); X full = 1; X return(NULL); X } X putfat(oldfat, (unsigned int) fat); X } X fclose(fp); X dir = mk_entry(fixed, 0x20, firstfat, size, now); X return(dir); X} X X/* X * Write to the cluster from the named Unix file descriptor. X */ X Xint Xputcluster(num, fp) Xint num; XFILE *fp; X{ X int buflen, c, start, current; X unsigned char tbuf[CLSTRBUF]; X void exit(), perror(), move(); X X start = (num - 2)*clus_size + dir_start + dir_len; X move(start); X X buflen = clus_size * MSECSIZ; X /* '\n' to '\r\n' translation */ X if (textmode) { X current = 0; X if (need_nl) { X tbuf[current++] = '\n'; X need_nl = 0; X } X while (current < buflen) { X if ((c = fgetc(fp)) == EOF) { X /* put a file EOF marker */ X tbuf[current++] = 0x1a; X /* make the file appear larger */ X filesize++; X break; X } X if (c == '\n') { X tbuf[current++] = '\r'; X /* make the file appear larger */ X filesize++; X /* if at the end of the buffer */ X if (current == buflen) { X need_nl++; X break; X } X } X tbuf[current++] = c; X } X } X else { X if ((current = fread((char *) tbuf, sizeof(*tbuf), buflen, fp)) < 0) { X perror("putcluster: fread"); X exit(1); X } X } X X if (write(fd, (char *) tbuf, buflen) != buflen) { X perror("putcluster: write"); X exit(1); X } X return(current); X} X X/* X * Returns next free cluster or -1 if none are available. X */ X Xint Xnextfat(last) Xint last; X{ X register int i; X X for (i=last+1; i 'putfat.c' X/* X * putfat(), writedir(), zapit() X */ X X#include X#include "msdos.h" X Xextern int fd, fat_len, dir_chain[25]; Xextern unsigned char *fatbuf; X X/* X * Puts a code into the FAT table. Is the opposite of getfat(). No X * sanity checking is done on the code. Returns a 1 on error. X */ X Xint Xputfat(num, code) Xint num; Xunsigned int code; 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 int start; X /* which bytes contain the entry */ X start = num * 3 / 2; X if (start < 0 || start+1 > (fat_len * MSECSIZ)) X return(1); X /* (odd) not on byte boundary */ X if (num % 2) { X *(fatbuf+start) = (*(fatbuf+start) & 0x0f) + ((code << 4) & 0xf0); X *(fatbuf+start+1) = (code >> 4) & 0xff; X } X /* (even) on byte boundary */ X else { X *(fatbuf+start) = code & 0xff; X *(fatbuf+start+1) = (*(fatbuf+start+1) & 0xf0) + ((code >> 8) & 0x0f); X } X return(0); X} X X/* X * Write a directory entry. The first argument is the directory entry X * number to write to. The second is a pointer to the directory itself. X * All errors are fatal. X */ X Xvoid Xwritedir(num, dir) Xint num; Xstruct directory *dir; X{ X int skip, entry; X struct directory dirs[16]; X void exit(), perror(), move(); X /* which sector */ X skip = dir_chain[num / 16]; X X move(skip); X /* read the sector */ X if (read(fd, (char *) &dirs[0], MSECSIZ) != MSECSIZ) { X perror("writedir: read"); X exit(1); X } X /* which entry in sector */ X entry = num % 16; X /* copy the structure */ X dirs[entry] = *dir; X move(skip); X /* write the sector */ X if (write(fd, (char *) &dirs[0], MSECSIZ) != MSECSIZ) { X perror("writedir: write"); X exit(1); X } X return; X} X X/* X * Remove a string of FAT entries (delete the file). The argument is X * the beginning of the string. Does not consider the file length, so X * if FAT is corrupted, watch out! All errors are fatal. X */ X Xvoid Xzapit(fat) Xint fat; X{ X int next; X X while (1) { X /* get next cluster number */ X next = getfat(fat); X /* mark current cluster as empty */ X if (putfat(fat, 0) || next == -1) { X fprintf(stderr, "zapit: FAT problem\n"); X exit(1); X } X if (next >= 0xff8) X break; X fat = next; X } X return; X} SHAR_EOF if test 2561 -ne "`wc -c < 'putfat.c'`" then echo shar: "error transmitting 'putfat.c'" '(should have been 2561 characters)' fi fi echo shar: "extracting 'search.c'" '(1083 characters)' if test -f 'search.c' then echo shar: "will not over-write existing file 'search.c'" else sed 's/^X//' << \SHAR_EOF > 'search.c' X/* X * Search and extract a directory structure. The argument is the X * relative directory entry number (no sanity checking). It returns a X * pointer to the directory structure at that location. Attempts to X * optimize by trying to determine if the buffer needs to be re-read. X * A call to writedir() will scribble on the real buffer, so watch out! X */ X X#include X#include "msdos.h" X /* dir_chain contains the list of sectors */ X /* that make up the current directory */ Xextern int fd, dir_chain[25]; X Xstruct directory * Xsearch(num) Xint num; X{ X int skip, entry; X static int last; X static struct directory dirs[16]; X void exit(), perror(), move(); X X /* first call disables optimzation */ X if (num == 0) X last = 0; X /* which sector */ X skip = dir_chain[num / 16]; X /* don't read it if same sector */ X if (skip != last) { X move(skip); X /* read the sector */ X if (read(fd, (char *) &dirs[0], MSECSIZ) != MSECSIZ) { X perror("mread: read"); X exit(1); X } X } X last = skip; X /* which entry in sector */ X entry = num % 16; X return(&dirs[entry]); X} SHAR_EOF if test 1083 -ne "`wc -c < 'search.c'`" then echo shar: "error transmitting 'search.c'" '(should have been 1083 characters)' fi fi echo shar: "extracting 'subdir.c'" '(3775 characters)' if test -f 'subdir.c' then echo shar: "will not over-write existing file 'subdir.c'" else sed 's/^X//' << \SHAR_EOF > 'subdir.c' X/* X * subdir(), getdir(), get_chain(), reset_dir() X */ X X#include X#include "msdos.h" X Xextern int dir_chain[25], dir_start, dir_len, dir_entries, clus_size; Xextern char *mcwd; Xstatic char lastpath[MAX_PATH]; X X/* X * Parse the path names of a sub directory. Both '/' and '\' are X * valid separators. However, the use of '\' will force the operator X * to use quotes in the command line to protect '\' from the shell. X * Returns 1 on error. Attempts to optimize by remembering the last X * path it parsed X */ X Xint Xsubdir(name) Xchar *name; X{ X char *s, *tmp, tbuf[MAX_PATH], *path, *strcpy(), *strcat(); X int code; X void reset_dir(); X /* if full pathname */ X if (*name == '/' || *name == '\\') X strcpy(tbuf, name); X /* if relative to MCWD */ X else { X if (!strlen(name)) X strcpy(tbuf, mcwd); X else { X strcpy(tbuf, mcwd); X strcat(tbuf, "/"); X strcat(tbuf, name); X } X } X /* if paths are same, do nothing */ X if (!strcmp(tbuf, lastpath)) X return(0); X /* not recursive, start at root */ X reset_dir(); X strcpy(lastpath, tbuf); X /* zap the leading separator */ X tmp = tbuf; X if (*tmp == '\\' || *tmp == '/') X tmp++; X for (s = tmp; *s; ++s) { X if (*s == '\\' || *s == '/') { X path = tmp; X *s = '\0'; X if (getdir(path)) X return(1); X tmp = s+1; X } X } X code = getdir(tmp); X return(code); X} X X/* X * Find the directory and get the starting cluster. A null directory X * is ok. Returns a 1 on error. X */ X Xint Xgetdir(path) Xchar *path; X{ X int entry, start; X char *newname, *unixname(), *strncpy(), name[9], ext[4]; X struct directory *dir, *search(); X void reset_dir(), free(); X /* nothing required */ X if (*path == '\0') X return(0); X X for (entry=0; entryname[0] == 0x0) 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 X strncpy(name, (char *) dir->name, 8); X strncpy(ext, (char *) dir->ext, 3); X name[8] = '\0'; X ext[3] = '\0'; X X newname = unixname(name, ext); X if (!strcmp(newname, path)) { X start = dir->start[1]*0x100 + dir->start[0]; X /* if '..' pointing to root */ X if (!start && !strcmp(path, "..")) { X reset_dir(); X return(0); X } X /* fill in the directory chain */ X dir_entries = get_chain(start) * 16; X return(0); X } X free(newname); X } X /* if '.' or '..', must be root */ X if (!strcmp(path, ".") || !strcmp(path, "..")) { X reset_dir(); X return(0); X } X fprintf(stderr, "Path component \"%s\" is not a directory\n", path); X return(1); X} X X/* X * Fill in the global variable dir_chain. Argument is the starting X * cluster number. Info, in this variable is used by search() to X * scan a directory. An arbitrary limit of 25 sectors is placed, this X * equates to 400 entries. Returns the number of sectors in the chain. X */ X Xint Xget_chain(num) /* fill the directory chain */ Xint num; X{ X int i, next; X void exit(); X X i = 0; X while (1) { X dir_chain[i] = (num - 2)*clus_size + dir_start + dir_len; X /* sectors, not clusters! */ X if (clus_size == 2) { X dir_chain[i+1] = dir_chain[i] + 1; X i++; X } X i++; X if (i >= 25) { X fprintf(stderr, "get_chain: directory too large\n"); X exit(1); X } X /* get next cluster number */ X next = getfat(num); X if (next == -1) { X fprintf(stderr, "get_chain: FAT problem\n"); X exit(1); X } X /* end of cluster chain */ X if (next >= 0xff8) { X break; X } X num = next; X } X return(i); X} X X/* X * Reset the global variable dir_chain to the root directory. X */ X Xvoid Xreset_dir() X{ X register int i; X X for (i=0; i 'unixname.c' X/* X * unixname(), getname(), getpath() X */ X X#include X#include X#include "msdos.h" X X/* X * Get rid of spaces in a MSDOS 'raw' name (one that has come from the X * directory structure) so that it can be used for regular expression X * matching with a unix file name. Also used to 'unfix' a name that has X * been altered by fixname(). Returns a pointer to the unix style name. X */ X Xchar * Xunixname(name, ext) Xchar *name, *ext; X{ X char *s, tname[9], text[4], *strcpy(), *strcat(), *strchr(); X char *ans, *malloc(); X X strcpy(tname, name); X if (s = strchr(tname, ' ')) X *s = '\0'; X X strcpy(text, ext); X if (s = strchr(text, ' ')) X *s = '\0'; X X ans = malloc(13); X X if (*text) { X strcpy(ans, tname); X strcat(ans, "."); X strcat(ans, text); X } X else X strcpy(ans, tname); X return(ans); X} X X/* X * Get name component of filename. Translates name to upper case. Returns X * pointer to new name. X */ X Xchar * Xgetname(filename) Xchar *filename; X{ X char *s, *ans, *malloc(), *temp, *strcpy(), *strrchr(); X char buf[MAX_PATH]; X X strcpy(buf, filename); X temp = buf; X /* find the last separator */ X if (s = strrchr(temp, '/')) X temp = s+1; X if (s = strrchr(temp, '\\')) X temp = s+1; X /* xlate to upper case */ X for (s = temp; *s; ++s) { X if (islower(*s)) X *s = toupper(*s); X } X X ans = malloc((unsigned int) strlen(temp)+1); X strcpy(ans, temp); X return(ans); X} X X/* X * Get the path component of the filename. Translates to upper case. X * Returns pointer to path. Doesn't alter leading separator, always X * strips trailing separator (unless it is the path itself). X */ X Xchar * Xgetpath(filename) Xchar *filename; X{ X char *s, *temp, *ans, *malloc(), *strcpy(), *strrchr(); X char buf[MAX_PATH]; X int has_sep; X X strcpy(buf, filename); X temp = buf; X /* find last separator */ X has_sep = 0; X if (s = strrchr(temp, '/')) { X has_sep++; X temp = s; X } X if (s = strrchr(temp, '\\')) { X has_sep++; X temp = s; X } X X *temp = '\0'; X /* translate to upper case */ X for (s = buf; *s; ++s) { X if (islower(*s)) X *s = toupper(*s); X } X /* if separator alone, put it back */ X if (!strlen(buf) && has_sep) X strcpy(buf, "/"); X X ans = malloc((unsigned int) strlen(buf)+1); X strcpy(ans, buf); X return(ans); X} SHAR_EOF if test 2215 -ne "`wc -c < 'unixname.c'`" then echo shar: "error transmitting 'unixname.c'" '(should have been 2215 characters)' fi fi exit 0 # End of shell archive