home *** CD-ROM | disk | FTP | other *** search
- Subject: v09i013: ELM Mail System, Part13/19
- Newsgroups: mod.sources
- Approved: rs@mirror.TMC.COM
-
- Submitted by: Dave Taylor <hplabs!taylor>
- Mod.sources: Volume 9, Issue 13
- Archive-name: elm2/Part13
-
- #! /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 13 (of 19)."
- # Contents: test/test.notes utils/arepdaemon.c utils/newalias.c
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo shar: Extracting \"test/test.notes\" \(13582 characters\)
- if test -f test/test.notes ; then
- echo shar: Will not over-write existing file \"test/test.notes\"
- else
- sed "s/^X//" >test/test.notes <<'END_OF_test/test.notes'
- X/***** hpfloat:net.micro.68K / barrett / 2:39 pm Dec 16, 1985*/
- XDoes anyone here at this site know anything about hang-gliding?
- X
- XI am thinking of learning to hang-glide, but am afraid of heights. I
- Xdo fly light planes and love the hairiest roller coaster rides available
- Xhowever. My main question is "is there a way to learn to hang-glide
- Xgradually?" I have seen some films of people learning on big sand dunes
- Xan such before leaping off of cliffs with the things.
- X
- XDave Barrett
- Xhpfcla!barrett
- X/* ---------- */
- X/***** hpcnof:fsd.rec / hpfcla!ajs / 5:57 pm Dec 16, 1985*/
- X> Does anyone here at this site know anything about hang-gliding?
- X
- XYeah. Don't waste your time, don't waste your money, don't risk your life.
- X
- X> I am thinking of learning to hang-glide, but am afraid of heights.
- X
- XI wasn't, but it still got me a broken arm.
- X
- X> My main question is "is there a way to learn to hang-glide gradually?"
- X
- XProbably not (yet). Five years ago, simulators were in practice non-
- Xexistent. We got twenty seconds hanging in a triangular control bar
- Xwith a person pushing. Next stop, rocky slopes, real gliders, and cheap
- Xwalkie-talkies.
- X
- XYou'd be amazed how easy it is to injure yourself. It's the nature of
- Xthe hobby. People with plenty of experience die doing it every day,
- Xdue to circumstances often beyond their control. There are better ways
- Xto get thrills.
- X
- XAlan
- X/* ---------- */
- X/***** hpcnof:fsd.rec / hpfcms!mpm / 8:58 pm Dec 16, 1985*/
- X
- X>You'd be amazed how easy it is to injure yourself. It's the nature of
- X>the hobby. People with plenty of experience die doing it every day,
- X>due to circumstances often beyond their control. There are better ways
- X>to get thrills.
- X>Alan
- X
- X I haven't done any hang-gliding myself, but I would like to try it
- Xsome day. (I have a moderate fear of heights; it depends on the altitude
- Xand the apparent stability of my "perch".)
- X
- X I read (or heard) that MOST hang-gliding accidents fall into two
- Xcategories:
- X
- X 1) novices attempt something beyond their experience (like jumping
- X off a tall building after one lesson on a gently sloped hill),
- X
- X 2) experts attempt VERY dramatic stuff (like jumping off El
- X Capitan in unpredictable thermal up- and down- drafts).
- X
- X Please note: Alan Silverstein doesn't fall in EITHER category. I
- Xtook some sport parachuting lessons a few years ago. It turned out to be
- Xquite safe GIVEN ADEQUATE TRAINING as I had at the time. I suspect the
- Xsame would hold true for hang-gliding (or rapelling, or ice climbing, or
- X...). The best way to find out if you can overcome your fears is by con-
- Xfronting them in a safe and supportive environment.
- X
- X My recommendation: check out any "school" before you sign up. Ask
- Xabout their safety record, the terrain where they offer lessons, amount of
- X"ground school" training before first "flight", etc. Above all, make sure
- Xthat you TRUST any prospective teacher. Even if you have no logical reason
- Xto distrust someone, don't try something like this unless you trust them.
- X(This is where your rational mind needs to work with your intuition.)
- XOtherwise you could easily get hurt.
- X
- X This is likely to be unknown territory for you, so be prepared and
- Xyou will likely have a more enjoyable (and safe) experience. Of course,
- Xthere is ALWAYS the chance for an accident.
- X
- X -- Mike "no I wasn't crazy at the time; I WANTED to do it" McCarthy
- X hpfcla!mpm
- X/* ---------- */
- X/***** hpcnof:fsd.rec / dat / 12:12 pm Dec 19, 1985*/
- X>> Does anyone here at this site know anything about hang-gliding?
- X>Yeah. Don't waste your time, don't waste your money, don't risk your life.
- X
- X Strong stuff! I think you're out on a limb this time, Alan.
- XI've known lots of people who've hang-glided and never gotten hurt.
- X(and we're talking the La Jolla cliffs in San Diego!!) (they also
- Xthink it's the best 'high' in the world (and they've tried some
- Xpretty strange things to compare!))
- X
- X>> I am thinking of learning to hang-glide, but am afraid of heights.
- X>I wasn't, but it still got me a broken arm.
- X
- X Fine. So I broke my arm a long time ago jumping off a bunk
- Xbed. Does this mean that bunk beds are too dangerous and that I
- Xshouldn't ever sleep in one???
- X
- X The point is that anything you do is dangerous and that the
- Xway to minimize the danger is to take things gradually and only
- Xprogress when you feel comfortable with your current level of learning.
- XAt the same time realize that even sitting in a chair in a warm room
- Xcould be dangerous, so don't be so foolishly optimistic to think that
- Xyou cannot get seriously hurt hang-gliding.
- X
- X On the other hand - if you want to go for it - GO FOR IT!!!
- X
- X -- Dave "Cheap Thrills, Inc." Taylor
- X/* ---------- */
- X/***** hpcnof:fsd.rec / hpfcmp!rjn / 11:33 pm Dec 16, 1985*/
- Xre: hang gliding
- X
- XI am a licensed [so what] pilot in powered aircraft and sailplanes. I was
- Xtaking hang gliding (HG) instruction four years ago (prior to moving to
- XColorado). I gave it up when I moved here. My impressions:
- X
- X* If your introduction to piloting flying machines is via HG, you will not
- X have enough understanding of aerodynamics to safely operate your craft in
- X calm or steady-wind conditions.
- X
- X* HGs which are controlled by weight shifting do not have adequate control
- X authority for normal conditions, unless you have lots of the
- X aforementioned understanding and fly only in ideal conditions. HGs with
- X 3-axis control offer a little more margin.
- X
- X* HGs are typically operated close to the ground. No HG designs have enough
- X control authority to handle gusty conditions. You can safely land a
- X parachute in conditions which are dangerous for HG operation. Flying in
- X gusty conditions is the most popular way to crash a HG. If you think
- X jumping is dangerous, don't take up HG. (I used to room with a jumpmaster
- X and have made one jump myself. I think jumping is safer.)
- X
- X* HGs operated at higher altitudes (away from ground reference) suffer from
- X lack of instrumentation. It is easy to enter a spiral dive, spin or deep
- X stall (luff the sail on Rogallo machines) without instruments or lots of
- X experience. Spiral dives usually overstress the airframe; the resulting
- X collection of parts crashes.
- X
- XIf you insist on K-Mart aviating, I suggest a 2-place ultra-light (with
- Xparachute), a good instructor and a calm day. At least the ground is level.
- XBring earplugs.
- X
- XBob Niland TN-226-4014 HP-UX: hpfcla!rjn DESK: rjn (hpfcla) /HP4000/UX
- X/* ---------- */
- X/***** hpcnof:fsd.rec / hpfloat!jim / 9:10 am Dec 17, 1985*/
- XTry flying across the waves on a windsurfer! I once met a guy from
- XDenver who said he had tried them all--hang gliding, sky diving. Windsurfing
- Xoffered just as much thrill with almost no risk.
- X
- XThe crash landings are rather painless. I've gotten 5 feet of air right
- Xhere in Colorado.
- X
- X "Jumping Jim" Tear
- X
- X/* ---------- */
- X/***** hpcnof:fsd.rec / hpfcmt!ron / 7:56 am Dec 17, 1985*/
- X
- X
- XI also am a "regular" aircraft (and sailplane) pilot.
- X
- XI have not tried hang gliding however I have a fairly close friend who
- Xwas into it before he totally demolished his craft. He was only bruised
- Xby the impact but came away considerably more careful about his sports.
- X
- XBesides the previously mentioned drawbacks I would like to mention the
- Xfollowing:
- X
- XA perfect landing consists of
- X
- X (a) Correct airspeed
- X (b) Level wings ( tolerance to prevent wingtip dragging)
- X (c) Correct yaw alignment (within tolerance of landing gear)
- X (d) Correct pitch
- X (e) Correct rate of descent (within tolerance of landing gear)
- X (f) Correct altitude
- X (g) Correct groundspeed (within tolerance of landing gear)
- X
- XConsider that the landing gear on an HG is your legs and gear collapse
- Xis fairly common due to the low maximum speed for the gear and the
- Xairspeed being right in that range at touchdown.
- XConsider also that even calm air has some "breezes" going.
- XAdd to the "breezes" the fact that your control authority relative to the
- Xvelocity of the breezes is poor and you can wind up with all the ingredients
- Xfor a face plant.
- X
- XNow to moderate the above, the idea of simple flight appeals greatly to
- Xme. Unfortunately my personal risk-taking threshold is below the minimum
- Xrisk for this sport.
- XI agree with Bob, try ultra-lights if you MUST . At least they have wheels.
- X
- X
- XRon Miller
- X
- X
- X"Show me a country where the newspapers are filled with good news
- Xand I'll show you a country where the jails are filled with good people."
- X -<I forgot>
- X
- XService Engineering (Hardware Support)
- XHewlett-Packard Co.
- XFt. Collins Systems Div. Home of the HP 9000 Series 200,300 & 500
- XFt. Collins Colorado
- X303-226-3800
- X
- Xat: {ihnp4}hpfcla!ron
- X/* ---------- */
- X/***** hpcnof:fsd.rec / hpfcla!ajs / 6:36 pm Dec 19, 1985*/
- X> Strong stuff! I think you're out on a limb this time, Alan.
- X> I've known lots of people who've hang-glided and never gotten hurt.
- X
- XYes, but, --
- X
- X> Fine. So I broke my arm a long time ago jumping off a bunk
- X> bed. Does this mean that bunk beds are too dangerous and that I
- X> shouldn't ever sleep in one???
- X
- XI'll be more explicit (and just as strong). Let's say sleeping is a
- Xzero (epsilon?) on the risk scale, and flying in a commercial aircraft
- Xis 1, and driving a car, oh, I'd guess about a 4, and parachuting maybe
- Xa 6, and SCUBA diving must be maybe a 7 or 8 then, comparable (?) with
- Xclimbing Fourteeners. Based on my experience with it, I'd rank hang
- Xgliding at around a 12 or 15. Don't risk your life.
- X
- XOne thing I discovered is that being under a "kite" feels very different
- Xfrom how you might guess while watching someone fly. Not nearly as
- Xcomfortable (until airborne); very exposed. Some people are naturals at
- Xit; some (like me) are not. If you are the former, and you are lucky,
- Xand it appeals to you, you'll go do it anyway, no matter what I or Dave
- Xsay about it; good luck to you.
- X
- XBut, if you are the latter, you'll likely injure yourself seriously
- Xtrying to learn, because there isn't much margin for error outside a
- Xsimulator. Look, I was gung-ho, being trained by a "professional"
- Xtraining school, determined to overcome inexperience, ignored warnings
- Xfrom concerned friends, was certain I could do it safely, paid close
- Xattention to instructions, studied the subject intensely, and when I
- Xcrashed, I'd been in the air about five seconds, was about ten feet off
- Xthe ground, and was amazed that I'd actually broken anything. A very
- Xsobering experience.
- X
- XOn the way to the hospital, the trainer doing the driving informed me
- Xthat someone was seriously injured in their classes about once a month.
- X
- XGee, Dave, I guess I must be "out on a limb", incapable of giving advice
- Xon the subject, because I survived the crash. :-)
- X
- XAlan
- X/* ---------- */
- X/***** hpcnof:fsd.rec / hpfcde!anny / 2:28 pm Dec 31, 1985*/
- XWARNING: Severe Base Note D r i f t
- X
- X<. . . and driving a car, oh, I'd guess about a 4, and parachuting maybe
- X<a 6, and SCUBA diving must be maybe a 7 or 8 then, . . .
- X
- XCome on Alan! SCUBA diving more dangerous than parachuting? Maybe if your
- Xparachuting off a jump tower versus SCUBA diving alone on the Great Barrier
- XReef at night carring shark bait making wounded fish sounds. . . ;-)
- X
- XAfter all, the FIRST time you parachute, you have to jump out of a PLANE! (/.\)
- XIn the SKY! You can SCUBA dive in a pool or a shallow lake or inlet.
- XIf something goes wrong in the water, your buddy's there to help. If
- Xsomething goes wrong in the sky, so long . . .
- X
- XJust defending what I consider to be a fun and safe sport!
- X
- XAnny (low altitude (4' or less) sports for me!) Randel
- X/* ---------- */
- X/***** hpcnof:fsd.rec / hpfcla!ajs / 9:27 am Jan 2, 1986*/
- X> Come on Alan! SCUBA diving more dangerous than parachuting?
- X
- XForgive me, I was just guessing, to make a point. I don't know the
- Xactual statistics, but you're probably right -- if you measure accidents
- Xper hour. On the other hand, if you measure accidents per jump or dive,
- Xit wouldn't surprise me if the rates were similar. Lotsa people go
- Xdiving without enough training, but skydiving requires decent training
- Xand the accident rate is surprisingly low.
- X
- XAlan "pick your poison" Silverstein
- X/* ---------- */
- X/***** hpcnof:fsd.rec / hpfcdc!donn / 9:32 am Jan 3, 1986*/
- XThe problem with SCUBA diving is the fact that "fly by nites" can
- Xafford to get into the business. A reputable dive shop will not
- Xlet you rent a tank unless you have a NAUI card (or ==) (and they'll hold
- Xit while you have the tanks). However there are always some who
- Xwill not do this, and some clown tries diving without essentially
- Xany training ("Gee, I can swim, so I can dive.") and gets into
- Xtrouble. It's much tougher to be a "fly by night" (or anytime)
- Xwhen you need an airplane and a pilot's license. Actually, the
- Xaccident rate for people with any significant training *and* who
- Xare doing something more-or-less reasonable is not bad. (Diving
- Xbelow 150ft (or maybe less) is like starting a jump at 50000 feet:
- Xit might work, but good luck unless you know what you're doing.
- XThe problem is that there isn't much reason to start at 50000 feet,
- Xbut there's a lot of interesting and valuable stuff below 150.)
- X
- XI like to dive (tropical saltwater only, so I don't do it much),
- Xand since one of the graduation exercises is diving while someone
- Xis *trying* to make you screw up (albeit in a pool where there's
- Xsomeone to fish you out), you learn to handle problems. If you're
- Xgutsy, try the NAUI *instructors* class: the graduation from that
- Xis a open-water dive with known defective equipment!
- X
- XDonn
- X/* ---------- */
- END_OF_test/test.notes
- if test 13582 -ne `wc -c <test/test.notes`; then
- echo shar: \"test/test.notes\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"utils/arepdaemon.c\" \(13412 characters\)
- if test -f utils/arepdaemon.c ; then
- echo shar: Will not over-write existing file \"utils/arepdaemon.c\"
- else
- sed "s/^X//" >utils/arepdaemon.c <<'END_OF_utils/arepdaemon.c'
- X/** arepdaemon.c **/
- X
- X/** (C) Copyright 1986 Dave Taylor **/
- X
- X/** Keep track of mail as it arrives, and respond by sending a 'recording'
- X file to the sender as new mail is received.
- X
- X Note: the user program that interacts with this program is the
- X 'autoreply' program and that should be consulted for further
- X usage information.
- X
- X This program is part of the 'autoreply' system, and is designed
- X to run every hour and check all mailboxes listed in the file
- X "/etc/autoreply.data", where the data is in the form:
- X
- X username replyfile current-mailfile-size
- X
- X To avoid a flood of autoreplies, this program will NOT reply to mail
- X that contains header "X-Mailer: fastmail". Further, each time the
- X program responds to mail, the 'mailfile size' entry is updated in
- X the file /etc/autoreply.data to allow the system to be brought
- X down and rebooted without any loss of data or duplicate messages.
- X
- X This daemon also uses a lock semaphore file, /usr/spool/uucp/LCK..arep,
- X to ensure that more than one copy of itself is never running. For this
- X reason, it is recommended that this daemon be started up each morning
- X from cron, since it will either start since it's needed or simply see
- X that the file is there and disappear.
- X
- X Since this particular program is the main daemon answering any
- X number of different users, it must be run with uid root.
- X
- X (C) 1985, Dave Taylor, HP Colorado Networks Operation
- X**/
- X
- X#include <stdio.h>
- X
- X#ifdef BSD
- X# include <sys/time.h>
- X#else
- X# include <time.h>
- X#endif
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X
- X#include "defs.h"
- X
- Xstatic char ident[] = { WHAT_STRING };
- X
- X#define arep_lock_file "/usr/spool/uucp/LCK..arep"
- X
- X#define autoreply_file "/etc/autoreply.data"
- X#define fastmail "/usr/local/bin/fastmail"
- X
- X#define logfile "/etc/autoreply.log" /* first choice */
- X#define logfile2 "/tmp/autoreply.log" /* second choice */
- X
- X#define BEGINNING 0 /* see fseek(3S) for info */
- X#define SLEEP_TIME 3600 /* run once an hour */
- X#define MAX_PEOPLE 20 /* max number in program */
- X
- X#define EXISTS 00 /* lock file exists?? */
- X#define MODE 0777 /* lockfile creation mode */
- X
- X#define remove_return(s) if (strlen(s) > 0) { \
- X if (s[strlen(s)-1] == '\n') \
- X s[strlen(s)-1] = '\0'; \
- X }
- X
- Xstruct replyrec {
- X char username[NLEN]; /* login name of user */
- X char mailfile[SLEN]; /* name of mail file */
- X char replyfile[SLEN]; /* name of reply file */
- X long mailsize; /* mail file size */
- X int in_list; /* for new replies */
- X } reply_table[MAX_PEOPLE];
- X
- XFILE *logfd; /* logfile (log action) */
- Xlong autoreply_size = 0L; /* size of autoreply file */
- Xint active = 0; /* # of people 'enrolled' */
- X
- XFILE *open_logfile(); /* forward declaration */
- X
- Xlong bytes(); /* ditto */
- X
- Xmain()
- X{
- X long size;
- X int person, data_changed;
- X
- X if (! lock())
- X exit(0); /* already running! */
- X
- X while (1) {
- X
- X logfd = open_logfile(); /* open the log */
- X
- X /* 1. check to see if autoreply table has changed.. */
- X
- X if ((size = bytes(autoreply_file)) != autoreply_size) {
- X read_autoreply_file();
- X autoreply_size = size;
- X }
- X
- X /* 2. now for each active person... */
- X
- X data_changed = 0;
- X
- X for (person = 0; person < active; person++) {
- X if ((size = bytes(reply_table[person].mailfile)) !=
- X reply_table[person].mailsize) {
- X if (size > reply_table[person].mailsize)
- X read_newmail(person);
- X /* else mail removed - resync */
- X reply_table[person].mailsize = size;
- X data_changed++;
- X }
- X }
- X
- X /* 3. if data changed, update autoreply file */
- X
- X if (data_changed)
- X update_autoreply_file();
- X
- X close_logfile(); /* close the logfile again */
- X
- X /* 4. Go to sleep... */
- X
- X sleep(SLEEP_TIME);
- X }
- X}
- X
- Xint
- Xread_autoreply_file()
- X{
- X /** We're here because the autoreply file has changed size!! It
- X could either be because someone has been added or because
- X someone has been removed...since the list will always be in
- X order (nice, eh?) we should have a pretty easy time of it...
- X **/
- X
- X FILE *file;
- X char username[SLEN], replyfile[SLEN];
- X int person;
- X long size;
- X
- X log("Autoreply data file has changed! Reading...");
- X
- X if ((file = fopen(autoreply_file,"r")) == NULL) {
- X log("No-one is using autoreply...");
- X return(0);
- X }
- X
- X for (person = 0; person < active; person++)
- X reply_table[person].in_list = 0;
- X
- X while (fscanf(file, "%s %s %dl", username, replyfile, &size) != EOF) {
- X /* check to see if this person is already in the list */
- X if ((person = in_list(username)) != -1) {
- X reply_table[person].in_list = 1;
- X reply_table[person].mailsize = size; /* sync */
- X }
- X else { /* if not, add them */
- X if (active == MAX_PEOPLE) {
- X unlock();
- X exit(log("Couldn't add %s - already at max people!",
- X username));
- X }
- X log("adding %s to the active list", username);
- X strcpy(reply_table[active].username, username);
- X sprintf(reply_table[active].mailfile, "/usr/mail/%s", username);
- X strcpy(reply_table[active].replyfile, replyfile);
- X reply_table[active].mailsize = size;
- X reply_table[active].in_list = 1; /* obviously! */
- X active++;
- X }
- X }
- X
- X /** now check to see if anyone has been removed... **/
- X
- X for (person = 0; person < active; person++)
- X if (reply_table[person].in_list == 0) {
- X log("removing %s from the active list",
- X reply_table[person].username);
- X strcpy(reply_table[person].username,
- X reply_table[active-1].username);
- X strcpy(reply_table[person].mailfile,
- X reply_table[active-1].mailfile);
- X strcpy(reply_table[person].replyfile,
- X reply_table[active-1].replyfile);
- X reply_table[person].mailsize = reply_table[active-1].mailsize;
- X active--;
- X }
- X}
- X
- Xupdate_autoreply_file()
- X{
- X /** update the entries in the autoreply file... **/
- X
- X FILE *file;
- X register int person;
- X
- X if ((file = fopen(autoreply_file,"w")) == NULL) {
- X log("Couldn't update autoreply file!");
- X return;
- X }
- X
- X for (person = 0; person < active; person++)
- X fprintf(file, "%s %s %ld\n",
- X reply_table[person].username,
- X reply_table[person].replyfile,
- X reply_table[person].mailsize);
- X
- X fclose(file);
- X
- X printf("updated autoreply file\n");
- X autoreply_size = bytes(autoreply_file);
- X}
- X
- Xint
- Xin_list(name)
- Xchar *name;
- X{
- X /** search the current active reply list for the specified username.
- X return the index if found, or '-1' if not. **/
- X
- X register int index;
- X
- X for (index = 0; index < active; index++)
- X if (strcmp(name, reply_table[index].username) == 0)
- X return(index);
- X
- X return(-1);
- X}
- X
- Xread_newmail(person)
- Xint person;
- X{
- X /** Read the new mail for the specified person. **/
- X
- X
- X FILE *mailfile;
- X char from_whom[LONG_SLEN], subject[SLEN];
- X int sendit;
- X
- X log("New mail for %s", reply_table[person].username);
- X
- X if ((mailfile = fopen(reply_table[person].mailfile,"r")) == NULL)
- X return(log("can't open mailfile for user %s",
- X reply_table[person].username));
- X
- X if (fseek(mailfile, reply_table[person].mailsize, BEGINNING) == -1)
- X return(log("couldn't seek to %ld in mail file!",
- X reply_table[person].mailsize));
- X
- X while (get_return(mailfile, person, from_whom, subject, &sendit) != -1)
- X if (sendit)
- X reply_to_mail(person, from_whom, subject);
- X
- X return;
- X}
- X
- Xint
- Xget_return(file, person, from, subject, sendit)
- XFILE *file;
- Xint person, *sendit;
- Xchar *from, *subject;
- X{
- X /** Reads the new message and return the from and subject lines.
- X sendit is set to true iff it isn't a machine generated msg
- X **/
- X
- X char name1[SLEN], name2[SLEN], lastname[SLEN];
- X char buffer[LONG_SLEN], hold_return[NLEN];
- X int done = 0, in_header = 0;
- X
- X from[0] = '\0';
- X *sendit = 1;
- X
- X while (! done) {
- X
- X if (fgets(buffer, LONG_SLEN, file) == NULL)
- X return(-1);
- X
- X if (first_word(buffer, "From ")) {
- X in_header++;
- X sscanf(buffer, "%*s %s", hold_return);
- X }
- X else if (in_header) {
- X if (first_word(buffer, ">From")) {
- X sscanf(buffer,"%*s %s %*s %*s %*s %*s %*s %*s %*s %s", name1, name2);
- X add_site(from, name2, lastname);
- X }
- X else if (first_word(buffer,"Subject:")) {
- X remove_return(buffer);
- X strcpy(subject, (char *) (buffer + 8));
- X }
- X else if (first_word(buffer,"X-Mailer: fastmail"))
- X *sendit = 0;
- X else if (strlen(buffer) == 1)
- X done = 1;
- X }
- X }
- X
- X if (from[0] == '\0')
- X strcpy(from, hold_return); /* default address! */
- X else
- X add_site(from, name1, lastname); /* get the user name too! */
- X
- X return(0);
- X}
- X
- Xadd_site(buffer, site, lastsite)
- Xchar *buffer, *site, *lastsite;
- X{
- X /** add site to buffer, unless site is 'uucp', or the same as
- X lastsite. If not, set lastsite to site.
- X **/
- X
- X char local_buffer[LONG_SLEN], *strip_parens();
- X
- X if (strcmp(site, "uucp") != 0)
- X if (strcmp(site, lastsite) != 0) {
- X if (buffer[0] == '\0')
- X strcpy(buffer, strip_parens(site)); /* first in list! */
- X else {
- X sprintf(local_buffer,"%s!%s", buffer, strip_parens(site));
- X strcpy(buffer, local_buffer);
- X }
- X strcpy(lastsite, strip_parens(site)); /* don't want THIS twice! */
- 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
- Xreply_to_mail(person, from, subject)
- Xint person;
- Xchar *from, *subject;
- X{
- X /** Respond to the message from the specified person with the
- X specified subject... **/
- X
- X char buffer[SLEN];
- X
- X if (strlen(subject) == 0)
- X strcpy(subject, "Auto-reply Mail");
- X else if (! first_word(subject,"Auto-reply")) {
- X sprintf(buffer, "Auto-reply to:%s", subject);
- X strcpy(subject, buffer);
- X }
- X
- X log("auto-replying to '%s'", from);
- X
- X mail(from, subject, reply_table[person].replyfile, person);
- 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
- Xlong
- Xbytes(name)
- Xchar *name;
- X{
- X /** return the number of bytes in the specified file. This
- X is to check to see if new mail has arrived.... **/
- X
- X int ok = 1;
- X extern int errno; /* system error number! */
- X struct stat buffer;
- X
- X if (stat(name, &buffer) != 0)
- X if (errno != 2) {
- X unlock();
- X exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name));
- X }
- X else
- X ok = 0;
- X
- X return(ok ? buffer.st_size : 0);
- X}
- X
- Xmail(to, subject, filename, person)
- Xchar *to, *subject, *filename;
- Xint person;
- X{
- X /** Mail 'file' to the user from person... **/
- X
- X char buffer[VERY_LONG_STRING];
- X
- X sprintf(buffer, "%s -f '%s [autoreply]' -s '%s' %s %s",
- X fastmail, reply_table[person].username,
- X subject, filename, to);
- X
- X system(buffer);
- X}
- X
- Xlog(message, arg)
- Xchar *message;
- Xchar *arg;
- X{
- X /** Put log entry into log file. Use the format:
- X date-time: <message>
- X **/
- X
- X struct tm *localtime(), *thetime;
- X long time(), clock;
- X char buffer[SLEN];
- X
- X /** first off, get the time and date **/
- X
- X clock = time((long *) 0); /* seconds since ??? */
- X thetime = localtime(&clock); /* and NOW the time... */
- X
- X /** then put the message out! **/
- X
- X sprintf(buffer, message, arg);
- X
- X fprintf(logfd,"%d/%d-%d:%02d: %s\n",
- X thetime->tm_mon+1, thetime->tm_mday,
- X thetime->tm_hour, thetime->tm_min,
- X buffer);
- X}
- X
- XFILE *open_logfile()
- X{
- X /** open the logfile. returns a valid file descriptor **/
- X
- X FILE *fd;
- X
- X if ((fd = fopen(logfile, "a")) == 0)
- X if ((fd = fopen(logfile2, "a")) == 0) {
- X unlock();
- X exit(1); /* give up! */
- X }
- X
- X return( (FILE *) fd);
- X}
- X
- Xclose_logfile()
- X{
- X /** Close the logfile until needed again. **/
- X
- X fclose(logfd);
- X}
- X
- Xchar *strip_parens(string)
- Xchar *string;
- X{
- X /** Return string with all parenthesized information removed.
- X This is a non-destructive algorithm... **/
- X
- X static char buffer[LONG_SLEN];
- X register int i, depth = 0, buffer_index = 0;
- X
- X for (i=0; i < strlen(string); i++) {
- X if (string[i] == '(')
- X depth++;
- X else if (string[i] == ')')
- X depth--;
- X else if (depth == 0)
- X buffer[buffer_index++] = string[i];
- X }
- X
- X buffer[buffer_index] = '\0';
- X
- X return( (char *) buffer);
- X}
- X
- X/*** LOCK and UNLOCK - ensure only one copy of this daemon running at any
- X given time by using a file existance semaphore (wonderful stuff!) ***/
- X
- Xlock()
- X{
- X /** Try to create the lock file. If it's there, or we can't
- X create it for some stupid reason, return zero, otherwise,
- X a non-zero return code indicates success in locking this
- X process in. **/
- X
- X if (access(arep_lock_file, EXISTS) == 0)
- X return(0); /* file already exists!! */
- X
- X if (creat(arep_lock_file, MODE) == -1)
- X return(0); /* can't create file!! */
- X
- X return(1);
- X}
- X
- Xunlock()
- X{
- X /** remove lock file if it's there! **/
- X
- X (void) unlink(arep_lock_file);
- X}
- END_OF_utils/arepdaemon.c
- if test 13412 -ne `wc -c <utils/arepdaemon.c`; then
- echo shar: \"utils/arepdaemon.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"utils/newalias.c\" \(13123 characters\)
- if test -f utils/newalias.c ; then
- echo shar: Will not over-write existing file \"utils/newalias.c\"
- else
- sed "s/^X//" >utils/newalias.c <<'END_OF_utils/newalias.c'
- X/** newalias.c **/
- X
- X/** (C) Copyright 1986 Dave Taylor **/
- X
- X/** Install a new set of aliases for the 'Elm' mailer.
- X
- X If invoked with a specific filename, it assumes that
- X it is working with an individual users alias tables, and
- X generates the .alias.hash and .alias.data files in their
- X home directory.
- X If, however, it is invoked with no arguments, then
- X it assumes that the user is updating the system alias
- X file and uses the defaults for everything.
- X
- X The format for the input file is;
- X alias1, alias2, ... : username : address
- Xor alias1, alias2, ... : groupname: member, member, member, ...
- X member, member, member, ...
- X
- X "-q" flag added: 6/17/86
- X**/
- X
- X#ifdef BSD
- X# include <sys/file.h>
- X#else
- X# include <fcntl.h>
- X#endif
- X
- X#include <stdio.h>
- X#include "defs.h" /* ELM system definitions */
- X
- Xstatic char ident[] = { WHAT_STRING };
- X
- X#ifndef TAB
- X# define TAB '\t' /* TAB character! */
- X#endif
- X
- X#define alias_hash ".alias_hash"
- X#define alias_data ".alias_data"
- X#define alias_text ".alias_text"
- X
- X#define group(string) (strpbrk(string,", ") != NULL)
- X
- Xstruct alias_rec
- Xshash_table[MAX_SALIASES]; /* the actual hash table */
- X
- Xstruct alias_rec
- Xuhash_table[MAX_UALIASES]; /* the actual hash table */
- X
- Xint hash_table_loaded=0; /* is system table actually loaded? */
- X
- Xint buff_loaded; /* for file input overlap... */
- Xint error= 0; /* if errors, don't save! */
- Xint system=0; /* system file updating? */
- Xint count=0; /* how many aliases so far? */
- Xlong offset = 0L; /* data file line offset! */
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X FILE *in, *data;
- X char inputname[SLEN], hashname[SLEN], dataname[SLEN];
- X char home[SLEN], buffer[LONG_STRING];
- X int hash, count = 0, owner, quiet = 0;
- X
- X if (argc != 1)
- X if (strcmp(argv[1], "-q") == 0)
- X quiet++;
- X else
- X exit(printf("Usage: %s\n", argv[0]));
- X
- X owner = getuid();
- X
- X if (owner == 0 && ! quiet) { /* being run by root! */
- X printf("Would you like to update the system aliases? (y/n)");
- X gets(buffer, 2);
- X if (buffer[0] == 'y' || buffer[0] == 'Y') {
- X printf("Updating the system alias file...\n");
- X
- X sprintf(inputname, "%s/%s", mailhome, alias_text);
- X sprintf(hashname, "%s/%s", mailhome, alias_hash);
- X sprintf(dataname, "%s/%s", mailhome, alias_data);
- X system++;
- X init_table(shash_table, MAX_SALIASES);
- X }
- X else
- X printf("Updating your personal alias file...\n");
- X }
- X
- X if (! system) {
- X if (strcpy(home, getenv("HOME")) == NULL)
- X exit(printf("Confused: No HOME variable in environment!\n"));
- X
- X sprintf(inputname, "%s/%s", home, alias_text);
- X sprintf(hashname, "%s/%s", home, alias_hash);
- X sprintf(dataname, "%s/%s", home, alias_data);
- X
- X init_table(uhash_table, MAX_UALIASES);
- X
- X read_in_system(shash_table, sizeof shash_table);
- X }
- X
- X if ((in = fopen(inputname,"r")) == NULL)
- X exit(printf("Couldn't open %s for input!\n", inputname));
- X
- X if ((hash = open(hashname, O_WRONLY | O_CREAT, 0644)) == -1)
- X exit(printf("Couldn't open %s for output!\n", hashname));
- X
- X if ((data = fopen(dataname,"w")) == NULL)
- X exit(printf("Couldn't open %s for output!\n", dataname));
- X
- X buff_loaded = 0; /* file buffer empty right now! */
- X
- X while (get_alias(in, buffer) != -1) {
- X if (system)
- X put_alias(data, buffer, shash_table, MAX_SALIASES);
- X else
- X put_alias(data, buffer, uhash_table, MAX_UALIASES);
- X count++;
- X }
- X
- X if (error) {
- X printf("\n** Not saving tables! Please fix and re-run %s!\n",
- X argv[0]);
- X exit(1);
- X }
- X else {
- X if (system)
- X write(hash, shash_table, sizeof shash_table);
- X else
- X write(hash, uhash_table, sizeof uhash_table);
- X
- X close(hash);
- X fclose(data);
- X close(in);
- X
- X printf("Processed %d aliases\n", count);
- X exit(0);
- X }
- X}
- X
- Xint
- Xget_alias(file, buffer)
- XFILE *file;
- Xchar *buffer;
- X{
- X /* load buffer with the next complete alias from the file.
- X (this can include reading in multiple lines and appending
- X them all together!) Returns EOF after last entry in file.
- X
- X Lines that start with '#' are assumed to be comments and are
- X ignored. White space as the first field of a line is taken
- X to indicate that this line is a continuation of the previous. */
- X
- X static char mybuffer[SLEN];
- X int done = 0, first_read = 1;
- X
- X /** get the first line of the entry... **/
- X
- X buffer[0] = '\0'; /* zero out line */
- X
- X do {
- X if (get_line(file, mybuffer, first_read) == -1)
- X return(-1);
- X first_read = 0;
- X if (mybuffer[0] != '#')
- X strcpy(buffer, mybuffer);
- X } while (strlen(buffer) == 0);
- X
- X /** now read in the rest (if there is any!) **/
- X
- X do {
- X if (get_line(file, mybuffer, first_read) == -1) {
- X buff_loaded = 0; /* force a read next pass! */
- X return(0); /* okay. let's just hand 'buffer' back! */
- X }
- X done = (mybuffer[0] != ' ' && mybuffer[0] != TAB);
- X if (mybuffer[0] != '#' && ! done)
- X strcat(buffer, mybuffer);
- X done = (done && mybuffer[0] != '#');
- X } while (! done);
- X
- X return(0); /* no sweat! */
- X}
- X
- Xput_alias(data, buffer, table, size)
- XFILE *data;
- Xchar *buffer;
- Xstruct alias_rec table[];
- Xint size;
- X{
- X /** break buffer down into three pieces: aliases, comment, and address.
- X Make the appropriate entries in the table (size)
- X **/
- X
- X char aliases[LONG_STRING], address[LONG_STRING];
- X char comment[LONG_STRING];
- X int first, last, i = 0, j = 0;
- X
- X remove_all(' ', TAB, buffer);
- X
- X for (i=0; buffer[i] != ':' && i < LONG_STRING; i++)
- X aliases[i] = buffer[i];
- X aliases[i] = '\0';
- X
- X for (i=strlen(buffer)-1; buffer[i] != ':' && i > 0; i--)
- X address[j++] = buffer[i];
- X address[j] = '\0';
- X
- X comment[0] = '\0'; /* default to nothing at all... */
- X
- X if ((first=strlen(aliases)+1) < (last=(strlen(buffer) - j))) {
- X extract_comment(comment, buffer, first, last);
- X }
- X
- X reverse(address);
- X
- X add_to_table(data, aliases, comment, address, table, size);
- X}
- X
- Xint
- Xget_line(file, buffer, first_line)
- XFILE *file;
- Xchar *buffer;
- Xint first_line;
- X{
- X /** read line from file. If first_line and buff_loaded,
- X then just return! **/
- X int stat;
- X
- X if (first_line && buff_loaded) {
- X buff_loaded = 1;
- X return;
- X }
- X
- X buff_loaded = 1; /* we're going to get SOMETHING in the buffer */
- X
- X stat = fgets(buffer, SLEN, file) == NULL ? -1 : 0;
- X
- X if (stat != -1)
- X no_ret(buffer);
- X
- X return(stat);
- X}
- X
- Xreverse(string)
- Xchar *string;
- X{
- X /** reverse the order of the characters in string...
- X uses a bubble-sort type of algorithm! **/
- X
- X register int f, l;
- X char c;
- X
- X f = 0;
- X l = strlen(string) - 1;
- X
- X while (f < l) {
- X c = string[f];
- X string[f] = string[l];
- X string[l] = c;
- X f++;
- X l--;
- X }
- X}
- X
- Xadd_to_table(data, aliases, comment, address, table, size)
- XFILE *data;
- Xchar *aliases, *comment, *address;
- Xstruct alias_rec table[];
- Xint size;
- X{
- X /** add address + comment to datafile, incrementing offset count
- X (bytes), then for each alias in the aliases string, add to the
- X hash table, with the associated pointer value! **/
- X
- X static char buf[SLEN], *word;
- X long additive = 1L;
- X
- X word = buf; /* use the allocated space! */
- X
- X if (group(address)) {
- X check_group(address, aliases);
- X if (error) return; /* don't do work if we aren't to save it! */
- X fprintf(data, "!%s\n", address);
- X additive = 2L;
- X }
- X else {
- X if (error) return; /* don't do work if we aren't to save it! */
- X if (strlen(comment) > 0) {
- X fprintf(data, "%s (%s)\n", address, comment);
- X additive = (long) (strlen(comment) + 4);
- X }
- X else
- X fprintf(data, "%s\n", address, comment);
- X }
- X
- X while ((word = (char *) strtok(aliases,", ")) != NULL) {
- X add_to_hash_table(word, offset, table, size);
- X aliases = NULL; /* let's get ALL entries via 'strtok' */
- X count++;
- X }
- X
- X if ( system ? count > MAX_SALIASES-35 : count > MAX_UALIASES-21) {
- X printf("** Too many aliases in file! **\n");
- X error++;
- X }
- X
- X offset = (offset + (long) strlen(address) + additive);
- X}
- X
- Xremove_all(c1, c2, string)
- Xchar c1, c2, *string;
- X{
- X /* Remove all occurances of character 'c1' or 'c2' from the string.
- X Hacked (literally) to NOT remove ANY characters from within the
- X colon fields. This will only be used if the line contains TWO
- X colons (and comments with colons in them are the kiss of death!)
- X */
- X
- X char buffer[LONG_STRING];
- X register int i = 0, j = 0, first_colon = -1, last_colon = -1;
- X
- X for (i = 0; string[i] != '\0' && i < LONG_STRING; i++) {
- X if (string[i] != c1 && string[i] != c2)
- X buffer[j++] = string[i];
- X
- X if (first_colon == -1 && string[i] == ':') {
- X first_colon = i;
- X for (last_colon=strlen(string);string[last_colon] != ':';
- X last_colon--) ;
- X }
- X else if (i > first_colon && i < last_colon)
- X if (string[i] == c1 || string[i] == c2)
- X buffer[j++] = string[i];
- X }
- X
- X buffer[j] = '\0';
- X strcpy(string, buffer);
- X}
- X
- Xadd_to_hash_table(word, offset, table, size)
- Xchar *word;
- Xlong offset;
- Xstruct alias_rec table[];
- Xint size;
- X{
- X /** add word and offset to current hash table. **/
- X register int loc;
- X
- X if (strlen(word) > 20)
- X exit(printf("Bad alias name: %s. Too long.\n", word));
- X
- X loc = hash_it(word, size);
- X
- X while (table[loc].name[0] != '\0' && strcmp(table[loc].name, word) != 0)
- X loc = loc + 1 % size;
- X
- X if (table[loc].name[0] == '\0') {
- X strcpy(table[loc].name, word);
- X table[loc].byte = offset;
- X }
- X else
- X printf("** Duplicate alias '%s' in file. Multiples ignored.\n",
- X word);
- X}
- X
- Xint
- Xhash_it(string, table_size)
- Xchar *string;
- X{
- X /** compute the hash function of the string, returning
- X it (mod table_size) **/
- X
- X register int i, sum = 0;
- X
- X for (i=0; string[i] != '\0'; i++)
- X sum += (int) string[i];
- X
- X return(sum % table_size);
- X}
- X
- Xinit_table(table, size)
- Xstruct alias_rec table[];
- Xint size;
- X{
- X /** initialize hash table! **/
- X
- X register int i;
- X
- X for (i=0; i < size; i++)
- X table[i].name[0] = '\0';
- X}
- X
- Xread_in_system(table, size)
- Xstruct alias_rec table[];
- Xint size;
- X{
- X /** read in the system hash table...to check for group aliases
- X from the user alias file (to ensure that there are no names
- X in the user group files that are not purely contained within
- X either alias table) **/
- X
- X int fd;
- X char fname[SLEN];
- X
- X sprintf(fname, "%s/%s", mailhome, alias_hash);
- X
- X if ((fd = open(fname, O_RDONLY)) == -1)
- X return; /* no sweat: flag 'hash_table_loaded' not set! */
- X
- X (void) read(fd, table, size);
- X close(fd);
- X hash_table_loaded++;
- X}
- X
- Xcheck_group(names, groupname)
- Xchar *names, *groupname;
- X{
- X /** one by one make sure each name in the group is defined
- X in either the system alias file or the user alias file.
- X This search is linearly dependent, so all group aliases
- X in the source file should appear LAST, after all the user
- X aliases! **/
- X
- X char *word, *bufptr, buffer[LONG_STRING];
- X
- X strcpy(buffer, names);
- X bufptr = (char *) buffer;
- X
- X while ((word = (char *) strtok(bufptr,", ")) != NULL) {
- X if (! can_find(word))
- X if (! valid_name(word)) {
- X error++;
- X printf("** Alias %s in group %s is bad!\n", word, groupname);
- X }
- X bufptr = NULL;
- X }
- X}
- X
- Xint
- Xcan_find(name)
- Xchar *name;
- X{
- X /** find name in either hash table...use 'system' variable to
- X determine if we should look in both or just system.... **/
- X
- X register int loc;
- X
- X if (strlen(name) > 20) {
- X error++;
- X printf("** Bad alias name: %s. Too long.\n", name);
- X return(1); /* fake out: don't want 2 error messages! */
- X }
- X
- X /** system alias table... **/
- X if (hash_table_loaded || system) {
- X loc = hash_it(name, MAX_SALIASES);
- X
- X while (strcmp(name, shash_table[loc].name) != 0 &&
- X shash_table[loc].name[0] != '\0')
- X loc = (loc + 1) % MAX_SALIASES;
- X
- X if (strcmp(name, shash_table[loc].name) == 0)
- X return(1); /* found it! */
- X }
- X
- X if (! system) { /* okay! Let's check the user alias file! */
- X loc = hash_it(name, MAX_UALIASES);
- X
- X while (strcmp(name, uhash_table[loc].name) != 0 &&
- X uhash_table[loc].name[0] != '\0')
- X loc = (loc + 1) % MAX_UALIASES;
- X
- X if (strcmp(name, uhash_table[loc].name) == 0)
- X return(1); /* found it! */
- X }
- X
- X return(0);
- X}
- X
- Xextract_comment(comment, buffer, first, last)
- Xchar *comment, *buffer;
- Xint first, last;
- X{
- X /** Buffer contains a comment, located between the first and last
- X values. Copy that into 'comment', but remove leading and
- X trailing white space. Note also that it doesn't copy past
- X a comma, so `unpublishable' comments can be of the form;
- X dave: Dave Taylor, HP Labs : taylor@hplabs
- X and the output will be "taylor@hplabs (Dave Taylor)".
- X **/
- X
- X register int loc = 0;
- X
- X /** first off, skip the LEADING white space... **/
- X
- X while (buffer[first] == ' ') first++;
- X
- X /** now let's backup the 'last' value until we hit a non-space **/
- X
- X last -= 2; /* starts at ch AFTER colon.. */
- X while (buffer[last] == ' ') last--;
- X
- X /** now a final check to make sure we're still talking about a
- X reasonable string (rather than a "joe :: joe@dec" type string) **/
- X
- X if (first < last) {
- X /* one more check - let's find the comma, if present... */
- X for (loc=first; loc < last; loc++)
- X if (buffer[loc] == ',') {
- X last = loc-1;
- X break;
- X }
- X loc = 0;
- X while (first <= last)
- X comment[loc++] = buffer[first++];
- X comment[loc] = '\0';
- X }
- X}
- END_OF_utils/newalias.c
- if test 13123 -ne `wc -c <utils/newalias.c`; then
- echo shar: \"utils/newalias.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 13 \(of 19\).
- cp /dev/null ark13isdone
- 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
-