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 >
C/C++ Source or Header  |  1991-06-29  |  19KB  |  654 lines

  1. /* $Revision Header *** Header built automatically - do not edit! ***********
  2.  *
  3.  *      (C) Copyright 1990/91 by Peter Vorwerk
  4.  *
  5.  *      Name .....: ATCopy.c
  6.  *      Created ..: Sunday 09-Sep-90 15:12
  7.  *      Revision .: 22
  8.  *
  9.  *      Date            Author          Comment
  10.  *      =========       ========        ====================
  11.  *      29-Apr-91       Peter Vorwerk   Recompiled with 5.0d
  12.  *      05-Feb-91       Peter Vorwerk   Now will find XT's
  13.  *      ---------       -------------   ------- 2.2 -----------
  14.  *      12-Jan-91       Peter Vorwerk   New Intro
  15.  *      12-Jan-91       Peter Vorwerk   Bugfixing for SideCar's
  16.  *      10-Jan-91       Peter Vorwerk   New FileRequester
  17.  *      08-Jan-91       Peter Vorwerk   Bugfixing Conversion of char's
  18.  *      07-Jan-91       Peter Vorwerk   Speed up OPT B option
  19.  *      ---------       -------------   ------- 2.1 ------------
  20.  *      01-Jan-91       Peter Vorwerk   Two versions
  21.  *      29-Dec-90       Peter Vorwerk   Bugfixing (File size)
  22.  *      ---------       -------------   ------- 2.0 ------------
  23.  *      11-Nov-90       Peter Vorwerk   Bugfixing (FileRequester)
  24.  *      29-Oct-90       Peter Vorwerk   PC Namenkonventionen (2.0)
  25.  *      27-Oct-90       Peter Vorwerk   Bugfixing
  26.  *      27-Oct-90       Peter Vorwerk   PC part resident
  27.  *      22-Oct-90       Peter Vorwerk   Bugfixing
  28.  *      22-Oct-90       Peter Vorwerk   Multi buffers (PD <-> SHARE)
  29.  *      19-Oct-90       Peter Vorwerk   8 small (128) buffers
  30.  *      18-Oct-90       Peter Vorwerk   Bugfixing
  31.  *      17-Oct-90       Peter Vorwerk   Double Buffer
  32.  *      15-Oct-90       Peter Vorwerk   Bugfixing
  33.  *      10-Oct-90       Peter Vorwerk   Allocates JanusRAM
  34.  *      21-Sep-90       Peter Vorwerk   Full WB Support
  35.  *      15-Sep-90       Peter Vorwerk   Suports conversion
  36.  *      14-Sep-90       Peter Vorwerk   Bugfixing
  37.  *      13-Sep-90       Peter Vorwerk   Now suports joker
  38.  *      13-Sep-90       Peter Vorwerk   Multi File no Wildcards
  39.  *      10-Sep-90       Peter Vorwerk   Stop at Timeout
  40.  *      10-Sep-90       Peter Vorwerk   Bugs fixed
  41.  *      09-Sep-90       Peter Vorwerk   Eine Datei keine Konversion
  42.  *      09-Sep-90       Peter Vorwerk   Created this file!
  43.  *
  44.  * $Revision Header ********************************************************/
  45.  #define REVISION 22
  46.  
  47. #define VERSION 2
  48.  
  49. #include <stdio.h>
  50. #include <exec/types.h>       /* Include-Files laden */
  51. #include <exec/memory.h>
  52. #include <exec/ports.h>
  53. #include <exec/devices.h>
  54. #include <exec/io.h>
  55. #include <exec/libraries.h>
  56. #include <exec/interrupts.h>
  57. #include <devices/trackdisk.h>
  58. #include <libraries/dos.h>
  59. #include <libraries/dosextens.h>
  60. #include <libraries/arpbase.h>
  61. #include <libraries/filehandler.h>
  62. #include <workbench/startup.h>
  63. #include <intuition/intuition.h>
  64. #include <string.h>
  65. #include <janus/janus.h>
  66.  
  67. #include <KDBase.h>
  68.  
  69. char *Copy = "ATCopy2.22 (c) 29.04.1991 by Peter Vorwerk";
  70.  
  71. extern char *scdir(char *);
  72.  
  73. #ifdef TEST
  74. long cumsec = 0,cummic = 0,sec1,sec2,mic1,mic2;
  75. #endif
  76.  
  77. #define NUMBUF   24
  78. #define DATA_LEN 129+1+1
  79.  
  80. /* 129 = 128 + 1 = Bufferlänge plus eins für überlange Blocke */
  81. /* 1 für akktuelle Blocklänge (neu ab V2.1) */
  82. /* 1 für Flag je Block */
  83.  
  84. #define BLOCK_LEN 129+1
  85.  
  86. /* 129 = 128 + 1 = Bufferlänge plus eins für überlange Blocke */
  87. /* 1 für akktuelle Blocklänge (neu ab V2.1) */
  88.  
  89. #define B    'B'
  90. #define NC   'N'
  91. #define CR   'C'
  92. #define NONE '\0'
  93.  
  94. /* Offset's für Parameter RAM (16K) */
  95. /* Diese Werte gelten sowohl für die PC- als auch für die AT-Karte. */
  96.  
  97. #define FileFlag0 BASIS
  98. #define FileData0 BASIS + NUMBUF
  99.  
  100. #define FILENAME   0x10
  101. #define NEWDATA    0x20
  102. #define LASTDATA   0x30
  103. #define CLOSEFILE  0x40
  104. #define EMERGENCY  0x50
  105.  
  106. #define SLEEP      0x60
  107. /* Wird NOCH nicht benötigt, da das Programm auf dem PC/AT
  108.    noch nicht resident mitläuft. Erst ab V2.0. */
  109.  
  110. #ifndef MAXTIME
  111. #define MAXTIME 20
  112. #endif
  113.  
  114. #define AT      1
  115. #define XT      2
  116. #define SideCar 3
  117.  
  118. struct AlertMessage
  119. {
  120.     SHORT LeftEdge;
  121.     BYTE  TopEdge;
  122.     char  AlertText[50];
  123.     BYTE  Flag;
  124. };
  125.  
  126. struct Library   *IconBase    = NULL;
  127. struct Library   *JanusBase   = NULL;
  128. struct Library   *KD_FReqBase = NULL;
  129. UBYTE            *Flag        = NULL;
  130. UBYTE            *Data        = NULL;
  131. FILE             *fh          = NULL;
  132. UBYTE            directory[128];
  133. UBYTE            filename[32];
  134. UBYTE            pattern[32];
  135. struct ExtraData extras;
  136.  
  137. extern struct AlertMessage TimeOut[];
  138.  
  139. #define TIMEOUT 80L
  140.  
  141. extern struct AlertMessage NoLib[];
  142.  
  143. #define NOLIB 80L
  144.  
  145. char tabelle[128] =
  146. {
  147.     /* 0x80 */ 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
  148.     /* 0x88 */ 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
  149.     /* 0x90 */ 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
  150.     /* 0x98 */ 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
  151.     /* 0xa0 */ 0x7f,0xad,0x9b,0x9c,0x7f,0x9d,0x7f,0x7f,
  152.     /* 0xa8 */ 0x7f,0x7f,0xa6,0xae,0xaa,0x7f,0x7f,0xfe,
  153.     /* 0xb0 */ 0xf8,0xf1,0xfd,0x7f,0x7f,0xe6,0x7f,0xf9,
  154.     /* 0xb8 */ 0x7f,0x7f,0xa7,0xaf,0xac,0xab,0x7f,0xa8,
  155.     /* 0xc0 */ 0x7f,0x7f,0x7f,0x7f,0x8e,0x8f,0x92,0x80,
  156.     /* 0xc8 */ 0x7f,0x90,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
  157.     /* 0xd0 */ 0x7f,0xa5,0x7f,0x7f,0x7f,0x7f,0x99,0x7f,
  158.     /* 0xd8 */ 0x7f,0x7f,0x7f,0x7f,0x9a,0x7f,0x7f,0xe1,
  159.     /* 0xe0 */ 0x85,0xa0,0x83,0x7f,0x84,0x86,0x91,0x87,
  160.     /* 0xe8 */ 0x8a,0x82,0x88,0x89,0x8d,0xa1,0x8c,0x8b,
  161.     /* 0xf0 */ 0xeb,0xa4,0x95,0xa2,0x93,0x7f,0x94,0xf6,
  162.     /* 0xf8 */ 0xed,0x97,0xa3,0x96,0x81,0x7f,0x7f,0x98
  163. };
  164.  
  165. /* In BASIS wird die BasisAdresse der PC/AT eingetragen. */
  166.  
  167. APTR BASIS = NULL;
  168.  
  169. char ATCP[16];
  170.  
  171. extern struct NewWindow NewWindowStructure1;
  172. extern struct IntuiText IText9;
  173.  
  174. void Version(void)
  175. {
  176.     SPrintf(ATCP,"ATCopy V%ld.%ld",VERSION,REVISION);
  177.     NewWindowStructure1.Title = (UBYTE *) ATCP;
  178.     IText9.IText = (UBYTE *) ATCP;
  179. }
  180.  
  181. void CheckForPC(void)
  182. {
  183. /* Ermitteln, ob und wenn ja ab welcher Adresse die PC/AT Karte ansprechbar ist. */
  184.  
  185.     if ((BASIS = AllocJanusMem(DATA_LEN * NUMBUF,MEMF_PARAMETER | MEM_BYTEACCESS)) == NULL)
  186.     {
  187.        DisplayAlert(RECOVERY_ALERT,(char *) &NoLib,NOLIB);
  188.        exit(20);
  189.     }
  190. }
  191.  
  192. int CheckPC(unsigned char *ptr)
  193. {
  194.     ptr += 0x7fff7;
  195. /* Modus Register der XT/AT Karte siehe 'Amiga SYSTEM-Handbuch' */
  196.  
  197.     if (*ptr >= 0xe0 || *ptr == 0)
  198.     {
  199.         return(SideCar);
  200.     }
  201. /* Beim SideCar ist dieses Register mit DIP-Schltern aufgebaut.
  202.    Daher die merkwürdige Abfrage. */
  203.     if (*ptr < 128)
  204.     {
  205.         return(AT);
  206.     }
  207.     return(XT);
  208. }
  209.  
  210. void WakeUpPC(void)
  211. {
  212.     unsigned char   *ptr,*key,*intr;
  213.     int    i;
  214.     UWORD  *offset;
  215.     long   stsecs,stmics,ensecs,enmics;
  216.  
  217. /* Auslösen eines (Software-) Interupts auf dem PC/AT um das schlafende Programm
  218.    zu wecken! */
  219.  
  220. /* Zur Zeit ( noch ? ) nicht so möglich! Es wird entweder das Programm AT.exe
  221.    oder das Programm XT.exe auf dem PC aufgerufen. Dazu werden die Zeichen
  222.    A (X), T und {CR} direkt zum PC gesendet. Simulierte Tastatur. */
  223.  
  224. /* Die Keyboard Addresse ist als positiver Offset 0x72 in der Janus.library abgelegt. */
  225. /* Achtung! Im 'Amiga SYSTEM-Handbuch wird die feste Addresse 0x7ffff als Keyboard Addresse
  226.    genannt. Bei meinem Amiga 2000 mit AT Karte stimmte dies, jedoch nicht beim SideCar.
  227.  
  228.    Die Offset Struktur wurde experimentell ( teilweiser Speicherdump vom Programm
  229.    PCWINDOW ) ermittelt. Zum Glück stimmte wenigstens die Adresse des Interrupts,
  230.    so konnte ich im Speicher nach dem Auftreten dieser Kombination suchen und die
  231.    nähere Umgebung disassemblieren. */
  232.  
  233.     key     = (unsigned char *) JanusBase;
  234.     key    += 0x72;
  235.     offset  = (UWORD *) key;
  236.     ptr     = (unsigned char *) GetJanusStart();
  237.     key     = ptr + 0x7e000;
  238.     key    += *offset;
  239.     intr    = ptr + 0x7fffb; /* Addresse aus 'Amiga SYSTEM-Handbuch' */
  240.     *key    = '\034';    /* {CR} */
  241.     *intr   = '\377';    /* 0xff */
  242.     Delay(1);
  243.     i       = CheckPC(ptr);
  244.     if (i == AT)
  245.     {
  246.         *key = '\036'; /* 'A'  */
  247.     }
  248.     else
  249.     {
  250.         *key = '\055'; /* 'X'  */
  251.     }
  252.     *intr     = '\377';    /* 0xff */
  253.     Delay(1);
  254.     *key      = '\024';    /* 'T'  */
  255.     *intr     = '\377';    /* 0xff */
  256.     Delay(1);
  257.     *key      = '\034';    /* {CR} */
  258.     *intr     = '\377';    /* 0xff */
  259.  
  260. /* Bei diesen Codes handelt es sich natürlich um die Roh-Codes der PC-Tastatur ! */
  261. /* Siehe Handbücher zu Turbo Pascal o.ä. */
  262.  
  263.     ptr = (unsigned char *) BASIS;
  264.     *ptr++ = '\011'; /* Länge des Strings "ATCopy2.1" octal ! */
  265.     strcpy((char *) ptr,"ATCopy2.1");
  266. /* Kein Änderung im Protokoll => 2.1 und 2.2 können gemischt werden.
  267.    Aber nicht 2.0 mit 2.x !!! */
  268.  
  269. /* Die Startaddresse des angeforderten Buffers wird mit dem Text markiert und
  270.    danach vom PC aus gesucht. Siehe PCCOPY.PAS */
  271.  
  272.     ptr--;
  273.     CurrentTime(&stsecs,&stmics);
  274.     while(*ptr != 0)
  275.     {
  276.         Chk_Abort();
  277.         CurrentTime(&ensecs,&enmics);
  278. /* Wenn der XT/AT nich innerhalb von 20 Sekunden antworted das Programm abbrechen. */
  279.         if (ensecs - stsecs > MAXTIME * 2)
  280.         {
  281.             DisplayAlert(RECOVERY_ALERT,(char *) &TimeOut,TIMEOUT);
  282.             FreeTrackedItem(GetTracker(TRAK_FREQ));
  283.             FreeJanusMem(BASIS,DATA_LEN * NUMBUF);
  284.             exit(20);
  285.         }
  286.     }
  287.     Flag = (UBYTE *) FileFlag0;
  288.     for(i = 0; i < NUMBUF; i++)
  289.     {
  290.         *Flag++ = 0;
  291.     }
  292. /* Alle Buffer sind leer und können benutzt werden. */
  293. }
  294.  
  295. void _abort(void)
  296. {
  297.  
  298. #ifdef TEST
  299.     Printf("\nInsgesamt %ld µsec gewarted.\n",cumsec*1000000+cummic);
  300. #endif
  301.  
  302. #ifdef DEBUG
  303.     Printf("\nLast Flag = <%lx>\n",*Flag);
  304. #endif
  305.  
  306.     *Flag = EMERGENCY;
  307.     FreeTrackedItem(GetTracker(TRAK_FREQ));
  308.     FreeJanusMem(BASIS,DATA_LEN * NUMBUF);
  309.     if (fh)
  310.         fclose(fh); /* Da hier Programmende kann <fh = NULL;> entfallen. */
  311.     exit(20);
  312. }
  313.  
  314. void timeout(void)
  315. {
  316.     long stsecs,stmics,ensecs,enmics;
  317.  
  318. /* Prüfen, ob der Kanal frei ist und ggf. darauf warten. Dauert es
  319.    allerdings länger als 10 Sekunden => Abbruch. */
  320.  
  321. #ifdef TEST
  322.     CurrentTime(&sec1,&mic1);
  323. #endif
  324.  
  325.     CurrentTime(&stsecs,&stmics);
  326.     while(*Flag != 0)
  327.     {
  328.         Delay(1);
  329.         Chk_Abort();
  330.         CurrentTime(&ensecs,&enmics);
  331.         if (ensecs - stsecs > MAXTIME)
  332.         {
  333.  
  334. #ifdef TEST
  335.     CurrentTime(&sec2,&mic2);
  336.     cumsec += sec2-sec1;
  337.     cummic += mic2-mic1;
  338.  
  339.     Printf("\nInsgesamt %ld µsec gewarted.\n",cumsec*1000000+cummic);
  340. #endif
  341.  
  342. #ifdef DEBUG
  343.             Printf("\nLast Flag = <%lx>\n",*Flag);
  344. #endif
  345.  
  346.             *Flag = EMERGENCY;
  347.             DisplayAlert(RECOVERY_ALERT,(char *) &TimeOut,TIMEOUT);
  348.             FreeTrackedItem(GetTracker(TRAK_FREQ));
  349.             FreeJanusMem(BASIS,DATA_LEN * NUMBUF);
  350.             if (fh)
  351.                 fclose(fh); /* Da hier Progende kann fh = NULL; entfallen. */
  352.             exit(20);
  353.         }
  354.     }
  355. #ifdef TEST
  356.     CurrentTime(&sec2,&mic2);
  357.     cumsec += sec2-sec1;
  358.     cummic += mic2-mic1;
  359. #endif
  360. }
  361.  
  362. extern int Konvert(int wert, char opt, int *flag);
  363.  
  364. extern int transfer(UBYTE * data, char opt);
  365.  
  366. int copyfile2(char *str, char *PC, char opt)
  367. {
  368.    register int         c;
  369.    static int           last = 0;
  370.    int                  flag2 = FALSE;
  371.    register char        *filename;
  372.    register UBYTE       *data;
  373.    char                 *s,buffer[80],buffer2[60];
  374.  
  375.    if (*str == '\0')
  376.    {
  377.        return(FALSE);
  378.    }
  379.  
  380.    if (strlen(PC) > 0)
  381.    {
  382.        s = &PC[strlen(PC)-1];
  383.        if (*s != ':' && *s != '\\')
  384.        {
  385.  
  386. /* Der PC-Pfad muß mit ':' oder '\\' enden. */
  387.            s++;
  388.            *s++ = '\\';
  389.            *s = '\0';
  390.        }
  391.    }
  392.  
  393.    filename = BaseName(str);
  394.    s = buffer2;
  395.    do
  396.    {
  397.        *s = *filename;
  398.        if (*s == '\0')
  399.            break;
  400. /* Nicht alle Zeichen sind beim PC für Dateinamen erlaubt. */
  401.  
  402.        if (*s <  '\041' || *s == '\\' ||
  403.            *s == '['    || *s == ']'  ||
  404.            *s == '|'    || *s >  '\177')
  405.        {
  406.            filename++;
  407.            s--;
  408.            continue;
  409.        }
  410.        if (*s == '.')
  411.        {
  412.            filename = strrchr(filename,'.');
  413.        }
  414. /* Suchen des letzten '.' nur eine Extension ist beim PC/AT möglich. */
  415.        filename++;
  416.    }
  417.    while(*s++ != '\0');
  418.    if (buffer2[0] == '.' || buffer2[0] == '\0')
  419.    {
  420.       return(TRUE);
  421.    }
  422. /* Der Name darf nicht leer "" sein oder nur aus einer Extension bestehen. */
  423.    if ((fh = fopen(str,"r")) == NULL)
  424.    {
  425.        return(FALSE);
  426.    }
  427. /* File läst sich auf der Amigaseite nicht öffnen. => Programm abbrechen. */
  428.    strcpy(buffer,PC);
  429.    strcat(buffer,buffer2);
  430.    timeout();
  431.    data = Data;
  432.    c = strlen(buffer);
  433.    *data++ = c;
  434.    filename = buffer;
  435.    while(*filename != '\0')
  436.    {
  437.        *data++ = *filename++;
  438.    }
  439. /* Dateiname übertragen. Längenbyte gefolgt vom Text ; PASCAL-Format. */
  440.    *Flag = FILENAME;
  441.    if (*Flag != FILENAME && *Flag != 0)
  442.         *Flag = EMERGENCY;
  443. /* Wenn direkt nach dem Schreibzugriff NICHT der Wert im Speicher steht ist
  444.    ein Fehler aufgetreten. Sollte NIE vorkommem. => Programm abbrechen. */
  445.    do
  446.    {
  447.        Flag++;
  448.        Data += BLOCK_LEN;
  449.        last++;
  450. /* Umschalten auf den nächsten Buffer. Ringpuffer */
  451.        if (last == NUMBUF)
  452.        {
  453.            last = 0;
  454.            Flag = (UBYTE *) FileFlag0;
  455.            Data = (UBYTE *) FileData0;
  456.        }
  457.    }
  458.    while(transfer(Data,opt));
  459.    Flag++;
  460.    Data += BLOCK_LEN;
  461.    last++;
  462.    if (last == NUMBUF)
  463.    {
  464.        last = 0;
  465.        Flag = (UBYTE *) FileFlag0;
  466.        Data = (UBYTE *) FileData0;
  467.    }
  468.    fclose(fh);
  469.    fh = NULL;
  470. /* FileHandle löschen damit bei einem Fehler nicht die Datei noch einmal
  471.    geschlossen wird. Der GURU läst grüßen! */
  472.    return(TRUE);
  473. }
  474.  
  475. extern char Intro(char **pc,char *opt);
  476.  
  477. int copyfile(char *str, char *PC, char *Option)
  478. {
  479.    int             flag;
  480.    char            buffer[162],opt;
  481.    struct FileList *ext;
  482.  
  483.    if (PC == NULL || *PC == '\0')
  484.       PC = "\0     default PC-path";
  485.  
  486.    if (Option == NULL)
  487.       Option = "\0  Option"; /* Hier die gewünschte 'Default' Option eintragen. */
  488.  
  489.    opt = Intro(&PC,Option);
  490.    if (opt == 255 || opt == -1)
  491.       return(FALSE);
  492.    *Option = opt;
  493. /* Per Requester ausgewählte Option speichern. */
  494.    if (str == NULL || *str == '\0')
  495.    {
  496. /* Wenn kein Dateiname per CLI oder WB übergeben wurde diesen per Requester anfordern. */
  497.        filename[0] = 0;
  498.        extras.oktext     = (UBYTE *) "Copy";
  499.        extras.canceltext = (UBYTE *) "No Way!";
  500.        if (FReq(NULL, (UBYTE *) ATCP,filename,directory,pattern, FR_CANCELTEXT |
  501.                       FR_EXTENDEDSELECT | FR_OKTEXT | FR_AUTOPOSITION | FR_AUTOSIZE |
  502.                       FR_NOINFO | FR_SCREENFONT ,&extras))
  503.        {
  504.            flag = FALSE;
  505.            if (extras.ExtendedList)
  506.            {
  507. /* Wenn Extendet Select, siehe KR_FREQ.DOC, gewählt wurde NUR diese auswerten. */
  508.                ext = extras.ExtendedList;
  509.                for (; ext; ext = ext->next)
  510.                {
  511.                    strcpy(buffer,(char *) directory);
  512.                    strcat(buffer,(char *) ext->FileName);
  513.                    flag = copyfile2(buffer,PC,opt);
  514.                }
  515.                FreeMem(extras.ExtendedList,extras.ExtendedList->private);
  516.                extras.ExtendedList = NULL;
  517.            }
  518.            else
  519.            {
  520. /* Ansonsten den Dateinamen lesen. */
  521.                strcpy(buffer,(char *) directory);
  522.                strcat(buffer,(char *) filename);
  523.                flag = copyfile2(buffer,PC,opt);
  524.            }
  525.        }
  526.        else
  527.        {
  528. /* Keine Auswahl bzw. CAncel gewählt => ENDE! */
  529.            return(FALSE);
  530.        }
  531.    }
  532.    else
  533.    {
  534. /* Dateinamen per CLI oder WB vorgegeben. */
  535.        flag = copyfile2(str,PC,opt);
  536.    }
  537.    return(flag);
  538. }
  539.  
  540. void main(int argc, char *argv[])
  541. {
  542.     register char     **demo;
  543.     register char     *s;
  544.     int               wbmax,i;
  545.     struct DiskObject *Do;
  546.     struct WBStartup  *Wbs;
  547.     struct Process    *proc = (struct Process *)FindTask(NULL);
  548.     struct FileLock   *origlock;
  549.  
  550.     Version();
  551.  
  552.     directory[0] = filename[0] = pattern[0] = 0;
  553.  
  554. /* Lib's öffnen. */
  555.  
  556.     if (!(JanusBase = ArpOpenLibrary("janus.library",0L)))
  557.     {
  558.         DisplayAlert(RECOVERY_ALERT,(char *) &NoLib,NOLIB);
  559.         exit(10);
  560.     }
  561.  
  562.     if (!(KD_FReqBase = ArpOpenLibrary(KLIBNAME,KLIBVERSION)))
  563.     {
  564.         Puts("KD_FREQ.LIBRARY fehlt!\n");
  565.         exit(10);
  566.     }
  567.  
  568.  
  569.     CheckForPC(); /* Ermitteln der Basisadresse. */
  570.  
  571.     WakeUpPC(); /* AT.EXE oder XT.EXE aufrufen. */
  572.  
  573.     Flag = (UBYTE *) FileFlag0;
  574.     Data = (UBYTE *) FileData0;
  575.  
  576.     if (argc > 0)
  577.     {
  578.         demo = (char **) argv[1];
  579.         if (demo != NULL)
  580.         {
  581.             if (*demo != NULL)
  582.             {
  583.                 while(*demo != NULL)
  584.                 {
  585. /* Wenn Jokerzeichen im Argument sind, diese Auswerten mit scdir(). */
  586.  
  587.                     while(s = scdir(*demo))
  588.                     {
  589. /* S ist aufgelöster Name, der zum Joker paßt. */
  590.  
  591.                         copyfile(s,argv[2],argv[3]);
  592.                     }
  593.                     demo++;
  594.                 }
  595.             }
  596.             else
  597.             {
  598.                 do ; while(copyfile(NULL,argv[2],argv[3]));
  599.             }
  600.         }
  601.         else
  602.         {
  603.             do ; while(copyfile(NULL,argv[2],argv[3]));
  604.         }
  605.     }
  606.     else /* WB Aufruf */
  607.     {
  608.         origlock = (struct FileLock *) CurrentDir(DupLock((BPTR) proc->pr_CurrentDir));
  609.         Wbs = (struct WBStartup *) argv;
  610.         if (!(IconBase = ArpOpenLibrary("icon.library",0L)))
  611.         {
  612.             exit(10);
  613.         }
  614.         if (Wbs->sm_ArgList[0].wa_Lock)
  615.         {
  616.             struct FileLock *savelock = (struct FileLock *) CurrentDir(Wbs->sm_ArgList[0].wa_Lock);
  617.             if (Do = (struct DiskObject *) GetDiskObject(Wbs->sm_ArgList[0].wa_Name))
  618.             {
  619.                 FreeDiskObject(Do);
  620.             }
  621.             CurrentDir((BPTR) savelock);
  622.         }
  623.         if ((wbmax = Wbs->sm_NumArgs - 1) == 0)
  624.         {
  625.             do ; while(copyfile(NULL,NULL,NULL)); /* Ganz ohne Parameter zB WorkBench */
  626.         }
  627.         else
  628.         {
  629.             for(i = 0; i < wbmax; i++)
  630.             {
  631.                 UnLock(CurrentDir(DupLock((BPTR) Wbs->sm_ArgList[i+1].wa_Lock)));
  632.                 if (Do = (struct DiskObject *) GetDiskObject(Wbs->sm_ArgList[i+1].wa_Name))
  633.                 {
  634.                     FreeDiskObject(Do);
  635.                 }
  636.                 copyfile(Wbs->sm_ArgList[i+1].wa_Name,NULL,NULL);
  637.             }
  638.         }
  639.         origlock = (struct FileLock *) CurrentDir((BPTR) origlock);
  640.     }
  641.     timeout();
  642.     *Flag = EMERGENCY;
  643.     timeout(); /* Warten bis XT/AT fertig ist. Dann Speicher freigeben! */
  644.  
  645. #ifdef TEST
  646.     Printf("\nInsgesamt %ld µsec gewarted.\n",cumsec*1000000+cummic);
  647. #endif
  648.  
  649.     FreeTrackedItem(GetTracker(TRAK_FREQ));
  650.     FreeJanusMem(BASIS,DATA_LEN * NUMBUF);
  651.  
  652. }
  653. /* Das war's. */
  654.