1 #ifndef OPT_H 2 #define OPT_H 3 4 #include <vstr.h> 5 #include <getopt.h> 6 #include <string.h> 7 8 #define OPT_SC_EXPORT_CSTR(e, x, mbs, desc) do { \ 9 if (vstr_srch_chr_fwd(x, 1, (x)->len, 0)) \ 10 usage(program_name, EXIT_FAILURE, \ 11 " The value for " desc " must not include a NIL character.\n"); \ 12 if ((mbs) && !(x)->len) \ 13 usage(program_name, EXIT_FAILURE, \ 14 " The value for " desc " can't be set to an empty string.\n"); \ 15 if ((x)->len && !((e) = vstr_export_cstr_ptr(x, 1, (x)->len))) \ 16 errno = ENOMEM, err(EXIT_FAILURE, "options"); \ 17 } while (FALSE) 18 19 #ifndef CONF_FULL_STATIC 20 # include <pwd.h> 21 # include <grp.h> 22 # include <sys/types.h> 23 # define OPT_SC_RESOLVE_UID(opts) do { \ 24 const char *name = NULL; \ 25 struct passwd *pw = NULL; \ 26 \ 27 OPT_SC_EXPORT_CSTR(name, opts->vpriv_uid, FALSE, "privilage uid"); \ 28 \ 29 if (name && (pw = getpwnam(name))) \ 30 (opts)->priv_uid = pw->pw_uid; \ 31 } while (FALSE) 32 # define OPT_SC_RESOLVE_GID(opts) do { \ 33 const char *name = NULL; \ 34 struct group *gr = NULL; \ 35 \ 36 OPT_SC_EXPORT_CSTR(name, opts->vpriv_gid, FALSE, "privilage gid"); \ 37 \ 38 if (name && (gr = getgrnam(name))) \ 39 (opts)->priv_uid = gr->gr_gid; \ 40 } while (FALSE) 41 #else 42 # define OPT_SC_RESOLVE_UID(opts) 43 # define OPT_SC_RESOLVE_GID(opts) 44 #endif 45 46 #define OPT_TOGGLE_ARG(val) (val = opt_toggle(val, optarg)) 47 #define OPT_NUM_ARG(val, desc, min, max, range_desc) do { \ 48 Vstr_base *opt__parse_num = vstr_dup_cstr_ptr(NULL, optarg); \ 49 unsigned int opt__nflags = VSTR_FLAG02(PARSE_NUM, OVERFLOW, SEP); \ 50 int opt__num = 0; \ 51 \ 52 if (!opt__parse_num) \ 53 errno = ENOMEM, err(EXIT_FAILURE, "parse_num(%s)", desc); \ 54 \ 55 opt__num = vstr_parse_ulong(opt__parse_num, 1, opt__parse_num->len, \ 56 opt__nflags, NULL, NULL); \ 57 if ((opt__num < min) || (opt__num > max)) \ 58 usage(program_name, EXIT_FAILURE, \ 59 " The value for " desc " must be in the range " \ 60 #min " to " #max range_desc ".\n"); \ 61 val = opt__num; \ 62 \ 63 vstr_free_base(opt__parse_num); \ 64 } while (FALSE) 65 #define OPT_NUM_NR_ARG(val, desc) do { \ 66 Vstr_base *opt__parse_num = vstr_dup_cstr_ptr(NULL, optarg); \ 67 unsigned int opt__nflags = VSTR_FLAG02(PARSE_NUM, OVERFLOW, SEP); \ 68 int opt__num = 0; \ 69 \ 70 if (!opt__parse_num) \ 71 errno = ENOMEM, err(EXIT_FAILURE, "parse_num(%s)", desc); \ 72 \ 73 opt__num = vstr_parse_ulong(opt__parse_num, 1, opt__parse_num->len, \ 74 opt__nflags, NULL, NULL); \ 75 val = opt__num; \ 76 \ 77 vstr_free_base(opt__parse_num); \ 78 } while (FALSE) 79 #define OPT_VSTR_ARG(val) do { \ 80 if (!vstr_sub_cstr_ptr((val), 1, (val)->len, optarg)) \ 81 errno = ENOMEM, err(EXIT_FAILURE, "parse_string(%s)", optarg); \ 82 } while (FALSE) 83 84 extern int opt_toggle(int, const char *); 85 86 /* get program name ... but ignore "lt-" libtool prefix */ 87 extern const char *opt_program_name(const char *, const char *); 88 89 extern const char *opt_def_toggle(int); 90 91 #endif 92