home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume11 / mtools / part02 / mread.c < prev    next >
C/C++ Source or Header  |  1987-08-27  |  5KB  |  202 lines

  1. /*
  2.  * Read (copy) a MSDOS file to Unix
  3.  *
  4.  * Emmet P. Gray            US Army, HQ III Corps & Fort Hood
  5.  * ...!ihnp4!uiucuxc!fthood!egray    Attn: AFZF-DE-ENV
  6.  *                     Directorate of Engineering & Housing
  7.  *                     Environmental Management Office
  8.  *                     Fort Hood, TX 76544-5057
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14. #include "msdos.h"
  15.  
  16. int fd;                /* the file descriptor for the floppy */
  17. int dir_start;            /* starting sector for directory */
  18. int dir_len;            /* length of directory (in sectors) */
  19. int dir_entries;        /* number of directory entries */
  20. int dir_chain[25];        /* chain of sectors in directory */
  21. int clus_size;            /* cluster size (in sectors) */
  22. int fat_len;            /* length of FAT table (in sectors) */
  23. int num_clus;            /* number of available clusters */
  24. unsigned char *fatbuf;        /* the File Allocation Table */
  25. char *mcwd;            /* the Current Working Directory */
  26.  
  27. long size;
  28. long current;
  29. int textmode = 0;
  30. int nowarn = 0;
  31.  
  32. main(argc, argv)
  33. int argc;
  34. char *argv[];
  35. {
  36.     extern int optind;
  37.     extern char *optarg;
  38.     int fat, i, ismatch, entry, subdir(), single, c, oops;
  39.     char *filename, *newfile, text[4], tname[9], *getname(), *unixname();
  40.     char *strncpy(), *pathname, *getpath(), *target, *tmp, *malloc();
  41.     char *strcat(), *strcpy();
  42.     void perror(), exit();
  43.     struct directory *dir, *search();
  44.     struct stat stbuf;
  45.  
  46.     if (init(0)) {
  47.         fprintf(stderr, "mread: Cannot initialize diskette\n");
  48.         exit(1);
  49.     }
  50.                     /* get command line options */
  51.     oops = 0;
  52.     while ((c = getopt(argc, argv, "tn")) != EOF) {
  53.         switch(c) {
  54.             case 't':
  55.                 textmode = 1;
  56.                 break;
  57.             case 'n':
  58.                 nowarn = 1;
  59.                 break;
  60.             default:
  61.                 oops = 1;
  62.                 break;
  63.         }
  64.     }
  65.  
  66.     if (oops || (argc - optind) < 2) {
  67.         fprintf(stderr, "Usage: mread [-t|-n] <MSDOS file> <Unix file>\n");
  68.         fprintf(stderr, "    or mread [-t|-n] <MSDOS file> [<MSDOS files...>] <Unix directory>\n");
  69.         exit(1);
  70.     }
  71.                     /* only 1 file to copy... */
  72.     single = 1;
  73.     target = argv[argc-1];
  74.                     /* ...unless last arg is a directory */
  75.     if (!stat(target, &stbuf)) {
  76.         if (stbuf.st_mode & 040000)
  77.             single = 0;    
  78.     }
  79.  
  80.     for (i=optind; i<argc-1; i++) {
  81.         filename = getname(argv[i]);
  82.         pathname = getpath(argv[i]);
  83.         if (subdir(pathname))
  84.             continue;
  85.         ismatch = 0;
  86.         for (entry=0; entry<dir_entries; entry++) {
  87.             dir = search(entry);
  88.                     /* if empty */
  89.             if (dir->name[0] == NULL)
  90.                 break;
  91.                     /* if erased */
  92.             if (dir->name[0] == 0xe5)
  93.                 continue;
  94.                     /* if dir or volume lable */
  95.             if ((dir->attr & 0x10) || (dir->attr & 0x08))
  96.                 continue;
  97.             strncpy(tname, dir->name, 8);
  98.             strncpy(text, dir->ext, 3);
  99.             newfile = unixname(tname, text);
  100.             fat = dir->start[1]*0x100 + dir->start[0];
  101.             size = dir->size[2]*0x10000 + dir->size[1]*0x100 + dir->size[0];
  102.                     /* if single file */
  103.             if (single) {
  104.                 if (!strcmp(newfile, filename)) {
  105.                     readit(fat, target);
  106.                     ismatch = 1;
  107.                     break;
  108.                 }
  109.             }
  110.                     /* if multiple files */
  111.             else {
  112.                 if (match(newfile, filename)) {
  113.                     printf("Copying %s\n", newfile);
  114.                     tmp = malloc(strlen(target)+1+strlen(newfile)+1);
  115.                     strcpy(tmp, target);
  116.                     strcat(tmp, "/");
  117.                     strcat(tmp, newfile);
  118.                     readit(fat, tmp);
  119.                     ismatch = 1;
  120.                 }
  121.             }
  122.         }
  123.         if (!ismatch) {
  124.             fprintf(stderr, "mread: File '%s' not found\n", filename);
  125.             continue;
  126.         }
  127.     }
  128.     close(fd);
  129.     exit(0);
  130. }
  131.  
  132. readit(fat, target)
  133. int fat;
  134. char *target;
  135. {
  136.     char ans[10];
  137.     void exit();
  138.     FILE *fp;
  139.  
  140.     current = 0L;
  141.     if (!nowarn) {
  142.         if (!access(target, 0)) {
  143.             while (1) {
  144.                 printf("File '%s' exists, overwrite (y/n) ? ", target);
  145.                 gets(ans);
  146.                 if (ans[0] == 'n' || ans[0] == 'N')
  147.                     return;
  148.                 if (ans[0] == 'y' || ans[0] == 'Y')
  149.                     break;
  150.             }
  151.         }
  152.     }
  153.  
  154.     if (!(fp = fopen(target, "w"))) {
  155.         fprintf(stderr, "mread: Can't open '%s' for write\n", target);
  156.         return;
  157.     }
  158.  
  159.     while (1) {
  160.         getcluster(fat, fp);
  161.                     /* get next cluster number */
  162.         fat = getfat(fat);
  163.         if (fat == -1) {
  164.             fprintf(stderr, "mread: FAT problem\n");
  165.             exit(1);
  166.         }
  167.                     /* end of cluster chain */
  168.         if (fat >= 0xff8)
  169.             break;
  170.     }
  171.     fclose(fp);
  172.     return;
  173. }
  174.  
  175. getcluster(num, fp)            /* read a cluster */
  176. int num;
  177. FILE *fp;
  178. {
  179.     int i, buflen, start;
  180.     void exit(), perror();
  181.     char buf[1024];
  182.  
  183.     start = (num - 2)*clus_size + dir_start + dir_len;
  184.     move(start);
  185.  
  186.     buflen = clus_size * MSECSIZ;
  187.     if (read(fd, buf, buflen) != buflen) {
  188.         perror("getcluster: read");
  189.         exit(1);
  190.     }
  191.                     /* stop at size not EOF marker */
  192.     for (i=0; i<buflen; i++) {
  193.         current++;
  194.         if (current > size) 
  195.             break;
  196.         if (textmode && buf[i] == '\r')
  197.             continue;
  198.         fputc(buf[i], fp);
  199.     }
  200.     return;
  201. }
  202.