X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Flibsmooth%2Fvarval.c;fp=src%2Flibsmooth%2Fvarval.c;h=9a64365af7a823f36aa060c8e3f91cb8098fbcb5;hb=765b17bc52643f84c03b1507411e1d2c394c141d;hp=0000000000000000000000000000000000000000;hpb=fa6c8fdcd04e87cfbef73bdf7ed2548b82af3864;p=ipfire-2.x.git diff --git a/src/libsmooth/varval.c b/src/libsmooth/varval.c new file mode 100644 index 0000000000..9a64365af7 --- /dev/null +++ b/src/libsmooth/varval.c @@ -0,0 +1,197 @@ +/* SmoothWall libsmooth. + * + * This program is distributed under the terms of the GNU General Public + * Licence. See the file COPYING for details. + * + * (c) Lawrence Manning, 2001 + * Contains functions for manipulation files full of VAR=VAL pairs. + * + * 2003-07-27 Robert Kerr - Added cooperative file locking to prevent any + * clashes between setuid programs reading configuration and cgi scripts + * trying to write it + * + */ + +#include "libsmooth.h" + +/* Sets up the list. First entry is a dummy one to avoid having to special + * case empty lists. */ +struct keyvalue *initkeyvalues(void) +{ + struct keyvalue *head = malloc(sizeof(struct keyvalue)); + + strcpy(head->key, "KEY"); + strcpy(head->value, "VALUE"); + head->next = NULL; + + return head; +} + +/* Splats all the entries in a list. */ +void freekeyvalues(struct keyvalue *head) +{ + struct keyvalue *cur = head->next; + struct keyvalue *next; + + while (cur) + { + next = cur->next; + free(cur); + cur = next; + } +} + +/* Reads from a file into a new list. Uses appendkeyvalue to add entries. + * Will bomb out on a error (eg bad format line). */ +int readkeyvalues(struct keyvalue *head, char *filename) +{ + FILE *file; + char buffer[STRING_SIZE]; + char *temp; + char *key, *value; + + if (!(file = fopen(filename, "r"))) + return 0; + + if (flock(fileno(file), LOCK_SH)) + { + fclose(file); + return 0; + } + + while (fgets(buffer, STRING_SIZE, file)) + { + temp = buffer; + while (*temp) + { + if (*temp =='\n') *temp = '\0'; + temp++; + } + if (!strlen(buffer)) + continue; + if (!(temp = strchr(buffer, '='))) + { + flock(fileno(file), LOCK_UN); + fclose(file); + return 0; + } + *temp = '\0'; + key = buffer; value = temp + 1; + /* See if string is quoted. If so, skip first quote, and + * nuke the one at the end. */ + if (value[0] == '\'') + { + value++; + if ((temp = strrchr(value, '\''))) + *temp = '\0'; + else + { + flock(fileno(file), LOCK_UN); + fclose(file); + return 0; + } + } + if (strlen(key)) + appendkeyvalue(head, key, value); + } + + flock(fileno(file), LOCK_UN); + fclose(file); + + return 1; +} + +/* Writes out a list to a file. Easy. */ +int writekeyvalues(struct keyvalue *head, char *filename) +{ + FILE *file; + struct keyvalue *cur = head->next; + + if (!(file = fopen(filename, "w"))) + return 0; + + if (flock(fileno(file), LOCK_EX)) + { + fclose(file); + return 0; + } + + + while (cur) + { + /* No space in value? If there is, we need to quote the value + * so the shell can read it. */ + if (!strchr(cur->value, ' ')) + fprintf(file, "%s=%s\n", cur->key, cur->value); + else + fprintf(file, "%s=\'%s\'\n", cur->key, cur->value); + cur = cur->next; + } + flock(fileno(file), LOCK_UN); + fclose(file); + + return 1; +} + +/* Finds a key and copies the value back. value must be at least STRING_SIZE + * long. Would be nice to have a func that just returns a pointer to the value? + */ +int findkey(struct keyvalue *head, char *key, char *value) +{ + struct keyvalue *cur = head->next; + + while (cur) + { + if (strcmp(key, cur->key) == 0) + { + strncpy(value, cur->value, STRING_SIZE); + value[STRING_SIZE-1] = '\0'; + return 1; + } + cur = cur->next; + } + + return 0; +} + +/* Appends a entry. Not very efficent because it rescans the list looking + * for the end. Maybe fix this later. */ +void appendkeyvalue(struct keyvalue *head, char *key, char *value) +{ + struct keyvalue *new = malloc(sizeof(struct keyvalue)); + struct keyvalue *cur = head->next; + struct keyvalue *tail = head; + + strncpy(new->key, key, STRING_SIZE); + strncpy(new->value, value, STRING_SIZE); + new->key[STRING_SIZE-1] = '\0'; + new->value[STRING_SIZE-1] = '\0'; + new->next = NULL; + + while (cur) + { + tail = cur; + cur = cur->next; + } + tail->next = new; +} + +/* Otherwrites a key with a new value, or if it dosn't exist, appends it + * on the end. */ +void replacekeyvalue(struct keyvalue *head, char *key, char *value) +{ + struct keyvalue *cur = head->next; + + while (cur) + { + if (strcmp(cur->key, key) == 0) + { + strncpy(cur->value, value, STRING_SIZE); + cur->value[STRING_SIZE-1] = '\0'; + return; + } + cur = cur->next; + } + + appendkeyvalue(head, key, value); +}