15 |
#include "getline.h" |
#include "getline.h" |
16 |
#include "history.h" |
#include "history.h" |
17 |
|
|
|
|
|
|
|
|
18 |
/* |
/* |
19 |
* Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for |
* Parse the INFOFILE file for the specified REPOSITORY. Invoke CALLPROC for |
20 |
* the first line in the file that matches the REPOSITORY, or if ALL != 0, any |
* the first line in the file that matches the REPOSITORY, or if ALL != 0, any |
142 |
if (!(opt & PIOPT_ALL)) |
if (!(opt & PIOPT_ALL)) |
143 |
error (0, 0, "Keyword `ALL' is ignored at line %d in %s file", |
error (0, 0, "Keyword `ALL' is ignored at line %d in %s file", |
144 |
line_number, infofile); |
line_number, infofile); |
145 |
else if ((expanded_value = expand_path (value, true, infofile, |
else if ((expanded_value = |
146 |
line_number)) != NULL) |
expand_path (value, current_parsed_root->directory, |
147 |
|
true, infofile, line_number))) |
148 |
{ |
{ |
149 |
err += callproc (repository, expanded_value, closure); |
err += callproc (repository, expanded_value, closure); |
150 |
free (expanded_value); |
free (expanded_value); |
170 |
continue; /* no match */ |
continue; /* no match */ |
171 |
|
|
172 |
/* it did, so do the callback and note that we did one */ |
/* it did, so do the callback and note that we did one */ |
173 |
expanded_value = expand_path (value, true, infofile, line_number); |
expanded_value = expand_path (value, current_parsed_root->directory, |
174 |
|
true, infofile, line_number); |
175 |
if (expanded_value) |
if (expanded_value) |
176 |
{ |
{ |
177 |
err += callproc (repository, expanded_value, closure); |
err += callproc (repository, expanded_value, closure); |
189 |
/* if we fell through and didn't callback at all, do the default */ |
/* if we fell through and didn't callback at all, do the default */ |
190 |
if (!callback_done && default_value) |
if (!callback_done && default_value) |
191 |
{ |
{ |
192 |
expanded_value = expand_path (default_value, true, infofile, |
expanded_value = expand_path (default_value, |
193 |
line_number); |
current_parsed_root->directory, |
194 |
|
true, infofile, line_number); |
195 |
if (expanded_value) |
if (expanded_value) |
196 |
{ |
{ |
197 |
err += callproc (repository, expanded_value, closure); |
err += callproc (repository, expanded_value, closure); |
345 |
|
|
346 |
|
|
347 |
|
|
348 |
|
#ifdef ALLOW_CONFIG_OVERRIDE |
349 |
|
const char * const allowed_config_prefixes[] = { ALLOW_CONFIG_OVERRIDE }; |
350 |
|
#endif /* ALLOW_CONFIG_OVERRIDE */ |
351 |
|
|
352 |
|
|
353 |
|
|
354 |
/* Parse the CVS config file. The syntax right now is a bit ad hoc |
/* Parse the CVS config file. The syntax right now is a bit ad hoc |
355 |
* but tries to draw on the best or more common features of the other |
* but tries to draw on the best or more common features of the other |
356 |
* *info files and various unix (or non-unix) config file syntaxes. |
* *info files and various unix (or non-unix) config file syntaxes. |
372 |
* xmalloc() failures are fatal, per usual. |
* xmalloc() failures are fatal, per usual. |
373 |
*/ |
*/ |
374 |
struct config * |
struct config * |
375 |
parse_config (const char *cvsroot) |
parse_config (const char *cvsroot, const char *path) |
376 |
{ |
{ |
377 |
char *infopath; |
const char *infopath; |
378 |
|
char *freeinfopath = NULL; |
379 |
FILE *fp_info; |
FILE *fp_info; |
380 |
char *line = NULL; |
char *line = NULL; |
381 |
unsigned int ln; /* Input file line counter. */ |
unsigned int ln; /* Input file line counter. */ |
386 |
|
|
387 |
TRACE (TRACE_FUNCTION, "parse_config (%s)", cvsroot); |
TRACE (TRACE_FUNCTION, "parse_config (%s)", cvsroot); |
388 |
|
|
389 |
retval = new_config (); |
#ifdef ALLOW_CONFIG_OVERRIDE |
390 |
|
if (path) |
391 |
|
{ |
392 |
|
const char * const *prefix; |
393 |
|
char *npath = xcanonicalize_file_name (path); |
394 |
|
bool approved = false; |
395 |
|
for (prefix = allowed_config_prefixes; *prefix != NULL; prefix++) |
396 |
|
{ |
397 |
|
if (!isreadable (*prefix)) continue; |
398 |
|
char *nprefix = xcanonicalize_file_name (*prefix); |
399 |
|
if (!strncmp (nprefix, npath, strlen (nprefix)) |
400 |
|
&& (((*prefix)[strlen (*prefix)] != '/' |
401 |
|
&& strlen (npath) == strlen (nprefix)) |
402 |
|
|| ((*prefix)[strlen (*prefix)] == '/' |
403 |
|
&& npath[strlen (nprefix)] == '/'))) |
404 |
|
approved = true; |
405 |
|
free (nprefix); |
406 |
|
if (approved) break; |
407 |
|
} |
408 |
|
if (!approved) |
409 |
|
error (1, 0, "Invalid path to config file specified: `%s'", |
410 |
|
path); |
411 |
|
infopath = path; |
412 |
|
free (npath); |
413 |
|
} |
414 |
|
else |
415 |
|
#endif |
416 |
|
infopath = freeinfopath = |
417 |
|
Xasprintf ("%s/%s/%s", cvsroot, CVSROOTADM, CVSROOTADM_CONFIG); |
418 |
|
|
419 |
infopath = Xasprintf ("%s/%s/%s", cvsroot, CVSROOTADM, CVSROOTADM_CONFIG); |
retval = new_config (); |
420 |
|
|
421 |
fp_info = CVS_FOPEN (infopath, "r"); |
fp_info = CVS_FOPEN (infopath, "r"); |
422 |
if (!fp_info) |
if (!fp_info) |
428 |
value, currently at least. */ |
value, currently at least. */ |
429 |
error (0, errno, "cannot open %s", infopath); |
error (0, errno, "cannot open %s", infopath); |
430 |
} |
} |
431 |
free (infopath); |
if (freeinfopath) free (freeinfopath); |
432 |
return retval; |
return retval; |
433 |
} |
} |
434 |
|
|
525 |
{ |
{ |
526 |
if (retval->lock_dir) |
if (retval->lock_dir) |
527 |
free (retval->lock_dir); |
free (retval->lock_dir); |
528 |
retval->lock_dir = xstrdup (p); |
retval->lock_dir = expand_path (p, cvsroot, false, infopath, line); |
529 |
/* Could try some validity checking, like whether we can |
/* Could try some validity checking, like whether we can |
530 |
opendir it or something, but I don't see any particular |
opendir it or something, but I don't see any particular |
531 |
reason to do that now rather than waiting until lock.c. */ |
reason to do that now rather than waiting until lock.c. */ |
535 |
if (retval->HistoryLogPath) free (retval->HistoryLogPath); |
if (retval->HistoryLogPath) free (retval->HistoryLogPath); |
536 |
|
|
537 |
/* Expand ~ & $VARs. */ |
/* Expand ~ & $VARs. */ |
538 |
retval->HistoryLogPath = expand_path (p, false, infopath, ln); |
retval->HistoryLogPath = expand_path (p, cvsroot, false, |
539 |
|
infopath, ln); |
540 |
|
|
541 |
if (retval->HistoryLogPath && !ISABSOLUTE (retval->HistoryLogPath)) |
if (retval->HistoryLogPath && !ISABSOLUTE (retval->HistoryLogPath)) |
542 |
{ |
{ |
549 |
else if (strcmp (line, "HistorySearchPath") == 0) |
else if (strcmp (line, "HistorySearchPath") == 0) |
550 |
{ |
{ |
551 |
if (retval->HistorySearchPath) free (retval->HistorySearchPath); |
if (retval->HistorySearchPath) free (retval->HistorySearchPath); |
552 |
retval->HistorySearchPath = expand_path (p, false, infopath, ln); |
retval->HistorySearchPath = expand_path (p, cvsroot, false, |
553 |
|
infopath, ln); |
554 |
|
|
555 |
if (retval->HistorySearchPath |
if (retval->HistorySearchPath |
556 |
&& !ISABSOLUTE (retval->HistorySearchPath)) |
&& !ISABSOLUTE (retval->HistorySearchPath)) |
656 |
error (0, errno, "cannot read %s", infopath); |
error (0, errno, "cannot read %s", infopath); |
657 |
if (fclose (fp_info) < 0) |
if (fclose (fp_info) < 0) |
658 |
error (0, errno, "cannot close %s", infopath); |
error (0, errno, "cannot close %s", infopath); |
659 |
free (infopath); |
if (freeinfopath) free (freeinfopath); |
660 |
if (line) free (line); |
if (line) free (line); |
661 |
|
|
662 |
return retval; |
return retval; |
663 |
} |
} |