home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / FCOPY32.ZIP / FCOPY.C < prev    next >
C/C++ Source or Header  |  1992-06-27  |  11KB  |  184 lines

  1. /*  FCOPY.C  --  contains fcopy() function                              */
  2. /*  Version 3.2                                                         */
  3. /*                                                                      */
  4. /*  This function copies one file to another, much as the DOS COPY      */
  5. /*  command does.  This version adds the capability to detect if        */
  6. /*  the source and target filespecs, in fact, refer to the same file.   */
  7. /*  It will not copy a file onto itself, and will return an error       */
  8. /*  if that is attempted.                                               */
  9. /*                                                                      */
  10. /*  fcopy now has three assembler functions to support it.  As in       */
  11. /*  earlier versions, _copyfile performs the actual file reads and      */
  12. /*  writes.  Two new functions have also been added: truename() uses    */
  13. /*  DOS function 60h to determine the canonical (fully qualified)       */
  14. /*  name of a file given a path name.  It needs the function strtrim()  */
  15. /*  to remove leading and trailing white space from the name string     */
  16. /*  before processing.                                                  */
  17. /*                                                                      */
  18. /*  fcopy() uses a farmalloc() call to allocate a large file buffer     */
  19. /*  from the far heap, regardless of the memory model being used.       */
  20. /*  BUFF_SIZE, indicating the buffer size, can be any int sized         */
  21. /*  value up to (but not including) 65,535.  It is recommended that     */
  22. /*  the buffer be a multiple of the sector size (512 bytes in the       */
  23. /*  current version of DOS), since reads and writes are more efficient  */
  24. /*  if they involve whole sectors.  A good value to use is 65024 (in    */
  25. /*  decimal), since this is 1 sector (512 bytes) short of a complete    */
  26. /*  segment (64k bytes).                                                */
  27. /*                                                                      */
  28. /*  Function prototypes are contained in fcopy.h                        */
  29. /*                                                                      */
  30. /*  Usage:                                                              */
  31. /*                                                                      */
  32. /*      #include "fcopy.h"                                              */
  33. /*      int fcopy (char *sourcename, char *targetname)                  */
  34. /*                                                                      */
  35. /*  Returns:  If successful, returns 0.                                 */
  36. /*                                                                      */
  37. /*            If copy fails, returns -1 and sets errno                  */
  38. /*            and _doserrno to one of the following:                    */
  39. /*                                                                      */
  40. /*              EINVFNC     Invalid function number  (1)                */
  41. /*              ENOFILE     File not found  (2)                         */
  42. /*              ENOPATH     Path not found  (3)                         */
  43. /*              EMFILE      Too many open files  (4)                    */
  44. /*              EACCESS     Permission denied  (5)                      */
  45. /*              EBADF       Bad file number  (6)                        */
  46. /*              ECONTR      Memory blocks destroyed  (7)                */
  47. /*              ENOMEM      Not enough core  (8)                        */
  48. /*              EINVMEM     Invalid memory block address  (9)           */
  49. /*              EINVACC     Invalid access code  (12)                   */
  50. /*              DISKFUL     Target disk full  (-2)                      */
  51. /*              NOCOPY      Cannot copy file onto itself (-3)           */
  52. /*  ------------------------------------------------------------------- */
  53. /*  Revision history:                                                   */
  54. /*                                                                      */
  55. /*      1.0      5 JAN 92       Original.  Written for Turbo C++.       */
  56. /*                                                                      */
  57. /*      1.1     19 JAN 92       Updated comments to reflect _farread()  */
  58. /*                              and _farwrite() being split into        */
  59. /*                              separate modules.  No code changes to   */
  60. /*                              this module.                            */
  61. /*                                                                      */
  62. /*      2.0     16 MAR 92       Replaced _farread() and _farwrite()     */
  63. /*                              functions with a single _copyfile()     */
  64. /*                              function.  fcopy() modified to match.   */
  65. /*                                                                      */
  66. /*      3.0     19 APR 92       Now checks to see if source and target  */
  67. /*                              filespecs refer to the same file, to    */
  68. /*                              avoid attempting to copy a file onto    */
  69. /*                              itself.                                 */
  70. /*                                                                      */
  71. /*                              Also dropped the leading underscore     */
  72. /*                              from the function name; it is now       */
  73. /*                              fcopy (rather than _fcopy).             */
  74. /*                                                                      */
  75. /*      3.1     12 MAY 92       Returns -1 for all error conditions,    */
  76. /*                              instead of returning _doserrno.         */
  77. /*                                                                      */
  78. /*      3.2     27 JUN 92       Added static modifier to __cleanup      */
  79. /*                              function to limit its scope to this     */
  80. /*                              module.                                 */
  81. /*                                                                      */
  82. /*                              Now deletes the bad target file if      */
  83. /*                              the file copy fails to avoid leaving    */
  84. /*                              it on disk and forcing the calling      */
  85. /*                              function to deal with it.               */
  86. /*  ------------------------------------------------------------------- */
  87. /*      Copyright (c) 1992 Ray Waters                                   */
  88. /*      All Rights Reserved                                             */
  89. /*  ------------------------------------------------------------------- */
  90.  
  91. #define BUFF_SIZE   65024U          /* size of file buffer */
  92.  
  93. #include <io.h>             /* _open, _creat, _close */
  94. #include <stdio.h>          /* remove */
  95. #include <fcntl.h>          /* definition for O_RDONLY */
  96. #include <alloc.h>          /* farmalloc, farfree */
  97. #include <string.h>         /* stricmp, strcmp */
  98. #include <errno.h>          /* errno, _doserrno */
  99. #include "fcopy.h"          /* fcopy, strtrim, truename, _copyfile */
  100.  
  101. /* ----- [ function prototype - limits scope to this module ] ----- */
  102. static void __cleanup(void);    /* function to close files, free memory */
  103.  
  104. char far *buffer;               /* far pointer to the file buffer */
  105. int  SrcHandle, TgtHandle;      /* file handles for source and target */
  106.  
  107. int fcopy(char *sourcename, char *targetname)
  108. {
  109.     struct ftime ft;                /* structure for file date/time stamp */
  110.     char qSrcName[128];             /* buffer for qualified source name */
  111.     char qTgtName[128];             /* buffer for qualified target name */
  112.  
  113.     /* First, just perform a simple case insensitive string compare to
  114.        see if the source and target names are identical.  This will
  115.        provide some protection for users running a version of DOS
  116.        earlier than 3.0, which is necessary to support the truename
  117.        function below.
  118.     */
  119.  
  120.     if (!stricmp(sourcename, targetname)) {     /* if the names are the same */
  121.         errno = NOCOPY;                         /* set errno */
  122.         _doserrno = NOCOPY;                     /* set _doserrno */
  123.         return -1;                              /* return error */
  124.     }
  125.  
  126.     /* Next, check to see if the source and target filespecs actually
  127.        refer to the same file.  If they do, return an error without
  128.        doing any further work.  If either truename call returns an error
  129.        see if truename is supported.  If not, proceed (and hope for the
  130.        best).  If the error is an invalid pathname, return the error
  131.        condition. */
  132.  
  133.     if (!truename(sourcename, qSrcName) && !truename(targetname, qTgtName)) {
  134.         if (!strcmp(qSrcName, qTgtName)) {      /* if the names are the same */
  135.             errno = NOCOPY;                     /* set errno */
  136.             _doserrno = NOCOPY;                 /* set _doserrno */
  137.             return -1;                          /* return error */
  138.         }
  139.     }
  140.     else if (errno != EINVFNC)                  /* if filespecs were invalid */
  141.         return -1;                              /* return error */
  142.  
  143.     SrcHandle = _open(sourcename, O_RDONLY);    /* open source (read only) */
  144.     if (SrcHandle == -1)                        /* if open failed, */
  145.         return -1;                              /* return error */
  146.     if (getftime(SrcHandle, &ft)) {             /* get date/time stamp */
  147.         _close(SrcHandle);                      /* if error, close file */
  148.         return -1;                              /* return error */
  149.     }
  150.  
  151.     TgtHandle = _creat(targetname, 0);          /* create/truncate target */
  152.     if (TgtHandle == -1) {                      /* if open failed, */
  153.         _close(SrcHandle);                      /* close source file */
  154.         return -1;                              /* return error */
  155.     }
  156.  
  157.     if  (!(buffer = farmalloc(BUFF_SIZE))) {    /* allocate a far buffer */
  158.                                                 /* if allocation failed, */
  159.         _close(SrcHandle);                      /* close source file */
  160.         _close(TgtHandle);                      /* close target file */
  161.         return -1;                              /* return error */
  162.     }
  163.  
  164.                                                 /* perform the copy */
  165.     if (_copyfile(SrcHandle, TgtHandle, buffer, BUFF_SIZE)) {
  166.         __cleanup();                /* if copy failed, close files, free mem */
  167.         remove(targetname);                     /* delete bad target file */
  168.         return -1;                              /* return error */
  169.     }
  170.  
  171.     setftime(TgtHandle, &ft);               /* set target date/time stamp */
  172.     __cleanup();                                /* close files, free mem */
  173.     return 0;                                   /* return success */
  174. }
  175.  
  176. /*------------------------------------------------------------------------*/
  177.  
  178. static void __cleanup(void)             /* close files and release memory */
  179. {
  180.     _close(SrcHandle);                          /* close source file */
  181.     _close(TgtHandle);                          /* close target file */
  182.     farfree(buffer);                            /* free memory */
  183. }
  184.