ry@cadre.UUCP (02/03/85)
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@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!
ry@cadre.UUCP (02/03/85)
echo x - daemons.5l.man cat > daemons.5l.man << '!Magic!Token!' .TH DAEMONS 5l "15 January 1985" .CA 4 .SH NAME daemons \- netd daemon data base .SH DESCRIPTION The .I daemons file contains information regarding the known services which are handled by the .I netd server. For each service a single line should be present with the following information: .HP 10 official service name .br .ns .HP 10 socket type .br .ns .HP 10 address family .br .ns .HP 10 protocol family .br .ns .HP 10 address .br .ns .HP 10 user .br .ns .HP 10 group .br .ns .HP 10 nice .br .ns .HP 10 log file name .br .ns .HP 10 program .br .ns .HP 10 optional arguments .br .PP The .I service name is a unique name for the service. .I Socket type , .I address family , and .I protocol family are used when creating socket for service. The .I address differs depending on .I address family and .I socket type. It can be given as a '-' when an address is not needed. Both the .I user and .I group can be short integers or names such as found in /etc/passwd or /etc/group or a '-' which uses translates to programs ownership and group membership and determine the actual .B uid and .B gid under which the program will be executed. .I Nice is the integer nice ( see .I setpriority(2) ) value at which the program will be executed. The .I log file may also be specified as a '-' for /dev/null, an '+' to append .I netd's log file, or may contain a '$' which will have the service name substituted for it. An '@' in the optional arguments is substituted with the address to which the socket is bound, in printable form. .SH EXAMPLES .PP Here are a few lines from a sample configuration file: .PP .nf .na .ta 0.5i # INTERNET SERVICES # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # ---- ------ ---- ------ ------- --- --- ---- --- ------- exec stream inet unspec *.exec root daemon 0 - rexecd @ login stream inet unspec *.login root daemon 0 - rlogind @ syslog dgram inet unspec *.syslog root daemon 0 $.log syslog .fi .ad .SH FILES %CONFFILE .SH "SEE ALSO" netd(8l), passwd(5), group(5), services(5) .SH AUTHOR Russell J. Yount .SH BUGS !Magic!Token! echo x - netd.8l.man cat > netd.8l.man << '!Magic!Token!' .TH NETD 8L "8 January 1985" .CA 4 .SH NAME netd \- network daemon server .SH SYNOPSIS .B netd [ .B \-extsn ] [ .B \-l .I logfile ] [ .B \-m .I logdir ] .br .B netd [ .B \-d .I execdir ] [ .B \-c .I conffile ] [ .B \-p .I logname ] .br .SH DESCRIPTION .I Netd is a generic daemon server through which specific service daemons are invoked as needed. Incoming requests for service are intercepted by .I netd which creates a process and passes the appropriate parameters to that process. One or more .I netd's are started by either .I /etc/rc or .I /etc/rc.local at boot time. .I Netd reads a configuration file (the default is .I /etc/deamons ) to determine the priority, process and user groups, and logs activity of the specific service invoked. Programs started by .I netd will have stdin and stdout attached to the socket and stderr attached to the service's logfile. In its environment, the variable .B DISC will be set to the services .I netd discipline and .B ADDR will be set to the address of the socket. .PP When .I netd receives a SIGHUP signal it rereads the configuration file and reconfigures. When .I Netd receives a SIGTERM signal it exits. .PP The following options are available. .IP \-c specify configuration file .IP \-d specify server directory .IP \-e log to .I stderr .IP \-l specify log file name .IP \-m specify log file directory .IP \-n do not date logfile entries .IP \-p specify program name to use in logging (default is %NAME) .IP \-s locking appends to logfile .IP \-t keep tty association .IP \-x turn on debugging information (option only available when selected at compile time) .PP .SH FILES .br %CONFFILE - default configuration file .br %EXECDIR - default server directory .br %LOGDIR - default log directory .br %LOGFILE - default log file .SH "SEE ALSO" rc(4), daemons(5) .SH AUTHOR Russell J. Yount .SH FEATURES Each .I netd has a limit of about 18 services each due to limits on number of open file descriptors. Only a small number of arguments may be specified in the configuration file, to increase this number .I netd must be recompiled. .SH BUGS .I Netd may fail to reconfigure properly when SIGHUP is receive if there are active datagram services that ignore SIGTERM. This is a temporary problem and is corrected by next SIGHUP received after active datagram service exits. !Magic!Token! echo x - EXAMPLE.dms cat > EXAMPLE.dms << '!Magic!Token!' # # EXAMPLE NETD DAEMONS CONFIGURATION FILE # # # Format of daemons file is as follows, one per line # # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # where # NAME is a unique service name # TYPE is the socket type used # AF is the socket address family used # PF is the socket protocol family used or unspec # ADDRESS differs with AF or can left a - if unused # UID is the username or user-id the program will execute as # GID is the groupname or group-id the program will execute as # NICE is nice level the progam will execute at # LOG will be stderr of program, may be either - for /dev/null, # + to append to netd's logfile or a filename, if the filename # contains a $ the $ will be expanded to be the services name # PROGRAM is the program name and arguments, any @ argument will # be expanded to be the connected address. The is a compile # time limit on number of arguments. # # # # # INTERNET SERVICES # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # ---- ------ ---- ------ ------- --- --- ---- --- ------- ftp stream inet unspec *.ftp root daemon 0 - ftpd @ telnet stream inet unspec *.telnet root daemon 0 - telnetd @ exec stream inet unspec *.exec root daemon 0 - rexecd @ login stream inet unspec *.login root daemon 0 - rlogind @ shell stream inet unspec *.shell root daemon 0 - rshd @ printer stream inet unspec *.printer root daemon 0 - lpd @ rfile stream inet unspec *.rfile root daemon 0 $.log rfiled daytime stream inet unspec *.daytime root daemon 0 - daytimed talk dgram inet unspec *.talk root daemon 0 - talkd comsat dgram inet unspec *.biff root daemon 0 - comsat syslog dgram inet unspec *.syslog root daemon 0 $.log syslog echo dgram inet unspec *.echo root daemon 0 $.log echod # time stream inet unspec *.time root daemon 0 $.log timed # sink dgram inet unspec *.sink root daemon 0 $.log sinkd # # UNIX SERVICES # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # ---- ------ ---- ------ ------- --- --- ---- --- ------- lpd stream unix unspec /dev/printer root daemon 0 - lpd @ # # PERQ SERVICES # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # ---- ------ ---- ------ ------- --- --- ---- --- ------- xtime raw xnet 1792 - root daemon 0 - xtimed xftp raw xnet 256 - root daemon 0 $.log xftpd # # DEVELOPMENT SERVICES # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # ---- ------ ---- ------ ------- --- --- ---- --- ------- # xxxx raw inet unspec *.780 xxxx xxxxxx 0 - xxxx # yyyy raw inet unspec - yyyy yyyyyy 0 - yyyy # # !Magic!Token! echo x - cadre.dms cat > cadre.dms << '!Magic!Token!' # # NETD CONFIGURATION FILE FOR CADRE.ARPA # # # INTERNET SERVICES # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # ---- ------ ---- ------ ------- --- --- ---- --- ------- ftp stream inet unspec *.ftp root daemon 0 - ftpd @ telnet stream inet unspec *.telnet root daemon 0 - telnetd @ exec stream inet unspec *.exec root daemon 0 - rexecd @ login stream inet unspec *.login root daemon 0 - rlogind @ shell stream inet unspec *.shell root daemon 0 - rshd @ printer stream inet unspec *.printer root daemon 4 - lpd @ rfile stream inet unspec *.rfile root daemon 0 - rfiled daytime stream inet unspec *.daytime root daemon 0 - daytimed finger stream inet unspec *.finger root daemon 0 - fingerd talk dgram inet unspec *.talk root daemon 0 - talkd comsat dgram inet unspec *.biff root daemon 0 - comsat syslog dgram inet unspec *.syslog root daemon 0 $.log syslog echo dgram inet unspec *.echo root daemon 0 $.log echod sink dgram inet unspec *.sink root daemon 0 $.log sinkd clock dgram inet unspec *.clock root daemon 0 $.log clockd # # UNIX SERVICES # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # ---- ------ ---- ------ ------- --- --- ---- --- ------- lpd stream unix unspec /dev/printer root daemon 4 - lpd @ # # PERQ SERVICES # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # ---- ------ ---- ------ ------- --- --- ---- --- ------- xtime raw xnet 1792 - root daemon 0 - xtimed xftp raw xnet 256 - root daemon 0 $.log xftpd # !Magic!Token! echo x - prodigal.dms cat > prodigal.dms << '!Magic!Token!' # # NETD CONFIGURATION FILE FOR PRODIGAL.ARPA # # # INTERNET SERVICES # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # ---- ------ ---- ------ ------- --- --- ---- --- ------- ftp stream inet unspec *.ftp root daemon 0 - ftpd @ telnet stream inet unspec *.telnet root daemon 0 - telnetd @ exec stream inet unspec *.exec root daemon 0 - rexecd @ login stream inet unspec *.login root daemon 0 - rlogind @ shell stream inet unspec *.shell root daemon 0 - rshd @ printer stream inet unspec *.printer root daemon 0 - lpd @ rfile stream inet unspec *.rfile root daemon 0 - rfiled daytime stream inet unspec *.daytime root daemon 0 - daytimed finger stream inet unspec *.finger root daemon 0 - fingerd talk dgram inet unspec *.talk root daemon 0 - talkd comsat dgram inet unspec *.biff root daemon 0 - comsat syslog dgram inet unspec *.syslog root daemon 0 $.log syslog echo dgram inet unspec *.echo root daemon 0 $.log echod sink dgram inet unspec *.sink root daemon 0 $.log sinkd clock dgram inet unspec *.clock root daemon 0 $.log clockd # # UNIX SERVICES # NAME TYPE AF PF ADDRESS UID GID NICE LOG PROGRAM # ---- ------ ---- ------ ------- --- --- ---- --- ------- lpd stream unix unspec /dev/printer root daemon 0 - lpd @ # !Magic!Token! echo x - INSTALL.doc cat > INSTALL.doc << '!Magic!Token!' INSTALLATION: Look at the Makefile, it installs 4 files: /usr/man/manl/netd.8l - the manual entry for netd /usr/lib/libnd.a - library used to compile servers /etc/netd - the daemon program /etc/daemons - the configuration for your site also creating a directory (if it does not exist): /usr/lib/netd - where server programs reside If these paths do not agree with your tastes: Edit the Makefile. It has four sections to it. The middle section is altered by "make make" and the tail end is created by "make depend". It will create backup copies of itself when "make or depend" is used. Type "make depend" followed by "make". The file EXAMPLE.dms shows a typical configuration. Copy it to a file with your site name and the extension ".dms", editing it as appropriate. Nroff the file netd.8l if you want for more information. Type "make install" You should now compile the server programs and install them on /usr/lib/netd (or whatever you changed it to be) REMEMBER: to terminate daemons netd will now replace! Execute /etc/netd as root and check its logfile. The file RC.doc has the lines that should be added to either /etc/rc.local or /etc/rc to startup netd at boot time. !Magic!Token! echo x - RC.doc cat > RC.doc << '!Magic!Token!' if [ -f /etc/netd ]; then /etc/netd fi !Magic!Token! echo x - README cat > README << '!Magic!Token!' NETD - Network Service Daemon, Version 1.0, Jan 24, 1985 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. Netd is a network server, it listens at mutiple network addresses for either datagrams or connects and then fires up the appropriate programs attached to the socket. Read the file INSTALL.doc for netd installation instructions. The file SERVER.doc should shed some light on servers use/creation. Russ 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 !Magic!Token! echo x - SERVER.doc cat > SERVER.doc << '!Magic!Token!' NETD SERVERS NOTES Server execution by netd: Executed with uid/gid/nice as set in configuration file. Working directory is same as servers directory. No tty association normally, this can be altered with command options. Stdin and stdout is attached to socket. Stderr is attached to logfile which may be /dev/null. All other descriptors are closed. The programs environment contains only variables "ADDR" and "DISC" as set by netd. The library libnd.a contains a main which uses the environment variable ADDR to get any address passed to it. It then calls doit() passing argc,argv from main along with a the sockets address and address length. (See libmain.c) There may be multiple server programs executing on a connection oriented services, but only one on a connectionless services. In either case it is the server process itself which must terminate itself, not netd. Connectionless services that are activated in burstes shoud likely wait around a while before exiting to be sure their really finished. WARNING: WHEN DEBUGING CONNECTIONLESS SERVICES, IF YOUR SERVICE NEVER READS INCOMING DATA BEFORE EXITING YOU WILL GET A VERY HIGH LOAD AVERAGE DUE TO NETD'S REPEATED EXEC'S OF SERVER. !Magic!Token! echo x - XNET.doc cat > XNET.doc << '!Magic!Token!' Unfinished 10Mbs ethernet at dsl, used to talk with perq workstations. Addresses are funny. Should finished route and bind problems. Completely #ifdef AF_XNET so as to still compile without kernel modes. !Magic!Token! echo x - daemon.h cat > daemon.h << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/daemon.h, Jan 19 23:47:41 1985 */ #define D_ZOMBIE 01 #define D_ACTIVE 02 typedef struct _d Daemon; struct _d { Daemon *succ, *pred; Service *service; Disc *disc; int fd; int flags; int refer; }; !Magic!Token! echo x - disc.h cat > disc.h << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/disc.h, Jan 19 23:47:45 1985 */ #define DISC_WILD -1 typedef int (*Func)(); typedef struct { int type; int af; int pf; Func startup; Func shutdown; } Disc; Disc *DiscLookUp(); !Magic!Token! echo x - disc2.h cat > disc2.h << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/disc2.h, Jan 19 23:47:49 1985 */ Table TableType[]; Table TableAF[]; Table TablePF[]; !Magic!Token! echo x - image.h cat > image.h << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/image.h, Jan 19 23:47:52 1985 */ typedef struct { int length; char *pointer; char buffer[1]; /* variable length */ } Image; Image *OpenImage(); !Magic!Token! echo x - service.h cat > service.h << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/service.h, Jan 19 23:47:56 1985 */ #define MINFLDS 10 #define NARGS 4 #define MAXFLDS ( MINFLDS + NARGS - 1 ) typedef struct { char *name; int af, pf, type; struct sockaddr addr; int addrlen; short uid, gid, nice; char *prog; char *args[ NARGS ]; char *log; char strings[ 100 ]; } Service; Service *MakeService(); !Magic!Token! echo x - syserr.h cat > syserr.h << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/syserr.h, Jan 19 23:48:00 1985 */ extern int errno; extern char *sys_errlist[]; extern int sys_nerr; #define syserror ((errno >= sys_nerr) ? "unknown" : sys_errlist[ errno ]) !Magic!Token! echo x - table.h cat > table.h << '!Magic!Token!' /* netd 1.0, /usr/src/net.dsl/netd/table.h, Jan 19 23:48:03 1985 */ typedef struct { char *name; int value; } Table; !Magic!Token! echo x - Makefile cat > Makefile << '!Magic!Token!' ### BEGIN HEADER, DO NOT REMOVE THIS LINE # netd 1.0, /usr/src/net.dsl/Makefile, Jan 19 23:47:50 1985 # # Our Name MAKEFILE=Makefile # # Where we belong BIN=${DEST}/usr/local ETC=${DEST}/etc LIB=${DEST}/usr/lib ADM=${DEST}/usr/adm MAN=${DEST}/usr/man # # Owner of all installed files OWNER=network GROUP=daemon # # # Complete list of source files, broken in two for usenet pdp-11's (>64K) SOURCE1= ${CFILES} ${SFILES} ${YFILES} ${LFILES} SOURCE2= ${MFILES} ${XFILES} ${DFILES} ${HFILES} ${MAKEFILE} # # CC and LD options # for debugging use # LDFLAGS=-g # CCFLAGS=-g -DDEBUG -DNAME...... # INCLUDE=. LDFLAGS=-s CCFLAGS=-O \ -DNAME='"${NAME}"' -DLOGDIR='"${LOGDIR}"' \ -DEXECDIR='"${EXECDIR}"' -DLOGFILE='"${LOGFILE}"' \ -DCONFFILE='"${CONFFILE}"' -DNAME='"${NAME}"' # # Where to tar sources TARDEV=netd.tar SHAR=netd.shar MAGIC='!Magic!Token!' # # Package defaults NAME=netd CONFFILE= ${ETC}/daemons LOGFILE= netd.log LOGDIR= ${ADM} EXECDIR= ${LIB}/netd # # # The Section below following line is created by "make make" ### END HEADER, DO NOT REMOVE THIS LINE CFILES= addr.c addr2.c addr3.c addr4.c conf.c daemon.c dgram.c disc.c disc2.c image.c init.c libmain.c main.c mplx.c option.c proc.c raw.c service.c stream.c table.c xnet.c HFILES= daemon.h disc.h disc2.h image.h service.h syserr.h table.h LFILES= YFILES= DFILES= INSTALL.doc RC.doc README SERVER.doc XNET.doc MFILES= daemons.5l.man netd.8l.man XFILES= EXAMPLE.dms cadre.dms prodigal.dms SFILES= OFILES= addr.o addr2.o addr3.o addr4.o conf.o daemon.o dgram.o disc.o disc2.o image.o init.o libmain.o main.o mplx.o option.o proc.o raw.o service.o stream.o table.o xnet.o ### BEGIN BODY, DO NOT REMOVE THIS LINE # # Everything we will need to create ALL= netd libnd.a netd.8l daemons.5l OBJS1= addr.o addr2.o addr4.o conf.o daemon.o dgram.o disc.o disc2.o \ image.o init.o main.o mplx.o option.o proc.o raw.o service.o \ stream.o table.o xnet.o OBJS2= addr3.o libmain.o # # How to do it all: ${ALL} .c.o: ; cc ${CCFLAGS} -c $*.c # Edit manual entries to reflect installation netd.8l: ${MFILES} for i in ${MFILES}; do \ sed -e 's;%NAME;${NAME};' \ -e 's;%LOGDIR;${LOGDIR};' \ -e 's;%EXECDIR;${EXECDIR};' \ -e 's;%LOGFILE;${LOGFILE};' \ -e 's;%CONFFILE;${CONFFILE};' \ < $$i > `echo $$i | sed -e 's/\.man//g'` ; \ done # the daemon netd: ${OBJS1} ; cc ${OBJS1} ${LDFLAGS} -o netd # the library for compiling servers libnd.a: ${OBJS2} ar cru libnd.a ${OBJS2} ranlib libnd.a # # To be tidy? lint: lint ${CFILES} @echo ignore mutiple main # How to install it, the `hostname.dms` file must exist by now install: netd libnd.a netd.8l -mkdir ${EXECDIR} chown ${OWNER} ${EXECDIR} chgrp ${GROUP} ${EXECDIR} chmod 755 ${EXECDIR} install -o ${OWNER} -g ${GROUP} -m 644 -c `hostname`.dms ${CONFFILE} -install -o ${OWNER} -g ${GROUP} -m 644 -c netd.8l ${MAN}/manl/netd.8l -install -o ${OWNER} -g ${GROUP} -m 644 -c daemons.5l ${MAN}/manl/daemons.5l install -o ${OWNER} -g ${GROUP} -m 644 -c libnd.a ${LIB}/libnd.a install -o ${OWNER} -g ${GROUP} -m 755 -c netd ${ETC}/netd ranlib ${LIB}/libnd.a ls -gl ${LIB}/libnd.a ${ETC}/netd ${CONFFILE} \ ${MAN}/manl/daemons.5l ${MAN}/manl/netd.8l # # Purge from system clobber: cd ${MAN}/manl; rm -f netd.8l cd ${ETC}; rm -f netd daemons cd ${LIB}; rm -f libnd.a # # Clean up everything clean: ; rm -f ${OFILES} ${ALL} # # Clean up others purge: ; rm -f ${TARDEV} ${SHAR} # # Tar all sources tar: ${SOURCE1} ${SOURCE2}; tar cf ${TARDEV} ${SOURCE1} ${SOURCE2} # # Make a shar File shar: ${SOURCE1} ${SOURCE2} rm -f ${SHAR}.1 ${SHAR}.2 for i in ${SOURCE1}; do\ echo "echo x - $$i" >> ${SHAR}.1;\ echo "cat > $$i << ${MAGIC}" >> ${SHAR}.1;\ cat $$i >> ${SHAR}.1;\ echo ${MAGIC} >> ${SHAR}.1;\ done for i in ${SOURCE2}; do\ echo "echo x - $$i" >> ${SHAR}.2;\ echo "cat > $$i << ${MAGIC}" >> ${SHAR}.2;\ cat $$i >> ${SHAR}.2;\ echo ${MAGIC} >> ${SHAR}.2;\ done ls -l ${SHAR}.1 ${SHAR}.2 # # Be carefull to save original ${MAKEFILE}.org: ; cp ${MAKEFILE} ${MAKEFILE}.org # # Create a new makefile after looking at file on current directory make: ${MAKEFILE}.org sed -n -e '/^### BEGIN HEADER/,/^### END HEADER/p' \ < ${MAKEFILE} > ${MAKEFILE}.new echo CFILES= `ls [a-zA-Z]*.c` >> ${MAKEFILE}.new echo HFILES= `ls [a-zA-Z]*.h` >> ${MAKEFILE}.new echo LFILES= `ls [a-zA-Z]*.l` >> ${MAKEFILE}.new echo YFILES= `ls [a-zA-Z]*.y` >> ${MAKEFILE}.new echo DFILES= `ls README [a-zA-Z]*.doc` >> ${MAKEFILE}.new echo MFILES= `ls [a-zA-Z]*.man` >> ${MAKEFILE}.new echo XFILES= `ls [a-zA-Z]*.dms` >> ${MAKEFILE}.new echo SFILES= `ls [a-zA-Z]*.sh` >> ${MAKEFILE}.new echo OFILES= `ls [a-zA-Z]*.c | sed -e 's/\.c/.o/g'` >> ${MAKEFILE}.new sed -n -e '/^### BEGIN BODY/,/^### END BODY/p' \ < ${MAKEFILE} >> ${MAKEFILE}.new mv $(MAKEFILE) $(MAKEFILE).bak mv $(MAKEFILE).new $(MAKEFILE) @echo remember to '"make depend"' # Create a dependency list for makefile depend: ${MAKEFILE}.org sed -n -e '1,/^### END BODY/p' < $(MAKEFILE) > $(MAKEFILE).new -for i in $(YACCFILES) $(LEXFILES) $(CFILES) $(FFILES) ; do \ base=`expr $$i ':' '\(.*\).[cylf]$$'`; \ suffix=`expr $$i ':' '.*\.\([cylf]\)$$'`;\ if /bin/test $$suffix = l ; then\ lex $$i;\ mv lex.yy.c $$base.c;\ suffix=c;\ echo "$$base.c: $$base.l" >> $(MAKEFILE).new;\ elif /bin/test $$suffix = y ; then\ yacc $(YFLAGS) $$i;\ mv y.tab.c $$base.c;\ suffix=c;\ echo "$$base.c: $$base.y" >> $(MAKEFILE).new;\ echo "y.tab.h: $$base.y" >> $(MAKEFILE).new;\ fi;\ $(CC) $(CLOCALFLAGS) -I$(INCLUDE) -E $$base.$$suffix |\ grep '^# [0-9][0-9]* ".*"$$' > /tmp/grep$$$$;\ sed -e 's/.*"\(.*\)"$$/\1/' -e 's/^.\///' < /tmp/grep$$$$ |\ sort -u |\ awk\ "BEGIN { line=\"$$base.o: \"}\ {\ if(length(line \$$0)>63)\ {\ print line,\"\\\\\";\ line=\" \"\$$0\ }\ else\ line=line\" \"\$$0\ }\ END { print line}"\ >> $(MAKEFILE).new;\ done;\ rm /tmp/grep$$$$ mv $(MAKEFILE) $(MAKEFILE).bak mv $(MAKEFILE).new $(MAKEFILE) # # The section below following line is created by "make depend" ### END BODY, DO NOT REMOVE THIS LINE !Magic!Token!
medin@ucbvax.ARPA (Milo Medin) (02/06/85)
Uh, I think you guys should realize that we at berkeley have an inet daemon as well, quite similar to this stuff, but ours will be distributed in the upcoming new 4.2 release. So, if you intend to upgrade to the new BSD, I'd suggest waiting for ours... Milo
mark@tove.UUCP (Mark Weiser) (02/08/85)
In article <4624@ucbvax.ARPA> medin@ucbvax.ARPA (Milo Medin) writes: >Uh, I think you guys should realize that we at berkeley have an inet >daemon as well, quite similar to this stuff, but ours will be distributed >in the upcoming new 4.2 release. So, if you intend to upgrade >to the new BSD, I'd suggest waiting for ours... > > > Milo How about leaking some ordering information ahead of time so those of us with incredibily long lead times to P.O. or license signature can try to get the ball rolling? New license needed? Cost? -- Spoken: Mark Weiser ARPA: mark@maryland Phone: +1-301-454-7817 CSNet: mark@umcp-cs UUCP: {seismo,allegra}!umcp-cs!mark USPS: Computer Science Dept., University of Maryland, College Park, MD 20742
medin@ucbvax.ARPA (Milo Medin) (02/10/85)
> How about leaking some ordering information ahead of time so those of us > with incredibily long lead times to P.O. or license signature can > try to get the ball rolling? > New license needed? > Cost? > > -- > Spoken: Mark Weiser ARPA: mark@maryland Phone: +1-301-454-7817 > CSNet: mark@umcp-cs UUCP: {seismo,allegra}!umcp-cs!mark > USPS: Computer Science Dept., University of Maryland, College Park, MD 20742 Well, what can I say? I mentioned that to prevent some waste of people's time. I know certain things about the release, but I am not part of the group that is involved with the distribution. I am sure when the time comes people will know about it. If you saw the paper in last summer's usenix conference about performance increases, thats all in there, plus a bit more. It's well worth upgrading to in my opinion. But as I am not part of the distribution group, it would be inappropriate to comment on P.O.'s or new licensing requirements. Milo