home *** CD-ROM | disk | FTP | other *** search
- /* devsupp.c:
- *
- * Support routines for the device handler.
- * - debugging
- * - Mountlist "Startup" field parsing
- *
- * ----------------------------------------------------------------------
- * This code is (C) Copyright 1993,1994 by Frank Munkert.
- * All rights reserved.
- * This software may be freely distributed and redistributed for
- * non-commercial purposes, provided this notice is included.
- * ----------------------------------------------------------------------
- * History:
- *
- * 17-May-94 fmu New option MAYBELOWERCASE (=ML).
- * 09-Apr-94 fmu Larger buffer for startup strings.
- * 02-Jan-94 fmu New options XPOS and YPOS.
- * 11-Dec-93 fmu Memory type can now be chosen by the user:
- * new options CHIP, DMA and ANY.
- * 11-Dec-93 fmu The assembly code stubs for the debugging process
- * are no longer necessary; the debugger code is now
- * called with CreateNewProcTags().
- * 21-Nov-93 fmu New option SCANINTERVAL.
- * 14-Nov-93 fmu Added Handle_Control_Packet for 'cdcontrol' program.
- * 10-Nov-93 fmu New options SHOWVERSION and HFSFIRST.
- * 23-Oct-93 fmu MacHFS options added.
- * 15-Oct-93 fmu Adapted to new VOLUME structure.
- */
-
- /*
- * Extract information from Mountlist "Startup" field.
- */
-
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <stdio.h>
-
- #ifdef _DCC
- #define abs
- #endif
-
- #include <exec/types.h>
- #include <dos/dostags.h>
- #include <clib/dos_protos.h>
- #include "device.h"
- #include "devsupp.h"
- #include "intui.h"
- #include "params.h"
- #include "cdcontrol.h"
-
- static char *TheVersion = "$VER: " VERSION;
-
- unsigned long g_memory_type;
-
- int
- Get_Startup (LONG p_startup)
- {
- enum {
- ARG_DEVICE,
- ARG_UNIT,
- ARG_CHIP,
- ARG_FAST,
- ARG_DMA,
- ARG_ANY,
- ARG_LOWERCASE,
- ARG_MAYBELOWERCASE,
- ARG_ROCKRIDGE,
- ARG_TRACKDISK,
- ARG_MACTOISO,
- ARG_CONVERTSPACES,
- ARG_SHOWVERSION,
- ARG_HFSFIRST,
- ARG_STDBUFFERS,
- ARG_FILEBUFFERS,
- ARG_DATAEXT,
- ARG_RESOURCEEXT,
- ARG_SCANINTERVAL,
- ARG_PLAYCDDA,
- ARG_XPOS,
- ARG_YPOS,
- ARGCOUNT
- };
-
- STRPTR Args[ARGCOUNT],Index;
- UBYTE LocalBuffer[250];
- struct RDArgs *ArgsPtr;
- int result = FALSE,len,i;
- int cnt;
-
- /* Clear the argument vector. */
- memset (Args, 0, sizeof(Args));
-
- /* valid startup entry? */
- if (!p_startup) {
- Display_Error ("Filesystem startup entry invalid");
- return FALSE;
- }
-
- /* Get the contents of the startup field. */
- len = ((STRPTR)(BADDR(p_startup)))[0];
- if (len > sizeof (LocalBuffer) - 1)
- len = sizeof (LocalBuffer) - 1;
- memcpy (LocalBuffer, ((STRPTR)(BADDR(p_startup))) + 1, len);
-
- /* Provide null-termination. */
- LocalBuffer[len] = 0;
-
- /* Remove leading quotes. */
- for (i = 0 ; i < len ; i++) {
- if (LocalBuffer[i] != ' ') {
- if (LocalBuffer[i] == '\"')
- LocalBuffer[i] = ' ';
- break;
- }
- }
-
- /* Remove trailing quotes. */
- for (i = len - 1 ; i >= 0 ; i--) {
- if (LocalBuffer[i] != ' '){
- if (LocalBuffer[i] == '\"')
- LocalBuffer[i] = ' ';
- break;
- }
- }
-
- /* Replace "-" by spaces, except "--" which is replaced by "-". */
- Index = LocalBuffer;
- for (i = 0 ; i < len ; i++) {
- if (LocalBuffer[i] == '-') {
- if (i+1 < len && LocalBuffer[i+1] == '-') {
- *Index++ = '-';
- i++;
- } else
- *Index++ = ' ';
- } else
- *Index++ = LocalBuffer[i];
- }
-
- /* Provide null-termination. */
- *Index = 0;
-
- /* Don't forget the newline, or ReadArgs won't work. */
- strcat ((char *) LocalBuffer, "\n");
-
- if (ArgsPtr = (struct RDArgs *) AllocDosObjectTags (DOS_RDARGS,TAG_DONE)) {
-
- /* Don't prompt for input! */
- ArgsPtr -> RDA_Flags |= RDAF_NOPROMPT;
-
- /* Set up for local parsing. */
- ArgsPtr->RDA_Source.CS_Buffer = LocalBuffer;
- ArgsPtr->RDA_Source.CS_Length = strlen ((char *) LocalBuffer);
- ArgsPtr->RDA_Source.CS_CurChr = 0;
-
- /* Read the arguments. */
- if (ReadArgs ((UBYTE *)
- "D=DEVICE,U=UNIT/N,C=CHIP/S,F=FAST/S,DMA/S,ANY/S,"
- "L=LOWERCASE/S,ML=MAYBELOWERCASE/S,"
- "R=ROCKRIDGE/S,T=TRACKDISK/S,"
- "MI=MACTOISO/S,CS=CONVERTSPACES/S,"
- "SV=SHOWVERSION/S,HF=HFSFIRST/S,"
- "SB=STDBUFFERS/K/N,FB=FILEBUFFERS/K/N,"
- "DE=DATAEXT/K,RE=RESOURCEEXT/K,"
- "SI=SCANINTERVAL/K/N,PC=PLAYCDDA/K,"
- "X=XPOS/K/N,Y=YPOS/K/N",
- (LONG *) Args, ArgsPtr)) {
- result = TRUE;
-
- if (Args[ARG_DEVICE]) {
- len = strlen((char *) (Args[ARG_DEVICE]));
-
- if (len >= sizeof (g_device)) {
- Display_Error ("Device name entry too long");
- result = FALSE;
- } else
- strcpy (g_device, (char *) (Args[ARG_DEVICE]));
- } else
- Display_Error("Device name entry missing");
-
- g_unit = *(long *) (Args[ARG_UNIT]);
-
- g_memory_type = MEMF_CHIP;
- cnt = 0;
- if (Args[ARG_FAST] != NULL) {
- g_memory_type = MEMF_FAST;
- cnt++;
- }
- if (Args[ARG_CHIP] != NULL) {
- g_memory_type = MEMF_CHIP;
- cnt++;
- }
- if (Args[ARG_DMA] != NULL) {
- g_memory_type = MEMF_24BITDMA;
- cnt++;
- }
- if (Args[ARG_ANY] != NULL) {
- g_memory_type = MEMF_ANY;
- cnt++;
- }
- if (cnt > 1) {
- Display_Error ("Only ONE memory option may be used!");
- result = FALSE;
- }
-
- g_map_to_lowercase = (Args[ARG_LOWERCASE] != NULL);
- g_maybe_map_to_lowercase = (Args[ARG_MAYBELOWERCASE] != NULL);
-
- if (g_map_to_lowercase && g_maybe_map_to_lowercase) {
- Display_Error ("Options L and ML are mutually exclusive!");
- result = FALSE;
- }
-
- g_use_rock_ridge = (Args[ARG_ROCKRIDGE] != NULL);
- g_trackdisk = (Args[ARG_TRACKDISK] != NULL);
- g_show_version_numbers = (Args[ARG_SHOWVERSION] != NULL);
- g_hfs_first = (Args[ARG_HFSFIRST] != NULL);
-
- if (Args[ARG_STDBUFFERS]) {
- g_std_buffers = *(long *) (Args[ARG_STDBUFFERS]);
- if (g_std_buffers <= 0) {
- Display_Error ("Illegal number of standard buffers: %ld", g_std_buffers);
- result = FALSE;
- }
- } else
- g_std_buffers = 5;
-
- if (Args[ARG_FILEBUFFERS]) {
- g_file_buffers = *(long *) (Args[ARG_FILEBUFFERS]);
- if (g_file_buffers <= 0) {
- Display_Error ("Illegal number of file buffers: %ld", g_std_buffers);
- result = FALSE;
- }
- } else
- g_file_buffers = 5;
-
- if (Args[ARG_DATAEXT])
- strcpy (g_data_fork_extension, (char *) Args[ARG_DATAEXT]);
-
- if (Args[ARG_RESOURCEEXT])
- strcpy (g_resource_fork_extension, (char *) Args[ARG_RESOURCEEXT]);
-
- g_convert_hfs_filenames = (Args[ARG_MACTOISO] != NULL);
- g_convert_hfs_spaces = (Args[ARG_CONVERTSPACES] != NULL);
-
- if (Args[ARG_SCANINTERVAL]) {
- g_scan_interval = *(long *) (Args[ARG_SCANINTERVAL]);
- if (g_scan_interval < 0)
- g_scan_interval = 0;
- } else
- g_scan_interval = 3;
-
- if (Args[ARG_PLAYCDDA]) {
- len = strlen((char *) (Args[ARG_PLAYCDDA]));
-
- if (len >= sizeof (g_play_cdda_command)) {
- Display_Error ("PLAYCDDA command name too long");
- result = FALSE;
- } else
- strcpy (g_play_cdda_command, (char *) (Args[ARG_PLAYCDDA]));
- } else
- g_play_cdda_command[0] = 0;
-
- if (Args[ARG_XPOS])
- g_xpos = *(long *) (Args[ARG_XPOS]);
- if (Args[ARG_YPOS])
- g_ypos = *(long *) (Args[ARG_YPOS]);
-
- FreeArgs(ArgsPtr);
- } else {
- Fault(IoErr (), (UBYTE *) "", LocalBuffer, sizeof (LocalBuffer));
- Display_Error ("Error while parsing \"Startup\" field in Mountlist:\n%s",
- LocalBuffer + 2);
- }
-
- FreeDosObject (DOS_RDARGS, ArgsPtr);
- } else
- Display_Error ("Out of memory");
-
- if (result) {
- if (!(g_cd = Open_CDROM (g_device, g_unit, g_trackdisk, g_memory_type,
- g_std_buffers, g_file_buffers))) {
- switch (g_cdrom_errno) {
- case CDROMERR_NO_MEMORY:
- Display_Error ("Out of memory: cannot allocate buffers\n"
- "(Try CHIP, FAST, DMA or ANY option.)");
- break;
- case CDROMERR_MSGPORT:
- Display_Error ("Cannot open the message port.");
- break;
- case CDROMERR_IOREQ:
- Display_Error ("Cannot open the I/O request structure.");
- break;
- case CDROMERR_DEVICE:
- Display_Error ("Cannot open \"%s\" unit %ld", g_device, (int) g_unit);
- break;
- case CDROMERR_BLOCKSIZE:
- Display_Error ("Cannot access CDROM drive: illegal blocksize.");
- break;
- default:
- break;
- }
- result = FALSE;
- }
- }
-
- return result;
- }
-
- int Handle_Control_Packet (ULONG p_type, ULONG p_par1, ULONG p_par2)
- {
- switch (p_type) {
- case CDCMD_LOWERCASE:
- g_map_to_lowercase = p_par1;
- break;
- case CDCMD_MACTOISO:
- g_convert_hfs_filenames = p_par1;
- break;
- case CDCMD_CONVERTSPACES:
- g_convert_hfs_spaces = p_par1;
- break;
- case CDCMD_SHOWVERSION:
- g_show_version_numbers = p_par1;
- break;
- case CDCMD_HFSFIRST:
- g_hfs_first = p_par1;
- break;
- case CDCMD_DATAEXT:
- strcpy (g_data_fork_extension, (char *) p_par1);
- break;
- case CDCMD_RESOURCEEXT:
- strcpy (g_resource_fork_extension, (char *) p_par1);
- break;
- default:
- return 999;
- }
- return 0;
- }
-
- #ifdef _DCC
- extern void debugproc (void);
- #if defined(NDEBUG) && !defined(DEBUG_SECTORS)
- void debugmain (void) {;}
- #endif
- #endif
-
- #if !defined(NDEBUG) || defined(DEBUG_SECTORS)
-
- char *typetostr (int ty)
- {
- switch(ty) {
- case ACTION_DIE: return("DIE");
- case ACTION_FINDUPDATE: return("OPEN-RW");
- case ACTION_FINDINPUT: return("OPEN-OLD");
- case ACTION_FINDOUTPUT: return("OPEN-NEW");
- case ACTION_READ: return("READ");
- case ACTION_WRITE: return("WRITE");
- case ACTION_END: return("CLOSE");
- case ACTION_SEEK: return("SEEK");
- case ACTION_EXAMINE_NEXT: return("EXAMINE NEXT");
- case ACTION_EXAMINE_OBJECT: return("EXAMINE OBJ");
- case ACTION_INFO: return("INFO");
- case ACTION_DISK_INFO: return("DISK INFO");
- case ACTION_PARENT: return("PARENTDIR");
- case ACTION_DELETE_OBJECT: return("DELETE");
- case ACTION_CREATE_DIR: return("CREATEDIR");
- case ACTION_LOCATE_OBJECT: return("LOCK");
- case ACTION_COPY_DIR: return("DUPLOCK");
- case ACTION_FREE_LOCK: return("FREELOCK");
- case ACTION_SET_PROTECT: return("SETPROTECT");
- case ACTION_SET_COMMENT: return("SETCOMMENT");
- case ACTION_RENAME_OBJECT: return("RENAME");
- case ACTION_INHIBIT: return("INHIBIT");
- case ACTION_RENAME_DISK: return("RENAME DISK");
- case ACTION_MORE_CACHE: return("MORE CACHE");
- case ACTION_WAIT_CHAR: return("WAIT FOR CHAR");
- case ACTION_FLUSH: return("FLUSH");
- case ACTION_SCREEN_MODE: return("SCREENMODE");
- case ACTION_IS_FILESYSTEM: return("IS_FILESYSTEM");
- case ACTION_SAME_LOCK: return("SAME_LOCK");
- case ACTION_COPY_DIR_FH: return("COPY_DIR_FH");
- case ACTION_PARENT_FH: return("PARENT_FH");
- case ACTION_EXAMINE_FH: return("EXAMINE_FH");
- case ACTION_FH_FROM_LOCK: return("FH_FROM_LOCK");
- case ACTION_CURRENT_VOLUME: return("CURRENT_VOLUME");
- case ACTION_READ_LINK: return("READ LINK");
- case ACTION_USER: return("USER");
- default: return("---------UNKNOWN-------");
- }
- }
-
- /*
- * DEBUGGING CODE. You cannot make DOS library calls that access other
- * devices from within a DOS device driver because they use the same
- * message port as the driver. If you need to make such calls you must
- * create a port and construct the DOS messages yourself. I do not
- * do this. To get debugging info out another PROCESS is created to which
- * debugging messages can be sent.
- *
- * You want the priority of the debug process to be larger than the
- * priority of your DOS handler. This is so if your DOS handler crashes
- * you have a better idea of where it died from the debugging messages
- * (remember that the two processes are asyncronous from each other).
- */
-
- /*
- * BTW, the DOS library used by debugmain() was actually opened by
- * the device driver. Note: DummyMsg cannot be on debugmain()'s stack
- * since debugmain() goes away on the final handshake.
- */
-
- #ifdef LATTICE
- void __saveds debugmain (void)
- #else
- void debugmain (void)
- #endif /* LATTICE */
- {
- MSG *msg;
- short len;
- void *fh;
- #ifdef LOG_MESSAGES
- void *out;
- #endif
-
- #ifdef AZTEC_C
- extern void geta4 (void);
-
- geta4();
- #endif
-
- Dbport = CreateMsgPort ();
- fh = (void *) Open ((UBYTE *) "con:0/0/640/100/debugwindow", 1006);
- PutMsg(Dback, &DummyMsg);
- #ifdef LOG_MESSAGES
- #ifdef LOG_TO_PAR
- out = (void *) Open ((UBYTE *) "PAR:", 1006);
- #else
- out = (void *) Open ((UBYTE *) "ram:cd.log", 1006);
- #endif
- #endif
- for (;;) {
- WaitPort(Dbport);
- msg = GetMsg(Dbport);
- len = msg->mn_Length;
- if (len == 0)
- break;
- --len; /* Fix length up */
- Write((BPTR) fh, msg+1, len);
- #ifdef LOG_MESSAGES
- Write((BPTR) out, msg+1, len);
- #endif
- FreeMem(msg,sizeof(MSG)+len+1);
- }
- Close ((BPTR) fh);
- #ifdef LOG_MESSAGES
- Close ((BPTR) out);
- #endif
- DeleteMsgPort(Dbport);
- PutMsg(Dback,&DummyMsg); /* Kill handshake */
- }
-
- void dbinit (void)
- {
- TASK *task = FindTask(NULL);
-
- Dback = CreateMsgPort();
- if (CreateNewProcTags (
- #ifdef _DCC
- NP_Seglist, (BPTR) (CTOB(debugproc)),
- #else
- NP_Entry, debugmain,
- #endif
- NP_Name, "DEV_DB",
- NP_Priority, task->tc_Node.ln_Pri+1,
- NP_StackSize, 4096,
- TAG_DONE)) {
- WaitPort(Dback); /* handshake startup */
- GetMsg(Dback); /* remove dummy msg */
- dbprintf("Debugger running: %s, %s\n", TheVersion+6, __TIME__);
- };
- }
-
- void dbuninit (void)
- {
- MSG killmsg;
-
- if (Dbport) {
- killmsg.mn_Length = 0; /* 0 means die */
- PutMsg(Dbport,&killmsg);
- WaitPort(Dback); /* He's dead jim! */
- GetMsg(Dback);
- DeleteMsgPort(Dback);
-
- /*
- * Since the debug process is running at a greater priority, I
- * am pretty sure that it is guarenteed to be completely removed
- * before this task gets control again. Still, it doesn't hurt...
- */
-
- Delay(100); /* ensure he's dead */
- }
- }
-
- void dbprintf (char *format, ...)
- {
- va_list arg;
- char buf[256];
- MSG *msg;
-
- va_start (arg, format);
- if (Dbport && !DBDisable) {
- vsprintf (buf, format, arg);
- msg = AllocMem(sizeof(MSG)+strlen(buf)+1, MEMF_PUBLIC|MEMF_CLEAR);
- msg->mn_Length = strlen(buf)+1; /* Length NEVER 0 */
- strcpy((char *) (msg+1), buf);
- PutMsg(Dbport,msg);
- }
- va_end (arg);
- }
-
- #endif /* !NDEBUG || DEBUG_SECTORS */
-