Subversion Repositories SvarDOS

Rev

Rev 421 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
402 mateuszvis 1
 
2
#include "doserr.h"
3
#include "helpers.h"
4
 
5
#include "redir.h"
6
 
7
static unsigned short oldstdout = 0xffff;
8
 
9
/* parse commandline and performs necessary redirections. cmdline is
10
 * modified so all redirections are cut out.
11
 * returns 0 on success, non-zero otherwise */
12
int redir_parsecmd(char far *cmdline, char *BUFFER) {
13
  unsigned short i;
14
  unsigned short rediroffset_stdin = 0;
15
  unsigned short rediroffset_stdout = 0;
16
  unsigned short pipesoffsets[16];
17
  unsigned short pipescount = 0;
18
 
19
  /* NOTE:
20
   *
21
   * 1. while it is possible to type a command with multiple
22
   *    redirections, MSDOS executes only the last redirection.
23
   *
24
   * 2. the order in which >, < and | are provided on the command line does
25
   *    not seem to matter for MSDOS. piped commands are executed first (in
26
   *    the order they appear) and the result of the last one is redirected to
27
   *    whenever the last > points at.
28
   */
29
 
30
  /* preset oldstdout to 0xffff in case no redirection is required */
31
  oldstdout = 0xffff;
32
 
33
  for (i = 0;; i++) {
34
    if (cmdline[i] == '>') {
35
      cmdline[i] = 0;
36
      rediroffset_stdout = i + 1;
37
    } else if (cmdline[i] == '<') {
38
      cmdline[i] = 0;
39
      rediroffset_stdin = i + 1;
40
    } else if (cmdline[i] == '|') {
41
      cmdline[i] = 0;
42
      pipesoffsets[pipescount++] = i + 1;
43
    } else if (cmdline[i] == 0) {
44
      break;
45
    }
46
  }
47
 
48
  if (rediroffset_stdin != 0) {
49
    outputnl("ERROR: stdin redirection is not supported yet");
50
    return(-1);
51
  }
52
 
53
  if (pipescount != 0) {
54
    outputnl("ERROR: pipe redirections are not supported yet");
55
    return(-1);
56
  }
57
 
58
  if (rediroffset_stdout != 0) {
59
    unsigned short openflag = 0x12;  /* used during the int 21h,ah=6c call */
60
    unsigned short errcode = 0;
61
    unsigned short handle = 0;
62
    char far *ptr;
63
    /* append? */
64
    if (cmdline[rediroffset_stdout] == '>') {
65
      openflag = 0x11;
66
      rediroffset_stdout++;
67
    }
68
 
69
    /* copy dst file to BUFFER */
70
    ptr = cmdline + rediroffset_stdout;
71
    while (*ptr == ' ') ptr++; /* skip leading white spaces */
72
    for (i = 0;; i++) {
73
      BUFFER[i] = ptr[i];
74
      if ((BUFFER[i] == ' ') || (BUFFER[i] == 0)) break;
75
    }
76
    BUFFER[i] = 0;
77
 
78
    /* */
79
    _asm {
80
      push ax
81
      push bx
82
      push cx
83
      push dx
84
      push si
85
      mov ax, 0x6c00     /* Extended Open/Create */
86
      mov bx, 1          /* access mode (0=read, 1=write, 2=r+w */
87
      xor cx, cx         /* attributes when(if) creating the file (0=normal) */
88
      mov dx, [openflag] /* action if file exists (0x11=open, 0x12=truncate)*/
89
      mov si, BUFFER     /* ASCIIZ filename */
90
      int 0x21           /* AX=handle on success (CF clear), otherwise dos err */
91
      mov [handle], ax   /* save the file handler */
92
      jnc DUPSTDOUT
93
      mov [errcode], ax
94
      jmp DONE
95
      DUPSTDOUT:
96
      /* save (duplicate) current stdout so I can revert it later */
97
      mov ah, 0x45       /* duplicate file handle */
98
      mov bx, 1          /* handle to dup (1=stdout) */
99
      int 0x21           /* ax = new file handle */
100
      mov [oldstdout], ax
101
      /* redirect the stdout handle */
102
      mov bx, [handle]   /* dst handle */
103
      mov cx, 1          /* src handle (1=stdout) */
104
      mov ah, 0x46       /* redirect a handle */
105
      int 0x21
106
      /* close the original file handle (no longer needed) */
107
      mov ah, 0x3e       /* close a file handle (handle in BX) */
108
      int 0x21
109
      DONE:
110
      pop si
111
      pop dx
112
      pop cx
113
      pop bx
114
      pop ax
115
    }
116
    if (errcode != 0) {
117
      outputnl(doserr(errcode));
118
      return(-1);
119
    }
120
  }
121
 
122
  return(0);
123
}
124
 
125
 
126
/* restores previous stdout/stdin handlers if they have been redirected */
127
void redir_revert(void) {
128
  _asm {
129
    /* if oldstdout is 0xffff then not redirected */
130
    cmp word ptr [oldstdout], 0xffff
131
    je DONE
132
    /* redirect the stdout handle */
133
    mov bx, [oldstdout] /* dst handle */
134
    mov cx, 1           /* src handle (1=stdout) */
135
    mov ah, 0x46        /* redirect a handle */
136
    int 0x21
137
    mov [oldstdout], 0xffff
138
    DONE:
139
  }
140
}