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() */