home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / mslang / fs25 / fs0.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-17  |  27.1 KB  |  775 lines

  1. /* FS0.C
  2.  * main program body
  3.  * MSC8 (VC++ 1.5)
  4.  * FS 2.5
  5.  * 170594
  6.  * Copyright (C) M.C.J. van Breemen, 1992-1994, All rights reserved.
  7.  */
  8.  
  9. #include "FS.H"       /* most C header files are included here ! */
  10. #include "spawno.h"
  11.  
  12. enum FILEATTRIB { EXIST, WRITE = 2, READ = 4, READWRITE = 6 };
  13. #define EXIST( name ) !_access( name, EXIST )
  14.  
  15. /* Prototypes */
  16. int set_turnover_datetime( char *datetime );
  17. int cdecl fs_systemo(const char *overlay_path, const char *command);
  18. int  handle_dir( char *searchstring, char *selected , int safe_mode);
  19. int execute(char *comm, char **a, int tot_commargs, int no_return, int testing);
  20. void main( int argc, char *argv[]);
  21. int convcolorinfo( char colinfo );
  22. int set_colors( char *scratch);
  23. char __near *saveScrn (void);
  24. char __near *restScrn(char __near *saveArea);
  25. int getkey(void);
  26. void show_error( char *message );
  27. int save_colors_in_exe( char *imagename , int setcolorresult);
  28. char *set_working_drive_and_dir( char *full_filename );
  29. void interpret_params( char *imagename, int argc, char *param,
  30.                int *no_return, int *init_screen, int *testing,
  31.                int *wait, int *swap_types, int *allowswap,
  32.                int *keep_path, int *max_files, int *mask_argc_number,
  33.                int *mask_starting_char, int *mask_length,
  34.                int *safe_mode, int *order_by, int *order_type);
  35. void locate_processor(char *command, char *processor);
  36. int _Cdecl fs_spawnlpeo(const char *overlay_path,const char *prog_name,...);
  37. int _Cdecl fs_spawnvpeo(const char *overlay_path, const char *prog_name,
  38.             const char **args, const char **env);
  39.  
  40. /* externals, used by the handle_dir routines */
  41. extern char __far turnover_datetime_string[];
  42. extern unsigned long turnover_datetime;
  43. extern int turnover_datetime_mode;       /* BEFORE,SINCE or ALL*/
  44.  
  45. extern char __far processor[];
  46. extern int setting_factory_defaults;
  47. extern char *swap_dir;
  48. extern int allow_swap;
  49. extern int swap_types;
  50. extern int max_files;          /* max. number of files accessible */
  51. extern int order_by;           /* NONE, NAME, DATE or SIZE */
  52. extern int order_type;         /* ASCENDING or DESCENDING */
  53. extern short int screen_bg_color;
  54. extern short int file_color;
  55. extern short int directory_color;
  56. extern short int hidden_file_color;
  57. extern short int hidden_directory_color;
  58. extern short int volume_label_color;
  59. extern short int cursor_bg_color;
  60. extern short int info_bg_color;
  61. extern short int info_text_color;
  62. extern short int error_bg_color;
  63. extern short int error_text_color;
  64. extern short int fsswitch;
  65.  
  66. /********************************************************************************/
  67. void main( int argc, char *argv[])
  68. {
  69.     char selected[_MAX_PATH];  /* selected file */
  70.     char trailer[_MAX_PATH];   /* trailing string appended to selected file */
  71.     char mask[_MAX_PATH];      /* filter */
  72.     char scratch[_MAX_PATH];   /* temporary strings, really scratch */
  73.     int init_screen=FALSE;     /* initialise display adapter */
  74.     int no_return=FALSE;       /* run FS once */
  75.     int keep_path=FALSE;       /* keep initial drive and directory path */
  76.     int wait=FALSE;            /* wait for a keystroke before resetting screen */
  77.     int safe_mode=FALSE;       /* changes to files not allowed (/N) */
  78.     int iTeller;               /* counter */
  79.     int mask_argc_number=2;    /* default place of mask in argument list */
  80.     unsigned int mask_starting_char=1; /* default first character of mask in argument */
  81.     unsigned int mask_length=0;        /* default up to string terminator */
  82.     char *slash;               /* pointer to FSSWITCH env (we only want the first char!) */
  83.     int olddrive;              /* old current drive */
  84.     char oldcwd[_MAX_PATH];    /* old current working directory */
  85.     int commarg[17];           /* initial argument list */
  86.     int tot_commargs=0;        /* number of command arguments */
  87.     char *arglist[17];         /* final argument list */
  88.     struct videoconfig vc;     /* video info structure */
  89.     char __near *savedscreen;  /* pointer to saved screen memory */
  90.     struct rccoord oldpos;     /* old cursor position (_setvideomode will reset to 0,0) */
  91.     int handle_dir_result;
  92.     int testing=FALSE;         /* if TRUE, test mode, show command line */
  93.     char *p;                   /* char pointer for strtok etc. */
  94.     short oldcursor=_gettextcursor();
  95.  
  96.     allow_swap=TRUE;
  97.     swap_types=SWAP_ANY;
  98.     swap_dir = getenv("SWAPDIR");
  99.     if (swap_dir == NULL)
  100.        swap_dir = getenv("TEMP");
  101.     if (swap_dir == NULL)
  102.        swap_dir = getenv("TMP");
  103.     if (swap_dir == NULL)
  104.        swap_dir = "." ;          /* default swap directory is current dir */
  105.     init_SPAWNO(swap_dir,swap_types);
  106.  
  107.     order_by=NAME;            /* order files by name */
  108.     order_type=ASCENDING;     /* order lowest-> highest = top->bottom (0-9,A-Z) */
  109.     strcpy(selected,"");
  110.  
  111.     _getvideoconfig( &vc );
  112.  
  113.     savedscreen=saveScrn();         /* save video memory */
  114.     oldpos = _gettextposition();
  115.  
  116.     /* Save current drive and current working directory. */
  117.     olddrive=_getdrive();
  118.     getcwd( oldcwd, _MAX_PATH );
  119.  
  120.     slash=getenv("FSSWITCH");          /* alternative FS switch character */
  121.     if (slash) fsswitch=(short int) *slash;
  122.  
  123.     /* process arguments from environment */
  124.     slash=getenv("FSPARAMS");
  125.     if (slash)
  126.     {
  127.     strcpy(scratch,slash);
  128.     strupr(scratch);
  129.     p = strtok( scratch, " ;" );     /* Find first token */
  130.     while( p != NULL )
  131.     {
  132.         if (p[0]!='D')                /* v parameters without switch */
  133.         interpret_params( argv[0], argc, p, &no_return, &init_screen,
  134.                   &testing, &wait, &swap_types,
  135.                   &allow_swap, &keep_path, &max_files, &mask_argc_number,
  136.                   &mask_starting_char, &mask_length,
  137.                   &safe_mode, &order_by, &order_type);
  138.         p = strtok( NULL, " ;");
  139.     }
  140.     }
  141.  
  142.     for (iTeller=0;iTeller<17;iTeller++) /* reset argument list */
  143.     {
  144.     commarg[iTeller]=0;
  145.     arglist[iTeller]=(char *) 0L;
  146.     }
  147.  
  148.     if (argc<2 || (argv[1][0]==(char) fsswitch)) /* at least a command should be present, show info */
  149.     {
  150.      printf("\nFS 2.5  Copyright (C) M.C.J. van Breemen, 1992-1994, All rights reserved.\n"
  151.         "Syntax:\n"
  152.         "FS command filemask %c1 %cChex %cM %cR %cFnum %cPa,c,l %cW %cSxxxx %cDhex %cT %cOxy\n"
  153.         "%c1\tRun FS one time, exit after selecting a file\n"
  154.         "%cChex\tSet color mode & optionally set run-time colors (11 hex digits)\n"
  155.         "%cM\tSet monochrome mode\n%cR\tRestore drive & dir before executing command\n"
  156.         "%cFnum\tAllocate memory for 'num' files per directory (default 912)\n"
  157.         "%cPa,c,l\tPosition of filemask in argument list, argument a,\n"
  158.         "\tstarting character c, length l  Default 2,1: argument 2 (FS=0),\n" 
  159.         "\tbeginning on first character, all remaining characters of the string\n"
  160.         "%cW\tWait for a key pressed before returning\n"
  161.         "%cSxxxx\tSwap types: Enable swapping to Disk, Ems, Xms, raw exT. Default %cSdext\n"
  162.         "\t%cS without types disables all swapping\n"
  163.         "%cDhex\tSave new default colors (hex: 11 hex digits, 0-F)\n"
  164.         "%cDs\tSave new default switch (s: 1 character)\n"
  165.         "\t%cD alone sets both default %cD17FEA342F47 and %cD/\n"
  166.         "%cT\tTest mode, show resulting commandline\n"
  167.         "%cN\tNo changes to files allowed in FS, safe mode\n"
  168.         "%cOxy\tOrder by x: Name, Date, Size. y: + Ascending, - Descending (default N+)\n"
  169.         "\t%cO alone cancels ordering\n"
  170.         "%cB+dd-mon-yyyy:hh:mm:ss\tShow only files since (+ or empty) or before (-) date\n"
  171.         "Other non-FS arguments are passed through in the same order\n",
  172.         fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,
  173.         fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,
  174.         fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,
  175.         fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch);
  176.      printf("-- More --");
  177.      getch();
  178.      printf("\nThe command string should always be entered, even if not significant\n"
  179.         "(like in FS DUMMY %cD).\n"
  180.         "The %c switch can be re-defined with environment variable FSSWITCH.\n"
  181.         "All parameters except D are also definable with environment variable FSPARAMS\n"
  182.         "which should be set as a list of parameters without switch, separated by ; or\n"
  183.         "space. Run-time commandline parameters will override FSPARAMS settings.\n"
  184.         "EXAMPLES: FS EDIT,   FS EDIT *.C,   FS C:\\UTILS\\ARJ e *.ARJ %cP3 %cR,\n"
  185.         "          FS COPY C:\\ALLC.TXT+*.C %cP2,13 C:\\ALLC.TXT\n"
  186.         "          FS ECHO [*.C] %cP2,2,3 %cW,   FS LHA a C:\\ARCHIVE.LZH *.* %cP4\n\n\n",
  187.         fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch);
  188.      exit(1);
  189.     }
  190.  
  191.     /* position of filemask is needed before processing of the commandline parameters */
  192.     for (iTeller=2;iTeller<argc;iTeller++)  /* where is the filemask ? */
  193.     {
  194.         strcpy(scratch,argv[iTeller]);
  195.         strupr(scratch);
  196.         if (scratch[0]==(char) fsswitch && (scratch[1]=='P'))
  197.         {                                 /* vvvvvvvvv skip switch */
  198.         interpret_params( argv[0], argc, scratch+1, &no_return, &init_screen,
  199.                   &testing, &wait, &swap_types,
  200.                   &allow_swap, &keep_path, &max_files, &mask_argc_number,
  201.                   &mask_starting_char, &mask_length,
  202.                   &safe_mode, &order_by, &order_type);
  203.         break;
  204.         }
  205.     }
  206.  
  207.     /* process arguments from command line (will override environment) */
  208.     for (iTeller=2;iTeller<argc;iTeller++)  /* process FS & command switches */
  209.     {
  210.         strcpy(scratch,argv[iTeller]);
  211.         strupr(scratch);
  212.         if (scratch[0]==(char) fsswitch)
  213.         {                                 /* vvvvvvvvv skip switch */
  214.         interpret_params( argv[0], argc, scratch+1, &no_return, &init_screen,
  215.                   &testing, &wait, &swap_types,
  216.                   &allow_swap, &keep_path, &max_files, &mask_argc_number,
  217.                   &mask_starting_char, &mask_length,
  218.                   &safe_mode, &order_by, &order_type);
  219.  
  220.         if (iTeller==mask_argc_number) commarg[tot_commargs++]=iTeller;
  221.            /* parameter found on filemask place */
  222.            /* count this one as filemask to enable selected string replacement */
  223.         } else
  224.          if (tot_commargs<15) /* mark command arguments */
  225.             commarg[tot_commargs++]=iTeller;
  226.          else show_error("Argument list full");
  227.     }
  228.  
  229.     /* no arguments at all, create the default filemask argument */
  230.     if (!tot_commargs) commarg[tot_commargs++]=mask_argc_number;
  231.  
  232.     /* construct arglist array */
  233.     /* arglist is an array of pointers to the run-time command line arguments, to be passed */
  234.     /* to the target command. The filemask substring will be replaced with the selected */
  235.     /* filename from the handle_dir function. */
  236.     /* This is done by replacing the address of the original filemask argument */
  237.     /* with the address of a string buffer 'selected' */
  238.     /* The leading characters (Pa,c c component) are skipped. The resulting address */
  239.     /* is fed to function handle_dir to enable a correct replacement */
  240.     /* The first parameter will be made the processor name */
  241.     for (iTeller=0;iTeller<tot_commargs;iTeller++)
  242.     {
  243.     if (commarg[iTeller]!=mask_argc_number) arglist[iTeller+1]=argv[commarg[iTeller]];
  244.     else
  245.     {
  246.          arglist[iTeller+1]=selected;               /* replace with buffer address for selected string */
  247.          strcpy(selected,argv[commarg[iTeller]]);  /* save leading characters */
  248.          strcpy(trailer,""); 
  249.          if (mask_length)
  250.          {
  251.            if ((mask_starting_char - 1 + mask_length) <= strlen(argv[commarg[iTeller]]))
  252.            strcpy(trailer,argv[commarg[iTeller]] + mask_starting_char - 1 + mask_length);
  253.            else  show_error("incorrect l in Pa,c,l"); 
  254.          }
  255.          selected[mask_starting_char-1]='\0';      /* get rid of original filemask */
  256.          p=selected;                               /* make a pointer of it */
  257.          if (mask_starting_char==1 || ((mask_starting_char-1) < strlen(argv[commarg[iTeller]]))) /* is the offset possible ? */
  258.          p+=(mask_starting_char-1);            /* skip leading characters  (do nothing if mask_starting_char== 1) */
  259.          else 
  260.          {
  261.          show_error("incorrect c in Pa,c");
  262.          mask_starting_char=1;
  263.          }
  264.     }
  265.     }
  266.  
  267.     /* get correct mask component */
  268.     if (argc==2) strcpy(mask,"*.*");    /* is there a filemask ? */
  269.     else
  270.     {
  271.      strcpy(mask, argv[mask_argc_number]+(mask_starting_char-1)); /* get mask */
  272.      if (mask_length) mask[mask_length]='\0';  /* remove trailer */
  273.     }
  274.     if (mask[0]==(char) fsswitch) strcpy(mask,"*.*"); /* a switch ? Replace it with *.* */      
  275.     if (strlen(mask)>13) mask[13]='\0';     /* max. 13 characters! */
  276.  
  277.     _settextposition( oldpos.row, oldpos.col );  /* recover from show_error calls */
  278.  
  279.     /* expand the processor name */
  280.     locate_processor( argv[1], processor);
  281.     if (!strlen(processor)) strcpy(processor,argv[1]); /* not found, let execute() do the work */
  282.  
  283.     /* put the processor name in the first argument of the argument list */
  284.     arglist[0]=processor;
  285.     
  286.     while (!setting_factory_defaults) /* select a file */
  287.     {
  288.     if (init_screen)
  289.     {
  290.       /* set video mode */
  291.       if (init_screen==COLOR)
  292.          if( !_setvideomode( _TEXTC80 ) )
  293.         _setvideomode( _TEXTMONO );
  294.       if (init_screen==MONO)
  295.          _setvideomode( _TEXTMONO );
  296.     }
  297.  
  298.     strcpy(p,"");
  299.     handle_dir_result=handle_dir( mask , p , safe_mode);  /* fill p here */
  300.     strcat(p,trailer);
  301.  
  302.     if (init_screen)
  303.     {
  304.         _setvideomode(vc.mode); /* restore old video mode */
  305.         _settextposition( oldpos.row, oldpos.col );
  306.     }
  307.     if (handle_dir_result==EXIT_RESTORE || handle_dir_result==FAILURE)
  308.     {
  309.           _chdrive( olddrive );     /* restore path */
  310.           chdir( oldcwd );
  311.           break; /* ESC, break out of TRUE loop */
  312.     }
  313.     if (handle_dir_result==EXIT_KEEP) break; /* ESC, break out of TRUE loop */
  314.  
  315.     /* a lot of foggy stuff with the _chdrive and chdir around this because we have to handle the L function */
  316.  
  317.     if (keep_path || no_return)  /* restore path before executing commands */
  318.     {
  319.        _chdrive( olddrive );
  320.        chdir( oldcwd );
  321.     }
  322.  
  323.     if (no_return) savedscreen=restScrn(savedscreen);             /* restore video memory */
  324.     execute( processor, arglist, tot_commargs, no_return, testing );
  325.     if (!keep_path && !no_return) /* change to the selected drive and directory for future calls */
  326.        set_working_drive_and_dir( selected );
  327.  
  328.     if (wait || testing)
  329.     {
  330.          _outtext("\n*** Press any key to continue ***");
  331.           getkey();
  332.          _outtext("\r                                 ");
  333.     }
  334.  
  335.     if (no_return) break;             /* /1 switch and still alive, get out! */
  336.     }
  337.  
  338.     savedscreen=restScrn(savedscreen);    /* this is double if execlp fails on /1, but who cares */
  339.     _settextcursor(oldcursor); /* the cursor should be balanced, but programs called with */
  340.                    /* function E could eat-up the cursor */
  341.  
  342.     if (handle_dir_result==FAILURE) exit( 1 );
  343.     else exit( 0 );
  344. }
  345.  
  346. /****************************************************************************
  347.    command executor, uses execlp for single run, spawnlp for multiple runs of
  348.    external commands, system for internal commands.
  349.    uses spawno functions if allow_swap=TRUE
  350.    comm        : command string
  351.    a           : pointer to the argument string list.
  352.    tot_commargs: number of arguments, excluding a[0] (==command string)
  353.    no_return   : single run, use execlp instead of spawnlp
  354.    testing     : show command, do not execute
  355. */
  356. int execute(char *comm, char **a, int tot_commargs, int no_return, int testing)
  357. {
  358.     char scratch[ _MAX_PATH];
  359.     int error, iTeller;
  360.        
  361.     if (testing)
  362.     {
  363.          strcpy(scratch,"\n");
  364.          strcat(scratch,comm);
  365.          for (iTeller=0;iTeller<tot_commargs;iTeller++)
  366.          {
  367.          strcat(scratch," ");
  368.          strcat(scratch,a[iTeller+1]); /* skip a[0] */
  369.          }
  370.          strcat(scratch,"\n");
  371.          _outtext(scratch);
  372.          return (0);
  373.     }
  374.  
  375.     if (no_return)
  376.          error=execvp( comm, a );
  377.         /* this will normally not return, write-over FS code, do not swap */
  378.     else
  379.     {
  380.         if (allow_swap) error=fs_spawnvpeo( swap_dir,comm,a,_environ ); /* swap FS code */
  381.         else error=spawnvp( P_WAIT, comm, a ); /* preserve FS code */
  382.     }
  383.     if (error==-1)
  384.     {
  385.          /* Can't execute or spawn this process, probably resident MS-DOS
  386.           * Let us hope spawn is not returning a -1 return code and try
  387.           * a system call now */
  388.          strcpy(scratch,comm);
  389.          for (iTeller=0;iTeller<tot_commargs;iTeller++)
  390.          {
  391.          strcat(scratch," ");
  392.          strcat(scratch,a[iTeller+1]); /* skip a[0] */
  393.          }
  394.          if (allow_swap) fs_systemo(swap_dir,scratch);
  395.          else error=system(scratch);
  396.     }
  397.     return (error);
  398. }
  399.  
  400. /* Converts hex digits to decimals, make invalid digits 0
  401. */
  402. int convcolorinfo( char colinfo)
  403. {
  404.     toupper(colinfo);
  405.     if ((colinfo >= '0') && (colinfo <= '9')) return ((int) (colinfo - '0'));
  406.     else if ((colinfo >= 'A') && (colinfo <= 'F')) return ((int) (colinfo - 'A') + 10);
  407.      else return 0;
  408. }
  409.  
  410. /* Process ?hhhhhhhhhhh option to colors
  411. *       or ?s option to fsswitch
  412. */
  413. int set_colors( char *scratch)
  414. {
  415.   if (strlen(scratch)==1) return FAILURE; /* do not set run-time colors */
  416.   if (strlen(scratch)==2 && scratch[0]=='D')
  417.   {
  418.       fsswitch=(short int) scratch[1];
  419.       return SUCCESS; /* side-effect: will set run-time colors to the same values */ 
  420.   }
  421.   if (strlen(scratch)==12) /* process color info */
  422.   {
  423.  
  424.      screen_bg_color       =convcolorinfo(scratch[1]);
  425.      file_color            =convcolorinfo(scratch[2]);
  426.      hidden_file_color     =convcolorinfo(scratch[3]);
  427.      directory_color       =convcolorinfo(scratch[4]);
  428.      hidden_directory_color=convcolorinfo(scratch[5]);
  429.      volume_label_color    =convcolorinfo(scratch[6]);
  430.      cursor_bg_color       =convcolorinfo(scratch[7]);
  431.      info_bg_color         =convcolorinfo(scratch[8]);
  432.      info_text_color       =convcolorinfo(scratch[9]);
  433.      error_bg_color        =convcolorinfo(scratch[10]);
  434.      error_text_color      =convcolorinfo(scratch[11]);
  435.      return SUCCESS;
  436.   }  else show_error("Incorrect color string, using defaults");
  437.   return FAILURE;
  438. }
  439.  
  440. /***************************************************************************
  441.  Save default colors, patch FS.EXE
  442.  setcolorresult SUCCESS: nieuwe colors zetten in image
  443.         FAILURE: default colors zetten in image en run-time
  444.  zoek naar fffefdfcfbfa, kontroleer of na 24 bytes (2*12) fafbfcfdfeff komt en
  445.  patch 12 short integers daartussen
  446. */
  447.  
  448.  
  449. int save_colors_in_exe( char *imagename , int setcolorresult)
  450. {
  451.      char *buff;                 /* Pointer to data buffer */
  452.      struct color  {
  453.             short int c1;
  454.             short int c2;
  455.             short int c3;
  456.             short int c4;
  457.             short int c5;
  458.             short int c6;
  459.             short int c7;
  460.             short int c8;
  461.             short int c9;
  462.             short int c10;
  463.             short int c11;
  464.             short int s1;
  465.            } colors;
  466.      int fn;                     /* file handle */
  467.      long fl;                    /* file length */
  468.      unsigned int count=0x7fff;  /* buffer size */
  469.                  /* does not work above 0x7fff. Cannot figure out why */
  470.      int  found;                 /* True if checkpoint code found */
  471.      long rsize;                 /* Amount of data read into buffer */
  472.      long tot_offset,offset;     /* Position where checkpoint code found */
  473.  
  474.      if (setcolorresult==FAILURE)    /* set & patch factory defaults */
  475.      {
  476.     set_colors("C17FEA342F47");
  477.     fsswitch=(short int) '/';
  478.      }
  479.      colors.c1=screen_bg_color;
  480.      colors.c2=file_color;
  481.      colors.c3=hidden_file_color;
  482.      colors.c4=directory_color;
  483.      colors.c5=hidden_directory_color;
  484.      colors.c6=volume_label_color;
  485.      colors.c7=cursor_bg_color;
  486.      colors.c8=info_bg_color;
  487.      colors.c9=info_text_color;
  488.      colors.c10=error_bg_color;
  489.      colors.c11=error_text_color;
  490.      colors.s1=fsswitch;
  491.    if( (fn = open( imagename, O_BINARY | O_RDWR )) == - 1 )
  492.    {
  493.      show_error("FS image not found");
  494.      return FAILURE;
  495.    }
  496.    /* Get size of file */
  497.    fl = filelength(fn);
  498.    if( (unsigned long) fl < (unsigned long) count )
  499.     count = (unsigned int) fl;
  500.  
  501.     /* Dynamically allocate a large file buffer. If there's not enough
  502.      * memory for it, find the largest amount available
  503.      */
  504.     if( !(buff = (char *)malloc( (size_t)count )) )
  505.     {
  506.     count = _memmax();
  507.     if( !(buff = (char *)malloc( (size_t)count )) )
  508.     {
  509.          show_error("Cannot allocate memory");
  510.          close(fn);
  511.          return FAILURE;
  512.     }
  513.     }
  514.  
  515.    found = FALSE;
  516.    tot_offset=0L;
  517.    while ( !eof(fn) && !found)
  518.    {
  519.      if( (rsize = (unsigned long) read( fn, buff, count )) == FAILURE )
  520.      {
  521.          show_error("Read error");
  522.          close(fn);
  523.          free(buff);
  524.          return FAILURE;
  525.      }
  526.      for (offset=0L; offset <= rsize-36L; offset++)     /* 6+24+6 */
  527.      {
  528.       if (!strncmp(&buff[offset], "\xFF\xFE\xFD\xFC\xFB\xFA", 6 ))
  529.       {
  530.     if (!strncmp(&buff[offset+30L], "\xFA\xFB\xFC\xFD\xFE\xFF", 6 ))
  531.     {
  532.       found = TRUE;
  533.       break;         /* escape from FOR loop */
  534.     }
  535.       }
  536.      }
  537.  
  538.      if (!found && !eof(fn)) /* reposition back 6+24+5 to recover from split search string */
  539.      {
  540.        if (lseek (fn, -35L, SEEK_CUR)==FAILURE)
  541.        {
  542.          show_error("Seek error");
  543.          close(fn);
  544.          free(buff);
  545.          return FAILURE;
  546.        }
  547.      }
  548.  
  549.      tot_offset+=offset;  /* after a lseek operation, the 36 bytes in the end-condition in the loop */
  550.               /* eliminates the need of substraction of 35 bytes for lseek */
  551.  
  552.    }
  553.    free(buff);
  554.  
  555.    if (!found)
  556.    {
  557.     show_error("Cannot locate color storage position");
  558.     close(fn);
  559.     return FAILURE;
  560.    }
  561.  
  562.    /* Write the colors structure into the exe file */
  563.    if (lseek (fn, tot_offset + 6L, SEEK_SET)==FAILURE) show_error("Seek error");
  564.       else if (write(fn,&colors, 24)==FAILURE) show_error("Write error");
  565.    if (close(fn)==FAILURE) show_error("Close error");
  566.    return SUCCESS;
  567. }
  568.  
  569.  
  570. /* process a command-line switch or environmental variable in string param */
  571. void interpret_params( char *imagename, int argc, char *param,
  572.                int *no_return, int *init_screen, int *testing,
  573.                int *wait, int *swap_types, int *allow_swap,
  574.                int *keep_path, int *max_files, int *mask_argc_number,
  575.                int *mask_starting_char, int *mask_length,
  576.                int *safe_mode, int *order_by, int *order_type)
  577. {
  578.     char scratch[_MAX_PATH];
  579.     char *p;
  580.     int swap_to_disk=TRUE;      /* can't test on symbol SWAP_DISK (0) */
  581.  
  582.     strcpy(scratch,param);
  583.     switch (scratch[0])
  584.     {
  585.     case '1': *no_return=TRUE;
  586.           break;
  587.     case 'C': *init_screen=COLOR;
  588.           set_colors(scratch);
  589.           break;
  590.     case 'D': setting_factory_defaults=TRUE;
  591.           if (save_colors_in_exe(imagename,set_colors(scratch))==FAILURE)
  592.              show_error("Can't save colors and/or switch");
  593.           break;
  594.     case 'T': *testing=TRUE;
  595.           break;
  596.     case 'M': *init_screen=MONO;
  597.           break;
  598.     case 'W': *wait=TRUE;
  599.           break;
  600.     case 'N': *safe_mode=TRUE;
  601.           break;
  602.     case 'S': if (!strlen(scratch+1)) *allow_swap=FALSE; /* only S, disable all swapping */
  603.           else
  604.           {
  605.             *swap_types=0;              /* reset all */
  606.             swap_to_disk=FALSE;
  607.             if (strchr(scratch+1,(int) 'D')) 
  608.             {
  609.              *swap_types |= SWAP_DISK; /* allow disk swaps */ 
  610.              swap_to_disk=TRUE;
  611.             }
  612.             if (strchr(scratch+1,(int) 'E')) *swap_types |= SWAP_EMS; /* allow EMS */ 
  613.             if (strchr(scratch+1,(int) 'X')) *swap_types |= SWAP_XMS; /* allow XMS */ 
  614.             if (strchr(scratch+1,(int) 'T')) *swap_types |= SWAP_EXT; /* allow raw EXT */
  615.             if (!swap_to_disk) strcpy(swap_dir,"");  /* disable disk_swaps */
  616.             init_SPAWNO(swap_dir,*swap_types);
  617.           }
  618.           break;
  619.     case 'O': *order_by=NONE;
  620.           if (strlen(scratch)>1)
  621.           switch(scratch[1])
  622.           { 
  623.             case 'D': *order_by=DATE;
  624.                   break;
  625.             case 'S': *order_by=SIZE;
  626.                   break;
  627.             case 'N':
  628.             default: *order_by=NAME;
  629.                  break;
  630.           }
  631.           if (strlen(scratch)>2)
  632.           switch(scratch[2])
  633.           { 
  634.             case '-': *order_type=DESCENDING;
  635.                   break;
  636.             case '+':
  637.             default: *order_type=ASCENDING;
  638.                  break; 
  639.           }
  640.           break;
  641.     case 'R': *keep_path=TRUE;
  642.           break;
  643.     case 'B': strcpy(turnover_datetime_string,scratch+1);
  644.               if (set_turnover_datetime( turnover_datetime_string )==FAILURE)
  645.           {
  646.               strcat(scratch," ignored");
  647.               show_error(scratch);
  648.           }
  649.           break;
  650.     case 'F': *max_files=atoi(scratch+1);
  651.           if (*max_files<=0 || *max_files>0x7FFF)
  652.           {
  653.               *max_files=MAX_FILES;
  654.               strcat(scratch," ignored");
  655.               show_error(scratch);
  656.           }
  657.           break;
  658.     case 'P': *mask_argc_number=atoi(scratch+1);
  659.           if (*mask_argc_number<2 || *mask_argc_number >=argc)
  660.           {
  661.              *mask_argc_number=2;
  662.              strcat(scratch," ignored");
  663.              show_error(scratch);
  664.              break;
  665.           }
  666.           p = strtok( scratch+1, "," );  /* skip first token, already processed */
  667.           p = strtok( NULL, ",");        /* find next token */
  668.           if (p!=NULL)
  669.           {
  670.              *mask_starting_char=atoi(p);
  671.              if (*mask_starting_char<1) 
  672.              {
  673.              *mask_starting_char=1;
  674.              strcat(scratch," c,l component ignored");
  675.              show_error(scratch);
  676.              break;
  677.              }
  678.              p = strtok(NULL, ",");
  679.           }
  680.           if (p!=NULL)
  681.           {
  682.              *mask_length=atoi(p);
  683.              if (*mask_length<0 || *mask_length>13) 
  684.              {
  685.              *mask_length=0;
  686.              strcat(scratch," l component ignored");
  687.              show_error(scratch);
  688.              break;
  689.              }
  690.           }
  691.           break;
  692.     default: /* ignore unknown FS switches*/
  693.          strcat(scratch," ignored");
  694.          show_error(scratch);
  695.          break;
  696.     }
  697. }
  698.  
  699.  
  700.  
  701. /* Puts complete filename in processor string or "" if not found
  702.  */
  703. void locate_processor(char *command, char *processor)
  704. {
  705.     char drive[_MAX_DRIVE], dir[_MAX_DIR];
  706.     char fname[_MAX_FNAME], ext[_MAX_EXT];
  707.     char scratch[_MAX_DRIVE + _MAX_DIR + _MAX_FNAME + _MAX_EXT];
  708.  
  709.     _strupr(command);
  710.     _splitpath( command, drive, dir, fname, ext );
  711.  
  712.     if (strlen(dir) || strlen(drive))    /* location is known */
  713.     {
  714.     if (strlen(ext))                 /* extension is known */
  715.     {
  716.         if (EXIST(command)) strcpy(processor,command);
  717.         else strcpy(processor,"");
  718.         return;
  719.     }
  720.  
  721.     strcpy(scratch,command);         /* look for .COM */
  722.     strcat(scratch,".COM");
  723.     if (EXIST(scratch))
  724.     {
  725.         strcpy(processor,scratch);
  726.         return;
  727.     }
  728.  
  729.     strcpy(scratch,command);         /* look for .EXE */
  730.     strcat(scratch,".EXE");
  731.     if (EXIST(scratch))
  732.     {
  733.         strcpy(processor,scratch);
  734.         return;
  735.     }
  736.  
  737.     strcpy(scratch,command);         /* look for .BAT */
  738.     strcat(scratch,".BAT");
  739.     if (EXIST(scratch))
  740.     {
  741.         strcpy(processor,scratch);
  742.         return;
  743.     }
  744.  
  745.     strcpy(processor,"");            /* failed */
  746.     return;
  747.     }
  748.  
  749.     if (strlen(ext))      /* complete filename.ext is known */
  750.     {
  751.     strcpy(scratch,fname);
  752.     strcat(scratch,ext);
  753.     _searchenv( scratch, "PATH", processor );
  754.     return;
  755.     }
  756.  
  757.     /* construct executable filenames */
  758.     strcpy(scratch,fname);
  759.     strcat(scratch,".COM");
  760.     _searchenv( scratch, "PATH", processor );
  761.     if (strlen(processor)) return;             /* found FILE.COM */
  762.  
  763.     strcpy(scratch,fname);
  764.     strcat(scratch,".EXE");
  765.     _searchenv( scratch, "PATH", processor );
  766.     if (strlen(processor)) return;             /* found FILE.EXE */
  767.  
  768.     strcpy(scratch,fname);
  769.     strcat(scratch,".BAT");
  770.     _searchenv( scratch, "PATH", processor );
  771.     if (strlen(processor)) return;             /* found FILE.BAT */
  772.  
  773.     strcpy(processor,"");                      /* failed */
  774. }
  775.