home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cenvi23.zip / BATCH.CMM < prev    next >
Text File  |  1996-01-02  |  21KB  |  798 lines

  1. /*
  2.  * Batch.cmm
  3.  *
  4.  *   Interpret a DOS batch file using CEnvi. This should work on all CEnvi
  5.  *   versions.
  6.  */
  7.  
  8. /* ---------------------------------------------------------------------- */
  9.  
  10. usage()
  11. {
  12.   printf("Use the BATCH command to interpret a DOS batch file under any system\n");
  13.   printf("that CEnvi supports.\n");
  14.   printf("Syntax:\n  BATCH [filename] [args]\nwhere:\n");
  15.   printf("  filename          The .BAT file to be interpreted.\n");
  16.   printf("  args              Any number of arguments for the batch file.\n");
  17.   exit(EXIT_FAILURE);;
  18. }
  19.  
  20. /* ---------------------------------------------------------------------- */
  21.  
  22. /*
  23.  * Setup sets up all system dependent variables. Later, when #ifdef is working
  24.  * this will be replaced using that.
  25.  */
  26.  
  27. search_path = "";       // make it global
  28. errorlevel = 0;
  29. echo = 1;               // echo on
  30.  
  31.  
  32. setup()
  33. {
  34.   if( defined(_NWNLM_) )
  35.     {
  36.       search_path = "SYS:/CENVI/";
  37.     } else {
  38.       if( defined(CMMPATH) ) search_path = CMMPATH;
  39.     }
  40. }
  41.  
  42. /*
  43.  * Change the current directory to the given one. Return 0 if successful.
  44.  */
  45. my_chdir(newdir)
  46. {
  47.   if( defined(_NWNLM_) ) return chdir(newdir);
  48.   if( defined(_DOS_) || defined(_DOS32_) || defined(_WINDOWS_) )
  49.     {
  50.       lReg.ah = 0x3B;
  51.       if !defined(_DOS32_)
  52.          lReg.ds = segment(newdir), lReg.dx = offset(newdir);
  53.       else
  54.          lReg.dx = pointer(newdir);
  55.       interrupt(0x21,lReg,out);
  56.  
  57.       return out.ax;
  58.     }
  59.   if( defined(_NTCON_) || defined(_NTWIN_) || defined(_95CON_) ||
  60.       defined(_95WIN_) )
  61.     {
  62.       return !DynamicLink("KERNEL32","SetCurrentDirectoryA",STDCALL,newdir);
  63.     }
  64.   if( defined(_OS2_) )
  65.     {
  66. #define ORD_DOS32SETCURRENTDIR   255
  67.       return DynamicLink("doscalls",ORD_DOS32SETCURRENTDIR,BIT32,CDECL,newdir);
  68.     }
  69. }
  70.  
  71. special_command = "__@%*&^%";
  72.  
  73. /* ---------------------------------------------------------------------- */
  74.  
  75. /*
  76.  * The count is the number of params, the array is the params. These
  77.  * correspond to %X where X is a digit. We also do %variable% for environment
  78.  * variables, all uppercase.
  79.  *
  80.  * To ease processing, we kill the '\n' too.
  81.  */
  82. substitute_line(line,count,array)
  83. {
  84.   it = ""; i = 0; j = 0;
  85.   while( line[i] )
  86.     {
  87.       if( line[i]!='%' )
  88.         {
  89.           if( line[i]!='\n' )
  90.             {
  91.               it[j++] = line[i];
  92.             }
  93.           i++;
  94.           continue;
  95.         }
  96. // Here we have a substitution...
  97.       if( isdigit(line[i+1]) )
  98.         {
  99.           i += 2;
  100.           num = line[i-1]-'0';
  101.           if( num>=count ) continue;     // no such argument
  102.           for( k=0;array[num][k];k++ ) it[j++] = array[num][k];
  103.         } else {
  104.           if( line[++i]=='%' )
  105.             {
  106.               i++; it[j++] = '%'; continue;
  107.             }
  108.  
  109.           env = ""; offset = 0;
  110.           for( ;line[i] && !isspace(line[i]) && line[i]!='%';i++ )
  111.             env[offset++] = line[i];
  112.  
  113.           if( isspace(line[i]) )
  114.             {
  115.               printf("Variable is not terminated.\n");
  116.               return "";
  117.             }
  118.  
  119.           env[offset] = 0; i++;
  120.           value = "";
  121.           sprintf(to_exec,"if( DataType(%s)==CMM_INT ) sprintf(value,\"%%d\",%s); else if( DataType(%s)==CMM_BYTE ) strcpy(value,%s);\n",env,env,env,env);
  122.           Interpret(to_exec,INTERP_TEXT);
  123.           while( value[0]!='\0' ) { it[j++] = value[0]; value++; }
  124.         }
  125.     }
  126.   it[j] = '\0';
  127.   return it;
  128. }
  129.  
  130. /*
  131.  * Search the appropriate places for the given name. If found, return the
  132.  * full filename else return NULL.
  133.  */
  134. find_cmm(name)
  135. {
  136. // First search the exact filename
  137.   if( fp = fopen(name,"r") )
  138.     {
  139.       fclose(fp);
  140.       return FullPath(name);
  141.     }
  142.  
  143. // Then search the filename converted to '.cmm'
  144.   path = SplitFileName(name);
  145.   sprintf(newname,"%s%s.cmm",path.dir,path.name);
  146.   if( fp = fopen(newname,"r") )
  147.     {
  148.       fclose(fp);
  149.       return FullPath(newname);
  150.     }
  151.  
  152. // Then search the converted filename using the search path.
  153.   strcpy(tmppath,search_path);
  154.   while( tmppath[0]!='\0' )
  155.     {
  156.       while( tmppath[0]==';' ) tmppath++;
  157.       start = tmppath;
  158.       while( tmppath[0]!='\0' && tmppath[0]!=';' ) tmppath++;
  159.       tmppath[0] = '\0'; tmppath++;
  160.       sprintf(newname,"%s%c%s.cmm",start,strchr(start,'/')?'/':'\\',path.name);
  161.       if( fp = fopen(newname,"r") )
  162.         {
  163.           fclose(fp);
  164.           return FullPath(newname);
  165.         }
  166.     }
  167.  
  168. // Else not found
  169.   return NULL;
  170. }
  171.  
  172. /* ---------------------------------------------------------------------- */
  173.  
  174. next_token(line,index)
  175. {
  176.   command = ""; j = 0;
  177.   while( isspace(line[index]) ) index++;
  178.   while( line[index] && !isspace(line[index]) )
  179.     command[j++] = line[index++];
  180.   while( isspace(line[index]) ) index++;
  181.   command[j] = '\0';
  182.   return command;
  183. }
  184.  
  185. /* ---------------------------------------------------------------------- */
  186.  
  187. // All these functions return the name of the label we have to GOTO, or ""
  188. // if none.
  189.  
  190.  
  191. /*
  192.  * We just ignore the line.
  193.  */
  194. REM_handler(the_line,ptr,line_num)
  195. {
  196.   return "";
  197. }
  198.  
  199.  
  200.  
  201. /*
  202.  * We dump the text to the terminal. The exceptions are if we have 'echo on'
  203.  * or 'echo off'.
  204.  */
  205. ECHO_handler(the_line,ptr,line_num)
  206. {
  207.   if( !stricmp(the_line+ptr,"ON") )
  208.     {
  209.       echo = 1;
  210.       return "";
  211.     }
  212.   if( !stricmp(the_line+ptr,"OFF") )
  213.     {
  214.       echo = 0;
  215.       return "";
  216.     }
  217.  
  218.   printf("%s\n",the_line+ptr);
  219.   return "";
  220. }
  221.  
  222.  
  223.  
  224. /*
  225.  * If no parameter, print the current directory. Otherwise, set the current
  226.  * directory to what is given.
  227.  */
  228. CD_handler(the_line,ptr,line_num)
  229. {
  230.   if( the_line[ptr]=='\0' )
  231.     {
  232.       printf("%s\n",getcwd(buffer));
  233.       return "";
  234.     }
  235.   if( my_chdir(the_line+ptr) )
  236.     printf("The system cannot find the path specified at line %d.\n",line_num);
  237.   return "";
  238. }
  239.  
  240.  
  241. /*
  242.  * Simply clear the screen.
  243.  */
  244. CLS_handler(the_line,ptr,line_num)
  245. {
  246.   ScreenClear();
  247.   return "";
  248. }
  249.  
  250.  
  251. /*
  252.  * TYPE a file to the terminal. This is an incredibly simple routine. Use
  253.  * MORE for some options.
  254.  */
  255. TYPE_handler(the_line,ptr,line_num)
  256. {
  257.   if( fp = fopen(the_line+ptr,"r") )
  258.     {
  259.       while( 1 )
  260.         {
  261.           if( (newline = fgets(fp))==NULL ) break;
  262.           printf("%s",newline);
  263.         }
  264.       fclose(fp);
  265.     } else {
  266.       printf("Unable to open file \"%s\" at line %d.\n",the_line+ptr,line_num);
  267.     }
  268.   return "";
  269. }
  270.  
  271.  
  272.  
  273. /*
  274.  * Since the variable we need to change is a local to one of our callers,
  275.  * we pass back a command to it to tell it to do what we want.
  276.  */
  277. SHIFT_handler(the_line,ptr,line_num)
  278. {
  279.   return special_command;
  280. }
  281.  
  282.  
  283.  
  284. /*
  285.  * Just waits for the user to press any key.
  286.  */
  287. PAUSE_handler(the_line,ptr,line_num)
  288. {
  289.   printf("Press any key when ready . . . "); fflush(stdout);
  290.   getch();
  291.   printf("\n");
  292.   return "";
  293. }
  294.  
  295.  
  296.  
  297. /*
  298.  * Invoke a new batch file and return to this one when it finishes
  299.  */
  300. CALL_handler(the_line,ptr,line_num)
  301. {
  302. // Set up a new argc/argv array and call main again.
  303.   strcpy(newargv[0],"CEnvi");
  304.   newargc = 1;
  305.   while( the_line[ptr]!='\0' )
  306.     {
  307.       command = next_token(the_line,ptr);
  308.       strcpy(newargv[newargc++],command);
  309.       while( isspace(the_line[ptr]) ) ptr++;
  310.     }
  311.   main(newargc,newargv);
  312.   return "";
  313. }
  314.  
  315.  
  316.  
  317. /*
  318.  * The _EVIL_ goto command...
  319.  */
  320. GOTO_handler(the_line,ptr,line_num)
  321. {
  322.   return the_line+ptr;
  323. }
  324.  
  325.  
  326.  
  327. /*
  328.  * No, this does not simulate a person skilled in dealing with evil
  329.  * Egyptian gods...
  330.  */
  331. SET_handler(the_line,ptr,line_num)
  332. {
  333.   if( defined(_NWNLM_) )
  334.     {
  335.       printf("Netware has no environment variables at line %d.\n",line_num);
  336.       return "";
  337.     }
  338.  
  339.   if( the_line[ptr]=='\0' )
  340.     {
  341.       array = getenv();
  342.       for( ii=0;ii<GetArraySpan(array);ii++ )
  343.         {
  344.           printf("%s=%s\n",array[ii],getenv(array[ii]));
  345.         }
  346.       return "";
  347.     }
  348.  
  349. // Else we extract the name and see if we have a '=' or not.
  350.   command = next_token(the_line,ptr);
  351.  
  352.   if( (where = strchr(command,'='))!=NULL )
  353.     {
  354.       where[0] = '\0';
  355.       strcpy(env_var,command);
  356.       strcpy(new_val,where+1);
  357.     } else {
  358.       strcpy(env_var,command);
  359.       new_val = NULL;
  360.       if( the_line[ptr]=='=' )
  361.         {
  362.           while( isspace(the_line[++ptr]) );
  363.           strcpy(new_val,the_line+ptr);
  364.         }
  365.     }
  366.  
  367.   if( new_val==NULL )
  368.     {
  369.       printval = getenv(env_var);
  370.       printf("%s=%s\n",env_var,(printval!=NULL)?printval:"");
  371.     } else {
  372.       putenv(env_var,new_val);
  373.     }
  374.   return "";
  375. }
  376.  
  377.  
  378.  
  379. /*
  380.  * A simple looping construct.
  381.  */
  382. FOR_handler(the_line,ptr,line_num)
  383. {
  384.   command = next_token(the_line,ptr);
  385.   if( command[0]!='%' )
  386.     {
  387.       printf("Illegal loop variable in FOR statement at line %d.\n",line_num);
  388.       return "";
  389.     }
  390.   strcpy(loop_variable,command);
  391.   command = next_token(the_line,ptr);
  392.  
  393.   if( stricmp(command,"IN") )
  394.     {
  395.       printf("Malformed FOR statement, missing IN clause at line %d.\n",line_num);
  396.       return "";
  397.     }
  398.   if( the_line[ptr++]!='(' )
  399.     {
  400.       printf("Malformed FOR statement, missing open parenthesis at line %d.\n",line_num);
  401.     }
  402.  
  403. // Next we need to collect all the things we index over...
  404.  
  405.   undefine(list); list_index = 0;
  406.   done = 0;
  407.   while( !done )
  408.     {
  409.       command = next_token(the_line,ptr);
  410.       if( command[strlen(command)-1]==')' )
  411.         {
  412.           command[strlen(command)-1] = '\0'; done = 1;
  413.         }
  414.       if( command[0]!='\0' )
  415.         {
  416.           if( strcspn(command,"*?")==strlen(command) )
  417.             {
  418.               strcpy(list[list_index++],command);
  419.             } else {
  420.               files = Directory(command);
  421.               for( i=0;files && i<=GetArraySpan(files);i++ )
  422.                 strcpy(list[list_index++],files[i].name);
  423.             }
  424.         }
  425.     }
  426.  
  427.   command = next_token(the_line,ptr);
  428.   if( stricmp(command,"DO") )
  429.     {
  430.       printf("Malformed FOR statement after arg list at line %d.\n",line_num);
  431.       return "";
  432.     }
  433.   for( i=0;i<list_index;i++ )
  434.     {
  435.       strcpy(to_do,the_line+ptr);
  436.       while( (indx = strstr(to_do,loop_variable))!=NULL )
  437.         {
  438.           index = indx-to_do;
  439.           strcpy(new_do,to_do);
  440.           strcpy(new_do+index,list[i]);
  441.           strcat(new_do,to_do+index+strlen(loop_variable));
  442.           strcpy(to_do,new_do);
  443.         }
  444.       process_command(to_do,line_num);
  445.     }
  446.   return "";
  447. }
  448.  
  449.  
  450.  
  451. /*
  452.  * And the testing construct.
  453.  */
  454. IF_handler(the_line,ptr,line_num)
  455. {
  456.   command = next_token(the_line,ptr);
  457.  
  458.   notted = 0;
  459.  
  460.   if( !stricmp(command,"NOT") )
  461.     {
  462.       notted = 1;
  463.       command = next_token(the_line,ptr);
  464.     }
  465.  
  466. // Here we decide which of the three considitions we have.
  467.   if( !stricmp(command,"EXIST") )
  468.     {
  469.       command = next_token(the_line,ptr);
  470.       
  471.       exist = (fp = fopen(command,"r"))!=NULL;
  472.       if( fp ) fclose(fp);
  473.       if( notted^exist )
  474.         {
  475.           return process_command(=the_line+ptr,line_num);
  476.         }
  477.       return "";
  478.     }
  479.   
  480.   if( !stricmp(command,"ERRORLEVEL") )
  481.     {
  482.       command = next_token(the_line,ptr,line_num);
  483.       
  484.       testlevel = atoi(command);
  485.       
  486.       command = next_token(the_line,ptr);
  487.       
  488.       if( notted^(errorlevel>=testlevel) )
  489.         {
  490.           return process_command(=the_line+ptr,line_num);
  491.         }
  492.       return "";
  493.     }
  494.  
  495.   if( where = strstr(command,"==") )
  496.     {
  497.       where[0] = 0; where += 2;
  498.       if( notted^!stricmp(command,where) )
  499.         {
  500.           return process_command(=the_line+ptr,line_num);
  501.         }
  502.       return "";
  503.     }
  504.  
  505.  
  506.   printf("Unrecognized IF syntax beginning with %s at line %d.\n",command,line_num);
  507.   return "";
  508. }
  509.  
  510.  
  511. command_names = {
  512.   "REM", "ECHO", "CD", "CLS", "TYPE", "SHIFT", "CAUSE", "CALL", "SET",
  513.   "GOTO", "FOR", "IF", "PAUSE"
  514. };
  515.  
  516. /* ---------------------------------------------------------------------- */
  517.  
  518. process_command(the_line,line_num)
  519. {
  520.   ptr = 0; while( isspace(the_line[ptr]) ) ptr++;
  521.  
  522. // If the line is blank, we skip it
  523.  
  524.   if( the_line[ptr]=='\n' || the_line[ptr]=='\0' ) return "";
  525.  
  526. // If it is a ':LABEL' line, we skip it.
  527.  
  528.   if( the_line[ptr]==':' ) return "";
  529.  
  530.  
  531. // Else it is either an internal command, a .CMM script, or we dump it
  532. // to the system processor.
  533.  
  534.   mark = ptr;
  535.   command = next_token(the_line,ptr);
  536.  
  537. // ----------------------------------------------------------------------
  538. // Here we process all internal commands
  539. // ----------------------------------------------------------------------
  540.  
  541.   for( i=0;i<=GetArraySpan(command_names);i++ )
  542.     {
  543.       if( !stricmp(command_names[i],command) )
  544.         {
  545.           sprintf(func_name,"%s_handler",command_names[i]);
  546.           return function(func_name,the_line,ptr,line_num);
  547.         }
  548.     }
  549.  
  550. // ----------------------------------------------------------------------
  551. // We check to see if it is a drive designation
  552. // ----------------------------------------------------------------------
  553.  
  554.   if( command[1]==':' && strlen(command)==2 )
  555.     {
  556. #define ORD_DOS32SETDEFAULTDISK  220
  557.       if( defined(_OS2_) )
  558.         {
  559.           DynamicLink("doscalls",ORD_DOS32SETDEFAULTDISK,BIT32,CDECL,
  560.                       toupper(command[0])-'A'+1);
  561.         }
  562.       if( defined(_NTWIN_) || defined(_NTCON_) || defined(_95CON_) ||
  563.           defined(_95WIN_) )
  564.         {
  565.           CD_handler(command,0,line_num);
  566.         }
  567.       if( defined(_WINDOWS_) || defined(_DOS_) || defined(_DOS32_) )
  568.         {
  569.           lReg.ah = 0x0E;
  570.           lReg.dl = toupper(command[0]) - 'A';
  571.           interrupt(0x21,lReg);
  572.         }
  573.       return "";
  574.     }
  575.  
  576. // -----------------------------------------------------------------------
  577. // Otherwise, it is either a CMM script or we dump it to the command shell
  578. // Here we check to see if we can find a .CMM file to run.
  579. // -----------------------------------------------------------------------
  580.  
  581.   if( (filename = find_cmm(command)) )
  582.     {
  583.       strcat(filename," ");
  584.       strcat(filename,the_line+ptr);
  585.       errorlevel = Interpret(filename,
  586.                              INTERP_FILE | 
  587.                              INTERP_NOINHERIT_LOCAL |
  588.                              INTERP_NOINHERIT_GLOBAL );
  589.       return "";
  590.     }
  591.  
  592.   errorlevel = system(the_line+mark);
  593.  
  594.   return "";
  595. }
  596.  
  597. /* ---------------------------------------------------------------------- */
  598.  
  599. /*
  600.  * Ok, we have a list of internal commands. All other commands are
  601.  * either CMM scripts which we interpret, else they are system commands
  602.  * which we execute as appropriate for each system.
  603.  *
  604.  * Lines beginning with a ':' are ignored except when searching for
  605.  * GOTO targets.
  606.  */
  607.  
  608. main(argc,argv)
  609. {
  610.   setup();
  611.   plus = 1;             // the offset into the parameter array for substitution
  612.  
  613.  
  614.   if( argc<2 || !strcmp(argv[1],"/?") )
  615.     {
  616.       usage();
  617.     }
  618.  
  619.   if( (fp = fopen(argv[1],"r"))==NULL )
  620.     {
  621.       path = SplitFileName(argv[1]);
  622.       sprintf(newname,"%s%s.bat",path.dir,path.name);
  623.       fp = fopen(newname,"r");
  624.     }
  625.   if( fp==NULL )
  626.     {
  627.       printf("Could not open source file \"%s\" for reading.\n",argv[1]);
  628.       return 1;
  629.     }
  630.  
  631.   line_count = 0;
  632.   while( 1 )
  633.     {
  634.       if( (newline = fgets(fp))==NULL ) break;
  635.       strcpy( lines[line_count++],newline);
  636.     }
  637.   fclose(fp);
  638.  
  639. // All right. We have the file in memory as a sequence of lines. Start doing them.
  640.  
  641.   for( i = 0;i<line_count;i++ )
  642.     {
  643.       strcpy(the_line,lines[i]);
  644.  
  645. // First we do any parameter substitution in the line
  646.       the_line = substitute_line(the_line,argc-plus,argv+plus);
  647.  
  648.       while( isspace(the_line[0]) ) the_line++;
  649.       if( the_line[0]=='@' )
  650.         {
  651.           echo_it = 0; the_line++;
  652.         } else {
  653.           echo_it = echo;
  654.         }
  655.  
  656.       if( echo_it ) printf("\n%s>%s\n",FullPath("."),the_line);
  657.  
  658.       redir_stdout = NULL;
  659.       redir_stdin = NULL;
  660.       redir_new = NULL;
  661.       to_delete = NULL;
  662.       mode = "";
  663.       in_quotes = 0;
  664.       start_from = 0;
  665.  
  666.       while( the_line[0] )
  667.         {
  668.           next_line = "";
  669.  
  670.           while( (loc = strcspn(the_line+start_from,"\"|<>"))
  671.                 !=strlen(the_line+start_from) )
  672.             {
  673.               loc += start_from;
  674.               if( the_line[loc]=='\"' )
  675.                 {
  676.                   in_quotes = 1 - in_quotes;
  677.                   start_from = loc+1;
  678.                   continue;
  679.                 }
  680.  
  681.               if( in_quotes )
  682.                 {
  683.                   start_from = loc+1;
  684.                   continue;
  685.                 }
  686.  
  687.               if( the_line[loc]=='<' )
  688.                 {
  689.                   if( redir_stdin )
  690.                     {
  691.                       fprintf(stderr,"Input already redirected.\n");
  692.                       exit(EXIT_FAILURE);
  693.                     }
  694.  
  695.                   newloc = loc+1;
  696.                   while( isspace(the_line[newloc]) ) newloc++;
  697.                   locstart = newloc;
  698.                   while( the_line[newloc] && !isspace(the_line[newloc]) )
  699.                     newloc++;
  700.                   tmp = the_line[newloc]; the_line[newloc] = 0;
  701.                   strcpy(redir_stdin,the_line+locstart);
  702.                   the_line[newloc] = tmp;
  703.                   strcpy(the_line+loc,the_line+newloc);
  704.                   continue;
  705.                 }
  706.               if( the_line[loc]=='>' )
  707.                 {
  708.                   if( redir_stdout )
  709.                     {
  710.                       fprintf(stderr,"Output already redirected.\n");
  711.                       exit(EXIT_FAILURE);
  712.                     }
  713.  
  714.                   mode = "wt";
  715.                   newloc = loc+1;
  716.                   if( the_line[newloc]=='>' )
  717.                     {
  718.                       mode = "at";
  719.                       newloc++;
  720.                     }
  721.  
  722.                   while( isspace(the_line[newloc]) ) newloc++;
  723.                   locstart = newloc;
  724.                   while( the_line[newloc] && !isspace(the_line[newloc]) )
  725.                     newloc++;
  726.                   tmp = the_line[newloc]; the_line[newloc] = 0;
  727.                   strcpy(redir_stdout,the_line+locstart);
  728.                   the_line[newloc] = tmp;
  729.                   strcpy(the_line+loc,the_line+newloc);
  730.                   continue;
  731.                 }
  732.  
  733.               if( the_line[loc]=='|' )
  734.                 {
  735.                   if( redir_stdout )
  736.                     {
  737.                       fprintf(stderr,"Output is already redirected to a file.\n");
  738.                       exit(EXIT_FAILURE);
  739.                     }
  740.                   mode = "wt";
  741.                   strcpy(next_line,the_line+loc+1);
  742.                   the_line[loc] = 0;
  743.                   strcpy(redir_new,tmpnam());
  744.                   strcpy(redir_stdout,redir_new);
  745.                   break;
  746.                 }
  747.             }
  748.  
  749.           if( redir_stdout && !freopen(redir_stdout,mode,stdout) )
  750.             {
  751.               fprintf(stderr,"Unable to open output redirection file \"%s\".\n",
  752.                       redir_stdout);
  753.               exit(EXIT_FAILURE);
  754.             }
  755.  
  756.           if( redir_stdin && !freopen(redir_stdin,"r",stdin) )
  757.             {
  758.               fprintf(stderr,"Unable to open input redirection file \"%s\".\n",
  759.                       redir_stdin);
  760.               exit(EXIT_FAILURE);
  761.             }
  762.  
  763.           label = process_command(the_line,i+1);
  764.           if( to_delete ) remove(to_delete);
  765.           to_delete = NULL;
  766.           if( redir_stdout ) { fclose(stdout); redir_stdout = NULL; }
  767.           if( redir_stdin ) { fclose(stdin); }
  768.           redir_stdin = redir_new; to_delete = redir_new; redir_new = NULL;
  769.  
  770.           strcpy(the_line,next_line);
  771.         }
  772.  
  773.       if( !stricmp(label,special_command) )
  774.         {
  775.           plus++; continue;
  776.         }
  777.  
  778.       if( label[0]!='\0' )
  779.         {
  780.           yep = 0;
  781.           length = strlen(label);
  782.           for( j=0;!yep && j<line_count;j++ )
  783.             {
  784.               if( lines[j][0]==':' && !strncmp(lines[j]+1,label,length) )
  785.                 {
  786.                   yep = 1;
  787.                   i = j - 1;
  788.                 }
  789.             }
  790.           if( !yep )
  791.             {
  792.               printf("Label \"%s\" not found.\n",label);
  793.               return 1;
  794.             }
  795.         }
  796.     }
  797. }
  798.