home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / crt / src / rename.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  10KB  |  363 lines

  1. /***
  2. *rename.c - rename file
  3. *
  4. *       Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Defines rename() - rename a file
  8. *
  9. *******************************************************************************/
  10.  
  11. #ifndef _MAC
  12.  
  13. #include <cruntime.h>
  14. #include <oscalls.h>
  15. #include <internal.h>
  16. #include <io.h>
  17. #include <tchar.h>
  18.  
  19. /***
  20. *int rename(oldname, newname) - rename a file
  21. *
  22. *Purpose:
  23. *       Renames a file to a new name -- no file with new name must
  24. *       currently exist.
  25. *
  26. *Entry:
  27. *       _TSCHAR *oldname -      name of file to rename
  28. *       _TSCHAR *newname -      new name for file
  29. *
  30. *Exit:
  31. *       returns 0 if successful
  32. *       returns not 0 and sets errno if not successful
  33. *
  34. *Exceptions:
  35. *
  36. *******************************************************************************/
  37.  
  38. int __cdecl _trename (
  39.         const _TSCHAR *oldname,
  40.         const _TSCHAR *newname
  41.         )
  42. {
  43.         ULONG dosretval;
  44.  
  45.         /* ask OS to move file */
  46.  
  47.         if (!MoveFile((LPTSTR)oldname, (LPTSTR)newname))
  48.             dosretval = GetLastError();
  49.         else
  50.             dosretval = 0;
  51.  
  52.         if (dosretval) {
  53.             /* error occured -- map error code and return */
  54.             _dosmaperr(dosretval);
  55.             return -1;
  56.         }
  57.  
  58.         return 0;
  59. }
  60.  
  61. #else  /* _MAC */
  62.  
  63.  
  64. #include <cruntime.h>
  65. #include <internal.h>
  66. #include <io.h>
  67. #include <string.h>
  68. #include <direct.h>
  69. #include <errno.h>
  70. #include <stdlib.h>
  71. #include <macos\osutils.h>
  72. #include <macos\files.h>
  73. #include <macos\errors.h>
  74.  
  75. /***
  76. *int rename(oldname, newname) - rename a file
  77. *
  78. *Purpose:
  79. *       Renames a file to a new name -- no file with new name must
  80. *       currently exist.
  81. *
  82. *Entry:
  83. *       char *oldname -         name of file to rename
  84. *       char *newname -         new name for file
  85. *
  86. *Exit:
  87. *       returns 0 if successful
  88. *       returns not 0 and sets errno if not successful
  89. *
  90. *Exceptions:
  91. *
  92. *******************************************************************************/
  93. void __getdirandname(char *szdir, char *szname, const char *szpath);
  94. int __srename ( const char *oldname, const char *newname);
  95. int __accesspath (const char *dirname, const char *filename);
  96.  
  97. int __cdecl rename (
  98.         const char *oldname,
  99.         const char *newname
  100.         )
  101. {
  102.         /* ask OS to move file */
  103.         HParamBlockRec hparamBlock;
  104.         char szOldName[32];       //old file name
  105.         char szOldDir[256];       //old dir name
  106.         char szNewName[32];       //new file name
  107.         char szNewDir[256];       //new dir name
  108.         char st[256];             //temp array for p-c string convertion
  109.         char st2[256];            //temp array for p-c string conversion
  110.         char szT[9];              //temp file name
  111.         OSErr osErr;
  112.         CMovePBRec cmovePB;
  113.         int fTemp = 0;
  114.         char *pch;
  115.         char *pchOld;
  116.  
  117.         pchOld = strrchr(oldname, ':');
  118.         if ( (pchOld!= NULL) && (*(pchOld+1) == '\0') &&
  119.              (strchr(oldname, ':') == strrchr(oldname, ':')) )
  120.         {
  121.             /* rename a volume*/
  122.             pch = strrchr(newname, ':');
  123.             if (pch != NULL && *(pch+1) != '\0')
  124.             {
  125.                 /* not rename to another volume name*/
  126.                 errno = EINVAL;
  127.                 return -1;
  128.             }
  129.             else if (pch != NULL && *(pch+1) == '\0')
  130.             {
  131.                 osErr = __srename(oldname, newname);
  132.                 if (osErr)
  133.                 {
  134.                     _dosmaperr(osErr);
  135.                     return -1;
  136.                 }
  137.                     return 0;
  138.             }
  139.             else if (pch == NULL)
  140.             {
  141.                 strcpy(szNewName, newname);
  142.                 strcat(szNewName, ":");
  143.                 osErr = __srename(oldname, szNewName);
  144.                 if (osErr)
  145.                 {
  146.                     _dosmaperr(osErr);
  147.                     return -1;
  148.                 }
  149.                 return 0;
  150.             }
  151.         }
  152.  
  153.         /*Separate file name and directory*/
  154.         __getdirandname(szOldDir, szOldName, oldname);
  155.         __getdirandname(szNewDir, szNewName, newname);
  156.         if (strcmp(szNewName, "")==0)
  157.         {
  158.             errno = EINVAL;
  159.             return -1;
  160.         }
  161.  
  162.         /*if same dir*/
  163.         if (strcmp(szNewDir, szOldDir)==0 )
  164.         {
  165.             osErr = __srename(oldname, newname);
  166.             if (osErr)
  167.             {
  168.                 /* error occured -- map error code and return */
  169.                 _dosmaperr(osErr);
  170.                 return -1;
  171.             }
  172.             return 0;
  173.         }
  174.  
  175.         /*if new directory didn't supplied, getcwd*/
  176.         if (!*szNewDir)
  177.         {
  178.             _getcwd(szNewDir, 255);
  179.         }
  180.  
  181.  
  182.         /*if same name*/
  183.         if (strcmp(szNewName, szOldName)==0 )
  184.         {
  185.             /*just move*/
  186.             strcpy(st, oldname);
  187.             strcpy(st2, szNewDir);
  188.             cmovePB.ioNamePtr = _c2pstr(st);
  189.             cmovePB.ioVRefNum = 0;
  190.             cmovePB.ioNewName =_c2pstr(st2);
  191.             cmovePB.ioNewDirID = 0;
  192.             cmovePB.ioDirID = 0;
  193.             osErr = PBCatMoveSync(&cmovePB);
  194.             if (osErr)
  195.             {
  196.                 /* error occured -- map error code and return */
  197.                 if (osErr == nsvErr || osErr == bdNamErr)
  198.                 {
  199.                     errno = EXDEV;
  200.                     _macerrno = osErr;
  201.                 }
  202.                 else
  203.                     _dosmaperr(osErr);
  204.                     return -1;
  205.             }
  206.                 return 0;
  207.         }
  208.  
  209.         osErr = __accesspath(szOldDir, szNewName);
  210.         if (osErr != fnfErr)
  211.         {
  212.             /* rename the file to a temp name */
  213.             strcpy(st, szOldDir);
  214.             strcpy(szT, "fnXXXXXX");
  215.             if (_mktemp(szT)!=NULL)
  216.             {
  217.                 strcat(st, szT);
  218.                 fTemp = 1;
  219.             }
  220.         }
  221.         else
  222.         {
  223.             *st='\0';
  224.             if (*szOldDir)
  225.             {
  226.                 strcpy(st, szOldDir);
  227.             }
  228.             strcat(st, szNewName);
  229.         }
  230.         osErr = __srename(oldname, st);
  231.         if (osErr)
  232.         {
  233.             _dosmaperr(osErr);
  234.             return -1;
  235.         }
  236.  
  237.         strcpy(st2, szNewDir);
  238.         /* move renamed file to new dir */
  239.         cmovePB.ioNamePtr = _c2pstr(st);
  240.         cmovePB.ioVRefNum = 0;
  241.         cmovePB.ioNewName =_c2pstr(st2);
  242.         cmovePB.ioNewDirID = 0;
  243.         cmovePB.ioDirID = 0;
  244.         osErr = PBCatMoveSync(&cmovePB);
  245.         if (osErr) {
  246.             /* error occured -- rename oldname back */
  247.             strcpy(st2, oldname);
  248.             hparamBlock.ioParam.ioNamePtr = st;
  249.             hparamBlock.ioParam.ioVRefNum = 0;
  250.             hparamBlock.ioParam.ioMisc = _c2pstr(st2);
  251.             hparamBlock.fileParam.ioDirID = 0;
  252.             PBHRenameSync(&hparamBlock);
  253.             if (osErr == nsvErr || osErr == bdNamErr)
  254.             {
  255.                 errno=EXDEV;
  256.                 _macerrno = osErr;
  257.             }
  258.             else
  259.                 _dosmaperr(osErr);
  260.                 return -1;
  261.         }
  262.  
  263.         /* rename it to the new name in new dir*/
  264.         if (fTemp)
  265.         {
  266.             strcpy(st, szNewDir);
  267.             strcat(st, szT);
  268.             osErr = __srename(st, newname);
  269.             if (osErr)
  270.             {
  271.                 _dosmaperr(osErr);
  272.                 remove(st);
  273.                 return -1;
  274.             }
  275.         }
  276.         return 0;
  277. }
  278.  
  279.  
  280.  
  281. void __getdirandname (
  282.         char *szdir,
  283.         char *szname,
  284.         const char *szpath
  285.         )
  286. {
  287.         char *pch;
  288.  
  289.         pch = strrchr(szpath, ':');
  290.         if (pch)
  291.         {
  292.             strcpy(szname, pch+1);
  293.             strncpy(szdir, szpath, (pch - szpath)+1);
  294.             szdir[(pch-szpath)+1]='\0';
  295.         }
  296.         else //no ':'
  297.         {
  298.             strcpy(szname, szpath);
  299.             *szdir = '\0';
  300.         }
  301. }
  302.  
  303. int __srename (
  304.         const char *oldname,
  305.         const char *newname
  306.         )
  307. {
  308.         /* ask OS to move file */
  309.         HParamBlockRec hparamBlock;
  310.         char stOld[256];
  311.         char stNew[256];
  312.         OSErr osErr;
  313.  
  314.         strcpy(stOld, oldname);
  315.         strcpy(stNew, newname);
  316.         hparamBlock.ioParam.ioNamePtr = _c2pstr(stOld);
  317.         hparamBlock.ioParam.ioVRefNum = 0;
  318.         hparamBlock.ioParam.ioMisc = _c2pstr(stNew);
  319.         hparamBlock.fileParam.ioDirID = 0;
  320.         osErr = PBHRenameSync(&hparamBlock);
  321.         return osErr;
  322. }
  323.  
  324. int __accesspath (
  325.         const char *dirname,
  326.         const char *filename
  327.         )
  328. {
  329.         CInfoPBRec cinfoPB;
  330.         OSErr osErr;
  331.         char szBuf[256];
  332.  
  333.         szBuf[0]='\0';
  334.         if (*dirname)
  335.         {
  336.             strcpy(szBuf, dirname);
  337.         }
  338.         strcat(szBuf, filename);
  339.         cinfoPB.hFileInfo.ioNamePtr = _c2pstr(szBuf);
  340.         cinfoPB.hFileInfo.ioFDirIndex = 0;
  341.         cinfoPB.hFileInfo.ioVRefNum = 0;
  342.         cinfoPB.hFileInfo.ioDirID = 0;
  343.         osErr = PBGetCatInfoSync(&cinfoPB);
  344.         if (osErr)
  345.         {
  346.             return osErr;
  347.         }
  348.         else
  349.         {
  350.             /* file or dir ? */
  351.             if (cinfoPB.hFileInfo.ioFlAttrib & 0x10)
  352.             { /*dir*/
  353.                 return 1;
  354.             }
  355.             else
  356.             {
  357.                 return 0;
  358.             }
  359.         }
  360. }
  361.  
  362. #endif  /* _MAC */
  363.