Upgrade to version 1.05
[unix-history] / gnu / libexec / uucp / libuuconf / rdperm.c
CommitLineData
41c799d4
C
1/* rdperm.c
2 Read the HDB Permissions file.
3
3469b437 4 Copyright (C) 1992, 1993 Ian Lance Taylor
41c799d4
C
5
6 This file is part of the Taylor UUCP uuconf library.
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public License
10 as published by the Free Software Foundation; either version 2 of
11 the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 The author of the program may be contacted at ian@airs.com or
3469b437 23 c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139.
41c799d4
C
24 */
25
26#include "uucnfi.h"
27
28#if USE_RCS_ID
3469b437 29const char _uuconf_rdperm_rcsid[] = "$Id: rdperm.c,v 1.7 1994/01/30 21:14:29 ian Rel $";
41c799d4
C
30#endif
31
32#include <errno.h>
33#include <ctype.h>
34\f
35static int ihcolon P((pointer pglobal, int argc, char **argv, pointer pvar,
36 pointer pinfo));
37static int ihsendfiles P((pointer pglobal, int argc, char **argv,
38 pointer pvar, pointer pinfo));
39static int ihunknownperm P((pointer pglobal, int argc, char **argv,
40 pointer pvar, pointer pinfo));
41static int ihadd_norw P((struct sglobal *qglobal, char ***ppz, char **pzno));
42\f
43/* These routines reads in the HDB Permissions file. We store the
44 entries in a linked list of shpermissions structures, so we only
45 have to actually read the file once. */
46
47/* This command table and static structure are used to parse a line
48 from Permissions. The entries are parsed as follows:
49
50 Multiple strings separated by colons: LOGNAME, MACHINE, READ,
51 WRITE, NOREAD, NOWRITE, COMMANDS, VALIDATE, ALIAS.
52
53 Boolean values: REQUEST, CALLBACK.
54
55 Simple strings: MYNAME, PUBDIR.
56
57 "Yes" or "call": SENDFILES.
58
59 The NOREAD and NOWRITE entries are merged into the READ and WRITE
60 entries, rather than being permanently stored. They are handled
61 specially in the uuconf_cmdtab table. */
62
63static const struct cmdtab_offset asHperm_cmds[] =
64{
65 { "NOREAD", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, ihcolon },
66 { "NOWRITE", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, ihcolon },
67 { "LOGNAME", UUCONF_CMDTABTYPE_FN | 2,
68 offsetof (struct shpermissions, pzlogname), ihcolon },
69 { "MACHINE", UUCONF_CMDTABTYPE_FN | 2,
70 offsetof (struct shpermissions, pzmachine), ihcolon },
71 { "REQUEST", UUCONF_CMDTABTYPE_BOOLEAN,
72 offsetof (struct shpermissions, frequest), NULL },
73 { "SENDFILES", UUCONF_CMDTABTYPE_FN | 2,
74 offsetof (struct shpermissions, fsendfiles), ihsendfiles },
75 { "READ", UUCONF_CMDTABTYPE_FN | 2,
76 offsetof (struct shpermissions, pzread), ihcolon },
77 { "WRITE", UUCONF_CMDTABTYPE_FN | 2,
78 offsetof (struct shpermissions, pzwrite), ihcolon },
79 { "CALLBACK", UUCONF_CMDTABTYPE_BOOLEAN,
80 offsetof (struct shpermissions, fcallback), NULL },
81 { "COMMANDS", UUCONF_CMDTABTYPE_FN | 2,
82 offsetof (struct shpermissions, pzcommands), ihcolon },
83 { "VALIDATE", UUCONF_CMDTABTYPE_FN | 2,
84 offsetof (struct shpermissions, pzvalidate), ihcolon },
85 { "MYNAME", UUCONF_CMDTABTYPE_STRING,
86 offsetof (struct shpermissions, zmyname), NULL },
87 { "PUBDIR", UUCONF_CMDTABTYPE_STRING,
88 offsetof (struct shpermissions, zpubdir), NULL },
89 { "ALIAS", UUCONF_CMDTABTYPE_FN | 2,
90 offsetof (struct shpermissions, pzalias), ihcolon },
91 { NULL, 0, 0, NULL }
92};
93
94#define CHPERM_CMDS (sizeof asHperm_cmds / sizeof asHperm_cmds[0])
95\f
96/* Actually read the Permissions file into a linked list of
97 structures. */
98
99int
100_uuconf_ihread_permissions (qglobal)
101 struct sglobal *qglobal;
102{
103 char *zperm;
104 FILE *e;
105 int iret;
106 struct uuconf_cmdtab as[CHPERM_CMDS];
107 char **pznoread, **pznowrite;
108 struct shpermissions shperm;
109 char *zline;
110 size_t cline;
111 char **pzsplit;
112 size_t csplit;
113 int cchars;
114 struct shpermissions *qlist, **pq;
115
116 if (qglobal->qprocess->fhdb_read_permissions)
117 return UUCONF_SUCCESS;
118
119 zperm = (char *) uuconf_malloc (qglobal->pblock,
120 (sizeof OLDCONFIGLIB
121 + sizeof HDB_PERMISSIONS - 1));
122 if (zperm == NULL)
123 {
124 qglobal->ierrno = errno;
125 return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
126 }
127
128 memcpy ((pointer) zperm, (pointer) OLDCONFIGLIB,
129 sizeof OLDCONFIGLIB - 1);
130 memcpy ((pointer) (zperm + sizeof OLDCONFIGLIB - 1),
131 (pointer) HDB_PERMISSIONS, sizeof HDB_PERMISSIONS);
132
133 e = fopen (zperm, "r");
134 if (e == NULL)
135 {
136 uuconf_free (qglobal->pblock, zperm);
137 qglobal->qprocess->fhdb_read_permissions = TRUE;
138 return UUCONF_SUCCESS;
139 }
140
141 _uuconf_ucmdtab_base (asHperm_cmds, CHPERM_CMDS, (char *) &shperm, as);
142 as[0].uuconf_pvar = (pointer) &pznoread;
143 as[1].uuconf_pvar = (pointer) &pznowrite;
144
145 zline = NULL;
146 cline = 0;
147 pzsplit = NULL;
148 csplit = 0;
149
150 qlist = NULL;
151 pq = &qlist;
152
153 qglobal->ilineno = 0;
154
155 iret = UUCONF_SUCCESS;
156
157 while ((cchars = _uuconf_getline (qglobal, &zline, &cline, e)) > 0)
158 {
159 int centries;
160 struct shpermissions *qnew;
161 int i;
162
163 ++qglobal->ilineno;
164
165 --cchars;
166 if (zline[cchars] == '\n')
167 zline[cchars] = '\0';
3469b437 168 if (zline[0] == '#')
41c799d4
C
169 continue;
170
171 centries = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
172 if (centries < 0)
173 {
174 qglobal->ierrno = errno;
175 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
176 break;
177 }
178
179 if (centries == 0)
180 continue;
181
182 shperm.pzlogname = (char **) &_uuconf_unset;
183 shperm.pzmachine = (char **) &_uuconf_unset;
184 shperm.frequest = -1;
185 shperm.fsendfiles = -1;
186 shperm.pzread = (char **) &_uuconf_unset;
187 shperm.pzwrite = (char **) &_uuconf_unset;
188 shperm.fcallback = -1;
189 shperm.pzcommands = (char **) &_uuconf_unset;
190 shperm.pzvalidate = (char **) &_uuconf_unset;
191 shperm.zmyname = (char *) &_uuconf_unset;
192 shperm.zpubdir = (char *) &_uuconf_unset;
193 shperm.pzalias = (char **) &_uuconf_unset;
194 pznoread = (char **) &_uuconf_unset;
195 pznowrite = (char **) &_uuconf_unset;
196
197 for (i = 0; i < centries; i++)
198 {
199 char *zeq;
200 char *azargs[2];
201
202 zeq = strchr (pzsplit[i], '=');
203 if (zeq == NULL)
204 {
205 iret = UUCONF_SYNTAX_ERROR;
206 qglobal->qprocess->fhdb_read_permissions = TRUE;
207 break;
208 }
209 *zeq = '\0';
210
211 azargs[0] = pzsplit[i];
212 azargs[1] = zeq + 1;
213
214 iret = uuconf_cmd_args (qglobal, 2, azargs, as, (pointer) NULL,
215 ihunknownperm, 0, qglobal->pblock);
216 if ((iret & UUCONF_CMDTABRET_KEEP) != 0)
217 {
218 iret &=~ UUCONF_CMDTABRET_KEEP;
219
220 if (uuconf_add_block (qglobal->pblock, zline) != 0)
221 {
222 qglobal->ierrno = errno;
223 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
224 break;
225 }
226
227 zline = NULL;
228 cline = 0;
229 }
230 if ((iret & UUCONF_CMDTABRET_EXIT) != 0)
231 {
232 iret &=~ UUCONF_CMDTABRET_EXIT;
233 break;
234 }
235 }
236
237 if (iret != UUCONF_SUCCESS)
238 break;
239
240 if (shperm.pzmachine == (char **) &_uuconf_unset
241 && shperm.pzlogname == (char **) &_uuconf_unset)
242 {
243 iret = UUCONF_SYNTAX_ERROR;
244 qglobal->qprocess->fhdb_read_permissions = TRUE;
245 break;
246 }
247
248 /* Attach any NOREAD or NOWRITE entries to the corresponding
249 READ or WRITE entries in the format expected for the
250 pzlocal_receive, etc., fields in uuconf_system. */
251 if (pznoread != NULL)
252 {
253 iret = ihadd_norw (qglobal, &shperm.pzread, pznoread);
254 if (iret != UUCONF_SUCCESS)
255 break;
256 uuconf_free (qglobal->pblock, pznoread);
257 }
258
259 if (pznowrite != NULL)
260 {
261 iret = ihadd_norw (qglobal, &shperm.pzwrite, pznowrite);
262 if (iret != UUCONF_SUCCESS)
263 break;
264 uuconf_free (qglobal->pblock, pznowrite);
265 }
266
267 qnew = ((struct shpermissions *)
268 uuconf_malloc (qglobal->pblock,
269 sizeof (struct shpermissions)));
270 if (qnew == NULL)
271 {
272 qglobal->ierrno = errno;
273 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
274 break;
275 }
276
277 *qnew = shperm;
278 *pq = qnew;
279 pq = &qnew->qnext;
280 *pq = NULL;
281 }
282
283 (void) fclose (e);
284
285 if (zline != NULL)
286 free ((pointer) zline);
287 if (pzsplit != NULL)
288 free ((pointer) pzsplit);
289
290 if (iret == UUCONF_SUCCESS)
291 {
292 qglobal->qprocess->qhdb_permissions = qlist;
293 qglobal->qprocess->fhdb_read_permissions = TRUE;
294 }
295 else
296 {
297 qglobal->zfilename = zperm;
298 iret |= UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
299 }
300
301 return iret;
302}
303\f
304/* Split the argument into colon separated strings, and assign a NULL
305 terminated array of strings to pvar. */
306
307/*ARGSUSED*/
308static int
309ihcolon (pglobal, argc, argv, pvar, pinfo)
310 pointer pglobal;
311 int argc;
312 char **argv;
313 pointer pvar;
314 pointer pinfo;
315{
316 struct sglobal *qglobal = (struct sglobal *) pglobal;
317 char ***ppz = (char ***) pvar;
318 char **pzsplit;
319 size_t csplit;
320 int centries;
321 int i;
322 int iret;
323
324 *ppz = NULL;
325
326 pzsplit = NULL;
327 csplit = 0;
328
329 centries = _uuconf_istrsplit (argv[1], ':', &pzsplit, &csplit);
330 if (centries < 0)
331 {
332 qglobal->ierrno = errno;
333 return (UUCONF_MALLOC_FAILED
334 | UUCONF_ERROR_ERRNO
335 | UUCONF_CMDTABRET_EXIT);
336 }
337
338 if (centries == 0)
339 {
340 if (pzsplit != NULL)
341 free ((pointer) pzsplit);
342 return UUCONF_CMDTABRET_CONTINUE;
343 }
344
345 iret = UUCONF_SUCCESS;
346
347 for (i = 0; i < centries; i++)
348 {
349 iret = _uuconf_iadd_string (qglobal, pzsplit[i], FALSE, FALSE,
350 ppz, qglobal->pblock);
351 if (iret != UUCONF_SUCCESS)
352 {
353 iret |= UUCONF_CMDTABRET_EXIT;
354 break;
355 }
356 }
357
358 free ((pointer) pzsplit);
359
360 return UUCONF_CMDTABRET_KEEP;
361}
362
363/* Handle the SENDFILES parameter, which can take "yes" or "call" or
364 "no" as an argument. The string "call" is equivalent to "no". */
365
366/*ARGSUSED*/
367static int
368ihsendfiles (pglobal, argc, argv, pvar, pinfo)
369 pointer pglobal;
370 int argc;
371 char **argv;
372 pointer pvar;
373 pointer pinfo;
374{
375 int *pi = (int *) pvar;
376
377 switch (argv[1][0])
378 {
379 case 'C':
380 case 'c':
381 case 'N':
382 case 'n':
383 *pi = FALSE;
384 break;
385 case 'Y':
386 case 'y':
387 *pi = TRUE;
388 break;
389 default:
390 return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
391 }
392
393 return UUCONF_CMDTABRET_CONTINUE;
394}
395
396/* If there is an unknown Permissions entry, return a syntax error.
397 This should probably be more clever. */
398
399/*ARGSUSED*/
400static int
401ihunknownperm (pglobal, argc, argv, pvar, pinfo)
402 pointer pglobal;
403 int argc;
404 char **argv;
405 pointer pvar;
406 pointer pinfo;
407{
408 return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
409}
410
411/* Add a NOREAD or NOWRITE entry to a READ or WRITE entry. */
412
413static int
414ihadd_norw (qglobal, ppz, pzno)
415 struct sglobal *qglobal;
416 char ***ppz;
417 char **pzno;
418{
419 register char **pz;
420
421 if (pzno == (char **) &_uuconf_unset)
422 return UUCONF_SUCCESS;
423
424 for (pz = pzno; *pz != NULL; pz++)
425 {
426 size_t csize;
427 char *znew;
428 int iret;
429
3469b437
AC
430 /* Ignore an attempt to say NOREAD or NOWRITE with an empty
431 string, since it will be interpreted as an attempt to deny
432 everything. */
433 if (**pz != '\0')
41c799d4 434 {
3469b437
AC
435 csize = strlen (*pz) + 1;
436 znew = (char *) uuconf_malloc (qglobal->pblock, csize + 1);
437 if (znew == NULL)
438 {
439 qglobal->ierrno = errno;
440 return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
441 }
442 znew[0] = '!';
443 memcpy ((pointer) (znew + 1), (pointer) *pz, csize);
444 iret = _uuconf_iadd_string (qglobal, znew, FALSE, FALSE, ppz,
445 qglobal->pblock);
446 if (iret != UUCONF_SUCCESS)
447 return iret;
41c799d4 448 }
41c799d4
C
449 }
450
451 return UUCONF_SUCCESS;
452}