- Report file and directory sizes using 64-bit arithmetic (like NT).

- Handle pipes in commands.
This commit is contained in:
Dave Pickles 2001-06-04 02:55:38 +00:00 committed by Alexandre Julliard
parent 27e7f28d8b
commit 64fba1cb84
6 changed files with 62 additions and 61 deletions

View File

@ -1,3 +1,9 @@
v0.17 - 4 June 2001
- Simple pipes now work, using temporary files (the DOS way).
v0.16 - 1 April 2001
-File, directory and free space sizes are all now computed in 64 bits.
v0.15 - 31 October 2000 v0.15 - 31 October 2000
-Running console mode programs the interpreter now waits for the -Running console mode programs the interpreter now waits for the
program to exit before issuing the next prompt. program to exit before issuing the next prompt.

View File

@ -10,7 +10,6 @@ WHAT'S INCLUDED
- A Makefile for Borland C++ (needs editing for directories). - A Makefile for Borland C++ (needs editing for directories).
WHAT'S MISSING WHAT'S MISSING
- Pipes
- Command-line qualifiers for most builtin commands - Command-line qualifiers for most builtin commands
- Wildcards and relative paths in COPY, MOVE and RENAME - Wildcards and relative paths in COPY, MOVE and RENAME
- Set functionality in DATE, TIME, ATTRIB, LABEL - Set functionality in DATE, TIME, ATTRIB, LABEL
@ -27,8 +26,6 @@ US date-time format is used. Set eg "LANG=en_GB" for DD/MM/YY dates and 24-hour
times. times.
- Line editing and command recall doesn't work due to missing functionality in - Line editing and command recall doesn't work due to missing functionality in
Wine. Wine.
- File sizes in the DIR function are all given in 32 bits, though totals and
free space are computed to 64 bits.
- DIR/S only works if no file specification is given, ie "DIR C:\TEMP /S" works - DIR/S only works if no file specification is given, ie "DIR C:\TEMP /S" works
but "DIR C:\TEMP\*.C" doesn't work if a matching file exists in a lower but "DIR C:\TEMP\*.C" doesn't work if a matching file exists in a lower
directory. directory.

View File

@ -11,7 +11,6 @@
/* /*
* FIXME: * FIXME:
* - No support for pipes, shell parameters * - No support for pipes, shell parameters
* - 32-bit limit on file sizes in DIR command
* - Lots of functionality missing from builtins * - Lots of functionality missing from builtins
* - Messages etc need international support * - Messages etc need international support
*/ */

View File

@ -10,7 +10,6 @@
/* /*
* FIXME: * FIXME:
* - 32-bit limit on individual file sizes (directories and free space are 64-bit)
* - DIR /S fails if the starting directory is not the current default. * - DIR /S fails if the starting directory is not the current default.
*/ */
@ -18,8 +17,7 @@
int WCMD_dir_sort (const void *a, const void *b); int WCMD_dir_sort (const void *a, const void *b);
void WCMD_list_directory (char *path, int level); void WCMD_list_directory (char *path, int level);
char * WCMD_filesize64 (__int64 n); char * WCMD_filesize64 (__int64 free);
char * WCMD_filesize32 (int n);
char * WCMD_strrev (char *buff); char * WCMD_strrev (char *buff);
@ -46,8 +44,7 @@ void WCMD_directory () {
char path[MAX_PATH], drive[8]; char path[MAX_PATH], drive[8];
int status; int status;
__int64 free_space; ULARGE_INTEGER avail, total, free;
DWORD spc, bps, fc, capacity;
line_count = 5; line_count = 5;
page_mode = (strstr(quals, "/P") != NULL); page_mode = (strstr(quals, "/P") != NULL);
@ -65,9 +62,8 @@ DWORD spc, bps, fc, capacity;
} }
WCMD_list_directory (path, 0); WCMD_list_directory (path, 0);
lstrcpyn (drive, path, 4); lstrcpyn (drive, path, 4);
GetDiskFreeSpace (drive, &spc, &bps, &fc, &capacity); GetDiskFreeSpaceEx (drive, &avail, &total, &free);
free_space = bps * spc * fc; WCMD_output (" %18s bytes free\n\n", WCMD_filesize64 (free.QuadPart));
WCMD_output (" %18s bytes free\n\n", WCMD_filesize64 (free_space));
if (recurse) { if (recurse) {
WCMD_output ("Total files listed:\n%8d files%25s bytes\n%8d directories\n\n", WCMD_output ("Total files listed:\n%8d files%25s bytes\n%8d directories\n\n",
file_total, WCMD_filesize64 (byte_total), dir_total); file_total, WCMD_filesize64 (byte_total), dir_total);
@ -80,7 +76,6 @@ DWORD spc, bps, fc, capacity;
* List a single file directory. This function (and those below it) can be called * List a single file directory. This function (and those below it) can be called
* recursively when the /S switch is used. * recursively when the /S switch is used.
* *
* FIXME: Assumes individual files are less than 2**32 bytes.
* FIXME: Entries sorted by name only. Should we support DIRCMD?? * FIXME: Entries sorted by name only. Should we support DIRCMD??
* FIXME: Assumes 24-line display for the /P qualifier. * FIXME: Assumes 24-line display for the /P qualifier.
* FIXME: Other command qualifiers not supported. * FIXME: Other command qualifiers not supported.
@ -98,12 +93,12 @@ FILETIME ft;
SYSTEMTIME st; SYSTEMTIME st;
HANDLE hff; HANDLE hff;
int status, dir_count, file_count, entry_count, i; int status, dir_count, file_count, entry_count, i;
__int64 byte_count; ULARGE_INTEGER byte_count, file_size;
dir_count = 0; dir_count = 0;
file_count = 0; file_count = 0;
entry_count = 0; entry_count = 0;
byte_count = 0; byte_count.QuadPart = 0;
/* /*
* If the path supplied does not include a wildcard, and the endpoint of the * If the path supplied does not include a wildcard, and the endpoint of the
@ -166,10 +161,12 @@ __int64 byte_count;
} }
else { else {
file_count++; file_count++;
byte_count += (fd+i)->nFileSizeLow; file_size.LowPart = (fd+i)->nFileSizeLow;
file_size.HighPart = (fd+i)->nFileSizeHigh;
byte_count.QuadPart += file_size.QuadPart;
WCMD_output ("%8s %8s %10s %s\n", WCMD_output ("%8s %8s %10s %s\n",
datestring, timestring, datestring, timestring,
WCMD_filesize32((fd+i)->nFileSizeLow), (fd+i)->cFileName); WCMD_filesize64(file_size.QuadPart), (fd+i)->cFileName);
} }
if (page_mode) { if (page_mode) {
if (++line_count > 23) { if (++line_count > 23) {
@ -180,10 +177,10 @@ __int64 byte_count;
} }
} }
if (file_count == 1) { if (file_count == 1) {
WCMD_output (" 1 file %25s bytes\n", WCMD_filesize64 (byte_count)); WCMD_output (" 1 file %25s bytes\n", WCMD_filesize64 (byte_count.QuadPart));
} }
else { else {
WCMD_output ("%8d files %24s bytes\n", file_count, WCMD_filesize64 (byte_count)); WCMD_output ("%8d files %24s bytes\n", file_count, WCMD_filesize64 (byte_count.QuadPart));
} }
if (page_mode) { if (page_mode) {
if (++line_count > 23) { if (++line_count > 23) {
@ -192,7 +189,7 @@ __int64 byte_count;
ReadFile (GetStdHandle(STD_INPUT_HANDLE), string, sizeof(string), &count, NULL); ReadFile (GetStdHandle(STD_INPUT_HANDLE), string, sizeof(string), &count, NULL);
} }
} }
byte_total = byte_total + byte_count; byte_total = byte_total + byte_count.QuadPart;
file_total = file_total + file_count; file_total = file_total + file_count;
dir_total = dir_total + dir_count; dir_total = dir_total + dir_count;
if (dir_count == 1) WCMD_output ("1 directory "); if (dir_count == 1) WCMD_output ("1 directory ");
@ -251,34 +248,6 @@ static char buff[32];
return buff; return buff;
} }
/*****************************************************************************
* WCMD_filesize32
*
* Convert a 32-bit number into a character string, with commas every three digits.
* Result is returned in a static string overwritten with each call.
* FIXME: There must be a better algorithm!
*/
char * WCMD_filesize32 (int n) {
int r, i;
char *p, *q;
static char buff1[16], buff2[16];
wsprintf (buff1, "%i", n);
r = lstrlen (buff1);
WCMD_strrev (buff1);
p = buff1;
q = buff2;
for (i=0; i<r; i++) {
if ((i-2)%3 == 1) *q++ = ',';
*q++ = *p++;
}
*q = '\0';
WCMD_strrev (buff2);
return buff2;
}
/***************************************************************************** /*****************************************************************************
* WCMD_strrev * WCMD_strrev
* *

View File

@ -36,8 +36,10 @@ void WCMD_output (char *format, ...);
void WCMD_output_asis (char *message); void WCMD_output_asis (char *message);
void WCMD_parse (char *s, char *q, char *p1, char *p2); void WCMD_parse (char *s, char *q, char *p1, char *p2);
void WCMD_pause (void); void WCMD_pause (void);
void WCMD_pipe (char *command);
void WCMD_print_error (void); void WCMD_print_error (void);
void WCMD_process_command (char *command); void WCMD_process_command (char *command);
int WCMD_read_console (char *string, int str_len);
void WCMD_remove_dir (void); void WCMD_remove_dir (void);
void WCMD_rename (void); void WCMD_rename (void);
void WCMD_run_program (char *command); void WCMD_run_program (char *command);

View File

@ -1,13 +1,11 @@
/* /*
* WCMD - Wine-compatible command line interface. * WCMD - Wine-compatible command line interface.
* *
* (C) 1999 D A Pickles * (C) 1999 - 2001 D A Pickles
*/ */
/* /*
* FIXME: * FIXME:
* - No support for pipes
* - 32-bit limit on file sizes in DIR command
* - Cannot handle parameters in quotes * - Cannot handle parameters in quotes
* - Lots of functionality missing from builtins * - Lots of functionality missing from builtins
*/ */
@ -25,7 +23,7 @@ DWORD errorlevel;
int echo_mode = 1, verify_mode = 0; int echo_mode = 1, verify_mode = 0;
char nyi[] = "Not Yet Implemented\n\n"; char nyi[] = "Not Yet Implemented\n\n";
char newline[] = "\n"; char newline[] = "\n";
char version_string[] = "WCMD Version 0.15\n\n"; char version_string[] = "WCMD Version 0.17\n\n";
char anykey[] = "Press any key to continue: "; char anykey[] = "Press any key to continue: ";
char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH]; char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
BATCH_CONTEXT *context = NULL; BATCH_CONTEXT *context = NULL;
@ -109,7 +107,12 @@ HANDLE h;
string[count-1] = '\0'; /* ReadFile output is not null-terminated! */ string[count-1] = '\0'; /* ReadFile output is not null-terminated! */
if (string[count-2] == '\r') string[count-2] = '\0'; /* Under Windoze we get CRLF! */ if (string[count-2] == '\r') string[count-2] = '\0'; /* Under Windoze we get CRLF! */
if (lstrlen (string) != 0) { if (lstrlen (string) != 0) {
WCMD_process_command (string); if (strchr(string,'|') != NULL) {
WCMD_pipe (string);
}
else {
WCMD_process_command (string);
}
} }
} }
} }
@ -131,14 +134,6 @@ DWORD count;
HANDLE old_stdin = 0, old_stdout = 0, h; HANDLE old_stdin = 0, old_stdout = 0, h;
char *whichcmd; char *whichcmd;
/*
* Throw away constructs we don't support yet
*/
if (strchr(command,'|') != NULL) {
WCMD_output ("Pipes not yet implemented\n");
return;
}
/* /*
* Expand up environment variables. * Expand up environment variables.
@ -614,3 +609,36 @@ char *ptr;
ptr--; ptr--;
} }
} }
/*************************************************************************
* WCMD_pipe
*
* Handle pipes within a command - the DOS way using temporary files.
*/
void WCMD_pipe (char *command) {
char *p;
char temp_path[MAX_PATH], temp_file[MAX_PATH], temp_file2[MAX_PATH], temp_cmd[1024];
GetTempPath (sizeof(temp_path), temp_path);
GetTempFileName (temp_path, "WCMD", 0, temp_file);
p = strchr(command, '|');
*p++ = '\0';
wsprintf (temp_cmd, "%s > %s", command, temp_file);
WCMD_process_command (temp_cmd);
command = p;
while ((p = strchr(command, '|'))) {
*p++ = '\0';
GetTempFileName (temp_path, "WCMD", 0, temp_file2);
wsprintf (temp_cmd, "%s < %s > %s", command, temp_file, temp_file2);
WCMD_process_command (temp_cmd);
DeleteFile (temp_file);
lstrcpy (temp_file, temp_file2);
command = p;
}
wsprintf (temp_cmd, "%s < %s", command, temp_file);
WCMD_process_command (temp_cmd);
DeleteFile (temp_file);
}