home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 421.lha / EasyBackup / support.c < prev    next >
C/C++ Source or Header  |  1990-09-29  |  12KB  |  502 lines

  1. /*************************************************/
  2. /* EasyBackup, Support.c (c)1989 Oliver Enseling */
  3. /*************************************************/
  4.  
  5. #include <exec/types.h>
  6. #include <exec/io.h>
  7. #include <exec/devices.h>
  8. #include <exec/types.h>
  9. #include <exec/memory.h>
  10. #include <libraries/dos.h>
  11. #include <libraries/dosextens.h>
  12. #include <stdio.h>
  13. #include <fcntl.h>
  14. #include <string.h>
  15. #include <devices/trackdisk.h>
  16. #include <intuition/intuition.h>
  17. #include <dos.h>
  18. #include <proto/all.h>
  19. #include <devices/audio.h>
  20. #include <intuition/intuition.h>
  21. #include <stdlib.h>
  22. #include <ctype.h>
  23.  
  24. #define TRACK_SIZE (11 * TD_SECTOR)
  25. #define LABEL_SIZE (11 * 16)
  26. #define MAX_TRACKS 160
  27.  
  28. #define MAX_SECTORS (11 * MAX_TRACKS)
  29. #define CONFIG_NAME "S:EasyBackup.config"
  30. #define BUFFER_SIZE (1024)             /* 1K File Buffer */
  31.  
  32. #define DATEIENDEMARKE '£'             /* empirisch sehr wenig
  33.                                         * vorkommendes Zeichen */
  34.  
  35. #define ID_FILE 0
  36. #define ID_DIR  1
  37. #define ID_ENDDIR 2
  38.  
  39. struct NewWindow TrackNW =
  40. {20, 20, 200, 50, 0, 1, NULL, SMART_REFRESH, NULL, NULL,
  41.  (UBYTE *) "EasyBackup Disk-Status",
  42.  NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN};
  43. struct Window  *TrackWin = NULL;
  44.  
  45. struct IntuitionBase *IntuitionBase;
  46.  
  47. extern int      _OSERR;
  48.  
  49. BYTE           *TrackBuffer, *LabelBuffer, *FileBuffer;
  50. struct IOExtTD *TrackDiskBlock;
  51.  
  52. /* MakeDB: Device-Block anlegen und initialisieren */
  53.  
  54. void           *
  55. MakeDB(len)
  56.     LONG            len;
  57. {
  58.   struct MsgPort *p;
  59.   APTR            req;
  60.  
  61.   if (!(p = (struct MsgPort *) CreatePort(0L, 0L)))
  62.     return (NULL);
  63.   if (!(req = (APTR) CreateExtIO(p, len))) {
  64.     DeletePort(p);
  65.     return (NULL);
  66.   }
  67.   return (req);
  68. }
  69.  
  70. /* FreeDB: Device-Block freigeben */
  71.  
  72. void
  73. FreeDB(req)
  74.     struct IORequest *req;
  75. {
  76.   if (req != 0L) {
  77.     if (req->io_Message.mn_ReplyPort != 0L)
  78.       DeletePort(req->io_Message.mn_ReplyPort);
  79.     DeleteExtIO(req);
  80.   }
  81. }
  82.  
  83. /* InitDevice: Device öffnen und initialisieren */
  84.  
  85. BOOL
  86. InitDevice(name, unit, req, fl, len)
  87.     char           *name;
  88.     LONG            unit;
  89.     struct IORequest **req;
  90.     ULONG           fl, len;
  91. {
  92.   if (len != 0L)
  93.     if (!(*req = MakeDB(len)))
  94.       return (FALSE);
  95.   if (OpenDevice(name, unit, *req, fl))
  96.     return (FALSE);
  97.   else
  98.     return (TRUE);
  99. }
  100.  
  101. /* ExitDevice: Device schließen und Device-Block freigeben */
  102.  
  103. void
  104. ExitDevice(req)
  105.     struct IORequest *req;
  106. {
  107.   if (req != 0L) {
  108.     if (req->io_Message.mn_ReplyPort != 0L)
  109.       DeletePort(req->io_Message.mn_ReplyPort);
  110.     if (req->io_Device != 0L)
  111.       CloseDevice(req);
  112.     DeleteExtIO(req);
  113.   }
  114. }
  115.  
  116. /* DeviceCommmand: Device-Kommando ausführen */
  117.  
  118. void
  119. DeviceCommand(db, com)
  120.     struct IORequest *db;
  121.     UWORD           com;
  122. {
  123.   db->io_Command = com;
  124.   DoIO(db);
  125. }
  126.  
  127. /* Fehlermeldungen des Trackdisk.device */
  128.  
  129. #ifdef DEUTSCH
  130. char           *Errors[] =
  131. {
  132.   "Nicht bestimmt.",
  133.   "Kein Sektorkopf.",
  134.   "Fehlerhafte Sektorpräambel.",
  135.   "Fehlerhafte Sektoridentifikation.",
  136.   "Fehlerhafte Sektorkopfsumme.",
  137.   "Fehlerhafte Sektorsumme.",
  138.   "Nicht genügend Sektoren.",
  139.   "Fehlerhafter Sektorkopf.",
  140.   "Diskette schreibgeschützt.",
  141.   "Diskette gewechselt.",
  142.   "Fehler beim Suchen.",
  143.   "Nicht genügend Speicher.",
  144.   "Falsche Laufwerksnummer.",
  145.   "Falscher Laufwerkstyp.",
  146.   "Laufwerk ist schon Betrieb.",
  147.   "Zugriff nach System-Reset."};
  148. #else
  149. char           *Errors[] =
  150. {
  151.   "Not defined",
  152.   "No sector header",
  153.   "Wrong sector preambule",
  154.   "Wrong sector id",
  155.   "Wrong sector head checksum",
  156.   "Wrong sector checksum",
  157.   "Not enough sectors",
  158.   "Wrong sector header",
  159.   "Disk write-protected",
  160.   "Diskette gewechselt.",
  161.   "Search error",
  162.   "Not enough memory",
  163.   "Wrong drive number",
  164.   "Wrong drive type",
  165.   "Drive already in use",
  166.   "Access past system reset"};
  167. #endif
  168.  
  169. char           *
  170. TrackDiskError(fn)
  171.     LONG            fn;
  172. {
  173.   if ((fn >= 20) && (fn <= 35))
  174.     return (Errors[fn - 20]);
  175. #ifdef DEUTSCH
  176.   else
  177.     return ("Fehlerdiagnose nicht möglich.");
  178. #else
  179.   else
  180.     return ("Unknown error");
  181. #endif
  182. }
  183.  
  184. /* WaitDisk: auf eine neue Diskette warten */
  185.  
  186. void
  187. WaitDisk(db)
  188.     struct IOExtTD *db;
  189. {
  190.   do {
  191.     DeviceCommand(db, (UWORD) TD_CHANGESTATE);
  192.   }
  193.   while (db->iotd_Req.io_Actual == 0);
  194.   do {
  195.     DeviceCommand(db, (UWORD) TD_CHANGESTATE);
  196.   }
  197.   while (db->iotd_Req.io_Actual != 0);
  198. }
  199.  
  200. /* ReadTrack: einen Track lesen */
  201.  
  202. void
  203. ReadTrack(db, tbuf, lbuf, nr)
  204.     struct IOExtTD *db;
  205.     BYTE           *tbuf;
  206.     BYTE           *lbuf;
  207.     LONG            nr;
  208. {
  209.   FOREVER
  210.   {
  211.     DeviceCommand(db, (UWORD) TD_CHANGENUM);
  212.     db->iotd_Count = db->iotd_Req.io_Actual;
  213.     db->iotd_Req.io_Data = (APTR) tbuf;
  214.     db->iotd_SecLabel = (ULONG) lbuf;
  215.     db->iotd_Req.io_Length = TRACK_SIZE;
  216.     db->iotd_Req.io_Offset = nr * TRACK_SIZE;
  217.     DeviceCommand(db, (UWORD) ETD_READ);
  218.     if (db->iotd_Req.io_Error) {
  219. #ifdef DEUTSCH
  220.       printf("Fehler beim Lesen von Spur #%d\n%s\n",
  221.              nr, TrackDiskError((LONG) db->iotd_Req.io_Error));
  222. #else
  223.       printf("Error reading track Track #%d\n%s\n",
  224.              nr, TrackDiskError((LONG) db->iotd_Req.io_Error));
  225. #endif
  226.       UserRequest();
  227.     } else
  228.       break;
  229.   }
  230. }
  231.  
  232. /* Alles geöffnete schließen und Programm beenden */
  233.  
  234. void
  235. CloseAll(err)
  236.     int             err;
  237. {
  238.   if (TrackWin) {
  239.     CloseWindow(TrackWin);
  240.     TrackWin = NULL;
  241.   }
  242.   if (IntuitionBase)
  243.     CloseLibrary(IntuitionBase);
  244.   if ((LONG) TrackDiskBlock->iotd_Req.io_Device != -1) {
  245.     if (!TrackDiskBlock->iotd_Req.io_Error)
  246.       EndBackup();
  247.     ExitDevice(TrackDiskBlock);
  248.   } else
  249.     FreeDB(TrackDiskBlock);
  250.   if (TrackBuffer)
  251.     FreeMem(TrackBuffer, TRACK_SIZE + LABEL_SIZE);
  252.   if (FileBuffer)
  253.     FreeMem(FileBuffer, BUFFER_SIZE);
  254.   exit (err);
  255. }
  256.  
  257. /* UserRequest: Ja-Nein-Abfrage */
  258.  
  259. void
  260. UserRequest()
  261. {
  262.   char            c;
  263.  
  264. #ifdef DEUTSCH
  265.   printf("Abbrechen ? \033[32m(J/N)\033[31m");
  266. #else
  267.   printf("Abort ? \033[32m(Y/N)\033[31m");
  268. #endif
  269.   FOREVER
  270.   {
  271.     c = getchar();
  272. #ifdef DEUTSCH
  273.     if (toupper(c) == 'J') {
  274.       printf("Abbruch !!!\n");
  275.       CloseAll(1);
  276.     }
  277. #else
  278.     if (toupper(c) == 'Y') {
  279.       printf("Aborted\n");
  280.       CloseAll(1);
  281.     }
  282. #endif
  283.     if (toupper(c) == 'N')
  284.       return;
  285.   }
  286. }
  287.  
  288.  
  289. int
  290. DoNothing()
  291. {
  292.   return (0);
  293. }
  294.  
  295. /* Alles benötigte Öffnen */
  296.  
  297. void
  298. OpenAll(devunit)
  299.     int             devunit;
  300. {
  301.   if (onbreak(DoNothing))
  302. #ifdef DEUTSCH
  303.     printf("Fehler beim Installieren der Unterbrechungsabfangroutine !!!\n"
  304.            "Bei Unterbrechen des Programmes mit Ctrl-C oder Ctrl-D\n"
  305.            "kann Datenverlust entstehen !\n");
  306. #else
  307.     printf("Error installing routine to catch user breaks\n"
  308.     "User breaks by Ctrl-C or Ctrl-D may lead into loss of data\n");
  309. #endif
  310.   if (!InitDevice("trackdisk.device", devunit, &TrackDiskBlock, 0,
  311.                   sizeof(*TrackDiskBlock))) {
  312. #ifdef DEUTSCH
  313.     printf("Trackdisk.device kann nicht geöffnet werden !!!\n"
  314.            "Prüfen sie, ob das Laufwerk vorhanden ist.\n");
  315. #else
  316.     printf("Unable to open trackdisk.device\n"
  317.            "Check disk drive\n");
  318. #endif
  319.     exit(10);
  320.   }
  321.   if (!(TrackBuffer = AllocMem(TRACK_SIZE * 2 + LABEL_SIZE, MEMF_CHIP))) {
  322. #ifdef DEUTSCH
  323.     printf("Nicht genügend CHIP-Speicher !!!\n");
  324. #else
  325.     printf("Not enough CHIP-memory\n");
  326. #endif
  327.     CloseAll(20);
  328.   }
  329.   LabelBuffer = TrackBuffer + 2 * TRACK_SIZE;
  330.   if (!(FileBuffer = AllocMem(BUFFER_SIZE, MEMF_PUBLIC))) {
  331. #ifdef DEUTSCH
  332.     printf("Nicht genügend Speicher für Datenpuffer (1K) !!!\n");
  333. #else
  334.     printf("Not enough memory for data buffer (1K)\n");
  335. #endif
  336.     CloseAll(20);
  337.   }
  338.   if (IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0))
  339.     TrackWin = OpenWindow(&TrackNW);
  340. }
  341.  
  342. /*
  343.  * ConcatPath: einen Dateinamen zusammensetzen p1: Directory oder
  344.  * Device p2: Directory oder Filename
  345.  */
  346.  
  347. void
  348. ConcatPath(buffer, p1, p2)
  349.     char           *buffer, *p1, *p2;
  350. {
  351.   strcpy(buffer, p1);
  352.   if (strlen(p1) > 0 && strlen(p2) > 0)
  353.     if (buffer[strlen(buffer) - 1] != ':')
  354.       strcat(buffer, "/");
  355.   strcat(buffer, p2);
  356. }
  357.  
  358. /* FileAbfrage: Abfrage für interaktiven Modus */
  359.  
  360. BOOL
  361. FileAbfrage()
  362. {
  363.   char            antwort[2];
  364.  
  365.   do {
  366. #ifdef DEUTSCH
  367.     printf("\033[33mJ\033[0ma/\033[33mN\033[0mein ");
  368. #else
  369.     printf("\033[33mY\033[0mes/\033[33mN\033[0mo ");
  370. #endif
  371.     scanf("%1s", antwort);
  372.   }
  373. #ifdef DEUTSCH
  374.   while (tolower(antwort[0]) != 'j' && tolower(antwort[0]) != 'n');
  375.   return ((BOOL) (tolower(antwort[0]) == 'j'));
  376. #else
  377.   while (tolower(antwort[0]) != 'y' && tolower(antwort[0]) != 'n');
  378.   return ((BOOL) (tolower(antwort[0]) == 'y'));
  379. #endif
  380. }
  381.  
  382. /*
  383.  * Beep: einen Ton variabler Höhe und Länge ausgeben freq: Frequenz
  384.  * cycles: Anzahl der Delay-Zyklen (1/50-Sekunde)
  385.  */
  386.  
  387. UBYTE           Channel_Map[] =
  388. {1, 8, 2, 4};
  389. BYTE            WaveForm[] =
  390. {0, 39, 74, 102, 120, 127, 120, 102, 74, 39,
  391.  0, -40, -75, -103, -121, -127, -121, -103, -75, -40};
  392.  
  393. struct IOAudio *
  394. MakeIOA(rate, vol, repeat, buf, len)
  395.     LONG            rate, vol, repeat;
  396.     UBYTE          *buf;
  397.     LONG            len;
  398. {
  399.   struct IOAudio *ioa;
  400.   struct MsgPort *port;
  401.   char           *PortName;
  402.  
  403.   PortName = "Beep-Port";
  404.  
  405.   /* IO-Request holen */
  406.   if (ioa = (struct IOAudio *) AllocMem((LONG) sizeof(struct IOAudio),
  407.                                         MEMF_PUBLIC | MEMF_CLEAR)) {
  408.     ioa->ioa_Request.io_Message.mn_Node.ln_Pri = 10;
  409.     if (!(port = CreatePort(PortName, 0L))) {
  410.       FreeMem(ioa, (LONG) sizeof(struct IOAudio));
  411.       /* War nix */
  412.     } else {
  413.       /* Audio-Kanal holen */
  414.       ioa->ioa_Request.io_Message.mn_ReplyPort = port;
  415.       ioa->ioa_Data = Channel_Map;
  416.       ioa->ioa_Length = (LONG) sizeof(Channel_Map);
  417.       /* Audio Device oeffnen */
  418.       if (OpenDevice(AUDIONAME, 0L, (struct IORequest *) ioa,
  419.                      0L)) {
  420.         /* war nix */
  421.         DeletePort(port);
  422.         FreeMem(ioa, (LONG) sizeof(struct IOAudio));
  423.       } else {
  424.         /* Request initialisieren */
  425.         ioa->ioa_Request.io_Flags = ADIOF_PERVOL;
  426.         ioa->ioa_Request.io_Command = CMD_WRITE;
  427.         ioa->ioa_Period = (SHORT) (3579545L / rate);
  428.         ioa->ioa_Volume = (SHORT) vol;
  429.         ioa->ioa_Length = len;
  430.         ioa->ioa_Data = buf;
  431.  
  432.         ioa->ioa_Cycles = (SHORT) repeat;
  433.       }
  434.     }
  435.   }
  436.   return (ioa);
  437. }
  438.  
  439. void
  440. Beep(freq, dauer, vol)
  441.     LONG            freq, dauer, vol;
  442. {
  443.   BYTE           *DataPtr;
  444.   LONG            PlayLen = sizeof(WaveForm);
  445.   LONG            rate;
  446.   struct IOAudio *ioa;
  447.  
  448.   rate = freq * sizeof(WaveForm);
  449.   if (DataPtr = (BYTE *) AllocMem(sizeof(WaveForm), MEMF_CHIP)) {
  450.     memcpy(DataPtr, WaveForm, sizeof(WaveForm));
  451.  
  452.     /* IO-Request initialisieren */
  453.     if (ioa = MakeIOA(rate, vol, 0, DataPtr, PlayLen)) {
  454.       /* Starten */
  455.       BeginIO((struct IORequest *) ioa);
  456.       Delay(dauer);
  457.       AbortIO((struct IORequest *) ioa);        /* Halt!!! */
  458.       if (ioa->ioa_Request.io_Device) {
  459.         CloseDevice((struct IORequest *) ioa);
  460.       }
  461.       if (ioa->ioa_Request.io_Message.mn_ReplyPort) {
  462.         DeletePort(ioa->ioa_Request.io_Message.mn_ReplyPort);
  463.       }
  464.       if (ioa) {
  465.         FreeMem(ioa, (LONG) sizeof(struct IOAudio));
  466.       }
  467.     }
  468.     FreeMem(DataPtr, sizeof(WaveForm));
  469.   }
  470. }
  471.  
  472. /* Ausgabe für die Trackanzeige */
  473.  
  474. struct IntuiText TrackText =
  475. {2, 0, JAM2, 0, 0, NULL, (UBYTE *) "                     "};
  476.  
  477. void
  478. PrintTrack(nr)
  479. {
  480.   if (TrackWin) {
  481. #ifdef DEUTSCH
  482.     sprintf(TrackText.IText, "Spur:%3d, Kopf:%2d", nr / 2, nr % 2);
  483. #else
  484.     sprintf(TrackText.IText,"Track:%3d, Head:%2d",nr / 2,nr % 2);
  485. #endif
  486.             PrintIText(TrackWin->RPort, &TrackText, 20, 34);
  487.   }
  488. }
  489.  
  490. void
  491. PrintDisk(nr)
  492. {
  493.   if (TrackWin) {
  494. #ifdef DEUTSCH
  495.     sprintf(TrackText.IText, "Diskette:%4d", nr);
  496. #else
  497.     sprintf(TrackText.IText, "Disk:%4d", nr);
  498. #endif
  499.     PrintIText(TrackWin->RPort, &TrackText, 20, 18);
  500.   }
  501. }
  502.