Msg Shar.part.7
sources-request at panda.UUCP
sources-request at panda.UUCP
Mon Mar 3 23:20:41 AEST 1986
Mod.sources: Volume 4, Issue 11
Submitted by: decvax!hplabs!hpcnou!dat (Dave Taylor)
# Msg Shar part 7 of 7
# Shell Archive created by hpcnou!dat at Wed Feb 26 15:57:03 1986
# To unpack the enclosed files, please use this file as input to the
# Bourne (sh) shell. This can be most easily done by the command;
# sh < thisfilename
# This archive contains;
# utils/cutfile.c utils/fastmail.c utils/from.c utils/newalias.c
# utils/newmail.c utils/printmail.c utils/readmsg.c utils/Makefile
# test/test.mail test/test.notes
if [ ! -d utils ]
then
echo creating directory utils
mkdir utils
fi
# ---------- file utils/cutfile.c ----------
if [ -f utils/cutfile.c ]
then
echo File 'utils/cutfile.c' already exists\!
exit 1
fi
echo extracting file utils/cutfile.c...
cat << 'END-OF-FILE' > utils/cutfile.c
/** cutfile.c **/
/** This program is written for the MSG mail system (and other programs
that could use it's functionality, of course!) for the express purpose
of allowing a message out of a file of messages to be QUICKLY extracted
into another file.
Usage: cutfile <filename> <offset-into-file> <number-of-lines> <dest-file>
It is fed to standard output if dest-file = "-".
(C) Copyright 1986 Dave Taylor
**/
#include <stdio.h>
#include <errno.h>
#define SLEN 256 /* string length */
extern int errno; /* system errno */
main(argc, argv)
int argc;
char *argv[];
{
FILE *infile, *outfile;
char buffer[SLEN];
register lines;
if (argc != 5)
exit (fprintf(stderr, "Usage: %s <filename> <offset> <lines> <dest-file>\n",
argv[0]));
if ((infile = fopen(argv[1], "r")) == NULL)
exit (fprintf(stderr, "%s cannot open file %s for reading!\n",
argv[0], argv[1]));
if (argv[4][0] == '-')
outfile = stdout;
else
if ((outfile = fopen(argv[4], "w")) == NULL)
exit (fprintf(stderr, "%s cannot open file %s for writing!\n",
argv[0], argv[1]));
if (fseek(infile, atoi(argv[2]), 0L) == -1)
exit (fprintf(stderr, "%s encountered error %d trying to fseek to %ld\n",
argv[0], errno, argv[2]));
lines = atoi(argv[3]);
while (fgets(buffer, SLEN, infile) != NULL) {
fputs(buffer, outfile);
if (--lines == 0)
exit(0);
}
exit(1); /* 1 indicates read past EOF */
}
END-OF-FILE
size=`wc -c < utils/cutfile.c`
if [ $size != 1454 ]
then
echo Warning: utils/cutfile.c changed - should be 1454 bytes, not $size bytes
fi
chmod 644 utils/cutfile.c
# ---------- file utils/fastmail.c ----------
if [ -f utils/fastmail.c ]
then
echo File 'utils/fastmail.c' already exists\!
exit 1
fi
echo extracting file utils/fastmail.c...
cat << 'END-OF-FILE' > utils/fastmail.c
/** fastmail.c **/
/** This program is specifically written for group mailing lists and
such batch type mail processing. It does NOT use aliases at all,
it does NOT read the /etc/password file to find the From: name
of the user and does NOT expand any addresses. It is meant
purely as a front-end for either /bin/mail or /usr/lib/sendmail
(according to what is available on the current system).
**** This program should be used with CAUTION *****
(C) Copyright 1985 Dave Taylor
**/
/** The calling sequence for this program is:
fastmail {-d} -f "from string" filename full-email-address
**/
#include <stdio.h>
#include <time.h>
#define NLEN 40
#define SLEN 80
#define READ_ACCESS 04
#define EXECUTE_ACCESS 01
#define sendmail "/usr/lib/sendmail"
#define binrmail "/bin/rmail"
#define temphome "/tmp/fastmail."
#define VERSION "1.1"
#define usage() fprintf(stderr, "Usage: fastmail {-d} %s %s\n", \
"-f \"from string\" -s \"subject\"", \
"filename full-email-address")
#define DONE 0
#define ERROR -1
char *optional_arg; /* optional argument as we go */
int opt_index; /* argnum + 1 when we leave */
char *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
"Fri", "Sat", "" };
char *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
char *get_arpa_date();
main(argc, argv)
int argc;
char *argv[];
{
FILE *tempfile;
char hostname[NLEN], username[NLEN], from_string[SLEN], subject[SLEN];
char filename[SLEN], tempfilename[SLEN], command_buffer[256];
int c, sendmail_available, debug = 0;
while ((c = get_options(argc, argv, "df:s:")) > 0) {
switch (c) {
case 'd' : debug++; break;
case 'f' : strcpy(from_string, optional_arg); break;
case 's' : strcpy(subject, optional_arg); break;
}
}
if (c == ERROR) exit(usage());
if (opt_index > argc)
exit(usage());
strcpy(filename, argv[opt_index++]);
if (opt_index > argc)
exit(usage());
gethostname(hostname, sizeof(hostname));
strcpy(username, getlogin());
if (strlen(username) == 0)
cuserid(username);
if (access(filename, READ_ACCESS) == -1)
exit(fprintf(stderr, "Error: can't find file %s!\n", filename));
sprintf(tempfilename, "%s%d", temphome, getpid());
if ((tempfile = fopen(tempfilename, "w")) == NULL)
exit(fprintf(stderr, "Couldn't open temp file %s\n", tempfilename));
if (strlen(from_string) > 0)
fprintf(tempfile, "From: %s!%s (%s)\n",
hostname, username, from_string);
else
fprintf(tempfile, "From: %s!%s\n", hostname, username);
fprintf(tempfile, "Date: %s\n", get_arpa_date());
if (strlen(subject) > 0)
fprintf(tempfile, "Subject: %s\n", subject);
fprintf(tempfile, "To: %s\n", argv[opt_index]);
fprintf(tempfile, "X-Mailer: fastmail [version %s]\n", VERSION);
fprintf(tempfile, "\n");
fclose(tempfile);
/** now we'll cat both files to /bin/rmail or sendmail... **/
sendmail_available = (access(sendmail, EXECUTE_ACCESS) != -1);
printf("Mailing to %s [via %s]\n", argv[opt_index],
sendmail_available? "sendmail" : "rmail");
sprintf(command_buffer, "cat %s %s | %s '%s'",
tempfilename, filename,
sendmail_available? sendmail : binrmail,
argv[opt_index]);
if (debug)
printf("%s\n", command_buffer);
system(command_buffer);
unlink(tempfilename);
}
char *get_arpa_date()
{
/** Returns an ARPA standard date. The format for the date
according to DARPA document RFC-822 is exemplified by;
Mon, 12 Aug 85 6:29:08 MST
**/
extern char *tzname[];
static char buffer[SLEN]; /* static character buffer */
struct tm *the_time; /* Time structure, see CTIME(3C) */
long junk; /* time in seconds.... */
junk = time(0); /* this must be here for it to work! */
the_time = (struct tm * ) localtime(&junk);
sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s",
arpa_dayname[the_time->tm_wday],
the_time->tm_mday % 32,
arpa_monname[the_time->tm_mon],
the_time->tm_year % 100,
the_time->tm_hour % 24,
the_time->tm_min % 61,
the_time->tm_sec % 61,
tzname[the_time->tm_isdst]);
return( (char *) buffer);
}
/** Starting argument parsing routine.
Called as "get_options(argc, argv, options)" where options is a string
of the form "abc:d" indicating that 'a' 'b' and 'd' are flags and
'c' is a flag with a trailing argument. Optional arguments are
returned in the external char * variable "optional_arg", and the
external int "opt_index" is set to the first entry in the argv list
that wasn't processed (ie after the flags).
For example, the C compiler would have something of the form
getopt(argc, argv, "Oo:l:") to allow "cc -O -o output -l lib file.c"
(C) Copyright 1986, Dave Taylor
**/
int _indx = 1, _argnum = 1;
int
get_options(argc, argv, options)
int argc;
char *argv[], *options;
{
/** Returns the character argument next, and optionally instantiates
"argument" to the argument associated with the particular option
**/
char *word, *strchr();
if (_indx >= strlen(argv[_argnum])) {
_argnum++;
_indx = 1; /* zeroeth char is '-' */
}
if (_argnum >= argc) {
opt_index = argc;
return(DONE);
}
if (argv[_argnum][0] != '-') {
opt_index = _argnum;
return(DONE);
}
word = strchr(options, argv[_argnum][_indx++]);
if (strlen(word) == 0)
return(ERROR);
if (word[1] == ':') {
/** Two possibilities - either tailing end of this argument or the
next argument in the list **/
if (_indx < strlen(argv[_argnum])) { /* first possibility */
optional_arg = (char *) (argv[_argnum] + _indx);
_argnum++;
_indx = 1;
}
else { /* second choice */
if (++_argnum >= argc)
return(ERROR); /* no argument!! */
optional_arg = (char *) argv[_argnum++];
_indx = 1;
}
}
return((int) word[0]);
}
END-OF-FILE
size=`wc -c < utils/fastmail.c`
if [ $size != 5979 ]
then
echo Warning: utils/fastmail.c changed - should be 5979 bytes, not $size bytes
fi
chmod 644 utils/fastmail.c
# ---------- file utils/from.c ----------
if [ -f utils/from.c ]
then
echo File 'utils/from.c' already exists\!
exit 1
fi
echo extracting file utils/from.c...
cat << 'END-OF-FILE' > utils/from.c
/** from.c **/
/** print out whom each message is from in the pending mailbox
or specified one, including a subject line if available.. **/
/** (C) Copyright 1986 Dave Taylor **/
#include <stdio.h>
#include "defs.h"
#define LINEFEED (char) 10
FILE *mailfile;
main(argc, argv)
int argc;
char *argv[];
{
char infile[LONG_SLEN], username[SLEN];
if (argc > 2)
exit(printf("Usage: %s {filename}\n", argv[0]));
if (argc == 2)
strcpy(infile, argv[1]);
else {
strcpy(username, getlogin());
if (strlen(username) == 0)
cuserid(username);
sprintf(infile,"%s/%s",mailhome, username);
}
if ((mailfile = fopen(infile,"r")) == NULL)
printf("%s\n", argc==1?"No mail!":"Could not open file!");
else
if (read_headers()==0)
printf("No messages in mailbox!\n");
}
int
read_headers()
{
/** read the headers, output as found **/
char buffer[LONG_SLEN], from_whom[SLEN], subject[SLEN];
register int subj = 0, in_header = 1, count = 0;
while (fgets(buffer, LONG_SLEN, mailfile) != NULL) {
if (first_word(buffer,"From ")) {
if (real_from(buffer, from_whom)) {
subj = 0;
in_header = 1;
}
}
else if (in_header) {
if (first_word(buffer,">From"))
forwarded(buffer, from_whom); /* return address */
else if (first_word(buffer,"Subject:") ||
first_word(buffer,"Re:")) {
if (! subj++) {
remove_first_word(buffer);
strcpy(subject, buffer);
}
}
else if (first_word(buffer,"From:"))
parse_arpa_from(buffer, from_whom);
else if (buffer[0] == LINEFEED) {
in_header = 0; /* in body of message! */
show_header(from_whom, subject);
from_whom[0] = 0;
subject[0] = 0;
count++;
}
}
}
return(count);
}
int
real_from(buffer, who)
char *buffer, *who;
{
/***** returns true iff 's' has the seven 'from' fields,
initializing the who to the sender *****/
char junk[80];
junk[0] = '\0';
sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
who, junk);
return(junk[0] != '\0');
}
forwarded(buffer, who)
char *buffer, *who;
{
/** change 'from' and date fields to reflect the ORIGINATOR of
the message by iteratively parsing the >From fields... **/
char machine[80], buff[80];
machine[0] = '\0';
sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
who, machine);
if (machine[0] == '\0') /* try for srm address */
sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
who, machine);
if (machine[0] == '\0')
sprintf(buff,"anonymous");
else
sprintf(buff,"%s!%s", machine, who);
strncpy(who, buff, 80);
}
remove_first_word(string)
char *string;
{ /** removes first word of string, ie up to first non-white space
following a white space! **/
register int loc;
for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++)
;
while (string[loc] == ' ' || string[loc] == '\t')
loc++;
move_left(string, loc);
}
move_left(string, chars)
char string[];
int chars;
{
/** moves string chars characters to the left DESTRUCTIVELY **/
register int i;
chars--; /* index starting at zero! */
for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
string[i-chars] = string[i];
string[i-chars] = '\0';
}
show_header(from, subject)
char *from, *subject;
{
/** output header in clean format, including abbreviation
of return address if more than one machine name is
contained within it! **/
char buffer[SLEN];
int loc, i=0, exc=0;
loc = strlen(from);
while (exc < 2 && loc > 0)
if (from[--loc] == '!')
exc++;
if (exc == 2) { /* lots of machine names! Get last one */
loc++;
while (loc < strlen(from) && loc < SLEN)
buffer[i++] = from[loc++];
buffer[i] = '\0';
printf("%-20s %s\n", buffer, subject);
}
else
printf("%-20s %s\n", from, subject);
}
parse_arpa_from(buffer, newfrom)
char *buffer, *newfrom;
{
/** try to parse the 'From:' line given... It can be in one of
two formats:
From: Dave Taylor <hpcnou!dat>
or From: hpcnou!dat (Dave Taylor)
Change 'newfrom' ONLY if sucessfully parsed this entry and
the resulting name is non-null!
**/
char temp_buffer[SLEN], *temp;
register int i, j = 0;
temp = (char *) temp_buffer;
temp[0] = '\0';
no_ret(buffer); /* blow away '\n' char! */
if (lastch(buffer) == '>') {
for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
buffer[i] != '('; i++)
temp[j++] = buffer[i];
temp[j] = '\0';
}
else if (lastch(buffer) == ')') {
for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
buffer[i] != '<'; i--)
temp[j++] = buffer[i];
temp[j] = '\0';
reverse(temp);
}
if (strlen(temp) > 0) { /* mess with buffer... */
/* remove leading spaces... */
while (whitespace(temp[0]))
temp = (char *) (temp + 1); /* increment address! */
/* remove trailing spaces... */
i = strlen(temp) - 1;
while (whitespace(temp[i]))
temp[i--] = '\0';
/* if anything is left, let's change 'from' value! */
if (strlen(temp) > 0)
strcpy(newfrom, temp);
}
}
reverse(string)
char *string;
{
/** reverse string... pretty trivial routine, actually! **/
char buffer[SLEN];
register int i, j = 0;
for (i = strlen(string)-1; i >= 0; i--)
buffer[j++] = string[i];
buffer[j] = '\0';
strcpy(string, buffer);
}
END-OF-FILE
size=`wc -c < utils/from.c`
if [ $size != 5388 ]
then
echo Warning: utils/from.c changed - should be 5388 bytes, not $size bytes
fi
chmod 644 utils/from.c
# ---------- file utils/newalias.c ----------
if [ -f utils/newalias.c ]
then
echo File 'utils/newalias.c' already exists\!
exit 1
fi
echo extracting file utils/newalias.c...
cat << 'END-OF-FILE' > utils/newalias.c
/** newalias.c **/
/** (C) Copyright 1986 Dave Taylor **/
/** Install a new set of aliases for the 'Msg' mailer.
If invoked with a specific filename, it assumes that
it is working with an individual users alias tables, and
generates the .alias.hash and .alias.data files in their
home directory.
If, however, it is invoked with no arguments, then
it assumes that the user is updating the system alias
file and uses the defaults for everything.
The format for the input file is;
alias1, alias2, ... : username : address
or alias1, alias2, ... : groupname: member, member, member, ...
member, member, member, ...
**/
#include <fcntl.h>
#include <stdio.h>
#include "defs.h" /* MSG system definitions */
#ifndef TAB
# define TAB '\t' /* TAB character! */
#endif
#define alias_hash ".alias_hash"
#define alias_data ".alias_data"
#define alias_text ".alias_text"
#define group(string) (strpbrk(string,", ") != NULL)
struct alias_rec
shash_table[MAX_SALIASES]; /* the actual hash table */
struct alias_rec
uhash_table[MAX_UALIASES]; /* the actual hash table */
int hash_table_loaded=0; /* is system table actually loaded? */
int buff_loaded; /* for file input overlap... */
int error= 0; /* if errors, don't save! */
int system=0; /* system file updating? */
int count=0; /* how many aliases so far? */
long offset = 0L; /* data file line offset! */
main(argc, argv)
int argc;
char *argv[];
{
FILE *in, *data;
char inputname[SLEN], hashname[SLEN], dataname[SLEN];
char home[SLEN], buffer[LONG_STRING];
int hash, count = 0, owner;
if (argc != 1)
exit(printf("Usage: %s\n", argv[0]));
owner = getuid();
if (owner == 0) { /* being run by root! */
printf("Would you like to update the system aliases? (y/n)");
gets(buffer, 2);
if (buffer[0] == 'y' || buffer[0] == 'Y') {
printf("Updating the system alias file...\n");
sprintf(inputname, "%s/%s", mailhome, alias_text);
sprintf(hashname, "%s/%s", mailhome, alias_hash);
sprintf(dataname, "%s/%s", mailhome, alias_data);
system++;
init_table(shash_table, MAX_SALIASES);
}
else
printf("Updating your personal alias file...\n");
}
if (! system) {
if (strcpy(home, getenv("HOME")) == NULL)
exit(printf("Confused: No HOME variable in environment!\n"));
sprintf(inputname, "%s/%s", home, alias_text);
sprintf(hashname, "%s/%s", home, alias_hash);
sprintf(dataname, "%s/%s", home, alias_data);
init_table(uhash_table, MAX_UALIASES);
read_in_system(shash_table, sizeof shash_table);
}
if ((in = fopen(inputname,"r")) == NULL)
exit(printf("Couldn't open %s for input!\n", inputname));
if ((hash = open(hashname, O_WRONLY | O_CREAT, 0644)) == -1)
exit(printf("Couldn't open %s for output!\n", hashname));
if ((data = fopen(dataname,"w")) == NULL)
exit(printf("Couldn't open %s for output!\n", dataname));
buff_loaded = 0; /* file buffer empty right now! */
while (get_alias(in, buffer) != -1) {
if (system)
put_alias(data, buffer, shash_table, MAX_SALIASES);
else
put_alias(data, buffer, uhash_table, MAX_UALIASES);
count++;
}
if (error) {
printf("\n** Not saving tables! Please fix and re-run %s!\n",
argv[0]);
exit(1);
}
else {
if (system)
write(hash, shash_table, sizeof shash_table);
else
write(hash, uhash_table, sizeof uhash_table);
close(hash);
fclose(data);
close(in);
printf("Processed %d aliases\n", count);
exit(0);
}
}
int
get_alias(file, buffer)
FILE *file;
char *buffer;
{
/* load buffer with the next complete alias from the file.
(this can include reading in multiple lines and appending
them all together!) Returns EOF after last entry in file.
Lines that start with '#' are assumed to be comments and are
ignored. White space as the first field of a line is taken
to indicate that this line is a continuation of the previous. */
static char mybuffer[SLEN];
int done = 0, first_read = 1;
/** get the first line of the entry... **/
do {
if (get_line(file, mybuffer, first_read) == -1)
return(-1);
first_read = 0;
if (mybuffer[0] != '#')
strcpy(buffer, mybuffer);
} while (strlen(buffer) == 0);
/** now read in the rest (if there is any!) **/
do {
if (get_line(file, mybuffer, first_read) == -1) {
buff_loaded = 0; /* force a read next pass! */
return(0); /* okay. let's just hand 'buffer' back! */
}
done = (mybuffer[0] != ' ' && mybuffer[0] != TAB);
if (mybuffer[0] != '#' && ! done)
strcat(buffer, mybuffer);
done = (done && mybuffer[0] != '#');
} while (! done);
return(0); /* no sweat! */
}
put_alias(data, buffer, table, size)
FILE *data;
char *buffer;
struct alias_rec table[];
int size;
{
/** break buffer down into two pieces: aliases, and address,
throwing away the username (comment) field.
Make the appropriate entries in the table (size) **/
char aliases[LONG_STRING], address[LONG_STRING];
int i = 0, j = 0;
remove_all(' ', TAB, buffer);
for (i=0; buffer[i] != ':' && i < LONG_STRING; i++)
aliases[i] = buffer[i];
aliases[i] = '\0';
for (i=strlen(buffer)-1; buffer[i] != ':' && i > 0; i--)
address[j++] = buffer[i];
address[j] = '\0';
reverse(address);
add_to_table(data, aliases, address, table, size);
}
int
get_line(file, buffer, first_line)
FILE *file;
char *buffer;
int first_line;
{
/** read line from file. If first_line and buff_loaded,
then just return! **/
int stat;
if (first_line && buff_loaded) {
buff_loaded = 1;
return;
}
buff_loaded = 1; /* we're going to get SOMETHING in the buffer */
stat = fgets(buffer, SLEN, file) == NULL ? -1 : 0;
if (stat != -1)
no_ret(buffer);
return(stat);
}
reverse(string)
char *string;
{
/** reverse the order of the characters in string...
uses a bubble-sort type of algorithm! **/
register int f, l;
char c;
f = 0;
l = strlen(string) - 1;
while (f < l) {
c = string[f];
string[f] = string[l];
string[l] = c;
f++;
l--;
}
}
add_to_table(data, aliases, address, table, size)
FILE *data;
char *aliases, *address;
struct alias_rec table[];
int size;
{
/** add address to datafile, incrementing offset count (bytes),
then for each alias in the aliases string, add to the
hash table, with the associated pointer value! **/
static char buf[SLEN], *word;
long additive = 1L;
word = buf; /* use the allocated space! */
if (group(address)) {
check_group(address, aliases);
if (error) return; /* don't do work if we aren't to save it! */
fprintf(data, "!%s\n", address);
additive = 2L;
}
else {
if (error) return; /* don't do work if we aren't to save it! */
fprintf(data, "%s\n", address);
}
while ((word = (char *) strtok(aliases,", ")) != NULL) {
add_to_hash_table(word, offset, table, size);
aliases = NULL; /* let's get ALL entries via 'strtok' */
count++;
}
if ((system && count > MAX_SALIASES-35) || count > MAX_UALIASES-21) {
printf("** Too many aliases in file! **\n");
error++;
}
offset = (offset + (long) strlen(address) + additive);
}
remove_all(c1, c2, string)
char c1, c2, *string;
{
/* remove all occurances of character 'c' from string. */
char buffer[LONG_STRING];
register int i = 0, j = 0;
for (i = 0; string[i] != '\0' && i < LONG_STRING; i++)
if (string[i] != c1 && string[i] != c2)
buffer[j++] = string[i];
buffer[j] = '\0';
strcpy(string, buffer);
}
add_to_hash_table(word, offset, table, size)
char *word;
long offset;
struct alias_rec table[];
int size;
{
/** add word and offset to current hash table. **/
register int loc;
if (strlen(word) > 20)
exit(printf("Bad alias name: %s. Too long.\n", word));
loc = hash_it(word, size);
while (table[loc].name[0] != '\0' && strcmp(table[loc].name, word) != 0)
loc = loc + 1 % size;
if (table[loc].name[0] == '\0') {
strcpy(table[loc].name, word);
table[loc].byte = offset;
}
else
printf("** Duplicate alias '%s' in file. Multiples ignored.\n",
word);
}
int
hash_it(string, table_size)
char *string;
{
/** compute the hash function of the string, returning
it (mod table_size) **/
register int i, sum = 0;
for (i=0; string[i] != '\0'; i++)
sum += (int) string[i];
return(sum % table_size);
}
init_table(table, size)
struct alias_rec table[];
int size;
{
/** initialize hash table! **/
register int i;
for (i=0; i < size; i++)
table[i].name[0] = '\0';
}
read_in_system(table, size)
struct alias_rec table[];
int size;
{
/** read in the system hash table...to check for group aliases
from the user alias file (to ensure that there are no names
in the user group files that are not purely contained within
either alias table) **/
int fd;
char fname[SLEN];
sprintf(fname, "%s/%s", mailhome, alias_hash);
if ((fd = open(fname, O_RDONLY)) == -1)
return; /* no sweat: flag 'hash_table_loaded' not set! */
(void) read(fd, table, size);
close(fd);
hash_table_loaded++;
}
check_group(names, groupname)
char *names, *groupname;
{
/** one by one make sure each name in the group is defined
in either the system alias file or the user alias file.
This search is linearly dependent, so all group aliases
in the source file should appear LAST, after all the user
aliases! **/
char *word, *bufptr, buffer[LONG_STRING];
strcpy(buffer, names);
bufptr = (char *) buffer;
while ((word = (char *) strtok(bufptr,", ")) != NULL) {
if (! can_find(word))
if (! valid_name(word)) {
error++;
printf("** Alias %s in group %s is bad!\n", word, groupname);
}
bufptr = NULL;
}
}
int
can_find(name)
char *name;
{
/** find name in either hash table...use 'system' variable to
determine if we should look in both or just system.... **/
register int loc;
if (strlen(name) > 20) {
error++;
printf("** Bad alias name: %s. Too long.\n", name);
return(1); /* fake out: don't want 2 error messages! */
}
/** system alias table... **/
if (hash_table_loaded || system) {
loc = hash_it(name, MAX_SALIASES);
while (strcmp(name, shash_table[loc].name) != 0 &&
shash_table[loc].name[0] != '\0')
loc = (loc + 1) % MAX_SALIASES;
if (strcmp(name, shash_table[loc].name) == 0)
return(1); /* found it! */
}
if (! system) { /* okay! Let's check the user alias file! */
loc = hash_it(name, MAX_UALIASES);
while (strcmp(name, uhash_table[loc].name) != 0 &&
uhash_table[loc].name[0] != '\0')
loc = (loc + 1) % MAX_UALIASES;
if (strcmp(name, uhash_table[loc].name) == 0)
return(1); /* found it! */
}
return(0);
}
END-OF-FILE
size=`wc -c < utils/newalias.c`
if [ $size != 10812 ]
then
echo Warning: utils/newalias.c changed - should be 10812 bytes, not $size bytes
fi
chmod 644 utils/newalias.c
# ---------- file utils/newmail.c ----------
if [ -f utils/newmail.c ]
then
echo File 'utils/newmail.c' already exists\!
exit 1
fi
echo extracting file utils/newmail.c...
cat << 'END-OF-FILE' > utils/newmail.c
/** newmail.c **/
/** Keep track of the mail for the current user...if new mail
arrives, output a line of the form;
Mail has arrived from <name> - <subject>
where <name> is either the persons full name, or machine!login.
If there is no subject, it will say.
This program also tries to keep track of if the user is still
logged in - if they log out it will quit execution.
(C) 1986, Dave Taylor
**/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "defs.h"
#define LINEFEED (char) 10
#define BEGINNING 0 /* seek fseek(3S) */
#define SLEEP_TIME 60
#define NO_SUBJECT "<no subject>"
FILE *mailfile;
long bytes();
main(argc, argv)
int argc;
char *argv[];
{
char filename[LONG_SLEN];
long size, newsize;
sprintf(filename,"%s/%s",mailhome, getlogin());
size = bytes(filename);
mailfile = (FILE *) NULL;
while (1) {
if (getppid() == 1) /* we've lost our shell! */
exit();
if (mailfile == (FILE *) NULL)
mailfile = fopen(filename,"r");
if ((newsize = bytes(filename)) > size) { /* new mail */
fseek(mailfile, size, BEGINNING); /* skip all current mail */
size = newsize;
printf("\n\r"); /* blank lines surrounding message */
read_headers();
printf("\n\r");
}
else if (newsize != size) {
size = newsize; /* mail's been removed... */
mailfile = (FILE *) NULL; /* let's reopen the file */
}
sleep(SLEEP_TIME);
}
}
int
read_headers()
{
/** read the headers, output as found **/
char buffer[LONG_SLEN], from_whom[SLEN], subject[SLEN];
register int subj = 0, in_header = 1, count = 0;
while (fgets(buffer, LONG_SLEN, mailfile) != NULL) {
if (first_word(buffer,"From ")) {
if (real_from(buffer, from_whom)) {
subj = 0;
in_header = 1;
}
}
else if (in_header) {
if (first_word(buffer,">From"))
forwarded(buffer, from_whom); /* return address */
else if (first_word(buffer,"Subject:") ||
first_word(buffer,"Re:")) {
if (! subj++) {
remove_first_word(buffer);
strcpy(subject, buffer);
}
}
else if (first_word(buffer,"From:"))
parse_arpa_from(buffer, from_whom);
else if (buffer[0] == LINEFEED) {
in_header = 0; /* in body of message! */
show_header(from_whom, subject);
from_whom[0] = 0;
subject[0] = 0;
count++;
}
}
}
return(count);
}
int
real_from(buffer, who)
char *buffer, *who;
{
/***** returns true iff 's' has the seven 'from' fields,
initializing the who to the sender *****/
char junk[80];
junk[0] = '\0';
sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
who, junk);
return(junk[0] != '\0');
}
forwarded(buffer, who)
char *buffer, *who;
{
/** change 'from' and date fields to reflect the ORIGINATOR of
the message by iteratively parsing the >From fields... **/
char machine[80], buff[80];
machine[0] = '\0';
sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
who, machine);
if (machine[0] == '\0') /* try for srm address */
sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
who, machine);
if (machine[0] == '\0')
sprintf(buff,"anonymous");
else
sprintf(buff,"%s!%s", machine, who);
strncpy(who, buff, 80);
}
remove_first_word(string)
char *string;
{ /** removes first word of string, ie up to first non-white space
following a white space! **/
register int loc;
for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++)
;
while (string[loc] == ' ' || string[loc] == '\t')
loc++;
move_left(string, loc);
}
move_left(string, chars)
char string[];
int chars;
{
/** moves string chars characters to the left DESTRUCTIVELY **/
register int i;
chars--; /* index starting at zero! */
for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
string[i-chars] = string[i];
string[i-chars] = '\0';
}
show_header(from, subject)
char *from, *subject;
{
/** output header in clean format, including abbreviation
of return address if more than one machine name is
contained within it! **/
char buffer[SLEN];
int loc, i=0, exc=0;
loc = strlen(from);
while (exc < 2 && loc > 0)
if (from[--loc] == '!')
exc++;
if (exc == 2) { /* lots of machine names! Get last one */
loc++;
while (loc < strlen(from) && loc < SLEN)
buffer[i++] = from[loc++];
buffer[i] = '\0';
strcpy(from, buffer);
}
if (strlen(subject) == 0)
strcpy(subject, NO_SUBJECT);
printf(">> New mail has arrived from %s - %s\n\r", from, subject);
}
parse_arpa_from(buffer, newfrom)
char *buffer, *newfrom;
{
/** try to parse the 'From:' line given... It can be in one of
two formats:
From: Dave Taylor <hpcnou!dat>
or From: hpcnou!dat (Dave Taylor)
Change 'newfrom' ONLY if sucessfully parsed this entry and
the resulting name is non-null!
**/
char temp_buffer[SLEN], *temp;
register int i, j = 0;
temp = (char *) temp_buffer;
temp[0] = '\0';
no_ret(buffer); /* blow away '\n' char! */
if (lastch(buffer) == '>') {
for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
buffer[i] != '('; i++)
temp[j++] = buffer[i];
temp[j] = '\0';
}
else if (lastch(buffer) == ')') {
for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
buffer[i] != '<'; i--)
temp[j++] = buffer[i];
temp[j] = '\0';
reverse(temp);
}
if (strlen(temp) > 0) { /* mess with buffer... */
/* remove leading spaces... */
while (whitespace(temp[0]))
temp = (char *) (temp + 1); /* increment address! */
/* remove trailing spaces... */
i = strlen(temp) - 1;
while (whitespace(temp[i]))
temp[i--] = '\0';
/* if anything is left, let's change 'from' value! */
if (strlen(temp) > 0)
strcpy(newfrom, temp);
}
}
reverse(string)
char *string;
{
/** reverse string... pretty trivial routine, actually! **/
char buffer[SLEN];
register int i, j = 0;
for (i = strlen(string)-1; i >= 0; i--)
buffer[j++] = string[i];
buffer[j] = '\0';
strcpy(string, buffer);
}
long
bytes(name)
char *name;
{
/** return the number of bytes in the specified file. This
is to check to see if new mail has arrived.... **/
int ok = 1;
extern int errno; /* system error number! */
struct stat buffer;
if (stat(name, &buffer) != 0)
if (errno != 2)
exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name));
else
ok = 0;
return(ok ? buffer.st_size : 0);
}
END-OF-FILE
size=`wc -c < utils/newmail.c`
if [ $size != 6533 ]
then
echo Warning: utils/newmail.c changed - should be 6533 bytes, not $size bytes
fi
chmod 644 utils/newmail.c
# ---------- file utils/printmail.c ----------
if [ -f utils/printmail.c ]
then
echo File 'utils/printmail.c' already exists\!
exit 1
fi
echo extracting file utils/printmail.c...
cat << 'END-OF-FILE' > utils/printmail.c
/** printmail.c **/
/** print mail, adding a formfeed between each message **/
/** (C) Copyright 1985, Dave Taylor **/
#include <stdio.h>
#define first_word(s,w) (strncmp(s,w,strlen(w)) == 0)
#define mailhome "/usr/mail"
#define dashes \
"\n\n------------------------------------------------------------------------------\n\n"
#define FF "\014" /* form feed! */
FILE *mailfile;
char separator[80];
main(argc, argv)
int argc;
char *argv[];
{
char infile[80], username[40], c;
strcpy(separator, FF);
if (argc > 1)
if (strcmp(argv[1], "-d") == 0) {
strcpy(separator, dashes);
--argc;
*argv++;
}
if (argc > 1)
if (argv[1][0] == '-')
exit(fprintf(stderr, "Usage: %s {-d} {filename}\n", argv[0]));
if (argc == 1) {
strcpy(username, getlogin());
if (strlen(username) == 0)
cuserid(username);
sprintf(infile,"%s/%s",mailhome, username);
if ((mailfile = fopen(infile,"r")) == NULL)
fprintf(stderr, "No mail!\n");
else if (read_headers()==0)
fprintf(stderr, "No messages in mailbox!\n");
}
while (--argc) {
if ((mailfile = fopen(*argv,"r")) == NULL)
fprintf(stderr, "Could not open file '%s'!", *argv);
else
if (read_headers()==0)
fprintf(stderr, "No messages in mailbox '%s'!\n", *argv);
*argv++;
if (argc) {
printf("%s", separator);
printf("%s", separator);
}
}
}
int
read_headers()
{
char buffer[100];
register int count = 0;
while (fgets(buffer, 100, mailfile) != NULL)
if (first_word(buffer,"From ")) {
if (real_from(buffer)) {
printf("%s%s", count ? separator : "", buffer);
count++;
}
}
else
printf("%s", buffer);
return(count);
}
int
real_from(buffer)
char *buffer;
{
/***** returns true iff 's' has the seven 'from' fields *****/
char junk[80];
junk[0] = '\0';
sscanf(buffer, "%*s %*s %*s %*s %*s %*s %s", junk);
return(junk[0] != '\0');
}
END-OF-FILE
size=`wc -c < utils/printmail.c`
if [ $size != 1937 ]
then
echo Warning: utils/printmail.c changed - should be 1937 bytes, not $size bytes
fi
chmod 644 utils/printmail.c
# ---------- file utils/readmsg.c ----------
if [ -f utils/readmsg.c ]
then
echo File 'utils/readmsg.c' already exists\!
exit 1
fi
echo extracting file utils/readmsg.c...
cat << 'END-OF-FILE' > utils/readmsg.c
/** readmsg.c **/
/** This is a quick and dirty way to read the specified message (or
messages) from the incoming mailbox. This does no parsing of the
header fields other than to simply find where each message starts,
and has no options other than to 'q' or '<return>' at then end of
each page of the message.
(C) Copyright 1985, Dave Taylor
**/
#include <stdio.h>
#define mailhome "/usr/mail"
#define SLEN 100
#define MAX_LIST 25
main(argc, argv)
int argc;
char *argv[];
{
FILE *file;
int read_message[MAX_LIST], filename[SLEN], buffer[SLEN];
int messages = 1, current_in_queue = 0, current = 0, num, total;
if (argc > MAX_LIST) {
printf("Can't have more than %d messages specified!\n", MAX_LIST);
exit(1);
}
*argv++;
if (argc == 1)
read_message[0] = 0;
else
while (--argc > 0) {
num = -1;
sscanf(*argv,"%d", &num);
if (num < 0) {
if (strcmp(*argv,"$") == 0)
num = 0;
else {
printf("Can't figure out what '%s' means!\n", *argv);
exit(1);
}
}
*argv++;
read_message[messages++] = num;
}
sprintf(filename, "%s/%s", mailhome, getenv("LOGNAME"));
if ((file = fopen(filename, "r")) == NULL) {
printf("You have no mail!\n");
exit(0);
}
else {
/** one pass to get how many messages there are... **/
total = count_messages(file);
if (total == 0) {
printf("There aren't any messages to read!\n");
exit(0);
}
/** now let's have some fun! **/
while (fgets(buffer, SLEN, file) != NULL) {
if (strncmp(buffer, "From ", 5) == 0) {
if (current == read_message[current_in_queue])
current_in_queue++;
if (current_in_queue >= messages) exit(0);
current++;
}
if (current == read_message[current_in_queue])
printf("%s", buffer);
else if (current == total && read_message[current_in_queue] == 0)
printf("%s", buffer);
}
}
exit(0);
}
int
count_messages(file)
FILE *file;
{
/** returns the number of messages in the file, and rewinds
the file too! **/
char buffer[SLEN];
int count = 0;
while (fgets(buffer, SLEN, file) != NULL)
if (strncmp(buffer, "From ", 5) == 0)
count++;
rewind(file);
return( count );
}
END-OF-FILE
size=`wc -c < utils/readmsg.c`
if [ $size != 2263 ]
then
echo Warning: utils/readmsg.c changed - should be 2263 bytes, not $size bytes
fi
chmod 644 utils/readmsg.c
# ---------- file utils/Makefile ----------
if [ -f utils/Makefile ]
then
echo File 'utils/Makefile' already exists\!
exit 1
fi
echo extracting file utils/Makefile...
cat << 'END-OF-FILE' > utils/Makefile
#
# Makefile for the MSG system utilities
#
# (C) Copyright 1986, Dave Taylor
#
# Last modification: January 10th, 1986
CFLAGS= -O -I../hdrs
CC= /bin/cc
RM= /bin/rm
ECHO= /bin/echo
all: newalias from newmail answer printmail fastmail readmsg cutfile \
checkalias arepdaemon autoreply
../bin/newalias: ../hdrs/defs.h newalias.c ../src/validname.o
${CC} ${CFLAGS} newalias.c ../src/validname.o -o ../bin/newalias
../src/validname.o: ../src/validname.c
${CC} -c ${CFLAGS} ../src/validnames.c -o ../src/validnames.o
../bin/from: from.c
${CC} ${CFLAGS} from.c -o ../bin/from
../bin/cutfile: cutfile.c
${CC} ${CFLAGS} cutfile.c -o ../bin/cutfile
../bin/newmail: newmail.c
${CC} ${CFLAGS} newmail.c -o ../bin/newmail
../bin/answer: answer.c
${CC} ${CFLAGS} answer.c -o ../bin/answer
../bin/printmail: printmail.c
${CC} ${CFLAGS} printmail.c -o ../bin/printmail
../bin/fastmail: fastmail.c
${CC} ${CFLAGS} fastmail.c -o ../bin/fastmail
../bin/readmsg: readmsg.c
${CC} ${CFLAGS} readmsg.c -o ../bin/readmsg
../bin/arepdaemon: arepdaemon.c
${CC} ${CFLAGS} arepdaemon.c -o ../bin/arepdaemon
../bin/autoreply: autoreply.c
${CC} ${CFLAGS} autoreply.c -o ../bin/autoreply
../bin/checkalias:
@echo 'msg -c $*' > ../bin/checkalias
@chmod +x ../bin/checkalias
clean:
${RM} *.o
lint:
lint -p -I../hdrs *.c > LINT.OUT
## crap to allow "make msg" and so on...
newalias: ../bin/newalias
from: ../bin/from
newmail: ../bin/newmail
answer: ../bin/answer
printmail: ../bin/printmail
fastmail: ../bin/fastmail
readmsg: ../bin/readmsg
cutfile: ../bin/cutfile
checkalias: ../bin/checkalias
arepdaemon: ../bin/arepdaemon
autoreply: ../bin/autoreply
END-OF-FILE
size=`wc -c < utils/Makefile`
if [ $size != 1669 ]
then
echo Warning: utils/Makefile changed - should be 1669 bytes, not $size bytes
fi
chmod 644 utils/Makefile
if [ ! -d test ]
then
echo creating directory test
mkdir test
fi
# ---------- file test/test.mail ----------
if [ -f test/test.mail ]
then
echo File 'test/test.mail' already exists\!
exit 1
fi
echo extracting file test/test.mail...
sed 's/^X//' << 'END-OF-FILE' > 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 at HP-VENUS>
XTo: hpcnou!dat
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
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 at HP-VENUS>
XTo: hpcnof!dat
XSubject: Re: Summary of Network Mail Headers
XReferences: <36700044 at 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 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: root
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
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 at Xerox.ARPA Sun Dec 8 20:45:55 1985 remote from hplabs
XReceived: from Xerox.ARPA by hplabsd ; Sun, 8 Dec 85 20:45:55 pst
XReceived: from Cabernet.ms by ArpaGateway.ms ; 08 DEC 85 20:47:19 PST
XDate: 8 Dec 85 20:36:36 PST (Sunday)
XFrom: hplabs!JLarson.pa at Xerox.ARPA
XSubject: How's it going, anyway?
XTo: hpcnou!dat at HPLABS.ARPA (Dave Taylor)
XCc: JLarson.pa at Xerox.ARPA
XMessage-Id: <851208-204719-1063 at Xerox>
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 at 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 at 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 at CSNET-RELAY
XVia: CSNet; 7 Aug 85 9:11-PDT
XSubject: Re: AI in Education mailing list...
XCc: RICHER at SUMEX-AIM
XIn-Reply-To: <8508030243.AA27641 at HP-VENUS>
XMessage-Id: <12132987812.61.RICHER at 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 at 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 at 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 at 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 at 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 at CSNET-RELAY>
XVia: CSNet; 21 Oct 85 1:56-PDT
XSubject: Re: More Mail Headers...
XMessage-Id: <MDC-DLS-7W9CS at 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-FILE
size=`wc -c < test/test.mail`
if [ $size != 10005 ]
then
echo Warning: test/test.mail changed - should be 10005 bytes, not $size bytes
fi
chmod 644 test/test.mail
# ---------- file test/test.notes ----------
if [ -f test/test.notes ]
then
echo File 'test/test.notes' already exists\!
exit 1
fi
echo extracting file test/test.notes...
cat << 'END-OF-FILE' > test/test.notes
/***** hpfloat:net.micro.68K / barrett / 2:39 pm Dec 16, 1985*/
Does anyone here at this site know anything about hang-gliding?
I am thinking of learning to hang-glide, but am afraid of heights. I
do fly light planes and love the hairiest roller coaster rides available
however. My main question is "is there a way to learn to hang-glide
gradually?" I have seen some films of people learning on big sand dunes
an such before leaping off of cliffs with the things.
Dave Barrett
hpfcla!barrett
/* ---------- */
/***** hpcnof:fsd.rec / hpfcla!ajs / 5:57 pm Dec 16, 1985*/
> Does anyone here at this site know anything about hang-gliding?
Yeah. Don't waste your time, don't waste your money, don't risk your life.
> I am thinking of learning to hang-glide, but am afraid of heights.
I wasn't, but it still got me a broken arm.
> My main question is "is there a way to learn to hang-glide gradually?"
Probably not (yet). Five years ago, simulators were in practice non-
existent. We got twenty seconds hanging in a triangular control bar
with a person pushing. Next stop, rocky slopes, real gliders, and cheap
walkie-talkies.
You'd be amazed how easy it is to injure yourself. It's the nature of
the hobby. People with plenty of experience die doing it every day,
due to circumstances often beyond their control. There are better ways
to get thrills.
Alan
/* ---------- */
/***** hpcnof:fsd.rec / hpfcms!mpm / 8:58 pm Dec 16, 1985*/
>You'd be amazed how easy it is to injure yourself. It's the nature of
>the hobby. People with plenty of experience die doing it every day,
>due to circumstances often beyond their control. There are better ways
>to get thrills.
>Alan
I haven't done any hang-gliding myself, but I would like to try it
some day. (I have a moderate fear of heights; it depends on the altitude
and the apparent stability of my "perch".)
I read (or heard) that MOST hang-gliding accidents fall into two
categories:
1) novices attempt something beyond their experience (like jumping
off a tall building after one lesson on a gently sloped hill),
2) experts attempt VERY dramatic stuff (like jumping off El
Capitan in unpredictable thermal up- and down- drafts).
Please note: Alan Silverstein doesn't fall in EITHER category. I
took some sport parachuting lessons a few years ago. It turned out to be
quite safe GIVEN ADEQUATE TRAINING as I had at the time. I suspect the
same would hold true for hang-gliding (or rapelling, or ice climbing, or
...). The best way to find out if you can overcome your fears is by con-
fronting them in a safe and supportive environment.
My recommendation: check out any "school" before you sign up. Ask
about their safety record, the terrain where they offer lessons, amount of
"ground school" training before first "flight", etc. Above all, make sure
that you TRUST any prospective teacher. Even if you have no logical reason
to distrust someone, don't try something like this unless you trust them.
(This is where your rational mind needs to work with your intuition.)
Otherwise you could easily get hurt.
This is likely to be unknown territory for you, so be prepared and
you will likely have a more enjoyable (and safe) experience. Of course,
there is ALWAYS the chance for an accident.
-- Mike "no I wasn't crazy at the time; I WANTED to do it" McCarthy
hpfcla!mpm
/* ---------- */
/***** hpcnof:fsd.rec / dat / 12:12 pm Dec 19, 1985*/
>> Does anyone here at this site know anything about hang-gliding?
>Yeah. Don't waste your time, don't waste your money, don't risk your life.
Strong stuff! I think you're out on a limb this time, Alan.
I've known lots of people who've hang-glided and never gotten hurt.
(and we're talking the La Jolla cliffs in San Diego!!) (they also
think it's the best 'high' in the world (and they've tried some
pretty strange things to compare!))
>> I am thinking of learning to hang-glide, but am afraid of heights.
>I wasn't, but it still got me a broken arm.
Fine. So I broke my arm a long time ago jumping off a bunk
bed. Does this mean that bunk beds are too dangerous and that I
shouldn't ever sleep in one???
The point is that anything you do is dangerous and that the
way to minimize the danger is to take things gradually and only
progress when you feel comfortable with your current level of learning.
At the same time realize that even sitting in a chair in a warm room
could be dangerous, so don't be so foolishly optimistic to think that
you cannot get seriously hurt hang-gliding.
On the other hand - if you want to go for it - GO FOR IT!!!
-- Dave "Cheap Thrills, Inc." Taylor
/* ---------- */
/***** hpcnof:fsd.rec / hpfcmp!rjn / 11:33 pm Dec 16, 1985*/
re: hang gliding
I am a licensed [so what] pilot in powered aircraft and sailplanes. I was
taking hang gliding (HG) instruction four years ago (prior to moving to
Colorado). I gave it up when I moved here. My impressions:
* If your introduction to piloting flying machines is via HG, you will not
have enough understanding of aerodynamics to safely operate your craft in
calm or steady-wind conditions.
* HGs which are controlled by weight shifting do not have adequate control
authority for normal conditions, unless you have lots of the
aforementioned understanding and fly only in ideal conditions. HGs with
3-axis control offer a little more margin.
* HGs are typically operated close to the ground. No HG designs have enough
control authority to handle gusty conditions. You can safely land a
parachute in conditions which are dangerous for HG operation. Flying in
gusty conditions is the most popular way to crash a HG. If you think
jumping is dangerous, don't take up HG. (I used to room with a jumpmaster
and have made one jump myself. I think jumping is safer.)
* HGs operated at higher altitudes (away from ground reference) suffer from
lack of instrumentation. It is easy to enter a spiral dive, spin or deep
stall (luff the sail on Rogallo machines) without instruments or lots of
experience. Spiral dives usually overstress the airframe; the resulting
collection of parts crashes.
If you insist on K-Mart aviating, I suggest a 2-place ultra-light (with
parachute), a good instructor and a calm day. At least the ground is level.
Bring earplugs.
Bob Niland TN-226-4014 HP-UX: hpfcla!rjn DESK: rjn (hpfcla) /HP4000/UX
/* ---------- */
/***** hpcnof:fsd.rec / hpfloat!jim / 9:10 am Dec 17, 1985*/
Try flying across the waves on a windsurfer! I once met a guy from
Denver who said he had tried them all--hang gliding, sky diving. Windsurfing
offered just as much thrill with almost no risk.
The crash landings are rather painless. I've gotten 5 feet of air right
here in Colorado.
"Jumping Jim" Tear
/* ---------- */
/***** hpcnof:fsd.rec / hpfcmt!ron / 7:56 am Dec 17, 1985*/
I also am a "regular" aircraft (and sailplane) pilot.
I have not tried hang gliding however I have a fairly close friend who
was into it before he totally demolished his craft. He was only bruised
by the impact but came away considerably more careful about his sports.
Besides the previously mentioned drawbacks I would like to mention the
following:
A perfect landing consists of
(a) Correct airspeed
(b) Level wings ( tolerance to prevent wingtip dragging)
(c) Correct yaw alignment (within tolerance of landing gear)
(d) Correct pitch
(e) Correct rate of descent (within tolerance of landing gear)
(f) Correct altitude
(g) Correct groundspeed (within tolerance of landing gear)
Consider that the landing gear on an HG is your legs and gear collapse
is fairly common due to the low maximum speed for the gear and the
airspeed being right in that range at touchdown.
Consider also that even calm air has some "breezes" going.
Add to the "breezes" the fact that your control authority relative to the
velocity of the breezes is poor and you can wind up with all the ingredients
for a face plant.
Now to moderate the above, the idea of simple flight appeals greatly to
me. Unfortunately my personal risk-taking threshold is below the minimum
risk for this sport.
I agree with Bob, try ultra-lights if you MUST . At least they have wheels.
Ron Miller
"Show me a country where the newspapers are filled with good news
and I'll show you a country where the jails are filled with good people."
-<I forgot>
Service Engineering (Hardware Support)
Hewlett-Packard Co.
Ft. Collins Systems Div. Home of the HP 9000 Series 200,300 & 500
Ft. Collins Colorado
303-226-3800
at: {ihnp4}hpfcla!ron
/* ---------- */
/***** hpcnof:fsd.rec / hpfcla!ajs / 6:36 pm Dec 19, 1985*/
> Strong stuff! I think you're out on a limb this time, Alan.
> I've known lots of people who've hang-glided and never gotten hurt.
Yes, but, --
> Fine. So I broke my arm a long time ago jumping off a bunk
> bed. Does this mean that bunk beds are too dangerous and that I
> shouldn't ever sleep in one???
I'll be more explicit (and just as strong). Let's say sleeping is a
zero (epsilon?) on the risk scale, and flying in a commercial aircraft
is 1, and driving a car, oh, I'd guess about a 4, and parachuting maybe
a 6, and SCUBA diving must be maybe a 7 or 8 then, comparable (?) with
climbing Fourteeners. Based on my experience with it, I'd rank hang
gliding at around a 12 or 15. Don't risk your life.
One thing I discovered is that being under a "kite" feels very different
from how you might guess while watching someone fly. Not nearly as
comfortable (until airborne); very exposed. Some people are naturals at
it; some (like me) are not. If you are the former, and you are lucky,
and it appeals to you, you'll go do it anyway, no matter what I or Dave
say about it; good luck to you.
But, if you are the latter, you'll likely injure yourself seriously
trying to learn, because there isn't much margin for error outside a
simulator. Look, I was gung-ho, being trained by a "professional"
training school, determined to overcome inexperience, ignored warnings
from concerned friends, was certain I could do it safely, paid close
attention to instructions, studied the subject intensely, and when I
crashed, I'd been in the air about five seconds, was about ten feet off
the ground, and was amazed that I'd actually broken anything. A very
sobering experience.
On the way to the hospital, the trainer doing the driving informed me
that someone was seriously injured in their classes about once a month.
Gee, Dave, I guess I must be "out on a limb", incapable of giving advice
on the subject, because I survived the crash. :-)
Alan
/* ---------- */
/***** hpcnof:fsd.rec / hpfcde!anny / 2:28 pm Dec 31, 1985*/
WARNING: Severe Base Note D r i f t
<. . . and driving a car, oh, I'd guess about a 4, and parachuting maybe
<a 6, and SCUBA diving must be maybe a 7 or 8 then, . . .
Come on Alan! SCUBA diving more dangerous than parachuting? Maybe if your
parachuting off a jump tower versus SCUBA diving alone on the Great Barrier
Reef at night carring shark bait making wounded fish sounds. . . ;-)
After all, the FIRST time you parachute, you have to jump out of a PLANE! (/.\)
In the SKY! You can SCUBA dive in a pool or a shallow lake or inlet.
If something goes wrong in the water, your buddy's there to help. If
something goes wrong in the sky, so long . . .
Just defending what I consider to be a fun and safe sport!
Anny (low altitude (4' or less) sports for me!) Randel
/* ---------- */
/***** hpcnof:fsd.rec / hpfcla!ajs / 9:27 am Jan 2, 1986*/
> Come on Alan! SCUBA diving more dangerous than parachuting?
Forgive me, I was just guessing, to make a point. I don't know the
actual statistics, but you're probably right -- if you measure accidents
per hour. On the other hand, if you measure accidents per jump or dive,
it wouldn't surprise me if the rates were similar. Lotsa people go
diving without enough training, but skydiving requires decent training
and the accident rate is surprisingly low.
Alan "pick your poison" Silverstein
/* ---------- */
/***** hpcnof:fsd.rec / hpfcdc!donn / 9:32 am Jan 3, 1986*/
The problem with SCUBA diving is the fact that "fly by nites" can
afford to get into the business. A reputable dive shop will not
let you rent a tank unless you have a NAUI card (or ==) (and they'll hold
it while you have the tanks). However there are always some who
will not do this, and some clown tries diving without essentially
any training ("Gee, I can swim, so I can dive.") and gets into
trouble. It's much tougher to be a "fly by night" (or anytime)
when you need an airplane and a pilot's license. Actually, the
accident rate for people with any significant training *and* who
are doing something more-or-less reasonable is not bad. (Diving
below 150ft (or maybe less) is like starting a jump at 50000 feet:
it might work, but good luck unless you know what you're doing.
The problem is that there isn't much reason to start at 50000 feet,
but there's a lot of interesting and valuable stuff below 150.)
I like to dive (tropical saltwater only, so I don't do it much),
and since one of the graduation exercises is diving while someone
is *trying* to make you screw up (albeit in a pool where there's
someone to fish you out), you learn to handle problems. If you're
gutsy, try the NAUI *instructors* class: the graduation from that
is a open-water dive with known defective equipment!
Donn
/* ---------- */
END-OF-FILE
size=`wc -c < test/test.notes`
if [ $size != 13582 ]
then
echo Warning: test/test.notes changed - should be 13582 bytes, not $size bytes
fi
chmod 644 test/test.notes
echo done
exit 0
More information about the Mod.sources
mailing list