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 >
C/C++ Source or Header  |  1993-02-24  |  19KB  |  533 lines

  1. /* FS0.C
  2.  * main program body
  3.  * MSC6
  4.  * FS 1.9.1
  5.  * 240293
  6.  * Copyright (C) M.C.J. van Breemen, 1993, All rights reserved.
  7.  */
  8.  
  9. #include "FS.H"       /* most C header files are included here ! */
  10. #include "xspawn.h"
  11.  
  12. /* Prototypes */
  13. int  handle_dir( char *searchstring, char *selected , int safe_mode);
  14. void execute(char *comm, char **a, int tot_commargs, int no_return, int testing);
  15. void main(int argc, char *argv[]);
  16. int convcolorinfo( char colinfo );
  17. int set_colors( char *scratch);
  18. char *saveScrn (void);
  19. char *restScrn(char *saveArea);
  20. int getkey(void);
  21. void show_error( char *message );
  22. int save_colors_in_exe( char *imagename , int setcolorresult);
  23. char *set_working_drive_and_dir( char *full_filename );
  24. void interpret_params( char *imagename, int argc, char *param,
  25.                int *no_return, int *init_screen, int *testing,
  26.                int *wait, int *_useems, int *_swap,
  27.                int *keep_path, int *max_files, int *mask_argc_number,
  28.                int *safe_mode);
  29.  
  30. extern int max_files; /* max. number of files accessible */
  31.  
  32. extern short int screen_bg_color;
  33. extern short int file_color;
  34. extern short int directory_color;
  35. extern short int cursor_bg_color;
  36. extern short int cursor_file_color;
  37. extern short int cursor_directory_color;
  38. extern short int info_bg_color;
  39. extern short int info_text_color;
  40. extern short int error_text_color;
  41. extern short int prompt_text_color;
  42. extern short int hidden_file_color;
  43. extern short int hidden_directory_color;
  44. extern short int volume_label_color;
  45. extern short int cursor_hidden_file_color;
  46. extern short int cursor_hidden_directory_color;
  47. extern short int cursor_volume_label_color;
  48.  
  49. /*******************************************************************************
  50. */
  51. void main( int argc, char *argv[] )
  52. {
  53.     char selected[_MAX_PATH]; /* selected file */
  54.     char mask[_MAX_PATH];     /* filter */
  55.     char scratch[_MAX_PATH];  /* temporary strings, really scratch */
  56.     int init_screen=FALSE;    /* initialise display adapter */
  57.     int no_return=FALSE;      /* run FS once */
  58.     int keep_path=FALSE;      /* keep initial drive and directory path */
  59.     int wait=FALSE;          /* wait for a keystroke before resetting screen */
  60.     int safe_mode=FALSE;      /* changes to files not allowed (/N) */
  61.     int iTeller;              /* counter */
  62.     int mask_argc_number=2;   /* default place of mask in argument list */
  63.     char *slash;              /* pointer to FSSWITCH env (we only want the first char!) */
  64.     char fsswitch;            /* parameter switch character for FS */
  65.     int olddrive;             /* old current drive */
  66.     char oldcwd[_MAX_PATH];   /* old current working directory */
  67.     int commarg[15];          /* initial argument list */
  68.     int tot_commargs=0;       /* number of command arguments */
  69.     char *arglist[15];        /* final argument list */
  70.     struct videoconfig vc;    /* video info structure */
  71.     char *savedscreen;        /* pointer to saved screen memory */
  72.     char swapto[_MAX_PATH];   /* stringspace for _swappath */
  73.     struct rccoord oldpos;    /* old cursor position (_setvideomode will reset to 0,0) */
  74.     int handle_dir_result;
  75.     int testing=FALSE;          /* if TRUE, test mode, show command line */
  76.     char *p;              /* char pointer for strtok */
  77.  
  78.     /* build the _swappath global, if NULL, xswap uses current dir */
  79.     strcpy( swapto, getenv("TMP") );    /* try this path first */
  80.     if (!strlen(swapto)) strcpy( swapto, getenv("TEMP") );  /* maybe this one ? */
  81.     if (strlen(swapto))
  82.     {
  83.      strcat( swapto, ";" );
  84.      getcwd( scratch, _MAX_PATH );
  85.      strcat( swapto, scratch );     /* try this path last */
  86.      _swappath=swapto;
  87.     }
  88.  
  89.     _getvideoconfig( &vc );
  90.  
  91.     savedscreen=saveScrn();         /* save video memory */
  92.     oldpos = _gettextposition();
  93.  
  94.     /* Save current drive and current working directory. */
  95.     olddrive=_getdrive();
  96.     getcwd( oldcwd, _MAX_PATH );
  97.  
  98.     slash=getenv("FSSWITCH");          /* alternative FS switch character */
  99.     if (slash) fsswitch=*slash;
  100.     else fsswitch='/';
  101.  
  102.     /* process arguments from environment */
  103.     strcpy(scratch,getenv("FSPARAMS"));
  104.     strupr(scratch);
  105.     p = strtok( scratch, " ;" );    /* Find first token */
  106.     while( p != NULL )
  107.     {
  108.     if (p[0]!='D')             /* v parameters without switch */
  109.        interpret_params( argv[0], argc, p, &no_return, &init_screen,
  110.                  &testing, &wait, &_useems,
  111.                  &_swap, &keep_path, &max_files, &mask_argc_number,
  112.                  &safe_mode);
  113.     p = strtok( NULL, " ;");
  114.     }
  115.  
  116.     for (iTeller=0;iTeller<15;iTeller++) /* reset argument list */
  117.     {
  118.     commarg[iTeller]=0;
  119.     arglist[iTeller]=(char *) 0L;
  120.     }
  121.  
  122.     if (argc<2 || (argv[1][0]==fsswitch)) /* at least a command should be present, show info */
  123.     {
  124.      printf("\nFS 1.9.1  Copyright (C) M.C.J. van Breemen, 1993, All rights reserved.\n"
  125.         "Syntax: FS command filemask %c1 %cChex %cM %cR %cFnum %cPnum %cW %cSe %cDhex %cT\n"
  126.         "%c1\tRun FS only once\n"
  127.         "%cChex\tSet color mode & optionally set run-time colors (16 hex digits)\n"
  128.         "%cM\tSet monochrome mode\n%cR\tRestore drive & dir\n"
  129.         "%cFnum\tAllocate memory for 'num' files pro directory (default 456)\n"
  130.         "%cPnum\tPosition of filemask (default 2, directly after command)\n"
  131.         "%cW\tWait for a key pressed before returning\n"
  132.         "%cS\tDisable all swapping (%cSE Disable swapping to EMS)\n"
  133.         "%cDhex\tSave & optionally set default colors (16 hex digits)\n"
  134.         "%cT\tTest mode, show resulting commandline\n"
  135.         "%cN\tNo changes to files allowed in FS, safe mode\n"
  136.         "\tOther non-FS arguments are passed through in the same order\n"
  137.         "The %c switch can be re-defined with environment variable FSSWITCH\n"
  138.         "All parameters except D are also definable with environment variable FSPARAMS\n"
  139.         "which should be defined as a list of parameters without switch character,\n"
  140.         "separated by space or ;\n"
  141.         "Run-time commandline parameters will override FSPARAMS settings\n",
  142.         fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,
  143.         fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,
  144.         fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch,fsswitch);
  145.      exit(1);
  146.     }
  147.  
  148.     /* position of filemask is needed before processing of the commandline parameters */
  149.     for (iTeller=2;iTeller<argc;iTeller++)  /* where is the filemask ? */
  150.     {
  151.         strcpy(scratch,argv[iTeller]);
  152.         strupr(scratch);
  153.         if (scratch[0]==fsswitch && (scratch[1]=='P'))
  154.         {                      /* vvvvvvvvv skip switch */
  155.         interpret_params( argv[0], argc, scratch+1, &no_return, &init_screen,
  156.                   &testing, &wait, &_useems,
  157.                   &_swap, &keep_path, &max_files, &mask_argc_number,
  158.                   &safe_mode);
  159.         break;
  160.         }
  161.     }
  162.  
  163.     /* process arguments from command line (will override environment) */
  164.     for (iTeller=2;iTeller<argc;iTeller++)  /* process FS & command switches */
  165.     {
  166.         strcpy(scratch,argv[iTeller]);
  167.         strupr(scratch);
  168.         if (scratch[0]==fsswitch)
  169.         {                      /* vvvvvvvvv skip switch */
  170.         interpret_params( argv[0], argc, scratch+1, &no_return, &init_screen,
  171.                   &testing, &wait, &_useems,
  172.                   &_swap, &keep_path, &max_files, &mask_argc_number,
  173.                   &safe_mode);
  174.  
  175.         if (iTeller==2 && mask_argc_number==2) commarg[tot_commargs++]=2;
  176.            /* parameter found on default filemask place */
  177.            /* count this one as filemask to enable selected string replacement */
  178.  
  179.         } else
  180.          if (tot_commargs<15) /* mark command arguments */
  181.             commarg[tot_commargs++]=iTeller;
  182.          else show_error("Argument list full");
  183.     }
  184.  
  185.     /* no arguments at all, create the default filemask argument */
  186.     if (!tot_commargs) commarg[tot_commargs++]=mask_argc_number;
  187.  
  188.  
  189.     /* construct arglist array */
  190.     for (iTeller=0;iTeller<tot_commargs;iTeller++)
  191.     {
  192.        if (commarg[iTeller]!=mask_argc_number) arglist[iTeller]=argv[commarg[iTeller]];
  193.        else arglist[iTeller]=selected;
  194.     }
  195.  
  196.     _settextposition( oldpos.row, oldpos.col );  /* recover from show_error calls */
  197.  
  198.     strcpy(mask, argv[mask_argc_number]);   /* get mask */
  199.     if (mask[0]==fsswitch) strcpy(mask,"*.*"); /* a switch ? */
  200.     if (strlen(mask)>13) mask[13]='\0';        /* max. 13 characters! */
  201.  
  202.     while (TRUE) /* select a file */
  203.     {
  204.     if (init_screen)
  205.     {
  206.       /* set video mode */
  207.       if (init_screen==COLOR)
  208.          if( !_setvideomode( _TEXTC80 ) )
  209.         _setvideomode( _TEXTMONO );
  210.       if (init_screen==MONO)
  211.          _setvideomode( _TEXTMONO );
  212.     }
  213.  
  214.     strcpy(selected,"");
  215.     handle_dir_result=handle_dir( mask , selected , safe_mode);
  216.     if (init_screen)
  217.     {
  218.         _setvideomode(vc.mode); /* restore old video mode */
  219.         _settextposition( oldpos.row, oldpos.col );
  220.     }
  221.     if (handle_dir_result==EXIT_RESTORE || handle_dir_result==FAILURE)
  222.     {
  223.           _chdrive( olddrive );    /* restore path */
  224.           chdir( oldcwd );
  225.           break; /* ESC, break out of TRUE loop */
  226.     }
  227.     if (handle_dir_result==EXIT_KEEP) break; /* ESC, break out of TRUE loop */
  228.  
  229.     /* a lot of foggy stuff with the _chdrive and chdir around this because we have to handle the L function */
  230.  
  231.     if (keep_path || no_return)  /* restore path before executing commands */
  232.     {
  233.        _chdrive( olddrive );
  234.        chdir( oldcwd );
  235.     }
  236.  
  237.     if (no_return) savedscreen=restScrn(savedscreen);          /* restore video memory */
  238.     execute( argv[1], arglist, tot_commargs, no_return, testing );
  239.     if (!keep_path && !no_return) /* change to the selected drive and directory for future calls */
  240.        set_working_drive_and_dir( selected );
  241.  
  242.     if (wait || testing)
  243.     {
  244.          _outtext("\n*** Press any key to continue ***");
  245.           getkey();
  246.          _outtext("\r                                 ");
  247.     }
  248.  
  249.     if (no_return) break;          /* /1 switch and still alive, get out! */
  250.     }
  251.  
  252.     savedscreen=restScrn(savedscreen);      /* this is double if execlp fails on /1, but who cares */
  253.     exit( 0 );
  254. }
  255.  
  256. /****************************************************************************
  257.    command executor, uses execlp for single run, spawnlp for multiple runs of
  258.    external commands, system for internal commands.
  259.    uses xspawn functions if _swap=0
  260.    comm        : command string
  261.    a           : pointer to the argument string list, short name to keep it readable.
  262.    tot_commargs: number of arguments
  263.    no_return   : single run, use execlp instead of spawnlp
  264.    testing     : show command, do not execute
  265. */
  266. void execute(char *comm, char **a, int tot_commargs, int no_return, int testing)
  267. {
  268.     char scratch[_MAX_PATH];
  269.     int error, iTeller;
  270.  
  271.     if (testing)
  272.     {
  273.          strcpy(scratch,"\n");
  274.          strcat(scratch,comm);
  275.          for (iTeller=0;iTeller<tot_commargs;iTeller++)
  276.          {
  277.          strcat(scratch," ");
  278.          strcat(scratch,a[iTeller]);
  279.          }
  280.          strcat(scratch,"\n");
  281.          _outtext(scratch);
  282.          return;
  283.     }
  284.  
  285.     if (no_return)
  286.          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 );
  287.         /* this will normally not return, write-over FS code, do not swap */
  288.     else
  289.     {
  290.         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 */
  291.         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 */
  292.     }
  293.     if (error==-1)
  294.     {
  295.          /* Can't execute or spawn this process, probably resident MS-DOS
  296.           * Let us hope spawn is not returning a -1 return code and try
  297.           * a system call now */
  298.          strcpy(scratch,comm);
  299.          for (iTeller=0;iTeller<tot_commargs;iTeller++)
  300.          {
  301.          strcat(scratch," ");
  302.          strcat(scratch,a[iTeller]);
  303.          }
  304.          if (!_swap) xsystem(scratch);
  305.          else system(scratch);
  306.     }
  307. }
  308.  
  309. /* Converts hex digits to decimals, make invalid digits 0
  310. */
  311. int convcolorinfo( char colinfo)
  312. {
  313.     toupper(colinfo);
  314.     if ((colinfo >= '0') && (colinfo <= '9')) return ((int) (colinfo - '0'));
  315.     else if ((colinfo >= 'A') && (colinfo <= 'F')) return ((int) (colinfo - 'A') + 10);
  316.      else return 0;
  317. }
  318.  
  319. /* Process ?hhhhhhhhhhhhhhhh option to colors
  320. */
  321. int set_colors( char *scratch)
  322. {
  323.   if (strlen(scratch)==1) return FAILURE; /* do not set run-time colors */
  324.   if (strlen(scratch)==17) /* process color info */
  325.   {
  326.      screen_bg_color       =convcolorinfo(scratch[1]);
  327.      file_color        =convcolorinfo(scratch[2]);
  328.      directory_color       =convcolorinfo(scratch[3]);
  329.      cursor_bg_color       =convcolorinfo(scratch[4]);
  330.      cursor_file_color       =convcolorinfo(scratch[5]);
  331.      cursor_directory_color=convcolorinfo(scratch[6]);
  332.      info_bg_color       =convcolorinfo(scratch[7]);
  333.      info_text_color       =convcolorinfo(scratch[8]);
  334.      error_text_color       =convcolorinfo(scratch[9]);
  335.      prompt_text_color       =convcolorinfo(scratch[10]);
  336.      hidden_file_color       =convcolorinfo(scratch[11]);
  337.      hidden_directory_color=convcolorinfo(scratch[12]);
  338.      volume_label_color    =convcolorinfo(scratch[13]);
  339.      cursor_hidden_file_color      =convcolorinfo(scratch[14]);
  340.      cursor_hidden_directory_color=convcolorinfo(scratch[15]);
  341.      cursor_volume_label_color      =convcolorinfo(scratch[16]);
  342.      return SUCCESS;
  343.   }  else show_error("Incorrect color string, using defaults ");
  344.   return FAILURE;
  345. }
  346.  
  347. /***************************************************************************
  348.  Save default colors, patch FS.EXE
  349.  setcolorresult SUCCESS: nieuwe colors zetten in image
  350.         FAILURE: default colors zetten in image en run-time
  351.  zoek naar fffefdfcfbfa, kontroleer of na 32 bytes fafbfcfdfeff komt en
  352.  patch 16 short integers daartussen
  353. */
  354.  
  355.  
  356. int save_colors_in_exe( char *imagename , int setcolorresult)
  357. {
  358.      char *buff;                 /* Pointer to data buffer */
  359.      struct color  {
  360.             short int c1;
  361.             short int c2;
  362.             short int c3;
  363.             short int c4;
  364.             short int c5;
  365.             short int c6;
  366.             short int c7;
  367.             short int c8;
  368.             short int c9;
  369.             short int c10;
  370.             short int c11;
  371.             short int c12;
  372.             short int c13;
  373.             short int c14;
  374.             short int c15;
  375.             short int c16;
  376.            } colors;
  377.      int fn;                     /* file handle */
  378.      long fl;                    /* file length */
  379.      unsigned int count=0x7fff;  /* buffer size */
  380.      int  found;                 /* True if checkpoint code found */
  381.      long rsize;                 /* Amount of data read into buffer */
  382.      long tot_offset,offset;     /* Position where checkpoint code found */
  383.  
  384.      if (setcolorresult==FAILURE)    /* set & patch factory defaults */
  385.     set_colors("C17E47E2FCEFA3FA3");
  386.  
  387.      colors.c1=screen_bg_color;
  388.      colors.c2=file_color;
  389.      colors.c3=directory_color;
  390.      colors.c4=cursor_bg_color;
  391.      colors.c5=cursor_file_color;
  392.      colors.c6=cursor_directory_color;
  393.      colors.c7=info_bg_color;
  394.      colors.c8=info_text_color;
  395.      colors.c9=error_text_color;
  396.      colors.c10=prompt_text_color;
  397.      colors.c11=hidden_file_color;
  398.      colors.c12=hidden_directory_color;
  399.      colors.c13=volume_label_color;
  400.      colors.c14=cursor_hidden_file_color;
  401.      colors.c15=cursor_hidden_directory_color;
  402.      colors.c16=cursor_volume_label_color;
  403.  
  404.    if( (fn = open( imagename, O_BINARY | O_RDWR )) == - 1 )
  405.    {
  406.      show_error("FS image not found ");
  407.      return FAILURE;
  408.    }
  409.    /* Get size of file */
  410.    fl = filelength(fn);
  411.    if( fl <  (long) count )
  412.     count = (unsigned int) fl;
  413.  
  414.     /* Dynamically allocate a large file buffer. If there's not enough
  415.      * memory for it, find the largest amount available on the near heap
  416.      */
  417.     if( !(buff = (char *)malloc( (size_t)count )) )
  418.     {
  419.     count = _memmax();
  420.     if( !(buff = (char *)malloc( (size_t)count )) )
  421.     {
  422.          show_error("Cannot allocate memory ");
  423.          close(fn);
  424.          return FAILURE;
  425.     }
  426.     }
  427.  
  428.    found = FALSE;
  429.    tot_offset=0L;
  430.    while ( !eof(fn) && !found)
  431.    {
  432.      if( (rsize = (long) read( fn, buff, count )) == FAILURE )
  433.      {
  434.          show_error("Read error ");
  435.          close(fn);
  436.          free(buff);
  437.          return FAILURE;
  438.      }
  439.      for (offset=0L; offset <= rsize-44L; offset++)    /* 6+32+6 */
  440.      {
  441.       if (!strncmp(&buff[offset], "\xFF\xFE\xFD\xFC\xFB\xFA", 6 ))
  442.       {
  443.     if (!strncmp(&buff[offset+38L], "\xFA\xFB\xFC\xFD\xFE\xFF", 6 ))
  444.     {
  445.       found = TRUE;
  446.       break;         /* escape from FOR loop */
  447.     }
  448.       }
  449.      }
  450.  
  451.      if (!found && !eof(fn)) /* reposition back 6+32+5 to recover from split search string */
  452.      {
  453.        if (lseek (fn, -43L, SEEK_CUR)==FAILURE)
  454.        {
  455.          show_error("Seek error ");
  456.          close(fn);
  457.          free(buff);
  458.          return FAILURE;
  459.        }
  460.      }
  461.  
  462.      tot_offset+=offset;  /* after a lseek operation, the 44 bytes in the end-condition in the loop */
  463.               /* eliminates the need of substraction of 43 bytes for lseek */
  464.  
  465.    }
  466.    free(buff);
  467.  
  468.    if (!found)
  469.    {
  470.     show_error("Cannot locate color storage position ");
  471.     close(fn);
  472.     return FAILURE;
  473.    }
  474.  
  475.    /* Write the colors structure into the exe file */
  476.    if (lseek (fn, tot_offset + 6L, SEEK_SET)==FAILURE) show_error("Seek error ");
  477.       else if (write(fn,&colors, 32)==FAILURE) show_error("Write error ");
  478.    if (close(fn)==FAILURE) show_error("Close error ");
  479.    return SUCCESS;
  480. }
  481.  
  482.  
  483.  
  484. void interpret_params( char *imagename, int argc, char *param,
  485.                int *no_return, int *init_screen, int *testing,
  486.                int *wait, int *_useems, int *_swap,
  487.                int *keep_path, int *max_files, int *mask_argc_number,
  488.                int *safe_mode)
  489. {
  490.     char scratch[_MAX_PATH];
  491.  
  492.     strcpy(scratch,param);
  493.     switch (scratch[0])
  494.     {
  495.     case '1': *no_return=TRUE;
  496.           break;
  497.     case 'C': *init_screen=COLOR;
  498.           set_colors(scratch);
  499.           break;
  500.     case 'D': if (save_colors_in_exe(imagename,set_colors(scratch))==FAILURE)
  501.              show_error("Can't save colors ");
  502.           break;
  503.     case 'T': *testing=TRUE;
  504.           break;
  505.     case 'M': *init_screen=MONO;
  506.           break;
  507.     case 'W': *wait=TRUE;
  508.           break;
  509.     case 'N': *safe_mode=TRUE;
  510.           break;
  511.     case 'S': if (scratch[1]=='E') *_useems=1; /* do not use EMS */
  512.           else *_swap=1;    /* disable all swapping, 0=do swap, ^0=do not swap */
  513.           break;
  514.     case 'R': *keep_path=TRUE;
  515.           break;
  516.     case 'F': *max_files=atoi(scratch+1);
  517.           if (*max_files<=0)
  518.           {
  519.               *max_files=MAX_FILES;
  520.               strcat(scratch," ignored");
  521.               show_error(scratch);
  522.           }
  523.           break;
  524.     case 'P': *mask_argc_number=atoi(scratch+1);
  525.           if (*mask_argc_number<2 || *mask_argc_number >=argc) *mask_argc_number=2;
  526.           break;
  527.     default: /* ignore unknown FS switches*/
  528.          strcat(scratch," ignored");
  529.          show_error(scratch);
  530.          break;
  531.     }
  532. }
  533.