remote.c revision 7527
1262566Sdes/*
299051Sdes * Copyright (c) 1992, 1993
357429Smarkm *	The Regents of the University of California.  All rights reserved.
498684Sdes *
598684Sdes *
676262Sgreen * Redistribution and use in source and binary forms, with or without
798941Sdes * modification, are permitted provided that the following conditions
898941Sdes * are met:
992559Sdes * 1. Redistributions of source code must retain the above copyright
1092559Sdes *    notice, this list of conditions and the following disclaimer.
11226046Sdes * 2. Redistributions in binary form must reproduce the above copyright
1292559Sdes *    notice, this list of conditions and the following disclaimer in the
1392559Sdes *    documentation and/or other materials provided with the distribution.
1499051Sdes * 3. All advertising materials mentioning features or use of this software
1599051Sdes *    must display the following acknowledgement:
1699051Sdes *	This product includes software developed by the University of
1792559Sdes *	California, Berkeley and its contributors.
18147005Sdes * 4. Neither the name of the University nor the names of its contributors
1957429Smarkm *    may be used to endorse or promote products derived from this software
2057429Smarkm *    without specific prior written permission.
2169591Sgreen *
22204917Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23204917Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24181111Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2592559Sdes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2692559Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2792559Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28181111Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2992559Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30221420Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31262566Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3257429Smarkm * SUCH DAMAGE.
3392559Sdes */
34124211Sdes
35181111Sdes#ifndef lint
3692559Sdesstatic char copyright[] =
37255767Sdes"@(#) Copyright (c) 1992, 1993\n\
38255767Sdes	The Regents of the University of California.  All rights reserved.\n";
39255767Sdes#endif /* not lint */
4057429Smarkm
41149753Sdes#ifndef lint
4292559Sdesstatic char sccsid[] = "@(#)remote.c	8.1 (Berkeley) 6/6/93";
4392559Sdes#endif /* not lint */
4457429Smarkm
4592559Sdes#include <sys/syslimits.h>
4692559Sdes#include <stdio.h>
47124211Sdes#include <stdlib.h>
4899051Sdes
4992559Sdes#include "tipconf.h"
50137019Sdes#include "tip.h"
51181111Sdes#include "pathnames.h"
5292559Sdes
5392559Sdes/*
5492559Sdes * Attributes to be gleened from remote host description
5592559Sdes *   data base.
56226046Sdes */
57248465Sdesstatic char **caps[] = {
58226046Sdes	&AT, &DV, &CM, &CU, &EL, &IE, &OE, &PN, &PR, &DI,
59240075Sdes	&ES, &EX, &FO, &RC, &RE, &PA, &LI, &LO
60240075Sdes};
61248619Sdes
62248619Sdesstatic char *capstrings[] = {
63248619Sdes	"at", "dv", "cm", "cu", "el", "ie", "oe", "pn", "pr",
6492559Sdes	"di", "es", "ex", "fo", "rc", "re", "pa", "li", "lo", 0
6592559Sdes};
6676262Sgreen
6792559Sdesstatic char	*db_array[3] = { _PATH_REMOTE, 0, 0 };
6892559Sdes
6992559Sdes#define cgetflag(f)	(cgetcap(bp, f, ':') != NULL)
7092559Sdes
71124211Sdes/*
72124211Sdes	Expand the start tilde sequence at the start of the
7357429Smarkm	specified path. Optionally, free space allocated to
74126009Sdes	path before reinitializing it.
75126009Sdes*/
7692559Sdesstatic int
7776262Sgreenexpand_tilde (char **path, void (*free) (char *p))
7899315Sdes{
7995456Sdes	int rc = 0;
8057429Smarkm	char buffer [PATH_MAX];
8192559Sdes	char *tailp;
8298684Sdes	if ((tailp = strchr (*path + 1, '/')) != NULL)
8357429Smarkm	{
8492559Sdes		struct passwd *pwd;
85126277Sdes		*tailp++ = '\0';
8657429Smarkm		if (*(*path + 1) == '\0')
87124211Sdes			strcpy (buffer, getlogin ());
88124211Sdes		else
89126277Sdes			strcpy (buffer, *path + 1);
9057429Smarkm		if ((pwd = getpwnam (buffer)) != NULL)
91162856Sdes		{
92262566Sdes			strcpy (buffer, pwd->pw_dir);
93162856Sdes			strcat (buffer, "/");
94162856Sdes			strcat (buffer, tailp);
95162856Sdes			if (free)
96162856Sdes				free (*path);
97162856Sdes			*path = strdup (buffer);
98162856Sdes			rc++;
99162856Sdes		}
100127033Sdes		return rc;
10192559Sdes	}
102181111Sdes}
103124211Sdes
104124211Sdesstatic
10599051Sdesgetremcap(host)
10692559Sdes	register char *host;
10792559Sdes{
108262566Sdes	register char **p, ***q;
10992559Sdes	char *bp;
11092559Sdes	char *rempath;
111126277Sdes	int   stat;
11257429Smarkm
113262566Sdes	rempath = getenv("REMOTE");
114106130Sdes	if (rempath != NULL)
115149753Sdes		if (*rempath != '/')
116124211Sdes			/* we have an entry */
117124211Sdes			cgetset(rempath);
118124211Sdes		else {	/* we have a path */
119124211Sdes			db_array[1] = rempath;
120248619Sdes			db_array[2] = _PATH_REMOTE;
121157019Sdes		}
122181111Sdes
123264692Sdes	if ((stat = cgetent(&bp, db_array, host)) < 0) {
12465674Skris		if (DV ||
12592559Sdes		    host[0] == '/' && access(DV = host, R_OK | W_OK) == 0) {
126181111Sdes			CU = DV;
12776262Sgreen			HO = host;
12892559Sdes			HW = 1;
12976262Sgreen			DU = 0;
130162856Sdes			if (!BR)
131224638Sbrooks				BR = DEFBR;
132224638Sbrooks			FS = DEFFS;
133224638Sbrooks			return;
134224638Sbrooks		}
135224638Sbrooks		switch(stat) {
136224638Sbrooks		case -1:
137224638Sbrooks			fprintf(stderr, "tip: unknown host %s\n", host);
138224638Sbrooks			break;
139224638Sbrooks		case -2:
140224638Sbrooks			fprintf(stderr,
141224638Sbrooks			    "tip: can't open host description file\n");
142224638Sbrooks			break;
143162856Sdes		case -3:
144162856Sdes			fprintf(stderr,
145162856Sdes			    "tip: possible reference loop in host description file\n");
146162856Sdes			break;
147262566Sdes		}
148162856Sdes		exit(3);
149	}
150
151	for (p = capstrings, q = caps; *p != NULL; p++, q++)
152		if (**q == NULL)
153			cgetstr(bp, *p, *q);
154	if (!BR && (cgetnum(bp, "br", &BR) == -1))
155		BR = DEFBR;
156	if (cgetnum(bp, "fs", &FS) == -1)
157		FS = DEFFS;
158	if (DU < 0)
159		DU = 0;
160	else
161		DU = cgetflag("du");
162	if (DV == NOSTR) {
163		fprintf(stderr, "%s: missing device spec\n", host);
164		exit(3);
165	}
166	if (DU && CU == NOSTR)
167		CU = DV;
168	if (DU && PN == NOSTR) {
169		fprintf(stderr, "%s: missing phone number\n", host);
170		exit(3);
171	}
172
173	HD = cgetflag("hd");
174
175	/*
176	 * This effectively eliminates the "hw" attribute
177	 *   from the description file
178	 */
179	if (!HW)
180		HW = (CU == NOSTR) || (DU && equal(DV, CU));
181	HO = host;
182
183	/*
184		If login script, verify access
185	*/
186	if (LI != NOSTR) {
187		if (*LI == '~')
188			(void) expand_tilde (&LI, NULL);
189		if (access (LI, F_OK | X_OK) != 0) {
190			printf("tip (warning): can't open login script \"%s\"\n", LI);
191			LI = NOSTR;
192		}
193	}
194
195	/*
196		If logout script, verify access
197	*/
198	if (LO != NOSTR) {
199		if (*LO == '~')
200			(void) expand_tilde (&LO, NULL);
201		if (access (LO, F_OK | X_OK) != 0) {
202			printf("tip (warning): can't open logout script \"%s\"\n", LO);
203			LO = NOSTR;
204		}
205	}
206
207	/*
208	 * see if uppercase mode should be turned on initially
209	 */
210	if (cgetflag("ra"))
211		boolean(value(RAISE)) = 1;
212	if (cgetflag("ec"))
213		boolean(value(ECHOCHECK)) = 1;
214	if (cgetflag("be"))
215		boolean(value(BEAUTIFY)) = 1;
216	if (cgetflag("nb"))
217		boolean(value(BEAUTIFY)) = 0;
218	if (cgetflag("sc"))
219		boolean(value(SCRIPT)) = 1;
220	if (cgetflag("tb"))
221		boolean(value(TABEXPAND)) = 1;
222	if (cgetflag("vb"))
223		boolean(value(VERBOSE)) = 1;
224	if (cgetflag("nv"))
225		boolean(value(VERBOSE)) = 0;
226	if (cgetflag("ta"))
227		boolean(value(TAND)) = 1;
228	if (cgetflag("nt"))
229		boolean(value(TAND)) = 0;
230	if (cgetflag("rw"))
231		boolean(value(RAWFTP)) = 1;
232	if (cgetflag("hd"))
233		boolean(value(HALFDUPLEX)) = 1;
234	if (RE == NOSTR)
235		RE = (char *)"tip.record";
236	if (EX == NOSTR)
237		EX = (char *)"\t\n\b\f";
238	if (ES != NOSTR)
239		vstring("es", ES);
240	if (FO != NOSTR)
241		vstring("fo", FO);
242	if (PR != NOSTR)
243		vstring("pr", PR);
244	if (RC != NOSTR)
245		vstring("rc", RC);
246	if (cgetnum(bp, "dl", &DL) == -1)
247		DL = 0;
248	if (cgetnum(bp, "cl", &CL) == -1)
249		CL = 0;
250	if (cgetnum(bp, "et", &ET) == -1)
251		ET = 10;
252}
253
254char *
255getremote(host)
256	char *host;
257{
258	register char *cp;
259	static char *next;
260	static int lookedup = 0;
261
262	if (!lookedup) {
263		if (host == NOSTR && (host = getenv("HOST")) == NOSTR) {
264			fprintf(stderr, "tip: no host specified\n");
265			exit(3);
266		}
267		getremcap(host);
268		next = DV;
269		lookedup++;
270	}
271	/*
272	 * We return a new device each time we're called (to allow
273	 *   a rotary action to be simulated)
274	 */
275	if (next == NOSTR)
276		return (NOSTR);
277	if ((cp = index(next, ',')) == NULL) {
278		DV = next;
279		next = NOSTR;
280	} else {
281		*cp++ = '\0';
282		DV = next;
283		next = cp;
284	}
285	return (DV);
286}
287