home *** CD-ROM | disk | FTP | other *** search
/ Aminet 18 / aminetcdnumber181997.iso / Aminet / dev / gcc / ixemulsrc.lha / ixemul / ixnet / socket.c < prev    next >
C/C++ Source or Header  |  1996-12-11  |  19KB  |  829 lines

  1. /*
  2.  *  This file is part of ixnet.library for the Amiga.
  3.  *  Copyright (C) 1996 by Jeff Shepherd
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  $Id:$
  20.  *
  21.  *  $Log:$
  22.  *
  23.  */
  24.  
  25. #define _KERNEL
  26. #include "ixnet.h"
  27.  
  28. #include <sys/socket.h>
  29. #include <sys/socketvar.h>
  30. #include <sys/ioctl.h>
  31. #include <net/if.h>
  32. #include <net/route.h>
  33. #include <netinet/in.h>
  34. #include <machine/param.h>
  35. #include <string.h>
  36. #include <inetd.h>
  37. #include <stdlib.h>
  38. #include "select.h"
  39. #include "ixprotos.h"
  40.  
  41. int _tcp_read    (struct file *fp, char *buf, int len);
  42. int _tcp_write    (struct file *fp, char *buf, int len);
  43. int _tcp_ioctl    (struct file *fp, int cmd, int inout, int arglen, caddr_t data);
  44. int _tcp_select (struct file *fp, int select_cmd, int io_mode, fd_set *, u_long *);
  45. int _tcp_close    (struct file *fp);
  46.  
  47. int
  48. _socket (int domain, int type, int protocol)
  49. {
  50.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  51.     register int network_protocol = p->u_networkprotocol;
  52.     int err = -1;
  53.  
  54.     switch (network_protocol) {
  55.     case IX_NETWORK_AS225:
  56.         err = SOCK_socket(domain, type, protocol);
  57.     break;
  58.  
  59.     case IX_NETWORK_AMITCP:
  60.         err = TCP_Socket(domain, type, protocol);
  61.     break;
  62.     }
  63.     return err;
  64. }
  65.  
  66.  
  67. int
  68. _bind (struct file *fp, const struct sockaddr *name, int namelen)
  69. {
  70.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  71.     register int network_protocol = p->u_networkprotocol;
  72.     int error = -1, oldlen;
  73.  
  74.     switch (network_protocol) {
  75.     case IX_NETWORK_AS225:
  76.         oldlen = name->sa_len;
  77.         ((struct sockaddr *)name)->sa_len = 0;
  78.         error = SOCK_bind(fp->f_so, name, namelen);
  79.         ((struct sockaddr *)name)->sa_len = oldlen;
  80.     break;
  81.  
  82.     case IX_NETWORK_AMITCP:
  83.         error = TCP_Bind(fp->f_so, name, namelen);
  84.     break;
  85.     }
  86.     return error;
  87. }
  88.  
  89. int
  90. _listen (struct file *fp, int backlog)
  91. {
  92.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  93.     register int network_protocol = p->u_networkprotocol;
  94.     int error = -1;
  95.  
  96.     switch (network_protocol) {
  97.     case IX_NETWORK_AS225:
  98.         error = SOCK_listen(fp->f_so, backlog);
  99.     break;
  100.  
  101.     case IX_NETWORK_AMITCP:
  102.         error = TCP_Listen(fp->f_so, backlog);
  103.     break;
  104.     }
  105.     return error;
  106. }
  107.  
  108. int
  109. _accept (struct file *fp, struct sockaddr *name, int *namelen)
  110. {
  111.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  112.     register int network_protocol = p->u_networkprotocol;
  113.     int err = -1;
  114.     switch (network_protocol) {
  115.     case IX_NETWORK_AS225:
  116.         err = SOCK_accept(fp->f_so, name, namelen);
  117.     break;
  118.  
  119.     case IX_NETWORK_AMITCP:
  120.         err = TCP_Accept(fp->f_so, name, namelen);
  121.     break;
  122.     }
  123.     return err;
  124. }
  125.  
  126.  
  127. int
  128. _connect (struct file *fp, const struct sockaddr *name, int namelen)
  129. {
  130.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  131.     register int network_protocol = p->u_networkprotocol;
  132.     int error = -1, oldlen;
  133.  
  134.     switch (network_protocol) {
  135.     case IX_NETWORK_AS225:
  136.         oldlen = name->sa_len;
  137.         ((struct sockaddr *)name)->sa_len = 0;
  138.         error = SOCK_connect(fp->f_so, name,namelen);
  139.         ((struct sockaddr *)name)->sa_len = oldlen;
  140.     break;
  141.  
  142.     case IX_NETWORK_AMITCP:
  143.         error = TCP_Connect(fp->f_so, name,namelen);
  144.     break;
  145.     }
  146.     return error;
  147. }
  148.  
  149. int
  150. _sendto (struct file *fp, const void *buf, int len, int flags, const struct sockaddr *to, int tolen)
  151. {
  152.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  153.     register int network_protocol = p->u_networkprotocol;
  154.     int rc = -1, oldlen;
  155.  
  156.     switch (network_protocol) {
  157.  
  158.     case IX_NETWORK_AS225:
  159.         oldlen = to->sa_len;
  160.         ((struct sockaddr *)to)->sa_len = 0;
  161.         rc = SOCK_sendto(fp->f_so,buf,len,flags,to,tolen);
  162.         ((struct sockaddr *)to)->sa_len = oldlen;
  163.     break;
  164.  
  165.     case IX_NETWORK_AMITCP:
  166.         rc = TCP_SendTo(fp->f_so,buf,len,flags,to,tolen);
  167.     break;
  168.     }
  169.  
  170.     return rc;
  171. }
  172.  
  173.  
  174. int
  175. _send (struct file *fp, const void *buf, int len, int flags)
  176. {
  177.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  178.     register int network_protocol = p->u_networkprotocol;
  179.     int rc = -1 ;
  180.  
  181.     switch (network_protocol) {
  182.  
  183.     case IX_NETWORK_AS225:
  184.         rc = SOCK_send(fp->f_so,buf,len,flags);
  185.     break;
  186.  
  187.     case IX_NETWORK_AMITCP:
  188.         rc = TCP_Send(fp->f_so,buf,len,flags);
  189.     break;
  190.     }
  191.  
  192.     return rc;
  193. }
  194.  
  195.  
  196. int
  197. _sendmsg (struct file *fp, const struct msghdr *msg, int flags)
  198. {
  199.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  200.     register int network_protocol = p->u_networkprotocol;
  201.     int rc = -1;
  202.  
  203.     switch (network_protocol) {
  204.  
  205.     case IX_NETWORK_AS225:
  206.         rc = SOCK_sendmsg(fp->f_so,msg,flags);
  207.     break;
  208.  
  209.     case IX_NETWORK_AMITCP:
  210.         rc = TCP_SendMsg(fp->f_so,msg,flags);
  211.     break;
  212.     }
  213.  
  214.     return rc;
  215. }
  216.  
  217.  
  218. int
  219. _recvfrom (struct file *fp, void *buf, int len, int flags, struct sockaddr *from, int *fromlen)
  220. {
  221.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  222.     register int network_protocol = p->u_networkprotocol;
  223.     int rc = -1;
  224.  
  225.     switch (network_protocol) {
  226.  
  227.     case IX_NETWORK_AS225:
  228.         rc = SOCK_recvfrom(fp->f_so,buf,len,flags, from, fromlen);
  229.     break;
  230.  
  231.     case IX_NETWORK_AMITCP:
  232.         rc = TCP_RecvFrom(fp->f_so,buf,len,flags, from, fromlen);
  233.     break;
  234.     }
  235.  
  236.     return rc;
  237. }
  238.  
  239.  
  240. int
  241. _recv (struct file *fp, void *buf, int len, int flags)
  242. {
  243.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  244.     register int network_protocol = p->u_networkprotocol;
  245.     int rc = -1;
  246.  
  247.     switch (network_protocol) {
  248.  
  249.     case IX_NETWORK_AS225:
  250.         rc = SOCK_recv(fp->f_so,buf,len,flags);
  251.     break;
  252.  
  253.     case IX_NETWORK_AMITCP:
  254.         rc = TCP_Recv(fp->f_so,buf,len,flags);
  255.     break;
  256.     }
  257.  
  258.     return rc;
  259. }
  260.  
  261.  
  262. int
  263. _recvmsg (struct file *fp, struct msghdr *msg, int flags)
  264. {
  265.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  266.     register int network_protocol = p->u_networkprotocol;
  267.     int rc = -1;
  268.  
  269.     switch (network_protocol) {
  270.  
  271.     case IX_NETWORK_AS225:
  272.         rc = SOCK_recvmsg(fp->f_so,msg,flags);
  273.     break;
  274.  
  275.     case IX_NETWORK_AMITCP:
  276.         rc = TCP_RecvMsg(fp->f_so,msg,flags);
  277.     break;
  278.     }
  279.  
  280.     return rc;
  281. }
  282.  
  283. int _socketpair(int d, int type, int protocol, int sv[2])
  284. {
  285.     errno = ENOSYS;
  286.     return -1;
  287. }
  288.  
  289. int
  290. _shutdown (struct file *fp, int how)
  291. {
  292.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  293.     register int network_protocol = p->u_networkprotocol;
  294.     int err = 0;
  295.  
  296.     switch (network_protocol) {
  297.  
  298.     case IX_NETWORK_AS225:
  299.         err = SOCK_shutdown(fp->f_so,how);
  300.     break;
  301.  
  302.     case IX_NETWORK_AMITCP:
  303.         err = TCP_ShutDown(fp->f_so,how);
  304.     break;
  305.     }
  306.     return err;
  307. }
  308.  
  309.  
  310. int
  311. _setsockopt (struct file *fp, int level, int name, const void *val, int valsize)
  312. {
  313.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  314.     register int network_protocol = p->u_networkprotocol;
  315.     int err = 0;
  316.  
  317.     switch (network_protocol) {
  318.  
  319.     case IX_NETWORK_AS225:
  320.         err = SOCK_setsockopt(fp->f_so,level,name,val, valsize);
  321.     break;
  322.  
  323.     case IX_NETWORK_AMITCP:
  324.         err = TCP_SetSockOpt(fp->f_so,level,name,val, valsize);
  325.     break;
  326.     }
  327.  
  328.     return err;
  329. }
  330.  
  331. int
  332. _getsockopt (struct file *fp, int level, int name, void *val, int *valsize)
  333. {
  334.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  335.     register int network_protocol = p->u_networkprotocol;
  336.     int err = 0;
  337.  
  338.     switch (network_protocol) {
  339.  
  340.     case IX_NETWORK_AS225:
  341.         err = SOCK_getsockopt(fp->f_so,level,name,val, valsize);
  342.     break;
  343.  
  344.     case IX_NETWORK_AMITCP:
  345.         err = TCP_GetSockOpt(fp->f_so,level,name,val, valsize);
  346.     break;
  347.     }
  348.  
  349.     return err;
  350. }
  351.  
  352.  
  353. /*
  354.  * Get socket name.
  355.  */
  356. int
  357. _getsockname (struct file *fp, struct sockaddr *asa, int *alen)
  358. {
  359.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  360.     register int network_protocol = p->u_networkprotocol;
  361.     int err = -1;
  362.  
  363.     switch (network_protocol) {
  364.  
  365.     case IX_NETWORK_AS225:
  366.         err = SOCK_getsockname(fp->f_so,asa,alen);
  367.     break;
  368.  
  369.     case IX_NETWORK_AMITCP:
  370.         err = TCP_GetSockName(fp->f_so,asa,alen);
  371.     break;
  372.     }
  373.  
  374.     return err;
  375. }
  376.  
  377. /*
  378.  * Get name of peer for connected socket.
  379.  */
  380. int
  381. _getpeername (struct file *fp, struct sockaddr *asa, int *alen)
  382. {
  383.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  384.     register int network_protocol = p->u_networkprotocol;
  385.     int err = -1;
  386.  
  387.     switch (network_protocol) {
  388.  
  389.     case IX_NETWORK_AS225:
  390.         err = SOCK_getpeername(fp->f_so,asa,alen);
  391.     break;
  392.  
  393.     case IX_NETWORK_AMITCP:
  394.         err = TCP_GetPeerName(fp->f_so,asa,alen);
  395.     break;
  396.     }
  397.  
  398.     return err;
  399. }
  400.  
  401. int
  402. _tcp_read (struct file *fp, char *buf, int len)
  403. {
  404.     int ostat, rc;
  405.     struct user *p = &u;
  406.  
  407.     ostat = p->p_stat;
  408.     p->p_stat = SWAIT;
  409.  
  410.     rc = _recv(fp,buf,len, 0);
  411.  
  412.     if (CURSIG (p))
  413.     SetSignal (0, SIGBREAKF_CTRL_C);
  414.  
  415.     p->p_stat = ostat;
  416.  
  417.     if (errno == EINTR)
  418.     setrun (FindTask (0));
  419.  
  420.     return rc;
  421. }
  422.  
  423.  
  424. int
  425. _tcp_write (struct file *fp, char *buf, int len)
  426. {
  427.     struct user *p = &u;
  428.     int ostat, rc;
  429.  
  430.     ostat = p->p_stat;
  431.     p->p_stat = SWAIT;
  432.  
  433.     rc = _send(fp,buf,len,0);
  434.  
  435.     if (CURSIG (p))
  436.     SetSignal (0, SIGBREAKF_CTRL_C);
  437.  
  438.     p->p_stat = ostat;
  439.  
  440.     if (errno == EINTR)
  441.     setrun (FindTask (0));
  442.  
  443.     return rc;
  444. }
  445.  
  446. int
  447. _tcp_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data)
  448. {
  449.     register struct user *usr = &u;
  450.     register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
  451.     register int network_protocol = p->u_networkprotocol;
  452.     int ostat, err = 0;
  453.  
  454.     ostat = usr->p_stat;
  455.     usr->p_stat = SWAIT;
  456.  
  457.     switch (network_protocol) {
  458.  
  459.     case IX_NETWORK_AS225:
  460.  
  461.         /* _SIGH_... they left almost everything neatly as it was in the BSD kernel
  462.          *    code they used, but for whatever reason they decided they needed their
  463.          *    own kind of ioctl encoding :-((
  464.          *
  465.          *    Well then, here we go, and map `normal' cmds into CBM cmds:
  466.          */
  467.  
  468.         switch (cmd) {
  469.         case SIOCADDRT         : cmd = ('r'<<8)|1; break;
  470.         case SIOCDELRT         : cmd = ('r'<<8)|2; break;
  471.         case SIOCSIFADDR     : cmd = ('i'<<8)|3; break;
  472.         case SIOCGIFADDR     : cmd = ('i'<<8)|4; break;
  473.         case SIOCSIFDSTADDR  : cmd = ('i'<<8)|5; break;
  474.         case SIOCGIFDSTADDR  : cmd = ('i'<<8)|6; break;
  475.         case SIOCSIFFLAGS    : cmd = ('i'<<8)|7; break;
  476.         case SIOCGIFFLAGS    : cmd = ('i'<<8)|8; break;
  477.         case SIOCGIFCONF     : cmd = ('i'<<8)|9; break;
  478.         case SIOCSIFMTU      : cmd = ('i'<<8)|10; break;
  479.         case SIOCGIFMTU      : cmd = ('i'<<8)|11; break;
  480.         case SIOCGIFBRDADDR  : cmd = ('i'<<8)|12; break;
  481.         case SIOCSIFBRDADDR  : cmd = ('i'<<8)|13; break;
  482.         case SIOCGIFNETMASK  : cmd = ('i'<<8)|14; break;
  483.         case SIOCSIFNETMASK  : cmd = ('i'<<8)|15; break;
  484.         case SIOCGIFMETRIC   : cmd = ('i'<<8)|16; break;
  485.         case SIOCSIFMETRIC   : cmd = ('i'<<8)|17; break;
  486.         case SIOCSARP         : cmd = ('i'<<8)|18; break;
  487.         case SIOCGARP         : cmd = ('i'<<8)|19; break;
  488.         case SIOCDARP         : cmd = ('i'<<8)|20; break;
  489.         case SIOCATMARK      : cmd = ('i'<<8)|21; break;
  490.         case FIONBIO         : cmd = ('m'<<8)|22; break;
  491.         case FIONREAD         : cmd = ('m'<<8)|23; break;
  492.         case FIOASYNC         : cmd = ('m'<<8)|24; break;
  493.         case SIOCSPGRP         : cmd = ('m'<<8)|25; break;
  494.         case SIOCGPGRP         : cmd = ('m'<<8)|26; break;
  495.  
  496.         default:
  497.         /* we really don't have to bother the library with cmds we can't even
  498.          * map over...
  499.          */
  500.         }
  501.         err = SOCK_ioctl(fp->f_so,cmd,data);
  502.     break;
  503.  
  504.     case IX_NETWORK_AMITCP:
  505.         err = TCP_IoctlSocket(fp->f_so,cmd,data);
  506.     break;
  507.     }
  508.     if (CURSIG (usr))
  509.     SetSignal (0, SIGBREAKF_CTRL_C);
  510.  
  511.     usr->p_stat = ostat;
  512.  
  513.     if (errno == EINTR)
  514.     setrun (FindTask (0));
  515.  
  516.     return err;
  517. }
  518.  
  519. /* looks like ixemul.library can't grog ixnet.library calling ix_lock_base()
  520.  * moved most of this code back into ixemul.library
  521.  */
  522. int
  523. _tcp_close (struct file *fp)
  524. {
  525.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  526.     register int network_protocol = p->u_networkprotocol;
  527.     int err = 0;
  528.  
  529. #if 0
  530.     ix_lock_base ();
  531.     fp->f_count--;
  532.  
  533.     if (fp->f_count == 0) {
  534.     /* don't have the base locked for IN_close, this MAY block!! */
  535.     ix_unlock_base ();
  536. #endif
  537.     switch (network_protocol) {
  538.  
  539.         case IX_NETWORK_AS225:
  540.         err = SOCK_close (fp->f_so);
  541.         break;
  542.  
  543.         case IX_NETWORK_AMITCP:
  544.         err = TCP_CloseSocket(fp->f_so);
  545.         break;
  546.     }
  547. #if 0
  548.     }
  549.     else
  550.     ix_unlock_base ();
  551. #endif
  552.     return err;
  553. }
  554.  
  555. static int
  556. _tcp_poll(struct file *fp, int io_mode)
  557. {
  558.     int rc = -1;
  559.     fd_set in, out, exc;
  560.     struct timeval tv = {0, 0};
  561.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  562.     register int network_protocol = p->u_networkprotocol;
  563.  
  564.     FD_ZERO(&in);
  565.     FD_ZERO(&out);
  566.     FD_ZERO(&exc);
  567.  
  568.     switch (io_mode) {
  569.     case SELMODE_IN:
  570.         FD_SET(fp->f_so,&in);
  571.     break;
  572.  
  573.     case SELMODE_OUT:
  574.         FD_SET(fp->f_so,&out);
  575.     break;
  576.  
  577.     case SELMODE_EXC:
  578.         FD_SET(fp->f_so,&exc);
  579.     break;
  580.     }
  581.  
  582.     switch (network_protocol) {
  583.     case IX_NETWORK_AS225:
  584.         rc = SOCK_selectwait(fp->f_so+1,&in,&out,&exc,&tv,NULL);
  585.     break;
  586.  
  587.     case IX_NETWORK_AMITCP:
  588.         rc = TCP_WaitSelect(fp->f_so+1,&in,&out,&exc,&tv,NULL);
  589.     break;
  590.     }
  591.  
  592.     return ((rc == 1) ? 1 : 0);
  593. }
  594.  
  595. int
  596. _tcp_select (struct file *fp, int select_cmd, int io_mode, fd_set *set, u_long *nfds)
  597. {
  598.   if (select_cmd == SELCMD_PREPARE)
  599.     {
  600.       register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  601.  
  602.       FD_SET(fp->f_so, set);
  603.       if (fp->f_so > *nfds)
  604.         *nfds = fp->f_so;
  605.       return (1L << p->u_sigurg | 1L << p->u_sigio);
  606.     }
  607.   if (select_cmd == SELCMD_CHECK)
  608.     return FD_ISSET(fp->f_so, set);
  609.   if (select_cmd == SELCMD_POLL)
  610.     return _tcp_poll(fp, io_mode);
  611.   return 0;
  612. }
  613.  
  614. u_long
  615. waitselect(long wait_sigs, fd_set *in, fd_set *out, fd_set *exc, u_long nfds)
  616. {
  617.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  618.     int rc = -1;
  619.  
  620.     switch (p->u_networkprotocol) {
  621.     case IX_NETWORK_AS225:
  622.         rc = SOCK_selectwait(nfds + 1, in, out, exc, NULL, &wait_sigs);
  623.     break;
  624.  
  625.     case IX_NETWORK_AMITCP:
  626.         rc = TCP_WaitSelect(nfds + 1, in, out, exc, NULL, &wait_sigs);
  627.     break;
  628.     }
  629.     return (rc == -1 ? -1 : wait_sigs);
  630. }
  631.  
  632. /*
  633.  *    init_inet_daemon.c - obtain socket accepted by the inetd
  634.  *
  635.  *    Copyright © 1994 AmiTCP/IP Group,
  636.  *             Network Solutions Development Inc.
  637.  *             All rights reserved.
  638.  *    Portions Copyright © 1995 by Jeff Shepherd
  639.  */
  640.  
  641. /* AS225 inet daemon stuff */
  642. struct inetmsg {
  643.     struct Message  msg;
  644.     ULONG   id;
  645. };
  646.  
  647. int
  648. init_inet_daemon(int *argc, char ***argv)
  649. {
  650.     register struct user *usr = &u;
  651.     register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
  652.     struct file *fp;
  653.     register int network_protocol = p->u_networkprotocol;
  654.     int sock;
  655.  
  656.     if (network_protocol == IX_NETWORK_AS225) {
  657.     static int init_d(int *, char ***);
  658.     return init_d(argc,argv);
  659.     }
  660.     else if (network_protocol == IX_NETWORK_AMITCP) {
  661.     struct Process *me = (struct Process *)SysBase->ThisTask;
  662.     struct DaemonMessage *dm = (struct DaemonMessage *)me->pr_ExitData;
  663.     int fd,ostat;
  664.     int err;
  665.  
  666.     if (dm == NULL) {
  667.         /*
  668.         * No DaemonMessage, return error code - probably not an inet daemon
  669.         */
  670.         return -1;
  671.     }
  672.  
  673.     /*
  674.      * Obtain the server socket
  675.      */
  676.     sock = TCP_ObtainSocket(dm->dm_Id, dm->dm_Family, dm->dm_Type, 0);
  677.     if (sock < 0) {
  678.         /*
  679.         * If ObtainSocket fails we need to exit with this specific exit code
  680.         * so that the inetd knows to clean things up
  681.         */
  682.         exit(DERR_OBTAIN);
  683.     }
  684.  
  685.     ostat = usr->p_stat;
  686.     usr->p_stat = SWAIT;
  687.  
  688.     do {
  689.  
  690.         if ((err = falloc(&fp, &fd)))
  691.         break;
  692.  
  693.         fp->f_so = sock;
  694.         _set_socket_params(fp,AF_INET);
  695.     } while (0);
  696.  
  697.     if (CURSIG (usr))
  698.         SetSignal (0, SIGBREAKF_CTRL_C);
  699.  
  700.     usr->p_stat = ostat;
  701.  
  702.     if (err == EINTR)
  703.         setrun (FindTask (0));
  704.  
  705.     errno = err;
  706.     return err ? -1 : fd;
  707.     }
  708.     else
  709.     return -1;
  710. }
  711.  
  712. /* code loosely derived from timed.c from AS225r2 */
  713. /* this program was called from inetd if :
  714.  * 1> the first arg is a valid protocol(call getprotobyname)
  715.  * 2> inetd is started - FindPort("inetd") returns non-NULL
  716.  * NOT 3> argv[0] is the program found in inetd.conf for the program (scan inetd.conf)
  717.  */
  718. #include <netdb.h>
  719. #include <stdio.h>
  720.  
  721. static int init_d(int *argc, char ***argv)
  722. {
  723.     struct user *usr = &u;
  724.     register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
  725.     int ostat;
  726.     int err = 1;
  727.     int fd = -1;
  728.  
  729.     ostat = usr->p_stat;
  730.     usr->p_stat = SWAIT;
  731.  
  732.     /* save a little time with this comparison */
  733.     if (*argc >= 4) {
  734.     struct servent *serv, *serv2;
  735.     serv = SOCK_getservbyname((*argv)[1],"tcp");
  736.     serv2 = SOCK_getservbyname((*argv)[1],"udp");
  737.     if (serv || serv2) {
  738.         if (FindPort("inetd")) {
  739. #if 0 /* I think this isn't needed, SOCK_inherit should be enough */
  740.         char daemon[MAXPATHLEN];
  741.         char line[1024];
  742.         char protocol[MAXPATHLEN];
  743.         FILE *inetdconf;
  744.         int founddaemon = 0;
  745.         if (inetdconf = fopen("inet:db/inetd.conf","r")) {
  746.             while (!feof(inetdconf)) {
  747.             fgets(line,sizeof(line),inetdconf);
  748.             sscanf(line,"%s %*s %*s %*s %s",protocol,daemon);
  749.             if (!strcmp(protocol,(*argv)[1])) {
  750.                 founddaemon = 1;
  751.                 break;
  752.             }
  753.             }
  754.             fclose(inetdconf);
  755.  
  756.             if (founddaemon)  {
  757.             char *filename = FilePart(daemon);
  758. #endif
  759.             if (/*!stricmp((*argv)[0],filename)*/1) {
  760.                 struct file *fp;
  761.             long sock_arg;
  762.             int sock;
  763.                 int i;
  764.  
  765.                 sock_arg = atol((*argv)[2]);
  766.                 p->sock_id = atoi((*argv)[3]);
  767.                 sock = SOCK_inherit((void *)sock_arg);
  768.                 if (sock != -1) {
  769.                 p->u_daemon = 1; /* I was started from inetd */
  770.                 do {
  771.                     fd = 0;
  772.                     if ((err = falloc(&fp, &fd)))
  773.                     break;
  774.  
  775.                     fp->f_so = sock;
  776.                     _set_socket_params(fp,AF_INET);
  777.  
  778.                     /* get rid of the args that AS225 put in */
  779.                     for (i=1; i < (*argc)-3; i++) {
  780.                     (*argv)[i] = (*argv)[i+3];
  781.                     }
  782.                     (*argc) -= 3;
  783.                 } while (0);
  784.  
  785.                 if (CURSIG (usr))
  786.                     SetSignal (0, SIGBREAKF_CTRL_C);
  787.                 }
  788.             }
  789. #if 0
  790.             }
  791.         }
  792. #endif
  793.         }
  794.     }
  795.     }
  796.     usr->p_stat = ostat;
  797.     errno = err;
  798.     return err ? -1 : fd;
  799. }
  800.  
  801. /* This is only needed for AS225 */
  802. void shutdown_inet_daemon(void)
  803. {
  804.     register struct ixnet *p = (struct ixnet *)u.u_ixnet;
  805.     struct inetmsg inet_message;
  806.     struct MsgPort *msgport, *replyport;
  807.  
  808.     if (p->u_networkprotocol != IX_NETWORK_AS225 || !p->u_daemon)
  809.     return;
  810.  
  811.     if((inet_message.id = p->sock_id)) {
  812.     replyport = CreateMsgPort();
  813.     if(replyport) {
  814.         inet_message.msg.mn_Node.ln_Type = NT_MESSAGE;
  815.         inet_message.msg.mn_Length = sizeof(struct inetmsg);
  816.         inet_message.msg.mn_ReplyPort = replyport;
  817.  
  818.         msgport = FindPort("inetd");
  819.         if(msgport) {
  820.         PutMsg(msgport,(struct Message *)&inet_message);
  821.         /* we can't exit until we received a reply */
  822.         (void)WaitPort(replyport);
  823.         }
  824.         DeleteMsgPort(replyport);
  825.     }
  826.     }
  827. }
  828.  
  829.