1    | /***************************************
2    |   $Revision: 1.9 $
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   | #include "memwrap.h"
58   | 
59   | #define COMMENT_CHARACTER #
60   | #define MAX_PROPERTIES    1024
61   | 
62   | 
63   | /*
64   |  * Type defs
65   |  */
66   | /*+ Each property has a +*/
67   | typedef struct _Property {
68   |   char *token;                  /*+ Token to be found in properties file. +*/
69   |   char *value;                  /*+ Value to be found in properties file. +*/
70   | } *Property;
71   | 
72   | 
73   | /*
74   |  * Global Variables
75   |  */
76   | /*+ Array of Properties +*/
77   | Property Properties[MAX_PROPERTIES];
78   | 
79   | /*+ The number of properties. +*/
80   | int Prop_count = 0;
81   | 
82   | /*+ The name of properties file. +*/
83   | char  *Prop_file_name;
84   | 
85   | 
86   | 
87   | /* PR_to_string() */
88   | /*++++++++++++++++++++++++++++++++++++++
89   |   Returns the properties as a string.
90   | 
91   |   More:
92   |   +html+ <PRE>
93   |   Authors:
94   |         ottrey
95   | 
96   |   Pre-Conditions:
97   |         The properties must be loaded first with load_properties().
98   | 
99   |   +html+ </PRE><DL COMPACT>
100  |   +html+ <DT>Online References:
101  |   +html+ <DD><UL>
102  |   +html+ </UL></DL>
103  | 
104  |   ++++++++++++++++++++++++++++++++++++++*/
105  | char *PR_to_string(void) {
106  |   char *props;
107  |   char props_buffer[2048];
108  |   char tmp_prop[1024];
109  |   int i=0;
110  | 
111  |   sprintf(props_buffer, "Properties = { ");
112  |   for(i=0; i< Prop_count; i++) {
113  |     sprintf(tmp_prop, "[%s]=\"%s\" ", Properties[i]->token, Properties[i]->value );
114  |     strcat(props_buffer, tmp_prop);
115  |   }
116  |   strcat(props_buffer, "}");
117  | 
118  |   /*
119  |   props = (char *)CopyString(props_buffer);
120  |   */
121  |   /* props = (char *)calloc(1, strlen(props_buffer)+1); */
122  |   dieif( wr_malloc((void **)&props, strlen(props_buffer)+1) != UT_OK);  
123  | 
124  |   strcpy(props, props_buffer);
125  | 
126  |   return props;
127  | } /* PR_to_string() */
128  | 
129  | /* purge_properties() */
130  | /*++++++++++++++++++++++++++++++++++++++
131  |   Purges the old properties.
132  | 
133  |   More:
134  |   +html+ <PRE>
135  |   Authors:
136  |         ottrey
137  |   +html+ </PRE><DL COMPACT>
138  |   +html+ <DT>Online References:
139  |   +html+ <DD><UL>
140  |   +html+   <LI><A HREF="../src/.properties">.properties</A>
141  |   +html+ </UL></DL>
142  | 
143  |   ++++++++++++++++++++++++++++++++++++++*/
144  | static void purge_properties(void) {
145  |   int i;
146  | 
147  |   for(i=0; i < Prop_count; i++) {
148  |     wr_free(Properties[i]->value);
149  |     wr_free(Properties[i]->token);
150  |     wr_free(Properties[i]);
151  |   }
152  | 
153  |   Prop_count = 0;
154  | } /* purge_properties() */
155  | 
156  | 
157  | /* add_property() */
158  | /*++++++++++++++++++++++++++++++++++++++
159  |   Adds a new property to the Properties array.
160  | 
161  |   More:
162  |   +html+ <PRE>
163  |   Authors:
164  |         ottrey
165  |   +html+ </PRE><DL COMPACT>
166  |   +html+ <DT>Online References:
167  |   +html+ <DD><UL>
168  |   +html+   <LI><A HREF=".properties">.properties</A>
169  |   +html+ </UL></DL>
170  | 
171  |   ++++++++++++++++++++++++++++++++++++++*/
172  | static void add_property(const char *token, const char *value) {
173  |   Property prop;
174  | 
175  |   /* prop = (Property)calloc(1, sizeof(struct _Property)); */
176  |   dieif( wr_calloc((void **)&prop,1, sizeof(struct _Property)) != UT_OK);
177  | 	   
178  |   /*
179  |     prop->token = (char *)CopyString(token);
180  |   */
181  |   /* prop->token = (char *)calloc(1, strlen(token)+1); */
182  |   dieif( wr_malloc((void **)&(prop->token), strlen(token)+1) != UT_OK);
183  |   strcpy(prop->token, token);
184  | 
185  |   /*
186  |   prop->value = (char *)CopyString(value);
187  |   */
188  |   /* prop->value = (char *)calloc(1, strlen(value)+1); */
189  |   dieif( wr_malloc((void **)&(prop->value), strlen(value)+1) != UT_OK);
190  |   strcpy(prop->value, value);
191  | 
192  |   Properties[Prop_count] = prop;
193  | 
194  |   Prop_count++;
195  |   Properties[Prop_count] = NULL;
196  | } /* add_property() */
197  | 
198  | 
199  | /* PR_set() */
200  | /*++++++++++++++++++++++++++++++++++++++
201  |   Sets the properties from the properties file.
202  | 
203  |   More:
204  |   +html+ <PRE>
205  |   Authors:
206  |         ottrey
207  |   +html+ </PRE><DL COMPACT>
208  |   +html+ <DT>Online References:
209  |   +html+ <DD><UL>
210  |   +html+   <LI><A HREF=".properties">.properties</A>
211  |   +html+ </UL></DL>
212  | 
213  |   ++++++++++++++++++++++++++++++++++++++*/
214  | char *PR_set() {
215  |   FILE    *prop_file;
216  |   char    prop_line[1024];
217  |   char    prop_line_more[1024];
218  |   char    *eql_ptr;
219  |   char    *token_ptr;
220  |   char    *token_e_ptr;
221  |   char    *value_ptr;
222  |   char    *value_more_ptr;
223  |   char    *value_e_ptr;
224  |   int     token_l, value_l;
225  |   int     more_lines;
226  |   char    the_token[64];
227  |   char    the_value[1024];
228  |   char    result_buff[256];
229  |   char    *result;
230  | 
231  |   prop_file = fopen(Prop_file_name, "r");
232  |   if (prop_file == NULL) {
233  |     fprintf(stderr, "Error: Can't find properties file: %s\n", Prop_file_name);
234  |     sprintf(result_buff, "Error: Can't find properties file: %s", Prop_file_name);
235  |   }
236  |   else {
237  |     purge_properties();
238  | 
239  |     while (fgets(prop_line, 1024, prop_file) != 0) {
240  |       if ( (eql_ptr = strchr(prop_line, '=')) != NULL) {
241  |         /* An "=" was found  */
242  | 
243  |         token_ptr = prop_line;
244  |         token_e_ptr = eql_ptr-1;
245  | 
246  |         /* Trim the trailing spaces/tabs off the token. */
247  |         while (( *(token_e_ptr) == ' ') || ( *(token_e_ptr) == '\t')) {
248  |           token_e_ptr--;
249  |         }
250  | 
251  |         /* Trim the leading spaces/tabs off the token. */
252  |         while (( *(token_ptr) == ' ') || ( *(token_ptr) == '\t')) {
253  |           token_ptr++;
254  |         }
255  | 
256  |         /* Skip if it's a comment line. */
257  |         if (token_ptr[0] == '#' ) {
258  |           continue;
259  |         }
260  | 
261  |         /* Assign the token */
262  |         token_l = (token_e_ptr - token_ptr) + 1;
263  |         strncpy(the_token, token_ptr, token_l);
264  |         the_token[token_l] = '\0';
265  | 
266  |         value_ptr = eql_ptr+1;
267  |         value_e_ptr = strchr(prop_line, '\n')-1;
268  | 
269  |         /* Trim the leading spaces/tabs off the value. */
270  |         while (( *(value_ptr) == ' ') || ( *(value_ptr) == '\t')) {
271  |           value_ptr++;
272  |         }
273  | 
274  |         /* Trim the trailing spaces/tabs off the value. */
275  |         while (( *(value_e_ptr) == ' ') || ( *(value_e_ptr) == '\t')) {
276  |           value_e_ptr--;
277  |         }
278  | 
279  |         /* Assign the value */
280  |         value_l = (value_e_ptr - value_ptr) + 1;
281  |         strncpy(the_value, value_ptr, value_l);
282  |         the_value[value_l] = '\0';
283  | 
284  |         /* If the value goes over the line */
285  |         if ((value_e_ptr = strrchr(the_value, '\\')) != NULL) {
286  |           *value_e_ptr = ' ';
287  |           more_lines = 0;
288  |           do {
289  |             if (fgets(prop_line_more, 1024, prop_file) != 0) {
290  | 
291  |               /* Trim the leading spaces/tabs off the line_more. */
292  |               value_more_ptr = prop_line_more;
293  |               while (( *(value_more_ptr) == ' ') || ( *(value_more_ptr) == '\t')) {
294  |                 value_more_ptr++;
295  |               }
296  | 
297  |               /* Trim the trailing spaces/tabs off the value. */
298  |               if ((value_e_ptr = strrchr(prop_line_more, '\\')) != NULL) {
299  |                 more_lines = 1;
300  |                 *value_e_ptr = ' ';
301  |               }
302  |               else {
303  |                 more_lines = 0;
304  |               }
305  |               value_e_ptr = strchr(prop_line_more, '\n');
306  |               *value_e_ptr = ' ';
307  |               while ((*value_e_ptr == ' ') || (*value_e_ptr == '\t')) {
308  |                 value_e_ptr--;
309  |               }
310  | 
311  |               *(value_e_ptr+1) = '\0';
312  |               strcat(the_value, value_more_ptr);
313  |               
314  |             }
315  |           } while (more_lines == 1);
316  | 
317  |           value_l = strlen(the_value);
318  |           the_value[value_l] = '\0';
319  |         }
320  | 
321  |         add_property(the_token, the_value);
322  |       } else {
323  |         /* Skip this line */
324  |         ;
325  |       }
326  |     }
327  | 
328  |     /*
329  |     printf("%s\n", PR_to_string() );
330  |     */
331  | 
332  |     fclose(prop_file);
333  | 
334  |     sprintf(result_buff, "Properties successfully set from %s file.  (%d properties)", Prop_file_name, Prop_count);
335  |   }
336  | 
337  |   /*
338  |   result = (char *)CopyString(result_buff);
339  |   */
340  |   /* result = (char *)calloc(1, strlen(result_buff)+1); */
341  |   dieif( wr_malloc((void **)&result, strlen(result_buff)+1 ) != UT_OK);  
342  | 
343  |   strcpy(result, result_buff);
344  | 
345  |   return result;
346  | } /* PR_set() */
347  | 
348  | 
349  | /* PR_load() */
350  | /*++++++++++++++++++++++++++++++++++++++
351  |   Sets the properties file name.  Then sets the properties with a call to set_properties().
352  | 
353  |   More:
354  |   +html+ <PRE>
355  |   Authors:
356  |         ottrey
357  |   +html+ </PRE><DL COMPACT>
358  |   +html+ <DT>Online References:
359  |   +html+ <DD><UL>
360  |   +html+   <LI><A HREF=".properties">.properties</A>
361  |   +html+ </UL></DL>
362  | 
363  |   ++++++++++++++++++++++++++++++++++++++*/
364  | void PR_load(const char *prop_file_name) {
365  |   
366  |   /*
367  |   Prop_file_name = (char *)CopyString(prop_file_name);
368  |   */
369  |   /* Prop_file_name = (char *)calloc(1, strlen(prop_file_name)+1); */
370  | 
371  |   dieif( wr_malloc((void **)&Prop_file_name, 
372  | 		   strlen(prop_file_name)+1) != UT_OK);  
373  |   strcpy(Prop_file_name, prop_file_name);
374  | 
375  |   free(PR_set());
376  | 
377  | } /* PR_load() */
378  | 
379  | 
380  | /* PR_get_property() */
381  | /*++++++++++++++++++++++++++++++++++++++
382  |   Sets the properties file name.  Then sets the properties with a call to set_properties().
383  | 
384  |   More:
385  |   +html+ <PRE>
386  |   Authors:
387  |         ottrey
388  |   +html+ </PRE><DL COMPACT>
389  |   +html+ <DT>Online References:
390  |   +html+ <DD><UL>
391  |   +html+   <LI><A HREF=".properties">.properties</A>
392  |   +html+ </UL></DL>
393  | 
394  |   ++++++++++++++++++++++++++++++++++++++*/
395  | char *PR_get_property(const char *token, const char *default_value) {
396  |   char *value;
397  |   int   i = 0;
398  | 
399  |   /* Search through the Properties until the token is found */
400  |   while (i < Prop_count) {
401  |     if (strcmp(token, Properties[i]->token) == 0) {
402  |       break;
403  |     }
404  |     i++;
405  |   }
406  |   
407  |   if (i == Prop_count) {
408  |     /* If token not found return the default value */
409  |     if (default_value == NULL) {
410  |       strcpy(value, "");
411  |     } else {
412  |       /*
413  |       value = (char *)CopyString(default_value);
414  |       */
415  |       /*      value = (char *)calloc(1, strlen(default_value)+1); */
416  |       dieif( wr_malloc((void **)&value, strlen(default_value)+1) != UT_OK);  
417  |       strcpy(value, default_value);
418  |     }
419  |   } else {
420  |     /* Return the found value */
421  |     /*
422  |     value = (char *)CopyString(Properties[i]->value);
423  |     */
424  |     /*     value = (char *)calloc(1, strlen(Properties[i]->value)+1); */
425  |     dieif( wr_malloc((void **)&value, strlen(Properties[i]->value)+1) != UT_OK); 
426  |     strcpy(value, Properties[i]->value);
427  |   }
428  | 
429  |   return value;
430  | 
431  | } /* PR_get_property() */