Article View: vmsnet.sources
Article #112VAXNOTES-TO-NEWS V2.2, part 01/01
From: Dick Munroe
Date: Fri, 04 Sep 1992 05:44
Date: Fri, 04 Sep 1992 05:44
565 lines
18470 bytes
18470 bytes
Submitted-by: munroe@dmc.com (Dick Munroe)
Posting-number: Volume 3, Issue 161
Archive-name: vaxnotes_to_news/part01
[ This submission provides a utility for converting a file
that results from a command similar to EXTRACT/ALL/UNSEEN
into a format suitable for submission to news. ]
$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-010 25-Jun-1992
$! On 26-AUG-1992 09:50:35.67 By user MUNROE
$!
$! 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. AAAREADME.1ST;1
$! 2. CONVERT.C;21
$!
$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 = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.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
$ x = P1 - f$parse(P1,,,"version")
$ y = f$search(x)
$ if y .eqs. "" then $ goto file_absent
$ x = f$integer(f$parse(P1,,,"version")-";")
$ y = f$integer(f$parse(y,,,"version")-";")
$ if x .gt. y then $ goto file_absent
$ if f$mode() .eqs. "INTERACTIVE" then $ goto file_interactive
$ if x .eq. y then e "-W-EXISTS, File ''P1' exists. Skipped."
$ if x .ne. y then e "-W-NEWERVERSION, of File ''P1' exists. Skipped."
$file_delete:
$ delete 'f'*
$ exit
$file_interactive:
$ if x .eq. y then e "-W-EXISTS, File ''P1' exists."
$ if x .ne. y then e "-W-NEWERVERSION, of File ''P1' exists."
$ read/error=file_delete/end=file_delete-
/prompt="Create new version [y/n]: " -
sys$command x
$ if .not. x then $ e "-W-SKIPPED, File ''P1' skipped."
$ if .not. x then $ goto file_delete
$ P1 = P1 - f$parse(P1,,,"version")
$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 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ 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");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);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 IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
XVAXNOTES-TO-NEWS V2.2
X
XBasically works the same way, but it can `5Boptionally`5D consume files sent
V via
Xinternet mail. It ignores the headers. It also is more robust in the face
V of
Xsome of the vagaries I've seen in the output of NOTES EXTRACT/UNSEEN.
X
XI'm currently using it to gateway the ISVNET notes files into newsgroups and
V it
Xworks great for that application.
X
XIf you have any questions contact me.
X
XIf you spot any bugs or make fixes, be a sport and let me know so I can keep
Xthings up to date.
X
XDick Munroe
XDoyle, Munroe Consultants, Inc.
X267 Cox St.
XHudson, Ma. 01749
X(508) 568-1618
X(FAX) (508) 562-1133
Xmunroe@dmc.com
$ CALL UNPACK AAAREADME.1ST;1 1209160627
$ create 'f'
X/*`20
X * COPYRIGHT (c) 1990 BY
V *
X * MITECH CORPORATION, CONCORD, MASSACHUSETTS.
V *
X *`09`09`09 ALL RIGHTS RESERVED *
X *
X * Copyright 1992 by Dick Munroe, All rights reserved.
X * Doyle, Munroe Consultants, Inc.
X * 267 Cox St.
X * Hudson, Ma. 01749
X *
XPermission to use, copy, modify, distribute and sell this software and
Xits documentation for any purpose and without fee is hereby granted,
Xprovided that the above copyright notice appear in all copies and that
Xboth that copyright notice and this permission notice appear in
Xsupporting documentation, and that the name of Mitech Corporation not
Xbe used in advertising or publicity pertaining to distribution of the
Xsoftware without specific, written prior permission.
X
XMITECH DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
XMITECH BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
XSOFTWARE.
X
XThe above applies to Doyle, Munroe Consultants, Inc. as well.
X
XProgram: Notesconvert
XPurpose: Convert a file generated by VAX NOTES using a command
X such as EXTRACT/ALL/UNSEEN XYZ.NOTES-DATA
X into a file suitable for usenet format news processing.
X e.g. by ANU-NEWS using a command such as
X $ NEWS/NOSCREEN ADD FILE/NETFEED XYZ.NEWS-DATA
XCreated: 18-DEC-1990
XAuthor: George Carrette, GJC@MITECH.COM
XVersion: 1.0
X 1.1 Added msg_note_major msg_note_minor, id and references, subj cl
Vean
X
XAuthor: Dick Munroe <munroe@dmc.com>
XVersion: 2.0
X`09 Rig this thing to be able to deal with messages containing notes
X`09 messages.
X
XVersion: 2.1
X`09 Apparently Notes doesn't consider blank lines trailing a note to be
X`09 part of the note.
X
XVersion: 2.2
X`09 Occasionally Notes OVERcounts the size of a note as well. Rig the code
X`09 to check for this case and scan for the next art header. This may
X`09 occasionally wind up with a bogus note entered (for example, when notes
X`09 are posted to notes AND the count gets off) but there won't be THAT
X`09 many of these.
X
X`09 Occaisionally Notes puts a blank line in BEFORE the header which
X`09 specifies the source of the notes. Skip blank lines before getting to
X`09 the sources of the notes.
X
X`09 Occaisionally Notes breaks the topic header following the note title.
X`09 I'm going to take advantage of the fact that all item header lines
X`09 should be at LEAST 80 characters in length to fix this.
X*/
X
X#include <stdio.h>
X#include <ctype.h>
X#include <errno.h>
X
Xchar *newsgroup_name;
Xchar *newsgroup_prefix = "dmc.isvnet.";
X
Xchar *art_header;
Xchar *art_sep;
X
Xlong header_size = 80;
Xlong buffn = 1024;
X
Xchar *inbuff;
Xchar *msg_subj;
Xchar *msg_subj_sub;
Xchar *outbuff;
Xlong msg_note_major;
Xlong msg_note_minor;
Xchar *msg_id;
X
Xlong msg_nlines;
Xchar *msg_from;
Xchar *msg_date;
X
Xchar *output_buffer = NULL;
Xlong output_buffn = 0;
Xlong output_nchars = 0;
X
Xchar *output_pointer;
X
Xoutput_reset()
X`7Boutput_pointer = output_buffer;
X output_nchars = 0;`7D
X
Xoutput_flush(to)
X FILE *to;
X`7Bfwrite(output_buffer,output_nchars,1,to);
X output_reset();`7D
X
Xoutput(line)
X char *line;
X`7Blong n;
X n = strlen(line);
X if ((n + output_nchars) >= output_buffn)
X `7Boutput_buffn *= 2;
X output_buffn += buffn;
X if (n > output_buffn) output_buffn = n;
X if (output_buffer == NULL)
X output_buffer = (char *) malloc(output_buffn);
X else
X output_buffer = (char *) realloc(output_buffer,output_buffn);
X output_pointer = output_buffer + output_nchars;`7D
X memcpy(output_pointer,line,n);
X output_nchars += n;
X output_pointer += n;`7D
X
Xchar *make_header(x)
X int x;
X`7Bchar *p;
X p = (char *) malloc(header_size + 2);
X p`5Bheader_size`5D = '\n';
X p`5Bheader_size+1`5D = 0;
X memset(p,x,header_size);
X return(p);`7D
X
Xmain(argc,argv)
X int argc;
X char **argv;
X`7BFILE *in,*out;
X char *p,*p1,*p2;
X long j;
X fpos_t filePosition, headerPosition ;
X int headerPositionValid = 0 ;
X`20
X if (argc < 3)
X `7Bfprintf(stderr,"%%NOTESCONVERT-F-ARGS wrong number of arguments\n");
X p = strrchr(argv`5B0`5D,'`5D');
X fprintf(stderr,"%s <input-file> <output-file> `5B-m`5D\n",
X`09 (p) ? p+1 : "notesconvert");
X exit(44);`7D
X if (!(in = fopen(argv`5B1`5D,"r")))
X `7Bperror(argv`5B1`5D);
X exit(vaxc$errno);`7D
X if (!(out = fopen(argv`5B2`5D,"w")))
X `7Bperror(argv`5B2`5D);
X exit(vaxc$errno);`7D
X inbuff = (char *) malloc(buffn);
X outbuff = (char *) malloc(buffn);
X msg_subj = (char *) malloc(buffn);
X msg_subj_sub = (char *) malloc(buffn);
X msg_from = (char *) malloc(buffn);
X msg_date = (char *) malloc(buffn);
X msg_id = (char *) malloc(buffn);
X art_header = make_header('=');
X art_sep = make_header('-');
X
X /*
X ** Skip the message header, if requested.
X */
X`20
X if (argc > 3)
X `7B
X for (p1 = fgets(inbuff,buffn,in);
X ((p1 != NULL) && (*p1 != '\n'));
X p1 = fgets(inbuff,buffn,in))
X `7B
X `7D ;
X if (!p1)
X `7B
X fprintf(stderr,"%%NOTESCONVERT-F-BAD no header line\n");
X exit(44);
X `7D ;
X `7D ;
X`20
X /*
X ** Skip over blank lines while getting to the notes header.
X */
X`20
X for (p1 = fgets(inbuff,buffn,in);
X ((p1 != NULL) && (*p1 == '\n'));
X p1 = fgets(inbuff,buffn,in))
X `7B
X `7D ;
X
X if (!p1)
X `7B
X fprintf(stderr,"%%NOTESCONVERT-F-BAD no header line\n");
X exit(44);
X `7D ;
X
X p1 = strrchr(inbuff,'`5D');
X ++p1;
X p2 = strchr(p1,'.');
X if (!p2)
X `7Bfprintf(stderr,"%%NOTESCONVERT-F-BAD bad header line\n");
X exit(44);`7D
X *p2 = 0;
X newsgroup_name = (char *) malloc(strlen(newsgroup_prefix) +
X`09`09`09`09 strlen(p1) + 1);
X strcpy(newsgroup_name,newsgroup_prefix);
X strcat(newsgroup_name,p1);
X fprintf(stderr,"Newsgroups: %s\n",newsgroup_name);
X fgets(inbuff,buffn,in);
X while(1)
X `7B
X fgetpos(in, &filePosition) ;`09`09`09/* Get the current file position.`0
V9`09`09`09`09 */
X p = fgets(inbuff,buffn,in);
X if ((!p) `7C`7C (*p == 0))
X `7Bfprintf(stderr,"%%NOTESCONVERT-I-END end of file\n");
X fclose(out);
X exit(1);`7D
X if ((inbuff`5B0`5D == '\f') && (inbuff`5B1`5D == '\n') && (inbuff`5B2`5D
V == 0))
X continue;`09`09`09`09`09`09/* The line consists of exactly <ff><nl> so
V ignore it.`09`09`09*/
X if ((inbuff`5B0`5D == '\n') && (inbuff`5B1`5D == 0))
X continue ;`09`09`09`09`09/* The line consists of exactly <nl>. I've s
Veen cases where notes`09*/
X`09`09`09`09`09`09`09/* doesn't count blank lines which trail the end of a n
Vote. This takes`09*/
X`09`09`09`09`09`09`09/* care of that case.`09`09`09`09`09`09`09*/
X if (strcmp(inbuff,art_header) != 0)
X `7B
X if (headerPositionValid == 0)
X `7B
X`09/*
X`09** The header position is not valid, no recovery is possible at this
X`09** time.
X`09*/
X`09
X`09fprintf(stderr,"%%NOTESCONVERT-F-BAD item header not found\n");
X`09fclose(out);
X`09exit(44);
X `7D ;
X
X if (fsetpos (in, &headerPosition) != 0)
X `7B
X`09fprintf(stderr,"%%NOTESCONVERT-F-BAD item header not found, setpos failed
V\n");
X`09fclose(out);
X`09exit(44);
X `7D ;
X
X /*
X ** The following loop terminates if end of file (the error occurred on
V the
X ** last note in the batch) or the beginning of the next note in the fi
Vle
X ** is detected. Note that this can result in the occasional bogus not
Ve
X ** being posted IF a counting error occurs AND the contents of the not
Ve
X ** was another note. On the other hand, this isn't all that common.
X */
X `20
X fprintf(stderr,"%%NOTESCONVERT-I-BAD item header not found, scanning f
Vor item header\n");
X for (j = 0 ; j < 2 ;)
X `7B
X`09fgetpos (in, &filePosition) ;
X`09p = fgets(inbuff,buffn,in);
X`09if ((!p) `7C`7C (*p == 0))
X`09`7B
X`09 fprintf(stderr,"%%NOTESCONVERT-I-END end of file\n");
X`09 fclose(out);
X`09 exit(1);
X`09`7D ;
X`09if (strcmp(inbuff,art_header) == 0)
X`09`7B
X`09 j++ ;
X`09`7D ;
X `7D ;
X `7D ;
X `20
X headerPosition = filePosition ;`09`09`09/* Note the position of the head
Ver of the current note.`09`09`09*/
X headerPositionValid = 1 ;`09`09`09`09/* Note the header position data st
Vructure is now valid.`09`09*/
X
X fgets(inbuff,buffn,in) ;
X if ((j = strlen (inbuff)) < 80)
X `7B
X inbuff`5Bj-1`5D = ' ' ;
X fgets(&inbuff`5Bj`5D ,buffn- j, in) ;`09`09`09/* For short message hea
Vder lines, get the next one, assuming that notes */
X`09`09`09`09`09`09`09/* has made a mistake or the user has embedded somethin
Vg like a carriage */
X`09`09`09`09`09`09`09/* return in the title.`09`09`09`09`09`09`09 */
X `7D ;
X
X extract_msg_subject(inbuff);
X extract_msg_info(fgets(inbuff,buffn,in));
X msg_subj_sub`5B0`5D = 0;
X while(fgets(inbuff,buffn,in))
X `7Bif (strcmp(inbuff,art_sep) == 0)
X`09 break;
X else
X`09 extract_msg_subj_sub(inbuff);`7D
X sprintf(outbuff,"From: %s\n",msg_from);
X output(outbuff);
X sprintf(outbuff,"Newsgroups: %s\n",newsgroup_name);
X output(outbuff);
X sprintf(outbuff,"Subject: `5B%d.%d`5D %s\n",
X`09 msg_note_major,
X`09 msg_note_minor,
X`09 (msg_subj_sub`5B0`5D == 0) ? msg_subj : msg_subj_sub);
X output(outbuff); `20
X set_msg_id(msg_note_major,msg_note_minor);
X sprintf(outbuff,"Message-ID: <%s>\n",msg_id);
X output(outbuff);
X sprintf(outbuff,"Date: %s\n",msg_date);
X output(outbuff);
X if (msg_note_minor != 0)
X `7Bset_msg_id(msg_note_major,0);
X sprintf(outbuff,"References: <%s>\n",msg_id);
X output(outbuff);`7D
X sprintf(outbuff,"Lines: %d\n",msg_nlines+1);
X output(outbuff);
X output("\n");
X for(j=0;j<msg_nlines;++j)
X `7Bfgets(inbuff,buffn,in);
X output(inbuff);`7D
X if (output_buffer`5Boutput_nchars-1`5D != '\n')
X output("\n");
X if (strcmp(msg_subj,"Reserved") == 0)
X output_reset();
X else
X `7Bfprintf(out,"#! rnews %d\n",output_nchars);
X output_flush(out);`7D`7D`7D
X
Xchar *msg_note_prefix = "Note ";
Xchar *msg_note_postfix1 = "No replies";
X
Xextract_msg_subject(line)
X char *line;
X`7Bchar *l,*p1,*p2;
X long n;
X if (!line)
X `7Bstrcpy(msg_subj,"UNKNOWN");
X msg_note_major = 0;
X msg_note_minor = 0;
X return;`7D
X n = strlen(msg_note_prefix);
X if (memcmp(line,msg_note_prefix,n) == 0)
X `7Bp1 = line + n;
X while(*p1 == ' ') ++p1;
X p2 = strchr(p1,' ');
X *p2 = 0;
X sscanf(p1,"%d.%d",&msg_note_major,&msg_note_minor);
X l = p2+1;`7D
X else
X `7Bmsg_note_major = 0;
X msg_note_minor = 0;
X l = line;`7D
X while(*l == ' ') ++l;
X n = strlen(l);
X p1 = l + n - 1;
X if (*p1 == '\n') *p1-- = 0;
X n = strlen(msg_note_postfix1);
X if (memcmp(p1 - n + 1,msg_note_postfix1,n) == 0)
X p1 -= n;
X else
X `7Bif (isdigit(*p1))
X while(isdigit(*p1)) *p1-- = 0;
X while(!isdigit(*p1)) *p1-- = 0;
X while(isdigit(*p1)) *p1-- = 0;`7D
X while(*p1 == ' ') *p1-- = 0;
X strcpy(msg_subj,l);`7D
X
Xextract_msg_info(line)
X char *line;
X`7Bchar *p1,*p2,*p3;
X long factor;
X if (!line)
X `7Bmsg_nlines = 0;
X strcpy(msg_from,"UNKNOWN");
X strcpy(msg_date,"UNKNOWN");
X return;`7D
X p1 = line + 61;
X p2 = p1;
X while(*p2 == ' ') ++p2;
X if (p3 = strchr(p2,'\n')) *p3 = 0;
X strcpy(msg_date,p2);
X while(!isdigit(*p1)) --p1;
X msg_nlines = 0;
X factor = 1;
X while(isdigit(*p1))
X `7Bmsg_nlines = msg_nlines + (factor * (*p1 - '0'));
X factor *= 10;
X --p1;`7D
X while(*p1 == ' ') --p1;
X *(p1+1) = 0;
X strcpy(msg_from,line);`7D
X
X
Xextract_msg_subj_sub(line)
X char *line;
X`7Bchar *p,*p1;
X long n;
X if (!(p = strchr(line,'-'))) return;
X if (p`5B1`5D != '<') return;
X p += 2;
X while(*p == ' ') ++p;
X n = strlen(p);
X p1 = p + n - 1;
X while((*p1 == ' ') `7C`7C (*p1 == '\n')) *p1-- = 0;
X if (*p1 != '-') return;
X *p1-- = 0;
X if (*p1 != '>') return;
X *p1-- = 0;
X while(*p1 == ' ') *p1-- = 0;
X strcpy(msg_subj_sub,p);`7D
X
X
Xset_msg_id(major,minor)
X long major,minor;
X`7Bsprintf(msg_id,"%d.%d.%s@dmc.com",
X`09 major,minor,
X`09 newsgroup_name);`7D
$ CALL UNPACK CONVERT.C;21 1798617680
$ v=f$verify(v)
$ EXIT
--
Dick Munroe Internet: munroe@dmc.com
Doyle Munroe Consultants, Inc. UUCP: ...uunet!thehulk!munroe
267 Cox St. Office: (508) 568-1618
Hudson, Ma. FAX: (508) 562-1133
GET CONNECTED!!! Send mail to info@dmc.com to find out about DMConnection.
--
Dick Munroe Internet: munroe@dmc.com
Doyle Munroe Consultants, Inc. UUCP: ...uunet!thehulk!munroe
267 Cox St. Office: (508) 568-1618
Hudson, Ma. 01749 USA FAX: (508) 562-1133
GET CONNECTED!!! Send mail to info@dmc.com to find out about DMConnection.
Technical Details
Message-ID:
<8045498@MVB.SAIC.COM>Path:
arc1-ca.pugleaf.net!sparky!uunet!stanford.edu!agate!dog.ee.lbl.gov!network.ucsd.edu!mvb.saic.com!vmsnet-sourcesShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!stanford.edu!agate!dog.ee.lbl.gov!network.ucsd.edu!mvb.saic.com!vmsnet-sources From: munroe@dmc.com (Dick Munroe) Newsgroups: vmsnet.sources Subject: VAXNOTES-TO-NEWS V2.2, part 01/01 Message-ID: <8045498@MVB.SAIC.COM> Date: Fri, 04 Sep 1992 05:44:48 GMT Organization: Doyle, Munroe Consultants, Inc., Hudson, MA Lines: 565 Approved: Mark.Berryman@Mvb.Saic.Com