home *** CD-ROM | disk | FTP | other *** search
- RCS_ID_C="$Id: netinfo.c,v 3.3 1994/05/19 04:29:29 ppessi Exp $";
- /*
- * netinfo.c --- netinfo.device main functions
- *
- * Author: ppessi <Pekka.Pessi@hut.fi>
- *
- * This file is part of the AmiTCP/IP NetInfo device.
- *
- * Copyright © 1993 AmiTCP/IP Group, <AmiTCP-Group@hut.fi>
- * Helsinki University of Technology, Finland.
- *
- * Created : Sun Nov 28 17:45:55 1993 ppessi
- * Last modified: Thu May 19 07:22:06 1994 ppessi
- *
- * $Log: netinfo.c,v $
- * Revision 3.3 1994/05/19 04:29:29 ppessi
- * Added support for DOS notifications
- *
- * Revision 3.2 1994/01/23 02:40:13 ppessi
- * Restructured pointer/unit hierarchy. Added some additional locking.
- *
- * Revision 3.1 1994/01/22 16:39:18 ppessi
- * New command structure
- *
- * Revision 2.6 1994/01/22 12:44:50 ppessi
- * Updated doc
- *
- * Revision 2.5 1994/01/21 12:12:06 ppessi
- * Removed <sys/errno.h> from includes
- *
- * Revision 2.4 1994/01/20 16:17:36 ppessi
- * Fixed bugs with device process creation
- *
- * Revision 2.3 1994/01/19 03:33:11 ppessi
- * The device process startup message was sometimes messed.
- *
- * Revision 2.2 94/01/18 08:51:28 ppessi
- * Removed the library functionality.
- *
- * Revision 2.1 94/01/17 14:28:01 ppessi
- * Revision 2
- *
- */
-
- /****** netinfo.device/--background-- **************************************
-
- PURPOSE
-
- The netinfo.device is intended to access various information from
- network database. It provides an uniform and well-defined interface
- to databases, so it is easy to adopt clients to different
- environments. There is a separate unit for each database.
-
- Currently the netinfo.device supports access to local password and
- group files. As a new feature since last release it supports file
- notification.
-
- The device file is located to "AmiTCP:devs/netinfo.device". It is
- recommended that the OpenDevice() call is given the macro NETINFONAME
- as device name.
-
- OVERVIEW
- Short overview of implemented IO commands is as follows:
-
- CMD_RESET - reset sequential access
- This command restarts the sequential database reading.
- Inputs: none
- Results:
- * io_Error contains possaible error code or 0 if command was
- successfull
-
- CMD_READ - read next entry
- Inputs:
- * io_Data contains buffer for database entry. The buffer will
- be filled wtih entry data upon successfull execution.
- * io_Length contains database len
- Results:
- * io_Actual contains length of the database entry
- * io_Error contains possaible error code or 0 if command was
- successfull
-
- CMD_WRITE - alter the database
- This command adds a new database entry or replace an old entry.
- If a matching entry with same name is found, it is replaced with
- the new entry.
-
- Inputs:
- * io_Data contains pointer for database entry structure
- Results:
- * io_Actual contains length of the database entry
- * io_Error contains possible error code or 0 if command was
- successfull
-
- CMD_UPDATE - copy the previous changes to permanent store
-
- This command updates the permanent copies of database. The
- netinfo.device does not ensure that entries updated with
- CMD_WRITE will be available by CMD_READ or written to permanent
- store before the CMD_UPDATE is executed.
-
- Inputs: none
- Results:
- * io_Error contains possible error code or 0 if command was
- successfull
-
- NI_BYNAME - search by name
- Inputs:
- * io_Data contains buffer for database entry. The buffer will
- be filled wtih entry data upon successfull execution. The name
- member of structure should be pointer to a C string containing
- the name of desired entry
- * io_Length contains database len
- Results:
- * io_Actual contains length of the database entry
- * io_Error contains possaible error code or 0 if command was
- successfull
-
- NI_BYUID - search by ID
- Inputs:
- * io_Data contains buffer for database entry. The buffer will
- be filled wtih entry data upon successfull execution. The ID
- member of structure should be set to desired value.
- * io_Length contains database len
- Results:
- * io_Actual contains length of the database entry
- * io_Error contains possaible error code or 0 if command was
- successfull
-
- NI_MEMBERS - find out memberships
- This command is implemented only for group unit. It collects
- the IDs of groups which have a given user as member.
-
- Inputs:
- * io_Data is address to LONG array which is filled with group
- IDs
- * io_Length is the length of the array in bytes
- * io_Offset is a pointer to C string containing the name of
- user whose memberships are desired
- Results:
- * io_Actual contains length of the group ID array in bytes
- * io_Error contains possaible error code or 0 if command was
- successfull.
-
- ****************************************************************************
- */
-
- #include "base.h"
- #include <dos/dostags.h>
-
- /*
- * Device initialization routine
- * Do only things that won't Wait()
- */
- SAVEDS ASM ULONG _DevInit(BASEREG, REG(a0) APTR seglist)
- {
- SysBase = *(APTR *)4;
- DOSBase = NULL;
-
- nid->nid_Task = NULL;
- nid->nid_SegList = seglist;
-
- InitSemaphore(nid->nid_Lock);
-
- return (ULONG)nid;
- }
-
- SAVEDS ASM LONG _DevOpen(BASEREG,
- REG(a1) struct IORequest *req,
- REG(d0) ULONG unit,
- REG(d1) ULONG flags)
- {
- WORD retval = IOERR_OPENFAIL;
-
- /* Enforce single threading so we can Wait() */
- ObtainSemaphore(nid->nid_Lock);
-
- /* Prevent us from expunging ourselves */
- nid->nid_Lib.lib_OpenCnt++;
-
- /* clear delayed expunges (standard procedure) */
- nid->nid_Lib.lib_Flags &= ~LIBF_DELEXP;
-
- if (unit >= NETINFO_UNITS)
- goto zap;
-
- /*
- * Create device task if necessary
- */
- while (nid->nid_Task == NULL) {
- struct MsgPort *mp;
- struct Message *msg;
- struct Process *task;
-
- nid->nid_DOSBase = OpenLibrary("dos.library",37L);
- if (nid->nid_DOSBase == NULL)
- break;
-
- mp = CreateMsgPort();
- if (mp == NULL)
- break;
- msg = CreateIORequest(mp, sizeof(*msg));
- if (msg) {
- /* Create new process, wait for the message */
- msg->mn_Node.ln_Type = NT_MESSAGE;
- msg->mn_Node.ln_Name = (void *)nid;
- task = CreateNewProcTags(NP_Entry, NetInfoStartup,
- NP_Priority, NID_PRIORITY,
- NP_Name, _DevName,
- NP_ExitData, msg,
- TAG_END);
- do {
- Wait(1L << mp->mp_SigBit);
- } while (GetMsg(mp) != msg);
-
- DeleteIORequest(msg);
- }
- DeleteMsgPort(mp);
- break;
- }
-
- if (nid->nid_Task == NULL)
- goto zap;
-
-
- /* OK, create a new unit structure, fill in a request and return */
- req->io_Device = (struct Device *) nid;
- if (req->io_Unit = CreateNewUnit(nid, unit)) {
- retval = 0;
- }
- zap:
- if (req->io_Error = retval) {
- nid->nid_Lib.lib_OpenCnt--;
- req->io_Unit = (struct Unit *) -1;
- req->io_Device = (struct Device *) -1;
- }
-
- ReleaseSemaphore(nid->nid_Lock);
-
- return retval;
- }
-
- SAVEDS ASM ULONG _DevClose(BASEREG, REG(a1) struct IORequest *req)
- {
- ULONG retval = 0;
- ObtainSemaphore(nid->nid_Lock);
- {
- ExpungeUnit(nid, req->io_Unit);
-
- nid->nid_Lib.lib_OpenCnt--;
-
- if ((nid->nid_Lib.lib_OpenCnt == 0 ) &&
- ( nid->nid_Lib.lib_Flags & LIBF_DELEXP )) {
- /*
- * no more people have me open,
- * and I have a delayed expunge pending
- */
- retval = _DevExpunge(nid); /* return segment list */
- }
- }
- ReleaseSemaphore(nid->nid_Lock);
-
- return retval;
- }
-
- /*
- * Device expunge
- */
- SAVEDS ASM ULONG _DevExpunge(BASEREG)
- {
- /* Device base is protected by opencount */
- if (AttemptSemaphore(nid->nid_Lock)) {
- /* Mark expunge request */
- nid->nid_Lib.lib_Flags |= LIBF_DELEXP;
- if (nid->nid_Task) {
- if (nid->nid_Death && nid->nid_Death->mn_Node.ln_Type == NT_MESSAGE)
- ReplyMsg(nid->nid_Death);
- } else {
- LONG nidsize = nid->nid_Lib.lib_NegSize + nid->nid_Lib.lib_PosSize;
- UBYTE *nidp = (UBYTE *)nid - nid->nid_Lib.lib_NegSize;
- APTR seglist = nid->nid_SegList;
-
- Remove((struct Node *)nid);
- FreeMem(nidp, nidsize);
- nid = NULL; nidp = NULL;
-
- return (ULONG)seglist;
- }
- ReleaseSemaphore(nid->nid_Lock);
- }
-
- return 0;
- }
-
- /*
- * Reserved
- */
- ASM ULONG _DevRes(void)
- {
- return 0;
- }
-
-
- /*
- * Queue requests
- */
- #define IMMEDIATE_CMDS 0L
-
- SAVEDS ASM VOID _NetInfoBeginIO(BASEREG, REG(a1) struct NetInfoReq *req)
- {
- req->io_Message.mn_Node.ln_Type = NT_MESSAGE;
-
- if (req->io_Command >= NI_END) {
- req->io_Error = IOERR_NOCMD;
- TermIO(req);
- #if IMMEDIATE_CMDS
- } else if ((req->io_Flags & IOF_QUICK) &&
- (1L << req->io_Command) & IMMEDIATE_CMDS) {
- PerformIO(nid, req);
- #endif
- } else {
- req->io_Flags &= ~IOF_QUICK;
- PutMsg(nid->nid_Port, (struct Message *)req);
- }
- }
-
- /*
- * The device AbortIO() entry point.
- *
- * A1 - The IO request to be aborted.
- * A6 - The device base.
- */
- SAVEDS ASM ULONG _NetInfoAbortIO(BASEREG, REG(a1) struct NetInfoReq *ni)
- {
- ULONG result = 0L;
- struct NetInfoMap *nim;
-
- if (ni->io_Unit == NULL)
- return NIERR_NULL_POINTER;
-
- nim = CheckUnit(nid, ni->io_Unit);
- if (nim == NULL)
- return IOERR_BADADDRESS;
-
- ObtainSemaphore(nim->nim_ReqLock);
-
- if (ni->io_Message.mn_Node.ln_Type != NT_REPLYMSG) {
- switch (ni->io_Command) {
- case CMD_READ:
- result = AbortReq(nid, nim->nim_Rx, ni);
- break;
- case CMD_WRITE:
- result = AbortReq(nid, nim->nim_Wx, ni);
- break;
- default:
- result = IOERR_NOCMD;
- break;
- }
- }
-
- ReleaseSemaphore(nim->nim_ReqLock);
-
- return(result);
- }
-
-