/*** *disklib.c - disked library * *Copyright (c) 1991-1995, Gregg Jennings. All wrongs reserved. * P O Box 200, Falmouth, MA 02541-0200 * *Purpose: * Main library functions. * *Notice: * This progam may be freely used and distributed. Any distrubution * with modifications must retain the above copyright statement and * modifications noted. * No pulp-publication, in whole or in part, permitted without * permission (magazines or books). *******************************************************************************/ /* Versions 2.7 18-Mar-1995 moved find() into SEARCH.C 2.6 15-Mar-1995 file tracking stuff 2.7 05-Mar-1995 rewrote dparams() to show everything 2.6 10-Sep-1994 fixed %u on num_sectors in dparams() complier checks in dparams() 2.5 02-Sep-1994 consolodated print vs printf 2.4 18-Apr-1994 removed text to data.c 2.3 13-Mar-1994 find() changes 2.2 01-Feb-1994 'dir_cluster' test bug fix 2.1 04-Jan-1994 added Translate if !Files for startup added 'dir_cluster' help() */ #include #include #include #include #include #include #include #include #include "disked.h" #include "diskio.h" #include "mylib.h" #include "files.h" #include "keys.h" #include "error.h" #include "dpb.h" #include "dirent.h" #include "console.h" /* static functions */ static void filename(unsigned int); /* set to track, sector, head Passed pointer to string, number of values, and struct of type Msg which holds the messages to display for each value and the number of digits for each value. Modification of get() to return immediately on an 'f' or 'b'. Returns a string containing the values seperated by commas to be converted by sscanf(). Globals: Display, Radix. */ extern int set(struct Msg *str, int *t, int *s, int *h) { register int c,i,n; long l; char ts[7]; for (i = n = 0; n < 3; n++, i = 0, str++) { if (Display) print(str->msg); while ((c = input()) != '\r' && c != ' ' && c != ',') { if (n == 0 && i == 0 && (c == 'f' || c == 'b')) { output(c); /* special: Fat, Boot */ return(c); } if (c == '\b' && i != 0) /* backspace, delete number */ { output(c); /* in buffer */ output(' '); /* and on screen */ output(c); --i; /* move pointer back */ } else if (c == 0x1b || c == 3) /* ESC, ^C to abort */ return 0; /* RETURN */ else if (Radix == 16 && !isxdigit(c)) continue; else if (Radix==10 && !isdigit(c)) continue; else { output(c); ts[i++] = (char)c; /* save and echo numbers */ if (i == str->len) break; } } ts[i] = '\0'; if (i) { l = strtol(ts,NULL,Radix); /* strtol() for radix */ if (n == 0) *t = (int)l; else if (n == 1) *s = (int)l; else *h = (int)l; } if (c == '\r') break; if (!Display && n < 2) output(','); } return 1; } /* get a string for conversion to numbers Passed pointer to string, number of values, and struct of type Msg which holds the messages to display for each value and the number of digits for each value. Returns a string containing the values seperated by commas to be converted by sscanf(). Globals: Display, Radix. */ extern int get(struct Msg *str,int *one, int *two) { register int t,v; char temp[7]; for (t = 0; t < 2; t++, str++) { if (Display) print(str->msg); if (getstr(temp,str->len,(Radix == 16) ? _HEX : _DIGIT) > 0) { v = atoi(temp); if (t == 0) *one = v; else *two = v; } else return 0; /* RETURN */ if (!Display && t < 1) output(','); } return 1; } /* get - long version */ extern int getl(struct Msg *str, long *one, int *two) { register int t; int i; char temp[7]; long l; for (t = 0; t < 2; t++, str++) { if (Display) print(str->msg); if ((i = getstr(temp,str->len,(Radix == 16) ? _HEX : _DIGIT)) > 0) { l = strtol(temp,NULL,Radix); if (t == 0) *one = l; else *two = (int)l; } else if (!t && i == -3) print("%l",*one); /* putlong(*one); */ else return 0; if (!Display && t < 1) output(','); } return(1); } /* display sector header */ extern void header(void) { register unsigned int i,j; print("\nSector %lu",log_sector); i = sectortocluster(log_sector); j = clustersector(log_sector)+1; if (log_sector > (dword)data_sector) { if (Radix == 10) print(", Cluster %u:%u",i,j); else print(", Cluster %x:%x",i,j); } else { unsigned sector = (word)log_sector; if (sector < reserved_secs) { print(" BOOT"); if (reserved_secs > 1) print(" %d:%d",sector+1,reserved_secs); } else if (sector >= reserved_secs && sector <= secs_fat) print(" FAT 1 %d:%d %d-BIT", sector-reserved_secs+1,secs_fat,fat_size); else if (num_fats > 1 && sector > secs_fat && sector <= (secs_fat*num_fats)) print(" FAT 2 %d:%d %d-BIT", (sector-reserved_secs-secs_fat)+1,secs_fat,fat_size); else if (sector >= dir_sector && sector <= data_sector) print(" ROOT %d:%d",(sector-dir_sector)+1,dir_sectors); } if (!Logical) print(" (t%u,h%u,s%u)",track,head,sector); if (diskio_error) print(" "); if (Files > 0 && n_files) filename(i); } static void filename(unsigned int i) { if (log_sector > (dword)data_sector && i < num_clusters) { if (clusters[i] > 0 && (unsigned)clusters[i] <= n_files) { output(' '); print(gfile(clusters[i])); if (files[clusters[i]].dir) print(" "); } } } /* display disk drive info Serial No: Drive Size: Root Sector: Buffer Size: Sectors: Data Sector: DOS Version: Sector Size: Reserved Sectors: Number of Drives: Clusters: Hidden Sectors: Current Drive: Cluster Size: Tracks: Media: Secs/Cluster: Heads: Volume: Number FATs: Sectors: Serial ID: Secs/FAT: Sector Size: Current Dir: */ extern void dparams(char *drivedir) { print("\n"); print("\n Serial No:%s",Version); print("\t Drive Size: %lu",drive_size); print("\t Root Sector: %u",dir_sector); print("\n Buffer Size: %u",max_bytes); print("\t Sectors: 0-%lu",num_sectors-1); print("\t Data Sector: %u",data_sector); #if defined(_MSC_VER) print("\n DOS Version: %d.%d.%d",_osmajor,_osminor,_osmode); #elif defined(__WATCOM__) print("\n DOS Version: %d.%d.%d",_osmajor,_osminor,_osmode); #else print("\n DOS Version: %d.%d",_osmajor,_osminor); #endif print("\t Sector Size: %u",sec_size); print("\t Reserved Sectors: %u",reserved_secs); print("\n Number of Drives: %u",max_drive); print("\t Clusters: 2-%u",num_clusters); print("\t Hidden Sectors: %lu",hidden_secs); print("\n Current Drive: %c:",disk+'@'); print("\t Cluster Size: %u",cluster_size); print("\t Tracks: 0-%u",max_track); print("\n Media: %s",format); print("\t Sectors/Cluster: %u",secs_cluster); print("\t Heads: 0-%u",max_head-1); print("\n Volume: %-11.11s", (volume[0]=='\0') ? "?" : volume); print("\t Number FATs: %u",num_fats); print("\t Sectors: 1-%u",max_sector); print("\n Serial ID:"); print("\t\t Sectors/FAT: %u",secs_fat); print("\t Sector Size: %u",sec_size); print("\n Current Dir: %s",&drivedir[2]); } /* Read the next sector, display, continue. Checks console for speed control and abort. pass: direction, forward or backward. value, number of sectors ver 1.1 9/91 added +1 to kbhit loop to correct '0' bug */ extern void range(int val) { register int i; static int speed=4*50; int io; int c='4',b='4'; for (;;) { if ((io = movesector(val)) != DISK_OK) { output('\n'); printerror(Debug); if (io == DISK_NREADY) /* door open! */ break; } dumpsector(); for (i = 0; i < speed; i++) /* loop in wait */ if (kbhit()) c = input(); if (isdigit(c)) /* reset speed, the same if c */ { speed = ((c-'0')*50+1); /* did not change */ b = c; } else if (c == ' ') { input(); c = b; } else break; } } /*** *dumpsector() - display sector buffer (front-end) * * 2.4 25-Nov-1994 BigScreen reference * 2.3 01-Apr-1994 no '\n' if !Partial * 2.2 01-Feb-1994 (dir_cluster && ) addtition * 2.1 04-Jan-1994 added Translate if !Files for startup ****/ extern void dumpsector(void) { int i; word sector; i = sectortocluster(log_sector); sector = (word)log_sector; if (Partial) output('\n'); header(); if (Translate) if ( (Files && clusters[i] > 0 && files[clusters[i]].dir) || (sector >= dir_sector && sector <= data_sector) || (dir_cluster && sectortocluster(log_sector) == dir_cluster) ) { dumpdir(sec_buf,sec_size); return; } if (!Ascii) { if (BigScreen) dump(sec_buf,0,sec_size,sec_size,Radix); else if (Partial) dump(sec_buf,0,sec_size,128,Radix); else dumpf(sec_buf,sec_size,Radix); } else view(sec_buf,0,sec_size,NOPAUSE,Radix); if (Partial || Ascii) output('\n'); } /*** * display databuffer, displaying all non-printable * characters enclosed in <> * * Another complicated, horrible looking function. * * 0.1 15-Mar-1995 ft_track ****/ view( register unsigned char *buffer, /* array of data */ unsigned int bfptr, /* index into array */ unsigned int bufend, /* size of array */ int pause, int base) { register int c; int length; int p,n,nn,np; p = n = nn = np = 0; output('\n'); if (pause) { length = 21; if (ft_track) { long l = filebytes(); if (base == 10) print("%ld:\n",(long)bfptr + l); else print("%lx:\n",(long)bfptr + l); } else { if (base == 10) print("%u:\n",bfptr); else print("%x:\n",bfptr); } } else { length=sec_size; output('\n'); } do { c = (int)buffer[bfptr++]; if (bfptr > bufend) { bfptr = 0; break; } if (p > 75) { p = 0; ++n; ++nn; ++np; } if (!isprint(c) && !isspace(c)) { if (Strip) /* do we strip? */ continue; if (Mask) /* do we mask ? */ c&=0x7f; else if (Convert) /* do we convert? */ { print("<%02x>",c); p+=4; continue; } } if (c==7 || c==255 || c==0 || c==8) continue; if (c=='\n') { n++; ++nn; p=0; } if (c!='\r') { output(c); p++; } } while (n