view lib-src/tcp.c @ 22293:0544aa57ff27

(cperl-style-alist): New variable, since `c-mode' is no longer loaded. - (Somebody who uses the styles should check that they work OK!) - (a lot of work is needed, especially with new `cperl-fix-line-spacing'). Old value of style is memorized when choosing a new style, may be restored from the same menu. (cperl-perldoc, cperl-pod-to-manpage): New commands; thanks to Anthony Foiani <afoiani@uswest.com> and Nick Roberts <Nick.Roberts@src.bae.co.uk>. (`Perl doc', `Regexp'): New submenus (latter to allow short displays). (cperl-clobber-lisp-bindings): New cfg variable. (cperl-find-pods-heres): $a->y() is not y///. (cperl-after-block-p): Add save-excursion. (cperl-init-faces): Was failing. Init faces when loading `ps-print'. (cperl-toggle-autohelp): New command. (cperl-electric-paren): `while SPACE LESS' was buggy. (cperl-init-faces): `-text' in `[-text => 1]' was not highlighted. (cperl-after-block-p): was FALSE after `sub f {}'. (cperl-electric-keyword): `foreachmy', `formy' expanded too, Expands `=pod-directive'. (cperl-linefeed): behaves reasonable in POD-directive lines. (cperl-message-electric-keyword): new cfg variable. (cperl-electric-keyword): print a message, governed by `cperl-message-electric-keyword'. (cperl-electric-paren): Typing `}' was not checking for being block or not. (cperl-beautify-regexp-piece): Did not know about lookbehind; finding *which* level to work with was not intuitive. (cperl-beautify-levels): New command. (cperl-electric-keyword): Allow here-docs contain `=head1' and friends for keyword expansion. Fix for broken `font-lock-unfontify-region-function'. Should preserve `syntax-table' properties even with `lazy-lock'. (cperl-indent-region-fix-else): New command. (cperl-fix-line-spacing): New command. (cperl-invert-if-unless): New command (C-c C-t and in Menu). (cperl-hints): mention 20.2's goods/bads. (cperl-extra-newline-before-brace-multiline): Started to use it. (cperl-break-one-line-blocks-when-indent): New cfg variable. (cperl-fix-hanging-brace-when-indent): New cfg variable. (cperl-merge-trailing-else): New cfg variable. Workaround for another `font-lock's `syntax-table' text-property bug. `zerop' could be applied to nil. At last, may work with `font-lock' without setting `cperl-font-lock'. (cperl-indent-region-fix-constructs): Renamed from `cperl-indent-region-fix-constructs'. (cperl-fix-line-spacing): could be triggered inside strings, would not know what to do with BLOCKs of map/printf/etc. (cperl-merge-trailing-else): Handle `continue' too. (cperl-fix-line-spacing): Likewise. (cperl-calculate-indent): Knows about map/printf/etc before {BLOCK}; treat after-comma lines as continuation lines. (cperl-mode): `continue' made electric. (cperl-electric-keyword): Electric `do' inserts `do/while'. (cperl-fontify-syntaxically): New function. (cperl-syntaxify-by-font-lock): New cfg variable. Make syntaxification to be autoredone via `font-lock', switched on by `cperl-syntaxify-by-font-lock', off by default so far. Remove some commented out chunks. (cperl-set-style-back): Old value of style is memorized when choosing a new style, may be restored from the same menu. Mode-documentation added to micro-docs. (cperl-praise): updated. (cperl-toggle-construct-fix): New command. Added on C-c C-w and menu. (auto-fill-mode): added on C-c C-f and menu. (cperl-style-alist): `PerlStyle' style added. (cperl-find-pods-heres): Message for termination of scan corrected. (cperl-speed): New variable with hints. (cperl-electric-else): Make backspace electric after expansion of `else/continue' too. Fixed customization to honor cperl-hairy. Created customization groups. All the compile-time warnings fixed. (cperl-syntaxify-by-font-lock): Interaction with `font-lock-hot-pass' fixed. (cperl-after-block-and-statement-beg): It is BLOCK if we reach lim when backup sexp. (cperl-after-block-p, cperl-after-expr-p): Likewise. (cperl-indent-region): Make a marker for END - text added/removed. (cperl-style-alist): Include `cperl-merge-trailing-else' where the value is clear. (cperl-styles-entries): Likewise. (cperl-tips, cperl-problems): Improvements to docs.
author Richard M. Stallman <rms@gnu.org>
date Sat, 30 May 1998 15:43:16 +0000
parents 38829b121db7
children 60712692fdbc
line wrap: on
line source

/*
 * TCP/IP stream emulation for GNU Emacs.
 * Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.

 * Author: Masanobu Umeda
 * Maintainer: umerin@mse.kyutech.ac.jp

This file is part of GNU Emacs.

GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING.  If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.

 *
 * Yasunari, Itoh at PFU limited contributed for Fujitsu UTS and SX/A.
 *
 * Thu Apr  6 13:47:37 JST 1989
 * USG fixes by Sakaeda <saka@mickey.trad.pf.fujitsu.junet>
 *
 * For Fujitsu UTS compile with:
 *	cc -O -o tcp tcp.c -DFUJITSU_UTS -lu -lsocket
 */

#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/types.h>

#ifdef FUJITSU_UTS
#define USG
#include <sys/ucbtypes.h>
#include <sys/tisp/socket.h>
#include <netdb.h>
#include <sys/tisp/in.h>
#else
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#endif

#ifdef USG
#include <sys/stat.h>
#include <signal.h>
#endif

#ifdef FUJITSU_UTS
#define bcopy(f, t, n)    memcpy (t, f, n)
#define bcmp(b1, b2, n)   (memcmp (b1, b2, n)!=0)
#define bzero(b, n)      memset (b, 0, n)
#endif

#ifdef USG
int selectable = 1;

sigout ()
{
  fcntl (fileno (stdin), F_SETFL, 0);
  exit (-1);
}
#endif

main (argc, argv)
     int argc;
     char *argv[];
{
  struct hostent	*host;
  struct sockaddr_in	sockin, sockme;
  struct servent	*serv;
  char	*hostname = NULL;
  char	*service = "nntp";
  int	port;
  int	readfds;
  int   writefds;
  int	server;			/* NNTP Server */
  int	emacsIn = fileno (stdin); /* Emacs intput */
  int	emacsOut = fileno (stdout); /* Emacs output */
  char	buffer[1024];
  int	nbuffer;		/* Number of bytes in buffer */
  int   wret;
  char  *retry;			/* retry bufferp */
  int   false = 0;		/* FALSE flag for setsockopt () */

  if (argc < 2)
    {
      fprintf (stderr, "Usage: %s HOST [SERVICE]\n", argv[0]);
      exit (1);
    }
  if (argc >= 2)
    hostname = argv[1];
  if (argc >= 3)
    service = argv[2];

  if ((host = gethostbyname (hostname)) == NULL)
    {
      perror ("gethostbyname");
      exit (1);
    }
  if (isdigit (service[0]))
    port = atoi (service);
  else
    {
      serv = getservbyname (service, "tcp");
      if (serv == NULL)
	{
	  perror ("getservbyname");
	  exit (1);
	}
      port = serv->s_port;
    }

  bzero (&sockin, sizeof (sockin));
  sockin.sin_family = host->h_addrtype;
  bcopy (host->h_addr, &sockin.sin_addr, host->h_length);
  sockin.sin_port = htons (port);
  if ((server = socket (AF_INET, SOCK_STREAM, 0)) < 0)
    {
      perror ("socket");
      exit (1);
    }
  if (setsockopt (server, SOL_SOCKET, SO_REUSEADDR, &false, sizeof (false)))
    {
      perror ("setsockopt");
      exit (1);
    }
  bzero (&sockme, sizeof (sockme));
  sockme.sin_family = sockin.sin_family;
  sockme.sin_addr.s_addr = INADDR_ANY;
  if (bind (server, &sockme, sizeof (sockme)) < 0)
    {
      perror ("bind");
      exit (1);
    }
  if (connect (server, &sockin, sizeof (sockin)) < 0)
    {
      perror ("connect");
      close (server);
      exit (1);
    }

#ifdef O_NDELAY
  fcntl (server, F_SETFL, O_NDELAY);

#ifdef USG
  /* USG pipe cannot not select emacsIn */
  {
    struct stat statbuf;
    fstat (emacsIn, &statbuf);
    if (statbuf.st_mode & 010000)
      selectable = 0;
    if (!selectable)
      {
	signal (SIGINT, sigout);
	fcntl (emacsIn, F_SETFL, O_NDELAY);
      }
  }
#endif
#endif

  /* Connection established. */
  while (1)
    {
      readfds = (1 << server) | (1 << emacsIn);
      if (select (32, &readfds, NULL, NULL, (struct timeval *)NULL) == -1)
	{
	  perror ("select");
	  exit (1);
	}
      if (readfds & (1 << emacsIn))
	{
	  /* From Emacs */
	  nbuffer = read (emacsIn, buffer, sizeof buffer -1);

#ifdef USG
	  if (selectable && nbuffer == 0)
	    {
	      goto finish;
	    }
	  else if (!(readfds & (1 << server)) && nbuffer == 0)
	    {
	      sleep (1);
	    }
	  else 
#else
	    if (nbuffer == 0)
	      goto finish;
#endif
	  for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret)
	    {
	      writefds = 1 << server;
	      if (select (server+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1)
		{
		  perror ("select");
		  exit (1);
		}
	      wret = write (server, retry, nbuffer);
	      if (wret < 0) goto finish;
	    }
	}
      if (readfds & (1 << server))
	{
	  /* From NNTP server */
	  nbuffer = read (server, buffer, sizeof buffer -1);
	  if (nbuffer == 0)
	    goto finish;
	  for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret)
	    {
	      writefds = 1 << emacsOut;
#ifdef USG
	      if (selectable)
#endif
		if (select (emacsOut+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1)
		  {
		    perror ("select");
		    exit (1);
		  }
	      wret = write (emacsOut, retry, nbuffer);
	      if (wret < 0) goto finish;
	    }
	}
    }

  /* End of communication. */
 finish:
  close (server);
#ifdef USG
  if (!selectable) fcntl (emacsIn, F_SETFL, 0);
#endif
  close (emacsIn);
  close (emacsOut);
  exit (0);
}