home *** CD-ROM | disk | FTP | other *** search
- Subject: v09i010: ELM Mail System, Part10/19
- Newsgroups: mod.sources
- Approved: rs@mirror.TMC.COM
-
- Submitted by: Dave Taylor <hplabs!taylor>
- Mod.sources: Volume 9, Issue 10
- Archive-name: elm2/Part10
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # If this archive is complete, you will see the message:
- # "End of archive 10 (of 19)."
- # Contents: doc/Form.guide src/alias.c src/date.c test/test.mail
- # utils/from.c
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo shar: Extracting \"doc/Form.guide\" \(9794 characters\)
- if test -f doc/Form.guide ; then
- echo shar: Will not over-write existing file \"doc/Form.guide\"
- else
- sed "s/^X//" >doc/Form.guide <<'END_OF_doc/Form.guide'
- X.PH ""
- X\"
- X\" A guide to using the Elm Forms mode
- X\" format with 'tbl Forms.guide | troff -mm > Forms.format'
- X\" or something similar.
- X\" (C) Copyright 1986 Dave Taylor
- X\"
- X\" Last modification: October 9th, 1986
- X\"
- X.SA 1
- X.nr Hy 1
- X.nr Pt 1
- X.nr Pi 8
- X.lg
- X.HM 1 1
- X.rs
- X.ds HF 3 3
- X.ds HP 12 12 10 10 10
- X.PF ""
- X.de eb
- X.sp -1
- X.nf
- X\h'-.5n'\L'|\\nau-1'\l'\\n(.lu+1n\(ul'\L'-|\\nau+1'\l'|0u-.5n\(ul'
- X.fi
- X..
- X.ce 99
- X.sp 9
- X.ps 20
- X\fBElm Forms Mode Guide\fR
- X.sp 7
- X.ps 12
- X\fIWhat Forms Mode is, how to use it to create
- Xcustom forms, how to reply to forms, and how to
- Xuse it for AT&T Mail messages\fR
- X.sp 5
- XDave Taylor
- X.sp
- XHewlett-Packard Laboratories
- X1501 Page Mill Road
- XPalo Alto CA
- X94304
- X.sp
- Xemail: taylor@hplabs.HP.COM or hplabs!taylor
- X.sp 10
- X.ps 18
- X\fB\(co\fR\s12 Copyright 1986, 1987 by Dave Taylor
- X.ps 10
- X.SK
- X.sp 5
- X.ps 14
- X\fBElm Forms Mode Guide\fR
- X.PH "'Forms Mode Guide''version 1.5'
- X.PF "''Page \\\\nP''"
- X.nr P 1
- X.sp
- X.ps 10
- X(version 1.5)
- X.sp 2
- XDave Taylor
- X.sp
- XHewlett-Packard Laboratories
- X1501 Page Mill Road
- XPalo Alto CA
- X94304
- X.sp
- Xemail: taylor@hplabs.HP.COM or hplabs!taylor
- X.sp 2
- X\*(DT
- X.ce 0
- X.sp 3
- X.P
- XWhile there are a lot of mail systems that allow the transmission
- Xof text and primitive pictures, to send and reply to more complex
- Xforms is simply not possible. \fBElm\fR, however, took
- Xthe forms mode implemented as part of the AT&T Mail package and has
- Xexpanded on it to be a smoothly fit part of the overall mail system.
- X.sp
- XForms mode gives you the ability to send 'template' files to people
- Xand receive the filled-in replies. Let's look at an example right
- Xoff.
- X.sp 2
- XSay we were going to use computer mail as a way to file defects with
- Xsoftware. There is a certain amount of information we want to be able
- Xto collect when each report is made, and if it is in a specific format
- Xwe can use programs to file the defects upon receipt.
- X.sp
- XThe form we'll try to emulate starts out looking like;
- X.DS CB
- X.mk a
- X.mk a
- X.sp
- X.tl ''Defect Reporting Form''
- X.sp
- X.tl 'Program:_________________________'Version:___________________''
- X.tl 'Operating System:________________'Version:___________________''
- X.sp
- X.tl 'Defect Type:_______________________''
- X.sp
- X.tl 'Date Found:_____________________''By Whom:_____________________'
- X.tl 'Date Reported:__________________''Phone:_______________________'
- X.sp
- X.tl 'Description:______________________________________________________________'
- X.tl '__________________________________________________________________________'
- X.tl '__________________________________________________________________________'
- X.tl '__________________________________________________________________________'
- X.tl '__________________________________________________________________________'
- X.sp
- X.eb
- X.DE
- X.sp
- XThis form can actually be created almost exactly as listed above in
- Xthe \fBElm\fR mail system by using your standard editor and can then
- Xbe mailed about as needed.
- X.sp
- XLet's say that we want a bit more information, however, especially with
- Xfields like ``Defect Type'', we want to list all the recommended answers.
- XTo create the actual form, we need merely to replace the underlines in
- Xthe above form with spaces. The multi-line comments can simply be
- Xindicated by a `:' by itself on a line;
- X.DS CB
- X.mk a
- X.sp
- X.tl ''Defect Reporting Form''
- X.sp
- X.tl 'Program: 'Version: ''
- X.tl 'Operating System: 'Version: ''
- X.sp
- X.tl '(Valid Defect Types are: user-error, doc-error, fatal, other)'
- X.tl 'Defect Type: ''
- X.sp
- X.tl 'Date Found: ''By Whom: '
- X.tl 'Date Reported: ''Phone: '
- X.sp
- X.tl 'Description'
- X.tl ':'
- X.sp
- XThank you for filling in this form.
- X.sp 4
- X.eb
- X.DE
- X.sp
- XAs we can see, it is quite simple to create forms!!
- X.sp 2
- XNow that we have an idea what we're talking about, let's actually officially
- Xdefine the system...
- X.sp 2
- X.ne 7
- X.ps 12
- X\fBForms Mode Specification\fR
- X.ps 10
- X.sp
- X[Note that this is all taken from the document \fIStandard for Exchanging
- XForms on AT&T Mail\fR, Version 1.9 of 6/7/86, from AT&T]
- X.sp
- XThe forms mode is really quite simple. Simple enough that it is amazing
- Xthat it hadn't been implemented before AT&T Mail came along!!
- X.sp
- XIn a nutshell, each field is delimited by a `:' followed by a number of
- Xblank spaces or tabs that represent the valid size for that field. That
- Xis, if we have a line in the form like;
- X.nf
- X ``Phone (area-code): Number: ''
- X.fi
- XThe area-code field will be limited to three characters and the number to nine.
- X(this is kind of hard to see with the proportionally spaced formatted copy,
- Xalas).
- XThe only exception to the rule is that a `:' by itself on a line represents
- Xa field that is as large as the user entering the data desires.
- X.sp 2
- XThe actual form that is transmitted, in AT&T Mail parlance, is a ``SIMPLE''
- Xforms handler message (as opposed to the ``ADVANCED'' handler). This means
- Xthat it contains three sections;
- X.nf
- X
- X The Message Header
- X
- X [OPTIONS-SECTION]
- X ***
- X [FORMS-IMAGE]
- X ***
- X [RULES-SECTION]
- X
- X.fi
- X\fBElm\fR generates form messages with the ``options'' section filled out,
- Xbut ignores it when receiving mail. The filled out section is;
- X.nf
- X
- X WIDTH=80
- X TYPE=SIMPLE
- X OUTPUT=TEXT
- X
- X.fi
- XThe FORMS-IMAGE section is that described above. The RULES-SECTION can
- Xcontain explicit rules about the possible values of each field, but
- Xthis is currently ignored by \fBElm\fR, being a ``SIMPLE'' forms mode
- Xmail system.
- X.sp
- XForms also have the header ``Content-Type: mailform'' to indicate to the
- Xmail system (either \fBElm\fR or AT&T Mail) that a form is being sent.
- X.sp
- X\fBElm\fR further indicates that a form has been received by having an
- X``F'' as the status character in the header display section (instead of
- X``N'' for new, etc).
- X.sp 2
- X.ne 5
- X.ps 12
- X\fBComposing and Sending a Form\fR
- X.ps 10
- X.sp
- XThe first step to enable sending forms is to change the setting of
- Xthe variable \fIforms\fR in your \fI.elmrc\fR file to ``ON''. E.g.;
- X.nf
- X
- X forms = ON
- X
- X.fi
- XThe next step is to send the message to someone using the `m' (\fImail\fR)
- Xcommand. This then will drop you into an editor. Type in the form as
- Xindicated above, with appropriate colons and comments, and end the entry
- Xby leaving the editor.
- X.sp
- XThe prompt is now;
- X.nf
- X
- X.tl ''Choose: E)dit msg, edit H)eaders, M)ake form, S)end or F)orget : @''
- X
- X.fi
- Xso we choose `m' - \fIMake form\fR. The program then will either
- Xrewrite the prompt without the M)ake form option, indicating that
- Xthe form has been accepted, or will indicate the problem and give you
- Xa chance to correct it.
- X.sp
- XOnce it has been accepted, simple use the `s' - \fIsend message\fR -
- Xcommand and it's off!
- X.sp
- XNote that you cannot reply to a message with a Form.
- X.sp 2
- X.ne 6
- X.ps 12
- X\fBReplying to a Form\fR
- X.ps 10
- X.sp
- XLet's reply to the form message we generated now. The header page of the
- X\fBElm\fR mail system will indicate that the message is a form by having
- Xan `F' next to it. So we use `r' to reply and the screen is immediately
- Xcleared and we're prompted, field by field, for the data requested.
- XEach field has underscores in the input area to indicate the size field that
- Xis expected.
- X.sp
- XAfter answering all the questions we'll have a screen that looks like;
- X.DS CB
- X.mk a
- X.sp
- X.tl ''Defect Reporting Form''
- X.sp
- XProgram: \fBThe Elm Mail System\fR____________
- XVersion: \fB1.5\fR_____________________
- XOperating System: \fBHP-UX\fR_________________
- XVersion: \fB5.141 C\fR__________________
- X.sp
- X(Valid Defect Types are: user-error, doc-error, fatal, other)
- XDefect Type: \fBfatal\fR____________________________________________________
- X.sp
- XDate Found: \fB10/9/86\fR_____________________
- XBy Whom: \fBDave Taylor\fR_______________
- XDate Reported: \fB10/9/86\fR__________________
- XPhone: \fB(415) 857-6887\fR______________
- X.sp
- XDescription
- X(Enter as many lines as needed, ending with a `.' by itself on a line)
- X
- X \fBWhen running it on a CPM system I cannot compile successfully.\fR
- X \fB.\fR
- X
- XThank you for filling in this form.
- X
- X.tl ''Choose: E)dit form, edit H)eaders, S)end or F)orget : @''
- X.sp
- X.eb
- X.DE
- X.sp
- XQuite simple. Notice, however, that the order of prompting is left to
- Xright on each line, so the fields that on the form are placed in what
- Xseems like a logical place, ``By Whom:'' and ``Phone:'' turn out to be
- Xconfusing when filling in the actual form since it isn't clear what
- X``Phone:'' is being asked for because of the intervention of the
- X``Date Reported:'' field.
- X.sp
- XThe message that will actually be sent out from this will have the
- Xfields in a more acceptable format;
- X.DS
- X.mk a
- X.sp
- XWIDTH=80
- XTYPE=SIMPLE
- XOUTPUT=TEXT
- X***
- X.tl ''Defect Reporting Form''
- X.sp
- X.tl 'Program: The Elm Mail System 'Version: 1.5 ''
- X.tl 'Operating System: HP-UX 'Version: 5.141 C ''
- X.sp
- X.tl '(Valid Defect Types are: user-error, doc-error, fatal, other)'
- X.tl 'Defect Type: fatal''
- X.sp
- X.tl 'Date Found: 10/9/86 ''By Whom: Dave Taylor '
- X.tl 'Date Reported: 10/9/86 ''Phone: (415) 857-6887 '
- X.sp
- X.tl 'Description'
- X.sp
- X When running it on a CPM system I cannot compile successfully.
- X.sp 2
- XThank you for filling in this form.
- X.sp
- X***
- X.sp
- X.eb
- X.DE
- X.ne 5
- X.sp 2
- X.ps 12
- X\fBComments on Forms Mode\fR
- X.ps 10
- X.sp
- XAs was said at the beginning, this way of sending about forms could
- Xprove to be very helpful and useful in a variety of contexts. On the
- Xother hand, until a more sophisticated forms language is used for the
- Xforms, this should be sufficient to embody the power of the idea.
- X.sp
- XI welcome any comments and thoughts on this system and also welcome
- Xpossible enhancements.
- X.sp
- XI also gratefully thank Dale DeJager of AT&T Information Systems
- Xfor sending me more
- Xinformation on AT&T Mail than I could possibly digest in any finite
- Xamount of time.
- END_OF_doc/Form.guide
- if test 9794 -ne `wc -c <doc/Form.guide`; then
- echo shar: \"doc/Form.guide\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"src/alias.c\" \(9636 characters\)
- if test -f src/alias.c ; then
- echo shar: Will not over-write existing file \"src/alias.c\"
- else
- sed "s/^X//" >src/alias.c <<'END_OF_src/alias.c'
- X/** alias.c **/
- X
- X/** This file contains alias stuff
- X
- X (C) Copyright 1986 Dave Taylor
- X**/
- X
- X#include "headers.h"
- X#include <errno.h>
- X
- Xchar *expand_group(), *get_alias_address(), *expand_system(), *get_token();
- Xchar *error_name(), *error_description();
- X
- Xunsigned long sleep();
- X
- Xextern int errno;
- X
- Xextern int findnode_has_been_initialized;
- X
- Xread_alias_files()
- X{
- X /** read the system and user alias files, if present.
- X Set the flags 'systemfiles' and 'userfiles' accordingly.
- X **/
- X
- X char fname[SLEN];
- X int hash;
- X
- X if ((hash = open(system_hash_file, O_RDONLY)) == -1) {
- X dprint1(1,
- X "Warning: Can't read system hash file %s (read_alias_files)\n",
- X system_hash_file);
- X goto user;
- X }
- X
- X read(hash, system_hash_table, sizeof system_hash_table);
- X close(hash);
- X
- X /* and data file opened.. */
- X
- X if ((system_data = open(system_data_file, O_RDONLY)) == -1) {
- X dprint1(1,
- X "Warning: Can't read system data file %s (read_alias_files)\n",
- X system_data_file);
- X goto user;
- X }
- X
- X system_files++; /* got the system files! */
- X
- Xuser: sprintf(fname, "%s/.alias_hash", home);
- X
- X if ((hash = open(fname, O_RDONLY)) == -1) {
- X dprint1(1,"Warning: Can't read user hash file %s (read_alias_files)\n",
- X fname);
- X return;
- X }
- X
- X read(hash, user_hash_table, sizeof user_hash_table);
- X close(hash);
- X
- X sprintf(fname, "%s/.alias_data", home);
- X
- X if ((user_data = open(fname, O_RDONLY)) == -1) {
- X dprint1(1,
- X "Warning: can't read user data file %s (read_alias_files)\n",
- X fname);
- X return;
- X }
- X
- X user_files++; /* got user files too! */
- X}
- X
- Xint
- Xadd_alias()
- X{
- X /** add an alias to the user alias text file. Return zero
- X if alias not added in actuality **/
- X
- X char name[SLEN], *address, address1[LONG_STRING];
- X char comment[SLEN];
- X char *strcpy();
- X
- X PutLine0(LINES-2,0,"Enter alias name: ");
- X CleartoEOLN();
- X Raw(OFF);
- X gets(name);
- X Raw(ON);
- X if (strlen(name) == 0)
- X return(0);
- X if ((address = get_alias_address(name, 0, 0)) != NULL) {
- X dprint1(2, "Attempt to add a duplicate alias [%s] (add_alias)\n",
- X address);
- X if (address[0] == '!') {
- X address[0] = ' ';
- X error1("already a group with that name:%s", address);
- X }
- X else
- X error1("already an alias for that: %s", address);
- X return(0);
- X }
- X PutLine1(LINES-2,0,"Full name for %s: ", name);
- X CleartoEOLN();
- X Raw(OFF);
- X gets(comment);
- X Raw(ON);
- X if (strlen(comment) == 0) strcpy(comment, name);
- X PutLine1(LINES-2,0,"Enter address for %s: ",name);
- X CleartoEOLN();
- X Raw(OFF);
- X gets(address1);
- X Raw(ON);
- X if (strlen(address1) == 0) {
- X error("No address specified!");
- X return(0);
- X }
- X add_to_alias_text(name, comment, address1);
- X return(1);
- X}
- X
- Xint
- Xadd_current_alias()
- X{
- X /** alias the current message to the specified name and
- X add it to the alias text file, for processing as
- X the user leaves the program. Returns non-zero iff
- X alias actually added to file **/
- X
- X char name[SLEN], address1[LONG_STRING], buffer[LONG_STRING], *address;
- X char comment[SLEN];
- X
- X if (current == 0) {
- X dprint0(3,"Add current alias called without any current message!\n");
- X error("No message to alias to!");
- X return(0);
- X }
- X
- X PutLine0(LINES-2,0,"Current message address aliased to: ");
- X CleartoEOLN();
- X Raw(OFF);
- X gets(name);
- X Raw(ON);
- X if (strlen(name) == 0) /* cancelled... */
- X return(0);
- X if ((address = get_alias_address(name, 0, 0)) != NULL) {
- X dprint1(3,
- X "Attempt to add a duplicate alias [%s] (add_current_alias)\n",
- X address);
- X if (address[1] == '!') {
- X address[0] = ' ';
- X error1("already a group with that name:%s", address);
- X }
- X else
- X error1("already an alias for that: %s", address);
- X return(0);
- X }
- X PutLine1(LINES-2,0,"Full name of %s: ", name);
- X CleartoEOLN();
- X Raw(OFF);
- X gets(comment);
- X Raw(ON);
- X get_return(buffer); /* grab the return address of this message */
- X strcpy(address1, strip_parens(buffer)); /* remove parens! */
- X#ifndef DONT_OPTIMIZE_RETURN
- X optimize_return(address1);
- X#endif
- X PutLine3(LINES-2,0,"%s (%s) = %s", comment, name, address1);
- X CleartoEOLN();
- X add_to_alias_text(name, comment, address1);
- X return(1);
- X}
- X
- Xadd_to_alias_text(name, comment, address)
- Xchar *name, *comment, *address;
- X{
- X /** Add the data to the user alias text file. Return zero if we
- X succeeded, 1 if not **/
- X
- X FILE *file;
- X char fname[SLEN];
- X
- X sprintf(fname,"%s/.alias_text", home);
- X
- X if ((file = fopen(fname, "a")) == NULL) {
- X dprint2(2, "FILE Failure attempting to add alias to file %s (%s)",
- X fname, "add_to_alias_text");
- X dprint2(2, "** %s - %s **\n", error_name(errno),
- X error_description(errno));
- X error1("couldn't open %s to add new alias!", fname);
- X return(1);
- X }
- X
- X fprintf(file,"%s : %s : %s\n", name, comment, address);
- X fclose(file);
- X
- X chown(fname, userid, groupid);
- X
- X return(0);
- X}
- X
- Xshow_alias_menu()
- X{
- X MoveCursor(LINES-7,0); CleartoEOLN();
- X MoveCursor(LINES-6,0); CleartoEOLN();
- X MoveCursor(LINES-5,0); CleartoEOLN();
- X
- X PutLine0(LINES-7,COLUMNS-45, "Alias commands");
- X Centerline(LINES-5,
- X"A)lias current msg, Check a P)erson or S)ystem, M)ake new alias, or R)eturn"
- X );
- X}
- X
- Xalias()
- X{
- X /** work with alias commands... **/
- X char name[NLEN], *address, ch, buffer[SLEN];
- X int newaliases = 0;
- X
- X if (mini_menu)
- X show_alias_menu();
- X
- X /** now let's ensure that we've initialized everything! **/
- X
- X#ifndef DONT_TOUCH_ADDRESSES
- X
- X if (! findnode_has_been_initialized) {
- X if (! mail_only)
- X error("initializing internal tables...");
- X#ifndef USE_DBM
- X get_connections();
- X open_domain_file();
- X#endif
- X init_findnode();
- X clear_error();
- X findnode_has_been_initialized = TRUE;
- X }
- X
- X#endif
- X
- X define_softkeys(ALIAS);
- X
- X while (1) {
- X prompt("Alias: ");
- X CleartoEOLN();
- X ch = ReadCh();
- X MoveCursor(LINES-1,0); CleartoEOS();
- X
- X dprint1(2,"\n-- Alias command: %c\n\n", ch);
- X
- X switch (tolower(ch)) {
- X case '?': alias_help(); break;
- X
- X case 'a': newaliases += add_current_alias(); break;
- X case 'm': newaliases += add_alias(); break;
- X
- X case RETURN:
- X case LINE_FEED:
- X case 'q':
- X case 'x':
- X case 'r': if (newaliases) install_aliases();
- X return;
- X case 'p': if (newaliases)
- X error("Warning: new aliases not installed yet!");
- X PutLine0(LINES-2,0,"Check for person: ");
- X CleartoEOLN();
- X Raw(OFF);
- X gets(name);
- X Raw(ON);
- X if ((address = get_alias_address(name, 0, 0))!=NULL) {
- X if (address[0] == '!') {
- X address[0] = ' ';
- X PutLine1(LINES-1,0,"Group alias:%-60.60s", address);
- X CleartoEOLN();
- X }
- X else
- X PutLine1(LINES-1,0,"Aliased address: %-60.60s",
- X address);
- X }
- X else
- X error("not found");
- X break;
- X
- X case 's': PutLine0(LINES-2,0,"Check for system: ");
- X CleartoEOS();
- X Raw(OFF);
- X gets(name);
- X Raw(ON);
- X if (talk_to(name))
- X#ifdef INTERNET_ADDRESS_FORMAT
- X PutLine1(LINES-1,0,
- X "You have a direct connection - the address is (user)@%s",
- X name);
- X#else
- X PutLine1(LINES-1,0,
- X "You have a direct connection - the address is %s!(user)",
- X name);
- X#endif
- X else {
- X sprintf(buffer, "(user)@%s", name);
- X#ifdef DONT_TOUCH_ADDRESS
- X strcpy(address, buffer);
- X#else
- X address = expand_system(buffer, FALSE);
- X#endif
- X if (strlen(address) > strlen(name) + 7)
- X PutLine1(LINES-1,0,"Address is: %.65s", address);
- X else
- X error1("couldn't expand system '%s'", name);
- X }
- X break;
- X
- X case '@': PutLine0(LINES-2,0,"Fully expand alias: ");
- X CleartoEOS();
- X Raw(OFF);
- X gets(name);
- X Raw(ON);
- X if ((address = get_alias_address(name, 1, 0)) != NULL) {
- X ClearScreen();
- X PutLine1(3,0,"Aliased address:\n\r%s", address);
- X PutLine0(LINES-1,0,"Press <return> to continue: ");
- X (void) getchar();
- X }
- X else
- X error("not found");
- X if (mini_menu) show_alias_menu();
- X break;
- X default : error("Invalid input!");
- X }
- X }
- X}
- X
- Xinstall_aliases()
- X{
- X /** run the 'newalias' program and install the newly
- X added aliases before going back to the main
- X program!
- X **/
- X
- X
- X error("Adding new aliases...");
- X sleep(2);
- X
- X if (system_call(newalias, SH) == 0) {
- X error("Re-reading the database in...");
- X sleep(2);
- X read_alias_files();
- X set_error("New aliases installed successfully");
- X }
- X else
- X set_error("'newalias' failed. Please check alias_text");
- X}
- X
- Xalias_help()
- X{
- X /** help section for the alias menu... **/
- X
- X char ch;
- X
- X MoveCursor(LINES-3, 0); CleartoEOS();
- X
- X if (! mini_menu)
- X lower_prompt("Key you want help for : ");
- X else {
- X Centerline(LINES-3,
- X"Enter key you want help for, '?' for list or '.' to leave help");
- X lower_prompt("Key : ");
- X }
- X
- X while ((ch = tolower(ReadCh())) != '.') {
- X switch(ch) {
- X case '?' : display_helpfile(ALIAS_HELP);
- X if (mini_menu) show_alias_menu(); return;
- X case 'a': error(
- X"a = Add return address of current message to alias database"); break;
- X case 'm': error(
- X"m = Make new user alias, adding to alias database when done"); break;
- X
- X case RETURN:
- X case LINE_FEED:
- X case 'q':
- X case 'x':
- X case 'r': error("return from alias menu"); break;
- X
- X case 'p': error(
- X"p = check for a person in the alias database"); break;
- X
- X case 's': error(
- X"s = check for a system in the host routing/domain database"); break;
- X
- X default : error("That key isn't used in this section"); break;
- X case '.': return;
- X }
- X if (! mini_menu)
- X lower_prompt("Key you want help for : ");
- X else
- X lower_prompt("Key : ");
- X }
- X}
- END_OF_src/alias.c
- if test 9636 -ne `wc -c <src/alias.c`; then
- echo shar: \"src/alias.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"src/date.c\" \(10281 characters\)
- if test -f src/date.c ; then
- echo shar: Will not over-write existing file \"src/date.c\"
- else
- sed "s/^X//" >src/date.c <<'END_OF_src/date.c'
- X/** date.c **/
- X
- X/** return the current date and time in a readable format! **/
- X/** also returns an ARPA RFC-822 format date... **/
- X
- X/** (C) Copyright 1985, Dave Taylor **/
- X
- X#include "headers.h"
- X
- X#ifdef BSD
- X# ifndef BSD4.1
- X# include <sys/time.h>
- X# else
- X# include <time.h>
- X# include <sys/types.h>
- X# include <sys/timeb.h>
- X# endif
- X#else
- X# include <time.h>
- X#endif
- X
- X#include <ctype.h>
- X
- X#ifdef BSD
- X#undef toupper
- X#undef tolower
- X#endif
- X
- X#define MONTHS_IN_YEAR 11 /* 0-11 equals 12 months! */
- X#define FEB 1 /* 0 = January */
- X#define DAYS_IN_LEAP_FEB 29 /* leap year only */
- X
- X#define ampm(n) (n > 12? n - 12 : n)
- X#define am_or_pm(n) (n > 11? (n > 23? "am" : "pm") : "am")
- X#define leapyear(year) ((year % 4 == 0) && (year % 100 != 0))
- X
- Xchar *monname[] = { "January", "February", "March", "April", "May", "June",
- X "July", "August", "September", "October", "November",
- X "December", ""};
- X
- Xchar *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
- X "Fri", "Sat", "" };
- X
- Xchar *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
- X
- Xint days_in_month[] = { 31, 28, 31, 30, 31, 30,
- X 31, 31, 30, 31, 30, 31, -1};
- X
- X#ifdef BSD
- X char *timezone();
- X#else
- X extern char *tzname[];
- X#endif
- X
- Xchar *shift_lower(), *strcpy(), *strncpy();
- X
- Xchar *get_arpa_date()
- X{
- X /** returns an ARPA standard date. The format for the date
- X according to DARPA document RFC-822 is exemplified by;
- X
- X Mon, 12 Aug 85 6:29:08 MST
- X
- X **/
- X
- X static char buffer[SLEN]; /* static character buffer */
- X struct tm *the_time, /* Time structure, see CTIME(3C) */
- X *localtime();
- X long junk, /* time in seconds.... */
- X time();
- X
- X#ifdef BSD
- X# ifdef BSD4.1
- X struct timeb loc_time;
- X
- X junk = time(long *) 0);
- X ftime(&loc_time);
- X# else
- X struct timeval time_val;
- X struct timezone time_zone;
- X
- X gettimeofday(&time_val, &time_zone);
- X junk = time_val.tv_sec;
- X# endif
- X
- X#else
- X junk = time((long *) 0); /* this must be here for it to work! */
- X#endif
- X
- X the_time = localtime(&junk);
- X
- X sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s",
- X arpa_dayname[the_time->tm_wday],
- X the_time->tm_mday % 32,
- X arpa_monname[the_time->tm_mon],
- X the_time->tm_year % 100,
- X the_time->tm_hour % 24,
- X the_time->tm_min % 61,
- X the_time->tm_sec % 61,
- X#ifdef BSD
- X# ifdef BSD4.1
- X timezone(time_zone.timezone, the_time->tm_isdst));
- X# else
- X timezone(time_zone.tz_minuteswest, the_time->tm_isdst));
- X# endif
- X#else
- X tzname[the_time->tm_isdst]);
- X#endif
- X
- X return( (char *) buffer);
- X}
- X
- Xchar *full_month(month)
- Xchar *month;
- X{
- X /** Given a three letter month abbreviation, return the
- X full name of the month. If can't figure it out, just
- X return the given argument. **/
- X
- X char name[4];
- X char *shift_lower();
- X register int i;
- X
- X /** ensure name in correct case... **/
- X
- X strncpy(name, shift_lower(month), 3);
- X name[0] = toupper(name[0]);
- X
- X /** now simply step through arpa_monname table to find a match **/
- X
- X for (i=0; i < 12; i++)
- X if (strncmp(name, arpa_monname[i], 3) == 0)
- X return((char *) monname[i]);
- X
- X dprint1(2, "Warning: Couldn't expand monthname %s (full_month)\n",
- X month);
- X
- X return( (char *) month);
- X}
- X
- Xdays_ahead(days, buffer)
- Xint days;
- Xchar *buffer;
- X{
- X /** return in buffer the date (Day, Mon Day, Year) of the date
- X 'days' days after today. **/
- X
- X struct tm *the_time, /* Time structure, see CTIME(3C) */
- X *localtime();
- X long junk, /* time in seconds.... */
- X time();
- X
- X junk = time((long *) 0); /* this must be here for it to work! */
- X the_time = localtime(&junk);
- X
- X /* increment the day of the week */
- X
- X the_time->tm_wday = (the_time->tm_wday + days) % 7;
- X
- X /* the day of the month... */
- X the_time->tm_mday += days;
- X
- X if (the_time->tm_mday > days_in_month[the_time->tm_mon]) {
- X if (the_time->tm_mon == FEB && leapyear(the_time->tm_year)) {
- X if (the_time->tm_mday > DAYS_IN_LEAP_FEB) {
- X the_time->tm_mday -= days_in_month[the_time->tm_mon];
- X the_time->tm_mon += 1;
- X }
- X }
- X else {
- X the_time->tm_mday -= days_in_month[the_time->tm_mon];
- X the_time->tm_mon += 1;
- X }
- X }
- X
- X /* check the month of the year */
- X if (the_time->tm_mon > MONTHS_IN_YEAR) {
- X the_time->tm_mon -= MONTHS_IN_YEAR;
- X the_time->tm_year += 1;
- X }
- X
- X /* now, finally, build the actual date string */
- X
- X sprintf(buffer, "%s, %d %s %d",
- X arpa_dayname[the_time->tm_wday],
- X the_time->tm_mday % 32,
- X arpa_monname[the_time->tm_mon],
- X the_time->tm_year % 100);
- X}
- X
- Xint
- Xvalid_date(day, mon, year)
- Xchar *day, *mon, *year;
- X{
- X /** Validate the given date - returns TRUE iff the date
- X handed is reasonable and valid.
- X Ignore month param, okay?
- X **/
- X
- X register int daynum, yearnum;
- X
- X daynum = atoi(day);
- X yearnum = atoi(year);
- X
- X if (daynum < 1 || daynum > 31) {
- X dprint1(3, "Error: day %d is obviously wrong! (valid_date)\n",
- X daynum);
- X return(0);
- X }
- X
- X if (yearnum < 1 || (yearnum > 100 && yearnum < 1900) ||
- X yearnum > 2000) {
- X dprint1(3, "Error: year %d is obviously wrong! (valid_date)\n",
- X yearnum);
- X return(0);
- X }
- X
- X return(1);
- X}
- X
- Xfix_date(entry)
- Xstruct header_rec *entry;
- X{
- X /** This routine will 'fix' the date entry for the specified
- X message. This consists of 1) adjusting the year to 0-99
- X and 2) altering time from HH:MM:SS to HH:MM am|pm **/
- X
- X if (atoi(entry->year) > 99)
- X sprintf(entry->year,"%d", atoi(entry->year) - 1900);
- X
- X fix_time(entry->time);
- X}
- X
- Xfix_time(timestring)
- Xchar *timestring;
- X{
- X /** Timestring in format HH:MM:SS (24 hour time). This routine
- X will fix it to display as: HH:MM [am|pm] **/
- X
- X int hour, minute;
- X
- X sscanf(timestring, "%d:%d", &hour, &minute);
- X
- X if (hour < 1 || hour == 24)
- X sprintf(timestring, "12:%2.2d (midnight)", minute);
- X else if (hour < 12)
- X sprintf(timestring, "%d:%2.2d am", hour, minute);
- X else if (hour == 12)
- X sprintf(timestring, "%d:%2.2d (noon)", hour, minute);
- X else if (hour < 24)
- X sprintf(timestring, "%d:%2.2d pm", hour-12, minute);
- X}
- X
- Xint
- Xcompare_dates(rec1, rec2)
- Xstruct header_rec *rec1, *rec2;
- X{
- X /** This function works similarly to the "strcmp" function, but
- X has lots of knowledge about the internal date format...
- X Apologies to those who "know a better way"...
- X **/
- X
- X int month1, day1, year1, hour1, minute1,
- X month2, day2, year2, hour2, minute2;
- X
- X year1 = atoi(rec1->year);
- X year2 = atoi(rec2->year);
- X
- X if (year1 != year2)
- X return( year1 - year2 );
- X
- X /* And HERE's where the performance of this sort dies... */
- X
- X month1 = month_number(rec1->month); /* retch... gag.... */
- X month2 = month_number(rec2->month); /* puke... */
- X
- X if (month1 == -1)
- X dprint1(2,"month_number failed on month '%s'\n", rec1->month);
- X
- X if (month2 == -1)
- X dprint1(2,"month_number failed on month '%s'\n", rec2->month);
- X
- X if (month1 != month2)
- X return( month1 - month2 );
- X
- X /* back and cruisin' now, though... */
- X
- X day1 = atoi(rec1->day); /* unfortunately, 2 is greater than 19 */
- X day2 = atoi(rec2->day); /* on a dump string-only compare... */
- X
- X if (day1 != day2)
- X return( day1 - day2 );
- X
- X /* we're really slowing down now... */
- X
- X minute1 = minute2 = -1;
- X
- X sscanf(rec1->time, "%d:%d", &hour1, &minute1);
- X sscanf(rec2->time, "%d:%d", &hour2, &minute2);
- X
- X /* did we get the time? If not, try again */
- X
- X if (minute1 < 0)
- X sscanf(rec1->time, "%2d%2d", &hour1, &minute1);
- X
- X if (minute2 < 0)
- X sscanf(rec2->time, "%2d%2d", &hour2, &minute2);
- X
- X /** deal with am/pm, if present... **/
- X
- X if (strlen(rec1->time) > 3)
- X if (rec1->time[strlen(rec1->time)-2] == 'p')
- X hour1 += 12;
- X
- X if (strlen(rec2->time) > 3)
- X if (rec2->time[strlen(rec2->time)-2] == 'p')
- X hour2 += 12;
- X
- X if (hour1 != hour2)
- X return( hour1 - hour2 );
- X
- X return( minute1 - minute2 ); /* ignore seconds... */
- X}
- X
- Xint
- Xcompare_parsed_dates(rec1, rec2)
- Xstruct date_rec rec1, rec2;
- X{
- X /** This function is very similar to the compare_dates
- X function but assumes that the two record structures
- X are already parsed and stored in "date_rec" format.
- X **/
- X
- X if (rec1.year != rec2.year)
- X return( rec1.year - rec2.year );
- X
- X if (rec1.month != rec2.month)
- X return( rec1.month - rec2.month );
- X
- X if (rec1.day != rec2.day)
- X return( rec1.day - rec2.day );
- X
- X if (rec1.hour != rec2.hour)
- X return( rec1.hour - rec2.hour );
- X
- X return( rec1.minute - rec2.minute ); /* ignore seconds... */
- X}
- X
- Xint
- Xmonth_number(name)
- Xchar *name;
- X{
- X /** return the month number given the month name... **/
- X
- X char ch;
- X
- X switch (tolower(name[0])) {
- X case 'a' : if ((ch = tolower(name[1])) == 'p') return(APRIL);
- X else if (ch == 'u') return(AUGUST);
- X else return(-1); /* error! */
- X
- X case 'd' : return(DECEMBER);
- X case 'f' : return(FEBRUARY);
- X case 'j' : if ((ch = tolower(name[1])) == 'a') return(JANUARY);
- X else if (ch == 'u') {
- X if ((ch = tolower(name[2])) == 'n') return(JUNE);
- X else if (ch == 'l') return(JULY);
- X else return(-1); /* error! */
- X }
- X else return(-1); /* error */
- X case 'm' : if ((ch = tolower(name[2])) == 'r') return(MARCH);
- X else if (ch == 'y') return(MAY);
- X else return(-1); /* error! */
- X case 'n' : return(NOVEMBER);
- X case 'o' : return(OCTOBER);
- X case 's' : return(SEPTEMBER);
- X default : return(-1);
- X }
- X}
- X
- X#ifdef SITE_HIDING
- X
- Xchar *get_ctime_date()
- X{
- X /** returns a ctime() format date, but a few minutes in the
- X past...(more cunningness to implement hidden sites) **/
- X
- X static char buffer[SLEN]; /* static character buffer */
- X struct tm *the_time, /* Time structure, see CTIME(3C) */
- X *localtime();
- X long junk, /* time in seconds.... */
- X time();
- X#ifdef BSD
- X struct timeval time_val;
- X struct timezone time_zone;
- X#endif
- X
- X#ifdef BSD
- X gettimeofday(&time_val, &time_zone);
- X junk = time_val.tv_sec;
- X#else
- X junk = time((long *) 0); /* this must be here for it to work! */
- X#endif
- X the_time = localtime(&junk);
- X
- X sprintf(buffer, "%s %s %d %02d:%02d:%02d %d",
- X arpa_dayname[the_time->tm_wday],
- X arpa_monname[the_time->tm_mon],
- X the_time->tm_mday % 32,
- X min(the_time->tm_hour % 24, (rand() % 24)),
- X min(abs(the_time->tm_min % 61 - (rand() % 60)), (rand() % 60)),
- X min(abs(the_time->tm_sec % 61 - (rand() % 60)), (rand() % 60)),
- X the_time->tm_year % 100 + 1900);
- X
- X return( (char *) buffer);
- X}
- X
- X#endif
- END_OF_src/date.c
- if test 10281 -ne `wc -c <src/date.c`; then
- echo shar: \"src/date.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"test/test.mail\" \(10003 characters\)
- if test -f test/test.mail ; then
- echo shar: Will not over-write existing file \"test/test.mail\"
- else
- sed "s/^X//" >test/test.mail <<'END_OF_test/test.mail'
- XFrom root Wed Oct 30 14:03:36 1985
- X>From srmmail Wed Oct 30 14:10:08 1985 remote from veeger
- X>From hplabs Wed Oct 30 14:00:16 1985 remote from hpcnof
- X>From hpl-opus!poulton Wed Oct 30 02:06:16 1985 remote from hplabs
- XDate: Wed, 30 Oct 85 01:55:05 pst
- XFrom: <hplabs!hpl-opus!poulton>
- XReceived: by HP-VENUS id AA26352; Wed, 30 Oct 85 01:55:05 pst
- XMessage-Id: <8510300955.AA26352@HP-VENUS>
- XTo: hplabs!hpldat!taylor
- XSubject: Re: announce(1)
- X
- XThe announce I got was shar'd July 8. NLEN was not defined in that
- Xsource, just used. LONG_SLEN is not defined in the newmail(1)
- Xthat you sent me. What system are you running on?
- XMy s500 doesn't have these def's.
- X
- X -> Monday, January 3rd: Call your mother
- X
- XAs to announce --> newmail: why the switch?
- XSeems like both are useful, in different situations.
- X
- XKen Poulton
- XHPL
- X
- X
- X
- X
- XFrom root Wed Oct 30 14:03:39 1985
- X>From srmmail Wed Oct 30 14:10:12 1985 remote from veeger
- X>From hplabs Wed Oct 30 13:59:53 1985 remote from hpcnof
- X>From fowler Wed Oct 30 12:57:11 1985 remote from hplabs
- XDate: Wed, 30 Oct 85 12:57:11 pst
- XFrom: Greg Fowler <hplabs!fowler>
- XReceived: by HP-VENUS id AA12562; Wed, 30 Oct 85 12:57:11 pst
- XMessage-Id: <8510302057.AA12562@HP-VENUS>
- XTo: mail-men@rochester
- XSubject: Re: Summary of Network Mail Headers
- XReferences: <36700044@hpcnof.UUCP>
- XPriority: Most Urgent
- X
- XI believe your introduction referred to the uucp network. usenet is the networXk news
- Xsoftware mechanism and isn't a "network".
- X
- X - > February 19, 1986
- X -
- X - A longer test of the system
- X -
- X
- X Greg
- X
- X
- X
- XFrom root Wed Oct 30 14:13:23 1985
- X>From srmmail Wed Oct 30 14:20:08 1985 remote from veeger
- X>From root Wed Oct 30 14:01:57 1985 remote from hpcnof
- XTo: DCC@hplabs
- XSubject: Log of backup tape #1
- X
- X
- XFull Backup starting at Wed Oct 30 12:45:14 MST 1985
- X
- X
- X
- Xbacking up directories:
- X ./users/fh ./users/rmd ./users/vince ./users/roberts ./users/row ./users/dt ./Xlost+found ./users/lost+found ./users/scb ./users/kevin ./users/du
- X
- X
- X
- X
- X
- XFrom root Wed Oct 30 15:33:24 1985
- X>From srmmail Wed Oct 30 15:40:26 1985 remote from veeger
- X>From root Wed Oct 30 15:37:17 1985 remote from hpcnof
- XTo: root, uucp, taylor@hplabs.ARPA
- XSubject: Log of backup tape #2
- X
- Xbacking up directories:
- X ./users/fh ./users/rmd ./users/vince ./users/roberts ./users/row ./users/dt ./Xlost+found ./users/lost+found ./users/scb ./users/kevin ./users/du
- X
- X
- X
- X
- Xbacking up directories:
- X ./users/sbh ./users/ges ./users/cpb ./users/amy ./net ./users/root ./users/balXza ./dev ./users/remple ./users/jr ./users/mwr ./users/larryf
- X
- X
- X
- X
- X
- XFrom root Sun Dec 8 22:50:18 1985
- X>From srmmail Mon Dec 9 00:50:05 1985 remote from veeger
- X>From root Mon Dec 9 00:41:15 1985 remote from hpcnof
- X>From JLarson.pa@Xerox.ARPA Sun Dec 8 20:45:55 1985 remote from hplabs
- XDate: 8 Dec 85 20:36:36 PST (Sunday)
- XFrom: hplabs!JLarson.pa@Xerox.ARPA
- XSubject: How's it going, anyway?
- XTo: hpcnou!dat@HPLABS.ARPA (Dave Taylor)
- XCc: JLarson.pa@Xerox.ARPA
- X
- XHow are things with you? Could you send me that paper we were talking
- Xabout?
- X
- X Thanks
- X
- XJohn Larson
- XXerox Palo Alto Research Center
- X3333 Coyote Hill Road
- XPalo Alto, Ca 94304
- X
- X
- X
- X
- XFrom root Wed Aug 7 19:58:30 1985
- X>From uucp Wed Aug 7 19:55:12 1985 remote from veeger
- X>From hplabs Wed Aug 7 19:48:10 1985 remote from hpcnof
- X>From RICHER@SUMEX-AIM Wed Aug 7 09:23:12 1985 remote from hplabs
- XReceived: by HP-VENUS id AA18269; Wed, 7 Aug 85 09:11:48 pdt
- XDate: Tue 6 Aug 85 09:12:37-PDT
- XFrom: Mark Richer <hplabs!RICHER@SUMEX-AIM>
- XReceived: by HP-VENUS via CSNET; 7 Aug 1985 09:11:37-PDT (Wed)
- XReceived: from sumex-aim.arpa by csnet-relay.arpa id a015812; 6 Aug 85 12:14 EDXT
- XTo: hpcnof!veeger!hpcnou!dat%hplabs.csnet@CSNET-RELAY
- XVia: CSNet; 7 Aug 85 9:11-PDT
- XSubject: Re: AI in Education mailing list...
- XCc: RICHER@SUMEX-AIM
- XIn-Reply-To: <8508030243.AA27641@HP-VENUS>
- XMessage-Id: <12132987812.61.RICHER@SUMEX-AIM.ARPA>
- X
- XI added you to aied. This message may be of interest to you:
- X
- XArtificial Intelligence in Education Meeting at IJCAI 85
- X---------- ------------ -- --------- ------- -- ----- --
- X
- XPlace: Math Sciences Auditorium (a.k.a. Math 4000A), UCLA campus
- XTime: 6:30 pm, Tuesday, Aug. 20, 1985 (length: 1 - 1 1/4 hr)
- X
- XAgenda:
- X I have two speakers scheduled to make presentations that
- Xshould stimulate questions and discussions:
- X
- X (1) Short Announcements
- X
- X (2) Jeff Bonar, Research Scientist, Learning Research and
- X Development Center (LRDC), University of Pittsburgh
- X
- X --- on-going ICAI research projects at LRDC
- X --- dissemination of ICAI technology in the form of software
- X tools, workshops, written materials, and video tapes.
- X
- X (3) Gary Fine, Product Engineering Manager, INTELLICORP,
- X formerly with a company producing CAI products, also graduate
- X work in ICAI
- X
- X --- bridging the gap between current ICAI technology and the
- X real world
- X
- X[IJCAI-85, the 9th International Joint Conference on Artificial
- XIntelligence is being held at UCLA Campus, August 18-23, 1985. This
- Xconference is co-sponsered by the American Association for Artificial
- XIntelligence (AAAI) this year, and I have been told by their office
- Xthat only walk-in registration is available at this time. For more
- Xinformation, contact AAAI: AAAI-OFFICE@SUMEX-AIM.ARPA
- X AAAI, 445 Burgess Drive, Menlo Park, CA 94025
- X or call (415) 328-3123]
- X
- XDirect questions on the AI in ED meeting (only) to Mark Richer,
- XRICHER@SUMEX-AIM.ARPA
- X-------
- X
- X
- X
- X
- XFrom root Tue Sep 24 09:53:24 1985
- X>From HPMAIL-gateway Tue Sep 24 9:46:47 1985 remote from veeger
- X>From Simon_CINTZ_/_HPD600/TR Tue Sep 24 9:46:47 1985 remote from hpmail
- XDate: Tue, 24 Sep 85 9:14:00 MDT
- XFrom: Simon_CINTZ_/_HPD600/TR (Simon Cintz)
- XSubject: ITF
- XFrom: Simon_CINTZ_/_HPD600/TR (Simon Cintz)
- XTo: Dave_TAYLOR_/_HPF100/00
- X
- XDave -
- X
- XJust as one programming language doesn't suit the needs of
- Xall programmers, one authoring facility will probably not
- Xsuit the needs of all HP entities that require CBT -- at least
- Xnot in the near future. Of course, this is my personal opinion
- Xand if I'm wrong, it won't be the first time.
- X
- XGood luck.
- X
- X
- X - Simon
- X
- XFrom root Mon Oct 21 10:43:37 1985
- X>From srmmail Mon Oct 21 10:30:16 1985 remote from veeger
- X>From root Mon Oct 21 10:28:58 1985 remote from hpcnof
- X>From DLS.MDC%office-X.arpa@CSNET-RELAY Mon Oct 21 01:57:05 1985 remote from hXplabs
- XReceived: by HP-VENUS id AA17376; Mon, 21 Oct 85 01:57:05 pdt
- XDate: 21 Oct 85 01:02 EDT
- XFrom: Duane Stone / McDonnell Douglas / CSC-ASD <hplabs!DLS.MDC%office-1.arpa@CXSNET-RELAY>
- XReceived: by HP-VENUS via CSNET; 21 Oct 1985 01:57:01-PDT (Mon)
- XReceived: from office-1.arpa by CSNET-RELAY.ARPA id a019220; 21 Oct 85 1:18 EDTX
- XTo: Dave Taylor <hpcnou!dat%hplabs.csnet@CSNET-RELAY>
- XVia: CSNet; 21 Oct 85 1:56-PDT
- XSubject: Re: More Mail Headers...
- XMessage-Id: <MDC-DLS-7W9CS@OFFICE-1>
- XComment: Dave -- this is the body of the message I previously 'sent' to you viaX
- X
- Xa Journal.
- X
- XI might suggest re-wording the para on Author -- my associates might object to X
- X'strange' -- something like:
- X
- X This is used to credit the original author, or to give credit on article
- X excerpts (from Newspapers, magazines, books, etc).
- X
- XOne field which I forgot is:
- X
- X Length: This is computed when the message is sent and gives the recipients X
- X an estimate of the number of pages in the document.
- X
- X Example:
- X
- X Length: 6 pages [estimate]
- X
- XAccess:
- X
- X Used to declare whether a Journal item should be Public or Private (to thoseX
- X that are on the distribution list or Extended Access list)
- X
- X Example:
- X
- X Access: Unrestricted
- X
- XAcknowledge-Delivery:
- X
- X Used to request the system mailer send back a message when it has
- X successfully delivered the item.
- X
- X Example:
- X
- X Acknowledge-Delivery: Requested
- X
- XAcknowledge-Receipt:
- X
- X Used to to ask the recipient to acknowledge receipt of the message.
- X
- X Example:
- X
- X Acknowledge-Receipt: Requested
- X
- XAddendum-To:
- X
- X A pointer to a previously submitted Journal item.
- X
- X Example:
- X
- X Addendum-To: <ASD,1234,>
- X
- XDelivery-Timing:
- X
- X Used by the sender to indicate when the message should be submitted to the
- X mailer.
- X
- X Examples:
- X
- X Rush: - immediate
- X
- X Soon: - as soon as possible
- X
- X Defer: - overnight
- X
- X Start-Delivery: DATE TIME
- X
- X Stop-Delivery: DATE TIME (if not yet delivered)
- X
- XDisposition-Code:
- X
- X Used by the system to group Journal items into one of several classes for
- X eventual archive to tape and as an indicator of how long the archive tapes
- X should be retained.
- X
- X Example:
- X
- X Disposition-Code: Temporary (2 years)
- X
- XExtended-access:
- X
- X Used with private Journal items to allow access by other than those on the
- X distribution list.
- X
- X Example:
- X
- X Extended-access: ASD.MDC
- X
- XLocation:
- X
- X Used to submit the message to the Journal. The adressees receive a short
- X citation with other header fields and a "Location:" field pointing to a fileX
- X in an electronic library.
- X
- X Example:
- X
- X Location: <MDC,1234,>
- X
- XPart-Of:
- X
- X A pointer to a previously submitted Journal item.
- X
- X Example:
- X
- X Part-Of: <MDC,1234,>
- X
- XRoute-To:
- X
- X Used to send a message "in-turn" to addressees in the "To:" field -- as
- X opposed to the broadcast method of delivery where everyone gets the message X
- X "simultaneously". Any addresses in the "Cc:" field receive a copy of the
- X message each time it is passed from one adressee to the next in the "To:"
- X field.
- X
- X Example:
- X
- X Routed-to: {addresses in To field}
- X
- XSigned:
- X
- X Created when the user employs the Sign command; used to electronically sign X
- X a message. It affixes a signature-block to a message. A "Verify Signature"X
- X command is available to recipients that lets them find out if anyone has
- X changed the body of the message since the message was signed.
- X
- X Example:
- X
- X SIGNED
- X
- X Duane L. Stone
- X App. Dev. Mgr.
- X
- XSupersedes:
- X
- X A pointer to a previously submitted Journal item.
- X
- X Example:
- X
- X Supersedes: <MDC,1234,>
- X
- X
- X--- last line of the file --
- END_OF_test/test.mail
- if test 10003 -ne `wc -c <test/test.mail`; then
- echo shar: \"test/test.mail\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"utils/from.c\" \(9633 characters\)
- if test -f utils/from.c ; then
- echo shar: Will not over-write existing file \"utils/from.c\"
- else
- sed "s/^X//" >utils/from.c <<'END_OF_utils/from.c'
- X/** from.c **/
- X
- X/** print out whom each message is from in the pending mailbox
- X or specified one, including a subject line if available..
- X
- X Added PREFER_UUCP knowledge 6/86
- X Added "-n" flag, 9/86
- X
- X (C) Copyright 1986 Dave Taylor
- X**/
- X
- X#include <stdio.h>
- X#include "defs.h"
- X
- Xstatic char ident[] = { WHAT_STRING };
- X
- X#define LINEFEED (char) 10
- X
- X#define metachar(c) (c == '=' || c == '+' || c == '%')
- X
- XFILE *mailfile;
- X
- Xchar *expand_define();
- Xint number = 0; /* should we number the messages?? */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X char infile[LONG_SLEN], username[SLEN];
- X
- X if (argc > 2) {
- X printf("Usage: %s [-n] {filename | username}\n", argv[0]);
- X exit(1);
- X }
- X
- X if (argc > 1)
- X if (strcmp(argv[1], "-n") == 0) {
- X number++;
- X *argv++;
- X argc--;
- X }
- X
- X if (argc == 2)
- X strcpy(infile, argv[1]);
- X else {
- X strcpy(username, getlogin());
- X if (strlen(username) == 0)
- X cuserid(username);
- X sprintf(infile,"%s%s",mailhome, username);
- X }
- X
- X if (metachar(infile[0])) {
- X if (expand(infile) == 0) {
- X fprintf(stderr, "%s: couldn't expand filename %s!\n",
- X argv[0], infile);
- X exit(1);
- X }
- X }
- X else
- X printf("filename '%s' doesn't have a metacharacter!\n", infile);
- X
- X if ((mailfile = fopen(infile,"r")) == NULL) {
- X if (argc == 1)
- X printf("No mail!\n");
- X else {
- X if (argv[1][0] == '/')
- X printf("Couldn't open folder/mailfile %s!\n", infile);
- X else {
- X sprintf(infile,"%s%s", mailhome, argv[1]);
- X if ((mailfile = fopen(infile,"r")) == NULL)
- X printf("Couldn't open folder/mailfile %s!\n", infile);
- X else if (read_headers()==0)
- X printf("No messages in mailbox!\n");
- X }
- X }
- X }
- X else
- X if (read_headers()==0)
- X printf("No messages in mailbox!\n");
- X}
- X
- Xint
- Xread_headers()
- X{
- X /** read the headers, output as found **/
- X
- X char buffer[LONG_SLEN], from_whom[SLEN], subject[SLEN];
- X register int subj = 0, in_header = 1, count = 0;
- X
- X while (fgets(buffer, LONG_SLEN, mailfile) != NULL) {
- X if (first_word(buffer,"From ")) {
- X if (real_from(buffer, from_whom)) {
- X subj = 0;
- X in_header = 1;
- X }
- X }
- X else if (in_header) {
- X if (first_word(buffer,">From"))
- X forwarded(buffer, from_whom); /* return address */
- X else if (first_word(buffer,"Subject:") ||
- X first_word(buffer,"Re:")) {
- X if (! subj++) {
- X remove_first_word(buffer);
- X strcpy(subject, buffer);
- X }
- X }
- X else if (first_word(buffer,"From:"))
- X parse_arpa_from(buffer, from_whom);
- X else if (buffer[0] == LINEFEED) {
- X in_header = 0; /* in body of message! */
- X show_header(count+1, from_whom, subject);
- X from_whom[0] = 0;
- X subject[0] = 0;
- X count++;
- X }
- X }
- X }
- X return(count);
- X}
- X
- Xint
- Xreal_from(buffer, who)
- Xchar *buffer, *who;
- X{
- X /***** returns true iff 's' has the seven 'from' fields,
- X initializing the who to the sender *****/
- X
- X char junk[80];
- X
- X junk[0] = '\0';
- X sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
- X who, junk);
- X return(junk[0] != '\0');
- X}
- X
- Xforwarded(buffer, who)
- Xchar *buffer, *who;
- X{
- X /** change 'from' and date fields to reflect the ORIGINATOR of
- X the message by iteratively parsing the >From fields... **/
- X
- X char machine[80], buff[80];
- X
- X machine[0] = '\0';
- X sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
- X who, machine);
- X
- X if (machine[0] == '\0') /* try for srm address */
- X sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
- X who, machine);
- X
- X if (machine[0] == '\0')
- X sprintf(buff,"anonymous");
- X else
- X sprintf(buff,"%s!%s", machine, who);
- X
- X strncpy(who, buff, 80);
- X}
- X
- X
- Xremove_first_word(string)
- Xchar *string;
- X{ /** removes first word of string, ie up to first non-white space
- X following a white space! **/
- X
- X register int loc;
- X
- X for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++)
- X ;
- X
- X while (string[loc] == ' ' || string[loc] == '\t')
- X loc++;
- X
- X move_left(string, loc);
- X}
- X
- Xmove_left(string, chars)
- Xchar string[];
- Xint chars;
- X{
- X /** moves string chars characters to the left DESTRUCTIVELY **/
- X
- X register int i;
- X
- X chars--; /* index starting at zero! */
- X
- X for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
- X string[i-chars] = string[i];
- X
- X string[i-chars] = '\0';
- X}
- X
- Xshow_header(count, from, subject)
- Xint count;
- Xchar *from, *subject;
- X{
- X /** output header in clean format, including abbreviation
- X of return address if more than one machine name is
- X contained within it! **/
- X
- X char buffer[SLEN];
- X int loc, i=0, exc=0;
- X
- X#ifdef PREFER_UUCP
- X
- X if (chloc(from,'!') != -1 && in_string(from, BOGUS_INTERNET))
- X from[strlen(from) - strlen(BOGUS_INTERNET)] = '\0';
- X
- X#endif
- X
- X loc = strlen(from);
- X
- X while (exc < 2 && loc > 0)
- X if (from[--loc] == '!')
- X exc++;
- X
- X if (exc == 2) { /* lots of machine names! Get last one */
- X loc++;
- X while (loc < strlen(from) && loc < SLEN)
- X buffer[i++] = from[loc++];
- X buffer[i] = '\0';
- X if (number)
- X printf("%3d: %-20s %s\n", count, buffer, subject);
- X else
- X printf("%-20s %s\n", buffer, subject);
- X }
- X else
- X if (number)
- X printf("%3d: %-20s %s\n", count, from, subject);
- X else
- X printf("%-20s %s\n", from, subject);
- X}
- X
- Xparse_arpa_from(buffer, newfrom)
- Xchar *buffer, *newfrom;
- X{
- X /** try to parse the 'From:' line given... It can be in one of
- X two formats:
- X From: Dave Taylor <hpcnou!dat>
- X or From: hpcnou!dat (Dave Taylor)
- X Change 'newfrom' ONLY if sucessfully parsed this entry and
- X the resulting name is non-null!
- X **/
- X
- X char temp_buffer[SLEN], *temp;
- X register int i, j = 0;
- X
- X temp = (char *) temp_buffer;
- X temp[0] = '\0';
- X
- X no_ret(buffer); /* blow away '\n' char! */
- X
- X if (lastch(buffer) == '>') {
- X for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
- X buffer[i] != '('; i++)
- X temp[j++] = buffer[i];
- X temp[j] = '\0';
- X }
- X else if (lastch(buffer) == ')') {
- X for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
- X buffer[i] != '<'; i--)
- X temp[j++] = buffer[i];
- X temp[j] = '\0';
- X reverse(temp);
- X }
- X
- X if (strlen(temp) > 0) { /* mess with buffer... */
- X
- X /* remove leading spaces... */
- X
- X while (whitespace(temp[0]))
- X temp = (char *) (temp + 1); /* increment address! */
- X
- X /* remove trailing spaces... */
- X
- X i = strlen(temp) - 1;
- X
- X while (whitespace(temp[i]))
- X temp[i--] = '\0';
- X
- X /* if anything is left, let's change 'from' value! */
- X
- X if (strlen(temp) > 0)
- X strcpy(newfrom, temp);
- X }
- X}
- X
- Xreverse(string)
- Xchar *string;
- X{
- X /** reverse string... pretty trivial routine, actually! **/
- X
- X char buffer[SLEN];
- X register int i, j = 0;
- X
- X for (i = strlen(string)-1; i >= 0; i--)
- X buffer[j++] = string[i];
- X
- X buffer[j] = '\0';
- X
- X strcpy(string, buffer);
- X}
- X
- Xint
- Xexpand(infile)
- Xchar *infile;
- X{
- X /** Expand the filename since the first character is a meta-
- X character that should expand to the "maildir" variable
- X in the users ".elmrc" file...
- X
- X Note: this is a brute force way of getting the entry out
- X of the .elmrc file, and isn't recommended for the faint
- X of heart!
- X **/
- X
- X FILE *rcfile;
- X char buffer[SLEN], *expanded_dir, *home, *getenv(), *bufptr;
- X int foundit = 0;
- X
- X bufptr = (char *) buffer; /* same address */
- X
- X if ((home = getenv("HOME")) == NULL) {
- X printf(
- X "Can't expand environment variable $HOME to find .elmrc file!\n");
- X exit(1);
- X }
- X
- X sprintf(buffer, "%s/%s", home, elmrcfile);
- X
- X if ((rcfile = fopen(buffer, "r")) == NULL) {
- X printf("Can't open your \".elmrc\" file (%s) for reading!\n",
- X buffer);
- X exit(1);
- X }
- X
- X while (fgets(buffer, SLEN, rcfile) != NULL && ! foundit) {
- X if (strncmp(buffer, "maildir", 7) == 0 ||
- X strncmp(buffer, "folders", 7) == 0) {
- X while (*bufptr != '=' && *bufptr)
- X bufptr++;
- X bufptr++; /* skip the equals sign */
- X while (whitespace(*bufptr) && *bufptr)
- X bufptr++;
- X home = bufptr; /* remember this address */
- X
- X while (! whitespace(*bufptr) && *bufptr != '\n')
- X bufptr++;
- X
- X *bufptr = '\0'; /* remove trailing space */
- X foundit++;
- X }
- X }
- X
- X fclose(rcfile); /* be nice... */
- X
- X if (! foundit) {
- X printf("Couldn't find \"maildir\" in your .elmrc file!\n");
- X exit(1);
- X }
- X
- X /** Home now points to the string containing your maildir, with
- X no leading or trailing white space...
- X **/
- X
- X expanded_dir = expand_define(home);
- X
- X sprintf(buffer, "%s%s%s", expanded_dir,
- X (expanded_dir[strlen(expanded_dir)-1] == '/' ||
- X infile[0] == '/') ? "" : "/", (char *) infile+1);
- X
- X strcpy(infile, buffer);
- X}
- X
- Xchar *expand_define(maildir)
- Xchar *maildir;
- X{
- X /** This routine expands any occurances of "~" or "$var" in
- X the users definition of their maildir directory out of
- X their .elmrc file.
- X
- X Again, another routine not for the weak of heart or staunch
- X of will!
- X **/
- X
- X static char buffer[SLEN]; /* static buffer AIEE!! */
- X char name[SLEN], /* dynamic buffer!! (?) */
- X *nameptr, /* pointer to name?? */
- X *value; /* char pointer for munging */
- X
- X if (*maildir == '~')
- X sprintf(buffer, "%s%s", getenv("HOME"), ++maildir);
- X else if (*maildir == '$') { /* shell variable */
- X
- X /** break it into a single word - the variable name **/
- X
- X strcpy(name, (char *) maildir + 1); /* hurl the '$' */
- X nameptr = (char *) name;
- X while (*nameptr != '/' && *nameptr) nameptr++;
- X *nameptr = '\0'; /* null terminate */
- X
- X /** got word "name" for expansion **/
- X
- X if ((value = getenv(name)) == NULL) {
- X printf("Couldn't expand shell variable $%s in .elmrc!\n", name);
- X exit(1);
- X }
- X sprintf(buffer, "%s%s", value, maildir + strlen(name) + 1);
- X }
- X else strcpy(buffer, maildir);
- X
- X return( ( char *) buffer);
- X}
- END_OF_utils/from.c
- if test 9633 -ne `wc -c <utils/from.c`; then
- echo shar: \"utils/from.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 10 \(of 19\).
- cp /dev/null ark10isdone
- DONE=true
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
- if test ! -f ark${I}isdone ; then
- echo shar: You still need to run archive ${I}.
- DONE=false
- fi
- done
- if test "$DONE" = "true" ; then
- echo You have unpacked all 19 archives.
- echo "See the Instructions file"
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- fi
- ## End of shell archive.
- exit 0
-