From:	ADVAX::"mcnc!VM1.NoDak.EDU!GIH900%SAO.AARNET.EDU.AU" "Geoff Huston"  7-JUN-1990 22:10:38.87
To:	Multiple recipients of list ANU-NEWS <ANU-NEWS@NDSUVM1>
CC:	
Subj:	RE: NNTP with NEWS 5.8 on VMS 4.7

Received: by ADVAX.DECnet (utk-mail11 v1.5) ; Thu, 7 Jun 90 22:11:25 EDT
Received:  from mcnc by ge-dab.GE.COM (5.61/GE-DAB 1.11) with UUCP
	id AA08751 for everhart; Thu, 7 Jun 90 22:11:12 -0400
Received: from VM1.NoDak.EDU by mcnc.mcnc.org (5.59/MCNC/5-16-88)
	id AA11410; Thu, 7 Jun 90 21:14:37 EDT
Message-Id: <9006080114.AA11410@mcnc.mcnc.org>
Received: from NDSUVM1.BITNET by VM1.NoDak.EDU (IBM VM SMTP R1.2.1MX) with BSMTP id 3027; Thu, 07 Jun 90 20:13:11 CDT
Received: from NDSUVM1.BITNET by NDSUVM1.BITNET (Mailer R2.07) with BSMTP id
 3013; Thu, 07 Jun 90 20:13:09 CDT
Date:         Fri, 8 Jun 90 11:12:08 GMT
Reply-To: Geoff Huston <mcnc!VM1.NoDak.EDU!GIH900%SAO.AARNET.EDU.AU>
Sender: ANU-NEWS Discussion <ANU-NEWS@VM1.NoDak.EDU>
From: Geoff Huston <mcnc!VM1.NoDak.EDU!GIH900%SAO.AARNET.EDU.AU>
Subject:      RE: NNTP with NEWS 5.8 on VMS 4.7
X-To:         ANU-NEWS@vm1.nodak.edu
To: Multiple recipients of list ANU-NEWS <ANU-NEWS@NDSUVM1>
 
>I'm trying to install ANU news 5.8 on psuecl, so that I can take advantage
>of the NNTP server.  Now, for many varied reasons, we're still running VMS
>4.7.  No problem, right?  Just get the objects and relink.  Ok, so, I got
>the objects and relinked.  News works fine, however, nntp_tcpcmu simply
>exits, whether I run it myself standalone or telnet to port 119.  It's
>installed with sysprv, telnetting to port 119 does actually run the program,
>it simply exits and closes the connection a second after it's opened.
>
>Anyone have any suggestions as to what to try?  Do you need more information?
>I got news_v58_obj.bck_z from kuhub.
 
OK there's some kind of problem with getting the remote node name on a TCP
connection with NNTP_TCPCMU.C
 
The following describes a patch to get around the problem as documented at the
base of the file within procedure getremhost()
 
 
Geoff
--------------------------------------
 
NNTP_TCPCMU.C
 
 
/*
**++
**  FACILITY:
**      NNTP_TCPCMU
**
**  ABSTRACT:
**      This module contains the QIO interface to the CMU/Tek implementation
**	of TCP/IP.  The module provices a single-threaded interface to
**	the NEWSSERVER module.
**
**  AUTHOR:
**      Geoff Huston
**
**  COPYRIGHT:
**      Copyright ) 1988
**
**  MODIFICATION HISTORY:
**      V5.3    14-Jun-1988 POK     (PEKKA KYTOLAAKSO VTKK/TLP)
**                                  Made some changes in READ_NET, Compile with
**                                  CC/DEFINE=DEBUG to get trace of the TCP/IP
**                                  traffic in file sy$manager:sys$error.
**
**	V5.5	 7-Oct-1988	GIH
**          Revised call interface to server added
**
**      V5.7    13-Dec-1988     GIH
**        - There still was an error in WIN support. READ_NET both in
**          nntp_tcpwin.c and in nntp_tcpcmu.c had an error.
**          change: if (!iosb[1]) return(-1);
**          to:     if (!iosb[1]) return(cancel_net(),-1);
**          Also make nntp_getchar a bit faster by defining it as a macro
**             Pekka Kytolaakso
**      V5.8    22-Feb-1989     GIH
**        - "While testing NEWS 5.7 I noticed that the CMU NNTP server did not
**          work properly.  When attempting to use NNTP_CLIENT to test the
**          server, it continually aborted on the READ sys$qiow in
**          nntp_fillbuf() in NNTP_TCPCMU.C.  After looking at all of the other
**          CMU code, the patch below seems to fix the problem.  I do not know
**          what other effects this might have, but it does seem to make the
**          server work. " Scott Allendorf, Astronomy System Manager,
**          The University of Iowa, sca@ceres.physics.uiowa.edu
**
**          #define X_BUF_SIZE  1024    - size of line assembly read buffer
**                    Changed from 2048 to 1024 - SCA 890128
**        - Add getremhost function
**      V5.9    18-Apr-1989
**        - Minor changes to allow complication by GNUCC compiler
**--
**/
 
#if vax11c
#module NNTP_TCPCMU "V5.8"
#endif
 
#if vax11c
#include descrip
#include iodef
#include signal
#include stdio
#else
#include <descrip.h>
#include <iodef.h>
#include <signal.h>
#include <stdio.h>
#endif
 
#define DEBUG       0
#define TIMEOUT     600         /* read wait timeout  - 10 minutes */
#define X_BUF_SIZE  1024        /* size of line assembly read buffer */
 
                                /* check status bits */
#define cks(s)      if (!((c$status = (s)) & 1)) lib$signal(c$status)
 
#define nntp_getchar() (!nntp_input_size ? nntp_fillbuf() : (--nntp_input_size,
*nntp_input_ptr++))
 
static unsigned short f;               /* tcp i/o channel */
 
static int c$status;                   /* return status */
 
static unsigned short iosb[4];    /* i/o status blocks */
static unsigned short *i_o_sts = iosb;
static char nntp_input_buffer[X_BUF_SIZE];
static char *nntp_input_ptr = nntp_input_buffer;
static int nntp_input_size = 0;
 
#define POK_OUTPUT_BUFFER
#ifdef POK_OUTPUT_BUFFER
static char nntp_output_buffer[X_BUF_SIZE];	/* NNTP output buffer */
static char *nntp_output_ptr = nntp_output_buffer;
static int nntp_output_size = X_BUF_SIZE;
#endif
 
int (*next_function)();
 
#if DEBUG
FILE *flog;
#define LOGFILE "NEWS_MANAGER:NNTP.LOG"
#endif
 
main()
{
#if DEBUG
    int cur_time;
 
    time(&cur_time);
    flog = fopen(LOGFILE,"a+");
    fprintf(flog,"TCP CMU open NNTP Connection %s",ctime(&cur_time));
    fclose(flog);
#endif
 
    if (!server_init(1)) exit(1);
#if DEBUG
    flog = fopen(LOGFILE,"a+");
    fprintf(flog,"server init\n");
    fclose(flog);
#endif
    if (!open_net()) exit(1);
#if DEBUG
    flog = fopen(LOGFILE,"a+");
    fprintf(flog,"opened net\n");
    fclose(flog);
#endif
    server_init_unit(1);
#if DEBUG
    flog = fopen(LOGFILE,"a+");
    fprintf(flog,"server unit inited\n");
    fclose(flog);
#endif
    while (next_function) {
 
#ifdef POK_OUTPUT_BUFFER
      write_out();
#endif
      (*next_function)(1);
      }
    server_shut();
    close_net();
#if DEBUG
    flog = fopen(LOGFILE,"a+");
    fprintf(flog,"net closed\n");
    fclose(flog);
#endif
}
 
/*
 *  cancel_net
 *
 *  If the read timer expires then cancel this server task (by exiting)
 */
 
cancel_net()
{
#if DEBUG
    fprintf(stderr,"Cancel_net\n");
#endif
    sys$cancel(f);
    log_to_file(1);
    write_net("400 service discontinued - read timeout\r\n");
 
#ifdef POK_OUTPUT_BUFFER
    write_out();
#endif
 
    cks(sys$qiow(0,f,IO$_DELETE,iosb,0,0,0,0,0,0,0,0));
    cks(*i_o_sts);
    sys$dassgn(f);
    exit(1);
}
 
static int nntp_fillbuf()
{
    signal(SIGALRM,cancel_net);
    alarm(TIMEOUT);
    cks(sys$qiow(0,f,IO$_READVBLK,iosb,0,0,nntp_input_buffer,
                 sizeof(nntp_input_buffer),0,0,0,0));
    alarm(0);
    if (!iosb[1]) return(cancel_net(),-1);
    nntp_input_ptr = nntp_input_buffer;
    nntp_input_size = iosb[1]-1;
    return(*nntp_input_ptr++);
}
 
/*
 *  read_net
 *
 *  Get a line of text from the server.  Strips CR's and LF's.
 *  Parameters:     string  has the buffer space for the line received.
 *                  size    is the size of the buffer.
 *  Returns:           -1 on error, 0 otherwise.
 *  Side effects:      Talks to server, changes contents of "string"
 */
 
read_net(string, size,unit)
    char *string;
    int size;
    int unit;
{
    char *cp;
    int c = 0;
 
    for (cp = string; size; size--) {
        c = nntp_getchar();
        if (c == '\r') c = nntp_getchar(); /* skip CR */
        *cp++ = c;
        if (c == '\n') break;
        }
    *cp = '\0';
#if DEBUG
    fprintf(stderr,"Read_net:%s\n",string);
#endif
    return(0);
}
 
/*
 *  write_net
 *
 *  write to the client process - catch i/o errors and abort
 */
 
#ifdef POK_OUTPUT_BUFFER
/*  this asumes that nobody ever writes more than X_BUF_SIZE bytes */
 
write_net(s,unit)
  char *s;
  int unit;
{
  register int size = strlen(s);
 
#if DEBUG
  fprintf(stderr,"Write_net:%s\n",s);
#endif
 
  if (nntp_output_size < size) write_out(); /* no space in buffer - flush */
  strncpy(nntp_output_ptr,s,size);
  nntp_output_ptr += size;
  nntp_output_size -= size;
}
 
write_out()
{
  if (nntp_output_ptr != nntp_output_buffer) {  /* something in the buffer */
    cks(sys$qiow(0,f,IO$_WRITEVBLK,iosb,0,0,nntp_output_buffer,
                 nntp_output_ptr - nntp_output_buffer,0,1,0,0));
    cks(*i_o_sts);
    nntp_output_ptr = nntp_output_buffer;
    nntp_output_size = X_BUF_SIZE;
    }
}
#else
 
write_net(s,unit)
  char *s;
  int unit;
{
#if DEBUG
  fprintf(stderr,"Write_net:%s\n",s);
#endif
 
  cks(sys$qiow(0,f,IO$_WRITEVBLK,iosb,0,0,s,strlen(s),0,1,0,0));
  cks(*i_o_sts);
}
#endif
 
next_call(unit,func,type)
    int unit;
    int (*func)();
    int type;
{
    next_function = func;
}
 
/*
 *  open_net
 *
 *  Open TCP channel
 */
 
open_net()
{
    $DESCRIPTOR(ipdsc,"IP:");
 
#if DEBUG
    fprintf(stderr,"Open_net\n");
#endif
    cks(sys$assign(&ipdsc,&f,0,0));
    cks(sys$qiow(0,f,IO$_CREATE,iosb,0,0,0,0,119,0,0,0));
    cks(*i_o_sts);
    return(1);
}
 
/*
 *  close_net
 *
 *  Close the TCP link
 */
 
close_net()
{
#if DEBUG
  fprintf(stderr,"Close_net\n");
#endif
 
#ifdef POK_OUTPUT_BUFFER
  write_out();
#endif
 
  sys$cancel(f);
  log_to_file(1);
  cks(sys$qiow(0,f,IO$_DELETE,iosb,0,0,0,0,0,0,0,0));
  cks(*i_o_sts);
  sys$dassgn(f);
}
 
/*
 *  getremhost
 *
 *  Return the remote host name
 */
 
struct ib {
    unsigned char fhost_len;
    unsigned char lhost_len;
    char fhost[128];
    short fill;
    unsigned short fport;
    short fill_1;
    char lhost[128];
    unsigned short lport;
    short fill_2;
    unsigned int linet_addr;
    unsigned int finet_addr;
    } _align(quadword) info_buffer;
 
void  getremhost(remhost,remuser,unit)
  char *remhost, *remuser; int unit;
{
  if (remhost) {
 
/* I have had some trouble with this call - it is reinserted in the
   distribution verion - BUT - take it out if you cannot get it to work,
   and replace it with the single line following!
 
    strcpy(remhost,"tcp");
*/
 
 
cks(sys$qiow(0,f,IO$_MODIFY,iosb,0,0,&info_buffer,sizeof(info_buffer),0,0,0,0));
    cks(*i_o_sts);
    strncpy(remhost,info_buffer.fhost,info_buffer.fhost_len);
    remhost[info_buffer.fhost_len] = '\0';
 
    if (!*remhost)	/* the name resolver may have failed with a timeout */
      sprintf(remhost,"%d.%d.%d.%d",
                (info_buffer.finet_addr) & 0xff,
                (info_buffer.finet_addr >> 8) & 0xff,
                (info_buffer.finet_addr >> 16) & 0xff,
                (info_buffer.finet_addr >> 24) & 0xff);
 
 
/* if you cannot get it to work comment out the above block and put back the
   strcpy line! */
 
    }
  if (remuser) strcpy(remuser,"nntp");
}
