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