/****************************************************************/ /* */ /* copy.c */ /* */ /* command.com copy command */ /* */ /* August 9, 1991 */ /* */ /* Copyright (c) 1995 */ /* Pasquale J. Villani */ /* All Rights Reserved */ /* */ /* This file is part of DOS-C. */ /* */ /* DOS-C is free software; you can redistribute it and/or */ /* modify it under the terms of the GNU General Public License */ /* as published by the Free Software Foundation; either version */ /* 2, or (at your option) any later version. */ /* */ /* DOS-C is distributed in the hope that it will be useful, but */ /* WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */ /* the GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public */ /* License along with DOS-C; see the file COPYING. If not, */ /* write to the Free Software Foundation, 675 Mass Ave, */ /* Cambridge, MA 02139, USA. */ /****************************************************************/ /* $Logfile: C:/dos-c/src/command/copy.c_v $ */ /* * $Log: C:/dos-c/src/command/copy.c_v $ * * Rev 1.1 01 Sep 1995 18:04:32 patv * First GPL release. * * Rev 1.0 02 Jul 1995 10:01:38 patv * Initial revision. */ #include "../../hdr/portab.h" #include "globals.h" #include "proto.h" static BYTE *RcsId = "$Header: C:/dos-c/src/command/copy.c_v 1.1 01 Sep 1995 18:04:32 patv $"; #define CHUNK 16384 BOOL copy() { COUNT ifd, ofd, ret, CopyCount = 0; seg MemSeg; BYTE FAR *MemBuffer; date fdate; time ftime; BYTE FromPath[MAX_CMDLINE], ToPath[MAX_CMDLINE]; COUNT dest_driveno = -1, src_driveno = -1; BYTE src_path[MAX_CMDLINE], src[MAX_CMDLINE]; BYTE dest_path[MAX_CMDLINE], dest[MAX_CMDLINE]; BOOL bflag, aflag, AppendMode = FALSE, FirstTime = TRUE, IsWild, Error; dmatch dmp; /* Intialize the dta to put the dir info into */ DosSetDta((BYTE FAR *)&dmp); /* And initialize our current location */ FindHome(); /* Parse the command line, and get our destination */ /* First initialize parameters ... */ aflag = bflag = FALSE; *dest = *src = *src_path = *dest_path = *FromPath = *ToPath = '\0'; /* Then get the options. */ dosopt("$d$p*$d$p*[ab]+", (BYTE FAR *)tail, &src_driveno, src_path, src, &dest_driveno, dest_path, dest, &aflag, &bflag); /* Need at least source or source and destination */ if(*src == '\0') { error_message(INV_NUM_PARAMS); GoHome(); return FALSE; } /* Now start looking at what was passed. */ /* First, substitute current drive if the source or destination */ /* drive was not specified. */ if(src_driveno < 0) src_driveno = DosGetDrive(); if(dest_driveno < 0) dest_driveno = DosGetDrive(); /* If the source path was not specified, get the current path */ /* and substitute that. */ if(*src_path == '\0') { *src_path = '\\'; DosPwd(src_driveno + 1, (BYTE FAR *)&src_path[1]); } /* If no destination has been specified, build one ... */ /* If the destination path was not specified, get the current */ /* path and substitute that. */ if(*dest_path == '\0') { /* No specification, build it as source in this */ /* directory. */ *dest_path = '\\'; DosPwd(dest_driveno + 1, (BYTE FAR *)&dest_path[1]); } /* Now check for special case where dest is really a directory */ if(*dest != '\0') { COUNT cudrvno; BYTE cudir[67]; /* Get where we are */ cudrvno = DosGetDrive(); *cudir = '\\'; DosPwd(cudrvno + 1, (BYTE FAR *)&cudir[1]); /* Change to the path and then test the file name. If */ /* it is a directory, concatenate the source base name */ /* to it to build a full path. */ DosSetDrive(dest_driveno); if(DosCd((BYTE FAR *)dest_path) == SUCCESS) { /* This is a gimmick. If the cd does not work, */ /* the path is unaffected, so we let DOS do our */ /* building of the path. */ if(DosCd((BYTE FAR *)dest) != SUCCESS) AppendMode = TRUE; DosPwd(DosGetDrive() + 1, (BYTE FAR *)&dest_path[1]); } /* Change back to the current drive and directory. */ DosSetDrive(cudrvno); if((DosCd((BYTE FAR *)cudir)) != SUCCESS) { error_message(INV_DIR); GoHome(); return FALSE; } } /* Since we have to comply with wild card specifications, the */ /* only way to expand the source is to switch there, do your */ /* thing and then switch back. */ /* Switch to the requested directory to copy from */ DosSetDrive(src_driveno); /* Change to the path and then test the file name. If it is a */ /* directory, concatenate the source base name to it to build a */ /* full path. */ if(DosCd((BYTE FAR *)src_path) != SUCCESS) { error_message(FILE_NOT_FOUND); GoHome(); return FALSE; } /* Finally ! Expand the wild cards! */ IsWild = iswild(src); if(DosFindFirst(D_NORMAL | D_RDONLY , (BYTE FAR *)src) != SUCCESS) { error_message(FILE_NOT_FOUND); GoHome(); return TRUE; } do { BYTE *s; /* Build the from file specification and the to file */ /* specification from above parts. */ /* First the source */ *FromPath = 'A' + src_driveno; strcpy(&FromPath[1], ":"); strcat(FromPath, src_path); if(FromPath[3] != '\0') strcat(FromPath, "\\"); strcat(FromPath, dmp.dm_name); for(s = FromPath; *s != '\0'; s++) *s = toupper(*s); /* Then the destination. */ if(!AppendMode || (AppendMode && FirstTime)) { *ToPath = 'A' + dest_driveno; strcpy(&ToPath[1], ":"); strcat(ToPath, dest_path); if(ToPath[3] != '\0') strcat(ToPath, "\\"); if(AppendMode) strcat(ToPath, dest); else strcat(ToPath, dmp.dm_name); for(s = ToPath; *s != '\0'; s++) *s = toupper(*s); } /* Check for a match between source and destination. */ /* Quit if they match */ if(strcmp(FromPath, ToPath) == 0) { if(AppendMode && !IsWild) { error_message(FILE_ON_ITSELF); if(AppendMode && !FirstTime) DosClose(ofd); GoHome(); } else continue; return FALSE; } if(IsWild) printf(" %s\n", dmp.dm_name); if((ifd = DosOpen((BYTE FAR *)FromPath, O_RDONLY)) < 0) { strcpy(error_mess_str, FromPath); error_message(FILE_NOT_FOUND); if(AppendMode && !FirstTime) DosClose(ofd); GoHome(); return FALSE; } if(!AppendMode || (AppendMode && FirstTime)) { if((ofd = DosCreat((BYTE FAR *)ToPath, D_NORMAL)) < 0) { strcpy(error_mess_str, ToPath); error_message(FILE_CREATE_ERR); GoHome(); DosClose(ifd); if(AppendMode && !FirstTime) DosClose(ofd); return FALSE; } FirstTime = FALSE; } /* Get a buffer from DOS */ MemSeg = DosAllocMem(CHUNK / PARASIZE, (BOOL FAR *)&Error); if(Error) { error_message(INSUFF_MEM); GoHome(); DosClose(ifd); if(AppendMode && !FirstTime) DosClose(ofd); return FALSE; } MemBuffer = MK_FP(MemSeg, 0); /* Dos the file copy itself */ while((ret = DosRead(ifd, (BYTE FAR *)MemBuffer, CHUNK)) > 0) { if(DosWrite(ofd, (BYTE FAR *)MemBuffer, ret) != ret) { error_message(INSUFF_DISK); DosClose(ifd); DosClose(ofd); DosDelete((BYTE FAR *)ToPath); return FALSE; } if(ret != CHUNK) break; } /* Free the buffer */ DosFreeMem(MemSeg, (BOOL FAR *)&Error); /* And update the file time if applicable */ if(!AppendMode || (AppendMode && !IsWild)) { DosGetftime(ifd, &fdate, &ftime); DosSetftime(ofd, &fdate, &ftime); } DosClose(ifd); ++CopyCount; if(!AppendMode) DosClose(ofd); } while(DosFindNext() == SUCCESS); /* Change back to the current drive and directory. */ if(AppendMode) DosClose(ofd); if(AppendMode) printf("\n%d File(s) copied\n", CopyCount); return GoHome(); }