/*
+ * $Id: config.c,v 1.10 2001-12-31 20:01:17 srittau Exp $
+ *
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
-#endif
+#endif /* HAVE_CONFIG_H */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <sys/param.h>
+#ifdef TRU64
+#include <sys/mbuf.h>
+#include <net/route.h>
+#endif /* TRU64 */
#include <net/if.h>
#include <netatalk/at.h>
#include <netatalk/endian.h>
#include <atalk/paths.h>
#include <atalk/util.h>
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <ctype.h>
+
+/* STDC check */
+#if STDC_HEADERS
+#include <string.h>
+#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 <fcntl.h>
-#include <errno.h>
+#endif /* HAVE_FCNTL_H */
#ifdef __svr4__
#include <sys/sockio.h>
#include <sys/stropts.h>
-#endif __svr4__
+#endif /* __svr4__ */
#include "interface.h"
#include "multicast.h"
#ifndef IFF_SLAVE /* a little backward compatibility */
#define IFF_SLAVE 0
-#endif
+#endif /* IFF_SLAVE */
int router(), dontroute(), seed(), phase(), net(), addr(), zone();
{ "zone", zone },
};
-static char **
-parseline( line )
- char *line;
+#define ARGV_CHUNK_SIZE 128
+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 );
+ 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 );
}
-writeconf( cf )
+int writeconf( cf )
char *cf;
{
struct stat st;
if (( p = strrchr( path, '/' )) == NULL ) {
strcpy( newpath, _PATH_ATALKDTMP );
} else {
- sprintf( newpath, "%.*s/%s", p - path, path, _PATH_ATALKDTMP );
+ 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 );
+ syslog( LOG_ERR, "%s: %s", newpath, strerror(errno) );
return( -1 );
}
if (( newconf = fdopen( fd, "w" )) == NULL ) {
- syslog( LOG_ERR, "fdreopen %s: %m", newpath );
+ syslog( LOG_ERR, "fdreopen %s: %s", newpath, strerror(errno) );
return( -1 );
}
if (( conf = fopen( path, "r" )) == NULL && cf ) {
- syslog( LOG_ERR, "%s: %m", path );
+ syslog( LOG_ERR, "%s: %s", path, strerror(errno) );
return( -1 );
}
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" );
+ syslog( LOG_ERR, "fputs: %s", strerror(errno) );
return( -1 );
}
+ freeline( argv );
continue;
}
fclose( newconf );
if ( rename( newpath, path ) < 0 ) {
- syslog( LOG_ERR, "rename %s to %s: %m", newpath, path );
+ syslog( LOG_ERR, "rename %s to %s: %s", newpath, path, strerror(errno) );
return( -1 );
}
return( 0 );
* zone for an interface is the first zone encountered for that
* interface.
*/
-readconf( cf )
+int readconf( cf )
char *cf;
{
struct ifreq ifr;
fclose(conf);
return -1;
}
-#endif __svr4__
+#endif /* __svr4__ */
while ( fgets( line, sizeof( line ), conf ) != NULL ) {
if (( argv = parseline( line )) == NULL ) {
* Check that av[ 0 ] is a valid interface.
* Not possible under sysV.
*/
- strcpy( ifr.ifr_name, argv[ 0 ] );
+ strncpy( ifr.ifr_name, argv[ 0 ], sizeof(ifr.ifr_name) );
+ ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
/* for devices that don't support appletalk */
if ((ioctl(s, SIOCGIFADDR, &ifr) < 0) && (errno == ENODEV)) {
if ((ifr.ifr_flags & IFF_MULTICAST) == 0)
fprintf(stderr, "%s: multicast may not work properly.\n",
ifr.ifr_name);
-#endif
+#endif /* IFF_MULTICAST */
/* configure hw multicast for this interface. */
if (addmulti(ifr.ifr_name, NULL) < 0) {
fprintf(stderr, "Can't configure multicast.\n");
goto read_conf_err;
}
-#endif __svr4__
+#endif /* __svr4__ */
if (( niface = newiface( argv[ 0 ] )) == NULL ) {
perror( "newiface" );
#ifndef __svr4__
close( s );
-#endif
+#endif /* __svr4__ */
fclose( conf );
read_conf_err:
#ifndef __svr4__
close(s);
-#endif
+#endif /* __svr4__ */
fclose(conf);
return -1;
}
/*ARGSUSED*/
-router( iface, av )
+int router( iface, av )
struct interface *iface;
char **av;
{
}
/*ARGSUSED*/
-dontroute( iface, av )
+int dontroute( iface, av )
struct interface *iface;
char **av;
{
}
/*ARGSUSED*/
-seed( iface, av )
+int seed( iface, av )
struct interface *iface;
char **av;
{
return( 1 );
}
-phase( iface, av )
+int phase( iface, av )
struct interface *iface;
char **av;
{
return( 2 );
}
-net( iface, av )
+int net( iface, av )
struct interface *iface;
char **av;
{
}
net = atoi( nrange );
if ( net < 0 || net >= 0xffff ) {
- fprintf( stderr, "Bad network: %d\n" );
+ fprintf( stderr, "Bad network: %d\n", net );
return -1;
}
if ( stop != 0 ) {
net = atoi( stop );
if ( net < 0 || net >= 0xffff ) {
- fprintf( stderr, "Bad network: %d\n" );
+ fprintf( stderr, "Bad network: %d\n", net );
return -1;
}
}
return( 2 );
}
-addr( iface, av )
+int addr( iface, av )
struct interface *iface;
char **av;
{
return( 2 );
}
-zone( iface, av )
+int zone( iface, av )
struct interface *iface;
char **av;
{
* Get the configuration from the kernel. Only called if there's no
* configuration.
*/
-getifconf()
+int getifconf()
{
struct interface *iface, *niface;
struct ifreq ifr;
if ((ifr.ifr_flags & IFF_MULTICAST) == 0)
fprintf(stderr, "%s: multicast may not work correctly.\n",
ifr.ifr_name);
-#endif
+#endif /* IFF_MULTICAST */
if (addmulti(ifr.ifr_name, NULL) < 0) {
fprintf(stderr, "%s: disabled.\n", ifr.ifr_name);
* Allocate a new interface structure. Centralized here so we can change
* the interface structure and have it updated nicely.
*/
- struct interface *
-newiface( name )
+
+struct interface *newiface( name )
const char *name;
{
struct interface *niface;
strncpy( niface->i_name, name, sizeof(niface->i_name));
#ifdef BSD4_4
niface->i_addr.sat_len = sizeof( struct sockaddr_at );
-#endif BSD4_4
+#endif /* BSD4_4 */
niface->i_addr.sat_family = AF_APPLETALK;
#ifdef BSD4_4
niface->i_caddr.sat_len = sizeof( struct sockaddr_at );
-#endif BSD4_4
+#endif /* BSD4_4 */
niface->i_caddr.sat_family = AF_APPLETALK;
return( niface );
}
#ifdef __svr4__
- int
-plumb()
+int plumb()
{
struct interface *iface;
char device[ MAXPATHLEN + 1], *p;
return( 0 );
}
-#endif __svr4__
+#endif /* __svr4__ */