[news.software.anu-news] NEWS V59A - DIFF/SLP version 2/3

gih900@csc.anu.oz (Geoff Huston) (10/10/89)

-+-+-+-+-+-+-+-+ START OF PART 2 -+-+-+-+-+-+-+-+
X  itmrab.rab$l_rop = RAB$M_KGE `124 RAB$M_RRL `124 RAB$M_NLK;
X  itmrab.rab$b_rac = RAB$C_KEY;
X  if (   !(sys$get(&itmrab) & 1)
X      `124`124 strcmp(l_id,newsitm.itm_id)
X      `124`124 !(sys$get(&grprab) & 1))
X    return(0);
X  itmrab.rab$b_rac = RAB$C_SEQ;
X  while (!check_ngperm(newsgrp.grp_name,stm))
X    if (   !(sys$get(&itmrab) & 1)
X        `124`124 strcmp(l_id,newsitm.itm_id)
X        `124`124 !(sys$get(&grprab) & 1))
X      return((*msg_status = M502),0);
X  sprintf(itm_fname,Itm_template,util_dir(newsgrp.grp_name),newsitm.itm_num)
V;
X  return(fopen(itm_fname,"r"));
X- 2165, 2166
X    if ((!strcmp(ibuf,"..\n")) && (fpl)) `123
X      --ihave_size;
X      fputs(ibuf + 1,fpl);
X      `125
X    else if (fpl) fputs(ibuf,fpl);
X    ihave_size += strlen(ibuf);
X/
$ CALL UNPACK NNTP_SERVER.SLP;2 1182717569
$ create/nolog 'f'
X-   67,   67
X#define DEBUG       0
X-  267,  267
X-  275,  275
X    `125 _align(quadword) info_buffer;
X-  282,  282
X        cks(sys$qiow(0,f,IO$_MODIFY,iosb,0,0,&info_buffer,sizeof(info_buffer
V),0,0,0,0));
X/
$ CALL UNPACK NNTP_TCPCMU.SLP;2 1429166531
$ create/nolog 'f'
X/
$ CALL UNPACK NNTP_TCPWIN.SLP;1 47
$ create/nolog 'f'
X/
$ CALL UNPACK NNTP_TTY.SLP;1 47
$ create/nolog 'f'
X/*
X**++
X**  FACILITY:
X**      NNTP_XFER
X**
X**  ABSTRACT:
X**      Use the NNTP NEWNEWS commands to implement a feed initiated by the
X**      receiver rather than the IHAVE/SENDME protocol which is sender
X**      initiated.
X**
X**  AUTHOR:
X**      Geoff Huston
X**
X**  COPYRIGHT:
X**      Copyright `169 1989
X**
X**  MODIFICATION HISTORY:
X**      V5.9.1`00925-Sep-1989`009GIH
X**`009    Initial version, based on NNTP_FEED
X**--
X**/
X`012
X#module NNTP_XFER "V5.9"
X
X#include "newsinclude.h"
X#include "newsdefine.h"
X
X#include iodef
X#include time
X#include signal
X
X#define DAYS       4
X
X#define CMUTCP     1
X#define WINTCP     2
X#define SRITCP     3
X
X#ifdef  TWG
X#define TWG        1
X#else
X#ifdef  SRI
X#define SRI        1
X#endif
X#endif
X
X#if TWG `124`124 SRI
X#include <types.h>
X#include <socket.h>
X#include <netdb.h>
X#include <in.h>
X#include <inetiodef.h>
X
X#define NNTP_PORT       (119)
X
Xstruct hostent *dest_host;
Xstruct sockaddr_in data_socket = `1230`125;
X#endif
X
X#define CLIENT_TIMER    250
X#define RESP_TIMER      30
X#define X_BUF_SIZE      1024
X#define MAX_BATCH_SIZE  250000
X#define MAX_RESTART_ATTEMPT`00920
X
Xchar net_open_chan`091128`093 = `123""`125,
X     ibuf`091X_BUF_SIZE`093,
X     fnode`091256`093,
X     scratch_area`091256`093;
X
Xshort net_chan;
X
Xint cmd_code,
X    offered = 0,
X    accepted = 0,
X    proto_num = 0,
X    net_proto = 0,
X    debugging = 0,
X    logging = 0;
X
Xstruct iosb_block `123
X    unsigned short iostatus;
X    unsigned short iosize;
X    int netinfo;
X    `125 iosb,
X      write_iosb;
X
Xint *c$_tmphead = 0;         /* head of side list */
X
Xchar node`091128`093,
X     logfile`091256`093;
X
Xchar *s_to_upper();
X`012
X`012
X/*
X *  c$alloc_tmp
X *
X *  Allocate temporary storage for use with c$ calls
X */
X
Xint *c$alloc_tmp(size)
X  int size;
X`123
X  int *tmp;
X
X  tmp = malloc(size + 4);
X  *tmp = c$_tmphead;
X  c$_tmphead = tmp;
X  return(c$_tmphead + 1);
X`125
X
X/*
X *  c$dsc
X *
X * Allocate a string descriptor in the temp arg area
X */
X
Xc$dsc(str)
X  char *str;
X`123
X  struct dsc$descriptor *tmpdsc;
X
X  tmpdsc = c$alloc_tmp(8);
X  tmpdsc->dsc$w_length = strlen(str);
X  tmpdsc->dsc$b_dtype = DSC$K_DTYPE_T;
X  tmpdsc->dsc$b_class = DSC$K_CLASS_S;
X  tmpdsc->dsc$a_pointer = str;
X  return(tmpdsc);
X`125
X
X/*
X *  c$cks
X *
X *  Check return status, signal errors, and free the temp argument area
X */
X
Xc$cks(status)
X  int status;
X`123
X  int *tmp;
X
X  if (!(status & 1)) lib$signal(status);
X  while (c$_tmphead) `123
X    tmp = *c$_tmphead;
X    free(c$_tmphead);
X    c$_tmphead = tmp;
X    `125
X  return(status);
X`125
X
X/*
X *  nosysprv
X *
X *  Turn off installed sysprv - BUT if user already had sysprv from AUTHORIZ
VE
X *  then leave it on (as there is no change in user functionality)
X */
X
Xnosysprv()
X`123
X  unsigned int authprivs`0912`093, msysprv`0912`093 ;
X  int item = JPI$_AUTHPRIV;
X
X  msysprv`0910`093 = PRV$M_SYSPRV;
X  msysprv`0911`093 = 0;
X  c$cks(lib$getjpi(&item,0,0,&authprivs,0,0));
X  if (!(authprivs`0910`093 & PRV$M_SYSPRV)) c$cks(sys$setprv(0,msysprv,0,0))
V;
X`125
X
X/*
X *  sysprv
X *
X *  Turn sysprv on as a temp priv - assumes image was installed with SYSPRV
X */
X
Xsysprv()
X`123
X  unsigned int msysprv`0912`093;
X
X  msysprv`0910`093 = PRV$M_SYSPRV;
X  msysprv`0911`093 = 0;
X  c$cks(sys$setprv(1,msysprv,0,0));
X`125
X`012
X/*
X *  nntp_write
X *
X *  Synchronous write of a string to the net channel
X */
X
Xnntp_write(b)
X  char *b;
X`123
X  static char obuf`091512`093;
X  int sts;
X
X  strcpy(obuf,b);
X  strcat(obuf,"\r\n");
X  if (debugging) printf("nntp_write: %s",obuf);
X  sts = sys$qiow(0,net_chan,IO$_WRITEVBLK,&write_iosb,0,0,
X                      obuf,strlen(obuf),0,(net_proto == CMUTCP),0,0);
X  if (!(sts & 1) `124`124 !(write_iosb.iostatus & 1)) `123
X    close_net();
X    if (debugging) printf("nntp_write: Lost connection to Server\n");
X    return(0);
X    `125
X  return(1);
X`125
X`012
X/*
X *  nntp_read
X *
X *  Timed read of the net channel for a full line
X */
X
Xjmp_buf nntp_env;
X
Xcancel_nntp_read()
X`123
X  close_net();
X  if (debugging) printf("nntp_read: ReadTimeout - Lost connection\n");
X  longjmp(nntp_env,1);
X`125
X
Xnntp_read(b,timer)
X  char *b;
X  int timer;
X`123
X  static char ibuf`091X_BUF_SIZE + 1`093;
X  struct iosb_block r_iosb;
X  char *cp, *rp;
X  int sts;
X
X  *b = '\0';
X  if (setjmp(nntp_env)) return(0);
X  signal(SIGALRM,cancel_nntp_read);
X  alarm(timer);
X  sts = sys$qiow(0,net_chan,IO$_READVBLK,&r_iosb,0,0,ibuf,X_BUF_SIZE,0,0,0,0
V);
X  alarm(0);
X  if (!(sts & 1) `124`124 (!(r_iosb.iostatus & 1))) `123
X    close_net();
X    if (debugging) printf("nntp_read: Error status return - connection lost\
Vn");
X    return(0);
X    `125
X  ibuf`091r_iosb.iosize`093 = '\0';
X  rp = ibuf;
X  do `123
X    if (cp = strchr(rp,'\r')) *cp++ = '\0';
X    strcat(b,rp);
X    rp = cp;
X    `125 while(rp);
X  return(1);
X`125
X`012
Xchar lbuf`091X_BUF_SIZE + 1`093 = `123""`125;
X
Xnntp_read_line(b,timer)
X  char *b;
X  int timer;
X`123
X  char *cp, *pp;
X
X  *b = '\0';
X  while (strlen(b) < 1024) `123
X    if (cp = strchr(lbuf,'\n')) `123
X      *cp = '\0';
X      strcat(b,lbuf);
X      strcat(b,"\n");
X      ++cp;
X      pp = lbuf;
X      while (*pp++ = *cp++);
X      return(1);
X      `125
X    strcat(b,lbuf);
X    if (!nntp_read(lbuf,timer)) return(0);
X    `125
X`125
X`012
X/*
X *  wait_net_response
X *
X *  Wait for a response from remote system - cmd indicates that all text
X *  should be skipped until NNTP command response is obtained
X */
X
Xwait_net_response(secs,cmd)
X  int secs,
X      cmd;
X`123
X  if (nntp_read_line(ibuf,secs)) `123
X    if (debugging) printf("nntp_read: %s",ibuf);
X    if (!cmd) return(1);
X    if (sscanf(ibuf,"%d",&cmd_code) == 1) `123
X      if ((cmd_code == 400) `124`124 (cmd_code == 205)) `123
X        close_net();
X        if (debugging) printf("nntp_read: connection shutdown response\n");
X        return(0);
X        `125
X      else return(cmd_code);
X      `125
X    `125
X  else `123
X    if (debugging) printf("nntp_read: connection lost\n");
X    return(0);
X    `125
X`125
X`012
X/*
X *  open_net
X *
X *  Open network link
X */
X
Xopen_net(node,proto)
X  char *node;
X  int proto;
X`123
X  char netobj`091128`093;
X
X  strcpy(netobj,node);
X  if (proto == CMUTCP) `123
X    if (!(sys$assign(c$dsc("IP:"),&net_chan,0,0) & 1)) return(0);
X    if (   (sys$qiow(0,net_chan,IO$_CREATE,&iosb,0,0,netobj,119,0,1,0,300) &
V 1)
X        && (iosb.iostatus & 1)) return(1);
X    sys$dassgn(net_chan);
X    return(0);
X    `125
X#if TWG
X  else if (proto == WINTCP) `123
X    if (sys$assign(c$dsc("INET:"),&net_chan,0,0) & 1) `123
X#elif SRI
X  else if (proto == SRITCP) `123
X    if (sys$assign(c$dsc("INET0:"),&net_chan,0,0) & 1) `123
X#endif
X#if TWG `124`124 SRI
X      if (   (sys$qiow(0,net_chan,IO$_SOCKET,&iosb,0,0,AF_INET,SOCK_STREAM,0
V,0,0,0) & 1)
X          && (iosb.iostatus & 1)) `123
X        if (!(dest_host = gethostbyname(netobj))) `123
X          if (debugging) printf("open_net: gethostbyname returned null\n");
X`009  sys$dassgn(net_chan);
X`009  return(0);
X`009  `125
X        data_socket.sin_addr.s_addr = *((u_long *)dest_host->h_addr);
X        data_socket.sin_family = AF_INET;
X        data_socket.sin_port = htons(NNTP_PORT);
X        if (   (sys$qiow(0,net_chan,IO$_CONNECT,&iosb,0,0,&data_socket,sizeo
Vf(data_socket),0,0,0,0) & 1)
X            && (iosb.iostatus & 1))
X          return(1);
X        `125
X      `125
X    if (debugging) printf("open_net: io$_connect or io$_Socket error\n");
X    if (debugging) printf("open_net: iosb.iostatus=%X\n",iosb.iostatus);
X    sys$dassgn(net_chan);
X    return(0);
X    `125
X#endif
X  else `123
X    char logname`091132`093,
X         *gotenv;
X
X    sprintf(logname,"NEWS_%s_TASK",node);
X    s_to_upper(logname);
X    if (gotenv = getenv(logname)) strcpy(logname,gotenv);
X    else sprintf(logname,"TASK=NNTP");
X    s_to_upper(logname);
X    sprintf(netobj,"%s::\"%s\"",node,logname);
X    return(sys$assign(c$dsc(netobj),&net_chan,0,0) & 1);
X    `125
X`125
X`012
X/*
X *  close_net
X *
X *  Close network link
X */
X
Xclose_net()
X`123
X  if (net_proto) `123
X    sys$cancel(net_chan);
X    sys$qiow(0,net_chan,IO$_DELETE,0,0,0,0,0,0,0,0,0);
X    `125
X  sys$dassgn(net_chan);
X`125
X`012
X/*
X *  toggle_link
X *
X *  Write a non-command to the net chan and wait for the command-not-recogni
Vsed
X *  response from the server.
X */
X
Xtoggle_link()
X`123
X  if (!nntp_write("STAT") `124`124 (!(wait_net_response(RESP_TIMER,1)))) `12
V3
X    if (*net_open_chan) `123
X      close_net();
X      printf("Lost connection to NEWS SERVER (`091%c`093 %s)",(net_proto?'T'
V:'D'),net_open_chan);
X      *net_open_chan = 0;
X      `125
X    return(0);
X    `125
X  return(1);
X`125
X`012
X/*
X *  s_to_lower, s_to_upper
X *
X */
X
Xchar *s_to_lower(s)
X  char *s;
X`123
X  char *save = s;
X
X  while (*s) `123
X    *s = tolower(*s);
X    s++;
X    `125
X  return(save);
X`125
X
Xchar *s_to_upper(s)
X  char *s;
X`123
X  char *save = s;
X
X  while (*s) `123
X    *s = toupper(*s);
X    s++;
X    `125
X  return(save);
X`125
X`012
X/*
X *  open_rem_chan
X *
X *  Open channel to remote NNTP server on host name node, using protocol
X *  proto_num (3 == SRITCP, 2 == WINTCP, 1 == CMUTCP, 0 = DECNET)
X */
X
Xchar restart_node`091256`093;
Xint restart_proto_num,
X    restarts = 0;
X
Xrestart_nntp()
X`123
X  if (++restarts > MAX_RESTART_ATTEMPT) return(0);
X  printf("(Lost NNTP connection - restart attempted)\n");
X  return(open_rem_chan(restart_node,restart_proto_num));
X`125
X
Xopen_rem_chan(node,proto_num)
X  char *node;
X  int proto_num;
X`123
X  int reply;
X
X  strcpy(restart_node,node);
X  restart_proto_num = proto_num;
X  s_to_lower(node);
X  if (*net_open_chan) `123
X    if ((proto_num != net_proto) `124`124 (strcmp(node,net_open_chan))) `123
X      close_net();
X      *net_open_chan = 0;
X      `125
X    else toggle_link();
X    `125
X  if (!*net_open_chan) `123
X    strcpy(net_open_chan,node);
X    if (!open_net(net_open_chan,proto_num)) `123
X      *net_open_chan = 0;
X      if (debugging) printf("open_chan: Could not open network channel\n");
X      return(0);
X      `125
X    else net_proto = proto_num;
X    if (!(reply = wait_net_response(CLIENT_TIMER,1))) `123
X      close_net();
X      *net_open_chan = 0;
X      if (debugging) printf("open_chan: No reply recieved in %d secs\n",CLIE
VNT_TIMER);
X      return(0);
X      `125
X    if ((reply!=200) && (reply!=201)) `123
X      printf("Connection refused to NEWS SERVER (`091%c`093 %s)",(net_proto
V ? 'T' : 'D'),net_open_chan);
X      return(0);
X      `125
X    `125
X  return(1);
X`125
X`012
X/*
X *  ITM routines
X *
X */
Xstruct FAB itmfab;              /* newsitem file fab */
X
Xstruct RAB itmrab;              /* newsitem file rab */
X
XITM newsitm;                    /* newsitem i/o buffer */
X
Xopen_itm_file()
X`123
X  itmfab = cc$rms_fab;
X  itmfab.fab$b_fac = FAB$M_GET;
X  itmfab.fab$l_fna = ITM_FILENAME;
X  itmfab.fab$b_fns = strlen(itmfab.fab$l_fna);
X  itmfab.fab$b_shr = FAB$M_SHRDEL `124 FAB$M_SHRGET `124 FAB$M_SHRPUT `124 F
VAB$M_SHRUPD;
X
X  itmrab = cc$rms_rab;
X  itmrab.rab$l_fab = &itmfab;
X  itmrab.rab$l_rbf = itmrab.rab$l_ubf = &newsitm;
X  itmrab.rab$w_rsz = itmrab.rab$w_usz = sizeof newsitm;
X
X  if (!(sys$open(&itmfab) & 1)) return(0);
X  if (!(sys$connect(&itmrab) & 1)) `123
X    sys$close(&itmfab);
X    return(0);
X    `125
X  return(1);
X`125
X
Xclose_itm_file()
X`123
X  sys$close(&itmfab);
X`125
X
Xitm_check(id)
X  char *id;
X`123
X  itmrab.rab$l_kbf = id;
X  itmrab.rab$b_ksz = IDLEN + 4;
X  itmrab.rab$b_krf = 1;
X  itmrab.rab$l_rop = RAB$M_KGE `124 RAB$M_RRL `124 RAB$M_NLK;
X  itmrab.rab$b_rac = RAB$C_KEY;
X
X  if ((!(sys$get(&itmrab) & 1)) `124`124 strcmp(id,newsitm.itm_id))
X    return(0);
X  return(1);
X`125
X`012
X/*
X *  HISTORY routines
X *
X */
X
Xint hist_file_open = 0,
X    hist_off = 0;
X
Xstruct FAB histfab;
X
Xstruct RAB histrab;
X
Xstruct hist `123
X  char hist_id`091IDLEN`093;
X  unsigned int hist_date;
X  `125 newshist;
X
Xopen_hist_file()
X`123
X  FILE *fpr;
X
X  if (fpr = fopen(HIST_OFF,"r")) `123
X    fclose(fpr);
X    hist_off = 1;
X    return(0);
X    `125
X
X  histfab = cc$rms_fab;
X  histfab.fab$b_fac = FAB$M_GET;
X  histfab.fab$l_fna = HIST_FILE;
X  histfab.fab$b_fns = strlen(histfab.fab$l_fna);
X  histfab.fab$b_shr = FAB$M_SHRDEL `124 FAB$M_SHRGET `124 FAB$M_SHRPUT `124
V FAB$M_SHRUPD;
X
X  histrab = cc$rms_rab;
X  histrab.rab$l_fab = &histfab;
X  histrab.rab$l_rbf = histrab.rab$l_ubf = &newshist;
X  histrab.rab$w_rsz = histrab.rab$w_usz = sizeof newshist;
X
+-+-+-+-+-+-+-+-  END  OF PART 2 +-+-+-+-+-+-+-+-