This is user.c in view mode; [Download] [Up]
/* @(#)src/directors/user.c 1.2 24 Oct 1990 05:22:39 */ /* * Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll * * See the file COPYING, distributed with smail, for restriction * and warranty information. */ /* * user.c: * direct mail to a transport which will deliver to local user * mailboxes. Match only local addresses which are login names * on the local host. * * Specifications for the user directing driver: * * private attribute data: * transport (name): the name of the transport to use in delivering * mail to local users. */ #include <stdio.h> #include <pwd.h> #include "defs.h" #include "../smail.h" #include "../smailconf.h" #include "../parse.h" #include "../addr.h" #include "../log.h" #include "../direct.h" #include "../transport.h" #include "../exitcodes.h" #include "../dys.h" #include "user.h" #ifndef DEPEND # include "../extern.h" # include "../debug.h" # include "../error.h" #endif /* * dtd_user - direct to local user mailboxes */ /*ARGSUSED*/ struct addr * dtd_user(dp, in, out, new, defer, fail) struct director *dp; /* director entry */ struct addr *in; /* input local-form addrs */ struct addr **out; /* output resolved addrs */ struct addr **new; /* output new addrs to resolve */ struct addr **defer; /* addrs to defer to a later time */ struct addr **fail; /* unresolvable addrs */ { register struct addr *cur; /* temp for processing input */ struct addr *pass = NULL; /* addrs to pass to next director */ struct addr *next; /* next value for cur */ struct user_private *priv = (struct user_private *)dp->private; DEBUG(DBG_DRIVER_HI, "dtd_user called\n"); for (cur = in; cur; cur = next) { next = cur->succ; if (priv->prefix) { struct addr *new; int len = strlen(priv->prefix); /* * if we are testing against a prefix, strip the prefix and * lookup the name in the passwd file. If found, return a * new fully resolved addr. */ if (strncmpic(priv->prefix, cur->remainder, len) != 0) { cur->succ = pass; pass = cur; continue; /* did not start with prefix */ } new = alloc_addr(); new->remainder = COPY_STRING(cur->remainder + len); director_user_info(new); if (new->flags&ADDR_NOTUSER) { /* we did not match a user on the local host */ xfree(new->remainder); xfree((char *)new); cur->succ = pass; pass = cur; continue; } new->in_addr = COPY_STRING(new->remainder); new->director = dp; new->parent = cur; cur = new; } else { /* fill in any user information */ director_user_info(cur); /* don't match it if it is not a local user */ if (cur->flags&ADDR_NOTUSER) { cur->succ = pass; pass = cur; continue; } } DEBUG2(DBG_DRIVER_LO, "director %s matched user %s\n", dp->name, cur->remainder); cur->director = dp; /* matched address */ /* attach the transport */ cur->transport = find_transport(priv->transport); if (cur->transport == NULL) { /* * ERR_122 - user transport not specified * * DESCRIPTION * No transport attribute was specified for a user * director. The attribute is required. * * ACTIONS * Defer the message with a configuration error. * * RESOLUTION * The director file should be edited to specify the * correct transport for local delivery. */ cur->error = note_error(ERR_CONFERR|ERR_122, xprintf("director %s: transport not defined", dp->name)); cur->succ = *defer; *defer = cur; continue; } cur->next_addr = COPY_STRING(cur->remainder); cur->succ = *out; *out = cur; } return pass; /* return addrs for next director */ } /* * dtv_user - verify a user on the local host */ /*ARGSUSED*/ void dtv_user(dp, in, retry, okay, defer, fail) struct director *dp; /* director entry */ struct addr *in; /* input local-form addrs */ struct addr **retry; /* output list of unmatched addrs */ struct addr **okay; /* output list of verified addrs */ struct addr **defer; /* temporariliy unverifiable addrs */ struct addr **fail; /* unverified addrs */ { register struct addr *cur; /* temp for processing input */ struct addr *next; /* next value for cur */ struct user_private *priv = (struct user_private *)dp->private; DEBUG(DBG_DRIVER_HI, "dtv_user called\n"); /* loop over all of the input addrs */ for (cur = in; cur; cur = next) { next = cur->succ; if (priv->prefix) { int len = strlen(priv->prefix); /* * if we are testing against a prefix, strip the prefix and * see if the remaining string matches a local user */ if (strncmpic(priv->prefix, cur->remainder, len) == 0 && getpwbyname(cur->remainder + len)) { /* matched */ cur->succ = *okay; *okay = cur; continue; } } else { /* fill in any user information */ director_user_info(cur); /* match only if this is a user */ if (cur->flags&ADDR_ISUSER) { cur->succ = *okay; *okay = cur; continue; } } /* didn't match */ cur->succ = *retry; *retry = cur; } } /* * dtb_user - read the configuration file attributes */ char * dtb_user(dp, attrs) struct director *dp; /* director entry being defined */ struct attribute *attrs; /* list of per-driver attributes */ { char *error; static struct attr_table user_attributes[] = { { "transport", t_string, NULL, NULL, OFFSET(user_private, transport) }, { "prefix", t_string, NULL, NULL, OFFSET(user_private, prefix) }, }; static struct attr_table *end_user_attributes = ENDTABLE(user_attributes); static struct user_private user_template = { "local", NULL, }; struct user_private *priv; /* new user_private structure */ /* copy the template private data */ priv = (struct user_private *)xmalloc(sizeof(*priv)); (void) memcpy((char *)priv, (char *)&user_template, sizeof(*priv)); dp->private = (char *)priv; /* fill in the attributes of the private data */ error = fill_attributes((char *)priv, attrs, &dp->flags, user_attributes, end_user_attributes); if (error) { return error; } else { if (priv->transport == NULL) { return "transport attribute required"; } if (find_transport(priv->transport) == NULL) { return xprintf("unknown transport: %s", priv->transport); } return NULL; } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.