Subversion Repositories SvarDOS

Rev

Rev 949 | Rev 958 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 949 Rev 957
Line 313... Line 313...
313
  *s = 0;
313
  *s = 0;
314
  output(buff);
314
  output(buff);
315
}
315
}
316
 
316
 
317
 
317
 
-
 
318
/* a few internal flags */
-
 
319
#define DELETE_STDIN_FILE 1
-
 
320
#define CALL_FLAG         2
-
 
321
 
318
static void run_as_external(char *buff, const char *cmdline, unsigned short envseg, struct rmod_props far *rmod, struct redir_data *redir, unsigned char delete_stdin_file) {
322
static void run_as_external(char *buff, const char *cmdline, unsigned short envseg, struct rmod_props far *rmod, struct redir_data *redir, unsigned char flags) {
319
  char *cmdfile = buff + 512;
323
  char *cmdfile = buff + 512;
320
  const char far *pathptr;
324
  const char far *pathptr;
321
  int lookup;
325
  int lookup;
322
  unsigned short i;
326
  unsigned short i;
323
  const char *ext;
327
  const char *ext;
Line 428... Line 432...
428
 
432
 
429
  RUNCMDFILE:
433
  RUNCMDFILE:
430
 
434
 
431
  /* special handling of batch files */
435
  /* special handling of batch files */
432
  if ((ext != NULL) && (imatch(ext, "bat"))) {
436
  if ((ext != NULL) && (imatch(ext, "bat"))) {
433
    /* free the bat-context linked list, if present, and replace it with a new entry */
-
 
434
    while (rmod->bat != NULL) {
-
 
435
      struct batctx far *victim = rmod->bat;
437
    struct batctx far *newbat;
436
      rmod->bat = rmod->bat->parent;
-
 
437
      rmod_ffree(victim);
-
 
438
    }
438
 
439
    rmod->bat = rmod_fmalloc(sizeof(struct batctx), rmod->rmodseg, "SVBATCTX");
439
    /* remember the echo flag (in case bat file disables echo, only when starting first bat) */
440
    if (rmod->bat == NULL) {
440
    if (rmod->bat == NULL) {
441
      outputnl("INTERNAL ERR: OUT OF MEMORY");
441
      rmod->flags &= ~FLAG_ECHO_BEFORE_BAT;
442
      return;
442
      if (rmod->flags & FLAG_ECHOFLAG) rmod->flags |= FLAG_ECHO_BEFORE_BAT;
443
    }
443
    }
444
    _fmemset(rmod->bat, 0, sizeof(struct batctx));
-
 
445
 
444
 
-
 
445
    /* if bat is not called via a CALL, then free the bat-context linked list */
-
 
446
    if ((flags & CALL_FLAG) == 0) {
-
 
447
      while (rmod->bat != NULL) {
446
    /* copy truename of the bat file to rmod buff */
448
        struct batctx far *victim = rmod->bat;
447
    _fstrcpy(rmod->bat->fname, cmdfile);
449
        rmod->bat = rmod->bat->parent;
-
 
450
        rmod_ffree(victim);
-
 
451
      }
-
 
452
    }
-
 
453
    /* allocate a new bat context */
-
 
454
    newbat = rmod_fcalloc(sizeof(struct batctx), rmod->rmodseg, "SVBATCTX");
-
 
455
    if (newbat == NULL) {
-
 
456
      nls_outputnl_doserr(8); /* insufficient memory */
-
 
457
      return;
-
 
458
    }
448
 
459
 
-
 
460
    /* fill the newly allocated batctx structure */
-
 
461
    _fstrcpy(newbat->fname, cmdfile); /* truename of the BAT file */
449
    /* explode args of the bat file and store them in rmod buff */
462
    /* explode args of the bat file and store them in rmod buff */
450
    cmd_explode(buff, cmdline, NULL);
463
    cmd_explode(buff, cmdline, NULL);
451
    _fmemcpy(rmod->bat->argv, buff, sizeof(rmod->bat->argv));
464
    _fmemcpy(newbat->argv, buff, sizeof(newbat->argv));
-
 
465
 
-
 
466
    /* push the new bat to the top of rmod's linked list */
-
 
467
    newbat->parent = rmod->bat;
-
 
468
    rmod->bat = newbat;
452
 
469
 
453
    /* reset the 'next line to execute' counter */
-
 
454
    rmod->bat->nextline = 0;
-
 
455
    /* remember the echo flag (in case bat file disables echo) */
-
 
456
    rmod->flags &= ~FLAG_ECHO_BEFORE_BAT;
-
 
457
    if (rmod->flags & FLAG_ECHOFLAG) rmod->flags |= FLAG_ECHO_BEFORE_BAT;
-
 
458
    return;
470
    return;
459
  }
471
  }
460
 
472
 
461
  /* copy full filename to execute, along with redirected files (if any) */
473
  /* copy full filename to execute, along with redirected files (if any) */
462
  _fstrcpy(rmod_execprog, cmdfile);
474
  _fstrcpy(rmod_execprog, cmdfile);
Line 464... Line 476...
464
  /* copy stdin file if a redirection is needed */
476
  /* copy stdin file if a redirection is needed */
465
  if (redir->stdinfile) {
477
  if (redir->stdinfile) {
466
    char far *farptr = MK_FP(rmod->rmodseg, RMOD_OFFSET_STDINFILE);
478
    char far *farptr = MK_FP(rmod->rmodseg, RMOD_OFFSET_STDINFILE);
467
    char far *delstdin = MK_FP(rmod->rmodseg, RMOD_OFFSET_STDIN_DEL);
479
    char far *delstdin = MK_FP(rmod->rmodseg, RMOD_OFFSET_STDIN_DEL);
468
    _fstrcpy(farptr, redir->stdinfile);
480
    _fstrcpy(farptr, redir->stdinfile);
469
    if (delete_stdin_file) {
481
    if (flags & DELETE_STDIN_FILE) {
470
      *delstdin = redir->stdinfile[0];
482
      *delstdin = redir->stdinfile[0];
471
    } else {
483
    } else {
472
      *delstdin = 0;
484
      *delstdin = 0;
473
    }
485
    }
474
  }
486
  }
Line 742... Line 754...
742
 
754
 
743
  res[reslen] = 0;
755
  res[reslen] = 0;
744
}
756
}
745
 
757
 
746
 
758
 
-
 
759
 
747
int main(void) {
760
int main(void) {
748
  static struct config cfg;
761
  static struct config cfg;
749
  static unsigned short far *rmod_envseg;
762
  static unsigned short far *rmod_envseg;
750
  static unsigned short far *lastexitcode;
763
  static unsigned short far *lastexitcode;
751
  static struct rmod_props far *rmod;
764
  static struct rmod_props far *rmod;
752
  static char cmdlinebuf[CMDLINE_MAXLEN + 2]; /* 1 extra byte for 0-terminator and another for memguard */
765
  static char cmdlinebuf[CMDLINE_MAXLEN + 2]; /* 1 extra byte for 0-terminator and another for memguard */
753
  static char *cmdline;
766
  static char *cmdline;
754
  static struct redir_data redirprops;
767
  static struct redir_data redirprops;
755
  static enum cmd_result cmdres;
768
  static enum cmd_result cmdres;
756
  static unsigned short i; /* general-purpose variable for short-lived things */
769
  static unsigned short i; /* general-purpose variable for short-lived things */
757
  static unsigned char delete_stdin_file;
770
  static unsigned char flags;
758
 
771
 
759
  rmod = rmod_find(BUFFER_len);
772
  rmod = rmod_find(BUFFER_len);
760
  if (rmod == NULL) {
773
  if (rmod == NULL) {
761
    /* look at command line parameters (in case env size if set there) */
774
    /* look at command line parameters (in case env size if set there) */
762
    parse_argv(&cfg);
775
    parse_argv(&cfg);
Line 826... Line 839...
826
 
839
 
827
    /* load awaiting command, if any (used to run piped commands) */
840
    /* load awaiting command, if any (used to run piped commands) */
828
    if (rmod->awaitingcmd[0] != 0) {
841
    if (rmod->awaitingcmd[0] != 0) {
829
      _fstrcpy(cmdline, rmod->awaitingcmd);
842
      _fstrcpy(cmdline, rmod->awaitingcmd);
830
      rmod->awaitingcmd[0] = 0;
843
      rmod->awaitingcmd[0] = 0;
831
      delete_stdin_file = 1;
844
      flags |= DELETE_STDIN_FILE;
832
      goto EXEC_CMDLINE;
845
      goto EXEC_CMDLINE;
833
    } else {
846
    } else {
834
      delete_stdin_file = 0;
847
      flags &= ~DELETE_STDIN_FILE;
835
    }
848
    }
836
 
849
 
837
    /* skip user input if I have a command to exec (/C or /K) */
850
    /* skip user input if I have a command to exec (/C or /K) */
838
    if (cfg.execcmd != NULL) {
851
    if (cfg.execcmd != NULL) {
839
      cmdline = cfg.execcmd;
852
      cmdline = cfg.execcmd;
Line 845... Line 858...
845
    if (rmod->bat != NULL) {
858
    if (rmod->bat != NULL) {
846
      if (getbatcmd(BUFFER, CMDLINE_MAXLEN, rmod) != 0) { /* end of batch */
859
      if (getbatcmd(BUFFER, CMDLINE_MAXLEN, rmod) != 0) { /* end of batch */
847
        struct batctx far *victim = rmod->bat;
860
        struct batctx far *victim = rmod->bat;
848
        rmod->bat = rmod->bat->parent;
861
        rmod->bat = rmod->bat->parent;
849
        rmod_ffree(victim);
862
        rmod_ffree(victim);
850
        /* end of batch? then restore echo flag as it was before running the bat file */
863
        /* end of batch? then restore echo flag as it was before running the (first) bat file */
851
        if (rmod->bat == NULL) {
864
        if (rmod->bat == NULL) {
852
          rmod->flags &= ~FLAG_ECHOFLAG;
865
          rmod->flags &= ~FLAG_ECHOFLAG;
853
          if (rmod->flags & FLAG_ECHO_BEFORE_BAT) rmod->flags |= FLAG_ECHOFLAG;
866
          if (rmod->flags & FLAG_ECHO_BEFORE_BAT) rmod->flags |= FLAG_ECHOFLAG;
854
        }
867
        }
855
        continue;
868
        continue;
Line 896... Line 909...
896
      rmod->awaitingcmd[0] = 0;
909
      rmod->awaitingcmd[0] = 0;
897
      continue;
910
      continue;
898
    }
911
    }
899
 
912
 
900
    /* try matching (and executing) an internal command */
913
    /* try matching (and executing) an internal command */
901
    cmdres = cmd_process(rmod, *rmod_envseg, cmdline, BUFFER, sizeof(BUFFER), &redirprops, delete_stdin_file);
914
    cmdres = cmd_process(rmod, *rmod_envseg, cmdline, BUFFER, sizeof(BUFFER), &redirprops, flags & DELETE_STDIN_FILE);
902
    if ((cmdres == CMD_OK) || (cmdres == CMD_FAIL)) {
915
    if ((cmdres == CMD_OK) || (cmdres == CMD_FAIL)) {
903
      /* internal command executed */
916
      /* internal command executed */
904
      continue;
917
      continue;
905
    } else if (cmdres == CMD_CHANGED) { /* cmdline changed, needs to be reprocessed */
918
    } else if (cmdres == CMD_CHANGED) { /* cmdline changed, needs to be reprocessed */
906
      goto EXEC_CMDLINE;
919
      goto EXEC_CMDLINE;
-
 
920
    } else if (cmdres == CMD_CHANGED_BY_CALL) { /* cmdline changed *specifically* by CALL */
-
 
921
      /* the distinction is important since it changes the way batch files are processed */
-
 
922
      flags |= CALL_FLAG;
-
 
923
      goto EXEC_CMDLINE;
907
    } else if (cmdres == CMD_NOTFOUND) {
924
    } else if (cmdres == CMD_NOTFOUND) {
908
      /* this was not an internal command, try matching an external command */
925
      /* this was not an internal command, try matching an external command */
909
      run_as_external(BUFFER, cmdline, *rmod_envseg, rmod, &redirprops, delete_stdin_file);
926
      run_as_external(BUFFER, cmdline, *rmod_envseg, rmod, &redirprops, flags);
-
 
927
      flags &= ~CALL_FLAG; /* reset callflag to make sure it is processed only once */
-
 
928
 
910
      /* perhaps this is a newly launched BAT file */
929
      /* is it a newly launched BAT file? */
911
      if ((rmod->bat != NULL) && (rmod->bat->nextline == 0)) goto SKIP_NEWLINE;
930
      if ((rmod->bat != NULL) && (rmod->bat->nextline == 0)) goto SKIP_NEWLINE;
912
      /* run_as_external() does not return on success, if I am still alive then
931
      /* run_as_external() does not return on success, if I am still alive then
913
       * external command failed to execute */
932
       * external command failed to execute */
914
      outputnl("Bad command or file name");
933
      outputnl("Bad command or file name");
915
      continue;
934
      continue;