/* Unix SMB/CIFS implementation. tdb utility functions Copyright (C) Andrew Tridgell 1992-2006 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 3 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, see . */ #include "includes.h" #include "lib/tdb/include/tdb.h" #include "pstring.h" #include "lib/util/util_tdb.h" /* these are little tdb utility functions that are meant to make dealing with a tdb database a little less cumbersome in Samba */ /*************************************************************** Make a TDB_DATA and keep the const warning in one place ****************************************************************/ static TDB_DATA make_tdb_data(const char *dptr, size_t dsize) { TDB_DATA ret; ret.dptr = discard_const_p(unsigned char, dptr); ret.dsize = dsize; return ret; } /**************************************************************************** Lock a chain by string. Return -1 if lock failed. ****************************************************************************/ int tdb_lock_bystring(struct tdb_context *tdb, const char *keyval) { TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); return tdb_chainlock(tdb, key); } /**************************************************************************** Unlock a chain by string. ****************************************************************************/ void tdb_unlock_bystring(struct tdb_context *tdb, const char *keyval) { TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); tdb_chainunlock(tdb, key); } /**************************************************************************** Read lock a chain by string. Return -1 if lock failed. ****************************************************************************/ int tdb_read_lock_bystring(struct tdb_context *tdb, const char *keyval) { TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); return tdb_chainlock_read(tdb, key); } /**************************************************************************** Read unlock a chain by string. ****************************************************************************/ void tdb_read_unlock_bystring(struct tdb_context *tdb, const char *keyval) { TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); tdb_chainunlock_read(tdb, key); } /**************************************************************************** Fetch a int32_t value by a arbitrary blob key, return -1 if not found. Output is int32_t in native byte order. ****************************************************************************/ int32_t tdb_fetch_int32_byblob(struct tdb_context *tdb, const char *keyval, size_t len) { TDB_DATA key = make_tdb_data(keyval, len); TDB_DATA data; int32_t ret; data = tdb_fetch(tdb, key); if (!data.dptr || data.dsize != sizeof(int32_t)) { SAFE_FREE(data.dptr); return -1; } ret = IVAL(data.dptr,0); SAFE_FREE(data.dptr); return ret; } /**************************************************************************** Fetch a int32_t value by string key, return -1 if not found. Output is int32_t in native byte order. ****************************************************************************/ int32_t tdb_fetch_int32(struct tdb_context *tdb, const char *keystr) { return tdb_fetch_int32_byblob(tdb, keystr, strlen(keystr) + 1); } /**************************************************************************** Store a int32_t value by an arbitary blob key, return 0 on success, -1 on failure. Input is int32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ int tdb_store_int32_byblob(struct tdb_context *tdb, const char *keystr, size_t len, int32_t v) { TDB_DATA key = make_tdb_data(keystr, len); TDB_DATA data; int32_t v_store; SIVAL(&v_store,0,v); data.dptr = (unsigned char *)&v_store; data.dsize = sizeof(int32_t); return tdb_store(tdb, key, data, TDB_REPLACE); } /**************************************************************************** Store a int32_t value by string key, return 0 on success, -1 on failure. Input is int32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ int tdb_store_int32(struct tdb_context *tdb, const char *keystr, int32_t v) { return tdb_store_int32_byblob(tdb, keystr, strlen(keystr) + 1, v); } /**************************************************************************** Fetch a uint32_t value by a arbitrary blob key, return -1 if not found. Output is uint32_t in native byte order. ****************************************************************************/ bool tdb_fetch_uint32_byblob(struct tdb_context *tdb, const char *keyval, size_t len, uint32_t *value) { TDB_DATA key = make_tdb_data(keyval, len); TDB_DATA data; data = tdb_fetch(tdb, key); if (!data.dptr || data.dsize != sizeof(uint32_t)) { SAFE_FREE(data.dptr); return false; } *value = IVAL(data.dptr,0); SAFE_FREE(data.dptr); return true; } /**************************************************************************** Fetch a uint32_t value by string key, return -1 if not found. Output is uint32_t in native byte order. ****************************************************************************/ bool tdb_fetch_uint32(struct tdb_context *tdb, const char *keystr, uint32_t *value) { return tdb_fetch_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); } /**************************************************************************** Store a uint32_t value by an arbitary blob key, return 0 on success, -1 on failure. Input is uint32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ bool tdb_store_uint32_byblob(struct tdb_context *tdb, const char *keystr, size_t len, uint32_t value) { TDB_DATA key = make_tdb_data(keystr, len); TDB_DATA data; uint32_t v_store; bool ret = true; SIVAL(&v_store, 0, value); data.dptr = (unsigned char *)&v_store; data.dsize = sizeof(uint32_t); if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) ret = false; return ret; } /**************************************************************************** Store a uint32_t value by string key, return 0 on success, -1 on failure. Input is uint32_t in native byte order. Output in tdb is in little-endian. ****************************************************************************/ bool tdb_store_uint32(struct tdb_context *tdb, const char *keystr, uint32_t value) { return tdb_store_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); } /**************************************************************************** Store a buffer by a null terminated string key. Return 0 on success, -1 on failure. ****************************************************************************/ int tdb_store_bystring(struct tdb_context *tdb, const char *keystr, TDB_DATA data, int flags) { TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); return tdb_store(tdb, key, data, flags); } /**************************************************************************** Fetch a buffer using a null terminated string key. Don't forget to call free() on the result dptr. ****************************************************************************/ TDB_DATA tdb_fetch_bystring(struct tdb_context *tdb, const char *keystr) { TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); return tdb_fetch(tdb, key); } /**************************************************************************** Delete an entry using a null terminated string key. ****************************************************************************/ int tdb_delete_bystring(struct tdb_context *tdb, const char *keystr) { TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); return tdb_delete(tdb, key); } /**************************************************************************** Atomic integer change. Returns old value. To create, set initial value in *oldval. ****************************************************************************/ int32_t tdb_change_int32_atomic(struct tdb_context *tdb, const char *keystr, int32_t *oldval, int32_t change_val) { int32_t val; int32_t ret = -1; if (tdb_lock_bystring(tdb, keystr) == -1) return -1; if ((val = tdb_fetch_int32(tdb, keystr)) == -1) { /* The lookup failed */ if (tdb_error(tdb) != TDB_ERR_NOEXIST) { /* but not because it didn't exist */ goto err_out; } /* Start with 'old' value */ val = *oldval; } else { /* It worked, set return value (oldval) to tdb data */ *oldval = val; } /* Increment value for storage and return next time */ val += change_val; if (tdb_store_int32(tdb, keystr, val) == -1) goto err_out; ret = 0; err_out: tdb_unlock_bystring(tdb, keystr); return ret; } /**************************************************************************** Atomic unsigned integer change. Returns old value. To create, set initial value in *oldval. ****************************************************************************/ bool tdb_change_uint32_atomic(struct tdb_context *tdb, const char *keystr, uint32_t *oldval, uint32_t change_val) { uint32_t val; bool ret = false; if (tdb_lock_bystring(tdb, keystr) == -1) return false; if (!tdb_fetch_uint32(tdb, keystr, &val)) { /* It failed */ if (tdb_error(tdb) != TDB_ERR_NOEXIST) { /* and not because it didn't exist */ goto err_out; } /* Start with 'old' value */ val = *oldval; } else { /* it worked, set return value (oldval) to tdb data */ *oldval = val; } /* get a new value to store */ val += change_val; if (!tdb_store_uint32(tdb, keystr, val)) goto err_out; ret = true; err_out: tdb_unlock_bystring(tdb, keystr); return ret; } /**************************************************************************** Allow tdb_delete to be used as a tdb_traversal_fn. ****************************************************************************/ int tdb_traverse_delete_fn(struct tdb_context *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { return tdb_delete(the_tdb, key); } /**************************************************************************** Useful pair of routines for packing/unpacking data consisting of integers and strings. ****************************************************************************/ size_t tdb_pack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...) { va_list ap; uint8_t bt; uint16_t w; uint32_t d; int i; void *p; int len; char *s; char c; char *buf0 = buf; const char *fmt0 = fmt; int bufsize0 = bufsize; tdb_log_func log_fn = tdb_log_fn(tdb); va_start(ap, fmt); while (*fmt) { switch ((c = *fmt++)) { case 'b': /* unsigned 8-bit integer */ len = 1; bt = (uint8_t)va_arg(ap, int); if (bufsize && bufsize >= len) SSVAL(buf, 0, bt); break; case 'w': /* unsigned 16-bit integer */ len = 2; w = (uint16_t)va_arg(ap, int); if (bufsize && bufsize >= len) SSVAL(buf, 0, w); break; case 'd': /* signed 32-bit integer (standard int in most systems) */ len = 4; d = va_arg(ap, uint32_t); if (bufsize && bufsize >= len) SIVAL(buf, 0, d); break; case 'p': /* pointer */ len = 4; p = va_arg(ap, void *); d = p?1:0; if (bufsize && bufsize >= len) SIVAL(buf, 0, d); break; case 'P': /* null-terminated string */ s = va_arg(ap,char *); w = strlen(s); len = w + 1; if (bufsize && bufsize >= len) memcpy(buf, s, len); break; case 'f': /* null-terminated string */ s = va_arg(ap,char *); w = strlen(s); len = w + 1; if (bufsize && bufsize >= len) memcpy(buf, s, len); break; case 'B': /* fixed-length string */ i = va_arg(ap, int); s = va_arg(ap, char *); len = 4+i; if (bufsize && bufsize >= len) { SIVAL(buf, 0, i); memcpy(buf+4, s, i); } break; default: log_fn(tdb, 0,"Unknown tdb_pack format %c in %s\n", c, fmt); len = 0; break; } buf += len; if (bufsize) bufsize -= len; if (bufsize < 0) bufsize = 0; } va_end(ap); log_fn(tdb, 18,"tdb_pack(%s, %d) -> %d\n", fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)); return PTR_DIFF(buf, buf0); } /**************************************************************************** Useful pair of routines for packing/unpacking data consisting of integers and strings. ****************************************************************************/ int tdb_unpack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...) { va_list ap; uint8_t *bt; uint16_t *w; uint32_t *d; int len; int *i; void **p; char *s, **b, **ps; char c; char *buf0 = buf; const char *fmt0 = fmt; int bufsize0 = bufsize; tdb_log_func log_fn = tdb_log_fn(tdb); va_start(ap, fmt); while (*fmt) { switch ((c=*fmt++)) { case 'b': len = 1; bt = va_arg(ap, uint8_t *); if (bufsize < len) goto no_space; *bt = SVAL(buf, 0); break; case 'w': len = 2; w = va_arg(ap, uint16_t *); if (bufsize < len) goto no_space; *w = SVAL(buf, 0); break; case 'd': len = 4; d = va_arg(ap, uint32_t *); if (bufsize < len) goto no_space; *d = IVAL(buf, 0); break; case 'p': len = 4; p = va_arg(ap, void **); if (bufsize < len) goto no_space; *p = (void *)IVAL(buf, 0); break; case 'P': /* Return a malloc'ed string. */ ps = va_arg(ap,char ** ); len = strlen((const char *)buf) + 1; *ps = strdup((const char *)buf); break; case 'f': s = va_arg(ap,char *); len = strlen(buf) + 1; if (bufsize < len || len > sizeof(fstring)) goto no_space; memcpy(s, buf, len); break; case 'B': i = va_arg(ap, int *); b = va_arg(ap, char **); len = 4; if (bufsize < len) goto no_space; *i = IVAL(buf, 0); if (! *i) { *b = NULL; break; } len += *i; if (bufsize < len) goto no_space; *b = (char *)malloc(*i); if (! *b) goto no_space; memcpy(*b, buf+4, *i); break; default: log_fn(tdb, 0, "Unknown tdb_unpack format %c in %s\n", c, fmt); len = 0; break; } buf += len; bufsize -= len; } va_end(ap); log_fn(tdb, 18, "tdb_unpack(%s, %d) -> %d\n", fmt0, bufsize0, (int)PTR_DIFF(buf, buf0)); return PTR_DIFF(buf, buf0); no_space: return -1; } &REgݡQ1H [L1*ߗ Otڸ%hE.I} !["֭js*S)j jvТ88&Gb2>CXZg0^\Wl:Wd>2yq7ߒaSHLeDS V4V;x3vQQxʼmi..9{zx:Χ]52}%W}'s)= AW SH7 t44Ufl؈ktӒLA>߼>zvz3&tXs-C: c1v稽#=iw5pR̆ΐA=4s Ӯ@I}d} =yBwV])l 3l<} 'I:LrPlU<Z0wK:@܂pϊlwŸxc/JN 6ءRqTeQ@oi`MiRl*nwʕ+FX7`I%^M6fb~9j.hqd" vdpWy?B~OB#ɾ/.T7E8[rvdha,O(yB/0_7/q4旸뵹iȔ| dXH舨B}0HsE<&`vnBJ. fƲ^#d$HAq_+= )~?9c[%:M\g eqz)# 뱭Xic5Fy@kOW@9#:M1sb(x˾HQ8g aRWm18GЛPÿ`f ^ T!bO~Tz40g:se*h{>=xv^vVYQf5Rk9IHcfMdjzTڙ0KuhSC=&o/B$T"?dSˡ7Esv:ww-oŁGUѦ/sedZgrڥ ~zMv@qJ^(38Q˹k!@ dp"h3RV{-`tPTUWχaFaoI}(hxrh;4RthI ҄py\1x1d!X7;sH/ w(ԟӮIXXUh|n~WOu:/R$㨴q7`fE*w4{ khCMf8P_zA. WR!KYz37g=A)'9q@}Ԁq-)sz~cgl(e;R).SgC AJ[Fz)0#i"Q>4=MrRٟśtwlY%?0#!R2OQdVGCk8 %}'zL1Z wgȯ 'o*4qjJ,e?*^ xl xA lld88ox܋Y ө\],pQυ;W}M@N-/bln7*QC@u3+ΣI B*1aA@& 3Į6kV|r`ZƠTN(+}[V9?`l)yZpx.y);=q =npG7iaDj e^H7k@4ܲ 2CYYIҚ4#qhM"I~;wDÉk= ,ʰ2ڣ.yͽ}=dkLo|>]>}翎Oy-h_c0*='D94_~`8n~*!LV įᲧmX*À"ThUo9"D_s'v-t %'_ d\VukBoghMjĺ=2O3d3M9AI[\ݗ?:_+HeM6]Wz;4J!!JXȞ(.P*SMA{&A* tegk + š"[$YPsUR͏t}! m@9)ja?Y)kI/L`f ^f $/Pz21Tg ޔػ9a$H?~UtW,76Mށ2h9 Z2ޙco]/%!u1##….ɒ}}AͰhV# cN)ho.i^PmvD.f{gjX - :P& m4~! J!M+OŔm0t/K;yb|+$"ss_F.ݸ^HvtTgZG;H7fq5F{dۥz>Kb){½Hf2dJHZ'uD%VUOڋ4X $2tl'*đFZ_$Z5^ 㫈p߯b wPלּzc@9J ("{:h'IQzůO6&'b%KPE$S ΃eW҂'*ϰ{SL[O@|",sD+mYwMZ*?͏D`?8%[e0|Hj B[hDTDř eN$_xa|kW} ـ$ڬR0dXhcxó^٫!`h~H!t_u!9 '5No.`1')xa8 -'3)cz0Ia>“llO83 Y^wpP~j7pd;PT6jAϪh_B!.ɾÓ{F_}6XfJX ",ٔ^Phpav5aY-o~oe6[/|r&YX53і*)Cժ?mVzHnX9+r g³Y.!]])78uGـ)n<A>Bd-T5c]~ 2;LWO<8Y1%:yRql+_܀|ާC=-7uƤeշe=qzq-B$Um!HJf0rB9]C1"W~{Ax)`4 :9,@: @)_ZP8䌵xlH֟hpp7m=$;F LT8]#0'apK24ӵT e\>`I'\1,KSCWpM ULnH s64o'5X.ń_0si9G*XV-4צv]j0S(VNvWUuo;eTʢajЄ`bH YdlR,_>4Հ)5>.fI[oNhy0\F!j1eq^2U̘0B&qa *= jp 0 P-'4ml<ˏ%MF>®r/꓎ YQT=n!EΣCU{ 5}- o3#1)^ ۧ\-zg*pdPk4$-_'h57Q¤5FHݻk7܁p>.^2>޷pFm{Ie1bP^"뷹AWu"v.oG2T7=ժk-ݹHNkxoqzl9וxçE=_';f/[ ';]sZ6 i0j.5.RxOILmV xQU@+@0I>fajG8݆}* O1aPF(Y1im>Cڊ.)^$Ydo[T+:4EsYWla5%cQcB ٮ!Q)xbmU x廥kSYÎE%lݽs{ ~00PpZ"Mq@pESx2_ аx%n²1J9nryFm)5i2PC.@Z,v6Ff=|~pT#7"a|9#iLՉW]kbq춌z!'H\Bl ;gWfe Fշ!%=)t]zq)_`xGhnҟ1=si-b"zp㠁 }3ۍbv)5RQeYn!GG/Lz#Sup +ġxI^&m&WPڧr3^0h;yыB Z37x_!`k T9:94ehH+M52Q/[2ȟ<?s-UH^FPSJF=%NrBX!lv*c[`:8]i?Z@(/eladkVuh~J'p`ET̞=\\ys;i]qc1X\ݭNoV $k)/!Ʊ{\wKlО Ul< ="4S꿚h6v롾d Ǯ6_BS7F%u!T!5@HY5*,+({lYW${VD~10Hާ~ + wC#RI-1wY_l7 #389o[yߣO:UM$A(X{,3kC[ KuF!ZeIHsh@p%#S;bA>n*hLͳ+a`.@:#Ip)f2MF7WcѷL k>ϥOA%CRſ2B˝صNs$EU^DKߐ#[v_㞬L2 ٠!w?(4]WZ7,"R6kFV{,t9*Vh񣖧ΌǹY05q؜6Ucr$q$-fss{)Ea5NF%e|+F[U;ҟ56&_\*?|$)Ĩ&͐POR W4'9 B7鄼ŦU,|"FbݎַG*mY(QM:aQ]z ^Wh9)Iůe%Y*ת%**M+}VոFu#_qV)aTo]^^px[bCv7b4J_N?C`1[;K@V4I(>ؤ58jV7#KK( y@:_(cLiV= q8qoXY?E:'g{?֋֠KlXcnQh,-HF>!OkvXK8-& X) 3oS03 炆cv5MkٳTH ^nzy,uO-F#MmG2};CL2M{9Jlz1illu5w%'W H3$6HLb' Y;ԷxS\~ĜN~ϯDȃ$# pļQ La93(V/kw|.D \nP @]n6^;CJ{7g36wyGMKD-nh])N9ٮrj`šhK1h%GsإʧqBʵSϟ\\(sܭmu wd2t7i7l2xĻ%RO-!s:7[an},0xTuByvp8a wwzuq3f? q\ce܏XI)\5( =W?R˥=[<:Z&}5ZLyz.@ߖߛ(([ۨg6GrykH 3T%g.9n7|<)gL[z(z_w7#2xe[&$Sl5 $^[Q1I"sEQk\\1m{SSU#FJC!e/z?낆@`1 |㸘[{>ʎX"%Ku77*FCI:4Yr~T"L|Q,\ަQN&E8d/B;а_η=oy6Xf%eBrM%/ pR>ldtNҼ\?eUy@8e !LO+xUğxXuar)H+]/(Ux~G _h ȫx6&kaքRYITٽ)_А7_=V%D(BTOݓwlɴZr%Êk+BT?//،WÊ&؝Ne{g#mK5{Y,qD|1DR[}p񌌐M7ے&FスpG`|&jKV;c:)`638^W~3Cp"@g܉E Bh>t7paqvA i=$jK|wo[z\ @N7Ҩ[٣Y|-@8*>#rm{EiorDžĠTtF&}8 bfYXKxS"Oi˸^vû%Cam>} r1&Sw-B\Vؚ_w*'g3NMK,ڱ'?ߗF7I <];ƫojXN_t;dūX<boPŵ@".֎ȣ_I0% @kf4#T` !uZz*8!ݎuu]$ 8%fDxr dYH4GZ.)7 bpҝ[*Cp ZjvtEVM$hJ4V*MpHr<.ӹI[)l}+Bas4_!OV1##T{Cj"^HjTo]:yߩXR> gw_@{~?.Сkm,>㶖eJ1w+]gj#i~r%v'5;O ;W zlPr|YCv (,Wc.pj@[-MTP*^iNeS9 {#&ƢY/k1kJӅ(mkeEQ|^hNlPfU Z4Ӆ@c5%\*U%)jP-)#-ŋ)OE*aHԳLx *=Z>-i&TyЗ 0Iw^-ͶÕkL@yK: 9+DX>il=GX]LyLv60>΢(5ѣ@_{:T 0mɇ ~<[6**Ub?nh#!%q>G7S[HF̗,p@XqV0.r0be#M(]tn=&x"Fh?kZufȐ"V[<I*;S!fJuuW?zu1=tFLTFq[ z\#uT%qL"ֲͫ t](ƶKɻ ܜ}՗/sъꗡ(h!zCςIPWu:( & i>&8Y`-üEtt\FV?|;]f;v8*G$­ZVo =]Ӎgޡn鹙h+j06SE3M8TOϵk}uj; hoMf:&_-pNh/BVmFCƫ$U7EŪ@'RPLUϾNjaZp c\D+]#گ} kѐTTIh5+փV- >G*F=O22QU>:d :_ x s$5tcwbR@>VL2A\R-UBJ@8WY.x};E8WɋR"1rvuBmeYfvK6}W\ n- ۂ9wB^D, %K?x}?C gk;.BCrKlOX+;yI4^M45V'K#21d5+C-vTyL' dPJ9[#U!t1RgwF ~@Z7!kRM3Er[%#z:EWC% f,PΞU#h9jRXكM` KѺf>0)nhP'R |h JXf<4V"gD1'd7C{$J.z#ioEsn$k|r袁Q9a9#l W,P?w":;lwZpr[-qdGFhٙ۵Qj^Fs_w*J] ~+e)6DMr߼]@_˜-v$t$JiKI.׍QzJF)>t48YSd~ Y˻7n.KwJveO@/WYҩ=RapwvgKd Q۹ J},Nݪ ]|m ]0gG(ʾ 28!=2Qºd"3my #hEOVj莚.@_&lx|,RO,N˝,u d h>nctQt:_NNT?.@/Fuŗ^qjHk3lA松j\xzLqe잜uyib~ V_w&c|A!fDv#@ž-%=~!;H? TV <(h5B_wM|" ݒ2PNq`g/(;ڑЏf aOeea6EQ TfrS TΞ>tG݈Ǫfds'U Q(s1$Rut1rSG-H 3[MyZ4_zђW ' w; 4 ~jʿ?ҪRCөuˢB}z4f8T`why-) g&cnHwl95.׹sfk Ǥ5urUGqA^=6!{yЋAOWt3j{SPI];FP]ce ) nV1t M忇-A)H$=ע/3d\`nuWw9BZ=ڣoNev"?+r,Ȫ}+TPVOY^~yTZ-=AOX;0[2ucmi3BjP@4rnfdNp_?C3d\4-P{8ysp5*ѭcb e,sUW Iv%5BV%ɭ4/҄B"S3i4!f//:sī( '٠0^{B9~_ȅ!շB57vnC%U(.ױ6|EFköNWNZ$*p#-$ŭk)H]ƥ <=bm'O9w }.7u`XuI`TwYpI֩ [yIB;ԯk撽O>[:'g"GiW)1n#}0fS6Tæ1fu> {/ØC L qwdzPI ti;`Du%K嬽I|5)TnGi ܜqK(^n !O{f/SCR8~f(ZLJAºQ \s漨Z(\slJc/PMiLklR mwg$)f148X4ssn_#N(q ^h~ Qg>mtQlqӰXuA}L!L@I5 aD)qCRd@8KbZ $NoPbx ӑ2I ڤfﳎ<%7kxIsOrY¸Fp5*ZG1fcoP9.*'6(%llc}kx7/t|h Ǹ$k_#BXeV(ADQR`U!6q v%Q+Q1{aWN~=>͍|i@HS"R); mӯlBE%,ș' _JV`,)h1lpI~Rn2j-Ww<eija%Ն>!c{K gP,s6.௣@`  w"Ox`C (OpU$AfouhC#鸨Qb8:Ng"!\m>Dws7ef#*>m!uJ(Py&K0'cHk̇P%yHL7y 75Y6.S*%⺏CKh%ʉETKW 1Lʡ?j/Ff`__9SspIzsTFu1+ܻvM帅{ˬm*I<]8ݘq= 1Pʉ/4*Nբ%|)|@ poBt6YB5GEbjB*ci49N9`)D4Ȅ@\/]_VZHq+f H6-u*GVɊG9PHim`݇nd8@c(فZ-Xu;17*SN(14ԭ9- vGxEMs.;q͙ ERSvIvdOp(WL9ۉ_M\ShzIһQvނ +p;mKG$:Op^EkZ w޿Jt8ܪDI[Xz0텎8!2@b`#uAmnD&  =%ve(Ա=@,eQ\DV $<ēIX"ak36M+nߗaTiOl?ΧWRT)-( ~rEͦ 'mjݱ$K}9fx"uπHRA"#>,mhHaСveBHFbB=nVƺEǨw7hJ3S2 ʼnϚYE%b&_ e@C!25"7EkÃu0/PYbEBISOS @ϠjvDKI E.O[ݽ]ϨLyuR~ޜ$|d /OvxU pp"mf,_+Ă p.A:wNW]jejV-Lm"  6j_KWA/I ՚A F/'N2$uCɎ3qɵe'?XԄءAVUPlނvѲLm­>$L3g|ABGVmK9`у0}aoGMcwRBtYƥiz6+"!cCfrH5|FUzyEߐVtr 苡EI"fL+ S } G|݅hJ/j& k/oۧ0/Ow5A FqiI E#LbOkӂ!q#-KG\6kz*CԣXDA9K}ח> xJ&~)b<0w|7qםֶW  |ԨП+Г#KtU:߫O<",En8jRK ~ @~j׾{_+5N|CW[UnYyh ]4FUCs敯mZ@j0師gw*TXn݌*qy"}]M*ܔ[Rt͇E ߆\՘hMD'%}Hj~vtFK`xQUEа`n _ɾȳJ`@C,eM2T(Wkj%( †:5Ǥ^9XAk un@S4fۇI#=TD]A9J>qMQe^ʕDVV_m=( `©^Ori)'=wSY5ɮվ0ɒ֮M0`ug^r-]e9 ؆{/0Rٵh%*LgpkSwWY;#hE^ sR>3T/]{)bĥLɽ켁Jd[GjcM[K f1zf;u`mnG Ō&'BRaSDfmu0#4!5GK cCH>1,5kn]Z߮>l U5#̴2z̲Y@`p">zy#&d:ނCNr0fC`n3[rگC Tvilk\\aϯ[]D ѾwMgNYUYȉNt9'q%Ó}O|eƷ6Bi.`pDc61^a#2dx][s2A=FV GxeIbetC\{7 e*>Ղge$Ht>gM._<Rȴ<&9Zg`֯J̳}iRˑ:,9hW o״{1oo]24`0b"$NfrS499)顔]I#FFfm}b=?ěgeXύ@h0bVfDl`TJi1VRsWЧoƤx9oxd<3B7ɓ8 :0߬ɻJGNdǝ`l5 )@@/iN?Du2wm]FIL-ȩ}BCV2K6Pcސ+~[wGN8zx&7+<l]$b?1)aqn{\e:dlM{_)D_[Q0XDBLw嶒"{%콥֕-(:&aNg .d=ª^ O'4l!ګXoHR\ 7aM(KmX{HRf!.Oj2FaTZD1ILI-&: z* E&wo*L |8l}AͰ^?g PwM2}j&'$Z/yV9X^cx|s? h̍"4'Ýӥpp%׽O.ԑ5ZL'HTT[tj`jԆqnIYÝ"_uXZ5gV ˪FiߩwN KRXvk-d2̆s; ھU!\eB{q8oxK9zԋ.p'(_S&RE͞@=rh(EQ]@4އ0f)-_ )ǹK`tB<@#SC !aq֣o &.?U#<A5lP~%2j_j7Kx?U`n{C:_y˾Δe6 6Fc"BAXyExNR r ?c.Rb^ّ5c?? d[J|k<1B \ `(g&6͝[dTltH^8quG2W/>R-TK;Dlt j/L*??(X Bj~jR=('!W+D|0Zt& ;8 gkж^F*!8X S \rJEJ}$t95V$*[i2#ZܹܬڎqJ#y\'_bėVH]wQ1 _٠a+}L.5Ce#r9ڏVH =X(̾MLPlan4,uT;ߤJ CŰRgWIq]pu_?-4mo|=~3G*.-7@DB)a䇪ӧcT0QWiF2k+=6N#TLmGڌ.;Z0H, XIʴ 7Ќl)Ep)Ş艁%W*_aRS=S,HS[4encu s(!&du vKA$F" tS,(#h$Z!'Xk<̂%8G̏o Oath5!`IxDíS$|Ny"`3UG3yZ`R֢?F`jh} kޙ:CZt-$t7{66nZ/S%*߆tFKGy\&tޚVFtBpht/8*#ʕ?CR>+`'PzI Y_d84jw í$I.{: ڊ :rnJi2CD*1J[ߡrkאTGt -42%yY_w Tb;ײQPd2T#0`2'mpO)( ΙAU#t7XĪ@JN+SZ[-GzYW6jQCfٖ◨n>Z,pu5'`A86+QtEF тfl po(j$9Z%vG 6pu4l[Dڌ%Eima6ДQJU󋃲#XxٚBk>%ȸ@|Njʆ&Q.%g_ZGmKlX?Ў%@*?zPU-ҿ)`]T+g $ggԣøO[! !\y52gd`4XuKeu;Kc^4Lyf< ԬoЅ44=X1RgTJhfZۭx,IW;#˟_NP- ֪rz"  O#%Œ5ɴ˫<3r%%H۪M:7Zw/%yF-"ɍni;B iMui V1RtrR-I8^!z%Ca|v|Oɋ[xK(o-6$1[e$8V:P:nJ8$lx0Mܨ^_}q6h}8:!(O0Dj)cwf;hd<pbv{*Ws/!oJlSqz1yygQVDfj_ThĢP:WelB0Oc*/y^dyvb!vKުX-WQ=H S]e [6' #:q\ƒڇn1,xNY}%D7|Am#kեY9}q'?! ybwcP/7od3!6_s`s"K#w`'wv hgCfJ\^oD&3vaNcDDzYDı f/"^3Dm%W=?!̝G%cWU8WP_|B s:1X/<ֵD-:JdVf6`hb$R-H;\iiyJqL* |fj񰂹{LD\Y3iuP7_V$\:n?THgruX2#5CҶ .z}4juRfIlF'aƎ I̝+= U7HY@0(3h7:Hޜ([YF*X<<}c1,wk^Rȉg^P欌Ve$]b,M-'g b[{^DBmPߌopc˝* (׋r6 9rv￉Wtо *Hgajpu`ӼXOR"Tp ɡH1j#]ځ^3@(U@;Xtoa(1vy?w?CfVMd X>Sd:j/ȦR&dod/IOviqHWu'3*BFU`f.Ӭŗ35O?+UϣL%(dZi0Rvć|nbS*O& }fg5B@vJB굅pHf}Ji ǭ` CjIx"fT$9J77F_ Ovwsx#%q=p hwZcc;6X;jgz֓2;S/Hyy^5" ҳ jWaNIߎg W6zV+\՛P[ iQn?4 |0}f0 h%(b)cj62ˊE >9 y8\_C<%é7'rfG~cʾ1rKB2j1=UO\D Q9MP'HLލQ9tiמp/Fixhf-l.UkuT,TOLOtՐ/j[91_p*Z\}Wئe|t)֮WF*۳eNl/ a*߱cNr ,nJꝋڰׁ23~| e#4! Yo捹]{L=»ќE+tGq~wZӾo(v]YꐋoU1+; T:`{G2~A@Wdk.~ NdLUm/d H]O*WL0[|7|h㦑t^9.wb5?Tt 3;n͎GaLE^fԱ1~ӞSv<_K?8f{x^xДT_@l1^Hokbg͸LOן|E?ˊ&#1gO Z%|p:cQ"TᲒn/8F!+&ViSu-VƤNWfD-YP,sfbptI)A@#-4[{2ջ Y*8dQ?^yxXlC0#ZU??4_K&ѓQ IB 35Mi#줖+P~5"J89!SyMf@Rk12VhZX?:Bw!%v])xFz2-,m列ye2п_'O#b:>}SpFa88ɴ*ƨY$@]WwU\NO ]/nۄ*6[uk_oRܟˠD-7UXCozfv*ZC{oh6 Q-C+lsЩd݅C<5QR/?LGT0kvVKZ,W|oC(n?*䔔 0Ʈ}gRwg:td1_ ?'!u_m^Q&fkc1쭞}ds˭_Reɜ#SwmJ}dd%9"<?Z1xuON^#6a%sr[9N8JW^cR7MwS$Yl[B_mFGO%1Lp~Sǡb0ѴDX)X>k+ LIҁ$ xmpR@_w}wMwPDKXIffխ9 nnSY;&MGs G|ODE dEິlYp0i4&y`-ڸE%H(?~kcR_( K#~dիc*V2?mЅL|sy>wڿl"{@?b4pД~x뿈2$.DhmGcºL,HK5YXZf8'(xq]u ռݔjg{qt0/=7l)X@s `blb~ړiH ߴMh1M7!VvڇPv<[ᩅWWZf}ƚC*q8M즁<}|g ]y' wo~U<2nMG{O)Jc 6XJSe7q$9NU(5:BBG'v܀q񠧥/?Ul+ h1c0u'J4 `Gh/2cMNià4٢? o3p[Vmu)5i}(˚Xe/o|AَmD@:wq-g@ YageNcA YlI?\h2y=S-Zt@t;u~:O󌃶TI%tn1ؙfZC{Bm}an?zC; UDB4g~kDU$; DGNf@`B PG`uusmZũIJ:,Q(Tp2`9quC4!8m3&FoHοy6 ٺW$q-P*S#'C,CǡLd̀۷]$=>q50x=.1iB_p$4Bjoۑj(2ن M ia;й? cHcVq0R9S6pK:31Oyl}x/m鶗~[V"aKwg,Nv0uhwJL~ש78jl`>y%y~ϔM0?L߻bЖ ">qse3%k3;vMߘCdqWߠ`6f֨ecjT =ЪP=#)@M?yRht#:P6"%"٥};R35'X5A8 ӄO]?^ z攪З۬j&+jw~-Hm>|9HUd4@(bY@`F- Uc 3n"T\FJf/n f5`z*BV2|ЌŸϣ[u E,d%AݱV^`q$rR${=xf*=>go Ȃ^k1gQ*]z&fI~Q¾@1bv, cXθT~Kj%r(+ /̈́H ajX@?8y Qmj%cw1%| ٜC L߹Gku)"D }%AlOL#v/O95޽Ze9uG+doə<>x;AH<`i]~(BVm%`Dys|;L%S(VUF?m8(wI g1 KӸc6;P_{l ./}# 3XV RM?nlR`=.8o<Ņ63w>#iEHߣr{2aՆm2?v sDgmtmj|}:u_K%j dTBrcÎPI]M~)NdS}@䋰{Y>uٟ{v6pD!Q+f[_0ǚM7vCL }c5:v>riGttRaD9~j8UqAΈ2 Ԣen(WFZ ;6LxO*0ߑCeI*8n~QU|L_F |_ǹoz'b54IBW})"aȓPF:]-u@W[(mlm5HrnFЀq3*rl05 Nbw" N o!M ۵"c#A(S2tLĔpN=l6dA1Qq2^iwkGT=Cs?i ][s $ @ Xaj m ܝ ;:1 屮=}eP[~#xOTd'iO~ gumcP<)NycWk~mzI^Z$X{^ivY偋ե'/zOWF-">7s 1@ i$&h֍?rVݸx1w'?,K9$߁9`xZ.p)RJ#dJXj++G`K W\ {mk¥b~A?;MTAmuqw`Cd`~Ah3H } 6nw2ӟ !|vqRN`D 69\/|uG-s*>bG4g.qMWo!UI uώɌ/yM~C3r 8IŖ Я*~KE3VTJUd2\Tq MkE1`2l{|'/c:X2:S46jSۭtdwk#4#もqk~m OHIuqqӹKDŚƏP0C" 5fr.rxG\ ghw|7Ö>yZ+]}?뛙@,=CXSF Dh8֌ϫ3Q%wj7/)T3br`.|Ҝ ktIq_[u9{~%"M1u7bA.rۉMJ"iQx@^=`4eΦs_W&7U9?.FP8@0ܕ֞LϪGkl>oZ]gR4k\ 23UthT4Ap*ŕ)W|0lӤ\KNy3mYMZm֘g=0:)gȪa 'Suhz_ڲKcJodٞ4x$EJL:[#_MCET؈<%ۘ" =i":zښdRrI;|;E< 9Њw{4}&V ޞ=/i,7 z5kc:"I Ể'1ͽkNhq-=Jz Bl Bc-o ۯtB4)\LDk0L%ʹ6UUvp~RdSH fŨ\I+AZm;*0pl')@Lf{/^f)LJm-]K~eYȯȢ (7Rz, v'b~3?\+|g ǚ,Uez +@>a7 69QQ'3B:P!3fCuf$y.@e&f鎘 ԋ(Kޫ'"A%3ƻǼ/Ud c3Ã@-0087QzIۺmє$|-w arjv3gA^m+a!`jw⃣KH++lź:"(Cqs9Bu(~VvH@ꌱ#f [>-?PT@,3IGݺ00!9ϔG,oPLtch)>|bK[ /cej6fm=~O~V!Vyn, A2-UTv0boQl޲R+9=xa(O=§^0 FiA{^I3_>4:KK/GQ,?j׫ EiXn" a ~jˁtɐ1_2{k3Ͷv"4$Gm:[UlCi>B=JDȊ##Oty 1ͷ}6|;_F'ja2 {┾舯Cr`~R%]`L&#DPN:>ywy&,%Vt: rKoz q=Oر8+*ÎͧO_dRBĠY:o9 jӽE*pA* XAj6mK j _~7wB#dzȗ)4 fN|)ݑtI:g"R~4jA`@~>2^BWV]싰"W3Yᎍi;wgBFƄmjGd&{`lRw匱3J ,_ 1%V w 'e[ON[N>T*CP * ow־5pN\#.znI]/D%SXw([lb wLbD$==zc\<{yIFoP9'S/;.|'E^trњh*cѷ\i;&QaAZ"IBd_d2&f$@5mhyGP]iu7j ͝PYܽGGґ5k,3(i,(Gc:c,UhH_8~1 ˻|]޿6瘢KyHt;r4_Z N1ԵSyχu*!%/[B1xmVIje[@;V7=A6mx^k>lPqYsc/9N@UdfV ˉƷplU2#7!*ڀ?2y?lڢ˨47}on_@Q%@OaQa)GF gW8jݯXb݅uTeBGI%yrmIvnI.[c Ev_GbCQ \)Uߟ֝JJq1L L74>̋ws 6q6AOk ā| .`ŤXyUJ.x$fc'>r#5gXPԌM1Ւ+ιIcR‰(|ێvlW[L@p"Tmqղף:وVJ/g߲%$si j8@5(YD%JDط1|Gu|9ЈF=ĉȵW(xkE6kh!Jj<؅:ƞ.<8,ڴXcc@:Or;Siy9=o o!{HMWm8ϔkK 9p%R"k`Nx3m(!\.'٤*%D_C ̚"߻VA(Ȼy@'Q}Ś #.rN}BKtd5떟76 X,u8|z+tiݱYVT"Ey8H=Hg_A7h$lBڄA~yϞn`dj? N $c'1dOoF ~ӱ䮝dSehBlEDEaa7u [*"xE("DThc/hOj}u_z)sjD!-ފ&܋dH*Utiu[̊@6f ziy"Q?smU/9nU{kc|i\wgSp~yM9 m-=#ڦ#?Z'dmKbv& ?_n<"ڛ.nwqtRd:Vf"l=eWC=W8mXVjnދCA|?\gO 2= PBILp,2}IANܓ9Jh_k{hU㕔ālxp5Th?f Oҍh$BƟ84eN-nni00fT?40G$xS fVmSfw-#2SaF^$e(HQӶ֤C~<ڳzf|pRL9Lx, Z7,_$nWTfٱ")ݶVu7?Wg&:bCz r?;3CHg9 >s7%zDrՁ"q14v&W6rHї㯐mLqΨc1 JՅ'Pr\AZdsߩTdix S=P.]ly7>VQڂ斅 `z06-Y]MSImnŧGABn|aMVpG_$t[[RU:E2Oxdrpn1"OVr4Dv$p C7rTFev>R/Al9 ukcFFt.d7N|D̫)ʲ'~=(bۑm&<{mM΢Va`pg`E,6{]]UQ{{{ypE86BY:z# < m}$&T:hN5t:.aOމ UͶF0ع(H@lʶ%Cfa57¹X PG[sj&/X+.rm}Q.%Y`]H`T+eOMa7*?ϱ+ߕØ¡s0{!AKj\vǟvs _EN+ ™_vͭC i U a'*U!ψ=6Q~@H?Zȅ=6?gb-l;e[ MwϥC[cpxUФhRh6IlQ{KqhlcM]E S׷ u?dצj38M ? He8aV凱?wPPN2ivL)$+{ìjbDWJXe?[-U?W~!yx9j ?l;2Kt>Ni.m~_ʡ .ꦏExQfm%i{*3_ۆcFIdW鬶|.՘t!/#VNPݖeukꇥ7]&xGuYy$}ڳLO&JB*c St8Y{E8 g؛9c}$~ t}ܻRVb~2?՗:nwO<l8A2NKzHi-@Vw= wL>nvWg\2퀓$Z֚P<^f\qeIj&l:{Cm~N)1Trde^Asy ظm}}:*ْv+?K A# QghZ*A4`xQbB e1 =~E|T-!w&q?5cvL$ŇU(I?0 gfn f%G`AbXPU8내I7SVx|I*+Y53$|f-^E`([T2>a%Z\88) "'-BSh\g]u~Pڳm4t76n9 ][~Nրs-Huр4[ɦؖ߇S]움S [x}3v96 @vmu1ǩ?ԔF fNHNhH-AdbaﹻR$ NlG `!?۬j#ݝ1dN/'<0LM6)6[%>oD &=)#FmGx,sw$*L-hٝg nm {.-"VM#i{RA.PKـ`j!cb&Itde?FLoGΤ=^zHN='b ]Yao0|-_J>  qA 0 \Ϣ@dZH Wqa当ۇqD^YU ɩ( HImсX0 z쇋e 5?z{Y{\d?cRwW.6# ܪh ېFyz$|#zpBD]Cj!E=@!Sf`u[Mi\{WNaVe94+R!@glzFėVQ DC,)c7V!򿋭Pwփs=;4J+ԶG?;MJZ&ah;)]=?.\|Q\D 4ac&:佄9d:hA*<pAVNLvع4O't1Cm`X ^~ )Kw-+a@ 14 $>mRuzrVfҥk k;;ĊESTtK;xO@DKYoN7+i\UΌ НP򵓟͑-gl\o9$N)h#}k؃p|YxaPlC0z$ ݶqxm`in.VNxX2o~F\HH܋%Zy 1O9}LnX M:Xxq'◚Q(5,yVI%e񼈟@= F$^XHS3e@;D#e^.z>!xGI}ķJ}L}LX-n{!`l4 ]xcZp2toM *NM0 B\ @S*F3|+-dq1U| UKwHuNh蚞`0mJkŲAz[<+{WV =F~, 2-!{IO%'Kvq_pr sy~=Djf|eANcVo5_|!E&q7_M;mfEZ:%=VQܴ~X(V=ZFdZ+>vf+יIuǠ;3uhJW%M Wy*٣rmMx[NŢy͐kBIwFYF