home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload / ShartewareOverload.cdr / progm / cpgms.zip / FLPYFIX.C < prev    next >
C/C++ Source or Header  |  1985-11-17  |  6KB  |  205 lines

  1. /*
  2.       This program reads from a floppy disk drive and copies
  3.       all files with non-deleted directory entries to the
  4.       currently logged-in drive.  */
  5. #include "stdio.h"
  6. #define EOF 0x1a
  7. #define ERROR 0
  8. #define CPMEOF 0X1A
  9. #define SECSIZE 512
  10. #define NULL 0
  11. #define EOS  0
  12. #define DeSmet 1
  13.  
  14. struct {
  15.     char dtype;   /* drive type */
  16.     int nsides;   /* # of sides */
  17.     int nsecpt;   /* # of sectors/track */
  18.     int nfats;    /* # of sectors/FAT (file allocation table) */
  19.     int nbits;    /* # of bits/FAT entry (12 or 16) */
  20.     int ndirs;    /* # of sectors/Root Directory */
  21.     int nspcl;    /* # of sectors/Cluster */
  22.     int ndire;      /* # of directory entries */
  23.   } dtbl[]  = {{0xFF,2,8,1,12,7,2,112},    /* 2-sided, 8-trks */
  24.            {0xFE,1,8,1,12,4,1,64},           /* 1-sided, 8-trks */
  25.            {0xFD,2,9,2,12,7,2,112},        /* 2-sided, 9-trks */
  26.            {0xFC,1,9,2,12,4,1,64},           /* 1-sided, 9-trks */
  27.            {0xF9,2,15,7,12,14,1,224},      /* 2-sided, 15-trks */
  28.            {0xF8,0,0,0,0,16,0,512},        /* Hard disk */
  29.            {0x00,0,0,0,0,0,0,0} };           /* Invalid entry */
  30. int mtype;            /* index to prior table */
  31.  
  32. struct dir {
  33.     char fn[8];        /* filename */
  34.     char ext[3];        /* extension */
  35.     char attr;        /* file attributes */
  36.     char res1[10];        /* reserved by IBM */
  37.     int dtime;        /* time of day of update */
  38.     int ddate;        /* date of update */
  39.     int dclust;        /* starting cluster */
  40.     long dsize;        /* file size in bytes */
  41.   } direct[14*SECSIZE/32];
  42. int dirndx;            /* index for above tbl */
  43.  
  44. /*                               */
  45. /*  equates below are for field attr in direct above   */
  46. /*                               */
  47. #define RO  0x01            /* Read Only */
  48. #define HID 0x02            /* Hidden */
  49. #define SYS 0x04            /* System */
  50. #define VOL 0x08            /* Volume Id */
  51. #define DIR 0x10            /* Sub-directory */
  52. #define ARC 0x20            /* Has been archived */
  53.  
  54. char fattbl[7*SECSIZE];
  55. char buffer[2*SECSIZE], lstrng[15];
  56. int indrv;
  57.  
  58. main(argc, argv)
  59. int argc;
  60. char *argv[];
  61. {
  62.     int loadtbls(), outdrv;
  63.  
  64.     indrv = 0;        /* force input drive = A */
  65.     if ((outdrv = getdrv()) == indrv)
  66.     error("Current drive must not equal input drive","");
  67.  
  68.     loadtbls(indrv);    /* load FAT and directory for input drive */
  69.  
  70.     for (dirndx=0; dirndx < dtbl[mtype].ndire; dirndx++)
  71.         if ((direct[dirndx].attr & (VOL|SYS|DIR)) == 0)   /* not vol or sys */
  72.             if (direct[dirndx].fn[0] != 0xe5)       /* not empty */
  73.                 procfil();
  74. }
  75.  
  76. int loadtbls(drive)    /* load FAT and directory */
  77. int drive;
  78. {
  79.    int nsecs, lsec, ret, readabs();
  80.  
  81.    /*  get initial sector of the FAT to get Media Type */
  82.  
  83.    nsecs = 1;    /* use one sector */
  84.    lsec  = 1;    /* logical sector 1 (FAT sector 1) */
  85.    ret = readabs(drive, nsecs, lsec, buffer);
  86.    if (ret != 0) {  /* error */
  87.        xtoa(ret,lstrng);
  88.        error("Initial read failed. ret=",lstrng);
  89.    }
  90.  
  91.    /* determine the drive parameters from the Media Type */
  92.  
  93.    for (mtype=0; dtbl[mtype].dtype; mtype++)
  94.        if (dtbl[mtype].dtype == buffer[0])
  95.        break;
  96.    if (!dtbl[mtype].dtype) {
  97.        xtoa(buffer[0], lstrng);
  98.        error("Invalid Media Type in FAT.  Type = ",lstrng);
  99.    }
  100.    if (dtbl[mtype].dtype == 0xF8)
  101.        error("May not be used on a hard disk.","");
  102.  
  103.    /*  read in the entire FAT (1st copy only) */
  104.  
  105.    nsecs = dtbl[mtype].nfats;    /* required sectors */
  106.    lsec  = 1;    /* logical sector 1 (FAT sector 1) */
  107.    ret = readabs(drive, nsecs, lsec, fattbl);
  108.    if (ret != 0) {  /* error */
  109.        xtoa(ret,lstrng);
  110.        error("Read of FAT failed. ret=",lstrng);
  111.    }
  112.  
  113.    /*  read in the entire directory */
  114.  
  115.    nsecs = dtbl[mtype].ndirs;    /* required sectors */
  116.    lsec  = 1 + (2*dtbl[mtype].nfats) ;     /* directory after duplicate FAT) */
  117.    ret = readabs(drive, nsecs, lsec, direct);
  118.    if (ret != 0) {  /* error */
  119.        xtoa(ret,lstrng);
  120.        error("read of directory failed. ret=",lstrng);
  121.    }
  122.    return(ret);
  123. }
  124.  
  125. int procfil()        /* process one directory entry */
  126. {
  127.     FILE *fout;
  128.     int ret, readabs(), nbytes;
  129.     char outname[sizeof(direct[0].fn)+sizeof(direct[0].ext)+2];
  130.     char wrkstr[15], *trim();
  131.     unsigned nxtsec;         /* next sector address to process */
  132.     unsigned cluster;         /* next cluster to process */
  133.     unsigned secpclu;         /* sectors per cluster */
  134.     unsigned frstsec;         /* first logical sector */
  135.     unsigned nxtclus();
  136.     long fsize;      /* remaining size in bytes */
  137.  
  138.    /* build dataset name from directory entry */
  139.      strncpy(outname,direct[dirndx].fn,sizeof(direct[0].fn));
  140.      outname[sizeof(direct[0].fn)] = EOS;
  141.      strncpy(&wrkstr[1],direct[dirndx].ext,sizeof(direct[0].ext));
  142.      wrkstr[0] = '.';
  143.      wrkstr[sizeof(direct[0].ext)+1] = EOS;
  144.      strncat(trim(outname),wrkstr,sizeof(outname));
  145.  
  146.      puts("Copying ");
  147.      puts(outname);
  148.      puts("\n");
  149.  
  150.     /* open output dataset */
  151.      if((fout=creat(outname)) == ERR)
  152.      error("Error opening output file - ",outname);
  153.  
  154.     /* set up loop to copy file to new device */
  155.       cluster = direct[dirndx].dclust;
  156.       fsize = direct[dirndx].dsize;
  157.       secpclu = dtbl[mtype].nspcl;
  158.       frstsec = 1 + dtbl[mtype].nfats * 2 + dtbl[mtype].ndirs;
  159.       while (cluster < 0x0ff8) {       /* for 12 bit FATs only */
  160.           nxtsec = (cluster - 2) * secpclu + frstsec;
  161.  
  162.         /* Note: must read and write one CLUSTER which may
  163.             be a multiple of one sector.  */
  164.  
  165.           ret = readabs(indrv, secpclu, nxtsec, buffer);
  166.           if (ret != 0) {  /* error */
  167.               xtoa(ret,lstrng);
  168.           error("Sector read failed. ret=",lstrng);
  169.           }
  170.           if (fsize >= secpclu * SECSIZE) {
  171.               fsize -= secpclu * SECSIZE;
  172.               nbytes = secpclu * SECSIZE;
  173.           }
  174.           else
  175.               nbytes = fsize;
  176.           if(1 != fwrite(buffer,nbytes,1,fout))
  177.           error("Error writing new file","");
  178.           cluster = nxtclus(cluster);
  179.      }
  180.  
  181.     /* close output dataset */
  182.      if(close(fout) == ERR)
  183.      error("Error closing output file - ",outname);
  184. }
  185.  
  186. unsigned nxtclus(cls)
  187. unsigned cls;
  188. {
  189.     unsigned temp, ret;
  190.  
  191.     temp = cls & 0x0001;     /* remember odd vs even */
  192.     cls += cls >> 1;     /* mult by 1.5 */
  193.  
  194.   /*  Note that the bytes are stored in reverse order in memory */
  195.  
  196.     if (temp)  /* odd */
  197.         ret = (unsigned)fattbl[cls+1]*16 + ((unsigned)fattbl[cls] >> 4);
  198.     else       /* even */
  199.         ret = (unsigned)(fattbl[cls+1] & 0x0f)*256 + (unsigned)fattbl[cls];
  200.  
  201.     if (!ret)        /* if new cluster = zero, error */
  202.     error("Encountered unused cluster","");
  203.     return ret;
  204. }
  205.