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 GNU Emacs.
10 GNU Emacs 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 2, or (at your option)
15 GNU Emacs 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 GNU Emacs; see the file COPYING. If not, write to
22 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 * Yasunari, Itoh at PFU limited contributed for Fujitsu UTS and SX/A.
27 * Thu Apr 6 13:47:37 JST 1989
28 * USG fixes by Sakaeda <saka@mickey.trad.pf.fujitsu.junet>
30 * For Fujitsu UTS compile with:
31 * cc -O -o tcp tcp.c -DFUJITSU_UTS -lu -lsocket
37 #include <sys/types.h>
41 #include <sys/ucbtypes.h>
42 #include <sys/tisp/socket.h>
44 #include <sys/tisp/in.h>
46 #include <sys/socket.h>
48 #include <netinet/in.h>
57 #define bcopy(f, t, n) memcpy (t, f, n)
58 #define bcmp(b1, b2, n) (memcmp (b1, b2, n)!=0)
59 #define bzero(b, n) memset (b, 0, n)
67 fcntl (fileno (stdin
), F_SETFL
, 0);
77 struct sockaddr_in sockin
, sockme
;
79 char *hostname
= NULL
;
80 char *service
= "nntp";
84 int server
; /* NNTP Server */
85 int emacsIn
= fileno (stdin
); /* Emacs intput */
86 int emacsOut
= fileno (stdout
); /* Emacs output */
88 int nbuffer
; /* Number of bytes in buffer */
90 char *retry
; /* retry bufferp */
91 int false = 0; /* FALSE flag for setsockopt () */
95 fprintf (stderr
, "Usage: %s HOST [SERVICE]\n", argv
[0]);
103 if ((host
= gethostbyname (hostname
)) == NULL
)
105 perror ("gethostbyname");
108 if (isdigit (service
[0]))
109 port
= atoi (service
);
112 serv
= getservbyname (service
, "tcp");
115 perror ("getservbyname");
121 bzero (&sockin
, sizeof (sockin
));
122 sockin
.sin_family
= host
->h_addrtype
;
123 bcopy (host
->h_addr
, &sockin
.sin_addr
, host
->h_length
);
124 sockin
.sin_port
= port
;
125 if ((server
= socket (AF_INET
, SOCK_STREAM
, 0)) < 0)
130 if (setsockopt (server
, SOL_SOCKET
, SO_REUSEADDR
, &false, sizeof (false)))
132 perror ("setsockopt");
135 bzero (&sockme
, sizeof (sockme
));
136 sockme
.sin_family
= sockin
.sin_family
;
137 sockme
.sin_addr
.s_addr
= INADDR_ANY
;
138 if (bind (server
, &sockme
, sizeof (sockme
)) < 0)
143 if (connect (server
, &sockin
, sizeof (sockin
)) < 0)
151 fcntl (server
, F_SETFL
, O_NDELAY
);
154 /* USG pipe cannot not select emacsIn */
157 fstat (emacsIn
, &statbuf
);
158 if (statbuf
.st_mode
& 010000)
162 signal (SIGINT
, sigout
);
163 fcntl (emacsIn
, F_SETFL
, O_NDELAY
);
169 /* Connection established. */
172 readfds
= (1 << server
) | (1 << emacsIn
);
173 if (select (32, &readfds
, NULL
, NULL
, (struct timeval
*)NULL
) == -1)
178 if (readfds
& (1 << emacsIn
))
181 nbuffer
= read (emacsIn
, buffer
, sizeof buffer
-1);
184 if (selectable
&& nbuffer
== 0)
188 else if (!(readfds
& (1 << server
)) && nbuffer
== 0)
197 for (retry
= buffer
; nbuffer
> 0; nbuffer
-= wret
, retry
+= wret
)
199 writefds
= 1 << server
;
200 if (select (server
+1, NULL
, &writefds
, NULL
, (struct timeval
*)NULL
) == -1)
205 wret
= write (server
, retry
, nbuffer
);
206 if (wret
< 0) goto finish
;
209 if (readfds
& (1 << server
))
211 /* From NNTP server */
212 nbuffer
= read (server
, buffer
, sizeof buffer
-1);
215 for (retry
= buffer
; nbuffer
> 0; nbuffer
-= wret
, retry
+= wret
)
217 writefds
= 1 << emacsOut
;
221 if (select (emacsOut
+1, NULL
, &writefds
, NULL
, (struct timeval
*)NULL
) == -1)
226 wret
= write (emacsOut
, retry
, nbuffer
);
227 if (wret
< 0) goto finish
;
232 /* End of communication. */
236 if (!selectable
) fcntl (emacsIn
, F_SETFL
, 0);