summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/ka.c
blob: 7b9d98fbe83b3119194d88792ae4201933fde53f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/*
 * Copyright 2005 Mandriva
 *
 * This software may be freely redistributed under the terms of the GNU
 * public license.
 *
 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include "ka.h"
#include <sys/mount.h>
#include "mount.h"
#include <sys/wait.h>
#include <dirent.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#include "config-stage1.h"
#include "frontend.h"
#include "log.h"
#include "tools.h"

struct in_addr next_server = { 0 };

#if 0
static void save_stuff_for_rescue(void) 
{
  copy_file("/etc/resolv.conf", STAGE2_LOCATION "/etc/resolv.conf", NULL);
}
#endif

static void my_pause(void) {
	unsigned char t;
	fflush(stdout);
	read(0, &t, 1);
}

static enum return_type ka_wait_for_stage2(int count)
{
	char * ramdisk = "/dev/ram3"; /* warning, verify that this file exists in the initrd*/
	char * ka_launch[] = { "/ka/ka-d-client", "-w","-s","getstage2","-e","(cd " STAGE2_LOCATION "; tar -x -f - )", NULL }; /* The command line for ka_launch */
	char * mkfs_launch[] = { "/sbin/mke2fs", "-m", "0", ramdisk, NULL}; /* The mkfs command for formating the ramdisk */

	log_message("KA: Preparing to receive stage 2....");
        wait_message("Preparing to receive stage 2");

	int pida, wait_status;

	if (!(pida = fork())) { /* Forking current process for running mkfs */
		    //close(1);
		    close(2);
		execv(mkfs_launch[0], mkfs_launch); /* Formating the ramdisk */
		printf("KA: Can't execute %s\n<press Enter>\n", mkfs_launch[0]);
		my_pause();
		return KAERR_CANTFORK;
	}
	while (wait4(-1, &wait_status, 0, NULL) != pida) {}; /* Waiting the end of mkfs */
	remove_wait_message();

        wait_message("Mounting /dev/ram3 at %s", STAGE2_LOCATION);
	if (my_mount(ramdisk, STAGE2_LOCATION, "ext2", 1)) {/* Trying to mount the ramdisk */
		return RETURN_ERROR;
	}
	remove_wait_message();

	log_message("KA: Waiting for stage 2....");
	wait_message("Waiting for rescue from KA server (Try %d/%d)", count, KA_MAX_RETRY);
	pid_t pid;          /* Process ID of the child process */
	pid_t wpid;         /* Process ID from wait() */
	int status;         /* Exit status from wait() */

	pid = fork();
	if ( pid == -1 ) {
		fprintf(stderr, "%s: Failed to fork()\n", strerror(errno));
		exit(13);
	} else if ( pid == 0 ) {
	  //	  close(2);
		execv(ka_launch[0], ka_launch);
	} else {
		// wpid = wait(&status);   /* Child's exit status */
		wpid = wait4(-1, &status, 0, NULL);
		if ( wpid == -1 ) {
			fprintf(stderr,"%s: wait()\n", strerror(errno));
			return RETURN_ERROR;
		} else if ( wpid != pid )
			abort();
		else {
			if ( WIFEXITED(status) ) {
				printf("Exited: $? = %d\n", WEXITSTATUS(status));
			} else if ( WIFSIGNALED(status) ) {
				printf("Signal: %d%s\n", WTERMSIG(status), WCOREDUMP(status) ? " with core file." : "");
			}
		}
	}

	remove_wait_message();
	return RETURN_OK;
	//  if (!(pid = fork())) { /* Froking current process for running ka-deploy (client side) */
	//  close(1); /* Closing stdout */
	//  close(2); /* Closing stderr */
	//  execve(ka_launch[0], ka_launch,grab_env()); /* Running ka-deploy (client side) */
	//  printf("KA: Can't execute %s\n<press Enter>\n", ka_launch[0]);
	//  log_message("KA: Can't execute %s\n<press Enter>\n", ka_launch[0]);
	//  my_pause();
	//  return KAERR_CANTFORK;
	//}

	//while (wait4(-1, &wait_status, 0, NULL) != pid) {}; /* Waiting the end of duplication */
	//  log_message("kalaunch ret %d\n", WIFEXITED(wait_status));
	//  remove_wait_message();
	//sleep(100000);
	//  return RETURN_OK;
}

enum return_type perform_ka(void) {
	enum return_type results;
	int server_failure = 1; /* Number of time we've failed to find a ka server */
	FILE *f = fopen ("/ka/tftpserver","w");

	if (f != NULL) {
		/* Writing the NEXT_SERVER value of the DHCP Request in the /ka/tftpserver file */
		fprintf(f,"%s\n",inet_ntoa(next_server));
		fclose(f);
	}

	log_message("KA: Trying to retrieve stage2 from server");
	log_message("KA: ka_wait_for_stage2");
	do {
		/* We are trying to get a valid stage 2 (rescue) */
		results=ka_wait_for_stage2(server_failure);
		if (results != RETURN_OK) {
			return results;
		} else {
			/* Trying to open STAGE2_LOCATION/ka directory */
			char dir[255] = STAGE2_LOCATION;
			strcat(dir,"/ka");
			DIR *dp = opendir(dir);

			/* Does the STAGE2_LOCATION/ka directory exists ? = Does the rescue with ka well downloaded ?*/
			if (!dp) {
				log_message("KA: Server not found !");
				/* Be sure that the STAGE2_LOCATION isn't mounted after receiving a wrong rescue */
				if (umount (STAGE2_LOCATION)) {
					log_perror("KA: Unable to umount STAGE2");
				}
				int cpt;

				if (server_failure++ == KA_MAX_RETRY){
					/* if the KA server can't be reach KA_MAX_RETRY times */
					char * reboot_launch[] = { "/sbin/reboot", NULL};
					for (cpt=5; cpt>0; cpt--) {
						wait_message("!!! Can't reach a valid KA server !!! (Rebooting in %d sec)",cpt);
						sleep (1);
					}
					/* Rebooting the computer to avoid infinite loop on ka mode */
					execv(reboot_launch[0], reboot_launch);
				}

				for (cpt=5; cpt>0; cpt--) {
					wait_message("KA server not found ! (Try %d/%d in %d sec)",server_failure,KA_MAX_RETRY,cpt);
					log_message("Ka not found %d/%d", server_failure,KA_MAX_RETRY);
					sleep (1);
				}
				remove_wait_message();
				/* We should try another time*/
				results=RETURN_BACK;
				continue;
			}

			if (dp) {
				log_message("KA: Stage 2 downloaded successfully");
				closedir(dp); /* Closing the /ka directory */
				server_failure=1; /* Resetting server_failure */
				results = RETURN_OK;
			}
		}

		log_message("KA: Preparing chroot");
		return RETURN_OK;

		//    if (IS_RESCUE) { /* if we are in rescue mode */
		//      save_stuff_for_rescue(); /* Saving resolve.conf */
		//      if (umount (STAGE2_LOCATION)) { /* Unmounting STAGE2 elseif kernel can't mount it ! */
		// log_perror("KA: Unable to umount STAGE2");
		// return RETURN_ERROR;
		//      }
		//    }
	} while (results == RETURN_BACK);

	//  method_name = strdup("ka");
	return RETURN_OK;
}
3 # Wt~ dz|.T`jxV33g̅F$B5t?Z MA^Z19{L[* 9GeWøMu\0unh9, 2/Hrù@m`_5_gx1e2`1{x?$z? mo^}RrR'C98"ߦF;.%,?FЁ^ZV랳bl[#ш˻txj9vO(˼,(|* DNZ0-l;R,eo]J*ZeoVb9A1R5";r-.zػ*yuH~7Q _vw?!h aɾ J6 `p‘ڏmEk39+Bjx~LT Z:嗾Xc=I(1Rmhu:3iP- HSofUHGX+YFj_19פOѯ gީ"D҅2L=zp`&i1,? *-|=m Ie"*byQTE8o@"Px;t>` ~Ʉw0/{qQl6径. ιa>FDFinhRAtEg gpSԚx#J rf'#mK$ ;e Nm+x3# .'~irNN *taIkh%WA+~7JBކ81ȼ=&#?PHKFx~U;o9WN%23X3vmB}Pcf;v*lG'4`3RV/WӉXtK'xL G&xYQ[_ŝMX'O-Z| Ҡ.ndճQbvIls lB#cg×5& J:8">ہԄSR)N #.0zM+㞕*]S_;uI+^> gX ^y)Sbz9Ӆ-G3!He_^zZA慒Oh?xt$e'eA;}y+ 2N4onI{Fn7IyK}ᤓNq y(N,R(ЁT}e:Q; ,R+и(~N~bIoy>٠R{]eXPX([N'ҋX/̿ZNZ;Dn*<37{p5 |MLM5+TOL6Ŧ'Mp\Ps,n qY~d4GQ&ޗfu?0^7K:VKU"Ǎ7T!}ƾeQ9 024*"OMj[Wߏ! IujpW)WÉiHU VR;6=KJrd/9T_R˖YLB{W#-l)2r8 uToa)}UE᛬n\L"LN//p[hA:*;Q46~KY$Jb(?AQ)G{Uyk a߃0(lf?\12 {~F٠>/O);\]i-\쇱V=QtşS-j0pLuh 0Wtl G(4VY,w:N4۸Ma/f)ѣR-<:kI'&9Rlڋ`gh'Rۄ[y`"ө t 冷LeMIGP::n>7b_f*^b7rԳ6*ZQx3;vd7Ʉފrߕʰe.Wkq/ /K];bu+B!^XgkGh8:T6eTeJSZh8l.sǩ$*ƒyXf[c4jx;kZDƅ{B9Bl}*|u_; '0#O5^yOO䲸?oOx_3{ȓR(7%H-6ڬ瞘EJ}6 z1TP벎&y5W ɫ,|*.vcASV9_f~;r~6~@LAк1n*ab4ˆC<-LY(ѻk 2ois&@L!'h>!GU\PC 8RM.oU ~q;vnͽkvoz*j>έ۩!(9 X'ͯB'n x-E o ا"؂k^G |YoyEq魰9 W{D+'I*q3P-?/Ec!%Y@_D7;{6 UiE\C—qt baa)WDFqpw:PyXz$_^V^6E?30SEDrŠLWV-/ Wf[P֡g?(XZ 2/x\ӈh9 ?ԾOBqCQJF=q{ @6Y= As鿗DoXȥi^t6L *yLgZ+O\k ռpDĚ5,&i0J4LF>9BgFO>>9Dq50y|ZxYˍͬq{*h\,˽ԉV+6hͮ^Ua[P}+l5*10o~UJdF6[7q橗eےc+|Ë@1y`1=;o%qumi :?rO$7ì`#>HRra]@aj-yWH_Q¾=;aey_)}Hh@Hk2U7S}z$,z^&#\!=b;O!&v϶/6֕`sb(,*M!PJ;xRObun,V.~FwdekPA9 n[dLK`5\ dJ*UHO+ /E G W(dF)GAUy HJq㝫d~?WB>dm]q txcRǞr zIO/f.z-([blfz0p6_ $#2W*Rc&2]/@S {]]s ҔD#k s !I 8e[k FkV4jYStK" Zi@] V02-GGĨ"EλcPw!}_Ydq`#ԩgw`6[&\я_>Xx|f?%"O>*k<1A ׎/3u@}~x"&ieAp!@^U$:޾@M\75M*E~d a}ʖP3!>WiGI]BAIiulqa4TE7  }"8'4ezkdGjSVe 6XGq(Iy{ɱZ$}֣v3 ÷݉]N=c)hX6Wٙ!$/@Yl> ֨%OEy!!({g}d^<R$Kn6to@;]d~y Xa%=Ҝ/%ZݑXz0{qpZoJՏc[]8!1$?9 ΀/1:mLљS4)ju|bx(N 5w=7i( ]'W^ͬjӛyj􅇺hߣڝJUEc;ɧJ9`19͜I5 ^;T_Aq[pޗdW4?w#.Ferj -xq[[>FBHTTwtI%xSfkMxo4ohszg)dRE̚mNDI&]Mg&>Fu|$XBpqUhd1%yC,-Jp[(lˏ@Ow u1Dƨ|.4 X\Gӥs`_Um]S24q0h֥/e}o/ &*C䪔L_pQko(jRRhuj%% 7غ;,.vҀ`c%MeOƒ&-+/-=(,lX, x!׆@b߉/51pl k6:%y;DjT>r YWc^5A@0}Xji; ƈ' JL I#'ޥޟIjdߏB剀+{xý_xѡM.P츽xwa"G(ݙ\<2ͺ)7CRqIngd|X_MGg7o~,,AZ\E̵%}gmCVl3 4NF9At rmfhkZ9ݺ6]g ɲt3<;&^L+>X&tpHl ӯ*HX,> tVrl@F,4x3 }nv>/GɌ&)oj#"$E#[lT2«eG+߼ 7Дq;gkw1-|Êݦ52}Dad`</(q 7C dxŽC~NbF,[_pB\Blƒ>(:*(O؜f^׎XHFV\,ٛu:v#>Z/ڲǓriyǰ|&P[o 1؉2B;LR߉1e`XW%k$?\-w ]p-C}#iBC:ɲycކԬVݜ#Y~9\Gθ0>T hN} Sx oǑ:@($zB% FG*l歜pfr-+M0-)xBD͔6PԺL&5 Ȋh1>7&v_mqe38wNI5y!BPNcLٕEwQR .Fi@F -墽s!&[<<l-ĶLf4VmcY0t;vQm1$hj ,Gb M;!f<d9o= 咳1E-ۑ I yTۂ,_ؐ&zUtnKS|5Rqt:ZuqCΉ :;Hx~p7 쯋i;;3 9z}Q 8Ҁ4;*O'^-zAQckN AM7֚Ls($r_aFw{)XC0B؜#6gobbIԘ3p1106 #ƌT^D"xgAˍIՉ;$Z+ǥRKX Ͱ-w{=\,g?يa\}h3n6 3v*v&?4-ߗMA!Q_jjp/,hm"ڻG,GsZ|҃Np;& :!lnK|X]ǼjqXpMږqU)ђQ0*`u1:htl*5kP=xTyl\18aZkYNk*5k '_ BCS2xh1cj3 ;9=fAA&b kyUKsr@խB\lZxɃ9ZؖbmaFw&A*jݢjkB7`~n na[.yp'6 1,泈(`E+Uu"k}iv3믚 :vҔ(2_0Fbؼ9$]@щ#OpEzU:A[@Ye+6_%J;>IkMHڠ]h`d?Ûpenh $B4_?*[qlJjHDHjH?:`14svO=4$](# 1Xwvb=v|,ԎN\ruO&MLޜ-^%*ruX-(HF9i[yOU? "ej,>$5Js)I jY ?/#}sulC&Id"kоK99qKHL9?(N`/,?Mϖ*S%uVbt=n!U؃>x&wv'v|{;"+E zS 8g( z.j Ƣ+4nڔa.hOM0`j ˸s$,r&fvbfzwq^|"kl)l!'slٌ[e-<NQB!` 5ײJCCP= XW3~0/LlgYSIIf@?(kn!TKf4m,GZڕ~E;yG-]|$r{50/'Dw[e,`Ѩ!?wzb}'EKl5zFM"}B}C\?E[me 5`08_,18S C;ޱ$K*iq-d(ݙˆ)+Dch[T@褭dr0>>?eHթ|ê͆4&\%ib Е?Wԉp{;sF]LzY!K:ƮGk f.wmfMh֠^)]uf2BShVY)n@١ZVy@IDόh)}' ė|끙S&d2`b17աv(:$Jyƃnv\i&fNR@FT@ b7Ť}z0>A/8մܘV3 ek\ 1d"Tq[鳫hJPzoOM~]W+O[vG>BDoW괝i<?؂hXH9Lv9(, J^,MnK#D?Ii3Cx!R$ {3)TJ 3z٢ե{iC@󚖦 N[iKܪe16+w:<{|Dj TyX B_Q/iʁ%ҩt~:GTSk璧wV|4(67WeZ$,\R8q`BZ2Q$/PF6E,nwՑ aoyRMÛn@ǿPM/<&u<Ľ1+O0<r g Vĝ-Khc&.T ?4Be&%ԘgH';EAƄ5W.sug4*{[U$ -dT$%/9[şW ˜.ׇƬV|!$Y-{7MZ=TLŹ)܉k5ʴ~"P2h%ݵ0a'$+dW=8CPbZ=dQ@1|> K?c|Kenm'iFg =c F#(K_ `/ +ɇ2BOK&M}H(BMX7,wB] CzN2EwqϜJ~W4f}kmAe'#)EK^N]UƽhSU1R؏M]A p&4t;HEEm#RP14 6%q"0 )eQlz.\-lѶ7CBZԋReb6VҾ R--)Ƙyveg B0J$j|88֭wb:W;'W6 []$RU@1Z_UFp&^ Xة}*-3b-R"9Ю1rG<CbpXCīh\9~$;%>"P'PܕT-!0`=OJF+xO-)4C>}>|`temNݱɩ=X%!S0 fG'T'/(dY&wu806wTt9PlJI6IZs[KE0"Gբ:[hS4am yƥV'v:RGD(C|iܟv{@lͅ^!>Ee ObzT] npHО)rn`z7HmIX}@U淵@|OY$BTJ*<v$rs7g)cmӫ"8ul?QҚ[En5(p=m`#A%$ ^D`LD>#.L:=]I G%!P7eut!AB"``ّSvte%#_3-惏Y0íR 2]L2D#,5Y1i'C_-MwXv#*/Ϣ1Hi)\%tUz?E~wLئѯSʤyק^QYUVEg$hOiX/6ule\IjI07[uL=`}˥{d4k\a=S2*-:s Bg]")BSg )M03yG]o;]ZLLNjQ60bMXyVҺ~SEV| MoHDڕWUŻzM7* W`i-@ fv|?!;"-'k e!ο>\ՒcnǙ[(:ENAORy' M+6l% ΗFj.Sc,4N:vJf w"[ʵ#=]dC DZE"Az1ƣ(50қV\U :DDQJR< էDf:XBӃtF™X1|K&bZS6qNb̰Ә'!˧Yȃ D-$K[R[v745J[XLpRvqA4~mz@o25E@~p) M}sfeUAW^<1:N-xW—.n~UMnf,YQ89ŪVšvbBVzWeSQv>;Ӱْ}[x4|TȐt>[?Hq#k7 l'a\\,ҫpsYjL -QZєU!~u#&}U*4C F|ÂzBuX` r]2{/%#VV00_&a 8ܻ q;qR1~ʫ]/N/@ %蜢f ˠ!5)]DY`iQ9R=$@$эL_>nܭsZQ&CiM+^PΆĈX>fӯCG\'7JW f,UvXe8wZиG j[ S٬A=fPS08*mqG-4bM2k_LTZүߒq#>&^&m\vR=5bk6(-İӾFI k X6Gg wI^S/n`gok''OsK9' k(q#Fyml'h]L g_pö5Y?Yy2#a{"b^2s{aEn6 lU"ɕIص$\xUe]IrZxH'yz{xZoQ!M ^OOH? i^֊+2~YʎjcA# KxDw¿u1 T{EHUfw4 G[wyq8@Ecg=~RrQ;"}dْ#&ve6S,`/̂(/h: Qf GWߑsrAa7]_ZNAú@irj GS)7Y#LSS?&1k71C5|OVKN[dЛ e>_eAd*` 692 ܯ .mYR#o WM<3lj߀6~n;asMu}"َ"Mdu=X9y2?WMg"}depyFȅNA! lW[2+{ v:ET]īA5>>.gF8}mL9h܆.>3T늊Ղ̪̌"8;B$H],/h<Ľ7K<->fuN:`Вvd7qnކ 3hd׈ -!c=6iV;kELdbվ/}!?ٳO{GI~ܟ'3pate'{K6eLK8ě6L| T(oGGŸ9jX S$ֱQ;ˏgю =B-ELOJx2T#Lrx bg@&WB/`tK)aB]5\/͂ͱl/WݺWbP>-f3{g5W.͉I{agW&*UYZ>uZ\DΑoUe-$lFp.?ob?EgF-dOfV[I[T/* '|c)+xM}ط&-/[X <<|)~,2S G!:3n`;F)u2qǺԵ" HXV!rr_c.1]Ab@ "1cfVrKz-]S}PiCC`Π$_l 1'im0MBsrr eۄa5 = U&ۿNzGZβk:J'v@>Ȋ(&H)M:8Ds# qm4oƦieGT$v~xG_?X|]~ړ9wA| ͅd3.Ia Ii * 3$y>mxCO[}AU_| Hpiq&qZ<= 6E>4x~/l"NxyP Z/,HKlwD;S0q>J ĿlKVh;c11Ȯ;֩ɫH#C6{e3U2[_qS˹=xSNZ=OT*MBdyrCmve7 Ȗ[2<S p s [v4,O|;tCOsf ,1{BFlo(i`a8GgJʰ01EW Сp2 dCBm׷o >5[Uڲ @LDC@'G n V+dud94"!3r hzcήVzۯygӭn 솒r,)s7&1aTY v9P8OSu@q{j߽KسbwP1U騬": WJ]oH^ɣj]02J_RRswr䍈jAzc$ʁt!~ &pV[C%[N6 c'T)h{mQ|A7U{6%'(uH[%jܨ@{Rۗ'Y\%ynq/!q?Yj8H™l^+^ü~7s%½lh 9)S c`ãY5ڏ-;iwxnX 7 _Li]w*Ix 4,(L wmP)2yGznwU˗簉gj#ZZs9p<@VJ@g룈BQ SJEf7, kgi @z\ [^1kd)<y)k32KU 7UivH^xGɷ$1 A5[YMӋ^E<Ĭ4Q02;[k5mi&|ҧS{<\ט3.}!qIvTAJ[bwJ@i-$mo4g q*/qPDbNG^]CۦH.b0XDcc lh{@xޗKsHNDbXΧZPK3$0$ ICĠZ[1L?,Vcyna*%5&* %0ᎃ!Rc.|cy2\|3E8h-.S-${Ւw){}cyh=IӼ\ʿ7yī7e1}}A5*7ߔ@{s߲ wt5|Nu&Bh ,DgoȁfҼia%ڬcq b_B^EYЄ Gp$HT_]KSLTvbϿiSNsoԴf≺u9M~O2n|{?SV2"/QH(DLyt]M؈.q,bDXQPHƦޅ䴕+وeXQb L V㰬 ~=?u'=k>b11C@ᙡG0N@&*+cZ# i )d0VQՙ}wZe\*G yvf@NUhIl}LFY3 lvq\g}C/E[$#Q9N+-WB#!?3)rgw-vX|E9Άဋry,Jo9eFSq^*zjRYw`okDnfIP vv_.'#kJ&dgG=qlXySyii|t =ݘ@[oe԰`^ČX[sx0C Yܶ[e4eu1.$Y\/^4T r\3'ܥ2BEQQڐ8њ3Z<_B<.eph.=ƼmqVؼdQd<ʔ6 Ї8\yU@gÉg;=F{ΪazCeV31gbx׃\̺P owjeZބp=`.2s&e3td' GZ S L҃&,Ή#tǖp\ց X`%IUݣrD|6X>Ȗ7ϐ% Xb'UY_չ^Z'J3V;{CHSQe\UTw烣#5vz٧:1ٽLőf'a V& P.U%nbHyliH3I놹SحckdWK&ɺKO-xOj^Կ eBWqQ6'OCtc?p+jk9c#U~q%`I!A%d e&eFh%m`)鍚\ԏA nDGj+қNۻ)o[cP6ے?wl7-!1OF|b٤>䥔*p|}`@QUaKᕑu.D Q)s0:ϓ R$~~#wdvr Z'}#^qx֩@ƻ.s! 8* w1ݯCujg8VǗA.2f|.~K\|5;,5@@\эa4ݛJ߃x*1nVѦ Ul/i&I9G# j,HQދBp4Ӝyl-QVhƁW@SXy $r[G BQO)J;(M]9bf?RCĻm#*oP?29GCXnN- \7DƓ,e1<4f|FQo[_`)ll=ygF=/,3x;h_(hs4V 9U1k?ڏՌpwOSqN6 ޤ܁w jތRdo|[%6H{ȥ%MpՔK(oGb uK]ˀ4ÅAhfN|)U@ws'M]"\RpHr_li=h诖cޥ.c]T D{~k%- 4;Z? zoC\@|<+&=;_+6|Oz=#?,"f)G19)`d! uILVCv/H{Yn%`ט-XTMd,zެީ>T>HasĽsgn rir=2SɟsTH!NqCXΏ8,0`= dn~0䗈`W;j'"UՎ%.ICy/T;a\Þ]@kFtڝ2ZLh1aPw ɟ:V*_S '  q,ZCVFs/wy(5׆-ܴC1Y U5ݓVkt=xθ({?  waq=!:T DvC]b /b}&{okqX ,uXOo;&x!Bu5l(6eܬ. 3ٻgj|Q]C(3&;,MC@7芖ӹWKsG ŒUuQ|q$d`B'oJ0s{jJY:Hg 6Kחuh2Dk+y1`P=~O< Vo ]Xd+Q3\ÍЩ}t* >ft fc}*5A3{QA fؒr2}!EjiL3Ye4TI7|k-wbN8(|