/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* |_o_o|\\ Copyright (c) 1987, 1988 The Software Distillery. All Rights */ /* |. o.| || Reserved. This program may not be distributed without the */ /* | . | || permission of the authors: BBS: */ /* | o | || John Toebes Doug Walker Dave Baker */ /* | . |// */ /* ====== */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "handler.h" /******************************************************************************/ /******************************************************************************/ /********************* Dispatch table to handle all packets *******************/ /******************************************************************************/ /******************************************************************************/ #define BP1 1 #define BP2 2 #define BP3 4 #define BP4 8 typedef void (*ifuncp)(GLOBAL, struct DosPacket *); struct LookupTable { ifuncp subr; int flags; }; #define LO_FIRST 0 #define LO_LAST 34 struct LookupTable lowork[LO_LAST+1] = { { NULL, 0 | 0 | 0 | 0 }, /* 0 - ACTION_NIL */ { NULL, 0 | 0 | 0 | 0 }, /* 1 - Unknown */ { NULL, BP1| BP2| BP3| 0 }, /* 2 - ACTION_GET_BLOCK */ { NULL, 0 | BP2| BP3| 0 }, /* 3 - Unknown */ { NULL, BP1| BP2| BP3| 0 }, /* 4 - ACTION_SET_MAP */ { ActDie, 0 | 0 | 0 | 0 }, /* 5 - ACTION_DIE */ { NULL, 0 | 0 | 0 | 0 }, /* 6 - ACTION_EVENT */ { ActCurentVol, BP1| 0 | 0 | 0 }, /* 7 - ACTION_CURRENT_VOLUME*/ { ActLock, BP1| BP2| 0 | 0 }, /* 8 - ACTION_LOCATE_OBJECT */ { ActRenameDisk, BP1| BP2| 0 | 0 }, /* 9 - ACTION_RENAME_DISK */ { NULL, 0 | 0 | 0 | 0 }, /* 10 - Unknown */ { NULL, 0 | 0 | 0 | 0 }, /* 11 - Unknown */ { NULL, 0 | 0 | 0 | 0 }, /* 12 - Unknown */ { NULL, 0 | 0 | 0 | 0 }, /* 13 - Unknown */ { NULL, 0 | 0 | 0 | 0 }, /* 14 - Unknown */ { ActUnLock, BP1| 0 | 0 | 0 }, /* 15 - ACTION_FREE_LOCK */ { ActDelete, BP1| BP2| 0 | 0 }, /* 16 - ACTION_DELETE_OBJECT */ { ActRename, BP1| BP2| BP3| BP4 }, /* 17 - ACTION_RENAME_OBJECT */ { NULL, 0 | 0 | 0 | 0 }, /* 18 - ACTION_MORE_CACHE */ { ActDupLock, BP1| 0 | 0 | 0 }, /* 19 - ACTION_COPY_DIR */ { NULL, 0 | 0 | 0 | 0 }, /* 20 - ACTION_WAIT_CHAR */ { ActSetProtection, 0 | BP2| BP3| 0 }, /* 21 - ACTION_SET_PROTECT */ { ActCreateDir, BP1| BP2| 0 | 0 }, /* 22 - ACTION_CREATE_DIR */ { ActExamine, BP1| BP2| 0 | 0 }, /* 23 - ACTION_EXAMINE_OBJECT*/ { ActExNext, BP1| BP2| 0 | 0 }, /* 24 - ACTION_EXAMINE_NEXT */ { ActDiskInfo, BP1| 0 | 0 | 0 }, /* 25 - ACTION_DISK_INFO */ { ActInfo, BP1| BP2| 0 | 0 }, /* 26 - ACTION_INFO */ { ActFlush, 0 | 0 | 0 | 0 }, /* 27 - ACTION_FLUSH */ { ActSetComment, 0 | BP2| BP3| BP4 }, /* 28 - ACTION_SET_COMMENT */ { ActParent, BP1| 0 | 0 | 0 }, /* 29 - ACTION_PARENT */ { NULL, BP1| 0 | 0 | 0 }, /* 30 - ACTION_TIMER */ { ActInhibit, 0 | 0 | 0 | 0 }, /* 31 - ACTION_INHIBIT */ { NULL, BP1| 0 | 0 | 0 }, /* 32 - ACTION_DISK_TYPE */ { NULL, 0 | 0 | 0 | 0 }, /* 33 - ACTION_DISK_CHANGE */ { ActSetFileDate, 0 | 0 | 0 | 0 } /* 34 - ACTION_SET_FILE_DATE */ }; #define HI_FIRST 1004 #define HI_LAST 1008 struct LookupTable hiwork[5] = { { ActFindwrite, BP1| BP2| BP3| 0 }, /* ACTION_FIND_WRITE - 1004 */ { ActFindwrite, BP1| BP2| BP3| 0 }, /* ACTION_FIND_INPUT - 1005 */ { ActFindwrite, BP1| BP2| BP3| 0 }, /* ACTION_FIND_OUTPUT - 1006 */ { ActEnd, 0 | 0 | 0 | 0 }, /* ACTION_END - 1007 */ { ActSeek, 0 | 0 | 0 | 0 } /* ACTION_SEEK - 1008 */ }; #define USER_FIRST 2010 #define USER_LAST 2012 struct LookupTable userwork[3] = { { ActSetDebug, 0 | 0 | 0 | 0 }, /* ACTION_HANDLER_DEBUG 2010 */ { NULL, BP1| 0 | 0 | 0 }, /* ACTION_SET_TRANS_TYPE2011 */ { ActNetHello, BP1| 0 | 0 | 0 }, /* ACTION_NETWORK_HELLO 2012 */ }; struct DosLibrary *DOSBase; void _main(x) char *x; { struct DosPacket *mypkt; /* a pointer to the dos packet sent */ int action; ifuncp subr; int flags; struct global global; DOSBase = (struct DosLibrary *)OpenLibrary(DOSNAME,0); /* Initialize our global data structure */ memset((char *)&global, 0, sizeof(struct global)); global.n.self = (struct Process *) FindTask(0L); /* find myself */ global.n.run = 1; global.n.port = &(global.n.self->pr_MsgPort); /* install our taskid ... */ /* Initialize the intuitext structures for the requesters we might have */ /* to display */ /* Because we have no scruples we can cheat and do this with a couple of */ /* long word assignments. We leave the acual C code commented out here */ /* so that if this structure ever changed we will still be able to work */ #if 0 global.n.line1.FrontPen = global.n.line1.BackPen = -1; global.n.line1.DrawMode = JAM1; global.n.line1.LeftEdge = global.n.line1.TopEdge = 4; global.n.line2 = global.n.line1; global.n.line3 = global.n.line1; global.n.retrytxt = global.n.line1; global.n.canceltxt = global.n.line1; #else *(long *)&global.n.line1.FrontPen = 0x00010000L | (JAM1<<8); *(long *)&global.n.line1.LeftEdge = 0x00040004L; /* 4,4 */ *(long *)&global.n.line2.FrontPen = 0x00010000L | (JAM1<<8); *(long *)&global.n.line2.LeftEdge = 0x0004000EL; /* 4,14 */ *(long *)&global.n.line3.FrontPen = 0x00010000L | (JAM1<<8); *(long *)&global.n.line3.LeftEdge = 0x00040018L; /* 4,24 */ *(long *)&global.n.retrytxt.FrontPen = 0x00010000L | (JAM1<<8); *(long *)&global.n.retrytxt.LeftEdge = 0x00040004L; *(long *)&global.n.canceltxt.FrontPen = 0x00010000L | (JAM1<<8); *(long *)&global.n.canceltxt.LeftEdge = 0x00040004L; #endif global.n.retrytxt.IText = "Retry"; global.n.canceltxt.IText = "Cancel"; /* since we were started as a non-BCPL module we get sent the parameter */ /* packet (ie. parameter packet not in D1) */ mypkt = taskwait(&global); /* wait for parameter packet */ global.n.devname = (((char *)BADDR(mypkt->dp_Arg1))+1); /* BSTR name */ /* get pointer to our device node */ global.node = (struct DeviceNode *) BADDR(mypkt->dp_Arg3); global.node->dn_Task = global.n.port; InitDevice(&global); Mount(&global, NULL); /* OpenTimer(&global); */ mypkt->dp_Res1 = DOS_TRUE; retpkt(&global, mypkt); /* PostTimerReq(&global); */ while(global.n.run) /* start of the real work */ { BUG(("Waiting for packet. . .")); mypkt = taskwait(&global); /* wait for a packet */ action = mypkt->dp_Type; BUG(("action #%ld\n", action)); switch (action) { case ACTION_NETWORK_KLUDGE: subr = ActNetKludge; flags = (BP1 | BP2); break; case ACTION_READ: subr = ActRead; flags = 0; break; case ACTION_WRITE: subr = ActWrite; flags = 0; break; case ACTION_SET_RAW_MODE: subr = NULL; flags = 0; break; case ACTION_FIND_WRITE: /* 1004 */ case ACTION_FIND_INPUT: /* 1005 */ case ACTION_FIND_OUTPUT: /* 1006 */ case ACTION_END: /* 1007 */ case ACTION_SEEK: /* 1008 */ subr = hiwork[action-HI_FIRST].subr; flags = hiwork[action-HI_FIRST].flags; break; case ACTION_HANDLER_DEBUG: /* 2010 */ case ACTION_SET_TRANS_TYPE: /* 2011 */ case ACTION_NETWORK_HELLO: /* 2012 */ subr = userwork[action-USER_FIRST].subr; flags = userwork[action-USER_FIRST].flags; break; default: if ((action >= LO_FIRST) && (action <= LO_LAST)) { subr = lowork[action-LO_FIRST].subr; flags = lowork[action-LO_FIRST].flags; } else subr = NULL; } mypkt->dp_Res1 = DOS_FALSE; mypkt->dp_Res2 = ERROR_ACTION_NOT_KNOWN; if (subr != NULL) { global.n.reply = 1; if (flags & BP1) mypkt->dp_Arg1 <<= 2; if (flags & BP2) mypkt->dp_Arg2 <<= 2; if (flags & BP3) mypkt->dp_Arg3 <<= 2; if (flags & BP4) mypkt->dp_Arg4 <<= 2; (*subr)(&global, mypkt); } #if DEBUG else { BUG(("Unknown packet type %ld\n",mypkt->dp_Type)); } #endif /* Now return the packet to them */ if (global.n.reply) retpkt(&global, mypkt); BUG(("-----\n")); } /* do our final cleanup */ global.node->dn_Task = FALSE; /* zero the taskid field of device node */ global.node->dn_SegList = 0; /* make us be gone */ DisMount(&global); TermDevice(&global); BUGTERM() } void ActSetDebug(global, pkt) /* ACTION_HANDLER_DEBUG */ GLOBAL global; struct DosPacket *pkt; /* DP_Arg1 - LONG type/flags 0=nodebug */ /* DP_Arg2 - BPTR FileHandle to do debugging to or NULL */ /* DP_Res1 - BPTR old filehandle */ { /********************************************************************/ /* */ /* Several possibilities: */ /* 1. Arg1 is 0: */ /* All debugging is turned off. Arg2 is not looked at. */ /* Res1 is DOS_TRUE, Res2 is a BPTR to the old filehandle. */ /* */ /* 2. Arg1 is a special handler-defined code: */ /* If the second bit from the top is ON, the code is a special*/ /* debugging command to the handler. If the handler knows the*/ /* command, it returns DOS_TRUE in Res1. If it doesn't, it */ /* returns DOS_FALSE in Res1 and Res2. */ /* */ /* 3. Neither of the above: */ /* Arg2 contains a BPTR to a FileHandle to send debugging to. */ /* Note that if this is NULL, debugging will be turned off. */ /* Res1 contains DOS_TRUE, Res2 contains a BPTR to the old */ /* debugging FileHandle, which may of course be NULL if no */ /* debugging was on before. */ /* */ /********************************************************************/ #define DEBUG_SPECIAL 0x40000000 /* Mask for handler-defined dbg type*/ #define DEBUG_SERVER 0x20000000 /* Mask indicating server command */ #define DEBUG_WAIT 0x40000001 /* Wait for debugger to catch us */ #define DEBUG_INFO 0x40000002 /* Send transmit info to msgport in */ /* dp_Arg2 */ struct NetNode *netnode; extern BPTR debuglog; pkt->dp_Res1 = DOS_TRUE; if(pkt->dp_Arg1 & DEBUG_SPECIAL) { BUG(("ActSetDebug: Special debug packet %lx\n", pkt->dp_Arg1)) if(pkt->dp_Arg1 == DEBUG_WAIT) { pkt->dp_Res2 = NULL; cprwait(global); } else if(pkt->dp_Arg1 == DEBUG_INFO) { global->n.infoport = (struct MsgPort *)BADDR(pkt->dp_Arg2); global->n.ntirec.m.mn_Node.ln_Type = global->n.ntitrans.m.mn_Node.ln_Type = NT_MESSAGE; if(!global->n.ntirec.m.mn_ReplyPort) global->n.ntirec.m.mn_ReplyPort = global->n.ntitrans.m.mn_ReplyPort = CreatePort(NULL,0); global->n.inf_rec = global->n.inf_trans = 0L; } else if(pkt->dp_Arg1 & DEBUG_SERVER) { global->RP.Type = ACTION_HANDLER_DEBUG; global->RP.Arg1 = pkt->dp_Arg1 & ~(DEBUG_SERVER|DEBUG_SPECIAL); BUG(("Remote debugging code %lx\n", global->RP.Arg1)) for(netnode=global->netchain.next; netnode; netnode=netnode->next) { if(netnode->status == NODE_UP && netnode->RootLock.RDevice) { RemotePacket(global, &netnode->RootLock); } } } else { pkt->dp_Res1 = pkt->dp_Res2 = DOS_FALSE; } } #if DEBUG else if(pkt->dp_Arg1) pkt->dp_Res2 = initdebug((BPTR)pkt->dp_Arg2); else { pkt->dp_Res2 = debuglog; debuglog = NULL; } #endif }