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 >
Wrap
C/C++ Source or Header
|
1992-06-27
|
11KB
|
184 lines
/* FCOPY.C -- contains fcopy() function */
/* Version 3.2 */
/* */
/* This function copies one file to another, much as the DOS COPY */
/* command does. This version adds the capability to detect if */
/* the source and target filespecs, in fact, refer to the same file. */
/* It will not copy a file onto itself, and will return an error */
/* if that is attempted. */
/* */
/* fcopy now has three assembler functions to support it. As in */
/* earlier versions, _copyfile performs the actual file reads and */
/* writes. Two new functions have also been added: truename() uses */
/* DOS function 60h to determine the canonical (fully qualified) */
/* name of a file given a path name. It needs the function strtrim() */
/* to remove leading and trailing white space from the name string */
/* before processing. */
/* */
/* fcopy() uses a farmalloc() call to allocate a large file buffer */
/* from the far heap, regardless of the memory model being used. */
/* BUFF_SIZE, indicating the buffer size, can be any int sized */
/* value up to (but not including) 65,535. It is recommended that */
/* the buffer be a multiple of the sector size (512 bytes in the */
/* current version of DOS), since reads and writes are more efficient */
/* if they involve whole sectors. A good value to use is 65024 (in */
/* decimal), since this is 1 sector (512 bytes) short of a complete */
/* segment (64k bytes). */
/* */
/* Function prototypes are contained in fcopy.h */
/* */
/* Usage: */
/* */
/* #include "fcopy.h" */
/* int fcopy (char *sourcename, char *targetname) */
/* */
/* Returns: If successful, returns 0. */
/* */
/* If copy fails, returns -1 and sets errno */
/* and _doserrno to one of the following: */
/* */
/* EINVFNC Invalid function number (1) */
/* ENOFILE File not found (2) */
/* ENOPATH Path not found (3) */
/* EMFILE Too many open files (4) */
/* EACCESS Permission denied (5) */
/* EBADF Bad file number (6) */
/* ECONTR Memory blocks destroyed (7) */
/* ENOMEM Not enough core (8) */
/* EINVMEM Invalid memory block address (9) */
/* EINVACC Invalid access code (12) */
/* DISKFUL Target disk full (-2) */
/* NOCOPY Cannot copy file onto itself (-3) */
/* ------------------------------------------------------------------- */
/* Revision history: */
/* */
/* 1.0 5 JAN 92 Original. Written for Turbo C++. */
/* */
/* 1.1 19 JAN 92 Updated comments to reflect _farread() */
/* and _farwrite() being split into */
/* separate modules. No code changes to */
/* this module. */
/* */
/* 2.0 16 MAR 92 Replaced _farread() and _farwrite() */
/* functions with a single _copyfile() */
/* function. fcopy() modified to match. */
/* */
/* 3.0 19 APR 92 Now checks to see if source and target */
/* filespecs refer to the same file, to */
/* avoid attempting to copy a file onto */
/* itself. */
/* */
/* Also dropped the leading underscore */
/* from the function name; it is now */
/* fcopy (rather than _fcopy). */
/* */
/* 3.1 12 MAY 92 Returns -1 for all error conditions, */
/* instead of returning _doserrno. */
/* */
/* 3.2 27 JUN 92 Added static modifier to __cleanup */
/* function to limit its scope to this */
/* module. */
/* */
/* Now deletes the bad target file if */
/* the file copy fails to avoid leaving */
/* it on disk and forcing the calling */
/* function to deal with it. */
/* ------------------------------------------------------------------- */
/* Copyright (c) 1992 Ray Waters */
/* All Rights Reserved */
/* ------------------------------------------------------------------- */
#define BUFF_SIZE 65024U /* size of file buffer */
#include <io.h> /* _open, _creat, _close */
#include <stdio.h> /* remove */
#include <fcntl.h> /* definition for O_RDONLY */
#include <alloc.h> /* farmalloc, farfree */
#include <string.h> /* stricmp, strcmp */
#include <errno.h> /* errno, _doserrno */
#include "fcopy.h" /* fcopy, strtrim, truename, _copyfile */
/* ----- [ function prototype - limits scope to this module ] ----- */
static void __cleanup(void); /* function to close files, free memory */
char far *buffer; /* far pointer to the file buffer */
int SrcHandle, TgtHandle; /* file handles for source and target */
int fcopy(char *sourcename, char *targetname)
{
struct ftime ft; /* structure for file date/time stamp */
char qSrcName[128]; /* buffer for qualified source name */
char qTgtName[128]; /* buffer for qualified target name */
/* First, just perform a simple case insensitive string compare to
see if the source and target names are identical. This will
provide some protection for users running a version of DOS
earlier than 3.0, which is necessary to support the truename
function below.
*/
if (!stricmp(sourcename, targetname)) { /* if the names are the same */
errno = NOCOPY; /* set errno */
_doserrno = NOCOPY; /* set _doserrno */
return -1; /* return error */
}
/* Next, check to see if the source and target filespecs actually
refer to the same file. If they do, return an error without
doing any further work. If either truename call returns an error
see if truename is supported. If not, proceed (and hope for the
best). If the error is an invalid pathname, return the error
condition. */
if (!truename(sourcename, qSrcName) && !truename(targetname, qTgtName)) {
if (!strcmp(qSrcName, qTgtName)) { /* if the names are the same */
errno = NOCOPY; /* set errno */
_doserrno = NOCOPY; /* set _doserrno */
return -1; /* return error */
}
}
else if (errno != EINVFNC) /* if filespecs were invalid */
return -1; /* return error */
SrcHandle = _open(sourcename, O_RDONLY); /* open source (read only) */
if (SrcHandle == -1) /* if open failed, */
return -1; /* return error */
if (getftime(SrcHandle, &ft)) { /* get date/time stamp */
_close(SrcHandle); /* if error, close file */
return -1; /* return error */
}
TgtHandle = _creat(targetname, 0); /* create/truncate target */
if (TgtHandle == -1) { /* if open failed, */
_close(SrcHandle); /* close source file */
return -1; /* return error */
}
if (!(buffer = farmalloc(BUFF_SIZE))) { /* allocate a far buffer */
/* if allocation failed, */
_close(SrcHandle); /* close source file */
_close(TgtHandle); /* close target file */
return -1; /* return error */
}
/* perform the copy */
if (_copyfile(SrcHandle, TgtHandle, buffer, BUFF_SIZE)) {
__cleanup(); /* if copy failed, close files, free mem */
remove(targetname); /* delete bad target file */
return -1; /* return error */
}
setftime(TgtHandle, &ft); /* set target date/time stamp */
__cleanup(); /* close files, free mem */
return 0; /* return success */
}
/*------------------------------------------------------------------------*/
static void __cleanup(void) /* close files and release memory */
{
_close(SrcHandle); /* close source file */
_close(TgtHandle); /* close target file */
farfree(buffer); /* free memory */
}