home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Zodiac Super OZ
/
MEDIADEPOT.ISO
/
FILES
/
16
/
FREEDOS.ZIP
/
FD_A4PRE.ZIP
/
SOURCE
/
POWERC.ZIP
/
move.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-20
|
15KB
|
543 lines
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <direct.h>
#include <malloc.h>
#define BOOLEAN char /* defining BOOLEAN type */
#define TRUE 1
#define FALSE 0
#define TESTMODE FALSE /* whether or not to manipulate files */
#define STRSIZ 256 /* default size for strings */
#define BUFMAX 0x0D000 /* buffer size for file copies */
#define MOVE_DEFAULT FA_ARCH
#define EXISTING_FILES FA_ARCH | FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_DIREC | FA_LABEL
#define EXPLANATIONS 1 /* errorlevel codes */
#define NO_SUCH_SOURCE 2
#define UNMOVEABLE_SOURCE 3
#define NO_SUCH_DESTINATION 4
#define EXISTING_BAD_DESTINATION 5
#define IDENTICAL_SOURCE_AND_DEST 6
#define SOURCE_TEMP_DEST_FILE 7
#define MALLOC_ERROR 8
#define FILE_OPEN_ERROR 9
#define RENAME_ERROR 10
#define COPY_ERROR 11
#define ERASE_ERROR 12
#define T_DIR 1 /* source / dest types */
#define T_FILE 2
#define T_TEMP 3
void *buffy; /* buffer for copies and its size */
unsigned int bufsize;
int srctype, dsttype, MOVEABLE_FILES = MOVE_DEFAULT;
char fullsrc[STRSIZ], fulldst[STRSIZ], srcpath[STRSIZ], dstpath[STRSIZ],
source[STRSIZ], dest[STRSIZ], srcfile[13], dstfile[13];
BOOLEAN always_overwrite = FALSE;
/*
-----------------------------------------------------
*/
char *fexpand(char *pathout, char *pathin) /* expand file name to full path */
{
char *chrptr;
_AH = 0x60;
chrptr = pathin;
_DS = FP_SEG(chrptr);
_SI = FP_OFF(chrptr);
chrptr = pathout;
_ES = FP_SEG(chrptr);
_DI = FP_OFF(chrptr);
geninterrupt(0x21);
return pathout;
}
/*
-----------------------------------------------------
*/
void matchfiletime(char *fnin, char *fnout) /* make timestamps equal */
{
unsigned int handle, tmpcx, tmpdx;
_AH = 0x3d; /* open input file */
_AL = 0x40;
_DS = FP_SEG(fnin);
_DX = FP_OFF(fnin);
geninterrupt(0x21);
handle = _AX;
_AH = 0x57; /* get file time from input */
_AL = 0x00;
_BX = handle;
geninterrupt(0x21);
tmpcx = _CX;
tmpdx = _DX;
_AH = 0x3e; /* close input file */
_BX = handle;
geninterrupt(0x21);
_AH = 0x3d; /* open output file */
_AL = 0x40;
_DS = FP_SEG(fnout);
_DX = FP_OFF(fnout);
geninterrupt(0x21);
handle = _AX;
_AH = 0x57; /* set output file time */
_AL = 0x01;
_BX = handle;
_CX = tmpcx;
_DX = tmpdx;
geninterrupt(0x21);
_AH = 0x3e; /* close output file */
_BX = handle;
geninterrupt(0x21);
}
/*
-----------------------------------------------------
*/
void setfileattrib(char *fname, char attrib) /* set file attributes */
{
_AH = 0x43;
_AL = 0x01;
_CH = 0x00;
_CL = attrib;
_DS = FP_SEG(fname);
_DX = FP_OFF(fname);
geninterrupt(0x21);
}
/*
-----------------------------------------------------
*/
void checkfrom(char *whattomove) /* determine if valid source supplied */
{
struct ffblk flrec;
char tmpfrom[STRSIZ];
fexpand(tmpfrom, whattomove);
if (findfirst(tmpfrom, &flrec, MOVEABLE_FILES) != 0) /* none found */
{
printf("Error: no such file exists to MOVE.\n");
exit(NO_SUCH_SOURCE);
}
if (strchr(tmpfrom, '?') > 0) srctype = T_TEMP; /* template or file? */
else srctype = T_FILE;
}
/*
-----------------------------------------------------
*/
void checkto(char *wheretomoveit) /* check if valid destination */
{
struct ffblk flrec;
int i;
char tmpdest[STRSIZ];
fexpand(tmpdest, wheretomoveit);
i = strlen(tmpdest) - 1;
while ((i >= 0) && (tmpdest[i] == '\\')) tmpdest[i--] = '\0';
if (strchr(tmpdest, '?') > 0)
{
dsttype = T_TEMP;
i = strlen(tmpdest) - 1;
while ((i >= 0) && (tmpdest[i] != '\\')) tmpdest[i--] = '\0';
while ((i >= 0) && (tmpdest[i] == '\\')) tmpdest[i--] = '\0';
if (tmpdest[2] != '\0')
{
if (findfirst(tmpdest, &flrec, FA_DIREC) != 0)
{
printf("Error: invalid path to destination.\n");
exit(NO_SUCH_DESTINATION);
}
}
}
else if (tmpdest[2] == '\0')
{
dsttype = T_DIR;
}
else
{
dsttype = T_FILE;
if (findfirst(tmpdest, &flrec, EXISTING_FILES) == 0)
{
if (flrec.ff_attrib & FA_LABEL == FA_LABEL)
{
printf("Error: destination is a volume label.\n");
exit(EXISTING_BAD_DESTINATION);
}
if ((flrec.ff_attrib & FA_DIREC) == FA_DIREC)
{
dsttype = T_DIR;
}
else
{
if (srctype == T_TEMP)
{
printf("Error: multiple files cannot be MOVEd to a single file.\n");
exit(SOURCE_TEMP_DEST_FILE);
}
}
}
else
{
dsttype = T_FILE;
if (srctype == T_TEMP)
{
printf("Error: multiple files cannot be MOVEd to a single file.\n");
exit(SOURCE_TEMP_DEST_FILE);
}
i = strlen(tmpdest) - 1;
while ((i >= 0) && (tmpdest[i] != '\\')) tmpdest[i--] = '\0';
while ((i >= 0) && (tmpdest[i] == '\\')) tmpdest[i--] = '\0';
if (tmpdest[2] != '\0')
{
if (findfirst(tmpdest, &flrec, FA_DIREC) != 0)
{
printf("Error: invalid path to destination.\n");
exit(NO_SUCH_DESTINATION);
}
}
}
}
}
/*
-----------------------------------------------------
*/
void parsepath(char *full, char *path, char *file) /* split path & file */
{
int i;
strcpy(path, full);
i = strlen(path) - 1;
while (path[i] != '\\') i--; /* find final slash; split there */
i++;
strcpy(file, path + i);
path[i] = '\0';
}
/*
-----------------------------------------------------
*/
void parsefile(char *fullname, char *name, char *ext) /* split name & ext */
{
char *chrptr;
strcpy(name, fullname);
chrptr = strchr(name, '.');
if (chrptr == NULL) /* no '.' -- no ext */
{
*ext = '\0';
}
else
{
strcpy(ext, chrptr + 1); /* ext is the part after the '.' */
*chrptr = '\0';
}
}
/*
-----------------------------------------------------
*/
void xlatname(char *dfil, char *sfil)
/* construct destination file name, given actual input file name and
destination template */
{
char sfname[13], sfext[4], dtname[13], dtext[4];
int dstcnt, srccnt, tmpcnt;
/* split input and template names into filename & ext */
parsefile(sfil, sfname, sfext);
parsefile(dstfile, dtname, dtext);
srccnt = 0;
tmpcnt = 0;
dstcnt = 0;
/* translate filename */
while ((sfname[srccnt] != '\0') && (dtname[tmpcnt] != '\0'))
{
if (dtname[tmpcnt] == '?') dfil[dstcnt] = sfname[srccnt];
else dfil[dstcnt] = dtname[tmpcnt];
srccnt++;
tmpcnt++;
dstcnt++;
}
/* tacking on any final chars specified in template's filename */
while ((dtname[tmpcnt] != '\0') && (dtname[tmpcnt] != '?'))
{
dfil[dstcnt] = dtname[tmpcnt];
tmpcnt++;
dstcnt++;
}
/* put decimal */
dfil[dstcnt] = '.';
dstcnt++;
srccnt = 0;
tmpcnt = 0;
/* translate extension */
while ((sfext[srccnt] != '\0') && (dtext[tmpcnt] != '\0'))
{
if (dtext[tmpcnt] == '?') dfil[dstcnt] = sfext[srccnt];
else dfil[dstcnt] = dtext[tmpcnt];
srccnt++;
tmpcnt++;
dstcnt++;
}
/* tacking on any final chars specified in template's extension */
while ((dtext[tmpcnt] != '\0') && (dtext[tmpcnt] != '?'))
{
dfil[dstcnt] = dtext[tmpcnt];
tmpcnt++;
dstcnt++;
}
dfil[dstcnt] = '\0';
}
/*
-----------------------------------------------------
*/
void copy(char *fnin, char *fnout, struct ffblk flrec) /* copy file */
{
FILE *fin, *fout;
size_t numread, numwritten;
fin = fopen(fnin, "rb");
if (fin == NULL) /* open input file */
{
printf("Error opening %s\n", fnin);
exit(FILE_OPEN_ERROR);
}
fout = fopen(fnout, "wb"); /* open output file */
if (fout == NULL)
{
printf("Error opening %s\n", fnout);
exit(FILE_OPEN_ERROR);
}
do /* copy file, one buffer's worth at a time */
{
numread = fread(buffy, 1, bufsize, fin);
if (numread > 0)
{
numwritten = fwrite(buffy, 1, numread, fout);
if (numread > numwritten)
{
fclose(fin);
fclose(fout);
printf("Error transfering data from %s to %s.\n", fnin, fnout);
exit(COPY_ERROR);
}
}
} while (numread == bufsize);
fclose(fin);
fclose(fout);
matchfiletime(fnin, fnout); /* fix output file time */
setfileattrib(fnout, flrec.ff_attrib); /* fix output file attribs */
}
/*
-----------------------------------------------------
*/
void erase(char *fname) /* erase a file */
{
setfileattrib(fname, 0);
if (remove(fname) != 0)
{
printf("Error erasing %s.\n", fname);
exit(ERASE_ERROR);
}
}
/*
-----------------------------------------------------
*/
void performmoves()
{
struct ffblk srcflrec, dstflrec;
char sfil[13], dfil[13], fullin[STRSIZ], fullout[STRSIZ], yn[STRSIZ];
int doserror;
BOOLEAN copyit;
doserror = findfirst(fullsrc, &srcflrec, MOVEABLE_FILES);
while (doserror == 0) /* loop thru files */
{
strcpy(sfil, srcflrec.ff_name);
xlatname(dfil, sfil);
strcpy(fullin, srcpath); strcat(fullin, sfil);
strcpy(fullout, dstpath); strcat(fullout, dfil);
printf("%s --> %s\n", fullin, fullout);
if (findfirst(fullout, &dstflrec, EXISTING_FILES) == 0)
{
if ((dstflrec.ff_attrib & FA_DIREC) == FA_DIREC)
{
printf(" -- Cannot move %s to %s:\n %s is an existing directory.\n",
fullin, fullout, fullout);
copyit = FALSE;
}
else if ((dstflrec.ff_attrib & FA_LABEL) == FA_LABEL)
{
printf(" -- Cannot move %s to %s:\n %s is a volume label.\n",
fullin, fullout, fullout);
copyit = FALSE;
}
else
{
if (!always_overwrite)
{
do
{
printf("Overwrite %s with %s? (y/n) ", fullout, fullin);
scanf("%s", yn);
strupr(yn);
} while ((yn[0] != 'Y') && (yn[0] != 'N'));
}
if ((always_overwrite) || (yn[0] == 'Y'))
{
copyit = TRUE;
if (TESTMODE)
{
printf(" Deleting %s ...\n", fullout);
}
else
{
erase(fullout);
}
}
else copyit = FALSE;
}
}
else copyit = TRUE;
if (copyit && !TESTMODE)
{
if (fullin[0] == fullout[0])
{
if (rename(fullin, fullout) != 0)
{
printf("Error occurred renaming %s to %s.\n", fullin, fullout);
exit(RENAME_ERROR);
}
}
else
{
copy(fullin, fullout, srcflrec);
erase(fullin);
}
}
doserror = findnext(&srcflrec);
}
}
/*
-----------------------------------------------------
*/
void explanation_screen() /* show proper syntax */
{
printf("\nMOVE\n\n");
printf("Syntax: MOVE [/options] <source> [destination]\n\n");
printf(" where <source> and [destination] are files or templates.\n");
printf(" If [destination] is omitted, the current directory is assumed.\n\n");
printf("OPTIONS: O overwrite any existing files without asking\n");
printf(" H MOVE hidden files\n");
printf(" S MOVE system files\n");
printf(" ? Display this screen\n");
exit(EXPLANATIONS);
}
/*
-----------------------------------------------------
*/
void process_argument(char *arg) /* interpret a command-line argument */
{
char opt;
int i;
if (arg[0] == '/') /* '/' options */
{
if (arg[1] == '\0')
{
printf("Invalid MOVE option.\n");
explanation_screen();
}
i = 1;
while (arg[i] != '\0')
{
opt = arg[i];
if ((opt >= 'a') && (opt <= 'z')) opt -= 0x20;
if (opt == 'H') MOVEABLE_FILES = (MOVEABLE_FILES | FA_HIDDEN);
else if (opt == 'S') MOVEABLE_FILES = (MOVEABLE_FILES | FA_SYSTEM);
else if (opt == 'O') always_overwrite = TRUE;
else if (opt == '?') explanation_screen();
else
{
printf("Invalid MOVE option -- %c\n", arg[i]);
explanation_screen();
}
i++;
}
}
else if (source[0] == '\0') strcpy(source, arg); /* no '/': must be file */
else if (dest[0] == '\0') strcpy(dest, arg);
else
{
printf("Error: another file besides source and dest was specified.\n");
explanation_screen();
}
}
/*
-----------------------------------------------------
*/
void main(int argc, char *argv[]) /* main drag */
{
int i;
source[0] = '\0';
dest[0] = '\0';
i = 1;
while (i < argc) /* process command line args */
{
process_argument(argv[i]);
i++;
}
if (source[0] == '\0') /* no source -- terminate */
{
printf("No source named!\n");
explanation_screen();
}
if (dest[0] == '\0') strcpy(dest, "."); /* no dest -- assume current */
checkfrom(source);
checkto(dest);
fexpand(fullsrc, source);
parsepath(fullsrc, srcpath, srcfile);
fexpand(fulldst, dest);
if (dsttype == T_DIR) /* make full dest template */
{
if (fulldst[strlen(fulldst) - 1] != '\\') strcat(fulldst, "\\");
strcat(fulldst, srcfile);
dsttype = T_TEMP;
}
parsepath(fulldst, dstpath, dstfile);
if (strcmp(fullsrc, fulldst) == 0)
{
printf("Source and destination files are identical.\n");
exit(IDENTICAL_SOURCE_AND_DEST);
}
if (fullsrc[0] != fulldst[0]) /* MOVE between drives -- make buffer */
{
if (farcoreleft() < BUFMAX) bufsize = farcoreleft();
else bufsize = BUFMAX;
buffy = malloc(bufsize);
if ((bufsize <= 0) || (buffy == NULL))
{
printf("Error: could not allocate buffer for file transfer.\n");
exit(MALLOC_ERROR);
}
}
performmoves();
if (fullsrc[0] != fulldst[0]) /* MOVE between drives -- lose buffer */
{
free(buffy);
}
}