Subversion Repositories SvarDOS

Rev

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

Rev 362 Rev 364
Line 78... Line 78...
78
    }
78
    }
79
  }
79
  }
80
}
80
}
81
 
81
 
82
 
82
 
83
static int explode_progparams(char *s, char const **argvlist) {
-
 
84
  int si = 0, argc = 0;
-
 
85
  for (;;) {
-
 
86
    /* skip to next non-space character */
-
 
87
    while (s[si] == ' ') si++;
-
 
88
    /* end of string? */
-
 
89
    if (s[si] == '\r') break;
-
 
90
    /* set argv ptr */
-
 
91
    argvlist[argc++] = s + si;
-
 
92
    /* find next space */
-
 
93
    while (s[si] != ' ' && s[si] != '\r') si++;
-
 
94
    /* is this end of string? */
-
 
95
    if (s[si] == '\r') {
-
 
96
      s[si] = 0;
-
 
97
      break;
-
 
98
    }
-
 
99
    /* not end: terminate arg and look for next one */
-
 
100
    s[si++] = 0;
-
 
101
  }
-
 
102
  /* terminate argvlist with a NULL value */
-
 
103
  argvlist[argc] = NULL;
-
 
104
  return(argc);
-
 
105
}
-
 
106
 
-
 
107
 
-
 
108
static void buildprompt(char *s, const char *fmt) {
83
static void buildprompt(char *s, const char *fmt) {
109
  for (; *fmt != 0; fmt++) {
84
  for (; *fmt != 0; fmt++) {
110
    if (*fmt != '$') {
85
    if (*fmt != '$') {
111
      *s = *fmt;
86
      *s = *fmt;
112
      s++;
87
      s++;
Line 204... Line 179...
204
  }
179
  }
205
  *s = '$';
180
  *s = '$';
206
}
181
}
207
 
182
 
208
 
183
 
-
 
184
static void run_as_external(const char far *cmdline) {
-
 
185
  char buff[256];
-
 
186
  char const *argvlist[256];
-
 
187
  int i, n;
-
 
188
  /* copy buffer to a near var (incl. trailing CR), insert a space before
-
 
189
     every slash to make sure arguments are well separated */
-
 
190
  n = 0;
-
 
191
  i = 0;
-
 
192
  for (;;) {
-
 
193
    if (cmdline[i] == '/') buff[n++] = ' ';
-
 
194
    buff[n++] = cmdline[i++];
-
 
195
    if (buff[n] == 0) break;
-
 
196
  }
-
 
197
 
-
 
198
  cmd_explode(buff, cmdline, argvlist);
-
 
199
 
-
 
200
  /* for (i = 0; argvlist[i] != NULL; i++) printf("arg #%d = '%s'\r\n", i, argvlist[i]); */
-
 
201
 
-
 
202
  /* must be an external command then. this call should never return, unless
-
 
203
   * the other program failed to be executed. */
-
 
204
  execvp(argvlist[0], argvlist);
-
 
205
}
-
 
206
 
-
 
207
 
209
int main(int argc, char **argv) {
208
int main(int argc, char **argv) {
210
  struct config cfg;
209
  struct config cfg;
211
  unsigned short rmod_seg;
210
  unsigned short rmod_seg;
212
  unsigned short far *rmod_envseg;
211
  unsigned short far *rmod_envseg;
213
  unsigned short far *lastexitcode;
212
  unsigned short far *lastexitcode;
Line 237... Line 236...
237
    envsiz *= 16;
236
    envsiz *= 16;
238
    printf("rmod_inpbuff at %04X:%04X, env_seg at %04X:0000 (env_size = %u bytes)\r\n", rmod_seg, RMOD_OFFSET_INPBUFF, *rmod_envseg, envsiz);
237
    printf("rmod_inpbuff at %04X:%04X, env_seg at %04X:0000 (env_size = %u bytes)\r\n", rmod_seg, RMOD_OFFSET_INPBUFF, *rmod_envseg, envsiz);
239
  }
238
  }
240
 
239
 
241
  for (;;) {
240
  for (;;) {
242
    int i, n, argcount;
-
 
243
    char far *cmdline = MK_FP(rmod_seg, RMOD_OFFSET_INPBUFF + 2);
241
    char far *cmdline = MK_FP(rmod_seg, RMOD_OFFSET_INPBUFF + 2);
-
 
242
 
-
 
243
    /* revert input history terminator to \r */
244
    char buff[256];
244
    if (cmdline[-1] != 0) {
245
    char const *argvlist[256];
245
      cmdline[(unsigned short)(cmdline[-1])] = '\r';
-
 
246
    }
246
 
247
 
247
    {
248
    {
248
      /* print shell prompt */
249
      /* print shell prompt */
-
 
250
      char buff[256];
249
      char *promptptr = buff;
251
      char *promptptr = buff;
250
      buildprompt(promptptr, "$p$g"); /* TODO: prompt should be configurable via environment */
252
      buildprompt(promptptr, "$p$g"); /* TODO: prompt should be configurable via environment */
251
      _asm {
253
      _asm {
-
 
254
        push ax
252
        push dx
255
        push dx
253
        mov ah, 0x09
256
        mov ah, 0x09
254
        mov dx, promptptr
257
        mov dx, promptptr
255
        int 0x21
258
        int 0x21
256
        pop dx
259
        pop dx
-
 
260
        pop ax
257
      }
261
      }
258
    }
262
    }
259
 
263
 
260
    /* wait for user input */
264
    /* wait for user input */
261
    _asm {
265
    _asm {
-
 
266
      push ax
-
 
267
      push bx
-
 
268
      push cx
-
 
269
      push dx
262
      push ds
270
      push ds
263
 
271
 
264
      /* is DOSKEY support present? (INT 2Fh, AX=4800h, returns non-zero in AL if present) */
272
      /* is DOSKEY support present? (INT 2Fh, AX=4800h, returns non-zero in AL if present) */
265
      mov ax, 0x4800
273
      mov ax, 0x4800
266
      int 0x2f
274
      int 0x2f
Line 284... Line 292...
284
      mov ax, 0x4810
292
      mov ax, 0x4810
285
      int 0x2f
293
      int 0x2f
286
 
294
 
287
      DONE:
295
      DONE:
288
      pop ds
296
      pop ds
-
 
297
      pop dx
-
 
298
      pop cx
-
 
299
      pop bx
-
 
300
      pop ax
289
    }
301
    }
290
    printf("\r\n");
302
    printf("\r\n");
291
 
303
 
292
    /* if nothing entered, loop again */
304
    /* if nothing entered, loop again */
293
    if (cmdline[-1] == 0) continue;
305
    if (cmdline[-1] == 0) continue;
294
 
306
 
295
    /* copy buffer to a near var (incl. trailing CR), insert a space before
-
 
296
       every slash to make sure arguments are well separated */
307
    /* replace \r by a zero terminator */
297
    n = 0;
-
 
298
    for (i = 0; i < cmdline[-1] + 1; i++) {
-
 
299
      if (cmdline[i] == '/') buff[n++] = ' ';
308
    cmdline[(unsigned char)(cmdline[-1])] = 0;
300
      buff[n++] = cmdline[i];
-
 
301
    }
-
 
302
    buff[n] = 0;
-
 
303
 
-
 
304
    argcount = explode_progparams(buff, argvlist);
-
 
305
 
-
 
306
    /* if no args found (eg. all-spaces), loop again */
-
 
307
    if (argcount == 0) continue;
-
 
308
 
-
 
309
    /* for (i = 0; i < argcount; i++) printf("arg #%d = '%s'\r\n", i, argvlist[i]); */
-
 
310
 
309
 
311
    /* is it about quitting? */
310
    /* move pointer forward to skip over any leading spaces */
312
    if (imatch(argvlist[0], "exit")) break;
311
    while (*cmdline == ' ') cmdline++;
313
 
312
 
314
    /* try running it as an internal command */
313
    /* try matching (and executing) an internal command */
315
    {
314
    {
316
      int ecode = cmd_process(argcount, argvlist, *rmod_envseg, cmdline);
315
      int ecode = cmd_process(*rmod_envseg, cmdline);
317
      if (ecode >= 0) *lastexitcode = ecode;
316
      if (ecode >= 0) *lastexitcode = ecode;
318
      if (ecode >= -1) continue; /* command is internal but did not set an exit code */
317
      if (ecode >= -1) continue; /* internal command executed */
319
    }
318
    }
320
 
319
 
321
    /* must be an external command then */
320
    /* if here, then this was not an internal command */
322
    execvp(argvlist[0], argvlist);
321
    run_as_external(cmdline);
323
 
322
 
324
    /* execvp() replaces the current process by the new one
323
    /* execvp() replaces the current process by the new one
325
    if I am still alive then external command failed to execute */
324
    if I am still alive then external command failed to execute */
326
    puts("Bad command or file name");
325
    puts("Bad command or file name");
327
 
326