This is resolve.c in view mode; [Download] [Up]
/* @(#)src/resolve.c 1.2 24 Oct 1990 05:24:14 */ /* * Copyright (C) 1987, 1988 Ronald S. Karr and Landon Curt Noll * * See the file COPYING, distributed with smail, for restriction * and warranty information. */ /* * resolve.c: * resolve addresses to completed addr structures with transports. * * external functions: resolve_addr_list, islocalhost */ #include <stdio.h> #include "defs.h" #include "smail.h" #include "hash.h" #include "log.h" #include "addr.h" #include "route.h" #include "transport.h" #include "exitcodes.h" #ifndef DEPEND # include "extern.h" # include "error.h" #endif /* exported variables */ struct hash_table *hit_table; /* table to recognize address hits */ /* * resolve_addr_list - resolve addresses to transports and next hosts * * given a list of user-supplied addresses on input, produce resolved * and unresolvable addresses on output. * * inputs: * in - the list of input address structures * * outputs: * out - the list of completely resolved address structures. * transport, next_host and next_addr will be properly * filled in for all of these structures. * defer - a list of temporarily unresolvable address structures. * an error structure is stored in the error element. * These addresses should be retried at a later time. If * ERR_CONFERR is set in the error->info element, the * problem is a configuration error. * fail - a list of unresolvable address structures. An error * structure is stored in the error element. If * ERR_NSENDER is set, a note is returned to the sender. * If ERR_NPOSTMASTER is set, then a note is mailed to * the postmaster. If ERR_NSOWNER is set then a note is * sent to an owner for an address, or to the sender if * the address has no owner. If ERR_NPOWNER is set then * a note is sent to an owner or to the postmaster if the * address has no owner. */ void resolve_addr_list(in, out, defer, fail, hash_addrs) struct addr *in; /* the address list to resolve */ struct addr **out; /* produced addr list w/transports */ struct addr **defer; /* addrs to defer to a later time */ struct addr **fail; /* unresolvable addrs */ int hash_addrs; /* TRUE to prevent duplicate addrs */ { struct addr *cur; /* current address being processed */ struct addr *local; /* addrs that parsed local */ struct addr *remote; /* addrs that parsed remote */ struct addr *next; /* next value for cur */ /* * resolve all addresses in our input queue * each step through the loop advances the progress * in resolving all addresses to a transport. * The loop is done when nothing remains to be processed. * as an optimization, remote form processing is not * done unless no local processing was required. */ remote = NULL; local = NULL; while (in || remote) { /* * split the input list into local and remote * forms. */ for (cur = in, in = NULL; cur; cur = next) { int form; /* form from parse_address */ next = cur->succ; if (hash_addrs && !(cur->flags & ADDR_DONTHASH) && add_to_hash(cur->work_addr, (char *)NULL, 0, hit_table) == ALREADY_HASHED) { /* * we have already seen this address, don't * process it again */ continue; } form = parse_address(cur->work_addr, &cur->target, &cur->remainder); switch (form) { case FAIL: case PARSE_ERROR: /* * ERR_111 - address parse error * * DESCRIPTION * parse_address() encountered an error while parsing * the work_addr for this address. The error is stored * in cur->remainder. * * ACTIONS * A message about the parse error should be returned * to the owner of the address or to the sender. * * RESOLUTION * The owner or sender should correct the address and * resubmit the message. */ cur->error = note_error(ERR_NSOWNER|ERR_111, cur->remainder); cur->flags |= PARSE_ERROR; cur->succ = *fail; *fail = cur; continue; case LOCAL: /* * a local-form in quotes must be reparsed */ if (strip(cur->remainder)) { /* it was in quotes, put it back on the input */ next = cur; } else { cur->succ = local; local = cur; } break; default: /* anything else is a remote-form address */ /* determine if this is actually the local host */ if (islocalhost(cur->target)) { /* it is the local host, parse it again */ (void) strcpy(cur->work_addr, cur->remainder); next = cur; continue; } cur->flags &= ~(ADDR_FORM_MASK); cur->flags |= form; cur->succ = remote; remote = cur; break; } } /* * either process local or remote addresses. */ if (local) { direct_local_addrs(local, out, &in, defer, fail); local = NULL; } else { route_remote_addrs(remote, out, &in, defer, fail); remote = NULL; } } } /* * islocalhost - determine if the given target is the local host * * given the currently known names for the localhost, determine * if the given name matches one of these known names. * * return TRUE or FALSE. */ int islocalhost(target) register char *target; /* name to match */ { if ((uucp_name && EQIC(target, uucp_name)) || (hostnames && is_string_in_list(target, hostnames)) || (more_hostnames && is_string_in_list(target, more_hostnames))) { return TRUE; } return FALSE; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.