Mercurial > emacs
annotate lib-src/tcp.c @ 26370:5f52cc1417ab
Use block statements in cases and declare v1 and v2
locally there. Rearrange case statements so that thos most
frequently executed come first. Avoid goto's in frequently
executed cases.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Sun, 07 Nov 1999 13:06:59 +0000 |
parents | 38829b121db7 |
children | 60712692fdbc |
rev | line source |
---|---|
6110 | 1 /* |
2 * TCP/IP stream emulation for GNU Emacs. | |
3 * Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc. | |
4 | |
5 * Author: Masanobu Umeda | |
6 * Maintainer: umerin@mse.kyutech.ac.jp | |
7 | |
8 This file is part of GNU Emacs. | |
9 | |
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) | |
13 any later version. | |
14 | |
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. | |
19 | |
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 | |
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
6110
diff
changeset
|
22 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
6110
diff
changeset
|
23 Boston, MA 02111-1307, USA. |
6110 | 24 |
25 * | |
26 * Yasunari, Itoh at PFU limited contributed for Fujitsu UTS and SX/A. | |
27 * | |
28 * Thu Apr 6 13:47:37 JST 1989 | |
29 * USG fixes by Sakaeda <saka@mickey.trad.pf.fujitsu.junet> | |
30 * | |
31 * For Fujitsu UTS compile with: | |
32 * cc -O -o tcp tcp.c -DFUJITSU_UTS -lu -lsocket | |
33 */ | |
34 | |
35 #include <stdio.h> | |
36 #include <fcntl.h> | |
37 #include <ctype.h> | |
38 #include <sys/types.h> | |
39 | |
40 #ifdef FUJITSU_UTS | |
41 #define USG | |
42 #include <sys/ucbtypes.h> | |
43 #include <sys/tisp/socket.h> | |
44 #include <netdb.h> | |
45 #include <sys/tisp/in.h> | |
46 #else | |
47 #include <sys/socket.h> | |
48 #include <netdb.h> | |
49 #include <netinet/in.h> | |
50 #endif | |
51 | |
52 #ifdef USG | |
53 #include <sys/stat.h> | |
54 #include <signal.h> | |
55 #endif | |
56 | |
57 #ifdef FUJITSU_UTS | |
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) | |
61 #endif | |
62 | |
63 #ifdef USG | |
64 int selectable = 1; | |
65 | |
66 sigout () | |
67 { | |
68 fcntl (fileno (stdin), F_SETFL, 0); | |
69 exit (-1); | |
70 } | |
71 #endif | |
72 | |
73 main (argc, argv) | |
74 int argc; | |
75 char *argv[]; | |
76 { | |
77 struct hostent *host; | |
78 struct sockaddr_in sockin, sockme; | |
79 struct servent *serv; | |
80 char *hostname = NULL; | |
81 char *service = "nntp"; | |
82 int port; | |
83 int readfds; | |
84 int writefds; | |
85 int server; /* NNTP Server */ | |
86 int emacsIn = fileno (stdin); /* Emacs intput */ | |
87 int emacsOut = fileno (stdout); /* Emacs output */ | |
88 char buffer[1024]; | |
89 int nbuffer; /* Number of bytes in buffer */ | |
90 int wret; | |
91 char *retry; /* retry bufferp */ | |
92 int false = 0; /* FALSE flag for setsockopt () */ | |
93 | |
94 if (argc < 2) | |
95 { | |
96 fprintf (stderr, "Usage: %s HOST [SERVICE]\n", argv[0]); | |
97 exit (1); | |
98 } | |
99 if (argc >= 2) | |
100 hostname = argv[1]; | |
101 if (argc >= 3) | |
102 service = argv[2]; | |
103 | |
104 if ((host = gethostbyname (hostname)) == NULL) | |
105 { | |
106 perror ("gethostbyname"); | |
107 exit (1); | |
108 } | |
109 if (isdigit (service[0])) | |
110 port = atoi (service); | |
111 else | |
112 { | |
113 serv = getservbyname (service, "tcp"); | |
114 if (serv == NULL) | |
115 { | |
116 perror ("getservbyname"); | |
117 exit (1); | |
118 } | |
119 port = serv->s_port; | |
120 } | |
121 | |
122 bzero (&sockin, sizeof (sockin)); | |
123 sockin.sin_family = host->h_addrtype; | |
124 bcopy (host->h_addr, &sockin.sin_addr, host->h_length); | |
14608
38829b121db7
(main): Convert port to network byte order.
Karl Heuer <kwzh@gnu.org>
parents:
14186
diff
changeset
|
125 sockin.sin_port = htons (port); |
6110 | 126 if ((server = socket (AF_INET, SOCK_STREAM, 0)) < 0) |
127 { | |
128 perror ("socket"); | |
129 exit (1); | |
130 } | |
131 if (setsockopt (server, SOL_SOCKET, SO_REUSEADDR, &false, sizeof (false))) | |
132 { | |
133 perror ("setsockopt"); | |
134 exit (1); | |
135 } | |
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) | |
140 { | |
141 perror ("bind"); | |
142 exit (1); | |
143 } | |
144 if (connect (server, &sockin, sizeof (sockin)) < 0) | |
145 { | |
146 perror ("connect"); | |
147 close (server); | |
148 exit (1); | |
149 } | |
150 | |
151 #ifdef O_NDELAY | |
152 fcntl (server, F_SETFL, O_NDELAY); | |
153 | |
154 #ifdef USG | |
155 /* USG pipe cannot not select emacsIn */ | |
156 { | |
157 struct stat statbuf; | |
158 fstat (emacsIn, &statbuf); | |
159 if (statbuf.st_mode & 010000) | |
160 selectable = 0; | |
161 if (!selectable) | |
162 { | |
163 signal (SIGINT, sigout); | |
164 fcntl (emacsIn, F_SETFL, O_NDELAY); | |
165 } | |
166 } | |
167 #endif | |
168 #endif | |
169 | |
170 /* Connection established. */ | |
171 while (1) | |
172 { | |
173 readfds = (1 << server) | (1 << emacsIn); | |
174 if (select (32, &readfds, NULL, NULL, (struct timeval *)NULL) == -1) | |
175 { | |
176 perror ("select"); | |
177 exit (1); | |
178 } | |
179 if (readfds & (1 << emacsIn)) | |
180 { | |
181 /* From Emacs */ | |
182 nbuffer = read (emacsIn, buffer, sizeof buffer -1); | |
183 | |
184 #ifdef USG | |
185 if (selectable && nbuffer == 0) | |
186 { | |
187 goto finish; | |
188 } | |
189 else if (!(readfds & (1 << server)) && nbuffer == 0) | |
190 { | |
191 sleep (1); | |
192 } | |
193 else | |
194 #else | |
195 if (nbuffer == 0) | |
196 goto finish; | |
197 #endif | |
198 for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret) | |
199 { | |
200 writefds = 1 << server; | |
201 if (select (server+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1) | |
202 { | |
203 perror ("select"); | |
204 exit (1); | |
205 } | |
206 wret = write (server, retry, nbuffer); | |
207 if (wret < 0) goto finish; | |
208 } | |
209 } | |
210 if (readfds & (1 << server)) | |
211 { | |
212 /* From NNTP server */ | |
213 nbuffer = read (server, buffer, sizeof buffer -1); | |
214 if (nbuffer == 0) | |
215 goto finish; | |
216 for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret) | |
217 { | |
218 writefds = 1 << emacsOut; | |
219 #ifdef USG | |
220 if (selectable) | |
221 #endif | |
222 if (select (emacsOut+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1) | |
223 { | |
224 perror ("select"); | |
225 exit (1); | |
226 } | |
227 wret = write (emacsOut, retry, nbuffer); | |
228 if (wret < 0) goto finish; | |
229 } | |
230 } | |
231 } | |
232 | |
233 /* End of communication. */ | |
234 finish: | |
235 close (server); | |
236 #ifdef USG | |
237 if (!selectable) fcntl (emacsIn, F_SETFL, 0); | |
238 #endif | |
239 close (emacsIn); | |
240 close (emacsOut); | |
241 exit (0); | |
242 } |