ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ren.c
Go to the documentation of this file.
00001 /*
00002  *  REN.C - rename internal command.
00003  *
00004  *
00005  *  History:
00006  *
00007  *
00008  *    27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
00009  *        added config.h include
00010  *
00011  *    18-Dec-1998 (Eric Kohl)
00012  *        Added support for quoted long file names with spaces.
00013  *
00014  *    20-Jan-1999 (Eric Kohl)
00015  *        Unicode and redirection safe!
00016  *
00017  *    17-Oct-2001 (Eric Kohl)
00018  *        Implemented basic rename code.
00019  *
00020  *    30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
00021  *        Remove all hardcode string to En.rc
00022  *    25-Nov-2008 (Victor Martinez) <vicmarcal@hotmail.com> Patch dedicated to Myrjala because her comprenhension and love :D
00023  *        Fixing following Bugs:
00024  *             -Wrong behavior with wildcards when Source and Destiny are Paths(FIXED).
00025  *             -Wrong general behavior (MSDN:"Rename cant move files between subdirectories")(FIXED)
00026  *             -Wrong behavior when renaming without path in destiny:(i.e) "ren C:\text\as.txt list.txt" it moves as.txt and then rename it(FIXED)
00027  *              (MSDN: If there is a Path in Source and no Path in Destiny, then Destiny Path is Source Path,because never Ren has to be used to move.)
00028  *             -Implemented checkings if SourcePath and DestinyPath are differents.
00029  *
00030  */
00031 
00032 #include <precomp.h>
00033 
00034 #ifdef INCLUDE_CMD_RENAME
00035 
00036 enum
00037 {
00038   REN_ATTRIBUTES = 0x001,   /* /A : not implemented */
00039   REN_ERROR      = 0x002,   /* /E */
00040   REN_NOTHING    = 0x004,   /* /N */
00041   REN_PROMPT     = 0x008,   /* /P : not implemented */
00042   REN_QUIET      = 0x010,   /* /Q */
00043   REN_SUBDIR     = 0x020,   /* /S */
00044   REN_TOTAL      = 0x040,   /* /T */
00045 };
00046 
00047 
00048 /*
00049  *  file rename internal command.
00050  *
00051  */
00052 INT cmd_rename (LPTSTR param)
00053 {
00054   LPTSTR *arg = NULL;
00055   INT args = 0;
00056   INT nSlash = 0;
00057   INT nEvalArgs = 0; /* nunber of evaluated arguments */
00058   DWORD dwFlags = 0;
00059   DWORD dwFiles = 0; /* number of renamedd files */
00060   INT i;
00061 
00062 
00063   LPTSTR srcPattern = NULL; /* Source Argument*/
00064   TCHAR srcPath[MAX_PATH]; /*Source Path Directories*/
00065   LPTSTR srcFILE = NULL;  /*Contains the files name(s)*/
00066   TCHAR srcFinal[MAX_PATH];
00067 
00068 
00069   LPTSTR dstPattern = NULL; /*Destiny Argument*/
00070   TCHAR dstPath[MAX_PATH]; /*Source Path Directories*/
00071   LPTSTR dstFILE = NULL; /*Contains the files name(s)*/
00072 
00073   TCHAR dstLast[MAX_PATH]; /*It saves the File name after unmasked with wildcarts*/
00074   TCHAR dstFinal[MAX_PATH]; /*It saves the Final destiny Path*/
00075 
00076   BOOL bDstWildcard = FALSE;
00077   BOOL bPath = FALSE;
00078 
00079 
00080 
00081 
00082 
00083 
00084   LPTSTR p,q,r;
00085 
00086   HANDLE hFile;
00087   WIN32_FIND_DATA f;
00088  /*If the PARAM=/? then show the help*/
00089   if (!_tcsncmp(param, _T("/?"), 2))
00090   {
00091 
00092 
00093     ConOutResPaging(TRUE,STRING_REN_HELP1);
00094     return 0;
00095   }
00096 
00097   nErrorLevel = 0;
00098 
00099   /* Split the argument list.Args will be saved in arg vector*/
00100   arg = split(param, &args, FALSE, FALSE);
00101 
00102   if (args < 2)
00103     {
00104       if (!(dwFlags & REN_ERROR))
00105     error_req_param_missing();
00106       freep(arg);
00107       return 1;
00108     }
00109 
00110   /* Read options */
00111   for (i = 0; i < args; i++)
00112     {
00113     /* Lets check if we have a special option choosen and set the flag(s)*/
00114       if (*arg[i] == _T('/'))
00115         {
00116             if (_tcslen(arg[i]) >= 2)
00117              {
00118                  switch (_totupper(arg[i][1]))
00119                     {
00120                          case _T('E'):
00121                          dwFlags |= REN_ERROR;
00122                          break;
00123 
00124                          case _T('N'):
00125                         dwFlags |= REN_NOTHING;
00126                          break;
00127 
00128                         case _T('P'):
00129                         dwFlags |= REN_PROMPT;
00130                         break;
00131 
00132                         case _T('Q'):
00133                         dwFlags |= REN_QUIET;
00134                         break;
00135 
00136                         case _T('S'):
00137                         dwFlags |= REN_SUBDIR;
00138                         break;
00139 
00140                         case _T('T'):
00141                         dwFlags |= REN_TOTAL;
00142                         break;
00143                     }
00144                 }
00145         nEvalArgs++;//Save the number of the options.
00146         }
00147     }
00148 
00149   /* keep quiet within batch files */
00150   if (bc != NULL)
00151     dwFlags |= REN_QUIET;
00152 
00153   /* there are only options on the command line --> error!!! */
00154   if (args < nEvalArgs + 2)
00155     {
00156       if (!(dwFlags & REN_ERROR))
00157         error_req_param_missing();
00158         freep(arg);
00159         return 1;
00160     }
00161 
00162 
00163   /* Get destination pattern and source pattern*/
00164   for (i = 0; i < args; i++)
00165     {
00166       if (*arg[i] == _T('/'))//We have find an Option.Jump it.
00167         continue;
00168       dstPattern = arg[i]; //we save the Last argument as dstPattern
00169       srcPattern = arg[i-1];
00170 
00171     }
00172 
00173 
00174 
00175 
00176 
00177   if (_tcschr(srcPattern, _T('\\')))  //Checking if the Source (srcPattern) is a Path to the file
00178     {
00179 
00180         bPath= TRUE;
00181 
00182         //Splitting srcPath and srcFile.
00183 
00184         srcFILE = _tcschr(srcPattern, _T('\\'));
00185         nSlash++;
00186         while(_tcschr(srcFILE, _T('\\')))
00187             {
00188             srcFILE++;
00189             if(*srcFILE==_T('\\')) nSlash++ ;
00190             if(!_tcschr(srcFILE, _T('\\'))) break;
00191             }
00192         _tcsncpy(srcPath,srcPattern,_tcslen(srcPattern)-_tcslen(srcFILE));
00193 
00194 
00195 
00196         if(_tcschr(dstPattern, _T('\\'))) //Checking if the Destiny (dstPattern)is also a Path.And splitting dstPattern in dstPath and srcPath.
00197             {
00198                 dstFILE = _tcschr(dstPattern, _T('\\'));
00199                 nSlash=0;
00200                 while(_tcschr(dstFILE, _T('\\')))
00201                         {
00202                         dstFILE++;
00203                         if(*dstFILE==_T('\\')) nSlash++ ;
00204                         if(!_tcschr(dstFILE, _T('\\'))) break;
00205                         }
00206                 _tcsncpy(dstPath,dstPattern,_tcslen(dstPattern)-_tcslen(dstFILE));
00207 
00208                 if((_tcslen(dstPath)!=_tcslen(srcPath))||(_tcsncmp(srcPath,dstPath,_tcslen(srcPath))!=0)) //If it has a Path,then MUST be equal than srcPath
00209                         {
00210                         error_syntax(dstPath);
00211                         freep(arg);
00212                         return 1;
00213                         }
00214             }else   { //If Destiny hasnt a Path,then (MSDN says) srcPath is its Path.
00215 
00216                     _tcscpy(dstPath,srcPath);
00217 
00218                     dstFILE=dstPattern;
00219 
00220                     }
00221 
00222 
00223 
00224     }
00225 
00226   if (!_tcschr(srcPattern, _T('\\'))) //If srcPattern isnt a Path but a  name:
00227   {
00228     srcFILE=srcPattern;
00229     if(_tcschr(dstPattern, _T('\\')))
00230                 {
00231                         error_syntax(dstPattern);
00232 
00233                         freep(arg);
00234                         return 1;
00235                 }else dstFILE=dstPattern;
00236   }
00237 
00238  //Checking Wildcards.
00239   if (_tcschr(dstFILE, _T('*')) || _tcschr(dstFILE, _T('?')))
00240         bDstWildcard = TRUE;
00241 
00242 
00243 
00244   TRACE("\n\nSourcePattern: %s SourcePath: %s SourceFile: %s", debugstr_aw(srcPattern),debugstr_aw(srcPath),debugstr_aw(srcFILE));
00245   TRACE("\n\nDestinationPattern: %s Destination Path:%s Destination File: %s\n", debugstr_aw(dstPattern),debugstr_aw(dstPath),debugstr_aw(dstFILE));
00246 
00247       hFile = FindFirstFile(srcPattern, &f);
00248 
00249       if (hFile == INVALID_HANDLE_VALUE)
00250         {
00251          if (!(dwFlags & REN_ERROR))
00252                 error_file_not_found();
00253 
00254         }
00255       do
00256         {
00257       /* ignore "." and ".." */
00258          if (!_tcscmp (f.cFileName, _T(".")) ||
00259               !_tcscmp (f.cFileName, _T("..")))
00260          continue;
00261 
00262       /* do not rename hidden or system files */
00263          if (f.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
00264             continue;
00265 
00266       /* do not rename directories when the destination pattern contains
00267        * wildcards, unless option /S is used */
00268           if ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00269              && bDstWildcard
00270              && !(dwFlags & REN_SUBDIR))
00271             continue;
00272 
00273          TRACE("Found source name: %s\n", debugstr_aw(f.cFileName));
00274       /* So here we have splitted the dstFILE and we have find a f.cFileName(thanks to srcPattern)
00275        * Now we have to use the mask (dstFILE) (which can have Wildcards) with f.cFileName to find destination file name(dstLast) */
00276          p = f.cFileName;
00277          q = dstFILE;
00278          r = dstLast;
00279          while(*q != 0)
00280             {
00281                 if (*q == '*')
00282                     {
00283                         q++;
00284                         while (*p != 0 && *p != *q)
00285                             {
00286                             *r = *p;
00287                             p++;
00288                             r++;
00289                             }
00290                     }
00291                     else if (*q == '?')
00292                                 {
00293                                 q++;
00294                                 if (*p != 0)
00295                                      {
00296                                     *r = *p;
00297                                     p++;
00298                                     r++;
00299                                      }
00300                                 }
00301                                 else
00302                                     {
00303                                     *r = *q;
00304                                     if (*p != 0)
00305                                             p++;
00306                                     q++;
00307                                     r++;
00308                                     }
00309             }
00310         *r = 0;
00311         //Well we have splitted the Paths,so now we have to paste them again(if needed),thanks bPath.
00312         if( bPath == TRUE)
00313             {
00314 
00315                 _tcscpy(srcFinal,srcPath);
00316 
00317                 _tcscat(srcFinal,f.cFileName);
00318 
00319                 _tcscpy(dstFinal,dstPath);
00320                 _tcscat(dstFinal,dstLast);
00321 
00322 
00323         }else{
00324                 _tcscpy(srcFinal,f.cFileName);
00325                 _tcscpy(dstFinal,dstLast);
00326 
00327                 }
00328 
00329 
00330 
00331         TRACE("DestinationPath: %s\n", debugstr_aw(dstFinal));
00332 
00333 
00334         if (!(dwFlags & REN_QUIET) && !(dwFlags & REN_TOTAL))
00335 
00336              ConOutPrintf(_T("%s -> %s\n"),srcFinal , dstFinal);
00337 
00338       /* Rename the file */
00339          if (!(dwFlags & REN_NOTHING))
00340          {
00341 
00342 
00343 
00344                 if (MoveFile(srcFinal, dstFinal))
00345             {
00346             dwFiles++;
00347             }
00348             else
00349                 {
00350                  if (!(dwFlags & REN_ERROR))
00351                         {
00352                         ConErrResPrintf(STRING_REN_ERROR1, GetLastError());
00353                         }
00354                 }
00355          }
00356       }
00357 
00358       while (FindNextFile(hFile, &f));
00359 //Closing and Printing errors.
00360 
00361       FindClose(hFile);
00362 
00363 
00364   if (!(dwFlags & REN_QUIET))
00365   {
00366     if (dwFiles == 1)
00367       ConOutResPrintf(STRING_REN_HELP2, dwFiles);
00368     else
00369       ConOutResPrintf(STRING_REN_HELP3, dwFiles);
00370   }
00371 
00372   freep(arg);
00373 
00374   return 0;
00375 }
00376 
00377 #endif
00378 
00379 /* EOF */

Generated on Sun May 27 2012 04:18:15 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.