Netd (Part 1 of 2)

ry at cadre.UUCP ry at cadre.UUCP
Sun Feb 3 20:08:08 AEST 1985


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 <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>


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 <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>


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 <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>


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 <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>

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 <sys/types.h>
#include <sys/socket.h>
#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 <sys/types.h>
#include <sys/socket.h>
#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 <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/stat.h>
#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 <sys/types.h>
#include <sys/socket.h>
#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 <sys/types.h>
#include <sys/socket.h>
#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 <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#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 <stdio.h>
#include <varargs.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#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 <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>

#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 at 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 <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#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 <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#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 <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/stat.h>
#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 <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <pwd.h>
#include <grp.h>
#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 <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/stat.h>
#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 <sys/types.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/stat.h>
#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!



More information about the Comp.sources.unix mailing list