#include "uucp.h"
#if defined(BSD4_2) || defined(ATTSVR4)
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#endif
#ifdef UNET
#include "UNET/unetio.h"
#include "UNET/tcp.h"
#endif
#include <libgen.h>
EXTERN void alarmtr();
EXTERN jmp_buf Sjbuf;
EXTERN char *fdig();
EXTERN int interface();
EXTERN int fd_mklock(), fd_cklock(), chat(), getdialline();
EXTERN void fixline(), fd_rmlock();
static void translate();
static int gdial();
EXTERN int Modemctrl;
EXTERN unsigned connecttime;
EXTERN int (*Setup)();
#ifdef DIAL801
EXTERN int dial801();
EXTERN int open801();
#endif
#ifdef DATAKIT
EXTERN int dkcall();
#endif
#ifdef V8
int Dialout();
#endif
#ifdef TCP
int unetcall();
int tcpcall();
#endif
#ifdef SYTEK
int sytcall();
#endif
#ifdef TLI
EXTERN int tlicall();
#endif
static struct caller Caller[] = {
#ifdef DIAL801
{"801", dial801},
{"212", dial801},
#endif
#ifdef V8
{"Dialout", Dialout},
#endif
#ifdef TCP
#if defined(BSD4_2) || defined(ATTSVR4)
{"TCP", tcpcall},
#else
#ifdef UNET
{"TCP", unetcall},
{"Unetserver", unetcall},
#endif
#endif
#endif
#ifdef DATAKIT
{"DK", dkcall},
#endif
#ifdef SYTEK
{"Sytek", sytcall},
#endif
#ifdef TLI
{"TLI", tlicall},
#ifdef TLIS
{"TLIS", tlicall},
#endif
#endif
{NULL, NULL}
};
static void
exphone(in, out)
char *in, *out;
{
FILE *fn;
char pre[MAXPH], npart[MAXPH], tpre[MAXPH], p[MAXPH];
char buf[BUFSIZ];
char *s1;
if (!isalpha(*in)) {
(void) strcpy(out, in);
return;
}
s1=pre;
while (isalpha(*in))
*s1++ = *in++;
*s1 = NULLCHAR;
s1 = npart;
while (*in != NULLCHAR)
*s1++ = *in++;
*s1 = NULLCHAR;
tpre[0] = NULLCHAR;
fn = fopen(DIALCODES, "r");
if (fn != NULL) {
while (fgets(buf, BUFSIZ, fn)) {
if ( sscanf(buf, "%s%s", p, tpre) < 1)
continue;
if (EQUALS(p, pre))
break;
tpre[0] = NULLCHAR;
}
fclose(fn);
}
(void) strcpy(out, tpre);
(void) strcat(out, npart);
return;
}
static char *
repphone(arg, phone, trstr)
char *arg, *phone, *trstr;
{
static char pbuf[2*(MAXPH+2)];
char *fp, *tp;
for (tp=pbuf; *arg; arg++) {
if (*arg != '\\') {
*tp++ = *arg;
continue;
} else {
switch (*(arg+1)) {
case 'T':
exphone(phone, tp);
translate(trstr, tp);
for(; *tp; tp++)
;
arg++;
break;
case 'D':
for(fp=phone; *tp = *fp++; tp++)
;
arg++;
break;
default:
*tp++ = *arg;
break;
}
}
}
*tp = '\0';
return(pbuf);
}
static u_int saved_mode;
static char saved_dcname[20];
GLOBAL int
processdev(flds, dev)
char *flds[], *dev[];
{
int dcf = -1;
struct caller *ca;
char *args[D_MAX+1], dcname[20];
char **sdev;
EXTERN int pop_push();
EXTERN void setdevcfg();
int nullfd;
char *phonecl;
char phoneex[2*(MAXPH+2)];
EXTERN void ttygenbrk();
struct termio tty_orig;
int ret_orig = -1;
sdev = dev;
genbrk = ttygenbrk;
DEBUG(5, "processdev: calling setdevcfg(%s, ", Progname);
DEBUG(5, "%s)\n", flds[F_TYPE]);
setdevcfg(Progname, flds[F_TYPE]);
for (ca = Caller; ca->CA_type != NULL; ca++) {
if (EQUALS(ca->CA_type, dev[D_CALLER])) {
DEBUG(5, "Internal caller type %s\n", dev[D_CALLER]);
if (dev[D_ARG] == NULL) {
dev[D_ARG+1] = NULL;
dev[D_ARG] = "\\T";
}
dev[D_ARG] = repphone(dev[D_ARG], flds[F_PHONE], "");
if ((dcf = (*(ca->CA_caller))(flds, dev)) < 0)
return(dcf) ;
if ( interface( ca->CA_type ) ) {
DEBUG(5, "interface(%s) failed", ca->CA_type);
Uerror = SS_DEVICE_FAILED;
(void)interface("UNIX");
return(FAIL);
}
dev += 2;
break;
}
}
if (dcf == -1) {
if ( *dev[D_LINE] != '/' ) {
(void) sprintf(dcname, "/dev/%s", dev[D_LINE]);
} else {
(void) strcpy(dcname, dev[D_LINE] );
}
(void) close(nullfd = open("/", O_RDONLY));
if (setjmp(Sjbuf)) {
(void) close(nullfd);
DEBUG(1, "generic open timeout\n%s", "");
logent("generic open", "TIMEOUT");
Uerror = SS_CANT_ACCESS_DEVICE;
goto bad;
}
(void) signal(SIGALRM, alarmtr);
(void) alarm(10);
if ( Modemctrl ) {
DEBUG(7, "opening with O_NDELAY set\n%s", "");
dcf = open(dcname, (O_RDWR | O_NDELAY) );
saved_mode = O_RDWR | O_NDELAY;
} else {
dcf = open(dcname, O_RDWR );
saved_mode = O_RDWR;
}
strcpy(saved_dcname, dcname);
(void) alarm(0);
if (dcf < 0) {
DEBUG(1, "generic open failed, errno = %d\n", errno);
(void) close(nullfd);
logent("generic open", "FAILED");
Uerror = SS_CANT_ACCESS_DEVICE;
goto bad;
}
if ( fd_mklock(dcf) != SUCCESS ) {
DEBUG(1, "failed to lock device %s\n", dcname);
Uerror = SS_LOCKED_DEVICE;
goto bad;
}
if ( Modemctrl ) {
DEBUG(7, "clear O_NDELAY\n%s", "");
if ( fcntl(dcf, F_SETFL,
(fcntl(dcf, F_GETFL, 0) & ~O_NDELAY)) < 0 ) {
DEBUG( 7, "clear O_NDELAY failed, errno %d\n", errno);
Uerror = SS_DEVICE_FAILED;
goto bad;
}
}
}
if ( (*Setup)( MASTER, &dcf, &dcf ) ) {
DEBUG(5, "MASTER Setup failed%s", "");
Uerror = SS_DEVICE_FAILED;
goto bad;
}
if ( !pop_push(dcf) ) {
DEBUG(5, "STREAMS module configuration failed%s\n","");
Uerror = SS_DEVICE_FAILED;
goto bad;
}
ret_orig = ioctl(dcf, TCGETA, &tty_orig);
fixline(dcf, atoi(fdig(sdev[D_CLASS])), D_DIRECT);
for (; dev[D_CALLER] != NULL; dev += 2) {
int w;
if ((w = gdial(dev[D_CALLER], args, D_MAX)) < 1) {
logent("generic call to gdial", "FAILED");
Uerror = SS_CANT_ACCESS_DEVICE;
goto bad;
}
if (w <= 2)
break;
if (dev[D_ARG] == NULL) {
dev[D_ARG+1] = NULL;
dev[D_ARG] = "\\D";
}
phonecl = repphone(dev[D_ARG], flds[F_PHONE], args[1]);
exphone(phonecl, phoneex);
translate(args[1], phoneex);
if (chat(w-2, &args[2], dcf, phonecl, phoneex) != SUCCESS) {
CDEBUG(5, "\nCHAT gdial(%s) FAILED\n", dev[D_CALLER]);
Uerror = SS_CHAT_FAILED;
goto bad;
}
}
strcpy(Dc, sdev[D_LINE]);
return(dcf);
bad:
if ( dcf >= 0 ) {
if ( ret_orig == 0 )
(void) ioctl(dcf, TCSETAW, &tty_orig);
fd_rmlock(dcf);
(void)close(dcf);
}
(void)interface("UNIX");
return(FAIL);
}
GLOBAL int
clear_hup(dcf)
int dcf;
{
int ndcf;
if ((ndcf = open(saved_dcname, saved_mode)) < 0) {
return (FAIL);
}
if (ndcf != dcf) {
close(ndcf);
}
return (SUCCESS);
}
static void
translate(ttab, str)
char *ttab, *str;
{
char *s;
for(;*ttab && *(ttab+1); ttab += 2)
for(s=str;*s;s++)
if(*ttab == *s)
*s = *(ttab+1);
return;
}
#define MAXLINE 512
static int
gdial(type, arps, narps)
char *type, *arps[];
int narps;
{
static char info[MAXLINE];
int na;
EXTERN void dialreset();
EXTERN char * currdial();
DEBUG(2, "gdial(%s) called\n", type);
while (getdialline(info, sizeof(info))) {
if ((info[0] == '#') || (info[0] == ' ') ||
(info[0] == '\t') || (info[0] == '\n'))
continue;
if ((na = getargs(info, arps, narps)) == 0)
continue;
if (EQUALS(arps[0], type)) {
DEBUG(5, "Trying caller script '%s'", type);
DEBUG(5, " from '%s'.\n", currdial());
dialreset();
bsfix(arps);
return(na);
}
}
DEBUG(1, "%s not found in Dialers file\n", type);
dialreset();
return(0);
}
#ifdef DATAKIT
#include "dk.h"
EXTERN int dkdial();
GLOBAL int
dkcall(flds, dev)
char *flds[], *dev[];
{
int fd;
#ifdef V8
extern int cdkp_ld;
#endif
char dialstring[64];
EXTERN void dkbreak();
strcpy(dialstring, dev[D_ARG]);
DEBUG(4, "dkcall(%s)\n", dialstring);
#ifdef V8
if (setjmp(Sjbuf)) {
Uerror = SS_DIAL_FAILED;
return(FAIL);
}
(void) signal(SIGALRM, alarmtr);
(void) alarm(connecttime);
DEBUG(4, "tdkdial(%s", flds[F_PHONE]);
DEBUG(4, ", %d)\n", atoi(dev[D_CLASS]));
if ((fd = tdkdial(flds[F_PHONE], atoi(dev[D_CLASS]))) >= 0)
if (dkproto(fd, cdkp_ld) < 0)
{
close(fd);
fd = -1;
}
(void) alarm(0);
#else
fd = dkdial(dialstring);
#endif
(void) strcpy(Dc, "DK");
if (fd < 0) {
Uerror = SS_DIAL_FAILED;
return(FAIL);
}
else {
genbrk = dkbreak;
return(fd);
}
}
#endif
#ifdef TCP
#if !(defined(BSD4_2) || defined(ATTSVR4))
GLOBAL int
tcpcall(flds, dev)
char *flds[], *dev[];
{
Uerror = SS_NO_DEVICE;
return(FAIL);
}
#else
GLOBAL int
tcpcall(flds, dev)
char *flds[], *dev[];
{
int ret;
short port;
struct servent *sp;
struct hostent *hp;
struct sockaddr_in sin;
if (EQUALS(flds[F_CLASS], "-")) {
sp = getservbyname("uucp", "tcp");
endservent();
ASSERT(sp != NULL, "No uucp service number", 0, 0);
port = sp->s_port;
} else {
sp = getservbyname(flds[F_CLASS], "tcp");
endservent();
if (sp == NULL) {
port = htons(atoi(flds[F_CLASS]));
if (port == 0) {
logent("tcpopen", "unknown port number");
Uerror = SS_NO_DEVICE;
return(FAIL);
}
} else
port = sp->s_port;
}
if (EQUALS(flds[F_PHONE], "-")) {
hp = gethostbyname(flds[F_NAME]);
} else {
hp = gethostbyname(flds[F_PHONE]);
}
endhostent();
if (hp == NULL) {
logent("tcpopen", "no such host");
Uerror = SS_NO_DEVICE;
return(FAIL);
}
DEBUG(4, "tcpdial host %s, ", hp->h_name);
DEBUG(4, "port %d\n", ntohs(port));
ret = socket(AF_INET, SOCK_STREAM, 0);
if (ret < 0) {
DEBUG(5, "no socket: %s\n", strerror(errno));
logent("no socket", strerror(errno));
Uerror = SS_NO_DEVICE;
return(FAIL);
}
sin.sin_family = hp->h_addrtype;
#ifdef BSD4_2
bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
#else
memcpy((caddr_t)&sin.sin_addr, hp->h_addr, hp->h_length);
#endif
sin.sin_port = port;
if (setjmp(Sjbuf)) {
DEBUG(4, "timeout tcpopen\n%s", "");
logent("tcpopen", "TIMEOUT");
Uerror = SS_NO_DEVICE;
return(FAIL);
}
(void) signal(SIGALRM, alarmtr);
(void) alarm(connecttime);
DEBUG(7, "family: %d\n", sin.sin_family);
DEBUG(7, "port: %d\n", sin.sin_port);
DEBUG(7, "addr: %08x\n",*((int *) &sin.sin_addr));
if (connect(ret, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
(void) alarm(0);
(void) close(ret);
DEBUG(5, "connect failed: %s\n", strerror(errno));
logent("connect failed", strerror(errno));
Uerror = SS_NO_DEVICE;
return(FAIL);
}
(void) signal(SIGPIPE, SIG_IGN);
(void) alarm(0);
(void) strcpy(Dc, "IPC");
return(ret);
}
#endif
#ifndef UNET
GLOBAL int
unetcall(flds, dev)
char *flds[], *dev[];
{
Uerror = SS_NO_DEVICE;
return(FAIL);
}
#else
GLOBAL int
unetcall(flds, dev)
char *flds[], *dev[];
{
int ret;
int port;
port = atoi(dev[D_ARG]);
DEBUG(4, "unetdial host %s, ", flds[F_PHONE]);
DEBUG(4, "port %d\n", port);
(void) alarm(connecttime);
ret = tcpopen(flds[F_PHONE], port, 0, TO_ACTIVE, "rw");
(void) alarm(0);
endhnent();
if (ret < 0) {
DEBUG(5, "tcpopen failed: errno %d\n", errno);
Uerror = SS_DIAL_FAILED;
return(FAIL);
}
(void) strcpy(Dc, "UNET");
return(ret);
}
#endif
#endif
#ifdef SYTEK
GLOBAL int
sytcall(flds, dev)
char *flds[], *dev[];
{
int dcr, dcr2, nullfd, ret;
char dcname[20], command[BUFSIZ];
(void) sprintf(dcname, "/dev/%s", dev[D_LINE]);
DEBUG(4, "dc - %s, ", dcname);
dcr = open(dcname, O_WRONLY|O_NDELAY);
if (dcr < 0) {
Uerror = SS_DIAL_FAILED;
DEBUG(4, "OPEN FAILED %s\n", dcname);
return(FAIL);
}
if ( fd_mklock(dcr) != SUCCESS ) {
(void)close(dcr);
DEBUG(1, "failed to lock device %s\n", dcname);
Uerror = SS_LOCKED_DEVICE;
return(FAIL);
}
sytfixline(dcr, atoi(fdig(dev[D_CLASS])), D_DIRECT);
(void) sleep(2);
DEBUG(4, "Calling Sytek unit %s\n", dev[D_ARG]);
(void) sprintf(command,"\r\rcall %s\r", dev[D_ARG]);
ret = (*Write)(dcr, command, strlen(command));
(void) sleep(1);
DEBUG(4, "COM1 return = %d\n", ret);
sytfix2line(dcr);
(void) close(nullfd = open("/", O_RDONLY));
(void) signal(SIGALRM, alarmtr);
if (setjmp(Sjbuf)) {
DEBUG(4, "timeout sytek open\n%s", "");
(void) close(nullfd);
(void) close(dcr2);
fd_rmlock(dcr);
(void) close(dcr);
Uerror = SS_DIAL_FAILED;
return(FAIL);
}
(void) alarm(10);
dcr2 = open(dcname,O_RDWR);
(void) alarm(0);
fd_rmlock(dcr);
(void) close(dcr);
if (dcr2 < 0) {
DEBUG(4, "OPEN 2 FAILED %s\n", dcname);
Uerror = SS_DIAL_FAILED;
(void) close(nullfd);
return(FAIL);
}
if ( fd_mklock(dcr2) != SUCCESS ) {
(void)close(dcr2);
DEBUG(1, "failed to lock device %s\n", dcname);
Uerror = SS_LOCKED_DEVICE;
return(FAIL);
return(dcr2);
}
#endif
#ifdef DIAL801
GLOBAL int
dial801(flds, dev)
char *flds[], *dev[];
{
char dcname[20], dnname[20], phone[MAXPH+2];
int dcf = -1, speed;
(void) sprintf(dnname, "/dev/%s", dev[D_CALLDEV]);
(void) sprintf(phone, "%s%s", dev[D_ARG] , ACULAST);
(void) sprintf(dcname, "/dev/%s", dev[D_LINE]);
CDEBUG(1, "Use Port %s, ", dcname);
DEBUG(4, "acu - %s, ", dnname);
VERBOSE("Trying modem - %s, ", dcname);
VERBOSE("acu - %s, ", dnname);
if(getuid()==0 || GRPCHK(getgid())) {
CDEBUG(1, "Phone Number %s\n", phone);
VERBOSE("calling %s: ", phone);
}
speed = atoi(fdig(dev[D_CLASS]));
dcf = open801(dcname, dnname, phone, speed);
if (dcf >= 0) {
if ( fd_mklock(dcf) != SUCCESS ) {
(void) close(dcf);
DEBUG(5, "fd_mklock line %s failed\n", dev[D_LINE]);
Uerror = SS_LOCKED_DEVICE;
return(FAIL);
}
fixline(dcf, speed, D_ACU);
(void) strcpy(Dc, dev[D_LINE]);
VERBOSE("SUCCEEDED\n%s", "");
} else {
VERBOSE("FAILED\n%s", "");
}
return(dcf);
}
#ifndef ATTSV
GLOBAL int
open801(dcname, dnname, phone, speed)
char *dcname, *dnname, *phone;
{
int nw, lt, dcf = -1, nullfd, dnf = -1;
pid_t w_ret, pid = -1;
unsigned timelim;
if ((dnf = open(dnname, O_WRONLY)) < 0) {
DEBUG(5, "can't open %s\n", dnname);
Uerror = SS_CANT_ACCESS_DEVICE;
return(FAIL);
}
DEBUG(5, "%s is open\n", dnname);
(void) close(nullfd = open("/dev/null", O_RDONLY));
if (setjmp(Sjbuf)) {
DEBUG(4, "timeout modem open\n%s", "");
(void) close(nullfd);
(void) close(dcf);
(void) close(dnf);
logent("801 open", "TIMEOUT");
if (pid > 0) {
kill(pid, 9);
wait((int *) 0);
}
Uerror = SS_DIAL_FAILED;
return(FAIL);
}
(void) signal(SIGALRM, alarmtr);
timelim = 5 * strlen(phone);
(void) alarm(timelim < connecttime ? connecttime : timelim);
if ((pid = fork()) == 0) {
sleep(2);
nw = (*Write)(dnf, phone, lt = strlen(phone));
if (nw != lt) {
DEBUG(4, "ACU write error %d\n", errno);
logent("ACU write", "FAILED");
exit(1);
}
DEBUG(4, "ACU write ok\n%s", "");
exit(0);
}
dcf = open(dcname, O_RDWR);
DEBUG(4, "dcf is %d\n", dcf);
if (dcf < 0) {
(void) alarm(0);
longjmp(Sjbuf, 1);
}
while ((w_ret = wait(<)) != pid)
if (w_ret == -1 && errno != EINTR) {
DEBUG(4, "Wait failed errno=%d\n", errno);
(void) close(dcf);
(void) close(dnf);
Uerror = SS_DIAL_FAILED;
return(FAIL);
}
(void) alarm(0);
(void) close(dnf);
if (lt != 0) {
DEBUG(4, "Fork Stat %o\n", lt);
(void) close(dcf);
Uerror = SS_DIAL_FAILED;
return(FAIL);
}
return(dcf);
}
#else
GLOBAL int
open801(dcname, dnname, phone, speed)
char *dcname, *dnname, *phone;
{
int nw, lt, dcf = -1, nullfd, dnf = -1, ret;
unsigned timelim;
(void) close(nullfd = open("/", O_RDONLY));
if (setjmp(Sjbuf)) {
DEBUG(4, "DN write %s\n", "timeout");
(void) close(dnf);
(void) close(dcf);
(void) close(nullfd);
Uerror = SS_DIAL_FAILED;
return(FAIL);
}
(void) signal(SIGALRM, alarmtr);
timelim = 5 * strlen(phone);
(void) alarm(timelim < connecttime ? connecttime : timelim);
if ((dnf = open(dnname, O_WRONLY)) < 0 ) {
DEBUG(5, "can't open %s\n", dnname);
Uerror = SS_CANT_ACCESS_DEVICE;
return(FAIL);
}
DEBUG(5, "%s is open\n", dnname);
if ( fd_mklock(dnf) != SUCCESS ) {
(void)close(dnf);
DEBUG(1, "failed to lock device %s\n", dnname);
Uerror = SS_LOCKED_DEVICE;
}
if ( (dcf = open(dcname, O_RDWR | O_NDELAY)) < 0 ) {
DEBUG(5, "can't open %s\n", dcname);
Uerror = SS_CANT_ACCESS_DEVICE;
return(FAIL);
}
if ( fd_mklock(dcf) != SUCCESS ) {
(void)close(dcf);
DEBUG(1, "failed to lock device %s\n", dcname);
Uerror = SS_LOCKED_DEVICE;
return(FAIL);
}
DEBUG(4, "dcf is %d\n", dcf);
fixline(dcf, speed, D_ACU);
nw = (*Write)(dnf, phone, lt = strlen(phone));
if (nw != lt) {
(void) alarm(0);
DEBUG(4, "ACU write error %d\n", errno);
(void) close(dnf);
(void) close(dcf);
Uerror = SS_DIAL_FAILED;
return(FAIL);
} else
DEBUG(4, "ACU write ok\n%s", "");
(void) close(dnf);
(void) close(nullfd = open("/", O_RDONLY));
ret = open(dcname, O_RDWR);
(void) alarm(0);
(void) close(ret);
if (ret < 0) {
DEBUG(4, "Line open %s\n", "failed");
Uerror = SS_DIAL_FAILED;
(void) close(nullfd);
return(FAIL);
}
(void) fcntl(dcf,F_SETFL, fcntl(dcf, F_GETFL, 0) & ~O_NDELAY);
return(dcf);
}
#endif
#endif
#ifdef V8
GLOBAL int
Dialout(flds)
char *flds[];
{
int fd;
char phone[MAXPH+2];
exphone(flds[F_PHONE], phone);
DEBUG(4, "call dialout(%s", phone);
DEBUG(4, ", %s)\n", dev[D_CLASS]);
fd = dialout(phone, dev[D_CLASS]);
if (fd == -1)
Uerror = SS_NO_DEVICE;
if (fd == -3)
Uerror = SS_DIAL_FAILED;
if (fd == -9)
Uerror = SS_DEVICE_FAILED;
(void) strcpy(Dc, "Dialout");
return(fd);
}
#endif
#ifdef TLI
#include <sys/tiuser.h>
EXTERN void tfaillog();
char *t_alloc();
int t_bind(), t_close(), t_connect(), t_free(), t_look(), t_open(), t_rcvdis();
#define CONNECT_ATTEMPTS 3
#define TFREE(p, type) if ((p)) t_free((char *)(p), (type))
GLOBAL int
tlicall(flds, dev)
char *flds[];
char *dev[];
{
char addrbuf[ BUFSIZ ];
char devname[MAXNAMESIZE];
int fd;
int i, j;
struct t_bind *bind_ret = 0;
struct t_info tinfo;
struct t_call *sndcall = 0, *rcvcall = 0;
extern int t_errno;
EXTERN struct netbuf *stoa();
if ( dev[D_LINE][0] != '/' ) {
sprintf(devname, "/dev/%s", dev[D_LINE]);
} else {
strcpy(devname, dev[D_LINE]);
}
errno = t_errno = 0;
if (setjmp(Sjbuf)) {
DEBUG(1, "t_open timeout\n%s", "");
logent("t_open", "TIMEOUT");
Uerror = SS_NO_DEVICE;
return(FAIL);
}
(void) signal(SIGALRM, alarmtr);
(void) alarm(5);
fd = t_open(devname, O_RDWR, &tinfo);
(void) alarm(0);
if (fd < 0) {
tfaillog(fd, "t_open" );
Uerror = SS_NO_DEVICE;
return(FAIL);
}
if ( fd_mklock(fd) != SUCCESS ) {
(void)t_close(fd);
DEBUG(1, "tlicall: failed to lock device %s\n", devname);
Uerror = SS_LOCKED_DEVICE;
return(FAIL);
}
errno = t_errno = 0;
if ( (bind_ret = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL)) ==
(struct t_bind *)NULL
|| (sndcall = (struct t_call *)t_alloc(fd, T_CALL, T_ALL)) ==
(struct t_call *)NULL
|| (rcvcall = (struct t_call *)t_alloc(fd, T_CALL, T_ALL)) ==
(struct t_call *)NULL ) {
tfaillog(fd, "t_alloc" );
TFREE(bind_ret, T_BIND);TFREE(sndcall, T_CALL);
TFREE(rcvcall, T_CALL);
Uerror = SS_NO_DEVICE;
return(FAIL);
}
errno = t_errno = 0;
if (t_bind(fd, (struct t_bind *) 0, bind_ret ) < 0) {
tfaillog(fd, "t_bind" );
TFREE(bind_ret, T_BIND);TFREE(sndcall, T_CALL);
TFREE(rcvcall, T_CALL);
Uerror = SS_NO_DEVICE;
fd_rmlock(fd);
(void) t_close(fd);
return(FAIL);
}
DEBUG(5, "tlicall: bound to %s\n", bind_ret->addr.buf);
DEBUG(5, "t_connect to addr \"%s\"\n",
strecpy( addrbuf, dev[D_ARG], "\\" ) );
if ( dev[D_ARG][0] == '\\' &&
( dev[D_ARG][1] == 'x' || dev[D_ARG][1] == 'X'
|| dev[D_ARG][1] == 'o' || dev[D_ARG][1] == 'O' ) ) {
if ( stoa(dev[D_ARG], &(sndcall->addr)) == (struct netbuf *)NULL ) {
DEBUG(5, "tlicall: stoa failed\n%s", "");
logent("tlicall", "string-to-address failed");
TFREE(bind_ret, T_BIND);TFREE(sndcall, T_CALL);
TFREE(rcvcall, T_CALL);
Uerror = SS_NO_DEVICE;
fd_rmlock(fd);
(void) t_close(fd);
return(FAIL);
}
} else {
for( i = j = 0; i < BUFSIZ && dev[D_ARG][i] != NULLCHAR;
++i, ++j ) {
if( dev[D_ARG][i] == '\\' && dev[D_ARG][i+1] == 'N' ) {
addrbuf[j] = NULLCHAR;
++i;
}
else {
addrbuf[j] = dev[D_ARG][i];
}
}
sndcall->addr.buf = addrbuf;
sndcall->addr.len = j;
}
if (setjmp(Sjbuf)) {
DEBUG(4, "timeout tlicall\n%s", "");
logent("tlicall", "TIMEOUT");
TFREE(bind_ret, T_BIND);TFREE(sndcall, T_CALL);
TFREE(rcvcall, T_CALL);
Uerror = SS_NO_DEVICE;
fd_rmlock(fd);
(void) t_close(fd);
return(FAIL);
}
(void) signal(SIGALRM, alarmtr);
(void) alarm(connecttime);
errno = t_errno = 0;
for ( i = 0; i < CONNECT_ATTEMPTS; ++i ) {
if (t_connect(fd, sndcall, rcvcall) == 0)
break;
if ( (t_errno == TLOOK) && (t_look(fd) == T_DISCONNECT)) {
t_rcvdis(fd,NULL);
(void) alarm(0);
} else {
(void) alarm(0);
tfaillog(fd, "t_connect");
TFREE(bind_ret, T_BIND);TFREE(sndcall, T_CALL);
TFREE(rcvcall, T_CALL);
Uerror = SS_DIAL_FAILED;
fd_rmlock(fd);
(void) t_close(fd);
return(FAIL);
}
}
(void) alarm(0);
TFREE(bind_ret, T_BIND);TFREE(sndcall, T_CALL);
TFREE(rcvcall, T_CALL);
if ( i == CONNECT_ATTEMPTS ) {
tfaillog(fd, "t_connect");
Uerror = SS_DIAL_FAILED;
fd_rmlock(fd);
(void) t_close(fd);
return(FAIL);
}
errno = t_errno = 0;
(void) strcpy(Dc, dev[D_CALLER]);
return(fd);
}
#endif