Article View: vmsnet.sources
Article #40MAIL-TO-NOTES, part 01/02
From: Dick Munroe
Date: Fri, 11 Sep 1992 20:25
Date: Fri, 11 Sep 1992 20:25
1697 lines
50542 bytes
50542 bytes
Submitted-by: munroe@dmc.com (Dick Munroe)
Posting-number: Volume 3, Issue 170
Archive-name: mail_to_vaxnotes/part01
The MAILTONOTES program takes a mail file, complete with headers, and
adds it to a VAXNOTES conference. Most mail headers are stripped out.
The subject of the mail message is used to keep messages together --
messages with the same subject (with leading "re:" stripped off) will
be kept under the same topic.
--
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.
$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-010 25-Jun-1992
$! On 5-SEP-1992 08:02:19.52 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
$!
$!+ THIS PACKAGE DISTRIBUTED IN 2 PARTS, TO KEEP EACH PART
$! BELOW 100 BLOCKS
$!
$! 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. 00README.TXT;6
$! 2. DELIVERTONOTES.COM;14
$! 3. ENVELOPE.COM;10
$! 4. MAIL.DELIVERY;14
$! 5. MAILTONOTES.C;1
$! 6. MAILTONOTES.OPT;2
$! 7. MAKESUBJECTS.COM;3
$! 8. NOTEDIR.C;72
$! 9. NOTEDIR.OPT;2
$! 10. NOTES.FDL;6
$! 11. NOTESCODES.H;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 = "!"
$ 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'
X17-October-1990
X
XThis documentation is sketchy at best. Hopefully, it will get
Xyou started.
X
XThe MAILTONOTES program takes a mail file, complete with headers, and
Xadds it to a VAXNOTES conference. Most mail headers are stripped out.
XThe subject of the mail message used to keep messages together --
Xmessages with the same subject (with leading "re:" stripped off) will
Xbe kept under the same topic.`20
X
XYou must create a subjects index file for each conference you wish
Xto use with MAILTONOTES, see MAKESUBJECTS.COM.
X
XEnclosed in this distribution are the PMDF/DELIVER configuration files
XI use here. You don't have to use PMDF, it is just one way
Xto direct incoming mail to the MAILTONOTES program.
X
XFor mailing lists, etc, that I want to go to a Notes conference, I
Xsetup a VMS mail forwarding entry:
X
Xe.g.:
XMAIL> SET FORW/USER=INFOVAX DELIVER%MAILTONOTES
X
XThere is a MAILTONOTES account setup to do all the forwarding.
X
XFiles in this distribution:
X
Xmailtonotes.c`09`09Source: $ cc mailtonotes
Xmailtonotes.opt`09`09Link options file: $link mailtonotes/opt
Xnotes.fdl`09`09Used by makesubjects.com
Xmakesubjects.com`09Creates notes$library:conferencename.subjects
Xmail.delivery`09`09DELIVER configuration file for MAILTONOTES user
Xdelivertonotes.com`09Called by DELIVER in MAILTONOTES account
Xenvelope.com`09`09Called by DELIVER in MAILTONOTES account
Xnotedir.c`09`09A utility program to mangle notesfiles
Xnotedir.opt`09`09Link options for notedir
X
X05-Sep-1992
X
XI ran across a reference to this nifty piece of code and thought it deserved
V a
Xlittle wider distribution. I'll be working on it to do the "other half" of
V the
Xnotes to news gateway problem I've been working on (as time allows). I have
Vn't
Xactually had a chance to try it yet, so I really DON'T know if it works or n
Vot.`20
XOne of the interesting things about it though is that it uses the callable
Xnotes interface.
X
XFor those of you without PMDF, you can get the DELIVER piece of it from any
XVMSNET.SOURCES archive site near you. You may need to to a little adjustmen
Vt
Xto the code as the expected environment for mail delivery is via TWGs SMTP,
V but
Xthat shouldn't be too bad.
X
XIn the mean time use it in good health.
X
XDick Munroe
XDoyle, Munroe Consultants, Inc.
Xmunroe@dmc.com
$ CALL UNPACK 00README.TXT;6 461229752
$ create 'f'
X$!
X$! delivertonotes
X$!
X$! usage: @delivertonotes notefilename
X$! other symbols: FROM, TO, SUBJECT, QFROM, QQFROM, QTO, QQTO,
X$! QSUBJECT, QQSUBJECT, MESSAGE_FILE, MESAGE_DELETE
X$!
X$ on error then goto bomb
X$ define sys$output dua0:`5Bmailtonotes`5Ddelivertonotes.log ! open a log
X$ set verify
X$ p1 = f$edit(p1,"TRIM, UPCASE")
X$ mailtonotes :== $dua0:`5Bmailtonotes`5Dmailtonotes
X$ mailtonotes 'p1' 'message_file' "notes$library:.subjects"
X$ exit
X$!
X$!
X$bomb:
X$ savestatus = $status
X$ define sys$output dua0:`5Bmailtonotes`5Dunknown.log ! open a log
X$ show symbol savestatus
X$ copy 'message_file' dua0:`5Bmailtonotes.unknown`5Dunknown.dat;0
X$ set noverify
X$ write sys$output "unknown.com called at ",f$time()
X$ write sys$output "To: ", to
X$ write sys$output "From: ", from
X$ write sys$output "Subject: ", subject
X$ mail /subject="mailtonotes bomb" nl: _ccaw001
X$ exit
$ CALL UNPACK DELIVERTONOTES.COM;14 1699092688
$ create 'f'
X$!
X$! delivertonotes - envelope version
X$!
X$! This moves the selection of the notesfile from matching
X$! in mail.delivery to mailtolist. It is assumed that the
X$! "X-Envelope-To" header will point to (probably via a logical)
X$! to the name of the notesfile to use. This is since the
X$! "To" field of the mail file isn't a very good thing
X$! to match to. Yuk.
X$!
X$! usage: @envelope
X$! other symbols: FROM, TO, SUBJECT, QFROM, QQFROM, QTO, QQTO,
X$! QSUBJECT, QQSUBJECT, MESSAGE_FILE, MESAGE_DELETE
X$!
X$ on error then goto bomb
X$ define sys$output dua0:`5Bmailtonotes`5Ddelivertonotes.log ! open a log
X$ set verify
X$ p1 = f$edit(p1,"TRIM, UPCASE")
X$ mailtolist :== $dua0:`5Bmailtonotes`5Dmailtolist
X$!
X$! define envelope to actual filename translation here
X$!
X$ define infotcpip "info-tcpip-2"
X$ define infovax "info-vax-2"
X$ define rfclist "rfc-list"
X$ define xwlist "xwindow-list-2"
X$ define egppeople "egp-people"
X$ define snmp "snmp-list"
X$ define ietf "ietf-list"
X$ define unknown "scratch"
X$!
X$ mailtolist envelope 'message_file' "dua0:`5Bnetdist.mailer`5D.subjects"
X$ exit
X$!`20
X$bomb:
X$ savestatus = $status
X$ define sys$output dua0:`5Bmailtonotes`5Dunknown.log ! open a log
X$ show symbol savestatus
X$ copy 'message_file' dua0:`5Bmailtonotes.unknown`5Dunknown.dat;0
X$ set noverify
X$ write sys$output "unknown.com called at ",f$time()
X$ write sys$output "To: ", to
X$ write sys$output "From: ", from
X$ write sys$output "Subject: ", subject
X$ mail /subject="envelope bomb" nl: _ccaw001
X$ exit
$ CALL UNPACK ENVELOPE.COM;10 1818205897
$ create 'f'
X!<from-pat> <to-pat> <subj-pat> <accept> <action> <parameter>
X! Accept items:
X! A - Always apply this directive; ignore results of comparison
X! X - Never apply this directive; ignore the results of comparison
X! T - Apply this directive if all patterns matched
X! F - Apply this directive if not all patterns matched
X! O - Apply this directive if all matched and no other directive has
X! been applied to this message
X! B - Apply this directive if no matches and no previous directives
X! have been applied.
X! E - This directive applies if all patterns matched OR no other
X! directive has been applied so far.
X!
X! Actions:
X! A - append the body of the message to file <parameter>. File
X! must already exist.
X! C - copy the body to file <parameter>.
X! D - deliver the message normally (place in NEWMAIL mail folder).
X! V - deliver message normally using SYSTEM privilege. This identical
X! to "D" except that the "From:" field is set to match original
X! sender. Requires that user be fully privileged.
X! E - execute the specified command. The DCL command <parameter> is executed
V.
X! DCL symbols provided are: FROM, TO, SUBJECT, QFROM, QQFROM, QTO, QQTO,
X! QSUBJECT, QQSUBJECT, MESSAGE_FILE, MESAGE_DELETE
X! F - Forward the message. The message is forwarded to <parameter>
X! W - Forward using privileges. Similar in effect to V.
X! Q - quit; take no action and abort.
X!
X!
X! New groups must also be defined in envelope.com
X!
X* "infotcpip*" * O E "@delivertonotes.com info-tcpip-2"
X* "infovax*" * O E "@delivertonotes.com info-vax-2"
X* "info-vax*" * O E "@delivertonotes.com info-vax-2"
X* "rfclist*" * O E "@delivertonotes.com rfc-list"
X* "xwlist*" * O E "@delivertonotes.com xwindow-list-2"
X* "xpert*" * O E "@delivertonotes.com xwindow-list-2"
X* "egppeople*" * O E "@delivertonotes.com egp-people"
X* "snmp*" * O E "@delivertonotes.com snmp-list"
X* "ietf*" * O E "@delivertonotes.com ietf-list"
X* * * O E "@envelope.com"
X
X
$ CALL UNPACK MAIL.DELIVERY;14 1180387275
$ create 'f'
X/*
X * Copyright 1989 The University of Texas at Austin
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation, and that the name of The University of Texas
X * not be used in advertising or publicity pertaining to distribution of
X * the software without specific, written prior permission. The
X * University of Texas makes no representations about the suitability of
X * this software for any purpose. It is provided "as is" without express
X * or implied warranty.
X *`20
X * THE UNIVERSITY OF TEXAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS BE LIABLE FOR ANY
X * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
X *
X * Author:`20
X * Rick Watson`20
X * The University of Texas Computation Center, 512/471-3241
X * internet: rick@digate.cc.utexas.edu bitnet: watson@utadnx
X * uucp: ...!cs.utexas.edu!ut-emx!rick span: utspan::utadnx::watso
Vn
X */
X
X/***`09mail-to-notes.
X*
X*`09Used by the notes remailer.
X*`091. Deletes mail extraneous headers.
X*`092. Keeps an index of subject lines and note id's. Notes
X*`09 with equivalent subjects will be "noted" under the same
X*`09 topic.
X*`09usage: mailtonotes notefilename inputfile `5Bsubjectsfileloc`5D
X*
X*`09Subjectsfile is an optional default specification of the
X*`09subjects file directory. e.g.: "twg$tcp:`5Bnetdist.mailer`5D.subjects"
X*
X*`0903/12/90 -- R. Watson
X*`09 Add hack for delivertonotes such that if`20
X*`09 notefilename == "envelope" use
X*`09 the x-envelope-to mail header as the notefilename.
X*`09 This notefilename will probably be a logical pointer
X*`09 to the real notefilename so that we can change the
X*`09 name of the notefile.
X*`0906/04/90 -- R. Watson
X*`09 Fix so that if the subject key is invalid (probably we
X*`09 deleted the note) we make a new note instead and update
X*`09 the key. Don't set duplicate notes hidden anymore - delete
X*`09 them.
X*/
X
X#include <rms.h>
X#include <stdio.h>
X#include "notescodes.h"
X`09
X#define TRUE 1
X#define FALSE 0
X
Xstruct hline `7B
X`09struct hline* next;`09`09`09/* pointer to next */
X`09int type;`09`09`09`09/* type of header */
X`09char buf`5B512`5D;`09`09`09`09/* line buffer */
X`7D;`20
X
Xstruct list `7B
X`09short`09len;
X`09short`09item;
X`09char`09*buf;
X`09short`09*rla;
X`7D;
X
XFILE *inp;`09`09`09`09`09/* files */
Xstatic struct hline *hlist = 0;`09`09`09/* list of headers */
Xstatic struct hline *dlist = 0;`09`09`09/* first data line */
Xstatic struct hline *h;`09`09`09`09/* current line */
Xstatic struct hline *hlast;`09`09`09/* last in list */
Xstatic char *sp;`09`09`09`09/* subject pointer */
Xstatic char *ep;`09`09`09`09/* envelope pointer */
Xstatic char key`5B80 + 8 + 1`5D;
Xstatic char *np;`09`09`09`09/* note number pointer */
Xstatic struct list ilst`5B15`5D;`09`09`09/* input list */
Xstatic struct list olst`5B15`5D;`09`09`09/* output list */
Xstatic int nf_context = 0;`09`09`09/* notesfile context */
Xstatic int note_context = 0;`09`09`09/* note context */
Xstatic int one = 1;
Xstatic int zero = 0;
Xstatic int update = 0;`09`09`09`09/* update flag */
Xstatic int numnotes;
Xstatic char added`5B20`5D;`09`09`09`09/* added note string */
Xstatic char blinkid`5B20`5D;`09`09`09/* topic id */
Xstatic char userarea`5B255`5D;`09`09`09/* existing user area */
Xstatic struct FAB fab;`09`09`09`09/* for subject key */
Xstatic struct RAB rab;
Xstatic char checkbuf`5B`5D = "xxxxxxxx xxxxxxxx xxxxxxxx\0";
Xstatic char *dflt_subjects = "notes$library:.subjects";
X
X#define NKEYS 4
X#define T_SUBJECT 0`09`09`09`09/* must keep following order */
X#define T_ENVELOPE 3
Xstatic char *hdrs`5B`5D = `7B"subject",`09`09/* must be 0 or fix above */
X`09`09`09"date",
X`09`09`09"from",
X`09`09`09"x-envelope-to"`7D;`09/* must be 3 */
X
Xmain(argc, argv)
Xint argc;
Xchar *argv`5B`5D;
X`7B
X`09int stat, hide;
X`09char record`5B80 + 8`5D;
X`09int newkey;
X`09`09
X/* parse the parameters */
X
X`09if (argc < 3) `7B
X`09`09fprintf(stdout, "invalid argument count\n");
X`09`09exit(0);
X`09`7D
X
X`09if (argc >= 4)`09`09`09`09/* if specified default subjects */
X`09 dflt_subjects = argv`5B3`5D;
X
X`09inp = fopen(argv`5B2`5D, "r");`09`09/* open the input file */
X`09if (inp == NULL) `7B
X`09`09perror("fopen inp");
X`09`09exit(0);
X`09`7D
X
X`09scavengeheader();`09`09`09/* parse the mail headers */
X
X`09/*
X`09 * If there is an x-envelope-to and the parameter is
X`09 * envelope, then use the envelope for the notefile.
X`09 */
X`09if (ep &&
X`09`09((strcmp(argv`5B1`5D, "envelope")==0) `7C`7C
X`09`09 (strcmp(argv`5B1`5D, "ENVELOPE")==0))) `7B
X`09`09`09argv`5B1`5D = ep;
X`09`09`09fprintf(stdout, "Using envelope: %s\n", ep);
X`09`7D
X
X`09lookup_subjectkey(argv`5B1`5D);`09`09/* look up subject */
X
X`09fprintf(stdout, "Subject key = %s\n", key);
X`09if (np)`20
X`09 fprintf(stdout, "Old note = %s\n", np);
X
X`09stat = notefile_begin(argv`5B1`5D);`09`09/* get the notes file */
X`09checkstat(stat, "notefile_begin");
X
X`09stat = note_begin();
X`09checkstat(stat, "note_begin");
X
X`09stat = note_add();
X
X`09stat = note_add_text();
X
X`09hide = checkother();
X
X`09if (hide) `7B
X`09`09fprintf(stdout, "Duplicate note so deleted\n");
X`09`09stat = deletenote(added);
X`09`09checkstat(stat, "delete note");
X`09`7D
X`09else `7B
X`09`09stat = moduserarea(checkbuf, FALSE);
X`09`09checkstat(stat, "moduserarea");
X`09`7D
X`09
X`09stat = note_end();
X`09checkstat(stat, "note_end");
X
X`09if (!np `7C`7C update) `7B`09`09`09/* if no key or updating */
X`09`09sscanf(added,"%d", &newkey);`09/* get correct format */
X`09`09sprintf(&key`5B80`5D, "%06d.0", newkey);
X`09`09fprintf(stdout, "%s key = %s\n",`20
X`09 (update)? "Updated" : "Added", added);
X`09`09write_key();
X`09`7D
X
X`09notefile_end();
X`7D
X
X
X/**`09scavengeheader - parse the mail headers.
X*/
Xscavengeheader()
X`7B
X`09int hl;`09`09`09`09`09/* header length */
X`09int n, i;
X`09char *buf;
X`09char hdr`5B512`5D;
X`09char *c1, *c2;
X
X`09hlast = &hlist;
X
X`09sp = 0;`09`09`09`09`09/* no subject yet */
X`09ep = 0;`09`09`09`09`09/* no envelope */
X
X/* prime the input buffer */
X
X`09h = (struct hline *) malloc(sizeof(struct hline));
X`09if (h == 0) `7B
X`09`09fprintf(stdout, "couldn't malloc hline\n");
X`09`09exit(0);
X`09`7D
X
X
X reread:
X`09if (fgets(h->buf, sizeof(h->buf), inp) == NULL) `7B`09 /* if eof */
X`09`09fprintf(stdout, "no lines in file\n");
X`09`09fclose(inp);
X`09`09exit(0);
X`09`7D
X`09n = strlen(h->buf);
X`09if (h->buf`5Bn-1`5D == '\n') `7B`09`09/* kill \n */
X`09`09h->buf`5Bn-1`5D = 0;
X`09`09n--;
X`09`7D
X`09if (n <= 0) goto reread;`09`09/* if blank ? */
X
X`09for (;;) `7B
X`09`09c1 = strchr(h->buf, ':');`09/* find end of header */
X`09`09if (c1 == NULL) `7B`09`09/* if end of headers */
X`09`09`09dlist = h;`09`09/* save 1st data line */
X`09`09`09break;
X`09`09`7D
X
X`09`09c2 = h->buf;
X`09`09hl = (int) (c1 - c2);`09`09/* # chars in keyword */
X`09`09strncpy(hdr, h->buf, hl);`09/* get keyword */
X`09`09hdr`5Bhl`5D = 0;
X`09`09for (i = 0; i < hl; i++) hdr`5Bi`5D = tolower(hdr`5Bi`5D);
X
X`09`09for (i = 0; i < NKEYS; i++) `7B`09/* match keyword */
X`09`09`09if (strcmp(hdr, hdrs`5Bi`5D) == 0) break;`09/* if match */
X`09`09`7D
X
X`09`09h->type = i;`09`09`09/* save header type */
X`09`09switch (i) `7B
X
X`09`09case T_SUBJECT:`09`09`09/* subject */
X`09`09`09sp = &(h->buf`5B8`5D);`09/* locate nonblank */
X`09`09`09while ((*sp == ' ') `7C`7C (*sp == '\t')) sp++;
X
X`09`09`09hlast->next = h;`09/* link to list */
X`09`09`09h->next = 0;
X`09`09`09hlast = h;
X`09`09`09copyrest(FALSE);
X`09`09`09break;
X
X`09`09case T_ENVELOPE:`09`09/* x-envelope-to */
X`09`09`09ep = &(h->buf`5B14`5D);`09/* locate nonblank */
X`09`09`09while ((*ep == ' ') `7C`7C (*ep == '\t')) ep++;
X
X`09`09`09hlast->next = h;`09/* link to list */
X`09`09`09h->next = 0;
X`09`09`09hlast = h;
X`09`09`09copyrest(FALSE);
X`09`09`09break;
X
X`09`09default:
X`09`09`09if (i >= NKEYS) `7B`09`09/* if not in list */
X`09`09`09`09free(h);`09`09/* drop this header */
X`09`09`09`09copyrest(TRUE);
X`09`09`09`09break;`09`09`09
X`09`09`09`7D
X`09`09`09else `7B`09`09`09
X`09`09`09`09hlast->next = h;`09/* link to list */
X`09`09`09`09h->next = 0;
X`09`09`09`09hlast = h;
X`09`09`09`09copyrest(FALSE);
X`09`09`09`09break;
X`09`09`09`7D
X`09`09`7D /* switch */
X`09`7D /* for */
X`7D
X
X
X/**`09copyrest(flush) - handle possible continuation lines
X*/
Xcopyrest(flush)
Xint flush;`09`09`09/* true if flushing cont lines */
X`7B
X`09int i, n;
X
X`09for (;;) `7B
X`09`09h = (struct hline *) malloc(sizeof(struct hline));
X`09`09if (h == 0) `7B
X`09`09`09fprintf(stdout, "couldn't malloc hline\n");
X`09`09`09exit(0);
X`09`09`7D
X`09`09if (fgets(h->buf, sizeof(h->buf), inp) == NULL) `7B`09 /* if eof */
X`09`09`09fclose(inp);
X`09`09`09fprintf(stdout, "no data after mail headers\n");
X`09`09`09exit(0);
X`09`09`7D
X`09`09n = strlen(h->buf);
X`09`09if (h->buf`5Bn-1`5D == '\n') `7B`09`09/* kill \n */
X`09`09`09h->buf`5Bn-1`5D = 0;
X`09`09`09n--;
X`09`09`7D
X
X`09`09if ((h->buf`5B0`5D == ' ') `7C`7C (h->buf`5B0`5D == '\t')) `7B`09/* po
Vssible cont */
X`09`09`09for (i = 0; i < n; i++) `7B`09/* find non-white */
X`09`09`09`09if ((h->buf`5Bi`5D != ' ') && (h->buf`5Bi`5D != '\t') &&
X`09`09`09`09`09(h->buf`5Bi`5D != '\n')) goto oks;
X`09`09`09`7D
X`09`09`7D
X
X`09`09return;`09`09/* leave line in buf */
X
X`09`09oks:
X`09`09if (!flush) `7B
X`09`09`09hlast->next = h;`09/* link to list */
X`09`09`09h->next = 0;
X`09`09`09hlast = h;
X`09`09`7D
X`09`09else free(h);
X`09`7D /* for */
X`7D
X
X
X/**`09notefile_begin.
X*/
Xnotefile_begin(notefile)
Xchar *notefile;
X`7B
X`09int stat, i;
X`09static char *dflt = "notes$library:.note";
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOTEFILE_FILE_NAME;
X`09ilst`5Bi`5D.len = strlen(notefile);
X`09ilst`5Bi`5D.buf = notefile;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTEFILE_DEFAULT_NAME;
X`09ilst`5Bi`5D.len = strlen(dflt);
X`09ilst`5Bi`5D.buf = dflt;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;`09`09/* terminator */
X`09ilst`5Bi`5D.len = 0;
X
X`09i = 0;
X`09olst`5Bi`5D.item = NOTES$K_NOTEFILE_NUMNOTES;
X`09olst`5Bi`5D.len = 4;
X`09olst`5Bi`5D.buf = (char*) &numnotes;
X`09olst`5Bi`5D.rla = 0;
X
X`09olst`5B++i`5D.item = 0;
X
X`09stat = notes$notefile_begin(&nf_context, &ilst, &olst);
X
X`09return stat;
X`7D
X
X
X/**`09notefile_end.
X*/
Xnotefile_end()
X`7B
X`09int stat, i;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09stat = notes$notefile_end(&nf_context, &ilst, &olst);
X
X`09return stat;
X`7D
X`09
X
X/**`09note_begin.
X*/
Xnote_begin()
X`7B
X`09int stat, i;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTEFILE_CONTEXT;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &nf_context;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09stat = notes$note_begin(¬e_context, &ilst, &olst);
X
X`09return stat;
X`7D
X
X
X/**`09note_end.
X*/
Xnote_end()
X`7B
X`09int stat, i;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09stat = notes$note_end(¬e_context, &ilst, &olst);
X
X`09return stat;
X`7D
X
X
X/**`09note_add.
X*/
Xnote_add()
X`7B
X`09int i, stat, blink;
X`09short addedl;
X`09short blinkidl;
X
X`09if (np && !validnote(np)) `7B`09`09/* if old note gone */
X`09`09np = 0;`09`09`09`09/* forget we have a key */
X`09`09update = TRUE;`09`09`09/* but update it */
X`09`09fprintf(stdout, "Old note was invalid (missing)\n");
X`09`7D
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09if (np) `7B`09`09`09/* if reply */
X`09`09ilst`5B++i`5D.item = NOTES$K_NOTE_BLINK_ID;
X`09`09ilst`5Bi`5D.buf = np;
X`09`09ilst`5Bi`5D.len = strlen(np);
X`09`09ilst`5Bi`5D.rla = 0;
X`09`09blink = i;
X`09`7D
X`09else `7B`09`09`09`09/* else main topic - set title */
X`09`09if (!sp) sp = "";`09`09`09/* if empty subject */
X`09`09ilst`5B++i`5D.item = NOTES$K_NOTE_TITLE;
X`09`09ilst`5Bi`5D.len = strlen(sp);
X`09`09ilst`5Bi`5D.buf = sp;
X`09`09ilst`5Bi`5D.rla = 0;
X`09`7D
X
X`09/* add a template user area so record won't change size */
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_USER_AREA;
X`09ilst`5Bi`5D.buf = "xxxxxxxx xxxxxxxx xxxxxxxx";
X`09ilst`5Bi`5D.len = strlen(ilst`5Bi`5D.buf);
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X/* THIS SHOULD MATCH UP WITH NUMNOTES+1 IF NEW NOTE */
X
X`09i = 0;
X`09olst`5Bi`5D.item = NOTES$K_NOTE_ID;`09`09/* find out what note was genera
Vted */
X`09olst`5Bi`5D.len = sizeof(added);
X`09olst`5Bi`5D.buf = added;
X`09olst`5Bi`5D.rla = &addedl;
X
X`09olst`5B++i`5D.item = NOTES$K_NOTE_BLINK_ID; /* get topic id */
X`09olst`5Bi`5D.len = sizeof(blinkid);
X`09olst`5Bi`5D.buf = blinkid;
X`09olst`5Bi`5D.rla = &blinkidl;
X
X`09olst`5B++i`5D.item = 0;
X
X`09stat = notes$note_add(¬e_context, &ilst, &olst);
X#if 0
X`09if (np && (stat == 0x3fb10b2)) `7B`09/* if couldn't find old note */
X`09`09/* try again with new note */
X`09`09fprintf(stdout, "Old note must be gone\n");
X`09`09if (!sp) sp = "";`09`09`09/* if empty subject */
X`09`09ilst`5Bblink`5D.item = NOTES$K_NOTE_TITLE;
X`09`09ilst`5Bblink`5D.len = strlen(sp);
X`09`09ilst`5Bblink`5D.buf = sp;
X`09`09ilst`5Bblink`5D.rla = 0;
X`09`09stat = notes$note_add(¬e_context, &ilst, &olst);
X`09`09update = TRUE;
X`09`7D
X#endif
X`09checkstat(stat, "note_add");
X
X`09added`5Baddedl`5D = 0;`09`09`09/* terminate strings */
X`09blinkid`5Bblinkidl`5D = 0;
X`09fprintf(stdout, "note added = %s\n", added);
X`7D
X
X`09
X/**`09note_add_text.
X*/
Xnote_add_text()
X`7B
X`09int i, ti, stat, n;
X`09char fname`5B255`5D;
X`09char buf`5B1024`5D;
X`09FILE *f;
X`09int sum, nline, nchar;
X
X`09sum = nline = nchar = 0;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_TEXT_STRING;
X`09ilst`5Bi`5D.rla = 0;
X`09ti = i;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09if (hlast != &hlist) `7B`09`09/* if headers were found */
X`09`09h = &hlist;
X`09`09while (h = h->next) `7B
X`09`09`09if (h->type == T_ENVELOPE)`09/* if envelope */
X`09`09`09 continue;`09`09`09/* don't put */
X`09`09`09ilst`5Bti`5D.buf = h->buf;
X`09`09`09ilst`5Bti`5D.len = strlen(h->buf);
X`09`09`09stat = notes$note_add_text(¬e_context, &ilst, &olst);
X`09`09`09checkstat(stat, "add_text");
X`09`09`7D
X`09`7D
X
X`09if (dlist) `7B`09`09`09`09/* if spare data line */
X`09`09h = dlist;
X
X`09`09for (i = 0; i < strlen(h->buf); i++) `7B`09/* sum the line */
X`09`09`09sum += h->buf`5Bi`5D;
X`09`09`7D
X`09`09nchar += strlen(h->buf);`09`09/* sum chars */
X`09`09nline += 1;
X
X`09`09ilst`5Bti`5D.buf = h->buf;
X`09`09ilst`5Bti`5D.len = strlen(h->buf);
X`09`09stat = notes$note_add_text(¬e_context, &ilst, &olst);
X`09`09checkstat(stat, "add_text");
X`09`7D
X
X`09while (fgets(buf, sizeof(buf)-1, inp) != 0) `7B`09/* while not eof */
X`09`09n = strlen(buf);
X`09`09if (buf`5Bn-1`5D == '\n') `7B`09`09`09/* kill \n */
X`09`09`09buf`5Bn-1`5D = 0;
X`09`09`09n--;
X`09`09`7D
X
X`09`09for (i = 0; i < n; i++) `7B`09`09/* sum the line */
X`09`09`09sum += buf`5Bi`5D;
X`09`09`7D
X`09`09nchar += n;`09`09`09`09/* sum chars */
X`09`09nline += 1;
X
X`09`09ilst`5Bti`5D.buf = buf;
X`09`09ilst`5Bti`5D.len = n;
X`09`09stat = notes$note_add_text(¬e_context, &ilst, &olst);
X`09`09checkstat(stat, "add_text");
X`09`7D
X
X`09fclose(inp);
X
X`09ilst`5Bti`5D.item = NOTES$K_TEXT_END;`09/* signal eof */
X`09ilst`5Bti`5D.len = 4;
X`09ilst`5Bti`5D.buf = (char*) &one;
X`09ilst`5Bti`5D.rla = 0;
X
X`09stat = notes$note_add_text(¬e_context, &ilst, &olst);
X`09checkstat(stat, "add_text");
X
X/* set the user data area */
X
X`09sprintf(checkbuf, "%08X %08X %08X", nline, nchar, sum);
X`7D
X
X
X/**`09checkstat.
X*/
Xcheckstat(stat, string)
Xint stat;
Xchar *string;
X`7B
X`09if ((stat & 1) == 1) return;
X
X`09fprintf(stdout, "%s: 0x%x\n", string, stat);
X`09lib$stop(stat);
X`7D
X
X
X/**`09lookup_subjectkey.
X*/
Xlookup_subjectkey(subjectfile)
Xchar *subjectfile;
X`7B
X`09static char record`5B80 + 8 + 1`5D;
X`09int i, stat, n;
X`09char *skp;
X
X`09np = 0;
X
X`09skp = 0;`09`09`09`09/* build the key */
X`09key`5B0`5D = 0; key`5B80`5D = 0;
X`09if (sp) strncpy(key, sp, 80);
X`09skp = key;
X`09for(i = 0; i < strlen(key); i++) key`5Bi`5D = tolower(key`5Bi`5D);
X`09for (;;) `7B`09`09`09`09/* remove leading re: */
X`09`09if (strncmp(skp, "re:", 3) == 0) skp += 3;
X`09`09else break;
X`09`7D
X`09for (;;) `7B`09`09`09`09/* remove leading white */
X`09`09if ((*skp == ' ') `7C`7C (*skp == '\t')) skp++;
X`09`09else break;
X`09`7D
X`09n = strlen(skp);
X`09if (skp != key) `7B`09`09`09/* if chars removed */
X`09`09for (i = 0; i < n; i++) key`5Bi`5D = *skp++;
X`09`09key`5Bn`5D = 0;
X`09`7D
X`09skp = key;
X`09for (i = strlen(skp); i < 79; i++) key`5Bi`5D = ' '; /* trail blanks */
X`09key`5B79`5D = '!';
X`09
X`09fab = cc$rms_fab;`09`09`09/* initialize fab */
X`09fab.fab$l_fna = subjectfile;
X`09fab.fab$b_fns = strlen(subjectfile);
X`09fab.fab$l_dna = dflt_subjects;
X`09fab.fab$b_dns = strlen(dflt_subjects);
X`09fab.fab$b_fac `7C= (FAB$M_GET `7C FAB$M_PUT `7C FAB$M_UPD);
X`09fab.fab$b_shr `7C= (FAB$M_SHRGET `7C FAB$M_SHRPUT);
X
X`09stat = sys$open(&fab);
X`09checkstat(stat, "no subject key file");
X
X`09rab = cc$rms_rab;`09`09`09/* initialize rab */
X`09rab.rab$l_fab = &fab;
X`09rab.rab$b_rac = RAB$C_KEY;
X
X`09stat = sys$connect(&rab);
X`09checkstat(stat, "couldn't connect");
X
X`09rab.rab$l_kbf = key;`09`09`09/* set key */
X`09rab.rab$b_ksz = 80;
X`09rab.rab$l_ubf = record;
X`09rab.rab$w_usz = sizeof(record);
X`09rab.rab$l_rop `7C= RAB$M_RRL;`09`09/* read even if locked */
X
X`09stat = sys$get(&rab, 0, 0);
X`09if ((stat & 1) == 1) `7B`09`09`09/* if found */
X`09`09np = &record`5B80`5D;
X`09`09record`5B80+8`5D = 0;`09`09/* insure string terminated */
X`09`7D
X`09else `7B`09`09`09`09`09/* DEBUG - SEE WHAT HAPPENS */
X`09`09fprintf(stdout, "no key stat=0x%x\n", stat);
X`09`7D
X`7D
X
X
X/**`09write_key - write key to subjects index.
X*/
Xwrite_key()
X`7B
X`09int stat;
X
X`09rab.rab$l_rbf = key;
X`09rab.rab$w_rsz = 80 + 8;
X
X`09if (update)
X`09 stat = sys$update(&rab, 0, 0);
X`09else
X`09 stat = sys$put(&rab, 0, 0);
X`09checkstat(stat, "put key");
X
X`09sys$close(&fab, 0, 0);
X`7D
X
X
X/**`09moduserarea - modify user area specified by current note id.
X*/
Xmoduserarea(string, hide)
Xchar *string;`09`09`09`09/* string to add to user data */
Xint hide;`09`09`09`09/* hide flag */
X`7B
X`09int i, stat;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09if (hide) `7B
X`09`09ilst`5Bi`5D.item = NOTES$K_NOTE_HIDDEN;
X`09`09ilst`5Bi`5D.len = 4;
X`09`09ilst`5Bi`5D.buf = (char*) &one;
X`09`09ilst`5Bi`5D.rla = 0;
X`09`7D
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09ilst`5Bi`5D.len = strlen(added);
X`09ilst`5Bi`5D.buf = (char *) added;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_USER_AREA;
X`09ilst`5Bi`5D.buf = string;
X`09ilst`5Bi`5D.len = strlen(ilst`5Bi`5D.buf);
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09stat = notes$note_modify(¬e_context, &ilst, &olst);
X
X`09return stat;
X`7D
X
X
X/**`09checkother - check other notes on this topic for duplicates.
X*/
Xcheckother()
X`7B
X`09int i, stat;
X`09static int first = TRUE;
X`09short userareal;
X`09int hide = FALSE;
X`09char currentid`5B20`5D;
X`09short currentidl;
X
X`09for (;;) `7B
X`09`09i = 0;
X`09`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09`09ilst`5Bi`5D.len = 4;
X`09`09ilst`5Bi`5D.buf = (char*) &one;
X`09`09ilst`5Bi`5D.rla = 0;
X
X`09`09ilst`5B++i`5D.item = NOTES$K_NOTE_ALL_RESPONSES;
X`09`09ilst`5Bi`5D.len = 4;
X`09`09ilst`5Bi`5D.buf = (char*) &one;
X`09`09ilst`5Bi`5D.rla = 0;
X
X`09`09if (first) `7B
X`09`09`09first = FALSE;
X`09`09`09ilst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09`09`09ilst`5Bi`5D.len = strlen(blinkid);
X`09`09`09ilst`5Bi`5D.buf = (char *) blinkid;
X`09`09`09ilst`5Bi`5D.rla = 0;
X`09`09`7D
X`09`09else `7B
X`09`09`09ilst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09`09`09ilst`5Bi`5D.buf = currentid;
X`09`09`09ilst`5Bi`5D.len = strlen(currentid);
X`09`09`09ilst`5Bi`5D.rla = 0;
X
X`09`09`09ilst`5B++i`5D.item = NOTES$K_NOTE_NEXT_RESPONSE;
X`09`09`09ilst`5Bi`5D.len = 4;
X`09`09`09ilst`5Bi`5D.buf = (char*) &one;
X`09`09`09ilst`5Bi`5D.rla = 0;
X`09`09`7D
X
X`09`09ilst`5B++i`5D.item = 0;
X
X`09`09i = 0;
X`09`09olst`5Bi`5D.item = NOTES$K_NOTE_USER_AREA;
X`09`09olst`5Bi`5D.buf = userarea;
X`09`09olst`5Bi`5D.len = sizeof(userarea) - 1;
X`09`09olst`5Bi`5D.rla = &userareal;
X`09
X`09`09olst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09`09olst`5Bi`5D.buf = currentid;
X`09`09olst`5Bi`5D.len = sizeof(currentid);
X`09`09olst`5Bi`5D.rla = ¤tidl;
X
X`09`09olst`5B++i`5D.item = 0;
X
X`09`09stat = notes$note_get(¬e_context, &ilst, &olst);
X`09`09if (stat == NOTES$_NO_MORE_REPLIES) break;
X`09`09checkstat(stat, "note get");
X
X`09`09userarea`5Buserareal`5D = 0;
X`09`09currentid`5Bcurrentidl`5D = 0;
X
X`09`09if (strcmp(currentid, added)==0) continue;
X
X`09`09if (strcmp(userarea, checkbuf)==0) `7B`09/* if same check */
X`09`09`09fprintf(stdout, "new matches %s\n", currentid);
X`09`09`09hide = TRUE;
X`09`09`7D
X`09`7D /* for */
X
X`09return hide;
X`7D
X
X
X/**`09validnote - validate that note exists.
X*
X* `09returns FALSE if note does not exist
X*/
Xvalidnote(id)
Xchar *id;`09`09`09`09/* id of note to validate */
X`7B
X`09int i, stat;
X`09int old, new;
X`09char currentid`5B20`5D;
X`09short currentidl;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09ilst`5Bi`5D.len = strlen(id);
X`09ilst`5Bi`5D.buf = (char *) id;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09i = 0;
X`09olst`5Bi`5D.item = NOTES$K_NOTE_ID;
X`09olst`5Bi`5D.buf = currentid;
X`09olst`5Bi`5D.len = sizeof(currentid);
X`09olst`5Bi`5D.rla = ¤tidl;
X
X`09olst`5B++i`5D.item = 0;
X
X`09stat = notes$note_get(¬e_context, &ilst, &olst);
X`09if (!(stat & 1))
X`09 return FALSE;
X
X`09currentid`5Bcurrentidl`5D = 0;
X`09sscanf(np, "%d", &old);
X`09sscanf(currentid, "%d", &new);
X`09if (new == old)
X`09 return TRUE;
X`09else
X`09 return FALSE;
X`7D
X
X
X/**`09deletenote - delete a note.
X*/
Xdeletenote(id)
Xchar *id;`09`09`09`09/* id of note to delete */
X`7B
X`09int i, stat;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09ilst`5Bi`5D.len = strlen(id);
X`09ilst`5Bi`5D.buf = (char *) id;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09i = 0;
X`09olst`5Bi`5D.item = 0;
X
X`09stat = notes$note_delete(¬e_context, &ilst, &olst);
X`09return stat;
X`7D
X
X
$ CALL UNPACK MAILTONOTES.C;1 124448320
$ create 'f'
Xmailtonotes,sys$share:notes$share/share,sys$share:vaxcrtl/share
$ CALL UNPACK MAILTONOTES.OPT;2 795441330
$ create 'f'
X$ inquire name "Conference name"
X$ create /fdl=notes notes$library:'name'.subjects
$ CALL UNPACK MAKESUBJECTS.COM;3 104942486
$ create 'f'
X/*
X * Copyright 1989 The University of Texas at Austin
X *
X * Permission to use, copy, modify, and distribute this software and its
X * documentation for any purpose and without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and that
X * both that copyright notice and this permission notice appear in
X * supporting documentation, and that the name of The University of Texas
X * not be used in advertising or publicity pertaining to distribution of
X * the software without specific, written prior permission. The
X * University of Texas makes no representations about the suitability of
X * this software for any purpose. It is provided "as is" without express
X * or implied warranty.
X *`20
X * THE UNIVERSITY OF TEXAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS BE LIABLE FOR ANY
X * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
X *
X * Author:`20
X * Rick Watson`20
X * The University of Texas Computation Center, 512/471-3241
X * internet: watson@utadnx.cc.utexas.edu bitnet: watson@utadnx
X * uucp: ...!cs.utexas.edu!ut-emx!rick span: utspan::utadnx::watso
Vn
X */
X
X#include <descrip.h>
X#include <rms.h>
X#include <stdio.h>
X#include "notescodes.h"
X
Xstruct list `7B
X`09short`09len;
X`09short`09item;
X`09char`09*buf;
X`09short`09*rla;
X`7D;
X
Xstatic char title`5B256`5D;
Xstatic short titlel;
Xstatic char noteid`5B20`5D;
Xstatic short noteidl;
Xstatic struct list ilst`5B15`5D;`09`09`09/* input list */
Xstatic struct list olst`5B15`5D;`09`09`09/* output list */
Xstatic int nf_context = 0;`09`09`09/* notesfile context */
Xstatic int note_context = 0;`09`09`09/* note context */
Xstatic int one = 1;
Xstatic int zero = 0;
Xstatic int numnotes;
Xstatic char *notefile = 0;`09`09`09/* notefile name */
Xstatic long sincetime`5B2`5D;`09`09`09/* sincetime quadword */
Xstatic long beforetime`5B2`5D;`09`09`09/* beforetime quadword */
Xstatic long createtime`5B2`5D;`09`09`09/* note create time */
Xstatic int since = 0;`09`09`09`09/* since flag */
Xstatic int before = 0;`09`09`09`09/* before flag */
Xstatic int delete = 0;`09`09`09`09/* delete flag */
Xstatic int modify = 0;`09`09`09`09/* modify flag */
Xstatic int buildsub = 0;`09`09`09/* building subjects flag */
Xstatic int iflag = 0;`09`09`09`09/* id specified flag */
Xstatic char userarea`5B255`5D;`09`09`09/* user area data */
Xstatic short userareal;`09`09`09`09/* length of user area */
Xstatic char *dflt_subjects = "twg$tcp:`5Bnetdist.mailer`5D.subjects";
Xstatic char subjects`5B80`5D;`09`09`09/* subjects file */
Xstatic char key`5B80 + 8 + 1`5D;
Xstatic struct FAB fab;`09`09`09`09/* for subject key */
Xstatic struct RAB rab;
Xstatic int inote, inoterep;`09`09`09/* individual note */
X
X#define NKEYS 3
Xstatic char *hdrs`5B`5D = `7B"SUBJECT",
X`09`09`09"DATE",
X`09`09`09"FROM"`7D;
X
Xmain(argc, argv)
Xint argc;
Xchar *argv`5B`5D;
X`7B
X`09int stat;
X`09int i;
X`09char creates`5B24`5D;
X`09struct dsc$descriptor_s timbuf = `7B23, DSC$K_DTYPE_T, DSC$K_CLASS_S, cre
Vates`7D;
X
X`09parsecommand(argc, argv);
X
X`09if (!notefile) `7B
X`09`09fprintf(stdout, "usage: notedir `5Bopts`5D <notefile>\n");
X`09`09fprintf(stdout, " -s since time\n");
X`09`09fprintf(stdout, " -b before time\n");
X`09`09fprintf(stdout, " -i note id\n");
X`09`09fprintf(stdout, " -delete\n");
X`09`09fprintf(stdout, " -m (set crc)\n");
X`09`09fprintf(stdout, " -r subjectsfile (rebuild file)\n");
X
X`09`09exit(-1);
X`09`7D
X
X`09stat = notefile_begin(notefile);`09/* get the notes file */
X`09checkstat(stat, "notefile_begin");
X
X`09stat = note_begin();
X`09checkstat(stat, "note_begin");
X
X`09for (;;) `7B
X`09`09stat = note_get_next();
X`09`09if (!(stat & 1)) break;
X
X`09`09title`5Btitlel`5D = 0;
X`09`09noteid`5Bnoteidl`5D = 0;
X`09`09sys$asctim(0, &timbuf, createtime, 0);
X`09`09creates`5B17`5D = 0;
X`09`09creates`5Btimbuf.dsc$w_length`5D = 0;
X`09`09printf("%s: %s %s\n", noteid, creates, title);
X`09`09if (userareal) `7B
X`09`09`09userarea`5Buserareal`5D = 0;
X`09`09`09printf("user: %s\n", userarea);
X`09`09`7D
X
X`09`09if (delete) `7B
X`09`09`09int n, nrep;
X
X`09`09`09sscanf(noteid, "%d.%d", &n, &nrep);
X`09`09`09if (iflag && ((inote != n) `7C`7C (inoterep != nrep))) `7B
X`09`09`09`09fprintf(stderr, "Requested %d.%d != actual %d.%d, not deleted\n"
V, inote, inoterep, n, nrep);
X`09`09`09`09break;
X`09`09`09`7D
X`09`09`09
X`09`09`09stat = note_delete();
X`09`09`09checkstat(stat, "delete note");
X`09`09`7D
X
X`09`09if (modify)`09`09`09/* if crc wanted */
X`09`09`09get_crc();
X
X`09`09if (buildsub)`09`09`09/* if building subjects */
X`09`09`09write_key(title, noteid);
X
X`09`09if (iflag)`20
X`09`09`09break;`09`09`09/* if 1 note */
X`09`7D
X
X`09stat = note_end();
X`09checkstat(stat, "note_end");
X
X`09notefile_end();
X`7D
X
X
X/**`09notefile_begin.
X*/
Xnotefile_begin(notefile)
Xchar *notefile;
X`7B
X`09int stat, i;
X`09static char *dflt = "notes$library:.note";
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOTEFILE_FILE_NAME;
X`09ilst`5Bi`5D.len = strlen(notefile);
X`09ilst`5Bi`5D.buf = notefile;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTEFILE_DEFAULT_NAME;
X`09ilst`5Bi`5D.len = strlen(dflt);
X`09ilst`5Bi`5D.buf = dflt;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTEFILE_MODERATE;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;`09`09/* terminator */
X`09ilst`5Bi`5D.len = 0;
X
X`09i = 0;
X`09olst`5Bi`5D.item = NOTES$K_NOTEFILE_NUMNOTES;
X`09olst`5Bi`5D.len = 4;
X`09olst`5Bi`5D.buf = (char*) &numnotes;
X`09olst`5Bi`5D.rla = 0;
X
X`09olst`5B++i`5D.item = 0;
X
X`09stat = notes$notefile_begin(&nf_context, &ilst, &olst);
X
X`09return stat;
X`7D
X
X
X/**`09notefile_end.
X*/
Xnotefile_end()
X`7B
X`09int stat, i;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09stat = notes$notefile_end(&nf_context, &ilst, &olst);
X
X`09return stat;
X`7D
X`09
X
X/**`09note_begin.
X*/
Xnote_begin()
X`7B
X`09int stat, i;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTEFILE_CONTEXT;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &nf_context;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09stat = notes$note_begin(¬e_context, &ilst, &olst);
X
X`09return stat;
X`7D
X
X
X/**`09note_end.
X*/
Xnote_end()
X`7B
X`09int stat, i;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09stat = notes$note_end(¬e_context, &ilst, &olst);
X
X`09return stat;
X`7D
X
X
X/**`09note_delete - delete note specified by current note id.
X*/
Xnote_delete()
X`7B
X`09int i, stat;
X`09char junk`5B`5D = "xxxxxxxx xxxxxxxx xxxxxxxx";
X
X/*`20
X * First delete the user area. This is because if we delete the
X * first note of a series, it doesn't all go away. If we
X * leave the userarea, the note might accidently match a new`20
X * note being added.
X */
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09ilst`5Bi`5D.len = strlen(noteid);
X`09ilst`5Bi`5D.buf = (char *) ¬eid;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_USER_AREA;
X`09ilst`5Bi`5D.buf = junk;
X`09ilst`5Bi`5D.len = strlen(ilst`5Bi`5D.buf);
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09stat = notes$note_modify(¬e_context, &ilst, &olst);
X`09/* ignore bad stat */
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09ilst`5Bi`5D.len = strlen(noteid);
X`09ilst`5Bi`5D.buf = (char *) ¬eid;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09stat = notes$note_delete(¬e_context, &ilst, &olst);
X
X`09return stat;
X`7D
X
X
X/**`09note_modify - modify note specified by current note id.
X*/
Xnote_modify(string)
Xchar *string;`09`09`09`09/* string to add to user data */
X`7B
X`09int i, stat;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09ilst`5Bi`5D.len = strlen(noteid);
X`09ilst`5Bi`5D.buf = (char *) ¬eid;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_USER_AREA;
X`09ilst`5Bi`5D.buf = string;
X`09ilst`5Bi`5D.len = strlen(ilst`5Bi`5D.buf);
X`09ilst`5Bi`5D.rla = 0;
X`09
X`09ilst`5B++i`5D.item = 0;
X
X`09olst`5B0`5D.item = 0;
X
X`09stat = notes$note_modify(¬e_context, &ilst, &olst);
X
X`09return stat;
X`7D
X
X
X/**`09note_get_next - get next note.
X*/
Xnote_get_next()
X`7B
X`09int i, stat;
X`09static int first = TRUE;
X
X`09i = 0;
X`09ilst`5Bi`5D.item = NOTES$K_NOSIGNAL;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09ilst`5B++i`5D.item = NOTES$K_NOTE_ALL_RESPONSES;
X`09ilst`5Bi`5D.len = 4;
X`09ilst`5Bi`5D.buf = (char*) &one;
X`09ilst`5Bi`5D.rla = 0;
X
X`09if (iflag `7C`7C !first) `7B`09`09`09/* if 1 note or not first */
X`09`09ilst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09`09ilst`5Bi`5D.len = strlen(noteid);
X`09`09ilst`5Bi`5D.buf = (char *) ¬eid;
X`09`09ilst`5Bi`5D.rla = 0;
X`09`7D
X
X`09if (first) `7B
X`09`09first = FALSE;
X`09`7D
X`09else `7B
X`09`09ilst`5B++i`5D.item = NOTES$K_NOTE_NEXT_NOTE;
X`09`09ilst`5Bi`5D.len = 4;
X`09`09ilst`5Bi`5D.buf = (char*) &one;
X`09`09ilst`5Bi`5D.rla = 0;
X`09`7D
X
X`09if (since) `7B
X`09`09ilst`5B++i`5D.item = NOTES$K_NOTE_SINCE_TIME;
X`09`09ilst`5Bi`5D.len = 8;
X`09`09ilst`5Bi`5D.buf = sincetime;
X`09`09ilst`5Bi`5D.rla = 0;
X`09`7D
X
X`09if (before) `7B
X`09`09ilst`5B++i`5D.item = NOTES$K_NOTE_BEFORE_TIME;
X`09`09ilst`5Bi`5D.len = 8;
X`09`09ilst`5Bi`5D.buf = beforetime;
X`09`09ilst`5Bi`5D.rla = 0;
X`09`7D
X
X`09ilst`5B++i`5D.item = 0;
X
X`09i = 0;
X`09olst`5Bi`5D.item = NOTES$K_NOTE_TITLE;
X`09olst`5Bi`5D.len = sizeof(title);
X`09olst`5Bi`5D.buf = title;
X`09olst`5Bi`5D.rla = &titlel;
X
X`09olst`5B++i`5D.item = NOTES$K_NOTE_ID;
X`09olst`5Bi`5D.len = sizeof(noteid);
X`09olst`5Bi`5D.buf = (char *) ¬eid;
X`09olst`5Bi`5D.rla = ¬eidl;
X
X`09olst`5B++i`5D.item = NOTES$K_NOTE_CREATE_TIME;
X`09olst`5Bi`5D.len = 8;
X`09olst`5Bi`5D.buf = (char *) createtime;
X`09olst`5Bi`5D.rla = 0;
X
X`09olst`5B++i`5D.item = NOTES$K_NOTE_USER_AREA;
X`09olst`5Bi`5D.buf = userarea;
X`09olst`5Bi`5D.len = sizeof(userarea) - 1;
X`09olst`5Bi`5D.rla = &userareal;
X`09
X`09olst`5B++i`5D.item = 0;
X
X`09stat = notes$note_get(¬e_context, &ilst, &olst);
X
X`09return stat;
X`7D
X
X
X/**`09checkstat.
X*/
Xcheckstat(stat, string)
Xint stat;
Xchar *string;
X`7B
X`09if ((stat & 1) == 1) return;
X
X`09fprintf(stdout, "%s: 0x%x\n", string, stat);
X`09lib$stop(stat);
X`7D
X
X
X/**`09parsecommand - parse command line.
X*/
Xparsecommand(argc, argv)
Xint argc;
Xchar *argv`5B`5D;
X`7B
X`09int i, stat;
X`09struct dsc$descriptor_s timbuf = `7B0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0`7D
V;
X
X`09for (i = 1; i < argc; i++) `7B
X`09`09if (argv`5Bi`5D`5B0`5D != '-') `7B`09`09/* if not switch */
X`09`09`09notefile = argv`5Bi`5D;
X`09`09`09continue;
X`09`09`7D
X
X`09`09switch (argv`5Bi`5D`5B1`5D) `7B
X
X`09`09case 's':`09`09`09/* since time */
X`09`09`09timbuf.dsc$w_length = strlen(argv`5B++i`5D);
X`09`09`09timbuf.dsc$a_pointer = argv`5Bi`5D;
X`09`09`09strtouc(argv`5Bi`5D);
X`09`09`09stat = sys$bintim(&timbuf, sincetime);
X`09`09`09checkstat(stat, "bintim");
X`09`09`09since++;
X`09`09`09break;
X
X`09`09case 'b':`09`09`09/* before time */
+-+-+-+-+-+-+-+- END OF PART 1 +-+-+-+-+-+-+-+-
Technical Details
Message-ID:
<8145897@MVB.SAIC.COM>Path:
arc1-ca.pugleaf.net!sparky!uunet!elroy.jpl.nasa.gov!usc!news.service.uci.edu!unogate!mvb.saic.com!vmsnet-sourcesShow Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!elroy.jpl.nasa.gov!usc!news.service.uci.edu!unogate!mvb.saic.com!vmsnet-sources From: munroe@dmc.com (Dick Munroe) Newsgroups: vmsnet.sources Subject: MAIL-TO-NOTES, part 01/02 Message-ID: <8145897@MVB.SAIC.COM> Date: Fri, 11 Sep 1992 20:25:34 GMT Organization: Doyle, Munroe Consultants, Inc., Hudson, MA Lines: 1697 Approved: Mark.Berryman@Mvb.Saic.Com