X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fatalkd%2Fconfig.c;h=957c18a27111deedfd0fd41d0c4b4c0f0b43b8b5;hb=b8c1894353b62eb52e59d4e0150fd3c25dcd86ba;hp=a0927371a024921935ad75acdcc21aa0af9968be;hpb=efc466d375e2b60c34990b39b135ce56bd38a99b;p=netatalk.git diff --git a/etc/atalkd/config.c b/etc/atalkd/config.c index a0927371..957c18a2 100644 --- a/etc/atalkd/config.c +++ b/etc/atalkd/config.c @@ -1,5 +1,5 @@ /* - * $Id: config.c,v 1.11 2002-01-04 04:45:47 sibaz Exp $ + * $Id: config.c,v 1.20 2009-10-29 11:35:58 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -55,21 +55,30 @@ char *strchr (), *strrchr (); #include #endif /* __svr4__ */ +#include #include "interface.h" #include "multicast.h" #include "rtmp.h" #include "zip.h" #include "list.h" +#include "main.h" #ifndef IFF_SLAVE /* a little backward compatibility */ #define IFF_SLAVE 0 #endif /* IFF_SLAVE */ -int router(), dontroute(), seed(), phase(), net(), addr(), zone(); +int router(struct interface *iface, char **av); +int dontroute(struct interface *iface, char **av); +int seed(struct interface *iface, char **av); +int phase(struct interface *iface, char **av); +int net(struct interface *iface, char **av); +int addr(struct interface *iface, char **av); +int zone(struct interface *iface, char **av); +int noallmulti(struct interface *iface, char **av); -static struct param { +static const struct param { char *p_name; - int (*p_func)(); + int (*p_func)(struct interface *iface, char **av); } params[] = { { "router", router }, { "dontroute", dontroute }, @@ -78,10 +87,12 @@ static struct param { { "net", net }, { "addr", addr }, { "zone", zone }, + { "noallmulti", noallmulti } }; #define ARGV_CHUNK_SIZE 128 -char **parseline(const char *line) +#define MAXLINELEN 2048 +static char **parseline(const char *line) { const char *p; int argc = 0; @@ -136,7 +147,7 @@ char **parseline(const char *line) /* Make room for a NULL pointer and our special pointer (s.b.) */ if ( (argc + 1) % ARGV_CHUNK_SIZE == 0 ) { char **tmp; - tmp = (char **) realloc( argv, argc + 1 + ARGV_CHUNK_SIZE ); + tmp = (char **) realloc( argv, argc + 1 + ARGV_CHUNK_SIZE * sizeof( char * ) ); if ( !tmp ) { /* FIXME: error handling */ free( argv ); @@ -161,7 +172,7 @@ char **parseline(const char *line) return argv; } -void freeline( char **argv ) +static void freeline( char **argv ) { char **tmp = argv; @@ -174,16 +185,17 @@ void freeline( char **argv ) } } -int writeconf( cf ) - char *cf; +int writeconf(char *cf) { struct stat st; - char *path, *p, newpath[ MAXPATHLEN ], line[ 1024 ]; + char *path, *p, newpath[ MAXPATHLEN ], line[ MAXLINELEN ]; char **argv; FILE *conf, *newconf; struct interface *iface; struct list *l; int mode = 0644, fd; + size_t len; + char *zonename; if ( cf == NULL ) { path = _PATH_ATALKDCONF; @@ -194,7 +206,7 @@ int writeconf( cf ) /* check if old conf is writable */ if ( stat( path, &st ) == 0 ) { if (( st.st_mode & S_IWUSR ) == 0 ) { - LOG(log_info, logtype_default, "%s not writable, won't rewrite", path ); + LOG(log_info, logtype_atalkd, "%s not writable, won't rewrite", path ); return( -1 ); } mode = st.st_mode; @@ -206,16 +218,16 @@ int writeconf( cf ) sprintf( newpath, "%.*s/%s", (int)(p - path), path, _PATH_ATALKDTMP ); } if (( fd = open( newpath, O_WRONLY|O_CREAT|O_TRUNC, mode )) < 0 ) { - LOG(log_error, logtype_default, "%s: %s", newpath, strerror(errno) ); + LOG(log_error, logtype_atalkd, "%s: %s", newpath, strerror(errno) ); return( -1 ); } if (( newconf = fdopen( fd, "w" )) == NULL ) { - LOG(log_error, logtype_default, "fdreopen %s: %s", newpath, strerror(errno) ); + LOG(log_error, logtype_atalkd, "fdreopen %s: %s", newpath, strerror(errno) ); return( -1 ); } if (( conf = fopen( path, "r" )) == NULL && cf ) { - LOG(log_error, logtype_default, "%s: %s", path, strerror(errno) ); + LOG(log_error, logtype_atalkd, "%s: %s", path, strerror(errno) ); return( -1 ); } @@ -224,7 +236,7 @@ int writeconf( cf ) while ( conf == NULL || fgets( line, sizeof( line ), conf ) != NULL ) { if ( conf != NULL && ( argv = parseline( line )) == NULL ) { if ( fputs( line, newconf ) == EOF ) { - LOG(log_error, logtype_default, "fputs: %s", strerror(errno) ); + LOG(log_error, logtype_atalkd, "fputs: %s", strerror(errno) ); return( -1 ); } freeline( argv ); @@ -242,6 +254,11 @@ int writeconf( cf ) if ( iface->i_flags & IFACE_DONTROUTE) { fprintf( newconf, " -dontroute"); } +#ifdef linux + if ( !(iface->i_flags & IFACE_ALLMULTI)) { + fprintf( newconf, " -noallmulti"); + } +#endif fprintf( newconf, " -phase %d", ( iface->i_flags & IFACE_PHASE1 ) ? 1 : 2 ); @@ -253,9 +270,20 @@ int writeconf( cf ) ntohs( iface->i_addr.sat_addr.s_net ), iface->i_addr.sat_addr.s_node ); for ( l = iface->i_rt->rt_zt; l; l = l->l_next ) { - fprintf( newconf, " -zone \"%.*s\"", - ((struct ziptab *)l->l_data)->zt_len, - ((struct ziptab *)l->l_data)->zt_name ); + /* codepage conversion */ + if ((size_t)(-1) == (len = convert_string_allocate(CH_MAC, CH_UNIX, + ((struct ziptab *)l->l_data)->zt_name, + ((struct ziptab *)l->l_data)->zt_len, + &zonename)) ) { + if ( NULL == + (zonename = strdup(((struct ziptab *)l->l_data)->zt_name))) { + LOG(log_error, logtype_atalkd, "malloc: %s", strerror(errno) ); + return( -1 ); + } + len = ((struct ziptab *)l->l_data)->zt_len; + } + fprintf( newconf, " -zone \"%.*s\"", (int)len, zonename); + free(zonename); } fprintf( newconf, "\n" ); @@ -271,7 +299,7 @@ int writeconf( cf ) fclose( newconf ); if ( rename( newpath, path ) < 0 ) { - LOG(log_error, logtype_default, "rename %s to %s: %s", newpath, path, strerror(errno) ); + LOG(log_error, logtype_atalkd, "rename %s to %s: %s", newpath, path, strerror(errno) ); return( -1 ); } return( 0 ); @@ -299,13 +327,13 @@ int writeconf( cf ) * zone for an interface is the first zone encountered for that * interface. */ -int readconf( cf ) - char *cf; +int readconf(char *cf) { struct ifreq ifr; struct interface *iface, *niface; - char line[ 1024 ], **argv, *p; - int i, j, s, cc; + char line[ MAXLINELEN ], **argv, *p; + unsigned int i, j; + int s, cc = 0; FILE *conf; if ( cf == NULL ) { @@ -335,8 +363,7 @@ int readconf( cf ) * Check that av[ 0 ] is a valid interface. * Not possible under sysV. */ - strncpy( ifr.ifr_name, argv[ 0 ], sizeof(ifr.ifr_name) ); - ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0'; + strlcpy( ifr.ifr_name, argv[ 0 ], sizeof(ifr.ifr_name) ); /* for devices that don't support appletalk */ if ((ioctl(s, SIOCGIFADDR, &ifr) < 0) && (errno == ENODEV)) { @@ -366,6 +393,7 @@ int readconf( cf ) fprintf(stderr, "Can't configure multicast.\n"); goto read_conf_err; } + #endif /* __svr4__ */ if (( niface = newiface( argv[ 0 ] )) == NULL ) { @@ -406,6 +434,15 @@ int readconf( cf ) goto read_conf_err; } +#ifdef linux + /* Don't set interface to allmulti if it already is, or -noallmulti was given */ + if ((ifr.ifr_flags & IFF_ALLMULTI)) + niface->i_flags |= IFACE_WASALLMULTI; + + if ((niface->i_flags & IFACE_ALLMULTI) && !(niface->i_flags & IFACE_WASALLMULTI)) + ifsetallmulti(ifr.ifr_name, 1); +#endif + if ( interfaces == NULL ) { interfaces = niface; } else { @@ -442,10 +479,16 @@ read_conf_err: return -1; } +int noallmulti( struct interface *iface, char **av _U_) +{ + /* Linux specific, no effect on other platforms */ + iface->i_flags &= !IFACE_ALLMULTI; + + return (1); +} + /*ARGSUSED*/ -int router( iface, av ) - struct interface *iface; - char **av; +int router(struct interface *iface, char **av _U_) { /* make sure "-router" and "-dontroute" aren't both on the same line. */ if (iface->i_flags & IFACE_DONTROUTE) { @@ -467,9 +510,7 @@ int router( iface, av ) } /*ARGSUSED*/ -int dontroute( iface, av ) - struct interface *iface; - char **av; +int dontroute(struct interface *iface, char **av _U_) { /* make sure "-router" and "-dontroute" aren't both on the same line. */ if (iface->i_flags & IFACE_RSEED) { @@ -482,9 +523,7 @@ int dontroute( iface, av ) } /*ARGSUSED*/ -int seed( iface, av ) - struct interface *iface; - char **av; +int seed( struct interface *iface, char **av _U_) { /* * Check to be sure "-seed" is before "-zone". we keep the old @@ -500,9 +539,7 @@ int seed( iface, av ) return( 1 ); } -int phase( iface, av ) - struct interface *iface; - char **av; +int phase(struct interface *iface, char **av) { int n; char *pnum; @@ -528,9 +565,7 @@ int phase( iface, av ) return( 2 ); } -int net( iface, av ) - struct interface *iface; - char **av; +int net(struct interface *iface, char **av) { char *nrange; char *stop; @@ -541,7 +576,7 @@ int net( iface, av ) return -1; } - if (( stop = strchr( nrange, '-' )) != 0 ) { + if (( stop = strchr( nrange, '-' )) != NULL ) { stop++; } net = atoi( nrange ); @@ -556,7 +591,7 @@ int net( iface, av ) } if ( iface->i_flags & IFACE_PHASE1 ) { - if ( stop != 0 ) { + if ( stop != NULL ) { fprintf( stderr, "Phase 1 doesn't use an address range.\n" ); return -1; } @@ -569,7 +604,7 @@ int net( iface, av ) iface->i_rt->rt_firstnet = iface->i_rt->rt_lastnet = htons( net ); } else if ( iface->i_flags & IFACE_PHASE2 ) { iface->i_rt->rt_firstnet = htons( net ); - if ( stop != 0 ) { + if ( stop != NULL ) { net = atoi( stop ); if ( net < 0 || net >= 0xffff ) { fprintf( stderr, "Bad network: %d\n", net ); @@ -598,9 +633,7 @@ int net( iface, av ) return( 2 ); } -int addr( iface, av ) - struct interface *iface; - char **av; +int addr(struct interface *iface, char **av) { if ( av[ 0 ] == NULL ) { fprintf( stderr, "No address.\n" ); @@ -634,18 +667,21 @@ int addr( iface, av ) return( 2 ); } -int zone( iface, av ) - struct interface *iface; - char **av; +int zone(struct interface *iface, char **av) { struct ziptab *zt; char *zname; - if (( zname = av[ 0 ] ) == NULL ) { + if ( av[ 0 ] == NULL ) { fprintf( stderr, "No zone.\n" ); return -1; } + /* codepage conversion */ + if ((size_t)(-1) == convert_string_allocate(CH_UNIX, CH_MAC, av[0], -1, &zname)) { + zname = strdup(av[0]); + } + /* * Only process "-zone" if this interface has "-seed". We keep our * list of configured zones in the interface structure. Then we can @@ -656,6 +692,7 @@ int zone( iface, av ) fprintf( stderr, "Must specify net-range before zones.\n" ); return -1; } + if (( zt = newzt( strlen( zname ), zname )) == NULL ) { perror( "newzt" ); return -1; @@ -667,6 +704,8 @@ int zone( iface, av ) iface->i_czt->zt_next = zt; } } + free(zname); + return( 2 ); } @@ -674,7 +713,7 @@ int zone( iface, av ) * Get the configuration from the kernel. Only called if there's no * configuration. */ -int getifconf() +int getifconf(void) { struct interface *iface, *niface; struct ifreq ifr; @@ -688,7 +727,7 @@ int getifconf() start = list = getifacelist(); while (list && *list) { - strncpy(ifr.ifr_name, *list, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, *list, sizeof(ifr.ifr_name)); list++; if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) @@ -754,8 +793,7 @@ int getifconf() * the interface structure and have it updated nicely. */ -struct interface *newiface( name ) - const char *name; +struct interface *newiface( const char *name) { struct interface *niface; @@ -763,7 +801,7 @@ struct interface *newiface( name ) == NULL ) { return( NULL ); } - strncpy( niface->i_name, name, sizeof(niface->i_name)); + strlcpy( niface->i_name, name, sizeof(niface->i_name)); #ifdef BSD4_4 niface->i_addr.sat_len = sizeof( struct sockaddr_at ); #endif /* BSD4_4 */ @@ -772,15 +810,19 @@ struct interface *newiface( name ) niface->i_caddr.sat_len = sizeof( struct sockaddr_at ); #endif /* BSD4_4 */ niface->i_caddr.sat_family = AF_APPLETALK; +#ifdef linux + niface->i_flags = IFACE_ALLMULTI; +#endif return( niface ); } #ifdef __svr4__ -int plumb() +int plumb(void) { struct interface *iface; - char device[ MAXPATHLEN + 1], *p; + char device[ MAXPATHLEN + 1], *p, *t; int fd, ppa; + int digits = 0; for ( iface = interfaces; iface != NULL; iface = iface->i_next ) { if ( strcmp( iface->i_name, LOOPIFACE ) == 0 ) { @@ -789,24 +831,33 @@ int plumb() strcpy( device, "/dev/" ); strcat( device, iface->i_name ); - if (( p = strpbrk( device, "0123456789" )) == NULL ) { - LOG(log_error, logtype_default, "plumb: invalid device: %s", device ); + for (t = device; *t != '\0' ; ++t) { + if (isdigit(*t) == 0) { + p = t + 1; + } + else { + digits++; + } + } + + if (digits == 0) { + LOG(log_error, logtype_atalkd, "plumb: invalid device: %s", device ); return -1; } ppa = atoi( p ); *p = '\0'; if (( fd = open( device, O_RDWR, 0 )) < 0 ) { - LOG(log_error, logtype_default, "%s: %m", device ); + LOG(log_error, logtype_atalkd, "%s: %s", device, strerror(errno) ); return -1; } if ( ioctl( fd, I_PUSH, "ddp" ) < 0 ) { - LOG(log_error, logtype_default, "I_PUSH: %m" ); + LOG(log_error, logtype_atalkd, "I_PUSH: %s", strerror(errno) ); close(fd); return -1; } if ( ioctl( fd, IF_UNITSEL, ppa ) < 0 ) { - LOG(log_error, logtype_default, "IF_UNITSEL: %m" ); + LOG(log_error, logtype_atalkd, "IF_UNITSEL: %s", strerror(errno) ); close(fd); return -1; } @@ -819,7 +870,7 @@ int plumb() return -1; } - LOG(log_info, logtype_default, "plumbed %s%d", device, ppa ); + LOG(log_info, logtype_atalkd, "plumbed %s%d", device, ppa ); } return( 0 );