Subversion Repositories SvarDOS

Rev

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

Rev 1714 Rev 1715
Line 42... Line 42...
42
/* this version byte is used to tag RMOD so I can easily make sure that
42
/* this version byte is used to tag RMOD so I can easily make sure that
43
 * the RMOD struct I find in memory is one that I know. Should the version
43
 * the RMOD struct I find in memory is one that I know. Should the version
44
 * mismatch, then it would likely mean that SvarCOM has been upgraded and
44
 * mismatch, then it would likely mean that SvarCOM has been upgraded and
45
 * RMOD should not be accessed as its structure might no longer be in sync
45
 * RMOD should not be accessed as its structure might no longer be in sync
46
 * with what I think it is.
46
 * with what I think it is.
47
 *          *** INCREMENT THIS AT EACH NEW SVARCOM RELEASE! ***          */
47
 *          *** INCREMENT THIS AT EACH NEW SVARCOM RELEASE! ***
-
 
48
 *            (or at least whenever RMOD's struct is changed)            */
48
#define BYTE_VERSION 4
49
#define BYTE_VERSION 4
49
 
50
 
50
 
51
 
51
struct config {
52
struct config {
52
  unsigned char flags; /* command.com flags, as defined in rmodinit.h */
53
  unsigned char flags; /* command.com flags, as defined in rmodinit.h */
Line 119... Line 120...
119
}
120
}
120
 
121
 
121
 
122
 
122
/* parses command line the hard way (directly from PSP) */
123
/* parses command line the hard way (directly from PSP) */
123
static void parse_argv(struct config *cfg) {
124
static void parse_argv(struct config *cfg) {
-
 
125
  unsigned char *cmdlinelen = (void *)0x80;
124
  char *cmdline = (void *)0x81;
126
  char *cmdline = (void *)0x81;
125
 
127
 
-
 
128
  /* The arg tail at [81h] needs some care when being processed.
-
 
129
   *
-
 
130
   * Its length should be provided in [80h], but it is not always exact:
-
 
131
   * https://github.com/SvarDOS/bugz/issues/67
-
 
132
   *
-
 
133
   * The tail string itself is usually terminated by a CR character. But
-
 
134
   * sometimes it might be terminated by a nul. Or by nothing at all.
-
 
135
   *
-
 
136
   * The cautious approach is therefore to read the tail up until the length
-
 
137
   * mentionned at [80h] or to first CR or nul, whichever comes first.
-
 
138
   */
-
 
139
 
126
  memset(cfg, 0, sizeof(*cfg));
140
  memset(cfg, 0, sizeof(*cfg));
127
 
141
 
-
 
142
  /* Make sure that the advertised cmdline length is no more than 126 bytes
-
 
143
   * because the PSP ends at [0xff] and there ought to be at least 1 byte of
-
 
144
   * room for the CR-terminator.
-
 
145
   * According to Matthias Paul cmdlines longer than 126 (and even longer than
-
 
146
   * 127) might happen with some buggy implementations. */
-
 
147
  if (*cmdlinelen > 126) *cmdlinelen = 126;
-
 
148
 
-
 
149
  /* trim out any trailing CR garbage (see the issue 67 mentioned above) */
-
 
150
  while ((*cmdlinelen > 0) && (cmdline[*cmdlinelen - 1] == '\r')) (*cmdlinelen)--;
-
 
151
 
-
 
152
  /* normalize the cmd so it is nul-terminated - this is expected later in a
-
 
153
   * few places in the codeflow, among others in run_as_external() */
-
 
154
  cmdline[*cmdlinelen] = 0;
-
 
155
 
-
 
156
  /* process the parameters given to COMMAND.COM */
128
  while (*cmdline != 0x0d) {
157
  while (*cmdline != 0) {
129
 
158
 
130
    /* skip over any leading spaces */
159
    /* skip over any leading spaces */
131
    if (*cmdline == ' ') {
160
    if (*cmdline == ' ') {
132
      cmdline++;
161
      cmdline++;
133
      continue;
162
      continue;
Line 149... Line 178...
149
        /* FALLTHRU */
178
        /* FALLTHRU */
150
      case 'k': /* /K = execute command and keep running */
179
      case 'k': /* /K = execute command and keep running */
151
      case 'K':
180
      case 'K':
152
        cmdline++;
181
        cmdline++;
153
        cfg->execcmd = cmdline;
182
        cfg->execcmd = cmdline;
154
        goto DONE; /* further arguments are for the executed program, not for me */
183
        return; /* further arguments are for the executed program, not for me */
155
 
184
 
156
      case 'y': /* /Y = execute batch file step-by-step (with /P, /K or /C) */
185
      case 'y': /* /Y = execute batch file step-by-step (with /P, /K or /C) */
157
      case 'Y':
186
      case 'Y':
158
        cfg->flags |= FLAG_STEPBYSTEP;
187
        cfg->flags |= FLAG_STEPBYSTEP;
159
        break;
188
        break;
Line 197... Line 226...
197
        break;
226
        break;
198
    }
227
    }
199
 
228
 
200
    /* move to next argument or quit processing if end of cmdline */
229
    /* move to next argument or quit processing if end of cmdline */
201
    SKIP_TO_NEXT_ARG:
230
    SKIP_TO_NEXT_ARG:
202
    while ((*cmdline != 0x0d) && (*cmdline != ' ') && (*cmdline != '/')) cmdline++;
231
    while ((*cmdline != 0) && (*cmdline != ' ') && (*cmdline != '/')) cmdline++;
203
  }
232
  }
204
 
-
 
205
  DONE:
-
 
206
 
-
 
207
  /* set a nul terminator on cmdline (expected later in the code) */
-
 
208
  while (*cmdline != 0x0d) cmdline++;
-
 
209
  *cmdline = 0;
-
 
210
}
233
}
211
 
234
 
212
 
235
 
213
/* builds the prompt string and displays it. buff is filled with a zero-terminated copy of the prompt. */
236
/* builds the prompt string and displays it. buff is filled with a zero-terminated copy of the prompt. */
214
static void build_and_display_prompt(char *buff, unsigned short envseg) {
237
static void build_and_display_prompt(char *buff, unsigned short envseg) {