155682Smarkm/*	$OpenBSD: remote.c,v 1.16 2006/06/06 23:24:52 deraadt Exp $	*/
255682Smarkm/*	$NetBSD: remote.c,v 1.5 1997/04/20 00:02:45 mellon Exp $	*/
355682Smarkm
455682Smarkm/*
555682Smarkm * Copyright (c) 1992, 1993
655682Smarkm *	The Regents of the University of California.  All rights reserved.
755682Smarkm *
855682Smarkm *
955682Smarkm * Redistribution and use in source and binary forms, with or without
1055682Smarkm * modification, are permitted provided that the following conditions
1155682Smarkm * are met:
1255682Smarkm * 1. Redistributions of source code must retain the above copyright
1355682Smarkm *    notice, this list of conditions and the following disclaimer.
1455682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1555682Smarkm *    notice, this list of conditions and the following disclaimer in the
1655682Smarkm *    documentation and/or other materials provided with the distribution.
1755682Smarkm * 3. Neither the name of the University nor the names of its contributors
1855682Smarkm *    may be used to endorse or promote products derived from this software
1955682Smarkm *    without specific prior written permission.
2055682Smarkm *
2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2455682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3155682Smarkm * SUCH DAMAGE.
3255682Smarkm */
3355682Smarkm
3455682Smarkm#include <sys/cdefs.h>
35178825Sdfr__FBSDID("$FreeBSD$");
3655682Smarkm
3755682Smarkm#ifndef lint
3855682Smarkmstatic const char copyright[] =
3955682Smarkm"@(#) Copyright (c) 1992, 1993\n\
4055682Smarkm	The Regents of the University of California.  All rights reserved.\n";
4155682Smarkm#endif /* not lint */
4255682Smarkm
4355682Smarkm#ifndef lint
4455682Smarkm#if 0
4555682Smarkmstatic char sccsid[] = "@(#)remote.c	8.1 (Berkeley) 6/6/93";
4655682Smarkmstatic const char rcsid[] = "$OpenBSD: remote.c,v 1.16 2006/06/06 23:24:52 deraadt Exp $";
4755682Smarkm#endif
4855682Smarkm#endif /* not lint */
4955682Smarkm
5055682Smarkm#include <stdio.h>
5155682Smarkm#include <stdlib.h>
5255682Smarkm
5355682Smarkm#include "pathnames.h"
5455682Smarkm#include "tip.h"
5555682Smarkm
5655682Smarkm/*
5755682Smarkm * Attributes to be gleened from remote host description
5855682Smarkm *   data base.
5955682Smarkm */
6055682Smarkmstatic char **caps[] = {
6155682Smarkm	&AT, &DV, &CM, &CU, &EL, &IE, &OE, &PN, &PR, &DI,
6255682Smarkm	&ES, &EX, &FO, &RC, &RE, &PA
6372445Sassar};
6455682Smarkm
6555682Smarkmstatic char *capstrings[] = {
6655682Smarkm	"at", "dv", "cm", "cu", "el", "ie", "oe", "pn", "pr",
6755682Smarkm	"di", "es", "ex", "fo", "rc", "re", "pa", 0
6855682Smarkm};
6955682Smarkm
7055682Smarkmstatic char	*db_array[3] = { _PATH_REMOTE, 0, 0 };
7155682Smarkm
7255682Smarkm#define cgetflag(f)	(cgetcap(bp, f, ':') != NULL)
7355682Smarkm
7455682Smarkmstatic void	getremcap(char *);
7555682Smarkm
7655682Smarkmstatic void
7755682Smarkmgetremcap(char *host)
7855682Smarkm{
7955682Smarkm	char **p, ***q, *bp, *rempath;
8055682Smarkm	int   stat;
8155682Smarkm
82178825Sdfr	rempath = getenv("REMOTE");
8355682Smarkm	if (rempath != NULL) {
8455682Smarkm		if (*rempath != '/')
8555682Smarkm			/* we have an entry */
8655682Smarkm			cgetset(rempath);
8755682Smarkm		else {	/* we have a path */
8855682Smarkm			db_array[1] = rempath;
8955682Smarkm			db_array[2] = _PATH_REMOTE;
9055682Smarkm		}
9155682Smarkm	}
9255682Smarkm
9355682Smarkm	if ((stat = cgetent(&bp, db_array, host)) < 0) {
9455682Smarkm		if ((DV != NULL) ||
9555682Smarkm		    (host[0] == '/' && access(DV = host, R_OK | W_OK) == 0)) {
9655682Smarkm			CU = DV;
9755682Smarkm			HO = host;
9855682Smarkm			HW = 1;
9955682Smarkm			DU = 0;
10055682Smarkm			if (!BR)
10155682Smarkm				BR = DEFBR;
10255682Smarkm			FS = DEFFS;
10355682Smarkm			return;
104178825Sdfr		}
10555682Smarkm		switch (stat) {
10655682Smarkm		case -1:
10755682Smarkm			fprintf(stderr, "%s: unknown host %s\n", __progname,
10855682Smarkm			    host);
10955682Smarkm			break;
110178825Sdfr		case -2:
11155682Smarkm			fprintf(stderr,
11255682Smarkm			    "%s: can't open host description file\n",
11355682Smarkm			    __progname);
11455682Smarkm			break;
11555682Smarkm		case -3:
11655682Smarkm			fprintf(stderr,
11755682Smarkm			    "%s: possible reference loop in host description file\n", __progname);
11855682Smarkm			break;
11955682Smarkm		}
12055682Smarkm		exit(3);
12155682Smarkm	}
12255682Smarkm
12355682Smarkm	for (p = capstrings, q = caps; *p != NULL; p++, q++)
12455682Smarkm		if (**q == NULL)
12555682Smarkm			cgetstr(bp, *p, *q);
12655682Smarkm	if (!BR && (cgetnum(bp, "br", &BR) == -1))
12755682Smarkm		BR = DEFBR;
12855682Smarkm	if (!LD && (cgetnum(bp, "ld", &LD) == -1))
12955682Smarkm		LD = TTYDISC;
13055682Smarkm	if (cgetnum(bp, "fs", &FS) == -1)
13155682Smarkm		FS = DEFFS;
13255682Smarkm	if (DU < 0)
13355682Smarkm		DU = 0;
13455682Smarkm	else
13555682Smarkm		DU = cgetflag("du");
13655682Smarkm	if (DV == NOSTR) {
13755682Smarkm		fprintf(stderr, "%s: missing device spec\n", host);
13855682Smarkm		exit(3);
13955682Smarkm	}
14055682Smarkm	if (DU && CU == NOSTR)
14155682Smarkm		CU = DV;
14255682Smarkm	if (DU && PN == NOSTR) {
14355682Smarkm		fprintf(stderr, "%s: missing phone number\n", host);
14455682Smarkm		exit(3);
14555682Smarkm	}
14655682Smarkm	if (DU && AT == NOSTR) {
14755682Smarkm		fprintf(stderr, "%s: missing acu type\n", host);
14855682Smarkm		exit(3);
14955682Smarkm	}
15055682Smarkm
15155682Smarkm	HD = cgetflag("hd");
15255682Smarkm
15355682Smarkm	/*
15455682Smarkm	 * This effectively eliminates the "hw" attribute
15555682Smarkm	 *   from the description file
15655682Smarkm	 */
15755682Smarkm	if (!HW)
15855682Smarkm		HW = (CU == NOSTR) || (DU && equal(DV, CU));
15955682Smarkm	HO = host;
16055682Smarkm	/*
16155682Smarkm	 * see if uppercase mode should be turned on initially
16255682Smarkm	 */
16355682Smarkm	if (cgetflag("ra"))
16455682Smarkm		setboolean(value(RAISE), 1);
16555682Smarkm	if (cgetflag("ec"))
16655682Smarkm		setboolean(value(ECHOCHECK), 1);
16755682Smarkm	if (cgetflag("be"))
16855682Smarkm		setboolean(value(BEAUTIFY), 1);
169178825Sdfr	if (cgetflag("nb"))
17055682Smarkm		setboolean(value(BEAUTIFY), 0);
17155682Smarkm	if (cgetflag("sc"))
17255682Smarkm		setboolean(value(SCRIPT), 1);
17355682Smarkm	if (cgetflag("tb"))
17455682Smarkm		setboolean(value(TABEXPAND), 1);
17555682Smarkm	if (cgetflag("vb"))
17655682Smarkm		setboolean(value(VERBOSE), 1);
17755682Smarkm	if (cgetflag("nv"))
178178825Sdfr		setboolean(value(VERBOSE), 0);
17955682Smarkm	if (cgetflag("ta"))
18055682Smarkm		setboolean(value(TAND), 1);
18155682Smarkm	if (cgetflag("nt"))
18255682Smarkm		setboolean(value(TAND), 0);
18355682Smarkm	if (cgetflag("rw"))
18455682Smarkm		setboolean(value(RAWFTP), 1);
18555682Smarkm	if (cgetflag("hd"))
186178825Sdfr		setboolean(value(HALFDUPLEX), 1);
18755682Smarkm	if (cgetflag("dc"))
18855682Smarkm		setboolean(value(DC), 1);
18955682Smarkm	if (cgetflag("hf"))
190178825Sdfr		setboolean(value(HARDWAREFLOW), 1);
19155682Smarkm	if (RE == NOSTR)
19255682Smarkm		RE = (char *)"tip.record";
19355682Smarkm	if (EX == NOSTR)
19455682Smarkm		EX = (char *)"\t\n\b\f";
19572445Sassar	if (ES != NOSTR)
19672445Sassar		vstring("es", ES);
19772445Sassar	if (FO != NOSTR)
19855682Smarkm		vstring("fo", FO);
199178825Sdfr	if (PR != NOSTR)
20055682Smarkm		vstring("pr", PR);
201178825Sdfr	if (RC != NOSTR)
20255682Smarkm		vstring("rc", RC);
203178825Sdfr	if (cgetnum(bp, "dl", &DL) == -1)
204178825Sdfr		DL = 0;
20572445Sassar	if (cgetnum(bp, "cl", &CL) == -1)
20672445Sassar		CL = 0;
20772445Sassar	if (cgetnum(bp, "et", &ET) == -1)
20872445Sassar		ET = 10;
20955682Smarkm}
21055682Smarkm
211178825Sdfrchar *
21255682Smarkmgetremote(char *host)
21355682Smarkm{
21455682Smarkm	char *cp;
21555682Smarkm	static char *next;
21672445Sassar	static int lookedup = 0;
21772445Sassar
21872445Sassar	if (!lookedup) {
21955682Smarkm		if (host == NOSTR && (host = getenv("HOST")) == NOSTR) {
22055682Smarkm			fprintf(stderr, "%s: no host specified\n", __progname);
22155682Smarkm			exit(3);
22272445Sassar		}
22372445Sassar		getremcap(host);
224178825Sdfr		next = DV;
22572445Sassar		lookedup++;
22672445Sassar	}
22772445Sassar	/*
22855682Smarkm	 * We return a new device each time we're called (to allow
22955682Smarkm	 *   a rotary action to be simulated)
23055682Smarkm	 */
23155682Smarkm	if (next == NOSTR)
23255682Smarkm		return (NOSTR);
233178825Sdfr	if ((cp = strchr(next, ',')) == NULL) {
234178825Sdfr		DV = next;
235178825Sdfr		next = NOSTR;
23655682Smarkm	} else {
23755682Smarkm		*cp++ = '\0';
23855682Smarkm		DV = next;
23955682Smarkm		next = cp;
24055682Smarkm	}
241178825Sdfr	return (DV);
242178825Sdfr}
24355682Smarkm