Home | History | Annotate | Download | only in bnu
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 
     22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
     23  *	  All Rights Reserved
     24  *
     25  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     26  * Use is subject to license terms.
     27  */
     28 
     29 #pragma ident	"%Z%%M%	%I%	%E% SMI"	/* from SVR4 bnu:dial.c 1.3 */
     30 
     31 /*LINTLIBRARY*/
     32 /***************************************************************
     33  *      dial() returns an fd for an open tty-line connected to the
     34  *      specified remote.  The caller should trap all ways to
     35  *      terminate, and call undial(). This will release the `lock'
     36  *      file and return the outgoing line to the system.  This routine
     37  *      would prefer that the calling routine not use the `alarm()'
     38  *      system call, nor issue a `signal(SIGALRM, xxx)' call.
     39  *      If you must, then please save and restore the alarm times.
     40  *      The sleep() library routine is ok, though.
     41  *
     42  *	#include <sys/types.h>
     43  *	#include <sys/stat.h>
     44  *      #include "dial.h"
     45  *
     46  *      int dial(call);
     47  *      CALL call;
     48  *
     49  *      void undial(rlfd);
     50  *      int rlfd;
     51  *
     52  *      rlfd is the "remote-lne file descriptor" returned from dial.
     53  *
     54  *      The CALL structure as (defined in dial.h):
     55  *
     56  *      typedef struct {
     57  *              struct termio *attr;    ptr to term attribute structure
     58  *              int     baud;           no longer used --
     59  *					left in for backwards compatibility
     60  *              int     speed;          212A modem: low=300, high=1200
     61  *					negative for "Any" speed
     62  *              char    *line;          device name for out-going line
     63  *              char    *telno;         ptr to tel-no digit string
     64  *		int	modem		no longer used --
     65  *					left in for backwards compatibility
     66  *		char 	*device		no longer used --
     67  *					left in for backwards compatibility
     68  *		int	dev_len		no longer used --
     69  *					left in for backwards compatibility
     70  *      } CALL;
     71  *
     72  *      The error returns from dial are negative, in the range -1
     73  *      to -13, and their meanings are:
     74  *
     75  *              INTRPT   -1: interrupt occured
     76  *              D_HUNG   -2: dialer hung (no return from write)
     77  *              NO_ANS   -3: no answer (caller script failed)
     78  *              ILL_BD   -4: illegal baud-rate
     79  *              A_PROB   -5: acu problem (open() failure)
     80  *              L_PROB   -6: line problem (open() failure)
     81  *              NO_Ldv   -7: can't open Devices file
     82  *              DV_NT_A  -8: specified device not available
     83  *              DV_NT_K  -9: specified device not known
     84  *              NO_BD_A -10: no device available at requested baud-rate
     85  *              NO_BD_K -11: no device known at requested baud-rate
     86  *		DV_NT_E -12: requested speed does not match
     87  *		BAD_SYS -13: system not in Systems file
     88  *
     89  *      Setting attributes in the termio structure indicated in
     90  *      the `attr' field of the CALL structure before passing the
     91  *      structure to dial(), will cause those attributes to be set
     92  *      before the connection is made.  This can be important for
     93  *      some attributes such as parity and baud.
     94  *
     95  *      With an error return (negative value), there will not be
     96  *      any `lock-file' entry, so no need to call undial().
     97  ***************************************************************/
     98 
     99 #include <stdio.h>
    100 #include <stdlib.h>
    101 #include <string.h>
    102 #include <sys/types.h>
    103 #include <unistd.h>
    104 #include <setjmp.h>
    105 #include <sys/stat.h>
    106 #include <sys/times.h>
    107 #include <fcntl.h>
    108 
    109 #include "dial.h"
    110 
    111 #include "uucp.h"
    112 #include "uucpdefs.c"
    113 
    114 #include "callers.c"
    115 #include "conn.c"
    116 #include "getargs.c"
    117 #include "interface.c"
    118 #include "line.c"
    119 #include "stoa.c"
    120 #include "strsave.c"
    121 #include "sysfiles.c"
    122 #include "ulockf.c"
    123 
    124 #ifdef DATAKIT
    125 #include "dkbreak.c"
    126 #include "dkerr.c"
    127 #include "dkdial.c"
    128 #include "dkminor.c"
    129 #include "dtnamer.c"
    130 #endif
    131 
    132 static int
    133         rlfd;                   /* fd for remote comm line */
    134 
    135 GLOBAL jmp_buf Sjbuf;			/*needed by connection routines*/
    136 
    137 /*VARARGS*/
    138 /*ARGSUSED*/
    139 static void
    140 assert(s1,s2,i1,s3,i2)
    141 char *s1, *s2, *s3;
    142 int i1, i2;
    143 {}	/* for ASSERT in conn() */
    144 
    145 /*ARGSUSED*/
    146 static void
    147 logent(s1,s2)
    148 char *s1, *s2;
    149 {}	/* so we can load unlockf() */
    150 
    151 static void
    152 cleanup(Cn) 	/*this is executed only in the parent process*/
    153 int Cn;		/*fd for remote comm line */
    154 {
    155 	(void)restline();
    156 	(void)setuid(Euid);
    157 	if(Cn > 0) {
    158 		(void) close(Cn);
    159 	}
    160 
    161 
    162 	rmlock((char*) NULL);	/*uucp routine in ulockf.c*/
    163 	return;		/* code=negative for signal causing disconnect*/
    164 }
    165 
    166 int
    167 dial(call)
    168 CALL call;
    169 {
    170 char *alt[7];
    171 char speed[10];		/* character value of speed passed to dial */
    172 
    173 	/* set service so we know which Sysfiles entries to use, then	*/
    174 	/* be sure can access Devices file(s).  use "cu" entries ...	*/
    175 	/* dial is more like cu than like uucico.			*/
    176 	(void)strcpy(Progname,"cu");
    177 	setservice(Progname);
    178 	if ( sysaccess(EACCESS_DEVICES) != 0 ) {
    179 		/* can't read Devices file(s)	*/
    180 		return(NO_Ldv);
    181 	}
    182 
    183 	if (call.attr != NULL) {
    184 		if ( call.attr->c_cflag & PARENB ) {
    185 			Evenflag = ((call.attr->c_cflag & PARODD) ? 0 : 1);
    186 			Oddflag = ((call.attr->c_cflag & PARODD) ? 1 : 0);
    187 		}
    188 		line_8bit = (call.attr->c_cflag & CS8 ? 1 : 0);
    189 	}
    190 
    191 	if (call.speed <= 0)
    192 		strcpy(speed,"Any");
    193 	else
    194 		sprintf(speed,"%d",call.speed);
    195 
    196 	/* Determine whether contents of "telno" is a system name. */
    197 	if ( (call.telno != NULL) &&
    198 	     (strlen(call.telno) != strspn(call.telno,"0123456789=-*#")) ) {
    199 		/* use conn() for system names */
    200 		rlfd = conn(call.telno);
    201 	} else {
    202 		alt[F_NAME] = "dummy";	/* to replace the Systems file fields */
    203 		alt[F_TIME] = "Any";    /* needed for getto(); [F_TYPE] and */
    204 		alt[F_TYPE] = "";	/* [F_PHONE] assignment below       */
    205 		alt[F_CLASS] = speed;
    206 		alt[F_PHONE] = "";
    207 		alt[F_LOGIN] = "";
    208 		alt[6] = "";
    209 
    210 		if ( (call.telno != NULL) && (*call.telno != '\0') ) {
    211 			/* given a phone number, use an ACU */
    212 			alt[F_PHONE] = call.telno;
    213 			alt[F_TYPE] = "ACU";
    214 		} else {
    215 			/* otherwise, use a Direct connection */
    216 			alt[F_TYPE] = "Direct";
    217 			/* If device name starts with "/dev/", strip it off  */
    218 			/* since Devices file entries will also be stripped. */
    219 			if ( (call.line != NULL) &&
    220 				(strncmp(call.line, "/dev/", 5) == 0) )
    221 				Myline = (call.line + 5);
    222 			else
    223 				Myline = call.line;
    224 		}
    225 
    226 #ifdef forfutureuse
    227 		if (call->class != NULL)
    228 			alt[F_TYPE] = call->class;
    229 #endif
    230 
    231 
    232 		rlfd = getto(alt);
    233 	}
    234 	if (rlfd < 0)
    235 		switch (Uerror) {
    236 			case SS_NO_DEVICE:	return(NO_BD_A);
    237 			case SS_DIAL_FAILED:	return(D_HUNG);
    238 			case SS_LOCKED_DEVICE:	return(DV_NT_A);
    239 			case SS_BADSYSTEM:	return(BAD_SYS);
    240 			case SS_CANT_ACCESS_DEVICE:	return(L_PROB);
    241 			case SS_CHAT_FAILED:	return(NO_ANS);
    242 			default:	return(-Uerror);
    243 		}
    244 	(void)savline();
    245 	if ((call.attr) && ioctl(rlfd, TCSETA, call.attr) < 0) {
    246 		perror("stty for remote");
    247 		return(L_PROB);
    248 	}
    249 	Euid = geteuid();
    250 	if(setuid(getuid()) && setgid(getgid()) < 0)
    251 		undial(rlfd);
    252 	return(rlfd);
    253 }
    254 
    255 /*
    256 * undial(fd)
    257 */
    258 void
    259 undial(fd)
    260 int fd;
    261 {
    262 	sethup(fd);
    263 	sleep(2);
    264 	cleanup(fd);
    265 }
    266