home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
cenvi23.zip
/
COPY.CMM
< prev
next >
Wrap
Text File
|
1996-02-05
|
16KB
|
544 lines
/*
* Copy.cmm
*
* A copy script for the CEnvi shell. It does what the DOS copy
* command does.
*/
#include "netware.lib"
#include "filename.lib"
usage()
{
printf("Use the COPY command to copy one or more file(s) from one\n");
printf("location to another.\n");
printf("Syntax:\n");
printf(" COPY [drive][path] filename [+][,,][drive][path][filename] [/V]\n");
printf("where:\n");
printf(" drive/path/filename Specifies the file to be copied.\n");
printf(" + Combines or appends files.\n");
printf(" + ,, Updates the time and date of a file.\n");
printf(" drive/path/filename Specifies the target file name.\n");
printf(" /V Verifies that sectors written to the target\n");
printf(" disk are recorded properly.\n");
exit(EXIT_FAILURE);
}
/* ---------------------------------------------------------------------- */
/*
* Some DOS functions
*/
SetFileAttributes(pFileName,pAttributes)
{
lReg.ah = 0x43;
lReg.al = 1;
lReg.cx = pAttributes;
if !defined(_DOS32_)
lReg.ds = segment(pFileName), lReg.dx = offset(pFileName);
else
lReg.dx = pointer(pFileName);
return interrupt(0x21,lReg);
}
SetFileDateAndTime(pFileName,pTime)
{
lSuccess = False;
// Open file to get a handle
lReg.ah = 0x3D;
lReg.al = 0x42;
if !defined(_DOS32_)
lReg.ds = segment(pFileName), lReg.dx = offset(pFileName);
else
lReg.dx = pointer(pFileName);
if ( interrupt(0x21,lReg,lRegout) ) {
lHandle = lRegout.ax;
// write date to file
undefine(lReg);
lReg.ah = 0x57;
lReg.al = 1;
lReg.bx = lHandle;
lTm = localtime(pTime);
lReg.cx = (lTm.tm_sec / 2)
| (lTm.tm_min << 5)
| (lTm.tm_hour << 11);
lReg.dx = lTm.tm_mday
| ((lTm.tm_mon+1) << 5)
| ((lTm.tm_year-80) << 9);
lSuccess = interrupt(0x21,lReg);
// close file
undefine(lReg);
lReg.ah = 0x3E;
lReg.bx = lHandle;
interrupt(0x21,lReg);
}
return lSuccess;
}
DOSTimeFromCalendar(time)
{
dos = DOSTimeStructFromCalendar(time);
return (dos.time<<16) | (dos.date);
}
DOSTimeStructFromCalendar(time)
{
tm = localtime(time);
dos.time = (tm.tm_sec/2) | (tm.tm_min<<5) | (tm.tm_hour<<11);
dos.date = tm.tm_mday | ((tm.tm_mon+1)<<5) | ((tm.tm_year-80)<<9);
return dos;
}
GMDOSTimeStructFromCalendar(time)
{
tm = gmtime(time);
dos.time = (tm.tm_sec/2) | (tm.tm_min<<5) | (tm.tm_hour<<11);
dos.date = tm.tm_mday | ((tm.tm_mon+1)<<5) | ((tm.tm_year-80)<<9);
return dos;
}
#define GENERIC_WRITE 0x40000000
#define FILE_SHARE_READ 0x01
#define FILE_SHARE_WRITE 0x02
#define OPEN_EXISTING 3
#define INVALID_HANDLE_VALUE -1
/* ---------------------------------------------------------------------- */
verify = FALSE;
source[0] = "";
num_source = 0;
target = "";
doing_plus = FALSE;
update_time = FALSE;
parse_command_line(argc,argv)
{
for( i=1;i<argc;i++ )
{
if( argv[i][0]=='-' || argv[i][0]=='/' )
{
switch( toupper(argv[i][1]) )
{
default: usage();
case 'V': verify = TRUE; break;
}
continue;
}
if( argv[i][0]=='+' )
{
if( doing_plus ) {
printf("Already doing plus mode.\n");
exit(EXIT_FAILURE);
}
if( num_source==0 ) {
printf("You must specify a file, then you can use + to specify more.\n");
exit(EXIT_FAILURE);
}
doing_plus = TRUE;
if( argv[i][1] ) {
argv[i]++;
i--;
}
continue;
}
if( argv[i][0]==',' )
{
if( !doing_plus || argv[i][1]!=',' ) {
printf("To update a file's time, use \"+ ,,\".\n");
exit(EXIT_FAILURE);
}
update_time = TRUE;
doing_plus = FALSE;
continue;
}
// Have a filename
if( num_source==0 || doing_plus ) {
strcpy(source[num_source++],argv[i]);
doing_plus = FALSE;
continue;
}
if( target[0]!='\0' ) {
printf("Too many target files specified.\n");
exit(EXIT_FAILURE);
}
strcpy(target,argv[i]);
}
if( doing_plus ) { printf("Extraneous plus.\n"); exit(EXIT_FAILURE); }
if( num_source==0 )
{ printf("No source file specified.\n"); exit(EXIT_FAILURE); }
if( target[0]=='\0' ) target = ".";
}
/*
* Copy a single file. When done, set the time to the old file's time
* stamps if update_time not set
*/
copy_file(source,target)
{
strcpy(src,FullPath(source));
strcpy(tar,FullPath(target));
if( !stricmp(src,tar) )
{
// Same file!
if( update_time )
{
dir = Directory(target);
if( dir==NULL || GetArraySpan(dir)>0 )
{
printf("Copy_file: error, target should be a single file.\n");
return;
}
curtime = time();
if( defined(_NWNLM_) )
{
tempcreate[0] = DOSTimeFromCalendar(curtime);
tempaccess[0] = DOSTimeFromCalendar(curtime);
tempdate[0] = DOSTimeFromCalendar(curtime);
tempbackup[0] = DOSTimeFromCalendar(curtime);
code = NLMLink("SetFileInfo", target, 0x06, dir[0].attrib,
tempcreate,
tempaccess,
tempdate,
tempbackup,
dir[0].uid);
if( code )
printf("\nError setting attributes for file %s\n",target);
return;
}
if( defined(_DOS_) || defined(_DOS32_) || defined(_WINDOWS_) )
{
SetFileDateAndTime(target,curtime);
return;
}
if( defined(_NTCON_) || defined(_NTWIN_) || defined(_95CON_) ||
defined(_95WIN_) )
{
newbuf = ""; SetArraySpan(newbuf,100);
if( (handle = DynamicLink("KERNEL32","CreateFileA",STDCALL,target,
GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,0,NULL))
!=INVALID_HANDLE_VALUE)
{
dos = GMDOSTimeStructFromCalendar(time());
if( !DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
dos.date,dos.time,newbuf) )
{
printf("Unable to convert to NT Time structure.\n");
return;
}
if( !DynamicLink("KERNEL32","SetFileTime",STDCALL,handle,newbuf,
newbuf,newbuf) )
{
err = DynamicLink("KERNEL32","GetLastError",STDCALL);
printf("Unable to set new file time.\n",err);
}
if( !DynamicLink("KERNEL32","CloseHandle",STDCALL,handle) )
printf("Unable to close the handle.\n");
} else {
printf("Unable to open the file to touch it.\n");
}
return;
}
if( defined(_OS2_) )
{
printf("Cannot set timestamps on OS/2 yet.\n");
return;
}
}
printf("Cannot copy file to itself.\n");
return;
}
if( (fp = fopen(source,stricmp(source,"con")?"rb":"rt"))==NULL )
{
printf("Unable to open source file %s\n",source);
return;
}
if( (fp2 = fopen(target,stricmp(target,"con")?"wb":"rt"))==NULL )
{
printf("Unable to open target file %s\n",target);
fclose(fp);
return;
}
buffer = ""; SetArraySpan(buffer,10000);
while( 1 )
{
num = fread(buffer,9900,fp);
if( num<1 ) break;
fwrite(buffer,num,fp2);
}
fclose(fp2);
fclose(fp);
if( verify )
{
if( !stricmp(target,"con") || !stricmp(source,"con") )
{
printf("Cannot verify to or from the console.\n");
return;
}
if( (fp = fopen(source,"rb"))==NULL )
{
printf("Unable to open source file %s\n",source);
return;
}
if( (fp2 = fopen(target,"rb"))==NULL )
{
printf("Unable to write target file %s; check path is correct\n",target);
fclose(fp);
return;
}
buffer2 = ""; SetArraySpan(buffer2,10000);
while( 1 )
{
num = fread(buffer,9900,fp);
if( num<1 ) break;
num2 = fread(buffer2,9900,fp2);
if( num!=num2 || memcmp(buffer,buffer2,num) )
{
printf("File \"%s\" was copied incorrectly.\n",target);
}
}
fclose(fp2);
fclose(fp);
}
if( !update_time && stricmp(target,"con") )
{
dir = Directory(source);
if( dir==NULL || GetArraySpan(dir)!=0 )
{
printf("Error, can no longer open source file!\n");
return;
}
if( defined(_NWNLM_) )
{
tempcreate[0] = DOSTimeFromCalendar(dir[0].Create);
tempaccess[0] = DOSTimeFromCalendar(dir[0].Access);
tempdate[0] = DOSTimeFromCalendar(dir[0].Write);
tempbackup[0] = DOSTimeFromCalendar(dir[0].Backup);
code = NLMLink("SetFileInfo",
target,
0x06,
dir[0].attrib,
tempcreate,
tempaccess,
tempdate,
tempbackup,
dir[0].uid);
if( code )
printf("\nError setting attributes for file %s\n",target);
}
if( defined(_DOS_) || defined(_DOS32_) || defined(_WINDOWS_) )
{
SetFileDateAndTime(target,dir[0].Create);
SetFileAttributes(target,dir[0].attrib);
}
if( defined(_NTCON_) || defined(_NTWIN_) || defined(_95CON) ||
defined(_95WIN_) )
{
DynamicLink("KERNEL32","SetFileAttributesA",STDCALL,target,dir[0].attrib);
FTimeDef.LowTime = UWORD32;
FTimeDef.HightTime = UWORD32;
if( (handle = DynamicLink("KERNEL32","CreateFileA",STDCALL,target,
GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,0,NULL))
!=INVALID_HANDLE_VALUE)
{
dos = GMDOSTimeStructFromCalendar(dir[0].Create);
DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
dos.date,dos.time,FTimeDef,CreateFTime);
dos = GMDOSTimeStructFromCalendar(dir[0].Access);
DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
dos.date,dos.time,FTimeDef,AccessFTime);
dos = GMDOSTimeStructFromCalendar(dir[0].Write);
DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
dos.date,dos.time,FTimeDef,WriteFTime);
if( !DynamicLink("KERNEL32","SetFileTime",STDCALL,handle,FTimeDef,CreateFTime,
FTimeDef,AccessFTime,FTimeDef,WriteFTime) )
{
err = DynamicLink("KERNEL32","GetLastError",STDCALL);
printf("Unable to set new file time.\n",err);
}
if( !DynamicLink("KERNEL32","CloseHandle",STDCALL,handle) )
printf("Unable to close the handle.\n");
} else {
printf("Unable to open the file to touch it.\n");
}
return;
}
if( defined(_OS2_) )
{
printf("Cannot set time on OS/2 yet.\n");
exit(EXIT_FAILURE);
}
}
}
copy_multiple(target)
{
if( (fp2 = fopen(target,"w"))==NULL )
{
printf("Unable to write target file %s; check path is correct.\n",target);
return;
}
buffer = ""; SetArraySpan(buffer,1024);
for( i=0;i<num_source;i++ )
{
files = Directory(source[i]);
for( j=0;files && j<=GetArraySpan(files);j++ )
{
if( (fp = fopen(files[j].name,"r"))==NULL )
{
printf("Unable to open source file %s\n",source);
fclose(fp2);
return;
}
do
{
num = fread(buffer,1024,fp);
if( num<1 ) break;
fwrite(buffer,num,fp2);
}
while( !feof(fp) );
fclose(fp);
}
}
fclose(fp2);
}
/*---------------------------------------------------------------------------*/
get_filename(source)
{
filestruct = SplitFileName(source);
sprintf(newdir,"%s%s",filestruct.name,filestruct.ext);
return newdir;
}
main(argc,argv)
{
if( defined(_OS2_) )
{
printf("This script does not yet support OS/2.\n");
exit(EXIT_FAILURE);
}
parse_command_line(argc,argv);
tar_dir = 0;
must_dir = 0;
s = strlen(target);
if( target[s-1]==filename_separator[0] )
{
target[s-1] = '\0';
must_dir = 1;
}
if( !strcmp(target,".") )
{
strcat(target,filename_separator);
tarfiles = NULL;
} else tarfiles = Directory(target);
if( tarfiles==NULL )
{
if( !strcmp(target,".\\") ) tar_dir = 1;
if( isalpha(target[0]) && target[1]==':' &&
(target[2]=='\0' ||
((target[2]=='/' || target[2]=='\\') && target[3]=='\0') ) )
tar_dir = 1;
} else {
if( GetArraySpan(tarfiles)>0 )
{
// This is the case where the user typed something like : copy *.txt *.bak
printf("Cannot copy file(s) to multiple destinations.\n");
exit(EXIT_FAILURE);
}
strcpy(target,tarfiles[0].name);
if( tarfiles[0].attrib & _A_SUBDIR )
{
tar_dir = 1;
strcat(target,"\\");
}
}
if( must_dir && !tar_dir )
{
printf("Destination specified as a directory but is actually a file.\n");
exit(EXIT_FAILURE);
}
if( num_source==1 )
{
files = Directory(source[0]);
if( files==NULL )
{
printf("No such file or directory.\n");
exit(EXIT_FAILURE);
}
// If multiple file move, the target must be a directory, otherwise just copy
// the old file to the new one.
if( GetArraySpan(files)>0 )
{
if( !tar_dir )
{
copy_multiple(target); exit(EXIT_SUCCESS);
}
for( i=0;i<=GetArraySpan(files);i++ )
{
if( (files[i].attrib & _A_SUBDIR)==0 )
{
strcpy(tmp,target);
strcat(tmp,get_filename(files[i].name));
copy_file(files[i].name,tmp);
}
}
} else {
if( tar_dir )
{
sprintf(tmp,"%s%s",target,get_filename(files[0].name));
} else {
strcpy(tmp,target);
}
copy_file(files[0].name,tmp);
}
} else {
// In this case, we copy multiple files into a single file, concatenating them
if( tar_dir )
{
sprintf(tmp,"%s%s",target,get_filename(files[0].name));
} else {
strcpy(tmp,target);
}
copy_multiple(tmp);
}
}