home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / mslang / fs24 / fs0.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-19  |  26.5 KB  |  763 lines

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