📄 clnt_tty.c
字号:
(void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); } } /* end successful completion */ else { /* maybe our credentials need to be refreshed ... */ if(nrefreshes > 0 && /* 4.0 */ AUTH_REFRESH(cl->cl_auth)) goto call_again; } /* end of unsuccessful completion */ } /* end of valid reply message */ else { cu->cu_error.re_status = RPC_CANTDECODERES; } return (cu->cu_error.re_status); }static void clnttty_geterr ( CLIENT *cl, struct rpc_err *errp ) { register struct cu_data *cu = (struct cu_data *)cl->cl_private; *errp = cu->cu_error; }static bool_t clnttty_freeres ( CLIENT *cl, xdrproc_t xdr_res, caddr_t res_ptr ) { register struct cu_data *cu = (struct cu_data *)cl->cl_private; register XDR *xdrs = &(cu->cu_outxdrs); xdrs->x_op = XDR_FREE; return ((*xdr_res)(xdrs, res_ptr)); }static void clnttty_abort ( CLIENT *h ) { }static bool_t clnttty_control ( CLIENT *cl, int request, char *info ) { register struct cu_data *cu = (struct cu_data *) cl->cl_private; switch(request) { case CLSET_TIMEOUT: cu->cu_total = *(struct timeval *) info; break; case CLGET_TIMEOUT: *(struct timeval *) info = cu->cu_total; break; case CLSET_RETRY_TIMEOUT: cu->cu_wait = *(struct timeval *)info; break; case CLGET_RETRY_TIMEOUT: *(struct timeval *) info = cu->cu_wait; break; default: return (FALSE); } return (TRUE); }static void clnttty_destroy ( CLIENT *cl ) { register struct cu_data *cu = (struct cu_data *)cl->cl_private; XDR_DESTROY(&(cu->cu_outxdrs)); mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz)); mem_free((caddr_t)cl, sizeof(CLIENT)); }/* TTY specific stuff */struct baudtable { int baudConst; int rate; };static struct baudtable baudTable[] = { {B150, 150}, {B300, 300}, {B600, 600}, {B1200, 1200}, {B1800, 1800}, {B2400, 2400}, {B4800, 4800}, {B9600, 9600}, {B19200, 19200}, {B38400, 38400}, {0, 0} };/* SLIP protocol characters */#define FRAME_END (char)0300 /* Frame End */#define FRAME_ESCAPE (char)0333 /* Frame Esc */#define TRANS_FRAME_END (char)0334 /* transposed frame end */#define TRANS_FRAME_ESCAPE (char)0335 /* transposed frame esc *//* dummy UDP/IP header info (in 16-bit words) */#define UDP_IP_HDR_SIZE 28#define IP_VERS_LEN 0 /* IP version + IP header length */#define IP_PROT 9 /* protocol to use */#define IP_DEST_ADDR 12 /* destination address */#define IP_SRC_ADDR 16 /* source address */#define UDP_SRC_PORT 20 /* source port */#define UDP_DEST_PORT 22 /* destination port */#define UDP_LEN 24 /* length */#define UDP_CKSUM 26 /* checksum */#define IN_BUF(offset) ((offset) < UDP_IP_HDR_SIZE ? \ pUdpIpHdr [offset] : \ inBuf [offset - UDP_IP_HDR_SIZE])#define BUF_PUT(ch) if (bytesRead >= UDP_IP_HDR_SIZE) \ buf[bytesRead - UDP_IP_HDR_SIZE] = ch#ifdef IPPROTO_UDP#undef IPPROTO_UDP#endif#define IPPROTO_UDP 0x11/******************************************************************************** clnttty_send - write data after encoding it with SLIP escape sequences.*/ static int clnttty_send ( int fd, char * inBuf, int nBytes ) { int inputIx; int outputIx; char * outBuf; char * outBufCopy; int bytesSent; int buf[UDP_IP_HDR_SIZE/sizeof (int)]; char * pUdpIpHdr; int loop = 8; /* set up a dummy UDP/IP header */ pUdpIpHdr = (char *) buf; bzero (pUdpIpHdr, UDP_IP_HDR_SIZE); pUdpIpHdr [IP_VERS_LEN] = 0x45; /* XXX - little endian 0x54? */ pUdpIpHdr [IP_PROT] = IPPROTO_UDP; * (short *) &pUdpIpHdr [UDP_DEST_PORT] = htons(WDBPORT); outBuf = (char *) malloc (nBytes * 2); if(outBuf == NULL) return (0); outBufCopy = outBuf; /* save the location */ outBuf[0] = FRAME_END; outputIx = 1; for(inputIx = 0; inputIx < nBytes + UDP_IP_HDR_SIZE; inputIx ++) { switch(IN_BUF (inputIx)) { case FRAME_END: outBuf [outputIx++] = FRAME_ESCAPE; outBuf [outputIx++] = TRANS_FRAME_END; break; case FRAME_ESCAPE: outBuf [outputIx++] = FRAME_ESCAPE; outBuf [outputIx++] = TRANS_FRAME_ESCAPE; break; default: outBuf [outputIx++] = IN_BUF(inputIx); } } outBuf [outputIx++] = FRAME_END; /* write out the data */#ifndef WIN32 bytesSent = write (fd, outBuf, outputIx);#else /* WIN32 */ bytesSent = win32SerialWrite ((HANDLE) fd, outBuf, outputIx);#endif /* WIN32 */ if (bytesSent < 0) { wpwrLogErr ("\nclnttty_send: write failed\n"); goto sendError; } /* SPR #8979 */ outputIx -= bytesSent; outBuf += bytesSent; loop--; while ((outputIx > 0) && (loop > 0)) { #ifndef WIN32 bytesSent = write (fd, outBuf, outputIx);#else /* WIN32 */ bytesSent = win32SerialWrite ((HANDLE) fd, outBuf, outputIx);#endif /* WIN32 */ if (bytesSent < 0) { wpwrLogErr ("\nclnttty_send: write failed\n"); goto sendError; } outputIx -= bytesSent; outBuf += bytesSent; loop--; } if ((loop == 0) || (outputIx > 0)) { wpwrLogErr ("\nclnttty_send: didn't send all bytes\n"); goto sendError; } free (outBufCopy); return (nBytes);sendError: free (outBufCopy); return 0; }/******************************************************************************** clnttty_rcv - get input over a serial line** This routine gets characters one at a time, and decodes the SLIP escape* sequences.* It assumes there is a UDP/IP header at the beggining, which it throws* away.*/ static int clnttty_rcv ( int fd, char * buf, int nBytes ) { char inChar; int bytesRead; for(bytesRead = 0; bytesRead < nBytes + UDP_IP_HDR_SIZE; bytesRead++) {#ifndef WIN32 if(read (fd, &inChar, 1) < 1)#else /* WIN32 */ if(win32SerialRead ((HANDLE) fd, &inChar, 1) <= 0)#endif /* WIN32 */ {#ifdef RS6000_AIX4 if(errno == ENOENT || errno == EACCES || errno > 100) return (0); printf (" \nRead failure: errno is %d\n", errno);#endif wpwrLogErr ("clnttty_rcv: read timed out"); return (0); } switch(inChar) { case FRAME_END: if(bytesRead == 0) { bytesRead = -1; continue; } return (bytesRead > UDP_IP_HDR_SIZE ? bytesRead - UDP_IP_HDR_SIZE : 0); break; case FRAME_ESCAPE:#ifndef WIN32 if(read (fd, &inChar, 1) < 1)#else /* WIN32 */ if(win32SerialRead ((HANDLE) fd, &inChar, 1) <= 0)#endif /* WIN32 */ { wpwrLogErr ("clnttty_rcv: read failed"); return (bytesRead); } switch(inChar) { case TRANS_FRAME_END: BUF_PUT (FRAME_END); break; case TRANS_FRAME_ESCAPE: BUF_PUT (FRAME_ESCAPE); break; default: wpwrLogErr ("clnttty_rcv: bad escape sequence\n"); BUF_PUT (inChar); } break; default: BUF_PUT (inChar); } } wpwrLogErr ("clnttty_rcv: no end of frame in input\n"); return (bytesRead - UDP_IP_HDR_SIZE); }/******************************************************************************** clnttty_BaudConstGet - get the baud constant to use for a specified baud rate.*/ int clnttty_BaudConstGet ( int buadRate ) { int ix; for(ix = 0; baudTable[ix].rate != 0; ix++) { if(baudTable[ix].rate == buadRate) return (baudTable[ix].baudConst); } return (-1); }/******************************************************************************** clnttty_open - open and initialize a serial device.** This routine uses POSIX defined routines in order to:* open the device.* verify it is a tty device.* set the device hardware options to 8 data bits, 1 stop bit, no parity* set the flow control if any,* set the specified baud rate.** RETURNS: a file handle, or -1 on error.*/ LOCAL int clnttty_open ( char * devName, int baudRate, BOOL hardFlowControl, struct timeval wait ) { int fd = -1; /* tty file handle */#ifndef WIN32 struct termios termIo; /* terminal I/O options */ int ix; /* counter */ char * pName = NULL; /* device name pointer */ int modemLine; /* modem lines status */#ifdef PARISC_HPUX10 struct termiox termIoX; /* extended terminal interface */#endif /* PARISC_HPUX10 */ /* We will try each of the following paths when trying to open the tty */ static char *prefix[] = {"", "/dev/", "/dev/tty", NULL}; /* * Attempt to open the serial device, appending the default pathname * prefixes if the device can't be opened under the name supplied. */ for(ix = 0; prefix[ix] != NULL; ix++) { pName = (char *) malloc (strlen (prefix[ix]) + strlen (devName) + 1); sprintf (pName,"%s%s", prefix[ix], devName);#ifndef RS6000_AIX4 if((fd = open (pName, O_RDWR, 0)) < 0)#else if((fd = open (pName, O_RDWR | O_NDELAY, 0)) < 0)#endif /* RS6000_AIX4 */ free (pName); else break; }#ifdef RS6000_AIX4 { int rc, flags; struct termio termio; flags = fcntl (fd, F_GETFL, NULL); flags &= O_NONBLOCK; fcntl (fd, F_SETFL, flags); ioctl (fd, TCGETA, &termio); /* change input mode flags */ termio.c_iflag &= ~BRKINT; termio.c_iflag &= ~ICRNL; /* change to non-canonical */ termio.c_cc[VMIN] = 1; termio.c_cc[VTIME] = 0; termio.c_lflag &= ~ICANON; /* change to CLOCAL */ termio.c_cflag |= CLOCAL; ioctl (fd, TCSETA, &termio); }#endif /* RS6000_AIX */ free (pName); if(fd < 0) return (-1); /* get current attributes */ if(tcgetattr (fd, &termIo) == -1) { close (fd); return (-1); } /* configure for 8 data bits, 1 stop bit, no parity */ termIo.c_iflag = 0; /* no input procesing */ termIo.c_oflag = 0; /* no output procesing */ termIo.c_cflag = CREAD | CS8 | CLOCAL; /* 8 data, 1 stop bits */ termIo.c_lflag = 0; /* no local processing */ termIo.c_cc[VMIN] = 0; /* */ termIo.c_cc[VTIME] = wait.tv_sec * 10; /* time out value */ /* set the CTS/RTS flow control if any */ if (hardFlowControl) {#ifdef SUN4_SOLARIS2 termIo.c_cflag |= CRTSXOFF | CRTSCTS; /* RTS/CTS flow control */#endif /* SUN4_SOLARIS2 */#ifdef PARISC_HPUX10 ioctl (fd, TCGETX, &termIoX); termIoX.x_hflag = RTSXOFF | CTSXON; /* RTS/CTS flow control */ ioctl (fd, TCSETXW, &termIoX);#endif /* PARISC_HPUX10 */ modemLine = TIOCM_DTR; /* set the DTR signal */ ioctl (fd, TIOCMBIS, &modemLine); } /* configure for baud rate for input and output */ cfsetispeed (&termIo, clnttty_BaudConstGet (baudRate)); cfsetospeed (&termIo, clnttty_BaudConstGet (baudRate)); /* set the attributes */ tcsetattr (fd, TCSAFLUSH, &termIo);#else fd = (int) win32SerialOpen (devName, baudRate, hardFlowControl);#endif /* WIN32 */ /* all done */ return (fd); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -