]> arthur.barton.de Git - netatalk.git/blobdiff - etc/atalkd/config.c
Re-added const qualifier to the argument to parseline. Instead, introduce a
[netatalk.git] / etc / atalkd / config.c
index 83ab824b892be9b56f586b6fddabb17649b87f3d..14d7f389977bb626e5e42fd305d2953b357320e7 100644 (file)
@@ -1,11 +1,13 @@
 /*
+ * $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"
@@ -38,7 +63,7 @@
 
 #ifndef IFF_SLAVE /* a little backward compatibility */
 #define IFF_SLAVE 0
-#endif
+#endif /* IFF_SLAVE */
 
 int    router(), dontroute(), seed(), phase(), net(), addr(), zone();
 
@@ -55,57 +80,101 @@ static struct param {
     { "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;
@@ -134,19 +203,19 @@ writeconf( cf )
     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 );
     }
 
@@ -155,9 +224,10 @@ 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" );
+               syslog( LOG_ERR, "fputs: %s", strerror(errno) );
                return( -1 );
            }
+           freeline( argv );
            continue;
        }
 
@@ -201,7 +271,7 @@ writeconf( cf )
     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 );
@@ -229,7 +299,7 @@ writeconf( cf )
  * zone for an interface is the first zone encountered for that
  * interface.
  */
-readconf( cf )
+int readconf( cf )
     char               *cf;
 {
     struct ifreq       ifr;
@@ -253,7 +323,7 @@ readconf( cf )
        fclose(conf);
        return -1;
     }
-#endif __svr4__
+#endif /* __svr4__ */
 
     while ( fgets( line, sizeof( line ), conf ) != NULL ) {
        if (( argv = parseline( line )) == NULL ) {
@@ -265,7 +335,8 @@ readconf( cf )
         * 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)) {
@@ -287,7 +358,7 @@ readconf( cf )
        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) {
@@ -295,7 +366,7 @@ readconf( cf )
          fprintf(stderr, "Can't configure multicast.\n");
          goto read_conf_err;
        }
-#endif __svr4__
+#endif /* __svr4__ */
 
        if (( niface = newiface( argv[ 0 ] )) == NULL ) {
            perror( "newiface" );
@@ -347,7 +418,7 @@ readconf( cf )
 
 #ifndef __svr4__
     close( s );
-#endif
+#endif /* __svr4__ */
 
     fclose( conf );
 
@@ -366,13 +437,13 @@ readconf( cf )
 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;
 {
@@ -396,7 +467,7 @@ router( iface, av )
 }
 
 /*ARGSUSED*/
-dontroute( iface, av )
+int dontroute( iface, av )
     struct interface   *iface;
     char               **av;
 {
@@ -411,7 +482,7 @@ dontroute( iface, av )
 }
 
 /*ARGSUSED*/
-seed( iface, av )
+int seed( iface, av )
     struct interface   *iface;
     char               **av;
 {
@@ -429,7 +500,7 @@ seed( iface, av )
     return( 1 );
 }
 
-phase( iface, av )
+int phase( iface, av )
     struct interface   *iface;
     char               **av;
 {
@@ -457,7 +528,7 @@ phase( iface, av )
     return( 2 );
 }
 
-net( iface, av )
+int net( iface, av )
     struct interface   *iface;
     char               **av;
 {
@@ -475,7 +546,7 @@ net( iface, av )
     }
     net = atoi( nrange );
     if ( net < 0 || net >= 0xffff ) {
-       fprintf( stderr, "Bad network: %d\n" );
+       fprintf( stderr, "Bad network: %d\n", net );
        return -1;
     }
 
@@ -501,7 +572,7 @@ net( iface, av )
        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;
            }
        }
@@ -527,7 +598,7 @@ net( iface, av )
     return( 2 );
 }
 
-addr( iface, av )
+int addr( iface, av )
     struct interface   *iface;
     char               **av;
 {
@@ -563,7 +634,7 @@ addr( iface, av )
     return( 2 );
 }
 
-zone( iface, av )
+int zone( iface, av )
     struct interface   *iface;
     char               **av;
 {
@@ -603,7 +674,7 @@ zone( iface, av )
  * Get the configuration from the kernel. Only called if there's no
  * configuration.
  */
-getifconf()
+int getifconf()
 {
     struct interface   *iface, *niface;
     struct ifreq        ifr;
@@ -647,7 +718,7 @@ getifconf()
        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);
@@ -682,8 +753,8 @@ getifconf()
  * 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;
@@ -695,18 +766,17 @@ newiface( name )
     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;
@@ -754,4 +824,4 @@ plumb()
 
     return( 0 );
 }
-#endif __svr4__
+#endif /* __svr4__ */