4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2014 Gary Mills
24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
33 * provide alternate definitions for the I/O functions through global
41 int t_bind(), t_close(), t_connect(), t_free(), t_look(), t_open(), t_rcvdis();
42 int t_getinfo(), t_getstate(), t_look(), t_rcv(), t_snd(), t_sync(), t_unbind();
49 static int dkteardown();
53 EXTERN
int restline();
55 extern int ioctl(int, int, ...);
59 static int usetup(), uteardown();
61 GLOBAL
ssize_t (*Read
)() = read
,
64 GLOBAL
int (*Ioctl
)(int, int, ...) = ioctl
,
66 GLOBAL
int (*Ioctl
)() = ioctl
,
69 (*Teardown
)() = uteardown
;
72 EXTERN
void tfaillog(), show_tlook();
73 static ssize_t
tread(), twrite(); /* TLI i/o */
75 static int tioctl(int, int, ...),
77 static int tioctl(), /* TLI i/o control */
79 tsetup(), /* TLI setup without streams module */
80 tssetup(), /* TLI setup with streams module */
81 tteardown(); /* TLI teardown, works with either setup */
84 * The IN_label in Interface[] imply different caller routines:
86 * If so, the names here and the names in callers.c must match.
91 char *IN_label
; /* interface name */
92 ssize_t (*IN_read
)(); /* read function */
93 ssize_t (*IN_write
)(); /* write function */
95 int (*IN_ioctl
)(int, int, ...);
97 int (*IN_ioctl
)(); /* ioctl function */
99 int (*IN_setup
)(); /* setup function, called before */
100 /* first i/o operation */
101 int (*IN_teardown
)(); /* teardown function, called after */
102 /* last i/o operation */
105 { "UNIX", read
, write
, ioctl
, usetup
, uteardown
},
107 /* TCP over sockets or UNET */
108 { "TCP", read
, write
, ioctl
, usetup
, uteardown
},
112 { "Sytek", read
, write
, ioctl
, usetup
, uteardown
},
113 #endif /* Sytek network */
115 /* 801 auto dialers */
116 { "801", read
, write
, ioctl
, usetup
, uteardown
},
119 /* 212 auto dialers */
120 { "212", read
, write
, ioctl
, usetup
, uteardown
},
123 /* AT&T Transport Interface Library WITHOUT streams */
124 { "TLI", tread
, twrite
, tioctl
, tsetup
, tteardown
},
126 /* AT&T Transport Interface Library WITH streams */
127 { "TLIS", read
, write
, tioctl
, tssetup
, uteardown
},
131 { "DK", read
, write
, ioctl
, dksetup
, dkteardown
},
134 { "Unetserver", read
, write
, ioctl
, usetup
, uteardown
},
146 for (i
= 0; Interface
[i
].IN_label
; ++i
) {
147 if (0 == strcmp(Interface
[i
].IN_label
, label
)) {
148 Read
= Interface
[i
].IN_read
;
149 Write
= Interface
[i
].IN_write
;
150 Ioctl
= Interface
[i
].IN_ioctl
;
151 Setup
= Interface
[i
].IN_setup
;
152 Teardown
= Interface
[i
].IN_teardown
;
153 DEBUG(5, "set interface %s\n", label
);
161 * usetup - vanilla unix setup routine
164 usetup(role
, fdreadp
, fdwritep
)
165 int *fdreadp
, *fdwritep
;
171 /* 2 has been re-opened to RMTDEBUG in main() */
177 * uteardown - vanilla unix teardown routine
180 uteardown(role
, fdread
, fdwrite
)
187 DEBUG(4, "ret restline - %d\n", ret
);
192 ttyn
= ttyname(fdread
);
193 if (ttyn
!= NULL
&& Dev_mode
!= 0)
194 chmod(ttyn
, Dev_mode
); /* can fail, but who cares? */
195 (void) close(fdread
);
196 (void) close(fdwrite
);
203 * dksetup - DATAKIT setup routine
205 * Put line in block mode.
209 dksetup(role
, fdreadp
, fdwritep
)
216 static short dkrmode
[3] = { DKR_BLOCK
| DKR_TIME
, 0, 0 };
219 (void) usetup(role
, fdreadp
, fdwritep
);
220 if ((ret
= (*Ioctl
)(*fdreadp
, DIOCRMODE
, dkrmode
)) < 0) {
221 DEBUG(4, "dksetup: failed to set block mode. ret=%d,\n", ret
);
222 DEBUG(4, "read fd=%d, ", *fdreadp
);
223 DEBUG(4, "errno=%d\n", errno
);
230 * dkteardown - DATAKIT teardown routine
233 dkteardown(role
, fdread
, fdwrite
)
234 int role
, fdread
, fdwrite
;
238 if (role
== MASTER
) {
239 ttyn
= ttyname(fdread
);
240 if (ttyn
!= NULL
&& Dev_mode
!= 0)
241 chmod(ttyn
, Dev_mode
); /* can fail, but who cares? */
244 /* must flush fd's for datakit */
245 /* else close can hang */
246 if (ioctl(fdread
, DIOCFLUSH
, NULL
) != 0)
247 DEBUG(4, "dkteardown: DIOCFLUSH of input fd %d failed",
249 if (ioctl(fdwrite
, DIOCFLUSH
, NULL
) != 0)
250 DEBUG(4, "dkteardown: DIOCFLUSH of output fd %d failed",
253 (void) close(fdread
);
254 (void) close(fdwrite
);
262 * tread - tli read routine
265 tread(fd
, buf
, nbytes
)
272 return ((ssize_t
)t_rcv(fd
, buf
, nbytes
, &rcvflags
));
276 * twrite - tli write routine
280 twrite(fd
, buf
, nbytes
)
286 static int n_writ
, got_info
;
287 static struct t_info info
;
290 if (t_getinfo(fd
, &info
) != 0) {
291 tfaillog(fd
, "twrite: t_getinfo\n");
297 /* on every N_CHECKth call, check that are still in DATAXFER state */
298 if (++n_writ
== N_CHECK
) {
300 if (t_getstate(fd
) != T_DATAXFER
)
304 if (info
.tsdu
<= 0 || nbytes
<= info
.tsdu
)
305 return (t_snd(fd
, buf
, nbytes
, NULL
));
307 /* if get here, then there is a limit on transmit size */
308 /* (info.tsdu > 0) and buf exceeds it */
310 while (nbytes
>= info
.tsdu
) {
311 if ((ret
= t_snd(fd
, &buf
[i
], info
.tsdu
, NULL
)) != info
.tsdu
)
312 return ((ret
>= 0 ? (i
+ ret
) : ret
));
317 if ((ret
= t_snd(fd
, &buf
[i
], nbytes
, NULL
)) != nbytes
)
318 return ((ssize_t
)(ret
>= 0 ? (i
+ ret
) : ret
));
326 * tioctl - stub for tli ioctl routine
331 tioctl(int fd
, int request
, ...)
333 tioctl(fd
, request
, arg
)
341 * tsetup - tli setup routine
342 * note blatant assumption that *fdreadp == *fdwritep == 0
345 tsetup(role
, fdreadp
, fdwritep
)
346 int *fdreadp
, *fdwritep
;
352 /* 2 has been re-opened to RMTDEBUG in main() */
354 if (t_sync(*fdreadp
) == -1 || t_sync(*fdwritep
) == -1) {
355 tfaillog(*fdreadp
, "tsetup: t_sync\n");
363 * tteardown - tli shutdown routine
367 tteardown(role
, fdread
, fdwrite
)
369 (void) t_unbind(fdread
);
370 (void) t_close(fdread
);
376 * tssetup - tli, with streams module, setup routine
377 * note blatant assumption that *fdreadp == *fdwritep
380 tssetup(role
, fdreadp
, fdwritep
)
388 /* 2 has been re-opened to RMTDEBUG in main() */
389 DEBUG(5, "tssetup: SLAVE mode: leaving ok\n%s", "");
393 DEBUG(4, "tssetup: MASTER mode: leaving ok\n%s", "");
398 * Report why a TLI call failed.
407 if (0 < t_errno
&& t_errno
< t_nerr
) {
408 sprintf(fmt
, "%s: %%s\n", s
);
409 DEBUG(5, fmt
, t_errlist
[t_errno
]);
410 logent(s
, t_errlist
[t_errno
]);
411 if (t_errno
== TSYSERR
) {
412 strcpy(fmt
, "tlicall: system error: %s\n");
413 DEBUG(5, fmt
, strerror(errno
));
414 } else if (t_errno
== TLOOK
) {
418 sprintf(fmt
, "unknown tli error %d", t_errno
);
420 sprintf(fmt
, "%s: unknown tli error %d", s
, t_errno
);
422 sprintf(fmt
, "%s: %%s\n", s
);
423 DEBUG(5, fmt
, strerror(errno
));
435 * Find out the current state of the interface.
438 switch (reason
= t_getstate(fd
)) {
439 case T_UNBND
: msg
= "T_UNBIND"; break;
440 case T_IDLE
: msg
= "T_IDLE"; break;
441 case T_OUTCON
: msg
= "T_OUTCON"; break;
442 case T_INCON
: msg
= "T_INCON"; break;
443 case T_DATAXFER
: msg
= "T_DATAXFER"; break;
444 case T_OUTREL
: msg
= "T_OUTREL"; break;
445 case T_INREL
: msg
= "T_INREL"; break;
446 default: msg
= NULL
; break;
451 DEBUG(5, "state is %s", msg
);
452 switch (reason
= t_look(fd
)) {
453 case -1: msg
= ""; break;
454 case 0: msg
= "NO ERROR"; break;
455 case T_LISTEN
: msg
= "T_LISTEN"; break;
456 case T_CONNECT
: msg
= "T_CONNECT"; break;
457 case T_DATA
: msg
= "T_DATA"; break;
458 case T_EXDATA
: msg
= "T_EXDATA"; break;
459 case T_DISCONNECT
: msg
= "T_DISCONNECT"; break;
460 case T_ORDREL
: msg
= "T_ORDREL"; break;
461 case T_UDERR
: msg
= "T_UDERR"; break;
462 default: msg
= "UNKNOWN ERROR"; break;
464 DEBUG(4, " reason is %s\n", msg
);
466 if (reason
== T_DISCONNECT
)
468 struct t_discon
*dropped
;
470 (struct t_discon
*)t_alloc(fd
, T_DIS
, T_ALL
)) == 0) ||
471 (t_rcvdis(fd
, dropped
) == -1)) {
473 t_free((char *)dropped
, T_DIS
);
476 DEBUG(5, "disconnect reason #%d\n", dropped
->reason
);
477 t_free((char *)dropped
, T_DIS
);