To add a new resource -- as an example, the BAZ resource, which will have foo record which is an integer, a storage record, which is the name of a storage resource, and a special time field. 1. Define the Resource type (R_xxx) in dir_config.h Be sure to update the R_LAST define. #define R_BAZ 1011 update R_LAST to be R_BAZ 2. Add a new definition of the resource in dir_config.h The first three are mandatory (will soon be changed to a header structure). struct s_res_baz { char * name; int rcode struct s_res_baz *next; int foo; struct res_store *storage; int time; }; 3. In dir_config.c add the new resource to the table of resources (resources[]) {"baz", baz_items, R_BAZ, NULL}, 4. Create a baz_items, which defines the records that can appear within the BAZ resource: static struct res_items bas_items[] = { name, store sub, where to store, extra info {"name", store_name, ITEM(res_baz.name), 0}, /* manditory */ {"foo", store_int, ITEM(res_baz.foo), 0}, {"storage", stor_res, ITEM(res_baz.storage), 0}, {"time", store_time, ITME(res_baz.time), 0}, }; 5. Update the dump_resource() subroutine to handle printing your resource. 6. Update the free_resource() subroutine to handle releasing any allocated memory. 7. Check for any special initialization in init_resource(). Normally, everything is just zeroed. 8. Update the new_resource() subroutine to handle the two passes of the configurator to be able to create your resource. Pass 2 is used only for finding a reference to a resource and stuffing its address. In the above example, you will need to include the storage resource. See the example for the Job Resource. Add an entry so that the correct size of your resource is allocated for pass one. 9. Write any new store routines that you may need. In this case, we used the store_int and store_res, which are already defined, but we need to add the new special routine store_time(). Note, the store subroutine gets control when the parser has identified the record. Everything after the record name must be scanned in the store routine. To add a new resource record: 1. Add the new record definition to the resource structure definition. See step 2 above. In this case, however, we only add a new field to the existing structure. 2. Add the new record to the existing res_items structure. See step 4 above. In this case, however, we only add a new record definition to the exising structure. 3. Update the dump_resource() routine to dump the new record. 4. Update the free_resource() routine if you allocated any memory. 5. Update init_resource() if you have any special requirements (not normally the case). 6. Update the new_resource() routine if necessary (not normally the case). 7. Write any new store routine that you may have created to store your record. Note, the store subroutine gets control when the parser has identified the record. Everything after the record name must be scanned in the store routine. See the examples of store routines that exist. Note, the core parsing code is in lib/parse_config.c and lib/parse_config.h. lib/parse_config.c provides the following store routines: store_name stores a resource name store_str stores a string store_res stores a resource store_int stores an integer and the following utilities: scan_to_eol causes the lexical scanner to scan to the end of the line scan_error prints an error message GetResWithName returns the resource of a specified type and name GetNextRes returns the next resource of a specified type parse_config parses the configuration file free_config_resources frees all the resources allocated. Note: when your store routine gets control, the parser will have already scanned the record name (i.e. "baz =") before calling your routine. The lexical scanner is by default in a mode where spaces will be compressed out of unquoted strings. Consequently if you want to scan baz = full backup every sunday and you do not want to get "full backup every sunday" as a single token "fullbackupeverysunday", you must set the no identifier option in the lexical scanner options field: int options = lc->options; lc->options |= LOPT_NO_IDENT; /* don't eat spaces */ get_token(lc) ... ... lc->options = options; return;