ast@cs.vu.nl (Andy Tanenbaum) (10/23/89)
------------------------------- Cut Here -------------------------------
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive"
# Contents:
# README umail.doc umail.cf umail
# Makefile uucp.h umail.h ummain.c
# umtime.c umheader.c umconvert.c umroute.c
# umsend.c umscanner.c
#
# Wrapped by root@minixug on Thu Oct 19 22:37:16 1989
#
PATH=/bin:/usr/bin:/usr/local/bin:/usr/ucb:/tmp ; export PATH
if test -f 'README' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'README'"
else
echo "x - README"
sed 's/^X//' <<\END_OF_SHAR >'README'
X U-MAIL Remote Mail Transport Agent (MINIX)
X
X MicroWalt U-MAIL V2.5
X =====================
X
X
XThis archive contains the sources of the UMAIL Network Mailer
Xfor the MINIX operating system. It runs on most UNIXes as well.
X
XThe file 'umail' is the executable program, and 'umail.doc' is
Xthe (preliminary) documentation of the program.
XSee 'umail.cf' for configuration information.
X
XOf course, this program needs the presence of either UUCP or
XRSMTP to run properly...
X
XEnjoy!
X+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
X| MINIX User Group (Holland) UUCP: hp4nl!kyber!minixug!waltje |
X| c/o Fred van Kempen, or: minixug!waltje@kyber.UUCP |
X| Hoefbladhof 27 |
X| 2215 DV VOORHOUT |
X| The Netherlands "A good programmer knows his Sources" |
X+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
X
END_OF_SHAR
fi
if test -f 'umail.doc' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'umail.doc'"
else
echo "x - umail.doc"
sed 's/^X//' <<\END_OF_SHAR >'umail.doc'
XUMAIL(1) MINIX User's Manual UMAIL(1)
X
X
XNAME
X umail - electronic mail delivery agent.
X
XSYNOPSIS
X umail [-c <config> [-d] [-i <inputfile> [-n] <user>
X
XDESCRIPTION
X Umail is a semi-intelligent mail transporting program
X which knows something about Internet adresses and mail
X adress routing to other systems.
X It is used as a back-end to the Mailx program; which
X is used to read or create messages. Umail only takes
X care of the transportation of the message to other
X MINIX (or UNIX) systems through the available network
X software like UUCP and RSMTP.
X
X In restricted mode ('rmail') it functions as a message
X delivery program for incoming network mail.
X Networking programs like uucico(1) and rsmtp(8) execute
X the rmail(1) command to deliver a received message to
X the adressed user, or to forward the message to another
X system.
X
X The program has some command-line options, which are
X used to alter the "standard" behaviour of the program.
X The options are:
X
X -c <config> Debug; use 'config' as the configura-
X tion file instead of the standard
X one. This is sometimes useful when
X debugging the package.
X
X -d Debug; generate some useful output
X while working.
X
X -i <infile> Input; use file 'infile' as the mes-
X sage file instead of standard input.
X
X -n Now; call the networking delivery
X software immediately after queueing
X the message. Not recommended!
X
X The 'user' string identifies the network-adress of the
X user who is to receive the message. It can be any legal
X UUCP or Internet mail-adress.
X
XDELIVERY
X The Mailx program can serve as both a user agent and a
X local delivery agent. If Mailx sees that the adressed
X user is on the local system, it will do the delivery
X itself. No header (except for From, To and Subject) is
X added, and delivery errors will cause the message to
X be returned to the user as a file 'dead.letter'.
X
X Otherwise, if the specified adress is not local, the
X message is sent to the Remote Mailer on the system.
X
X
X
X -- 1 --
X
X
X
XUMAIL(1) MINIX User's Manual UMAIL(1)
X
X
X
X Usually, this is the rmail(1) command; programs like
X sendmail(8) or smail(1) (or links to them) are used as
X well. On MINIX systems, rmail(1) is a separate program.
X
X This small remote mailer knows something about UUCP, and
X how to interpret old-style UUCP (host!user) adresses.
X This works fine for most users, but it is sometimes nice
X to have a somewhat more intelligent mailer.
X Therefore, one could install Umail as a link to rmail(1)
X so that the mail(1) or Mailx(1) programs will never see
X the difference.
X
X These (more or less) intelligent mailers add a standard
X (RFC-822) header to the message, and then send it to the
X networking software. On MINIX systems, messages will be
X transported using either the UUCP networking software
X (serial lines) or the Amoeba RSMTP (Ethernet) software.
X
X Because it would be too difficult to program all sorts
X of networks, system names and the lot in the mailer
X software, a file exists which contains the Configuration
X parameters of Umail: the Config File. This is a plain
X ASCII text file, containing a mixture of comments, data
X and instructions.
X
XAUTHOR
X Steve R. Sampson (first draft of rmail program)
X Fred van Kempen, waltje@kyber.UUCP
X
XFILES
X /usr/spool/mail/user maildrop file
X /usr/spool/mail/user.lock lock for maildrop files
X /tmp/um* temporary file
X /usr/spool/uucp/* UUCP networking files
X /usr/spool/rsmtp/* SMTP networking files
X /usr/lib/uucp/umail.cf configuration file
X
XSEE ALSO
X wmail.doc
X
XBUGS
X The routing algorithm could be improved a lot.
X Also, the Config scanner should be more robust.
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X -- 2 --
X
X
END_OF_SHAR
fi
if test -f 'umail.cf' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'umail.cf'"
else
echo "x - umail.cf"
sed 's/^X//' <<\END_OF_SHAR >'umail.cf'
X#
X# MicroWalt Corporation -- UMAIL Configuration File
X#
X# System: MINIX User Group Holland, minixug.nluug.nl
X# OS: MicroWalt Advanced MINIX 1.4B
X#
X# Author: F. van Kempen, MicroWalt Corporation
X#
X
X# These are some configuration variables for the
X# mailer. They define the working environment.
XBEGIN
X Organization := "MINIX User Group Holland, Netherlands"
X System := "minixug"
X Domain := "nluug.nl"
X TimeZone := "MET +0100"
X OldMailer := TRUE # We want V6 "From <user> <date>" lines
X Escape := TRUE # We can send all undeliverable mail
X # to another host.
XEND
X
X# The next table defines all the names under which
X# our system could possibly be adressed. It is used
X# to map domain adresses back to local adresses.
XNAMES BEGIN
X minixug.nluug.nl # Our official name
X minixug.nl # other possible names
X minixug.uucp # old-style UUCP name
X minixug # local name
XEND
X
X# This table defines the systems that we know of, and
X# what networking software to use to get to it.
X# 'TRUE' means, that the specified host understands
X# route-adressing (and can thus do things itself).
X# FALSE means that we have to give that host a ready-
X# to-run UUCP adress in bang-style.
XHOSTS BEGIN
X minixug := TRUE , $$ , "@" # Just local mail !
X kyber := FALSE , $$ , "@" # My UUCP host site
X archvax := FALSE , "rsmtp" , "<%s archvax!" # SMTP via Ethernet
XEND
X
X# This is the actual routing table.
X# It defines where mail for the various domains
X# should be sent to. Note, that domain "." is
X# the "default domain", which is used if no
X# matching domain can be found.
X# Format:
X#
X# DOMAIN := HOST , ROUTE
X#
XDOMAINS BEGIN
X aha.nl := kyber , htsa # Algemene Hogeschool Amsterdam
X edu := kyber , hp4nl # Educational Institutes Network
X nl := kyber , hp4nl # UUCP-Netherlands
X nluug := kyber , hp4nl # Dutch UNIX User Group Network
X nluug.nl := kyber , hp4nl
X uu.net := kyber , hp4nl # USA UUCP Network
X uucp := kyber , hp4nl # Old-style UUCP Network
X uunet := kyber , hp4nl # USA UUCP Network
X . := kyber , hp4nl # Default host
XEND
END_OF_SHAR
fi
if test -f 'umail' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'umail'"
else
if uudecode <<\END_OF_UUTEST 1>/dev/null 2>/dev/null
begin 777 /tmp/unpacker
end
END_OF_UUTEST
then
rm -f /tmp/unpacker
else
echo "x - uudecode (for non-ascii files)"
cat <<END_OF_UUDECODE >/tmp/uudecode.c
#include <stdio.h>
#define DEC(c) (((c) - ' ') & 077)
main()
{
int n, fmode;
char fname[512], a, b, c, d;
scanf("begin %o %s", &fmode, fname); getchar();
if (freopen(fname, "w", stdout) == NULL) {
perror(fname);
exit(1);
}
while ((n = getchar()) != EOF && (n = DEC(n)) != 0) {
while (n > 0) {
a = DEC(getchar());
b = DEC(getchar());
c = DEC(getchar());
d = DEC(getchar());
if (n-- > 0) putchar (a << 2 | b >> 4);
if (n-- > 0) putchar (b << 4 | c >> 2);
if (n-- > 0) putchar (c << 6 | d);
}
n = getchar();
}
chmod(fname, fmode);
exit(0);
}
END_OF_UUDECODE
if cc -o /tmp/uudecode /tmp/uudecode.c 1>/dev/null 2>/dev/null
then
rm -f /tmp/uudecode.c
else
echo "$0: can't compile uudecode!"
exit 1
fi
fi
echo "x - umail (non-ascii)"
uudecode <<\END_OF_UUENCODED
begin 755 umail
M 0,@!" !@.P * X &(H "G4 ")XXL/@\,"B<A T> !
MV*, %!34>C$!(/$!E#HD#95B>505E>+?@2)_H \ '0;B@28/6$ ?!"*!)@]
M>@!_"(H$F"T@ (@$1NO@B?CIV3I5B>505E>+?@2)_H \ '0;B@28/4$ ?!"*
M!)@]6@!_"(H$F"W@_X@$1NO@B?CIJ3I5B>504%97N 0 4.@_+5N)QH,^"
M=0:)-@@ ZP^+/@@ @ST = 2+/>OWB37'! _W8$Z#(P6P4" %#H#BU;B40"
M_W8$_W0"Z)<P6UOI6#I5B>504%97N H 4.CN+%N)QH,^# =0:)-@P ZP^+
M/@P @ST = 2+/>OWB37'! _W8$Z.$O6P4" %#HO2Q;B40"_W8(Z,\O6P4"
M %#HJRQ;B40&_W8*Z+TO6P4" %#HF2Q;B40(_W8$_W0"Z"(P6UO_=@C_= ;H
M%S!;6_]V"O]T".@,,%M;BT8&B40$Z<<Y58GE4%!65[@( %#H72Q;B<:#/@X
M '4&B38. .L/BSX. (,] '0$BSWK]XDUQP0 /]V!.A0+UL% @!0Z"PL6XE$
M O]V!N@^+UL% @!0Z!HL6XE$!/]V".@L+UL% @!0Z @L6XE$!O]V!/]T NB1
M+UM;_W8&_W0$Z(8O6UO_=@C_= ;H>R];6^D\.56)Y5!05E?_=@3H)OY;N 8
M4.C+*UN)QH,^"@ =0:)-@H ZP^+/@H @ST = 2+/>OWB37'! _W8$Z+XN
M6P4" %#HFBM;B40"_W8&Z*PN6P4" %#HB"M;B40$_W8$_W0"Z!$O6UO_=@;_
M= 3H!B];6^G'.%6)Y5!6BS8* GV=!C_=@3_= +H.RY;6PG =07_= 3K!XLT
MZ^0QP%!8Z9PX58GE5HMV!%;HA_U;"?9T#K@X %!6Z TN6UL)P'4%,<!0ZR:X
M/@!05NCZ+5M;"<!U!K@! %#K$E:X1 !0_S8*#>BC'H/$!C' 4%CI3SA5B>50
M5HLV# )]G06_W8$_W0"Z,(M6UL)P'4#5NL'BS3KYC' 4%CI)3A5B>505HLV
M#@ )]G06_W8$_W0"Z)@M6UL)P'4#5NL'BS3KYC' 4%CI^S=5B>504%97BWX(
MBW8$_TX&?B%7Z-XG6XE&_H-^_O]T$X-^_@IU!<8$ .L(BT;^B 1&Z]J#?O[_
M=0HY=@1U!3' 4.L#_W8$6.FP-U6)Y?\V$@#_-A _W8$N& 4+@P#E#H0"&#
MQ JX, [ID#=5B>505O]V!.A_'UN)Q@GV= 7_= CK!+AJ %!8Z7 W58GE4%:X
M> !0Z)S^6XG&"?9U [Z" %;_=@3HE@);4+B$ %"X8 Y0Z.X@@\0(N& .Z3TW
M58GE@>P !%:+=@97BWX$5[@ !%"-A@#\4.A[&X/$!@G =0+K'%:-A@#\4.C.
M+%M0N $ 4(V& /Q0Z*4;@\0(Z\[I^#95B>56BW8$5N@"&EL)P'0-5N@>(5NX
M 0!0Z&,R6[B* %#H#?Y;HQ @SX0 !U%;B2 %#_-@H-Z D=6UNX__]0Z#PR
M6[BN %#HYOU;HQ( @SX2 !U%;BV %#_-@H-Z.(<6UNX__]0Z!4R6[C2 %#H
MO_U;HQ0 N. 4.BT_5M0Z-O]6Z,6 +CJ %#HI/U;4.C+_5NC& #I8#95B>6X
M\@!0_S8*#>B<'%M;Z4XV58GE@^P*5E?'1O@N 8M>!HL?@#]R=0;'!@8 0"X
M1@%0_W8&_W8$Z"D;@\0&B<:#_O]T1%;K.HL.*BF)3OCKW<<&! ! .O5N'\
M4/\V*BFX$!M0Z,X@@\0&Z\''!A(< 0#KN>B&_[@! %#H93%;ZZR[&@!8Z9$S
MBT8$.0:*"7P+Z&G_N/__4.A(,5NX3P!0Z!HL6_]V^.BZ_ENX3@%0N) ;4.C@
M*UM;N) ;4.CS'5NX7 %0N) ;4.AH)EM;B4;^@W[^ '40N%X!4.BY'UNX 0!0
MZ/XP6XL>B@G1XP->!O\WZ*H*6XE&^H-^^@!U!#'VZPG_=OKHQ0M;B<: /A ;
M '0EN&8!4+@0&U#H%B9;6XG'"?]U%K@0&U#H:A];N $ 4.BO,%OK!(L^!@W_
M=OY7Z"H*6UO_=OY7Z-7]6UO_=O[HH"1;.3XF%5^B5)%L)]G41,<!0N! 9
M4.BF$UM;OO__ZQRXD!M0N) .4+C0#E"XT!!0N! 14.@&$X/$"HG&N) ;4.A$
M*UM6Z$<P6^F\-%6)Y8/L"(M>!(L'BT\"B4;\B4[^QP8>' QP8<' QP8:
M' $ QP88' QP86' QP84' _W;^_W;\N $ 4+B 45#H4S(%! "#T@"Y
M!P"9]_F)%B <N00 H1X<F??Y_W;^_W;\@_H"=0JXX@%0N "%4.L(N.$!4+B
M,U"/1OB/1OK_=OK_=OCH.#0)P'P8_P8>'(M&_(M._BM&^!M.^HE&_(E._NNO
M@08>'+('_W;^_W;\N $ 4+B 45#HVS&C(AS'!FH!' "Y! "A'AR9]_D)TG4$
M_P9J 8L>'!S1XXN': &9_W;^_W;\4E"X@%&Z 0#H@S)24.C*,PG ?#"+#AP<
M_P8<'(G+T>.+AV@!F?]V_O]V_%)0N(!1N@$ Z%@R65LIP1G3B4[\B5[^ZZO_
M=O[_=ORX 0!0N(!14.B%,PG ?!B+1OR+3OXM@%&#V0&)1OR)3O[_!AH<Z]/_
M=O[_=OPQP%"X$ Y0Z%DS"<!\&(M&_(M._BT0#H/9 (E&_(E._O\&&!SKU/]V
M_O]V_#' 4+@\ %#H+3,)P'P8BT;\BT[^+3P @]D B4;\B4[^_P86'.O4BT[\
MB0X4'(L.'AR!Z6P'BQX<'-'C_S84'/\V%AS_-A@<4?^W@ &+'B <T>/_-AH<
M_[>8 ;CR 5"X)AQ0Z'$<@\02N"8<Z<$R58GE@^PR5HLV% ()]G0M_W0(C4;.
M4.C@*%M;C4;.4.B4]UO_=@2-1LY0Z!PH6UL)P'4%_W0*ZP>+-.O/,<!06.E]
M,E6)Y8/L,E:+-A0""?9T-O]T"(U&SE#HG2A;6XU&SE#H4?=;_W8$C4;.4.C9
M)UM;"<!U#H-\ @!U",=$ @$ 5NL'BS3KQC' 4%CI,3)5B>6#[ 965[AP E#H
M8O];B<8)]G48N) ;4+AV E"X$!E0Z+0;@\0&,<!0Z<< 5KBD'%#H-"A;6[ZD
M'( \ '0-@#P@= B / ET T;K[L8$ $:)=OJ)\T:X<@!04^CE&UM;B<<)_W03
MN P 4+B( E!7Z/H<@\0&"<!UV@G_=$:X( !05^C '%M;B<;&1?\ _W;ZN'0<
M4.C2)UM;1E:X1!Q0Z,<G6UNXI!Q0N$0<4+B6 E"X$!50Z"$;@\0(BUX$QP<!
M .LM_W;ZN'0<4.B<)UM;N)P"4+A$'%#HCR=;6[BD'%"X$!50Z((G6UN+7@3'
M!P N $ 4%CI-S%5B>6#[ I65[B> E#H:?Y;B<>XI )0Z%_^6XG&"?9T! G_
M=2R#/A8 70#Z9\ C4;^4.C2_EL)P'0#Z9 N*H"4+@0&5#HU!I;6S' 4.F
M %:X=!Q0Z!DG6UM7N$0<4.@/)UM;OD0<@#P = V /"!T"( \"70#1NONQ@0
MN$0<4+@0%5#HZB9;6[@A %"X1!Q0Z+<:6UN)Q@GV=!7'1OX! ,8$ $96N*0<
M4.C$)EM;ZQS'1OX %>XI!Q0Z+,F6UNXQ )0N$0<4.BF)EM;_W;^6.EC,%6)
MY8/L#%97BWX$QT;XQ@+'1O;. HU&_%#HX"9;C4;\4.C0^%N)1OJ#/A8 74<
M_S80 (U&_%#H;?M;4+BD'%"XT@)05^AF%H/$"KBD'%#H@_A;4+BD'%#_-A
MN.X"4%?H2A:#Q K_=OK_-@( _S82 /\V$ "X -05^@P%H/$#+BD'%#H3?A;
M4+BD'%#H(OA;4+@X U!7Z!,6@\0(@SX4 !T#_\V% "X2@-05^C]%8/$!KA<
M U#HZ?Q;B<8)]G0,5KA@ U!7Z.,5@\0&N&@#4.C/_%N)Q@GV= Q6N' #4%?H
MR16#Q :X=!Q0N'X#4%?HNA6#Q :XB -05^BO%5M;Z5\O58GE@^P.5E>+?@3'
M1OB* \=&]I(#C4;\4.C<)5N-1OQ0Z,SW6XE&^H,^%@ !=4^XE@-0Z*W\6XG&
M@#Y$' !U'O\V$ "-1OQ0Z%CZ6U"XI!Q0N)P#4%?H416#Q KK(/\V$ "-1OQ0
MZ#KZ6U"XI!Q0N$0<4+BX U!7Z"\5@\0,N-8#4.A>_%N)Q@GV="^#/A < 747
M_W0*_S80 /]T"+C< U!7Z 45@\0*ZQ'_= K_= BXZ -05^CR%(/$"/]V^O\V
M @#_-A( _S80 +CP U!7Z-@4@\0,N"@$4.@'_%N)Q@GV=">#? 0!?@__= K_
M=O97Z+<4@\0&Z]W_= K_= C_=OA7Z*44@\0(Z\NX,@10Z-+[6XG&"?9T)8-\
M! %^#_]T"O]V]E?H@A2#Q ;K$/]T"O]T"/]V^%?H<!2#Q B+-A0""?9T'X-\
M!@!U%<=$ @$ _W0*_W0(_W;X5^A-%(/$"(LTZ]VX.@10Z'C[6XG&"?9T)8-\
M! %^#_]T"O]V]E?H*!2#Q ;K$/]T"O]T"/]V^%?H%A2#Q BX/@10Z$7[6XG&
M"?9T)8-\! %^#_]T"O]V]E?H]1.#Q ;K$/]T"O]T"/]V^%?HXQ.#Q BX0@10
MZ!+[6XG&"?9T)8-\! %^#_]T"O]V]E?HPA.#Q ;K$/]T"O]T"/]V^%?HL!.#
MQ BX1@10Z-_Z6XG&"?9T)8-\! %^#_]T"O]V]E?HCQ.#Q ;K$/]T"O]T"/]V
M^%?H?1.#Q BX3@10Z*SZ6XG&"?9T)8-\! %^#_]T"O]V]E?H7!.#Q ;K$/]T
M"O]T"/]V^%?H2A.#Q BX6@10Z'GZ6XG&"?9T)X-\! %^#_]T"O]V]E?H*1.#
MQ ;K(_]T"O]T"/]V^%?H%Q.#Q CK$?]V^KA@!%#_=OA7Z 03@\0(N&@$4%?H
M^1);6^FI+%6)Y8'LC@165\>&?/L ,>&>OL! /]V!+@ !%"-A@#\4.B+](/$
M!@G =0/IB & O@#\ '4#Z7X!_X9\^XV& /R)AG3[N 4 4+AJ!%"-A@#\4.B2
M%X/$!@G =0/I:P"+GG3[@#\@= F+GG3[@#\)=13_AGK[C8: ^XF&=/N-A@#\
MB<;K4;@Z %#_MG3[Z"X66UN)Q@GV="S&! !&@#P = V /"!T!8 \"74#1NON
M_[9T^XV&@/M0Z"HB6UO'AGK[ 0#K$HNV=/OK#,>&=/MP!(V&!?R)QK@, %#H
M<1Y;B<>#/A0" '4&B3X4 NLCBPX4 HF.=ON+GG;[@S\ = R+GG;[BP>)AG;[
MZ^N+GG;[B3_'!0 _[9T^^A/(5L% @!0Z"L>6XE%"%;H/R%;!0( 4.@;'EN)
M10K_MG3[_W4(Z*,A6UM6_W4*Z)HA6UO'10( (N&>ON)103'108 ,>&?OL
M (N>?OO1XXNW%@+_=0B-A@#\4.AL(5M;C88 _%#H'_!;"?9T(8V& /Q05NBD
M(%M;"<!U NL0_X9^^XN>?OO1XXNW%@+KVPGV=0/I9_['108! .E?_NGP*E6)
MY5!05HMV!E>+?@17Z#;^6U;HH_E;B4;^@W[^ '4'5NAI^EOK!5;H9OM;BT;^
MZ;XJ58GE@>P*!%97_W8$N! 14.CE(%M;Q@:D(0#&!J0B ,:& /P Q@:D( "X
M0 !0N! 14.B@%5M;B<8)]G4#Z9T Q@0 1K@0$5"XI"!0Z*H@6UM6C88 _%#H
MGR!;6XV& /Q0Z(+O6[@N %"-A@#\4.AB%%M;B<8)]G5"C88 _%#H\/%;B<<)
M_W0:C88 _%"XI"%0Z&4@6UO&!J0B +BD(%#IB@"-A@#\4+BD(E#H2R!;6\8&
MI"$ N*0@4.MQQ@0 1HV& /Q0N*0A4.@N(%M;5KBD(E#H)"!;6[BD(%#K3[@A
M %"X$!%0Z.L36UN)Q@GV="'&! !&N! 14+BD(5#H^A];6U:XI"!0Z/ ?6UNX
MI"!0ZQNX$!%0N*0@4.C='UM;Q@:D(0#&!J0B +BD(%!8Z8\I58GE@>P*!%:+
M=@17@+P @!U$8V$ %0C88 _%#HJ1];6^L9C80 E"-A !4+AV!%"-A@#\
M4.C^$H/$"(V& /Q0Z/<#6PG = K&A ! ,:$ ( @+P @!U ^D2 H"\ $
M=!N-A "4(V$ %0N'P$4(V& /Q0Z+T2@\0(ZP^-A "4(V& /Q0Z#P?6UN-
MA@#\4(V$ %0Z"T?6UN-A@#\B8;^^S'_BX;^^XF&_/O_MO[[Z+3P6XG'"?]T
M$/^V_ON-A "4.C_'EM;ZR"X+@!0_[;\^^C*$EM;B8;^^X.^_OL =0+K!O^&
M_OOKN@G_=52#/A@ '49C80 E"X@@10N! 94.@O$H/$!C' 4.D' [B8!%#H
M4O!;B<<)_W4FC80 E"XF@10N! 94.@($H/$!KBP!%"X$!E0Z#826ULQP%#I
MTP+_=03H]>];B8;X^X.^^/L =1?_=02XS 10N! 94.C2$8/$!C' 4.FJ HN>
M^/N#?P0!= /I>@"+70: /T!U-("\ $ =1>-A "4%:XY 10N! 14.B<$8/$
M".F& (V$ %05KCJ!%"X$!%0Z(41@\0(ZW" O ! '49C80 E!6_W4&N/ $
M4+@0$5#H91&#Q KK4(V$ )0C80 5!6_W4&N/H$4+@0$5#H1Q&#Q SK,H"\
M $ =116_W4&N 8%4+@0$5#H+!&#Q CK%U:-A !4/]U!K@,!5"X$!%0Z!,1
M@\0*_W4$C80 5#HEAU;6XN>^/O_=P:XT Y0Z(8=6UN+GOC[_W<(N) .4.AV
M'5M;C80 5"XT!!0Z&@=6UO'!A < 0"X 0!0Z:D!@+P 0!U ^DV <:$ (
MC80 5#HNNY;B8;X^X.^^/L = /IB@"#/A@ '49C80 5"X%@50N! 94.B+
M$(/$!C' 4.EC ;@J!5#HKNY;B<<)_W4FC80 5"X+ 50N! 94.AD$(/$!KA
M!5"X$!E0Z)(06ULQP%#I+P'_=02-A "4.C4'%M;_W4$Z$3N6XF&^/N#OOC[
M '47_W4$N%P%4+@0&5#H(1"#Q 8QP%#I^0" O " '1%BY[X^X-_! %U%HV$
M %05KAT!5"X$!%0Z/8/@\0(ZQ16C80 5"X>@50N! 14.C@#X/$"(V$ )0
MC80 5#H81Q;6^L*5K@0$5#H51Q;6XV$ %0N- 04.A''%M;BY[X^_]W!KC0
M#E#H-QQ;6XN>^/O_=PBXD Y0Z"<<6UO'!A < 0"X 0!0ZVE6Z-<-6XF&]ON#
MOO;[ '445KB !5"X$!E0Z&P/@\0&,<!0ZT7_-A Z&;M6XF&^/M6N! 14.CA
M&UM;Q@;0$ "+GOC[_W<&N- .4.C,&UM;BY[X^_]W"+B0#E#HO!M;6\<&$!P
M +@! %!8Z7(E58GE4%;_=@3H&>U;B<8)]G4%,<!0ZP2X 0!06.E4)56)Y5!6
MBS8( GV=!G_=@3_= +HQQI;6PG =0:X 0!0ZP>+-.OC,<!06.DG)56)Y8/L
M$E97QT;^ "^E 7'1O"L!3' 4%;H2PE;6PG = ^X@ %05NCT%EM;4.C0&EO_
M=O!6Z)P-6UL)P'07N 4 4.C##5O_1OZ#?OX%?N(QP%#IF "XR 505NB@%5M;
MB<=7N H 4(U&]%#H% F#Q 97Z$D46_]V\.@J&UN-1O10Z,$36T")1OZXR@50
M5NAM%5M;B<<)_W4%,<!0ZU#_=OZXS 505^C)"H/$!E?H#A1;@WX& '49_W;^
M_W8(_W8$N- %4+BD(U#H!0Z#Q KK&O]V_O]V!O]V"/]V!+C>!5"XI"-0Z.D-
M@\0,N*0C4%CI-215B>6![(( 5HMV!%=6Z"$,6XG'"?]U(?\V$ !6N.X%4(V&
M?O]0Z+8-@\0(,<!0C89^_U#HM@);6U;_=@:X& 90N @&4(V&?O]0Z)(-@\0*
MC89^_U#H9 ];Z=HC58GE@>R( E:+=@175NA8_EL)P'4;5K@>!E"-1H!0Z&(-
M@\0&,<!0C4: 4.AC EM;5C' 4+A" %#H>?Z#Q 90C88 _U#HS1E;6U:X3@!0
MN$, 4.A?_H/$!E"-AH#^4.BS&5M;_S80 #' 4+A$ %#H0_Z#Q 90C88 _E#H
MEQE;6U:X3@!0N%@ 4.@I_H/$!E"-AH#]4.A]&5M;N#H&4(V& /Y0Z P46UN)
MAGK]@[YZ_0!U$K@\!E#H6PU;N $ 4.B@'EOK+;A$!E#_=@CHXQ-;6XF&>/W_
MMGK]_[9X_>B_ZUM;_[9Z_>B)$EO_MGC]Z($26[A&!E"-A@#_4.BT$UM;B89\
M_8.^?/T =1*X2 90Z ,-6[@! %#H2!Y;ZR?_=@:-A@#^4%#_-A N&X&4+A0
M!E#_MGS]Z.T(@\0._[9\_>@O$ENX= 90C8: _E#H8A-;6XG'"?]U$KAV!E#H
MM@Q;N $ 4.C['5OK,HV& /]0N+ &4(V&@/U0C88 _U"-A@#^4+BJ!E"-A@#^
M4%"X?@905^B2"(/$%%?HUQ%;N"@ 4%"-A@#_4.A*!H/$!K@H %!0C8: _E#H
M.@:#Q :X* !04(V& /Y0Z"H&@\0&N"@ 4%"-AH#]4.@:!H/$!H,^$AP!=2BX
MM@90C4: 4.@G&%M;5KCJ!E"XS 90C4: 4.B$"X/$"(U&@%#H5PU;,<#IRR%5
MB>6![ $5HMV#%>+?@2X =0Z*(&6[@0!U#_=@CH-!=;6PG =1Z+7@: /P!U
M"597Z&+]6UOK1U97_W8&Z+']@\0&ZSK_=@K_=@BX% =0C88 _%#H'0N#Q A6
MC88 _%"-A@#^4.@,"X/$!E>-A@#^4.@\"UM;C88 _E#HTPQ;Z4DA58GE@>RH
M %97N" '4(U&V%#H;Q=;6XU&V%#H@@E;N# '4(U&V%#H]Q%;6XG&N#('4+B0
M&U#HZ!%;6XG'C4;X4.B?%UN-1OA0Z$+L6U"X0 =0N#0'4%;H.P>#Q BX$!4)
MP'0/N! 54+A,!U!6Z"4'@\0&N%0'4%;H&@=;6[AN!U!6Z! '6UO_=@2XG =0
M5N@#!X/$!KB@!U!6Z/@&6UM7N( 4(V&6/]0Z*3H@\0&"<!T$HV&6/]0N,8'
M4%;HU0:#Q ;KVE;H&!!;5^@3$%N#?@8 =1J-1MA0N-0'4+C.!U"XS =0N! 5
M4.B3_H/$"HU&V%"X[ =0N.@'4+CF!U"XV@=0Z'G^@\0*C4;84.BY%ENXD!M0
MZ+$66[@! %#HL1M;Z28@58GE4%;_-B8IZ!006XG&@_X*=1/_!O('BQ[N!\8'
M ,<&[@<F)>L,BQ[N!XGPB ?_!NX'B?#I[Q]5B>6#[ 965XL^\ ?HN?^)1OJ#
M?OH*= :#?OK_=>['!O@' 0"X)B50_S;R![C,"%#_-@H-Z (&@\0(OB8E3SGW
M=A"XW@A0_S8*#>CL!5M;1NOL_W8$N. (4/\V"@WHV06#Q ;IB!]5B>505K[\
M!X-\ @!T&/]V!/\TZ/P46UL)P'4%_W0"ZPB#Q@3KXC' 4%CI7!]5B>504%:+
M=@17O^8(5NC"_UN)1OZ#/O@' 70#Z=, _W;^Z<8 @S[V!P%T!X,^]@<#=0G'
M!O0' 0#IM@!7Z"W_6^FN (,^]@<!= >#/O8' W4)QP;T!P( Z9< 5^@._UOI
MCP"#/O8' 70'@S[V!P-U"<<&] <# .EX %?H[_Y;Z7 @S[V!P%T!X,^]@<#
M=0C'!O0'! #K6E?HT?Y;ZU/_-O0'ZQC'!O@' 0#'!O8' @#K/[CT"%#HL_Y;
MZS6[' A8Z3 <@S[V!P)U#L<&]@<! ,<&] < .L9N H)4.B-_EOK#\<&^ <"
M .L'NRH(6.D"'/\V^ ?I;0'_-O0'ZRQ6N*8D4.B.%%M;QP;X!P, Z5L!5NB<
MXUO'!O@' 0#I30&X&@E0Z$;^6^E" ;L\"%CIPAM6Z)W^6XE&_H-^_@%U*/\V
M] ?K&\<&^ <% .D> <<&^ <& .D5 <<&^ <( .D, ;M*"%CIC!NX,@E0Z/[]
M6^GZ %;H7/Y;B4;^@W[^ G5+_S;T!^L^QP;X!P< Z=T _S;Z!^L=QP;X!PD
MZ<X QP;X!PH Z<4 N$()4.B^_5OIN@"[6 A8Z3H;N% )4.BL_5OIJ "[8@A8
MZ2@;N%X)4.B:_5OIE@!6N*8D4.A Y%M;QP;X!P$ Z8, 5K@F)%#HHQ-;6\<&
M^ <$ .MQ5K@F)%"XIB10Z(SC@\0&QP;X!P$ ZUI6Z*GD6Z,D),<&^ <$ ,<&
M^@<( .M$5K@F)%#H9!-;6\<&^ <$ ,<&^@<) .LL5K@F)%#_-B0DN*8D4.BR
MXH/$",<&^ <! .L1N&X)4.@*_5OK![ML"%CIAQKIZQQ5B>6![ @"5E>-A@#^
MB<;'AOK] #'AOC] "XB E0_W8$Z)T-6UNC)BF#/B8I '4'N/__4.G' ,<&
M[@<F)>B$_(G'5^F< .A[_(G'@_\*=?;IE@"#OOK] '4SBP[N!XD.\ ?H7_R)
MQX/_('3V@_\)=/'&! "-A@#^.<9T;8V& /Y0Z O]6XV& /Z)QNM<B?B(!$;H
M+_R)Q^M0QX;X_0$ Q@0 @+X _@!T#XV& /Y0Z-[\6XV& /Z)QH/__W0LZ 3\
MB<?K);@! "N&^OV)AOK]Z/+[B<?K$XGXB 1&Z.;[B<?K![N&"%CIOAF#OOC]
M '4#Z4___S8F*>B'"ULQP%!8Z>@;58GE5HMV!#' 4%!6_W8(_W8&5N@1&5M0
MN! 4+@! %#H/1B#Q!#IP!M5B>7_=@3_=@:X(0!0N $ 4.A>&(/$".FG&U6)
MY5!05E>+=@2+1@8M 0")1@:#?@8 =AC_=@CH@ M;B<>#__]T"HGXB 1&@_\*
M==F#__]U"CEV!'4%,<!0ZP;&! #_=@18Z5L;58GE4%!65S'V@WX& '0T.78(
M=B^+?@:+7@3_1@2*!YC_=@I0Z,H56UN+7@KV1P00= -6ZP^)^"T! (G'"?]U
MUT;KS%98Z1,;58GE_W8$,<!0N P 4+@! %#HLA>#Q CI^QI5B>504%97BWX&
MQP8J*0 @SZ."0!T#(L>C@F /P!T ^EQ (,^B@D =03_!HH)BT8$.0:*"7T?
MBQZ*"='C ?N+'X _+740BQZ*"='C ?N+'X!_ 0!U![C__U#IXP"+'HH)T>,!
M^[B0"5#_-^@5$%M;"<!U"_\&B@FX__]0Z<$ BQZ*"='C ?N+'X/# 8D>C@G_
M!HH)BQZ."?\&C@F*!XA&_YBC*"F84/]V".A@!%M;B<8)]G0&@'[_.G4B@SZ,
M"0!T%8I&_YA0_S6XE E0_S8*#>AP (/$"+@_ %#K8T: /#IU6(L>C@F /P!T
M$(L.C@F)#BHIQP:."0 ZS^+1@0Y!HH)?12+'HH)T>,!^XL/B0XJ*?\&B@GK
M(H,^C D =!6*1O^84/\UN*P)4/\V"@WH$@"#Q BX/P!0ZP6*1O^84%CIM1E5
MB>56BW8$C48(4/]V!E;H@A&#Q ;V1 1 = 56Z&056^F3&56)Y8U&!E#_=@3_
M-@@-Z& 1@\0&BQX(#?9'!$!T"/\V" WH.Q5;Z6L958GE@S[2"0!\$3' 4%!0
M_S;2">AE"X/$".L/,<!0N,8)4.@\#UM;H]()QP8Z*0 H=()Z34958GE@S[2
M"0!\"/\VT@GH_ Y;QP;2"?__QP8Z*0 Z10958GE@S[2"0!]#.B<_PG ?04Q
MP%#K;<<&/"E +?\..BE_)[@ !%"X0"E0_S;2">CS#H/$!J,Z*8,^.BD ?P4Q
MP%#K0,<&/BE *8L>/BG_!CXI,<"*!U"+'CPI6(@'_P8\*8L>/BF /PIULO\&
M/BG_#CHIBQX\*<8' ,<&/"E +;@! %!8Z8T858GEBQX\*8 _.G0&_P8\*>OQ
MBQX\*<8' /\&/"GI;1A5B>7H4_\)P'4%,<!0ZU2+#CPIB0XL*>C&_XL./"F)
M#BXIZ+O__S8\*>A=!UNC,"GHK?__-CPIZ$\'6Z,R*>B?_XL./"F)#C0IZ)3_
MBPX\*8D.-BGHB?^+#CPIB0XX*;@L*5!8Z08858GE4%;HD_[HCO^)Q@GV= [_
M=@3_-.AU#5M;"<!UZ>BO_@GV= -6ZP,QP%!8Z=4758GE4%;H8_[H7O^)Q@GV
M= B+1@0Y1 1U[^B%_@GV= -6ZP,QP%!8Z:L758GE@^P&5E?H,@")QXMV!(GS
M1H _ '0"Z_9.3H \6'46N0H B?B9]_F#PC"(%(GXF??YB<?KY(M&!.EM%U6)
MY3' 4%!04%!0N!0 4#' 4.C0$X/$$.E4%U6)Y5:+=@97BWX$,<!05E=05NA\
M%%M05^AV%%M0N D 4+@! %#HHA.#Q!#I)!=5B>7I(!=5B>6#[ 965X-^! !U
M!C' 4.EW #' 4.AU %N)Q@GV= 4Y=@1S1;@#)%"X#@!0Z%$%6UN)1OK_=@3H
M4P!;Z&P ,<!0Z$D 6XG'_W;ZN X 4.@O!5M;.78$<PZ+1@0I^"GP]]A0Z"@
M6U?K(%;H( !;Z#D ,<!0Z!8 6XG'5^@/ %N)\"GX*T8$]]A06.F/%E6)Y3'
M4%!04%#_=@2X&P!0,<!0Z/ 2@\00Z70658GE,<!04%!04%"X'0!0,<!0Z-42
M@\00Z5D658GE@^P*5HMV!,=&]O__QT;Z@@")=OR)=OZ-1@A0_W8&C4;V4.@.
M#H/$!HU&]E QP%#HN!!;6XGPZ1P658GE4%:+=@17BWX&B7;^@#P = -&Z_B
M/0!T"HG[1XH'B 1&Z_'&! "+1O[I[!55B>56BW8$B@284(I&!IA9.<%U U;K
M"XGS1H _ '7H,<!06.G'%56)Y5:+=@2#/G V 'P'@SYP-B-\%+@. %"X;@Q0
MN ( 4.CX$8/$!NM85NA7 %M05K@" %#HY1&#Q :X @!0N'X,4+@" %#HTQ&#
MQ :+'G VT>/_M]0)Z"L 6XL><#;1XU#_M]0)N ( 4.BP$8/$!K@! %"X@@Q0
MN ( 4.B>$8/$!NE#%56)Y5!65XM^!#'VB?M'@#\ = -&Z_6)\.DG%56)Y5!6
M5XM^!HMV!(-^" !^)8G[1XH'B 1&F G = ?_3@AT NOL@WX( '0+_TX(= ;&
M! !&Z_6+1@3IZA15B>505HMV!%<Q_XH$F%"*1@:863G!=0*)]XGS1H _ '7I
MB?CIPQ15B>56BW8$5XM^!H-^" !_!3' 4.LOB?-&B@>8B?M'4(H'F%DYP740
M@'S_ '0%_TX(=>,QP%#K#8I$_YA0BD7_F%DIP5%8Z7H458GE@^P*5E?HN *)
MQ@GV=2 QP%#_=@2XD Q0N(P,4+B$#%#H<P"#Q JX?P!0Z-$/6PGV?0:X ']0
MZUJX 0!0N ( 4.B8 EM;B4;XN $ 4+@# %#HB );6XE&]HU&_E#H.Q!;B<<Y
M_G0'@___= +KZX/__W4%QT;^____=OBX @!0Z%H"6UO_=O:X P!0Z$X"6UO_
M=OY8Z>$358GE_S8 (U&!E#_=@3H1 "#Q ;IS!-5B>505HU&!HG&B?.#Q@*#
M/P!T NOT_S2-1@90_W8$Z!P @\0&Z:,358GE_S8 /]V!O]V!.@& (/$!NF.
M$U6)Y8'L% A65\>&\O< ,>&\/< (M&!HF&_O>+1@B)AOSWBY[^]X.&_O<"
M@S\ = ;_AO+WZ^R+GOSW@X;\]P*#/P!T!O^&\/?K[(N&\/<#AO+WT> %!@"-
MG@#X <.)WHN>\O<!\P.>\/>-1@ YPW(-QP9P-@< N/__4.DG 8V& /B)QXN&
M\O>)!8/' L>&]/< (N&\O<YAO3W?5:-A@#XB?$IP8F.[/>+ANSWB06#QP*+
M7@:#1@8"BP>)AO;WBY[V]X _ '0ABY[V]_^&]O>*!X@$1HU& #G&<N/'!G V
M!P"X__]0Z;P Q@0 1O^&]/?KH,<% "#QP+'AO3W "+AO#W.8;T]WU5C88
M^(GQ*<&)CNSWBX;L]XD%@\<"BUX(@T8( HL'B8;V]XN>]O> /P!T((N>]O?_
MAO;WB@>(!$:-1@ YQG+CQP9P-@< N/__4.M0Q@0 1O^&]/?KH<<% "#QP*-
MA@#XB?$IP4&[ @")R)GW^]'@B8;N]S' 4(V& /A0_W8$,<!0_[;N]_]V!.@V
M#UM0N#L 4#' 4.AC#H/$$%!8Z>,158GE5HMV!#' 4+A +E!6,<!0N 8 4%;H
M" ];4+@[ % QP%#H-0Z#Q!#IN!%5B>4QP%!04%!04+@" % QP%#H&@Z#Q!#I
MGA%5B>504%:+=@97BT8$T> M @")PXN_1BZ+3@2)#C(-@_X!= 0)]G4&B38\
M#>L4BT8$T> M @")PXFW1B['!CP-%"JX, !0,<!0Z$\.6UN)1OZ#?OX ?1.+
M1@31X"T" (G#B;]&+O]V_NL;BT8$T> M @")PXFW1BZ#?OX!=0:X 0!0ZP%7
M6.D3$5!345)65U4>!HGCBU\2B=A+ =N+GT8N_S8P#5#_TUB/!C -!Q]=7UY:
M65M8CP:4#,]5B>6#[ 96BW8$5S'_QT;Z "*!)BC9BZ#/F8N('0<@SYF+@ET
M%8,^9BX-= Z#/F8N"G0'@SYF+@QU T;KU( \+74&1L=&^@$ B?-&B@>8+3
MB4;\@W[\"G,,N H ]^>)QP-^_.OB@W[Z '0'B?CWV%#K 5=8Z6D058GE4%97
MBWX$,?:#_A1]&8GST>,YOP8-=0R)\]'CQX<� ZP-&Z^*#_A1\!KC__U#K
M*U?H_PM;_S7H!09;]D4$('0-@WT& '0'_W4&Z+D$6X/^ GX%5^BO!%LQP%!8
MZ08058GE4%:+=@3V1 08= >X__]0Z<0 .38˦BQX(#8-_ @!^"/\V" WH
MJ M;]D0$ 74G]D0$ W4'N/__4.F9 %;HD M;QT0" "+1 :)1 B!9 3]_X%,
M! $ @WP" ']1]D0$!'05N $ 4(U&_E#_-.BE!8/$!HE$ NL2N $4/]T!O\T
MZ)$%@\0&B40"@WP" '\8@WP" '4'@4P$" #K!8%,!! N/__4.LNBT0&B40(
MBT0"2(E$ O9$! 1T"8M&_B7_ %#K$HM$"(G#@\,!B5P(B<,QP(H'4%CI*@]5
MB>6#[ A65\=&^ ,?^)^]'C@[\�!T#H/_%'P&,<!0Z?@ 1^OGBUX&B@>8
M4.F5 (%.^ ( N+8!4/]V!.C@ %M;B4;Z@W[Z 'P#Z7\ ,<!0Z<@ @4[X @"X
M 0!0_W8$Z+T$6UN)1OJ#?OH ?2*#/G V G45N+8!4/]V!.BA %M;B4;Z@W[Z
M 'T&,<!0Z8P N ( 4#' 4%#_=OKHG "#Q CK*H%.^ $ ,<!0_W8$Z&\$6UN)
M1OJ#?OH ?1$QP%#K6S' 4.M6NY8,6.D8#+@* %#H^ !;B<8)]G4%,<!0ZSS'
M1 ( (M&^HD$BT;XB40$N $4.C5 %N)1 :#? 8 =0>!3 0$ .L%@4P$( "+
M1 :)1 B)^]'CB;<ɖZ0@.58GE_W8$_W8&N @ 4+@! %#HIPJ#Q CI\ U5
MB>505HM.!(D.,@V+3@:+5@B)#C@-B18Z#8M."HD.- VX$P!0N $ 4.C!"EM;
MB<8)]G0'B?"94E#K"/\V.@W_-C@-6%KIIPU5B>505HL.:BX#3@2!P?\#@>$
M_(G..39J+G<)5NB7 EL)P'0%,<!0ZQR+'FHNB7?^QT3^ #_-FHNZ H"6XDV
M:BZX 0!06.E=#56)Y8/L#%97@WX$ '4%QT8$ @#'1O0 (-^] )R ^FM (M&
M!$ E_O\% @")1O:#/FPN '4BN 0 4.AH EN)QHGP0"7^_XG&@\8"B39L+HDV
M:B['1/X ,=&_@ BS9H+@GV=%>+1/Z)1OJ+7O8!\XG?.7[Z<P+K/(M&^HU-
M CG!<P^+1OJ)1?Z)?/Z+!(D%B3PY-FPN=@4QP%#K-8-^_@!T"8L$BU[^B0?K
M!HL,B0YH+E;K'8EV_HLTZZ7_=O;H]?Y;"<!U NL&_T;TZ4K_,<!06.F'#%6)
MY8/L#%97BT8&0"7^_P4" (E&]HM>!(M'_HE&^HM&^BM&!(E&],=&_@ BS9H
M+@GV=#PY=OIS NLU.7;Z=2F+7@2+1/Z)1_Z#?OX = F+!(M>_HD'ZP:+#(D.
M:"Z+7@2+1_Z)1OKK!XEV_HLTZ\"+7O8#7@2)WSE^^G(@BT;ZC4T".<%S$8M&
M^HE%_HM>!(E__E?HD0!;_W8$ZR?_=@;HB/Y;B<<)_W4%,<!0ZQ7_=O17_W8$
MZ \ @\0&_W8$Z&8 6U=8Z;\+58GE5HMV!E>+?@2+1@C_3@@)P'0*B?M'B@>(
M!$;K[.F="U6)Y5!05E>+1@3W9@:)1@3_=@3H*_Y;B<8)]G4%,<!0ZQB)]XM&
M!(G!@^D!B4X$"<!T!L8% $?KZU98Z5\+58GE4%!65S'_BS9H+@GV= TY=@1S
M NL&B?>+-.OOBUX$B3<)_W0'BT8$B07K!XM.!(D.:"X)]G08BUX$.7?^=1"+
M7@2+1/Z)1_Z+!(M>!(D'"?]T&(M&!#E%_G40BUX$BT?^B47^BUX$BP>)!>GO
M"E6)Y5!6,<!04/]V!%!04+@1 % QP%#H3@>#Q!")Q@GV=0V+#D -B0[F##'
M4.L$N/__4%CIN0I5B>504%97BS[F#(M>! ,>Y@R)WH-^! !^!#GW=PJ#?@0
M?0HY]W,&N/__4.L05NB7_UL)P'4#5^L$N/__4%CI=@I5B>56BW8$5XM^!HH$
MF%"*!9A9.<%T#8H$F%"*!9A9*<%1ZPZ / !U!3' 4.L$1D?KV5CI0 I5B>50
M5HMV!%>)]X \ '0#1NOXB? I^.DF"E6)Y3' 4%!04%#_=@2X!@!0N $ 4.B&
M!H/$$.D*"E6)Y?]V!/]V!K@% %"X 0!0Z*<&@\0(Z? )58GE4%8QP%!0_W8&
M4/]V"/]V!+@# %"X 0!0Z$@&@\00B<:)\.G'"56)Y5!6BW8$5XM^!HEV_H ]
M '0*B?M'B@>(!$;K\<8$ (M&_NF?"56)Y3' 4%!04%#_=@2X/ !0N $ 4.C_
M!8/$$.F#"56)Y?]V!#' 4+@* %"X 0!0Z" &@\0(Z6D)58GE@^P&5E>+?@0Q
MP%!04%!04+@- %"X 0!0Z,$%@\00B<:#/C - 'P$"?9T%(L., WWV8D.<#:X
M__]0N/__4.LCBPXX#8L6.@V)3OJ)5OP)_W0+BT;ZBT[\B06)30+_=OS_=OI8
M6NG]"%6)Y5!05E>+7@2#PPN)WHM&!C'2]W8(B=>#QS"#_SE^ X/'!TZ)^(@$
MBT8&,=+W=@B)1@:#?@8 ==6+7@0I\X/#"XG?B?-&,<"*!U"+7@18B ?_1@1/
M"?]UZHM&!.F="%6)Y5!05E>+7@2#PPN)WHM&"IG_=@C_=@924.A>!XG'@\<P
M@_\Y?@.#QP=.B?B(!(M&"IG_=@C_=@924.C+!HE&!HE6"/]V"/]V!C' 4%#H
MP@4)P'6YBUX$*?.#PPN)WXGS1C' B@=0BUX$6(@'_T8$3PG_=>J+1@3I(0A5
MB>6#["165XM>!O]&!HH'F(G'"?]U ^D'"(/_)70+_W8$5^B1 EM;Z]Z-1O2)
MQHU&](E&\,=&Y BUX&@#\M=0;_1@;_1N3'1N(@ (M>!H _,'4(_T8&QT;B
M, #'1NH (M>!O]&!HH'F(G'@_\P? J#_SE_!8/O,.L.@_\J=1>+7@B#1@@"
MBS^X"@#W9NJ)1NH!?NKKRL=&Y@ QT;H "#_RYU.8M>!O]&!HH'F(G'@_\P
M? J#_SE_!8/O,.L.@_\J=1J+7@B#1@@"BS^X"@#W9NB)1N@!?NC_1N;KQ\=&
MX @_]L= 6#_TQU%O]&X(M>!H _ '0+BUX&_T8&B@>8B<=7Z1<!_T;@OQ
MZP[_1N"_"@#K!O]&X+\( (-^X !T&8M>"(-&" 17_W<"_S=6Z$[^@\0(B<;I
MZ0"+7@B#1@@"5_\W5NC8_8/$!HG&Z=, _T;@@W[@ '0\BUX(@T8(!(L'BT\"
MB4;<B4[>@W[> 'T.Q@0M1O=>W/=>WH->W@"X"@!0_W;>_W;<5NCS_8/$"(G&
MZ8X BUX(@T8( HL'B4;L@W[L 'T'Q@0M1O=>[+@* %#_=NQ6Z&?]@\0&B<;K
M8\=&XB Q@0_1NM8QT;B( "+7@B#1@@"BP>(!$;K1<=&XB BUX(@T8( HL'
MB4;P@W[P '4%QT;PW@R#?N@ =07'1NC_?XMV\( \ '06_T[H?!%&Z_.)^(@$
M1NL'NZ8,6.FW XGP*T;PB4;LBT;J*T;LB4;J@W[J 'T%QT;J "#?N0 =0/W
M7NJ#?NH ?3.+7O" /RUU&X-^XC!U%8M>\/]&\(H'F/]V!%#H1P!;6_].[/]V
M!/]VXN@Y %M;_T;J=?#_3NQ\%(M>\/]&\(H'F/]V!%#H'0!;6^OG@W[J '4#
MZ6']_W8$_W;BZ < 6UO_3NKKYU6)Y5!05HMV!E<Q__9$!!AT![C__U#IJP#V
M1 0"=0>X__]0Z9X ]D0$!'0;N $ 4(U&!%#_-.B' 8/$!HE&_L=$ @$ 1^M(
MQP9N+H4VBT0(B<.#PP$QR8I.!%&)7 B)PUB(!XM$ D")1 *!? ( !'P>]D0$
M@'48_W0"_W0&_S3H/@&#Q :)1OZ+1 :)1 A'"?]T*X-^_@!^"(M&_CE$ G08
M@W[^ 'T'@4P$$ #K!8%,! @ N/__4.L+QT0" QP(I&!%!8Z:($58GE4%8Q
M]H/^%'T:B?/1XX._!@T = R)\]'C_[<&#>A. %M&Z^'I>@15B>6#/FXN '0&
MBPYN+O_1,<!04%!04/]V!+@! % QP%#HS0"#Q!#I4015B>4QP%!04%!0_W8$
MN $ 4#' 4.BP (/$$.DT!%6)Y5!6BW8$5_9$! 1U!O9$! )U!3' 4.LW@WP"
M '\%,<!0ZRS_= +_= ;_-.A8 (/$!HG'.7P"=0['1 ( (M$!HE$"%?K"8%,
M!! N/__4%CIW0-5B>505E>+?@0QP%!04%!04+@' % QP%#H.@"#Q!")Q@GV
M? H)_W0&BPXR#8D-B?#IJ@-5B>4QP%!0_W8&4/]V"/]V!+@$ %"X 0!0Z 8
M@\00Z8H#58GEBTX(B0XR#8M."HD.- V+3@R)#C8-BTX.B0XX#8M.$(D..@V+
M3A*)#CP-_W8&_W8$Z%$ 6UOI3P-5B>504%97_W8*Z'\ 6XG'B3XR#8M."(D.
M- V+3@J)#C8-OC@-@_\.?Q2)^$\)P'0-BUX*_T8*B@>(!$;K[/]V!O]V!.@%
M %M;Z0$#58GE4%:+3@:)#C -N"X-4/]V!.A0 %M;B<8)]G0#5NL;@SXP#0!]
M$(L., WWV8D.<#:X__]0ZP3_-C -6.G" E6)Y5!6BW8$5S'_B?-&@#\ = -'
MZ_6)^$#II0*Y 0#K"KD" .L%N0, ZP!5B>6+1@2+7@;-(%W#6UE:6%:)YH=<
M EXYTW</<@8YR'<)= 2X___#,<##N $ PXL7*T<".T<$=PO1X '#BU\&A=MU
M#8G3A=MU![@4 %#I>0'_XXL7BT\"@\,$27P4.P=U]HM? H7;=0>X% !0Z5H!
M_^.)T^OO5E>)YHM<!HM$")F)USG"=38ATGT$]]MT+C'2BTP*BT0,(<!]"/?8
M]]D9T/?7]_.1]_,A_WT']]GWV(/9 (G*7UY;@\0(_^-2B<<QVR'_?0?WW_=<
M!AG?BT0*BU0,(=)]"??:]]@9VO=4_KD0 -'@T=+1TSG?=P=R"3E4!G8$XNWK
M""M4!AG[0.+C7^NE5E>)YHM<!HM$" G =1<QTHM,"HM$#/?SD??SB<I?7EN#
MQ C_XXG',=N+1 J+5 RY$ #1X-'2T=,YWW<'<@DY5 9V!.+MZ]0K5 89^T#B
MX^O*B>-2B<'W9P1:4(G0]V<"6@'"B<B)T?=G @'*6X/$!/_C5E>)YHM<!HM$
M" G =1LQTHM,"HM$#/?SD??S,=N)T(G:7UY;@\0(_^.)QS';BT0*BU0,N1
MT>#1TM'3.=]W!W().50&=@3B[>O2*U0&&?M XN/KR.A9 .C# +@& +IP#>LP
MN!( NH<-ZRBX% "ZG@WK(+@! +JU#>L8N ( NLP-ZQ"X$@"ZX@WK"+@1 +KY
M#>L ,=N''B8.A=MT!5#_TUC#NQ8 4U*X @!0Z#L Z/?[B<*#^A5S$='BNT8-
M =.+'X7;= 2)VNL>NQ<.N08 B<*!X@< Q8P (@72]'ZT?K1^N+MN@D.ZZI5
MB>7'!G0V! "+7@2)'G8VBUX(B1YX-HM>!HD>?#:X<C90N $ 4+@! +MR-KD#
M ,T@B>Q=P^B'^U]>B>Q=PUY?Z_A;65I85HGFAUP"7CG3?P]\!CG(=PET!+C_
M_\,QP,.X 0## +@
M /P4$ &, $@5D !L%:0 C!6X -P4R+C4O34E.25@ 1D%,4T4 5%)510
M0F%D('9A;'5E(&]F(&)O;VQE86XZ("(E<R(* "5S0"5S+B5S !U;FMN;W=N
M(&9L86< %1)345:3TY% "5S("5S %-94U1%30 36ES<VEN9R!365-4
M14T@9&5F:6YI=&EO;@H $1/34%)3@ 36ES<VEN9R!$3TU!24X@9&5F:6YI
M=&EO;@H $]21T%.25I!5$E/3@ 3TQ$34%)3$52 $530T%010 57-A9V4Z
M('5M86EL(%LM8R \8V]N9FEG/ET@6RUD72!;+6D@/&EN9FEL93Y=(%LM;ET@
M/'5S97)S/@H +W5S<B]L:6(O=75C<"]U;6%I;"YC9@ 8SID:3IN O=&UP
M+W5M6%A86%A8 '< <FUA:6P@,0!R !\ ' ? !X 'P > !\ 'P > !\ '@ ?
M *8!J@&N ;(!M@&Z ;X!P@'& <H!S@'2 =8!V@'> >(!Y@'J >X!2F%N $9E
M8@!-87( 07!R $UA>0!*=6X 2G5L $%U9P!397 3V-T $YO=@!$96, 4W5N
M $UO;@!4=64 5V5D %1H=0!&<FD 4V%T "5S+" E,BXR9" E<R E,BXR9" E
M,#)D.B4P,F0Z)3 R9 "P",@(X D("2@). E("5@)> FH" !&4D]-( !&
M4D]- !214-%259%1 4T5.1$52 !43P 0T, $)#0P!354)*14-4 $U%
M4U-!1T4M240 $1!5$4 $923TT@ "5S.B!N;R!&<F]M(&QI;F4 ')E;6]T
M92!F<F]M( )7,A)7, !&4D]- !$051% *"D)A9"!A9')E<W,@;W(@
M:&5A9&5R(0H )7,Z)7,* E<PH 1G)O;2 E<R E<R!R96UO=&4@9G)O
M;2 E<PH $9R;VTZ("5S(25S("@E<RD* %)E8V5I=F5D.B!B>2 E<RXE<R H
M54U!24P@)7,I('=I=&@@555#4#L*(" @(" @(" @("5S"@ 4V5N9&5R.B E
M<R H)7,I"@ 3W)G86YI>F%T:6]N.B E<PH 5$\ %1O.B E<PH 4U5"2D5#
M5 !3=6)J96-T.B E<PH $1A=&4Z("5S"@ * "5S.B E<PH )7,* $923TT@
M $9R;VT@)7,@)7,@<F5M;W1E(&9R;VT@)7,* !&<F]M("5S(25S("5S(')E
M;6]T92!F<F]M("5S"@!&4D]- E<SH@)7,A)7,* E<SH@)7,* %)E8V5I
M=F5D.B!B>2 E<RXE<R H54U!24P@)7,I('=I=&@@555#4#L*(" @(" @(" @
M("5S"@ 4D5#14E6140 %-%3D1%4@ 5$\ $-# !"0T, 4U5"2D5#5 !-
M15-304=%+4E$ !$051% !$871E.B H 1G)O;2 1G)O;2 )7,N)7,
M)7,N)7, )7,@+BXN(&1O;6%I;B!U;FMN;W=N "X )7,@+BXN(&1O;6%I;B!U
M;FMN;W=N H*15-#05!%(&1O;6%I;B!N;W0@9F]U;F0N E<R N+BX@:&]S
M="!U;G)E86-H96)L90 E<T E<P E<T E<P E<R$E<T E<P )7,A)7- )7,N
M)7, )7,A)7, )7,A)7,A)7, "5S("XN+B!H;W-T('5N:VYO=VX +@ E<R N
M+BX@:&]S="!U;FMN;W=N H*15-#05!%(&1O;6%I;B!N;W0@9F]U;F0N E
M<R N+BX@:&]S="!U;G)E86-H96)L90 E<T E<P E<R$E<P E<R N+BX@=7-E
M<B!U;FMN;W=N "]U<W(O;&EB+W5U8W O4U!/3TQ315$ "]U<W(O;&EB+W5U
M8W O4U!/3TQ315$N3$-+ !R '< )60* "5C+B4N-W,E,#0N-'@ )6,N)2XW
M<R5C)3 T+C1X "5S("XN+B!U;FMN;W=N('5S97(@870@)7, 97AE8R E<R M
M:25S("5S &QM86EL "5S("XN+B!U;FMN;W=N(&AO<W0@;6%C:&EN90!W ')M
M86EL(#0 <@!W ')M86EL(#0 52 E<R E<PI&("5S"DD@)7,*0R!R;6%I;" E
M<PH =75C< =P!R;6%I;" U %,@)7,@)7,@)7,@+2 E<R P-C8V"E,@)7,@
M)7,@)7,@+2 E<R P-C8V"@ =75C< =75C< +W5S<B]L:6(O=75C<"]U
M=6-I8V\ &5X96,@)7,@+7,E<R M>#$@/B]D978O;G5L;" F "]U<W(O;&EB
M+W5U8W O=75C:6-O O=7-R+W-P;V]L+W5U8W )"0 &5X96,@)7,@)7,@
M "]T;7 O=6UE6%A86%A8 !W '( 1G)O;2 E<R E<PH <&]S=&UA<W1E<@
M5&\Z("5S"@!3=6)J96-T.B!2971U<FYE9"!M86EL"@H " @("TM+2T@5')A
M;G-C<FEP="!O9B!S97-S:6]N(&9O;&QO=W,@+2TM+0H* E<PH "B @("TM
M+2T@56YS96YT(&UE<W-A9V4@9F]L;&]W<R M+2TM"@ ^("5S"@ ')M86EL
M " \)7, '!O<W1M87-T97( )"0 $ 0 ! $ 0"B" $
MI@@" *@( P"N" 0 L@@% +@(!@"^" < Q@@( '\< 0 # '$<<1QQ''$<KQP#
M 4 :QR0'/$;$!PO'$X<[!P! , RQS>',L<RQPY'@$ P 2'3D>&QTD'70=
M" ! &(=:QV&'0, 0!3'5P=*!X! D .1[%'/X</QVC';8=R!W?'?4=#1X3
M'P8 ___6'@D D!X* -P>( "0'B( 1\C (,>.CT "P 0D5'24X 14Y$ $1!
M5$$ $Y!3453 $1/34%)3E, 2$]35%, )3 U+C5D("5S"B @(" @( ( !>
M("5S"@!E>'!E8W1E9"!%3D0 &5X<&5C=&5D(&-L87-S('!R969I> !E>'!E
M8W1E9"!"14=)3@ 97AP96-T960@0D5'24X@;W(@0TQ!4U, 97AP96-T960@
M05-324=. &YO(&-O;6UA(&AE<F4 ;F\@8V]M;6$@:&5R90!E>'!E8W1E9"!#
M3TU-00 2'5H/R!9;W4@;75S="!B92!J;VMI;F<A !R 0 "TM E
M<SH@=6YK;F]W;B!O<'1I;VX@+25C"@ E<SH@+25C(&%R9W5M96YT(&UI<W-I
M;F<* "]E=&,O<&%S<W=D /__' HD"BX*2 I8"G *>@J4"J8*N K("M0*Y@KV
M"@@+% LJ"SP+2 M:"VH+>@N*"YP+L O$"]8+Y@OV"PX,' PR#$(,3@Q<#",
M17)R;W(@, !.;W0@;W=N97( 3F\@<W5C:"!F:6QE(&]R(&1I<F5C=&]R>0!.
M;R!S=6-H('!R;V-E<W, 26YT97)R=7!T960@<WES=&5M(&-A;&P 22]/(&5R
M<F]R $YO('-U8V@@9&5V:6-E(&]R(&%D9')E<W, 07)G(&QI<W0@=&]O(&QO
M;F< 17AE8R!F;W)M870@97)R;W( 0F%D(&9I;&4@;G5M8F5R $YO(&-H:6QD
M<F5N $YO(&UO<F4@<')O8V5S<V5S $YO="!E;F]U9V@@8V]R90!097)M:7-S
M:6]N(&1E;FEE9 !"860@861D<F5S<P!";&]C:R!D979I8V4@<F5Q=6ER960
M36]U;G0@9&5V:6-E(&)U<WD 1FEL92!E>&ES=', 0W)O<W,M9&5V:6-E(&QI
M;FL 3F\@<W5C:"!D979I8V4 $YO="!A(&1I<F5C=&]R>0!)<R!A(&1I<F5C
M=&]R>0 26YV86QI9"!A<F=U;65N= 1FEL92!T86)L92!O=F5R9FQO=P!4
M;V\@;6%N>2!O<&5N(&9I;&5S $YO="!A('1Y<&5W<FET97( %1E>'0@9FEL
M92!B=7-Y !&:6QE('1O;R!L87)G90 3F\@<W!A8V4@;&5F="!O;B!D979I
M8V4 26QL96=A;"!S965K !296%D+6]N;'D@9FEL92!S>7-T96T 5&]O(&UA
M;GD@;&EN:W, $)R;VME;B!P:7!E $UA=&@@87)G=6UE;G0 4F5S=6QT('1O
M;R!L87)G90 26YV86QI9"!E<G)N;PH #H@ * "]B:6XO<V@ <V@ "UC
M , L P!A %,L<@"B+'< ,"P?-0T 1 !:-$\ 'S15 !<T6 /-&, U31D
M %TT90#*-&8 RC1G ,HT;P B-', Z#1U !HT> 2-"AN=6QL*0 BC8
M 0!P,G R 0 $( <"YP+@( & #H#/(,_ P
M
M "U#<P- < T /D-APV'#9X-17)R
M;W(Z($1I=FES:6]N(&)Y(# @"@!);&QE9V%L($5-(&EN<W1R=6-T)VX* $5R
M<B!I;B!%32!C87-E(&EN<W1R( H 5F%R:6%B;&4@;W5T(&]F(')A;F=E"@!%
M<G(@:6X@14T@<V5T(&EN<W1R( H 1FQO871I;F<@<'0@;F]T(&EM<&PN"@!(
M96%P(&]V97)F;&]W( H 14T@=')A<" P,# P,# P(&]C=&%L"@"*-HHV
! &%P
end
END_OF_UUENCODED
fi
if test -f 'Makefile' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'Makefile'"
else
echo "x - Makefile"
sed 's/^X//' <<\END_OF_SHAR >'Makefile'
X#
X# Makefile for UMAIL Mail Router (MINIX)
X#
X# Author: Fred van Kempen, MicroWalt Corporation
X#
X# Define WMAILER if the local mailer is W-MAIL.
X# This mailer understands the "-i filename" option,
X# and this works much faster than stdIO redirecting.
X#
XCFLAGS = -DMINIX -DWMAILER
X
XBIN = /usr/bin
X
XOBJS = ummain.s umtime.s umheader.s umconvert.s \
X umroute.s umsend.s umscanner.s
XSRCS = ummain.c umtime.c umheader.c umconvert.c \
X umroute.c umsend.c umscanner.c
XOTHERS = README umail.doc umail.cf umail Makefile uucp.h umail.h
X
Xumail: Makefile $(OBJS)
X cc -i -o umail $(OBJS)
X @chmem =16000 umail >/dev/null
X
Xinstall: umail
X @rm -f $(BIN)/umail $(BIN)/rmail
X @echo 'Copying files...'
X @cp umail $(BIN)/umail
X @echo 'Setting up links...'
X @ln $(BIN)/umail $(BIN)/rmail
X @echo 'Setting up permissions:'
X chown root.root $(BIN)/umail
X chmod 6555 $(BIN)/umail
X
Xshar:
X @shar -v -o umail.shar $(OTHERS) $(SRCS)
X
Xtar:
X @tar c umail.tar $(OTHERS) $(SRCS)
X
Xummain.s: umail.h ummain.c
X cc $(CFLAGS) -S ummain.c
X
Xumtime.s: umail.h umtime.c
X cc $(CFLAGS) -S umtime.c
X
Xumheader.s: umail.h umheader.c
X cc $(CFLAGS) -S umheader.c
X
Xumconvert.s: umail.h umconvert.c
X cc $(CFLAGS) -S umconvert.c
X
Xumroute.s: umail.h umroute.c
X cc $(CFLAGS) -S umroute.c
X
Xumsend.s: umail.h uucp.h umsend.c
X cc $(CFLAGS) -S umsend.c
X
Xumscanner.s: umscanner.c
X cc $(CFLAGS) -S umscanner.c
X
END_OF_SHAR
fi
if test -f 'uucp.h' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'uucp.h'"
else
echo "x - uucp.h"
sed 's/^X//' <<\END_OF_SHAR >'uucp.h'
X/*
X * UUCP.H- DCP: A UUCP clone.
X * Definitions for the UUCP package
X *
X * Copyright Richard H. Lamb 1985,1986,1987
X * Copyright S. R. Sampson, August 1989
X * Copyright F. N. G. van Kempen Jul-Oct '89
X */
X
X#ifndef TRUE
X# define FALSE 0
X# define TRUE 1
X#endif
X
X#define LSYS "/usr/lib/uucp/L.sys"
X#define LDEVICE "/usr/lib/uucp/L-devices"
X#define UUCICO "/usr/lib/uucp/uucico"
X#define UUXQT "/usr/lib/uucp/uuxqt"
X#define RMAIL "rmail" /* Remote Mailer */
X#define SMAIL "smail" /* Internet Mailer */
X#define LMAIL "lmail" /* Local Mailer */
X#define SYSLOG "/usr/lib/uucp/Log/uucico.log"
X#define XQTLOG "/usr/lib/uucp/Log/uuxqt.log"
X#define PUBDIR "/usr/spool/uucppublic"
X#define SPOOLDIR "/usr/spool/uucp"
X#define SPOOLSEQ "/usr/lib/uucp/SPOOLSEQ"
X#define LSPOOLSEQ "/usr/lib/uucp/SPOOLSEQ.LCK"
X#define LOCKFILE "/usr/spool/locks/LCK..%s" /* terminal LOCKfile */
X#define GLOCKFILE "/usr/spool/locks/GLOCK..%s" /* terminal LOCKfile */
X#define NODENAME "/etc/uucpname"
X#define CALLFILE "C.%s"
X#define XQTFILE "X.%s"
X#define MAILFILE "B.%s"
X
X#define UUCPUSER "uucp"
X#define ERRUSER "postmaster"
X
X#define UUCPUID 40 /* RMAIL needs these */
X#define UUCPGID 40
X#define POSTUID 41 /* RMAIL needs these */
X#define POSTGID 40
X
X#define SITENAMELEN 32
X#define PATHLEN 256
X
X#define MSGTIME 20
X#define MAXPACK 256
X
X/* L.sys field defines */
X#define FLD_REMOTE 0 /* remote system name */
X#define FLD_CCTIME 1 /* legal call times */
X#define FLD_DEVICE 2 /* device, or ACU for modem */
X#define FLD_SPEED 3 /* bit rate */
X#define FLD_PHONE 4 /* phone number */
X#define FLD_EXPECT 5 /* first login "expect" field */
X#define FLD_SEND 6 /* first login "send" field */
X
END_OF_SHAR
fi
if test -f 'umail.h' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'umail.h'"
else
echo "x - umail.h"
sed 's/^X//' <<\END_OF_SHAR >'umail.h'
X/*
X * UMAIL - MINIX Remote Domain-adressing Mail Router
X *
X * This version of RMAIL handles message-headers in a much
X * more "standard" way. It can handle bang-adresses, plus
X * the new-style Internet adressing (user@host.domain).
X * It is called by programs as "Mail" and "Uuxqt".
X *
X * D E F I N I T I O N S
X *
X * Author: F. van Kempen, Jul-Oct '89 (waltje@minixug.nluug.nl)
X */
X
X#ifdef MINIX
X# define VERSION "2.5/MINIX" /* 10/19/89 */
X# define CONFIG "/usr/lib/uucp/umail.cf"
X#endif
X
X#ifdef UNIX
X# define VERSION "2.5/UNIX" /* 10/19/89 */
X# define CONFIG "/usr/lib/uucp/umail.cf"
X#endif
X
X#ifndef TRUE
X# define FALSE 0
X# define TRUE 1
X#endif
X
Xtypedef struct __name {
X struct __name *next;
X char *name;
X} NAME;
X
Xtypedef struct __var {
X struct __var *next;
X char *name;
X char *value;
X} VAR;
X
Xtypedef struct __host {
X struct __host *next;
X char *name;
X int smart;
X char *command;
X char *opts;
X} HOST;
X
Xtypedef struct __routemap {
X struct __routemap *next;
X char *domain;
X char *host;
X char *route;
X} ROUTE;
X
Xtypedef struct {
X char user[256]; /* user name of adress */
X char host[256]; /* host name of adress */
X char domain[256]; /* domain name of adress */
X} BOX;
X
X#define NILNAME ((NAME *)NULL)
X#define NILVAR ((VAR *)NULL)
X#define NILHOST ((HOST *)NULL)
X#define NILROUTE ((ROUTE *)NULL)
X#define NILBOX ((BOX *)NULL)
X
X
X/* globals in ummain.c */
Xextern char *Version; /* UMAIL version ID */
Xextern int immediate, debug; /* commandline option flags */
Xextern int restrict; /* restricted (UUCP) use only */
Xextern int aremote; /* is adressee REMOTE or LOCAL ? */
Xextern char dfile[], infile[]; /* names of message temp-files */
Xextern char errmsg[]; /* global error message */
Xextern char mailsender[]; /* who sent the message? */
Xextern char mailaddr[]; /* final routed adress to use. */
Xextern char mailhost[]; /* which host to send to */
Xextern char mailcmd[]; /* command to use to send the mail */
Xextern char mailopts[]; /* which options the mailer uses */
Xextern NAME *namelist; /* list of my network names */
Xextern VAR *varlist; /* list of configuration variables */
Xextern HOST *hostlist; /* list of reacheable host names */
Xextern ROUTE *routemap; /* list of domain routes */
X
X/* configuration settings */
Xextern char *myname; /* my UUCP site name */
Xextern char *mydomain; /* my UUCP domain name */
Xextern char *myorg; /* Name of my organization */
Xextern int oldmailer; /* mailer uses old From-lines? */
Xextern int escape; /* routing ESCAPE enable */
X
X/* external routines */
Xextern char *xtime(/* time_t *salt */);
Xextern BOX *convert(/* char *adr */);
Xextern int route(/* BOX *box */);
Xextern int header(/* FILE *infp, FILE *outfp */);
Xextern char *strupr(/* char *s */);
Xextern char *strlwr(/* char *s */);
Xextern void add_name(/* char *name */);
Xextern void add_host(/* char *name, int smart, char *cmd, char *opts */);
Xextern void add_route(/* char *domain, char *host, char *route */);
Xextern void add_var(/* char *name, char *val */);
Xextern char *lookup(/* char *what */);
Xextern int boolean(/* char *ascii */);
Xextern HOST *gethost(/* char *host */);
Xextern ROUTE *getdomain(/* char *domain */);
Xextern char *mfgets(/* char *s, int n, FILE *iop */);
Xextern char *whoami(/* void */);
Xextern char *full_id(/* char *user */);
Xextern char *realname(/* char *who */);
Xextern char *maketime(/* long *salt */);
Xextern void fcopy(/* FILE *inf, FILE *outf */);
Xextern int scanner(/* char *fname */);
Xextern int KnowHost(/* char *name */);
Xextern int islocal(/* char *name */);
Xextern char *genname(/* int prefix, int grade, char *sysname */);
Xextern int send_local(/* char *user, char *data */);
Xextern int send_remote(/* char *rmtname, char *rmtuser, char *data */);
Xextern void errmail(/* char *str, int mgronly */);
Xextern int sendit(/* char *who, char *host, char *cmd, char *opts, char *data */);
END_OF_SHAR
fi
if test -f 'ummain.c' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'ummain.c'"
else
echo "x - ummain.c"
sed 's/^X//' <<\END_OF_SHAR >'ummain.c'
X/*
X * UMAIL - MINIX Remote Domain-adressing Mail Router
X *
X * This version of RMAIL handles message-headers in a much
X * more "standard" way. It can handle bang-adresses, plus
X * the new-style Internet adressing (user@host.domain).
X * It is called by programs as "Mail" and "Uuxqt".
X *
X * Usage: umail [-c <config>] [-d] [-i <infile>] [-n] <user> ...
X *
X * Author: F. van Kempen, Jul-Oct '89 (waltje@minixug.nluug.nl)
X */
X#include <stdio.h>
X#include <string.h>
X#include <alloc.h>
X#include <ctype.h>
X#include <time.h>
X#include <pwd.h>
X#include "umail.h"
X
X
Xchar *Version = VERSION; /* UMAIL version ID */
Xint immediate, debug = FALSE; /* commandline option flags */
Xint restrict = FALSE; /* restricted (UUCP) use only */
Xint aremote; /* is the adressee REMOTE or LOCAL ? */
Xchar dfile[128], infile[128]; /* names of message temp-files */
Xchar errmsg[512]; /* global error message */
Xchar mailsender[1024]; /* who sent the message? */
Xchar mailaddr[1024]; /* final routed adress to use. */
Xchar mailhost[64]; /* which host to send to */
Xchar mailcmd[512]; /* command to use to send the mail */
Xchar mailopts[64]; /* which options the mailer uses */
XNAME *namelist = NILNAME; /* list of my network names */
XVAR *varlist = NILVAR; /* list of configuration variables */
XHOST *hostlist = NILHOST; /* list of reacheable host names */
XROUTE *routemap = NILROUTE; /* list of domain routes */
X
X/* configuration settings */
Xchar *myname = NULL; /* my UUCP site name */
Xchar *mydomain = NULL; /* my UUCP domain name */
Xchar *myorg = NULL; /* Name of my organization */
Xint oldmailer = FALSE; /* does our mailer use old From-lines? */
Xint escape = FALSE; /* can we offer a routing-escape? */
X
X
Xextern int getopt(), optind; /* from standard library */
Xextern char *optarg, *fgets();
Xextern long ftell();
X
X
X/*
X * Convert strings S to upper case.
X */
Xchar *strupr(s)
Xchar *s;
X{
X register char *sp;
X
X sp = s;
X while (*sp) {
X if (*sp>='a' && *sp<='z') *sp = _toupper(*sp);
X sp++;
X }
X return(s);
X}
X
X
X/*
X * Convert strings S to lower case.
X */
Xchar *strlwr(s)
Xchar *s;
X{
X register char *sp;
X
X sp = s;
X while (*sp) {
X if (*sp>='A' && *sp<='Z') *sp = _tolower(*sp);
X sp++;
X }
X return(s);
X}
X
X
X/*
X * Add 'NAME' to the list of our names.
X */
Xvoid add_name(name)
Xchar *name;
X{
X register NAME *np, *xp;
X
X np = (NAME *) malloc(sizeof(NAME)); /* allocate new variable */
X if (namelist == NILNAME) { /* first variable */
X namelist = np;
X } else {
X xp = namelist;
X while (xp->next != NILNAME) xp = xp->next;
X xp->next = np;
X }
X
X np->next = NILNAME;
X np->name = (char *) malloc(strlen(name) + 2);
X
X strcpy(np->name, name);
X}
X
X
X/*
X * Add host 'NAME' to the list of hosts.
X */
Xvoid add_host(name, smart, cmd, opts)
Xchar *name;
Xint smart;
Xchar *cmd;
Xchar *opts;
X{
X register HOST *hp, *xp;
X
X hp = (HOST *) malloc(sizeof(HOST)); /* allocate new variable */
X if (hostlist == NILHOST) { /* first variable */
X hostlist = hp;
X } else {
X xp = hostlist;
X while (xp->next != NILHOST) xp = xp->next;
X xp->next = hp;
X }
X
X hp->next = NILHOST;
X hp->name = (char *) malloc(strlen(name) + 2);
X hp->command = (char *) malloc(strlen(cmd) + 2);
X hp->opts = (char *) malloc(strlen(opts) + 2);
X
X strcpy(hp->name, name);
X strcpy(hp->command, cmd);
X strcpy(hp->opts, opts);
X hp->smart = smart;
X}
X
X
X/*
X * Add route 'DOMAIN' to the routing table.
X */
Xvoid add_route(domain, host, route)
Xchar *domain;
Xchar *host;
Xchar *route;
X{
X register ROUTE *rp, *xp;
X
X rp = (ROUTE *) malloc(sizeof(ROUTE)); /* allocate new route */
X if (routemap == NILROUTE) { /* first route */
X routemap = rp;
X } else {
X xp = routemap;
X while (xp->next != NILROUTE) xp = xp->next;
X xp->next = rp;
X }
X
X rp->next = NILROUTE;
X rp->domain = (char *) malloc(strlen(domain) + 2);
X rp->host = (char *) malloc(strlen(host) + 2);
X rp->route = (char *) malloc(strlen(route) + 2);
X
X strcpy(rp->domain, domain);
X strcpy(rp->host, host);
X strcpy(rp->route, route);
X}
X
X
X/*
X * Add variable 'NAME' to the variable list.
X */
Xvoid add_var(name, val)
Xchar *name;
Xchar *val;
X{
X register VAR *vp, *xp;
X
X strupr(name);
X
X vp = (VAR *) malloc(sizeof(VAR)); /* allocate new variable */
X if (varlist == NILVAR) { /* first variable */
X varlist = vp;
X } else {
X xp = varlist;
X while (xp->next != NILVAR) xp = xp->next;
X xp->next = vp;
X }
X
X vp->next = NILVAR;
X vp->name = (char *) malloc(strlen(name) + 2);
X vp->value = (char *) malloc(strlen(val) + 2);
X
X strcpy(vp->name, name);
X strcpy(vp->value, val);
X}
X
X
X/*
X * Get a variable from the variable list.
X * Return NULL if not defined.
X */
Xchar *lookup(what)
Xchar *what;
X{
X register VAR *vp;
X
X vp = varlist;
X while (vp != NILVAR) {
X if (!strcmp(vp->name, what)) return(vp->value);
X vp = vp->next;
X }
X return(NULL);
X}
X
X
X/*
X * Return TRUE or FALSE value, depending on
X * the value of the given variable.
X */
Xint boolean(ascii)
Xchar *ascii;
X{
X strupr(ascii);
X if (ascii==NULL || !strcmp(ascii, "FALSE")) return(FALSE);
X else if (!strcmp(ascii, "TRUE")) return(TRUE);
X else fprintf(stderr, "Bad value of boolean: \"%s\"\n", ascii);
X return(FALSE);
X}
X
X
X/*
X * Lookup a host in our hosts-table.
X */
XHOST *gethost(host)
Xchar *host;
X{
X register HOST *hp;
X
X hp = hostlist;
X while (hp != NILHOST) {
X if (!strcmp(hp->name, host)) return(hp);
X hp = hp->next;
X }
X return(NILHOST);
X}
X
X
X/*
X * Lookup a domain in our domain-table.
X */
XROUTE *getdomain(domain)
Xchar *domain;
X{
X register ROUTE *rp;
X
X rp = routemap;
X while (rp != NILROUTE) {
X if (!strcmp(rp->domain, domain)) return(rp);
X rp = rp->next;
X }
X return(NILROUTE);
X}
X
X
X/*
X * mfgets (modified fgets)
X * Same as fgets() only this version deletes '\n'
X */
Xchar *mfgets(s, n, iop)
Xchar *s;
Xregister int n;
Xregister FILE *iop;
X{
X register int c;
X register char *cs;
X
X cs = s;
X while (--n > 0 && (c = getc(iop)) != EOF) {
X if (c == '\n') {
X *cs = '\0';
X break;
X } else *cs++ = c;
X }
X return((c == EOF && cs == s) ? (char *)NULL : s);
X}
X
X
X/*
X * Return the full UUCP ID of the calling user
X */
Xchar *full_id(user)
Xchar *user;
X{
X static char fullbuf[48];
X
X sprintf(fullbuf, "%s@%s.%s", user, myname, mydomain);
X return(fullbuf);
X}
X
X
X/*
X * Return the Real Name of the calling user
X */
Xchar *realname(who)
Xchar *who;
X{
X struct passwd *pw;
X
X if ((pw = getpwnam(who)) != NULL) return(pw->pw_gecos);
X else return("unknown flag");
X}
X
X
X/*
X * Make a decent DATE/TIME string.
X * Note, that there are TWO possible date formats:
X *
X * Sat, 12 Oct 89 20:29:00\0
X * and
X * Sat 12 Oct 20:29:00 1989\0
X *
X * Most Internet mailers use this first form, so we try
X * to this also. We use the function xtime() for the work...
X */
Xchar *maketime(salt)
Xlong *salt;
X{
X static char datetime[48]; /* date and time in MET format */
X char *sp;
X
X sp = lookup("TIMEZONE"); /* get Time Zone from config file */
X if (sp == NULL) sp = ""; /* must have SOME pointer! */
X
X sprintf(datetime, "%s %s", xtime(salt), sp);
X
X return(datetime);
X}
X
X
X/*
X * Copy a file from 'inf' to 'outf'.
X */
Xvoid fcopy(inf, outf)
Xregister FILE *inf, *outf;
X{
X char cpbuff[1024];
X
X while (TRUE) {
X if (fgets(cpbuff, sizeof(cpbuff), inf) == (char *)NULL) break;
X fwrite(cpbuff, sizeof(char), strlen(cpbuff), outf);
X }
X}
X
X
X/*
X * Load the configuration parameters into their variables.
X */
Xstatic void setup(cfg)
Xchar *cfg;
X{
X if (scanner(cfg) != 0) { /* read the configuration file */
X perror(cfg);
X exit(1);
X }
X
X myname = lookup("SYSTEM");
X if (myname == NULL) {
X fprintf(stderr, "Missing SYSTEM definition\n");
X exit(-1);
X }
X mydomain = lookup("DOMAIN");
X if (mydomain == NULL) {
X fprintf(stderr, "Missing DOMAIN definition\n");
X exit(-1);
X }
X myorg = lookup("ORGANIZATION");
X oldmailer = boolean(lookup("OLDMAILER"));
X escape = boolean(lookup("ESCAPE"));
X}
X
X
X/*
X * Something went wrong.
X * Tell the caller how we should be called!
X */
Xstatic void usage()
X{
X fprintf(stderr,
X "Usage: umail [-c <config>] [-d] [-i <infile>] [-n] <users>\n");
X}
X
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X FILE *fdfile, *infp; /* message file pointers */
X BOX *box; /* conversion/routing adresses */
X char *cfgfile = CONFIG; /* config file; to save space */
X register int st; /* error status, to exit() */
X
X if (argv[0][0] == 'r') { /* 'rmail' link? */
X restrict = TRUE; /* yes, restrict usage */
X }
X
X while ((st = getopt(argc, argv, "c:di:n")) != EOF) switch(st) {
X case 'c': /* use non-standard CONFIGH file */
X cfgfile = optarg;
X break;
X
X case 'd': /* turn on DEBUG mode */
X debug = TRUE;
X break;
X case 'i': /* use non-stdin input file */
X strncpy(infile, optarg, 128 - 1);
X break;
X case 'n': /* call UUCICO after processing */
X immediate = TRUE;
X break;
X default:
X usage();
X exit(1);
X }
X
X if (optind >= argc) { /* we need another parameter! */
X usage(); /* (the adressee ) */
X exit(-1);
X }
X
X umask(0117); /* change umask to -rw-rw---- */
X
X setup(cfgfile); /* read CONFIG and setup */
X
X strcpy(dfile, "/tmp/umXXXXXX"); /* create temp. message file */
X mktemp(dfile);
X if ((fdfile = fopen(dfile, "w")) == (FILE *)NULL) {
X perror("rmail 1");
X exit(1);
X }
X
X box = convert(argv[optind]); /* convert Internet adress to UUCP */
X if (box == NILBOX) st = FALSE;
X else st = route(box); /* run it through routing tables */
X
X if (infile[0] != '\0') { /* open input file if -i option */
X infp = fopen(infile, "r");
X if (infp == (FILE *)NULL) {
X perror(infile);
X exit(1);
X }
X } else infp = stdin; /* otherwise use stdin! */
X
X header(infp, fdfile); /* analyze message header */
X
X fcopy(infp, fdfile); /* copy message to the temp. file */
X
X fclose(fdfile);
X if (infp != stdin) fclose(infp);
X
X if (st == FALSE) { /* conversion/routing went wrong? */
X errmail(errmsg, FALSE); /* yes; return the message! */
X st = -1;
X } else st = sendit(mailaddr, mailhost, mailcmd, mailopts, dfile);
X
X unlink(dfile); /* remote data file */
X exit(st); /* and exit! */
X}
END_OF_SHAR
fi
if test -f 'umtime.c' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'umtime.c'"
else
echo "x - umtime.c"
sed 's/^X//' <<\END_OF_SHAR >'umtime.c'
X/*
X * XTIME - Create ASCII string of the given time.
X * This file contains a modified version
X * of the ctime(3) function from the MINIX
X * C library. The format of the string is:
X *
X * Sat, Oct 14 89 20:26:00\0
X *
X */
X#include <time.h>
X
X
Xstatic int days_per_month[] = {
X 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
X};
Xstatic char *months[] = {
X "Jan", "Feb", "Mar", "Apr", "May", "Jun",
X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
X};
Xstatic char *days[] = {
X "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
X};
X
X#define MIN 60L /* # seconds in a minute */
X#define HOUR (60 * MIN) /* # seconds in an hour */
X#define DAY (24 * HOUR) /* # seconds in a day */
X#define YEAR (365 * DAY) /* # seconds in a year */
X
X
Xchar *xtime(pt)
Xlong *pt;
X{
X static struct tm tm;
X static char xtmbuf[30];
X
X register long t = *pt;
X long year;
X
X tm.tm_year = 0;
X tm.tm_mon = 0;
X tm.tm_mday = 1;
X tm.tm_hour = 0;
X tm.tm_min = 0;
X tm.tm_sec = 0;
X
X /* t is elapsed time in seconds since Jan 1, 1970. */
X tm.tm_wday = (int) (t/DAY + 4L) % 7; /* Jan 1, 1970 is 4th wday */
X while (t >= (year=((tm.tm_year%4)==2) ? YEAR+DAY : YEAR)) {
X tm.tm_year += 1;
X t -= year;
X }
X tm.tm_year += 1970;
X
X /* t is now the offset into the current year, in seconds. */
X tm.tm_yday = (t/DAY); /* day # of the year, Jan 1 = 0 */
X
X days_per_month[1] = 28;
X if ((tm.tm_year % 4) == 0) /* check for leap year */
X days_per_month[1]++;
X
X /* Compute month. */
X while (t >= (days_per_month[tm.tm_mon] * DAY))
X t -= days_per_month[tm.tm_mon++] * DAY;
X
X /* Month established, now compute day of the month */
X while (t >= DAY) {
X t -= DAY;
X tm.tm_mday++;
X }
X
X /* Day established, now do hour. */
X while (t >= HOUR) {
X t -= HOUR;
X tm.tm_hour++;
X }
X
X /* Hour established, now do minute. */
X while (t >= MIN) {
X t -= MIN;
X tm.tm_min++;
X }
X
X /* Residual time is # seconds. */
X tm.tm_sec = (int) t;
X
X /* Generate output in ASCII in _buf_. */
X sprintf(xtmbuf, "%s, %2.2d %s %2.2d %02d:%02d:%02d",
X days[tm.tm_wday], tm.tm_mday, months[tm.tm_mon],
X tm.tm_year - 1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
X return(xtmbuf);
X}
END_OF_SHAR
fi
if test -f 'umheader.c' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'umheader.c'"
else
echo "x - umheader.c"
sed 's/^X//' <<\END_OF_SHAR >'umheader.c'
X/*
X * UMAIL - MINIX Remote Domain-adressing Mail Router
X *
X * This version of RMAIL handles message-headers in a much
X * more "standard" way. It can handle bang-adresses, plus
X * the new-style Internet adressing (user@host.domain).
X * It is called by programs as "Mail" and "Uuxqt".
X *
X * M A I L H E A D E R C O N V E R S I O N M O D U L E
X *
X * Headers: This module reads the header part of a message into
X * memory, and then rearranges it into RFC-822 order.
X * The preferred order of fields is:
X *
X * 1. From (old-style V6/V7)
X * 2. From:
X * 3. Received: (top to bottom)
X * 4. Sender:
X *
X * 5. Unknown fields (user-defined)
X *
X * 6. To:
X * 7. Cc:
X * 8. Bcc:
X * 9. Subject:
X * 10. Message-ID:
X * 11. Date:
X *
X * This order may be changed and/or expanded in the future,
X * especially the "Resent-" fields should be added.
X *
X * Author: F. van Kempen, Jul-Oct '89 (waltje@minixug.nluug.nl)
X */
X#include <stdio.h>
X#include <alloc.h>
X#include <string.h>
X#include <time.h>
X#include "umail.h"
X
X
Xtypedef struct __hdr {
X struct __hdr *next;
X int done; /* 1==READ, 0==UNREAD */
X int count; /* 1==FIRST, 2.. == NEXT PART */
X int std; /* 1==RFC, 0==USER_DEFINED */
X char *name; /* field name */
X char *value; /* field value */
X} HEADER;
X#define NILHEAD ((HEADER *)NULL)
X
X
Xstatic HEADER *hlist = NILHEAD; /* old message header */
Xstatic char *rfcfields[] = { /* list of RFC-822 fields */
X "FROM ", "FROM", "RECEIVED", "SENDER",
X "TO", "CC", "BCC", "SUBJECT",
X "MESSAGE-ID", "DATE", NULL
X};
Xstatic char olduser[1024]; /* old user */
Xstatic char olddate[48]; /* old date */
Xstatic char oldhost[48]; /* old host machine */
X
X
X/*
X * Look for a field in the header table in memory.
X * If found, return its value, otherwise return NULL.
X */
Xstatic char *hfind(name)
Xchar *name;
X{
X register HEADER *hp;
X char tmp[48];
X
X hp = hlist;
X while (hp != NILHEAD) {
X strcpy(tmp, hp->name);
X strupr(tmp);
X if (!strcmp(tmp, name)) return(hp->value);
X hp = hp->next;
X }
X return(NULL);
X}
X
X
X/*
X * Look for a field in the header table in memory.
X * If found, mark the field as READ, and return its adress.
X * Otherwise, return NILHEAD.
X */
Xstatic HEADER *hsearch(name)
Xchar *name;
X{
X register HEADER *hp;
X char tmp[48];
X
X hp = hlist;
X while (hp != NILHEAD) {
X strcpy(tmp, hp->name);
X strupr(tmp);
X if (!strcmp(tmp, name)) {
X if (hp->done == 0) {
X hp->done = 1;
X return(hp);
X }
X }
X hp = hp->next;
X }
X return(NILHEAD);
X}
X
X
X/*
X * Decode an old-style (V6/V7) mail header.
X * This has a syntax like:
X *
X * From <user> <date> [remote from <host>]
X * To: <user>
X * Subject: <text>
X *
X * We want to find out the <user>, <date> and possible <date> fields.
X * Return TRUE for OK, or FALSE if error.
X */
Xstatic int get_oldhdr(rmt)
Xint *rmt; /* REMOTE or LOCAL mail? */
X{
X register char *bp, *sp, *cp;
X
X sp = hfind("FROM ");
X if (sp == NULL) { /* No From-line??? */
X sprintf(errmsg, "%s: no From line", dfile);
X return(FALSE);
X }
X
X strcpy(olduser, sp); /* stuff field into 'user' */
X sp = olduser; /* skip until <date> field */
X while (*sp && *sp!=' ' && *sp!='\t') sp++;
X *sp++ = '\0'; /* mark 'end-of-user' */
X
X /*
X * SP now contains <date> and (possible) <remote> fields.
X * Parse line to seek out "remote from".
X */
X cp = sp; /* save the Date-pointer */
X while (TRUE) {
X bp = strchr(sp++, 'r');
X if (bp != NULL) { /* we found an 'r' */
X if (!strncmp(bp, "remote from ", 12)) break;
X } else break;
X }
X
X if (bp != NULL) { /* remote host found --> remote mail */
X sp = strrchr(bp, ' '); /* seek to start of "remote from" text */
X *(bp - 1) = '\0'; /* mark end-of-date */
X strcpy(olddate, cp); /* set old date */
X strcpy(oldhost, ++sp); /* set host name */
X sprintf(mailsender, "%s!%s", oldhost, olduser);
X *rmt = TRUE;
X } else {
X strcpy(olddate, cp); /* set old date */
X strcpy(oldhost, ""); /* no remote host */
X strcpy(mailsender, olduser);
X *rmt = FALSE;
X }
X return(TRUE);
X}
X
X
X/*
X * Analyze the current header.
X *
X * See if this mail was generated locally or came from somewhere else.
X * Note, that old-style mailers use "postmarks" (i.e. header lines
X * looking like "From <user> <date>" with a possible suffix of
X * "remote from <host>". New-style mailers (should) only use the
X * "From: <path>" and "Date: <date>" lines in their headers.
X * UMAIL knows both types. By default it uses new-style headers,
X * but it can use (and generate) old headers by defining OLDMAILER.
X *
X * Return TRUE if we think this mail has been generated remotely,
X * or FALSE if this message was generated by local mail.
X */
Xstatic int chk_hdr(void)
X{
X int remmail; /* remote mail? */
X long now;
X register char *sp, *bp; /* fast scanning pointers */
X
X bp = hfind("FROM"); /* get RFC-From: field */
X sp = hfind("DATE"); /* get RFC-Date: field */
X
X if (sp==NULL || bp==NULL) { /* should have both or none! */
X if (oldmailer == TRUE) { /* try old-style header */
X if (get_oldhdr(&remmail) == FALSE) {
X strcat(errmsg, "\n\nBad adress or header!\n");
X return(FALSE);
X }
X }
X } else { /* only use new-style From:=lines */
X strcpy(olddate, sp); /* Save the DATE field */
X strcpy(oldhost, bp);
X sp = oldhost; /* skip comments */
X while (*sp && *sp!=' ' && *sp!='\t') sp++;
X *sp = '\0';
X strcpy(mailsender, oldhost);
X
X sp = strchr(oldhost, '!'); /* check for pathname! */
X if (sp != NULL) { /* found one; this was remote! */
X remmail = TRUE;
X *sp++ = '\0';
X strcpy(olduser, sp);
X } else {
X remmail = FALSE;
X strcpy(olduser, bp);
X strcpy(oldhost, "");
X }
X }
X return(remmail);
X}
X
X
X/*
X * Create a new RFC-822 message header.
X * This is necessary because we are processing
X * a locally-generated message.
X * The header should become:
X *
X * From <host!user> <date> remote from <here>
X * From: <host>!<user>
X * Received: by <here> with <proto>;
X * <receive-date>
X * Sender: <user>@<host>.<domain> (Real Name)
X * To: <user>
X * Subject: <text>
X */
Xstatic void new_hdr(outfp)
XFILE *outfp;
X{
X long rcvtm; /* current time */
X char *date; /* current date in MET */
X char *fmt1 = "%s:%s\n";
X char *fmt2 = "%s\n";
X register char *sp;
X
X /* get the current date and time */
X time(&rcvtm); date = maketime(&rcvtm);
X
X if (oldmailer == TRUE) {
X fprintf(outfp, "From %s %s remote from %s\n",
X olduser, xtime(&rcvtm), myname);
X }
X fprintf(outfp, "From: %s!%s (%s)\n", myname, olduser, realname(olduser));
X fprintf(outfp, "Received: by %s.%s (UMAIL %s) with UUCP;\n %s\n",
X myname, mydomain, Version, date);
X fprintf(outfp, "Sender: %s (%s)\n", full_id(olduser), realname(olduser));
X if (myorg != NULL) fprintf(outfp, "Organization: %s\n", myorg);
X if ((sp = hfind("TO")) != NULL) fprintf(outfp, "To: %s\n", sp);
X if ((sp = hfind("SUBJECT")) != NULL) fprintf(outfp, "Subject: %s\n", sp);
X fprintf(outfp, "Date: %s\n", olddate);
X fprintf(outfp, "\n");
X}
X
X
X/*
X * Update the current header.
X * This is necessary because the message comes from
X * a remote system without RFC-conforming mailer...
X * We should include ALL RFC-822 fields in this routine!
X */
Xstatic void upd_hdr(outfp)
XFILE *outfp;
X{
X long rcvtm; /* current time */
X char *date; /* current date in MET */
X char *fmt1 = "%s: %s\n";
X char *fmt2 = "%s\n";
X register char *sp;
X register HEADER *hp;
X
X /* get the current date and time */
X time(&rcvtm); date = maketime(&rcvtm);
X
X /* First of all, get the Old V6/V7 From-line */
X if (oldmailer == TRUE) {
X hp = hsearch("FROM "); /* to make it DONE */
X if (oldhost[0] == '\0')
X fprintf(outfp, "From %s %s remote from %s\n",
X olduser, xtime(&rcvtm), myname);
X else fprintf(outfp, "From %s!%s %s remote from %s\n",
X oldhost, olduser, xtime(&rcvtm), myname);
X }
X
X /*
X * Write the modified From:-line
X * Note, that we must only add our name if the mail is to be forwarded
X * to another system. If it will be delivered locally, leave it.
X */
X hp = hsearch("FROM");
X if (hp != NILHEAD) {
X if (aremote == TRUE) { /* adressee is REMOTE. add our name! */
X fprintf(outfp, "%s: %s!%s\n", hp->name, myname, hp->value);
X } else { /* adressee is LOCAL */
X fprintf(outfp, "%s: %s\n", hp->name, hp->value);
X }
X }
X
X /* Our own Receive:-line */
X fprintf(outfp, "Received: by %s.%s (UMAIL %s) with UUCP;\n %s\n",
X myname, mydomain, Version, date);
X
X /* Next, all other Received:-lines */
X while ((hp = hsearch("RECEIVED")) != NILHEAD) {
X if (hp->count > 1) fprintf(outfp, fmt2, hp->value);
X else fprintf(outfp, fmt1, hp->name, hp->value);
X }
X
X /* The old Sender:-line */
X hp = hsearch("SENDER");
X if (hp != NILHEAD) {
X if (hp->count > 1) fprintf(outfp, fmt2, hp->value);
X else fprintf(outfp, fmt1, hp->name, hp->value);
X }
X
X /* insert all unknown fields here */
X hp = hlist;
X while (hp != NILHEAD) {
X if (hp->std == 0) {
X hp->done = 1;
X fprintf(outfp, fmt1, hp->name, hp->value);
X }
X hp = hp->next;
X }
X
X /* Write the To:-line too */
X hp = hsearch("TO");
X if (hp != NILHEAD) {
X if (hp->count > 1) fprintf(outfp, fmt2, hp->value);
X else fprintf(outfp, fmt1, hp->name, hp->value);
X }
X
X /* The CarbonCopy Cc:-line */
X hp = hsearch("CC");
X if (hp != NILHEAD) {
X if (hp->count > 1) fprintf(outfp, fmt2, hp->value);
X else fprintf(outfp, fmt1, hp->name, hp->value);
X }
X
X /* And the BlindCarbonCopy as well */
X hp = hsearch("BCC");
X if (hp != NILHEAD) {
X if (hp->count > 1) fprintf(outfp, fmt2, hp->value);
X else fprintf(outfp, fmt1, hp->name, hp->value);
X }
X
X /* Finally, the old Subject:-line */
X hp = hsearch("SUBJECT");
X if (hp != NILHEAD) {
X if (hp->count > 1) fprintf(outfp, fmt2, hp->value);
X else fprintf(outfp, fmt1, hp->name, hp->value);
X }
X
X /* A message ID */
X hp = hsearch("MESSAGE-ID");
X if (hp != NILHEAD) {
X if (hp->count > 1) fprintf(outfp, fmt2, hp->value);
X else fprintf(outfp, fmt1, hp->name, hp->value);
X }
X
X /* And the old date of sending */
X hp = hsearch("DATE");
X if (hp != NILHEAD) {
X if (hp->count > 1) fprintf(outfp, fmt2, hp->value);
X else fprintf(outfp, fmt1, hp->name, hp->value);
X } else fprintf(outfp, fmt1, "Date: ", date);
X
X /* an empty line marks the end of the header! */
X fprintf(outfp, "\n");
X}
X
X
X/*
X * Read the message-header into memory.
X */
Xstatic int read_hdr(infp)
Xregister FILE *infp;
X{
X char hdrbuf[1024];
X char lastf[128];
X int i, numfields = 0;
X int lastc = 1;
X register HEADER *hp, *xp;
X register char *bp, *sp;
X
X while (TRUE) {
X if (mfgets(hdrbuf, 1024, infp) == NULL) break; /* end of file */
X if (hdrbuf[0] == '\0') break; /* end of header */
X
X numfields++;
X bp = hdrbuf;
X
X /* first check if this is the V6/V7 From-line */
X if (strncmp(hdrbuf, "From ", 5)) {
X /* No From-line. */
X if (*bp==' ' || *bp=='\t') {
X lastc++; /* next part of previous field */
X bp = lastf; /* previous field */
X sp = hdrbuf; /* value */
X } else {
X sp = strchr(bp, ':'); /* plain field, get sepa */
X if (sp != NULL) { /* do we have one? */
X *sp++ = '\0'; /* end it */
X while (*sp && (*sp==' ' || *sp=='\t')) sp++;
X strcpy(lastf, bp); /* set as prev field */
X lastc = 1;
X } else sp = bp; /* no sepa, use entire field */
X }
X } else {
X bp = "From ";
X sp = &hdrbuf[5];
X }
X
X /* Add a new header field to the message header in memory */
X hp = (HEADER *) malloc(sizeof(HEADER)); /* allocate new variable */
X if (hlist == NILHEAD) { /* first variable */
X hlist = hp;
X } else {
X xp = hlist;
X while (xp->next != NILHEAD) xp = xp->next;
X xp->next = hp;
X }
X
X hp->next = NILHEAD;
X hp->name = (char *) malloc(strlen(bp) + 2);
X hp->value = (char *) malloc(strlen(sp) + 2);
X
X strcpy(hp->name, bp);
X strcpy(hp->value, sp);
X hp->done = 0; /* not yet read */
X hp->count = lastc; /* folding level */
X hp->std = 0; /* standard field? */
X
X /* now see if this field is an RFC-822 field */
X i = 0;
X sp = rfcfields[i];
X strcpy(hdrbuf, hp->name); /* convert field name to uppercase */
X strupr(hdrbuf);
X while (sp != NULL) {
X if (!strcmp(sp, hdrbuf)) break;
X sp = rfcfields[++i];
X }
X if (sp != NULL) hp->std = 1;
X }
X}
X
X
X/*
X * Read the header from the input file 'infd', and adapt some
X * fields to the new values.
X * Then, sort the entries and generate a new header.
X * Put that new header into file 'outfp'.
X * Return TRUE if REMOTE, FALSE if LOCAL mail.
X */
Xint header(infp, outfp)
Xregister FILE *infp;
Xregister FILE *outfp;
X{
X int remote;
X char *sp;
X
X (void) read_hdr(infp); /* read in the current header */
X
X remote = chk_hdr(outfp); /* analyze old header */
X
X if (remote == FALSE) new_hdr(outfp); /* locally-generated mail */
X else upd_hdr(outfp);
X
X return(remote);
X}
END_OF_SHAR
fi
if test -f 'umconvert.c' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'umconvert.c'"
else
echo "x - umconvert.c"
sed 's/^X//' <<\END_OF_SHAR >'umconvert.c'
X/*
X * UMAIL - MINIX Remote Domain-adressing Mail Router
X *
X * This version of RMAIL handles message-headers in a much
X * more "standard" way. It can handle bang-adresses, plus
X * the new-style Internet adressing (user@host.domain).
X * It is called by programs as "Mail" and "Uuxqt".
X *
X * A D R E S S C O N V E R S I O N M O D U L E
X *
X * Convert adresses into manageable chunks.
X *
X * We understand the following notations:
X *
X * 1. user@host.domain --> waltje@minixug.UUCP
X *
X * 2. host!user --> minixug!waltje
X *
X * 3. user --> waltje
X *
X * Return TRUE (1) if OK, or FALSE (0) if an error was encountered.
X *
X * Author: F. van Kempen, Jul-Oct '89 (waltje@minixug.nluug.nl)
X */
X#include <stdio.h>
X#include <alloc.h>
X#include <string.h>
X#include "umail.h"
X
X
X/*
X * Convert adress 'adr' into more manageable chunks.
X * Stuff the output into 'mailaddr' (the final user)
X * and 'mailcmd' (the mailer command to use).
X * Return NILBOX if an error ocurred.
X */
XBOX *convert(adr)
Xchar *adr;
X{
X static BOX box;
X char temp[1024];
X register char *bp, *sp, *cp;
X register ROUTE *rp;
X register HOST *hp;
X
X strcpy(mailaddr, adr);
X box.domain[0] = box.host[0] = '\0';
X box.user[0] = temp[0] = '\0';
X
X /*
X * Rule 1: Check for user@host.domain
X */
X sp = strrchr(mailaddr, '@');
X if (sp != NULL) {
X *sp++ = '\0';
X strcpy(box.user, mailaddr);
X strcpy(temp, sp);
X strlwr(temp); /* convert domain to lower case: RFC822 */
X
X /*
X * Rule 1A: Now check for "." in the domain part.
X * This indicates that a host name was given.
X */
X sp = strchr(temp, '.'); /* syntax host.domain ?? */
X if (sp == NULL) { /* no, onlky 'host' part */
X hp = gethost(temp); /* is this a local host? */
X if (hp != NILHOST) { /* yes! */
X strcpy(box.host, temp);
X box.domain[0] = '\0';
X return(&box);
X } else { /* no, must be a domain.... */
X strcpy(box.domain, temp);
X box.host[0] = '\0';
X return(&box);
X }
X } else { /* domain and host given! */
X *sp++ = '\0';
X strcpy(box.host, temp);
X strcpy(box.domain, sp);
X return(&box);
X }
X }
X
X /*
X * Rule 2: Check for host!user
X */
X sp = strchr(mailaddr, '!');
X if (sp != NULL) {
X *sp++ = '\0';
X strcpy(box.host, mailaddr);
X strcpy(box.user, sp);
X return(&box);
X }
X
X /*
X * Rule 3: Must be local user.
X */
X strcpy(box.user, mailaddr);
X box.host[0] = '\0';
X box.domain[0] = '\0';
X return(&box);
X}
X
END_OF_SHAR
fi
if test -f 'umroute.c' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'umroute.c'"
else
echo "x - umroute.c"
sed 's/^X//' <<\END_OF_SHAR >'umroute.c'
X/*
X * UMAIL - MINIX Remote Domain-adressing Mail Router
X *
X * This version of RMAIL handles message-headers in a much
X * more "standard" way. It can handle bang-adresses, plus
X * the new-style Internet adressing (user@host.domain).
X * It is called by programs as "Mail" and "Uuxqt".
X *
X * M A I L R O U T E R M O D U L E
X *
X * Some rules exist for routing to other machines.
X *
X * 1. Check for local system names.
X *
X * 2. If we have a domain, check it for validity.
X *
X * 3. If we have a hostname, check it for validity.
X *
X * 4. Local user: check existence.
X *
X * Examples are:
X *
X * user@host.domain@newdomain -
X * -> ast@cs.vu@nluug.nl
X * host!user@domain
X * --> cs.vu!ast@nluug.nl
X *
X * If we cannot find a matching domain or system name,
X * then we get stuck. Fortunately, we can define the
X * ESCAPE parameter, which allows us to send all mail
X * for unknown hosts or domains to a "default" domain.
X * This is the domain called "." in the tables.
X * If the ESCAPE parameter is FALSE, we cannot deliver
X * the message, so return it to the sender!
X *
X * Return TRUE (1) if OK, or FALSE (0) if an error was encountered.
X *
X * Author: F. van Kempen, Jul-Oct '89 (waltje@minixug.nluug.nl)
X */
X#include <stdio.h>
X#include <alloc.h>
X#include <pwd.h>
X#include <string.h>
X#include "umail.h"
X
X
X/*
X * Route the adress in BOX into a ready-to-run
X * UUCP adress.
X */
Xint route(b)
XBOX *b;
X{
X char temp[1024];
X register char *bp, *sp;
X register ROUTE *rp;
X register HOST *hp;
X struct passwd *pw;
X
X /*
X * Rule 1: check for local system names.
X * convert to LOCAL if possible.
X */
X if (b->domain[0] == '\0') strcpy(temp, b->host);
X else sprintf(temp, "%s.%s", b->host, b->domain);
X if (islocal(temp)) {
X b->host[0] = '\0';
X b->domain[0] = '\0';
X }
X
X /*
X * Rule 2: Do we have a domain?
X */
X if (b->domain[0] != '\0') { /* domain given? */
X if (b->host[0]) sprintf(temp, "%s.%s", b->host, b->domain);
X else strcpy(temp, b->domain);
X strcpy(b->host, temp);
X bp = temp;
X rp = NILROUTE;
X while (TRUE) { /* iterate on domain fragments */
X sp = bp;
X rp = getdomain(bp);
X if (rp != NILROUTE) { /* a matching domain! */
X strcpy(b->domain, bp);
X break;
X }
X bp = strchr(sp, '.');
X if (bp == NULL) break;
X else bp++;
X }
X
X /*
X * We now have checked the DOMAIN table for a matching domain.
X * If we failed to find a match, there is a problem.
X * If the mailer was defined with the ESCAPE parameter, we can
X * try to route it to the default (".") domain.
X * Otherwise, we cannot deliver the message...
X */
X
X /* check if we found a matching domain */
X if (rp == NILROUTE) { /* we did not. try to re-route it */
X if (escape == FALSE) {
X sprintf(errmsg, "%s ... domain unknown", b->domain);
X return(FALSE);
X }
X rp = getdomain("."); /* get default domain! */
X if (rp == NILROUTE) {
X sprintf(errmsg, "%s ... domain unknown", b->domain);
X strcat(errmsg, "\n\nESCAPE domain not found.");
X return(FALSE);
X }
X }
X
X /*
X * At this point we have all the information we
X * need to build an UUCP-adress.
X * We have a HOST as well.
X * Check if we can indeed reach that host.
X */
X hp = gethost(rp->host);
X if (hp == NILHOST) {
X sprintf(errmsg, "%s ... host unreacheble", rp->host);
X return(FALSE);
X }
X
X /* is the host smart enough to get "@"-adresses?? */
X if (hp->smart == TRUE) { /* yes, it is! */
X if (*(rp->route) == '@') {
X if (b->host[0] == '\0') sprintf(mailaddr,"%s@%s",
X b->user, b->domain);
X else sprintf(mailaddr, "%s@%s", b->user, b->host);
X } else {
X if (b->host[0] == '\0') sprintf(mailaddr,"%s!%s@%s",
X rp->route, b->user, b->domain);
X else sprintf(mailaddr, "%s!%s@%s.%s",
X rp->route, b->user, b->host, b->domain);
X }
X } else {
X if (b->host[0] == '\0') sprintf(mailaddr,"%s!%s",
X rp->route, b->user);
X else sprintf(mailaddr, "%s!%s!%s",
X rp->route, b->host, b->user);
X }
X strcpy(b->host, rp->host);
X
X /*
X * We now have a HOST and an ADRESS.
X */
X strcpy(mailcmd, hp->command);
X strcpy(mailopts, hp->opts);
X strcpy(mailhost, b->host);
X aremote = TRUE;
X return(TRUE);
X }
X
X /*
X * Rule 3: Do we have a host name ?
X */
X if (b->host[0] != '\0') { /* host name given? */
X b->domain[0] = '\0'; /* signal 'no routing' */
X hp = gethost(b->host);
X if (hp == NILHOST) {
X if (escape == FALSE) {
X sprintf(errmsg, "%s ... host unknown", b->host);
X return(FALSE);
X }
X rp = getdomain("."); /* get default domain! */
X if (rp == NILROUTE) {
X sprintf(errmsg, "%s ... host unknown", b->host);
X strcat(errmsg, "\n\nESCAPE domain not found.");
X return(FALSE);
X }
X
X /*
X * We now have a HOST as well.
X * Check if we can indeed reach that host.
X */
X strcpy(b->domain, rp->host);
X hp = gethost(rp->host);
X if (hp == NILHOST) {
X sprintf(errmsg, "%s ... host unreacheble", rp->host);
X return(FALSE);
X }
X }
X
X /*
X * USER contains the user-part
X * HOST contains the (old) host-part
X * DOMAIN now contains the new hostname
X */
X
X /* is the host smart enough to get "@"-adresses?? */
X if (b->domain[0] != '\0') { /* are we routing? */
X if (hp->smart == TRUE) sprintf(mailaddr, "%s@%s",
X b->user, b->host);
X else sprintf(mailaddr, "%s!%s", b->host, b->user);
X strcpy(b->host, b->domain);
X } else { /* no, ordinary case */
X strcpy(mailaddr, b->user);
X }
X
X strcpy(mailhost, b->host);
X strcpy(mailcmd, hp->command);
X strcpy(mailopts, hp->opts);
X aremote = TRUE;
X return(TRUE);
X }
X
X /*
X * Rule 4: Check for local user.
X */
X if ((pw = getpwnam(b->user)) == (struct passwd *)NULL) {
X sprintf(errmsg, "%s ... user unknown", b->user);
X return(FALSE);
X }
X hp = gethost(myname);
X strcpy(mailaddr, b->user);
X mailhost[0] = '\0';
X strcpy(mailcmd, hp->command);
X strcpy(mailopts, hp->opts);
X aremote = FALSE;
X return(TRUE);
X}
END_OF_SHAR
fi
if test -f 'umsend.c' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'umsend.c'"
else
echo "x - umsend.c"
sed 's/^X//' <<\END_OF_SHAR >'umsend.c'
X/*
X * UMAIL - MINIX Remote Domain-adressing Mail Router
X *
X * This version of RMAIL handles message-headers in a much
X * more "standard" way. It can handle bang-adresses, plus
X * the new-style Internet adressing (user@host.domain).
X * It is called by programs as "Mail" and "Uuxqt".
X *
X * M A I L T R A N S P O R T M O D U L E
X *
X * Author: F. van Kempen, Jul-Oct '89 (waltje@minixug.nluug.nl)
X */
X#include <stdio.h>
X#include <sys/types.h>
X#include <dirent.h>
X#include <errno.h>
X#include <string.h>
X#include <time.h>
X#include <uucp.h>
X#include "umail.h"
X
X
X/*
X * Check the host machine name.
X *
X * returns FALSE if not found, else TRUE
X */
Xint KnowHost(name)
Xchar *name;
X{
X register HOST *hp;
X
X hp = gethost(name);
X return((hp==NILHOST) ? FALSE : TRUE);
X}
X
X
X/*
X * Check if this is one of our local names.
X * Return 1 if TRUE, or 0 if FALSE.
X */
Xint islocal(name)
Xchar *name;
X{
X register NAME *np;
X
X np = namelist;
X while (np != NILNAME) {
X if (!strcmp(np->name, name)) return(TRUE);
X np = np->next;
X }
X return(FALSE);
X}
X
X
X/*
X * Creates a unique UUCP file name, and returns a pointer
X * to it. The filename is a combination of prefix, grade, system name
X * and a sequential number taken from SPOOLSEQ.
X */
Xchar *genname(prefix, grade, sysname)
Xint prefix, grade;
Xchar *sysname;
X{
X static char _gen_buf[128];
X int i = 0;
X char seqline[10];
X char *seqname = SPOOLSEQ; /* to save some string space */
X char *lseqname = LSPOOLSEQ; /* to save some string space */
X FILE *spoolseq;
X
X if (access(seqname, 0) != 0) close(creat(seqname, 0600));
X
X while(link(seqname, lseqname) != 0) {
X sleep(5);
X if (++i > 5) return(NULL);
X }
X
X spoolseq = fopen(seqname, "r");
X fgets(seqline, sizeof(seqline), spoolseq);
X fclose(spoolseq);
X unlink(lseqname);
X
X i = (atoi(seqline) + 1);
X
X if ((spoolseq = fopen(seqname, "w")) == (FILE *)NULL) return(NULL);
X fprintf(spoolseq, "%d\n", i);
X fclose(spoolseq);
X
X if (grade == 0) sprintf(_gen_buf, "%c.%.7s%04.4x", prefix, sysname, i);
X else sprintf(_gen_buf, "%c.%.7s%c%04.4x", prefix, sysname, grade, i);
X
X return(_gen_buf);
X}
X
X
X/*
X * Deliver this message to a local user.
X * We do this by calling "LMAIL" (which is actually
X * a link to "Mail"; the Local Mail Agent.
X */
Xint send_local(user, data)
Xchar *user;
Xchar *data;
X{
X struct passwd *pw;
X char tmpbuf[128];
X
X /* See if destination user name exists on this machine */
X pw = (struct passwd *) getpwnam(user);
X if (pw == (struct passwd *)NULL) {
X sprintf(tmpbuf, "%s ... unknown user at %s", user, myname);
X errmail(tmpbuf, FALSE);
X }
X
X#ifdef WMAILER /* faster than redirecting! */
X sprintf(tmpbuf, "exec %s -i%s %s", LMAIL, data, user);
X#else
X sprintf(tmpbuf, "exec %s <%s %s", LMAIL, data, user);
X#endif WMAILER
X
X return(system(tmpbuf));
X}
X
X
X/*
X * Deliver this message to a remote user.
X * We do this by creating the spoolfiles needed by UUCICO.
X * Then we call that program daemon to do the real work.
X */
Xint send_remote(rmtname, rmtuser, data)
Xchar *rmtname;
Xchar *rmtuser;
Xchar *data;
X{
X char tmpbuf[128];
X char Bfile[128], Cfile[128], Dfile[128], Xfile[128];
X FILE *fcfile, *fbfile, *fdfile, *fp;
X
X if (KnowHost(rmtname) == FALSE) {
X sprintf(tmpbuf, "%s ... unknown host machine", rmtname);
X errmail(tmpbuf, FALSE);
X }
X
X /* make the spool files for uucico */
X strcpy(Bfile, genname('B', 0, rmtname));
X strcpy(Cfile, genname('C', 'N', rmtname));
X strcpy(Dfile, genname('D', 0, myname));
X strcpy(Xfile, genname('X', 'N', rmtname));
X
X /* Copy the temp-file to the UUCP data file (D.???) */
X if ((fdfile = fopen(Dfile, "w")) == (FILE *)NULL) {
X perror("rmail 4");
X exit(1);
X } else {
X fp = fopen(data, "r"); /* open temp-file */
X fcopy(fp, fdfile);
X fclose(fdfile);
X fclose(fp);
X }
X
X if ((fbfile = fopen(Bfile, "w")) == (FILE *)NULL) {
X perror("rmail 4");
X exit(1);
X } else {
X fprintf(fbfile, "U %s %s\nF %s\nI %s\nC rmail %s\n",
X UUCPUSER, myname, Dfile, Dfile, rmtuser);
X fclose(fbfile);
X }
X
X if ((fcfile = fopen(Cfile, "w")) == (FILE *)NULL) {
X perror("rmail 5");
X exit(1);
X } else {
X fprintf(fcfile,"S %s %s %s - %s 0666\nS %s %s %s - %s 0666\n",
X Dfile, Dfile, UUCPUSER, Dfile, Bfile, Xfile, UUCPUSER, Bfile);
X fclose(fcfile);
X }
X
X /* RMAIL is setUID root... UUCP cannot read these files! */
X chown(Bfile, UUCPUID, UUCPGID);
X chown(Cfile, UUCPUID, UUCPGID);
X chown(Dfile, UUCPUID, UUCPGID);
X chown(Xfile, UUCPUID, UUCPGID);
X
X if (immediate == TRUE) { /* call uucico now! */
X strcpy(tmpbuf, UUCICO);
X sprintf(tmpbuf, "exec %s -s%s -x1 >/dev/null &", UUCICO, rmtname);
X system(tmpbuf);
X }
X
X return(FALSE);
X}
X
X
X/*
X * Perform the mail-transport.
X * We do this by calling the appropriate mailer.
X * If the name of the mailer is "$$" then we can use
X * this program to deliver. This saves a lot of memory.
X */
Xint sendit(who, host, cmd, opts, data)
Xchar *who; /* who is the adressee? */
Xchar *host; /* on which machine? */
Xchar *cmd; /* what command should we use? */
Xchar *opts; /* which options? */
Xchar *data; /* name of data (message) file */
X{
X char cmdline[512];
X char tmpbuff[512];
X
X chdir(SPOOLDIR); /* Change to UUCP directory */
X
X if (!strcmp(cmd, "$$")) { /* run our own mail routines */
X if (*host == '\0') send_local(who, data);
X else send_remote(host, who, data);
X } else {
X sprintf(tmpbuff, "exec %s %s ", cmd, opts);
X sprintf(cmdline, tmpbuff, data); /* create commandline */
X strcat(cmdline, who); /* add user adress */
X system(cmdline); /* execute command (mailer) */
X }
X}
X
X
X/*
X * Send mail to system manager upon errors
X *
X * Mail is contained in a file referenced
X * by Global variable 'dfile'
X */
Xvoid errmail(str, mgronly)
Xchar *str;
Xint mgronly;
X{
X FILE *fp, *tp;
X long now;
X char fname[32];
X char tmp[128];
X
X strcpy(fname, "/tmp/umeXXXXXX");
X mktemp(fname);
X
X tp = fopen(fname, "w");
X fp = fopen(dfile, "r");
X
X time(&now);
X
X /* create header of the report-message */
X fprintf(tp, "From %s %s\n", ERRUSER, xtime(&now));
X if (mailsender != NULL) fprintf(tp, "To: %s\n", mailsender);
X fprintf(tp, "Subject: Returned mail\n\n");
X
X /* create an error transcript */
X fprintf(tp, " ---- Transcript of session follows ----\n\n");
X fprintf(tp, "%s\n", str);
X fprintf(tp, "\n ---- Unsent message follows ----\n");
X
X /* copy the message */
X while (mfgets(tmp, sizeof(tmp), fp) != (char *)NULL)
X fprintf(tp, "> %s\n", tmp);
X
X fclose(tp); /* flush and close message file */
X fclose(fp); /* flush and close orig. file */
X
X /* Return mail to system manager (and sender if mgronly == FALSE) */
X if (mgronly == FALSE) sendit(mailsender, "", RMAIL, " <%s", fname);
X
X /* send mail to UUCP administrator */
X sendit(ERRUSER, "", "$$", "", fname);
X
X unlink(fname); /* remove data files */
X unlink(dfile);
X
X exit(1); /* and exit! */
X}
END_OF_SHAR
fi
if test -f 'umscanner.c' -a "${1}" != "-c"
then
echo "$0: Will not overwrite existing file: 'umscanner.c'"
else
echo "x - umscanner.c"
sed 's/^X//' <<\END_OF_SHAR >'umscanner.c'
X/*
X * UMAIL - MINIX Remote Domain-adressing Mail Router
X *
X * This version of RMAIL handles message-headers in a much
X * more "standard" way. It can handle bang-adresses, plus
X * the new-style Internet adressing (user@host.domain).
X * It is called by programs as "Mail" and "Uuxqt".
X *
X * C O N F I G U R A T I O N F I L E S C A N N E R
X *
X * Author: F. van Kempen, Jul-Oct '89 (waltje@minixug.nluug.nl)
X */
X#include <stdio.h>
X
X
Xtypedef struct {
X char *name;
X int opcode;
X} WORD;
X
X
X/* operator opcodes */
X#define O_ASSIGN 1 /* ":=" */
X#define O_COMMA 2 /* "," */
X#define O_BEGIN 3 /* "BEGIN" */
X#define O_END 4 /* "END" */
X#define O_DATA 5 /* "DATA" */
X#define O_NAMES 6 /* "NAMES" */
X#define O_DOMAIN 7 /* "DOMAINS" */
X#define O_HOST 8 /* "HOST" */
X
X
X/* main scanner states */
X#define S_LOOK 1 /* looking for a keyword */
X#define S_BEGIN 2 /* got O_BEGIN */
X#define S_END 3 /* got O_END */
X
X/* block classes */
X#define SC_DATA 1 /* DATA (variable) class */
X#define SC_NAMES 2 /* NAMES (my domains) class */
X#define SC_DOMAIN 3 /* DOMAIN TABLE class */
X#define SC_HOST 4 /* HOSTS class */
X
X#define SS_LOOK 1 /* looking for keyword or variable name */
X#define SS_IDENT 2 /* looking for identifier */
X#define SS_ASSIGN 3 /* got varname, looking for O_COMMA */
X#define SS_COMMA 4 /* got varname, looking for O_ASSIGN */
X#define SS_VALUE 5 /* got O_ASSIGN, looking for value */
X#define SS_DOMAIN1 6 /* got domain, looking for hostname */
X#define SS_DOMAIN2 7 /* got boolean, looking for domain descr. */
X#define SS_HOST1 8 /* got host, looking for boolean */
X#define SS_HOST2 9 /* got host, looking for host mailer name */
X#define SS_HOST3 10 /* got host, looking for host mailer opts */
X
X
Xstatic FILE *infp; /* input file pointer */
Xstatic char scbuf[1024]; /* input line buffer */
Xstatic char *scptr = NULL; /* input line pointer */
Xstatic char *errptr = NULL; /* error pointer */
Xstatic char sctemp1[128]; /* current identifier */
Xstatic char sctemp2[128]; /* current identifier */
Xstatic int scbool; /* temp. boolean value */
Xstatic int lineno = 1; /* current line number */
Xstatic int sclass = SC_DATA; /* temporary state */
Xstatic int state = S_LOOK; /* state of scanner */
Xstatic int sstate = SS_LOOK; /* secondairy state */
Xstatic int tstate = SS_LOOK; /* triple state */
Xstatic WORD table[] = { /* language table */
X { ":=" , O_ASSIGN },
X { "," , O_COMMA },
X { "BEGIN" , O_BEGIN },
X { "END" , O_END },
X { "DATA" , O_DATA },
X { "NAMES" , O_NAMES },
X { "DOMAINS" , O_DOMAIN },
X { "HOSTS" , O_HOST },
X};
X
X
Xextern int debug;
X
X
X/*
X * Return next character of input file;
X * also do some bookkeeping for error-recovery.
X */
Xstatic int nextch(void)
X{
X register int ch;
X
X ch = fgetc(infp);
X if (ch == '\n') {
X lineno++;
X *scptr = '\0';
X scptr = scbuf;
X } else *scptr++ = ch;
X return(ch);
X}
X
X
X/*
X * Handle a syntax error.
X * Also, perform some error recovery.
X */
Xstatic void syntax(s)
Xchar *s;
X{
X register char *bp, *ep;
X register int ch;
X
X ep = errptr;
X do {
X ch = nextch(); /* read up to end of line */
X } while (ch!='\n' && ch!=EOF); /* and start over on next line */
X
X sstate = SS_LOOK; /* reset state machine #2 */
X
X fprintf(stderr, "%05.5d %s\n ", lineno, scbuf);
X bp = scbuf;
X ep--;
X while (bp < ep) {
X fprintf(stderr, " ");
X bp++;
X }
X fprintf(stderr, "^ %s\n", s);
X}
X
X
X/*
X * Check the text of a keyword.
X */
Xstatic int crunch(text)
Xchar *text;
X{
X register WORD *wp;
X
X wp = &table[0];
X while (wp->opcode != 0) {
X if (!strcmp(wp->name, text)) return(wp->opcode);
X wp++;
X }
X return(0);
X}
X
X
X/*
X * Decode a word, and perform some action if necessary.
X * This routine holds all the syntax grammar.
X * It is far from perfect, but it works...
X */
Xstatic void do_word(name)
Xchar *name;
X{
X int op; /* decoded keyword code */
X char *s = "expected END";
X
X op = crunch(name);
X if (sstate == SS_LOOK) switch(op) {
X case O_DATA:
X if (state==S_LOOK || state==S_END) sclass = SC_DATA;
X else syntax(s);
X break;
X case O_NAMES:
X if (state==S_LOOK || state==S_END) sclass = SC_NAMES;
X else syntax(s);
X break;
X case O_DOMAIN:
X if (state==S_LOOK || state==S_END) sclass = SC_DOMAIN;
X else syntax(s);
X break;
X case O_HOST:
X if (state==S_LOOK || state==S_END) sclass = SC_HOST;
X else syntax(s);
X break;
X case O_BEGIN:
X switch(sclass) {
X case SC_DATA:
X case SC_DOMAIN:
X case SC_HOST:
X case SC_NAMES:
X sstate = SS_LOOK;
X state = S_BEGIN;
X break;
X default:
X syntax("expected class prefix");
X break;
X }
X break;
X case O_END:
X if (state == S_BEGIN) {
X state = S_LOOK;
X sclass = 0;
X } else syntax("expected BEGIN");
X break;
X default:
X sstate = SS_IDENT;
X break;
X }
X switch(sstate) {
X case SS_LOOK: /* propagated from the above switch() */
X break;
X case SS_IDENT: /* looking for identifier */
X switch(sclass) {
X case SC_DATA:
X case SC_HOST:
X case SC_DOMAIN:
X strcpy(sctemp1, name);
X sstate = SS_ASSIGN;
X break;
X case SC_NAMES:
X add_name(name);
X sstate = SS_LOOK;
X break;
X default:
X syntax("expected BEGIN or CLASS");
X }
X break;
X case SS_ASSIGN: /* looking for O_ASSIGN */
X op = crunch(name);
X if (op == O_ASSIGN) switch(sclass) { /* found O_ASSIGN */
X case SC_DATA:
X sstate = SS_VALUE;
X break;
X case SC_DOMAIN:
X sstate = SS_DOMAIN1;
X break;
X case SC_HOST:
X sstate = SS_HOST1;
X break;
X default:
X break;
X } else syntax("expected ASSIGN");
X break;
X case SS_COMMA: /* field separator */
X op = crunch(name);
X if (op == O_COMMA) switch(sclass) {
X case SC_DOMAIN:
X sstate = SS_DOMAIN2;
X break;
X case SC_HOST:
X switch(tstate) {
X case SS_HOST1:
X sstate = SS_HOST2;
X break;
X case SS_HOST2:
X sstate = SS_HOST3;
X break;
X default:
X syntax("no comma here");
X break;
X }
X break;
X default:
X syntax("no comma here");
X break;
X } else syntax("expected COMMA");
X break;
X case SS_VALUE: /* looking for value */
X add_var(sctemp1, name);
X sstate = SS_LOOK;
X break;
X case SS_DOMAIN1: /* looking for route hostname */
X strcpy(sctemp2, name);
X sstate = SS_COMMA;
X break;
X case SS_DOMAIN2: /* looking for host route */
X add_route(sctemp1, sctemp2, name);
X sstate = SS_LOOK;
X break;
X case SS_HOST1: /* looking for host 'smart' boolean */
X scbool = boolean(name);
X sstate = SS_COMMA;
X tstate = SS_HOST1;
X break;
X case SS_HOST2: /* looking for host mailer name */
X strcpy(sctemp2, name); /* mailer name */
X sstate = SS_COMMA; /* look for mailer opts */
X tstate = SS_HOST2;
X break;
X case SS_HOST3: /* looking for host mailer opts */
X add_host(sctemp1, scbool, sctemp2, name);
X sstate = SS_LOOK;
X break;
X default: /* this can't be for real! */
X syntax("Huh? You must be joking!");
X break;
X }
X}
X
X
X/*
X * This is the Configuration File Scanner.
X * It has *some* level of intelligence, but is must
X * be improved a lot.
X */
Xint scanner(fname)
Xchar *fname;
X{
X char wordbuf[512];
X register char *bp = wordbuf;
X register int ch;
X register int quote = 0;
X register int stopped = 0;
X
X infp = fopen(fname, "r");
X if (infp == (FILE *)NULL) return(-1);
X
X scptr = scbuf;
X ch = nextch();
X do {
X switch(ch) {
X case '#': /* comment, skip rest of line */
X do {
X ch = nextch();
X } while (ch != '\n');
X break;
X case ' ': /* SPACE */
X case '\t':
X if (quote == 0) {
X errptr = scptr;
X do { /* skip rest of leading space */
X ch = nextch();
X } while (ch==' ' || ch=='\t');
X *bp = '\0';
X if (bp != wordbuf) {
X do_word(wordbuf);
X bp = wordbuf;
X }
X } else {
X *bp++ = ch;
X ch = nextch();
X }
X break;
X case EOF: /* EOF, done! */
X stopped = 1;
X case '\n': /* end-of-word marker, handle word */
X *bp = '\0';
X if (wordbuf[0]) {
X do_word(wordbuf);
X bp = wordbuf;
X }
X if (ch != EOF) ch = nextch();
X break;
X case '"': /* quote, set/reset quoting flag */
X quote = 1 - quote;
X ch = nextch();
X break;
X default: /* anything else: text */
X *bp++ = ch;
X ch = nextch();
X break;
X }
X } while (!stopped);
X
X fclose(infp);
X
X return(0);
X}
END_OF_SHAR
fi
echo " End of archive"
rm -f /tmp/uudecode
exit 0
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+
| MINIX User Group (Holland) UUCP: hp4nl!kyber!minixug!waltje |
| c/o Fred van Kempen, or: minixug!waltje@kyber.UUCP |
| Hoefbladhof 27 |
| 2215 DV VOORHOUT |
| The Netherlands "A good programmer knows his Sources" |
+-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-+