home *** CD-ROM | disk | FTP | other *** search
- /***
- *setup.c - disked setup
- *
- *Copyright (c) 1991-1995, Gregg Jennings. All wrongs reserved.
- * P O Box 200, Falmouth, MA 02541-0200
- *
- *Purpose:
- * Initialization.
- *
- *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 15-Dec-1994 corrected Processor ID equate order
- 2.6 09-Nov-1994 general cleaning, comments,
- 2.5 04-Sep-1994 consolodated all extern references.
- removed some code in setup() and startup()
- and placed into functions.
- 2.4 18-Apr-1994 cleaned up extern defs
- 2.3 09-Mar-1994 hugefree() file/clusters, bump to revision
- 2.2 03-Feb-1994 added startup()
- 2.1 04-Jan-1994 added get_volume()
-
-
- Notes: The startup code (startup()) is just plain confusing.
- It will probably be the last to be cleaned up.
-
- Also: the logdisk() functions return DISKIO for no errors,
- less than DISKIO for warnings, and greater than DISKIO
- for unrecoverable errors. I forgot this once and
- totally messed things up!
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <string.h>
- #include <ctype.h>
- #include <direct.h>
- #ifdef __BORLANDC__
- #include <conio.h>
- #endif
-
- #include "disked.h"
- #include "diskio.h"
- #include "files.h"
- #include "mylib.h"
- #include "alloc.h"
- #include "error.h"
- #include "direct.h"
- #include "console.h"
-
- /* globals referenced here
-
- All of the DISKED configuration switches (mixed case
- identifiers), all of the "start-up" variables (for
- initial sector position, control switches.
- Some of the DISKIO globals.
-
- error, err_msg[] ERROR.C
- enum DISKIO_RETURNS DISKIO.H
- comspec[],promptvar[] DISKED.C
-
- (probably more)
- */
-
- /* gloabls defined here */
-
- /* version nu. */
-
- const char * const Version=" 2.9."
-
- #ifdef _QC /* Compiler ID */
- "MQ." /* keep track of compiler */
- #elif defined(__BORLANDC__) /* for BUGZZZZ! */
- "BC."
- #elif defined(_MSC_VER)
- "MC."
- #elif defined(__WATCOMC__)
- "WC."
- #else
- "XX." /* put others here and below */
- #endif
-
- #if defined(M_I386) || defined(__386__) /* Processor ID */
- "I386"; /* note order */
- #elif defined(M_I286) || defined(__286__)
- "I286";
- #elif defined(M_I8086) || defined(M_I86)
- "I86";
- #else
- "x86";
- #endif
- /* Borland does not have such defines, I edit the EXE */
- /* Watcom's WCL does not define these either! */
-
- /* error message stuff -- for the INT 24 handler */
-
- const char *harderr_list[] = {
- "Disk is write-protected",
- "Unknown unit",
- "Drive not ready",
- "Unknown command",
- "CRC error in data",
- "Bad drive-request structure length",
- "Seek error",
- "Unknown media type",
- "Sector not found",
- "Printer out of paper",
- "Write fault",
- "Read fault",
- "General failure",
- };
-
-
- /* internal data */
-
- /* copyleft stuff */
-
- static const char * const Author="Gregg Jennings";
- static const char * const Title="DISKED The DISK EDitor";
- static const char * const Copyr="(c) 1989-1995, All wrongs reserved";
- static const char * const Namep="DISKED";
-
- static const char *disked_ini="DISKED.INI";
- static const char *disked_sav="DISKED.SAV";
- static int min_mem; /* for running with an IDE */
- static int find_flag; /* find string arg */
- static char set_file[67]; /* file being set-to/tracked */
-
- /* internal functions */
-
- static void setupmem(void);
- static void set_inifile(char *arv);
- static void program_args(char **argv, int drives[], unsigned int *dsk);
- static void drive_status(int status);
- static int getdriveinfo(int *drives, unsigned int *num);
- static void do_find(void);
- static void do_set(unsigned int cdisk);
- static int do_files(void);
- static void quit(int e);
-
- #ifdef __WATCOMC__
- int _far hhandler(unsigned deverr, unsigned doserr, unsigned _far *hdr);
- #else
- void _cdecl _far hhandler(unsigned deverr, unsigned doserr, unsigned _far *hdr);
- #endif
-
- /***
- *setup - sets up everything
- *
- * args: char **argv passed to option handler
- * int drives[] gets filled with system drives (boolean)
- * UNIT *dsk gets set to current drive or to drive set
- * by command line
- *
- * Return: void
- *
- * 2.11 23-Mar-1995 returns current drive
- * 2.10 25-Nov-1994 BigScreen reference
- * 2.9 09-Nov-1994 void return
- * 2.8 02-Oct-1994 fixed error of setting current disk if drive arg
- * 2.7 08-Apr-1994 put some code in sub-functions
- * 2.6 03-Feb-1994 /s, moved stuff here (startup()) from DISKED.C
- * ver 2.5 21-Jan-1994 added +|-t
- * ver 2.4 03-Dec-1993 added /@
- * ver 2.3 20-Nov-1993 order of options parsed
- * ver 2.2 13-Nov-1993 better finding of INI file, newalloc()
- * ver 2.1 19-Apr-1992 Added /?
- ****/
-
- extern int setup(char **argv, int drives[], unsigned int *dsk)
- {
- int cdisk;
-
- /* preset all non-init-structure globals */
-
- write_to = FALSE; /* global booleans */
- files_indexed = FALSE;
- Signon = TRUE;
- Save = Restore = FALSE;
- BigScreen = FALSE;
-
- byte_cnt = 0; /* global object counters */
- n_files = 1;
- n_dirs = 1;
-
- find_flag = min_mem = 0; /* start-up flags */
- set_sector = -1L;
- dir_cluster = 0;
- set_file[0] = '\0';
-
- volume[0] = format[0] = /* others */
- fatsize[0] = '\0';
- memset(tagged,0,sizeof(tagged));
-
- /* get drive info -- set current drive and get drive count */
-
- cdisk = *dsk = getdriveinfo(drives,&max_drive);
-
- /* initialize the world */
-
- set_inifile(*argv);
- initialize(inifile);
-
- /* setup video stuff */
-
- initvideo(Output);
-
- _harderr(hhandler); /* capture INT 24 handler */
-
- program_args(argv,drives,dsk); /* check command line parameters */
- /* set disk to use if an arg */
- return cdisk;
- }
-
- /***
- *program_args - Check command line arguments, set global prameters etc.
- *
- * Args: same as for setup()
- * Return: void
- *
- ****/
-
- static void program_args(char **argv, int drives[], unsigned int *dsk)
- {
- int c;
- int tempd;
-
- if (*++argv)
- {
- do
- {
- c=tolower(**argv);
- if (c == '-') /* turn things off */
- {
- switch (*++*argv)
- {
- case '?': goto Help;
- case 'D': Debug=FALSE; break;
- case 't': Translate=FALSE; break;
- case 's': Save=FALSE; break;
- case 'r': Restore=FALSE; break;
- case 'f': Files=FALSE; break;
- case 'h': Home=FALSE; break;
- default: break;
- }
- }
- else if (c == '/') /* do/set things */
- {
- switch (*++*argv)
- {
- case 's':
- ++*argv;
- if (**argv == '\0')
- ++argv;
- switch(**argv)
- {
- case 'B':
- set_sector = 0;
- break;
- case 'F':
- set_sector = reserved_secs + 1;
- break;
- default:
- if (isdigit(**argv))
- set_sector = atoi(*argv);
- if (isalpha(**argv))
- strcpy(set_file,*argv);
- break;
- }
- break;
- case '@':
- Signon = 0;
- break;
- case 'h': /* help ! */
-
- case '?':
- Help:
- printc(Title); /* display (centered) logo */
- printc(Version);
- printc(Copyr);
- disptext(com_line_text);
- exit(0);
- break;
- case 'm': /* minimize memory */
- min_mem = 1;
- break;
- case 'x': /* set INI file name */
- ++*argv;
- if (**argv)
- strcpy(inifile,*argv);
- else if (**(argv+1))
- strcpy(inifile,*++argv);
- break;
- case 'r': /* set Restore/Save file name */
- ++*argv;
- if (**argv)
- strcpy(savfile,*argv);
- else if (**(argv+1))
- strcpy(savfile,*++argv);
- break;
- case 'f': /* find string arg */
- ++*argv;
- if (**argv) /* be careful of space after 'f' */
- {
- find_flag = 1;
- strcpy(findstr,*argv);
- }
- else if (**(argv+1))
- {
- find_flag = 1;
- strcpy(findstr,*++argv);
- }
- break;
- case '5':
- BigScreen = 1;
- break;
- default:
- break;
- }
- }
- else if (c == '+') /* turn things on */
- {
- switch (*++*argv)
- {
- case 'D': Debug=TRUE; break;
- case 't': Translate=TRUE; break;
- case 's': Save=TRUE; break;
- case 'r': Restore=TRUE; break;
- case 'f':
- if (find_flag == 1)
- find_flag = 2; /* index files AFTER find() */
- Files = TRUE;
- break;
- case 'h': Home=TRUE; break;
- default: break;
- }
- }
- else if (isalpha(c)) /* disk drive letter */
- {
- tempd=toupper(**argv)-'@'; /* make valid */
- if (drives[tempd]) /* check it */
- {
- *dsk=tempd; /* log it */
- Restore=FALSE; /* drive spec higher precedence */
- /*Save=FALSE;*/ /* than Restore */
- }
- }
- } while (*++argv);
- }
- }
-
- /***
- *getdriveinfo - makes a list of all valid drives, set the number
- * of drives
- * RETURNS current drive
- *
- * 1.0 02-Sep-1994 moved from setup()
- ****/
-
- static int getdriveinfo(int *drives, unsigned int *num)
- {
- unsigned i,tempd,cdisk;
-
- *num = 0; /* initialize */
- _dos_getdrive(&cdisk); /* get current drive */
-
- for (i = 0; i < MAX_DRIVE; i++) /* loop to verify drives */
- {
- _dos_setdrive(i,&tempd); /* try and set */
- _dos_getdrive(&tempd); /* see if it was set */
- if (i == tempd) /* if it was set */
- {
- drives[i] = TRUE; /* then the drive is real */
- ++(*num); /* increment count */
- }
- else
- drives[i] = FALSE;
- }
- _dos_setdrive(cdisk,&tempd); /* reset current disk */
-
- return cdisk;
- }
-
- /***
- *set_inifile - Form the INI filespecs.
- *
- * 1.1 29-Nov-1994 prompt variable string now global to work
- * with MSC 8.0
- *
- ****/
-
- static void set_inifile(char *argv)
- {
- unsigned i,tempd;
- char *tempc;
-
- strcpy(comspec,getenv("COMSPEC")); /* get where COMMAND.COM is */
- strcpy(promptvar,"PROMPT=");
- strcat(promptvar,getenv("PROMPT")); /* change prompt for shell */
- strcat(promptvar,"(DE)");
- putenv(promptvar);
-
- tempd = 1; /* for INI file test */
-
- if ((tempc = getenv("INIT")) != NULL)
- {
- strcpy(savfile,tempc); /* get env dir */
- strcpy(inifile,tempc);
- if (inifile[strlen(inifile)-1]!='\\')
- {
- strcat(savfile,"\\");
- strcat(inifile,"\\");
- }
- strcat(savfile,disked_sav);
- strcat(inifile,disked_ini);
- tempd = !exist(inifile);
- }
- if (tempd) /* if INI file not in dir */
- {
- if (exist(disked_ini))
- {
- strcpy(inifile,disked_ini);
- strcpy(savfile,disked_sav);
- return;
- }
- strcpy(savfile,argv); /* get where DISKED resides */
- strcpy(inifile,argv);
- i=strlen(inifile);
- inifile[--i]='I';
- inifile[--i]='N';
- inifile[--i]='I';
- i=strlen(savfile);
- savfile[--i]='V';
- savfile[--i]='A';
- savfile[--i]='S';
- }
- }
-
- /***
- *startup() - login drive and do startup stuff like index files,
- * set to particular spot, etc.
- *
- * Args: char *curdir gets set to current directory
- * UNIT cdisk current disk
- *
- * Returns: void
- *
- * NOTES: The disk to use is the global 'disk' which has been
- * previously set (by setup()).
- *
- *
- * 1.1 03-Feb-1994 set_sector
- * ver 1.0 22-Jan-1994
- ****/
-
- extern void startup(char *ccurdir, unsigned int cdisk)
- {
- int c,status;
-
- /* get current directory, and save it for exit */
-
- _getcwd(curdir,_MAX_DIR);
- _getcwd(ccurdir,_MAX_DIR);
-
- /* login drive and if error find out what to do */
-
- while ((status = logdisk(disk)) > DISK_OK)
- {
- printerror(Debug);
- if (disk == cdisk) /* if disk is current disk */
- exit(2); /* just quit */
-
- print(" %c: Use current? (or Retry) ",disk+'@');
- if ((c = input()) == 'y' || c == 'Y') /* use current drive ? */
- disk = cdisk; /* yes, try it */
- else if (tolower(c) != 'r') /* try again ? */
- exit(0); /* no, quit */
- output('\n');
- }
-
- /* allocate memory for sector buffers and file buffer */
-
- setupmem();
-
- /*
- First do Special Commands which bypass normal start-up sequence
- only one for now: /f{text}. Note that the order of /f and +|-f
- on the command line is followed.
- */
-
- if (find_flag) /* find text via command line */
- {
- do_find();
- }
- /* end of Special Commands */
- else
- {
- if (Signon == TRUE)
- disptext(signon_text); /* signon text */
-
- if (Files > 0)
- do_files(); /* index files */
-
- else if (Signon == TRUE) /* use the delay of do_files() */
- { /* for the pause */
- pause();
- output('\n');
- }
-
- if (!Files) /* didn't index so get volume label */
- get_volume(volume);
-
- do_set(cdisk); /* find out what sector to start at */
-
- if (!(Files && !Home && Translate)) /* display disk parameters */
- dparams(curdir); /* if not dir display */
-
- print("\n\n\t'/' for help");
- }
-
- /* Now display any errors */
-
- if (error.num != -1) /* if error */
- {
- output('\n'); /* place the message */
- printerror(Debug); /* before the dump */
- }
-
- drive_status(status); /* display anything weird */
-
- if (Restore)
- {
- if (Display && !Verify)
- print("restoring...");
- if (Verify && getver(" restore",0))
- getinit(savfile,INIT_RESTORE);
- else
- Restore = FALSE;
- }
- }
-
- /***
- *do_find - Search for text specified on command line.
- * The complexity is due to whether or no to index the
- * files before or after seaching (command line order).
- *
- ****/
-
- static void do_find(void)
- {
- int i;
-
- rootsector(); /* set to root */
- if (Display)
- {
- printc(Title); /* display (centered) logo */
- printc(Copyr); /* instead of drive parameters */
- }
- if (Files && find_flag == 1) /* index files first? */
- i = do_files();
- else
- i = 1;
- if (error.num != -1) /* was there an error? */
- {
- output('\n');
- printerror(Debug);
- output('\n');
- }
- if (i == 0 && Verify)
- getver(" find",MOV_YN);
-
- print("\nfind %s",findstr);
-
- if ((i = find(1,0,0)) >= 0) /* find text */
- {
- print("found at ");
- pn(i,Radix);
- }
- if (Files && find_flag == 2) /* index files now? */
- do_files();
- }
-
- /***
- *do_set - Set to the proper starting sector. More complexity
- * due to command line arguments.
- *
- * 0.1 19-Mar-1995 changed set file for filetrack()
- ****/
-
- static void do_set(unsigned int cdisk)
- {
- int i,tempd;
- long templ;
- char tempstr[67];
-
- if (Restore) /* if Restored */
- { /* read current sector */
- readsector();
- }
- else if (set_sector != -1L) /* set to a sector? */
- {
- setsector(set_sector);
- }
- else if (set_file[0] != '\0') /* set to file? */
- {
- if ((tempd = file_start(set_file)) != 0) /* if found */
- {
- setcluster(tempd); /* set to first sector */
- if (Files)
- {
- tempd = clusters[tempd];
- if ((i = filetrack(gfile(tempd),tempd)) != 1)
- print("file track error: %d",i);
- }
- }
- else
- rootsector(); /* not found */
- }
- else if (Files && !Home) /* if indexed files and not go home */
- { /* set to current directory */
- strcpy(tempstr,&curdir[2]);
- if ((tempd = findfile(tempstr)) != 0)
- setcluster(tempd);
- else
- rootsector();
- }
- else if (cdisk == disk) /* else goto current directory */
- {
- set_sector = templ = cwdstart();
- dir_cluster = sectortocluster(templ);
- setsector(templ);
- }
- else
- rootsector();
- }
-
- /***
- *do_files - Index the files.
- *
- ****/
-
- static int do_files(void)
- {
- if (Display)
- bprint(" indexing...");
- files_indexed = Files = initfiles();
- if (Display)
- clreol();
- return files_indexed;
- }
-
- /***
- *setupmem -
- *
- ****/
-
- static void setupmem(void)
- {
- unsigned u;
-
- /*
- Yeah I can make it a long and get a huge pointer for a really
- large buffer, but so far that large of a buffer has not been
- needed. Next time Im bored...
- */
-
- /* try and get memory */
-
- for (u = (min_mem) ? 8192U : 65024U ; ; u -= 512U)
- if ((data_buf = (unsigned char *)alloc(u,sizeof(char)))!=NULL)
- break;
- if (u < 512U*10U)
- quit(NO_MEM);
- max_bytes = u;
-
- /****** can only alloc sector buffer if sector size is known ******/
-
- if ((sec_buf = alloc(sec_size,sizeof(char))) == NULL)
- quit(NO_MEM);
-
- if ((save_sec = alloc(sec_size,sizeof(char))) != NULL)
- if ((spare_sec = alloc(sec_size,sizeof(char))) == NULL)
- freep(save_sec);
- }
-
- /***
- *newdisk() - consolated disk change stuff
- *
- * 1.3 23-Mar-1995 tempd != disk test for 0'ing tagged
- * ver 1.2 19-Jan-1994 'removable' test
- ****/
-
- extern int newdisk(int tempd)
- {
- int i;
- unsigned int temps;
-
- temps = sec_size; /* save current sector size */
- savesector(); /* and sector data */
- if ((i = logdisk(tempd)) > DISK_OK)
- {
- restoresector();
- disk_moved = 0;
- return 0; /* RETURN */
- }
-
- drive_status(i);
-
- if (temps != sec_size) /* new sector size */
- {
- sec_buf = newalloc(sec_buf,sec_size*sizeof(char));
- if (sec_buf == NULL)
- {
- print("\nReallocation Failure.\n");
- print("Sorry, but I am too confused to continue...\n");
- exit(3);
- }
- save_sec = newalloc(save_sec,sec_size*sizeof(char));
- spare_sec = newalloc(spare_sec,sec_size*sizeof(char));
- }
-
- _getcwd(curdir,_MAX_DIR); /* get current directory */
- n_files = 1; /* setup for files */
- n_dirs = 1;
-
- if (Files) /* if to index them */
- {
- if (files_indexed) /* if already */
- {
- hugefreep(clusters); /* free them first */
- hugefreep(files);
- }
- do_files();
- }
- if (!Files)
- get_volume(volume);
-
- set_sector = -1L; /* kill original start-sector */
-
- if (Home)
- rootsector();
- else
- {
- if (log_sector >= num_sectors)
- lastsector();
- else
- readsector();
- }
- return 1;
- }
-
- /***
- * Handler to deal with hard error codes. Since DOS is not reentrant,
- * it is not safe to use DOS calls for doing I/O within the DOS Critical
- * Error Handler (int 24h) used by _harderr. Therefore, screen output and
- * keyboard input must be done through the BIOS.
- ****/
-
- #if defined (_MSC_VER) && (_MSC_VER > 600)
- #pragma warning (disable:4100)
- #endif
- #ifdef __BORLANDC__
- #pragma warn -par
- #endif
-
- #ifdef __WATCOMC__
- int _far hhandler(unsigned deverr, unsigned doserr, unsigned _far *hdr)
- #else
- void _cdecl _far hhandler(unsigned deverr, unsigned doserr, unsigned _far *hdr)
- #endif
- {
- if (doserr <= 0x0C)
- error.msg = harderr_list[doserr];
- error.num = doserr;
- error.mod = error.func = "harderr";
- _hardretn(doserr&0xff);
- #ifdef __WATCOMC__
- return _HARDERR_IGNORE;
- #endif
- }
-
- #ifdef __BORLANDC__
- #pragma warn +par
- #endif
- #if defined (_MSC_VER) && (_MSC_VER > 600)
- #pragma warning (default:4100)
- #endif
-
-
- /* exit() shell */
-
- static void quit(int e)
- {
- print(err_msg[e]);
- exit(e);
- }
-
- /* common index files stuff */
-
- static void drive_status(int status)
- {
- if (removable && status == USE_DPB) /* floppy BOOT record bad */
- print("\nInvalid BOOT record. Using DPB.");
- if (!removable && status == USE_BOOT) /* non-floppy no DPB available */
- print("\nDPB not supported (ramdrive?)");
- }
-