home *** CD-ROM | disk | FTP | other *** search
- /* $Header: addr.c,v 2.2 90/03/06 12:21:18 chip Exp $
- *
- * Operations on addresses, (ASCII representations of destinations).
- *
- * $Log: addr.c,v $
- * Revision 2.2 90/03/06 12:21:18 chip
- * Move logging into log.c and address parsing into addr.c.
- * New: error delivery file for messages that fail.
- * Major rearrangement of delivery file code.
- *
- */
-
- #include "deliver.h"
-
- /*----------------------------------------------------------------------
- * Check an address for cleanliness.
- * That is, make sure that it is devoid of shell metacharacters.
- * And make sure it's got at least one character, too.
- */
-
- addr_clean(addr)
- char *addr;
- {
- char *p;
- static char sanitize[] = SANITIZE;
-
- if (*addr == 0)
- return FALSE;
-
- for (p = addr; *p; ++p)
- {
- if (strchr(sanitize, *p))
- return FALSE;
- }
-
- return TRUE;
- }
-
- /*----------------------------------------------------------------------
- * Report the class of a string representation of a destination.
- */
-
- DCLASS
- addr_class(s)
- char *s;
- {
- char *p;
-
- for (p = s; *p; ++p)
- {
- switch (*p)
- {
- case '!':
- return CL_UUCP;
- case ':':
- return CL_MBOX;
- case '|':
- return CL_PROG;
- case '?':
- return CL_USER;
- }
- }
-
- return CL_USER;
- }
-
- /*----------------------------------------------------------------------
- * Parse a string representation of a destination.
- * If dfile_ct is non-NULL, then a missing user name refers to that user;
- * otherwise, a missing user name refers to the effective user id.
- * If dfile_ct is NULL, then we only permit user names and UUCP addresses;
- * otherwise, we permit all kinds of addresses.
- */
-
- DEST *
- addr_dest(s, dfile_ct)
- char *s;
- CONTEXT *dfile_ct;
- {
- DEST *d;
- CONTEXT *ct;
- char *buf, *p, *q, *user, *param;
- char sep;
- int i, legal;
-
- /*
- * If this is NOT a delivery file, restrict address class
- * to user and UUCP.
- */
-
- if (!dfile_ct)
- {
- DCLASS class;
-
- class = addr_class(s);
- if ((class != CL_USER && class != CL_UUCP)
- || strcmp(s, DFILE_DROP) == 0)
- {
- d = dest(s, CL_USER, (char *)NULL);
- dest_err(d, E_DFONLY);
- return d;
- }
- }
-
- /*
- * Find the additional information after the user name.
- * Bang means UUCP, colon means mailbox, pipe means pipe,
- * question means error.
- */
-
- for (i = 0; (sep = s[i]) != 0; ++i)
- {
- if (sep == '!' || sep == ':' || sep == '|' || sep == '?')
- break;
- }
-
- /*
- * Deal with UUCP paths before the user-name parsing begins.
- */
-
- if (sep == '!')
- return dest(s, CL_UUCP, (char *)NULL);
-
- /*
- * Copy string to local buffer so we can mangle it.
- * Chop it up into user name and parameter.
- */
-
- buf = copystr(s);
- if (buf[i])
- buf[i++] = 0;
- user = buf;
- param = buf + i;
-
- /*
- * If user name is blank, provide default.
- */
-
- if (*user == 0)
- user = (dfile_ct ? dfile_ct : eff_ct)->ct_name;
-
- /*
- * Determine if we can get there from here.
- */
-
- if ((ct = name_context(user)) == NULL)
- legal = TRUE; /* we can report "no such user" later */
- else if (dfile_ct)
- legal = ok_context(dfile_ct->ct_uid, dfile_ct->ct_uid,
- dfile_ct->ct_gid, ct);
- else
- legal = ok_context(eff_uid, real_uid, real_gid, ct);
-
- /*
- * Now take action based on address class.
- */
-
- /* Could be "user|program" ... */
-
- if (sep == '|')
- d = legal ? dest(user, CL_PROG, param) : NULL;
-
- /* Could be "user?error" ... */
-
- else if (sep == '?')
- {
- if (legal)
- {
- d = dest(user, CL_USER, (char *)NULL);
- dest_err(d, E_ERRMSG);
- d->d_errmsg = copystr(param);
- }
- else
- d = NULL;
- }
-
- /* Must be "user" or "user:mailbox" */
-
- else
- {
- /*
- * Strip whitespace, eliminate duplicate slashes from
- * mailbox filename.
- */
-
- p = q = param;
- while (*p)
- {
- if (isspace(*p))
- ++p;
- else if ((*q++ = *p++) == '/')
- {
- while (*p == '/')
- ++p;
- }
- }
- *q = 0;
-
- /*
- * Now that blanks are gone, we decide mailbox or not.
- * Delaying this test means that "user" equals "user: ".
- */
-
- if (*param)
- d = legal ? dest(user, CL_MBOX, param) : NULL;
- else
- d = dest(user, CL_USER, (char *)NULL);
- }
-
- /*
- * We allocated the buffer; now we free it.
- */
-
- free(buf);
-
- /* Return parsed destination. */
-
- return d;
- }
-
-