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.
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.
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]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
35 #if defined(BSD4_2) || defined(ATTSVR4)
37 #include <netinet/in.h>
38 #include <sys/socket.h>
41 #include "UNET/unetio.h"
47 EXTERN
void alarmtr();
50 EXTERN
int interface();
51 EXTERN
int fd_mklock(), fd_cklock(), chat(), getdialline();
52 EXTERN
void fixline(), fd_rmlock();
53 static void translate();
56 EXTERN
unsigned connecttime
;
57 EXTERN
int (*Setup
)();
60 * to add a new caller:
61 * declare the function that knows how to call on the device,
62 * add a line to the callers table giving the name of the device
63 * (from Devices file) and the name of the function
64 * add the function to the end of this file
93 static struct caller Caller
[] = {
101 {"Dialout", Dialout
}, /* ditto but using dialout(III) */
105 #if defined(BSD4_2) || defined(ATTSVR4)
106 {"TCP", tcpcall
}, /* 4.2BSD sockets */
109 {"TCP", unetcall
}, /* 3com implementation of tcp */
110 {"Unetserver", unetcall
},
112 #endif /* BSD4_2 || ATTSVR4 */
116 {"DK", dkcall
}, /* standard AT&T DATAKIT VCS caller */
120 {"Sytek", sytcall
}, /* untested but should work */
124 {"TLI", tlicall
}, /* AT&T Transport Layer Interface */
126 {"TLIS", tlicall
}, /* AT&T Transport Layer Interface */
130 {NULL
, NULL
} /* this line must be last */
134 * exphone - expand phone number for given prefix and number
144 char pre
[MAXPH
], npart
[MAXPH
], tpre
[MAXPH
], p
[MAXPH
];
149 (void) strcpy(out
, in
);
158 while (*in
!= NULLCHAR
)
163 fn
= fopen(DIALCODES
, "r");
165 while (fgets(buf
, BUFSIZ
, fn
)) {
166 if ( sscanf(buf
, "%s%s", p
, tpre
) < 1)
175 (void) strcpy(out
, tpre
);
176 (void) strcat(out
, npart
);
181 * repphone - Replace \D and \T sequences in arg with phone
182 * expanding and translating as appropriate.
185 repphone(arg
, phone
, trstr
)
186 char *arg
, *phone
, *trstr
;
188 static char pbuf
[2*(MAXPH
+2)];
191 for (tp
=pbuf
; *arg
; arg
++) {
199 translate(trstr
, tp
);
205 for(fp
=phone
; *tp
= *fp
++; tp
++)
219 static u_int saved_mode
;
220 static char saved_dcname
[20];
223 * processdev - Process a line from the Devices file
226 * file descriptor - succeeded
230 processdev(flds
, dev
)
231 char *flds
[], *dev
[];
235 char *args
[D_MAX
+1], dcname
[20];
237 EXTERN
int pop_push();
238 EXTERN
void setdevcfg();
240 char *phonecl
; /* clear phone string */
241 char phoneex
[2*(MAXPH
+2)]; /* expanded phone string */
242 EXTERN
void ttygenbrk();
243 struct termio tty_orig
;
247 /* set up default "break" routine */
250 /* initialize Devconfig info */
251 DEBUG(5, "processdev: calling setdevcfg(%s, ", Progname
);
252 DEBUG(5, "%s)\n", flds
[F_TYPE
]);
253 setdevcfg(Progname
, flds
[F_TYPE
]);
255 for (ca
= Caller
; ca
->CA_type
!= NULL
; ca
++) {
256 /* This will find built-in caller functions */
257 if (EQUALS(ca
->CA_type
, dev
[D_CALLER
])) {
258 DEBUG(5, "Internal caller type %s\n", dev
[D_CALLER
]);
259 if (dev
[D_ARG
] == NULL
) {
260 /* if NULL - assume translate */
261 dev
[D_ARG
+1] = NULL
; /* needed for for loop later to mark the end */
264 dev
[D_ARG
] = repphone(dev
[D_ARG
], flds
[F_PHONE
], "");
265 if ((dcf
= (*(ca
->CA_caller
))(flds
, dev
)) < 0)
267 if ( interface( ca
->CA_type
) ) {
268 DEBUG(5, "interface(%s) failed", ca
->CA_type
);
269 Uerror
= SS_DEVICE_FAILED
;
270 /* restore vanilla unix interface */
271 (void)interface("UNIX");
274 dev
+= 2; /* Skip to next CALLER and ARG */
279 /* Here if not a built-in caller function */
281 /* We do locking (file and advisory) after open */
286 if ( *dev
[D_LINE
] != '/' ) {
287 (void) sprintf(dcname
, "/dev/%s", dev
[D_LINE
]);
289 (void) strcpy(dcname
, dev
[D_LINE
] );
291 /* take care of the possible partial open fd */
292 (void) close(nullfd
= open("/", O_RDONLY
));
294 (void) close(nullfd
);
295 DEBUG(1, "generic open timeout\n%s", "");
296 logent("generic open", "TIMEOUT");
297 Uerror
= SS_CANT_ACCESS_DEVICE
;
300 (void) signal(SIGALRM
, alarmtr
);
303 DEBUG(7, "opening with O_NDELAY set\n%s", "");
304 dcf
= open(dcname
, (O_RDWR
| O_NDELAY
) );
305 saved_mode
= O_RDWR
| O_NDELAY
;
307 dcf
= open(dcname
, O_RDWR
);
310 strcpy(saved_dcname
, dcname
);
313 DEBUG(1, "generic open failed, errno = %d\n", errno
);
314 (void) close(nullfd
);
315 logent("generic open", "FAILED");
316 Uerror
= SS_CANT_ACCESS_DEVICE
;
320 /* check locks BEFORE modifying the stream */
322 if ( fd_mklock(dcf
) != SUCCESS
) {
323 DEBUG(1, "failed to lock device %s\n", dcname
);
324 Uerror
= SS_LOCKED_DEVICE
;
329 DEBUG(7, "clear O_NDELAY\n%s", "");
330 if ( fcntl(dcf
, F_SETFL
,
331 (fcntl(dcf
, F_GETFL
, 0) & ~O_NDELAY
)) < 0 ) {
332 DEBUG( 7, "clear O_NDELAY failed, errno %d\n", errno
);
333 Uerror
= SS_DEVICE_FAILED
;
339 if ( (*Setup
)( MASTER
, &dcf
, &dcf
) ) {
340 /* any device|system lock files we should remove? */
341 DEBUG(5, "MASTER Setup failed%s", "");
342 Uerror
= SS_DEVICE_FAILED
;
346 /* configure any requested streams modules */
347 if ( !pop_push(dcf
) ) {
348 DEBUG(5, "STREAMS module configuration failed%s\n","");
349 Uerror
= SS_DEVICE_FAILED
;
353 /* save initial state of line in case script fails */
354 ret_orig
= ioctl(dcf
, TCGETA
, &tty_orig
);
356 /* use sdev[] since dev[] is incremented for internal callers */
357 fixline(dcf
, atoi(fdig(sdev
[D_CLASS
])), D_DIRECT
);
360 * Now loop through the remaining callers and chat
361 * according to scripts in dialers file.
363 for (; dev
[D_CALLER
] != NULL
; dev
+= 2) {
366 * Scan Dialers file to find an entry
368 if ((w
= gdial(dev
[D_CALLER
], args
, D_MAX
)) < 1) {
369 logent("generic call to gdial", "FAILED");
370 Uerror
= SS_CANT_ACCESS_DEVICE
;
373 if (w
<= 2) /* do nothing - no chat */
376 * Translate the phone number
378 if (dev
[D_ARG
] == NULL
) {
379 /* if NULL - assume no translation */
380 dev
[D_ARG
+1] = NULL
; /* needed for for loop to mark the end */
384 phonecl
= repphone(dev
[D_ARG
], flds
[F_PHONE
], args
[1]);
385 exphone(phonecl
, phoneex
);
386 translate(args
[1], phoneex
);
390 if (chat(w
-2, &args
[2], dcf
, phonecl
, phoneex
) != SUCCESS
) {
391 CDEBUG(5, "\nCHAT gdial(%s) FAILED\n", dev
[D_CALLER
]);
392 Uerror
= SS_CHAT_FAILED
;
399 strcpy(Dc
, sdev
[D_LINE
]);
403 /* reset line settings if we got them in the beginning */
405 (void) ioctl(dcf
, TCSETAW
, &tty_orig
);
409 /* restore vanilla unix interface */
410 (void)interface("UNIX");
415 * clear_hup() clear the hangup state of the given device
422 if ((ndcf
= open(saved_dcname
, saved_mode
)) < 0) {
433 * translate the pairs of characters present in the first
434 * string whenever the first of the pair appears in the second
443 for(;*ttab
&& *(ttab
+1); ttab
+= 2)
452 * Get the information about the dialer.
453 * gdial(type, arps, narps)
454 * type -> type of dialer (e.g., penril)
455 * arps -> array of pointers returned by gdial
456 * narps -> number of elements in array returned by gdial
458 * -1 -> Can't open DIALERFILE
459 * 0 -> requested type not found
460 * >0 -> success - number of fields filled in
463 gdial(type
, arps
, narps
)
467 static char info
[MAXLINE
];
469 EXTERN
void dialreset();
470 EXTERN
char * currdial();
472 DEBUG(2, "gdial(%s) called\n", type
);
473 while (getdialline(info
, sizeof(info
))) {
474 if ((info
[0] == '#') || (info
[0] == ' ') ||
475 (info
[0] == '\t') || (info
[0] == '\n'))
477 if ((na
= getargs(info
, arps
, narps
)) == 0)
479 if (EQUALS(arps
[0], type
)) {
480 DEBUG(5, "Trying caller script '%s'", type
);
481 DEBUG(5, " from '%s'.\n", currdial());
487 DEBUG(1, "%s not found in Dialers file\n", type
);
496 * dkcall(flds, dev) make a DATAKIT VCS connection
497 * DATAKIT VCS is a trademark of AT&T
500 * >0 - file number - ok
510 char *flds
[], *dev
[];
518 EXTERN
void dkbreak();
520 strcpy(dialstring
, dev
[D_ARG
]);
521 DEBUG(4, "dkcall(%s)\n", dialstring
);
526 Uerror
= SS_DIAL_FAILED
;
530 (void) signal(SIGALRM
, alarmtr
);
531 (void) alarm(connecttime
);
532 DEBUG(4, "tdkdial(%s", flds
[F_PHONE
]);
533 DEBUG(4, ", %d)\n", atoi(dev
[D_CLASS
]));
534 if ((fd
= tdkdial(flds
[F_PHONE
], atoi(dev
[D_CLASS
]))) >= 0)
535 if (dkproto(fd
, cdkp_ld
) < 0)
542 fd
= dkdial(dialstring
);
545 (void) strcpy(Dc
, "DK");
547 Uerror
= SS_DIAL_FAILED
;
561 * tcpcall(flds, dev) make ethernet/socket connection
564 * >0 - file number - ok
568 #if !(defined(BSD4_2) || defined(ATTSVR4))
572 char *flds
[], *dev
[];
574 Uerror
= SS_NO_DEVICE
;
581 char *flds
[], *dev
[];
587 struct sockaddr_in sin
;
589 if (EQUALS(flds
[F_CLASS
], "-")) {
591 * Use standard UUCP port number.
593 sp
= getservbyname("uucp", "tcp");
595 ASSERT(sp
!= NULL
, "No uucp service number", 0, 0);
599 * Systems file specifies a port number.
601 sp
= getservbyname(flds
[F_CLASS
], "tcp");
604 port
= htons(atoi(flds
[F_CLASS
]));
606 logent("tcpopen", "unknown port number");
607 Uerror
= SS_NO_DEVICE
;
613 if (EQUALS(flds
[F_PHONE
], "-")) {
615 * Use UUCP name as host name.
617 hp
= gethostbyname(flds
[F_NAME
]);
620 * Systems file specifies a host name different from the UUCP
623 hp
= gethostbyname(flds
[F_PHONE
]);
627 logent("tcpopen", "no such host");
628 Uerror
= SS_NO_DEVICE
;
631 DEBUG(4, "tcpdial host %s, ", hp
->h_name
);
632 DEBUG(4, "port %d\n", ntohs(port
));
634 ret
= socket(AF_INET
, SOCK_STREAM
, 0);
636 DEBUG(5, "no socket: %s\n", strerror(errno
));
637 logent("no socket", strerror(errno
));
638 Uerror
= SS_NO_DEVICE
;
641 sin
.sin_family
= hp
->h_addrtype
;
643 bcopy(hp
->h_addr
, (caddr_t
)&sin
.sin_addr
, hp
->h_length
);
645 memcpy((caddr_t
)&sin
.sin_addr
, hp
->h_addr
, hp
->h_length
);
649 DEBUG(4, "timeout tcpopen\n%s", "");
650 logent("tcpopen", "TIMEOUT");
651 Uerror
= SS_NO_DEVICE
;
654 (void) signal(SIGALRM
, alarmtr
);
655 (void) alarm(connecttime
);
656 DEBUG(7, "family: %d\n", sin
.sin_family
);
657 DEBUG(7, "port: %d\n", sin
.sin_port
);
658 DEBUG(7, "addr: %08x\n",*((int *) &sin
.sin_addr
));
659 if (connect(ret
, (struct sockaddr
*)&sin
, sizeof (sin
)) < 0) {
662 DEBUG(5, "connect failed: %s\n", strerror(errno
));
663 logent("connect failed", strerror(errno
));
664 Uerror
= SS_NO_DEVICE
;
667 (void) signal(SIGPIPE
, SIG_IGN
); /* watch out for broken ipc link...*/
669 (void) strcpy(Dc
, "IPC");
676 * unetcall(flds, dev) make ethernet connection
679 * >0 - file number - ok
687 char *flds
[], *dev
[];
689 Uerror
= SS_NO_DEVICE
;
695 char *flds
[], *dev
[];
700 port
= atoi(dev
[D_ARG
]);
701 DEBUG(4, "unetdial host %s, ", flds
[F_PHONE
]);
702 DEBUG(4, "port %d\n", port
);
703 (void) alarm(connecttime
);
704 ret
= tcpopen(flds
[F_PHONE
], port
, 0, TO_ACTIVE
, "rw");
708 DEBUG(5, "tcpopen failed: errno %d\n", errno
);
709 Uerror
= SS_DIAL_FAILED
;
712 (void) strcpy(Dc
, "UNET");
722 * sytcall(flds, dev) make a sytek connection
725 * >0 - file number - ok
732 char *flds
[], *dev
[];
734 int dcr
, dcr2
, nullfd
, ret
;
735 char dcname
[20], command
[BUFSIZ
];
737 (void) sprintf(dcname
, "/dev/%s", dev
[D_LINE
]);
738 DEBUG(4, "dc - %s, ", dcname
);
739 dcr
= open(dcname
, O_WRONLY
|O_NDELAY
);
741 Uerror
= SS_DIAL_FAILED
;
742 DEBUG(4, "OPEN FAILED %s\n", dcname
);
745 if ( fd_mklock(dcr
) != SUCCESS
) {
747 DEBUG(1, "failed to lock device %s\n", dcname
);
748 Uerror
= SS_LOCKED_DEVICE
;
752 sytfixline(dcr
, atoi(fdig(dev
[D_CLASS
])), D_DIRECT
);
754 DEBUG(4, "Calling Sytek unit %s\n", dev
[D_ARG
]);
755 (void) sprintf(command
,"\r\rcall %s\r", dev
[D_ARG
]);
756 ret
= (*Write
)(dcr
, command
, strlen(command
));
758 DEBUG(4, "COM1 return = %d\n", ret
);
760 (void) close(nullfd
= open("/", O_RDONLY
));
761 (void) signal(SIGALRM
, alarmtr
);
763 DEBUG(4, "timeout sytek open\n%s", "");
764 (void) close(nullfd
);
768 Uerror
= SS_DIAL_FAILED
;
772 dcr2
= open(dcname
,O_RDWR
);
777 DEBUG(4, "OPEN 2 FAILED %s\n", dcname
);
778 Uerror
= SS_DIAL_FAILED
;
779 (void) close(nullfd
); /* kernel might think dc2 is open */
782 if ( fd_mklock(dcr2
) != SUCCESS
) {
784 DEBUG(1, "failed to lock device %s\n", dcname
);
785 Uerror
= SS_LOCKED_DEVICE
;
795 * dial801(flds, dev) dial remote machine on 801/801
796 * char *flds[], *dev[];
799 * file descriptor - succeeded
802 * unfortunately, open801() is different for usg and non-usg
808 char *flds
[], *dev
[];
810 char dcname
[20], dnname
[20], phone
[MAXPH
+2];
813 (void) sprintf(dnname
, "/dev/%s", dev
[D_CALLDEV
]);
814 (void) sprintf(phone
, "%s%s", dev
[D_ARG
] , ACULAST
);
815 (void) sprintf(dcname
, "/dev/%s", dev
[D_LINE
]);
816 CDEBUG(1, "Use Port %s, ", dcname
);
817 DEBUG(4, "acu - %s, ", dnname
);
818 VERBOSE("Trying modem - %s, ", dcname
); /* for cu */
819 VERBOSE("acu - %s, ", dnname
); /* for cu */
820 if(getuid()==0 || GRPCHK(getgid())) {
821 CDEBUG(1, "Phone Number %s\n", phone
);
822 /* In cu, only give out the phone number to trusted people. */
823 VERBOSE("calling %s: ", phone
); /* for cu */
825 speed
= atoi(fdig(dev
[D_CLASS
]));
826 dcf
= open801(dcname
, dnname
, phone
, speed
);
828 if ( fd_mklock(dcf
) != SUCCESS
) {
830 DEBUG(5, "fd_mklock line %s failed\n", dev
[D_LINE
]);
831 Uerror
= SS_LOCKED_DEVICE
;
834 fixline(dcf
, speed
, D_ACU
);
835 (void) strcpy(Dc
, dev
[D_LINE
]); /* for later unlock() */
836 VERBOSE("SUCCEEDED\n%s", "");
838 VERBOSE("FAILED\n%s", "");
847 open801(dcname
, dnname
, phone
, speed
)
848 char *dcname
, *dnname
, *phone
;
850 int nw
, lt
, dcf
= -1, nullfd
, dnf
= -1;
851 pid_t w_ret
, pid
= -1;
854 if ((dnf
= open(dnname
, O_WRONLY
)) < 0) {
855 DEBUG(5, "can't open %s\n", dnname
);
856 Uerror
= SS_CANT_ACCESS_DEVICE
;
859 DEBUG(5, "%s is open\n", dnname
);
861 (void) close(nullfd
= open("/dev/null", O_RDONLY
));/* partial open hack */
863 DEBUG(4, "timeout modem open\n%s", "");
864 (void) close(nullfd
);
867 logent("801 open", "TIMEOUT");
872 Uerror
= SS_DIAL_FAILED
;
875 (void) signal(SIGALRM
, alarmtr
);
876 timelim
= 5 * strlen(phone
);
877 (void) alarm(timelim
< connecttime
? connecttime
: timelim
);
878 if ((pid
= fork()) == 0) {
880 nw
= (*Write
)(dnf
, phone
, lt
= strlen(phone
));
882 DEBUG(4, "ACU write error %d\n", errno
);
883 logent("ACU write", "FAILED");
886 DEBUG(4, "ACU write ok\n%s", "");
889 /* open line - will return on carrier */
890 dcf
= open(dcname
, O_RDWR
);
892 DEBUG(4, "dcf is %d\n", dcf
);
893 if (dcf
< 0) { /* handle like a timeout */
899 while ((w_ret
= wait(<
)) != pid
)
900 if (w_ret
== -1 && errno
!= EINTR
) {
901 DEBUG(4, "Wait failed errno=%d\n", errno
);
904 Uerror
= SS_DIAL_FAILED
;
909 (void) close(dnf
); /* no reason to keep the 801 open */
911 DEBUG(4, "Fork Stat %o\n", lt
);
913 Uerror
= SS_DIAL_FAILED
;
922 open801(dcname
, dnname
, phone
, speed
)
923 char *dcname
, *dnname
, *phone
;
925 int nw
, lt
, dcf
= -1, nullfd
, dnf
= -1, ret
;
928 (void) close(nullfd
= open("/", O_RDONLY
)); /* partial open hack */
930 DEBUG(4, "DN write %s\n", "timeout");
933 (void) close(nullfd
);
934 Uerror
= SS_DIAL_FAILED
;
937 (void) signal(SIGALRM
, alarmtr
);
938 timelim
= 5 * strlen(phone
);
939 (void) alarm(timelim
< connecttime
? connecttime
: timelim
);
941 if ((dnf
= open(dnname
, O_WRONLY
)) < 0 ) {
942 DEBUG(5, "can't open %s\n", dnname
);
943 Uerror
= SS_CANT_ACCESS_DEVICE
;
946 DEBUG(5, "%s is open\n", dnname
);
947 if ( fd_mklock(dnf
) != SUCCESS
) {
949 DEBUG(1, "failed to lock device %s\n", dnname
);
950 Uerror
= SS_LOCKED_DEVICE
;
952 if ( (dcf
= open(dcname
, O_RDWR
| O_NDELAY
)) < 0 ) {
953 DEBUG(5, "can't open %s\n", dcname
);
954 Uerror
= SS_CANT_ACCESS_DEVICE
;
957 if ( fd_mklock(dcf
) != SUCCESS
) {
959 DEBUG(1, "failed to lock device %s\n", dcname
);
960 Uerror
= SS_LOCKED_DEVICE
;
964 DEBUG(4, "dcf is %d\n", dcf
);
965 fixline(dcf
, speed
, D_ACU
);
966 nw
= (*Write
)(dnf
, phone
, lt
= strlen(phone
));
969 DEBUG(4, "ACU write error %d\n", errno
);
972 Uerror
= SS_DIAL_FAILED
;
975 DEBUG(4, "ACU write ok\n%s", "");
978 (void) close(nullfd
= open("/", O_RDONLY
)); /* partial open hack */
979 ret
= open(dcname
, O_RDWR
); /* wait for carrier */
981 (void) close(ret
); /* close 2nd modem open() */
982 if (ret
< 0) { /* open() interrupted by alarm */
983 DEBUG(4, "Line open %s\n", "failed");
984 Uerror
= SS_DIAL_FAILED
;
985 (void) close(nullfd
); /* close partially opened modem */
988 (void) fcntl(dcf
,F_SETFL
, fcntl(dcf
, F_GETFL
, 0) & ~O_NDELAY
);
1001 char phone
[MAXPH
+2];
1003 exphone(flds
[F_PHONE
], phone
);
1005 DEBUG(4, "call dialout(%s", phone
);
1006 DEBUG(4, ", %s)\n", dev
[D_CLASS
]);
1007 fd
= dialout(phone
, dev
[D_CLASS
]);
1009 Uerror
= SS_NO_DEVICE
;
1011 Uerror
= SS_DIAL_FAILED
;
1013 Uerror
= SS_DEVICE_FAILED
;
1015 (void) strcpy(Dc
, "Dialout");
1024 * AT&T Transport Layer Interface
1026 * expected in Devices
1029 * TLIS line1 - - TLIS
1033 #include <sys/tiuser.h>
1035 EXTERN
void tfaillog();
1038 int t_bind(), t_close(), t_connect(), t_free(), t_look(), t_open(), t_rcvdis();
1040 #define CONNECT_ATTEMPTS 3
1041 #define TFREE(p, type) if ((p)) t_free((char *)(p), (type))
1044 * returns fd to remote uucp daemon
1052 char addrbuf
[ BUFSIZ
];
1053 char devname
[MAXNAMESIZE
];
1056 struct t_bind
*bind_ret
= 0;
1057 struct t_info tinfo
;
1058 struct t_call
*sndcall
= 0, *rcvcall
= 0;
1061 EXTERN
struct netbuf
*stoa();
1063 if ( dev
[D_LINE
][0] != '/' ) {
1064 /* dev holds device name relative to /dev */
1065 sprintf(devname
, "/dev/%s", dev
[D_LINE
]);
1067 /* dev holds full path name of device */
1068 strcpy(devname
, dev
[D_LINE
]);
1070 /* gimme local transport endpoint */
1071 errno
= t_errno
= 0;
1072 if (setjmp(Sjbuf
)) {
1073 DEBUG(1, "t_open timeout\n%s", "");
1074 logent("t_open", "TIMEOUT");
1075 Uerror
= SS_NO_DEVICE
;
1078 (void) signal(SIGALRM
, alarmtr
);
1080 fd
= t_open(devname
, O_RDWR
, &tinfo
);
1083 tfaillog(fd
, "t_open" );
1084 Uerror
= SS_NO_DEVICE
;
1087 if ( fd_mklock(fd
) != SUCCESS
) {
1089 DEBUG(1, "tlicall: failed to lock device %s\n", devname
);
1090 Uerror
= SS_LOCKED_DEVICE
;
1094 /* allocate tli structures */
1095 errno
= t_errno
= 0;
1096 if ( (bind_ret
= (struct t_bind
*)t_alloc(fd
, T_BIND
, T_ALL
)) ==
1097 (struct t_bind
*)NULL
1098 || (sndcall
= (struct t_call
*)t_alloc(fd
, T_CALL
, T_ALL
)) ==
1099 (struct t_call
*)NULL
1100 || (rcvcall
= (struct t_call
*)t_alloc(fd
, T_CALL
, T_ALL
)) ==
1101 (struct t_call
*)NULL
) {
1102 tfaillog(fd
, "t_alloc" );
1103 TFREE(bind_ret
, T_BIND
);TFREE(sndcall
, T_CALL
);
1104 TFREE(rcvcall
, T_CALL
);
1105 Uerror
= SS_NO_DEVICE
;
1110 errno
= t_errno
= 0;
1111 if (t_bind(fd
, (struct t_bind
*) 0, bind_ret
) < 0) {
1112 tfaillog(fd
, "t_bind" );
1113 TFREE(bind_ret
, T_BIND
);TFREE(sndcall
, T_CALL
);
1114 TFREE(rcvcall
, T_CALL
);
1115 Uerror
= SS_NO_DEVICE
;
1120 DEBUG(5, "tlicall: bound to %s\n", bind_ret
->addr
.buf
);
1123 * Prepare to connect.
1125 * If address begins with "\x", "\X", "\o", or "\O",
1126 * assume is hexadecimal or octal address and use stoa()
1129 * Else is usual uucico address -- only \N's left to process.
1130 * Walk thru connection address, changing \N's to NULLCHARs.
1131 * Note: If a NULLCHAR must be part of the connection address,
1132 * it must be overtly included in the address. One recommended
1133 * way is to do it in the Devices file, thusly:
1134 * Netname /dev/netport - - TLI \D\000
1135 * bsfix() turns \000 into \N and then the loop below makes it a
1136 * real, included-in-the-length null-byte.
1138 * The DEBUG must print the strecpy'd address (so that
1139 * non-printables will have been replaced with C escapes).
1142 DEBUG(5, "t_connect to addr \"%s\"\n",
1143 strecpy( addrbuf
, dev
[D_ARG
], "\\" ) );
1145 if ( dev
[D_ARG
][0] == '\\' &&
1146 ( dev
[D_ARG
][1] == 'x' || dev
[D_ARG
][1] == 'X'
1147 || dev
[D_ARG
][1] == 'o' || dev
[D_ARG
][1] == 'O' ) ) {
1148 if ( stoa(dev
[D_ARG
], &(sndcall
->addr
)) == (struct netbuf
*)NULL
) {
1149 DEBUG(5, "tlicall: stoa failed\n%s", "");
1150 logent("tlicall", "string-to-address failed");
1151 TFREE(bind_ret
, T_BIND
);TFREE(sndcall
, T_CALL
);
1152 TFREE(rcvcall
, T_CALL
);
1153 Uerror
= SS_NO_DEVICE
;
1159 for( i
= j
= 0; i
< BUFSIZ
&& dev
[D_ARG
][i
] != NULLCHAR
;
1161 if( dev
[D_ARG
][i
] == '\\' && dev
[D_ARG
][i
+1] == 'N' ) {
1162 addrbuf
[j
] = NULLCHAR
;
1166 addrbuf
[j
] = dev
[D_ARG
][i
];
1169 sndcall
->addr
.buf
= addrbuf
;
1170 sndcall
->addr
.len
= j
;
1173 if (setjmp(Sjbuf
)) {
1174 DEBUG(4, "timeout tlicall\n%s", "");
1175 logent("tlicall", "TIMEOUT");
1176 TFREE(bind_ret
, T_BIND
);TFREE(sndcall
, T_CALL
);
1177 TFREE(rcvcall
, T_CALL
);
1178 Uerror
= SS_NO_DEVICE
;
1183 (void) signal(SIGALRM
, alarmtr
);
1184 (void) alarm(connecttime
);
1186 /* connect to the service -- some listeners can't handle */
1187 /* multiple connect requests, so try it a few times */
1188 errno
= t_errno
= 0;
1189 for ( i
= 0; i
< CONNECT_ATTEMPTS
; ++i
) {
1190 if (t_connect(fd
, sndcall
, rcvcall
) == 0)
1192 if ( (t_errno
== TLOOK
) && (t_look(fd
) == T_DISCONNECT
)) {
1197 tfaillog(fd
, "t_connect");
1198 TFREE(bind_ret
, T_BIND
);TFREE(sndcall
, T_CALL
);
1199 TFREE(rcvcall
, T_CALL
);
1200 Uerror
= SS_DIAL_FAILED
;
1207 TFREE(bind_ret
, T_BIND
);TFREE(sndcall
, T_CALL
);
1208 TFREE(rcvcall
, T_CALL
);
1209 if ( i
== CONNECT_ATTEMPTS
) {
1210 tfaillog(fd
, "t_connect");
1211 Uerror
= SS_DIAL_FAILED
;
1216 errno
= t_errno
= 0;
1217 (void) strcpy(Dc
, dev
[D_CALLER
]);