17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 1998 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 287c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate /* 347c478bd9Sstevel@tonic-gate * mailx -- a modified version of a University of California at Berkeley 357c478bd9Sstevel@tonic-gate * mail program 367c478bd9Sstevel@tonic-gate * 377c478bd9Sstevel@tonic-gate * Network name modification routines. 387c478bd9Sstevel@tonic-gate */ 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate #include "rcv.h" 417c478bd9Sstevel@tonic-gate #include "configdefs.h" 427c478bd9Sstevel@tonic-gate #include <locale.h> 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate static char *arpafix(char name[], char from[]); 457c478bd9Sstevel@tonic-gate static char *lasthost(char *addr); 467c478bd9Sstevel@tonic-gate static char *makeremote(char name[], char from[]); 477c478bd9Sstevel@tonic-gate static int mstash(char name[], int attnet); 487c478bd9Sstevel@tonic-gate static int mtype(int mid); 497c478bd9Sstevel@tonic-gate static int netlook(char machine[], int attnet); 507c478bd9Sstevel@tonic-gate static int nettype(int mid); 517c478bd9Sstevel@tonic-gate static int ntype(register int nc); 527c478bd9Sstevel@tonic-gate static void stradd(register char *str, int n, register int c); 537c478bd9Sstevel@tonic-gate static char *tackon(char *sys, char *rest); 547c478bd9Sstevel@tonic-gate static struct xtrahash *xlocate(char name[]); 557c478bd9Sstevel@tonic-gate #ifdef OPTIM 567c478bd9Sstevel@tonic-gate static char best(int src, int dest); 577c478bd9Sstevel@tonic-gate static char *mlook(int mid); 587c478bd9Sstevel@tonic-gate static int netkind(register int nt); 597c478bd9Sstevel@tonic-gate static void optiboth(char net[]); 607c478bd9Sstevel@tonic-gate static void optim(char net[], char name[]); 617c478bd9Sstevel@tonic-gate static void optim1(char netstr[], char name[]); 627c478bd9Sstevel@tonic-gate static int optimex(char net[], char name[]); 637c478bd9Sstevel@tonic-gate static int optimimp(char net[], char name[]); 647c478bd9Sstevel@tonic-gate static void prefer(char name[]); 657c478bd9Sstevel@tonic-gate static char *rpair(char str[], int mach); 667c478bd9Sstevel@tonic-gate #endif 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate /* 697c478bd9Sstevel@tonic-gate * Map a name into the correct network "view" of the 707c478bd9Sstevel@tonic-gate * name. This is done by prepending the name with the 717c478bd9Sstevel@tonic-gate * network address of the sender, then optimizing away 727c478bd9Sstevel@tonic-gate * nonsense. 737c478bd9Sstevel@tonic-gate */ 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate char * 767c478bd9Sstevel@tonic-gate netmap(char name[], char from[]) 777c478bd9Sstevel@tonic-gate { 787c478bd9Sstevel@tonic-gate char nbuf[BUFSIZ], ret[BUFSIZ]; 797c478bd9Sstevel@tonic-gate register char *cp, *oname; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "netmap(name '%s', from '%s')\n", name, from); 827c478bd9Sstevel@tonic-gate if (strlen(from) == 0) 837c478bd9Sstevel@tonic-gate return(name); /* "from" is empty - can't do anything */ 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate if (strcmp(from, name) == 0) 867c478bd9Sstevel@tonic-gate return(name); /* "from" and "name" are the same, do nothing */ 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate /* 897c478bd9Sstevel@tonic-gate * If the name contains an "@" or a "%", remove it and the host 907c478bd9Sstevel@tonic-gate * following it if that host is "known". 917c478bd9Sstevel@tonic-gate */ 927c478bd9Sstevel@tonic-gate if (any('@', name) || any('%', name)) 937c478bd9Sstevel@tonic-gate return(arpafix(name, from)); 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate /* 967c478bd9Sstevel@tonic-gate * If the sender contains a "@" or a "%", make "name" into an 977c478bd9Sstevel@tonic-gate * address on that host, on the presumption that it should 987c478bd9Sstevel@tonic-gate * really have read "name@from" when we received the message 997c478bd9Sstevel@tonic-gate * rather than just "name". 1007c478bd9Sstevel@tonic-gate */ 1017c478bd9Sstevel@tonic-gate if (any('@', from) || any('%', from)) 1027c478bd9Sstevel@tonic-gate return(unuucp(makeremote(name, from))); 1037c478bd9Sstevel@tonic-gate if (value("onehop") && (cp = strchr(name, '!')) && cp > name) { 1047c478bd9Sstevel@tonic-gate /* 1057c478bd9Sstevel@tonic-gate * "onehop" is set, meaning all machines are one UUCP 1067c478bd9Sstevel@tonic-gate * hop away (fat chance, in this day and age), and "name" 1077c478bd9Sstevel@tonic-gate * is a UUCP path rather than just a name. Leave it alone. 1087c478bd9Sstevel@tonic-gate */ 1097c478bd9Sstevel@tonic-gate nstrcpy(nbuf, sizeof (nbuf), name); 1107c478bd9Sstevel@tonic-gate } else { 1117c478bd9Sstevel@tonic-gate from = tackon(host, from); 1127c478bd9Sstevel@tonic-gate *strrchr(from, '!') = 0; 1137c478bd9Sstevel@tonic-gate name = tackon(lasthost(from), name); 1147c478bd9Sstevel@tonic-gate while (((cp = lasthost(from)) != 0) && ishost(cp, name)) { 1157c478bd9Sstevel@tonic-gate oname = name; 1167c478bd9Sstevel@tonic-gate name = strchr(name, '!') + 1; 1177c478bd9Sstevel@tonic-gate if (cp == from) { 1187c478bd9Sstevel@tonic-gate from[strlen(from)] = '!'; 1197c478bd9Sstevel@tonic-gate if (value("mustbang") && !strchr(name, '!')) 1207c478bd9Sstevel@tonic-gate name = oname; 1217c478bd9Sstevel@tonic-gate return(unuucp(name)); 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate *--cp = 0; 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate from[strlen(from)] = '!'; 1267c478bd9Sstevel@tonic-gate from = strchr(from, '!') + 1; 1277c478bd9Sstevel@tonic-gate snprintf(nbuf, sizeof (nbuf), "%s!%s", from, name); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "before optim, nbuf '%s'\n", name); 1307c478bd9Sstevel@tonic-gate #ifdef OPTIM 1317c478bd9Sstevel@tonic-gate if ((cp = value("conv"))==NOSTR || strcmp(cp, "optimize") != 0) 1327c478bd9Sstevel@tonic-gate nstrcpy(ret, sizeof (ret), nbuf); 1337c478bd9Sstevel@tonic-gate else 1347c478bd9Sstevel@tonic-gate optim(nbuf, ret); 1357c478bd9Sstevel@tonic-gate #else 1367c478bd9Sstevel@tonic-gate nstrcpy(ret, sizeof (ret), nbuf); 137*6c83d09fSrobbin #endif /* OPTIM */ 1387c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "after optim, nbuf '%s', ret '%s'\n", nbuf, ret); 1397c478bd9Sstevel@tonic-gate cp = ret; 1407c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "wind up with '%s'\n", name); 1417c478bd9Sstevel@tonic-gate if (!icequal(name, cp)) 1427c478bd9Sstevel@tonic-gate return(unuucp((char *) savestr(cp))); 1437c478bd9Sstevel@tonic-gate return(unuucp(name)); 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate /* 1477c478bd9Sstevel@tonic-gate * Stick a host on the beginning of a uucp 1487c478bd9Sstevel@tonic-gate * address if it isn't there already. 1497c478bd9Sstevel@tonic-gate */ 1507c478bd9Sstevel@tonic-gate static char * 1517c478bd9Sstevel@tonic-gate tackon(char *sys, char *rest) 1527c478bd9Sstevel@tonic-gate { 1537c478bd9Sstevel@tonic-gate while (*rest == '!') 1547c478bd9Sstevel@tonic-gate rest++; 1557c478bd9Sstevel@tonic-gate if (!ishost(sys, rest)) { 1567c478bd9Sstevel@tonic-gate char *r = (char *)salloc(strlen(sys) + strlen(rest) + 2); 1577c478bd9Sstevel@tonic-gate sprintf(r, "%s!%s", sys, rest); 1587c478bd9Sstevel@tonic-gate rest = r; 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate return rest; 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate 1637c478bd9Sstevel@tonic-gate /* 1647c478bd9Sstevel@tonic-gate * Check equality of the first host in a uucp address. 1657c478bd9Sstevel@tonic-gate */ 1667c478bd9Sstevel@tonic-gate int 1677c478bd9Sstevel@tonic-gate ishost(char *sys, char *rest) 1687c478bd9Sstevel@tonic-gate { 1697c478bd9Sstevel@tonic-gate while (*sys && *sys == *rest) 1707c478bd9Sstevel@tonic-gate sys++, rest++; 1717c478bd9Sstevel@tonic-gate return(*sys == 0 && *rest == '!'); 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate /* 1757c478bd9Sstevel@tonic-gate * Return last host in a uucp address. 1767c478bd9Sstevel@tonic-gate */ 1777c478bd9Sstevel@tonic-gate static char * 1787c478bd9Sstevel@tonic-gate lasthost(char *addr) 1797c478bd9Sstevel@tonic-gate { 1807c478bd9Sstevel@tonic-gate char *r = strrchr(addr, '!'); 1817c478bd9Sstevel@tonic-gate return r ? ++r : addr; 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate /* 1857c478bd9Sstevel@tonic-gate * Optionally translate an old format uucp name into a new one, e.g. 1867c478bd9Sstevel@tonic-gate * "mach1!mach2!user" becomes "user@mach2.UUCP". This optional because 1877c478bd9Sstevel@tonic-gate * some information is necessarily lost (e.g. the route it got here 1887c478bd9Sstevel@tonic-gate * via) and if we don't have the host in our routing tables, we lose. 1897c478bd9Sstevel@tonic-gate * XXX THIS IS NO LONGER VALID WITH THE NEW UUCP PROJECT PLANS TO 1907c478bd9Sstevel@tonic-gate * REGISTER UUCP HOSTS IN THE STANDARD INTERNET NAMESPACE, E.G. 1917c478bd9Sstevel@tonic-gate * ihnp4 BECOMES "ihnp4.att.com". 1927c478bd9Sstevel@tonic-gate */ 1937c478bd9Sstevel@tonic-gate char * 1947c478bd9Sstevel@tonic-gate unuucp(char *name) 1957c478bd9Sstevel@tonic-gate { 1967c478bd9Sstevel@tonic-gate register char *np, *hp, *cp; 1977c478bd9Sstevel@tonic-gate char result[100]; 1987c478bd9Sstevel@tonic-gate char tname[300]; 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate if (UnUUCP==0 && 2017c478bd9Sstevel@tonic-gate ((cp = value("conv"))==NOSTR || strcmp(cp, "internet"))) 2027c478bd9Sstevel@tonic-gate return name; 2037c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "unuucp(%s)\n", name); 2047c478bd9Sstevel@tonic-gate nstrcpy(tname, sizeof (tname), name); 2057c478bd9Sstevel@tonic-gate np = strrchr(tname, '!'); 2067c478bd9Sstevel@tonic-gate if (np == NOSTR) 2077c478bd9Sstevel@tonic-gate return name; 2087c478bd9Sstevel@tonic-gate *np++ = 0; 2097c478bd9Sstevel@tonic-gate hp = strrchr(tname, '!'); 2107c478bd9Sstevel@tonic-gate if (hp == NOSTR) 2117c478bd9Sstevel@tonic-gate hp = tname; 2127c478bd9Sstevel@tonic-gate else 2137c478bd9Sstevel@tonic-gate *hp++ = 0; 2147c478bd9Sstevel@tonic-gate cp = strchr(np, '@'); 2157c478bd9Sstevel@tonic-gate if (cp == NOSTR) 2167c478bd9Sstevel@tonic-gate cp = strchr(np, '%'); 2177c478bd9Sstevel@tonic-gate if (cp) 2187c478bd9Sstevel@tonic-gate *cp = 0; 2197c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "host %s, name %s\n", hp, np); 2207c478bd9Sstevel@tonic-gate snprintf(result, sizeof (result), "%s@%s.UUCP", np, hp); 2217c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "unuucp returns %s\n", result); 2227c478bd9Sstevel@tonic-gate return savestr(result); 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate /* 2267c478bd9Sstevel@tonic-gate * Turn a network machine name into a unique character 2277c478bd9Sstevel@tonic-gate */ 2287c478bd9Sstevel@tonic-gate static int 2297c478bd9Sstevel@tonic-gate netlook(char machine[], int attnet) 2307c478bd9Sstevel@tonic-gate { 2317c478bd9Sstevel@tonic-gate register struct netmach *np; 2327c478bd9Sstevel@tonic-gate register char *cp, *cp2; 2337c478bd9Sstevel@tonic-gate char nbuf[BUFSIZ]; 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate /* 2367c478bd9Sstevel@tonic-gate * Make into lower case. 2377c478bd9Sstevel@tonic-gate */ 2387c478bd9Sstevel@tonic-gate for (cp = machine, cp2 = nbuf; 2397c478bd9Sstevel@tonic-gate *cp && cp2 < &nbuf[BUFSIZ-1]; 2407c478bd9Sstevel@tonic-gate *cp2++ = tolower(*cp++)) 2417c478bd9Sstevel@tonic-gate /*nothing*/; 2427c478bd9Sstevel@tonic-gate *cp2 = 0; 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate /* 2457c478bd9Sstevel@tonic-gate * If a single letter machine, look through those first. 2467c478bd9Sstevel@tonic-gate */ 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate if (strlen(nbuf) == 1) 2497c478bd9Sstevel@tonic-gate for (np = netmach; np->nt_mid != 0; np++) 2507c478bd9Sstevel@tonic-gate if (np->nt_mid == nbuf[0]) 2517c478bd9Sstevel@tonic-gate return(nbuf[0]); 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate /* 2547c478bd9Sstevel@tonic-gate * Look for usual name 2557c478bd9Sstevel@tonic-gate */ 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate for (np = netmach; np->nt_mid != 0; np++) 2587c478bd9Sstevel@tonic-gate if (strcmp(np->nt_machine, nbuf) == 0) 2597c478bd9Sstevel@tonic-gate return(np->nt_mid); 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate /* 2627c478bd9Sstevel@tonic-gate * Look in side hash table. 2637c478bd9Sstevel@tonic-gate */ 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate return(mstash(nbuf, attnet)); 2667c478bd9Sstevel@tonic-gate } 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate #ifdef OPTIM 2697c478bd9Sstevel@tonic-gate /* 2707c478bd9Sstevel@tonic-gate * Turn a network unique character identifier into a network name. 2717c478bd9Sstevel@tonic-gate */ 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate static char * 2747c478bd9Sstevel@tonic-gate netname(int mid) 2757c478bd9Sstevel@tonic-gate { 2767c478bd9Sstevel@tonic-gate register struct netmach *np; 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate if (mid & 0200) 2797c478bd9Sstevel@tonic-gate return(mlook(mid)); 2807c478bd9Sstevel@tonic-gate for (np = netmach; np->nt_mid != 0; np++) 2817c478bd9Sstevel@tonic-gate if (np->nt_mid == mid) 2827c478bd9Sstevel@tonic-gate return(np->nt_machine); 2837c478bd9Sstevel@tonic-gate return(NOSTR); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate #endif 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate /* 2887c478bd9Sstevel@tonic-gate * Deal with arpa net addresses. The way this is done is strange. 2897c478bd9Sstevel@tonic-gate * name contains an "@" or "%". Look up the machine after it in 2907c478bd9Sstevel@tonic-gate * the hash table. If it isn't found, return name unmolested. 2917c478bd9Sstevel@tonic-gate * If ???, return name unmolested. 2927c478bd9Sstevel@tonic-gate * Otherwise, delete the "@" or "%" and the machine after it from 2937c478bd9Sstevel@tonic-gate * name, and return the new string. 2947c478bd9Sstevel@tonic-gate */ 2957c478bd9Sstevel@tonic-gate static char * 2967c478bd9Sstevel@tonic-gate arpafix(char name[], char from[]) 2977c478bd9Sstevel@tonic-gate { 2987c478bd9Sstevel@tonic-gate register char *cp; 2997c478bd9Sstevel@tonic-gate register int arpamach; 3007c478bd9Sstevel@tonic-gate char newname[BUFSIZ]; 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate if (debug) { 3037c478bd9Sstevel@tonic-gate fprintf(stderr, "arpafix(%s, %s)\n", name, from); 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate cp = strrchr(name, '@'); 3067c478bd9Sstevel@tonic-gate if (cp == NOSTR) 3077c478bd9Sstevel@tonic-gate cp = strrchr(name, '%'); 3087c478bd9Sstevel@tonic-gate if (cp == NOSTR) { 3097c478bd9Sstevel@tonic-gate fprintf(stderr, 3107c478bd9Sstevel@tonic-gate gettext("Something's amiss -- no @ or %% in arpafix\n")); 3117c478bd9Sstevel@tonic-gate return(name); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate cp++; 3147c478bd9Sstevel@tonic-gate arpamach = netlook(cp, '@'); 3157c478bd9Sstevel@tonic-gate if (debug) 3167c478bd9Sstevel@tonic-gate fprintf(stderr, 3177c478bd9Sstevel@tonic-gate "cp '%s', arpamach %o, nettypes arpamach %o LOCAL %o\n", 3187c478bd9Sstevel@tonic-gate cp, arpamach, nettype(arpamach), nettype(LOCAL)); 3197c478bd9Sstevel@tonic-gate if (arpamach == 0) { 3207c478bd9Sstevel@tonic-gate if (debug) 3217c478bd9Sstevel@tonic-gate fprintf(stderr, "machine %s unknown, uses: %s\n", 3227c478bd9Sstevel@tonic-gate cp, name); 3237c478bd9Sstevel@tonic-gate return(name); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate if (((nettype(arpamach) & nettype(LOCAL)) & ~AN) == 0) { 3267c478bd9Sstevel@tonic-gate if (debug) 3277c478bd9Sstevel@tonic-gate fprintf(stderr, "machine %s known but remote, uses: %s\n", 3287c478bd9Sstevel@tonic-gate cp, name); 3297c478bd9Sstevel@tonic-gate return(name); 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate nstrcpy(newname, sizeof (newname), name); 3327c478bd9Sstevel@tonic-gate cp = strrchr(newname, '@'); 3337c478bd9Sstevel@tonic-gate if (cp == NOSTR) 3347c478bd9Sstevel@tonic-gate cp = strrchr(newname, '%'); 3357c478bd9Sstevel@tonic-gate *cp = 0; 3367c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "local address, return '%s'\n", newname); 3377c478bd9Sstevel@tonic-gate return(savestr(newname)); 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate /* 3417c478bd9Sstevel@tonic-gate * We have name with no @'s in it, and from with @'s. 3427c478bd9Sstevel@tonic-gate * Assume that name is meaningful only on the site in from, 3437c478bd9Sstevel@tonic-gate * and return "name@site_in_from". 3447c478bd9Sstevel@tonic-gate */ 3457c478bd9Sstevel@tonic-gate static char * 3467c478bd9Sstevel@tonic-gate makeremote(char name[], char from[]) 3477c478bd9Sstevel@tonic-gate { 3487c478bd9Sstevel@tonic-gate register char *cp; 3497c478bd9Sstevel@tonic-gate char rbuf[BUFSIZ]; 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate if (!value("makeremote")) 3527c478bd9Sstevel@tonic-gate return(name); 3537c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "makeremote(%s, %s) returns ", name, from); 3547c478bd9Sstevel@tonic-gate cp = strrchr(from, '@'); 3557c478bd9Sstevel@tonic-gate if (cp == NOSTR) 3567c478bd9Sstevel@tonic-gate cp = strrchr(from, '%'); 3577c478bd9Sstevel@tonic-gate snprintf(rbuf, sizeof (rbuf), "%s%s", name, cp); 3587c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "%s\n", rbuf); 3597c478bd9Sstevel@tonic-gate return(savestr(rbuf)); 3607c478bd9Sstevel@tonic-gate } 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate /* 3637c478bd9Sstevel@tonic-gate * Take a network machine descriptor and find the types of connected 3647c478bd9Sstevel@tonic-gate * nets and return it. 3657c478bd9Sstevel@tonic-gate */ 3667c478bd9Sstevel@tonic-gate static int 3677c478bd9Sstevel@tonic-gate nettype(int mid) 3687c478bd9Sstevel@tonic-gate { 3697c478bd9Sstevel@tonic-gate register struct netmach *np; 3707c478bd9Sstevel@tonic-gate 3717c478bd9Sstevel@tonic-gate if (mid & 0200) 3727c478bd9Sstevel@tonic-gate return(mtype(mid)); 3737c478bd9Sstevel@tonic-gate for (np = netmach; np->nt_mid != 0; np++) 3747c478bd9Sstevel@tonic-gate if (np->nt_mid == mid) 3757c478bd9Sstevel@tonic-gate return(np->nt_type); 3767c478bd9Sstevel@tonic-gate return(0); 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate /* 3807c478bd9Sstevel@tonic-gate * Hashing routines to salt away machines seen scanning 3817c478bd9Sstevel@tonic-gate * networks paths that we don't know about. 3827c478bd9Sstevel@tonic-gate */ 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate #define XHSIZE 97 /* Size of extra hash table */ 3857c478bd9Sstevel@tonic-gate #define NXMID (XHSIZE*3/4) /* Max extra machines */ 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate struct xtrahash { 3887c478bd9Sstevel@tonic-gate char *xh_name; /* Name of machine */ 3897c478bd9Sstevel@tonic-gate short xh_mid; /* Machine ID */ 3907c478bd9Sstevel@tonic-gate short xh_attnet; /* Attached networks */ 3917c478bd9Sstevel@tonic-gate } xtrahash[XHSIZE]; 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate static struct xtrahash *xtab[XHSIZE]; /* F: mid-->machine name */ 3947c478bd9Sstevel@tonic-gate 3957c478bd9Sstevel@tonic-gate static short midfree; /* Next free machine id */ 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate /* 3987c478bd9Sstevel@tonic-gate * Initialize the extra host hash table. 3997c478bd9Sstevel@tonic-gate * Called by sreset. 4007c478bd9Sstevel@tonic-gate */ 4017c478bd9Sstevel@tonic-gate void 4027c478bd9Sstevel@tonic-gate minit(void) 4037c478bd9Sstevel@tonic-gate { 4047c478bd9Sstevel@tonic-gate register struct xtrahash *xp, **tp; 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate midfree = 0; 4077c478bd9Sstevel@tonic-gate tp = &xtab[0]; 4087c478bd9Sstevel@tonic-gate for (xp = &xtrahash[0]; xp < &xtrahash[XHSIZE]; xp++) { 4097c478bd9Sstevel@tonic-gate xp->xh_name = NOSTR; 4107c478bd9Sstevel@tonic-gate xp->xh_mid = 0; 4117c478bd9Sstevel@tonic-gate xp->xh_attnet = 0; 4127c478bd9Sstevel@tonic-gate *tp++ = (struct xtrahash *) 0; 4137c478bd9Sstevel@tonic-gate } 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate /* 4177c478bd9Sstevel@tonic-gate * Stash a net name in the extra host hash table. 4187c478bd9Sstevel@tonic-gate * If a new entry is put in the hash table, deduce what 4197c478bd9Sstevel@tonic-gate * net the machine is attached to from the net character. 4207c478bd9Sstevel@tonic-gate * 4217c478bd9Sstevel@tonic-gate * If the machine is already known, add the given attached 4227c478bd9Sstevel@tonic-gate * net to those already known. 4237c478bd9Sstevel@tonic-gate */ 4247c478bd9Sstevel@tonic-gate static int 4257c478bd9Sstevel@tonic-gate mstash(char name[], int attnet) 4267c478bd9Sstevel@tonic-gate { 4277c478bd9Sstevel@tonic-gate register struct xtrahash *xp; 4287c478bd9Sstevel@tonic-gate int x; 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate xp = xlocate(name); 4317c478bd9Sstevel@tonic-gate if (xp == (struct xtrahash *) 0) { 4327c478bd9Sstevel@tonic-gate printf(gettext("Ran out of machine id spots\n")); 4337c478bd9Sstevel@tonic-gate return(0); 4347c478bd9Sstevel@tonic-gate } 4357c478bd9Sstevel@tonic-gate if (xp->xh_name == NOSTR) { 4367c478bd9Sstevel@tonic-gate if (midfree >= XHSIZE) { 4377c478bd9Sstevel@tonic-gate printf(gettext("Out of machine ids\n")); 4387c478bd9Sstevel@tonic-gate return(0); 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate xtab[midfree] = xp; 4417c478bd9Sstevel@tonic-gate xp->xh_name = savestr(name); 4427c478bd9Sstevel@tonic-gate xp->xh_mid = 0200 + midfree++; 4437c478bd9Sstevel@tonic-gate } 4447c478bd9Sstevel@tonic-gate x = ntype(attnet); 4457c478bd9Sstevel@tonic-gate if (x == 0) 4467c478bd9Sstevel@tonic-gate xp->xh_attnet |= AN; 4477c478bd9Sstevel@tonic-gate else 4487c478bd9Sstevel@tonic-gate xp->xh_attnet |= x; 4497c478bd9Sstevel@tonic-gate return(xp->xh_mid); 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate /* 4537c478bd9Sstevel@tonic-gate * Search for the given name in the hash table 4547c478bd9Sstevel@tonic-gate * and return the pointer to it if found, or to the first 4557c478bd9Sstevel@tonic-gate * empty slot if not found. 4567c478bd9Sstevel@tonic-gate * 4577c478bd9Sstevel@tonic-gate * If no free slots can be found, return 0. 4587c478bd9Sstevel@tonic-gate */ 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate static struct xtrahash * 4617c478bd9Sstevel@tonic-gate xlocate(char name[]) 4627c478bd9Sstevel@tonic-gate { 4637c478bd9Sstevel@tonic-gate register int h, q, i; 4647c478bd9Sstevel@tonic-gate register char *cp; 4657c478bd9Sstevel@tonic-gate register struct xtrahash *xp; 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate for (h = 0, cp = name; *cp; h = (h << 2) + *cp++) 4687c478bd9Sstevel@tonic-gate ; 4697c478bd9Sstevel@tonic-gate if (h < 0 && (h = -h) < 0) 4707c478bd9Sstevel@tonic-gate h = 0; 4717c478bd9Sstevel@tonic-gate h = h % XHSIZE; 4727c478bd9Sstevel@tonic-gate cp = name; 4737c478bd9Sstevel@tonic-gate for (i = 0, q = 0; q < XHSIZE; i++, q = i * i) { 4747c478bd9Sstevel@tonic-gate xp = &xtrahash[(h + q) % XHSIZE]; 4757c478bd9Sstevel@tonic-gate if (xp->xh_name == NOSTR) 4767c478bd9Sstevel@tonic-gate return(xp); 4777c478bd9Sstevel@tonic-gate if (strcmp(cp, xp->xh_name) == 0) 4787c478bd9Sstevel@tonic-gate return(xp); 4797c478bd9Sstevel@tonic-gate if (h - q < 0) 4807c478bd9Sstevel@tonic-gate h += XHSIZE; 4817c478bd9Sstevel@tonic-gate xp = &xtrahash[(h - q) % XHSIZE]; 4827c478bd9Sstevel@tonic-gate if (xp->xh_name == NOSTR) 4837c478bd9Sstevel@tonic-gate return(xp); 4847c478bd9Sstevel@tonic-gate if (strcmp(cp, xp->xh_name) == 0) 4857c478bd9Sstevel@tonic-gate return(xp); 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate return((struct xtrahash *) 0); 4887c478bd9Sstevel@tonic-gate } 4897c478bd9Sstevel@tonic-gate 4907c478bd9Sstevel@tonic-gate #ifdef OPTIM 4917c478bd9Sstevel@tonic-gate /* 4927c478bd9Sstevel@tonic-gate * Return the name from the extra host hash table corresponding 4937c478bd9Sstevel@tonic-gate * to the passed machine id. 4947c478bd9Sstevel@tonic-gate */ 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate static char * 4977c478bd9Sstevel@tonic-gate mlook(int mid) 4987c478bd9Sstevel@tonic-gate { 4997c478bd9Sstevel@tonic-gate register int m; 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate if ((mid & 0200) == 0) 5027c478bd9Sstevel@tonic-gate return(NOSTR); 5037c478bd9Sstevel@tonic-gate m = mid & 0177; 5047c478bd9Sstevel@tonic-gate if (m >= midfree) { 5057c478bd9Sstevel@tonic-gate printf(gettext("Use made of undefined machine id\n")); 5067c478bd9Sstevel@tonic-gate return(NOSTR); 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate return(xtab[m]->xh_name); 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate #endif 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate /* 5137c478bd9Sstevel@tonic-gate * Return the bit mask of net's that the given extra host machine 5147c478bd9Sstevel@tonic-gate * id has so far. 5157c478bd9Sstevel@tonic-gate */ 5167c478bd9Sstevel@tonic-gate static int 5177c478bd9Sstevel@tonic-gate mtype(int mid) 5187c478bd9Sstevel@tonic-gate { 5197c478bd9Sstevel@tonic-gate register int m; 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate if ((mid & 0200) == 0) 5227c478bd9Sstevel@tonic-gate return(0); 5237c478bd9Sstevel@tonic-gate m = mid & 0177; 5247c478bd9Sstevel@tonic-gate if (m >= midfree) { 5257c478bd9Sstevel@tonic-gate printf(gettext("Use made of undefined machine id\n")); 5267c478bd9Sstevel@tonic-gate return(0); 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate return(xtab[m]->xh_attnet); 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate #ifdef OPTIM 5327c478bd9Sstevel@tonic-gate /* 5337c478bd9Sstevel@tonic-gate * Take a network name and optimize it. This gloriously messy 5347c478bd9Sstevel@tonic-gate * operation takes place as follows: the name with machine names 5357c478bd9Sstevel@tonic-gate * in it is tokenized by mapping each machine name into a single 5367c478bd9Sstevel@tonic-gate * character machine id (netlook). The separator characters (network 5377c478bd9Sstevel@tonic-gate * metacharacters) are left intact. The last component of the network 5387c478bd9Sstevel@tonic-gate * name is stripped off and assumed to be the destination user name -- 5397c478bd9Sstevel@tonic-gate * it does not participate in the optimization. As an example, the 5407c478bd9Sstevel@tonic-gate * name "res!vax!res!uvax!bill" becomes, tokenized, 5417c478bd9Sstevel@tonic-gate * "r!x!r!v!" and "bill" A low level routine, optim1, fixes up the 5427c478bd9Sstevel@tonic-gate * network part (eg, "r!x!r!v!"), then we convert back to network 5437c478bd9Sstevel@tonic-gate * machine names and tack the user name on the end. 5447c478bd9Sstevel@tonic-gate * 5457c478bd9Sstevel@tonic-gate * The result of this is copied into the parameter "name" 5467c478bd9Sstevel@tonic-gate */ 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate static void 5497c478bd9Sstevel@tonic-gate optim(char net[], char name[]) 5507c478bd9Sstevel@tonic-gate { 5517c478bd9Sstevel@tonic-gate char netcomp[BUFSIZ], netstr[STSIZ], xfstr[STSIZ]; 5527c478bd9Sstevel@tonic-gate register char *cp, *cp2; 5537c478bd9Sstevel@tonic-gate register int c; 5547c478bd9Sstevel@tonic-gate 5557c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "optim(%s, %s) called\n", net, name); 5567c478bd9Sstevel@tonic-gate *netstr = '\0'; 5577c478bd9Sstevel@tonic-gate cp = net; 5587c478bd9Sstevel@tonic-gate for (;;) { 5597c478bd9Sstevel@tonic-gate /* 5607c478bd9Sstevel@tonic-gate * Rip off next path component into netcomp 5617c478bd9Sstevel@tonic-gate */ 5627c478bd9Sstevel@tonic-gate cp2 = netcomp; 5637c478bd9Sstevel@tonic-gate while (*cp && !any(*cp, metanet)) 5647c478bd9Sstevel@tonic-gate *cp2++ = *cp++; 5657c478bd9Sstevel@tonic-gate *cp2 = 0; 5667c478bd9Sstevel@tonic-gate /* 5677c478bd9Sstevel@tonic-gate * If we hit null byte, then we just scanned 5687c478bd9Sstevel@tonic-gate * the destination user name. Go off and optimize 5697c478bd9Sstevel@tonic-gate * if its so. 5707c478bd9Sstevel@tonic-gate */ 5717c478bd9Sstevel@tonic-gate if (*cp == 0) 5727c478bd9Sstevel@tonic-gate break; 5737c478bd9Sstevel@tonic-gate if ((c = netlook(netcomp, *cp)) == 0) { 5747c478bd9Sstevel@tonic-gate printf(gettext("No host named \"%s\"\n"), netcomp); 5757c478bd9Sstevel@tonic-gate err: 5767c478bd9Sstevel@tonic-gate nstrcpy(name, BUFSIZ, net); 5777c478bd9Sstevel@tonic-gate return; 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate stradd(name, BUFSIZ, c); 5807c478bd9Sstevel@tonic-gate stradd(name, BUFSIZ, *cp++); 5817c478bd9Sstevel@tonic-gate /* 5827c478bd9Sstevel@tonic-gate * If multiple network separators given, 5837c478bd9Sstevel@tonic-gate * throw away the extras. 5847c478bd9Sstevel@tonic-gate */ 5857c478bd9Sstevel@tonic-gate while (any(*cp, metanet)) 5867c478bd9Sstevel@tonic-gate cp++; 5877c478bd9Sstevel@tonic-gate } 5887c478bd9Sstevel@tonic-gate if (strlen(netcomp) == 0) { 5897c478bd9Sstevel@tonic-gate printf(gettext("net name syntax\n")); 5907c478bd9Sstevel@tonic-gate goto err; 5917c478bd9Sstevel@tonic-gate } 5927c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "optim1(%s,%s) called\n", netstr, xfstr); 5937c478bd9Sstevel@tonic-gate optim1(netstr, xfstr); 5947c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "optim1(%s,%s) returns\n", netstr, xfstr); 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate /* 5977c478bd9Sstevel@tonic-gate * Convert back to machine names. 5987c478bd9Sstevel@tonic-gate */ 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate cp = xfstr; 6017c478bd9Sstevel@tonic-gate *name = '\0'; 6027c478bd9Sstevel@tonic-gate while (*cp) { 6037c478bd9Sstevel@tonic-gate if ((cp2 = netname(*cp++)) == NOSTR) { 6047c478bd9Sstevel@tonic-gate printf(gettext("Made up bad net name\n")); 6057c478bd9Sstevel@tonic-gate printf(gettext("Machine code %c (0%o)\n"), cp[-1], 6067c478bd9Sstevel@tonic-gate cp[-1]); 6077c478bd9Sstevel@tonic-gate printf(gettext("Sorry.\n")); 6087c478bd9Sstevel@tonic-gate goto err; 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate nstrcat(name, BUFSIZ, cp2); 6117c478bd9Sstevel@tonic-gate stradd(name, BUFSIZ, *cp++); 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate nstrcat(name, BUFSIZ, netcomp); 6147c478bd9Sstevel@tonic-gate if (debug) fprintf(stderr, "optim returns %s in name\n", name); 6157c478bd9Sstevel@tonic-gate } 6167c478bd9Sstevel@tonic-gate 6177c478bd9Sstevel@tonic-gate /* 6187c478bd9Sstevel@tonic-gate * Take a string of network machine id's and separators and 6197c478bd9Sstevel@tonic-gate * optimize them. We process these by pulling off maximal 6207c478bd9Sstevel@tonic-gate * leading strings of the same type, passing these to the appropriate 6217c478bd9Sstevel@tonic-gate * optimizer and concatenating the results. 6227c478bd9Sstevel@tonic-gate */ 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate static void 6257c478bd9Sstevel@tonic-gate optim1(char netstr[], char name[]) 6267c478bd9Sstevel@tonic-gate { 6277c478bd9Sstevel@tonic-gate char path[STSIZ], rpath[STSIZ]; 6287c478bd9Sstevel@tonic-gate register char *cp, *cp2; 6297c478bd9Sstevel@tonic-gate register int tp, nc; 6307c478bd9Sstevel@tonic-gate 6317c478bd9Sstevel@tonic-gate cp = netstr; 6327c478bd9Sstevel@tonic-gate prefer(cp); 6337c478bd9Sstevel@tonic-gate *name = '\0'; 6347c478bd9Sstevel@tonic-gate /* 6357c478bd9Sstevel@tonic-gate * If the address ultimately points back to us, 6367c478bd9Sstevel@tonic-gate * just return a null network path. 6377c478bd9Sstevel@tonic-gate */ 6387c478bd9Sstevel@tonic-gate if ((int)strlen(cp) > 1 && cp[strlen(cp) - 2] == LOCAL) 6397c478bd9Sstevel@tonic-gate return; 6407c478bd9Sstevel@tonic-gate while (*cp != 0) { 6417c478bd9Sstevel@tonic-gate *path = '\0'; 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate tp = ntype(cp[1]); 6447c478bd9Sstevel@tonic-gate nc = cp[1]; 6457c478bd9Sstevel@tonic-gate while (*cp && tp == ntype(cp[1])) { 6467c478bd9Sstevel@tonic-gate stradd(path, sizeof (path), *cp++); 6477c478bd9Sstevel@tonic-gate cp++; 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate switch (netkind(tp)) { 6507c478bd9Sstevel@tonic-gate default: 6517c478bd9Sstevel@tonic-gate nstrcpy(rpath, sizeof (rpath), path); 6527c478bd9Sstevel@tonic-gate break; 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate case IMPLICIT: 6557c478bd9Sstevel@tonic-gate optimimp(path, rpath); 6567c478bd9Sstevel@tonic-gate break; 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate case EXPLICIT: 6597c478bd9Sstevel@tonic-gate optimex(path, rpath); 6607c478bd9Sstevel@tonic-gate break; 6617c478bd9Sstevel@tonic-gate } 6627c478bd9Sstevel@tonic-gate for (cp2 = rpath; *cp2 != 0; cp2++) { 6637c478bd9Sstevel@tonic-gate stradd(name, BUFSIZ, *cp2); 6647c478bd9Sstevel@tonic-gate stradd(name, BUFSIZ, nc); 6657c478bd9Sstevel@tonic-gate } 6667c478bd9Sstevel@tonic-gate } 6677c478bd9Sstevel@tonic-gate optiboth(name); 6687c478bd9Sstevel@tonic-gate prefer(name); 6697c478bd9Sstevel@tonic-gate } 670*6c83d09fSrobbin #endif /* OPTIM */ 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate /* 6737c478bd9Sstevel@tonic-gate * Return the network of the separator -- 6747c478bd9Sstevel@tonic-gate * AN for arpa net 6757c478bd9Sstevel@tonic-gate * BN for Bell labs net (e.g. UUCP, NOT Berknet) 6767c478bd9Sstevel@tonic-gate * SN for Schmidt net (Berknet) 6777c478bd9Sstevel@tonic-gate * 0 if we don't know. 6787c478bd9Sstevel@tonic-gate */ 6797c478bd9Sstevel@tonic-gate static int 6807c478bd9Sstevel@tonic-gate ntype(register int nc) 6817c478bd9Sstevel@tonic-gate { 6827c478bd9Sstevel@tonic-gate register struct ntypetab *np; 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate for (np = ntypetab; np->nt_char != 0; np++) 6857c478bd9Sstevel@tonic-gate if (np->nt_char == nc) 6867c478bd9Sstevel@tonic-gate return(np->nt_bcode); 6877c478bd9Sstevel@tonic-gate return(0); 6887c478bd9Sstevel@tonic-gate } 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate #ifdef OPTIM 6917c478bd9Sstevel@tonic-gate /* 6927c478bd9Sstevel@tonic-gate * Return the kind of routing used for the particular net 6937c478bd9Sstevel@tonic-gate * EXPLICIT means explicitly routed 6947c478bd9Sstevel@tonic-gate * IMPLICIT means implicitly routed 6957c478bd9Sstevel@tonic-gate * 0 means don't know 6967c478bd9Sstevel@tonic-gate */ 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate static int 6997c478bd9Sstevel@tonic-gate netkind(register int nt) 7007c478bd9Sstevel@tonic-gate { 7017c478bd9Sstevel@tonic-gate register struct nkindtab *np; 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate for (np = nkindtab; np->nk_type != 0; np++) 7047c478bd9Sstevel@tonic-gate if (np->nk_type == nt) 7057c478bd9Sstevel@tonic-gate return(np->nk_kind); 7067c478bd9Sstevel@tonic-gate return(0); 7077c478bd9Sstevel@tonic-gate } 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate /* 7107c478bd9Sstevel@tonic-gate * Do name optimization for an explicitly routed network (eg uucp). 7117c478bd9Sstevel@tonic-gate */ 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate static int 7147c478bd9Sstevel@tonic-gate optimex(char net[], char name[]) 7157c478bd9Sstevel@tonic-gate { 7167c478bd9Sstevel@tonic-gate register char *cp, *rp; 7177c478bd9Sstevel@tonic-gate register int m; 7187c478bd9Sstevel@tonic-gate 7197c478bd9Sstevel@tonic-gate nstrcpy(name, STSIZ, net); 7207c478bd9Sstevel@tonic-gate cp = name; 7217c478bd9Sstevel@tonic-gate if (strlen(cp) == 0) 7227c478bd9Sstevel@tonic-gate return(-1); 7237c478bd9Sstevel@tonic-gate if (cp[strlen(cp)-1] == LOCAL) { 7247c478bd9Sstevel@tonic-gate name[0] = 0; 7257c478bd9Sstevel@tonic-gate return(0); 7267c478bd9Sstevel@tonic-gate } 7277c478bd9Sstevel@tonic-gate for (cp = name; *cp; cp++) { 7287c478bd9Sstevel@tonic-gate m = *cp; 7297c478bd9Sstevel@tonic-gate rp = strrchr(cp+1, m); 7307c478bd9Sstevel@tonic-gate if (rp != NOSTR) 7317c478bd9Sstevel@tonic-gate strcpy(cp, rp); 7327c478bd9Sstevel@tonic-gate } 7337c478bd9Sstevel@tonic-gate return(0); 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate /* 7377c478bd9Sstevel@tonic-gate * Do name optimization for implicitly routed network (eg, arpanet). 7387c478bd9Sstevel@tonic-gate */ 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate static int 7417c478bd9Sstevel@tonic-gate optimimp(char net[], char name[]) 7427c478bd9Sstevel@tonic-gate { 7437c478bd9Sstevel@tonic-gate register char *cp; 7447c478bd9Sstevel@tonic-gate register char m; 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate cp = net; 7477c478bd9Sstevel@tonic-gate if (strlen(cp) == 0) 7487c478bd9Sstevel@tonic-gate return(-1); 7497c478bd9Sstevel@tonic-gate m = cp[strlen(cp) - 1]; 7507c478bd9Sstevel@tonic-gate if (m == LOCAL) { 7517c478bd9Sstevel@tonic-gate *name = '\0'; 7527c478bd9Sstevel@tonic-gate return(0); 7537c478bd9Sstevel@tonic-gate } 7547c478bd9Sstevel@tonic-gate name[0] = m; 7557c478bd9Sstevel@tonic-gate name[1] = 0; 7567c478bd9Sstevel@tonic-gate return(0); 7577c478bd9Sstevel@tonic-gate } 7587c478bd9Sstevel@tonic-gate 7597c478bd9Sstevel@tonic-gate /* 7607c478bd9Sstevel@tonic-gate * Perform global optimization on the given network path. 7617c478bd9Sstevel@tonic-gate * The trick here is to look ahead to see if there are any loops 7627c478bd9Sstevel@tonic-gate * in the path and remove them. The interpretation of loops is 7637c478bd9Sstevel@tonic-gate * more strict here than in optimex since both the machine and net 7647c478bd9Sstevel@tonic-gate * type must match. 7657c478bd9Sstevel@tonic-gate */ 7667c478bd9Sstevel@tonic-gate 7677c478bd9Sstevel@tonic-gate static void 7687c478bd9Sstevel@tonic-gate optiboth(char net[]) 7697c478bd9Sstevel@tonic-gate { 7707c478bd9Sstevel@tonic-gate register char *cp, *cp2; 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate cp = net; 7737c478bd9Sstevel@tonic-gate if (strlen(cp) == 0) 7747c478bd9Sstevel@tonic-gate return; 7757c478bd9Sstevel@tonic-gate if (((int)strlen(cp) % 2) != 0) { 7767c478bd9Sstevel@tonic-gate printf(gettext("Strange arg to optiboth\n")); 7777c478bd9Sstevel@tonic-gate return; 7787c478bd9Sstevel@tonic-gate } 7797c478bd9Sstevel@tonic-gate while (*cp) { 7807c478bd9Sstevel@tonic-gate cp2 = rpair(cp+2, *cp); 7817c478bd9Sstevel@tonic-gate if (cp2 != NOSTR) 7827c478bd9Sstevel@tonic-gate strcpy(cp, cp2); 7837c478bd9Sstevel@tonic-gate cp += 2; 7847c478bd9Sstevel@tonic-gate } 7857c478bd9Sstevel@tonic-gate } 7867c478bd9Sstevel@tonic-gate 7877c478bd9Sstevel@tonic-gate /* 7887c478bd9Sstevel@tonic-gate * Find the rightmost instance of the given (machine, type) pair. 7897c478bd9Sstevel@tonic-gate */ 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate static char * 7927c478bd9Sstevel@tonic-gate rpair(char str[], int mach) 7937c478bd9Sstevel@tonic-gate { 7947c478bd9Sstevel@tonic-gate register char *cp, *last; 7957c478bd9Sstevel@tonic-gate 7967c478bd9Sstevel@tonic-gate cp = str; 7977c478bd9Sstevel@tonic-gate last = NOSTR; 7987c478bd9Sstevel@tonic-gate while (*cp) { 7997c478bd9Sstevel@tonic-gate if (*cp == mach) 8007c478bd9Sstevel@tonic-gate last = cp; 8017c478bd9Sstevel@tonic-gate cp += 2; 8027c478bd9Sstevel@tonic-gate } 8037c478bd9Sstevel@tonic-gate return(last); 8047c478bd9Sstevel@tonic-gate } 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate /* 8077c478bd9Sstevel@tonic-gate * Change the network separators in the given network path 8087c478bd9Sstevel@tonic-gate * to the preferred network transmission means. 8097c478bd9Sstevel@tonic-gate */ 8107c478bd9Sstevel@tonic-gate 8117c478bd9Sstevel@tonic-gate static void 8127c478bd9Sstevel@tonic-gate prefer(char name[]) 8137c478bd9Sstevel@tonic-gate { 8147c478bd9Sstevel@tonic-gate register char *cp, n; 8157c478bd9Sstevel@tonic-gate register int state; 8167c478bd9Sstevel@tonic-gate 8177c478bd9Sstevel@tonic-gate state = LOCAL; 8187c478bd9Sstevel@tonic-gate for (cp = name; *cp; cp += 2) { 8197c478bd9Sstevel@tonic-gate n = best(state, *cp); 8207c478bd9Sstevel@tonic-gate if (n) 8217c478bd9Sstevel@tonic-gate cp[1] = n; 8227c478bd9Sstevel@tonic-gate state = *cp; 8237c478bd9Sstevel@tonic-gate } 8247c478bd9Sstevel@tonic-gate } 8257c478bd9Sstevel@tonic-gate 8267c478bd9Sstevel@tonic-gate /* 8277c478bd9Sstevel@tonic-gate * Return the best network separator for the given machine pair. 8287c478bd9Sstevel@tonic-gate */ 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate static char 8317c478bd9Sstevel@tonic-gate best(int src, int dest) 8327c478bd9Sstevel@tonic-gate { 8337c478bd9Sstevel@tonic-gate register int dtype, stype; 8347c478bd9Sstevel@tonic-gate register struct netorder *np; 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate stype = nettype(src); 8377c478bd9Sstevel@tonic-gate dtype = nettype(dest); 8387c478bd9Sstevel@tonic-gate fflush(stdout); 8397c478bd9Sstevel@tonic-gate if (stype == 0 || dtype == 0) { 8407c478bd9Sstevel@tonic-gate printf(gettext("ERROR: unknown internal machine id\n")); 8417c478bd9Sstevel@tonic-gate return(0); 8427c478bd9Sstevel@tonic-gate } 8437c478bd9Sstevel@tonic-gate if ((stype & dtype) == 0) 8447c478bd9Sstevel@tonic-gate return(0); 8457c478bd9Sstevel@tonic-gate np = &netorder[0]; 8467c478bd9Sstevel@tonic-gate while ((np->no_stat & stype & dtype) == 0) 8477c478bd9Sstevel@tonic-gate np++; 8487c478bd9Sstevel@tonic-gate return(np->no_char); 8497c478bd9Sstevel@tonic-gate } 850*6c83d09fSrobbin #endif /* OPTIM */ 8517c478bd9Sstevel@tonic-gate 8527c478bd9Sstevel@tonic-gate #ifdef notdef 8537c478bd9Sstevel@tonic-gate /* 8547c478bd9Sstevel@tonic-gate * Code to twist around arpa net names. 8557c478bd9Sstevel@tonic-gate */ 8567c478bd9Sstevel@tonic-gate 8577c478bd9Sstevel@tonic-gate #define WORD 257 /* Token for a string */ 8587c478bd9Sstevel@tonic-gate 8597c478bd9Sstevel@tonic-gate static char netbuf[256]; 8607c478bd9Sstevel@tonic-gate static char *yylval; 8617c478bd9Sstevel@tonic-gate 8627c478bd9Sstevel@tonic-gate /* 8637c478bd9Sstevel@tonic-gate * Reverse all of the arpa net addresses in the given name to 8647c478bd9Sstevel@tonic-gate * be of the form "host @ user" instead of "user @ host" 8657c478bd9Sstevel@tonic-gate * This function is its own inverse. 8667c478bd9Sstevel@tonic-gate */ 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate char * 8697c478bd9Sstevel@tonic-gate revarpa(char str[]) 8707c478bd9Sstevel@tonic-gate { 8717c478bd9Sstevel@tonic-gate 8727c478bd9Sstevel@tonic-gate if (yyinit(str) < 0) 8737c478bd9Sstevel@tonic-gate return(NOSTR); 8747c478bd9Sstevel@tonic-gate if (name()) 8757c478bd9Sstevel@tonic-gate return(NOSTR); 8767c478bd9Sstevel@tonic-gate if (strcmp(str, netbuf) == 0) 8777c478bd9Sstevel@tonic-gate return(str); 8787c478bd9Sstevel@tonic-gate return(savestr(netbuf)); 8797c478bd9Sstevel@tonic-gate } 8807c478bd9Sstevel@tonic-gate 8817c478bd9Sstevel@tonic-gate /* 8827c478bd9Sstevel@tonic-gate * Parse (by recursive descent) network names, using the following grammar: 8837c478bd9Sstevel@tonic-gate * name: 8847c478bd9Sstevel@tonic-gate * term {':' term} 8857c478bd9Sstevel@tonic-gate * term {'^' term} 8867c478bd9Sstevel@tonic-gate * term {'!' term} 8877c478bd9Sstevel@tonic-gate * term '@' name 8887c478bd9Sstevel@tonic-gate * term '%' name 8897c478bd9Sstevel@tonic-gate * 8907c478bd9Sstevel@tonic-gate * term: 8917c478bd9Sstevel@tonic-gate * string of characters. 8927c478bd9Sstevel@tonic-gate */ 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate static int 8957c478bd9Sstevel@tonic-gate name(void) 8967c478bd9Sstevel@tonic-gate { 8977c478bd9Sstevel@tonic-gate register int t; 8987c478bd9Sstevel@tonic-gate register char *cp; 8997c478bd9Sstevel@tonic-gate 9007c478bd9Sstevel@tonic-gate for (;;) { 9017c478bd9Sstevel@tonic-gate t = yylex(); 9027c478bd9Sstevel@tonic-gate if (t != WORD) 9037c478bd9Sstevel@tonic-gate return(-1); 9047c478bd9Sstevel@tonic-gate cp = yylval; 9057c478bd9Sstevel@tonic-gate t = yylex(); 9067c478bd9Sstevel@tonic-gate switch (t) { 9077c478bd9Sstevel@tonic-gate case 0: 9087c478bd9Sstevel@tonic-gate nstrcat(netbuf, sizeof (netbuf), cp); 9097c478bd9Sstevel@tonic-gate return(0); 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate case '@': 9127c478bd9Sstevel@tonic-gate case '%': 9137c478bd9Sstevel@tonic-gate if (name()) 9147c478bd9Sstevel@tonic-gate return(-1); 9157c478bd9Sstevel@tonic-gate stradd(netbuf, sizeof (netbuf), '@'); 9167c478bd9Sstevel@tonic-gate nstrcat(netbuf, sizeof (netbuf), cp); 9177c478bd9Sstevel@tonic-gate return(0); 9187c478bd9Sstevel@tonic-gate case WORD: 9197c478bd9Sstevel@tonic-gate return(-1); 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate default: 9227c478bd9Sstevel@tonic-gate nstrcat(netbuf, sizeof (netbuf), cp); 9237c478bd9Sstevel@tonic-gate stradd(netbuf, sizeof (netbuf), t); 9247c478bd9Sstevel@tonic-gate } 9257c478bd9Sstevel@tonic-gate } 9267c478bd9Sstevel@tonic-gate } 9277c478bd9Sstevel@tonic-gate 9287c478bd9Sstevel@tonic-gate /* 9297c478bd9Sstevel@tonic-gate * Scanner for network names. 9307c478bd9Sstevel@tonic-gate */ 9317c478bd9Sstevel@tonic-gate 9327c478bd9Sstevel@tonic-gate static char *charp; /* Current input pointer */ 9337c478bd9Sstevel@tonic-gate static int nexttok; /* Salted away next token */ 9347c478bd9Sstevel@tonic-gate 9357c478bd9Sstevel@tonic-gate /* 9367c478bd9Sstevel@tonic-gate * Initialize the network name scanner. 9377c478bd9Sstevel@tonic-gate */ 9387c478bd9Sstevel@tonic-gate 9397c478bd9Sstevel@tonic-gate int 9407c478bd9Sstevel@tonic-gate yyinit(char str[]) 9417c478bd9Sstevel@tonic-gate { 9427c478bd9Sstevel@tonic-gate static char lexbuf[BUFSIZ]; 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate netbuf[0] = 0; 9457c478bd9Sstevel@tonic-gate if (strlen(str) >= sizeof lexbuf - 1) 9467c478bd9Sstevel@tonic-gate return(-1); 9477c478bd9Sstevel@tonic-gate nexttok = 0; 9487c478bd9Sstevel@tonic-gate nstrcpy(lexbuf, sizeof (lexbuf), str); 9497c478bd9Sstevel@tonic-gate charp = lexbuf; 9507c478bd9Sstevel@tonic-gate return(0); 9517c478bd9Sstevel@tonic-gate } 9527c478bd9Sstevel@tonic-gate 9537c478bd9Sstevel@tonic-gate /* 9547c478bd9Sstevel@tonic-gate * Scan and return a single token. 9557c478bd9Sstevel@tonic-gate * yylval is set to point to a scanned string. 9567c478bd9Sstevel@tonic-gate */ 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate int 9597c478bd9Sstevel@tonic-gate yylex(void) 9607c478bd9Sstevel@tonic-gate { 9617c478bd9Sstevel@tonic-gate register char *cp, *dotp; 9627c478bd9Sstevel@tonic-gate register int s; 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate if (nexttok) { 9657c478bd9Sstevel@tonic-gate s = nexttok; 9667c478bd9Sstevel@tonic-gate nexttok = 0; 9677c478bd9Sstevel@tonic-gate return(s); 9687c478bd9Sstevel@tonic-gate } 9697c478bd9Sstevel@tonic-gate cp = charp; 9707c478bd9Sstevel@tonic-gate while (*cp && isspace(*cp)) 9717c478bd9Sstevel@tonic-gate cp++; 9727c478bd9Sstevel@tonic-gate if (*cp == 0) 9737c478bd9Sstevel@tonic-gate return(0); 9747c478bd9Sstevel@tonic-gate if (any(*cp, metanet)) { 9757c478bd9Sstevel@tonic-gate charp = cp+1; 9767c478bd9Sstevel@tonic-gate return(*cp); 9777c478bd9Sstevel@tonic-gate } 9787c478bd9Sstevel@tonic-gate dotp = cp; 9797c478bd9Sstevel@tonic-gate while (*cp && !any(*cp, metanet) && !any(*cp, " \t")) 9807c478bd9Sstevel@tonic-gate cp++; 9817c478bd9Sstevel@tonic-gate if (any(*cp, metanet)) 9827c478bd9Sstevel@tonic-gate nexttok = *cp; 9837c478bd9Sstevel@tonic-gate if (*cp == 0) 9847c478bd9Sstevel@tonic-gate charp = cp; 9857c478bd9Sstevel@tonic-gate else 9867c478bd9Sstevel@tonic-gate charp = cp+1; 9877c478bd9Sstevel@tonic-gate *cp = 0; 9887c478bd9Sstevel@tonic-gate yylval = dotp; 9897c478bd9Sstevel@tonic-gate return(WORD); 9907c478bd9Sstevel@tonic-gate } 9917c478bd9Sstevel@tonic-gate #endif 9927c478bd9Sstevel@tonic-gate 9937c478bd9Sstevel@tonic-gate /* 9947c478bd9Sstevel@tonic-gate * Add a single character onto a string. Here dstsize is the size of the 9957c478bd9Sstevel@tonic-gate * destnation buffer. 9967c478bd9Sstevel@tonic-gate */ 9977c478bd9Sstevel@tonic-gate 9987c478bd9Sstevel@tonic-gate static void 9997c478bd9Sstevel@tonic-gate stradd(register char *dst, int dstsize, register int c) 10007c478bd9Sstevel@tonic-gate { 10017c478bd9Sstevel@tonic-gate while (*dst != '\0') { 10027c478bd9Sstevel@tonic-gate dst++; 10037c478bd9Sstevel@tonic-gate dstsize--; 10047c478bd9Sstevel@tonic-gate } 10057c478bd9Sstevel@tonic-gate if (--dstsize > 0) 10067c478bd9Sstevel@tonic-gate *dst++ = (char)c; 10077c478bd9Sstevel@tonic-gate *dst = '\0'; 10087c478bd9Sstevel@tonic-gate } 1009