svn commit: trunk/busybox: include libbb miscutils networking

vda at busybox.net vda at busybox.net
Wed Jul 16 22:12:21 UTC 2008


Author: vda
Date: 2008-07-16 15:12:18 -0700 (Wed, 16 Jul 2008)
New Revision: 22848

Log:
update of config file parser from Vladimir



Modified:
   trunk/busybox/include/libbb.h
   trunk/busybox/libbb/parse_config.c
   trunk/busybox/miscutils/crond.c
   trunk/busybox/networking/nameif.c


Changeset:
Modified: trunk/busybox/include/libbb.h
===================================================================
--- trunk/busybox/include/libbb.h	2008-07-16 21:55:03 UTC (rev 22847)
+++ trunk/busybox/include/libbb.h	2008-07-16 22:12:18 UTC (rev 22848)
@@ -985,30 +985,20 @@
 char *bb_askpass(int timeout, const char * prompt) FAST_FUNC;
 int bb_ask_confirmation(void) FAST_FUNC;
 
-extern int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC;
+int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC;
 
 /*
  * Uniform config file parser helpers
  */
-#define PARSER_STDIO_BASED 1
-#if !PARSER_STDIO_BASED
 typedef struct parser_t {
-	char *data;
-	char *line;
-	int lineno;
-} parser_t;
-extern char* config_open(parser_t *parser, const char *filename) FAST_FUNC;
-#else
-typedef struct parser_t {
 	FILE *fp;
-	char *line;
+	char *line, *data;
 	int lineno;
 } parser_t;
-extern FILE* config_open(parser_t *parser, const char *filename) FAST_FUNC;
-#endif
+FILE* config_open(parser_t *parser, const char *filename) FAST_FUNC;
 /* TODO: add define magic to collapse ntokens/mintokens/comment into one int param */
-extern char* config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment) FAST_FUNC;
-extern void config_close(parser_t *parser) FAST_FUNC;
+int config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment) FAST_FUNC;
+void config_close(parser_t *parser) FAST_FUNC;
 
 /* Concatenate path and filename to new allocated buffer.
  * Add "/" only as needed (no duplicate "//" are produced).

Modified: trunk/busybox/libbb/parse_config.c
===================================================================
--- trunk/busybox/libbb/parse_config.c	2008-07-16 21:55:03 UTC (rev 22847)
+++ trunk/busybox/libbb/parse_config.c	2008-07-16 22:12:18 UTC (rev 22848)
@@ -31,101 +31,6 @@
 
 */
 
-#if !PARSER_STDIO_BASED
-
-char* FAST_FUNC config_open(parser_t *parser, const char *filename)
-{
-	// empty file configures nothing!
-	char *data = xmalloc_open_read_close(filename, NULL);
-	if (!data)
-		return data;
-
-	// convert 0x5c 0x0a (backslashes at the very end of line) to 0x20 0x20 (spaces)
-	for (char *s = data; (s = strchr(s, '\\')) != NULL; ++s)
-		if ('\n' == s[1]) {
-			s[0] = s[1] = ' ';
-		}
-
-	// init parser
-	parser->line = parser->data = data;
-	parser->lineno = 0;
-
-	return data;
-}
-
-void FAST_FUNC config_close(parser_t *parser)
-{
-	// for now just free config data
-	free(parser->data);
-}
-
-char* FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment)
-{
-	char *ret, *line;
-	int noreduce = (ntokens<0); // do not treat subsequent delimiters as one delimiter
-	if (ntokens < 0)
-		ntokens = -ntokens;
-	ret = line = parser->line;
-	// nullify tokens
-	memset(tokens, 0, sizeof(void *) * ntokens);
-	// now split to lines
-	while (*line) {
-		int token_num = 0;
-		// limit the line
-		char *ptr = strchrnul(line, '\n');
-		*ptr++ = '\0';
-		// line number
-		parser->lineno++;
-		// comments mean EOLs
-		if (comment)
-			*strchrnul(line, comment) = '\0';
-		// skip leading delimiters
-		while (*line && strchr(delims, *line))
-			line++;
-		// skip empty lines
-		if (*line) {
-			char *s;
-			// now split line to tokens
-			s = line;
-			while (s) {
-				char *p;
-				// get next token
-				if (token_num+1 >= ntokens)
-					break;
-				p = s;
-				while (*p && !strchr(delims, *p))
-					p++;
-				if (!*p)
-					break;
-				*p++ = '\0';
-				// pin token
-				if (noreduce || *s) {
-					tokens[token_num++] = s;
-//bb_error_msg("L[%d] T[%s]", token_num, s);
-				}
-				s = p;
-	 		}
-			// non-empty remainder is also a token. So if ntokens == 0, we just return the whole line
-			if (s && (noreduce || *s))
-				tokens[token_num++] = s;
-			// sanity check: have we got all required tokens?
-			if (token_num < mintokens)
-				bb_error_msg_and_die("bad line %u, %d tokens found, %d needed", parser->lineno, token_num, mintokens);
-			// advance data for the next call
-			line = ptr;
-			break;
-		}
-		// line didn't contain any token -> try next line
-		ret = line = ptr;
- 	}
-	parser->line = line;
-
-	// return current line. caller must check *ret to determine whether to continue
-	return ret;
-}
-
-#else // stdio-based
-
 FILE* FAST_FUNC config_open(parser_t *parser, const char *filename)
 {
 	// empty file configures nothing!
@@ -142,10 +47,12 @@
 
 void FAST_FUNC config_close(parser_t *parser)
 {
+	free(parser->line);
+	free(parser->data);
 	fclose(parser->fp);
 }
 
-char* FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment)
+int FAST_FUNC config_read(parser_t *parser, char **tokens, int ntokens, int mintokens, const char *delims, char comment)
 {
 	char *line, *q;
 	int token_num, len;
@@ -160,6 +67,8 @@
 	// free used line
 	free(parser->line);
 	parser->line = NULL;
+	free(parser->data);
+	parser->data = NULL;
 
 	while (1) {
 		int n;
@@ -211,6 +120,7 @@
 
 	// store line
 	parser->line = line = xrealloc(line, len + 1);
+	parser->data = xstrdup(line);
 
 	// now split line to tokens
 //TODO: discard consecutive delimiters?
@@ -241,7 +151,5 @@
 		bb_error_msg_and_die("bad line %u: %d tokens found, %d needed",
 				parser->lineno, token_num, mintokens);
 
-	return parser->line; // maybe token_num instead?
+	return token_num;
 }
-
-#endif

Modified: trunk/busybox/miscutils/crond.c
===================================================================
--- trunk/busybox/miscutils/crond.c	2008-07-16 21:55:03 UTC (rev 22847)
+++ trunk/busybox/miscutils/crond.c	2008-07-16 22:12:18 UTC (rev 22848)
@@ -304,7 +304,7 @@
 	/* "Jan""Feb""Mar""Apr""May""Jun""Jul""Aug""Sep""Oct""Nov""Dec" */
 ;
 
-static char *ParseField(char *user, char *ary, int modvalue, int off,
+static void ParseField(char *user, char *ary, int modvalue, int off,
 				const char *names, char *ptr)
 /* 'names' is a pointer to a set of 3-char abbreviations */
 {
@@ -312,11 +312,11 @@
 	int n1 = -1;
 	int n2 = -1;
 
-	if (base == NULL) {
-		return NULL;
-	}
+	// this can't happen due to config_read()
+	/*if (base == NULL)
+		return;*/
 
-	while (!isspace(*ptr)) {
+	while (1) {
 		int skip = 0;
 
 		/* Handle numeric digit or symbol or '*' */
@@ -352,8 +352,7 @@
 
 		/* handle optional range '-' */
 		if (skip == 0) {
-			crondlog(WARN9 "user %s: parse error at %s", user, base);
-			return NULL;
+			goto err;
 		}
 		if (*ptr == '-' && n2 < 0) {
 			++ptr;
@@ -388,8 +387,7 @@
 					s0 = skip;
 				}
 				if (--failsafe == 0) {
-					crondlog(WARN9 "user %s: parse error at %s", user, base);
-					return NULL;
+					goto err;
 				}
 			} while (n1 != n2);
 
@@ -402,9 +400,10 @@
 		n2 = -1;
 	}
 
-	if (!isspace(*ptr)) {
+	if (*ptr) {
+ err:
 		crondlog(WARN9 "user %s: parse error at %s", user, base);
-		return NULL;
+		return;
 	}
 
 	if (DebugOpt && (LogLevel <= 5)) { /* like LVL5 */
@@ -414,7 +413,6 @@
 			fprintf(stderr, "%d", (unsigned char)ary[i]);
 		fputc('\n', stderr);
 	}
-	return skip_whitespace(ptr);
 }
 
 static void FixDayDow(CronLine *line)
@@ -445,11 +443,10 @@
 
 static void SynchronizeFile(const char *fileName)
 {
-	FILE *fi;
+	struct parser_t parser;
 	struct stat sbuf;
-	int maxEntries;
 	int maxLines;
-	char buf[1024];
+	char *tokens[6];
 #if ENABLE_FEATURE_CROND_CALL_SENDMAIL
 	char *mailTo = NULL;
 #endif
@@ -458,57 +455,44 @@
 		return;
 
 	DeleteFile(fileName);
-	fi = fopen(fileName, "r");
-	if (!fi)
+	if (!config_open(&parser, fileName))
 		return;
 
-	maxEntries = MAXLINES;
-	if (strcmp(fileName, "root") == 0) {
-		maxEntries = 65535;
-	}
-	maxLines = maxEntries * 10;
+	maxLines = (strcmp(fileName, "root") == 0) ? 65535 : MAXLINES;
 
-	if (fstat(fileno(fi), &sbuf) == 0 && sbuf.st_uid == DaemonUid) {
+	if (fstat(fileno(parser.fp), &sbuf) == 0 && sbuf.st_uid == DaemonUid) {
 		CronFile *file = xzalloc(sizeof(CronFile));
 		CronLine **pline;
+		int n;
 
 		file->cf_User = xstrdup(fileName);
 		pline = &file->cf_LineBase;
 
-		while (fgets(buf, sizeof(buf), fi) != NULL && --maxLines) {
+		while (--maxLines && (n=config_read(&parser, tokens, 6, 0, " \t", '#')) > 0) {
 			CronLine *line;
-			char *ptr;
 
-			trim(buf);
-			if (buf[0] == '\0' || buf[0] == '#') {
-				continue;
-			}
-			if (--maxEntries == 0) {
-				break;
-			}
 			if (DebugOpt) {
-				crondlog(LVL5 "user:%s entry:%s", fileName, buf);
+				crondlog(LVL5 "user:%s entry:%s", fileName, parser.data);
 			}
+
 			/* check if line is setting MAILTO= */
-			if (0 == strncmp("MAILTO=", buf, 7)) {
+			if (0 == strncmp(tokens[0], "MAILTO=", 7)) {
 #if ENABLE_FEATURE_CROND_CALL_SENDMAIL
 				free(mailTo);
-				mailTo = (buf[7]) ? xstrdup(buf+7) : NULL;
+				mailTo = (tokens[0][7]) ? xstrdup(&tokens[0][7]) : NULL;
 #endif /* otherwise just ignore such lines */
 				continue;
 			}
+			/* check if a minimum of tokens is specified */
+			if (n < 5)
+				continue;
 			*pline = line = xzalloc(sizeof(CronLine));
 			/* parse date ranges */
-			ptr = ParseField(file->cf_User, line->cl_Mins, 60, 0, NULL, buf);
-			ptr = ParseField(file->cf_User, line->cl_Hrs, 24, 0, NULL, ptr);
-			ptr = ParseField(file->cf_User, line->cl_Days, 32, 0, NULL, ptr);
-			ptr = ParseField(file->cf_User, line->cl_Mons, 12, -1, MonAry, ptr);
-			ptr = ParseField(file->cf_User, line->cl_Dow, 7, 0, DowAry, ptr);
-			/* check failure */
-			if (ptr == NULL) {
-				free(line);
-				continue;
-			}
+			ParseField(file->cf_User, line->cl_Mins, 60, 0, NULL, tokens[0]);
+			ParseField(file->cf_User, line->cl_Hrs, 24, 0, NULL, tokens[1]);
+			ParseField(file->cf_User, line->cl_Days, 32, 0, NULL, tokens[2]);
+			ParseField(file->cf_User, line->cl_Mons, 12, -1, MonAry, tokens[3]);
+			ParseField(file->cf_User, line->cl_Dow, 7, 0, DowAry, tokens[4]);
 			/*
 			 * fix days and dow - if one is not "*" and the other
 			 * is "*", the other is set to 0, and vise-versa
@@ -519,22 +503,23 @@
 			line->cl_MailTo = xstrdup(mailTo);
 #endif
 			/* copy command */
-			line->cl_Shell = xstrdup(ptr);
+			line->cl_Shell = xstrdup(tokens[5]);
 			if (DebugOpt) {
-				crondlog(LVL5 " command:%s", ptr);
+				crondlog(LVL5 " command:%s", tokens[5]);
 			}
 			pline = &line->cl_Next;
+//bb_error_msg("M[%s]F[%s][%s][%s][%s][%s][%s]", mailTo, tokens[0], tokens[1], tokens[2], tokens[3], tokens[4], tokens[5]);
 		}
 		*pline = NULL;
 
 		file->cf_Next = FileBase;
 		FileBase = file;
 
-		if (maxLines == 0 || maxEntries == 0) {
+		if (maxLines == 0) {
 			crondlog(WARN9 "user %s: too many lines", fileName);
 		}
 	}
-	fclose(fi);
+	config_close(&parser);
 }
 
 static void CheckUpdates(void)

Modified: trunk/busybox/networking/nameif.c
===================================================================
--- trunk/busybox/networking/nameif.c	2008-07-16 21:55:03 UTC (rev 22847)
+++ trunk/busybox/networking/nameif.c	2008-07-16 22:12:18 UTC (rev 22848)
@@ -160,21 +160,13 @@
 			prepend_new_eth_table(&clist, ifname, *argv++);
 		}
 	} else {
-		ifh = xfopen(fname, "r");
-		while ((line = xmalloc_fgets(ifh)) != NULL) {
-			char *next;
-
-			line_ptr = skip_whitespace(line);
-			if ((line_ptr[0] == '#') || (line_ptr[0] == '\n'))
-				goto read_next_line;
-			next = skip_non_whitespace(line_ptr);
-			if (*next)
-				*next++ = '\0';
-			prepend_new_eth_table(&clist, line_ptr, next);
-			read_next_line:
-			free(line);
+		struct parser_t parser;
+		if (config_open(&parser, fname)) {
+			char *tokens[2];
+			while (config_read(&parser, tokens, 2, 2, " \t", '#'))
+				prepend_new_eth_table(&clist, tokens[0], tokens[1]);
+			config_close(&parser);
 		}
-		fclose(ifh);
 	}
 
 	ctl_sk = xsocket(PF_INET, SOCK_DGRAM, 0);




More information about the busybox-cvs mailing list