0
+ − 1 /*
613
+ − 2 * TCP/IP stream emulation for XEmacs.
0
+ − 3 * Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
+ − 4
+ − 5 * Author: Masanobu Umeda
+ − 6 * Maintainer: umerin@mse.kyutech.ac.jp
+ − 7
613
+ − 8 This file is part of XEmacs.
0
+ − 9
613
+ − 10 XEmacs is free software; you can redistribute it and/or modify
0
+ − 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
613
+ − 15 XEmacs is distributed in the hope that it will be useful,
0
+ − 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
613
+ − 21 along with XEmacs; see the file COPYING. If not, write to
0
+ − 22 the Free the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 23 Boston, MA 02111-1307, USA.
+ − 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 USG
+ − 58 int selectable = 1;
+ − 59
+ − 60 sigout ()
+ − 61 {
+ − 62 fcntl (fileno (stdin), F_SETFL, 0);
+ − 63 exit (-1);
+ − 64 }
+ − 65 #endif
+ − 66
+ − 67 main (argc, argv)
+ − 68 int argc;
+ − 69 char *argv[];
+ − 70 {
+ − 71 struct hostent *host;
+ − 72 struct sockaddr_in sockin, sockme;
+ − 73 struct servent *serv;
+ − 74 char *hostname = NULL;
+ − 75 char *service = "nntp";
+ − 76 int port;
+ − 77 int readfds;
+ − 78 int writefds;
+ − 79 int server; /* NNTP Server */
+ − 80 int emacsIn = fileno (stdin); /* Emacs intput */
+ − 81 int emacsOut = fileno (stdout); /* Emacs output */
+ − 82 char buffer[1024];
+ − 83 int nbuffer; /* Number of bytes in buffer */
+ − 84 int wret;
+ − 85 char *retry; /* retry bufferp */
+ − 86 int false = 0; /* FALSE flag for setsockopt () */
+ − 87
+ − 88 if (argc < 2)
+ − 89 {
+ − 90 fprintf (stderr, "Usage: %s HOST [SERVICE]\n", argv[0]);
+ − 91 exit (1);
+ − 92 }
+ − 93 if (argc >= 2)
+ − 94 hostname = argv[1];
+ − 95 if (argc >= 3)
+ − 96 service = argv[2];
+ − 97
+ − 98 if ((host = gethostbyname (hostname)) == NULL)
+ − 99 {
+ − 100 perror ("gethostbyname");
+ − 101 exit (1);
+ − 102 }
+ − 103 if (isdigit (service[0]))
+ − 104 port = atoi (service);
+ − 105 else
+ − 106 {
+ − 107 serv = getservbyname (service, "tcp");
+ − 108 if (serv == NULL)
+ − 109 {
+ − 110 perror ("getservbyname");
+ − 111 exit (1);
+ − 112 }
+ − 113 port = serv->s_port;
+ − 114 }
+ − 115
+ − 116 memset (&sockin, 0, sizeof (sockin));
+ − 117 sockin.sin_family = host->h_addrtype;
+ − 118 memcpy (&sockin.sin_addr, host->h_addr, host->h_length);
+ − 119 sockin.sin_port = port;
+ − 120 if ((server = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ − 121 {
+ − 122 perror ("socket");
+ − 123 exit (1);
+ − 124 }
+ − 125 if (setsockopt (server, SOL_SOCKET, SO_REUSEADDR, &false, sizeof (false)))
+ − 126 {
+ − 127 perror ("setsockopt");
+ − 128 exit (1);
+ − 129 }
+ − 130 memset (&sockme, 0, sizeof (sockme));
+ − 131 sockme.sin_family = sockin.sin_family;
+ − 132 sockme.sin_addr.s_addr = INADDR_ANY;
+ − 133 if (bind (server, &sockme, sizeof (sockme)) < 0)
+ − 134 {
+ − 135 perror ("bind");
+ − 136 exit (1);
+ − 137 }
+ − 138 if (connect (server, &sockin, sizeof (sockin)) < 0)
+ − 139 {
+ − 140 perror ("connect");
+ − 141 close (server);
+ − 142 exit (1);
+ − 143 }
+ − 144
+ − 145 #ifdef O_NDELAY
+ − 146 fcntl (server, F_SETFL, O_NDELAY);
+ − 147
+ − 148 #ifdef USG
+ − 149 /* USG pipe cannot not select emacsIn */
+ − 150 {
+ − 151 struct stat statbuf;
+ − 152 fstat (emacsIn, &statbuf);
+ − 153 if (statbuf.st_mode & 010000)
+ − 154 selectable = 0;
+ − 155 if (!selectable)
+ − 156 {
+ − 157 signal (SIGINT, sigout);
+ − 158 fcntl (emacsIn, F_SETFL, O_NDELAY);
+ − 159 }
+ − 160 }
+ − 161 #endif
+ − 162 #endif
+ − 163
+ − 164 /* Connection established. */
+ − 165 while (1)
+ − 166 {
+ − 167 readfds = (1 << server) | (1 << emacsIn);
+ − 168 if (select (32, &readfds, NULL, NULL, (struct timeval *)NULL) == -1)
+ − 169 {
+ − 170 perror ("select");
+ − 171 exit (1);
+ − 172 }
+ − 173 if (readfds & (1 << emacsIn))
+ − 174 {
+ − 175 /* From Emacs */
+ − 176 nbuffer = read (emacsIn, buffer, sizeof buffer -1);
+ − 177
+ − 178 #ifdef USG
+ − 179 if (selectable && nbuffer == 0)
+ − 180 {
+ − 181 goto finish;
+ − 182 }
+ − 183 else if (!(readfds & (1 << server)) && nbuffer == 0)
+ − 184 {
+ − 185 sleep (1);
+ − 186 }
+ − 187 else
+ − 188 #else
+ − 189 if (nbuffer == 0)
+ − 190 goto finish;
+ − 191 #endif
+ − 192 for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret)
+ − 193 {
+ − 194 writefds = 1 << server;
+ − 195 if (select (server+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1)
+ − 196 {
+ − 197 perror ("select");
+ − 198 exit (1);
+ − 199 }
+ − 200 wret = write (server, retry, nbuffer);
+ − 201 if (wret < 0) goto finish;
+ − 202 }
+ − 203 }
+ − 204 if (readfds & (1 << server))
+ − 205 {
+ − 206 /* From NNTP server */
+ − 207 nbuffer = read (server, buffer, sizeof buffer -1);
+ − 208 if (nbuffer == 0)
+ − 209 goto finish;
+ − 210 for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret)
+ − 211 {
+ − 212 writefds = 1 << emacsOut;
+ − 213 #ifdef USG
+ − 214 if (selectable)
+ − 215 #endif
+ − 216 if (select (emacsOut+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1)
+ − 217 {
+ − 218 perror ("select");
+ − 219 exit (1);
+ − 220 }
+ − 221 wret = write (emacsOut, retry, nbuffer);
+ − 222 if (wret < 0) goto finish;
+ − 223 }
+ − 224 }
+ − 225 }
+ − 226
+ − 227 /* End of communication. */
+ − 228 finish:
+ − 229 close (server);
+ − 230 #ifdef USG
+ − 231 if (!selectable) fcntl (emacsIn, F_SETFL, 0);
+ − 232 #endif
+ − 233 close (emacsIn);
+ − 234 close (emacsOut);
+ − 235 exit (0);
+ − 236 }