elks-enhanced
public
Read
Owner: themaster
Branch: master
Commits: 6893
Updated: 2026-04-19 00:15
Git CLI clone URL
git clone https://www.xt-emporium.com/git/elks-enhanced.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
elks-enhanced
/
elkscmd
/
unused
/
mtools
/
mread.c
File editor
/* * Read (copy) a MSDOS file to Unix * * Emmet P. Gray US Army, HQ III Corps & Fort Hood * ...!uunet!uiucuxc!fthood!egray Attn: AFZF-DE-ENV * Directorate of Engineering & Housing * Environmental Management Office * Fort Hood, TX 76544-5057 */ #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include "msdos.h" #define LOWERCASE int fd; /* the file descriptor for the floppy */ int dir_start; /* starting sector for directory */ int dir_len; /* length of directory (in sectors) */ int dir_entries; /* number of directory entries */ int dir_chain[25]; /* chain of sectors in directory */ int clus_size; /* cluster size (in sectors) */ int fat_len; /* length of FAT table (in sectors) */ int num_clus; /* number of available clusters */ unsigned char *fatbuf; /* the File Allocation Table */ char *buf; /* The input buffer */ long bufsiz; /* It's size */ int maxcontig; /* In clusters */ char *mcwd; /* the Current Working Directory */ extern union bootblock bb; long size; long current; int textmode = 0; int nowarn = 0; main(argc, argv) int argc; char *argv[]; { extern int optind; extern char *optarg; int fat, i, ismatch, entry, single, c, oops, mod_time; long mod_date, convstamp(); char *filename, *newfile, text[4], tname[9], *getname(), *unixname(); char *strncpy(), *pathname, *getpath(), *target, tmp[MAX_PATH]; char *strcat(), *strcpy(); void perror(), exit(), free(); struct directory *dir, *search(); struct stat stbuf; if (init(0)) { fprintf(stderr, "mread: Cannot initialize diskette\n"); exit(1); } /* get command line options */ oops = 0; mod_time = 0; while ((c = getopt(argc, argv, "tnm")) != EOF) { switch(c) { case 't': textmode = 1; break; case 'n': nowarn = 1; break; case 'm': mod_time = 1; break; default: oops = 1; break; } } if (oops || (argc - optind) < 2) { fprintf(stderr, "Usage: mread [-tn] msdosfile unixfile\n"); fprintf(stderr, " or mread [-tn] msdosfile [msdosfiles...] unixdirectory\n"); exit(1); } /* only 1 file to copy... */ single = 1; target = argv[argc-1]; /* ...unless last arg is a directory */ if (!stat(target, &stbuf)) { if ((stbuf.st_mode & S_IFMT) == S_IFDIR) single = 0; } /* too many arguments */ if (single && (argc - optind) != 2) { fprintf(stderr, "mread: too many arguments or target dir omitted\n"); exit(1); } bufsiz = NSECT(bb.sb) * NTRACK(bb.sb) ; maxcontig = (bufsiz += clus_size - (--bufsiz) % clus_size)/clus_size; if ( (buf = (char *)malloc(bufsiz *= MSECSIZ)) == NULL ) { fprintf(stderr,"Could not allocate input buffer\n"); exit(1) ; } for (i=optind; i<argc-1; i++) { filename = getname(argv[i]); pathname = getpath(argv[i]); if (subdir(pathname)) { free(filename); free(pathname); continue; } ismatch = 0; for (entry=0; entry<dir_entries; entry++) { dir = search(entry); /* if empty */ if (dir->name[0] == 0x0) break; /* if erased */ if (dir->name[0] == 0xe5) continue; /* if dir or volume lable */ if ((dir->attr & 0x10) || (dir->attr & 0x08)) continue; strncpy(tname, (char *) dir->name, 8); strncpy(text, (char *) dir->ext, 3); tname[8] = '\0'; text[3] = '\0'; newfile = unixname(tname, text); fat = dir->start[1]*0x100 + dir->start[0]; size = dir->size[2]*0x10000L + dir->size[1]*0x100 + dir->size[0]; if (mod_time) mod_date = convstamp(dir->time, dir->date); else mod_date = 0L; /* if single file */ if (single) { if (!strcmp(newfile, filename)) { readit(fat, target, mod_date); ismatch = 1; break; } } /* if multiple files */ else { if (match(newfile, filename)) { printf("Copying %s\n", newfile); strcpy(tmp, target); strcat(tmp, "/"); strcat(tmp, newfile); readit(fat, tmp, mod_date); ismatch = 1; } } free(newfile); } if (!ismatch) fprintf(stderr, "mread: File \"%s\" not found\n", filename); free(filename); free(pathname); } close(fd); exit(0); } /* * Decode the FAT chain given the begining FAT entry, open the named Unix * file for write. */ static int readpos; int readit(fat, target, mod_date) int fat; char *target; long mod_date; { void getclusters() ; char ans[10]; void exit(); int curfat; FILE *fp; struct stat stbuf; struct utimbuf { time_t actime; time_t modtime; } utbuf; #ifdef LOWERCASE char *c; c = target; while (*c) { if (isupper(*c)) *c = tolower(*c); c++; } #endif /* LOWERCASE */ if (!nowarn) { if (!access(target, 0)) { while (1) { printf("File \"%s\" exists, overwrite (y/n) ? ", target); gets(ans); if (ans[0] == 'n' || ans[0] == 'N') return; if (ans[0] == 'y' || ans[0] == 'Y') break; } /* sanity checking */ if (!stat(target, &stbuf)) { if ((stbuf.st_mode & S_IFREG) != S_IFREG) { fprintf(stderr, "mread: \"%s\" is not a regular file\n", target); return; } } } } if (!(fp = fopen(target, "w"))) { fprintf(stderr, "mread: Can't open \"%s\" for write\n", target); return; } current = 0L; readpos = -1; for (;;) { /* * Find chain of contiguous clusters * curfat -> last in chain + 1 */ for (curfat=fat; ++curfat < fat + maxcontig && getfat(curfat-1)==curfat;) ; getclusters(fat, curfat, fp); /* get next cluster number */ fat = getfat(--curfat); if (fat == -1) { fprintf(stderr, "mread: FAT problem\n"); exit(1); } /* end of cluster chain */ if (fat >= 0xff8) break; } if (fclose(fp)) { fprintf(stderr,"Error closing %s\n",target) ; perror("close?") ; exit(1) ; } /* preserve mod times ? */ if (mod_date != 0L) { utbuf.actime = mod_date; utbuf.modtime = mod_date; utime(target, &utbuf); } return; } /* * Read the named cluster, write to the Unix file descriptor. */ void getclusters(start, end, fp) FILE *fp; { register int i; int buflen, blk; void exit(), perror(), move(); blk = (start - 2)*clus_size + dir_start + dir_len; if (blk != readpos) move(blk); buflen = (end-start) * clus_size * MSECSIZ; if (read(fd, (char *) buf, buflen) != buflen) { perror("getcluster: read"); exit(1); } readpos = blk + (end-start)*clus_size; /* stop at size not EOF marker */ if (textmode) { for (i=0; i<buflen; i++) { current++; if (current > size) break; if ( buf[i] == '\r') continue; if ( current == size && buf[i] == 0x1a) continue; putc((char) buf[i], fp); } } else { buflen = (size > buflen) ? buflen : size; if (fwrite(buf,buflen,1,fp)!=1) { perror("getclusters: fwrite") ; exit(1) ; } size -= buflen ; } return; }
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
master
Visibility
public
Your access
Read
Remote
Configured
File activity
View file history