Subversion Repositories SvarDOS

Rev

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

Rev 475 Rev 479
Line 77... Line 77...
77
#include "helpers.h"
77
#include "helpers.h"
78
#include "redir.h"
78
#include "redir.h"
79
#include "rmodinit.h"
79
#include "rmodinit.h"
80
#include "sayonara.h"
80
#include "sayonara.h"
81
 
81
 
-
 
82
#include "rmodcore.h" /* rmod binary inside a BUFFER array */
82
 
83
 
83
struct config {
84
struct config {
84
  unsigned char flags; /* command.com flags, as defined in rmodinit.h */
85
  unsigned char flags; /* command.com flags, as defined in rmodinit.h */
85
  char *execcmd;
86
  char *execcmd;
86
  unsigned short envsiz;
87
  unsigned short envsiz;
Line 347... Line 348...
347
  if (explicitpath) return(-2); /* don't bother trying other paths, the caller had its own path preset anyway */
348
  if (explicitpath) return(-2); /* don't bother trying other paths, the caller had its own path preset anyway */
348
  return(-1);
349
  return(-1);
349
}
350
}
350
 
351
 
351
 
352
 
352
static void run_as_external(char *buff, const char far *cmdline, unsigned short envseg, struct rmod_props far *rmod) {
353
static void run_as_external(char *buff, const char *cmdline, unsigned short envseg, struct rmod_props far *rmod) {
353
  char *cmdfile = buff + 512;
354
  char *cmdfile = buff + 512;
354
  const char far *pathptr;
355
  const char far *pathptr;
355
  int lookup;
356
  int lookup;
356
  unsigned short i;
357
  unsigned short i;
357
  const char *ext;
358
  const char *ext;
358
  char *cmd = buff + 256;
359
  char *cmd = buff + 256;
359
  const char far *cmdtail;
360
  const char *cmdtail;
360
  char far *rmod_execprog = MK_FP(rmod->rmodseg, RMOD_OFFSET_EXECPROG);
361
  char far *rmod_execprog = MK_FP(rmod->rmodseg, RMOD_OFFSET_EXECPROG);
361
  char far *rmod_cmdtail = MK_FP(rmod->rmodseg, 0x81);
362
  char far *rmod_cmdtail = MK_FP(rmod->rmodseg, 0x81);
362
  _Packed struct {
363
  _Packed struct {
363
    unsigned short envseg;
364
    unsigned short envseg;
364
    unsigned long cmdtail;
365
    unsigned long cmdtail;
Line 522... Line 523...
522
    pop ax
523
    pop ax
523
  }
524
  }
524
}
525
}
525
 
526
 
526
 
527
 
527
/* fetches a line from batch file and write it to buff, increments
528
/* fetches a line from batch file and write it to buff (NULL-terminated),
528
 * rmod counter on success. returns 0 on success.
529
 * increments rmod counter and returns 0 on success. */
529
 * buff starts with a length byte and is NULL-terminated */
-
 
530
static int getbatcmd(char *buff, struct rmod_props far *rmod) {
530
static int getbatcmd(char *buff, struct rmod_props far *rmod) {
531
  unsigned short i;
531
  unsigned short i;
532
  unsigned short batname_seg = FP_SEG(rmod->batfile);
532
  unsigned short batname_seg = FP_SEG(rmod->batfile);
533
  unsigned short batname_off = FP_OFF(rmod->batfile);
533
  unsigned short batname_off = FP_OFF(rmod->batfile);
534
  unsigned short filepos_cx = rmod->batnextline >> 16;
534
  unsigned short filepos_cx = rmod->batnextline >> 16;
535
  unsigned short filepos_dx = rmod->batnextline & 0xffff;
535
  unsigned short filepos_dx = rmod->batnextline & 0xffff;
536
  unsigned char blen = 0;
536
  unsigned char blen = 0;
537
 
537
 
538
  buff++; /* make room for the len byte prefix */
-
 
539
 
-
 
540
  /* open file, jump to offset filpos, and read data into buff.
538
  /* open file, jump to offset filpos, and read data into buff.
541
   * result in blen (unchanged if EOF or failure). */
539
   * result in blen (unchanged if EOF or failure). */
542
  _asm {
540
  _asm {
543
    push ax
541
    push ax
544
    push bx
542
    push bx
Line 595... Line 593...
595
      if ((buff[i] == '\r') && ((i+1) < blen) && (buff[i+1] == '\n')) rmod->batnextline += 1;
593
      if ((buff[i] == '\r') && ((i+1) < blen) && (buff[i+1] == '\n')) rmod->batnextline += 1;
596
      break;
594
      break;
597
    }
595
    }
598
  }
596
  }
599
  buff[i] = 0;
597
  buff[i] = 0;
600
  buff[-1] = i;
-
 
601
  rmod->batnextline += i + 1;
598
  rmod->batnextline += i + 1;
602
 
599
 
603
  return(0);
600
  return(0);
604
 
601
 
605
  OOPS:
602
  OOPS:
Line 611... Line 608...
611
 
608
 
612
int main(void) {
609
int main(void) {
613
  static struct config cfg;
610
  static struct config cfg;
614
  static unsigned short far *rmod_envseg;
611
  static unsigned short far *rmod_envseg;
615
  static unsigned short far *lastexitcode;
612
  static unsigned short far *lastexitcode;
616
  static unsigned char BUFFER[4096];
-
 
617
  static struct rmod_props far *rmod;
613
  static struct rmod_props far *rmod;
-
 
614
  static char *cmdline;
618
 
615
 
619
  rmod = rmod_find();
616
  rmod = rmod_find(BUFFER_len);
620
  if (rmod == NULL) {
617
  if (rmod == NULL) {
621
    rmod = rmod_install(cfg.envsiz);
618
    rmod = rmod_install(cfg.envsiz, BUFFER, BUFFER_len);
622
    if (rmod == NULL) {
619
    if (rmod == NULL) {
623
      outputnl("ERROR: rmod_install() failed");
620
      outputnl("ERROR: rmod_install() failed");
624
      return(1);
621
      return(1);
625
    }
622
    }
626
    /* look at command line parameters */
623
    /* look at command line parameters */
Line 649... Line 646...
649
    envsiz *= 16;
646
    envsiz *= 16;
650
    printf("rmod_inpbuff at %04X:%04X, env_seg at %04X:0000 (env_size = %u bytes)\r\n", rmod->rmodseg, RMOD_OFFSET_INPBUFF, *rmod_envseg, envsiz);
647
    printf("rmod_inpbuff at %04X:%04X, env_seg at %04X:0000 (env_size = %u bytes)\r\n", rmod->rmodseg, RMOD_OFFSET_INPBUFF, *rmod_envseg, envsiz);
651
  }*/
648
  }*/
652
 
649
 
653
  do {
650
  do {
654
    char far *cmdline;
-
 
655
 
-
 
656
    if (rmod->flags & FLAG_ECHOFLAG) outputnl(""); /* terminate the previous command with a CR/LF */
651
    if (rmod->flags & FLAG_ECHOFLAG) outputnl(""); /* terminate the previous command with a CR/LF */
657
 
652
 
658
    SKIP_NEWLINE:
653
    SKIP_NEWLINE:
659
 
654
 
660
    /* cancel any redirections that may have been set up before */
655
    /* cancel any redirections that may have been set up before */
661
    redir_revert();
656
    redir_revert();
662
 
657
 
-
 
658
    /* preset cmdline to point at the end of my general-purpose buffer */
663
    cmdline = rmod->inputbuf + 2;
659
    cmdline = BUFFER + sizeof(BUFFER) - 130;
664
 
660
 
665
    /* (re)load translation strings if needed */
661
    /* (re)load translation strings if needed */
666
    nls_langreload(BUFFER, *rmod_envseg);
662
    nls_langreload(BUFFER, *rmod_envseg);
667
 
663
 
668
    /* skip user input if I have a command to exec (/C or /K) */
664
    /* skip user input if I have a command to exec (/C or /K) */
Line 672... Line 668...
672
      goto EXEC_CMDLINE;
668
      goto EXEC_CMDLINE;
673
    }
669
    }
674
 
670
 
675
    /* if batch file is being executed -> fetch next line */
671
    /* if batch file is being executed -> fetch next line */
676
    if (rmod->batfile[0] != 0) {
672
    if (rmod->batfile[0] != 0) {
677
      char *tmpbuff = BUFFER + sizeof(BUFFER) - 256;
-
 
678
      if (getbatcmd(tmpbuff, rmod) != 0) { /* end of batch */
673
      if (getbatcmd(cmdline, rmod) != 0) { /* end of batch */
679
        redir_revert(); /* cancel redirections (if there were any) */
-
 
680
        /* restore echo flag as it was before running the bat file */
674
        /* restore echo flag as it was before running the bat file */
681
        rmod->flags &= ~FLAG_ECHOFLAG;
675
        rmod->flags &= ~FLAG_ECHOFLAG;
682
        if (rmod->flags & FLAG_ECHO_BEFORE_BAT) rmod->flags |= FLAG_ECHOFLAG;
676
        if (rmod->flags & FLAG_ECHO_BEFORE_BAT) rmod->flags |= FLAG_ECHOFLAG;
683
        continue;
677
        continue;
684
      }
678
      }
685
      /* output prompt and command on screen if echo on and command is not
679
      /* output prompt and command on screen if echo on and command is not
686
       * inhibiting it with the @ prefix */
680
       * inhibiting it with the @ prefix */
687
      if ((rmod->flags & FLAG_ECHOFLAG) && (tmpbuff[1] != '@')) {
681
      if ((rmod->flags & FLAG_ECHOFLAG) && (cmdline[0] != '@')) {
688
        build_and_display_prompt(BUFFER, *rmod_envseg);
682
        build_and_display_prompt(BUFFER, *rmod_envseg);
689
        outputnl(tmpbuff + 1);
683
        outputnl(cmdline);
690
      }
-
 
691
      /* strip the @ prefix if present, it is no longer useful */
-
 
692
      if (tmpbuff[1] == '@') {
-
 
693
        memmove(tmpbuff + 1, tmpbuff + 2, tmpbuff[0] + 1);
-
 
694
        tmpbuff[0] -= 1; /* update the length byte */
-
 
695
      }
684
      }
-
 
685
      /* skip the @ prefix if present, it is no longer useful */
696
      cmdline = tmpbuff + 1;
686
      if (cmdline[0] == '@') cmdline++;
697
    } else {
687
    } else {
698
      /* interactive mode: display prompt (if echo enabled) and wait for user
688
      /* interactive mode: display prompt (if echo enabled) and wait for user
699
       * command line */
689
       * command line */
700
      if (rmod->flags & FLAG_ECHOFLAG) build_and_display_prompt(BUFFER, *rmod_envseg);
690
      if (rmod->flags & FLAG_ECHOFLAG) build_and_display_prompt(BUFFER, *rmod_envseg);
701
      /* revert input history terminator to \r so DOS or DOSKEY are not confused */
-
 
702
      cmdline[(unsigned short)(cmdline[-1])] = '\r';
-
 
703
      /* collect user input */
691
      /* collect user input */
704
      cmdline_getinput(FP_SEG(rmod->inputbuf), FP_OFF(rmod->inputbuf));
692
      cmdline_getinput(FP_SEG(rmod->inputbuf), FP_OFF(rmod->inputbuf));
705
      /* replace \r by a zero terminator */
693
      /* copy it to local cmdline */
706
      cmdline[(unsigned char)(cmdline[-1])] = 0;
694
      if (rmod->inputbuf[1] != 0) _fmemcpy(cmdline, rmod->inputbuf + 2, rmod->inputbuf[1]);
-
 
695
      cmdline[(unsigned)(rmod->inputbuf[1])] = 0; /* zero-terminate local buff (oriignal is '\r'-terminated) */
707
    }
696
    }
708
 
697
 
709
    /* if nothing entered, loop again (but without appending an extra CR/LF) */
698
    /* if nothing entered, loop again (but without appending an extra CR/LF) */
710
    if (cmdline[-1] == 0) goto SKIP_NEWLINE;
699
    if (cmdline[0] == 0) goto SKIP_NEWLINE;
711
 
700
 
712
    /* I jump here when I need to exec an initial command (/C or /K) */
701
    /* I jump here when I need to exec an initial command (/C or /K) */
713
    EXEC_CMDLINE:
702
    EXEC_CMDLINE:
714
 
703
 
715
    /* move pointer forward to skip over any leading spaces */
704
    /* move pointer forward to skip over any leading spaces */