COMINT.C
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:56k
源码类别:

操作系统开发

开发平台:

Asm

  1. /*
  2. ;    File              : $Workfile: COMINT.C$
  3. ;
  4. ;    Description       :
  5. ;
  6. ;    Original Author   : DIGITAL RESEARCH
  7. ;
  8. ;    Last Edited By    : $CALDERA$
  9. ;
  10. ;-----------------------------------------------------------------------;
  11. ;    Copyright Work of Caldera, Inc. All Rights Reserved.
  12. ;      
  13. ;    THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
  14. ;    PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
  15. ;    ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
  16. ;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
  17. ;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
  18. ;    HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
  19. ;    AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
  20. ;    AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
  21. ;    COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
  22. ;    CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
  23. ;    TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
  24. ;    CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
  25. ;    AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
  26. ;    CIVIL LIABILITY.
  27. ;-----------------------------------------------------------------------;
  28. ;
  29. ;    *** Current Edit History ***
  30. ;    *** End of Current Edit History ***
  31. ;
  32. ;    $Log$
  33. ;
  34. ;    ENDLOG
  35. */
  36. #include "defines.h"
  37. #include <string.h>
  38. #if defined(MWC) && defined(strlen)
  39. #undef strcmp /* These are defined as macros in string.h */
  40. #undef strcpy /* which are expaneded in line under */
  41. #undef strlen /* Metaware C. These undefs avoid this. */
  42. #endif
  43. #include <portab.h>
  44. #include <mserror.h>
  45. #if !defined(DOSPLUS)
  46. #include <pd.h>
  47. #include <ccpm.h>
  48. #include <sysdat.h>
  49. #endif
  50. #include "command.h" /* COMMAND Definitions */
  51. #include "dos.h"  /* MSDOS Functions */
  52. #include "dosif.h" /* DOS interface definitions  */
  53. #include "toupper.h"
  54. #include "support.h" /* Support routines  */
  55. #include "global.h"
  56. /*RG-00-*/
  57. #if !defined(NOXBATCH)
  58. #if !defined(NOSECURITY) && (defined(CDOSTMP) || defined(CDOS))
  59. #define PATH_LEN     65  /* max path length (null terminated) */
  60. #include "security.h"
  61. #include "login.h"
  62. #include "txlogin.h"
  63. #endif
  64. #endif /*NOXBATCH*/
  65. /*RG-00-end*/
  66. EXTERN VOID CDECL restore_error_mode();
  67. EXTERN VOID batch_start(BYTE *, BYTE *, BYTE *);
  68. EXTERN VOID batch_end(VOID); /* BATCH.C */
  69. EXTERN VOID batch_close(VOID); /* BATCH.C */
  70. MLOCAL VOID erase(BYTE *, BOOLEAN); /* COMINT.C */
  71. MLOCAL BYTE * date_format(UWORD); /* COMINT.C */
  72. MLOCAL BOOLEAN check_date(BYTE *); /* COMINT.C */
  73. MLOCAL BOOLEAN check_time(BYTE *); /* COMINT.C */
  74. MLOCAL VOID show_crlf(BOOLEAN); /* COMINT.C */
  75. /*RG-02-*/
  76. #if !defined(NOXBATCH)
  77. GLOBAL VOID CDECL cmd_pauseerr(BYTE *);    /* COMINT.C */
  78. /*RG-02-end*/
  79. #endif
  80. GLOBAL VOID CDECL cmd_pause(BYTE *);    /* COMINT.C */
  81. GLOBAL VOID CDECL cmd_set(BYTE *); /* COMINT.C */
  82. GLOBAL VOID CDECL cmd_vol(BYTE *); /* COMINT.C */
  83. EXTERN WORD CDECL findfile(BYTE *, UWORD *); /* DOSIF.A86 || COM.C */
  84. EXTERN VOID CDECL int_break(VOID); /* COM.C */
  85. EXTERN VOID docmd(BYTE *, BOOLEAN); /* COM.C */
  86. #if defined(CPM)
  87. EXTERN UWORD CDECL cpm_de_init(VOID); /* CP/M Clean-Up Routine*/
  88. #endif
  89. MLOCAL WORD linesleft; /* Remaining lines on Screen */
  90. MLOCAL WORD ret; /* general BDOS return code */
  91. #if defined(CDOSTMP) || defined(CDOS)
  92. /*.pa*/
  93. /*
  94.  * USER BEWARE
  95.  *
  96.  * A process descriptor exists in both DOS Plus and Concurrent
  97.  * DOS. But is an internal Structure in DOS Plus and should only
  98.  * be used with the upmost care.
  99.  */
  100. EXTERN PD FAR * CDECL pd; /* Far pointer to Current PD */
  101. /*
  102.  * The following command will enable APPEND processing and set
  103.  * path searched by the BDOS on every OPEN function call.
  104.  *
  105.  * APPEND[=][d:]path[[;[d:]path]..] | [;] [/X|/E]
  106.  *
  107.  * APPEND without any command line options will display the current
  108.  * search path while APPEND ; will remove the Search Path and disable
  109.  * the APPEND facility.
  110.  *
  111.  * /E Forces the search path to be saved in the environment under
  112.  * Concurrent DOS this is always true and this flag is ignored.
  113.  *
  114.  * /X Forces APPEND to be active for the SEARCH FIRST(0x11), 
  115.  * FIND FIRST(0x4E) and EXEC(0x4B) functions. In addition
  116.  * to the normal functions FCB OPEN(0x0F), FCB FileSize(0x23)
  117.  * and OPEN(0x3D).
  118.  * /B Forces APPEND to provide batch command compatible output
  119.  *          that when redirected to a file, can be used to regenerate a
  120.  *          given append state.
  121.  */
  122. MLOCAL BYTE msg_appeq  [] = "APPEND="; /* Static Environment String */
  123. /*RG-03*/
  124. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  125. #define APPEND_BAT (flags & 4) /* /B Append Option */
  126. #endif
  127. /*RG-03-end*/
  128. #define APPEND_X (flags & 2) /* /X Append Option */
  129. #define APPEND_E (flags & 1) /* /E Append Option */
  130. GLOBAL VOID CDECL cmd_append(path)
  131. REG BYTE *path;
  132. {
  133. REG BYTE *s;
  134. UWORD  flags; /* Command Flags     */
  135. #if !STACK
  136. BYTE  sbuf[MAX_ENVLEN];
  137. #endif
  138. #if defined(CDOS) || defined(CDOSTMP)
  139. if (f_check (path, "exb", &flags, NO)) /* Check for valid Flags    */
  140. #else
  141.         if (f_check (path, "ex", &flags, NO)) /* Check for valid Flags    */
  142. #endif
  143.             return;
  144. zap_spaces(path); /* Remove White Space     */
  145. if(!*path && !APPEND_X) {
  146.     if(env_scan(msg_appeq, s = (BYTE *)heap())) /* look for current value   */
  147.     s = NULLPTR;
  148.     if(s && (pd->P_SFLAG & PSF_APPEND)) { /* If a path exists and the */
  149.     printf(msg_appeq); /* Append bit is set in the */
  150.     puts(s);
  151.     }
  152. /*RG-03*/
  153.             else  { /* PD then display path     */
  154. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  155.                 if (APPEND_BAT)
  156.                     printf("APPEND=");
  157.                 else
  158. #endif
  159.                     printf(MSG_APPEND);
  160.             }
  161. /*RG-03-end*/
  162.     crlfflg = YES;
  163.     return; 
  164. }
  165. pd->P_SFLAG |= APPEND_X ? PSF_XAPPEND : 0;
  166. if(*path == '=' || *path == ';')/* Skip Leading '=' or ';' chars    */
  167.     path++; /* and disable the APPEND command   */
  168. /* if no path is specified.     */
  169. if(*path) { /* Assign APPEND Path     */
  170.     pd->P_SFLAG |= PSF_APPEND; /* Set the APPEND and XAPPEND Bits  */
  171. #if STACK
  172.     s = stack(strlen(msg_appeq) + strlen(path) + 1);
  173. #else
  174.     s = &sbuf[0];
  175. #endif
  176.     strcpy(s, msg_appeq); /* build command line for "SET"  */
  177.     strcat(s, strupr(path)); /* Force Path to UPPER case     */
  178.     cmd_set(s);  /* set new path using "SET"     */
  179. }
  180. else if(!APPEND_X) { /* Disable APPEND Processing     */
  181.     pd->P_SFLAG &= ~(PSF_APPEND | PSF_XAPPEND);
  182.     cmd_set(msg_appeq);
  183. }     
  184. }
  185. #endif
  186. #if !defined(EXT_SUBST)
  187. /*.pa*/
  188. /************************************************************************/
  189. /* */
  190. /* ASSIGN (x [=] y ...) [/a][/b] */
  191. /* */
  192. /* This command forces future references to the X: to physically */
  193. /* reference the Y: drive. */
  194. /* */
  195. /* When no command line parameters are given then all assignments */
  196. /* are removed. If the /A option is used the current drive  */
  197. /* assignments are displayed. For the purpose of the display and */
  198. /* remove functions an "ASSIGNed" drives is any physical drive */
  199. /* which does not reference itself. */
  200. /* */
  201. /************************************************************************/
  202. /*
  203.  * ASSIGN_DRV returns TRUE if the drive pointed to by BP
  204.  * is a valid physical drive.
  205.  */
  206. MLOCAL BOOLEAN assign_drv(bp)
  207. BYTE *bp;
  208. {
  209. if(!d_check(bp))
  210.     return FALSE;
  211.     
  212. if(physical_drvs() & (1L << ddrive))
  213.     return TRUE;
  214. e_check(ED_DRIVE);
  215. return FALSE;
  216. }
  217. /*RG-03*/
  218. #define ASSIGN_BAT (flags & 2) /* Display Current Assignments in batch form */
  219. /*RG-03-end*/
  220. #define ASSIGN_ALL (flags & 1) /* Display Current Assignments */
  221. GLOBAL VOID CDECL cmd_assign(s)
  222. REG BYTE *s;
  223. {
  224. BYTE temp[7]; /* Temporary Command Buffer */
  225. BYTE path[MAX_PATHLEN];
  226. BYTE src, dst;
  227. ULONG vec,pvec,lvec,nvec;
  228. UWORD drv;
  229. UWORD flags; /* Command Flags */
  230. WORD    ret; /* General purpose variable */
  231. if (f_check (s, "ab", &flags, NO)) /* Check for Flags if any are   */
  232.             return;   /* invalid then don't do it     */
  233. pvec = physical_drvs();
  234. lvec = logical_drvs();
  235. /*
  236.  * Display the current drive assignments. 
  237.  */
  238. /*RG-03*/
  239. if((ASSIGN_ALL)||(ASSIGN_BAT))
  240.         {
  241.     vec = 1L;
  242.     drv = 0;
  243.     while(drv < 26) {
  244.     if((lvec & vec) && (pdrive(drv) != drv)) {
  245.                     if (ASSIGN_BAT)
  246.             printf("ASSIGN %c = %cn", drv+'A', pdrive(drv)+'A');
  247.                     else
  248. /*RG-03-end*/
  249.             printf("%c: => %c:n", drv+'A', pdrive(drv)+'A');
  250.                 }
  251.     vec <<= 1;
  252.     drv++;
  253.     }
  254.     return;
  255. }
  256. /*
  257.  * Remove ALL drive assignments. 
  258.  */
  259. s = deblank(s); /* If no command line options */
  260. if(!*s) { /* are given then remove the */
  261.      /* current assignments. */
  262.     vec = 1L;
  263.     drv = 0;     
  264.     while(drv < 26) {
  265. if((lvec & vec) && (pdrive(drv) != drv)) {
  266.     sprintf(temp, "%c:=%c:", drv+'A', drv+'A');
  267.     ms_x_chdir(temp);
  268. }
  269. vec <<= 1;
  270. drv++;
  271.     }
  272.     return;
  273. }
  274. /*
  275.  * Scan the command line and make all the drive assignments
  276.  * specified by the user.
  277.  */
  278. do {
  279.     dst = *s++; /* Get the Destinaion */
  280.     s = deblank(s);
  281.     if(*s == '=') /* Skip the optional '='  */
  282.         s = deblank(s+1); /* character and get the source */
  283.     if(!*s) { /* if no second drive has been */
  284. syntax(); /* specified the return error */
  285. return;
  286.     }
  287.     src = *s++;
  288.     sprintf(temp, "%c:=%c:", dst, src);
  289. #if defined(DOSPLUS)
  290.     nvec = network_drvs();
  291.     if ((nvec & (1L << (toupper(src)-'A')))
  292.           || (nvec & (1L << (toupper(dst)-'A')))) {
  293.      eprintf(MSG_NETASSIGN); /* if either is remote */
  294.      return; /* complain and exit */
  295.     }
  296. #endif
  297.     if(assign_drv(temp) && assign_drv(temp+3)) {
  298.      ret = ms_x_chdir(temp);
  299. if (ret) {
  300.     e_check(ret);
  301.       return;
  302. }
  303.     }
  304.     else
  305. return;
  306.     sprintf (path, "%c:%c", dst, *pathchar);
  307.     ms_x_curdir (tolower(src) - 'a'+1, path+3);
  308.      /* set dst drive to cur path on */
  309. /* source */
  310.     ms_x_chdir (path);
  311.     s = deblank(s); /* Deblank the renmainder of */
  312. } while(*s); /* command line and repeat */
  313. }
  314. #endif
  315. /*
  316.  * The CALL command accepts the name of a batch file with an
  317.  * optional parameter list. Any current batch processing is
  318.  * halted and the new batch file is used until the EOF is reached
  319.  * or an EXIT command is executed. Control then passes back to
  320.  * the original Batch file.
  321.  */
  322. EXTERN UWORD CDECL heap_size(VOID);
  323. GLOBAL VOID CDECL cmd_call(line)
  324. REG BYTE *line;
  325. {
  326. BYTE path[MAX_FILELEN];
  327. UWORD loadtype;
  328. BYTE argv0[MAX_FILELEN];
  329. BYTE *s;
  330. heap_get(0); /* check for stack overflow */
  331. s = get_filename(path, deblank(line), NO);
  332. strcpy(argv0, path);
  333. strlwr(path);
  334. if((ret = findfile(path, &loadtype)) >= 0) {
  335.     if(loadtype == BAT_FILETYPE) { /* treat .BAT differently */
  336. batch_start(argv0, path, s); /* nested batch files */
  337. return;
  338.     }
  339. }
  340. line = deblank(line);
  341. docmd(line,YES); /* call normal code */
  342. }
  343. /*
  344.  * Display the current directory assignment of a logical drive
  345.  * Currently the Absolute path is specified with the physical drive
  346.  */
  347. /*RG-03*/
  348. #define CHDIR_BAT (flags & 2) /* Display dir in command line compatible form */
  349. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  350. MLOCAL VOID display_cd(drv,flags)
  351. #else
  352. MLOCAL VOID display_cd(drv)
  353. #endif
  354. REG WORD drv;
  355. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  356. UWORD flags; /* Command Flags */
  357. #endif
  358. {
  359. BYTE dispbuf[MAX_PATHLEN];
  360. WORD ret;
  361. dispbuf[0] = (BYTE) (drv + 'A'); /* Display the path of the */
  362. dispbuf[1] = ':'; /* requested drive    */
  363. dispbuf[2] = *pathchar;
  364. ret = ms_x_curdir(drv+1, dispbuf+3);
  365. if (ret < 0) return;
  366. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  367.         if (CHDIR_BAT)
  368.             printf ("CHDIR %sn", dispbuf);
  369.         else
  370. #endif
  371.             printf ("%sn", dispbuf);
  372. }
  373. /*RG-03-end*/
  374. #define CHDIR_ALL (flags & 1) /* Display Current Assignments */
  375. GLOBAL VOID CDECL cmd_cd(s)
  376. REG BYTE *s;
  377. {
  378. BYTE *cp;
  379. ULONG login; /* Login Vector  */
  380. WORD    ret; /* General purpose variable */
  381. UWORD flags; /* Command Flags */
  382. /*rbf remove trailing spaces from string 's'*/
  383. char *p = s;
  384. while ( (*p!=' ') && *p)
  385. p++;
  386. *p=0;
  387. /*rbf-end*/
  388. #if defined(CDOS) || defined(CDOSTMP)
  389.         if (f_check (s, "ab", &flags, NO)) /* Check for valid Flags    */
  390. #else
  391.         if (f_check (s, "a", &flags, NO)) /* Check for valid Flags    */
  392. #endif
  393.             return;   /* invalid then don't do it     */
  394. if(CHDIR_ALL) { /* Display the current drive */
  395.     for(ret = 0; ret < 26; ret++)
  396. /*RG-03*/
  397. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  398. display_cd(ret,flags);
  399. #else
  400.                 display_cd(ret);
  401. #endif
  402. /*RG-03-end*/
  403.     return;
  404. }
  405. cp = s = deblank(strlwr(s)); /* Deblank after the Flag Check   */
  406. if(*(s+1) == ':') { /* check for a drive specifier   */
  407.     ddrive = *s - 'a'; /* Get the drive letter and check */
  408.     s = deblank(s+2); /* that it is a valid drive and   */
  409. /* is not the LOAD Drive.   */
  410.     if(INVALID_DRV(ddrive)) {
  411. e_check(ED_DRIVE);
  412. return;
  413.     }
  414. }
  415. else
  416.     ddrive = drive; /* Use the default drive   */
  417. if(*s == '=') {  /* Floating Drive Assignment   */
  418.     if(*++s) { /* Check source drive if spec.   */
  419.      if((s = d_check(s)) == 0)/* Abort if an illegal drive is   */
  420.     return;  /* selected.   */
  421. if(!*s) /* If the command is of the form  */
  422.     strcpy(s, ".");  /* x:=y: then append a "."   */
  423.     }
  424. }
  425. else if(!*s) { /* Display the selected drives   */
  426.     if(d_check(cp)) /* current sub-directory.   */
  427. /*RG-03-*/
  428. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  429. display_cd(ddrive,flags);
  430. #else
  431. display_cd(ddrive);
  432. #endif
  433. /*RG-03-end*/
  434.     return;
  435. }
  436. if (*cp == '.') {
  437. while (cp[1] == 32) {
  438. ret = 1;
  439. while (cp[ret]) {
  440. cp[ret] = cp[ret+1];
  441. ret++;
  442. }
  443. }
  444. }
  445. /* Make the drive Assignment   */
  446. if (!d_check(cp)) ddrive = -1;
  447. e_check(ddrive != -1 ? ms_x_chdir(cp) : ED_DRIVE);
  448. }
  449. #if !defined(EXT_SUBST)
  450. /*.pa*/
  451. #define SUBST_DEL (flags & 1)
  452. /*RG-03-*/
  453. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  454. #define SUBST_BAT (flags & 2)
  455. #endif
  456. /*RG-03-end*/
  457. GLOBAL VOID CDECL cmd_subst(s)
  458. BYTE *s;
  459. {
  460. BYTE cp[MAX_FILELEN+3]; /* CHDIR Path Buffer */
  461. BYTE root[4];
  462. ULONG login; /* Logical Drive Vector */
  463. UWORD flags; /* Command Flags */
  464. UWORD drv;
  465. WORD i;
  466. #if defined(CDOS) || defined(CDOSTMP)
  467. if(f_check(s, "db", &flags, NO)) /* Check for Flags if any are   */
  468. #else
  469.         if(f_check(s, "d", &flags, NO)) /* Check for Flags if any are   */
  470. #endif
  471.     return; /* invalid then don't do it     */
  472. s = deblank(strlwr(s)); /* Deblank after the Flag Check   */
  473. if(!*s) { /* If the command line is blank   */
  474.     login = logical_drvs(); /* then display the assignments   */
  475.      /* for all the logical drives   */
  476.     for(drv = 0; drv < 26; drv++, login >>= 1)
  477. if(login & 1L) {
  478.     sprintf(root,"%c:\", drv+'A');
  479.     ms_x_expand(cp, root);
  480. /*RG-03*/
  481. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  482.                 if(SUBST_BAT)
  483.         printf("SUBST %c: %sn", drv + 'A',cp);
  484.                 else
  485. #endif
  486. /*RG-03-end*/
  487.         printf("%c: => %sn", drv + 'A',cp);
  488. }
  489.     return;
  490. }
  491. if(*(s+1) == ':') { /* Check for a drive specifier   */
  492.     ddrive = *s - 'a'; /* Get the drive letter and check */
  493.     s = deblank(s+2); /* that it is a valid drive and   */
  494. /* is not the LOAD Drive.   */
  495.     if(INVALID_DRV(ddrive)) {
  496. e_check(ED_DRIVE);
  497. return;
  498.     }
  499. }
  500. else {
  501.     syntax(); /* If no drive is specified then  */
  502.     return; /* return after displaying a   */
  503. }      /* syntax error message   */
  504. #if defined(DOSPLUS)
  505. if(network_drvs() & (1L << ddrive)) { /* if requested drive is  */
  506.     eprintf(MSG_NETSUBST); /* remote then complain   */
  507.     return; /* and don't do anything  */
  508. }
  509. #endif
  510. sprintf(cp, "%c:=", ddrive+'A'); /* Prepare CHDIR command   */
  511. if(!SUBST_DEL) { /* Check for the Delete Flag   */
  512.     strcat(cp, s);
  513.     if((s = d_check(s)) == 0) /* Abort if an illegal drive   */
  514. return;  /* is selected.    */
  515.     if(!*s) { /* If no PATH is specified then   */
  516. printf(MSG_INOP); /* display display error message. */
  517. return;
  518.     }
  519. }
  520. e_check(ms_x_chdir(cp)); /* Make the drive Assignment   */
  521. }
  522. #endif
  523. /*.pa*/
  524. /*
  525.  * DATE [DD/MM/YY]
  526.  *
  527.  * Display or Set the current date making full use of the DOS
  528.  * international system call.
  529.  */
  530. GLOBAL VOID CDECL cmd_date(s)
  531. BYTE *s;
  532. {
  533. BYTE buffer[18]; /* Local Input Buffer */
  534. if (*s) {
  535.     if(check_date(s))
  536. return;
  537.     printf (INV_DATE);
  538. }
  539. else {
  540.     printf (CUR_DATE);
  541.     disp_sysdate();
  542. }
  543. FOREVER {
  544.     printf (NEW_DATE, date_format(country.dt_fmt));
  545.     buffer[0] = sizeof(buffer) -2; /* Set maximum string length */
  546.     system(MS_C_READSTR, buffer);
  547.     crlf ();
  548.     if (buffer[1] == 0)  /* Check for 0 length input */
  549. return;  /* and return if so */
  550.     buffer [buffer[1]+2] = '';
  551.     if (check_date (buffer+2))
  552. return;
  553.     printf (INV_DATE);
  554. }
  555. }
  556. MLOCAL BYTE * date_format(fmt)
  557. UWORD fmt;
  558. {
  559.     switch (fmt)
  560.     {
  561.     case 1: return EURO_DATE;
  562.     case 2: return JAP_DATE;
  563.     default: break;
  564.     }
  565.     return US_DATE;
  566. }
  567. /*
  568.  * Parse the string pointed to by s and check for a valid date
  569.  * specification. If the date has been specified correctly then
  570.  * set the system date.
  571.  */
  572. MLOCAL BYTE date_sep[] = "/.-";
  573. MLOCAL BOOLEAN check_date(s)
  574. BYTE *s;
  575. {
  576. SYSDATE date;
  577. WORD p1, p2, p3; /* Input Parameters */
  578. deblank(s); /* Remove spaces */
  579. if (!getdigit (&p1, &s) ||
  580.     !strchr(date_sep, *s++) ||
  581.     !getdigit (&p2, &s) ||
  582.     !strchr(date_sep, *s++) ||
  583.     !getdigit (&p3, &s))
  584. {
  585.     return NO;
  586. }
  587. switch (country.dt_fmt) {
  588.  case 1: /* European Format dd/mm/yy */
  589.     date.day = p1;
  590.     date.month = p2;
  591.     date.year = p3;
  592.     break;
  593.  case 2: /* Japanese Format yy/mm/dd */
  594.     date.day = p3;
  595.     date.month = p2;
  596.     date.year = p1;
  597.     break;
  598.  default: /* US Format mm/dd/yy */
  599.     date.day = p2;
  600.     date.month = p1;
  601.     date.year = p3;
  602.     break;
  603. }
  604. if (date.year >= 80 && date.year <= 99)
  605.    date.year += 1900;
  606. return !ms_setdate(&date);
  607. }
  608. /*.pa*/
  609. /*
  610.  * DEL [d:][path][filename][.ext]
  611.  *
  612.  * Erase a file(s) as specified by the path if no path is given
  613.  * erase all files on the default|specified drive.
  614.  */
  615. GLOBAL VOID CDECL cmd_del(path)
  616. BYTE *path;
  617. {
  618. erase (path, NO); /* erase files, don't confirm */
  619. }
  620. #define DIR_DIR (0x0001) /* Display Directory Files */
  621. #define DIR_SYS (0x0002) /* Display System Files    */
  622. #define DIR_ALL (0x0004) /* Display ALL Files    */
  623. #define DIR_WIDE (0x0008) /* Wide Directory Listing  */
  624. #define DIR_LONG (0x0010) /* Long Directory Listing  */
  625. #define DIR_PAGE (0x0020) /* Page Output    */
  626. #define DIR_REM (0x0040) /* Remember these Options  */
  627. #define DIR_CHANGE (0x0080) /* Change the Default Opts */
  628. #define DIR_NOPAGE (0x0100) /* No Paging of Output    */
  629. #define DIR_2COLS (0x0200) /* double column listing   */
  630. #define OPT(x) (flags & x) /* Return Flag Conditions  */
  631. MLOCAL UWORD dir_default = DIR_DIR | DIR_LONG;
  632. MLOCAL UWORD dir_flags(flags)
  633. REG UWORD flags;
  634. {
  635. if(OPT(DIR_NOPAGE)) /* Force DIR_PAGE to be cleared */
  636.     flags &= ~DIR_PAGE; /* if NOPAGE has be selected */
  637. if(OPT(DIR_LONG)) { /* Force DIR_WIDE to be cleared */
  638.     flags &= ~DIR_WIDE; /* if the LONG format has been */
  639.     flags &= ~DIR_2COLS; /* selected. */
  640. }
  641. if(OPT(DIR_2COLS)) {
  642.     flags &= ~DIR_LONG;
  643.     flags &= ~DIR_WIDE;
  644. }
  645. if(page_wid < 76) /* Check the screen is wide */
  646.     flags &= ~DIR_WIDE; /* enough to display directory */
  647.     
  648. if(page_wid < 78)
  649.     flags &= ~DIR_2COLS;
  650. if(OPT(DIR_DIR))
  651.     flags &= ~DIR_SYS;
  652. /* Check if the new options  */
  653. if(OPT((DIR_CHANGE|DIR_REM))) { /* should become the default */ 
  654.     dir_default = flags & ~(DIR_CHANGE|DIR_REM);
  655. }
  656. if (flags) return(flags);
  657. else       return(dir_default);
  658. }
  659. GLOBAL VOID CDECL cmd_dir (cmd)
  660. REG BYTE *cmd;
  661. {
  662. WORD  nfiles, system, others, i;
  663. LONG  nfree = 0L;
  664. DTA  search;
  665. BYTE  path[MAX_FILELEN];
  666. BYTE  s[MAX_PATHLEN], temp[3];
  667. BYTE  *ext, *memory;
  668. UWORD  free, secsiz, nclust;
  669. UWORD  flags;
  670. if(f_check (cmd, "dsawlprcn2", &flags, NO)) /* if any bad flags */
  671.     return; /*    don't do it   */
  672. flags = dir_flags(flags); /* Manipulate the flags to remove   */
  673. /* duplication and conflicts     */
  674. if(OPT(DIR_CHANGE)) /* Just change the default values   */
  675.     return; /* then return to the caller     */
  676. get_filename(path, deblank(cmd), YES); /* Extract the filename     */
  677. if (path[0]=='.' && path[1]=='.' && path[2]=='.' && path[3]=='')
  678. {
  679.    path[0]='*';
  680.    path[2]='';
  681. }
  682. if (d_check(path) == NULLPTR) return;/* get out now if invalid drive */
  683. if (ddrive != -1)
  684. {
  685.     strcpy(s,"d:"); s[0] = (BYTE) (ddrive + 'A');
  686.     append_slash(s);
  687.     ms_x_curdir(ddrive+1,s+3); /* get the current dir */
  688. }
  689. else
  690.     ms_x_expand(s,path);
  691. ext = fptr(path);
  692. if(*ext == '.' && strcmp(dotdot+1, ext) && strcmp(dotdot, ext)) {
  693.     strcpy(heap(), ext);
  694.     strcpy(ext, "*");
  695.     strcat(ext, heap());
  696. }
  697. #if defined(PASSWORD)
  698. *(BYTE *)heap() = ''; /* Remove the Password    */
  699. memory = strchr(ext, *pwdchar); /* if one has been used    */
  700. if(memory) { /* and save on the heap    */
  701.     strcpy(heap(), memory);
  702.     *memory = '';
  703. }
  704. #endif
  705. while(*ext && !strchr(ext, '.')) { /* If a filename has been   */
  706.     if(!iswild(ext)) { /* specified and it does not*/
  707. #if defined(PASSWORD)
  708.       if (ddrive != -1 && ms_x_chdir(s) < 0) {
  709. /* if cd to current dir fails then current dir must be password     */
  710. /* protected. So let's do the next bit the non-novell way.     */
  711. /* This method of determining if the user has specified a directory */
  712. /* DOES NOT work on NOVELL drives.     */
  713. ret = ms_x_chmod(path, 0, 0); /* contain a '.'. Skip if   */
  714. if(ret > 0 && (ret & ATTR_DIR)) /* a path was specified.    */
  715.     break; /* Otherwise append ".*".   */
  716.       }
  717.       else {
  718. #endif
  719. /* This method of determining if the user has specified a directory */
  720. /* DOES work on NOVELL drives.     */
  721. /* But not when the current directory is password protected!        */
  722. #if defined(PASSWORD)
  723. if (memory) strcpy(memory,heap());  /* reattach password */
  724. #endif
  725. if (ddrive != -1)
  726. {
  727.     ret = ms_x_chdir(path);  /* try to cd to path specified */
  728. #if defined(PASSWORD)
  729.     if (memory) *memory = 0; /* remove password again */
  730. #endif
  731.     if (ret >= 0) {  /* if there wasn't an error... */
  732. ms_x_chdir(s);  /* ...restore original directory... */
  733. break;  /* ...and get the hell out */
  734.     }
  735. }
  736. else
  737. {
  738.     ret = ms_x_chmod(path,0,0);
  739.     if (ret >= 0 && (ret & ATTR_DIR)) break; 
  740. }
  741. #if defined(PASSWORD)
  742.       }
  743. #endif
  744.     }
  745.     strcat(ext, ".*");          /* append ".*" to pathname */
  746. }
  747. #if defined(PASSWORD)
  748. strcat(ext, heap()); /* Reattach the Password    */
  749. #endif
  750. if(nofiles(path, ATTR_ALL, NO, YES))  /* if no files/dirs or error*/
  751.     return; /* then we can't do this    */
  752. if (ddrive != -1)
  753. {
  754.     strcpy (temp, "d:"); /* Display the drive Volume */
  755.     temp[0] = (BYTE) (ddrive+'A'); /* label using the VOL command */
  756.     cmd_vol(temp);
  757. }
  758. else
  759.     show_crlf(OPT(DIR_PAGE));
  760. #if 0
  761. /* this has been done earlier */
  762. strcpy(s, "d:"); s[0] = (BYTE) (ddrive + 'A');
  763. append_slash(s);
  764. ms_x_curdir(ddrive+1, s+3); /* Get the current dir */
  765. #endif
  766. strip_path(path, memory = (BYTE *)heap());/* Get the Path Spec and  */
  767. if((i = strlen(memory)) > /* Remove the Trailing      */
  768. (memory[1] == ':' ? 3 : 1)) /* Path Character.     */
  769. memory[--i] = '';
  770. if(i == 0 || (i == 2 && memory[1] == ':')) {
  771.     printf (MSG_DIR, temp, s+3); /* DIR of current Directory  */
  772. }
  773. else
  774. {
  775.   if (ddrive == -1 || ms_x_chdir(s) < 0) { /* assume this means pword protected */
  776.     ext = memory+strlen(memory)+1;
  777.     ms_x_expand(ext,memory);
  778.     if (ddrive != -1)
  779.       printf(MSG_DIR, temp, ext+3);
  780.     else
  781.       printf(MSG_DIR,"",ext+1);
  782.   }
  783.   else {
  784.     ms_x_chdir(memory);  /* Change the directory      */
  785.     ms_x_curdir(ddrive+1, memory); /* Get the current directory */
  786.     ms_x_chdir(s); /* Restore the directory     */
  787.     printf (MSG_DIR, temp, memory);
  788.   }
  789. }
  790. others = 0; /* assume no SYS/DIR files */
  791. nfiles = 0; /* initialize file count */
  792. linesleft = page_len - 4; /* lines until pause */
  793. system = OPT(DIR_SYS) ? ATTR_SYS : 0;
  794. ret = ms_x_first(path, ATTR_ALL, &search);
  795. if(!ret && (search.fattr & ATTR_DEV)) /* Check if the user has     */
  796.     ret = ED_FILE; /* specified a device then   */
  797. /* generate an error.      */
  798. while(!ret) {
  799.     if(!OPT(DIR_ALL) && (search.fattr & ATTR_SYS) != system) {
  800. /* not the correct file type*/
  801. others++; /* remember others do exist */
  802. ret = ms_x_next(&search); /* get the next file and    */
  803. continue; /* continue the display     */
  804.     }
  805.     ext = strchr(search.fname, '.'); /* Get the file extension   */
  806.     if(ext && ext != search.fname) /* set the extension to NULL*/
  807. *ext++ = ''; /* if no '.' exists or this */
  808.     else /* is the ".." or "." entry.*/
  809. ext = "";
  810.     if(OPT(DIR_WIDE)) {
  811. if ((nfiles % 5) == 0)
  812.     show_crlf(OPT(DIR_PAGE));
  813. printf ("%c:%c%-9s%-3s",
  814. (nfiles % 5) ? ' ' : ddrive + 'A',
  815. (search.fattr & ATTR_DIR) ? *pathchar : ' ',
  816. search.fname, ext);
  817.     }
  818.     else {
  819. if (OPT(DIR_2COLS)) {
  820.     if ((nfiles % 2) == 0) show_crlf(OPT(DIR_PAGE));
  821. }
  822. else
  823.     show_crlf(OPT(DIR_PAGE));
  824. printf("%-9s%-3s", search.fname, ext);
  825. if (search.fattr & ATTR_DIR)
  826.     printf(" <DIR>   ");
  827. else
  828.     printf ("%9lu", search.fsize);
  829. if(search.fdate) {    /* if timestamp exists */
  830.     printf (" "); disp_filedate (search.fdate);
  831.     printf (" "); disp_filetime (search.ftime);
  832.     if ((OPT(DIR_2COLS)) && (nfiles%2 == 0)) printf ("   ");
  833. }
  834. else {
  835.     if ((OPT(DIR_2COLS)) && (nfiles%2 == 0)) printf("ttt");
  836. }
  837.     }
  838.     nfiles ++;
  839.     ret = ms_x_next(&search);
  840. }
  841. if(others + nfiles == 0) { /* If no matching files then exit  */
  842.     e_check(ED_FILE); /* after displaying File Not Found */
  843. }
  844. if(ddrive != -1 && (ret = ms_drv_space(ddrive+1, &free, &secsiz, &nclust)) < 0) {
  845.     /*e_check(ED_PATH);*/
  846.     /*return;*/
  847.     ret = 0; /* This prevents 'Invalid directory...' when looking */
  848.      /* at a PNW login drive. */
  849. }
  850. show_crlf(OPT(DIR_PAGE));
  851. nfree = (LONG)ret * (LONG)free * (LONG)secsiz;
  852. if (ddrive != -1)
  853.     printf ("%9d %s%10ld %s", nfiles, MSG_FILES, nfree, MSG_FREE);
  854. else
  855.     printf ("%9d %s", nfiles, MSG_FILES);
  856. show_crlf(OPT(DIR_PAGE));
  857. if(others) /* if others do exist, tell them */
  858.     printf (MSG_EXIST, system ? MSG_NSYS : MSG_NDIR);
  859. }
  860. GLOBAL VOID CDECL cmd_echo(s, o)
  861. REG BYTE *s; /* Deblanked Command Line */
  862. REG BYTE *o; /* Original Untainted Commmand */
  863. {
  864. if (*o) o++; /* delete 1 whitespace or   */
  865. /* punctuation char from the*/
  866. /* original command line    */
  867. s = deblank(s);
  868. switch(onoff(s)) { /* if "ECHO=on/off"     */
  869.     case YES: /* ECHO = ON     */
  870. echoflg = ECHO_ON;
  871. break;
  872.     case NO: /* ECHO = OFF     */
  873. echoflg = ECHO_OFF;
  874. break;
  875.     default:
  876. if(*s || (o != s && batchflg)) { /* if command line   */
  877.     puts(o); /* display string    */
  878.          crlf();
  879. }
  880. else
  881.          printf (MSG_ECHO, /* print current     */
  882.      echoflg ? MSG_ON : MSG_OFF); /* echo status      */
  883. break;
  884. }
  885. }
  886. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  887. /*RG-02-*/
  888. GLOBAL VOID CDECL cmd_echoerr(s, o)
  889. REG BYTE *s; /* Deblanked Command Line */
  890. REG BYTE *o; /* Original Untainted Commmand */
  891. {
  892.         BOOLEAN  err_save;
  893.         err_save=err_flag;
  894. err_flag = TRUE;
  895.         cmd_echo(s,o);
  896. err_flag = err_save;
  897. }
  898. #endif
  899. /*RG-02-end*/
  900. GLOBAL VOID CDECL cmd_exit(cmd)
  901. BYTE *cmd;
  902. {
  903. err_ret = 0;
  904. if(*deblank(cmd)) /* If a number has be     */
  905.     check_num(cmd, 0, 255, &err_ret); /* specified use this for  */
  906.      /* the exit code.    */
  907. if(batchflg) { /* If processing a batch file     */
  908.     batch_end(); /* then exit batch file      */
  909. #if defined(CDOSTMP)
  910.     return;
  911. #endif
  912. }
  913. #if defined(CDOSTMP)      
  914. bdos(C_DETACH, 0); /* Allow another process to attach */
  915. bdos(P_DISPATCH, 0); /* to the console if they are    */
  916. bdos(C_ATTACH, 0); /* waiting in the background.    */
  917. #else
  918. if(execed) { /* If command.com has been execed   */
  919.     *parent_psp = save_parent;
  920.     ms_set_break(break_flag); /* then return to the invoking prog */
  921.      /* Otherwise ignore the command     */
  922. #if defined(CPM) /* Clean-Up the CPM disk handling   */
  923.     cpm_de_init(); /* code before we terminate.     */
  924. #endif
  925.     restore_error_mode();
  926.     restore_term_addr(); /* restore the PSP terminate address*/
  927.     ms_x_exit(err_ret); /* If we return from the EXIT call  */
  928.     execed = NO; /* then this must be the root     */
  929.     printf("Hellon");
  930. } /* process. Invoked without '/P'    */
  931. #endif
  932. }
  933. GLOBAL VOID CDECL cmd_md(s)
  934. REG BYTE *s;
  935. {
  936. /*BYTE  path[MAX_FILELEN];*/
  937. crlfflg = YES;
  938. #if 0
  939. get_filename(path, deblank(s), FALSE); /* Pathname  */
  940. if(!d_check(path))
  941.     return;
  942. #endif
  943. if((ret = ms_x_mkdir(s)) != 0) { /* if any errors occurred    */
  944.     if (ret == ED_DRIVE) /* if invalid drive      */
  945. e_check(ret); /*    then say so      */
  946.     else /* else use standard formula */
  947. eprintf(MSG_MKDIR); /* Unable to create directory*/
  948.     return;
  949. }
  950. crlfflg = NO;
  951. }
  952. /*.pa*/
  953. /*
  954.  * PATH [[d:]path[[;[d:]path]..]] | [;]
  955.  *
  956.  * Display or set the command search path in environment.
  957.  */
  958. GLOBAL BYTE msg_patheq [] = "PATH="; /* Static Environment String   */
  959. GLOBAL VOID CDECL cmd_path(path)
  960. REG BYTE *path;
  961. {
  962. REG BYTE *s;
  963. #if !STACK
  964. BYTE  sbuf[MAX_ENVLEN];
  965. #endif
  966. zap_spaces(path); /* Remove all white space     */
  967. if(!*path) {
  968.     if(env_scan(msg_patheq, s = (BYTE *)heap()))
  969. printf(MSG_PATH); /* If no path exists then    */
  970.     else { /* display "NO PATH" otherwise */
  971. printf(msg_patheq); /* display the current path  */
  972. /*printf("%.122sn",s);*/
  973. printf(path_template,s);
  974.     }
  975.     crlfflg = YES;
  976.     return;
  977. }
  978. if(*path == '=' || *path == ';')/* Skip Leading '=' or ';' chars    */
  979.     path++; /* then set the PATH     */
  980. #if STACK
  981. s = stack(strlen(msg_patheq) + strlen(path) + 1);
  982. #else
  983. s = &sbuf[0];
  984. #endif
  985. strcpy(s, msg_patheq); /* build command line for "SET"   */
  986. strcat(s, strupr(path));
  987. cmd_set(s);  /* set new path using "SET"     */
  988. }
  989. GLOBAL VOID CDECL cmd_pause(msg)
  990. BYTE *msg;
  991. {
  992. BYTE c;
  993. if (*msg) printf("%sn",msg);
  994. batch_close(); /* Close Any Batch files in case */
  995. /* the user is going to swap the */
  996. /* disk with the batch file.  */
  997. printf(MSG_PAUSE); /* prompt to hit any key */
  998. #if defined(CDOSTMP)
  999. c =(BYTE) bdos(C_RAWIO, 0xFD); /* Get a character from console */
  1000. if ((c==0) ||(dbcs_lead(c)))
  1001.     bdos(C_RAWIO, 0xFD); /* skip second byte in DBCS pair */
  1002. #else
  1003. c = (BYTE) msdos(MS_C_RAWIN, 0);/* Get a character from console */
  1004. if ((c==0) || (dbcs_lead(c)))
  1005.     msdos(MS_C_RAWIN, 0); /* skip second byte in DBCS pair */
  1006. #endif
  1007. sprintf(heap(), "%s", MSG_PAUSE); /* Copy MSG_PAUSE into  */
  1008. printf("r%*sr", strlen(heap()), "");  /* Data Segment and  */
  1009. /* then calculate length*/
  1010. if(c == 0x03) /* Control C Check */
  1011.     int_break();
  1012. }
  1013. /*
  1014.  * This PAUSE command will output the prompt string to STDOUT regardless
  1015.  * of its destination. However it will ensure that the character is read
  1016.  * from the console device by "POKING" the PSP.
  1017.  */
  1018. GLOBAL VOID CDECL cmd_stdin_pause(void)
  1019. {
  1020. UWORD in_h,stderr_h;
  1021. BYTE c;
  1022. batch_close(); /* Close Any Batch files in case */
  1023. /* the user is going to swap the */
  1024. /* disk with the batch file.  */
  1025. printf(MSG_PAUSE); /* prompt to hit any key */
  1026. stderr_h = psp_poke(STDERR,1);
  1027. in_h = psp_poke(STDIN, stderr_h); /* Get the Real Console */
  1028. psp_poke(STDERR,stderr_h);
  1029. #if defined(CDOSTMP)
  1030. c =(BYTE) bdos(C_RAWIO, 0xFD); /* Get a character from console */
  1031. if ((c==0) ||(dbcs_lead(c)))
  1032.     bdos(C_RAWIO, 0xFD); /* skip second byte in DBCS pair */
  1033. #else
  1034. c = (BYTE) msdos(MS_C_RAWIN, 0);/* Get a character from console */
  1035. if ((c==0) || (dbcs_lead(c)))
  1036.     msdos(MS_C_RAWIN, 0); /* skip second byte in DBCS pair */
  1037. #endif
  1038. psp_poke(STDIN, in_h); /* restore original handle  */
  1039. sprintf(heap(), "%s", MSG_PAUSE); /* Copy MSG_PAUSE into  */
  1040. printf("r%*sr", strlen(heap()), "");  /* Data Segment and  */
  1041. /* then calculate length*/
  1042. if(c == 0x03) /* Control C Check */
  1043.     int_break();
  1044. }
  1045. #if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
  1046. /*
  1047.  * The PAUSE command will output the prompt string to STDOUT regardless
  1048.  * of its destination. However it will ensure that the character is read
  1049.  * from the console device by "POKING" the PSP.
  1050.  */
  1051. GLOBAL VOID CDECL cmd_pauseerr()
  1052. {
  1053.         BOOLEAN  err_save;
  1054.         err_save=err_flag;
  1055. err_flag = TRUE;
  1056.         cmd_pause();
  1057. err_flag = err_save;
  1058. }
  1059. #endif
  1060. /*RG-02-end*/
  1061. /*.pa*/
  1062. /*
  1063.  * PROMPT [prompt-text]
  1064.  *
  1065.  * Set the system prompt as specified by the prompt text if no 
  1066.  * prompt text is specified then the default $n$g is used.
  1067.  */
  1068. GLOBAL BYTE msg_prmeq  [] = "PROMPT="; /* Static Environment String */
  1069. GLOBAL VOID CDECL cmd_prompt(s)
  1070. REG BYTE    *s;
  1071. {
  1072. REG BYTE *bp;
  1073. #if !STACK
  1074. BYTE  bpbuf[MAX_ENVLEN];
  1075. #endif
  1076. if (!*s) /* if no string */
  1077.     s = DEFAULT_PROMPT;  /* use the default */
  1078. while ((*s == '=') || (*s == ' ')) s++;
  1079. #if STACK
  1080. bp = stack(strlen(msg_prmeq) + strlen(s) + 1);
  1081. #else
  1082. bp = &bpbuf[0];
  1083. #endif
  1084. strcpy(bp, msg_prmeq); /* environment variable */
  1085. strcat(bp, s); /* add new value */
  1086. cmd_set(bp); /* update environment */
  1087. }
  1088. GLOBAL VOID CDECL cmd_rem ()
  1089. {
  1090. crlfflg = 0;
  1091. /* Make sure REM turns off pipes too */
  1092. /* You can't do this !!!!! MSDOS allows "REM | DIR" etc - IJ */
  1093. #if 0
  1094. pipe_in=pipe_out=NO;
  1095. #endif
  1096. }
  1097. #define REN_CHECK (flags & 1)
  1098. GLOBAL VOID CDECL cmd_ren(s)
  1099. REG BYTE *s;
  1100. {
  1101. BYTE  srcfile[MAX_FILELEN], dstfile[MAX_FILELEN];
  1102. BYTE  pattern[MAX_FILELEN-MAX_PATHLEN];  
  1103. BYTE  *enddir;
  1104. #if defined(PASSWORD)
  1105. BYTE *password;
  1106. #endif
  1107. DTA  search;
  1108. UWORD flags;
  1109. WORD attr;
  1110. #if !STACK
  1111. BYTE passbuf[MAX_FILELEN];
  1112. #endif
  1113.         char lastchar;
  1114.         unsigned length;
  1115. if(f_check(s, "c", &flags, NO)) /* Check the selected flags */
  1116.     return; /* and return on error     */
  1117. s = get_filename(srcfile, deblank(s), TRUE); /* Source Filename  */
  1118. s = get_filename(dstfile, deblank(s), TRUE); /* Destination File */
  1119. length = strlen(dstfile);
  1120. lastchar = dstfile[ length-1];
  1121.         
  1122. if (dbcs_expected()){
  1123.  if ( (length > 2) && (!dbcs_lead(dstfile[length-2])) ){
  1124. /*
  1125. if ( (lastchar == ':') || (lastchar == '\') ){
  1126. */
  1127. if (lastchar == ':'){
  1128. printf(msg_invalid_file);
  1129. return;
  1130. }
  1131.  }
  1132. }
  1133. else{
  1134. /*
  1135. if ( (lastchar == ':') || (lastchar == '\') ){
  1136. */
  1137. if (lastchar == ':'){
  1138. printf(msg_invalid_file);
  1139. return;
  1140.     }
  1141. }
  1142. if (!iswild(srcfile)) {
  1143.     attr = ms_x_chmod(srcfile,0,0);
  1144.     if ((attr > 0) && (attr & ATTR_DIR)) {
  1145. /* Don't try to rename directories. Leave it to RENDIR. */
  1146. printf(MSG_USE_RENDIR);
  1147. return;
  1148.     }
  1149. }
  1150. if(nofiles(srcfile, ATTR_ALL, YES, NO)) /* if no source files then  */
  1151.     return; /* error message and stop   */
  1152. if(nofiles(dstfile, ATTR_ALL, NO, NO)) /* Check the Destination    */
  1153.     return; /* path exists     */
  1154. if(fptr(srcfile) != srcfile && fptr(dstfile) == dstfile) {
  1155.     strcpy(heap(), dstfile); /* If no path is specified  */
  1156.     strip_path(srcfile, dstfile); /* on the NewFile then force*/
  1157.     strcat(dstfile, heap()); /* use the OldFile Path.    */
  1158. /* Because of the Holy Grail*/
  1159. } /* of MS-DOS compatiblity.  */
  1160. enddir = fptr(srcfile);  /* Isolate source filename  */
  1161. #if defined(PASSWORD)
  1162. password = strchr(enddir, *pwdchar); /* Check for Source password*/
  1163. if(password) { /* and save in internal buf.*/
  1164. #if STACK
  1165.     password = stack(strlen(password)+1);
  1166. #else
  1167.     password = &passbuf[0];
  1168. #endif
  1169.     strcpy(password, strchr(enddir, *pwdchar));
  1170. }
  1171. #endif
  1172. strcpy(pattern, fptr(dstfile));  /* Save the destination     */
  1173. /* match pattern.     */
  1174. ms_x_first (srcfile, (ATTR_STD&(~ATTR_SYS)), &search);
  1175. do {
  1176.     strcpy(enddir, search.fname); /* append file name to path */
  1177.     if(REN_CHECK) { /* confirm option active?   */
  1178. printf(MSG_ERAQ, srcfile); /* then prompt the user and */
  1179. if(!yes(YES, NO)) /* act on the reponse     */
  1180.     continue;
  1181.     }
  1182.     strcpy(fptr(dstfile), pattern); /* Assert the Destination   */
  1183.     repwild(srcfile, dstfile); /* pattern.     */
  1184. #if defined(PASSWORD)
  1185.     if(password) /* Append the password to   */
  1186. strcat(srcfile, password); /* the sorce file if one    */
  1187. /* has been specified.     */
  1188. #endif
  1189.     if((ret = ms_x_rename(srcfile, dstfile)) < 0) {
  1190. crlfflg = YES;
  1191. #if defined(CDOSTMP) || defined(CDOS)
  1192. if((ret == ED_ACCESS) &&
  1193.    (ms_x_first(dstfile, ATTR_ALL, &search) >= 0))
  1194. #else
  1195. if(ret == ED_ACCESS)
  1196. #endif
  1197.     eprintf(MSG_REN);
  1198. else
  1199.     e_check(ret);
  1200. return;
  1201.     }
  1202. } while(!ms_x_next(&search)); /* get the next file */
  1203. }
  1204. /*.pa*/
  1205. /*
  1206.  *
  1207.  */
  1208. GLOBAL VOID CDECL cmd_rd(s)
  1209. REG BYTE *s;
  1210. {
  1211. /*BYTE  path[MAX_FILELEN];*/
  1212. crlfflg = YES;
  1213. #if 0
  1214. get_filename(path, deblank(s), FALSE); /* Pathname  */
  1215. if(!d_check(path))
  1216.     return;
  1217. #endif
  1218. if((ret = ms_x_rmdir(s)) != 0) { /* if can't remove directory */
  1219.     if(ret == ED_DIR || ret == ED_FILE || ret == ED_ACCESS)
  1220.      /* because its in use by     */
  1221. eprintf(MSG_RMDIR); /* by another process or is  */
  1222.     else /* empty then print special  */
  1223. e_check(ret); /* message other wise use    */
  1224.     return; /* standard error handler    */
  1225. }
  1226. crlfflg = NO;
  1227. }
  1228. GLOBAL VOID CDECL cmd_set(s)
  1229. BYTE *s;
  1230. {
  1231. BYTE  c;
  1232. REG BYTE *key;
  1233. BYTE *t;
  1234. WORD  i;
  1235. if(!*s) { /* if no cmd, display env */
  1236.     for(i=0; !env_entry(key = (BYTE *)heap(), i); i++) {
  1237.         puts(key); /* Print the Environment   */
  1238. crlf(); /* variables directly to   */
  1239.     } /* avoid size problems.    */
  1240.     return;
  1241. }
  1242. /* else need to set env var */
  1243. /* msdos removes leading blanks, commas, semicolons and equal signs,
  1244. but keeps spaces in the variable name (SPR 770044) JBM */
  1245. /* remove any spaces before the equals sign
  1246. key = s;
  1247. while (*s && (*s != '=')) {
  1248. if (*s == 32 || *s == 9) {
  1249. t = s;
  1250. while (*t++) *(t-1) = *t;
  1251. }
  1252. if (*s == '=') break;
  1253. s++;
  1254. }
  1255. */
  1256. key = s;
  1257. while (*s && (*s == 0x20 || *s == 0x09 || *s == ',' || *s == ';' || *s == '=')) {
  1258. t = s;
  1259. while (*t++) *(t-1) = *t;
  1260. }
  1261. s = key;
  1262. while (*s && (*s != '=')) /* look for end of variable */
  1263.     s ++;
  1264. if (!*s || key == s) { /* If no key has been specified */
  1265.     syntax(); /* or the '=' is missing return */
  1266.     return;
  1267. } /* a syntax error. */
  1268. s++;
  1269. #if 0
  1270. /* msdos doesn't do this */
  1271. /* remove any space after the equals sign */
  1272. while (*s == 32 || *s == 9) {
  1273. t = s;
  1274. while (*t++) *(t-1) = *t;
  1275. }
  1276. #endif
  1277. c = *s; /* Save Character */
  1278. *s = ''; /* terminate keyword */
  1279. strupr (key); /* make keyword upper case  */
  1280. if(env_del(key) < 0) { /* remove it first */
  1281.     printf(MSG_ENVERR);  /* check for an error. */
  1282.     crlfflg = YES;
  1283.     return;
  1284. }
  1285. if((*s-- = c) != 0) { /* Add the definition to the end*/
  1286. /* of the environment if the new*/
  1287.     if(env_ins(key)) { /* definition is not NULL */
  1288. printf(MSG_ENVFULL); /* check for an error. */
  1289. crlfflg = YES;
  1290. return;
  1291.     }
  1292. }
  1293. }
  1294. /*.pa*/
  1295. /*
  1296.  * Displays or Sets the current system time 
  1297.  */
  1298. #define TIME_CON (flags & 1)
  1299. GLOBAL VOID CDECL cmd_time(s)
  1300. REG BYTE *s;
  1301. {
  1302. BYTE buffer[18]; /* Local Input Buffer */
  1303. UWORD flags; /* Continuous Display */
  1304. if(f_check (s, "c", &flags, NO)) /* Check for valid Flags    */
  1305.     return;
  1306. if(TIME_CON) {
  1307.     crlfflg = YES;
  1308.     printf(CUR_TIME); /* Display the Message */ 
  1309.     FOREVER {
  1310. disp_systime (); /* Display the Current Time  */
  1311. printf("bbbbbbbbbbb"); /* BackSpace over the Time */
  1312. #if defined(CDOSTMP)
  1313. if(bdos(C_RAWIO, 0xFE))  /* check for a character     */
  1314.     return; /* and return if one typed   */
  1315. #else
  1316. if(msdos(MS_C_STAT, 0) & 0xFF) { /*  Check for a character   */
  1317.     msdos(MS_C_RAWIN, 0xFF);  /* read it and return to the*/
  1318.     return;  /* main routine.      */
  1319. }
  1320. #endif
  1321.     }
  1322. }
  1323. if(*s) {
  1324.     if (check_time(s))
  1325. return;
  1326.     printf(INV_TIME);
  1327. }
  1328. else {
  1329.     printf(CUR_TIME);
  1330.     disp_systime ();
  1331. }
  1332. FOREVER {
  1333.     printf (NEW_TIME);
  1334.     buffer[0] = sizeof(buffer)-2; /* Set maximum string length */
  1335.     system(MS_C_READSTR, buffer);
  1336.     crlf ();
  1337.     if (!buffer[1]) /* Check for 0 length input */
  1338. return;  /* and return if so */
  1339.     buffer[buffer[1]+2] = '';
  1340.     if (check_time (buffer+2))
  1341. return;
  1342.     printf (INV_TIME);
  1343. }
  1344. }
  1345. /*.pa*/
  1346. /*
  1347.  *
  1348.  */
  1349. GLOBAL VOID CDECL cmd_truename(s)
  1350. REG BYTE *s;
  1351. {
  1352. BYTE  path[MAX_FILELEN];
  1353. *path = 0;
  1354. /* expand path, current directory if none specified */
  1355. if (*s)
  1356. ret = ms_x_expand(path, s);
  1357. else
  1358. ret = ms_x_expand(path, ".");
  1359. /* if we get an error report it, otherwise display expanded path */
  1360. if (ret)
  1361. e_check(ret);
  1362. else
  1363. printf(path);
  1364. }
  1365. /*
  1366.  * Parse the string pointed to by s and check for a valid date
  1367.  * specification. If the time has been specified correctly then
  1368.  * set the system time.
  1369.  */
  1370. MLOCAL BYTE    hour_sep[] = ":.";
  1371. MLOCAL BYTE    sec_sep[]  = ".,";
  1372. MLOCAL BOOLEAN check_time(s)
  1373. BYTE *s;
  1374. {
  1375. SYSTIME time;
  1376. WORD hour, min, sec, hsec;
  1377. min = sec = hsec = 0; /* Seconds and Hundredths are optional */
  1378. /* and default to zero when omitted */
  1379. zap_spaces(s); /* Remove all spaces from command   */
  1380. if (!getdigit (&hour, &s))
  1381.     return NO;
  1382. while(*s) { /* if more than HH */
  1383.     if (!strchr(hour_sep,*s)) return NO; /* Check for Minute */
  1384.     s++;
  1385.     if (!getdigit (&min, &s)) return NO;
  1386.     if (!*s) break;
  1387.     
  1388.     if (!strchr(hour_sep,*s)) break; /* Check for Seconds */
  1389.     s++;
  1390.     if (!getdigit (&sec, &s)) break;
  1391.     if (!*s) break;
  1392.     
  1393.     if (!strchr(sec_sep,*s)) break;
  1394.     s++;
  1395.     if (!getdigit (&hsec, &s)) break;
  1396.     break;
  1397. }
  1398. if (*s) {
  1399.     *s = toupper(*s);
  1400.     if (*s == 'P' && hour != 12) hour += 12;
  1401.             if (*s == 'A' && hour == 12) hour = 0;
  1402. }
  1403. time.hour = hour;
  1404. time.min  = min;
  1405. time.sec  = sec;
  1406. time.hsec = hsec;
  1407. return !ms_settime(&time);
  1408. }
  1409. #define BUFSIZE 256 /* SHOW_FILE buffer size */
  1410. MLOCAL VOID show_crlf(paging)
  1411. BOOLEAN paging;
  1412. {
  1413. crlf();
  1414. if(paging && (--linesleft == 0)) {
  1415.     cmd_pause("");
  1416.     linesleft = page_len - 1;
  1417. }
  1418. }
  1419. /*
  1420.  * Read from channel h until the first Control-Z or the endof file
  1421.  * has been reached. The display is paged if the PAGE_MODE flag is
  1422.  * true otherwise the information is displayed continuous using
  1423.  * the standard flow control.
  1424.  */
  1425. /*RG-00-make this one public*/
  1426. /* MLOCAL VOID show_file(h, paging) */
  1427. VOID show_file(h, paging)
  1428. /*RG-00-end*/
  1429. UWORD h; /* Channel for File access */
  1430. BOOLEAN paging;  /* Page Mode Flag    */
  1431. {
  1432. BYTE FAR *cp; /* pointer to end of path   */
  1433. BYTE FAR *ptr; /* temporary address for printing */
  1434. BYTE FAR *buf; /* Input Buffer    */
  1435. UWORD bufsize;
  1436. WORD  n;
  1437. /*BOOLEAN  lfflg = NO;*/ /* Last character a LineFeed   */
  1438. BOOLEAN  eof = FALSE; /* End of File Flag   */
  1439. UWORD scr_width;
  1440. UWORD nchars    = 0;
  1441. UWORD stderr_h,in_h;
  1442. scr_width = get_scr_width();
  1443. mem_alloc(&show_file_buf,&bufsize,BUFSIZE,BUFSIZE);
  1444. buf = show_file_buf;
  1445. while (!eof && (n = far_read (h, buf, BUFSIZE)) > 0) {
  1446.     cp = ptr = buf;
  1447.     while (n) {  /* while more data */
  1448. while (n && /* while more data */
  1449.       (*cp != 0x1a) && /* and not EOF Char */
  1450.       (*cp != 'n') && /* and Linefeed Char */
  1451.       (nchars<scr_width)) {     
  1452. if (*cp == 9) nchars = (nchars&-8)+7;
  1453. n--; cp++; nchars++; /* count chars, next */
  1454. }
  1455. if (cp != ptr) { /* if any ordinary data */
  1456.     far_write(STDOUT, ptr, (UWORD) (cp-ptr));
  1457.      /* write to CON:        */
  1458.     ptr = cp; /* flush the rest */
  1459.     /*lfflg = NO;*/
  1460. }
  1461. if(n == 0) /* if end of data */
  1462.     break;
  1463. if(*cp == 0x1a) { /* If ^Z then set */
  1464.     eof = TRUE;  /* EOF flag to TRUE */
  1465.     break; /* and stop printing */
  1466. }
  1467. if (*cp == 'n') {
  1468.     ms_x_write(STDOUT,"n",1); /* Display a LF */
  1469.     /*lfflg = YES;*/ /* Set the LineFeed Flag*/
  1470.     n--; /* count LF */
  1471.     ptr = ++cp; /* point past it */
  1472. }
  1473.         if(paging && (--linesleft == 0)) {
  1474.     cmd_stdin_pause();
  1475.     linesleft = page_len - 1;
  1476. }
  1477.         nchars = 0;
  1478.     }
  1479. }
  1480. mem_free(&show_file_buf);
  1481. }
  1482. /*.pa*/
  1483. /*
  1484.  *
  1485.  */
  1486. #define TYPE_PAGE (flags & 1)
  1487. GLOBAL VOID CDECL cmd_type(cmd)
  1488. REG BYTE *cmd;
  1489. {
  1490. WORD  ret, h; /* file handle   */
  1491. BYTE path[MAX_FILELEN]; /* Path and File Name   */
  1492. BYTE *files; /* pointer to file spec    */
  1493. #if defined(PASSWORD)
  1494. BYTE *password;
  1495. #endif
  1496. DTA search;  /* Local Search Buffer   */
  1497. UWORD flags; /* only one switch permitted   */
  1498. BOOLEAN wild_flag = FALSE; /* Wild Card Type   */
  1499. BYTE passbuf[MAX_FILELEN];
  1500. if(f_check(cmd, "p", &flags, NO))       /* if any bad flags */
  1501.     return; /*    don't do it */
  1502. get_filename(path, deblank(cmd), YES); /* Extract the Filename     */
  1503. if(d_check(path) == NULLPTR) /* Check if the specified   */
  1504.     return; /* drive is valid     */
  1505. files = fptr(path); /* isolate the filename     */
  1506. #if defined(PASSWORD)
  1507. password = strchr(files, *pwdchar); /* Check for Source password*/
  1508. if(password) { /* and save in internal buf.*/
  1509.     strcpy(passbuf, password);
  1510.     *password = 0; /* discard path password */
  1511.     password = &passbuf[0]; /* and use local copy */
  1512. }
  1513. #endif
  1514. if(iswild(files))
  1515.     wild_flag = TRUE;
  1516. linesleft = page_len - 1; /* Initialize the paging     */
  1517. /* variable used by SHOW_?   */
  1518. /*
  1519.  * For wild card searches we must initialise search.fname
  1520.  * with an initial ms_x_first for the DO/WHILE loop.
  1521.  */
  1522. if (wild_flag) {
  1523.     search.fattr = ATTR_STD;
  1524.     ret = ms_x_first(path, ATTR_STD, &search);
  1525.     if (ret < 0) {
  1526.      e_check(ret); /* if we can't find anything */
  1527. return; /* we'd better say so */
  1528.     }
  1529. }
  1530. do {
  1531.     if (wild_flag)
  1532. strcpy(files, search.fname);   /* make it full pathname     */
  1533.     strcpy(heap(), path);
  1534. #if defined(PASSWORD)
  1535.     if(password)
  1536.         strcat(heap(), password);
  1537. #endif
  1538.     h = ms_x_open(heap(), OPEN_READ); /* Open file in sharing mode */
  1539.     if(h == ED_SHAREFAIL || h == ED_ACCESS) /* if fails with a   */
  1540.         h = ms_x_open(heap(), 0); /* sharing violation then try*/
  1541. /* opening with compatibilty */
  1542.     if(h < 0) { /* mode.      */
  1543. e_check(h);
  1544. return;
  1545.     }
  1546.     if (wild_flag) { /* if wild card type */
  1547. strupr(path); /* Display UpperCase Filename */
  1548. show_crlf(TYPE_PAGE); /* Print a CRLF with PAGING flag*/
  1549. revon(); printf ("%s:", path); revoff();
  1550. show_crlf(TYPE_PAGE); /* Print a CRLF with PAGING flag*/
  1551.     }
  1552.     show_file(h, TYPE_PAGE); /* Output the File to the Screen */
  1553.     ms_x_close(h); /* Close the File */
  1554. } while (wild_flag && (ms_x_next(&search) >= 0));
  1555. }
  1556. /*
  1557.  * Displays the data read from Channel 0 until the end of file or 
  1558.  * Control-Z. If no output redirection is inforce then MORE pages
  1559.  * the display using the CMD_PAUSE function.
  1560.  *
  1561.  * MORE will only enable PAGING if the output device is the CONSOLE
  1562.  * otherwise paging is disabled.
  1563.  */
  1564. GLOBAL VOID CDECL cmd_more()
  1565. {
  1566. linesleft = page_len -1; /* Set the Page length and */
  1567. show_file(STDIN, YES); /* display STDIN till EOF  */
  1568. /* or a Control-Z    */
  1569. }
  1570. /*.pa*/
  1571. /*
  1572.  *
  1573.  */
  1574. GLOBAL VOID CDECL cmd_ver()
  1575. {
  1576. printf(MSG_VERSION, (env_scan("VER=", heap()) ? "" : heap()));
  1577. printf(MSG_CPYRIGHT);
  1578. #if !defined(FINAL)
  1579. if(!env_scan("BETA=", heap()))
  1580.     printf("%sn", heap());
  1581. #endif
  1582. }
  1583. GLOBAL VOID CDECL cmd_vol(path)
  1584. BYTE *path;
  1585. {
  1586. BYTE *s;
  1587. BYTE temp[7];
  1588. DTA search;
  1589. WORD ret,i;
  1590. BYTE label[12];
  1591. strcpy(temp,d_slash_stardotstar);
  1592. if ((path = d_check(path)) == 0)
  1593.     return;
  1594. if (ddrive == -1) return;
  1595. temp[0] = (BYTE) (ddrive+'A');
  1596. ret = ms_x_first(temp, ATTR_LBL, &search);
  1597. if (ret == ED_DRIVE)
  1598.     e_check(ret); /* display error if invalid drive */
  1599. else {
  1600.     printf(MSG_LBL, ddrive+'A');
  1601.     if (ret)
  1602. printf(MSG_NOLBL);
  1603.     else {
  1604. s = search.fname;
  1605. for (i = 0; *s && (i < 8); i++)
  1606.     label[i] = (*s == '.') ? ' ' : *s++;
  1607. if (*s == '.') s++;       /* if there was a '.' skip it */
  1608. for (; *s && (i < 11); ) label[i++] = *s++; /* copy the rest */
  1609. label[i] = '';         /* null terminate label */
  1610. printf(MSG_OKLBL, label);
  1611.     }
  1612.     crlf();
  1613. }
  1614. }
  1615. /*.pa*/
  1616. /*
  1617.  *
  1618.  */
  1619. GLOBAL VOID CDECL cmd_delq(path)   /* erase files with query */
  1620. BYTE *path;
  1621. {
  1622. erase (path, YES); /* erase files, confirm deletes */
  1623. }
  1624. EXTERN BYTE FAR * CDECL farptr(BYTE *);
  1625. #define YES_CHAR (*farptr(YES_NO+0))
  1626. #define NO_CHAR (*farptr(YES_NO+1))
  1627. #define ERASE_CONFIRM (flags & 3)
  1628. #define ERASE_SYS (flags & 4)
  1629. MLOCAL VOID erase(s, confirm)
  1630. BYTE *s;
  1631. BOOLEAN  confirm;
  1632. {
  1633. BYTE path[MAX_FILELEN]; /* FileName Buffer     */
  1634. BYTE answer[20]; /* Yes/No string     */
  1635. BYTE  *files; /* pointer to file spec     */
  1636. #if defined(PASSWORD)
  1637. BYTE *password;
  1638. #endif
  1639. UWORD flags; /* only one switch permitted*/
  1640. DTA search;  /* Local Search Buffer     */
  1641. UWORD attr; /* Erase Search Attributes  */
  1642. #if !STACK
  1643. BYTE passbuf[MAX_FILELEN];
  1644. #endif
  1645. #if !(defined (CDOSTMP))
  1646. BYTE savepath[MAX_PATHLEN+1];
  1647. BYTE newpath[MAX_PATHLEN+2]; /* including trailing      */
  1648. BYTE fcb[37];
  1649. WORD ret;
  1650. WORD i;
  1651. #endif
  1652. if(f_check(s, "cps", &flags, NO))      /* if any bad flags return  */
  1653.     return;
  1654. get_filename(path, s, YES); /* Extract the Filename     */
  1655. if(strlen(path) == 0) { /* and check for 0 length   */
  1656.     printf(MSG_NEEDFILE); /* path caused by invalid   */
  1657.     crlfflg = YES; /* filename characters in   */
  1658.     return; /* the command line.     */
  1659. }
  1660. if ((strcmp(path,dotdot+1) == 0) || (strcmp(path,dotdot) == 0)) {
  1661. strcat(path,d_slash_stardotstar+2);
  1662. }
  1663. /* Neil's bodge */
  1664. /* del d:. should be the same as del d:*.* */
  1665. if (strlen(path)==3 && path[1] == ':' && path[2] == '.') {
  1666.     path[2] = 0;
  1667.     strcat(path,d_slash_stardotstar+3);
  1668. }
  1669. /* end of Neil's bodge */
  1670. attr = ATTR_STD & ~ATTR_SYS; /* Prevent SYS files from   */
  1671. attr |= ERASE_SYS ? ATTR_SYS : 0; /* being deleted unless the */
  1672. /* /S option is specified.  */
  1673. if(nofiles(path, attr, YES, YES)) /* if no files or error     */
  1674.     return; /*    then we can't do this */
  1675. files = fptr(path); /* isolate the filename     */
  1676. #if defined(PASSWORD)
  1677. password = strchr(files, *pwdchar); /* Check for Source password*/
  1678. if(password) { /* and save in internal buf.*/
  1679. #if STACK
  1680.     password = stack(strlen(password)+1);
  1681. #else
  1682.     password = &passbuf[0];
  1683. #endif
  1684.     strcpy(password, strchr(files, *pwdchar));
  1685. }
  1686. #endif
  1687. confirm |= ERASE_CONFIRM; /* DELQ implies "/c" switch */
  1688. if (!confirm && /* if not confirming anyway */
  1689.     (!strncmp(files, "*", 1)&& /* and all files specified  */
  1690.     strstr(files, ".*"))) /* ie * at start of name & ext */
  1691. {
  1692.     printf(MSG_ERAALL);    /* "Are you sure (Y/N)? " */
  1693.     answer[0] = sizeof(answer)-2; /* max. one character   */
  1694.     answer[1] = 0;   /* no command recall permitted */
  1695.     system (MS_C_READSTR, answer);/* read the response */
  1696.     crlf();
  1697.     if ((answer[2] & 0xdf) != YES_CHAR) {
  1698.      crlfflg = YES; /* if not 'Y' or 'y' given */
  1699. return; /* then return   */
  1700.     }
  1701. }
  1702. if(!confirm && ERASE_SYS && /* If no confirmation is required */
  1703. #if !(defined (CDOSTMP))
  1704.    !iswild(path) && /* and this is an ambigous file   */
  1705. #endif
  1706.    !ms_x_unlink(path)) /* specification and all the files*/
  1707.     return; /* are deleted without error then */
  1708. /* return to the calling function */
  1709. /* otherwise delete files   */
  1710. /* individually.   */
  1711. #if !(defined (CDOSTMP))
  1712. /* use fcb delete if no confirm and system files are not to be   */
  1713. /* deleted, since it's much quicker. Any problems, go and do it the  */
  1714. /* standard way so we can report on problem files.   */
  1715. d_check (path);
  1716. if (ddrive != -1 && (!confirm) && (!ERASE_SYS)
  1717. #if defined(PASSWORD)
  1718. && (!password)
  1719. #endif
  1720. ) {
  1721.     if (!d_check (path))
  1722.         return;
  1723.     if ((ms_f_parse (fcb, files, 0)) < 0) /* set up fname in fcb  */
  1724.         goto fcbdel_end;
  1725.     *fcb = ddrive+1;
  1726.     strcpy (savepath, "d:\"); /* get curpath on relevant drive  */
  1727.     *savepath = ddrive + 'A';
  1728.     ms_x_curdir (ddrive+1, savepath+3);
  1729.     
  1730.     strncpy (newpath, path, files - path);
  1731.      /* extract new path */
  1732.     newpath[files - path] = '';
  1733.     if ((i = strlen (newpath)) > (newpath[1] == ':' ? 3 : 1))
  1734.         newpath[--i] = ''; /* remove trailing backslash */
  1735.     if (! ((i == 0) || ((i == 2) && (newpath[1] == ':'))) )
  1736.         if (ms_x_chdir (newpath))
  1737.     goto fcbdel_end;
  1738.     ret = ms_f_delete (fcb);
  1739.     ms_x_chdir (savepath);
  1740.     
  1741.     if (!ret)
  1742.         return; /* all done   */
  1743. fcbdel_end:
  1744.     ;
  1745. }
  1746. #endif
  1747.     
  1748. if (ms_x_first(path, attr, &search)) return;
  1749. do {
  1750.     strcpy(files, search.fname); /* make it full file name */
  1751.     strcpy(heap(), path); /* copy to an internal    */
  1752. #if defined(PASSWORD)
  1753.     if(password) /* buffer and append the  */
  1754. strcat(heap(), password); /* password if present   */
  1755. #endif
  1756.     if(confirm) {
  1757. printf(MSG_ERAQ, path);
  1758. if(!yes(YES, NO))
  1759.     continue;
  1760.     }
  1761.     if((ret = ms_x_unlink(heap())) != 0) {
  1762. printf(MSG_ERA, path);
  1763. e_check(ret);
  1764. crlf();
  1765.     }
  1766. } while (!ms_x_next (&search));
  1767. }
  1768. #if defined(DOSPLUS)
  1769. /*
  1770.  * The HILOAD command accepts a trailing command line.
  1771.  * It will attempt to execute the command line, running any programs
  1772.  * specified in high memory.
  1773.  */
  1774. GLOBAL VOID CDECL cmd_hiload(s)
  1775. REG BYTE *s;
  1776. {
  1777. int region, i;
  1778. s = deblank(s);
  1779. if (*s == 0) {
  1780.     printf(msg_inop);
  1781.     return;
  1782. }
  1783. global_in_hiload++;
  1784. if (global_in_hiload == 1) {
  1785.     global_link  = get_upper_memory_link();
  1786.     global_strat = get_alloc_strategy();
  1787.     region = 1;
  1788.     set_upper_memory_link(1);
  1789.     /* Look out for /L:r1[,s1][;r2[,s2]...] */
  1790.     /* We parse r1, and discard the rest */
  1791.     if ((s[0]==*switchar)&&(toupper(s[1])=='L')&&(s[2]==':')&&isdigit(s[3])){
  1792. region = s[3]-'0'; /* assume region is 1 digit */
  1793. s += 4; /* skip what we parsed */
  1794. while ((*s==';') || (*s==',') || isdigit(*s))
  1795. s++;
  1796. s = deblank(s); /* deblank rest of line */
  1797.     }
  1798.     /* discard any /S we find (really we should minimise) */
  1799.     if ((s[0]==*switchar) && (toupper(s[1])=='S')) {
  1800. s += 2; /* skip the /S */
  1801. s = deblank(s); /* deblank rest of line */
  1802.     }
  1803.     /* only bother if we have upper memory and are forcing location */
  1804.     if ((region > 1) && (get_upper_memory_link() != 0)) {
  1805. set_alloc_strategy(0x40); /* First fit high only */
  1806. for(i=1;i<region;i++) /* allocate regions to skip */
  1807. hidden_umb[i] = alloc_region();
  1808.     }
  1809.     set_alloc_strategy(0x80); /* First fit high */
  1810. }
  1811. docmd(s,YES); /* call normal code */
  1812. if (global_in_hiload == 1) {
  1813.     for(i=1;i<10;i++) { /* free up any UMB's we have */
  1814. if (hidden_umb[i]) {
  1815. free_region(hidden_umb[i]);
  1816. hidden_umb[i] = 0;
  1817. }
  1818.     }
  1819.     set_upper_memory_link(global_link);
  1820.     set_alloc_strategy(global_strat);
  1821. }
  1822. global_in_hiload --; /* all back as before */
  1823. }
  1824. #endif