Commit 079b060c authored by Petter Reinholdtsen's avatar Petter Reinholdtsen

[svn-inject] Forking sysvinit source to Trunk

parent 45eb7dfe
Sysvinit is Copyright (C) 1991-2004 Miquel van Smoorenburg
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
On Debian GNU/Linux systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL'.
contrib Unofficial stuff
doc Documentation, mostly obsolete
man Manual pages, not obsolete
obsolete Really obsolete stuff ;)
src Source code
There are several things on the wishlist. See also the "wishlist" bugs filed
against sysvinit in the debian bugs system (http://www.debian.org/Bugs/).
1. A special target for kbrequest, so that extra CHILDs are
created (each one needs its own utmp/wtmp bookkeeping)
2. Extend the initreq.h interface?
3. Add GNU last long options to last
4. Write all boot messages to a logfile
Problem: TIOCCONS ioctl redirects console output, it doesn't copy it.
I think this is not easily possible without kernel support.
I do not like the idea of booting with a pseudo tty as console and
a redirect process behind it writing to both the real console and a
logfile - too fragile.
I proposed moving some stuff to a seperate file, such as the
re-exec routines. Alexander wrote:
According to Alexander Viro <viro@math.psu.edu>:
> As for the code separation - I think it's nice. Actually, read_inittab()
> with get_part() and newFamily are also pretty separatable. Another good
> set is any(), spawn(), startup(), spawn_emerg() and start_if_needed().
> BTW, fail_check();process_signals(); is equivalent to process_signal();
> fail_check();. I think that swapping them (in main loop) would be a good
> idea - then we can move fail_check() into start_if_needed(). And one more
> - I'ld propose to move start_if_needed to the beginning of the main loop,
> as in
> foo();
> while(1) { bar();foo();
> #if 0
> baz();
> #endif
> }
> to
> while(1) { foo();bar();
> #if 0
> baz();
> #endif
> }
>
>
> What do you think about it?
Start-stop-daemon is the program that is used by the DEBIAN style init
scripts to start and stop services. This program is part of the "dpkg"
package by Ian Jackson. However there is also a seperate C version (the
original is in perl) available written by Marek Michalkiewicz. I'm including
it for your convinience.
Note that the latest debian dpkg packages (4.0.18 and later) contain
a much improved update-rc.d. This code is almost a year old.
The original announcement follows:
From: Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>
Message-Id: <199606060324.FAA19493@i17linuxb.ists.pwr.wroc.pl>
Subject: Fast start-stop-daemon in C
To: debian-devel@lists.debian.org
Date: Thu, 6 Jun 1996 05:24:18 +0200 (MET DST)
Some time ago I wrote a faster C replacement for the start-stop-daemon
perl script. I use it for some time now (the most recent changes were
just a nicer help screen; the code is quite stable).
This makes the system boot faster (especially on low end machines),
and important system startup scripts no longer depend on another big
package (perl). Maybe in the future we can get to the point where
a minimal system will work without perl installed at all (packages
which need it in {pre,post}{inst,rm} scripts would depend on perl).
The only problem known so far to me is that I have to reinstall this
program after every dpkg upgrade which overwrites it with that nice
slooow perl script :-).
Just compile this program and drop the binary in /usr/sbin instead
of the original /usr/sbin/start-stop-daemon perl script (make a copy
of it first, just in case). See below for source code. I placed it
in the public domain, but if it has to be GPL-ed to be included in
dpkg, just tell me. Including it in dpkg would close Bug#1670.
I am posting it here so that it can be tested by more people than
just me. Bugs are unlikely though.
Have fun,
Marek
/*
* A rewrite of the original Debian's start-stop-daemon Perl script
* in C (faster - it is executed many times during system startup).
*
* Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
* public domain.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <getopt.h>
#include <pwd.h>
#define VERSION "version 0.3, 1996-06-05"
static int testmode = 0;
static int quietmode = 0;
static int exitnodo = 1;
static int start = 0;
static int stop = 0;
static int signal_nr = 15;
static int user_id = -1;
static const char *userspec = NULL;
static const char *cmdname = NULL;
static char *execname = NULL;
static char *startas = NULL;
static const char *pidfile = NULL;
static const char *progname = "";
static struct stat exec_stat;
struct pid_list {
struct pid_list *next;
int pid;
};
static struct pid_list *found = NULL;
static struct pid_list *killed = NULL;
static void *xmalloc(int size);
static void push(struct pid_list **list, int pid);
static void do_help(void);
static void parse_options(int argc, char * const *argv);
static int pid_is_exec(int pid, const struct stat *esb);
static int pid_is_user(int pid, int uid);
static int pid_is_cmd(int pid, const char *name);
static void check(int pid);
static void do_pidfile(const char *name);
static void do_procfs(void);
static void do_stop(void);
#ifdef __GNUC__
static void fatal(const char *format, ...)
__attribute__((noreturn, format(printf, 1, 2)));
static void badusage(const char *msg)
__attribute__((noreturn));
#else
static void fatal(const char *format, ...);
static void badusage(const char *msg);
#endif
static void
fatal(const char *format, ...)
{
va_list arglist;
fprintf(stderr, "%s: ", progname);
va_start(arglist, format);
vfprintf(stderr, format, arglist);
va_end(arglist);
putc('\n', stderr);
exit(2);
}
static void *
xmalloc(int size)
{
void *ptr;
ptr = malloc(size);
if (ptr)
return ptr;
fatal("malloc(%d) failed", size);
}
static void
push(struct pid_list **list, int pid)
{
struct pid_list *p;
p = xmalloc(sizeof(*p));
p->next = *list;
p->pid = pid;
*list = p;
}
static void
do_help(void)
{
printf("\
start-stop-daemon for Debian Linux - small and fast C version written by\n\
Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, public domain.\n"
VERSION "\n\
\n\
Usage:
start-stop-daemon -S|--start options ... -- arguments ...\n\
start-stop-daemon -K|--stop options ...\n\
start-stop-daemon -H|--help\n\
start-stop-daemon -V|--version\n\
\n\
Options (at least one of --exec|--pidfile|--user is required):
-x|--exec <executable> program to start/check if it is running\n\
-p|--pidfile <pid-file> pid file to check\n\
-u|--user <username>|<uid> stop this user's processes\n\
-n|--name <process-name> stop processes with this name\n\
-s|--signal <signal> signal to send (default 15)\n\
-a|--startas <pathname> program to start (default <executable>)\n\
-t|--test test mode, don't do anything\n\
-o|--oknodo exit status 0 (not 1) if nothing done\n\
-q|--quiet | -v, --verbose\n\
\n\
Exit status: 0 = done 1 = nothing done (=> 0 if --oknodo) 2 = trouble\n");
}
static void
badusage(const char *msg)
{
if (msg && *msg)
fprintf(stderr, "%s: %s\n", progname, msg);
fprintf(stderr, "Try `%s --help' for more information.\n", progname);
exit(2);
}
static void
parse_options(int argc, char * const *argv)
{
static struct option longopts[] = {
{ "help", 0, NULL, 'H'},
{ "stop", 0, NULL, 'K'},
{ "start", 0, NULL, 'S'},
{ "version", 0, NULL, 'V'},
{ "startas", 1, NULL, 'a'},
{ "name", 1, NULL, 'n'},
{ "oknodo", 0, NULL, 'o'},
{ "pidfile", 1, NULL, 'p'},
{ "quiet", 0, NULL, 'q'},
{ "signal", 1, NULL, 's'},
{ "test", 0, NULL, 't'},
{ "user", 1, NULL, 'u'},
{ "verbose", 0, NULL, 'v'},
{ "exec", 1, NULL, 'x'},
{ NULL, 0, NULL, 0}
};
int c;
for (;;) {
c = getopt_long(argc, argv, "HKSVa:n:op:qs:tu:vx:",
longopts, (int *) 0);
if (c == -1)
break;
switch (c) {
case 'H': /* --help */
do_help();
exit(0);
case 'K': /* --stop */
stop = 1;
break;
case 'S': /* --start */
start = 1;
break;
case 'V': /* --version */
printf("start-stop-daemon " VERSION "\n");
exit(0);
case 'a': /* --startas <pathname> */
startas = optarg;
break;
case 'n': /* --name <process-name> */
cmdname = optarg;
break;
case 'o': /* --oknodo */
exitnodo = 0;
break;
case 'p': /* --pidfile <pid-file> */
pidfile = optarg;
break;
case 'q': /* --quiet */
quietmode = 1;
break;
case 's': /* --signal <signal> */
if (sscanf(optarg, "%d", &signal_nr) != 1)
badusage("--signal takes a numeric argument");
break;
case 't': /* --test */
testmode = 1;
break;
case 'u': /* --user <username>|<uid> */
userspec = optarg;
break;
case 'v': /* --verbose */
quietmode = -1;
break;
case 'x': /* --exec <executable> */
execname = optarg;
break;
default:
badusage(""); /* message printed by getopt */
}
}
if (start == stop)
badusage("need one of --start or --stop");
if (!execname && !pidfile && !userspec)
badusage("need at least one of --exec, --pidfile or --user");
if (!startas)
startas = execname;
if (start && !startas)
badusage("--start needs --exec or --startas");
}
static int
pid_is_exec(int pid, const struct stat *esb)
{
struct stat sb;
char buf[32];
sprintf(buf, "/proc/%d/exe", pid);
if (stat(buf, &sb) != 0)
return 0;
return (sb.st_dev == esb->st_dev && sb.st_ino == esb->st_ino);
}
static int
pid_is_user(int pid, int uid)
{
struct stat sb;
char buf[32];
sprintf(buf, "/proc/%d", pid);
if (stat(buf, &sb) != 0)
return 0;
return (sb.st_uid == uid);
}
static int
pid_is_cmd(int pid, const char *name)
{
char buf[32];
FILE *f;
int c;
sprintf(buf, "/proc/%d/stat", pid);
f = fopen(buf, "r");
if (!f)
return 0;
while ((c = getc(f)) != EOF && c != '(')
;
if (c != '(') {
fclose(f);
return 0;
}
/* this hopefully handles command names containing ')' */
while ((c = getc(f)) != EOF && c == *name)
name++;
fclose(f);
return (c == ')' && *name == '\0');
}
static void
check(int pid)
{
if (execname && !pid_is_exec(pid, &exec_stat))
return;
if (userspec && !pid_is_user(pid, user_id))
return;
if (cmdname && !pid_is_cmd(pid, cmdname))
return;
push(&found, pid);
}
static void
do_pidfile(const char *name)
{
FILE *f;
int pid;
f = fopen(name, "r");
if (f) {
if (fscanf(f, "%d", &pid) == 1)
check(pid);
fclose(f);
}
}
static void
do_procfs(void)
{
DIR *procdir;
struct dirent *entry;
int foundany, pid;
procdir = opendir("/proc");
if (!procdir)
fatal("opendir /proc: %s", strerror(errno));
foundany = 0;
while ((entry = readdir(procdir)) != NULL) {
if (sscanf(entry->d_name, "%d", &pid) != 1)
continue;
foundany++;
check(pid);
}
closedir(procdir);
if (!foundany)
fatal("nothing in /proc - not mounted?");
}
static void
do_stop(void)
{
char what[1024];
struct pid_list *p;
if (cmdname)
strcpy(what, cmdname);
else if (execname)
strcpy(what, execname);
else if (pidfile)
sprintf(what, "process in pidfile `%s'", pidfile);
else if (userspec)
sprintf(what, "process(es) owned by `%s'", userspec);
else
fatal("internal error, please report");
if (!found) {
if (quietmode <= 0)
printf("no %s found; none killed.\n", what);
exit(exitnodo);
}
for (p = found; p; p = p->next) {
if (testmode)
printf("would send signal %d to %d.\n",
signal_nr, p->pid);
else if (kill(p->pid, signal_nr) == 0)
push(&killed, p->pid);
else
printf("%s: warning: failed to kill %d: %s\n",
progname, p->pid, strerror(errno));
}
if (quietmode < 0 && killed) {
printf("stopped %s (pid", what);
for (p = killed; p; p = p->next)
printf(" %d", p->pid);
printf(").\n");
}
}
int
main(int argc, char **argv)
{
progname = argv[0];
parse_options(argc, argv);
argc -= optind;
argv += optind;
if (execname && stat(execname, &exec_stat))
fatal("stat %s: %s", execname, strerror(errno));
if (userspec && sscanf(userspec, "%d", &user_id) != 1) {
struct passwd *pw;
pw = getpwnam(userspec);
if (!pw)
fatal("user `%s' not found\n", userspec);
user_id = pw->pw_uid;
}
if (pidfile)
do_pidfile(pidfile);
else
do_procfs();
if (stop) {
do_stop();
exit(0);
}
if (found) {
if (quietmode <= 0)
printf("%s already running.\n", execname);
exit(exitnodo);
}
if (testmode) {
printf("would start %s ", startas);
while (argc-- > 0)
printf("%s ", *argv++);
printf(".\n");
exit(0);
}
if (quietmode < 0)
printf("starting %s ...\n", startas);
*--argv = startas;
execv(startas, argv);
fatal("unable to start %s: %s", startas, strerror(errno));
}
Date: Mon, 14 Apr 1997 15:39:08 +0100 (BST)
From: Zefram <zefram@dcs.warwick.ac.uk>
Message-Id: <25042.199704141439@stone.dcs.warwick.ac.uk>
Subject: SysVinit patch
To: miquels@drinkel.cistron.nl
Hi. Enclosed is a patch for SysVinit that I am finding tiresome to
keep updating; you might like to fold it into your official releases.
It does the following:
* shutdown: use /etc/shutdown.allow if an option -s is given instead
of testing for a controlling tty. The tty check was inflexible and
unreliable.
* sulogin(8): refer to inittab(5) instead of inittab(4).
* sulogin: use libc passwd/shadow functions instead of home-grown ones
(there's just no point in using the special version).
* shutdown/sulogin: don't rely on the username "root" -- it's the UID
that counts.
-zefram
begin 644 initdiffs.gz
M'XL(``IG43,"`^T[:U/;R+*?E5_1>&L3&\G&#Y[FD%H")/%9)U"8G-0](44)
M>62KD"6M1K+7)YO_?KM[1K)DFP"[V:T]=2^5`FFFIZ??W=.C##W7A;H3@YS+
MJ1=X2;W=V#W8DN,T&8:SH+%?GC`+,\\V-S?O76:\CCWX9QI`:QO_=3N[W68;
M6@<'N\_J]?K].(T!+CF.8FAUH-WI-G>Z.QU:MD>;%7]X\U;+:NT!OP(T7L&6
MO/6"'!N-7;Z"3W!=3^BY=PE2./#YV48^'M^-`\?%(9J&Q)L(7M3#R9D=!UXP
MJD^$E/9(*)CKRM>O7YD#M34^U?_0UO*I>Z\3P^Z!M;>MQ$"DX>M^*R--_!KY
M-DHZC.>0H0L#2,8"G'`RL8,A^%X@<,!.8.;Y/MP*I#5((`G!]GU$D4H1R\:"
M!),>OGSY`E"7]-*[@&OWU75=7KL7^'X6R#36"&U>#'::C,/8DV)(6$E(0%)B
M*M`4$C$!3X(?CD8(X04-Q'(UQA'\%X3Q!,F8$Z(AS,8BH,TR.>..!.0@!,[>
MSFF.[`K'J_LU"_'PBI,D]NO'?E(_%3[!1S%*0@P;``,A%!7"2;R0</>.'0=G
MX20,DCCT%4^WP@]GX(8Q3$+DS0M<(HM6-)0X2"Z0RR53)DNF1V^$!N`C$:,E
MP/:^WJJ;.U9K8=?(TLG59;]^W+^JGY[UB64;:=`\6,2U$PLD)AB!'8`=17$8
MQ9Z="$`UHMJ]@+'TMD3B;)%T$OL6L324C"?"#J32EIB*>!ZB,<S&(8QME--X
M+CT4+M@L$T2#Q"O3"63H"[@3\]O0CH>H@4#IM:!2YA"N0B)URA:%^UGH`DL*
MI+7.6#AW+!I4B.<R(\IH_H.*92,J6@B:,.(A4D.7MYQZ<9(BH9HPV8">>[^A
MN'$X*9@*T>0EB@99(((0NQZRF0DOUQNB"6<:)RD"N2,'Z3'_`7E6A#J2C`&)
M1H(#&[V/*&=),]:9EXP5A"<38B028>23X2C?B46)872F)2ZAJAGI;4WM>"M.
M@ZTTF41(5ZT!YX$_)[[<A9A"*9:E*DD,:-9Q&"::GWQ/BX1"(0'1H$TY@CSF
M'`F.9^C*V23,8B]13J3C"UF^C*!%?P-767`FN2XZ]"H-^9;D)BJZMJU6>SL+
M8O_O`FM=@#1+;O![7"`W/H10D1L11131K/^[OE"2+QLWBF+5]%6X^%.,?_A`
M.>;<6SHYWRK''.,J%7"<CJBN:C6[.[O=UL'#Y9CSM'+LP&H5RA!\V\D<&#8-
M`\L%E,`P1"$D,"(GBL-T-`;:&&ZY)""QAFDLA3\57''H=4Z7/,3!Y$U.X:.K
M#^>`*J8BJ9!,<_B$\KG$S81OSS%Y)S.!ECCHO;DZNWP'5//@\\^]?I]3.A%`
M:5POQG43^PY=F*J8A1/*=4ZH]N1?*%V"ZQKOO%]2I'2*2P>3$,N%X#:-1Q9,
M>%S^-(R]X$[X#0<M/<8"(O`5DG42W6M:>[M9(3`-/2(!C:Q:P]<OM,S%,!<D
M;E4F0Q''%%F,R@<"Z5XGD(L&/M7OXK$;.)_Q20GG,Q<I\$F7FIGY?KX.*HC7
MJ%PGA*!^UP7^&8;!BP10\%2*96@M="=\)12-I76Q7A>+6\PL8+L)2B[7U!+P
M6`./;7\M*%G37LO:R^OM[R`)^=\IBK5&LF_M=Q9^MX?E?^YX.>(@IW[9_ZXK
M7`95V`=QG,5$[(%KRV290$?CR?QQU0V7%JSWQ4S6Y(MW%$BE-PILGQ>;B\52
M[_9XARSOCM+A'%?A&KR">6243B@/4];'O6TZ%VU`E6J$ZTJ`>:Q2PT6(I'9(
M1H7')R^IMOAE_=FKO;MOM?<*XF^CS[;1:;/(AT1A:/.&08A$PA$T#_-1+</2
M6(26S0.F'D#I$=\YT.M>_PPVW4B].6,[ADV2.R>33YWVY\+$;>I^:K7W<6@M
MZ?O;5J=SD(47XI!^8U1RHGF5<-[X6+7X%E1:2A[/ZCB_M<FG)DRF,X%V.D6=
M4!*FPY)/*D6;G7BD2]C<X@4(64V<D4BB41Q5FS78.(+LK0;/G_,+\HTO1T?0
MPA%>1C]5-T+.W3`2075P>MSOGW]$:N)*C9&\_]#OU]#[ZT28@72]#]=28A&E
M,X%2+-;_'/85C8:GY*NP7&)Z@34U3@8\&V/%4G61:EE%"5N`(K8P_M04+89!
M#)/HFY^)H1<_O(#??H/"P'7PHL:$>D$J#O,E'KR$3FMY!C-459(4$,$A;,KH
M$&1DFC46ZR;-9!CY1;-A+$S",TW<EM0Z3".BJ\807YEOWO8?T&G7H+#B<X['
M=7RLE%`-O"@7\PP=V+_+0TBIY**BT?6HKY"74JJ#4!+?!HW=A'>D_RH&'C:)
M-$'?K*Y3KK&PND1W!G1O@<LS/*]S4?BODVP79BU-ZB_3Y":91X)0?AB<7=Y<
M7)Z?G`T&RV*6.GVP0BM;0S'=^E%6+-`HJ$=26ZA*)G:B0)_+I(8";*Y3*((U
M9'(3(S)X#LU?7[\^4=;?_+6YW5Q:DG%Y24F"V/-G]ES"^<\ECL@Y)U'&&`F`
M_`&75-AYFID)&EJ\IJG(,6XQHM^IYZ_?D"F55VCJ.K3F6Y,1*A\!92ZDMJ+!
MX#C:I-J*Z-Q`0@.BM`B42U/1_>'JYOWQN[-![]]GN>NL$EZD7!DM_Q+!4%M+
MP3`U-VP7,UMFO.1>3H1I_$5?+4:9D_/W@_/^&4IUMA)EJ#S,ZPPW0ICK^)&U
M?>,Z5DDEPU+R*\V8D6<;S26%9&0.5-2]T)9.&4T=U91/T;1RJJJC_`AGJYCJ
M'(L2WA3I='[!JB=PYTEWU/6ZFK&S\]<U53N!(?$`YHRK#C-*66Q_SVH?M%46
M6Y<\.GMMJ[/?7N2]3GL'!_(C.RN+_RP2"<<_(AVIPN=#-:_UBUG?<&P\E;V0
M+[HJR7#BFX1#05S2O)$GPY9:D"UF'HRA<.W43[KZU=`58C:M@0WU^E6G/!,X
MU>*&IV'6"DSQ5#<GIPA&#;6WRF)Z>PI9CTI,)EOE1_&">X99*B>.+)#A@U7-
M)B'`DT7IY*O/NPU0D6(8"LD5':X/J27I<%VJ?C($O^!!V7/G%J%@&7LJQ#AT
M@D9HW#X-T*ZG:$2TD^TX81HDFO<L.YH/9T?S@>QH/CT[FO=F1_/W94?SP>QH
MDG68#V5'LYP=V8[^8'8TGYP=U:Y/RX[FT[*C^>CL:#XJ.V90&X.;WN#D[:7.
MDN05M75P3\BB]TMC35XSGY#7S#^2U\SEO&86\YJI0F5F<\6\EIO4M_*:N9K7
MS"?E-?.[Y#5S-:^9H!E;Y#7-I8Z[.J]Q1*%S3^BNG"95J6ZK)J'.=<NL#4XO
M>J=KHB\&>5?B&4OS].,0#?8Y[H-TW-=F2[E!N>;2,YM8UV3+YOC*<R`B@%WJ
ML37;W>W._3VV?-636FS[>8L-H#%X"Z=G@Y/+WL55[_R]ND?4>/&%+#^8AG>E
MB['J?HU:M7PK5NA3CT)NR%*[%Z6/HF93(Y=\1J=C[47#D"\*551#E\IZZ]1U
MU4WUZG9-M5QQOYZZ74%KE2$U<F-/<$=9_(IY,.%.LJ8V)TGEI<B6?%6HN]/4
MJ0?7MT>(A,V!)JB7,@GY8A.J8F1!O]<_K_$MY86Z0V!191>T?T=1[?PM1/6`
M*SCW&:[S#5=PC(](U#]3']K;T-KIMMK=SNZ#KN`8[T+M"MO01`=J=EO?<(7V
M-E:HA;[+MM5I9OK^P0L</\7"\1^N$R1^8_RR-*B;34NCT6Q(0V81<&QC%%H&
MY+Y"*%>PSN66%SJ+[5RXN7GS_L--O_?J\OCR?VYNX.41[*XOISO6=C-S[!^P
MD*4[^9.W9R<_WZ#=&JV5T7>G.SR*YX-LXN)X,/AX:E2X."/#F`TKA>G!V^/3
M\X]Z6C%6*:!]U7L_>(NSZC,&FGF6M9?^A2&?+L>/H/)3]8>:UA>T&GO0VJ^C
MFNND6G@W'30JA^HP@,HXN/_P0"5A>]%Y^JHVV]JD(\^F,1#TX0`639Y]Z^>7
M3U/;3X7Z(B#A$-]@:#K8<3M8BJ2JR-W$I98F'5?1J?1+=ORC=QJ-D1E\II.6
M/@YOJ3:^\4:H&SPZ5+-[S<)XJ/Q7=?LI"6$5D#IZ>@B;6)P1>#3CQ,T=Z0T\
M4R54CB_!HI$=TN2BC;>`9)*IEOK4WMG]O#(CRU.*0>X#4JIC^K'8-UY3.S7$
MHE&&$P'Z3,37;?9P2AW'A@+<(B1D\]'LAF[D2+W<23@L3&BJ<:HT/!).*&ET
MD$88_3Y@""S-#ST2<&6K-"C'PO=74*59P[.`?3%$H\OY7MEYEO"/%@D?80TD
M)\:B3L'4&*L18^T<!YC[2?;ZZ$<3*+(-+3(LR%GAGHKUN=ZI[F@H*):7/F<S
M,7S$(9U8@$K19YR-,CFZ9\,EHP)E&7>Q%-E116R-X8Q%$<M<@'D$.^J9#/MY
M21T6V904$0XC/CK.*\@J.4)M:>[!J2)^UNM]Z(N`J.#'@+'*RX!4+M8R+H_8
MW-6;KH<W2#\;Y;/51EE=/1411.#$\RC!3).K"\,#>K4WU("8\"A:N'B81:$I
M,RAJD[03+5O0TD42%HZ2BV"5PMWL8XD`57B_E65<Z)CC#:LE#:*A+!EER86O
MBB:HBA/"P3?Z=`G-<=#6P"J4Y_`6<*61%+U<M_27C*BB+6"EGN9$<8]_K95.
M.59J:A\IH16/DD]P*?FG^]23K;*H-YGP-P1*'I:&(UY0/Q;??7U_FU3:RWSQ
MFXK/+71CO8G^+HT_<G_@S9><8%$(<"H^EG?,6U&L#7@?)OKKPMP5@E`MT,F.
M[W,I`^)1>286GQ#*.R]2+8%A&M,IDRKC+*EOZ(J!+J.8SOQJV=`97)=]$/KD
M9,G\4,TM$C2M^]3:58U-A0T91,.F"1ZD"SWO4*<?+=?*&V^Z7&[PEX8V3HN`
M,G9V'YDOJ9)4J&^COU*LG_(2Q2F:G1TG:53K@E[FNGXJQZ1!E(J^R:.OK-I[
M5FL_OZI<DOZ?7`BAKK(XL(1D:5A&-"C7Q<DGE3IJP_75SF)NN>!9S-Q;\RQ`
MRF7/8GRI\EE,%(N?PDYKZI^(B2+CG.&B:O,1D?G$I@\5N-EHPX?>*30S$;,2
ME5$5XW*FDE*)!`]GVSRU%D)8'E'J+]=DO;\BZ97W5G</S47"D[E$980&D9-*
MQE$0[GK17A0=]4=9"H`E1+R?\"4?8[(X*QE$1C?X%Q/<NBU4`JL,RFP^?CN5
M\4H2H"YW<>/#0@#^6\9?]<Y\_961^$?YK3AL@1;T=XW&:_L;!WM6IYEW^PP5
M<`V4CX/"&6/$LV!W6Z'$>D8$TVKE[?F[,R113;:4.61S_?,WU):N9!?&*P!T
M`;`T6T`]>'O6[^.P3'51K^:U"ZL.S+;5WLG_Y\%W)+AHX_>1O0KS:.+7-F3V
M]ZW.P4XN_3Q,K76*0MA1]6RK6*UR<5NH*PJA.[^_5)!K8A8&+?CM-X;(OL[!
MPI=C<35:L*TC[,J`^BI`W;1J[FF7FN[3=':LSO9"94_D<HFQ<@C5+?B_G*__