1 /*
2 * The contents of this file are subject to the terms of the
3 * Common Development and Distribution License, Version 1.0 only
4 * (the "License"). You may not use this file except in compliance
5 * with the License.
6 *
7 * See the file CDDL.Schily.txt in this distribution for details.
8 *
9 * When distributing Covered Code, include this CDDL HEADER in each
10 * file and include the License file CDDL.Schily.txt from this distribution.
11 */
12 /*
13 * @(#)parsex.c 1.10 20/08/24 Copyright 2018-2020 J. Schilling
14 */
15 #if defined(sun)
16 #pragma ident "@(#)parsex.c 1.10 20/08/24 Copyright 2018-2020 J. Schilling"
17 #endif
18
19 #if defined(sun)
20 #pragma ident "@(#)parsex.c"
21 #pragma ident "@(#)sccs:lib/comobj/parsex.c"
22 #endif
23 #include <defines.h>
24 #include <i18n.h>
25
26 int
parseX(X)27 parseX(X)
28 Xparms *X;
29 {
30 char *opts = X->x_parm;
31 char *ep;
32 char *np;
33 int optlen;
34 long optflags = X->x_opts;
35 unsigned flags = X->x_flags;
36 BOOL not = FALSE;
37
38 while (*opts) {
39 /*
40 * If '=' appears in the string to the right of a ',', this
41 * would be a wrong match.
42 */
43 np = strchr(opts, ',');
44 if ((ep = strchr(opts, '=')) != NULL &&
45 (np == NULL || np > ep)) {
46 Intptr_t pdiff = ep - opts;
47
48 optlen = (int)pdiff;
49 if (optlen != pdiff) /* lint paranoia */
50 return (FALSE);
51 optlen++;
52 if ((np = strchr(opts, ',')) == NULL) {
53 np = &opts[strlen(opts)];
54 } else {
55 np++;
56 }
57 } else if ((ep = np) != NULL) { /* pointer to ',' */
58 Intptr_t pdiff = ep - opts;
59
60 optlen = (int)pdiff;
61 if (optlen != pdiff) /* lint paranoia */
62 return (FALSE);
63 np = &ep[1];
64 } else {
65 optlen = strlen(opts);
66 np = &opts[optlen];
67 }
68 if (opts[0] == '!') {
69 opts++;
70 optlen--;
71 not = TRUE;
72 }
73 if (strncmp(opts, "not", optlen) == 0 ||
74 strncmp(opts, "!", optlen) == 0) {
75 not = TRUE;
76 } else if ((flags & XO_INIT_PATH) &&
77 strncmp(opts, "Gp=", optlen) == 0) {
78 size_t l = np - &opts[3];
79
80 if (optlen != 3)
81 goto bad;
82 if (opts[3]) {
83 if (*np == '\0')
84 l++;
85 X->x_init_path = xmalloc(l);
86 strlcpy(X->x_init_path, &opts[3], l);
87 optflags |= XO_INIT_PATH;
88 }
89
90 } else if ((flags & XO_URAND) &&
91 strncmp(opts, "Gr=", optlen) == 0) {
92 size_t l = np - &opts[3];
93 char buf[33];
94
95 if (*np == '\0')
96 l++;
97 if (optlen != 3 || l > sizeof (buf))
98 goto bad;
99 if (opts[3]) {
100 strlcpy(buf, &opts[3], l);
101 if (*urand_ab(buf, &X->x_rand))
102 goto bad;
103 optflags |= XO_URAND;
104 }
105
106 } else if ((flags & XO_G_PATH) &&
107 strncmp(opts, "gpath=", optlen) == 0) {
108 size_t l = np - &opts[6];
109
110 if (optlen != 6)
111 goto bad;
112 if (opts[6]) {
113 if (*np == '\0')
114 l++;
115 X->x_gpath = xmalloc(l);
116 strlcpy(X->x_gpath, &opts[6], l);
117 optflags |= XO_G_PATH;
118 }
119
120 } else if ((flags & XO_MAIL) &&
121 strncmp(opts, "mail=", optlen) == 0) {
122 size_t l = np - &opts[5];
123
124 if (optlen != 5)
125 goto bad;
126 if (opts[5]) {
127 if (*np == '\0')
128 l++;
129 X->x_mail = xmalloc(l);
130 strlcpy(X->x_mail, &opts[5], l);
131 optflags |= XO_MAIL;
132 }
133
134 } else if ((flags & XO_USER) &&
135 strncmp(opts, "user=", optlen) == 0) {
136 size_t l = np - &opts[5];
137
138 if (optlen != 5)
139 goto bad;
140 if (opts[5]) {
141 if (*np == '\0')
142 l++;
143 X->x_user = xmalloc(l);
144 strlcpy(X->x_user, &opts[5], l);
145 optflags |= XO_USER;
146 }
147
148 } else if ((flags & XO_DATE) &&
149 strncmp(opts, "date=", optlen) == 0) {
150 if (optlen != 5)
151 goto bad;
152 if (opts[5]) {
153 parse_datez(&opts[5], &X->x_dtime, PF_V6);
154 optflags |= XO_DATE;
155 }
156 } else if ((flags & XO_PREPEND_FILE) &&
157 strncmp(opts, "prepend", optlen) == 0) {
158 optflags |= XO_PREPEND_FILE;
159 } else if ((flags & XO_UNLINK) &&
160 strncmp(opts, "unlink", optlen) == 0) {
161 optflags |= XO_UNLINK;
162 } else if ((flags & XO_NULLPATH) &&
163 strncmp(opts, "0", optlen) == 0) {
164 optflags |= XO_NULLPATH;
165 } else if ((flags & XO_NOBULK) &&
166 strncmp(opts, "nobulk", optlen) == 0) {
167 optflags |= XO_NOBULK;
168 } else if (strncmp(opts, "help", optlen) == 0) {
169 sccshelp(stdout, "Xopts");
170 exit(0);
171 } else {
172 bad:
173 Fflags &= ~FTLEXIT;
174 fatal(gettext("illegal Xopt (co41)"));
175 sccshelp(stdout, "Xopts");
176 exit(1);
177 }
178 opts = np;
179 }
180 if (not)
181 optflags = ~optflags;
182
183 X->x_opts = optflags;
184
185 return (TRUE);
186 }
187