amiga-ixemul/ixnet/socket.c

974 lines
22 KiB
C
Raw Permalink Blame History

/*
* This file is part of ixnet.library for the Amiga.
* Copyright (C) 1996 by Jeff Shepherd
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: socket.c,v 1.1.1.1 2005/03/15 15:57:09 laire Exp $
*
* $Log: socket.c,v $
* Revision 1.1.1.1 2005/03/15 15:57:09 laire
* a new beginning
*
* Revision 1.2 2000/06/20 22:17:11 emm
* First attempt at a native MorphOS ixemul
*
* Revision 1.1.1.1 2000/05/07 19:37:48 emm
* Imported sources
*
* Revision 1.1.1.1 2000/04/29 00:44:46 nobody
* Initial import
*
*
*/
#define _KERNEL
#include "ixnet.h"
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <machine/param.h>
#include <string.h>
#include <inetd.h>
#include <stdlib.h>
#include "select.h"
#include "ixprotos.h"
int _tcp_read (struct file *fp, char *buf, int len);
int _tcp_write (struct file *fp, char *buf, int len);
int _tcp_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data);
int _tcp_select (struct file *fp, int select_cmd, int io_mode, fd_set *, u_long *);
int _tcp_close (struct file *fp);
int
_socket (int domain, int type, int protocol)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int err = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
err = SOCK_socket(domain, type, protocol);
break;
case IX_NETWORK_AMITCP:
err = TCP_Socket(domain, type, protocol);
break;
}
return err;
}
int
_bind (struct file *fp, const struct sockaddr *name, int namelen)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int error = -1, oldlen;
switch (network_protocol) {
case IX_NETWORK_AS225:
oldlen = name->sa_len;
((struct sockaddr *)name)->sa_len = 0;
error = SOCK_bind(fp->f_so, name, namelen);
((struct sockaddr *)name)->sa_len = oldlen;
break;
case IX_NETWORK_AMITCP:
error = TCP_Bind(fp->f_so, name, namelen);
break;
}
return error;
}
int
_listen (struct file *fp, int backlog)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int error = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
error = SOCK_listen(fp->f_so, backlog);
break;
case IX_NETWORK_AMITCP:
error = TCP_Listen(fp->f_so, backlog);
break;
}
return error;
}
int
_accept (struct file *fp, struct sockaddr *name, int *namelen)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int err = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
err = SOCK_accept(fp->f_so, name, namelen);
break;
case IX_NETWORK_AMITCP:
err = TCP_Accept(fp->f_so, name, namelen);
break;
}
return err;
}
int
_dup(struct file *fp)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int error = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
/* only INET-225 has dup */
if (((struct Library *)p->u_SockBase)->lib_Version >= 8)
error = SOCK_dup(fp->f_so);
else
error = fp->f_so;
break;
case IX_NETWORK_AMITCP:
error = TCP_Dup2Socket(fp->f_so, -1);
break;
}
return error;
}
int release_socket(struct file *fp)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int error = -1;
/* dup the socket first, since for AmiTCP, we can only release once */
int s2 = _dup(fp);
if (s2 != -1) {
switch (network_protocol) {
case IX_NETWORK_AS225:
error = (int)SOCK_release(s2);
SOCK_close(s2);
break;
case IX_NETWORK_AMITCP:
error = TCP_ReleaseSocket(s2, -1);
TCP_CloseSocket(s2);
break;
}
}
return error;
}
int obtain_socket(long id, int inet, int stream, int protocol)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int error = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
error = SOCK_inherit((void *)id);
break;
case IX_NETWORK_AMITCP:
error = TCP_ObtainSocket(id, inet, stream, protocol);
break;
}
return error;
}
int
_connect (struct file *fp, const struct sockaddr *name, int namelen)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int error = -1, oldlen;
switch (network_protocol) {
case IX_NETWORK_AS225:
oldlen = name->sa_len;
((struct sockaddr *)name)->sa_len = 0;
error = SOCK_connect(fp->f_so, name,namelen);
((struct sockaddr *)name)->sa_len = oldlen;
break;
case IX_NETWORK_AMITCP:
error = TCP_Connect(fp->f_so, name,namelen);
break;
}
return error;
}
int
_sendto (struct file *fp, const void *buf, int len, int flags, const struct sockaddr *to, int tolen)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int rc = -1, oldlen;
switch (network_protocol) {
case IX_NETWORK_AS225:
oldlen = to->sa_len;
((struct sockaddr *)to)->sa_len = 0;
rc = SOCK_sendto(fp->f_so,buf,len,flags,to,tolen);
((struct sockaddr *)to)->sa_len = oldlen;
break;
case IX_NETWORK_AMITCP:
rc = TCP_SendTo(fp->f_so,buf,len,flags,to,tolen);
break;
}
return rc;
}
int
_send (struct file *fp, const void *buf, int len, int flags)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int rc = -1 ;
switch (network_protocol) {
case IX_NETWORK_AS225:
rc = SOCK_send(fp->f_so,buf,len,flags);
break;
case IX_NETWORK_AMITCP:
rc = TCP_Send(fp->f_so,buf,len,flags);
break;
}
return rc;
}
int
_sendmsg (struct file *fp, const struct msghdr *msg, int flags)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int rc = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
rc = SOCK_sendmsg(fp->f_so,msg,flags);
break;
case IX_NETWORK_AMITCP:
rc = TCP_SendMsg(fp->f_so,msg,flags);
break;
}
return rc;
}
int
_recvfrom (struct file *fp, void *buf, int len, int flags, struct sockaddr *from, int *fromlen)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int rc = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
rc = SOCK_recvfrom(fp->f_so,buf,len,flags, from, fromlen);
break;
case IX_NETWORK_AMITCP:
rc = TCP_RecvFrom(fp->f_so,buf,len,flags, from, fromlen);
break;
}
return rc;
}
int
_recv (struct file *fp, void *buf, int len, int flags)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int rc = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
rc = SOCK_recv(fp->f_so,buf,len,flags);
break;
case IX_NETWORK_AMITCP:
rc = TCP_Recv(fp->f_so,buf,len,flags);
break;
}
return rc;
}
int
_recvmsg (struct file *fp, struct msghdr *msg, int flags)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int rc = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
rc = SOCK_recvmsg(fp->f_so,msg,flags);
break;
case IX_NETWORK_AMITCP:
rc = TCP_RecvMsg(fp->f_so,msg,flags);
break;
}
return rc;
}
int _socketpair(int d, int type, int protocol, int sv[2])
{
usetup;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
errno = ENOSYS;
return -1;
}
int
_shutdown (struct file *fp, int how)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int err = 0;
switch (network_protocol) {
case IX_NETWORK_AS225:
err = SOCK_shutdown(fp->f_so,how);
break;
case IX_NETWORK_AMITCP:
err = TCP_ShutDown(fp->f_so,how);
break;
}
return err;
}
int
_setsockopt (struct file *fp, int level, int name, const void *val, int valsize)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int err = 0;
switch (network_protocol) {
case IX_NETWORK_AS225:
err = SOCK_setsockopt(fp->f_so,level,name,val, valsize);
break;
case IX_NETWORK_AMITCP:
err = TCP_SetSockOpt(fp->f_so,level,name,val, valsize);
break;
}
return err;
}
int
_getsockopt (struct file *fp, int level, int name, void *val, int *valsize)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int err = 0;
switch (network_protocol) {
case IX_NETWORK_AS225:
err = SOCK_getsockopt(fp->f_so,level,name,val, valsize);
break;
case IX_NETWORK_AMITCP:
err = TCP_GetSockOpt(fp->f_so,level,name,val, valsize);
break;
}
return err;
}
/*
* Get socket name.
*/
int
_getsockname (struct file *fp, struct sockaddr *asa, int *alen)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int err = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
err = SOCK_getsockname(fp->f_so,asa,alen);
break;
case IX_NETWORK_AMITCP:
err = TCP_GetSockName(fp->f_so,asa,alen);
break;
}
return err;
}
/*
* Get name of peer for connected socket.
*/
int
_getpeername (struct file *fp, struct sockaddr *asa, int *alen)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int err = -1;
switch (network_protocol) {
case IX_NETWORK_AS225:
err = SOCK_getpeername(fp->f_so,asa,alen);
break;
case IX_NETWORK_AMITCP:
err = TCP_GetPeerName(fp->f_so,asa,alen);
break;
}
return err;
}
int
_tcp_read (struct file *fp, char *buf, int len)
{
usetup;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
int ostat, rc;
struct user *p = &u;
ostat = p->p_stat;
p->p_stat = SWAIT;
rc = _recv(fp,buf,len, 0);
if (CURSIG (p))
SetSignal (0, SIGBREAKF_CTRL_C);
p->p_stat = ostat;
if (errno == EINTR)
setrun (SysBase->ThisTask);
return rc;
}
int
_tcp_write (struct file *fp, char *buf, int len)
{
usetup;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
struct user *p = &u;
int ostat, rc;
ostat = p->p_stat;
p->p_stat = SWAIT;
rc = _send(fp,buf,len,0);
if (CURSIG (p))
SetSignal (0, SIGBREAKF_CTRL_C);
p->p_stat = ostat;
if (errno == EINTR)
setrun (SysBase->ThisTask);
return rc;
}
int
_tcp_ioctl (struct file *fp, int cmd, int inout, int arglen, caddr_t data)
{
usetup;
register struct user *usr = &u;
register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int ostat, err = 0;
ostat = usr->p_stat;
usr->p_stat = SWAIT;
switch (network_protocol) {
case IX_NETWORK_AS225:
/* _SIGH_... they left almost everything neatly as it was in the BSD kernel
* code they used, but for whatever reason they decided they needed their
* own kind of ioctl encoding :-((
*
* Well then, here we go, and map `normal' cmds into CBM cmds:
*/
switch (cmd) {
case SIOCADDRT : cmd = ('r'<<8)|1; break;
case SIOCDELRT : cmd = ('r'<<8)|2; break;
case SIOCSIFADDR : cmd = ('i'<<8)|3; break;
case SIOCGIFADDR : cmd = ('i'<<8)|4; break;
case SIOCSIFDSTADDR : cmd = ('i'<<8)|5; break;
case SIOCGIFDSTADDR : cmd = ('i'<<8)|6; break;
case SIOCSIFFLAGS : cmd = ('i'<<8)|7; break;
case SIOCGIFFLAGS : cmd = ('i'<<8)|8; break;
case SIOCGIFCONF : cmd = ('i'<<8)|9; break;
case SIOCSIFMTU : cmd = ('i'<<8)|10; break;
case SIOCGIFMTU : cmd = ('i'<<8)|11; break;
case SIOCGIFBRDADDR : cmd = ('i'<<8)|12; break;
case SIOCSIFBRDADDR : cmd = ('i'<<8)|13; break;
case SIOCGIFNETMASK : cmd = ('i'<<8)|14; break;
case SIOCSIFNETMASK : cmd = ('i'<<8)|15; break;
case SIOCGIFMETRIC : cmd = ('i'<<8)|16; break;
case SIOCSIFMETRIC : cmd = ('i'<<8)|17; break;
case SIOCSARP : cmd = ('i'<<8)|18; break;
case SIOCGARP : cmd = ('i'<<8)|19; break;
case SIOCDARP : cmd = ('i'<<8)|20; break;
case SIOCATMARK : cmd = ('i'<<8)|21; break;
case FIONBIO : cmd = ('m'<<8)|22; break;
case FIONREAD : cmd = ('m'<<8)|23; break;
case FIOASYNC : cmd = ('m'<<8)|24; break;
case SIOCSPGRP : cmd = ('m'<<8)|25; break;
case SIOCGPGRP : cmd = ('m'<<8)|26; break;
/* we really don't have to bother the library with cmds we can't even
* map over...
*/
}
err = SOCK_ioctl(fp->f_so,cmd,data);
break;
case IX_NETWORK_AMITCP:
err = TCP_IoctlSocket(fp->f_so,cmd,data);
break;
}
if (CURSIG (usr))
SetSignal (0, SIGBREAKF_CTRL_C);
usr->p_stat = ostat;
if (errno == EINTR)
setrun (SysBase->ThisTask);
return err;
}
/* looks like ixemul.library can't grog ixnet.library calling ix_lock_base()
* moved most of this code back into ixemul.library
*/
int
_tcp_close (struct file *fp)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
register int network_protocol = p->u_networkprotocol;
int err = 0;
#if 0
ix_lock_base ();
fp->f_count--;
if (fp->f_count == 0) {
/* don't have the base locked for IN_close, this MAY block!! */
ix_unlock_base ();
#endif
switch (network_protocol) {
case IX_NETWORK_AS225:
err = SOCK_close (fp->f_so);
break;
case IX_NETWORK_AMITCP:
err = TCP_CloseSocket(fp->f_so);
break;
}
#if 0
}
else
ix_unlock_base ();
#endif
return err;
}
static int
_tcp_poll(struct file *fp, int io_mode)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
int rc = -1;
fd_set in, out, exc;
struct timeval tv = {0, 0};
register int network_protocol = p->u_networkprotocol;
FD_ZERO(&in);
FD_ZERO(&out);
FD_ZERO(&exc);
switch (io_mode) {
case SELMODE_IN:
FD_SET(fp->f_so,&in);
break;
case SELMODE_OUT:
FD_SET(fp->f_so,&out);
break;
case SELMODE_EXC:
FD_SET(fp->f_so,&exc);
break;
}
switch (network_protocol) {
case IX_NETWORK_AS225:
rc = SOCK_selectwait(fp->f_so+1,&in,&out,&exc,&tv,NULL);
break;
case IX_NETWORK_AMITCP:
rc = TCP_WaitSelect(fp->f_so+1,&in,&out,&exc,&tv,NULL);
break;
}
return ((rc == 1) ? 1 : 0);
}
int
_tcp_select (struct file *fp, int select_cmd, int io_mode, fd_set *set, u_long *nfds)
{
usetup;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
if (select_cmd == SELCMD_PREPARE)
{
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
FD_SET(fp->f_so, set);
if (fp->f_so > *nfds)
*nfds = fp->f_so;
return (1L << p->u_sigurg | 1L << p->u_sigio);
}
if (select_cmd == SELCMD_CHECK)
return FD_ISSET(fp->f_so, set);
if (select_cmd == SELCMD_POLL)
return _tcp_poll(fp, io_mode);
return 0;
}
u_long
waitselect(long wait_sigs, fd_set *in, fd_set *out, fd_set *exc, u_long nfds)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
int rc = -1;
switch (p->u_networkprotocol) {
case IX_NETWORK_AS225:
rc = SOCK_selectwait(nfds + 1, in, out, exc, NULL, &wait_sigs);
break;
case IX_NETWORK_AMITCP:
rc = TCP_WaitSelect(nfds + 1, in, out, exc, NULL, &wait_sigs);
break;
}
return (rc == -1 ? -1 : wait_sigs);
}
/*
* init_inet_daemon.c - obtain socket accepted by the inetd
*
* Copyright <20> 1994 AmiTCP/IP Group,
* Network Solutions Development Inc.
* All rights reserved.
* Portions Copyright <20> 1995 by Jeff Shepherd
*/
/* AS225 inet daemon stuff */
struct inetmsg {
struct Message msg;
ULONG id;
};
int
init_inet_daemon(int *argc, char ***argv)
{
usetup;
register struct user *usr = &u;
register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
struct file *fp;
register int network_protocol = p->u_networkprotocol;
int sock;
if (network_protocol == IX_NETWORK_AS225) {
static int init_d(int *, char ***);
return init_d(argc,argv);
}
else if (network_protocol == IX_NETWORK_AMITCP) {
struct Process *me = (struct Process *)SysBase->ThisTask;
struct DaemonMessage *dm = (struct DaemonMessage *)me->pr_ExitData;
int fd,ostat;
int err;
if (dm == NULL) {
/*
* No DaemonMessage, return error code - probably not an inet daemon
*/
return -1;
}
/*
* Obtain the server socket
*/
sock = TCP_ObtainSocket(dm->dm_Id, dm->dm_Family, dm->dm_Type, 0);
if (sock < 0) {
/*
* If ObtainSocket fails we need to exit with this specific exit code
* so that the inetd knows to clean things up
*/
exit(DERR_OBTAIN);
}
ostat = usr->p_stat;
usr->p_stat = SWAIT;
do {
if ((err = falloc(&fp, &fd)))
break;
fp->f_so = sock;
_set_socket_params(fp, dm->dm_Family, dm->dm_Type, 0);
} while (0);
if (CURSIG (usr))
SetSignal (0, SIGBREAKF_CTRL_C);
usr->p_stat = ostat;
if (err == EINTR)
setrun (SysBase->ThisTask);
errno = err;
return err ? -1 : fd;
}
else
return -1;
}
/* code loosely derived from timed.c from AS225r2 */
/* this program was called from inetd if :
* 1> the first arg is a valid protocol(call getprotobyname)
* 2> inetd is started - FindPort("inetd") returns non-NULL
* NOT 3> argv[0] is the program found in inetd.conf for the program (scan inetd.conf)
*/
#include <netdb.h>
#include <stdio.h>
static int init_d(int *argc, char ***argv)
{
usetup;
struct user *usr = &u;
register struct ixnet *p = (struct ixnet *)usr->u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
int ostat;
int err = 1;
int fd = -1;
ostat = usr->p_stat;
usr->p_stat = SWAIT;
/* save a little time with this comparison */
if (*argc >= 4) {
struct servent *serv, *serv2;
serv = SOCK_getservbyname((*argv)[1],"tcp");
serv2 = SOCK_getservbyname((*argv)[1],"udp");
if (serv || serv2) {
if (FindPort("inetd")) {
#if 0 /* I think this isn't needed, SOCK_inherit should be enough */
char daemon[MAXPATHLEN];
char line[1024];
char protocol[MAXPATHLEN];
FILE *inetdconf;
int founddaemon = 0;
if (inetdconf = fopen("inet:db/inetd.conf","r")) {
while (!feof(inetdconf)) {
fgets(line,sizeof(line),inetdconf);
sscanf(line,"%s %*s %*s %*s %s",protocol,daemon);
if (!strcmp(protocol,(*argv)[1])) {
founddaemon = 1;
break;
}
}
fclose(inetdconf);
if (founddaemon) {
char *filename = FilePart(daemon);
#endif
if (/*!stricmp((*argv)[0],filename)*/1) {
struct file *fp;
long sock_arg;
int sock;
int i;
sock_arg = atol((*argv)[2]);
p->sock_id = atoi((*argv)[3]);
sock = SOCK_inherit((void *)sock_arg);
if (sock != -1) {
p->u_daemon = 1; /* I was started from inetd */
do {
int type;
fd = 0;
if ((err = falloc(&fp, &fd)))
break;
fp->f_so = sock;
_set_socket_params(fp, AF_INET, type, 0);
/* get rid of the args that AS225 put in */
for (i=1; i < (*argc)-3; i++) {
(*argv)[i] = (*argv)[i+3];
}
(*argc) -= 3;
} while (0);
if (CURSIG (usr))
SetSignal (0, SIGBREAKF_CTRL_C);
}
}
#if 0
}
}
#endif
}
}
}
usr->p_stat = ostat;
errno = err;
return err ? -1 : fd;
}
/* This is only needed for AS225 */
void shutdown_inet_daemon(void)
{
usetup;
register struct ixnet *p = (struct ixnet *)u.u_ixnet;
if (u.u_parent_userdata)u_ptr=u.u_parent_userdata;
struct inetmsg inet_message;
struct MsgPort *msgport, *replyport;
if (p->u_networkprotocol != IX_NETWORK_AS225 || !p->u_daemon)
return;
if ((inet_message.id = p->sock_id)) {
replyport = CreateMsgPort();
if (replyport) {
inet_message.msg.mn_Node.ln_Type = NT_MESSAGE;
inet_message.msg.mn_Length = sizeof(struct inetmsg);
inet_message.msg.mn_ReplyPort = replyport;
msgport = FindPort("inetd");
if (msgport) {
PutMsg(msgport,(struct Message *)&inet_message);
/* we can't exit until we received a reply */
WaitPort(replyport);
}
DeleteMsgPort(replyport);
}
}
}