First, the mixed impression in Joey Hesses example is due to the fact that Termnet will replace any non-resolvable host name or non-IPv4-address with a hardcoded 'localhost'. Thus Hesses second call in fact got a positive response from his private workstation!
With this email there are two difference files: one NMU-diff, and for convenience a separate copy of the C-code patching. This patch is not final, but I hope a reader of this mail will use the opportunity to test it. By intention I do not tag this with the Control daemon as containing patches. Termpkg scores indeed poorly in popcon numbers, and knowing now that it contains more errors than really can be called comfortable, one could justifiably claim that Termpkg should be dropped from future releases. That said, my present patches implement IPv6 support for the two services Ttyd and Termnet. Both can now use service names for the port option, not only numerical values. In addition I have done most in closing outdated pipes and file descriptors that the official Ttyd simply leaves, without ever closing them. I will address the question of passing environmental variables through Ttyd next. The present lack of this ability is clearly impeding the usefulness of Ttyd at present. Regards, Mats Erik Andersson, fil. dr Abbonerar på: debian-mentors, debian-devel-games, debian-perl, debian-ipv6
diff -u termpkg-3.3/libtn/SocketIO.c termpkg-3.3/libtn/SocketIO.c --- termpkg-3.3/libtn/SocketIO.c +++ termpkg-3.3/libtn/SocketIO.c @@ -63,16 +63,14 @@ int connectSocket(char *pHost, char *pService, char *pProtocol, int timeout_val) { - struct hostent *phe; + struct addrinfo hints, *ai, *aiptr; struct servent *pse; struct protoent *ppe; - struct sockaddr_in sin; struct itimerval waitTime; int n, s, type; + u_short port; tn_errno = 0; - bzero((char *)&sin, sizeof(sin)); - sin.sin_family = AF_INET; signal(SIGALRM, (void (*)(int))timerExpired); waitTime.it_interval.tv_sec = waitTime.it_interval.tv_usec = 0; @@ -81,21 +79,13 @@ setitimer(ITIMER_REAL, &waitTime, NULL); if ((pse = getservbyname(pService, pProtocol)) != NULL) - sin.sin_port = pse->s_port; - else if ((sin.sin_port = htons((u_short)atoi(pService))) == 0) + port = pse->s_port; + else if ((port = htons((u_short)atoi(pService))) == 0) { tn_errno = TNL_NOSERVENTRY_ERR; return(-1); } - if ((phe = gethostbyname(pHost)) != NULL) - bcopy(phe->h_addr, (char *)&sin.sin_addr, phe->h_length); - else if ((sin.sin_addr.s_addr = inet_addr(pHost)) == INADDR_NONE) - { - tn_errno = TNL_NOHOSTENTRY_ERR; - return(-1); - } - if ((ppe = getprotobyname(pProtocol)) == 0) { tn_errno = TNL_INVPROTOCOL_ERR; @@ -107,24 +97,47 @@ else type = SOCK_STREAM; - if ((s = socket(PF_INET, type, ppe->p_proto)) < 0) + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = type; + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; + + if (getaddrinfo(pHost, pService, &hints, &ai)) { - tn_errno = TNL_SOCKET_ERR; + tn_errno = TNL_NOHOSTENTRY_ERR; return(-1); } - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) + for (aiptr = ai; aiptr; aiptr = aiptr->ai_next) { + if ((s = socket(aiptr->ai_family, aiptr->ai_socktype, + aiptr->ai_protocol)) < 0) + { + tn_errno = TNL_SOCKET_ERR; + continue; + } + + if (connect(s, aiptr->ai_addr, aiptr->ai_addrlen) >= 0) + break; + if (tn_errno == 0) tn_errno = TNL_NOCONNECT_ERR; - return(-1); + close(s); + continue; } + freeaddrinfo(ai); + waitTime.it_interval.tv_sec = waitTime.it_interval.tv_usec = 0; waitTime.it_value.tv_sec = waitTime.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &waitTime, NULL); signal(SIGALRM, SIG_DFL); + if (aiptr == NULL) + return(-1); + + tn_errno == 0; + if ((n = fcntl(s, F_GETFL, 0)) < 0) return(-6); return(s); diff -u termpkg-3.3/termnet/ttyd.c termpkg-3.3/termnet/ttyd.c --- termpkg-3.3/termnet/ttyd.c +++ termpkg-3.3/termnet/ttyd.c @@ -42,6 +42,10 @@ #endif #include "termnet.h" +#if __linux__ +# define DEV_PTMX "/dev/ptmx" +#endif + #if defined (AIX) || defined(SunOS) #define LOG_PERROR 0 #endif @@ -149,16 +153,21 @@ { char buf[256]; - syslog(LOG_DEBUG, "Have some form of error!"); - if (iVal == 1) + if (dbg) + syslog(LOG_DEBUG, "Some form of error!"); + if (iVal == TNL_SOCKETREAD_ERR) { - sprintf(buf, "Error String: |%d|", (int)pArg1); - syslog(LOG_DEBUG, "%s:Connection Closed", buf); + if ((int)pArg1 && (int)pArg1 != ESPIPE) + { + sprintf(buf, "Error number: |%d|", (int)pArg1); + syslog(LOG_DEBUG, "%s:Connection Closed", buf); + } netClosed = 1; } else { - syslog(LOG_ERR, "Recieved error reading %s:%m", (iVal == 1) ? "socket" : "internal pipe"); + syslog(LOG_ERR, "Received error while reading %s:%m", + (iVal == TNL_SOCKETREAD_ERR) ? "socket" : "internal pipe"); } } @@ -381,7 +390,9 @@ fflush(userOut); fflush(tnlout); } - tnlShutdown(2); + fclose(tnlin); + fclose(tnlout); + tnlShutdown(SHUT_RDWR); } else { @@ -403,6 +414,9 @@ int main(int argc, char *argv[]) { int opt, opFlg, fd, NoDetach, cpid; +#ifdef DEV_PTMX + int firstCall = 1; +#endif char *cp; NoDetach = 0; @@ -461,9 +475,11 @@ else { chdir("/etc"); - close(0); - close(1); - close(2); + close(STDIN_FILENO); +#if !defined(DEV_PTMX) + close(STDOUT_FILENO); /* No need to report '/dev/pts/#'. */ +#endif + close(STDERR_FILENO); } } else @@ -488,9 +504,11 @@ if (argc >= 1) { - if (gethostbyname(argv[0]) != NULL || - inet_addr(argv[0]) != INADDR_NONE) + struct addrinfo *ai; + + if (getaddrinfo(argv[0], NULL, NULL, &ai) == 0) { + freeaddrinfo(ai); argn++; pHost = argv[0]; } @@ -504,13 +522,24 @@ break_char = '\0'; while ((fd = openPtyDevice(sDevice)) >= 0) { +#ifdef DEV_PTMX + if (firstCall) + { + char *slaveName; + firstCall = 0; + if (slaveName = ptsname(fd)) + printf("%s\n", slaveName); + } + if (!NoDetach) + close(STDOUT_FILENO); /* Was delayed to report '/dev/pts/#'. */ +#endif FD_ZERO(&ReadFds); FD_SET(fd, &ReadFds); select(fd+1, &ReadFds, NULL, NULL, NULL); if (dbg) syslog(LOG_DEBUG, "main():Calling doTermServ()!"); tcgetattr(fd, &OrgTermios); /* get current console tty mode */ - RunTermios = OrgTermios; /* copy (structure) to RunTermios */ + RunTermios = OrgTermios; /* copy (structure) to RunTermios */ RunTermios.c_oflag = 0; RunTermios.c_iflag &= ~(IXON | IXOFF | ICRNL | INLCR) | IGNCR; @@ -519,9 +548,12 @@ RunTermios.c_cc[VTIME] = 1; tcsetattr(fd, TCSANOW, &RunTermios); doTermServ(fd, pHost, pService); + tcsetattr(fd, TCSANOW, &OrgTermios); + syslog(LOG_INFO, "Completed one service request."); close(fd); sleep(1); } + if (dbg) syslog(LOG_DEBUG, "main():All done!"); doExit(0); return(0); diff -u termpkg-3.3/debian/changelog termpkg-3.3/debian/changelog --- termpkg-3.3/debian/changelog +++ termpkg-3.3/debian/changelog @@ -1,3 +1,13 @@ +termpkg (3.3-9.2) unstable; urgency=low + + * Non-maintainer upload. + * IPv6 support for libtn, ttyd, and termnet. + * Ports can be standard service name or numerical values. + * Support for Unix98 pseudo-terminal in ttyd. + * Closing unneeded pipes and file descriptors in ttyd. + + -- Mats Erik Andersson <mats.anders...@gisladisker.se> Fri, 05 Mar 2010 23:07:11 +0100 + termpkg (3.3-9.1) unstable; urgency=low * Non-maintainer upload. only in patch2: unchanged: --- termpkg-3.3.orig/doc/ttyd.1 +++ termpkg-3.3/doc/ttyd.1 @@ -1,12 +1,12 @@ .TH ttyd 1 01/08/00 GNU Remote Modem Utility for Unix .SH NAME -ttyd \- Remote Modem Utility for Unix +ttyd \- Remote modem utility for Unix .SH SYNOPSIS .BR ttyd \-d -.I pty device +.I pty-device [ .I options ] @@ -18,48 +18,57 @@ remote modem daemon. The .BR ttyd -daemon is fully telnet compatible allowing programs to connect to any remote -device such as networked modems and terminal servers as if they were -local devices as long as the device utilizes the telnet protocol. +daemon is fully telnet compatible, allowing programs to connect to any remote +device such as networked modems, and terminal servers, as if they were +local devices. This holds true as long as the device utilizes the telnet protocol. .PP -After opening a Master Pseudo tty device, the daemon will wait for some other process -to open the corresponding slave device. Once the slave device is opened, a connection -will be made, using the telnet protocol, to a remote server. The remote end may be any -server supporting the telnet protocol such as a terminal server, network modem, or +After opening a pseudo-terminal master device, the daemon will wait for some other process +to open the corresponding slave device. Once the slave device has been opened, a connection +will be made to the remote server, using the telnet protocol. The remote end may be any +server supporting the telnet protocol such as a terminal server, a network modem, or the .BR termnetd process. .PP -For reference, in Linux the Master Pseudo tty devices art the devices +For reference, on Linux systems the pseudo-terminal master devices are the devices .B /dev/pty[a-ep-z][0-9a-f] and the slave devices are .B /dev/tty[a-ep-z][0-9a-f]. Other Unices may have different naming schemes. +.PP +An alternative is to use the Unix98 pseudo-terminals. The device path is +\fI/dev/ptmx\fR to the master device. The use of this path will then +dynamically allocate a new slave device \fI/dev/pts/#\fR. .SH OPTIONS .TP .I "\-b baud-rate" Sets the initial baud-rate of the device. .TP -.I "\-d pty device" -Master Pseudo tty device to open and wait for a connection on. This -.I option -is not optional, it must be provided +.I "\-d pty-device" +The pseudo-terminal master device to open, and whose slave device will +wait for a connection. In case \fIpty-device\fR is taken as +\fI/dev/ptmx\fR, then a successful allocation of a slave device will +result in the name of this slave device to be printed to \fIstdout\fR. +Observe that this option is mandatory! +.TP .I "\-p port-settings" -Configures the port as specified by port settings. +Configures the port as specified by the port settings. .TP .I "\-n" -No detach, do not run as a background process. +Do not detach, run as a foreground process. .PP The .I host and .I port -parameters specify the host and IP port to connect to when the Slave Pseudo device is -opened. +parameters specify the host and TCP port to connect to when the pseudo-terminal +slave device is opened. .SH "SEE ALSO" termnet(1), termnetd(1), termios(2) .SH AUTHOR Joe Croft <j...@croftj.net> +.TP +Additions by Mats Erik Andersson. only in patch2: unchanged: --- termpkg-3.3.orig/doc/termnet.1 +++ termpkg-3.3/doc/termnet.1 @@ -19,14 +19,14 @@ This man page documents the .BR termnet program. This command is a simple telnet replacement. It does -not implement for the complete telnet protocol, but does provide a few -nifty features of it's own. Especially when used with the +not implement the complete telnet protocol, but it does provide a few +nifty features of its own. Especially when used with the .BR termnetd terminal server daemon. .PP The following features are available: .IP -Telnet compatible (it can used to connect to telnetd). +Telnet compatibility (it can used to connect to telnetd). .IP Live setting of a device's baud rate and port configuration when connected to the @@ -37,16 +37,16 @@ .SH OPTIONS .TP .I "\-7 -Emulate 7 bit even parity data. This will calculate an even parity bit on the -least significant 7 bits of each outgoing character and append it to the charater. -It will also strip the 8th (MSb) bit from the incomming data before displaying it. +Emulate 7 bit, even parity data. This will calculate an even parity bit on the +least significant 7 bits of each outgoing character and append it to the character. +It will also strip the 8th bit (MSb) from incoming data before displaying it. .TP .I "\-b baud-rate" Sets the initial baud-rate of the device. .TP .I \-c -Do not drop the connection after running the chat sequences either -presented on the command line or performed through the +Do not drop the connection after running the chat sequences, either +presented on the command line or performed using the .I \-f option. .TP @@ -76,19 +76,20 @@ .TP .I "$ [unix-command]" Executes the -.I unix-command -it's stdio redirected to the socket. Sadly, -this does not run programs like sz and rz, though it is handily for +.I unix-command, +with its \fIstdio\fR redirected to the socket. Sadly, +this does not work well with programs like sz and rz, though it comes +handy for down-loading ASCII files or the like. A space must be present between -the +the character .I $ and the command. .TP .I "! [unix-command]" Executes the .I unix-command -and sends it's output to the output file (normally stdout). A space -must be present between the +and sends its output to the output file (normally \fIstdout\fR). A space +must be present between the character .I ! and the command. .TP @@ -138,7 +139,7 @@ .RE .TP .I "CHAT chat-file" -This command executes the chat-file specified. See the section CHAT +This command executes the specified chat-file. See the section on CHAT Scripts for further information. .TP .I DEVC @@ -150,7 +151,7 @@ to the output. .TP .I "ECHO ON|OFF" -Turns the local echoing of characters input from the keyboard on or +Turns the local echoing of character input from the keyboard on or off. .TP .I EXIT @@ -164,10 +165,10 @@ .I "PORT [port-settings]" If .I port-settings -is present, the port will be configured to them. Otherwise, the +is present, the port will be configured according to them. Otherwise, the current settings will be displayed. The settings are specified by a -string of one or more of the following concatenated together with no -intervening spaces: +string of one or more of the following, concatenated together with no +intervening space: .RS .PP .I 8 @@ -207,7 +208,7 @@ The chat scripts are composed of a sequence of send strings followed by expect strings. The program will first send a string then wait for the expected string to be received. Commands my be injected into the -sequence at any point be surrounding the entire command with \'`\' +sequence at any point by surrounding the entire command with \'`\' quotes. The biggest weakness is that there are no time limits on how long the program will wait for the expected string. Fortunately the keyboard is fully active while they are being executed. @@ -231,15 +232,15 @@ .br "ath0\\r" "OK" .PP -This simple script dials out the number, then waits for \'ogin\' then -logs in as the user \'et\' giving the required password when requested. +This simple script dials the number, then waits for \'ogin\', then +logs in as the user \'et\', and giving the required password when requested. At that point it waits to see a \'+++\' from the login script, and -forces the modem to go into the command mode with the \'+++\' and -hangs it up with the \'ath0\' command. +forces the modem to go into command mode with the string \'+++\', and +hangs up with the \'ath0\' command. .PP -Though the quotes are not required, I find they make the scripts much +Although the quotes are not required, I find they make the scripts much easier to read. Also, if the script is on the command line, you have -to be mindful of the substitutions that may occur from the shell. +to be mindful of the substitutions that may be conducted by the shell. .SH "SEE ALSO" termnetd(1), ttyd(1), termios(2) only in patch2: unchanged: --- termpkg-3.3.orig/libtn/tnlSelect.c +++ termpkg-3.3/libtn/tnlSelect.c @@ -29,7 +29,12 @@ void tnlShutdown(int how) { + fclose(aplout); + fclose(aplin); + fclose(nfp); shutdown(nfd, how); + if (how == SHUT_RDWR) + close(nfd); } /* only in patch2: unchanged: --- termpkg-3.3.orig/libtn/tnlMisc.c +++ termpkg-3.3/libtn/tnlMisc.c @@ -42,6 +42,10 @@ static char ttydev_mask[] = "/dev/pty$$"; #endif +#if __linux__ +# define DEV_PTMX "/dev/ptmx" +#endif + static char ttydev_z[256]; int openPtyDevice(char *pName) @@ -106,6 +110,15 @@ { if (dbg) syslog(LOG_DEBUG, "openPtyDevice():Device exists"); fd = open(pName, O_RDWR); +#ifdef DEV_PTMX + if (strstr(pName, DEV_PTMX)) + if (grantpt(fd) || unlockpt(fd)) + { + syslog(LOG_INFO, "grantpt()/unlockpt() failure: %m"); + close(fd); + return(-1); + } +#endif } else { only in patch2: unchanged: --- termpkg-3.3.orig/termnet/termnet.c +++ termpkg-3.3/termnet/termnet.c @@ -638,9 +638,11 @@ if (argc >= 1) { - if (gethostbyname(argv[0]) != NULL || - inet_addr(argv[0]) != INADDR_NONE) + struct addrinfo *ai; + + if (getaddrinfo(argv[0], NULL, NULL, &ai) == 0) { + freeaddrinfo(ai); argn++; pHost = argv[0]; }
--- termpkg-3.3/termnet/termnet.c.debian +++ termpkg-3.3/termnet/termnet.c @@ -638,9 +638,11 @@ int main(int argc, char *argv[]) if (argc >= 1) { - if (gethostbyname(argv[0]) != NULL || - inet_addr(argv[0]) != INADDR_NONE) + struct addrinfo *ai; + + if (getaddrinfo(argv[0], NULL, NULL, &ai) == 0) { + freeaddrinfo(ai); argn++; pHost = argv[0]; } --- termpkg-3.3/libtn/SocketIO.c.debian +++ termpkg-3.3/libtn/SocketIO.c @@ -63,16 +63,14 @@ static void timerExpired(int sig) int connectSocket(char *pHost, char *pService, char *pProtocol, int timeout_val) { - struct hostent *phe; + struct addrinfo hints, *ai, *aiptr; struct servent *pse; struct protoent *ppe; - struct sockaddr_in sin; struct itimerval waitTime; int n, s, type; + u_short port; tn_errno = 0; - bzero((char *)&sin, sizeof(sin)); - sin.sin_family = AF_INET; signal(SIGALRM, (void (*)(int))timerExpired); waitTime.it_interval.tv_sec = waitTime.it_interval.tv_usec = 0; @@ -81,21 +79,13 @@ int connectSocket(char *pHost, char *pSe setitimer(ITIMER_REAL, &waitTime, NULL); if ((pse = getservbyname(pService, pProtocol)) != NULL) - sin.sin_port = pse->s_port; - else if ((sin.sin_port = htons((u_short)atoi(pService))) == 0) + port = pse->s_port; + else if ((port = htons((u_short)atoi(pService))) == 0) { tn_errno = TNL_NOSERVENTRY_ERR; return(-1); } - if ((phe = gethostbyname(pHost)) != NULL) - bcopy(phe->h_addr, (char *)&sin.sin_addr, phe->h_length); - else if ((sin.sin_addr.s_addr = inet_addr(pHost)) == INADDR_NONE) - { - tn_errno = TNL_NOHOSTENTRY_ERR; - return(-1); - } - if ((ppe = getprotobyname(pProtocol)) == 0) { tn_errno = TNL_INVPROTOCOL_ERR; @@ -107,24 +97,47 @@ int connectSocket(char *pHost, char *pSe else type = SOCK_STREAM; - if ((s = socket(PF_INET, type, ppe->p_proto)) < 0) + memset(&hints, 0, sizeof(hints)); + hints.ai_socktype = type; + hints.ai_family = AF_UNSPEC; + hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME; + + if (getaddrinfo(pHost, pService, &hints, &ai)) { - tn_errno = TNL_SOCKET_ERR; + tn_errno = TNL_NOHOSTENTRY_ERR; return(-1); } - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) + for (aiptr = ai; aiptr; aiptr = aiptr->ai_next) { + if ((s = socket(aiptr->ai_family, aiptr->ai_socktype, + aiptr->ai_protocol)) < 0) + { + tn_errno = TNL_SOCKET_ERR; + continue; + } + + if (connect(s, aiptr->ai_addr, aiptr->ai_addrlen) >= 0) + break; + if (tn_errno == 0) tn_errno = TNL_NOCONNECT_ERR; - return(-1); + close(s); + continue; } + freeaddrinfo(ai); + waitTime.it_interval.tv_sec = waitTime.it_interval.tv_usec = 0; waitTime.it_value.tv_sec = waitTime.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &waitTime, NULL); signal(SIGALRM, SIG_DFL); + if (aiptr == NULL) + return(-1); + + tn_errno == 0; + if ((n = fcntl(s, F_GETFL, 0)) < 0) return(-6); return(s); --- termpkg-3.3/termnet/ttyd.c.debian +++ termpkg-3.3/termnet/ttyd.c @@ -42,6 +42,10 @@ #endif #include "termnet.h" +#if __linux__ +# define DEV_PTMX "/dev/ptmx" +#endif + #if defined (AIX) || defined(SunOS) #define LOG_PERROR 0 #endif @@ -149,16 +153,21 @@ void handleTelNetErrors(int iVal, void * { char buf[256]; - syslog(LOG_DEBUG, "Have some form of error!"); - if (iVal == 1) + if (dbg) + syslog(LOG_DEBUG, "Some form of error!"); + if (iVal == TNL_SOCKETREAD_ERR) { - sprintf(buf, "Error String: |%d|", (int)pArg1); - syslog(LOG_DEBUG, "%s:Connection Closed", buf); + if ((int)pArg1 && (int)pArg1 != ESPIPE) + { + sprintf(buf, "Error number: |%d|", (int)pArg1); + syslog(LOG_DEBUG, "%s:Connection Closed", buf); + } netClosed = 1; } else { - syslog(LOG_ERR, "Recieved error reading %s:%m", (iVal == 1) ? "socket" : "internal pipe"); + syslog(LOG_ERR, "Received error while reading %s:%m", + (iVal == TNL_SOCKETREAD_ERR) ? "socket" : "internal pipe"); } } @@ -381,7 +390,9 @@ int doTermServ(int fd, char *pHost, char fflush(userOut); fflush(tnlout); } - tnlShutdown(2); + fclose(tnlin); + fclose(tnlout); + tnlShutdown(SHUT_RDWR); } else { @@ -403,6 +414,9 @@ int doTermServ(int fd, char *pHost, char int main(int argc, char *argv[]) { int opt, opFlg, fd, NoDetach, cpid; +#ifdef DEV_PTMX + int firstCall = 1; +#endif char *cp; NoDetach = 0; @@ -461,9 +475,11 @@ int main(int argc, char *argv[]) else { chdir("/etc"); - close(0); - close(1); - close(2); + close(STDIN_FILENO); +#if !defined(DEV_PTMX) + close(STDOUT_FILENO); /* No need to report '/dev/pts/#'. */ +#endif + close(STDERR_FILENO); } } else @@ -488,9 +504,11 @@ int main(int argc, char *argv[]) if (argc >= 1) { - if (gethostbyname(argv[0]) != NULL || - inet_addr(argv[0]) != INADDR_NONE) + struct addrinfo *ai; + + if (getaddrinfo(argv[0], NULL, NULL, &ai) == 0) { + freeaddrinfo(ai); argn++; pHost = argv[0]; } @@ -504,13 +522,24 @@ int main(int argc, char *argv[]) break_char = '\0'; while ((fd = openPtyDevice(sDevice)) >= 0) { +#ifdef DEV_PTMX + if (firstCall) + { + char *slaveName; + firstCall = 0; + if (slaveName = ptsname(fd)) + printf("%s\n", slaveName); + } + if (!NoDetach) + close(STDOUT_FILENO); /* Was delayed to report '/dev/pts/#'. */ +#endif FD_ZERO(&ReadFds); FD_SET(fd, &ReadFds); select(fd+1, &ReadFds, NULL, NULL, NULL); if (dbg) syslog(LOG_DEBUG, "main():Calling doTermServ()!"); tcgetattr(fd, &OrgTermios); /* get current console tty mode */ - RunTermios = OrgTermios; /* copy (structure) to RunTermios */ + RunTermios = OrgTermios; /* copy (structure) to RunTermios */ RunTermios.c_oflag = 0; RunTermios.c_iflag &= ~(IXON | IXOFF | ICRNL | INLCR) | IGNCR; @@ -519,9 +548,12 @@ int main(int argc, char *argv[]) RunTermios.c_cc[VTIME] = 1; tcsetattr(fd, TCSANOW, &RunTermios); doTermServ(fd, pHost, pService); + tcsetattr(fd, TCSANOW, &OrgTermios); + syslog(LOG_INFO, "Completed one service request."); close(fd); sleep(1); } + if (dbg) syslog(LOG_DEBUG, "main():All done!"); doExit(0); return(0); --- termpkg-3.3/libtn/tnlSelect.c.debian +++ termpkg-3.3/libtn/tnlSelect.c @@ -29,7 +29,12 @@ void tnlShutdown(int how) { + fclose(aplout); + fclose(aplin); + fclose(nfp); shutdown(nfd, how); + if (how == SHUT_RDWR) + close(nfd); } /* --- termpkg-3.3/libtn/tnlMisc.c.debian +++ termpkg-3.3/libtn/tnlMisc.c @@ -42,6 +42,10 @@ static char ttydev_y[] = "fedcba98765432 static char ttydev_mask[] = "/dev/pty$$"; #endif +#if __linux__ +# define DEV_PTMX "/dev/ptmx" +#endif + static char ttydev_z[256]; int openPtyDevice(char *pName) @@ -106,6 +110,15 @@ int openPtyDevice(char *pName) { if (dbg) syslog(LOG_DEBUG, "openPtyDevice():Device exists"); fd = open(pName, O_RDWR); +#ifdef DEV_PTMX + if (strstr(pName, DEV_PTMX)) + if (grantpt(fd) || unlockpt(fd)) + { + syslog(LOG_INFO, "grantpt()/unlockpt() failure: %m"); + close(fd); + return(-1); + } +#endif } else {
signature.asc
Description: Digital signature