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, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.
26 * Yasunari, Itoh at PFU limited contributed for Fujitsu UTS and SX/A.
28 * Thu Apr 6 13:47:37 JST 1989
29 * USG fixes by Sakaeda <saka@mickey.trad.pf.fujitsu.junet>
31 * For Fujitsu UTS compile with:
32 * cc -O -o tcp tcp.c -DFUJITSU_UTS -lu -lsocket
38 #include <sys/types.h>
42 #include <sys/ucbtypes.h>
43 #include <sys/tisp/socket.h>
45 #include <sys/tisp/in.h>
47 #include <sys/socket.h>
49 #include <netinet/in.h>
58 #define bcopy(f, t, n) memcpy (t, f, n)
59 #define bcmp(b1, b2, n) (memcmp (b1, b2, n)!=0)
60 #define bzero(b, n) memset (b, 0, n)
68 fcntl (fileno (stdin
), F_SETFL
, 0);
78 struct sockaddr_in sockin
, sockme
;
80 char *hostname
= NULL
;
81 char *service
= "nntp";
85 int server
; /* NNTP Server */
86 int emacsIn
= fileno (stdin
); /* Emacs intput */
87 int emacsOut
= fileno (stdout
); /* Emacs output */
89 int nbuffer
; /* Number of bytes in buffer */
91 char *retry
; /* retry bufferp */
92 int false = 0; /* FALSE flag for setsockopt () */
96 fprintf (stderr
, "Usage: %s HOST [SERVICE]\n", argv
[0]);
104 if ((host
= gethostbyname (hostname
)) == NULL
)
106 perror ("gethostbyname");
109 if (isdigit (service
[0]))
110 port
= atoi (service
);
113 serv
= getservbyname (service
, "tcp");
116 perror ("getservbyname");
122 bzero (&sockin
, sizeof (sockin
));
123 sockin
.sin_family
= host
->h_addrtype
;
124 bcopy (host
->h_addr
, &sockin
.sin_addr
, host
->h_length
);
125 sockin
.sin_port
= htons (port
);
126 if ((server
= socket (AF_INET
, SOCK_STREAM
, 0)) < 0)
131 if (setsockopt (server
, SOL_SOCKET
, SO_REUSEADDR
, &false, sizeof (false)))
133 perror ("setsockopt");
136 bzero (&sockme
, sizeof (sockme
));
137 sockme
.sin_family
= sockin
.sin_family
;
138 sockme
.sin_addr
.s_addr
= INADDR_ANY
;
139 if (bind (server
, &sockme
, sizeof (sockme
)) < 0)
144 if (connect (server
, &sockin
, sizeof (sockin
)) < 0)
152 fcntl (server
, F_SETFL
, O_NDELAY
);
155 /* USG pipe cannot not select emacsIn */
158 fstat (emacsIn
, &statbuf
);
159 if (statbuf
.st_mode
& 010000)
163 signal (SIGINT
, sigout
);
164 fcntl (emacsIn
, F_SETFL
, O_NDELAY
);
170 /* Connection established. */
173 readfds
= (1 << server
) | (1 << emacsIn
);
174 if (select (32, &readfds
, NULL
, NULL
, (struct timeval
*)NULL
) == -1)
179 if (readfds
& (1 << emacsIn
))
182 nbuffer
= read (emacsIn
, buffer
, sizeof buffer
-1);
185 if (selectable
&& nbuffer
== 0)
189 else if (!(readfds
& (1 << server
)) && nbuffer
== 0)
198 for (retry
= buffer
; nbuffer
> 0; nbuffer
-= wret
, retry
+= wret
)
200 writefds
= 1 << server
;
201 if (select (server
+1, NULL
, &writefds
, NULL
, (struct timeval
*)NULL
) == -1)
206 wret
= write (server
, retry
, nbuffer
);
207 if (wret
< 0) goto finish
;
210 if (readfds
& (1 << server
))
212 /* From NNTP server */
213 nbuffer
= read (server
, buffer
, sizeof buffer
-1);
216 for (retry
= buffer
; nbuffer
> 0; nbuffer
-= wret
, retry
+= wret
)
218 writefds
= 1 << emacsOut
;
222 if (select (emacsOut
+1, NULL
, &writefds
, NULL
, (struct timeval
*)NULL
) == -1)
227 wret
= write (emacsOut
, retry
, nbuffer
);
228 if (wret
< 0) goto finish
;
233 /* End of communication. */
237 if (!selectable
) fcntl (emacsIn
, F_SETFL
, 0);