home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
C
/
FS191
/
FS0.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-24
|
19KB
|
533 lines
/* FS0.C
* main program body
* MSC6
* FS 1.9.1
* 240293
* Copyright (C) M.C.J. van Breemen, 1993, All rights reserved.
*/
#include "FS.H" /* most C header files are included here ! */
#include "xspawn.h"
/* Prototypes */
int handle_dir( char *searchstring, char *selected , int safe_mode);
void execute(char *comm, char **a, int tot_commargs, int no_return, int testing);
void main(int argc, char *argv[]);
int convcolorinfo( char colinfo );
int set_colors( char *scratch);
char *saveScrn (void);
char *restScrn(char *saveArea);
int getkey(void);
void show_error( char *message );
int save_colors_in_exe( char *imagename , int setcolorresult);
char *set_working_drive_and_dir( char *full_filename );
void interpret_params( char *imagename, int argc, char *param,
int *no_return, int *init_screen, int *testing,
int *wait, int *_useems, int *_swap,
int *keep_path, int *max_files, int *mask_argc_number,
int *safe_mode);
extern int max_files; /* max. number of files accessible */
extern short int screen_bg_color;
extern short int file_color;
extern short int directory_color;
extern short int cursor_bg_color;
extern short int cursor_file_color;
extern short int cursor_directory_color;
extern short int info_bg_color;
extern short int info_text_color;
extern short int error_text_color;
extern short int prompt_text_color;
extern short int hidden_file_color;
extern short int hidden_directory_color;
extern short int volume_label_color;
extern short int cursor_hidden_file_color;
extern short int cursor_hidden_directory_color;
extern short int cursor_volume_label_color;
/*******************************************************************************
*/
void main( int argc, char *argv[] )
{
char selected[_MAX_PATH]; /* selected file */
char mask[_MAX_PATH]; /* filter */
char scratch[_MAX_PATH]; /* temporary strings, really scratch */
int init_screen=FALSE; /* initialise display adapter */
int no_return=FALSE; /* run FS once */
int keep_path=FALSE; /* keep initial drive and directory path */
int wait=FALSE; /* wait for a keystroke before resetting screen */
int safe_mode=FALSE; /* changes to files not allowed (/N) */
int iTeller; /* counter */
int mask_argc_number=2; /* default place of mask in argument list */
char *slash; /* pointer to FSSWITCH env (we only want the first char!) */
char fsswitch; /* parameter switch character for FS */
int olddrive; /* old current drive */
char oldcwd[_MAX_PATH]; /* old current working directory */
int commarg[15]; /* initial argument list */
int tot_commargs=0; /* number of command arguments */
char *arglist[15]; /* final argument list */
struct videoconfig vc; /* video info structure */
char *savedscreen; /* pointer to saved screen memory */
char swapto[_MAX_PATH]; /* stringspace for _swappath */
struct rccoord oldpos; /* old cursor position (_setvideomode will reset to 0,0) */
int handle_dir_result;
int testing=FALSE; /* if TRUE, test mode, show command line */
char *p; /* char pointer for strtok */
/* build the _swappath global, if NULL, xswap uses current dir */
strcpy( swapto, getenv("TMP") ); /* try this path first */
if (!strlen(swapto)) strcpy( swapto, getenv("TEMP") ); /* maybe this one ? */
if (strlen(swapto))
{
strcat( swapto, ";" );
getcwd( scratch, _MAX_PATH );
strcat( swapto, scratch ); /* try this path last */
_swappath=swapto;
}
_getvideoconfig( &vc );
savedscreen=saveScrn(); /* save video memory */
oldpos = _gettextposition();
/* Save current drive and current working directory. */
olddrive=_getdrive();
getcwd( oldcwd, _MAX_PATH );
slash=getenv("FSSWITCH"); /* alternative FS switch character */
if (slash) fsswitch=*slash;
else fsswitch='/';
/* process arguments from environment */
strcpy(scratch,getenv("FSPARAMS"));
strupr(scratch);
p = strtok( scratch, " ;" ); /* Find first token */
while( p != NULL )
{
if (p[0]!='D') /* v parameters without switch */
interpret_params( argv[0], argc, p, &no_return, &init_screen,
&testing, &wait, &_useems,
&_swap, &keep_path, &max_files, &mask_argc_number,
&safe_mode);
p = strtok( NULL, " ;");
}
for (iTeller=0;iTeller<15;iTeller++) /* reset argument list */
{
commarg[iTeller]=0;
arglist[iTeller]=(char *) 0L;
}
if (argc<2 || (argv[1][0]==fsswitch)) /* at least a command should be present, show info */
{
printf("\nFS 1.9.1 Copyright (C) M.C.J. van Breemen, 1993, All rights reserved.\n"
"Syntax: FS command filemask %c1 %cChex %cM %cR %cFnum %cPnum %cW %cSe %cDhex %cT\n"
"%c1\tRun FS only once\n"
"%cChex\tSet color mode & optionally set run-time colors (16 hex digits)\n"
"%cM\tSet monochrome mode\n%cR\tRestore drive & dir\n"
"%cFnum\tAllocate memory for 'num' files pro directory (default 456)\n"
"%cPnum\tPosition of filemask (default 2, directly after command)\n"
"%cW\tWait for a key pressed before returning\n"
"%cS\tDisable all swapping (%cSE Disable swapping to EMS)\n"
"%cDhex\tSave & optionally set default colors (16 hex digits)\n"
"%cT\tTest mode, show resulting commandline\n"
"%cN\tNo changes to files allowed in FS, safe mode\n"
"\tOther non-FS arguments are passed through in the same order\n"
"The %c switch can be re-defined with environment variable FSSWITCH\n"
"All parameters except D are also definable with environment variable FSPARAMS\n"
"which should be defined as a list of parameters without switch character,\n"
"separated by space or ;\n"
"Run-time commandline parameters will override FSPARAMS settings\n",
fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,
fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,
fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch);
exit(1);
}
/* position of filemask is needed before processing of the commandline parameters */
for (iTeller=2;iTeller<argc;iTeller++) /* where is the filemask ? */
{
strcpy(scratch,argv[iTeller]);
strupr(scratch);
if (scratch[0]==fsswitch && (scratch[1]=='P'))
{ /* vvvvvvvvv skip switch */
interpret_params( argv[0], argc, scratch+1, &no_return, &init_screen,
&testing, &wait, &_useems,
&_swap, &keep_path, &max_files, &mask_argc_number,
&safe_mode);
break;
}
}
/* process arguments from command line (will override environment) */
for (iTeller=2;iTeller<argc;iTeller++) /* process FS & command switches */
{
strcpy(scratch,argv[iTeller]);
strupr(scratch);
if (scratch[0]==fsswitch)
{ /* vvvvvvvvv skip switch */
interpret_params( argv[0], argc, scratch+1, &no_return, &init_screen,
&testing, &wait, &_useems,
&_swap, &keep_path, &max_files, &mask_argc_number,
&safe_mode);
if (iTeller==2 && mask_argc_number==2) commarg[tot_commargs++]=2;
/* parameter found on default filemask place */
/* count this one as filemask to enable selected string replacement */
} else
if (tot_commargs<15) /* mark command arguments */
commarg[tot_commargs++]=iTeller;
else show_error("Argument list full");
}
/* no arguments at all, create the default filemask argument */
if (!tot_commargs) commarg[tot_commargs++]=mask_argc_number;
/* construct arglist array */
for (iTeller=0;iTeller<tot_commargs;iTeller++)
{
if (commarg[iTeller]!=mask_argc_number) arglist[iTeller]=argv[commarg[iTeller]];
else arglist[iTeller]=selected;
}
_settextposition( oldpos.row, oldpos.col ); /* recover from show_error calls */
strcpy(mask, argv[mask_argc_number]); /* get mask */
if (mask[0]==fsswitch) strcpy(mask,"*.*"); /* a switch ? */
if (strlen(mask)>13) mask[13]='\0'; /* max. 13 characters! */
while (TRUE) /* select a file */
{
if (init_screen)
{
/* set video mode */
if (init_screen==COLOR)
if( !_setvideomode( _TEXTC80 ) )
_setvideomode( _TEXTMONO );
if (init_screen==MONO)
_setvideomode( _TEXTMONO );
}
strcpy(selected,"");
handle_dir_result=handle_dir( mask , selected , safe_mode);
if (init_screen)
{
_setvideomode(vc.mode); /* restore old video mode */
_settextposition( oldpos.row, oldpos.col );
}
if (handle_dir_result==EXIT_RESTORE || handle_dir_result==FAILURE)
{
_chdrive( olddrive ); /* restore path */
chdir( oldcwd );
break; /* ESC, break out of TRUE loop */
}
if (handle_dir_result==EXIT_KEEP) break; /* ESC, break out of TRUE loop */
/* a lot of foggy stuff with the _chdrive and chdir around this because we have to handle the L function */
if (keep_path || no_return) /* restore path before executing commands */
{
_chdrive( olddrive );
chdir( oldcwd );
}
if (no_return) savedscreen=restScrn(savedscreen); /* restore video memory */
execute( argv[1], arglist, tot_commargs, no_return, testing );
if (!keep_path && !no_return) /* change to the selected drive and directory for future calls */
set_working_drive_and_dir( selected );
if (wait || testing)
{
_outtext("\n*** Press any key to continue ***");
getkey();
_outtext("\r ");
}
if (no_return) break; /* /1 switch and still alive, get out! */
}
savedscreen=restScrn(savedscreen); /* this is double if execlp fails on /1, but who cares */
exit( 0 );
}
/****************************************************************************
command executor, uses execlp for single run, spawnlp for multiple runs of
external commands, system for internal commands.
uses xspawn functions if _swap=0
comm : command string
a : pointer to the argument string list, short name to keep it readable.
tot_commargs: number of arguments
no_return : single run, use execlp instead of spawnlp
testing : show command, do not execute
*/
void execute(char *comm, char **a, int tot_commargs, int no_return, int testing)
{
char scratch[_MAX_PATH];
int error, iTeller;
if (testing)
{
strcpy(scratch,"\n");
strcat(scratch,comm);
for (iTeller=0;iTeller<tot_commargs;iTeller++)
{
strcat(scratch," ");
strcat(scratch,a[iTeller]);
}
strcat(scratch,"\n");
_outtext(scratch);
return;
}
if (no_return)
error=execlp( comm,comm,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],NULL );
/* this will normally not return, write-over FS code, do not swap */
else
{
if (!_swap) error=xspawnlp( P_WAIT, comm,comm,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],NULL ); /* swap FS code */
else error=spawnlp( P_WAIT, comm,comm,a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],NULL ); /* preserve FS code */
}
if (error==-1)
{
/* Can't execute or spawn this process, probably resident MS-DOS
* Let us hope spawn is not returning a -1 return code and try
* a system call now */
strcpy(scratch,comm);
for (iTeller=0;iTeller<tot_commargs;iTeller++)
{
strcat(scratch," ");
strcat(scratch,a[iTeller]);
}
if (!_swap) xsystem(scratch);
else system(scratch);
}
}
/* Converts hex digits to decimals, make invalid digits 0
*/
int convcolorinfo( char colinfo)
{
toupper(colinfo);
if ((colinfo >= '0') && (colinfo <= '9')) return ((int) (colinfo - '0'));
else if ((colinfo >= 'A') && (colinfo <= 'F')) return ((int) (colinfo - 'A') + 10);
else return 0;
}
/* Process ?hhhhhhhhhhhhhhhh option to colors
*/
int set_colors( char *scratch)
{
if (strlen(scratch)==1) return FAILURE; /* do not set run-time colors */
if (strlen(scratch)==17) /* process color info */
{
screen_bg_color =convcolorinfo(scratch[1]);
file_color =convcolorinfo(scratch[2]);
directory_color =convcolorinfo(scratch[3]);
cursor_bg_color =convcolorinfo(scratch[4]);
cursor_file_color =convcolorinfo(scratch[5]);
cursor_directory_color=convcolorinfo(scratch[6]);
info_bg_color =convcolorinfo(scratch[7]);
info_text_color =convcolorinfo(scratch[8]);
error_text_color =convcolorinfo(scratch[9]);
prompt_text_color =convcolorinfo(scratch[10]);
hidden_file_color =convcolorinfo(scratch[11]);
hidden_directory_color=convcolorinfo(scratch[12]);
volume_label_color =convcolorinfo(scratch[13]);
cursor_hidden_file_color =convcolorinfo(scratch[14]);
cursor_hidden_directory_color=convcolorinfo(scratch[15]);
cursor_volume_label_color =convcolorinfo(scratch[16]);
return SUCCESS;
} else show_error("Incorrect color string, using defaults ");
return FAILURE;
}
/***************************************************************************
Save default colors, patch FS.EXE
setcolorresult SUCCESS: nieuwe colors zetten in image
FAILURE: default colors zetten in image en run-time
zoek naar fffefdfcfbfa, kontroleer of na 32 bytes fafbfcfdfeff komt en
patch 16 short integers daartussen
*/
int save_colors_in_exe( char *imagename , int setcolorresult)
{
char *buff; /* Pointer to data buffer */
struct color {
short int c1;
short int c2;
short int c3;
short int c4;
short int c5;
short int c6;
short int c7;
short int c8;
short int c9;
short int c10;
short int c11;
short int c12;
short int c13;
short int c14;
short int c15;
short int c16;
} colors;
int fn; /* file handle */
long fl; /* file length */
unsigned int count=0x7fff; /* buffer size */
int found; /* True if checkpoint code found */
long rsize; /* Amount of data read into buffer */
long tot_offset,offset; /* Position where checkpoint code found */
if (setcolorresult==FAILURE) /* set & patch factory defaults */
set_colors("C17E47E2FCEFA3FA3");
colors.c1=screen_bg_color;
colors.c2=file_color;
colors.c3=directory_color;
colors.c4=cursor_bg_color;
colors.c5=cursor_file_color;
colors.c6=cursor_directory_color;
colors.c7=info_bg_color;
colors.c8=info_text_color;
colors.c9=error_text_color;
colors.c10=prompt_text_color;
colors.c11=hidden_file_color;
colors.c12=hidden_directory_color;
colors.c13=volume_label_color;
colors.c14=cursor_hidden_file_color;
colors.c15=cursor_hidden_directory_color;
colors.c16=cursor_volume_label_color;
if( (fn = open( imagename, O_BINARY | O_RDWR )) == - 1 )
{
show_error("FS image not found ");
return FAILURE;
}
/* Get size of file */
fl = filelength(fn);
if( fl < (long) count )
count = (unsigned int) fl;
/* Dynamically allocate a large file buffer. If there's not enough
* memory for it, find the largest amount available on the near heap
*/
if( !(buff = (char *)malloc( (size_t)count )) )
{
count = _memmax();
if( !(buff = (char *)malloc( (size_t)count )) )
{
show_error("Cannot allocate memory ");
close(fn);
return FAILURE;
}
}
found = FALSE;
tot_offset=0L;
while ( !eof(fn) && !found)
{
if( (rsize = (long) read( fn, buff, count )) == FAILURE )
{
show_error("Read error ");
close(fn);
free(buff);
return FAILURE;
}
for (offset=0L; offset <= rsize-44L; offset++) /* 6+32+6 */
{
if (!strncmp(&buff[offset], "\xFF\xFE\xFD\xFC\xFB\xFA", 6 ))
{
if (!strncmp(&buff[offset+38L], "\xFA\xFB\xFC\xFD\xFE\xFF", 6 ))
{
found = TRUE;
break; /* escape from FOR loop */
}
}
}
if (!found && !eof(fn)) /* reposition back 6+32+5 to recover from split search string */
{
if (lseek (fn, -43L, SEEK_CUR)==FAILURE)
{
show_error("Seek error ");
close(fn);
free(buff);
return FAILURE;
}
}
tot_offset+=offset; /* after a lseek operation, the 44 bytes in the end-condition in the loop */
/* eliminates the need of substraction of 43 bytes for lseek */
}
free(buff);
if (!found)
{
show_error("Cannot locate color storage position ");
close(fn);
return FAILURE;
}
/* Write the colors structure into the exe file */
if (lseek (fn, tot_offset + 6L, SEEK_SET)==FAILURE) show_error("Seek error ");
else if (write(fn,&colors, 32)==FAILURE) show_error("Write error ");
if (close(fn)==FAILURE) show_error("Close error ");
return SUCCESS;
}
void interpret_params( char *imagename, int argc, char *param,
int *no_return, int *init_screen, int *testing,
int *wait, int *_useems, int *_swap,
int *keep_path, int *max_files, int *mask_argc_number,
int *safe_mode)
{
char scratch[_MAX_PATH];
strcpy(scratch,param);
switch (scratch[0])
{
case '1': *no_return=TRUE;
break;
case 'C': *init_screen=COLOR;
set_colors(scratch);
break;
case 'D': if (save_colors_in_exe(imagename,set_colors(scratch))==FAILURE)
show_error("Can't save colors ");
break;
case 'T': *testing=TRUE;
break;
case 'M': *init_screen=MONO;
break;
case 'W': *wait=TRUE;
break;
case 'N': *safe_mode=TRUE;
break;
case 'S': if (scratch[1]=='E') *_useems=1; /* do not use EMS */
else *_swap=1; /* disable all swapping, 0=do swap, ^0=do not swap */
break;
case 'R': *keep_path=TRUE;
break;
case 'F': *max_files=atoi(scratch+1);
if (*max_files<=0)
{
*max_files=MAX_FILES;
strcat(scratch," ignored");
show_error(scratch);
}
break;
case 'P': *mask_argc_number=atoi(scratch+1);
if (*mask_argc_number<2 || *mask_argc_number >=argc) *mask_argc_number=2;
break;
default: /* ignore unknown FS switches*/
strcat(scratch," ignored");
show_error(scratch);
break;
}
}