home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
500-599
/
ff510.lzh
/
ATCopy
/
ATCopy.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-29
|
19KB
|
654 lines
/* $Revision Header *** Header built automatically - do not edit! ***********
*
* (C) Copyright 1990/91 by Peter Vorwerk
*
* Name .....: ATCopy.c
* Created ..: Sunday 09-Sep-90 15:12
* Revision .: 22
*
* Date Author Comment
* ========= ======== ====================
* 29-Apr-91 Peter Vorwerk Recompiled with 5.0d
* 05-Feb-91 Peter Vorwerk Now will find XT's
* --------- ------------- ------- 2.2 -----------
* 12-Jan-91 Peter Vorwerk New Intro
* 12-Jan-91 Peter Vorwerk Bugfixing for SideCar's
* 10-Jan-91 Peter Vorwerk New FileRequester
* 08-Jan-91 Peter Vorwerk Bugfixing Conversion of char's
* 07-Jan-91 Peter Vorwerk Speed up OPT B option
* --------- ------------- ------- 2.1 ------------
* 01-Jan-91 Peter Vorwerk Two versions
* 29-Dec-90 Peter Vorwerk Bugfixing (File size)
* --------- ------------- ------- 2.0 ------------
* 11-Nov-90 Peter Vorwerk Bugfixing (FileRequester)
* 29-Oct-90 Peter Vorwerk PC Namenkonventionen (2.0)
* 27-Oct-90 Peter Vorwerk Bugfixing
* 27-Oct-90 Peter Vorwerk PC part resident
* 22-Oct-90 Peter Vorwerk Bugfixing
* 22-Oct-90 Peter Vorwerk Multi buffers (PD <-> SHARE)
* 19-Oct-90 Peter Vorwerk 8 small (128) buffers
* 18-Oct-90 Peter Vorwerk Bugfixing
* 17-Oct-90 Peter Vorwerk Double Buffer
* 15-Oct-90 Peter Vorwerk Bugfixing
* 10-Oct-90 Peter Vorwerk Allocates JanusRAM
* 21-Sep-90 Peter Vorwerk Full WB Support
* 15-Sep-90 Peter Vorwerk Suports conversion
* 14-Sep-90 Peter Vorwerk Bugfixing
* 13-Sep-90 Peter Vorwerk Now suports joker
* 13-Sep-90 Peter Vorwerk Multi File no Wildcards
* 10-Sep-90 Peter Vorwerk Stop at Timeout
* 10-Sep-90 Peter Vorwerk Bugs fixed
* 09-Sep-90 Peter Vorwerk Eine Datei keine Konversion
* 09-Sep-90 Peter Vorwerk Created this file!
*
* $Revision Header ********************************************************/
#define REVISION 22
#define VERSION 2
#include <stdio.h>
#include <exec/types.h> /* Include-Files laden */
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/devices.h>
#include <exec/io.h>
#include <exec/libraries.h>
#include <exec/interrupts.h>
#include <devices/trackdisk.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/arpbase.h>
#include <libraries/filehandler.h>
#include <workbench/startup.h>
#include <intuition/intuition.h>
#include <string.h>
#include <janus/janus.h>
#include <KDBase.h>
char *Copy = "ATCopy2.22 (c) 29.04.1991 by Peter Vorwerk";
extern char *scdir(char *);
#ifdef TEST
long cumsec = 0,cummic = 0,sec1,sec2,mic1,mic2;
#endif
#define NUMBUF 24
#define DATA_LEN 129+1+1
/* 129 = 128 + 1 = Bufferlänge plus eins für überlange Blocke */
/* 1 für akktuelle Blocklänge (neu ab V2.1) */
/* 1 für Flag je Block */
#define BLOCK_LEN 129+1
/* 129 = 128 + 1 = Bufferlänge plus eins für überlange Blocke */
/* 1 für akktuelle Blocklänge (neu ab V2.1) */
#define B 'B'
#define NC 'N'
#define CR 'C'
#define NONE '\0'
/* Offset's für Parameter RAM (16K) */
/* Diese Werte gelten sowohl für die PC- als auch für die AT-Karte. */
#define FileFlag0 BASIS
#define FileData0 BASIS + NUMBUF
#define FILENAME 0x10
#define NEWDATA 0x20
#define LASTDATA 0x30
#define CLOSEFILE 0x40
#define EMERGENCY 0x50
#define SLEEP 0x60
/* Wird NOCH nicht benötigt, da das Programm auf dem PC/AT
noch nicht resident mitläuft. Erst ab V2.0. */
#ifndef MAXTIME
#define MAXTIME 20
#endif
#define AT 1
#define XT 2
#define SideCar 3
struct AlertMessage
{
SHORT LeftEdge;
BYTE TopEdge;
char AlertText[50];
BYTE Flag;
};
struct Library *IconBase = NULL;
struct Library *JanusBase = NULL;
struct Library *KD_FReqBase = NULL;
UBYTE *Flag = NULL;
UBYTE *Data = NULL;
FILE *fh = NULL;
UBYTE directory[128];
UBYTE filename[32];
UBYTE pattern[32];
struct ExtraData extras;
extern struct AlertMessage TimeOut[];
#define TIMEOUT 80L
extern struct AlertMessage NoLib[];
#define NOLIB 80L
char tabelle[128] =
{
/* 0x80 */ 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
/* 0x88 */ 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
/* 0x90 */ 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
/* 0x98 */ 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
/* 0xa0 */ 0x7f,0xad,0x9b,0x9c,0x7f,0x9d,0x7f,0x7f,
/* 0xa8 */ 0x7f,0x7f,0xa6,0xae,0xaa,0x7f,0x7f,0xfe,
/* 0xb0 */ 0xf8,0xf1,0xfd,0x7f,0x7f,0xe6,0x7f,0xf9,
/* 0xb8 */ 0x7f,0x7f,0xa7,0xaf,0xac,0xab,0x7f,0xa8,
/* 0xc0 */ 0x7f,0x7f,0x7f,0x7f,0x8e,0x8f,0x92,0x80,
/* 0xc8 */ 0x7f,0x90,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
/* 0xd0 */ 0x7f,0xa5,0x7f,0x7f,0x7f,0x7f,0x99,0x7f,
/* 0xd8 */ 0x7f,0x7f,0x7f,0x7f,0x9a,0x7f,0x7f,0xe1,
/* 0xe0 */ 0x85,0xa0,0x83,0x7f,0x84,0x86,0x91,0x87,
/* 0xe8 */ 0x8a,0x82,0x88,0x89,0x8d,0xa1,0x8c,0x8b,
/* 0xf0 */ 0xeb,0xa4,0x95,0xa2,0x93,0x7f,0x94,0xf6,
/* 0xf8 */ 0xed,0x97,0xa3,0x96,0x81,0x7f,0x7f,0x98
};
/* In BASIS wird die BasisAdresse der PC/AT eingetragen. */
APTR BASIS = NULL;
char ATCP[16];
extern struct NewWindow NewWindowStructure1;
extern struct IntuiText IText9;
void Version(void)
{
SPrintf(ATCP,"ATCopy V%ld.%ld",VERSION,REVISION);
NewWindowStructure1.Title = (UBYTE *) ATCP;
IText9.IText = (UBYTE *) ATCP;
}
void CheckForPC(void)
{
/* Ermitteln, ob und wenn ja ab welcher Adresse die PC/AT Karte ansprechbar ist. */
if ((BASIS = AllocJanusMem(DATA_LEN * NUMBUF,MEMF_PARAMETER | MEM_BYTEACCESS)) == NULL)
{
DisplayAlert(RECOVERY_ALERT,(char *) &NoLib,NOLIB);
exit(20);
}
}
int CheckPC(unsigned char *ptr)
{
ptr += 0x7fff7;
/* Modus Register der XT/AT Karte siehe 'Amiga SYSTEM-Handbuch' */
if (*ptr >= 0xe0 || *ptr == 0)
{
return(SideCar);
}
/* Beim SideCar ist dieses Register mit DIP-Schltern aufgebaut.
Daher die merkwürdige Abfrage. */
if (*ptr < 128)
{
return(AT);
}
return(XT);
}
void WakeUpPC(void)
{
unsigned char *ptr,*key,*intr;
int i;
UWORD *offset;
long stsecs,stmics,ensecs,enmics;
/* Auslösen eines (Software-) Interupts auf dem PC/AT um das schlafende Programm
zu wecken! */
/* Zur Zeit ( noch ? ) nicht so möglich! Es wird entweder das Programm AT.exe
oder das Programm XT.exe auf dem PC aufgerufen. Dazu werden die Zeichen
A (X), T und {CR} direkt zum PC gesendet. Simulierte Tastatur. */
/* Die Keyboard Addresse ist als positiver Offset 0x72 in der Janus.library abgelegt. */
/* Achtung! Im 'Amiga SYSTEM-Handbuch wird die feste Addresse 0x7ffff als Keyboard Addresse
genannt. Bei meinem Amiga 2000 mit AT Karte stimmte dies, jedoch nicht beim SideCar.
Die Offset Struktur wurde experimentell ( teilweiser Speicherdump vom Programm
PCWINDOW ) ermittelt. Zum Glück stimmte wenigstens die Adresse des Interrupts,
so konnte ich im Speicher nach dem Auftreten dieser Kombination suchen und die
nähere Umgebung disassemblieren. */
key = (unsigned char *) JanusBase;
key += 0x72;
offset = (UWORD *) key;
ptr = (unsigned char *) GetJanusStart();
key = ptr + 0x7e000;
key += *offset;
intr = ptr + 0x7fffb; /* Addresse aus 'Amiga SYSTEM-Handbuch' */
*key = '\034'; /* {CR} */
*intr = '\377'; /* 0xff */
Delay(1);
i = CheckPC(ptr);
if (i == AT)
{
*key = '\036'; /* 'A' */
}
else
{
*key = '\055'; /* 'X' */
}
*intr = '\377'; /* 0xff */
Delay(1);
*key = '\024'; /* 'T' */
*intr = '\377'; /* 0xff */
Delay(1);
*key = '\034'; /* {CR} */
*intr = '\377'; /* 0xff */
/* Bei diesen Codes handelt es sich natürlich um die Roh-Codes der PC-Tastatur ! */
/* Siehe Handbücher zu Turbo Pascal o.ä. */
ptr = (unsigned char *) BASIS;
*ptr++ = '\011'; /* Länge des Strings "ATCopy2.1" octal ! */
strcpy((char *) ptr,"ATCopy2.1");
/* Kein Änderung im Protokoll => 2.1 und 2.2 können gemischt werden.
Aber nicht 2.0 mit 2.x !!! */
/* Die Startaddresse des angeforderten Buffers wird mit dem Text markiert und
danach vom PC aus gesucht. Siehe PCCOPY.PAS */
ptr--;
CurrentTime(&stsecs,&stmics);
while(*ptr != 0)
{
Chk_Abort();
CurrentTime(&ensecs,&enmics);
/* Wenn der XT/AT nich innerhalb von 20 Sekunden antworted das Programm abbrechen. */
if (ensecs - stsecs > MAXTIME * 2)
{
DisplayAlert(RECOVERY_ALERT,(char *) &TimeOut,TIMEOUT);
FreeTrackedItem(GetTracker(TRAK_FREQ));
FreeJanusMem(BASIS,DATA_LEN * NUMBUF);
exit(20);
}
}
Flag = (UBYTE *) FileFlag0;
for(i = 0; i < NUMBUF; i++)
{
*Flag++ = 0;
}
/* Alle Buffer sind leer und können benutzt werden. */
}
void _abort(void)
{
#ifdef TEST
Printf("\nInsgesamt %ld µsec gewarted.\n",cumsec*1000000+cummic);
#endif
#ifdef DEBUG
Printf("\nLast Flag = <%lx>\n",*Flag);
#endif
*Flag = EMERGENCY;
FreeTrackedItem(GetTracker(TRAK_FREQ));
FreeJanusMem(BASIS,DATA_LEN * NUMBUF);
if (fh)
fclose(fh); /* Da hier Programmende kann <fh = NULL;> entfallen. */
exit(20);
}
void timeout(void)
{
long stsecs,stmics,ensecs,enmics;
/* Prüfen, ob der Kanal frei ist und ggf. darauf warten. Dauert es
allerdings länger als 10 Sekunden => Abbruch. */
#ifdef TEST
CurrentTime(&sec1,&mic1);
#endif
CurrentTime(&stsecs,&stmics);
while(*Flag != 0)
{
Delay(1);
Chk_Abort();
CurrentTime(&ensecs,&enmics);
if (ensecs - stsecs > MAXTIME)
{
#ifdef TEST
CurrentTime(&sec2,&mic2);
cumsec += sec2-sec1;
cummic += mic2-mic1;
Printf("\nInsgesamt %ld µsec gewarted.\n",cumsec*1000000+cummic);
#endif
#ifdef DEBUG
Printf("\nLast Flag = <%lx>\n",*Flag);
#endif
*Flag = EMERGENCY;
DisplayAlert(RECOVERY_ALERT,(char *) &TimeOut,TIMEOUT);
FreeTrackedItem(GetTracker(TRAK_FREQ));
FreeJanusMem(BASIS,DATA_LEN * NUMBUF);
if (fh)
fclose(fh); /* Da hier Progende kann fh = NULL; entfallen. */
exit(20);
}
}
#ifdef TEST
CurrentTime(&sec2,&mic2);
cumsec += sec2-sec1;
cummic += mic2-mic1;
#endif
}
extern int Konvert(int wert, char opt, int *flag);
extern int transfer(UBYTE * data, char opt);
int copyfile2(char *str, char *PC, char opt)
{
register int c;
static int last = 0;
int flag2 = FALSE;
register char *filename;
register UBYTE *data;
char *s,buffer[80],buffer2[60];
if (*str == '\0')
{
return(FALSE);
}
if (strlen(PC) > 0)
{
s = &PC[strlen(PC)-1];
if (*s != ':' && *s != '\\')
{
/* Der PC-Pfad muß mit ':' oder '\\' enden. */
s++;
*s++ = '\\';
*s = '\0';
}
}
filename = BaseName(str);
s = buffer2;
do
{
*s = *filename;
if (*s == '\0')
break;
/* Nicht alle Zeichen sind beim PC für Dateinamen erlaubt. */
if (*s < '\041' || *s == '\\' ||
*s == '[' || *s == ']' ||
*s == '|' || *s > '\177')
{
filename++;
s--;
continue;
}
if (*s == '.')
{
filename = strrchr(filename,'.');
}
/* Suchen des letzten '.' nur eine Extension ist beim PC/AT möglich. */
filename++;
}
while(*s++ != '\0');
if (buffer2[0] == '.' || buffer2[0] == '\0')
{
return(TRUE);
}
/* Der Name darf nicht leer "" sein oder nur aus einer Extension bestehen. */
if ((fh = fopen(str,"r")) == NULL)
{
return(FALSE);
}
/* File läst sich auf der Amigaseite nicht öffnen. => Programm abbrechen. */
strcpy(buffer,PC);
strcat(buffer,buffer2);
timeout();
data = Data;
c = strlen(buffer);
*data++ = c;
filename = buffer;
while(*filename != '\0')
{
*data++ = *filename++;
}
/* Dateiname übertragen. Längenbyte gefolgt vom Text ; PASCAL-Format. */
*Flag = FILENAME;
if (*Flag != FILENAME && *Flag != 0)
*Flag = EMERGENCY;
/* Wenn direkt nach dem Schreibzugriff NICHT der Wert im Speicher steht ist
ein Fehler aufgetreten. Sollte NIE vorkommem. => Programm abbrechen. */
do
{
Flag++;
Data += BLOCK_LEN;
last++;
/* Umschalten auf den nächsten Buffer. Ringpuffer */
if (last == NUMBUF)
{
last = 0;
Flag = (UBYTE *) FileFlag0;
Data = (UBYTE *) FileData0;
}
}
while(transfer(Data,opt));
Flag++;
Data += BLOCK_LEN;
last++;
if (last == NUMBUF)
{
last = 0;
Flag = (UBYTE *) FileFlag0;
Data = (UBYTE *) FileData0;
}
fclose(fh);
fh = NULL;
/* FileHandle löschen damit bei einem Fehler nicht die Datei noch einmal
geschlossen wird. Der GURU läst grüßen! */
return(TRUE);
}
extern char Intro(char **pc,char *opt);
int copyfile(char *str, char *PC, char *Option)
{
int flag;
char buffer[162],opt;
struct FileList *ext;
if (PC == NULL || *PC == '\0')
PC = "\0 default PC-path";
if (Option == NULL)
Option = "\0 Option"; /* Hier die gewünschte 'Default' Option eintragen. */
opt = Intro(&PC,Option);
if (opt == 255 || opt == -1)
return(FALSE);
*Option = opt;
/* Per Requester ausgewählte Option speichern. */
if (str == NULL || *str == '\0')
{
/* Wenn kein Dateiname per CLI oder WB übergeben wurde diesen per Requester anfordern. */
filename[0] = 0;
extras.oktext = (UBYTE *) "Copy";
extras.canceltext = (UBYTE *) "No Way!";
if (FReq(NULL, (UBYTE *) ATCP,filename,directory,pattern, FR_CANCELTEXT |
FR_EXTENDEDSELECT | FR_OKTEXT | FR_AUTOPOSITION | FR_AUTOSIZE |
FR_NOINFO | FR_SCREENFONT ,&extras))
{
flag = FALSE;
if (extras.ExtendedList)
{
/* Wenn Extendet Select, siehe KR_FREQ.DOC, gewählt wurde NUR diese auswerten. */
ext = extras.ExtendedList;
for (; ext; ext = ext->next)
{
strcpy(buffer,(char *) directory);
strcat(buffer,(char *) ext->FileName);
flag = copyfile2(buffer,PC,opt);
}
FreeMem(extras.ExtendedList,extras.ExtendedList->private);
extras.ExtendedList = NULL;
}
else
{
/* Ansonsten den Dateinamen lesen. */
strcpy(buffer,(char *) directory);
strcat(buffer,(char *) filename);
flag = copyfile2(buffer,PC,opt);
}
}
else
{
/* Keine Auswahl bzw. CAncel gewählt => ENDE! */
return(FALSE);
}
}
else
{
/* Dateinamen per CLI oder WB vorgegeben. */
flag = copyfile2(str,PC,opt);
}
return(flag);
}
void main(int argc, char *argv[])
{
register char **demo;
register char *s;
int wbmax,i;
struct DiskObject *Do;
struct WBStartup *Wbs;
struct Process *proc = (struct Process *)FindTask(NULL);
struct FileLock *origlock;
Version();
directory[0] = filename[0] = pattern[0] = 0;
/* Lib's öffnen. */
if (!(JanusBase = ArpOpenLibrary("janus.library",0L)))
{
DisplayAlert(RECOVERY_ALERT,(char *) &NoLib,NOLIB);
exit(10);
}
if (!(KD_FReqBase = ArpOpenLibrary(KLIBNAME,KLIBVERSION)))
{
Puts("KD_FREQ.LIBRARY fehlt!\n");
exit(10);
}
CheckForPC(); /* Ermitteln der Basisadresse. */
WakeUpPC(); /* AT.EXE oder XT.EXE aufrufen. */
Flag = (UBYTE *) FileFlag0;
Data = (UBYTE *) FileData0;
if (argc > 0)
{
demo = (char **) argv[1];
if (demo != NULL)
{
if (*demo != NULL)
{
while(*demo != NULL)
{
/* Wenn Jokerzeichen im Argument sind, diese Auswerten mit scdir(). */
while(s = scdir(*demo))
{
/* S ist aufgelöster Name, der zum Joker paßt. */
copyfile(s,argv[2],argv[3]);
}
demo++;
}
}
else
{
do ; while(copyfile(NULL,argv[2],argv[3]));
}
}
else
{
do ; while(copyfile(NULL,argv[2],argv[3]));
}
}
else /* WB Aufruf */
{
origlock = (struct FileLock *) CurrentDir(DupLock((BPTR) proc->pr_CurrentDir));
Wbs = (struct WBStartup *) argv;
if (!(IconBase = ArpOpenLibrary("icon.library",0L)))
{
exit(10);
}
if (Wbs->sm_ArgList[0].wa_Lock)
{
struct FileLock *savelock = (struct FileLock *) CurrentDir(Wbs->sm_ArgList[0].wa_Lock);
if (Do = (struct DiskObject *) GetDiskObject(Wbs->sm_ArgList[0].wa_Name))
{
FreeDiskObject(Do);
}
CurrentDir((BPTR) savelock);
}
if ((wbmax = Wbs->sm_NumArgs - 1) == 0)
{
do ; while(copyfile(NULL,NULL,NULL)); /* Ganz ohne Parameter zB WorkBench */
}
else
{
for(i = 0; i < wbmax; i++)
{
UnLock(CurrentDir(DupLock((BPTR) Wbs->sm_ArgList[i+1].wa_Lock)));
if (Do = (struct DiskObject *) GetDiskObject(Wbs->sm_ArgList[i+1].wa_Name))
{
FreeDiskObject(Do);
}
copyfile(Wbs->sm_ArgList[i+1].wa_Name,NULL,NULL);
}
}
origlock = (struct FileLock *) CurrentDir((BPTR) origlock);
}
timeout();
*Flag = EMERGENCY;
timeout(); /* Warten bis XT/AT fertig ist. Dann Speicher freigeben! */
#ifdef TEST
Printf("\nInsgesamt %ld µsec gewarted.\n",cumsec*1000000+cummic);
#endif
FreeTrackedItem(GetTracker(TRAK_FREQ));
FreeJanusMem(BASIS,DATA_LEN * NUMBUF);
}
/* Das war's. */