home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- ** File: ID-handler.c
- ** Program: ID-handler - an AmigaDOS handler for generating unique names
- ** Version: 1.0
- ** Author: Ed Puckett qix@mit-oz
- **
- ** Copyright 1987 EpAc Software. All Rights Reserved.
- **
- ** History: 02-Feb-87 Original Version
- */
-
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
- #include <libraries/filehandler.h>
- #include <exec/exec.h>
- #include <ctype.h>
-
-
-
- /*---------------------------------------------------------------------------
- ** References to system
- */
-
- extern struct Library *OpenLibrary ();
- extern void CloseLibrary ();
- extern struct Task *FindTask ();
- extern ULONG Wait ();
- extern struct Message *GetMsg ();
- extern void PutMsg ();
- extern BYTE *AllocMem ();
- extern void FreeMem ();
-
- extern struct Library *AbsExecBase;
-
-
-
- /*---------------------------------------------------------------------------
- ** These are new to the 1.2 release
- */
-
- #ifndef MODE_READWRITE
- # define MODE_READWRITE 1004
- #endif MODE_READWRITE
-
- #ifndef MODE_READONLY
- # define MODE_READONLY MODE_OLDFILE
- #endif MODE_READONLY
-
- #ifndef ACTION_END
- # define ACTION_END 1007 /* not really new, just missing */
- #endif ACTION_END
-
-
-
- /*---------------------------------------------------------------------------
- */
-
- #define ALLOCMEM_FLAGS MEMF_PUBLIC
-
-
- #define ID_DIGITS 16
-
- typedef struct opendata
- { char id[ID_DIGITS];
- UBYTE pos;
- }
- OPENDATA;
-
-
- struct Library *SysBase = NULL;
- struct Library *DOSBase = NULL;
-
- static char ID[ID_DIGITS];
-
-
-
- /*---------------------------------------------------------------------------
- */
-
- #define BPTRtoCptr(Bp) ((char *) ((ULONG) (Bp) << 2))
- #define CptrtoBPTR(Cp) ((BPTR) ((ULONG) (Cp) >> 2))
-
- #define ReplyPkt(pkt) PutMsg ((pkt)->dp_Port, (pkt)->dp_Link)
-
-
-
- /*---------------------------------------------------------------------------
- ** handler() performs initialization, replies to startup packet, and
- ** dispatches incoming request packets to the apropriate functions.
- ** Our DeviceNode Task field is patched with our process ID so that this
- ** process is used for subsequent handler requests. The function exits only
- ** if there is some initialization error.
- */
-
- void handler (StartPkt)
-
- struct DosPacket *StartPkt;
-
- { struct Task *Task;
- struct MsgPort *IDPort;
- ULONG WakeupMask, SigMask;
- struct DeviceNode *DevNode;
- struct DosPacket *pkt, *GetPkt();
- unsigned i;
- void OpenID(), CloseID(), ReadID();
-
-
- SysBase= AbsExecBase;
- if ((DOSBase= OpenLibrary (DOSNAME, 0)) == NULL)
- goto QUIT;
-
- Task= FindTask (0);
- IDPort= (struct MsgPort *) ((ULONG) Task + sizeof (struct Task));
- ((struct Process *) Task)->pr_CurrentDir= 0; /* initial file system root */
-
- WakeupMask= (1L << IDPort->mp_SigBit);
-
- DevNode= (struct DeviceNode *) BPTRtoCptr (StartPkt->dp_Arg3);
- DevNode->dn_Task= IDPort;
-
- ReplyPkt (StartPkt);
-
-
- for (i= 0; i < ID_DIGITS; ++i)
- ID[i]= '0';
-
-
- LOOP:
- SigMask= Wait (WakeupMask);
-
- if (SigMask & WakeupMask)
- while ((pkt= GetPkt (IDPort)) != NULL)
- switch (pkt->dp_Type)
- { case MODE_READWRITE:
- OpenID (pkt);
- break;
-
- case MODE_NEWFILE: /* syn: ACTION_FINDOUTPUT */
- pkt->dp_Res1= 0;
- pkt->dp_Res2= ERROR_WRITE_PROTECTED;
- ReplyPkt (pkt);
- break;
-
- case MODE_READONLY: /* syn: MODE_OLDFILE, ACTION_FINDINPUT */
- OpenID (pkt);
- break;
-
- case ACTION_END:
- CloseID (pkt);
- break;
-
- case ACTION_READ:
- ReadID (pkt);
- break;
-
- case ACTION_WRITE:
- pkt->dp_Res1= -1;
- pkt->dp_Res2= ERROR_WRITE_PROTECTED;
- ReplyPkt (pkt);
- break;
-
- default:
- pkt->dp_Res1= 0;
- pkt->dp_Res2= ERROR_ACTION_NOT_KNOWN;
- ReplyPkt (pkt);
- }
-
- goto LOOP;
-
-
- QUIT:
- DevNode->dn_Task= NULL; /* bad if someone in process of accessing us . . . */
-
- if (DOSBase != NULL)
- CloseLibrary (DOSBase);
- }
-
-
-
- /*---------------------------------------------------------------------------
- ** GetPkt() returns the DosPacket associated with the next message on
- ** "port", or NULL if the port is empty. The message is removed from the
- ** port. A related macro, ReplyPkt(), is provided above.
- */
-
- static struct DosPacket *GetPkt (port)
-
- register struct MsgPort *port;
-
- { register struct Message *msg;
-
- return ((msg= GetMsg (port)) == NULL)
- ? NULL
- : (struct DosPacket *) msg->mn_Node.ln_Name;
- }
-
-
-
- /*---------------------------------------------------------------------------
- */
-
- static void OpenID (pkt)
-
- struct DosPacket *pkt;
-
- { struct FileHandle *handle;
- OPENDATA *OpenData = NULL;
- unsigned i;
- void NextID();
-
-
- if ((OpenData= (OPENDATA *) AllocMem (sizeof (OPENDATA), ALLOCMEM_FLAGS)) == NULL)
- { pkt->dp_Res1= 0;
- pkt->dp_Res2= ERROR_NO_FREE_STORE;
- ReplyPkt (pkt);
- }
-
- for (i= 0; i < ID_DIGITS; ++i)
- OpenData->id[i]= ID[i];
-
- OpenData->pos= 0;
-
- NextID ();
-
- handle= (struct FileHandle *) BPTRtoCptr (pkt->dp_Arg1);
- handle->fh_Arg1= (LONG) OpenData; /* for identification on Read, Close */
-
- pkt->dp_Res1= 1;
- pkt->dp_Res2= 0; /* for successful open */
- ReplyPkt (pkt);
- }
-
-
-
- /*---------------------------------------------------------------------------
- */
-
- static void CloseID (pkt)
-
- struct DosPacket *pkt;
-
- { OPENDATA *OpenData;
-
-
- OpenData= (OPENDATA *) pkt->dp_Arg1;
-
- FreeMem (OpenData, sizeof (OPENDATA));
-
- pkt->dp_Res1= 1;
- pkt->dp_Res2= 0;
- ReplyPkt (pkt);
- }
-
-
-
- /*---------------------------------------------------------------------------
- */
-
- static void ReadID (pkt)
-
- struct DosPacket *pkt;
-
- { OPENDATA *OpenData;
- unsigned n;
-
-
- OpenData= (OPENDATA *) pkt->dp_Arg1;
-
- pkt->dp_Res1= 0;
-
- if (OpenData->pos < ID_DIGITS)
- { if ((n= pkt->dp_Arg3) > (ID_DIGITS - OpenData->pos))
- n= (ID_DIGITS - OpenData->pos);
-
- for ( ; pkt->dp_Res1 < n; ++(pkt->dp_Res1), ++(OpenData->pos))
- ((char *) pkt->dp_Arg2)[pkt->dp_Res1]= OpenData->id[OpenData->pos];
- }
-
- pkt->dp_Res2= 0;
- ReplyPkt (pkt);
- }
-
-
-
- /*---------------------------------------------------------------------------
- */
-
- static void NextID ()
-
- { int i;
-
- for (i= ID_DIGITS - 1; (i >= 0) && (++(ID[i]) > '9'); --i)
- ID[i]= '0';
- }
-