88 #define LEN_TOTREPLY 600
90 #define RECUR_LIMIT 40
92 #define ENV_VAR_1 "APPS_DEFAULTS_USER"
93 #define ENV_VAR_2 "APPS_DEFAULTS_PROG"
94 #define ENV_VAR_3 "APPS_DEFAULTS_SITE"
95 #define ENV_VAR_4 "APPS_DEFAULTS"
96 #define ENV_VAR_LENGTH 20
97 #define ENV_VAR_NUMBER 4
100 #define RFR_CLOSE ")"
103 #define QUOTE1 '\"' /* 1st valid quote character */
104 #define QUOTE2 '\'' /* 2nd valid quote character */
105 #define BSLASH '\\' /* back slash */
107 #define QPHRASE1 (opt_line[ilast] == QUOTE1 && ilast > 0 && opt_line[ilast - 1] != BSLASH)
108 #define QPHRASE2 (opt_line[ilast] == QUOTE2 && ilast > 0 && opt_line[ilast - 1] != BSLASH)
109 #define NPHRASE2 (isspace(opt_line[ilast]) && ilast > 0 && opt_line[ilast - 1] != BSLASH)
111 static int r_cou = 0; /* counter to limit recursion */
112 static int ifile = 0; /* file loop counter */
113 static int i = 0; /* miscellaneous counter */
114 static int i_tok = 0; /* found token index */
115 static int i_rep = 0; /* found reply in variable resource */
116 static int ilast = 0; /* last character position holder */
117 static int opt_line_len; /* number of chars in opt_line */
118 static int iphrase = 0; /* conditional phrase-ending indicator */
119 static char token[LEN_TOKEN+1]; /* working token array */
120 static char *as_env_var; /* returned env. var. value */
121 static char env_var_array[ENV_VAR_NUMBER][ENV_VAR_LENGTH];
122 static int r_len = 0; /* length of reply in referback */
123 static int e_len = 0; /* length of end of reply after a referback */
125 static FILE *in[ENV_VAR_NUMBER]; /* file descripter */
126 static char *opts_file[ENV_VAR_NUMBER]; /* file name holder */
129 /*------------------------------------------------------------------------------------------------*/
130 int get_apps_defaults(char *request, int *request_len, char *reply, int *reply_len)
133 void get_apps_defaults_r(char *, char *);
135 char inquest[LEN_TOKEN+1]; /* entered token string recopied */
136 char resource[LEN_TOTREPLY+1]; /* working resource array */
138 /* Set output to null in case something goes wrong, check input length for bad number */
141 if ( *request_len>0 && *request_len<=LEN_TOKEN && *request_len<=LEN_TOTREPLY )
144 /* Place entered string into local variable; append '\0';set recursion count global */
146 (void)strncpy(inquest,request,*request_len);
147 inquest[*request_len] = '\0';
150 /* Fill the environment variable array */
152 for (i = 0; i < ENV_VAR_NUMBER; i++)
154 (void)memset(env_var_array[i], '\0', ENV_VAR_LENGTH);
157 (void)strcpy(env_var_array[0], ENV_VAR_1);
158 (void)strcpy(env_var_array[1], ENV_VAR_2);
159 (void)strcpy(env_var_array[2], ENV_VAR_3);
160 (void)strcpy(env_var_array[3], ENV_VAR_4);
162 /* Make sure apps files are initialized as not-opened */
164 for (ifile = 0; ifile < ENV_VAR_NUMBER; ifile++)
167 opts_file[ifile] = '\0';
170 /* Call true "C" routine that can be recursive using global variable "r_cou" */
172 get_apps_defaults_r(inquest,resource);
174 /* Close any apps files that may have been opened */
176 for (ifile = 0; ifile < ENV_VAR_NUMBER; ifile++)
178 if (in[ifile] != NULL) (void)fclose(in[ifile]);
181 /* Place local output string into returned string */
183 if ( (r_cou <= RECUR_LIMIT) && ((int)strlen(resource) < LEN_REPLY) )
185 (void)strcpy(reply, &resource[0]);
189 /* Get length, set return error status ( 0=token found, 1=error or no token ) */
190 /* old return was: return ( (*reply) ? 0 : 1 ); */
192 *reply_len = strlen(reply);
193 return ( ( *reply_len != 0 ) ? 0 : 1 );
196 /*------------------------------------------------------------------------------------------------*/
197 void get_apps_defaults_r(char inquest[], char resource[])
200 char *pOpen; /* referback opening position holder */
201 char *pClose; /* referback closing position holder */
202 int diff = 0; /* string comparison result */
203 char referback[LEN_TOKEN+1]; /* referback token array */
204 char refer_val[LEN_TOTREPLY+1]; /* referback value array */
205 char substitute[LEN_TOTREPLY+1]; /* expanded referback-ed resource */
207 /* Initialize the result to NULL */
209 (void)memset(resource, '\0', LEN_TOTREPLY+1);
211 /* Check for the requested variable found as an environment variable */
213 as_env_var = getenv(inquest);
215 if ( as_env_var ) /* SAM, RTi */
216 (void)strcpy(resource, as_env_var);
220 /* Increment recursive counter (needed to avoid referbacks calling itself) */
223 if (r_cou <= RECUR_LIMIT+1)
226 /* The resource file to be read is indicated by the value of an
227 environment variable */
229 for (ifile = 0; ifile < ENV_VAR_NUMBER; ifile++)
231 char opt_line[LEN_LINE+1]; /* t-r file line array */
234 /* See if file can be opened for reading */
236 if (in[ifile] == NULL)
238 opts_file[ifile] = getenv(env_var_array[ifile]);
239 if ( opts_file[ifile] != NULL )
242 olen=(int)strlen(opts_file[ifile]);
244 in[ifile] = fopen(opts_file[ifile], "r");
252 if (in[ifile] != NULL)
255 /* Read file until either match is found or EOF reached */
257 while (fgets(opt_line, LEN_LINE+1, in[ifile]) != NULL)
260 /* Only scan lines with the delimiter in them */
262 if (strchr(opt_line, DELIM) != NULL)
265 opt_line_len = strlen(opt_line);
267 /* Look for first non-blank character on line */
269 while (i < opt_line_len-1 && isspace(opt_line[i]) != 0)
272 /* Discard line if first character is either delimiter or comment indicator */
274 if (opt_line[i] != COMMENT && opt_line[i] != DELIM)
279 /* Look for token based on rules for delimiting tokens */
281 while (ilast <= opt_line_len &&
282 i_tok <= LEN_TOKEN &&
283 isprint(opt_line[ilast]) != 0 &&
284 isspace(opt_line[ilast]) == 0 &&
285 opt_line[ilast] != DELIM )
287 token[i_tok++] = opt_line[ilast++];
291 /* Got proposed token, skip thru spaces */
293 while (ilast < opt_line_len && isspace(opt_line[ilast]) != 0 )
296 /* See if token on line is one to be retrieved */
298 if (opt_line[ilast] == DELIM &&
299 strlen(inquest) == strlen(token) &&
300 strncmp(token, inquest, i_tok) == 0 )
303 /* Match found, now determine associated resource. */
304 /* Resource can not start with DELIM or COMMENT characters */
305 /* or any non-printing characters */
311 /* Skip space after colon */
313 while (i < opt_line_len-1 && isspace(opt_line[i]) != 0)
316 /* Determine contents of resource until: */
317 /* 1. End of line is reached, or */
318 /* 2. White space is found for resources not quoted, or */
319 /* 3. Closing matching quote character is found for quoted strings. */
321 if (i < opt_line_len)
323 if (opt_line[i] != COMMENT)
328 /* Check to see if resource string is quoted (single or double) */
337 /* Complete resource based on start character conditions */
342 while (isprint(opt_line[ilast]) && !NPHRASE2)
343 resource[i_rep++] = opt_line[ilast++];
347 while (isprint(opt_line[ilast]) && !QPHRASE1)
348 resource[i_rep++] = opt_line[ilast++];
352 while (isprint(opt_line[ilast]) && !QPHRASE2)
353 resource[i_rep++] = opt_line[ilast++];
356 resource[i_rep] = '\0';
358 /* Now look for any embedded referbacks in the resource string */
360 while ( ((pOpen = strstr(resource, RFR_OPEN)) != NULL) &&
361 ((pClose = strstr(pOpen, RFR_CLOSE)) != NULL) &&
362 ((diff = (int)(pClose - pOpen) - 2) >= 0 ) )
364 (void)memset(substitute, '\0', LEN_TOTREPLY+1);
365 if (strcmp(resource, pOpen)) /* SAM, RTi */
366 (void)strncpy(substitute, resource, (pOpen - &resource[0]));
369 (void)memset(referback, '\0', LEN_TOKEN+1);
370 (void)memset(refer_val, '\0', LEN_REPLY+1);
371 (void)strncpy(referback, pOpen + 2, diff);
373 (void)get_apps_defaults_r(referback, refer_val);
375 if (r_cou > RECUR_LIMIT+1)
378 e_len = (int)(strlen(resource) - (int)(pClose - &resource[0]));
380 r_len = (int)(strlen(refer_val));
381 if ( ((int)strlen(substitute) + r_len + e_len) > LEN_TOTREPLY)
383 r_cou = RECUR_LIMIT+1;
389 (void)strcat(substitute, refer_val);
392 (void)strcat(substitute, pClose + 1);
393 (void)strcpy(resource, substitute);
394 } /* end of referback expansion while-loop */
396 } /* end of non-comment part of resource request if-loop */
397 } /* end of resource request characters if-loop */
398 } /* end of token-been-found if-loop */
399 } /* end of discard-if-delimiter-or-comment check if-loop */
400 } /* end of check for line with a delimiter in it if-loop */
401 } /* end of t-r file read to EOL if-loop */
402 } /* end of legitimate file opening loop */
404 /* Break out of file loop if token is found, else will search lower priority files */
405 /* This will also end search if token gives null reply, old way: */
406 /* if (resource[0]) break; */
407 /* searched later files if token reply was null */
409 if ( found_token == 1 )
412 } /* end of loop thru files named by env vars */
413 } /* end of loop where recursion is less than limit */
418 } /* end obtaining of resource for given token */
420 /* ============== Statements containing RCS keywords: */
421 {static char rcs_id1[] = "$Source: /fs/hseb/ob6/rfc/util/src/util_gen1/RCS/get_apps_defaults.c,v $";
422 static char rcs_id2[] = "$Id: get_apps_defaults.c,v 1.8 2005/07/07 19:20:36 dws Exp $";}
423 /* =================================================== */