Category : C Source Code
Archive   : CPGMS.ZIP
Filename : FLPYFIX.C

 
Output of file : FLPYFIX.C contained in archive : CPGMS.ZIP
/*
This program reads from a floppy disk drive and copies
all files with non-deleted directory entries to the
currently logged-in drive. */
#include "stdio.h"
#define EOF 0x1a
#define ERROR 0
#define CPMEOF 0X1A
#define SECSIZE 512
#define NULL 0
#define EOS 0
#define DeSmet 1

struct {
char dtype; /* drive type */
int nsides; /* # of sides */
int nsecpt; /* # of sectors/track */
int nfats; /* # of sectors/FAT (file allocation table) */
int nbits; /* # of bits/FAT entry (12 or 16) */
int ndirs; /* # of sectors/Root Directory */
int nspcl; /* # of sectors/Cluster */
int ndire; /* # of directory entries */
} dtbl[] = {{0xFF,2,8,1,12,7,2,112}, /* 2-sided, 8-trks */
{0xFE,1,8,1,12,4,1,64}, /* 1-sided, 8-trks */
{0xFD,2,9,2,12,7,2,112}, /* 2-sided, 9-trks */
{0xFC,1,9,2,12,4,1,64}, /* 1-sided, 9-trks */
{0xF9,2,15,7,12,14,1,224}, /* 2-sided, 15-trks */
{0xF8,0,0,0,0,16,0,512}, /* Hard disk */
{0x00,0,0,0,0,0,0,0} }; /* Invalid entry */
int mtype; /* index to prior table */

struct dir {
char fn[8]; /* filename */
char ext[3]; /* extension */
char attr; /* file attributes */
char res1[10]; /* reserved by IBM */
int dtime; /* time of day of update */
int ddate; /* date of update */
int dclust; /* starting cluster */
long dsize; /* file size in bytes */
} direct[14*SECSIZE/32];
int dirndx; /* index for above tbl */

/* */
/* equates below are for field attr in direct above */
/* */
#define RO 0x01 /* Read Only */
#define HID 0x02 /* Hidden */
#define SYS 0x04 /* System */
#define VOL 0x08 /* Volume Id */
#define DIR 0x10 /* Sub-directory */
#define ARC 0x20 /* Has been archived */

char fattbl[7*SECSIZE];
char buffer[2*SECSIZE], lstrng[15];
int indrv;

main(argc, argv)
int argc;
char *argv[];
{
int loadtbls(), outdrv;

indrv = 0; /* force input drive = A */
if ((outdrv = getdrv()) == indrv)
error("Current drive must not equal input drive","");

loadtbls(indrv); /* load FAT and directory for input drive */

for (dirndx=0; dirndx < dtbl[mtype].ndire; dirndx++)
if ((direct[dirndx].attr & (VOL|SYS|DIR)) == 0) /* not vol or sys */
if (direct[dirndx].fn[0] != 0xe5) /* not empty */
procfil();
}

int loadtbls(drive) /* load FAT and directory */
int drive;
{
int nsecs, lsec, ret, readabs();

/* get initial sector of the FAT to get Media Type */

nsecs = 1; /* use one sector */
lsec = 1; /* logical sector 1 (FAT sector 1) */
ret = readabs(drive, nsecs, lsec, buffer);
if (ret != 0) { /* error */
xtoa(ret,lstrng);
error("Initial read failed. ret=",lstrng);
}

/* determine the drive parameters from the Media Type */

for (mtype=0; dtbl[mtype].dtype; mtype++)
if (dtbl[mtype].dtype == buffer[0])
break;
if (!dtbl[mtype].dtype) {
xtoa(buffer[0], lstrng);
error("Invalid Media Type in FAT. Type = ",lstrng);
}
if (dtbl[mtype].dtype == 0xF8)
error("May not be used on a hard disk.","");

/* read in the entire FAT (1st copy only) */

nsecs = dtbl[mtype].nfats; /* required sectors */
lsec = 1; /* logical sector 1 (FAT sector 1) */
ret = readabs(drive, nsecs, lsec, fattbl);
if (ret != 0) { /* error */
xtoa(ret,lstrng);
error("Read of FAT failed. ret=",lstrng);
}

/* read in the entire directory */

nsecs = dtbl[mtype].ndirs; /* required sectors */
lsec = 1 + (2*dtbl[mtype].nfats) ; /* directory after duplicate FAT) */
ret = readabs(drive, nsecs, lsec, direct);
if (ret != 0) { /* error */
xtoa(ret,lstrng);
error("read of directory failed. ret=",lstrng);
}
return(ret);
}

int procfil() /* process one directory entry */
{
FILE *fout;
int ret, readabs(), nbytes;
char outname[sizeof(direct[0].fn)+sizeof(direct[0].ext)+2];
char wrkstr[15], *trim();
unsigned nxtsec; /* next sector address to process */
unsigned cluster; /* next cluster to process */
unsigned secpclu; /* sectors per cluster */
unsigned frstsec; /* first logical sector */
unsigned nxtclus();
long fsize; /* remaining size in bytes */

/* build dataset name from directory entry */
strncpy(outname,direct[dirndx].fn,sizeof(direct[0].fn));
outname[sizeof(direct[0].fn)] = EOS;
strncpy(&wrkstr[1],direct[dirndx].ext,sizeof(direct[0].ext));
wrkstr[0] = '.';
wrkstr[sizeof(direct[0].ext)+1] = EOS;
strncat(trim(outname),wrkstr,sizeof(outname));

puts("Copying ");
puts(outname);
puts("\n");

/* open output dataset */
if((fout=creat(outname)) == ERR)
error("Error opening output file - ",outname);

/* set up loop to copy file to new device */
cluster = direct[dirndx].dclust;
fsize = direct[dirndx].dsize;
secpclu = dtbl[mtype].nspcl;
frstsec = 1 + dtbl[mtype].nfats * 2 + dtbl[mtype].ndirs;
while (cluster < 0x0ff8) { /* for 12 bit FATs only */
nxtsec = (cluster - 2) * secpclu + frstsec;

/* Note: must read and write one CLUSTER which may
be a multiple of one sector. */

ret = readabs(indrv, secpclu, nxtsec, buffer);
if (ret != 0) { /* error */
xtoa(ret,lstrng);
error("Sector read failed. ret=",lstrng);
}
if (fsize >= secpclu * SECSIZE) {
fsize -= secpclu * SECSIZE;
nbytes = secpclu * SECSIZE;
}
else
nbytes = fsize;
if(1 != fwrite(buffer,nbytes,1,fout))
error("Error writing new file","");
cluster = nxtclus(cluster);
}

/* close output dataset */
if(close(fout) == ERR)
error("Error closing output file - ",outname);
}

unsigned nxtclus(cls)
unsigned cls;
{
unsigned temp, ret;

temp = cls & 0x0001; /* remember odd vs even */
cls += cls >> 1; /* mult by 1.5 */

/* Note that the bytes are stored in reverse order in memory */

if (temp) /* odd */
ret = (unsigned)fattbl[cls+1]*16 + ((unsigned)fattbl[cls] >> 4);
else /* even */
ret = (unsigned)(fattbl[cls+1] & 0x0f)*256 + (unsigned)fattbl[cls];

if (!ret) /* if new cluster = zero, error */
error("Encountered unused cluster","");
return ret;
}


  3 Responses to “Category : C Source Code
Archive   : CPGMS.ZIP
Filename : FLPYFIX.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/