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