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

  1. /*
  2.  * Write (copy) a Unix file to MSDOS
  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. int full = 0;
  28. int textmode = 0;
  29. int nowarn = 0;
  30. int filesize;
  31.  
  32. main(argc, argv)
  33. int argc;
  34. char *argv[];
  35. {
  36.     extern int optind;
  37.     extern char *optarg;
  38.     int i, entry, ismatch, nogo, slot, start, dot, subdir(), single;
  39.     int isdir(), root, c, oops;
  40.     char *filename, *newfile, tname[9], text[4], *fixname(), *getname();
  41.     char *unixname(), ans[10], *strncpy(), *pathname, *getpath(), *fixed;
  42.     char *tmp, *malloc(), *strcat(), *strcpy();
  43.     void exit();
  44.     struct directory *dir, *search(), *writeit();
  45.  
  46.     if (init(2)) {
  47.         fprintf(stderr, "mwrite: 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: mwrite [-t|-n] <Unix file> <MSDOS file>\n");
  68.         fprintf(stderr, "    or mwrite [-t|-n] <Unix file> [<Unix files...>] <MSDOS directory>\n");
  69.         exit(1);
  70.     }
  71.     root = 0;
  72.     if (!strcmp(argv[argc-1], "/") || !strcmp(argv[argc-1], "\\"))
  73.         root = 1;
  74.     filename = getname(argv[argc-1]);
  75.     pathname = getpath(argv[argc-1]);
  76.                     /* test if path is ok first */
  77.     if (subdir(pathname))
  78.         exit(1);
  79.                     /* test if last argv is a dir */
  80.     if (isdir(filename) || root) {
  81.         if (!strlen(pathname)) {
  82.                     /* don't alter the presence or */
  83.                     /* absence of a leading separator */
  84.             tmp = malloc(strlen(filename)+1);
  85.             strcpy(tmp, filename);
  86.         }
  87.         else {
  88.             tmp = malloc(strlen(pathname)+1+strlen(filename)+1);
  89.             strcpy(tmp, pathname);
  90.             strcat(tmp, "/");
  91.             strcat(tmp, filename);
  92.         }
  93.                     /* subdir is not recursive */
  94.         subdir(tmp);
  95.         single = 0;
  96.     }
  97.     else
  98.         single = 1;
  99.  
  100.     for (i=optind; i<argc-1; i++) {
  101.         if (single) {
  102.             fixed = fixname(argv[argc-1]);
  103.             filename = unixname(fixed, fixed+8);
  104.         }
  105.         else {
  106.             fixed = fixname(argv[i]);
  107.             filename = unixname(fixed, fixed+8);
  108.             printf("Copying %s\n", filename);
  109.         }
  110.                     /* see if exists and get slot */
  111.         ismatch = 0;
  112.         slot = -1;
  113.         dot = 0;
  114.         nogo = 0;
  115.         for (entry=0; entry<dir_entries; entry++) {
  116.             dir = search(entry);
  117.                     /* is empty */
  118.             if (dir->name[0] == NULL) {
  119.                 if (slot < 0)
  120.                     slot = entry;
  121.                 break;
  122.             }
  123.                     /* is erased */
  124.             if (dir->name[0] == 0xe5) {
  125.                 if (slot < 0)
  126.                     slot = entry;
  127.                 continue;
  128.             }
  129.             strncpy(tname, dir->name, 8);
  130.             strncpy(text, dir->ext, 3);
  131.             newfile = unixname(tname, text);
  132.                     /* save the '.' entry info */
  133.             if ((dir->attr & 0x10) && !strcmp(".", newfile)) {
  134.                 dot = dir->start[1]*0x100 + dir->start[0];
  135.                 continue;
  136.             }
  137.                     /* is dir or volume lable */
  138.             if ((dir->attr & 0x10) || (dir->attr & 0x08))
  139.                 continue;
  140.                     /* if file exists, delete it first */
  141.             if (!strcmp(filename, newfile)) {
  142.                 ismatch = 1;
  143.                 start = dir->start[1]*0x100 + dir->start[0];
  144.                 if (nowarn) {
  145.                     zapit(start);
  146.                     dir->name[0] = 0xe5;
  147.                     writedir(entry, dir);
  148.                     if (slot < 0)
  149.                         slot = entry;
  150.                 } else {
  151.                     while (1) {
  152.                         printf("File '%s' exists, overwrite (y/n) ? ", filename);
  153.                         gets(ans);
  154.                         if (ans[0] == 'n' || ans[0] == 'N') {
  155.                             nogo = 1;
  156.                             break;
  157.                         }
  158.                         if (ans[0] == 'y' || ans[0] == 'Y') {
  159.                             zapit(start);
  160.                             dir->name[0] = 0xe5;
  161.                             writedir(entry, dir);
  162.                             if (slot < 0)
  163.                                 slot = entry;
  164.                             break;
  165.                         }
  166.                     }
  167.                 }
  168.             }
  169.             if (ismatch)
  170.                 break;
  171.         }
  172.         if (nogo)        /* chickened out... */
  173.             continue;
  174.                     /* no '.' entry means root directory */
  175.         if (dot == 0 && slot < 0) {
  176.             printf(stderr, "mwrite: No directory slots\n");
  177.             exit(1);
  178.         }
  179.                     /* make the directory grow */
  180.         if (dot && slot < 0) {
  181.             if (grow(dot)) {
  182.                 fprintf(stderr, "mwrite: Disk full\n");
  183.                 exit(1);
  184.             }
  185.                     /* first entry in 'new' directory */
  186.             slot = entry;
  187.         }
  188.                     /* write the file */
  189.         dir = writeit(fixed, argv[i]);
  190.         if (dir != NULL)
  191.             writedir(slot, dir);
  192.  
  193.         if (full) {
  194.             fprintf(stderr, "mwrite: Disk Full\n");
  195.             break;
  196.         }
  197.         if (single)
  198.             break;
  199.     }
  200.                     /* write FAT sectors */
  201.     writefat();
  202.     close(fd);
  203.     exit(0);
  204. }
  205.  
  206. struct directory *
  207. writeit(fixed, path)
  208. char *fixed;
  209. char *path;
  210. {
  211.     FILE *fp;
  212.     int size, fat, firstfat, oldfat, nextfat(), putcluster(), putfat();
  213.     struct directory *mk_entry();
  214.     static struct directory *dir;
  215.     struct stat stbuf;
  216.  
  217.     if (stat(path, &stbuf) < 0) {
  218.         fprintf(stderr, "mwrite: Can't stat '%s'\n", path);
  219.         return(NULL);
  220.     }
  221.     filesize = stbuf.st_size;
  222.     if (!(fp = fopen(path, "r"))) {
  223.         fprintf(stderr, "mwrite: Can't open '%s' for read\n", path);
  224.         return(NULL);
  225.     }
  226.     size = 0;
  227.     firstfat = nextfat(0);
  228.     if (firstfat == -1) {
  229.         full = 1;
  230.         return(NULL);
  231.     }
  232.     fat = firstfat;
  233.     while (1) {
  234.         size += putcluster(fat, fp);
  235.         if (size >= filesize) {
  236.             putfat(fat, 0xfff);
  237.             break;
  238.         }
  239.         oldfat = fat;
  240.                     /* get next free cluster */
  241.         fat = nextfat(oldfat);
  242.         if (fat == -1) {
  243.             putfat(oldfat, 0xfff);
  244.             full = 1;
  245.             break;
  246.         }
  247.         putfat(oldfat, fat);
  248.     }
  249.     fclose(fp);
  250.     dir = mk_entry(fixed, 0, firstfat, size);
  251.     return(dir);
  252. }
  253.  
  254. int
  255. putcluster(num, fp)            /* write to a cluster */
  256. int num;
  257. FILE *fp;
  258. {
  259.     long start;
  260.     void exit(), perror();
  261.     int buflen, c;
  262.     static int current;
  263.     char tbuf[1024];
  264.  
  265.     start = (num - 2)*clus_size + dir_start + dir_len;
  266.     move(start);
  267.  
  268.     buflen = clus_size * MSECSIZ;
  269.                     /* '\n' to '\r\n' translation */
  270.     if (textmode) {
  271.         current = 0;
  272.         while (current < buflen) {
  273.             if ((c = fgetc(fp)) == EOF) {
  274.                     /* put a file EOF marker */
  275.                 tbuf[current] = 0x1a;
  276.                 break;
  277.             }
  278.             if (c == '\n') {
  279.                 tbuf[current++] = '\r';
  280.                 if (current == buflen)
  281.                     break;
  282.                 tbuf[current++] = '\n';
  283.                     /* make the file appear larger */
  284.                 filesize++;
  285.             }
  286.             else 
  287.                 tbuf[current++] = c;
  288.         }
  289.     }
  290.     else {
  291.         if ((current = fread(tbuf, sizeof(char), buflen, fp)) < 0) {
  292.             perror("putcluster: fread");
  293.             exit(1);
  294.         }
  295.                     /* all files get an EOF marker */
  296.         if (current != buflen) 
  297.             tbuf[current+1] = 0x1a;
  298.     }
  299.     
  300.     if (write(fd, tbuf, buflen) != buflen) {
  301.         perror("putcluster: write");
  302.         exit(1);
  303.     }
  304.     return(current);
  305. }
  306.  
  307. int
  308. nextfat(last)                /* returns next free cluster */
  309. int last;
  310. {
  311.     static int i;
  312.  
  313.     for (i=last+1; i<num_clus+2; i++) {
  314.         if (!getfat(i))
  315.             return(i);
  316.     }
  317.     return(-1);
  318. }
  319.