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
978
+ − 35 #ifdef HAVE_CONFIG_H
+ − 36 #include <config.h>
+ − 37 #endif
0
+ − 38 #include <stdio.h>
+ − 39 #include <fcntl.h>
+ − 40 #include <ctype.h>
+ − 41 #include <sys/types.h>
+ − 42
+ − 43 #ifdef FUJITSU_UTS
+ − 44 #define USG
+ − 45 #include <sys/ucbtypes.h>
+ − 46 #include <sys/tisp/socket.h>
+ − 47 #include <netdb.h>
+ − 48 #include <sys/tisp/in.h>
+ − 49 #else
+ − 50 #include <sys/socket.h>
+ − 51 #include <netdb.h>
+ − 52 #include <netinet/in.h>
+ − 53 #endif
+ − 54
+ − 55 #ifdef USG
+ − 56 #include <sys/stat.h>
978
+ − 57 #include "syssignal.h"
0
+ − 58 #endif
+ − 59
+ − 60 #ifdef USG
+ − 61 int selectable = 1;
+ − 62
+ − 63 sigout ()
+ − 64 {
+ − 65 fcntl (fileno (stdin), F_SETFL, 0);
+ − 66 exit (-1);
+ − 67 }
+ − 68 #endif
+ − 69
+ − 70 main (argc, argv)
+ − 71 int argc;
+ − 72 char *argv[];
+ − 73 {
+ − 74 struct hostent *host;
+ − 75 struct sockaddr_in sockin, sockme;
+ − 76 struct servent *serv;
+ − 77 char *hostname = NULL;
+ − 78 char *service = "nntp";
+ − 79 int port;
+ − 80 int readfds;
+ − 81 int writefds;
+ − 82 int server; /* NNTP Server */
+ − 83 int emacsIn = fileno (stdin); /* Emacs intput */
+ − 84 int emacsOut = fileno (stdout); /* Emacs output */
+ − 85 char buffer[1024];
+ − 86 int nbuffer; /* Number of bytes in buffer */
+ − 87 int wret;
+ − 88 char *retry; /* retry bufferp */
+ − 89 int false = 0; /* FALSE flag for setsockopt () */
+ − 90
+ − 91 if (argc < 2)
+ − 92 {
+ − 93 fprintf (stderr, "Usage: %s HOST [SERVICE]\n", argv[0]);
+ − 94 exit (1);
+ − 95 }
+ − 96 if (argc >= 2)
+ − 97 hostname = argv[1];
+ − 98 if (argc >= 3)
+ − 99 service = argv[2];
+ − 100
+ − 101 if ((host = gethostbyname (hostname)) == NULL)
+ − 102 {
+ − 103 perror ("gethostbyname");
+ − 104 exit (1);
+ − 105 }
+ − 106 if (isdigit (service[0]))
+ − 107 port = atoi (service);
+ − 108 else
+ − 109 {
+ − 110 serv = getservbyname (service, "tcp");
+ − 111 if (serv == NULL)
+ − 112 {
+ − 113 perror ("getservbyname");
+ − 114 exit (1);
+ − 115 }
+ − 116 port = serv->s_port;
+ − 117 }
+ − 118
+ − 119 memset (&sockin, 0, sizeof (sockin));
+ − 120 sockin.sin_family = host->h_addrtype;
+ − 121 memcpy (&sockin.sin_addr, host->h_addr, host->h_length);
+ − 122 sockin.sin_port = port;
+ − 123 if ((server = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ − 124 {
+ − 125 perror ("socket");
+ − 126 exit (1);
+ − 127 }
+ − 128 if (setsockopt (server, SOL_SOCKET, SO_REUSEADDR, &false, sizeof (false)))
+ − 129 {
+ − 130 perror ("setsockopt");
+ − 131 exit (1);
+ − 132 }
+ − 133 memset (&sockme, 0, sizeof (sockme));
+ − 134 sockme.sin_family = sockin.sin_family;
+ − 135 sockme.sin_addr.s_addr = INADDR_ANY;
+ − 136 if (bind (server, &sockme, sizeof (sockme)) < 0)
+ − 137 {
+ − 138 perror ("bind");
+ − 139 exit (1);
+ − 140 }
+ − 141 if (connect (server, &sockin, sizeof (sockin)) < 0)
+ − 142 {
+ − 143 perror ("connect");
+ − 144 close (server);
+ − 145 exit (1);
+ − 146 }
+ − 147
+ − 148 #ifdef O_NDELAY
+ − 149 fcntl (server, F_SETFL, O_NDELAY);
+ − 150
+ − 151 #ifdef USG
+ − 152 /* USG pipe cannot not select emacsIn */
+ − 153 {
+ − 154 struct stat statbuf;
+ − 155 fstat (emacsIn, &statbuf);
+ − 156 if (statbuf.st_mode & 010000)
+ − 157 selectable = 0;
+ − 158 if (!selectable)
+ − 159 {
+ − 160 signal (SIGINT, sigout);
+ − 161 fcntl (emacsIn, F_SETFL, O_NDELAY);
+ − 162 }
+ − 163 }
+ − 164 #endif
+ − 165 #endif
+ − 166
+ − 167 /* Connection established. */
+ − 168 while (1)
+ − 169 {
+ − 170 readfds = (1 << server) | (1 << emacsIn);
+ − 171 if (select (32, &readfds, NULL, NULL, (struct timeval *)NULL) == -1)
+ − 172 {
+ − 173 perror ("select");
+ − 174 exit (1);
+ − 175 }
+ − 176 if (readfds & (1 << emacsIn))
+ − 177 {
+ − 178 /* From Emacs */
+ − 179 nbuffer = read (emacsIn, buffer, sizeof buffer -1);
+ − 180
+ − 181 #ifdef USG
+ − 182 if (selectable && nbuffer == 0)
+ − 183 {
+ − 184 goto finish;
+ − 185 }
+ − 186 else if (!(readfds & (1 << server)) && nbuffer == 0)
+ − 187 {
+ − 188 sleep (1);
+ − 189 }
+ − 190 else
+ − 191 #else
+ − 192 if (nbuffer == 0)
+ − 193 goto finish;
+ − 194 #endif
+ − 195 for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret)
+ − 196 {
+ − 197 writefds = 1 << server;
+ − 198 if (select (server+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1)
+ − 199 {
+ − 200 perror ("select");
+ − 201 exit (1);
+ − 202 }
+ − 203 wret = write (server, retry, nbuffer);
+ − 204 if (wret < 0) goto finish;
+ − 205 }
+ − 206 }
+ − 207 if (readfds & (1 << server))
+ − 208 {
+ − 209 /* From NNTP server */
+ − 210 nbuffer = read (server, buffer, sizeof buffer -1);
+ − 211 if (nbuffer == 0)
+ − 212 goto finish;
+ − 213 for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret)
+ − 214 {
+ − 215 writefds = 1 << emacsOut;
+ − 216 #ifdef USG
+ − 217 if (selectable)
+ − 218 #endif
+ − 219 if (select (emacsOut+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1)
+ − 220 {
+ − 221 perror ("select");
+ − 222 exit (1);
+ − 223 }
+ − 224 wret = write (emacsOut, retry, nbuffer);
+ − 225 if (wret < 0) goto finish;
+ − 226 }
+ − 227 }
+ − 228 }
+ − 229
+ − 230 /* End of communication. */
+ − 231 finish:
+ − 232 close (server);
+ − 233 #ifdef USG
+ − 234 if (!selectable) fcntl (emacsIn, F_SETFL, 0);
+ − 235 #endif
+ − 236 close (emacsIn);
+ − 237 close (emacsOut);
+ − 238 exit (0);
+ − 239 }