aboutsummaryrefslogtreecommitdiff
path: root/gnu/libexec/uucp/libuuconf/rdperm.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/libexec/uucp/libuuconf/rdperm.c')
-rw-r--r--gnu/libexec/uucp/libuuconf/rdperm.c446
1 files changed, 446 insertions, 0 deletions
diff --git a/gnu/libexec/uucp/libuuconf/rdperm.c b/gnu/libexec/uucp/libuuconf/rdperm.c
new file mode 100644
index 000000000000..950ba3bf943b
--- /dev/null
+++ b/gnu/libexec/uucp/libuuconf/rdperm.c
@@ -0,0 +1,446 @@
+/* rdperm.c
+ Read the HDB Permissions file.
+
+ Copyright (C) 1992 Ian Lance Taylor
+
+ This file is part of the Taylor UUCP uuconf library.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ The author of the program may be contacted at ian@airs.com or
+ c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
+ */
+
+#include "uucnfi.h"
+
+#if USE_RCS_ID
+const char _uuconf_rdperm_rcsid[] = "$Id: rdperm.c,v 1.1 1993/08/05 18:25:50 conklin Exp $";
+#endif
+
+#include <errno.h>
+#include <ctype.h>
+
+static int ihcolon P((pointer pglobal, int argc, char **argv, pointer pvar,
+ pointer pinfo));
+static int ihsendfiles P((pointer pglobal, int argc, char **argv,
+ pointer pvar, pointer pinfo));
+static int ihunknownperm P((pointer pglobal, int argc, char **argv,
+ pointer pvar, pointer pinfo));
+static int ihadd_norw P((struct sglobal *qglobal, char ***ppz, char **pzno));
+
+/* These routines reads in the HDB Permissions file. We store the
+ entries in a linked list of shpermissions structures, so we only
+ have to actually read the file once. */
+
+/* This command table and static structure are used to parse a line
+ from Permissions. The entries are parsed as follows:
+
+ Multiple strings separated by colons: LOGNAME, MACHINE, READ,
+ WRITE, NOREAD, NOWRITE, COMMANDS, VALIDATE, ALIAS.
+
+ Boolean values: REQUEST, CALLBACK.
+
+ Simple strings: MYNAME, PUBDIR.
+
+ "Yes" or "call": SENDFILES.
+
+ The NOREAD and NOWRITE entries are merged into the READ and WRITE
+ entries, rather than being permanently stored. They are handled
+ specially in the uuconf_cmdtab table. */
+
+static const struct cmdtab_offset asHperm_cmds[] =
+{
+ { "NOREAD", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, ihcolon },
+ { "NOWRITE", UUCONF_CMDTABTYPE_FN | 2, (size_t) -1, ihcolon },
+ { "LOGNAME", UUCONF_CMDTABTYPE_FN | 2,
+ offsetof (struct shpermissions, pzlogname), ihcolon },
+ { "MACHINE", UUCONF_CMDTABTYPE_FN | 2,
+ offsetof (struct shpermissions, pzmachine), ihcolon },
+ { "REQUEST", UUCONF_CMDTABTYPE_BOOLEAN,
+ offsetof (struct shpermissions, frequest), NULL },
+ { "SENDFILES", UUCONF_CMDTABTYPE_FN | 2,
+ offsetof (struct shpermissions, fsendfiles), ihsendfiles },
+ { "READ", UUCONF_CMDTABTYPE_FN | 2,
+ offsetof (struct shpermissions, pzread), ihcolon },
+ { "WRITE", UUCONF_CMDTABTYPE_FN | 2,
+ offsetof (struct shpermissions, pzwrite), ihcolon },
+ { "CALLBACK", UUCONF_CMDTABTYPE_BOOLEAN,
+ offsetof (struct shpermissions, fcallback), NULL },
+ { "COMMANDS", UUCONF_CMDTABTYPE_FN | 2,
+ offsetof (struct shpermissions, pzcommands), ihcolon },
+ { "VALIDATE", UUCONF_CMDTABTYPE_FN | 2,
+ offsetof (struct shpermissions, pzvalidate), ihcolon },
+ { "MYNAME", UUCONF_CMDTABTYPE_STRING,
+ offsetof (struct shpermissions, zmyname), NULL },
+ { "PUBDIR", UUCONF_CMDTABTYPE_STRING,
+ offsetof (struct shpermissions, zpubdir), NULL },
+ { "ALIAS", UUCONF_CMDTABTYPE_FN | 2,
+ offsetof (struct shpermissions, pzalias), ihcolon },
+ { NULL, 0, 0, NULL }
+};
+
+#define CHPERM_CMDS (sizeof asHperm_cmds / sizeof asHperm_cmds[0])
+
+/* Actually read the Permissions file into a linked list of
+ structures. */
+
+int
+_uuconf_ihread_permissions (qglobal)
+ struct sglobal *qglobal;
+{
+ char *zperm;
+ FILE *e;
+ int iret;
+ struct uuconf_cmdtab as[CHPERM_CMDS];
+ char **pznoread, **pznowrite;
+ struct shpermissions shperm;
+ char *zline;
+ size_t cline;
+ char **pzsplit;
+ size_t csplit;
+ int cchars;
+ struct shpermissions *qlist, **pq;
+
+ if (qglobal->qprocess->fhdb_read_permissions)
+ return UUCONF_SUCCESS;
+
+ zperm = (char *) uuconf_malloc (qglobal->pblock,
+ (sizeof OLDCONFIGLIB
+ + sizeof HDB_PERMISSIONS - 1));
+ if (zperm == NULL)
+ {
+ qglobal->ierrno = errno;
+ return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
+ }
+
+ memcpy ((pointer) zperm, (pointer) OLDCONFIGLIB,
+ sizeof OLDCONFIGLIB - 1);
+ memcpy ((pointer) (zperm + sizeof OLDCONFIGLIB - 1),
+ (pointer) HDB_PERMISSIONS, sizeof HDB_PERMISSIONS);
+
+ e = fopen (zperm, "r");
+ if (e == NULL)
+ {
+ uuconf_free (qglobal->pblock, zperm);
+ qglobal->qprocess->fhdb_read_permissions = TRUE;
+ return UUCONF_SUCCESS;
+ }
+
+ _uuconf_ucmdtab_base (asHperm_cmds, CHPERM_CMDS, (char *) &shperm, as);
+ as[0].uuconf_pvar = (pointer) &pznoread;
+ as[1].uuconf_pvar = (pointer) &pznowrite;
+
+ zline = NULL;
+ cline = 0;
+ pzsplit = NULL;
+ csplit = 0;
+
+ qlist = NULL;
+ pq = &qlist;
+
+ qglobal->ilineno = 0;
+
+ iret = UUCONF_SUCCESS;
+
+ while ((cchars = _uuconf_getline (qglobal, &zline, &cline, e)) > 0)
+ {
+ int centries;
+ struct shpermissions *qnew;
+ int i;
+
+ ++qglobal->ilineno;
+
+ --cchars;
+ if (zline[cchars] == '\n')
+ zline[cchars] = '\0';
+ if (isspace (BUCHAR (zline[0])) || zline[0] == '#')
+ continue;
+
+ centries = _uuconf_istrsplit (zline, '\0', &pzsplit, &csplit);
+ if (centries < 0)
+ {
+ qglobal->ierrno = errno;
+ iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
+ break;
+ }
+
+ if (centries == 0)
+ continue;
+
+ shperm.pzlogname = (char **) &_uuconf_unset;
+ shperm.pzmachine = (char **) &_uuconf_unset;
+ shperm.frequest = -1;
+ shperm.fsendfiles = -1;
+ shperm.pzread = (char **) &_uuconf_unset;
+ shperm.pzwrite = (char **) &_uuconf_unset;
+ shperm.fcallback = -1;
+ shperm.pzcommands = (char **) &_uuconf_unset;
+ shperm.pzvalidate = (char **) &_uuconf_unset;
+ shperm.zmyname = (char *) &_uuconf_unset;
+ shperm.zpubdir = (char *) &_uuconf_unset;
+ shperm.pzalias = (char **) &_uuconf_unset;
+ pznoread = (char **) &_uuconf_unset;
+ pznowrite = (char **) &_uuconf_unset;
+
+ for (i = 0; i < centries; i++)
+ {
+ char *zeq;
+ char *azargs[2];
+
+ zeq = strchr (pzsplit[i], '=');
+ if (zeq == NULL)
+ {
+ iret = UUCONF_SYNTAX_ERROR;
+ qglobal->qprocess->fhdb_read_permissions = TRUE;
+ break;
+ }
+ *zeq = '\0';
+
+ azargs[0] = pzsplit[i];
+ azargs[1] = zeq + 1;
+
+ iret = uuconf_cmd_args (qglobal, 2, azargs, as, (pointer) NULL,
+ ihunknownperm, 0, qglobal->pblock);
+ if ((iret & UUCONF_CMDTABRET_KEEP) != 0)
+ {
+ iret &=~ UUCONF_CMDTABRET_KEEP;
+
+ if (uuconf_add_block (qglobal->pblock, zline) != 0)
+ {
+ qglobal->ierrno = errno;
+ iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
+ break;
+ }
+
+ zline = NULL;
+ cline = 0;
+ }
+ if ((iret & UUCONF_CMDTABRET_EXIT) != 0)
+ {
+ iret &=~ UUCONF_CMDTABRET_EXIT;
+ break;
+ }
+ }
+
+ if (iret != UUCONF_SUCCESS)
+ break;
+
+ if (shperm.pzmachine == (char **) &_uuconf_unset
+ && shperm.pzlogname == (char **) &_uuconf_unset)
+ {
+ iret = UUCONF_SYNTAX_ERROR;
+ qglobal->qprocess->fhdb_read_permissions = TRUE;
+ break;
+ }
+
+ /* Attach any NOREAD or NOWRITE entries to the corresponding
+ READ or WRITE entries in the format expected for the
+ pzlocal_receive, etc., fields in uuconf_system. */
+ if (pznoread != NULL)
+ {
+ iret = ihadd_norw (qglobal, &shperm.pzread, pznoread);
+ if (iret != UUCONF_SUCCESS)
+ break;
+ uuconf_free (qglobal->pblock, pznoread);
+ }
+
+ if (pznowrite != NULL)
+ {
+ iret = ihadd_norw (qglobal, &shperm.pzwrite, pznowrite);
+ if (iret != UUCONF_SUCCESS)
+ break;
+ uuconf_free (qglobal->pblock, pznowrite);
+ }
+
+ qnew = ((struct shpermissions *)
+ uuconf_malloc (qglobal->pblock,
+ sizeof (struct shpermissions)));
+ if (qnew == NULL)
+ {
+ qglobal->ierrno = errno;
+ iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
+ break;
+ }
+
+ *qnew = shperm;
+ *pq = qnew;
+ pq = &qnew->qnext;
+ *pq = NULL;
+ }
+
+ (void) fclose (e);
+
+ if (zline != NULL)
+ free ((pointer) zline);
+ if (pzsplit != NULL)
+ free ((pointer) pzsplit);
+
+ if (iret == UUCONF_SUCCESS)
+ {
+ qglobal->qprocess->qhdb_permissions = qlist;
+ qglobal->qprocess->fhdb_read_permissions = TRUE;
+ }
+ else
+ {
+ qglobal->zfilename = zperm;
+ iret |= UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO;
+ }
+
+ return iret;
+}
+
+/* Split the argument into colon separated strings, and assign a NULL
+ terminated array of strings to pvar. */
+
+/*ARGSUSED*/
+static int
+ihcolon (pglobal, argc, argv, pvar, pinfo)
+ pointer pglobal;
+ int argc;
+ char **argv;
+ pointer pvar;
+ pointer pinfo;
+{
+ struct sglobal *qglobal = (struct sglobal *) pglobal;
+ char ***ppz = (char ***) pvar;
+ char **pzsplit;
+ size_t csplit;
+ int centries;
+ int i;
+ int iret;
+
+ *ppz = NULL;
+
+ pzsplit = NULL;
+ csplit = 0;
+
+ centries = _uuconf_istrsplit (argv[1], ':', &pzsplit, &csplit);
+ if (centries < 0)
+ {
+ qglobal->ierrno = errno;
+ return (UUCONF_MALLOC_FAILED
+ | UUCONF_ERROR_ERRNO
+ | UUCONF_CMDTABRET_EXIT);
+ }
+
+ if (centries == 0)
+ {
+ if (pzsplit != NULL)
+ free ((pointer) pzsplit);
+ return UUCONF_CMDTABRET_CONTINUE;
+ }
+
+ iret = UUCONF_SUCCESS;
+
+ for (i = 0; i < centries; i++)
+ {
+ iret = _uuconf_iadd_string (qglobal, pzsplit[i], FALSE, FALSE,
+ ppz, qglobal->pblock);
+ if (iret != UUCONF_SUCCESS)
+ {
+ iret |= UUCONF_CMDTABRET_EXIT;
+ break;
+ }
+ }
+
+ free ((pointer) pzsplit);
+
+ return UUCONF_CMDTABRET_KEEP;
+}
+
+/* Handle the SENDFILES parameter, which can take "yes" or "call" or
+ "no" as an argument. The string "call" is equivalent to "no". */
+
+/*ARGSUSED*/
+static int
+ihsendfiles (pglobal, argc, argv, pvar, pinfo)
+ pointer pglobal;
+ int argc;
+ char **argv;
+ pointer pvar;
+ pointer pinfo;
+{
+ int *pi = (int *) pvar;
+
+ switch (argv[1][0])
+ {
+ case 'C':
+ case 'c':
+ case 'N':
+ case 'n':
+ *pi = FALSE;
+ break;
+ case 'Y':
+ case 'y':
+ *pi = TRUE;
+ break;
+ default:
+ return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
+ }
+
+ return UUCONF_CMDTABRET_CONTINUE;
+}
+
+/* If there is an unknown Permissions entry, return a syntax error.
+ This should probably be more clever. */
+
+/*ARGSUSED*/
+static int
+ihunknownperm (pglobal, argc, argv, pvar, pinfo)
+ pointer pglobal;
+ int argc;
+ char **argv;
+ pointer pvar;
+ pointer pinfo;
+{
+ return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
+}
+
+/* Add a NOREAD or NOWRITE entry to a READ or WRITE entry. */
+
+static int
+ihadd_norw (qglobal, ppz, pzno)
+ struct sglobal *qglobal;
+ char ***ppz;
+ char **pzno;
+{
+ register char **pz;
+
+ if (pzno == (char **) &_uuconf_unset)
+ return UUCONF_SUCCESS;
+
+ for (pz = pzno; *pz != NULL; pz++)
+ {
+ size_t csize;
+ char *znew;
+ int iret;
+
+ csize = strlen (*pz) + 1;
+ znew = (char *) uuconf_malloc (qglobal->pblock, csize + 1);
+ if (znew == NULL)
+ {
+ qglobal->ierrno = errno;
+ return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO;
+ }
+ znew[0] = '!';
+ memcpy ((pointer) (znew + 1), (pointer) *pz, csize);
+ iret = _uuconf_iadd_string (qglobal, znew, FALSE, FALSE, ppz,
+ qglobal->pblock);
+ if (iret != UUCONF_SUCCESS)
+ return iret;
+ }
+
+ return UUCONF_SUCCESS;
+}