home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / comm / tcp / amitcp / src / devs / netinfo / netinfo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-19  |  9.7 KB  |  365 lines

  1. RCS_ID_C="$Id: netinfo.c,v 3.3 1994/05/19 04:29:29 ppessi Exp $"; 
  2. /*
  3.  * netinfo.c --- netinfo.device main functions
  4.  *
  5.  * Author: ppessi <Pekka.Pessi@hut.fi>
  6.  *
  7.  * This file is part of the AmiTCP/IP NetInfo device.
  8.  *
  9.  * Copyright © 1993 AmiTCP/IP Group, <AmiTCP-Group@hut.fi>
  10.  *                  Helsinki University of Technology, Finland.
  11.  *
  12.  * Created      : Sun Nov 28 17:45:55 1993 ppessi
  13.  * Last modified: Thu May 19 07:22:06 1994 ppessi
  14.  *
  15.  * $Log: netinfo.c,v $
  16.  * Revision 3.3  1994/05/19  04:29:29  ppessi
  17.  * Added support for DOS notifications
  18.  *
  19.  * Revision 3.2  1994/01/23  02:40:13  ppessi
  20.  * Restructured pointer/unit hierarchy. Added some additional locking.
  21.  *
  22.  * Revision 3.1  1994/01/22  16:39:18  ppessi
  23.  * New command structure
  24.  *
  25.  * Revision 2.6  1994/01/22  12:44:50  ppessi
  26.  * Updated doc
  27.  *
  28.  * Revision 2.5  1994/01/21  12:12:06  ppessi
  29.  * Removed <sys/errno.h> from includes
  30.  *
  31.  * Revision 2.4  1994/01/20  16:17:36  ppessi
  32.  * Fixed bugs with device process creation
  33.  *
  34.  * Revision 2.3  1994/01/19  03:33:11  ppessi
  35.  * The device process startup message was sometimes messed.
  36.  *
  37.  * Revision 2.2  94/01/18  08:51:28  ppessi
  38.  * Removed the library functionality.
  39.  * 
  40.  * Revision 2.1  94/01/17  14:28:01  ppessi
  41.  * Revision 2
  42.  * 
  43.  */
  44.  
  45. /****** netinfo.device/--background-- **************************************
  46.  
  47.     PURPOSE
  48.  
  49.         The netinfo.device is intended to access various information from
  50.     network database.  It provides an uniform and well-defined interface
  51.     to databases, so it is easy to adopt clients to different
  52.     environments.  There is a separate unit for each database.
  53.  
  54.         Currently the netinfo.device supports access to local password and
  55.     group files.  As a new feature since last release it supports file
  56.     notification.
  57.  
  58.     The device file is located to "AmiTCP:devs/netinfo.device".  It is
  59.     recommended that the OpenDevice() call is given the macro NETINFONAME
  60.     as device name.
  61.  
  62.     OVERVIEW
  63.         Short overview of implemented IO commands is as follows:
  64.  
  65.     CMD_RESET - reset sequential access
  66.         This command restarts the sequential database reading.
  67.         Inputs: none
  68.         Results:
  69.           * io_Error contains possaible error code or 0 if command was
  70.             successfull
  71.  
  72.     CMD_READ - read next entry
  73.         Inputs:
  74.           * io_Data contains buffer for database entry. The buffer will
  75.             be filled wtih entry data upon successfull execution.
  76.           * io_Length contains database len
  77.         Results:
  78.           * io_Actual contains length of the database entry
  79.           * io_Error contains possaible error code or 0 if command was
  80.             successfull
  81.  
  82.     CMD_WRITE - alter the database
  83.         This command adds a new database entry or replace an old entry.
  84.         If a matching entry with same name is found, it is replaced with
  85.         the new entry.
  86.  
  87.         Inputs:
  88.           * io_Data contains pointer for database entry structure
  89.         Results:
  90.           * io_Actual contains length of the database entry
  91.           * io_Error contains possible error code or 0 if command was
  92.             successfull
  93.  
  94.     CMD_UPDATE - copy the previous changes to permanent store
  95.  
  96.     This command updates the permanent copies of database.  The
  97.         netinfo.device does not ensure that entries updated with
  98.         CMD_WRITE will be available by CMD_READ or written to permanent
  99.         store before the CMD_UPDATE is executed.
  100.  
  101.     Inputs: none
  102.     Results:
  103.           * io_Error contains possible error code or 0 if command was
  104.             successfull
  105.  
  106.     NI_BYNAME - search by name
  107.         Inputs:
  108.           * io_Data contains buffer for database entry. The buffer will
  109.             be filled wtih entry data upon successfull execution. The name
  110.         member of structure should be pointer to a C string containing 
  111.         the name of desired entry
  112.           * io_Length contains database len
  113.         Results:
  114.           * io_Actual contains length of the database entry
  115.           * io_Error contains possaible error code or 0 if command was
  116.             successfull
  117.  
  118.     NI_BYUID - search by ID
  119.         Inputs:
  120.           * io_Data contains buffer for database entry. The buffer will
  121.             be filled wtih entry data upon successfull execution. The ID
  122.         member of structure should be set to desired value.
  123.           * io_Length contains database len
  124.         Results:
  125.           * io_Actual contains length of the database entry
  126.           * io_Error contains possaible error code or 0 if command was
  127.             successfull
  128.     
  129.     NI_MEMBERS - find out memberships 
  130.         This command is implemented only for group unit.  It collects
  131.         the IDs of groups which have a given user as member.
  132.  
  133.         Inputs:
  134.           * io_Data is address to LONG array which is filled with group
  135.             IDs
  136.           * io_Length is the length of the array in bytes
  137.           * io_Offset is a pointer to C string containing the name of
  138.             user whose memberships are desired
  139.         Results:
  140.           * io_Actual contains length of the group ID array in bytes
  141.           * io_Error contains possaible error code or 0 if command was
  142.             successfull.
  143.  
  144. ****************************************************************************
  145. */
  146.  
  147. #include "base.h"
  148. #include <dos/dostags.h>
  149.  
  150. /*
  151.  * Device initialization routine
  152.  * Do only things that won't Wait()
  153.  */
  154. SAVEDS ASM ULONG _DevInit(BASEREG, REG(a0) APTR seglist)
  155. {
  156.   SysBase = *(APTR *)4;
  157.   DOSBase = NULL;
  158.   
  159.   nid->nid_Task = NULL;
  160.   nid->nid_SegList = seglist;
  161.  
  162.   InitSemaphore(nid->nid_Lock);
  163.  
  164.   return (ULONG)nid;
  165. }
  166.  
  167. SAVEDS ASM LONG _DevOpen(BASEREG,
  168.              REG(a1) struct IORequest *req,
  169.              REG(d0) ULONG unit,
  170.              REG(d1) ULONG flags)
  171. {
  172.   WORD retval = IOERR_OPENFAIL;
  173.  
  174.   /* Enforce single threading so we can Wait() */
  175.   ObtainSemaphore(nid->nid_Lock);
  176.  
  177.   /* Prevent us from expunging ourselves */
  178.   nid->nid_Lib.lib_OpenCnt++;
  179.  
  180.   /* clear delayed expunges (standard procedure) */
  181.   nid->nid_Lib.lib_Flags &= ~LIBF_DELEXP;
  182.  
  183.   if (unit >= NETINFO_UNITS)
  184.     goto zap;
  185.  
  186.   /*
  187.    * Create device task if necessary
  188.    */
  189.   while (nid->nid_Task == NULL) {
  190.     struct MsgPort *mp;
  191.     struct Message *msg;
  192.     struct Process *task;
  193.  
  194.     nid->nid_DOSBase = OpenLibrary("dos.library",37L);
  195.     if (nid->nid_DOSBase == NULL)
  196.       break;
  197.  
  198.     mp = CreateMsgPort();
  199.     if (mp == NULL)
  200.       break;
  201.     msg = CreateIORequest(mp, sizeof(*msg));
  202.     if (msg) {
  203.       /* Create new process, wait for the message */
  204.       msg->mn_Node.ln_Type = NT_MESSAGE;
  205.       msg->mn_Node.ln_Name = (void *)nid;
  206.       task = CreateNewProcTags(NP_Entry, NetInfoStartup,
  207.                    NP_Priority, NID_PRIORITY,
  208.                    NP_Name, _DevName,
  209.                    NP_ExitData, msg,
  210.                    TAG_END);
  211.       do {
  212.     Wait(1L << mp->mp_SigBit);
  213.       } while (GetMsg(mp) != msg);
  214.  
  215.       DeleteIORequest(msg);
  216.     }
  217.     DeleteMsgPort(mp);
  218.     break;
  219.   }
  220.  
  221.   if (nid->nid_Task == NULL)
  222.     goto zap;
  223.  
  224.   
  225.   /* OK, create a new unit structure, fill in a request and return */
  226.   req->io_Device = (struct Device *) nid;
  227.   if (req->io_Unit = CreateNewUnit(nid, unit)) {
  228.     retval = 0;
  229.   }
  230.  zap:
  231.   if (req->io_Error = retval) {
  232.     nid->nid_Lib.lib_OpenCnt--;
  233.     req->io_Unit = (struct Unit *) -1;
  234.     req->io_Device = (struct Device *) -1;
  235.   }
  236.  
  237.   ReleaseSemaphore(nid->nid_Lock);
  238.  
  239.   return retval;
  240. }
  241.  
  242. SAVEDS ASM ULONG _DevClose(BASEREG, REG(a1) struct IORequest *req)
  243. {
  244.   ULONG retval = 0;
  245.   ObtainSemaphore(nid->nid_Lock);
  246.   {
  247.     ExpungeUnit(nid, req->io_Unit);
  248.  
  249.     nid->nid_Lib.lib_OpenCnt--;  
  250.  
  251.     if ((nid->nid_Lib.lib_OpenCnt == 0 ) &&
  252.     ( nid->nid_Lib.lib_Flags & LIBF_DELEXP )) {
  253.       /*
  254.        * no more people have me open,
  255.        * and I have a delayed expunge pending
  256.        */
  257.       retval = _DevExpunge(nid); /* return segment list */
  258.     }
  259.   }
  260.   ReleaseSemaphore(nid->nid_Lock);
  261.  
  262.   return retval;
  263. }
  264.  
  265. /*
  266.  * Device expunge
  267.  */
  268. SAVEDS ASM ULONG _DevExpunge(BASEREG)
  269. {
  270.   /* Device base is protected by opencount */
  271.   if (AttemptSemaphore(nid->nid_Lock)) {
  272.     /* Mark expunge request */
  273.     nid->nid_Lib.lib_Flags |= LIBF_DELEXP;
  274.     if (nid->nid_Task) {
  275.       if (nid->nid_Death && nid->nid_Death->mn_Node.ln_Type == NT_MESSAGE)
  276.     ReplyMsg(nid->nid_Death);
  277.     } else {
  278.       LONG nidsize = nid->nid_Lib.lib_NegSize + nid->nid_Lib.lib_PosSize;
  279.       UBYTE *nidp  = (UBYTE *)nid - nid->nid_Lib.lib_NegSize;
  280.       APTR seglist = nid->nid_SegList;
  281.  
  282.       Remove((struct Node *)nid);
  283.       FreeMem(nidp, nidsize);
  284.       nid = NULL; nidp = NULL;
  285.  
  286.       return (ULONG)seglist;
  287.     }
  288.     ReleaseSemaphore(nid->nid_Lock);
  289.   }
  290.  
  291.   return 0;
  292. }
  293.  
  294. /*
  295.  * Reserved
  296.  */
  297. ASM ULONG _DevRes(void)
  298. {
  299.   return 0;
  300. }
  301.  
  302.  
  303. /*
  304.  * Queue requests
  305.  */
  306. #define IMMEDIATE_CMDS 0L
  307.  
  308. SAVEDS ASM VOID _NetInfoBeginIO(BASEREG, REG(a1) struct NetInfoReq  *req)
  309. {
  310.   req->io_Message.mn_Node.ln_Type = NT_MESSAGE;
  311.  
  312.   if (req->io_Command >= NI_END) {
  313.     req->io_Error = IOERR_NOCMD;
  314.     TermIO(req);
  315. #if IMMEDIATE_CMDS
  316.   } else if ((req->io_Flags & IOF_QUICK) &&
  317.          (1L << req->io_Command) & IMMEDIATE_CMDS) {
  318.     PerformIO(nid, req);
  319. #endif
  320.   } else {
  321.     req->io_Flags &= ~IOF_QUICK;
  322.     PutMsg(nid->nid_Port, (struct Message *)req);
  323.   }
  324. }
  325.  
  326. /*
  327.  * The device AbortIO() entry point.
  328.  *
  329.  * A1 - The IO request to be aborted.
  330.  * A6 - The device base.
  331.  */
  332. SAVEDS ASM ULONG _NetInfoAbortIO(BASEREG, REG(a1) struct NetInfoReq *ni)
  333. {
  334.   ULONG result = 0L;
  335.   struct NetInfoMap *nim;
  336.  
  337.   if (ni->io_Unit == NULL)
  338.     return NIERR_NULL_POINTER;
  339.  
  340.   nim = CheckUnit(nid, ni->io_Unit);
  341.   if (nim == NULL)
  342.     return IOERR_BADADDRESS;
  343.  
  344.   ObtainSemaphore(nim->nim_ReqLock);
  345.  
  346.   if (ni->io_Message.mn_Node.ln_Type != NT_REPLYMSG) {
  347.     switch (ni->io_Command) {
  348.     case CMD_READ:    
  349.       result = AbortReq(nid, nim->nim_Rx, ni);
  350.       break;
  351.     case CMD_WRITE: 
  352.       result = AbortReq(nid, nim->nim_Wx, ni);
  353.       break;
  354.     default:        
  355.       result = IOERR_NOCMD;
  356.       break;
  357.     }
  358.   }
  359.  
  360.   ReleaseSemaphore(nim->nim_ReqLock);
  361.  
  362.   return(result);
  363. }
  364.  
  365.