Subversion Repositories SvarDOS

Rev

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

Rev 457 Rev 458
Line 266... Line 266...
266
  }
266
  }
267
  *s = '$';
267
  *s = '$';
268
}
268
}
269
 
269
 
270
 
270
 
-
 
271
/* tries locating executable fname in path and fille res with result. returns 0 on success,
-
 
272
 * -1 on failed match and -2 on failed match + "don't even try with other paths"
-
 
273
 * format is filled the offset where extension starts in fname (-1 if not found) */
-
 
274
int lookup_cmd(char *res, const char *fname, const char *path, const char **extptr) {
-
 
275
  unsigned short lastbslash = 0xffff;
-
 
276
  unsigned short i, len;
-
 
277
  unsigned char explicitpath = 0;
-
 
278
 
-
 
279
  /* does the original fname had an explicit path prefix or explicit ext? */
-
 
280
  *extptr = NULL;
-
 
281
  for (i = 0; fname[i] != 0; i++) {
-
 
282
    switch (fname[i]) {
-
 
283
      case ':':
-
 
284
      case '\\':
-
 
285
        explicitpath = 1;
-
 
286
        *extptr = NULL; /* extension is the last dot AFTER all path delimiters */
-
 
287
        break;
-
 
288
      case '.':
-
 
289
        *extptr = fname + i + 1;
-
 
290
        break;
-
 
291
    }
-
 
292
  }
-
 
293
 
-
 
294
  /* normalize filename */
-
 
295
  if (file_truename(fname, res) != 0) return(-2);
-
 
296
 
-
 
297
  /* printf("truename: %s\r\n", res); */
-
 
298
 
-
 
299
  /* figure out where the command starts and if it has an explicit extension */
-
 
300
  for (len = 0; res[len] != 0; len++) {
-
 
301
    switch (res[len]) {
-
 
302
      case '?':   /* abort on any wildcard character */
-
 
303
      case '*':
-
 
304
        return(-2);
-
 
305
      case '\\':
-
 
306
        lastbslash = len;
-
 
307
        break;
-
 
308
    }
-
 
309
  }
-
 
310
 
-
 
311
  /* printf("lastbslash=%u\r\n", lastbslash); */
-
 
312
 
-
 
313
  /* if no path prefix in fname (':' or backslash), then assemble path+filename */
-
 
314
  if (!explicitpath) {
-
 
315
    if (path != NULL) {
-
 
316
      i = strlen(path);
-
 
317
    } else {
-
 
318
      i = 0;
-
 
319
    }
-
 
320
    if ((i != 0) && (path[i - 1] != '\\')) i++; /* add a byte for inserting a bkslash after path */
-
 
321
    memmove(res + i, res + lastbslash + 1, len - lastbslash);
-
 
322
    if (i != 0) {
-
 
323
      memmove(res, path, i);
-
 
324
      res[i - 1] = '\\';
-
 
325
    }
-
 
326
  }
-
 
327
 
-
 
328
  /* if no extension was initially provided, try matching COM, EXE, BAT */
-
 
329
  if (*extptr == NULL) {
-
 
330
    const char *ext[] = {".COM", ".EXE", ".BAT", NULL};
-
 
331
    len = strlen(res);
-
 
332
    for (i = 0; ext[i] != NULL; i++) {
-
 
333
      strcpy(res + len, ext[i]);
-
 
334
      /* printf("? '%s'\r\n", res); */
-
 
335
      *extptr = ext[i] + 1;
-
 
336
      if (file_getattr(res) >= 0) return(0);
-
 
337
    }
-
 
338
  } else { /* try finding it as-is */
-
 
339
    /* printf("? '%s'\r\n", res); */
-
 
340
    if (file_getattr(res) >= 0) return(0);
-
 
341
  }
-
 
342
 
-
 
343
  /* not found */
-
 
344
  if (explicitpath) return(-2); /* don't bother trying other paths, the caller had its own path preset anyway */
-
 
345
  return(-1);
-
 
346
}
-
 
347
 
-
 
348
 
271
static void run_as_external(char *buff, const char far *cmdline) {
349
static void run_as_external(char *buff, const char far *cmdline, unsigned short envseg) {
272
  char const **argvlist = (void *)(buff + 512);
350
  char const **argvlist = (void *)(buff + 512);
-
 
351
  char *cmdfile = buff + 1024;
-
 
352
  const char far *pathptr;
-
 
353
  int lookup;
-
 
354
  unsigned short i;
-
 
355
  const char *ext;
273
 
356
 
274
  cmd_explode(buff, cmdline, argvlist);
357
  cmd_explode(buff + 2048, cmdline, argvlist);
275
 
358
 
276
  /* for (i = 0; argvlist[i] != NULL; i++) printf("arg #%d = '%s'\r\n", i, argvlist[i]); */
359
  /* for (i = 0; argvlist[i] != NULL; i++) printf("arg #%d = '%s'\r\n", i, argvlist[i]); */
277
 
360
 
-
 
361
  /* is this a command in curdir? */
-
 
362
  lookup = lookup_cmd(cmdfile, argvlist[0], NULL, &ext);
-
 
363
  if (lookup == 0) {
-
 
364
    /* printf("FOUND LOCAL EXEC FILE: '%s'\r\n", cmdfile); */
-
 
365
    goto RUNCMDFILE;
-
 
366
  } else if (lookup == -2) {
-
 
367
    /* puts("NOT FOUND"); */
-
 
368
    return;
-
 
369
  }
-
 
370
 
-
 
371
  /* try matching something in PATH */
-
 
372
  pathptr = env_lookup_val(envseg, "PATH");
-
 
373
  if (pathptr == NULL) return;
-
 
374
 
-
 
375
  /* try each path in %PATH% */
-
 
376
  for (;;) {
-
 
377
    for (i = 0;; i++) {
-
 
378
      buff[i] = *pathptr;
-
 
379
      if ((buff[i] == 0) || (buff[i] == ';')) break;
-
 
380
      pathptr++;
-
 
381
    }
-
 
382
    buff[i] = 0;
-
 
383
    lookup = lookup_cmd(cmdfile, argvlist[0], buff, &ext);
-
 
384
    if (lookup == 0) break;
-
 
385
    if (lookup == -2) return;
-
 
386
    if (*pathptr == ';') {
-
 
387
      pathptr++;
-
 
388
    } else {
-
 
389
      return;
-
 
390
    }
-
 
391
  }
-
 
392
 
-
 
393
  RUNCMDFILE:
-
 
394
  /* TODO run command through INT 0x21 */
-
 
395
  /* TODO copy environment and append full exec path */
-
 
396
  /* TODO special handling of batch files */
-
 
397
  if ((ext != NULL) && (imatch(ext, "bat"))) {
-
 
398
    outputnl("batch processing not supported yet");
-
 
399
    return;
-
 
400
  }
-
 
401
 
-
 
402
  /* printf("Exec: '%s'\r\n", cmdfile); */
-
 
403
 
278
  /* this call should never return, unless the program failed to be executed */
404
  /* this call should never return, unless the program failed to be executed */
279
  execvp(argvlist[0], argvlist);
405
  execvp(cmdfile, argvlist);
280
}
406
}
281
 
407
 
282
 
408
 
283
static void set_comspec_to_self(unsigned short envseg) {
409
static void set_comspec_to_self(unsigned short envseg) {
284
  unsigned short *psp_envseg = (void *)(0x2c); /* pointer to my env segment field in the PSP */
410
  unsigned short *psp_envseg = (void *)(0x2c); /* pointer to my env segment field in the PSP */
Line 466... Line 592...
466
      redir_revert(); /* revert stdout (in case it was redirected) */
592
      redir_revert(); /* revert stdout (in case it was redirected) */
467
      continue;
593
      continue;
468
    }
594
    }
469
 
595
 
470
    /* if here, then this was not an internal command */
596
    /* if here, then this was not an internal command */
471
    run_as_external(BUFFER, cmdline);
597
    run_as_external(BUFFER, cmdline, *rmod_envseg);
472
 
598
 
473
    /* revert stdout (in case it was redirected) */
599
    /* revert stdout (in case it was redirected) */
474
    redir_revert();
600
    redir_revert();
475
 
601
 
476
    /* execvp() replaces the current process by the new one
602
    /* execvp() replaces the current process by the new one