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