Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!brutus.cs.uiuc.edu!wuarchive!kuhub.cc.ukans.edu!sloane From: SLOANE@kuhub.cc.ukans.edu (Bob Sloane) Newsgroups: news.software.anu-news Subject: Mailing list/newsgroup gateway programs. Message-ID: <10040@kuhub.cc.ukans.edu> Date: 28 Aug 89 20:45:57 GMT Organization: University of Kansas Academic Computing Services Lines: 677 Hi All, Well, I got several requests for the mailing list/newsgroup gateway software, so here it is. Be sure and let me know if you have any problems with it. +-------------------+-------------------------------------+------------------+ | Bob Sloane \Internet: SLOANE@KUHUB.CC.UKANS.EDU/Anything I said is | | Computer Center \ BITNET: SLOANE@UKANVAX.BITNET / my opinion, not my | | University of Kansas\ AT&T: (913) 864-0444 / employer's. | +-----------------------+-----------------------------+----------------------+ $! ------------------ CUT HERE ----------------------- $ v='f$verify(f$trnlnm("SHARE_VERIFY"))' $! $! This archive created by VMS_SHARE Version 7.1-004 3-AUG-1989 $! On 28-AUG-1989 15:21:33.26 By user SLOANE $! $! This VMS_SHARE Written by: $! Andy Harper, Kings College London UK $! $! Acknowledgements to: $! James Gray - Original VMS_SHARE $! Michael Bednarek - Original Concept and implementation $! $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER $! AND EXECUTE AS A COMMAND PROCEDURE ( @name ) $! $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING: $! 1. GATEMAIL.C;1 $! 2. GATEMAIL.TXT;1 $! 3. GATENEWS.C;1 $! 4. GATENEWS.TXT;1 $! $set="set" $set symbol/scope=(nolocal,noglobal) $f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID")) $e="write sys$error ""%UNPACK"", " $w="write sys$output ""%UNPACK"", " $ if f$trnlnm("SHARE_LOG") then $ w = "!" $ if f$getsyi("version") .ges. "V4.4" then $ goto START $ e "-E-OLDVER, Must run at least VMS 4.4" $ v=f$verify(v) $ exit 44 $UNPACK: SUBROUTINE ! P1=filename, P2=checksum $ if f$search(P1) .eqs. "" then $ goto file_absent $ e "-W-EXISTS, File ''P1' exists. Skipped." $ delete/nolog 'f'* $ exit $file_absent: $ if f$parse(P1) .nes. "" then $ goto dirok $ dn=f$parse(P1,,,"DIRECTORY") $ w "-I-CREDIR, Creating directory ''dn'." $ create/dir 'dn' $ if $status then $ goto dirok $ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped." $ delete/nolog 'f'* $ exit $dirok: $ w "-I-PROCESS, Processing file ''P1'." $ define/user sys$output nl: $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1' PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET( SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name"); buff:=CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(buff)) ;LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION( BEGINNING_OF(buff));g:=0;LOOP EXITIF MARK(NONE)=END_OF(buff);x:= ERASE_CHARACTER(1);IF g = 0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x= "V" THEN APPEND_LINE;MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF; IF x="+" THEN g:=1;ERASE_LINE;ENDIF;ELSE IF x="-" THEN g:=0;ENDIF;ERASE_LINE; ENDIF;ENDLOOP;p:="`";POSITION(BEGINNING_OF(buff));LOOP r:=SEARCH(p,FORWARD); EXITIF r=0;POSITION(r);ERASE(r);COPY_TEXT(ASCII(INT(ERASE_CHARACTER(3)))); ENDLOOP;o:=GET_INFO(COMMAND_LINE,"output_file");WRITE_FILE(buff,o); ENDPROCEDURE;Unpacker;EXIT; $ delete/nolog 'f'* $ CHECKSUM 'P1' $ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT $ e "-E-CHKSMFAIL, Checksum of ''P1' failed." $ ENDSUBROUTINE $START: $ create/nolog 'f' X/* X * Gatemail - a program to convert Mail messages from a mailing list into X * News articles suitable for input to the ANU-NEWS ADD FILE X * command. X * X * Copyright 1989 by Robert R. Sloane . X * Permission is granted to anyone to make or distribute copie Vs X * of this program, provided that this copyright notice is X * preserved. X */ X#include X#include X XFILE *mfd;`009/* MAIL file */ XFILE *bfd;`009/* NEWS Batch file */ X Xmain(int argc, char **argv) `123 X char line`0911024`093; X int i; X/* X * make sure user gave us both file names and the newsgroup name. X */ X if (argc < 2) `123 X`009printf("Usage: gtmail \n"); X`009exit(SS$_NORMAL); X `125 X if (argc < 5) X`009exit(SS$_INSFARG); X/* X * now open the input file X */ X if ( !(mfd=fopen(argv`0911`093,"r")) ) `123 X`009perror("can't open input file:"); X`009exit(SS$_ABORT); X `125 X/* X * and the output file X */ X if ( !(bfd=fopen(argv`0912`093,"a")) ) `123 X`009perror("can't open output file:"); X`009exit(SS$_ABORT); X `125 X/* X * now copy selected parts of the input to the output file X */ X while ( get_line(line) ) `123 X/* X * check to see if this is the start of a new mail message X * and if it is, process it. X */ X`009if ( !strncmp(line,"\f\nFrom:\t",8) ) `123 X/* X * skip over unwanted mail headers X */ X`009 while (get_head(line)) ; /* skip MAIL headers */ X/* X * now output the headers we want to keep X */ X`009 fputs("#! rnews ???\n",bfd); /* output batch separator */ X`009 fputs("Path: ",bfd); fputs(argv`0913`093,bfd); fputs("!list\n",bfd); X`009 fputs("Newsgroups: ",bfd); fputs(argv`0914`093,bfd); fputs("\n",bfd) V; X`009 while (get_head(line)) `123 /* look for first null line * V/ X`009`009if (!strncmp(line,"Return-path: ",13))continue; X`009`009if (!strncmp(line,"Newsgroups: ", 12))continue; X`009`009if (!strncmp(line,"Received: ", 10))continue; X`009`009if (!strncmp(line,"X-To: ", 6))continue; X`009`009if (!strncmp(line,"Path: ", 6))continue; X`009`009if (!strncmp(line,"To: ", 4))continue; X`009`009fputs(line,bfd); X`009 `125 X`009 fputs("\n",bfd); /* mark end of headers */ X`009`125 X/* X * if we get here, the headers are done, so copy each line of the text X */ X`009else `123 X/* X * Check each line, and if it looks like and NEWS Batch file separator, X * put a > in front of is, so NEWS won't get confused. X */ X`009 if (!strncmp(line,"#! rnews ",9)) X`009`009fputs(">",bfd); X`009 fputs(line,bfd); X`009`125 X `125 X`125 X/* X * get_line: get one line of text from the input file, exit on EOF. X * If the line consists of just a form feed, concatenate the X * next line on the end. Makes looking for \f\nFrom:\t that X * separates mail messages easier to find. X */ Xget_line( char *line ) `123 X int status; X extern char *mygets(); X/* X * read the next line from the file X */ X if ( !mygets(line,1024,mfd) ) `123 X`009fclose(bfd); X`009exit(SS$_NORMAL); X `125 X/* X * if this line is just a FORMFEED, Combine it with the next line X */ X if ( line`0910`093 == '\f' && line`0911`093 == '\n' ) `123 X`009if ( !mygets(line+2,1022,mfd) ) `123 /* get the next line */ X`009 fclose(bfd); /* trailing formfeeds ignored */ X`009 exit(SS$_NORMAL); X`009`125 X `125 X return 1; X`125 X/* X * get_head: routine to get a single header line from the input file. X * RFC822 standard continuation lines are concatenated together X * to make processing easier. I assume that no header line wil Vl X * be longer than 1024 characters. X */ Xget_head( char *line ) `123 X int ch; X extern char *mygets(); X/* X * read the header line X */ X if ( !mygets(line,1024,mfd) ) `123 X`009fclose(bfd); /* close off the output file */ X`009exit(SS$_ENDOFFILE); /* error in header, exit */ X `125 X/* X * if this line is just a newline, then we have reached the end of the X * headers. X */ X if ( *line == '\n' ) return 0; X/* X * if the next line begins with a blank, then it is a continuation X * of this line. Append it to the end of the current line. X */ X while ( ungetc(getc(mfd),mfd) == ' ' ) X`009if ( !mygets(line+strlen(line),1024-strlen(line),mfd) ) `123 X`009 fclose(bfd); X`009 exit(SS$_ENDOFFILE); X`009`125 X return 1; X`125 X/* X * You may have been wondering why I used mygets rather than the standard X * C library routine gets. I started out that way, but there seems to be X * a problem in the C library when using ungetc, getc, and gets together X * on the same file. It was easier to just write my own than try to find X * out what the problem was with DEC's routine. X */ Xchar *mygets( char *line, int max, FILE *fd ) `123 X int i,ch; X/* X * read up to max characters from the input file X */ X for ( i=0; i SELECT/TO=news.group.GATEWAY NEWMAIL !same as the "personal name" ab Vove XMAIL> EXTRACT/ALL/APPEND temp.file !moves the messages to the file X !and also moves them to the fol Vder X !named MAIL XMAIL> SELECT/TO=news.group.GATEWAY MAIL !Assumes that the MAIL folder i Vs X !always empty. XMAIL> DELETE/ALL !delete what we just extracted X X XNext, run the GATEMAIL program on the extracted MAIL: X X$ GATEMAIL:==$disk:`091dir`093GATEMAIL X$ IF F$SEARCH ("temp.file") .nes. "" then - X GATEMAIL temp.file news-group.MAIL news-group news.group X$ IF F$SEARCH ("temp.file") .nes. "" then - X DELETE temp.file;* X Xwhere temp.file is the name of the file containing the extracted mail, Xnews-group.MAIL is the file to be added to news using ADD FILE, system is Xthe system name to be put in the Path: header of the generated article, and Xnews.group is the newsgroup name to go in the Newsgroups: header. The system Xname (news-group) should be the same as was specified in the NEWS.SYS file f Vor Xthe GATENEWS program. See GATENEWS.TXT for more information. X XFinally, you need to add the generated file into the News database: X X$ NEWS/NOSCREEN ADD FILE news-group.MAIL/DELETE X XYou will also need to create the newsgroup in NEWS, and update your NEWS.SYS Xfile to accept the newsgroup. X XIf you have any problems with this program, let me know. X+-------------------+-------------------------------------+----------------- V-+ X`124 Bob Sloane \Internet: SLOANE@KUHUB.CC.UKANS.EDU/Anything I said V is `124 X`124 Computer Center \ BITNET: SLOANE@UKANVAX.BITNET / my opinion, not V my `124 X`124 University of Kansas\ AT&T: (913) 864-0444 / employer's. V `124 X+-----------------------+-----------------------------+--------------------- V-+ $ CALL UNPACK GATEMAIL.TXT;1 1332696240 $ create/nolog 'f' X/* X * Gatenews: a program to take Batches of NEWS from the ANU-NEWS program X * and feed them to a mailing list via BITNET. X * X * Copyright 1989 by Robert R. Sloane . X * Permission is granted to anyone to make or distribute copie Vs X * of this program, provided that this copyright notice is X * preserved. X */ X#include X#include X XFILE *mfd = 0;`009/* MAIL file */ XFILE *bfd;`009/* NEWS Batch file */ X Xmain(int argc, char **argv) `123 X char line`0911024`093; X int i; X char sendcmd`0911024`093; X int control; X extern char *mygets(); X/* X * make sure user gave us the file name and the mailing address. X */ X if (argc < 2) `123 X`009printf("Usage: gtnews
\n"); X`009exit(SS$_NORMAL); X `125 X if (argc < 3) X`009exit(SS$_INSFARG); X/* X * now open the input file X */ X if ( !(bfd=fopen(argv`0911`093,"r")) ) `123 X`009perror("can't open input file:"); X`009exit(SS$_ABORT); X `125 X/* X * now fix up the command to send the mail X */ X strcpy(sendcmd, X"SEND/FILE/PUNCH/CLASS=M/PRIO=50/NAME=\"LISTSERV MAIL\"/DELETE TEMPMAIL.TMP V "); X strcat(sendcmd,argv`0912`093); X/* X * we don't want to send control messages to the mailing list, so set up X * a flag that says the current message is a control message. If we find X * a Control: line in the message this will be 1, otherwise 0 X */ X control = 0; /* not a control message for now */ X/* X * now copy selected parts of the input to the output file X */ X while ( mygets(line,1024,bfd) ) `123 X/* X * check to see if this is the start of a new mail message X * and if it is, process it. X */ X`009if ( !strncmp(line,"#! rnews ",9) `124`124 !mfd ) `123 X/* X * first we need to close any previous file and send it to the mailing li Vst X */ X`009 if ( mfd && !control ) `123 X`009`009fclose(mfd); X`009`009mfd = 0; X`009`009system(sendcmd); X`009 `125 X`009 else if ( mfd ) `123 X`009`009fclose(mfd); X`009`009mfd = 0; X`009`009delete("TEMPMAIL.TMP"); X`009 `125 X/* X * now open a new output temp file to hold the mail message X */ X`009 if ( !(mfd=fopen("TEMPMAIL.TMP","w")) ) `123 X`009`009perror("can't open scratch file:"); X`009`009exit(SS$_ABORT); X`009 `125 X/* X * skip over unwanted headers and output the ones we want to keep X */ X`009 fputs("To: ",mfd); fputs(argv`0912`093,mfd); fputs("\n",mfd); X`009 control=0; /* assume it's no control msg */ X`009 while (get_head(line)) `123 /* look for first null line */ X`009`009if (!strncmp(line,"From: ", 6))fputs(line,mfd); X`009`009if (!strncmp(line,"Date: ", 6))fputs(line,mfd); X`009`009if (!strncmp(line,"Sender: ", 8))fputs(line,mfd); X`009`009if (!strncmp(line,"Subject: ", 9))fputs(line,mfd); X`009`009if (!strncmp(line,"Reply-to: ", 10))fputs(line,mfd); X`009`009if (!strncmp(line,"Message-ID: ", 12))fputs(line,mfd); X`009`009if (!strncmp(line,"Organization: ",14))fputs(line,mfd); X`009`009if (!strncmp(line,"Control: ", 9))control=1; X`009 `125 X`009 fputs("\n",mfd); /* mark the end of the headers */ X`009`125 X`009else X/* X * if we get here, the headers for this message have been processed, X * so output the line of text. X */ X`009 fputs(line,mfd); X `125 X/* X * found the end of the input file, so send off the last message, if we X * haven't already. X */ X if ( mfd && !control ) `123 X`009fclose(mfd); X`009system(sendcmd); X `125 X else if ( mfd ) `123 X`009fclose(mfd); X`009delete("TEMPMAIL.TMP"); X `125 X`125 X/* X * get_head: get one header line from the input file. Continuation lines X * are concatenated into one long line. It is assumed that no header lin Ve X * is longer than 1024 characters. X */ Xget_head( char *line ) `123 X int ch; X char cline`0911024`093; X extern char *mygets(); X/* X * get the next header line from the input file. X */ X if ( !mygets(line,1024,bfd) ) `123 X`009fclose(mfd); X`009exit(SS$_ENDOFFILE); /* shouldn't get EOF here */ X `125 X/* X * if this line is null, it marks the end of the headers. X */ X if ( *line == '\n' ) return 0; /* return false if no more headers */ X/* X * make sure the header lines aren't longer than 80 characters. X * fold and continue them if needed. X */ X fold_header(line); X/* X * if the next input line starts with a blank, it is a continuation of th Vis X * line, so concatenate it onto the end of this line. X */ X while ( ungetc(ch=fgetc(bfd),bfd) == ' ' ) `123 X`009if ( !mygets(cline,1024-strlen(line),bfd) ) `123 X`009 fclose(mfd); X`009 exit(SS$_ENDOFFILE); /* this shouldn't happen */ X`009`125 X`009fold_header(cline); X`009strcat(line,cline); X `125 X return 1; X`125 X/* X * fold_header: folds headers so that they don't exceed the 80 column lim Vit X * on BITNET mail messages. X */ Xfold_header( char *line ) `123 X char cline`0911024`093; X char ch; X char *cp; X X cline`0910`093 = '\0'; X while ( strlen(line) > 80 ) `123 X`009ch = line`09180`093;`009`009`009 /* save the 80th character */ X`009line`09180`093 = '\0'; /* truncate line at col 80 * V/ X`009cp = strrchr( line, ' ' ); /* find the rightmost blank */ X`009line`09180`093 = ch; /* in the first 80 character Vs */ X`009if ( cp == NULL ) `123 /* if there is no delimiter */ X`009 strcpy( &line`09181`093,&line`09180`093 ); /* make room for a bla Vnk */ X`009 line`09180`093 = ' '; /* and put one in */ X`009 cp = &line`09180`093;`009`009 /* set pointer to the blank */ X`009`125 X`009*cp = '\0'; /* end the line at the blank */ X`009strcat(cline,line); /* build the new line */ X`009strcat(cline,"\n "); /* and continue it later */ X`009strcpy(line,cp+1); /* now move rest of line over */ X `125 X strcat(cline,line); strcpy(line,cline); /* now put the line back */ X`125 X/* X * You may have been wondering why I used mygets rather than the standard X * C library routine gets. I started out that way, but there seems to be X * a problem in the C library when using ungetc, getc, and gets together X * on the same file. It was easier to just write my own than try to find X * out what the problem was with DEC's routine. X */ Xchar *mygets( char *line, int max, FILE *fd ) `123 X int i,ch; X/* X * read up to max characters from the input file X */ X for ( i=0; i.DIR . X$! Send all batch files in the list-specific directory to the mailing list. X$! This procedure assumes that all the mailing lists are on the BITNET node X$! NDSUVM1, where the ANU-NEWS mailing list is. Since other lists probably X$! aren't on that system, you will need to change this procedure to suit yo Vur X$! individual needs. One possibility is to define a logical for each mailin Vg X$! list, ie: X$! X$! $ define anu-news "anu-news@ndsuvm1" X$! ... X$! X$! and then change the GATENEWS command below to: X$! X$! $ gatenews news_manager_dev:`091MAIL_'Node'`093NEWS.BATCH "''f$trnl(''No Vde')'" X$! X$! At least I think this should work. I haven't actually tried it. X$! X$DO_MAIL_NEWS: X$ X$ ws "Checking for (and forwarding) to BITNET Mailing lists ..." X$ X$ gatenews:==$dua8:`091newsmgr.exe`093gatenews X$ X$DIR_SEARCH_MAIL: X$ on error then goto ABORT X$ Post_Dir = f$search ("NEWS_MANAGER:MAIL_*.DIR",MAIL_Node_Search) X$ if Post_Dir .eqs. "" then RETURN X$ X$ Node = f$parse (Post_Dir,,,"NAME","SYNTAX_ONLY") - "MAIL_" X$ X$ ws "Checking for News to send to node ''Node' ..." X$ Post_Files = f$search ("NEWS_MANAGER_DEV:`091MAIL_"+Node+"`093NEWS.BATCH;* V",MAIL_File_search) X$ if Post_Files .eqs. "" then ws "No News to send" X$ if Post_Files .eqs. "" then goto DIR_SEARCH_MAIL X$ X$ on error then goto DIR_SEARCH_MAIL X$ ws "Send News to mailing lists..." X$ gatenews news_manager_dev:`091MAIL_'Node'`093NEWS.BATCH "''Node'@NDSUVM1" X$ delete news_manager_dev:`091MAIL_'Node'`093NEWS.BATCH; X$ goto DIR_SEARCH_MAIL X$ X$ RETURN X XRemember that the mailing list must be a LISTSERV type mailing list on a BIT VNET Xnode, and you must be running the JNET software from Joiner Associates for a Vll Xthis to work. Let me know if you have any problems. X+-------------------+-------------------------------------+----------------- V-+ X`124 Bob Sloane \Internet: SLOANE@KUHUB.CC.UKANS.EDU/Anything I said V is `124 X`124 Computer Center \ BITNET: SLOANE@UKANVAX.BITNET / my opinion, not V my `124 X`124 University of Kansas\ AT&T: (913) 864-0444 / employer's. V `124 X+-----------------------+-----------------------------+--------------------- V-+ $ CALL UNPACK GATENEWS.TXT;1 1448763146 $ v=f$verify(v) $ EXIT