2 * TCP/IP stream emulation for GNU Emacs.
3 * Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
5 * Author: Masanobu Umeda
6 * Maintainer: umerin@mse.kyutech.ac.jp
8 This file is part of SXEmacs.
10 SXEmacs is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 SXEmacs is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * Yasunari, Itoh at PFU limited contributed for Fujitsu UTS and SX/A.
26 * Thu Apr 6 13:47:37 JST 1989
27 * USG fixes by Sakaeda <saka@mickey.trad.pf.fujitsu.junet>
29 * For Fujitsu UTS compile with:
30 * cc -O -o tcp tcp.c -DFUJITSU_UTS -lu -lsocket
36 #include <sys/types.h>
40 #include <sys/ucbtypes.h>
41 #include <sys/tisp/socket.h>
43 #include <sys/tisp/in.h>
45 #include <sys/socket.h>
47 #include <netinet/in.h>
60 fcntl(fileno(stdin), F_SETFL, 0);
70 struct sockaddr_in sockin, sockme;
72 char *hostname = NULL;
73 char *service = "nntp";
77 int server; /* NNTP Server */
78 int emacsIn = fileno(stdin); /* Emacs intput */
79 int emacsOut = fileno(stdout); /* Emacs output */
81 int nbuffer; /* Number of bytes in buffer */
83 char *retry; /* retry bufferp */
84 int false = 0; /* FALSE flag for setsockopt () */
87 fprintf(stderr, "Usage: %s HOST [SERVICE]\n", argv[0]);
95 if ((host = gethostbyname(hostname)) == NULL) {
96 perror("gethostbyname");
99 if (isdigit(service[0]))
100 port = atoi(service);
102 serv = getservbyname(service, "tcp");
104 perror("getservbyname");
110 memset(&sockin, 0, sizeof(sockin));
111 sockin.sin_family = host->h_addrtype;
112 memcpy(&sockin.sin_addr, host->h_addr, host->h_length);
113 sockin.sin_port = port;
114 if ((server = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
118 if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &false, sizeof(false))) {
119 perror("setsockopt");
122 memset(&sockme, 0, sizeof(sockme));
123 sockme.sin_family = sockin.sin_family;
124 sockme.sin_addr.s_addr = INADDR_ANY;
125 if (bind(server, &sockme, sizeof(sockme)) < 0) {
129 if (connect(server, &sockin, sizeof(sockin)) < 0) {
135 fcntl(server, F_SETFL, O_NDELAY);
138 /* USG pipe cannot not select emacsIn */
141 fstat(emacsIn, &statbuf);
142 if (statbuf.st_mode & 010000)
145 signal(SIGINT, sigout);
146 fcntl(emacsIn, F_SETFL, O_NDELAY);
152 /* Connection established. */
154 readfds = (1 << server) | (1 << emacsIn);
155 if (select(32, &readfds, NULL, NULL, (struct timeval *)NULL) ==
160 if (readfds & (1 << emacsIn)) {
162 nbuffer = read(emacsIn, buffer, sizeof buffer - 1);
165 if (selectable && nbuffer == 0) {
167 } else if (!(readfds & (1 << server)) && nbuffer == 0) {
174 for (retry = buffer; nbuffer > 0;
175 nbuffer -= wret, retry += wret) {
176 writefds = 1 << server;
178 (server + 1, NULL, &writefds, NULL,
179 (struct timeval *)NULL) == -1) {
183 wret = write(server, retry, nbuffer);
188 if (readfds & (1 << server)) {
189 /* From NNTP server */
190 nbuffer = read(server, buffer, sizeof buffer - 1);
193 for (retry = buffer; nbuffer > 0;
194 nbuffer -= wret, retry += wret) {
195 writefds = 1 << emacsOut;
200 (emacsOut + 1, NULL, &writefds,
202 (struct timeval *)NULL) == -1) {
206 wret = write(emacsOut, retry, nbuffer);
213 /* End of communication. */
218 fcntl(emacsIn, F_SETFL, 0);