Subversion Repositories SvarDOS

Rev

Rev 402 | Rev 479 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 402 Rev 421
-
 
1
/* This file is part of the SvarCOM project and is published under the terms
-
 
2
 * of the MIT license.
-
 
3
 *
-
 
4
 * Copyright (C) 2021 Mateusz Viste
-
 
5
 *
-
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a
-
 
7
 * copy of this software and associated documentation files (the "Software"),
-
 
8
 * to deal in the Software without restriction, including without limitation
-
 
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
-
 
10
 * and/or sell copies of the Software, and to permit persons to whom the
-
 
11
 * Software is furnished to do so, subject to the following conditions:
-
 
12
 *
-
 
13
 * The above copyright notice and this permission notice shall be included in
-
 
14
 * all copies or substantial portions of the Software.
-
 
15
 *
-
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-
 
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-
 
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-
 
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-
 
22
 * DEALINGS IN THE SOFTWARE.
-
 
23
 */
1
 
24
 
2
#include "doserr.h"
25
#include "doserr.h"
3
#include "helpers.h"
26
#include "helpers.h"
4
 
27
 
5
#include "redir.h"
28
#include "redir.h"
6
 
29
 
7
static unsigned short oldstdout = 0xffff;
30
static unsigned short oldstdout = 0xffff;
8
 
31
 
9
/* parse commandline and performs necessary redirections. cmdline is
32
/* parse commandline and performs necessary redirections. cmdline is
10
 * modified so all redirections are cut out.
33
 * modified so all redirections are cut out.
11
 * returns 0 on success, non-zero otherwise */
34
 * returns 0 on success, non-zero otherwise */
12
int redir_parsecmd(char far *cmdline, char *BUFFER) {
35
int redir_parsecmd(char far *cmdline, char *BUFFER) {
13
  unsigned short i;
36
  unsigned short i;
14
  unsigned short rediroffset_stdin = 0;
37
  unsigned short rediroffset_stdin = 0;
15
  unsigned short rediroffset_stdout = 0;
38
  unsigned short rediroffset_stdout = 0;
16
  unsigned short pipesoffsets[16];
39
  unsigned short pipesoffsets[16];
17
  unsigned short pipescount = 0;
40
  unsigned short pipescount = 0;
18
 
41
 
19
  /* NOTE:
42
  /* NOTE:
20
   *
43
   *
21
   * 1. while it is possible to type a command with multiple
44
   * 1. while it is possible to type a command with multiple
22
   *    redirections, MSDOS executes only the last redirection.
45
   *    redirections, MSDOS executes only the last redirection.
23
   *
46
   *
24
   * 2. the order in which >, < and | are provided on the command line does
47
   * 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
48
   *    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
49
   *    the order they appear) and the result of the last one is redirected to
27
   *    whenever the last > points at.
50
   *    whenever the last > points at.
28
   */
51
   */
29
 
52
 
30
  /* preset oldstdout to 0xffff in case no redirection is required */
53
  /* preset oldstdout to 0xffff in case no redirection is required */
31
  oldstdout = 0xffff;
54
  oldstdout = 0xffff;
32
 
55
 
33
  for (i = 0;; i++) {
56
  for (i = 0;; i++) {
34
    if (cmdline[i] == '>') {
57
    if (cmdline[i] == '>') {
35
      cmdline[i] = 0;
58
      cmdline[i] = 0;
36
      rediroffset_stdout = i + 1;
59
      rediroffset_stdout = i + 1;
37
    } else if (cmdline[i] == '<') {
60
    } else if (cmdline[i] == '<') {
38
      cmdline[i] = 0;
61
      cmdline[i] = 0;
39
      rediroffset_stdin = i + 1;
62
      rediroffset_stdin = i + 1;
40
    } else if (cmdline[i] == '|') {
63
    } else if (cmdline[i] == '|') {
41
      cmdline[i] = 0;
64
      cmdline[i] = 0;
42
      pipesoffsets[pipescount++] = i + 1;
65
      pipesoffsets[pipescount++] = i + 1;
43
    } else if (cmdline[i] == 0) {
66
    } else if (cmdline[i] == 0) {
44
      break;
67
      break;
45
    }
68
    }
46
  }
69
  }
47
 
70
 
48
  if (rediroffset_stdin != 0) {
71
  if (rediroffset_stdin != 0) {
49
    outputnl("ERROR: stdin redirection is not supported yet");
72
    outputnl("ERROR: stdin redirection is not supported yet");
50
    return(-1);
73
    return(-1);
51
  }
74
  }
52
 
75
 
53
  if (pipescount != 0) {
76
  if (pipescount != 0) {
54
    outputnl("ERROR: pipe redirections are not supported yet");
77
    outputnl("ERROR: pipe redirections are not supported yet");
55
    return(-1);
78
    return(-1);
56
  }
79
  }
57
 
80
 
58
  if (rediroffset_stdout != 0) {
81
  if (rediroffset_stdout != 0) {
59
    unsigned short openflag = 0x12;  /* used during the int 21h,ah=6c call */
82
    unsigned short openflag = 0x12;  /* used during the int 21h,ah=6c call */
60
    unsigned short errcode = 0;
83
    unsigned short errcode = 0;
61
    unsigned short handle = 0;
84
    unsigned short handle = 0;
62
    char far *ptr;
85
    char far *ptr;
63
    /* append? */
86
    /* append? */
64
    if (cmdline[rediroffset_stdout] == '>') {
87
    if (cmdline[rediroffset_stdout] == '>') {
65
      openflag = 0x11;
88
      openflag = 0x11;
66
      rediroffset_stdout++;
89
      rediroffset_stdout++;
67
    }
90
    }
68
 
91
 
69
    /* copy dst file to BUFFER */
92
    /* copy dst file to BUFFER */
70
    ptr = cmdline + rediroffset_stdout;
93
    ptr = cmdline + rediroffset_stdout;
71
    while (*ptr == ' ') ptr++; /* skip leading white spaces */
94
    while (*ptr == ' ') ptr++; /* skip leading white spaces */
72
    for (i = 0;; i++) {
95
    for (i = 0;; i++) {
73
      BUFFER[i] = ptr[i];
96
      BUFFER[i] = ptr[i];
74
      if ((BUFFER[i] == ' ') || (BUFFER[i] == 0)) break;
97
      if ((BUFFER[i] == ' ') || (BUFFER[i] == 0)) break;
75
    }
98
    }
76
    BUFFER[i] = 0;
99
    BUFFER[i] = 0;
77
 
100
 
78
    /* */
101
    /* */
79
    _asm {
102
    _asm {
80
      push ax
103
      push ax
81
      push bx
104
      push bx
82
      push cx
105
      push cx
83
      push dx
106
      push dx
84
      push si
107
      push si
85
      mov ax, 0x6c00     /* Extended Open/Create */
108
      mov ax, 0x6c00     /* Extended Open/Create */
86
      mov bx, 1          /* access mode (0=read, 1=write, 2=r+w */
109
      mov bx, 1          /* access mode (0=read, 1=write, 2=r+w */
87
      xor cx, cx         /* attributes when(if) creating the file (0=normal) */
110
      xor cx, cx         /* attributes when(if) creating the file (0=normal) */
88
      mov dx, [openflag] /* action if file exists (0x11=open, 0x12=truncate)*/
111
      mov dx, [openflag] /* action if file exists (0x11=open, 0x12=truncate)*/
89
      mov si, BUFFER     /* ASCIIZ filename */
112
      mov si, BUFFER     /* ASCIIZ filename */
90
      int 0x21           /* AX=handle on success (CF clear), otherwise dos err */
113
      int 0x21           /* AX=handle on success (CF clear), otherwise dos err */
91
      mov [handle], ax   /* save the file handler */
114
      mov [handle], ax   /* save the file handler */
92
      jnc DUPSTDOUT
115
      jnc DUPSTDOUT
93
      mov [errcode], ax
116
      mov [errcode], ax
94
      jmp DONE
117
      jmp DONE
95
      DUPSTDOUT:
118
      DUPSTDOUT:
96
      /* save (duplicate) current stdout so I can revert it later */
119
      /* save (duplicate) current stdout so I can revert it later */
97
      mov ah, 0x45       /* duplicate file handle */
120
      mov ah, 0x45       /* duplicate file handle */
98
      mov bx, 1          /* handle to dup (1=stdout) */
121
      mov bx, 1          /* handle to dup (1=stdout) */
99
      int 0x21           /* ax = new file handle */
122
      int 0x21           /* ax = new file handle */
100
      mov [oldstdout], ax
123
      mov [oldstdout], ax
101
      /* redirect the stdout handle */
124
      /* redirect the stdout handle */
102
      mov bx, [handle]   /* dst handle */
125
      mov bx, [handle]   /* dst handle */
103
      mov cx, 1          /* src handle (1=stdout) */
126
      mov cx, 1          /* src handle (1=stdout) */
104
      mov ah, 0x46       /* redirect a handle */
127
      mov ah, 0x46       /* redirect a handle */
105
      int 0x21
128
      int 0x21
106
      /* close the original file handle (no longer needed) */
129
      /* close the original file handle (no longer needed) */
107
      mov ah, 0x3e       /* close a file handle (handle in BX) */
130
      mov ah, 0x3e       /* close a file handle (handle in BX) */
108
      int 0x21
131
      int 0x21
109
      DONE:
132
      DONE:
110
      pop si
133
      pop si
111
      pop dx
134
      pop dx
112
      pop cx
135
      pop cx
113
      pop bx
136
      pop bx
114
      pop ax
137
      pop ax
115
    }
138
    }
116
    if (errcode != 0) {
139
    if (errcode != 0) {
117
      outputnl(doserr(errcode));
140
      outputnl(doserr(errcode));
118
      return(-1);
141
      return(-1);
119
    }
142
    }
120
  }
143
  }
121
 
144
 
122
  return(0);
145
  return(0);
123
}
146
}
124
 
147
 
125
 
148
 
126
/* restores previous stdout/stdin handlers if they have been redirected */
149
/* restores previous stdout/stdin handlers if they have been redirected */
127
void redir_revert(void) {
150
void redir_revert(void) {
128
  _asm {
151
  _asm {
129
    /* if oldstdout is 0xffff then not redirected */
152
    /* if oldstdout is 0xffff then not redirected */
130
    cmp word ptr [oldstdout], 0xffff
153
    cmp word ptr [oldstdout], 0xffff
131
    je DONE
154
    je DONE
132
    /* redirect the stdout handle */
155
    /* redirect the stdout handle */
133
    mov bx, [oldstdout] /* dst handle */
156
    mov bx, [oldstdout] /* dst handle */
134
    mov cx, 1           /* src handle (1=stdout) */
157
    mov cx, 1           /* src handle (1=stdout) */
135
    mov ah, 0x46        /* redirect a handle */
158
    mov ah, 0x46        /* redirect a handle */
136
    int 0x21
159
    int 0x21
137
    mov [oldstdout], 0xffff
160
    mov [oldstdout], 0xffff
138
    DONE:
161
    DONE:
139
  }
162
  }
140
}
163
}
141
 
164