]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/install+setup/libsmooth/varval.c
Ich hab mal ein bisschen die Arbeit vom Cuebernommen :D
[people/pmueller/ipfire-2.x.git] / src / install+setup / libsmooth / varval.c
CommitLineData
cd1a2927
MT
1/* SmoothWall libsmooth.\r
2 *\r
3 * This program is distributed under the terms of the GNU General Public\r
4 * Licence. See the file COPYING for details.\r
5 *\r
6 * (c) Lawrence Manning, 2001\r
7 * Contains functions for manipulation files full of VAR=VAL pairs.\r
8 * \r
9 * 2003-07-27 Robert Kerr - Added cooperative file locking to prevent any\r
10 * clashes between setuid programs reading configuration and cgi scripts\r
11 * trying to write it\r
12 *\r
13 * $Id: varval.c,v 1.4 2003/12/11 11:25:53 riddles Exp $\r
14 * \r
15 */\r
16 \r
17#include "libsmooth.h"\r
18\r
19/* Sets up the list. First entry is a dummy one to avoid having to special\r
20 * case empty lists. */\r
21struct keyvalue *initkeyvalues(void)\r
22{\r
23 struct keyvalue *head = malloc(sizeof(struct keyvalue));\r
24 \r
25 strcpy(head->key, "KEY");\r
26 strcpy(head->value, "VALUE");\r
27 head->next = NULL;\r
28 \r
29 return head;\r
30}\r
31\r
32/* Splats all the entries in a list. */\r
33void freekeyvalues(struct keyvalue *head)\r
34{\r
35 struct keyvalue *cur = head->next;\r
36 struct keyvalue *next;\r
37 \r
38 while (cur)\r
39 {\r
40 next = cur->next;\r
41 free(cur);\r
42 cur = next;\r
43 }\r
44}\r
45\r
46/* Reads from a file into a new list. Uses appendkeyvalue to add entries.\r
47 * Will bomb out on a error (eg bad format line). */\r
48int readkeyvalues(struct keyvalue *head, char *filename)\r
49{\r
50 FILE *file;\r
51 char buffer[STRING_SIZE];\r
52 char *temp;\r
53 char *key, *value;\r
54 \r
55 if (!(file = fopen(filename, "r")))\r
56 return 0;\r
57 \r
58 if (flock(fileno(file), LOCK_SH))\r
59 {\r
60 fclose(file);\r
61 return 0;\r
62 }\r
63 \r
64 while (fgets(buffer, STRING_SIZE, file))\r
65 {\r
66 temp = buffer;\r
67 while (*temp)\r
68 {\r
69 if (*temp =='\n') *temp = '\0';\r
70 temp++;\r
71 }\r
72 if (!strlen(buffer))\r
73 continue;\r
74 if (!(temp = strchr(buffer, '=')))\r
75 {\r
76 flock(fileno(file), LOCK_UN);\r
77 fclose(file);\r
78 return 0;\r
79 }\r
80 *temp = '\0';\r
81 key = buffer; value = temp + 1;\r
82 /* See if string is quoted. If so, skip first quote, and\r
83 * nuke the one at the end. */\r
84 if (value[0] == '\'')\r
85 {\r
86 value++;\r
87 if ((temp = strrchr(value, '\'')))\r
88 *temp = '\0';\r
89 else\r
90 {\r
91 flock(fileno(file), LOCK_UN);\r
92 fclose(file);\r
93 return 0;\r
94 }\r
95 }\r
96 if (strlen(key))\r
97 appendkeyvalue(head, key, value);\r
98 }\r
99 \r
100 flock(fileno(file), LOCK_UN);\r
101 fclose(file);\r
102\r
103 return 1;\r
104}\r
105\r
106/* Writes out a list to a file. Easy. */\r
107int writekeyvalues(struct keyvalue *head, char *filename)\r
108{\r
109 FILE *file;\r
110 struct keyvalue *cur = head->next;\r
111 \r
112 if (!(file = fopen(filename, "w")))\r
113 return 0;\r
114 \r
115 if (flock(fileno(file), LOCK_EX))\r
116 {\r
117 fclose(file);\r
118 return 0;\r
119 }\r
120 \r
121 \r
122 while (cur)\r
123 {\r
124 /* No space in value? If there is, we need to quote the value\r
125 * so the shell can read it. */\r
126 if (!strchr(cur->value, ' '))\r
127 fprintf(file, "%s=%s\n", cur->key, cur->value);\r
128 else\r
129 fprintf(file, "%s=\'%s\'\n", cur->key, cur->value);\r
130 cur = cur->next;\r
131 }\r
132 flock(fileno(file), LOCK_UN);\r
133 fclose(file);\r
134 \r
135 return 1;\r
136}\r
137\r
138/* Finds a key and copies the value back. value must be at least STRING_SIZE\r
139 * long. Would be nice to have a func that just returns a pointer to the value?\r
140 */\r
141int findkey(struct keyvalue *head, char *key, char *value)\r
142{\r
143 struct keyvalue *cur = head->next;\r
144\r
145 while (cur)\r
146 {\r
147 if (strcmp(key, cur->key) == 0)\r
148 {\r
149 strncpy(value, cur->value, STRING_SIZE);\r
150 value[STRING_SIZE-1] = '\0';\r
151 return 1;\r
152 }\r
153 cur = cur->next;\r
154 }\r
155\r
156 return 0;\r
157}\r
158\r
159/* Appends a entry. Not very efficent because it rescans the list looking\r
160 * for the end. Maybe fix this later. */\r
161void appendkeyvalue(struct keyvalue *head, char *key, char *value)\r
162{\r
163 struct keyvalue *new = malloc(sizeof(struct keyvalue));\r
164 struct keyvalue *cur = head->next;\r
165 struct keyvalue *tail = head;\r
166\r
167 strncpy(new->key, key, STRING_SIZE);\r
168 strncpy(new->value, value, STRING_SIZE);\r
169 new->key[STRING_SIZE-1] = '\0';\r
170 new->value[STRING_SIZE-1] = '\0';\r
171 new->next = NULL;\r
172\r
173 while (cur)\r
174 {\r
175 tail = cur;\r
176 cur = cur->next;\r
177 }\r
178 tail->next = new;\r
179}\r
180\r
181/* Otherwrites a key with a new value, or if it dosn't exist, appends it\r
182 * on the end. */\r
183void replacekeyvalue(struct keyvalue *head, char *key, char *value)\r
184{\r
185 struct keyvalue *cur = head->next;\r
186\r
187 while (cur)\r
188 {\r
189 if (strcmp(cur->key, key) == 0)\r
190 {\r
191 strncpy(cur->value, value, STRING_SIZE);\r
192 cur->value[STRING_SIZE-1] = '\0';\r
193 return;\r
194 }\r
195 cur = cur->next;\r
196 }\r
197\r
198 appendkeyvalue(head, key, value);\r
199}\r