Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site cadre.ARPA Path: utzoo!watmath!clyde!bonnie!akgua!mcnc!idis!cadre!ry From: ry@cadre.UUCP Newsgroups: net.sources Subject: Netd (Part 1 of 2) Message-ID: <238@cadre.ARPA> Date: Sun, 3-Feb-85 05:08:08 EST Article-I.D.: cadre.238 Posted: Sun Feb 3 05:08:08 1985 Date-Received: Fri, 8-Feb-85 00:38:54 EST Reply-To: ry@cadre.ARPA (Russell J. Yount) Organization: Decision Systems Lab., Univ. of Pgh. Lines: 1975 echo x - addr.c cat > addr.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/addr.c, Jan 19 23:46:24 1985 */ #include#include #include #include #include static char Hex[]="0123456789abcdef"; static PutHex( cpp, h ) char **cpp; unsigned int h; { *(*cpp)++ = Hex[ h & 0xf ]; } static PutHexByte( cpp ,b ) char **cpp; unsigned char b; { PutHex( cpp ,(unsigned int)(b >> 4) ); PutHex( cpp ,(unsigned int)b ); } static PutHexShort( cpp ,s ) char **cpp; unsigned short s; { PutHexByte( cpp ,(unsigned char)(s >> 8) ); PutHexByte( cpp ,(unsigned char)s ); } AddrToString( addr, addrlen, string ) struct sockaddr *addr; int addrlen; char *string; { if (addrlen <= 0) { *string = 0; return; } switch ( addr->sa_family ) { case AF_UNIX: { struct sockaddr_un *un = ( struct sockaddr_un * ) addr; addrlen -= sizeof( u_short ); bcopy( un->sun_path, string, addrlen ); string[ addrlen ] = 0; break; } case AF_INET: { struct sockaddr_in *in = (struct sockaddr_in *) addr; *string++ = '@'; PutHexByte( &string ,in->sin_addr.S_un.S_un_b.s_b4 ); PutHexByte( &string ,in->sin_addr.S_un.S_un_b.s_b3 ); PutHexByte( &string ,in->sin_addr.S_un.S_un_b.s_b2 ); PutHexByte( &string ,in->sin_addr.S_un.S_un_b.s_b1 ); PutHexShort( &string ,in->sin_port ); *string++ = 0; break; } default: { int i; *string++ = '#'; PutHexShort( &string ,addr->sa_family ); for (i = 0; i < 14; i++) PutHexByte( &string ,(unsigned char)addr->sa_data[i] ); *string++ = 0; break; } } } !Magic!Token! echo x - addr2.c cat > addr2.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/addr2.c, Jan 19 23:46:28 1985 */ #include #include #include #include #include StringToAddr2( string, addr, addrlen ) char *string; struct sockaddr *addr; int *addrlen; { bzero( addr ,sizeof( *addr ) ); switch ( string[0] ) { case '*': { struct servent *sp; struct sockaddr_in *in = (struct sockaddr_in *) addr; u_short port; if ( string[1] != '.' ) return -1; if ( sscanf( &string[2], "%hd", &port ) != 1 ) { if ((sp = getservbyname( &string[2], 0 )) == 0 ) return -1; port = sp->s_port; } else port = htons( port ); in->sin_family = AF_INET; in->sin_addr.s_addr = INADDR_ANY; in->sin_port = port; *addrlen = sizeof( struct sockaddr_in ); break; } case '/': { struct sockaddr_un *un = (struct sockaddr_un *) addr; int len = strlen( string ); if ( len > 14) return -1; un->sun_family = AF_UNIX; bcopy( string ,un->sun_path ,len ); *addrlen = len + sizeof(u_short); break; } case '-': *addrlen = 0; break; default: return -1; } return 0; } !Magic!Token! echo x - addr3.c cat > addr3.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/addr3.c, Jan 19 23:46:32 1985 */ #include #include #include #include #include static int GetHex( cpp, hp ) char **cpp; unsigned int *hp; { if (**cpp >= '0' && **cpp <= '9') { *hp = *(*cpp)++ - '0'; return 0; } if (**cpp >= 'a' && **cpp <= 'f') { *hp = (*(*cpp)++ - 'a') + 10; return 0; } return -1; } static int GetHexByte( cpp, bp ) char **cpp; unsigned char *bp; { unsigned int lo, hi; if (GetHex( cpp, &hi ) ) return -1; if (GetHex( cpp, &lo ) ) return -1; *bp = lo + ( hi << 4 ); return 0; } static int GetHexShort( cpp, sp ) char **cpp; unsigned short *sp; { unsigned char lo, hi; if (GetHexByte( cpp, &hi ) ) return -1; if (GetHexByte( cpp, &lo ) ) return -1; *sp = lo + ( hi << 8 ); return 0; } StringToAddr( string ,addr ,addrlen ) char *string; struct sockaddr *addr; int *addrlen; { bzero( addr ,sizeof( *addr ) ); switch (*string++) { case '/': { struct sockaddr_un *un = (struct sockaddr_un *) addr; int len = strlen( --string ); if ( len > 14) return -1; un->sun_family = AF_UNIX; bcopy( string ,un->sun_path ,len ); *addrlen = len + sizeof(u_short); break; } case '@': { struct sockaddr_in *in = (struct sockaddr_in *) addr; in->sin_family = AF_INET; in->sin_addr.s_addr = INADDR_ANY; if (GetHexByte( &string ,&in->sin_addr.S_un.S_un_b.s_b4 ) || GetHexByte( &string ,&in->sin_addr.S_un.S_un_b.s_b3 ) || GetHexByte( &string ,&in->sin_addr.S_un.S_un_b.s_b2 ) || GetHexByte( &string ,&in->sin_addr.S_un.S_un_b.s_b1 ) || GetHexShort( &string ,&in->sin_port )) return -1; *addrlen = sizeof( struct sockaddr_in ); break; } case '#': { int i; if (GetHexShort( &string, &addr->sa_family )) return -1; for (i = 0; i < 14; i++) if (GetHexByte( &string ,(unsigned char *)&addr->sa_data[i] )) return -1; *addrlen = sizeof( struct sockaddr ); break; } case 0: *addrlen = 0; break; default: return -1; } return 0; } !Magic!Token! echo x - addr4.c cat > addr4.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/addr4.c, Jan 19 23:46:36 1985 */ #include #include #include #include #include extern char *sprintf(); AddrToString4( addr, addrlen, string ) struct sockaddr *addr; int addrlen; char *string; { if (addrlen <= 0) { *string = 0; return; } switch ( addr->sa_family ) { case AF_UNIX: { struct sockaddr_un *un = ( struct sockaddr_un * ) addr; addrlen -= sizeof( u_short ); bcopy( un->sun_path, string, addrlen ); string[ addrlen ] = 0; break; } case AF_INET: { struct sockaddr_in *in = (struct sockaddr_in *) addr; struct hostent *hp; hp = gethostbyaddr( &in->sin_addr, sizeof(struct in_addr), in->sin_family ); if (hp == 0) { int i1, i2, i3, i4; i1 = in->sin_addr.S_un.S_un_b.s_b1; i2 = in->sin_addr.S_un.S_un_b.s_b2; i3 = in->sin_addr.S_un.S_un_b.s_b3; i4 = in->sin_addr.S_un.S_un_b.s_b4; (void)sprintf(string,"%d.%d.%d.%d.%hd" ,i1 ,i2 ,i3 ,i4 ,ntohs( in->sin_port )); } else { (void)sprintf( string ,"%s.%hd" ,hp->h_name ,ntohs( in->sin_port )); } break; } default: { *string++ = 'X'; *string = 0; break; } } } !Magic!Token! echo x - conf.c cat > conf.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/conf.c, Jan 19 23:46:39 1985 */ #include #include #include "image.h" #include "disc.h" #include "service.h" extern char *ConfFile; /* * reconfiguration code * call every sighup, and at startup */ SyncSigHup() { Image *im; Service *sv; Disc *di; char *flds[ MAXFLDS + 1 ]; int nf; char msg[256]; LogMsg( "Reconfiguring..." ); if (( im = OpenImage( ConfFile )) == 0 ) { LogMsg( "OpenImage %s failed" ,ConfFile ); return; } ClearActiveDaemons(); while ( nf = ImageToFeilds( im ,flds ,sizeof(flds)/sizeof(flds[0])) ) { if (( sv = MakeService( flds, nf ,msg )) == 0 ) { LogMsg( "%s: %s; %s" ,ConfFile ,flds[0] ,msg ); continue; } if (( di = DiscLookUp( sv->type, sv->af, sv->pf )) == 0 ) { LogMsg( "%s: service %s: unsupported" ,ConfFile ,flds[0] ); FreeService( sv ); continue; } MakeDaemon( di, sv ); } CloseImage( im ); KillNonActiveDaemons(); } SyncSigTerm() { LogMsg( "caught SIGTERM" ); ClearActiveDaemons(); KillNonActiveDaemons(); exit(0); } !Magic!Token! echo x - daemon.c cat > daemon.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/daemon.c, Jan 19 23:46:43 1985 */ #include #include #include "service.h" #include "disc.h" #include "daemon.h" extern char *sprintf(), *malloc(); int Limit; /* initalized by init.c */ static int Active; /* count of active daemons */ static struct { /* must overlay Daemon structure */ Daemon *succ, *pred; } Head = { (Daemon *)&Head, (Daemon *)&Head }; /* * create daemon and attaching service and disc structures */ MakeDaemon( di, sv ) Disc *di; Service *sv; { Daemon *dm; Service *sv2; for ( dm = Head.succ; dm != (Daemon *)&Head; dm = dm->succ ) { if (( dm->flags & D_ZOMBIE ) == D_ZOMBIE ) continue; if ( strcmp( sv->name, dm->service->name ) == 0 ) { sv2 = dm->service; if ( sv->type == sv2->type && sv->af == sv2->af && sv->pf == sv2->pf && sv->addrlen == sv2->addrlen && bcmp( &sv->addr, &sv2->addr, sizeof( sv->addr )) == 0 ) { dm->service = sv; FreeService( sv2 ); dm->flags |= D_ACTIVE; return; } ( *dm->disc->shutdown )( dm ); Active--; sleep( 2 ); /* wait for children to dye */ break; } } if ( Active >= Limit ) { LogMsg( "%s: Over %d services" ,sv->name ,Limit ); return; } if (( dm = (Daemon *) malloc( sizeof( Daemon ))) == 0 ) { LogMsg( "%s: out of memory" ,sv->name ); return; } dm->succ = Head.succ; Head.succ->pred = dm; Head.succ = dm; dm->pred = (Daemon *)&Head; dm->service = sv; dm->disc = di; dm->refer = 0; dm->flags = D_ACTIVE; if ((*di->startup)( dm ) < 0) FreeDaemon( dm ); else Active++; } /* * free daemon and associated service structure */ FreeDaemon( dm ) Daemon *dm; { dm->flags |= D_ZOMBIE; dm->flags &= ~D_ACTIVE; if (dm->refer > 0) return; dm->succ->pred = dm->pred; dm->pred->succ = dm->succ; FreeService( dm->service ); free( (char *)dm ); } ClearActiveDaemons() { Daemon *dm; for ( dm = Head.succ; dm != (Daemon *)&Head; dm = dm->succ ) dm->flags &= ~D_ACTIVE; } KillNonActiveDaemons() { Daemon *dm; for ( dm = Head.succ; dm != (Daemon *)&Head; dm = dm->succ ) if (( dm->flags & D_ACTIVE ) == 0 ) ( *dm->disc->shutdown )( dm ); } !Magic!Token! echo x - dgram.c cat > dgram.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/dgram.c, Jan 19 23:46:47 1985 */ #include #include #include #include #include "service.h" #include "disc.h" #include "daemon.h" #include "syserr.h" typedef caddr_t arg; #ifdef DEBUG extern int Debug; #endif DEBUG int DGramReady(); /*ARGSUSED*/ static DGramSigChild( ar, pid ) arg ar; int pid; { Daemon *dm = (Daemon *) ar; if ( --dm->refer == 0 && ( dm->flags & D_ZOMBIE ) == D_ZOMBIE ) FreeDaemon( dm ); else IWait( dm->fd, DGramReady, (arg)dm ); } /*ARGSUSED*/ static int DGramReady( ar, fd ) arg ar; int fd; { Daemon *dm = (Daemon *) ar; Service *sv = dm->service; int pid; char tmp[64], *args[NARGS], **cpp, **bpp; static char *envp[] = { "DISC=dgram", "ADDR=XXXXXXXXXXXXXXXXXXXXXXXXXX", 0 }; for ( cpp = sv->args, bpp = args; *cpp; ) { if (**cpp != '@') { *bpp++ = *cpp++; continue; } AddrToString4( &sv->addr, sv->addrlen, *bpp++ = tmp ); cpp++; } *bpp = 0; AddrToString( &sv->addr, sv->addrlen, &envp[1][5] ); (void)fcntl( dm->fd, F_SETFD, 0 ); pid = Process( sv ,dm->fd ,args ,envp ); (void)fcntl( dm->fd, F_SETFD, 1 ); if ( pid > 0 ) { dm->refer++; UnIWait( dm->fd ); PWait( pid, DGramSigChild, (arg)dm ); } } DGramStartUp( dm ) Daemon *dm; { Service *sv = dm->service; #ifdef DEBUG if ( Debug ) LogMsg("DGramStartUp; %s" ,sv->name ); #endif DEBUG if (( dm->fd = socket( sv->af ,sv->type ,sv->pf )) < 0 ) { LogMsg( "DGramStartUp; %s socket: %s" ,sv->name ,syserror ); return -1; } #ifndef notdef /* 4.2 feature fix */ { struct stat stb; if ( sv->addr.sa_family == AF_UNIX ) if ( stat( sv->addr.sa_data, &stb ) >= 0 ) if (( stb.st_mode & S_IFMT ) == S_IFSOCK ) (void)unlink( sv->addr.sa_data ); } #endif notdef (void)fcntl( dm->fd ,F_SETFD ,1 ); if ( bind( dm->fd ,&sv->addr ,sv->addrlen ) < 0 ) { LogMsg( "DGramStartUp; %s bind: %s" ,sv->name ,syserror ); (void)close( dm->fd ); return -1; } IWait( dm->fd ,DGramReady ,(arg)dm ); return 0; } DGramShutDown( dm ) Daemon *dm; { #ifdef DEBUG Service *sv = dm->service; if ( Debug ) LogMsg( "DGramShutDown; %s" ,sv->name ); #endif DEBUG UnIWait( dm->fd ); (void)close( dm->fd ); KillProcsUseing( (arg) dm ); FreeDaemon( dm ); } !Magic!Token! echo x - disc.c cat > disc.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/disc.c, Jan 19 23:46:51 1985 */ #include #include #include "disc.h" extern int DGramStartUp() ,DGramShutDown(); extern int StreamStartUp() ,StreamShutDown(); extern int RawStartUp() ,RawShutDown(); #ifdef AF_XNET extern int RawXNetStartUp() ,RawXNetShutDown(); #endif AF_XNET Disc disc[] = { { SOCK_DGRAM ,DISC_WILD ,DISC_WILD ,DGramStartUp ,DGramShutDown } ,{ SOCK_STREAM ,DISC_WILD ,DISC_WILD ,StreamStartUp ,StreamShutDown } #ifdef AF_XNET ,{ SOCK_RAW ,AF_XNET ,DISC_WILD ,RawXNetStartUp ,RawXNetShutDown } #endif AF_XNET ,{ SOCK_STREAM ,DISC_WILD ,DISC_WILD ,RawStartUp ,RawShutDown } ,{ 0 ,0 ,0 ,0 ,0 } }; /* * lookup discipline by socket type, address family and protocal family */ Disc *DiscLookUp( st, af, pf ) int st, af, pf; { Disc *d; for ( d = disc; d->startup != 0; d++ ) if (( d->type == DISC_WILD || d->type == st ) && ( d->af == DISC_WILD || d->af == af ) && ( d->pf == DISC_WILD || d->pf == pf )) break; return d; } !Magic!Token! echo x - disc2.c cat > disc2.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/disc2.c, Jan 19 23:46:54 1985 */ #include #include #include "table.h" Table TableType[] = { { "stream" ,SOCK_STREAM } ,{ "dgram" ,SOCK_DGRAM } ,{ "raw" ,SOCK_RAW } ,{ 0 ,0 } }; Table TableAF[] = { { "unix" ,AF_UNIX } ,{ "inet" ,AF_INET } #ifdef AF_XNET ,{ "xnet" ,AF_XNET } #endif AF_XNET ,{ 0 ,0 } }; Table TablePF[] = { { "unspec" ,PF_UNSPEC } ,{ 0 ,0 } }; !Magic!Token! echo x - image.c cat > image.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/image.c, Jan 19 23:46:58 1985 */ #include #include #include #include "image.h" extern char *malloc(); Image *OpenImage( file ) char *file; { struct stat stb; int fd; Image *im; if (( fd = open( file, O_RDONLY ,0 )) < 0 ) return 0; if ( fstat( fd, &stb ) < 0 ) return 0; if ((im = (Image *) malloc((unsigned)(sizeof(Image)+stb.st_size))) == 0 ) { (void)close( fd ); return 0; } if (( im->length = read( fd ,im->buffer ,stb.st_size )) < 0 ) { free( (char *) im ); (void)close( fd ); return 0; } (void)close( fd ); im->buffer[ im->length ] = 0; im->pointer = im->buffer; return im; } CloseImage( im ) Image *im; { free( (char *) im ); } int ImageToFeilds( im ,flds ,nfld ) Image *im; char **flds; int nfld; { int n = 0; char *cp = im->pointer; for ( ;; ) { while ( *cp == ' ' || *cp == '\t' ) *cp++ = 0; if ( *cp == '#' ) { *cp++ = 0; while ( *cp && *cp++ != '\n' ); if ( n != 0 ) break; continue; } if ( *cp == 0 ) break; if ( *cp == '\n' ) { *cp++ = 0; if ( n != 0 ) break; continue; } if ( n >= nfld ) { *cp++ = 0; while ( *cp && *cp++ != '\n' ); break; } flds[ n++ ] = cp; while ( *cp != 0 && *cp != ' ' && *cp != '#' && *cp != '\t' & *cp != '\n' ) cp++; } im->pointer = cp; return n; } !Magic!Token! echo x - init.c cat > init.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/init.c, Jan 19 23:47:02 1985 */ #include #include #include #include #include #include #include "syserr.h" extern long lseek(); extern char *strcpy(); extern char *LogDir ,*Name ,*LogFile, *ExecDir; extern int LogFd, KeepStderr ,KeepTTy ,LogShare, NoDate, Uid, Gid; extern int Limit; /* * append message to log file */ #ifdef lint /*VARARGS0*/ /*ARGSUSED*/ LogMsg( format ) char *format; #else lint LogMsg( va_alist ) va_dcl #endif lint { va_list args; char *fmt, buf[1024]; /* blow away if line is bigger than buf */ struct _iobuf _str; #ifdef lint args = (va_list)0; #else lint va_start( args ); #endif lint fmt = va_arg( args, char *); _str._flag = _IOWRT+_IOSTRG; _str._ptr = buf; _str._cnt = sizeof( buf ); if (!NoDate) { struct tm *tp; struct timeval tv; struct timezone tz; (void)gettimeofday( &tv, &tz ); tp = localtime( (time_t *)&tv.tv_sec ); fprintf( &_str ,"%02d/%02d %02d:%02d:%02d " ,tp->tm_mon + 1 ,tp->tm_mday ,tp->tm_hour ,tp->tm_min ,tp->tm_sec ); } fprintf( &_str, "%s: ", Name ); (void)_doprnt( fmt, args, &_str ); va_end( args ); *_str._ptr++ = '\n'; if ( LogShare ) { (void)flock( LogFd, LOCK_EX ); (void)lseek( LogFd, 0L, L_XTND ); } (void)write( LogFd, buf, _str._ptr - buf ); if ( LogShare ) (void)flock( LogFd, LOCK_UN ); } /* * initalization - open LogFile, create background */ Init() { int fd, topfd, pid; char logpath[128]; /* close all but log descriptor */ topfd = getdtablesize() - 1; Limit = topfd - 1; /* for daemon.c */ for ( fd = topfd; fd >= 0; --fd) if (fd != LogFd) (void)close( fd ); /* change directory to our exec directory */ if ( chdir( ExecDir ) < 0 ) { LogMsg( "chdir %s; %s" ,ExecDir ,syserror ); exit( 10 ); } /* open LogFd as highest desc */ if (!KeepStderr) { if ( *LogDir ) (void)sprintf( logpath ,"%s/%s" ,LogDir ,LogFile ); else (void)strcpy( logpath, LogFile ); fd = open( logpath, O_WRONLY|O_APPEND ); if ( fd < 0 ) { fd = open( logpath, O_WRONLY|O_CREAT, LogShare ? 0660 : 0600 ); if ( fd < 0 ) { LogMsg( "open %s %s" ,logpath, syserror ); exit(3); } } (void)close( LogFd ); LogFd = fd; } fd = fcntl( LogFd ,F_DUPFD ,topfd ); if (fd < 0) { LogMsg( "dup %s %s" ,KeepStderr ?"(stderr)":logpath ,syserror); exit(4); } (void)close( LogFd ); LogFd = fd; /* set close-on-exec flag for log desc */ (void)fcntl( LogFd ,F_SETFD ,1 ); if (!KeepTTy) { /* fork(), parent exits/child continues */ pid = fork(); if ( pid < 0 ) { LogMsg( "fork failed %s" ,syserror ); exit( 5 ); } if ( pid != 0 ) { exit( 0 ); } /* dissassociate from tty */ fd = open( "/dev/tty" ,O_RDWR ,0 ); if ( fd >= 0 ) { (void)ioctl( fd ,(int)TIOCNOTTY ,(char *)0 ); (void)close( fd ); } } Uid = getuid(); Gid = getgid(); } !Magic!Token! echo x - libmain.c cat > libmain.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/libmain.c, Jan 19 23:47:05 1985 */ #include #include #include #ifndef lint static char Version[] = "Netd 1.0, Copyright (c) 1985, Russell J. Yount" ; #endif main( argc ,argv ) int argc; char **argv; { struct sockaddr addr; int addrlen; char *string, *getenv(); if (( string = getenv("ADDR")) == 0 ) { fprintf( stderr ,"%s: getenv ADDR\n" ,argv[0] ); exit( 126 ); } if ( StringToAddr( string, &addr, &addrlen )) { fprintf( stderr ,"%s: ???? ADDR=%s\n" ,argv[0] , string ); exit( 127 ); } doit( argc ,argv ,&addr ,addrlen ); exit( 0 ); } !Magic!Token! echo x - main.c cat > main.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/main.c, Jan 19 23:47:09 1985 */ #ifndef lint static char Version[] = "Netd 1.0, Copyright (c) 1985, Russell J. Yount" ; #endif /* * Copyright (c) 1985, Russell J. Yount, All rights reserved. * Permission for distribution is granted provided no direct commercial * advantage is gained and that this copyright notice and authors address * appears on all copies. * * Russell J. Yount * (412) 624-3490 * Decision Systems Laboratory, University of Pittsburgh * ry@cadre.arpa * {decvax!idis,mi-cec,pitt,vax135,akgua,cmcl2,sun}!cadre!ry */ main( argc ,argv ) int argc; char **argv; { char *cp; while ( --argc > 0 ) { ++argv; if ( argv[0][0] != '-' ) Usage(); for ( cp = &argv[0][1]; *cp; cp++ ) { if ( SetBOption( *cp ,1 )) continue; if ( --argc > 0 && SetSOption( *cp ,*++argv )) continue; Usage(); } } Init(); LogMsg( "startup" ); Mplx(); LogMsg( "done main" ); exit( 0 ); } !Magic!Token! echo x - mplx.c cat > mplx.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/mplx.c, Jan 19 23:47:13 1985 */ #include #include #include #include #include #include #include "syserr.h" #ifdef DEBUG extern int Debug; #endif DEBUG #define PROCESS #define SELECT #define ISELECT /* #define OSELECT */ /* #define ESELECT */ typedef int ret; typedef caddr_t arg; #ifdef PROCESS static struct { int pid; ret (*func)(); arg argm; } PSlot[ 256 ]; #endif PROCESS #ifdef SELECT static struct { struct { ret (*func)(); arg argm; } inp ,out ,exc; } DSel[ 20 ]; static struct { int inp ,out ,exc; } DTest ,DReady; int NDTest ,NDReady; int DChange; #endif SELECT int CaughtSigChild ,CaughtSigTerm ,CaughtSigHup; #ifdef ISELECT IWait( d ,f ,a ) int d; ret (*f)(); arg a; { #ifdef DEBUG if ( Debug ) LogMsg( "IWait %d" ,d ); #endif DEBUG DTest.inp |= ( 1 << d ); DSel[ d ].inp.func = f; DSel[ d ].inp.argm = a; DChange++; } UnIWait( d ) int d; { #ifdef DEBUG if ( Debug ) LogMsg( "IUnWait %d" ,d ); #endif DEBUG DTest.inp &= ~( 1 << d ); DChange++; } #endif ISELECT #ifdef OSELECT OWait( d ,f ,a ) int d; ret (*f)(); arg a; { DTest.out |= ( 1 << d ); DSel[ d ].out.func = f; DSel[ d ].out.argm = a; DChange++; } UnOWait( d ) int d; { DTest.out &= ~( 1 << d ); DChange++; } #endif OSELECT #ifdef ESELECT EWait( d ,f ,a ) int d; ret (*f)(); arg a; { DTest.exc |= ( 1 << d ); DSel[ d ].exc.func = f; DSel[ d ].exc.argm = a; DChange++; } UnEWait( d ) int d; { DTest.exc &= ~( 1 << d ); DChange++; } #endif ESELECT #ifdef PROCESS #ifdef UNPROCESS UnPWait( p ) int p; { int hv ,sv; hv = p % ( sizeof( PSlot ) / sizeof( PSlot[0] )); if ( PSlot[ hv ].pid != 0 ) for ( sv = hv--; sv != hv; hv-- ) if ( PSlot[ hv ].pid == 0 ) break; PSlot[ hv ].pid = 0; } #endif UNPROCESS PWait( p ,f ,a ) int p; ret (*f)(); arg a; { int hv ,sv; hv = p % ( sizeof( PSlot ) / sizeof( PSlot[0] )); if ( PSlot[ hv ].pid != 0 ) for ( sv = hv--; sv != hv; hv-- ) if ( PSlot[ hv ].pid == 0 ) break; PSlot[ hv ].pid = p; PSlot[ hv ].func = f; PSlot[ hv ].argm = a; } KillProcsUseing( a ) arg a; { int sn; for (sn = 0; sn < ( sizeof( PSlot ) / sizeof( PSlot[0] )); sn++) if ( PSlot[ sn ].pid != 0 && PSlot[ sn ].argm == a ) (void)kill( PSlot[ sn ].pid, SIGTERM ); } #endif PROCESS static SigHup() { CaughtSigHup++; } static SigChild() { CaughtSigChild++; } static SigTerm() { CaughtSigTerm++; } Mplx() { int sblk; #ifdef SELECT int fd, msk; #endif SELECT #ifdef PROCESS union wait status; int hv ,sv ,pid; #endif PROCESS (void)signal( SIGHUP, SigHup ); (void)signal( SIGCHLD, SigChild ); (void)signal( SIGTERM, SigTerm ); CaughtSigHup++; for ( ;; ) { if ( CaughtSigHup ) { CaughtSigHup = 0; SyncSigHup(); continue; } if ( CaughtSigTerm ) { #ifdef DEBUG if ( Debug ) LogMsg("mplx; caught sigterm"); #endif DEBUG CaughtSigTerm = 0; SyncSigTerm(); continue; } if ( CaughtSigChild ) { #ifdef DEBUG if ( Debug ) LogMsg("mplx; caught sigchild"); #endif DEBUG CaughtSigChild = 0; while ((pid = wait3( &status ,WNOHANG ,(struct rusage *)0))>0) { #ifdef PROCESS hv = pid % ( sizeof( PSlot ) / sizeof( PSlot[0] )); if ( PSlot[ hv ].pid != pid ) for ( sv = hv--; sv != hv; hv-- ) if ( PSlot[ hv ].pid == pid ) break; ( *PSlot[ hv ].func )( PSlot[ hv ].argm ,pid ); PSlot[ hv ].pid = 0; #endif PROCESS } continue; } #ifdef SELECT if ( DChange ) { msk = DTest.inp | DTest.out | DTest.exc; for ( NDTest = 0; msk; NDTest++ ) msk >>= 1; DChange = 0; #ifdef DEBUG if ( Debug ) LogMsg( "mplx; DChanged; NDTest = %d", NDTest); #endif DEBUG } #ifdef DEBUG if ( Debug ) LogMsg( "mplx; DTest= %x,%x,%x", DTest.inp, DTest.out, DTest.exc ); #endif DEBUG if ( NDTest == 0 ) { #ifdef DEBUG if ( Debug ) LogMsg("mplx; pause"); #endif DEBUG sigpause( 0 ); continue; } DReady = DTest; NDReady = select( NDTest ,&DReady.inp ,&DReady.out ,&DReady.exc ,(struct timeval *)0 ); if ( NDReady < 0 ) { if ( errno == EINTR ) continue; LogMsg( "select %s" ,syserror ); LogMsg( "aborting...." ); exit( 0 ); } #ifdef DEBUG if ( Debug ) LogMsg( "mplx; %d selected" ,NDReady ); #endif DEBUG sblk = sigblock((1<<(SIGCHLD-1)) | (1<<(SIGHUP-1)) | (1<<(SIGTERM-1))); # ifdef ISELECT for ( fd = 0; DReady.inp; fd++ ,DReady.inp >>= 1 ) if ( DReady.inp & 1 ) ( *DSel[ fd ].inp.func )( DSel[ fd ].inp.argm ,fd ); # endif ISELECT # ifdef OSELECT for ( fd = 0; DReady.out; fd++ ,DReady.out >>= 1 ) if ( DReady.out & 1 ) ( *DSel[ fd ].out.func )( DSel[ fd ].out.argm ,fd ); # endif OSELECT # ifdef ESELECT for ( fd = 0; DReady.exc; fd++ ,DReady.exc >>= 1 ) if ( DReady.exc & 1 ) ( *DSel[ fd ].exc.func )( DSel[ fd ].exc.argm ,fd ); # endif ESELECT (void)sigsetmask( sblk ); #endif SELECT } } !Magic!Token! echo x - option.c cat > option.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/option.c, Jan 19 23:47:16 1985 */ #ifdef lint # ifndef EXECDIR # define EXECDIR "/usr/lib/netd" # endif EXECDIR # ifndef LOGDIR # define LOGDIR "/usr/adm" # endif LOGDIR # ifndef LOGFILE # define LOGFILE "netd.log" # endif LOGFILE # ifndef CONFFILE # define CONFFILE "/etc/daemons" # endif CONFFILE # ifndef NAME # define NAME "netd" # endif NAME #endif lint char *ExecDir = EXECDIR; char *LogDir = LOGDIR; char *LogFile = LOGFILE; char *Name = NAME; char *ConfFile = CONFFILE; int LogFd = 2; /* fileno( stderr ) */ int LogShare; int KeepStderr; int KeepTTy; int NoDate; #ifdef DEBUG int Debug; /* global */ #endif DEBUG extern char *sprintf(); static struct { char flag; int *value; } BOpt[] = { { 'e' ,&KeepStderr } #ifdef DEBUG ,{ 'x' ,&Debug } #endif DEBUG ,{ 't' ,&KeepTTy } ,{ 's' ,&LogShare } ,{ 'n' ,&NoDate } ,{ 0 , 0 } }; static struct { char flag; char **value; char *name; } SOpt[] = { { 'd' ,&ExecDir ,"execdir" } ,{ 'm' ,&LogDir ,"logdir" } ,{ 'l' ,&LogFile ,"logfile" } ,{ 'c' ,&ConfFile ,"conffile" } ,{ 'p' ,&Name ,"logname" } ,{ 0 , 0 } }; Usage() { int i; char buf[128], *cp; cp = buf; (void)sprintf( cp, "Usage: %s ", Name ); cp += strlen( buf ); if ( BOpt[0].flag ) { (void)sprintf( cp ,"[ -" ); cp += 3; for ( i = 0; BOpt[i].flag; i++ ) *cp++ = BOpt[i].flag; (void)sprintf( cp ," ]" ); cp += 2; } for (i = 0; SOpt[i].flag; i++) { (void)sprintf( cp, " [ -%c %s ]", SOpt[i].flag ,SOpt[i].name ); cp = buf + strlen( buf ); } *cp++ = '\n'; (void)write( LogFd, buf, cp - buf ); exit( 127 ); } SetBOption( nm, va ) char nm; int va; { int i; for (i = 0; BOpt[i].flag; i++) if (BOpt[i].flag == nm) { *BOpt[i].value = va; return 1; } return 0; } SetSOption( nm, va ) char nm, *va; { int i; for ( i = 0; SOpt[i].flag; i++ ) if ( SOpt[i].flag == nm ) { *SOpt[i].value = va; return 1; } return 0; } !Magic!Token! echo x - proc.c cat > proc.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/proc.c, Jan 19 23:47:20 1985 */ #include #include #include #include #include "service.h" typedef caddr_t arg; #ifdef DEBUG extern int Debug; #endif DEBUG extern int LogFd; extern int KeepStderr; int Uid, Gid; /* filled in by init() */ int Process( sv ,fd ,args ,envp ) Service *sv; int fd; char **args; char **envp; { int pid, fd2; #ifdef DEBUG if ( Debug ) LogMsg("Process %s",sv->prog); #endif DEBUG if (( pid = vfork()) != 0 ) return pid; (void)sigsetmask( 0 ); if ( fd != 0 ) { (void)close( 0 ); (void)fcntl( fd ,F_DUPFD ,0 ); (void)close( fd ); } (void)close( 1 ); (void)close( 2 ); (void)dup2( 0 ,1 ); switch ( *sv->log ) { case '-': /* throw away output */ fd = open( "/dev/null", O_WRONLY|O_APPEND ); break; case '+': /* append our logfile */ fd = LogFd; (void)fcntl( LogFd ,F_SETFD ,0 ); if ( KeepStderr ) { fd2 = open( "/dev/tty" ,O_RDWR ,0 ); if ( fd2 >= 0 ) { (void)ioctl( fd2 ,(int)TIOCNOTTY ,(char *)0 ); (void)close( fd2 ); } } break; default: /* open logfile */ fd = open( sv->log, O_WRONLY|O_APPEND ); if (fd < 0 ) { LogMsg( "Can't open %s", sv->log ); fd = open( "/dev/null", O_WRONLY ); } break; } if ( fd != 2 ) { (void)dup2( fd ,2 ); (void)close( fd ); } if ( sv->nice ) (void)nice( sv->nice ); if ( sv->uid != Uid ) (void)setuid( sv->uid ); if ( sv->gid != Gid ) (void)setgid( sv->gid ); execve( sv->prog ,args ,envp ); LogMsg( "Child exec failed %s" ,sv->prog ); sleep( 2 ); _exit( 127 ); /*NOTREACHED*/ } !Magic!Token! echo x - raw.c cat > raw.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/raw.c, Jan 19 23:47:23 1985 */ #include #include #include #include #include "service.h" #include "disc.h" #include "daemon.h" #include "syserr.h" typedef caddr_t arg; #ifdef DEBUG extern int Debug; #endif DEBUG int RawReady(); /*ARGSUSED*/ static RawSigChild( ar, pid ) arg ar; int pid; { Daemon *dm = (Daemon *) ar; if ( --dm->refer == 0 && ( dm->flags & D_ZOMBIE ) == D_ZOMBIE ) FreeDaemon( dm ); else IWait( dm->fd, RawReady, (arg)dm ); } /*ARGSUSED*/ static int RawReady( ar, fd ) arg ar; int fd; { Daemon *dm = (Daemon *) ar; Service *sv = dm->service; int pid; char tmp[64], *args[NARGS], **cpp, **bpp; static char *envp[] = { "DISC=dgram", "ADDR=XXXXXXXXXXXXXXXXXXXXXXXXXX", 0 }; for ( cpp = sv->args, bpp = args; *cpp; ) { if (**cpp != '@') { *bpp++ = *cpp++; continue; } AddrToString4( &sv->addr, sv->addrlen, *bpp++ = tmp ); cpp++; } *bpp = 0; AddrToString( &sv->addr, sv->addrlen, &envp[1][5] ); (void)fcntl( dm->fd, F_SETFD, 0 ); pid = Process( sv ,dm->fd ,args ,envp ); (void)fcntl( dm->fd, F_SETFD, 1 ); if ( pid > 0 ) { dm->refer++; UnIWait( dm->fd ); PWait( pid, RawSigChild, (arg)dm ); } } RawStartUp( dm ) Daemon *dm; { Service *sv = dm->service; #ifdef DEBUG if ( Debug ) LogMsg("RawStartUp; %s" ,sv->name ); #endif DEBUG if (( dm->fd = socket( sv->af ,sv->type ,sv->pf )) < 0 ) { LogMsg( "RawStartUp; %s socket: %s" ,sv->name ,syserror ); return -1; } #ifndef notdef /* 4.2 feature fix */ if (sv->addrlen > 2) { struct stat stb; if ( sv->addr.sa_family == AF_UNIX ) if ( stat( sv->addr.sa_data, &stb ) >= 0 ) if (( stb.st_mode & S_IFMT ) == S_IFSOCK ) (void)unlink( sv->addr.sa_data ); } #endif notdef (void)fcntl( dm->fd ,F_SETFD ,1 ); if ( sv->addrlen > 2 && bind( dm->fd ,&sv->addr ,sv->addrlen ) < 0 ) { LogMsg( "RawStartUp; %s bind: %s" ,sv->name ,syserror ); (void)close( dm->fd ); return -1; } IWait( dm->fd ,RawReady ,(arg)dm ); return 0; } RawShutDown( dm ) Daemon *dm; { #ifdef DEBUG Service *sv = dm->service; if ( Debug ) LogMsg( "RawShutDown; %s" ,sv->name ); #endif DEBUG UnIWait( dm->fd ); (void)close( dm->fd ); KillProcsUseing( (arg) dm ); FreeDaemon( dm ); } !Magic!Token! echo x - service.c cat > service.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/service.c, Jan 19 23:47:27 1985 */ #include #include #include #include #include #include "service.h" #include "table.h" #include "disc2.h" extern char *malloc(), *sprintf(), *rindex(); extern char *LogDir; Service *MakeService( flds ,nflds ,msg ) char **flds; int nflds; char *msg; { Service *sv; struct passwd *pw; struct group *gr; struct stat stb; char *bp ,*cp, *sp, *pp, *dp, tmp[256]; int cc ,i ,j; if ( nflds < MINFLDS || nflds > MAXFLDS ) { (void)sprintf( msg, "syntax error" ); return 0; } if (( sv = (Service *) malloc( sizeof( Service ))) == 0 ) { (void)sprintf( msg, "out of memory" ); return 0; } cp = sv->strings; cc = sizeof( sv->strings ); bp = flds[0]; sv->name = cp; do { if ( cc-- <= 0 ) { (void)sprintf( msg, "out of string space" ); free((char *)sv); return 0; } } while (*cp++ = *bp++); sv->log = cp; if ( flds[8][0] == '-' || flds[8][0] == '+' ) { bp = flds[8]; } else { bp = dp = tmp; if ( flds[8][0] != '/' && *LogDir ) { for (sp = LogDir; *sp ; *dp++ = *sp++); *dp++ = '/'; } for (sp = flds[8]; *sp ; sp++ ) if ( *sp == '$' ) for ( pp = flds[0]; *pp; *dp++ = *pp++); else *dp++ = *sp; *dp++ = 0; } do { if ( cc-- <= 0 ) { (void)sprintf( msg, "out of string space" ); free((char *)sv); return 0; } } while (*cp++ = *bp++); if (( sv->type = TableLookUp( TableType ,flds[1] )) < 0 ) { (void)sprintf( msg, "unsupported type %s" ,flds[1] ); free((char *)sv); return 0; } if (( sv->af = TableLookUp( TableAF ,flds[2] )) < 0 ) { (void)sprintf( msg, "unsupported af %s" ,flds[2] ); free((char *)sv); return 0; } if (( sv->pf = TableLookUp( TablePF ,flds[3] )) < 0 ) { (void)sprintf( msg, "unsupported pf %s" ,flds[3] ); free((char *)sv); return 0; } if ( StringToAddr2( flds[4], &sv->addr, &sv->addrlen )) { (void)sprintf( msg, "address format error %s", flds[4] ); free((char *)sv); return 0; } for ( i = 0, j = 9; j < nflds; j++, i++ ) { sv->args[ i ] = cp; bp = flds[ j ]; do { if ( cc-- <= 0 ) { (void)sprintf( msg, "out of string space" ); free((char *)sv); return 0; } } while (*cp++ = *bp++); } sv->args[ i ] = 0; sv->prog = sv->args[ 0 ]; cp = rindex( sv->args[ 0 ] ,'/' ); if ( cp ) sv->args[ 0 ] = cp + 1; if ( sscanf( flds[7] ,"%hd" ,&sv->nice ) != 1 || sv->nice > 20 || sv->nice < -20 ) { (void)sprintf( msg, "invalid nice %s" ,flds[7] ); free((char *)sv); return 0; } if ( stat( sv->prog, &stb ) < 0 ) { (void)sprintf( msg, "program does not exist" ); free((char *)sv); return 0; } if (( stb.st_mode & S_IEXEC ) == 0 ) { (void)sprintf( msg, "program is not executable" ); free((char *)sv); return 0; } if ( strcmp( flds[6], "-" ) == 0 ) sv->gid = stb.st_gid; else if ( sscanf( flds[6], "%hd", &sv->gid ) != 1 ) { if (( gr = getgrnam( flds[6] )) == 0 ) { (void)sprintf( msg, "unknown group %s" ,flds[6] ); free((char *)sv); return 0; } sv->gid = gr->gr_gid; } if ( strcmp( flds[5], "-" ) == 0 ) sv->uid = stb.st_uid; else if ( sscanf( flds[5], "%hd", &sv->uid ) != 1 ) { if (( pw = getpwnam( flds[5] )) == 0 ) { (void)sprintf( msg, "unknown user %s" , flds[5] ); free((char *)sv); return 0; } sv->uid = pw->pw_uid; } return sv; } FreeService( sv ) Service *sv; { free((char *) sv ); } !Magic!Token! echo x - stream.c cat > stream.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/stream.c, Jan 19 23:47:31 1985 */ #include #include #include #include #include "service.h" #include "disc.h" #include "daemon.h" #include "syserr.h" typedef caddr_t arg; #ifdef DEBUG extern int Debug; #endif DEBUG /*ARGSUSED*/ static StreamSigChild( ar, pid ) arg ar; int pid; { Daemon *dm = (Daemon *) ar; #ifdef DEBUG if ( Debug ) LogMsg("Stream sigchild"); #endif DEBUG if ( --dm->refer < 0 && ( dm->flags & D_ZOMBIE ) == D_ZOMBIE ) FreeDaemon( dm ); /* NOP */ } /*ARGSUSED*/ static StreamAccept( ar, fd ) arg ar; int fd; { Daemon *dm = (Daemon *) ar; Service *sv = dm->service; int fd2, pid; struct sockaddr from; int fromlen = sizeof( from ); char tmp[64], *args[NARGS], **cpp, **bpp; static char *envp[] = { "DISC=stream","ADDR=XXXXXXXXXXXXXXXXXXXXXXXXX", 0 }; #ifdef DEBUG if ( Debug ) LogMsg("Stream accept"); #endif DEBUG if (( fd2 = accept( dm->fd, &from, &fromlen )) < 0 ) { LogMsg( "StreamAccept; %s accept %s" ,sv->name ,syserror ); return; } for ( cpp = sv->args, bpp = args; *cpp; ) { if (**cpp != '@') { *bpp++ = *cpp++; continue; } AddrToString4( &from, fromlen, *bpp++ = tmp ); cpp++; } *bpp = 0; AddrToString( &from, fromlen, &envp[1][5] ); pid = Process( sv, fd2 ,args ,envp ); (void)close( fd2 ); if ( pid > 0 ) { dm->refer++; PWait( pid, StreamSigChild, (arg)dm ); } } StreamStartUp( dm ) Daemon *dm; { Service *sv = dm->service; #ifdef DEBUG if ( Debug ) LogMsg("StreamStartUp; %s" ,sv->name ); #endif DEBUG if (( dm->fd = socket( sv->af ,sv->type ,sv->pf )) < 0 ) { LogMsg( "StreamStartUp; %s socket: %s" ,sv->name ,syserror ); return -1; } #ifndef notdef /* 4.2 feature fix */ { struct stat stb; if ( sv->addr.sa_family == AF_UNIX ) if ( stat( sv->addr.sa_data, &stb ) >= 0 ) if (( stb.st_mode & S_IFMT ) == S_IFSOCK ) (void)unlink( sv->addr.sa_data ); } #endif notdef (void)fcntl( dm->fd ,F_SETFD ,1 ); if ( bind( dm->fd ,&sv->addr ,sv->addrlen ) < 0 ) { LogMsg( "StreamStartUp; %s bind: %s" ,sv->name ,syserror ); (void)close( dm->fd ); return -1; } if ( listen( dm->fd ,SOMAXCONN ) < 0 ) { LogMsg( "StreamStartUp; %s listen: %s" ,sv->name ,syserror ); (void)close( dm->fd ); return -1; } IWait( dm->fd ,StreamAccept ,(arg)dm ); return 0; } StreamShutDown( dm ) Daemon *dm; { #ifdef DEBUG Service *sv = dm->service; if ( Debug ) LogMsg( "StreamShutDown; %s" ,sv->name ); #endif DEBUG UnIWait( dm->fd ); (void)close( dm->fd ); FreeDaemon( dm ); } !Magic!Token! echo x - table.c cat > table.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/table.c, Jan 19 23:47:34 1985 */ #include "table.h" int TableLookUp( tp, nm ) Table *tp; char *nm; { while ( tp->name ) { if ( strcmp( tp->name, nm ) == 0 ) return tp->value; tp++; } /* return -1; */ return atoi( nm ); /* permit integer use also */ } !Magic!Token! echo x - xnet.c cat > xnet.c << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/xnet.c, Jan 19 23:47:38 1985 */ #include #include #include #include #include "service.h" #include "disc.h" #include "daemon.h" #include "syserr.h" /*VARARGS0*/ LogMsg(); #ifdef AF_XNET typedef caddr_t arg; #ifdef DEBUG extern int Debug; #endif DEBUG int RawXNetReady(); /*ARGSUSED*/ static RawXNetSigChild( ar, pid ) arg ar; int pid; { Daemon *dm = (Daemon *) ar; if ( --dm->refer == 0 && ( dm->flags & D_ZOMBIE ) == D_ZOMBIE ) FreeDaemon( dm ); else IWait( dm->fd, RawXNetReady, (arg)dm ); } /*ARGSUSED*/ static int RawXNetReady( ar, fd ) arg ar; int fd; { Daemon *dm = (Daemon *) ar; Service *sv = dm->service; int pid; char tmp[64], *args[NARGS], **cpp, **bpp; static char *envp[] = { "DISC=rxnet", "ADDR=XXXXXXXXXXXXXXXXXXXXXXXXXX", 0 }; for ( cpp = sv->args, bpp = args; *cpp; ) { if (**cpp != '@') { *bpp++ = *cpp++; continue; } AddrToString4( &sv->addr, sv->addrlen, *bpp++ = tmp ); cpp++; } *bpp = 0; AddrToString( &sv->addr, sv->addrlen, &envp[1][5] ); (void)fcntl( dm->fd, F_SETFD, 0 ); pid = Process( sv ,dm->fd ,args ,envp ); (void)fcntl( dm->fd, F_SETFD, 1 ); if ( pid > 0 ) { dm->refer++; UnIWait( dm->fd ); PWait( pid, RawXNetSigChild, (arg)dm ); } } RawXNetStartUp( dm ) Daemon *dm; { Service *sv = dm->service; #ifdef DEBUG if ( Debug ) LogMsg("RawXNetStartUp; %s" ,sv->name ); #endif DEBUG if (( dm->fd = socket( sv->af ,sv->type ,sv->pf )) < 0 ) { LogMsg( "RawXNetStartUp; %s socket: %s" ,sv->name ,syserror ); return -1; } (void)fcntl( dm->fd ,F_SETFD ,1 ); IWait( dm->fd ,RawXNetReady ,(arg)dm ); return 0; } RawXNetShutDown( dm ) Daemon *dm; { #ifdef DEBUG Service *sv = dm->service; if ( Debug ) LogMsg( "RawXNetShutDown; %s" ,sv->name ); #endif DEBUG UnIWait( dm->fd ); (void)close( dm->fd ); KillProcsUseing( (arg) dm ); FreeDaemon( dm ); } #endif AF_XNET !Magic!Token!