X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fatalkd%2Fconfig.c;h=4630f7c5ede0559789dc52ae4267877e8074ba5b;hb=ecfc96169ab669b578e53fa8e13592934fe37788;hp=488ba8c423773e67c707f89ce9ab192c475959b3;hpb=644c7d4f1a295df818a7f8339ac750821e7c26dc;p=netatalk.git diff --git a/etc/atalkd/config.c b/etc/atalkd/config.c index 488ba8c4..4630f7c5 100644 --- a/etc/atalkd/config.c +++ b/etc/atalkd/config.c @@ -1,5 +1,5 @@ /* - * $Id: config.c,v 1.4 2001-06-25 20:13:45 rufustfirefly Exp $ + * $Id: config.c,v 1.14 2005-04-28 20:49:46 bfernhomberg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -13,40 +13,63 @@ #include #include #include -#include +#include #include +#ifdef TRU64 +#include +#include +#endif /* TRU64 */ #include #include #include #include #include +#include #include #include #include +#include #include + +/* STDC check */ +#if STDC_HEADERS +#include +#else /* STDC_HEADERS */ +#ifndef HAVE_STRCHR +#define strchr index +#define strrchr index +#endif /* HAVE_STRCHR */ +char *strchr (), *strrchr (); +#ifndef HAVE_MEMCPY +#define memcpy(d,s,n) bcopy ((s), (d), (n)) +#define memmove(d,s,n) bcopy ((s), (d), (n)) +#endif /* ! HAVE_MEMCPY */ +#endif /* STDC_HEADERS */ + #ifdef HAVE_FCNTL_H #include #endif /* HAVE_FCNTL_H */ -#include #ifdef __svr4__ #include #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(), dontroute(), seed(), phase(), net(), addr(), zone(), noallmulti(); -static struct param { +static const struct param { char *p_name; int (*p_func)(); } params[] = { @@ -57,68 +80,116 @@ static struct param { { "net", net }, { "addr", addr }, { "zone", zone }, + { "noallmulti", noallmulti } }; -static char ** -parseline( line ) - char *line; +#define ARGV_CHUNK_SIZE 128 +#define MAXLINELEN 2048 +char **parseline(const char *line) { - char *p; - int argc = 0; - static char *argv[ 128 ]; - static char buf[ 1024 ]; + const char *p; + int argc = 0; + char *buffer, *tmpbuf; + char **argv; - if ( *line == '#' ) { - return( NULL ); + /* Ignore empty lines and lines with leading hash marks. */ + p = line; + while ( isspace( *p ) ) { + p++; + } + if ( *p == '#' || *p == '\0' ) { + return NULL; } - argc = 0; - memset(argv, 0, sizeof(argv)); - strcpy( buf, line ); - p = buf; + buffer = (char *) malloc( strlen( p ) + 1 ); + if ( !buffer ) { + /* FIXME: error handling */ + return NULL; + } + strcpy( buffer, p ); + tmpbuf = buffer; + + argv = (char **) malloc( ARGV_CHUNK_SIZE * sizeof( char * ) ); + if ( !argv ) { + /* FIXME: error handling */ + free( buffer ); + return NULL; + } /* * This parser should be made more powerful -- it should * handle various escapes, e.g. \" and \031. */ - while ( *p != '\0' ) { - while ( *p != '\0' && *p != '"' && isspace( *p )) { - p++; - } - if ( *p == '\0' ) { - argv[ argc ] = 0; - break; - } - if ( *p == '"' ) { - argv[ argc ] = ++p; - while ( *p != '\0' && *p != '"' ) { - p++; + do { + if ( *tmpbuf == '"' ) { + argv[ argc++ ] = ++tmpbuf; + while ( *tmpbuf != '\0' && *tmpbuf != '"' ) { + tmpbuf++; + } + if ( *tmpbuf == '"' ) { + /* FIXME: error handling */ } } else { - argv[ argc ] = p; - while ( *p != '\0' && !isspace( *p )) { - p++; + argv[ argc++ ] = tmpbuf; + while ( *tmpbuf != '\0' && !isspace( *tmpbuf )) { + tmpbuf++; } } - *p++ = '\0'; - argc++; - } - if ( argv[ 0 ] == '\0' || *argv[ 0 ] == '#' ) { - return( NULL ); + *tmpbuf++ = '\0'; + + /* 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 * sizeof( char * ) ); + if ( !tmp ) { + /* FIXME: error handling */ + free( argv ); + free( buffer ); + return NULL; + } + argv = tmp; + } + + /* Skip white spaces. */ + while ( isspace( *tmpbuf ) ) { + tmpbuf++; + } + } while ( *tmpbuf != '\0' ); + + argv[ argc++ ] = NULL; + /* We store our buffer pointer in argv, too, so we can free it later. + * (But don't tell anyone.) + */ + argv[ argc ] = buffer; + + return argv; +} + +void freeline( char **argv ) +{ + char **tmp = argv; + + if ( argv ) { + while ( *tmp ) { + tmp++; + } + free( *++tmp ); + free( argv ); } - return( argv ); } int writeconf( cf ) 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; @@ -129,7 +200,7 @@ int writeconf( cf ) /* check if old conf is writable */ if ( stat( path, &st ) == 0 ) { if (( st.st_mode & S_IWUSR ) == 0 ) { - syslog( LOG_INFO, "%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; @@ -141,16 +212,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 ) { - syslog( LOG_ERR, "%s: %m", newpath ); + LOG(log_error, logtype_atalkd, "%s: %s", newpath, strerror(errno) ); return( -1 ); } if (( newconf = fdopen( fd, "w" )) == NULL ) { - syslog( LOG_ERR, "fdreopen %s: %m", newpath ); + LOG(log_error, logtype_atalkd, "fdreopen %s: %s", newpath, strerror(errno) ); return( -1 ); } if (( conf = fopen( path, "r" )) == NULL && cf ) { - syslog( LOG_ERR, "%s: %m", path ); + LOG(log_error, logtype_atalkd, "%s: %s", path, strerror(errno) ); return( -1 ); } @@ -159,9 +230,10 @@ int writeconf( cf ) while ( conf == NULL || fgets( line, sizeof( line ), conf ) != NULL ) { if ( conf != NULL && ( argv = parseline( line )) == NULL ) { if ( fputs( line, newconf ) == EOF ) { - syslog( LOG_ERR, "fputs: %m" ); + LOG(log_error, logtype_atalkd, "fputs: %s", strerror(errno) ); return( -1 ); } + freeline( argv ); continue; } @@ -176,6 +248,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 ); @@ -187,9 +264,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: %m" ); + return( -1 ); + } + len = ((struct ziptab *)l->l_data)->zt_len; + } + fprintf( newconf, " -zone \"%.*s\"", (int)len, zonename); + free(zonename); } fprintf( newconf, "\n" ); @@ -205,7 +293,7 @@ int writeconf( cf ) fclose( newconf ); if ( rename( newpath, path ) < 0 ) { - syslog( LOG_ERR, "rename %s to %s: %m", newpath, path ); + LOG(log_error, logtype_atalkd, "rename %s to %s: %s", newpath, path, strerror(errno) ); return( -1 ); } return( 0 ); @@ -238,8 +326,9 @@ int readconf( 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 ) { @@ -269,7 +358,7 @@ int readconf( cf ) * Check that av[ 0 ] is a valid interface. * Not possible under sysV. */ - strcpy( ifr.ifr_name, argv[ 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)) { @@ -299,6 +388,7 @@ int readconf( cf ) fprintf(stderr, "Can't configure multicast.\n"); goto read_conf_err; } + #endif /* __svr4__ */ if (( niface = newiface( argv[ 0 ] )) == NULL ) { @@ -339,6 +429,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 { @@ -375,10 +474,20 @@ read_conf_err: return -1; } +int noallmulti( iface, av ) + 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; + char **av _U_; { /* make sure "-router" and "-dontroute" aren't both on the same line. */ if (iface->i_flags & IFACE_DONTROUTE) { @@ -402,7 +511,7 @@ int router( iface, av ) /*ARGSUSED*/ int dontroute( iface, av ) struct interface *iface; - char **av; + char **av _U_; { /* make sure "-router" and "-dontroute" aren't both on the same line. */ if (iface->i_flags & IFACE_RSEED) { @@ -417,7 +526,7 @@ int dontroute( iface, av ) /*ARGSUSED*/ int seed( iface, av ) struct interface *iface; - char **av; + char **av _U_; { /* * Check to be sure "-seed" is before "-zone". we keep the old @@ -574,11 +683,16 @@ int zone( iface, 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], strlen(av[0]), &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 @@ -589,6 +703,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; @@ -600,6 +715,8 @@ int zone( iface, av ) iface->i_czt->zt_next = zt; } } + free(zname); + return( 2 ); } @@ -621,7 +738,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) @@ -696,7 +813,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 */ @@ -705,6 +822,9 @@ 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 ); } @@ -723,23 +843,23 @@ int plumb() strcpy( device, "/dev/" ); strcat( device, iface->i_name ); if (( p = strpbrk( device, "0123456789" )) == NULL ) { - syslog( LOG_ERR, "plumb: invalid device: %s", device ); + 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 ) { - syslog( LOG_ERR, "%s: %m", device ); + LOG(log_error, logtype_atalkd, "%s: %m", device ); return -1; } if ( ioctl( fd, I_PUSH, "ddp" ) < 0 ) { - syslog( LOG_ERR, "I_PUSH: %m" ); + LOG(log_error, logtype_atalkd, "I_PUSH: %m" ); close(fd); return -1; } if ( ioctl( fd, IF_UNITSEL, ppa ) < 0 ) { - syslog( LOG_ERR, "IF_UNITSEL: %m" ); + LOG(log_error, logtype_atalkd, "IF_UNITSEL: %m" ); close(fd); return -1; } @@ -752,7 +872,7 @@ int plumb() return -1; } - syslog( LOG_INFO, "plumbed %s%d", device, ppa ); + LOG(log_info, logtype_atalkd, "plumbed %s%d", device, ppa ); } return( 0 );