/* * REN.C - rename internal command. * * * History: * * 27-Jul-1998 (John P Price ) * added config.h include * * 18-Dec-1998 (Eric Kohl * Added support for quoted long file names with spaces. * * 20-Jan-1999 (Eric Kohl * Unicode and redirection safe! * * 17-Oct-2001 (Eric Kohl * Implemented basic rename code. */ #include "config.h" #ifdef INCLUDE_CMD_RENAME #include #include #include #include #include "cmd.h" #include "batch.h" enum { REN_ATTRIBUTES = 0x001, /* /A : not implemented */ REN_ERROR = 0x002, /* /E */ REN_NOTHING = 0x004, /* /N */ REN_PROMPT = 0x008, /* /P : not implemented */ REN_QUIET = 0x010, /* /Q */ REN_SUBDIR = 0x020, /* /S */ REN_TOTAL = 0x040, /* /T */ }; /* * file rename internal command. * */ INT cmd_rename (LPTSTR cmd, LPTSTR param) { LPTSTR *arg = NULL; INT args = 0; INT nEvalArgs = 0; /* nunber of evaluated arguments */ DWORD dwFlags = 0; DWORD dwFiles = 0; /* number of renamedd files */ INT i; LPTSTR srcPattern = NULL; LPTSTR dstPattern = NULL; TCHAR dstFile[MAX_PATH]; BOOL bDstWildcard = FALSE; LPTSTR p,q,r; HANDLE hFile; WIN32_FIND_DATA f; if (!_tcsncmp(param, _T("/?"), 2)) { ConOutPuts(_T("Renames a file/directory or files/directories.\n" "\n" "RENAME [/E /N /P /Q /S /T] old_name ... new_name\n" "REN [/E /N /P /Q /S /T] old_name ... new_name\n" "\n" " /E No eror messages.\n" " /N Nothing.\n" " /P Prompts for confirmation before renaming each file.\n" " (Not implemented yet!)\n" " /Q Quiet.\n" " /S Rename subdirectories.\n" " /T Display total number of renamed files.\n" "\n" "Note that you cannot specify a new drive or path for your destination. Use\n" "the MOVE command for that purpose.")); return(0); } /* split the argument list */ arg = split(param, &args); if (args < 2) { if (!(dwFlags & REN_ERROR)) error_req_param_missing(); freep(arg); return(1); } /* read options */ for (i = 0; i < args; i++) { if (*arg[i] == _T('/')) { if (_tcslen(arg[i]) >= 2) { switch (_totupper(arg[i][1])) { case _T('E'): dwFlags |= REN_ERROR; break; case _T('N'): dwFlags |= REN_NOTHING; break; case _T('P'): dwFlags |= REN_PROMPT; break; case _T('Q'): dwFlags |= REN_QUIET; break; case _T('S'): dwFlags |= REN_SUBDIR; break; case _T('T'): dwFlags |= REN_TOTAL; break; } } nEvalArgs++; } } /* keep quiet within batch files */ if (bc != NULL) dwFlags |= REN_QUIET; /* there are only options on the command line --> error!!! */ if (args < nEvalArgs + 2) { if (!(dwFlags & REN_ERROR)) error_req_param_missing(); freep(arg); return(1); } /* get destination pattern */ for (i = 0; i < args; i++) { if (*arg[i] == _T('/')) continue; dstPattern = arg[i]; } if (_tcschr(dstPattern, _T('*')) || _tcschr(dstPattern, _T('?'))) bDstWildcard = TRUE; /* enumerate source patterns */ for (i = 0; i < args; i++) { if (*arg[i] == _T('/') || arg[i] == dstPattern) continue; srcPattern = arg[i]; #ifdef _DEBUG ConErrPrintf(_T("\n\nSourcePattern: %s\n"), srcPattern); ConErrPrintf(_T("DestinationPattern: %s\n"), dstPattern); #endif hFile = FindFirstFile(srcPattern, &f); if (hFile == INVALID_HANDLE_VALUE) { if (!(dwFlags & REN_ERROR)) error_file_not_found(); continue; } do { /* ignore "." and ".." */ if (!_tcscmp (f.cFileName, _T(".")) || !_tcscmp (f.cFileName, _T(".."))) continue; /* do not rename hidden or system files */ if (f.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) continue; /* do not rename directories when the destination pattern contains * wildcards, unless option /S is used */ if ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && bDstWildcard && !(dwFlags & REN_SUBDIR)) continue; #ifdef _DEBUG ConErrPrintf(_T("Found source name: %s\n"), f.cFileName); #endif /* build destination file name */ p = f.cFileName; q = dstPattern; r = dstFile; while(*q != 0) { if (*q == '*') { q++; while (*p != 0 && *p != *q) { *r = *p; p++; r++; } } else if (*q == '?') { q++; if (*p != 0) { *r = *p; p++; r++; } } else { *r = *q; if (*p != 0) p++; q++; r++; } } *r = 0; #ifdef _DEBUG ConErrPrintf(_T("DestinationFile: %s\n"), dstFile); #endif if (!(dwFlags & REN_QUIET) && !(dwFlags & REN_TOTAL)) ConOutPrintf(_T("%s -> %s\n"), f.cFileName, dstFile); /* rename the file */ if (!(dwFlags & REN_NOTHING)) { if (MoveFile(f.cFileName, dstFile)) { dwFiles++; } else { if (!(dwFlags & REN_ERROR)) ConErrPrintf(_T("MoveFile() failed. Error: %lu\n"), GetLastError()); } } } while (FindNextFile(hFile, &f)); FindClose(hFile); } if (!(dwFlags & REN_QUIET)) { if (dwFiles == 1) ConOutPrintf(_T(" %lu file renamed\n"), dwFiles); else ConOutPrintf(_T(" %lu files renamed\n"), dwFiles); } freep(arg); return(0); } #endif /* EOF */