This is smarthost.c in view mode; [Download] [Up]
/* @(#)src/routers/smarthost.c 1.2 24 Oct 1990 05:24:52 */ /* * Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll * * See the file COPYING, distributed with smail, for restriction * and warranty information. */ /* * smarthost.c: * route to a smarter host. This is useful as the last router * to send otherwise undeliverable addresses on to another host. * * Specifications for the smarthost routing driver: * * associated transports: * No specific transport is set. * * private attribute data: * host (string): specifies the next_host value for * the addr structure; i.e., this is the next host to * which the message should be sent. * * route (string): specifies the route value for * the addr structure; i.e., this is the route past the * next_host to get to the smart host. * * path (string): and if host and route are not specified, * then the path is parsed by parse_address, with the * host attribute being set to the returned target, and * the route attribute being set to the returned remainder. * * private attribute flags: * No private flag attributes. * * NOTE: If no path or host attribute is specified, the smart_path * config file attribute will be used. If neither of these exist, * then the smarthost driver does not match anything. This makes * it possible to have a compiled-in configuration that does not * match anything, while making it possible to enable the smartuser * driver using only a config file. To help in this, as well, * a smart_transport config file attribute will be used to * define the transport as well. * * NOTE: at the present time, a transport or method must be specified * in the generic attributes. In the future, the routing * software is expected to be able to allow for secondary passes * through the routers to resolve the transport to the smarthost. */ #include <stdio.h> #include "defs.h" #include "../smail.h" #include "../smailconf.h" #include "../parse.h" #include "../addr.h" #include "../route.h" #include "../transport.h" #include "../dys.h" #include "smarthost.h" #ifndef DEPEND # include "../extern.h" # include "../debug.h" # include "../error.h" #endif /* functions local to this file */ static struct error *no_smarthost_info(); static struct error *smarthost_parse_error(); /* * smarthost - route to smart host. */ /*ARGSUSED*/ void rtd_smarthost(rp, in, out, defer, fail) struct router *rp; /* router table entry */ struct addr *in; /* input addr structures */ struct addr **out; /* non-failed addr structures */ struct addr **defer; /* addrs to defer to a later time */ struct addr **fail; /* unresolvable addrs */ { register struct addr *cur; /* current addr being processed */ struct addr *next; /* next addr to process */ struct smarthost_private *priv = (struct smarthost_private *)rp->private; static struct transport *smart_tp; /* entry for smart_transport */ DEBUG(DBG_DRIVER_HI, "rtd_smarthost called\n"); if (priv->path == NULL && priv->host == NULL) { if (smart_path == NULL) { /* there is no smarthost information, don't match anything */ *out = in; return; } if (smart_transport && smart_tp == NULL) { smart_tp = find_transport(smart_transport); } } for (cur = in; cur; cur = next) { next = cur->succ; if (! (cur->flags & ADDR_FINISHED)) { /* * don't match using a smarthost router more than once * for a single addr. */ if (cur->flags & ADDR_SMARTHOST) { DEBUG2(DBG_DRIVER_MID, "router %s: did not match %s\n", rp->name, cur->target); } else { if (priv->host == NULL) { char *p; if (priv->path == NULL && smart_path == NULL) { cur->error = no_smarthost_info(rp); cur->succ = *defer; *defer = cur; continue; } /* need a modifiable copy of the path */ p = COPY_STRING(priv->path? priv->path: smart_path); if (parse_address(p, &priv->host, &priv->route) == FAIL) { /* error stored in priv->route */ cur->error = smarthost_parse_error(rp, priv->path, priv->route); cur->succ = *defer; *defer = cur; continue; } /* * if the smart path parsed to local form, it really * represents a single host with a null route. */ if (priv->host == NULL) { priv->host = priv->route; priv->route = NULL; } } route_driver_finish(rp, cur, 0, priv->host, priv->route, smart_tp); cur->flags |= ADDR_SMARTHOST; } } /* link into the non-error output */ cur->succ = *out; *out = cur; } } /* * rtv_smarthost - match anything, unless ADDR_SMARTHOST is set */ /*ARGSUSED*/ void rtv_smarthost(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; /* current addr being processed */ struct addr *next; /* next addr to process */ for (cur = in; cur; cur = next) { next = cur->succ; if (cur->flags & ADDR_SMARTHOST) { /* no match if we are disabling smarthost routing here */ cur->succ = *retry; *retry = cur; } else { /* otherwise we match */ cur->succ = *okay; *okay = cur; } } } /* * rtb_smarthost - read the configuration file attributes */ char * rtb_smarthost(rp, attrs) struct router *rp; /* router entry being defined */ struct attribute *attrs; /* list of per-driver attributes */ { char *error; static struct attr_table smarthost_attributes[] = { { "path", t_string, NULL, NULL, OFFSET(smarthost_private, path) }, { "host", t_string, NULL, NULL, OFFSET(smarthost_private, host) }, { "route", t_string, NULL, NULL, OFFSET(smarthost_private, route) }, }; static struct attr_table *end_smarthost_attributes = ENDTABLE(smarthost_attributes); static struct smarthost_private smarthost_template = { NULL, /* host */ NULL, /* route */ }; struct smarthost_private *priv; /* new smarthost_private structure */ /* copy the template private data */ priv = (struct smarthost_private *)xmalloc(sizeof(*priv)); (void) memcpy((char *)priv, (char *)&smarthost_template, sizeof(*priv)); rp->private = (char *)priv; /* fill in the attributes of the private data */ error = fill_attributes((char *)priv, attrs, &rp->flags, smarthost_attributes, end_smarthost_attributes); if (error) { return error; } else { return NULL; } } static struct error * no_smarthost_info(rp) struct router *rp; { char *error_text; /* * ERR_125 - no smarthost information * * DESCRIPTION * Either a smart_path or smart_host attribute * is required when using the smarthost driver. * Neither was specified. * * ACTIONS * Defer the message with a configuration error. * * RESOLUTION * The smarthost router should be corrected to * define either a smart_host/smart_route pair * or a smart_path attribute. */ error_text = xprintf("router %s: smart_host or smart_path required", rp->name); DEBUG1(DBG_DRIVER_LO, "%s\n", error_text); return note_error(ERR_125, error_text); } static struct error * smarthost_parse_error(rp, path, parse_error) struct router *rp; char *path; char *parse_error; { char *error_text; /* * ERR_126 - smart_path parse error * * DESCRIPTION * parse_address() encountered an error while * parsing the smart_path attribute, which * should be a UUCP-style !-path. An error is * stored in priv->route. * * ACTIONS * Defer the message with a configuration error. * * RESOLUTION * The smart_path attribute in the router file * should be corrected to be a valid !-path. */ error_text = xprintf("router %s: error parsing %s: %s", rp->name, path, parse_error); DEBUG1(DBG_DRIVER_LO, "%s\n", error_text); return note_error(ERR_CONFERR|ERR_126, error_text); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.