/*
- * $Id: config.c,v 1.6 2001-09-06 20:00:59 rufustfirefly Exp $
+ * $Id: config.c,v 1.6.2.1 2002-01-14 02:54:47 srittau Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#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
#endif /* ! HAVE_MEMCPY */
#endif /* STDC_HEADERS */
-#include <ctype.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif /* HAVE_FCNTL_H */
-#include <errno.h>
#ifdef __svr4__
#include <sys/sockio.h>
{ "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 );
}
int writeconf( cf )
syslog( LOG_ERR, "fputs: %m" );
return( -1 );
}
+ freeline( argv );
continue;
}
* 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)) {
#define IFACE_NUM 5
/* we leave all of the ioctl's to the application */
-static int addname(char **list, int *i, int *length, const char *name)
+static int addname(char **list, int *i, const char *name)
{
/* if we've run out of room, allocate some more. just return
}
-static int getifaces(const int sockfd, char ***list, int *length)
+static int getifaces(const int sockfd, char ***list)
{
#ifdef HAVE_IFNAMEINDEX
struct if_nameindex *ifstart, *ifs;
new = (char **) malloc((sizeof(ifs)/sizeof(struct if_nameindex) + 1) * sizeof(char *));
while (ifs && ifs->if_name) {
/* just bail if there's a problem */
- if (addname(new, &i, length, ifs->if_name) < 0)
+ if (addname(new, &i, ifs->if_name) < 0)
break;
ifs++;
}
nextifr = (struct ifreq *)((caddr_t)ifr + ifrsize );
/* just bail if there's a problem */
- if (addname(new, &i, length, ifr->ifr_name) < 0)
+ if (addname(new, &i, ifr->ifr_name) < 0)
break;
}
*list = new;
char **getifacelist()
{
char **list;
- int length, i, fd;
+ int i, fd;
if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
return NULL;
- if ((i = getifaces(fd, &list, &length)) == 0) {
+ if ((i = getifaces(fd, &list)) == 0) {
free(list);
close(fd);
return NULL;