blob: d9504b919fe1cee2e9d6f8a7d2949bb9ac8a5184 [file] [log] [blame]
Dave Pickles74f440e1999-06-06 15:24:04 +00001/*
2 * WCMD - Wine-compatible command line interface - built-in functions.
3 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00004 * Copyright (C) 1999 D A Pickles
Dave Pickles74f440e1999-06-06 15:24:04 +00005 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00006 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/*
22 * NOTES:
Dave Pickles74f440e1999-06-06 15:24:04 +000023 * On entry to each function, global variables quals, param1, param2 contain
24 * the qualifiers (uppercased and concatenated) and parameters entered, with
25 * environment-variable and batch parameter substitution already done.
26 */
27
28/*
29 * FIXME:
Dave Pickles036a9f71999-07-10 11:36:45 +000030 * - No support for pipes, shell parameters
Dave Pickles74f440e1999-06-06 15:24:04 +000031 * - Lots of functionality missing from builtins
32 * - Messages etc need international support
33 */
34
35#include "wcmd.h"
36
Dave Pickles036a9f71999-07-10 11:36:45 +000037void WCMD_execute (char *orig_command, char *parameter, char *substitution);
38
Dave Pickles74f440e1999-06-06 15:24:04 +000039extern HINSTANCE hinst;
40extern char *inbuilt[];
41extern char nyi[];
42extern char newline[];
43extern char version_string[];
44extern char anykey[];
Dave Pickles5f8f4f71999-06-26 10:24:08 +000045extern int echo_mode, verify_mode;
Dave Pickles74f440e1999-06-06 15:24:04 +000046extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
Dave Pickles5f8f4f71999-06-26 10:24:08 +000047extern BATCH_CONTEXT *context;
Dave Picklesebecf502000-08-01 22:02:18 +000048extern DWORD errorlevel;
Dave Pickles74f440e1999-06-06 15:24:04 +000049
50
Dave Pickles74f440e1999-06-06 15:24:04 +000051
52/****************************************************************************
53 * WCMD_clear_screen
54 *
55 * Clear the terminal screen.
56 */
57
58void WCMD_clear_screen () {
59
60 WCMD_output (nyi);
61
62}
63
64/****************************************************************************
65 * WCMD_change_tty
66 *
67 * Change the default i/o device (ie redirect STDin/STDout).
68 */
69
70void WCMD_change_tty () {
71
72 WCMD_output (nyi);
73
74}
75
76/****************************************************************************
77 * WCMD_copy
78 *
79 * Copy a file or wildcarded set.
80 * FIXME: No wildcard support
Dave Pickles74f440e1999-06-06 15:24:04 +000081 */
82
83void WCMD_copy () {
84
85DWORD count;
86WIN32_FIND_DATA fd;
87HANDLE hff;
88BOOL force, status;
89static char *overwrite = "Overwrite file (Y/N)?";
Dave Picklesebecf502000-08-01 22:02:18 +000090char string[8], outpath[MAX_PATH], inpath[MAX_PATH], *infile;
Dave Pickles74f440e1999-06-06 15:24:04 +000091
92 if ((strchr(param1,'*') != NULL) && (strchr(param1,'%') != NULL)) {
93 WCMD_output ("Wildcards not yet supported\n");
94 return;
95 }
96 GetFullPathName (param2, sizeof(outpath), outpath, NULL);
Dave Picklesebecf502000-08-01 22:02:18 +000097 hff = FindFirstFile (outpath, &fd);
98 if (hff != INVALID_HANDLE_VALUE) {
99 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
100 GetFullPathName (param1, sizeof(inpath), inpath, &infile);
101 strcat (outpath, "\\");
102 strcat (outpath, infile);
103 }
104 FindClose (hff);
105 }
Dave Pickles74f440e1999-06-06 15:24:04 +0000106 force = (strstr (quals, "/Y") != NULL);
107 if (!force) {
108 hff = FindFirstFile (outpath, &fd);
109 if (hff != INVALID_HANDLE_VALUE) {
110 FindClose (hff);
111 WCMD_output (overwrite);
Dave Pickles036a9f71999-07-10 11:36:45 +0000112 ReadFile (GetStdHandle(STD_INPUT_HANDLE), string, sizeof(string), &count, NULL);
Dave Pickles74f440e1999-06-06 15:24:04 +0000113 if (toupper(string[0]) == 'Y') force = TRUE;
114 }
115 else force = TRUE;
116 }
117 if (force) {
118 status = CopyFile (param1, outpath, FALSE);
119 if (!status) WCMD_print_error ();
120 }
121}
122
123/****************************************************************************
124 * WCMD_create_dir
125 *
126 * Create a directory.
127 */
128
129void WCMD_create_dir () {
130
131 if (!CreateDirectory (param1, NULL)) WCMD_print_error ();
132}
133
134/****************************************************************************
135 * WCMD_delete
136 *
137 * Delete a file or wildcarded set.
138 *
139 */
140
141void WCMD_delete (int recurse) {
142
143WIN32_FIND_DATA fd;
144HANDLE hff;
145char fpath[MAX_PATH];
146char *p;
147
148 hff = FindFirstFile (param1, &fd);
149 if (hff == INVALID_HANDLE_VALUE) {
150 WCMD_output ("File Not Found\n");
151 return;
152 }
153 if ((strchr(param1,'*') == NULL) && (strchr(param1,'?') == NULL)
154 && (!recurse) && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
155 strcat (param1, "\\*");
156 WCMD_delete (1);
157 return;
158 }
159 if ((strchr(param1,'*') != NULL) || (strchr(param1,'?') != NULL)) {
160 strcpy (fpath, param1);
161 do {
162 p = strrchr (fpath, '\\');
163 if (p != NULL) {
164 *++p = '\0';
165 strcat (fpath, fd.cFileName);
166 }
167 else strcpy (fpath, fd.cFileName);
168 if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
169 if (!DeleteFile (fpath)) WCMD_print_error ();
170 }
171 } while (FindNextFile(hff, &fd) != 0);
172 FindClose (hff);
173 }
174 else {
175 if (!DeleteFile (param1)) WCMD_print_error ();
176 }
177}
178
179/****************************************************************************
180 * WCMD_echo
181 *
182 * Echo input to the screen (or not). We don't try to emulate the bugs
183 * in DOS (try typing "ECHO ON AGAIN" for an example).
184 */
185
186void WCMD_echo (char *command) {
187
188static char *eon = "Echo is ON\n", *eoff = "Echo is OFF\n";
189int count;
190
191 count = strlen(command);
192 if (count == 0) {
193 if (echo_mode) WCMD_output (eon);
194 else WCMD_output (eoff);
195 return;
196 }
197 if ((count == 1) && (command[0] == '.')) {
198 WCMD_output (newline);
199 return;
200 }
201 if (lstrcmpi(command, "ON") == 0) {
202 echo_mode = 1;
203 return;
204 }
205 if (lstrcmpi(command, "OFF") == 0) {
206 echo_mode = 0;
207 return;
208 }
Jason Edmeadesa5910f42000-08-01 02:14:33 +0000209 WCMD_output_asis (command);
Dave Pickles74f440e1999-06-06 15:24:04 +0000210 WCMD_output (newline);
211
212}
213
Dave Pickles036a9f71999-07-10 11:36:45 +0000214/**************************************************************************
Dave Pickles74f440e1999-06-06 15:24:04 +0000215 * WCMD_for
216 *
217 * Batch file loop processing.
Dave Pickles036a9f71999-07-10 11:36:45 +0000218 * FIXME: We don't exhaustively check syntax. Any command which works in MessDOS
219 * will probably work here, but the reverse is not necessarily the case...
Dave Pickles74f440e1999-06-06 15:24:04 +0000220 */
221
Dave Pickles5f8f4f71999-06-26 10:24:08 +0000222void WCMD_for (char *p) {
Dave Pickles74f440e1999-06-06 15:24:04 +0000223
Dave Pickles036a9f71999-07-10 11:36:45 +0000224WIN32_FIND_DATA fd;
225HANDLE hff;
226char *cmd, *item;
227char set[MAX_PATH], param[MAX_PATH];
228int i;
229
230 if (lstrcmpi (WCMD_parameter (p, 1, NULL), "in")
231 || lstrcmpi (WCMD_parameter (p, 3, NULL), "do")
232 || (param1[0] != '%')) {
Dave Pickles5f8f4f71999-06-26 10:24:08 +0000233 WCMD_output ("Syntax error\n");
234 return;
235 }
Dave Pickles036a9f71999-07-10 11:36:45 +0000236 lstrcpyn (set, WCMD_parameter (p, 2, NULL), sizeof(set));
237 WCMD_parameter (p, 4, &cmd);
238 lstrcpy (param, param1);
Dave Pickles74f440e1999-06-06 15:24:04 +0000239
Dave Pickles036a9f71999-07-10 11:36:45 +0000240/*
241 * If the parameter within the set has a wildcard then search for matching files
242 * otherwise do a literal substitution.
243 */
244
245 i = 0;
246 while (*(item = WCMD_parameter (set, i, NULL))) {
247 if (strpbrk (item, "*?")) {
248 hff = FindFirstFile (item, &fd);
249 if (hff == INVALID_HANDLE_VALUE) {
250 return;
251 }
252 do {
253 WCMD_execute (cmd, param, fd.cFileName);
254 } while (FindNextFile(hff, &fd) != 0);
255 FindClose (hff);
Dave Pickles74f440e1999-06-06 15:24:04 +0000256}
Dave Pickles036a9f71999-07-10 11:36:45 +0000257 else {
258 WCMD_execute (cmd, param, item);
259 }
260 i++;
261 }
262}
263
Dave Picklesebecf502000-08-01 22:02:18 +0000264/*****************************************************************************
265 * WCMD_Execute
266 *
Dave Pickles036a9f71999-07-10 11:36:45 +0000267 * Execute a command after substituting variable text for the supplied parameter
268 */
269
270void WCMD_execute (char *orig_cmd, char *param, char *subst) {
271
272char *new_cmd, *p, *s, *dup;
273int size;
274
275 size = lstrlen (orig_cmd);
276 new_cmd = (char *) LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, size);
277 dup = s = strdup (orig_cmd);
278
279 while ((p = strstr (s, param))) {
280 *p = '\0';
281 size += lstrlen (subst);
282 new_cmd = (char *) LocalReAlloc ((HANDLE)new_cmd, size, 0);
283 strcat (new_cmd, s);
284 strcat (new_cmd, subst);
285 s = p + lstrlen (param);
286 }
287 strcat (new_cmd, s);
288 WCMD_process_command (new_cmd);
289 free (dup);
290 LocalFree ((HANDLE)new_cmd);
291}
292
Dave Pickles74f440e1999-06-06 15:24:04 +0000293
294/**************************************************************************
295 * WCMD_give_help
296 *
297 * Simple on-line help. Help text is stored in the resource file.
298 */
299
300void WCMD_give_help (char *command) {
301
302int i;
303char buffer[2048];
304
305 command = WCMD_strtrim_leading_spaces(command);
306 if (lstrlen(command) == 0) {
Alexandre Julliardbc4b88f2000-04-19 16:47:20 +0000307 LoadString (0, 1000, buffer, sizeof(buffer));
Dave Pickles74f440e1999-06-06 15:24:04 +0000308 WCMD_output (buffer);
309 }
310 else {
311 for (i=0; i<=WCMD_EXIT; i++) {
312 if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
Dave Picklesebecf502000-08-01 22:02:18 +0000313 param1, -1, inbuilt[i], -1) == 2) {
314 LoadString (hinst, i, buffer, sizeof(buffer));
315 WCMD_output (buffer);
316 return;
Dave Pickles74f440e1999-06-06 15:24:04 +0000317 }
318 }
319 WCMD_output ("No help available for %s\n", param1);
320 }
321 return;
322}
323
324/****************************************************************************
Dave Pickles5f8f4f71999-06-26 10:24:08 +0000325 * WCMD_go_to
326 *
327 * Batch file jump instruction. Not the most efficient algorithm ;-)
328 * Prints error message if the specified label cannot be found - the file pointer is
329 * then at EOF, effectively stopping the batch file.
330 * FIXME: DOS is supposed to allow labels with spaces - we don't.
331 */
332
333void WCMD_goto () {
334
335char string[MAX_PATH];
336
337 if (context != NULL) {
338 SetFilePointer (context -> h, 0, NULL, FILE_BEGIN);
339 while (WCMD_fgets (string, sizeof(string), context -> h)) {
340 if ((string[0] == ':') && (strcmp (&string[1], param1) == 0)) return;
341 }
342 WCMD_output ("Target to GOTO not found\n");
343 }
344 return;
345}
346
347
348/****************************************************************************
Dave Pickles74f440e1999-06-06 15:24:04 +0000349 * WCMD_if
350 *
351 * Batch file conditional.
Dave Pickles036a9f71999-07-10 11:36:45 +0000352 * FIXME: Much more syntax checking needed!
Dave Pickles74f440e1999-06-06 15:24:04 +0000353 */
354
Dave Pickles036a9f71999-07-10 11:36:45 +0000355void WCMD_if (char *p) {
Dave Pickles74f440e1999-06-06 15:24:04 +0000356
Dave Pickles036a9f71999-07-10 11:36:45 +0000357HANDLE h;
358int negate = 0, test = 0;
359char condition[MAX_PATH], *command, *s;
Dave Pickles74f440e1999-06-06 15:24:04 +0000360
Dave Pickles036a9f71999-07-10 11:36:45 +0000361 if (!lstrcmpi (param1, "not")) {
362 negate = 1;
363 lstrcpy (condition, param2);
364}
365 else {
366 lstrcpy (condition, param1);
367 }
368 if (!lstrcmpi (condition, "errorlevel")) {
Dave Picklesebecf502000-08-01 22:02:18 +0000369 if (errorlevel >= atoi(WCMD_parameter (p, 1+negate, NULL))) test = 1;
Dave Pickles036a9f71999-07-10 11:36:45 +0000370 return;
371 }
372 else if (!lstrcmpi (condition, "exist")) {
373 if ((h = CreateFile (WCMD_parameter (p, 1+negate, NULL), GENERIC_READ, 0, NULL,
François Gouget12b35262001-01-02 20:40:58 +0000374 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) {
Dave Pickles036a9f71999-07-10 11:36:45 +0000375 CloseHandle (h);
376 test = 1;
377 }
378 }
379 else if ((s = strstr (p, "=="))) {
380 s += 2;
381 if (!lstrcmpi (condition, WCMD_parameter (s, 0, NULL))) test = 1;
382 }
383 else {
384 WCMD_output ("Syntax error\n");
385 return;
386 }
387 if (test != negate) {
388 WCMD_parameter (p, 2+negate, &s);
389 command = strdup (s);
390 WCMD_process_command (command);
391 free (command);
392 }
Dave Pickles74f440e1999-06-06 15:24:04 +0000393}
394
395/****************************************************************************
396 * WCMD_move
397 *
398 * Move a file, directory tree or wildcarded set of files.
Dave Pickles036a9f71999-07-10 11:36:45 +0000399 * FIXME: Needs input and output files to be fully specified.
Dave Pickles74f440e1999-06-06 15:24:04 +0000400 */
401
402void WCMD_move () {
403
Dave Pickles036a9f71999-07-10 11:36:45 +0000404int status;
405
406 if ((strchr(param1,'*') != NULL) || (strchr(param1,'%') != NULL)) {
407 WCMD_output ("Wildcards not yet supported\n");
408 return;
409}
410 status = MoveFile (param1, param2);
411 if (!status) WCMD_print_error ();
Dave Pickles74f440e1999-06-06 15:24:04 +0000412}
413
414/****************************************************************************
415 * WCMD_pause
416 *
417 * Wait for keyboard input.
418 */
419
420void WCMD_pause () {
421
422DWORD count;
423char string[32];
424
425 WCMD_output (anykey);
Dave Pickles036a9f71999-07-10 11:36:45 +0000426 ReadFile (GetStdHandle(STD_INPUT_HANDLE), string, sizeof(string), &count, NULL);
Dave Pickles74f440e1999-06-06 15:24:04 +0000427}
428
429/****************************************************************************
430 * WCMD_remove_dir
431 *
432 * Delete a directory.
433 */
434
435void WCMD_remove_dir () {
436
437 if (!RemoveDirectory (param1)) WCMD_print_error ();
438}
439
440/****************************************************************************
441 * WCMD_rename
442 *
443 * Rename a file.
444 * FIXME: Needs input and output files to be fully specified.
445 */
446
447void WCMD_rename () {
448
449int status;
Dave Pickles74f440e1999-06-06 15:24:04 +0000450
451 if ((strchr(param1,'*') != NULL) || (strchr(param1,'%') != NULL)) {
452 WCMD_output ("Wildcards not yet supported\n");
453 return;
454 }
Dave Pickles74f440e1999-06-06 15:24:04 +0000455 status = MoveFile (param1, param2);
456 if (!status) WCMD_print_error ();
457}
458
459/*****************************************************************************
460 * WCMD_setshow_attrib
461 *
462 * Display and optionally sets DOS attributes on a file or directory
463 *
464 * FIXME: Wine currently uses the Unix stat() function to get file attributes.
465 * As a result only the Readonly flag is correctly reported, the Archive bit
466 * is always set and the rest are not implemented. We do the Right Thing anyway.
467 *
Dave Pickles036a9f71999-07-10 11:36:45 +0000468 * FIXME: No SET functionality.
469 *
Dave Pickles74f440e1999-06-06 15:24:04 +0000470 */
471
472void WCMD_setshow_attrib () {
473
474DWORD count;
475HANDLE hff;
476WIN32_FIND_DATA fd;
477char flags[9] = {" "};
478
Dave Pickles036a9f71999-07-10 11:36:45 +0000479 if (param1[0] == '-') {
480 WCMD_output (nyi);
481 return;
482 }
483
Dave Pickles74f440e1999-06-06 15:24:04 +0000484 if (lstrlen(param1) == 0) {
485 GetCurrentDirectory (sizeof(param1), param1);
486 strcat (param1, "\\*");
487 }
488
489 hff = FindFirstFile (param1, &fd);
490 if (hff == INVALID_HANDLE_VALUE) {
491 WCMD_output ("File Not Found\n");
492 }
493 else {
494 do {
495 if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
496 if (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
497 flags[0] = 'H';
498 }
499 if (fd.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) {
500 flags[1] = 'S';
501 }
502 if (fd.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) {
503 flags[2] = 'A';
504 }
505 if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
506 flags[3] = 'R';
507 }
508 if (fd.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
509 flags[4] = 'T';
510 }
511 if (fd.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) {
512 flags[5] = 'C';
513 }
514 WCMD_output ("%s %s\n", flags, fd.cFileName);
515 for (count=0; count < 8; count++) flags[count] = ' ';
516 }
517 } while (FindNextFile(hff, &fd) != 0);
518 }
519 FindClose (hff);
520}
521
522/*****************************************************************************
523 * WCMD_setshow_default
524 *
525 * Set/Show the current default directory
526 */
527
528void WCMD_setshow_default () {
529
530BOOL status;
531char string[1024];
532
533 if (strlen(param1) == 0) {
534 GetCurrentDirectory (sizeof(string), string);
535 strcat (string, "\n");
536 WCMD_output (string);
537 }
538 else {
539 status = SetCurrentDirectory (param1);
540 if (!status) {
541 WCMD_print_error ();
542 return;
543 }
544 }
545 return;
546}
547
548/****************************************************************************
549 * WCMD_setshow_date
550 *
551 * Set/Show the system date
552 * FIXME: Can't change date yet
553 */
554
555void WCMD_setshow_date () {
556
557char curdate[64], buffer[64];
558DWORD count;
559
560 if (lstrlen(param1) == 0) {
561 if (GetDateFormat (LOCALE_USER_DEFAULT, 0, NULL, NULL,
562 curdate, sizeof(curdate))) {
563 WCMD_output ("Current Date is %s\nEnter new date: ", curdate);
Dave Pickles036a9f71999-07-10 11:36:45 +0000564 ReadFile (GetStdHandle(STD_INPUT_HANDLE), buffer, sizeof(buffer), &count, NULL);
Dave Pickles74f440e1999-06-06 15:24:04 +0000565 if (count > 2) {
566 WCMD_output (nyi);
567 }
568 }
569 else WCMD_print_error ();
570 }
571 else {
572 WCMD_output (nyi);
573 }
574}
575
576/****************************************************************************
577 * WCMD_setshow_env
578 *
579 * Set/Show the environment variables
580 *
581 * FIXME: need to sort variables into order for display?
582 */
583
584void WCMD_setshow_env (char *s) {
585
586LPVOID env;
587char *p;
588int status;
Jason Edmeadesa5910f42000-08-01 02:14:33 +0000589char buffer[1048];
Dave Pickles74f440e1999-06-06 15:24:04 +0000590
591 if (strlen(param1) == 0) {
592 env = GetEnvironmentStrings ();
593 p = (char *) env;
594 while (*p) {
595 WCMD_output ("%s\n", p);
596 p += lstrlen(p) + 1;
597 }
598 }
599 else {
600 p = strchr (s, '=');
601 if (p == NULL) {
Jason Edmeadesa5910f42000-08-01 02:14:33 +0000602
603 /* FIXME: Emulate Win98 for now, ie "SET C" looks ONLY for an
604 environment variable C, whereas on NT it shows ALL variables
605 starting with C.
606 */
607 status = GetEnvironmentVariable(s, buffer, sizeof(buffer));
608 if (status) {
609 WCMD_output("%s=%s\n", s, buffer);
610 } else {
611 WCMD_output ("Environment variable %s not defined\n", s);
612 }
Dave Pickles74f440e1999-06-06 15:24:04 +0000613 return;
614 }
615 *p++ = '\0';
Jason Edmeadesa5910f42000-08-01 02:14:33 +0000616
617 if (strlen(p) == 0) p = 0x00;
618 status = SetEnvironmentVariable (s, p);
Dave Pickles74f440e1999-06-06 15:24:04 +0000619 if (!status) WCMD_print_error();
620 }
Jason Edmeadesa5910f42000-08-01 02:14:33 +0000621 /* WCMD_output (newline); @JED*/
Dave Pickles74f440e1999-06-06 15:24:04 +0000622}
623
624/****************************************************************************
625 * WCMD_setshow_path
626 *
627 * Set/Show the path environment variable
628 */
629
630void WCMD_setshow_path () {
631
632char string[1024];
633DWORD status;
634
635 if (strlen(param1) == 0) {
636 status = GetEnvironmentVariable ("PATH", string, sizeof(string));
637 if (status != 0) {
638 WCMD_output ("PATH=%s\n", string);
639 }
640 else {
641 WCMD_output ("PATH not found\n");
642 }
643 }
644 else {
645 status = SetEnvironmentVariable ("PATH", param1);
646 if (!status) WCMD_print_error();
647 }
648}
649
650/****************************************************************************
651 * WCMD_setshow_prompt
652 *
653 * Set or show the command prompt.
654 */
655
656void WCMD_setshow_prompt () {
657
658char *s;
659
660 if (strlen(param1) == 0) {
661 SetEnvironmentVariable ("PROMPT", NULL);
662 }
663 else {
664 s = param1;
665 while ((*s == '=') || (*s == ' ')) s++;
666 if (strlen(s) == 0) {
667 SetEnvironmentVariable ("PROMPT", NULL);
668 }
669 else SetEnvironmentVariable ("PROMPT", s);
670 }
671}
672
673/****************************************************************************
674 * WCMD_setshow_time
675 *
676 * Set/Show the system time
677 * FIXME: Can't change time yet
678 */
679
680void WCMD_setshow_time () {
681
682char curtime[64], buffer[64];
683DWORD count;
Dave Pickles036a9f71999-07-10 11:36:45 +0000684SYSTEMTIME st;
Dave Pickles74f440e1999-06-06 15:24:04 +0000685
686 if (strlen(param1) == 0) {
Dave Pickles036a9f71999-07-10 11:36:45 +0000687 GetLocalTime(&st);
688 if (GetTimeFormat (LOCALE_USER_DEFAULT, 0, &st, NULL,
Dave Pickles74f440e1999-06-06 15:24:04 +0000689 curtime, sizeof(curtime))) {
690 WCMD_output ("Current Time is %s\nEnter new time: ", curtime);
Dave Pickles036a9f71999-07-10 11:36:45 +0000691 ReadFile (GetStdHandle(STD_INPUT_HANDLE), buffer, sizeof(buffer), &count, NULL);
Dave Pickles74f440e1999-06-06 15:24:04 +0000692 if (count > 2) {
693 WCMD_output (nyi);
694 }
695 }
696 else WCMD_print_error ();
697 }
698 else {
699 WCMD_output (nyi);
700 }
701}
702
703/****************************************************************************
704 * WCMD_shift
705 *
706 * Shift batch parameters.
707 */
708
709void WCMD_shift () {
710
Dave Pickles5f8f4f71999-06-26 10:24:08 +0000711 if (context != NULL) context -> shift_count++;
Dave Pickles74f440e1999-06-06 15:24:04 +0000712
713}
714
715/****************************************************************************
716 * WCMD_type
717 *
718 * Copy a file to standard output.
719 */
720
721void WCMD_type () {
722
723HANDLE h;
724char buffer[512];
725DWORD count;
726
727 h = CreateFile (param1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
François Gouget12b35262001-01-02 20:40:58 +0000728 FILE_ATTRIBUTE_NORMAL, NULL);
Dave Pickles74f440e1999-06-06 15:24:04 +0000729 if (h == INVALID_HANDLE_VALUE) {
730 WCMD_print_error ();
731 return;
732 }
733 while (ReadFile (h, buffer, sizeof(buffer), &count, NULL)) {
734 if (count == 0) break; /* ReadFile reports success on EOF! */
Dave Pickles036a9f71999-07-10 11:36:45 +0000735 WriteFile (GetStdHandle(STD_OUTPUT_HANDLE), buffer, count, &count, NULL);
Dave Pickles74f440e1999-06-06 15:24:04 +0000736 }
737 CloseHandle (h);
738}
739
740/****************************************************************************
741 * WCMD_verify
742 *
743 * Display verify flag.
Dave Pickles5f8f4f71999-06-26 10:24:08 +0000744 * FIXME: We don't actually do anything with the verify flag other than toggle
745 * it...
Dave Pickles74f440e1999-06-06 15:24:04 +0000746 */
747
Dave Pickles5f8f4f71999-06-26 10:24:08 +0000748void WCMD_verify (char *command) {
Dave Pickles74f440e1999-06-06 15:24:04 +0000749
Dave Pickles5f8f4f71999-06-26 10:24:08 +0000750static char *von = "Verify is ON\n", *voff = "Verify is OFF\n";
751int count;
Dave Pickles74f440e1999-06-06 15:24:04 +0000752
Dave Pickles5f8f4f71999-06-26 10:24:08 +0000753 count = strlen(command);
754 if (count == 0) {
755 if (verify_mode) WCMD_output (von);
756 else WCMD_output (voff);
757 return;
758 }
759 if (lstrcmpi(command, "ON") == 0) {
760 verify_mode = 1;
761 return;
762 }
763 else if (lstrcmpi(command, "OFF") == 0) {
764 verify_mode = 0;
765 return;
766 }
767 else WCMD_output ("Verify must be ON or OFF\n");
Dave Pickles74f440e1999-06-06 15:24:04 +0000768}
769
770/****************************************************************************
771 * WCMD_version
772 *
773 * Display version info.
774 */
775
776void WCMD_version () {
777
778 WCMD_output (version_string);
779
780}
781
782/****************************************************************************
783 * WCMD_volume
784 *
785 * Display volume info and/or set volume label. Returns 0 if error.
786 */
787
788int WCMD_volume (int mode, char *path) {
789
790DWORD count, serial;
791char string[MAX_PATH], label[MAX_PATH], curdir[MAX_PATH];
792BOOL status;
793static char syntax[] = "Syntax Error\n\n";
794
795 if (lstrlen(path) == 0) {
796 status = GetCurrentDirectory (sizeof(curdir), curdir);
797 if (!status) {
798 WCMD_print_error ();
799 return 0;
800 }
801 status = GetVolumeInformation (NULL, label, sizeof(label), &serial, NULL,
802 NULL, NULL, 0);
803 }
804 else {
805 if ((path[1] != ':') || (lstrlen(path) != 2)) {
Dave Pickles036a9f71999-07-10 11:36:45 +0000806 WriteFile (GetStdHandle(STD_OUTPUT_HANDLE), syntax, strlen(syntax), &count, NULL);
Dave Pickles74f440e1999-06-06 15:24:04 +0000807 return 0;
808 }
809 wsprintf (curdir, "%s\\", path);
810 status = GetVolumeInformation (curdir, label, sizeof(label), &serial, NULL,
811 NULL, NULL, 0);
812 }
813 if (!status) {
814 WCMD_print_error ();
815 return 0;
816 }
817 WCMD_output ("Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n",
818 curdir[0], label, HIWORD(serial), LOWORD(serial));
819 if (mode) {
820 WCMD_output ("Volume label (11 characters, ENTER for none)?");
Dave Pickles036a9f71999-07-10 11:36:45 +0000821 ReadFile (GetStdHandle(STD_INPUT_HANDLE), string, sizeof(string), &count, NULL);
822 if (count > 1) {
823 string[count-1] = '\0'; /* ReadFile output is not null-terminated! */
824 if (string[count-2] == '\r') string[count-2] = '\0'; /* Under Windoze we get CRLF! */
825 }
Dave Pickles74f440e1999-06-06 15:24:04 +0000826 if (lstrlen(path) != 0) {
827 if (!SetVolumeLabel (curdir, string)) WCMD_print_error ();
828 }
829 else {
830 if (!SetVolumeLabel (NULL, string)) WCMD_print_error ();
831 }
832 }
833 return 1;
834}