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

  1. /*
  2.  * server.c -- Netinfo Server Process
  3.  *
  4.  * Author: ppessi <Pekka.Pessi@hut.fi>
  5.  *
  6.  * Copyright © 1993 AmiTCP/IP Group, <AmiTCP-group@hut.fi>
  7.  *                  Helsinki University of Technology, Finland.
  8.  *
  9.  * Created      : Fri Jan 14 14:07:09 1994 ppessi
  10.  * Last modified: Thu May 19 04:33:55 1994 ppessi
  11.  */
  12.  
  13. #include "base.h"
  14. #include <assert.h>
  15.  
  16. static void NetInfoPoll(BASE);
  17.  
  18. /*
  19.  * Task Startup routine
  20.  * This is called from DOS, so it has got no devbase
  21.  */
  22. #undef SysBase
  23. #define SysBase (*(APTR *)4)
  24.  
  25. SAVEDS ASM LONG NetInfoStartup(void)
  26. {
  27.   struct NetInfoDevice *dev;
  28.   struct Message *ok_message = (struct Message *)
  29.     ((struct Process*)FindTask(NULL))->pr_ExitData;
  30.  
  31.   if (ok_message) {
  32.     dev = (struct NetInfoDevice *) ok_message->mn_Node.ln_Name;
  33.     if (dev) {
  34.       NetInfoTask(dev, ok_message);
  35.     } else {
  36.       Forbid();
  37.       ReplyMsg(ok_message);
  38.     }
  39.   }
  40.  
  41.   return 0;
  42. }
  43.  
  44. void TermIO(struct NetInfoReq *req)
  45. {
  46.   if ((req->io_Flags & IOF_QUICK) == 0)
  47.     ReplyMsg((struct Message *)req);
  48. }
  49.  
  50. #undef SysBase
  51. #define SysBase (nid->nid_ExecBase)
  52.  
  53. /*
  54.  * Initialize device port
  55.  */
  56. void NetInfoTask(BASE, struct Message *ok_message) 
  57. {
  58.   BYTE ps = AllocSignal(-1);
  59.   struct Message *death;
  60.  
  61.   /* Create main message port */
  62.   if (ps != -1) {
  63.  
  64.     /* Mr. Death */
  65.     if (death = CreateIORequest(nid->nid_Port, sizeof(*death))) {
  66.       struct NetInfoMap *maps[NETINFO_UNITS];
  67.       struct NetInfoMap *mapp;
  68.       short map;
  69.  
  70.       for (map = NETINFO_PASSWD_UNIT; map < NETINFO_UNITS; map++) {
  71.     mapp = maps[map] = InitNetInfoMap(nid, nid->nid_Port, map);
  72.     if (!mapp) 
  73.       break;
  74.       }
  75.  
  76.       /* If everything went well */
  77.       if (map == NETINFO_UNITS) {
  78.     /* Init ports */
  79.     nid->nid_Port->mp_Flags = PA_SIGNAL;
  80.     nid->nid_Port->mp_SigBit = ps;
  81.     nid->nid_Port->mp_SigTask = FindTask(NULL);
  82.     InitList(&nid->nid_Port->mp_MsgList);
  83.  
  84.     nid->nid_NotifyPort->mp_Flags = PA_SIGNAL;
  85.     nid->nid_NotifyPort->mp_SigBit = ps;
  86.     nid->nid_NotifyPort->mp_SigTask = FindTask(NULL);
  87.     InitList(&nid->nid_NotifyPort->mp_MsgList);
  88.  
  89.     death->mn_Node.ln_Type = NT_MESSAGE;
  90.     nid->nid_Death = death;
  91.     for (map = NETINFO_PASSWD_UNIT; map < NETINFO_UNITS; map++)
  92.       nid->nid_Maps[map] = maps[map];
  93.     
  94.     ReplyMsg(ok_message);
  95.  
  96.     NetInfoPoll(nid);
  97.     return;
  98.       } else {
  99.     while (map > 0) {
  100.       DeInitNetInfoMap(nid, maps[map--]);
  101.     }
  102.       }
  103.       DeleteIORequest(death);
  104.     } 
  105.     FreeSignal(ps);
  106.   }
  107.  
  108.   ok_message->mn_Node.ln_Name = NULL;
  109.   ReplyMsg(ok_message);
  110. }
  111.  
  112. static void NetInfoPoll(BASE)
  113. {
  114.   ULONG mask = 1L << nid->nid_Port->mp_SigBit;
  115.  
  116.   while (mask) {
  117.     struct NetInfoReq *req;
  118.     struct NotifyMessage *notify;
  119.  
  120.     Wait(mask);
  121.  
  122.     while (req = (struct NetInfoReq *)GetMsg(nid->nid_Port)) {
  123.       if (nid->nid_Death == &req->io_Message)
  124.     mask = 0;
  125.       else
  126.     PerformIO(nid, req);
  127.     } 
  128.  
  129.     while (notify = (struct NotifyMessage *)GetMsg(nid->nid_NotifyPort)) {
  130.       struct NetInfoMap *nim = (void *)notify->nm_NReq->nr_UserData;
  131.  
  132.       ReplyMsg(notify);
  133.  
  134.       if (nim != NULL) {
  135.     Method(notify, nim)(nid, nim);
  136.       }
  137.     }
  138.   }
  139.  
  140.   {
  141.     /*
  142.      * Free all allocated resources when die
  143.      */
  144.     struct NetInfoMap *mapp;
  145.     short map;
  146.  
  147.     ObtainSemaphore(nid->nid_Lock);
  148.  
  149.     for (map = NETINFO_PASSWD_UNIT; map < NETINFO_UNITS; map++) {
  150.       if (mapp = nid->nid_Maps[map]) 
  151.     DeInitNetInfoMap(nid, mapp);
  152.       nid->nid_Maps[map] = NULL;
  153.     }
  154.  
  155.     if (nid->nid_SigBit != -1)
  156.       FreeSignal(nid->nid_SigBit), nid->nid_SigBit = (UBYTE)-1;
  157.  
  158.     if (nid->nid_Death)
  159.       DeleteIORequest(nid->nid_Death), nid->nid_Death = NULL;
  160.  
  161.     nid->nid_Task = NULL;
  162.  
  163.     ReleaseSemaphore(nid->nid_Lock);
  164.     return;
  165.   }
  166. }
  167.  
  168. /*
  169.  * Create netinfo pointer 
  170.  */
  171. struct Unit *CreateNewUnit(BASE, short unit)
  172. {
  173.   struct NetInfoMap *nim = nid->nid_Maps[unit];
  174.   struct NetInfoPointer *nip = AllocVec(sizeof(*nip), MEMF_CLEAR);
  175.  
  176.   if (nip) {
  177.     nim->nim_OpenCnt++;
  178.     nip->nip_Name = nim->nim_Name;
  179.     nip->nip_UnitNumber = unit;
  180.     nip->nip_Map = nim;
  181.     nip->nip_Ent = NULL;
  182.     ObtainSemaphore(nim->nim_PointerLock);
  183.     AddHead(nim->nim_Pointer, nip->nip_Node);
  184.     ReleaseSemaphore(nim->nim_PointerLock);
  185.   }
  186.  
  187.   return (struct Unit *)nip;
  188. }
  189.  
  190. /*
  191.  * Delete netinfo pointer 
  192.  */
  193. void ExpungeUnit(BASE, struct Unit *u)
  194. {
  195.   struct NetInfoPointer *nip = (struct NetInfoPointer *)u;
  196.   struct NetInfoMap *nim = CheckUnit(nid, u);
  197.   
  198.   if (nim == NULL) {
  199.     /* We should do an Alert */
  200.     InMsg("CloseDevice(): illegal unit pointer %lx", u);
  201.   } else {
  202.     ObtainSemaphore(nim->nim_PointerLock);
  203.     nim->nim_OpenCnt--;
  204.     Remove(nip->nip_Node);
  205.     ReleaseSemaphore(nim->nim_PointerLock);
  206.     FreeVec(nip);
  207.   }
  208.   return;
  209. }
  210.  
  211. void PerformIO(BASE, struct NetInfoReq *req)
  212. {
  213.   struct NetInfoMap *nim = CheckUnit(nid, req->io_Unit);
  214.  
  215.   if (nim) {
  216.     DoMethod(req->io_Command, req, nim);
  217.   } else {
  218.     req->io_Error = IOERR_BADADDRESS;
  219.     TermIO(req);
  220.   }
  221. }
  222.  
  223. ULONG AbortReq(BASE, struct List *l, struct NetInfoReq *req)
  224. {
  225.   struct Node *n;
  226.  
  227.   for (n = l->lh_Head; n->ln_Succ; n = n->ln_Succ) {
  228.     if (n == (struct Node *)req) {
  229.       Remove((struct Node *)req);
  230.       req->io_Error = IOERR_ABORTED;
  231.       TermIO(req);
  232.       return 0;
  233.     }
  234.   }
  235.  
  236.   return IOERR_NOCMD;
  237. }
  238.  
  239. void UnknownCommand(BASE, struct NetInfoReq * req, struct NetInfoMap *nim)
  240. {
  241.   req->io_Error = IOERR_NOCMD;
  242.   TermIO(req);
  243. }
  244.