fix for bug 875. Patch by jvangael@wisc.edu Modified: trunk/reactos/subsys/system/cmd/cmd.h Modified: trunk/reactos/subsys/system/cmd/dir.c Modified: trunk/reactos/subsys/system/cmd/misc.c _____
Modified: trunk/reactos/subsys/system/cmd/cmd.h --- trunk/reactos/subsys/system/cmd/cmd.h 2005-11-02 01:39:30 UTC (rev 18946) +++ trunk/reactos/subsys/system/cmd/cmd.h 2005-11-02 13:49:14 UTC (rev 18947) @@ -293,6 +293,7 @@
BOOL SetRootPath(TCHAR *InPath); TCHAR cgetchar (VOID); BOOL CheckCtrlBreak (INT); +BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry); LPTSTR *split (LPTSTR, LPINT, BOOL); VOID freep (LPTSTR *); LPTSTR _stpcpy (LPTSTR, LPCTSTR); _____
Modified: trunk/reactos/subsys/system/cmd/dir.c --- trunk/reactos/subsys/system/cmd/dir.c 2005-11-02 01:39:30 UTC (rev 18946) +++ trunk/reactos/subsys/system/cmd/dir.c 2005-11-02 13:49:14 UTC (rev 18947) @@ -228,20 +228,29 @@
* * Parse the parameters and switches of the command line and exports them */ -static BOOL -DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */ - LPTSTR *param, /* [OUT] The parameters after parsing */ - LPDIRSWITCHFLAGS lpFlags) /* [IN/OUT] The flags after calculating switches */ +static BOOL DirReadParam(LPTSTR Line, /* [IN] The line with the parameters & switches */ + LPTSTR** params, /* [OUT] The parameters after parsing */ + LPINT entries, /* [OUT] The number of parameters after parsing */ + LPDIRSWITCHFLAGS lpFlags) /* [IN/OUT] The flags after calculating switches */ { - TCHAR cCurSwitch; /* The current switch */ - TCHAR cCurChar; /* Current examing character */ - TCHAR cCurUChar; /* Current upper examing character */ - BOOL bNegative; /* Negative switch */ - BOOL bPNegative; /* Negative switch parameter */ - BOOL bIntoQuotes; /* A flag showing if we are in quotes (") */ - LPTSTR ptrLast; /* A pointer to the last character of param */ + TCHAR cCurSwitch; /* The current switch */ + TCHAR cCurChar; /* Current examing character */ + TCHAR cCurUChar; /* Current upper examing character */ + BOOL bNegative; /* Negative switch */ + BOOL bPNegative; /* Negative switch parameter */ + BOOL bIntoQuotes; /* A flag showing if we are in quotes (") */ + LPTSTR ptrStart; /* A pointer to the first character of a parameter */ + LPTSTR ptrEnd; /* A pointer to the last character of a parameter */ + LPTSTR temp;
- + /* Initialize parameter array */ + *params = malloc(sizeof(LPTSTR)); + if(!params) + return FALSE; + *params = NULL; + *entries = 0; + ptrStart = NULL; + ptrEnd = NULL;
/* Initialize variables; */ cCurSwitch = _T(' '); @@ -249,10 +258,6 @@ bPNegative = FALSE; bIntoQuotes = FALSE;
- /* No parameters yet */ - *param = NULL; - ptrLast = NULL; - /* We suppose that switch parameters were given to avoid setting them to default if the switch was not given */ @@ -352,8 +357,25 @@ if (!bIntoQuotes) { cCurSwitch = _T(' '); - if ((*param) && !(ptrLast)) - ptrLast = Line; + if(ptrStart && ptrEnd) + { + temp = malloc((ptrEnd - ptrStart) + 2 * sizeof (TCHAR)); + if(!temp) + return FALSE; + memcpy(temp, ptrStart, (ptrEnd - ptrStart) + 2 * sizeof (TCHAR)); + temp[(ptrEnd - ptrStart + 1)] = _T('\0'); + if(!add_entry(entries, params, temp)) + { + free(temp); + freep(*params); + return FALSE; + } + + free(temp); + + ptrStart = NULL; + ptrEnd = NULL; + } }
} @@ -361,19 +383,35 @@ { /* Process a quote */ bIntoQuotes = !bIntoQuotes; - if (!bIntoQuotes) ptrLast = Line; + if(!bIntoQuotes) + ptrEnd = Line; } else { /* Process a character for parameter */ - if ((cCurSwitch == _T(' ')) && (*param)) - { - error_too_many_parameters(Line); - return FALSE; + if ((cCurSwitch == _T(' ')) && ptrStart && ptrEnd) + { + temp = malloc((ptrEnd - ptrStart) + 2 * sizeof (TCHAR)); + if(!temp) + return FALSE; + memcpy(temp, ptrStart, (ptrEnd - ptrStart) + 2 * sizeof (TCHAR)); + temp[(ptrEnd - ptrStart + 1)] = _T('\0'); + if(!add_entry(entries, params, temp)) + { + free(temp); + freep(*params); + return FALSE; + } + + free(temp); + + ptrStart = NULL; + ptrEnd = NULL; } cCurSwitch = _T('P'); - if (!(*param)) - *param = Line; + if(!ptrStart) + ptrStart = ptrEnd = Line; + ptrEnd = Line; } } else @@ -522,8 +560,26 @@ Line++; } /* Terminate the parameters */ - if (ptrLast) *ptrLast = 0; + if(ptrStart && ptrEnd) + { + temp = malloc((ptrEnd - ptrStart) + 2 * sizeof (TCHAR)); + if(!temp) + return FALSE; + memcpy(temp, ptrStart, (ptrEnd - ptrStart) + 2 * sizeof (TCHAR)); + temp[(ptrEnd - ptrStart + 1)] = _T('\0'); + if(!add_entry(entries, params, temp)) + { + free(temp); + freep(*params); + return FALSE; + }
+ free(temp); + + ptrStart = NULL; + ptrEnd = NULL; + } + /* Calculate the switches with no switch paramater */ if (!(lpFlags->stAttribs.bParSetted)) { @@ -1120,7 +1176,21 @@ ConOutPrintf(szMsg,ulFiles, szBuffer); }
- /* Print total directories and freespace */ + /* Print File Summary */ + /* Condition to print summary is: + If we are not in bare format and if we have results! */ + if (ulFiles > 0) + { + ConvertULargeInteger(u64Bytes, szBuffer, 20, lpFlags->bTSeperator); + LoadString(CMD_ModuleHandle, STRING_DIR_HELP8, szMsg, RC_STRING_MAX_SIZE); + if(lpFlags->bPause) + ConOutPrintfPaging(FALSE,szMsg,ulFiles, szBuffer); + else + ConOutPrintf(szMsg,ulFiles, szBuffer); + + } + + /* Print total directories and freespace */ szRoot[0] = szPath[0]; GetUserDiskFreeSpace(szRoot, &uliFree); ConvertULargeInteger(uliFree, szBuffer, sizeof(szBuffer), lpFlags->bTSeperator); @@ -1710,13 +1780,11 @@ PDIRFINDLISTNODE ptrNextNode; /* A pointer used for relatives refernces */ TCHAR szFullPath[MAX_PATH]; /* The full path that we are listing with trailing \ */ TCHAR szFullFileSpec[MAX_PATH]; /* The full path with file specs that we ll request\ */ -TCHAR szBytes[20]; /* A string for converting ULARGE integer */ DWORD dwCount; /* A counter of files found in directory */ DWORD dwCountFiles; /* Counter for files */ DWORD dwCountDirs; /* Counter for directories */ ULARGE_INTEGER u64CountBytes; /* Counter for bytes */ ULARGE_INTEGER u64Temp; /* A temporary counter */ -TCHAR szMsg[RC_STRING_MAX_SIZE];
/* Initialize Variables */ ptrStartNode = NULL; @@ -1853,20 +1921,6 @@ /* Free array */ free(ptrFileArray);
- /* Print Directory Summary */ - /* Condition to print summary is: - If we are not in bare format and if we have results! */ - if (!(lpFlags->bBareFormat) && (dwCount > 0)) - { - ConvertULargeInteger(u64CountBytes, szBytes, 20, lpFlags->bTSeperator); - LoadString(CMD_ModuleHandle, STRING_DIR_HELP8, szMsg, RC_STRING_MAX_SIZE); - if(lpFlags->bPause) - ConOutPrintfPaging(FALSE,szMsg,dwCountFiles, szBytes); - else - ConOutPrintf(szMsg,dwCountFiles, szBytes); - - } - /* Add statistics to recursive statistics*/ recurse_dir_cnt += dwCountDirs; recurse_file_cnt += dwCountFiles; @@ -1922,14 +1976,18 @@ */ INT CommandDir(LPTSTR first, LPTSTR rest) { - TCHAR dircmd[256]; /* A variable to store the DIRCMD enviroment variable */ - TCHAR szPath[MAX_PATH]; - TCHAR szFilespec[MAX_PATH]; - LPTSTR param; - INT nLine = 0; + TCHAR dircmd[256]; /* A variable to store the DIRCMD enviroment variable */ + TCHAR cDrive; + TCHAR szPath[MAX_PATH]; + TCHAR szFilespec[MAX_PATH]; + LPTSTR* params; + UINT entries = 0; + INT nLine = 0; + UINT loop = 0; DIRSWITCHFLAGS stFlags;
/* Initialize variables */ + cDrive = 0; recurse_dir_cnt = 0L; recurse_file_cnt = 0L; recurse_bytes.QuadPart = 0; @@ -1958,67 +2016,77 @@ /* read the parameters from the DIRCMD environment variable */ if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, 256)) - if (!DirReadParam(dircmd, ¶m, &stFlags)) + if (!DirReadParam(dircmd, ¶ms, &entries, &stFlags)) { nErrorLevel = 1; return 1; }
/* read the parameters */ - if (!DirReadParam(rest, ¶m, &stFlags)) + if (!DirReadParam(rest, ¶ms, &entries, &stFlags)) { nErrorLevel = 1; return 1; }
/* default to current directory */ - if (!param) - param = _T("."); - - /* parse the directory info */ - if (DirParsePathspec (param, szPath, szFilespec)) - { - nErrorLevel = 1; - return 1; + if(entries == 0) { + if(!add_entry(&entries, ¶ms, _T("."))) { + nErrorLevel = 1; + return 1; + } }
-/* <Debug :> - Uncomment this to show the final state of switch flags*/ -#ifdef _DEBUG + for(loop = 0; loop < entries; loop++) { - int i; - ConOutPrintf(_T("Attributes mask/value %x/%x\n"),stFlags.stAttribs.dwAttribMask,stFlags.stAttribs.dwAttribVal ); - ConOutPrintf(_T("(B) Bare format : %i\n"), stFlags.bBareFormat ); - ConOutPrintf(_T("(C) Thousand : %i\n"), stFlags.bTSeperator ); - ConOutPrintf(_T("(W) Wide list : %i\n"), stFlags.bWideList ); - ConOutPrintf(_T("(D) Wide list sort by column : %i\n"), stFlags.bWideListColSort ); - ConOutPrintf(_T("(L) Lowercase : %i\n"), stFlags.bLowerCase ); - ConOutPrintf(_T("(N) New : %i\n"), stFlags.bNewLongList ); - ConOutPrintf(_T("(O) Order : %i\n"), stFlags.stOrderBy.sCriteriaCount ); - for (i =0;i<stFlags.stOrderBy.sCriteriaCount;i++) - ConOutPrintf(_T(" Order Criteria [%i]: %i (Reversed: %i)\n"),i, stFlags.stOrderBy.eCriteria[i], stFlags.stOrderBy.bCriteriaRev[i] ); - ConOutPrintf(_T("(P) Pause : %i\n"), stFlags.bPause ); - ConOutPrintf(_T("(Q) Owner : %i\n"), stFlags.bUser ); - ConOutPrintf(_T("(S) Recursive : %i\n"), stFlags.bRecursive ); - ConOutPrintf(_T("(T) Time field : %i\n"), stFlags.stTimeField.eTimeField ); - ConOutPrintf(_T("(X) Short names : %i\n"), stFlags.bShortName ); - ConOutPrintf(_T("Parameter : %s\n"), param ); - } -#endif + /* parse the directory info */ + if (DirParsePathspec (params[loop], szPath, szFilespec)) + { + nErrorLevel = 1; + return 1; + }
- /* print the header */ - if (!stFlags.bBareFormat) - if (!PrintDirectoryHeader (szPath, &nLine, &stFlags)) + /* <Debug :> + Uncomment this to show the final state of switch flags*/ + #ifdef _DEBUG { + int i; + ConOutPrintf(_T("Attributes mask/value %x/%x\n"),stFlags.stAttribs.dwAttribMask,stFlags.stAttribs.dwAttribVal ); + ConOutPrintf(_T("(B) Bare format : %i\n"), stFlags.bBareFormat ); + ConOutPrintf(_T("(C) Thousand : %i\n"), stFlags.bTSeperator ); + ConOutPrintf(_T("(W) Wide list : %i\n"), stFlags.bWideList ); + ConOutPrintf(_T("(D) Wide list sort by column : %i\n"), stFlags.bWideListColSort ); + ConOutPrintf(_T("(L) Lowercase : %i\n"), stFlags.bLowerCase ); + ConOutPrintf(_T("(N) New : %i\n"), stFlags.bNewLongList ); + ConOutPrintf(_T("(O) Order : %i\n"), stFlags.stOrderBy.sCriteriaCount ); + for (i =0;i<stFlags.stOrderBy.sCriteriaCount;i++) + ConOutPrintf(_T(" Order Criteria [%i]: %i (Reversed: %i)\n"),i, stFlags.stOrderBy.eCriteria[i], stFlags.stOrderBy.bCriteriaRev[i] ); + ConOutPrintf(_T("(P) Pause : %i\n"), stFlags.bPause ); + ConOutPrintf(_T("(Q) Owner : %i\n"), stFlags.bUser ); + ConOutPrintf(_T("(S) Recursive : %i\n"), stFlags.bRecursive ); + ConOutPrintf(_T("(T) Time field : %i\n"), stFlags.stTimeField.eTimeField ); + ConOutPrintf(_T("(X) Short names : %i\n"), stFlags.bShortName ); + ConOutPrintf(_T("Parameter : %s\n"), params[loop] ); + } + #endif + + /* Print the drive header if the drive changed */ + if(cDrive != szPath[0] && !stFlags.bBareFormat) { + if (!PrintDirectoryHeader (szPath, &nLine, &stFlags)) { + nErrorLevel = 1; + return 1; + } + + cDrive = szPath[0]; + } + + + /* do the actual dir */ + if (DirList (szPath, szFilespec, &nLine, &stFlags)) + { nErrorLevel = 1; return 1; } - - /* do the actual dir */ - if (DirList (szPath, szFilespec, &nLine, &stFlags)) - { - nErrorLevel = 1; - return 1; }
/* print the footer */ _____
Modified: trunk/reactos/subsys/system/cmd/misc.c --- trunk/reactos/subsys/system/cmd/misc.c 2005-11-02 01:39:30 UTC (rev 18946) +++ trunk/reactos/subsys/system/cmd/misc.c 2005-11-02 13:49:14 UTC (rev 18947) @@ -162,7 +162,7 @@
}
/* add new entry for new argument */ -static BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry) +BOOL add_entry (LPINT ac, LPTSTR **arg, LPCTSTR entry) { LPTSTR q; LPTSTR *oldarg;