home *** CD-ROM | disk | FTP | other *** search
- /* $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. */
-