gih900@csc.anu.oz (Geoff Huston) (10/10/89)
-+-+-+-+-+-+-+-+ START OF PART 5 -+-+-+-+-+-+-+-+
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
X if (!(sys$open(&histfab) & 1)) return(0);
X if (!(sys$connect(&histrab) & 1)) `123
X sys$close(&histfab);
X return(0);
X `125
X return(hist_file_open = 1);
X`125
X
Xclose_hist_file()
X`123
X if (hist_file_open) sys$close(&histfab);
X`125
X
Xhist_check(id)
X char *id;
X`123
X if (!hist_file_open) return(0);
X histrab.rab$l_kbf = id;
X histrab.rab$b_krf = 0;
X histrab.rab$b_ksz = IDLEN;
X histrab.rab$l_rop= RAB$M_RRL `124 RAB$M_NLK ;
X histrab.rab$b_rac = RAB$C_KEY;
X return(sys$find(&histrab) & 1);
X`125
X`012
X/*
X * open_server_files
X *
X * Open the item and newsgroup files for sharing
X */
X
Xopen_server_files()
X`123
X if (!open_itm_file()) return(0);
X open_hist_file();
X return(1);
X`125
X
Xclose_server_files()
X`123
X close_itm_file();
X close_hist_file();
X`125
X
Xid_check(id)
X char *id;
X`123
X char l_id`091IDLEN + 4`093;
X int i;
X
X for (i = 0; i < (IDLEN + 4); ++i) l_id`091i`093 = '\0';
X strncpy(l_id,id,IDLEN);
X s_to_lower(l_id);
X
X if (itm_check(l_id) `124`124 hist_check(l_id)) return(1);
X return(0);
X`125
X`012
Xcollect_newids(stmfile,idfile)
X char *stmfile,*idfile;
X`123
X char cmd`091256`093,
X *cp;
X int start_time,
X last_time = 0,
X i;
X struct tm *stm;
X FILE *fpr,
X *fpw;
X
X time(&start_time);
X if (fpr = fopen(stmfile,"r")) `123
X if (fscanf(fpr,"%X",&last_time) != 1) last_time = 0;
X fclose(fpr);
X `125
X
X last_time -= DAYS * 60 * 60 * 24;
X if (last_time < 0) last_time = 1;
X stm = localtime(&last_time);
X
X if (!(fpw = fopen(idfile,"a"))) `123
X printf("Collect_ids: Cannot append to id file %s\n",idfile);
X return(0);
X `125
X
X printf("Collect_ids: Connect to NNTP server %s at %s",node,ctime(&start_ti
Vme));
X if (!open_rem_chan(node,proto_num)) `123
X printf(" Connection refused\n");
X fclose(fpw);
X return(0);
X `125
X
X printf(" Request item-id list: since %s",ctime(&last_time));
X sprintf(cmd,"NEWNEWS * %02d%02d%02d %02d%02d%02d",
X stm->tm_year,stm->tm_mon + 1,stm->tm_mday,
X stm->tm_hour,stm->tm_min,stm->tm_sec);
X if (!nntp_write(cmd) `124`124 (wait_net_response(CLIENT_TIMER,1) != 230))
V `123
X fclose(fpw);
X close_net();
X printf(" 0 item-ids returned - Comm error\n");
X return(0);
X `125
X while (wait_net_response(RESP_TIMER,0) == 1) `123
X if (!strcmp(ibuf,".\n")) break;
X else if (!strcmp(ibuf,"..\n")) strcpy(ibuf,".\n");
X if (strlen(ibuf) > 1) `123
X ++offered;
X fputs(ibuf,fpw);
X `125
X `125
X close_net();
X printf(" %d item-ids returned",offered);
X fclose(fpw);
X if (!strcmp(ibuf,".\n")) `123
X printf("\n");
X if (fpr = fopen(stmfile,"w")) `123
X fprintf(fpr,"%X\n",start_time);
X fclose(fpr);
X strcat(stmfile,";-1");
X while (!delete(stmfile));
X cp = strrchr(stmfile,';');
X *++cp = '\0';
X strcpy(cmd,stmfile);
X strcat(cmd,"1");
X rename(stmfile,cmd);
X `125
X `125
X else printf(" - Transmission aborted - comm errors\n");
X`125
X
Xstruct tree `123
X char *str;
X struct tree *left, *right;
X `125 *idtree = 0;
X
Xtsearch(t,s)
X struct tree **t;
X char *s;
X`123
X int cmp;
X
X if (!*t) `123
X *t = malloc(sizeof **t);
X strcpy((*t)->str = malloc(strlen(s) + 1),s);
X (*t)->left = (*t)->right = 0;
X return(0);
X `125
X if (!(cmp = strcmp(s,(*t)->str))) return(1);
X if (cmp < 0) return(tsearch(&((*t)->left),s));
X return(tsearch(&((*t)->right),s));
X`125
X
Xcleart(t)
X struct tree *t;
X`123
X if (t->right) cleart(t->right);
X if (t->left) cleart(t->left);
X free(t->str);
X free(t);
X`125
X
X`012
Xprocess_idfile(idfilename,batchfile)
X char *idfilename, *batchfile;
X`123
X FILE *fpr,
X *fpw = 0;
X char inl`091512`093,
X nfn`091256`093,
X cmd`091256`093,
X *cp;
X int ids = 0,
X start_time,
X resp,
X art_count = 0,
X fsize = 0;
X
X if ( !(fpr = fopen(idfilename,"r"))
X `124`124 !(fpw = fopen(idfilename,"w"))) return(0);
X while (fgets(inl,512,fpr)) `123
X if (cp = strchr(inl,'\n')) *cp = '\0';
X if (!strlen(inl) `124`124 (cp = strchr(inl,' ')) `124`124 id_check(inl))
V continue;
X if (!tsearch(&idtree,inl)) `123
X ++ids;
X fputs(inl,fpw);
X fputs("\n",fpw);
X `125
X `125
X if (idtree) cleart(idtree);
X idtree = 0;
X fclose(fpr);
X fclose(fpw);
X if (!ids) while (!delete(idfilename));
X else `123
X strcpy(nfn,idfilename);
X strcat(nfn,";-1");
X while (!delete(nfn));
X strcat(idfilename,";");
X strcpy(nfn,idfilename);
X strcat(nfn,"1");
X rename(idfilename,nfn);
X if (cp = strchr(idfilename,';')) *cp = '\0';
X fpw = 0;
X `125
X
X if (!ids`124`124 !(fpr = fopen(idfilename,"r"))) return(0);
X time(&start_time);
X printf("Process_ids: Connect to NNTP server %s at %s",node,ctime(&start_ti
Vme));
X if (!open_rem_chan(node,proto_num)) `123
X printf(" Connection refused\n");
X fclose(fpr);
X return(0);
X `125
X strcpy(nfn,batchfile);
X cp = strrchr(nfn,'.');
X strcpy(cp,".OPEN");
X while (fgets(inl,512,fpr)) `123
X if (cp = strchr(inl,'\n')) *cp = '\0';
X sprintf(cmd,"ARTICLE %s",inl);
X if ( !nntp_write(cmd)
X `124`124 ((resp = wait_net_response(CLIENT_TIMER,1)) != 220)) `123
X if (resp == 430) continue;
X if (!restart_nntp()) `123
X if (fpw) `123
X fclose(fpw);
X rename(nfn,batchfile);
X `125
X fclose(fpr);
X printf(" %d items received - Transmission aborted - comm errors\n"
V,art_count);
X return(art_count);
X `125
X continue;
X `125
X if (!fpw) fpw = fopen(nfn,"w");
X fprintf(fpw,"#! rnews 1\n");
X while (wait_net_response(RESP_TIMER,0) == 1) `123
X if (!strcmp(ibuf,".\n")) break;
X else if (!strcmp(ibuf,"..\n")) strcpy(ibuf,".\n");
X fputs(ibuf,fpw);
X fsize += strlen(ibuf);
X `125
X if (strcmp(ibuf,".\n")) `123
X fclose(fpw);
X while (!delete(nfn));
X fpw = 0;
X if (!restart_nntp()) `123
X fclose(fpr);
X printf(" %d items received - Transmission aborted - comm errors\n"
V,art_count);
X return(art_count);
X `125
X continue;
X `125
X ++art_count;
X if (fsize > MAX_BATCH_SIZE) `123
X fclose(fpw);
X rename(nfn,batchfile);
X fpw = 0;
X fsize = 0;
X `125
X `125
X close_net();
X printf(" %d items received\n",art_count);
X if (fpw) `123
X fclose(fpw);
X rename(nfn,batchfile);
X `125
X fclose(fpr);
X while (!delete(idfilename));
X return(art_count);
X`125
X`012
X/*
X * main
X */
X
Xmain(argc,argv)
X int argc;
X char *argv`091`093;
X`123
X char proto`09132`093,
X batch_stamp_file`091256`093,
X all_ids`091256`093,
X control_ids`091256`093,
X out_all`091256`093,
X out_control`091256`093,
X cmd`091256`093,
X idfile`091256`093,
X *np;
X int`032
X start_time,
X last_time = 0,
X i;
X FILE *fpr,
X *fpw;
X
X`009`009`009`009/* startup code - initialize environment */
X sysprv();
X if ((argc < 3) `124`124 (argc > 5)) `123
X printf("Usage: NNTPXFER node proto `091log`093 `091debug`093\n");
X exit(1);
X `125
X if (!open_server_files()) `123
X printf("FileError: Cannot open NEWS datafiles\n");
X exit(1);
X `125
X if (np = getenv("NNTP_SCRATCH")) strcpy(scratch_area,np);
X else if (!getenv("SYS$SCRATCH")) strcpy(scratch_area,"NEWS_MANAGER");
X else strcpy(scratch_area,"SYS$SCRATCH");
X
X`009`009`009`009/* interpret program arguments */
X strcpy(node,argv`0911`093);
X strcpy(fnode,node);
X while (np = strchr(fnode,'.')) *np = '-';
X strcpy(proto,argv`0912`093);
X#if TWG
X if (tolower(*proto) == 't') proto_num = WINTCP;
X if (tolower(*proto) == 'w') proto_num = WINTCP;
X#elif SRI
X if (tolower(*proto) == 't') proto_num = SRITCP;
X if (tolower(*proto) == 's') proto_num = SRITCP;
X#else
X if (tolower(*proto) == 't') proto_num = CMUTCP;
X if (tolower(*proto) == 'c') proto_num = CMUTCP;
X#endif
X if (argc>=4) `123
X strcpy(logfile,argv`0913`093);
X logging = 1;
X `125
X if (argc==5) debugging = 1;
X
X
X sprintf(idfile,"NEWS_MANAGER:NNTP_%s.IDS",fnode);
X sprintf(out_all,"NEWS_MANAGER:NNTP_%s.BATCH",fnode);
X accepted += process_idfile(idfile,out_all);
X
X sprintf(batch_stamp_file,"NEWS_MANAGER:NNTP_%s.LASTCALL",fnode);
X sprintf(idfile,"NEWS_MANAGER:NNTP_%s.IDS",fnode);
X collect_newids(batch_stamp_file,idfile);
X
X sprintf(idfile,"NEWS_MANAGER:NNTP_%s.IDS",fnode);
X accepted += process_idfile(idfile,out_all);
X
X close_server_files();
X
X if (logging)`123
X struct tm *stm;
X int cur_time;
X char *p,
X datum`09132`093;
X FILE *fpl;
X
X time(&cur_time);
X p = ctime(&cur_time);
X p += 4;
X stm = localtime(&cur_time);
X sprintf(datum,"%d %.3s %d %02d:%02d:%02d ",
X stm->tm_mday,p,stm->tm_year,stm->tm_hour,stm->tm_min,stm->tm_se
Vc);
X fpl = fopen(logfile,"a");
X fprintf(fpl,"%s nntpxfer: %s - %d items listed, %d transferred\n",
X datum,node,offered,accepted);
X fclose(fpl);
X `125
X`125
$ CALL UNPACK NNTP_XFER.C;1 2079707824
$ v=f$verify(v)
$ EXIT