/* * Code to convert a stream input into a dynamic array * that can be parsed as argc and argv. * * Authors: Horms * * Released under the terms of the GNU GPL * * ChangeLog * Horms : scanf Glibc under Red Hat 7 does not appear * to return EOF when input ends. Fall through * code has been added to handle this case correctly */ #include "config_stream.h" /********************************************************************** * config_stream_read * Read in a config file and put elements in a dynamic array * pre: stream: stream to read configuration from * return: dynamic array whose elements are the space delimited * tokens read from the stream. Result is returned * once a newline is reached so multiple calls * will be required to read an entire stream. * Everything including and after a hash (#) on a line is * ignored **********************************************************************/ dynamic_array_t * config_stream_read(FILE * stream, const char *first_element) { char token[MAX_LINE_LENGTH]; char tail[2]; char format[MAX_LINE_LENGTH]; char format_whitespace[MAX_LINE_LENGTH]; int status; int ntoken; int comment = 0; char *s; int c; int flag; dynamic_array_t *a; if ((a = dynamic_array_create((size_t) 0)) == NULL) { perror("config_file_read: dynamic_array_create"); return (NULL); } /*insert a argv[0] into the dynamic array */ if ((a = dynamic_array_add_element(a, (first_element != NULL ? first_element : ""), DESTROY_STR, DUP_STR)) == NULL) { perror("config_file_read: dynamic_array_add_element"); return (NULL); } sprintf(format, "%%%d[^ \t\n\r]%%1[ \t\n\r]", MAX_LINE_LENGTH); sprintf(format_whitespace, "%%%d[ \t\r]%%1[\n]", MAX_LINE_LENGTH); ntoken = 0; while ((status = fscanf(stream, format, token, tail)) != EOF) { if (status == 0) { flag = 1; while (flag) { c = fgetc(stream); switch (c) { case EOF: dynamic_array_destroy(a, DESTROY_STR); return (NULL); case '\n': return (a); case '\t': case '\r': case ' ': break; default: ungetc(c, stream); flag = 0; } } continue; } if (!comment && strcmp(token, "ipvsadm")) { ntoken++; if ((a = dynamic_array_add_element(a, token, DESTROY_STR, DUP_STR)) == NULL) { perror("config_file_read: dynamic_array_add_element"); dynamic_array_destroy(a, DESTROY_STR); return (NULL); } } if ((s = strrchr(tail, '\n')) != NULL) { return (a); } if (!comment) { comment = (strchr((s != NULL ? s : tail), '#') == NULL) ? 0 : 1; } } if (ntoken == 0) { dynamic_array_destroy(a, DESTROY_STR); return (NULL); } return (a); }