1 | /***************************************
2 | $Revision: 1.3 $
3 |
4 | Properties module (pr) - this _should_ eventually get merged in with the
5 |
6 | Status: NOT REVUED, NOT TESTED
7 |
8 | +html+ <DL COMPACT>
9 | +html+ <DT>Online References:
10 | +html+ <DD><UL>
11 | +html+ <LI><A HREF=".properties">.properties</A>
12 | +html+ </UL>
13 | +html+ </DL>
14 | +html+ <PRE>
15 | Instructions for use:
16 |
17 | To get a property:
18 | use the PR_get_property("Property.name") function from your other code.
19 | +html+ </PRE>
20 |
21 | ******************/ /******************
22 | Filename : properties.c
23 | Description : Provides a hash table of tokens and their values.
24 | Author : ottrey@ripe.net
25 | Date : 04/03/1999
26 | OSs Tested : Solaris, BSDI, Linux
27 | Input Files : .properties
28 | Related Modules : Used in conjunction with the constants module.
29 | Problems :
30 | To Do : Fix up handling multi-lined properties.
31 | : PR_set() could be cleaned up a little.
32 | Comments :
33 | ******************/ /******************
34 | Copyright (c) 1999 RIPE NCC
35 |
36 | All Rights Reserved
37 |
38 | Permission to use, copy, modify, and distribute this software and its
39 | documentation for any purpose and without fee is hereby granted,
40 | provided that the above copyright notice appear in all copies and that
41 | both that copyright notice and this permission notice appear in
42 | supporting documentation, and that the name of the author not be
43 | used in advertising or publicity pertaining to distribution of the
44 | software without specific, written prior permission.
45 |
46 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
47 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
48 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
49 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
50 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
51 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
52 | ***************************************/
53 | #include <stdio.h>
54 | #include <stdlib.h>
55 | #include <string.h>
56 |
57 | #define COMMENT_CHARACTER #
58 | #define MAX_PROPERTIES 1024
59 |
60 |
61 | /*
62 | * Type defs
63 | */
64 | /*+ Each property has a +*/
65 | typedef struct _Property {
66 | char *token; /*+ Token to be found in properties file. +*/
67 | char *value; /*+ Value to be found in properties file. +*/
68 | } *Property;
69 |
70 |
71 | /*
72 | * Global Variables
73 | */
74 | /*+ Array of Properties +*/
75 | Property Properties[MAX_PROPERTIES];
76 |
77 | /*+ The number of properties. +*/
78 | int Prop_count = 0;
79 |
80 | /*+ The name of properties file. +*/
81 | char *Prop_file_name;
82 |
83 |
84 |
85 | /* PR_to_string() */
86 | /*++++++++++++++++++++++++++++++++++++++
87 | Returns the properties as a string.
88 |
89 | More:
90 | +html+ <PRE>
91 | Authors:
92 | ottrey
93 |
94 | Pre-Conditions:
95 | The properties must be loaded first with load_properties().
96 |
97 | +html+ </PRE><DL COMPACT>
98 | +html+ <DT>Online References:
99 | +html+ <DD><UL>
100 | +html+ </UL></DL>
101 |
102 | ++++++++++++++++++++++++++++++++++++++*/
103 | char *PR_to_string(void) {
104 | char *props;
105 | char props_buffer[1024];
106 | char tmp_prop[128];
107 | int i=0;
108 |
109 | sprintf(props_buffer, "Properties = { ");
110 | for(i=0; i< Prop_count; i++) {
111 | sprintf(tmp_prop, "[%s]=\"%s\" ", Properties[i]->token, Properties[i]->value );
112 | strcat(props_buffer, tmp_prop);
113 | }
114 | strcat(props_buffer, "}");
115 |
116 | /*
117 | props = (char *)CopyString(props_buffer);
118 | */
119 | props = (char *)calloc(1, strlen(props_buffer)+1);
120 | strcpy(props, props_buffer);
121 |
122 | return props;
123 | } /* PR_to_string() */
124 |
125 | /* purge_properties() */
126 | /*++++++++++++++++++++++++++++++++++++++
127 | Purges the old properties.
128 |
129 | More:
130 | +html+ <PRE>
131 | Authors:
132 | ottrey
133 | +html+ </PRE><DL COMPACT>
134 | +html+ <DT>Online References:
135 | +html+ <DD><UL>
136 | +html+ <LI><A HREF="../src/.properties">.properties</A>
137 | +html+ </UL></DL>
138 |
139 | ++++++++++++++++++++++++++++++++++++++*/
140 | static void purge_properties(void) {
141 | int i;
142 |
143 | for(i=0; i < Prop_count; i++) {
144 | free(Properties[i]->value);
145 | free(Properties[i]->token);
146 | free(Properties[i]);
147 | }
148 |
149 | Prop_count = 0;
150 | } /* purge_properties() */
151 |
152 |
153 | /* add_property() */
154 | /*++++++++++++++++++++++++++++++++++++++
155 | Adds a new property to the Properties array.
156 |
157 | More:
158 | +html+ <PRE>
159 | Authors:
160 | ottrey
161 | +html+ </PRE><DL COMPACT>
162 | +html+ <DT>Online References:
163 | +html+ <DD><UL>
164 | +html+ <LI><A HREF=".properties">.properties</A>
165 | +html+ </UL></DL>
166 |
167 | ++++++++++++++++++++++++++++++++++++++*/
168 | static void add_property(const char *token, const char *value) {
169 | Property prop;
170 |
171 | prop = (Property)calloc(1, sizeof(struct _Property));
172 |
173 | /*
174 | prop->token = (char *)CopyString(token);
175 | */
176 | prop->token = (char *)calloc(1, strlen(token)+1);
177 | strcpy(prop->token, token);
178 |
179 | /*
180 | prop->value = (char *)CopyString(value);
181 | */
182 | prop->value = (char *)calloc(1, strlen(value)+1);
183 | strcpy(prop->value, value);
184 |
185 | Properties[Prop_count] = prop;
186 |
187 | Prop_count++;
188 | Properties[Prop_count] = NULL;
189 | } /* add_property() */
190 |
191 |
192 | /* PR_set() */
193 | /*++++++++++++++++++++++++++++++++++++++
194 | Sets the properties from the properties file.
195 |
196 | More:
197 | +html+ <PRE>
198 | Authors:
199 | ottrey
200 | +html+ </PRE><DL COMPACT>
201 | +html+ <DT>Online References:
202 | +html+ <DD><UL>
203 | +html+ <LI><A HREF=".properties">.properties</A>
204 | +html+ </UL></DL>
205 |
206 | ++++++++++++++++++++++++++++++++++++++*/
207 | char *PR_set() {
208 | FILE *prop_file;
209 | char prop_line[1024];
210 | char prop_line_more[1024];
211 | char *eql_ptr;
212 | char *newln_ptr;
213 | char *token_ptr;
214 | char *token_e_ptr;
215 | char *value_ptr;
216 | char *value_more_ptr;
217 | char *value_e_ptr;
218 | int token_l, value_l;
219 | int more_lines;
220 | char the_token[64];
221 | char the_value[1024];
222 | char result_buff[256];
223 | char *result;
224 |
225 | prop_file = fopen(Prop_file_name, "r");
226 | if (prop_file == NULL) {
227 | fprintf(stderr, "Error: Can't find properties file: %s\n", Prop_file_name);
228 | sprintf(result_buff, "Error: Can't find properties file: %s", Prop_file_name);
229 | }
230 | else {
231 | purge_properties();
232 |
233 | while (fgets(prop_line, 1024, prop_file) != 0) {
234 | if ( (eql_ptr = strchr(prop_line, '=')) != NULL) {
235 | /* An "=" was found */
236 |
237 | token_ptr = prop_line;
238 | token_e_ptr = eql_ptr-1;
239 |
240 | /* Trim the trailing spaces/tabs off the token. */
241 | while (( *(token_e_ptr) == ' ') || ( *(token_e_ptr) == '\t')) {
242 | token_e_ptr--;
243 | }
244 |
245 | /* Trim the leading spaces/tabs off the token. */
246 | while (( *(token_ptr) == ' ') || ( *(token_ptr) == '\t')) {
247 | token_ptr++;
248 | }
249 |
250 | /* Skip if it's a comment line. */
251 | if (token_ptr[0] == '#' ) {
252 | continue;
253 | }
254 |
255 | /* Assign the token */
256 | token_l = (token_e_ptr - token_ptr) + 1;
257 | strncpy(the_token, token_ptr, token_l);
258 | the_token[token_l] = '\0';
259 |
260 | value_ptr = eql_ptr+1;
261 | value_e_ptr = strchr(prop_line, '\n')-1;
262 |
263 | /* Trim the leading spaces/tabs off the value. */
264 | while (( *(value_ptr) == ' ') || ( *(value_ptr) == '\t')) {
265 | value_ptr++;
266 | }
267 |
268 | /* Trim the trailing spaces/tabs off the value. */
269 | while (( *(value_e_ptr) == ' ') || ( *(value_e_ptr) == '\t')) {
270 | value_e_ptr--;
271 | }
272 |
273 | /* Assign the value */
274 | value_l = (value_e_ptr - value_ptr) + 1;
275 | strncpy(the_value, value_ptr, value_l);
276 | the_value[value_l] = '\0';
277 |
278 | /* If the value goes over the line */
279 | if ((value_e_ptr = strrchr(the_value, '\\')) != NULL) {
280 | *value_e_ptr = ' ';
281 | more_lines = 0;
282 | do {
283 | if (fgets(prop_line_more, 1024, prop_file) != 0) {
284 |
285 | /* Trim the leading spaces/tabs off the line_more. */
286 | value_more_ptr = prop_line_more;
287 | while (( *(value_more_ptr) == ' ') || ( *(value_more_ptr) == '\t')) {
288 | value_more_ptr++;
289 | }
290 |
291 | /* Trim the trailing spaces/tabs off the value. */
292 | if ((value_e_ptr = strrchr(prop_line_more, '\\')) != NULL) {
293 | more_lines = 1;
294 | *value_e_ptr = ' ';
295 | }
296 | else {
297 | more_lines = 0;
298 | }
299 | value_e_ptr = strchr(prop_line_more, '\n');
300 | *value_e_ptr = ' ';
301 | while ((*value_e_ptr == ' ') || (*value_e_ptr == '\t')) {
302 | value_e_ptr--;
303 | }
304 |
305 | *(value_e_ptr+1) = '\0';
306 | strcat(the_value, value_more_ptr);
307 |
308 | }
309 | } while (more_lines == 1);
310 |
311 | value_l = strlen(the_value);
312 | the_value[value_l] = '\0';
313 | }
314 |
315 | add_property(the_token, the_value);
316 | } else {
317 | /* Skip this line */
318 | ;
319 | }
320 | }
321 |
322 | /*
323 | printf("%s\n", PR_to_string() );
324 | */
325 |
326 | fclose(prop_file);
327 |
328 | sprintf(result_buff, "Properties successfully set from %s file. (%d properties)", Prop_file_name, Prop_count);
329 | }
330 |
331 | /*
332 | result = (char *)CopyString(result_buff);
333 | */
334 | result = (char *)calloc(1, strlen(result_buff)+1);
335 | strcpy(result, result_buff);
336 |
337 | return result;
338 | } /* PR_set() */
339 |
340 |
341 | /* PR_load() */
342 | /*++++++++++++++++++++++++++++++++++++++
343 | Sets the properties file name. Then sets the properties with a call to set_properties().
344 |
345 | More:
346 | +html+ <PRE>
347 | Authors:
348 | ottrey
349 | +html+ </PRE><DL COMPACT>
350 | +html+ <DT>Online References:
351 | +html+ <DD><UL>
352 | +html+ <LI><A HREF=".properties">.properties</A>
353 | +html+ </UL></DL>
354 |
355 | ++++++++++++++++++++++++++++++++++++++*/
356 | void PR_load(const char *prop_file_name) {
357 |
358 | /*
359 | Prop_file_name = (char *)CopyString(prop_file_name);
360 | */
361 | Prop_file_name = (char *)calloc(1, strlen(prop_file_name)+1);
362 | strcpy(Prop_file_name, prop_file_name);
363 |
364 | PR_set();
365 |
366 | } /* PR_load() */
367 |
368 |
369 | /* PR_get_property() */
370 | /*++++++++++++++++++++++++++++++++++++++
371 | Sets the properties file name. Then sets the properties with a call to set_properties().
372 |
373 | More:
374 | +html+ <PRE>
375 | Authors:
376 | ottrey
377 | +html+ </PRE><DL COMPACT>
378 | +html+ <DT>Online References:
379 | +html+ <DD><UL>
380 | +html+ <LI><A HREF=".properties">.properties</A>
381 | +html+ </UL></DL>
382 |
383 | ++++++++++++++++++++++++++++++++++++++*/
384 | char *PR_get_property(const char *token, const char *default_value) {
385 | char *value;
386 | int i = 0;
387 |
388 | /* Search through the Properties until the token is found */
389 | while (i < Prop_count) {
390 | if (strcmp(token, Properties[i]->token) == 0) {
391 | break;
392 | }
393 | i++;
394 | }
395 |
396 | if (i == Prop_count) {
397 | /* If token not found return the default value */
398 | if (default_value == NULL) {
399 | strcpy(value, "");
400 | } else {
401 | /*
402 | value = (char *)CopyString(default_value);
403 | */
404 | value = (char *)calloc(1, strlen(default_value)+1);
405 | strcpy(value, default_value);
406 | }
407 | } else {
408 | /* Return the found value */
409 | /*
410 | value = (char *)CopyString(Properties[i]->value);
411 | */
412 | value = (char *)calloc(1, strlen(Properties[i]->value)+1);
413 | strcpy(value, Properties[i]->value);
414 | }
415 |
416 | return value;
417 |
418 | } /* PR_get_property() */