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 +-+-+-+-+-+-+-+-