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