188 static const char *pcf_valid_master_types[] = {
196 static const char pcf_valid_bool_types[] =
"yn-";
198 #define STR(x) vstring_str(x)
202 static void pcf_extract_field(
ARGV *argv,
int field,
const char *parens)
204 char *arg = argv->
argv[field];
216 static void pcf_normalize_nameval(
ARGV *argv,
int field)
218 char *arg = argv->
argv[field];
227 normalized =
concatenate(name,
"=", value, (
char *) 0);
235 static void pcf_normalize_daemon_args(
ARGV *argv)
247 arg = argv->
argv[field];
248 if (arg[0] !=
'-' || strcmp(arg,
"--") == 0)
250 for (cp = arg + 1; *cp; cp++) {
270 }
else if (argv->
argv[field + 1] != 0) {
279 if (argv->
argv[field - 1][1] ==
'o')
280 pcf_normalize_nameval(argv, field);
284 for ( ; argv->
argv[field] != 0; field++)
310 static void pcf_check_master_entry(
ARGV *argv,
const char *raw_text)
318 for (cpp = pcf_valid_master_types; ; cpp++) {
322 if (strcmp(*cpp, cp) == 0)
327 cp = argv->
argv[field];
328 if (cp[1] != 0 || strchr(pcf_valid_bool_types, *cp) == 0)
329 pcf_fix_fatal(
"invalid %s field \"%s\" in \"%s\"",
335 if (len > 0 && cp[len - 1] ==
'?')
337 if (!(cp[0] ==
'-' && len == 1) && strspn(cp,
"0123456789") != len)
342 if (strcmp(
"-", cp) != 0 && cp[strspn(cp,
"0123456789")] != 0)
385 return (
"bad field count");
387 pcf_check_master_entry(argv, buf);
388 pcf_normalize_daemon_args(argv);
393 masterp->
argv = argv;
398 strcmp(process_name, argv->
argv[0]) != 0 ?
399 argv->
argv[0] : process_name);
410 const char *myname =
"pcf_read_master";
423 msg_panic(
"%s: master table is already initialized", myname);
442 if (fail_on_open_error)
447 while (
readllines(buf, fp, &last_line, &line_count) != 0) {
452 msg_fatal(
"file %s: line %d: %s", path, line_count, err);
476 int in_daemon_options;
478 static int column_goal[] = {
489 #define ADD_TEXT(text, len) do { \
490 vstream_fputs(text, fp); line_len += len; } \
492 #define ADD_SPACE ADD_TEXT(" ", 1)
503 }
while (line_len < column_goal[field]);
513 in_daemon_options = 1;
514 for ( ; (arg = argv[field]) != 0; field++) {
515 arg_len = strlen(arg);
518 if (in_daemon_options) {
524 if (arg[0] !=
'-' || strcmp(arg,
"--") == 0) {
525 in_daemon_options = 0;
537 && (aval = argv[field + 1]) != 0) {
545 if (strcmp(arg,
"-o") == 0
553 arg_len += strlen(aval) + 3;
573 if (in_daemon_options == 0 && need_parens)
576 if (in_daemon_options == 0 && need_parens)
611 mymalloc(
sizeof(*field_reqs) * argc);
612 for (req = field_reqs; req < field_reqs + argc; req++) {
618 msg_fatal(
"-M option requires service_name[/type]");
627 for (req = field_reqs; req < field_reqs + argc; req++) {
644 for (req = field_reqs; req < field_reqs + argc; req++) {
649 myfree((
void *) field_reqs);
655 static void pcf_print_master_field(
VSTREAM *fp,
int mode,
664 int in_daemon_options;
671 #define ADD_CHAR(ch) ADD_TEXT((ch), 1)
685 if (line_len > 0 && line_len + strlen(argv[field]) >
PCF_LINE_LIMIT) {
689 ADD_TEXT(argv[field], strlen(argv[field]));
698 in_daemon_options = 1;
699 for (field += 1; (arg = argv[field]) != 0; field++) {
700 arg_len = strlen(arg);
703 if (in_daemon_options) {
709 if (arg[0] !=
'-' || strcmp(arg,
"--") == 0) {
710 in_daemon_options = 0;
712 && (aval = argv[field + 1]) != 0) {
720 if (strcmp(arg,
"-o") == 0
728 arg_len += strlen(aval) + 1;
748 if (in_daemon_options == 0 && need_parens)
751 if (in_daemon_options == 0 && need_parens)
777 const char *myname =
"pcf_show_master_fields";
788 mymalloc(
sizeof(*field_reqs) * argc);
789 for (req = field_reqs; req < field_reqs + argc; req++) {
795 msg_fatal(
"-F option requires service_name[/type[/field]]");
800 msg_panic(
"%s: bad attribute field index: %d",
810 for (req = field_reqs; req < field_reqs + argc; req++) {
818 pcf_print_master_field(fp, mode, masterp, field);
820 pcf_print_master_field(fp, mode, masterp, field);
826 pcf_print_master_field(fp, mode, masterp, field);
834 for (req = field_reqs; req < field_reqs + argc; req++) {
839 myfree((
void *) field_reqs);
846 const char *new_value)
855 pcf_normalize_daemon_args(masterp->
argv);
868 pcf_check_master_entry(masterp->
argv, new_value);
873 static void pcf_print_master_param(
VSTREAM *fp,
int mode,
875 const char *param_name,
876 const char *param_value)
878 if (mode & PCF_HIDE_VALUE) {
883 if ((mode & PCF_SHOW_EVAL) != 0)
885 param_value, masterp);
886 if ((mode & PCF_HIDE_NAME) == 0) {
889 param_name, param_value);
900 static int pcf_sort_argv_cb(
const void *a,
const void *b)
902 return (strcmp(*(
char **) a, *(
char **) b));
907 static void pcf_show_master_any_param(
VSTREAM *fp,
int mode,
910 const char *myname =
"pcf_show_master_any_param";
913 const char *param_name;
914 const char *param_value;
928 dict->
sequence(dict, how, ¶m_name, ¶m_value) == 0;
936 qsort(argv->
argv, param_count,
sizeof(argv->
argv[0]), pcf_sort_argv_cb);
937 for (cpp = argv->
argv; (param_name = *cpp) != 0; cpp++) {
938 if ((param_value =
dict_get(dict, param_name)) == 0)
939 msg_panic(
"%s: parameter name not found: %s", myname, param_name);
940 pcf_print_master_param(fp, mode, masterp, param_name, param_value);
957 const char *param_value;
964 mymalloc(
sizeof(*field_reqs) * argc);
965 for (req = field_reqs; req < field_reqs + argc; req++) {
971 msg_fatal(
"-P option requires service_name[/type[/parameter]]");
982 for (req = field_reqs; req < field_reqs + argc; req++) {
987 pcf_show_master_any_param(fp, mode, masterp);
989 }
else if ((param_value =
dict_get(dict,
991 pcf_print_master_param(fp, mode, masterp,
999 pcf_show_master_any_param(fp, mode, masterp);
1008 for (req = field_reqs; req < field_reqs + argc; req++) {
1013 myfree((
void *) field_reqs);
1020 const char *param_name,
1021 const char *param_value)
1023 const char *myname =
"pcf_edit_master_param";
1027 int param_match = 0;
1028 int name_len = strlen(param_name);
1032 arg = argv->
argv[field];
1037 if (arg[0] !=
'-' || strcmp(arg,
"--") == 0) {
1045 && (aval = argv->
argv[field + 1]) != 0) {
1050 if (strcmp(arg,
"-o") == 0) {
1051 if (strncmp(aval, param_name, name_len) == 0
1052 && aval[name_len] ==
'=') {
1061 param_value, (
char *) 0);
1080 msg_panic(
"%s: unexpected mode: %d", myname, mode);
1099 param_value, (
char *) 0);
void htable_free(HTABLE *table, void(*free_fn)(void *))
#define dict_put(dp, key, val)
char * extpar(char **bp, const char *parens, int flags)
void pcf_show_master_entries(VSTREAM *fp, int mode, int argc, char **argv)
const char * param_pattern
#define PCF_MASTER_FLD_TYPE
ARGV * argv_free(ARGV *argvp)
#define DICT_SEQ_FUN_FIRST
PCF_MASTER_ENT * pcf_master_table
NORETURN msg_panic(const char *fmt,...)
ARGV * pcf_parse_service_pattern(const char *, int, int)
void argv_replace_one(ARGV *argvp, ssize_t where, const char *arg)
void * myrealloc(void *ptr, ssize_t len)
#define DICT_SEQ_FUN_NEXT
void pcf_edit_master_field(PCF_MASTER_ENT *masterp, int field, const char *new_value)
char * pcf_expand_parameter_value(VSTRING *, int, const char *, PCF_MASTER_ENT *)
#define PCF_MASTER_FLD_PRIVATE
void pcf_show_master_fields(VSTREAM *fp, int mode, int argc, char **argv)
#define EXTPAR_FLAG_STRIP
void argv_add(ARGV *argvp,...)
const char * pcf_parse_master_entry(PCF_MASTER_ENT *masterp, const char *buf)
void pcf_edit_master_param(PCF_MASTER_ENT *masterp, int mode, const char *param_name, const char *param_value)
#define MASTER_XPORT_NAME_PASS
char * translit(char *, const char *, const char *)
ARGV * argv_alloc(ssize_t len)
#define PCF_NAMESP_SEP_CH
const char * split_nameval(char *buf, char **name, char **value)
ARGV * argv_splitq_append(ARGV *, const char *, const char *, const char *)
#define pcf_str_field_pattern(pat)
void pcf_print_master_entry(VSTREAM *fp, int mode, PCF_MASTER_ENT *masterp)
#define PCF_MASTER_NAME_TYPE
#define PCF_MASTER_NAME_MAXPROC
VSTREAM * vstream_fopen(const char *path, int flags, mode_t mode)
void pcf_read_master(int fail_on_open_error)
const char pcf_daemon_options_expecting_value[]
VSTRING * vstring_vsprintf(VSTRING *vp, const char *format, va_list ap)
#define PCF_MATCH_SERVICE_PATTERN(pat, name, type)
#define PCF_IS_MAGIC_PARAM_PATTERN(pat)
ARGV * argv_splitq(const char *, const char *, const char *)
#define PCF_MASTER_FLD_CMD
#define dict_get(dp, key)
int vstream_fclose(VSTREAM *stream)
DICT * dict_handle(const char *dict_name)
void msg_warn(const char *fmt,...)
VSTRING * vstring_alloc(ssize_t len)
#define PCF_MASTER_FLD_CHROOT
void argv_truncate(ARGV *argvp, ssize_t len)
int pcf_parse_field_pattern(const char *)
#define PCF_NAMESP_SEP_STR
void argv_delete(ARGV *argvp, ssize_t first, ssize_t how_many)
#define MASTER_XPORT_NAME_FIFO
#define MASTER_XPORT_NAME_INET
NORETURN msg_fatal(const char *fmt,...)
int dict_update(const char *dict_name, const char *member, const char *value)
#define MASTER_XPORT_NAME_UNIX
VSTRING * readllines(VSTRING *buf, VSTREAM *fp, int *lineno, int *first_line)
int vstream_fflush(VSTREAM *stream)
char * concatenate(const char *arg0,...)
#define ADD_TEXT(text, len)
#define pcf_is_magic_field_pattern(pat)
void pcf_free_master_entry(PCF_MASTER_ENT *masterp)
VSTRING * vstring_free(VSTRING *vp)
#define PCF_MASTER_FLD_WAKEUP
#define PCF_MASTER_NAME_WAKEUP
void pcf_set_config_dir(void)
int(* sequence)(struct DICT *, int, const char **, const char **)
void pcf_show_master_params(VSTREAM *fp, int mode, int argc, char **argv)
#define dict_del(dp, key)
void pcf_print_line(VSTREAM *fp, int mode, const char *fmt,...)
void argv_insert_one(ARGV *argvp, ssize_t where, const char *arg)
#define PCF_MASTER_BLANKS
#define PCF_MASTER_FLD_MAXPROC
#define PCF_MASTER_MIN_FIELDS
void * mymalloc(ssize_t len)
int vstream_fputs(const char *str, VSTREAM *stream)