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