Subversion Repositories SvarDOS

Rev

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

Rev 548 Rev 571
Line 1... Line 1...
1
/* This file is part of the SvarCOM project and is published under the terms
1
/* This file is part of the SvarCOM project and is published under the terms
2
 * of the MIT license.
2
 * of the MIT license.
3
 *
3
 *
4
 * Copyright (C) 2021 Mateusz Viste
4
 * Copyright (C) 2021-2022 Mateusz Viste
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
Line 304... Line 304...
304
  *s = 0;
304
  *s = 0;
305
  output(buff);
305
  output(buff);
306
}
306
}
307
 
307
 
308
 
308
 
309
/* tries locating executable fname in path and fill res with result. returns 0 on success,
-
 
310
 * -1 on failed match and -2 on failed match + "don't even try with other paths"
-
 
311
 * extptr contains a ptr to the extension in fname (NULL if not found) */
-
 
312
static int lookup_cmd(char *res, const char *fname, const char *path, const char **extptr) {
-
 
313
  unsigned short lastbslash = 0;
-
 
314
  unsigned short i, len;
-
 
315
  unsigned char explicitpath = 0;
-
 
316
 
-
 
317
  /* does the original fname has an explicit path prefix or explicit ext? */
-
 
318
  *extptr = NULL;
-
 
319
  for (i = 0; fname[i] != 0; i++) {
-
 
320
    switch (fname[i]) {
-
 
321
      case ':':
-
 
322
      case '\\':
-
 
323
        explicitpath = 1;
-
 
324
        *extptr = NULL; /* extension is the last dot AFTER all path delimiters */
-
 
325
        break;
-
 
326
      case '.':
-
 
327
        *extptr = fname + i + 1;
-
 
328
        break;
-
 
329
    }
-
 
330
  }
-
 
331
 
-
 
332
  /* normalize filename */
-
 
333
  if (file_truename(fname, res) != 0) return(-2);
-
 
334
 
-
 
335
  /* printf("truename: %s\r\n", res); */
-
 
336
 
-
 
337
  /* figure out where the command starts and if it has an explicit extension */
-
 
338
  for (len = 0; res[len] != 0; len++) {
-
 
339
    switch (res[len]) {
-
 
340
      case '?':   /* abort on any wildcard character */
-
 
341
      case '*':
-
 
342
        return(-2);
-
 
343
      case '\\':
-
 
344
        lastbslash = len;
-
 
345
        break;
-
 
346
    }
-
 
347
  }
-
 
348
 
-
 
349
  /* printf("lastbslash=%u\r\n", lastbslash); */
-
 
350
 
-
 
351
  /* if no path prefix was found in fname (no colon or backslash) AND we have
-
 
352
   * a path arg, then assemble path+filename */
-
 
353
  if ((!explicitpath) && (path != NULL) && (path[0] != 0)) {
-
 
354
    i = strlen(path);
-
 
355
    if (path[i - 1] != '\\') i++; /* add a byte for inserting a bkslash after path */
-
 
356
    /* move the filename at the place where path will end */
-
 
357
    memmove(res + i, res + lastbslash + 1, len - lastbslash);
-
 
358
    /* copy path in front of the filename and make sure there is a bkslash sep */
-
 
359
    memmove(res, path, i);
-
 
360
    res[i - 1] = '\\';
-
 
361
  }
-
 
362
 
-
 
363
  /* if no extension was initially provided, try matching COM, EXE, BAT */
-
 
364
  if (*extptr == NULL) {
-
 
365
    const char *ext[] = {".COM", ".EXE", ".BAT", NULL};
-
 
366
    len = strlen(res);
-
 
367
    for (i = 0; ext[i] != NULL; i++) {
-
 
368
      strcpy(res + len, ext[i]);
-
 
369
      /* printf("? '%s'\r\n", res); */
-
 
370
      *extptr = ext[i] + 1;
-
 
371
      if (file_getattr(res) >= 0) return(0);
-
 
372
    }
-
 
373
  } else { /* try finding it as-is */
-
 
374
    /* printf("? '%s'\r\n", res); */
-
 
375
    if (file_getattr(res) >= 0) return(0);
-
 
376
  }
-
 
377
 
-
 
378
  /* not found */
-
 
379
  if (explicitpath) return(-2); /* don't bother trying other paths, the caller had its own path preset anyway */
-
 
380
  return(-1);
-
 
381
}
-
 
382
 
-
 
383
 
-
 
384
static void run_as_external(char *buff, const char *cmdline, unsigned short envseg, struct rmod_props far *rmod, struct redir_data *redir) {
309
static void run_as_external(char *buff, const char *cmdline, unsigned short envseg, struct rmod_props far *rmod, struct redir_data *redir) {
385
  char *cmdfile = buff + 512;
310
  char *cmdfile = buff + 512;
386
  const char far *pathptr;
311
  const char far *pathptr;
387
  int lookup;
312
  int lookup;
388
  unsigned short i;
313
  unsigned short i;
Line 418... Line 343...
418
    return;
343
    return;
419
  }
344
  }
420
 
345
 
421
  /* try matching something in PATH */
346
  /* try matching something in PATH */
422
  pathptr = env_lookup_val(envseg, "PATH");
347
  pathptr = env_lookup_val(envseg, "PATH");
423
  if (pathptr == NULL) return;
-
 
424
 
348
 
425
  /* try each path in %PATH% */
349
  /* try each path in %PATH% */
426
  for (;;) {
350
  while (pathptr) {
427
    for (i = 0;; i++) {
351
    for (i = 0;; i++) {
428
      buff[i] = *pathptr;
352
      buff[i] = *pathptr;
429
      if ((buff[i] == 0) || (buff[i] == ';')) break;
353
      if ((buff[i] == 0) || (buff[i] == ';')) break;
430
      pathptr++;
354
      pathptr++;
431
    }
355
    }
432
    buff[i] = 0;
356
    buff[i] = 0;
433
    lookup = lookup_cmd(cmdfile, cmd, buff, &ext);
357
    lookup = lookup_cmd(cmdfile, cmd, buff, &ext);
434
    if (lookup == 0) break;
358
    if (lookup == 0) goto RUNCMDFILE;
435
    if (lookup == -2) return;
359
    if (lookup == -2) return;
436
    if (*pathptr == ';') {
360
    if (*pathptr == ';') {
437
      pathptr++;
361
      pathptr++;
438
    } else {
362
    } else {
439
      return;
363
      break;
440
    }
364
    }
441
  }
365
  }
442
 
366
 
-
 
367
  /* last chance: is it an executable link? (trim extension from cmd first) */
-
 
368
  for (i = 0; (cmd[i] != 0) && (cmd[i] != '.') && (i < 9); i++) buff[128 + i] = cmd[i];
-
 
369
  buff[128 + i] = 0;
-
 
370
  if ((i < 9) && (link_computefname(buff, buff + 128, envseg) == 0)) {
-
 
371
    /* try opening the link file (if it exists) and read it into buff */
-
 
372
    i = 0;
-
 
373
    _asm {
-
 
374
      push ax
-
 
375
      push bx
-
 
376
      push cx
-
 
377
      push dx
-
 
378
 
-
 
379
      mov ax, 0x3d00  /* DOS 2+ - OPEN EXISTING FILE, READ-ONLY */
-
 
380
      mov dx, buff    /* file name */
-
 
381
      int 0x21
-
 
382
      jc ERR_FOPEN
-
 
383
      /* file handle in AX, read from file now */
-
 
384
      mov bx, ax      /* file handle */
-
 
385
      mov ah, 0x3f    /* Read from file via handle bx */
-
 
386
      mov cx, 128     /* up to 128 bytes */
-
 
387
      /* mov dx, buff */ /* dest buffer (already set) */
-
 
388
      int 0x21        /* read up to 256 bytes from file and write to buff */
-
 
389
      jc ERR_READ
-
 
390
      mov i, ax
-
 
391
      ERR_READ:
-
 
392
      mov ah, 0x3e    /* close file handle in BX */
-
 
393
      int 0x21
-
 
394
      ERR_FOPEN:
-
 
395
 
-
 
396
      pop dx
-
 
397
      pop cx
-
 
398
      pop bx
-
 
399
      pop ax
-
 
400
    }
-
 
401
 
-
 
402
    /* did I read anything? */
-
 
403
    if (i != 0) {
-
 
404
      buff[i] = 0;
-
 
405
      /* trim buff at first \n or \r, just in case someone fiddled with the
-
 
406
       * link file using a text editor */
-
 
407
      for (i = 0; (buff[i] != 0) && (buff[i] != '\r') && (buff[i] != '\n'); i++);
-
 
408
      buff[i] = 0;
-
 
409
      /* lookup check */
-
 
410
      if (buff[0] != 0) {
-
 
411
        lookup = lookup_cmd(cmdfile, cmd, buff, &ext);
-
 
412
        if (lookup == 0) goto RUNCMDFILE;
-
 
413
      }
-
 
414
    }
-
 
415
  }
-
 
416
 
-
 
417
  /* all failed (ie. executable file not found) */
-
 
418
  return;
-
 
419
 
443
  RUNCMDFILE:
420
  RUNCMDFILE:
444
 
421
 
445
  /* special handling of batch files */
422
  /* special handling of batch files */
446
  if ((ext != NULL) && (imatch(ext, "bat"))) {
423
  if ((ext != NULL) && (imatch(ext, "bat"))) {
447
    /* copy truename of the bat file to rmod buff */
424
    /* copy truename of the bat file to rmod buff */