// macCOPY.c 10/3/90 G.Garchar
#include "Resources.h"
#include "memory.h"
#include "Files.h"
#include "Types.h"
#include "dosintosh.h"
void macCOPY(char line1[], char line2[], int (*callback[])());
main(char *input, int (*callback[])(), short prefrefnum) {
unsigned char sPath[256], dPath[256];
int i;
i = (*callback[ParsePathCallBack])(input,sPath);
input += i;
i = (*callback[ParsePathCallBack])(input,dPath);
macCOPY(sPath,dPath,callback);
}
#include "Common.c" // done after the main() proc!!!
void WildStamp(char pat[], char name[]) {
/* takes a name and pattern and returns a new name */
short x, y = 0; // POSITIONS IN PAT AND NAME CHARACTER ARRAYS
short nLen;
nLen = strlen(name);
for (x = 0; pat[x] != '\0'; x++) {
if (pat[x] == '?') { // SKIP THIS CHARACTER
if (x < nLen) // PATTERN POSITION WITHIN NAME?
y += 1;
}
else { // STAMP THIS CHARACTER
if (pat[x] == '*') { // STAMP REMAINING CHARACTERS?
if (nLen < strlen(name)) name[y] = '\0';
return;
}
name[y] = pat[x];
y += 1;
}
}
name[y] = '\0'; // NAME SAME LENGTH AS PATTERN
}
void MakeName(char name[], char spec[]) {
char dotStr[2] = {'.','\0'};
char nameExt[256];
char specExt[256];
SplitDot(name, nameExt);
SplitDot(spec, specExt);
WildStamp(spec, name);
WildStamp(specExt, nameExt);
if (strcmp(nameExt, dotStr) == 0) *nameExt = '\0';
strcat(name, nameExt);
strcat(spec, specExt);
}
long GetFileNum(index, volNo, dirID, name, info)
short index;
short volNo;
long dirID;
char name[];
struct {
OSType fdType;
OSType fdCreator;
unsigned long mdDate;
} *info;
{
char pString[256];
HFileInfo pBlock;
pBlock.ioNamePtr = pString; // RESERVE STRING MEMORY
pBlock.ioVRefNum = volNo;
pBlock.ioFDirIndex = index;
pBlock.ioDirID = dirID;
strcpy(pBlock.ioNamePtr, name);
c2pstr(pBlock.ioNamePtr);
if (PBHGetFInfo((HParmBlkPtr)&pBlock, false) == noErr) {
p2cstr(pBlock.ioNamePtr);
strcpy(name, pBlock.ioNamePtr);
info->fdType = pBlock.ioFlFndrInfo.fdType;
info->fdCreator = pBlock.ioFlFndrInfo.fdCreator;
info->mdDate = pBlock.ioFlMdDat;
return pBlock.ioDirID;
}
else
return 0L;
}
long OpenDest(short dVolNo, long dDirID, char dName[]) {
/* opens, or creates empty destination file, returns refnum */
char pString[256];
HFileInfo pBlock;
pBlock.ioNamePtr = pString; // RESERVE STRING MEMORY
pBlock.ioVRefNum = dVolNo;
pBlock.ioDirID = dDirID;
strcpy(pBlock.ioNamePtr, dName);
c2pstr(pBlock.ioNamePtr);
if (PBHOpen((HParmBlkPtr)&pBlock, false)) { // OPEN DESTINATION
if (PBHCreate((HParmBlkPtr)&pBlock, false) == noErr)
PBHOpen((HParmBlkPtr)&pBlock, false);
else // FILE CREATION ERROR
return 0L;
}
return pBlock.ioFRefNum;
}
OSErr DupFile(short sVolNo, long sDirID, char sName[], short dRefNum) {
/* opens and reads source file, writes destination, closes source */
char buffer[512];
char pString[256];
HFileInfo pBlock;
HIOParam pBlock2;
OSErr eofFlag;
short sRefNum;
pBlock.ioNamePtr = pString; // RESERVE STRING MEMORY
pBlock.ioVRefNum = sVolNo;
pBlock.ioDirID = sDirID;
strcpy(pBlock.ioNamePtr, sName);
c2pstr(pBlock.ioNamePtr);
if (PBHOpen((HParmBlkPtr)&pBlock, false)) // OPEN SOURCE
return pBlock.ioResult;
pBlock.ioFDirIndex = 0; // USE NAME & DIRID
if (PBHGetFInfo((HParmBlkPtr)&pBlock, false))
return pBlock.ioResult;
sRefNum = pBlock.ioFRefNum;
pBlock2.ioBuffer = buffer;
pBlock2.ioReqCount = sizeof(buffer);
SetFPos(sRefNum, fsFromStart, 0L);
do { // TRANSFER DATA
pBlock2.ioRefNum = sRefNum;
pBlock2.ioPosMode = fsAtMark;
PBRead((ParmBlkPtr)&pBlock2, false); // READ SOURCE
eofFlag = pBlock2.ioResult;
pBlock2.ioRefNum = dRefNum;
pBlock2.ioReqCount = pBlock2.ioActCount;
pBlock2.ioPosMode = fsFromLEOF;
pBlock2.ioPosOffset = 0;
if (PBWrite((ParmBlkPtr)&pBlock2, false)) // WRITE DESTINATION
return pBlock2.ioResult;
} while (eofFlag == noErr);
pBlock2.ioRefNum = sRefNum;
PBClose((ParmBlkPtr)&pBlock2, false);
return pBlock2.ioResult;
}
OSErr SetInfo(volNo, dirID, name, info)
short volNo;
long dirID;
char name[];
struct {
OSType fdType;
OSType fdCreator;
unsigned long mdDate;
} info;
{
char pString[256];
HFileInfo pBlock;
pBlock.ioNamePtr = pString; // RESERVE STRING MEMORY
pBlock.ioVRefNum = volNo;
pBlock.ioDirID = dirID;
strcpy(pBlock.ioNamePtr, name);
c2pstr(pBlock.ioNamePtr);
pBlock.ioFDirIndex = 0; // USE NAME & DIRID
if (PBHGetFInfo((HParmBlkPtr)&pBlock, false))
return pBlock.ioResult;
pBlock.ioFlFndrInfo.fdType = info.fdType;
pBlock.ioFlFndrInfo.fdCreator = info.fdCreator;
pBlock.ioFlMdDat = info.mdDate;
pBlock.ioDirID = dirID; //(needed?)
if (PBHSetFInfo((HParmBlkPtr)&pBlock, false))
return pBlock.ioResult;
}
short CopySpec(sVolNo, sDirID, sSpec, dVolNo, dDirID, dSpec, callback)
short sVolNo;
long sDirID;
char sSpec[];
short dVolNo;
long dDirID;
char dSpec[];
int (*callback[])();
{
Boolean dSeparate = true; // FOR AT LEAST FIRST SOURCE FILE
char dName[256], sName[256];
char sNameOld[256]; // NEW FILE MIGHT MAKE INDEX+1 REREAD
HIOParam pBlock2;
long dRefNum = 0;
long sFileNum;
short dFileCount = 0; // TO BE RETURNED
short index = 0;
struct {
OSType fdType;
OSType fdCreator;
unsigned long mdDate;
} info;
do { // FIND FIRST SOURCE FILE
index += 1;
sFileNum = GetFileNum(index, sVolNo, sDirID, sName, &info);
if (!sFileNum) { // FILE NOT FOUND?
print(string(fnfstr), sSpec);
return dFileCount;
}
} while (SpecMatch(sSpec, sName) == false);
for (;;) { // DUPLICATE AND FIND NEXT SOURCE
strcpy(dName, sName);
MakeName(dName, dSpec);
if (sDirID == dDirID)
if (strcmp(sName, dName) == 0) {
print(string(NoSelfCopyStr));
return dFileCount;
}
/* OPEN DESTINATION */
dRefNum = OpenDest(dVolNo, dDirID, dName);
if (!dRefNum) {
print(string(FCrtErrStr));
return dFileCount;
}
if (dSeparate) { // RESET MARK?
dFileCount += 1;
pBlock2.ioRefNum = dRefNum;
pBlock2.ioMisc = 0; // CLEAR DESTINATION
PBSetEOF((ParmBlkPtr)&pBlock2, false);
dSeparate = strchr(dSpec, '*') || strchr(dSpec, '?');
}
print(string(nameStr2), sName);
DupFile (sVolNo, sDirID, sName, dRefNum); // DUPLICATE SOURCE FILE
pBlock2.ioRefNum = dRefNum;
PBClose((ParmBlkPtr)&pBlock2, false); // CLOSE DESTINATION
SetInfo(dVolNo, dDirID, dName, info);
strcpy(sNameOld, sName); // SAVE TO COMPARE
do { // GET NEXT MATCHING SOURCE FILE
do { // GET NEXT NEW SOURCE FILE
index += 1;
sFileNum = GetFileNum(index, sVolNo, sDirID, sName, &info);
if (sFileNum == 0) return dFileCount;
} while (strcmp(sNameOld, sName) == 0);
} while (SpecMatch(sSpec, sName) == false);
if (!dSeparate) GetDateTime(&info.mdDate);
}
}
void macCOPY(char line1[], char line2[], int (*callback[])()) {
char path[256];
char dSpec[256], sSpec[256];
long dDirID, sDirID;
short dVolNo, sVolNo;
short fileCount;
short result;
if (*line1 == '\0') { // EMPTY COMMAND LINE?
print(string(invParamStr)); // INVALID NUMBER OF PARAMETERS!
return;
}
/* FIGURE SOURCE */
result = GetSpec(line1, path, sSpec, &sDirID, &sVolNo);
if (result == 1) print(string(invSVolStr));
else if (result == 2) print(string(invSDirStr));
else { /* FIGURE DESTINATION */
result = GetSpec(line2, path, dSpec, &dDirID, &dVolNo);
if (result == 1) print(string(invDVolStr));
else if (result == 2) print(string(invDDirStr));
else { // DO COPY
fileCount =
CopySpec(sVolNo, sDirID, sSpec, dVolNo, dDirID, dSpec, callback);
print(string(footerCopStr), fileCount);
}
}
}