PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i WWWWWW
Current Directory: /usr/share/doc/mrtg/contrib/NSI
Viewing File: /usr/share/doc/mrtg/contrib/NSI/Mrtg_nsi
#! /usr/bin/perl # -*- mode: Perl -*- BEGIN{ #$main::OS = 'UNIX'; $main::OS = 'NT'; #$main::OS = 'VMS'; ################################################################## # MRTG-NSI 1.0 Network Status Imager for MRTG ################################################################## # Created by: Mac Kloberg <mac@nacs.net><mac.kloberg@lam.liebherr.com> # # WARNING: This thing was developed 'quick and dirty' on WinNT... # I've never actually tried this on Unix or VMS, so I # don't know if it will work. Guess you'll find out... # Send me mail... # # Built and based on: MRTG by Tobias Oetiker <oetiker@ee.ethz.ch> # and Dave Rand <dlr@bungi.com> # # Credits: THANKS, TOBI AND DAVE!!! K.U.T.G.W. # ################################################################# # # Distributed under the GNU copyleft # ################################################################### # The path separator is a slash, backslash or semicolon, depending # on the platform. $main::SL = { UNIX=>'/', WINDOWS=>'\\', NT=>'\\', VMS=>'' }->{$main::OS}; # The search path separator is a colon or semicolon depending on the # operating system. $main::PS = { UNIX=>':', WINDOWS=>';', NT=>';', VMS=>':' }->{$main::OS}; # We need to find the place where mrtg is installed, and # then take it from there... $main::binpath =""; if ($0 =~ /^(.+\Q${main::SL}\E)/) { $main::binpath="$1"; } else { foreach $pathname ( split ${main::PS}, $ENV{'PATH'}) { if ((($main::OS eq 'NT') && (-e "$pathname${main::SL}$0")) || (-x "$pathname${main::SL}$0")) { $main::binpath=$pathname; last; } } } die "ERROR: Can\'t find location of mrtg executable\n" unless $main::binpath; unshift (@INC,$main::binpath); } # There older perls tend to behave peculiar with # large integers ... require 5.003; if ($main::OS eq 'UNIX' || $main::OS eq 'NT') { use GD; use Net::SMTP; #requires libnet package to be installed #use SNMP_Session "0.71"; #use BER "0.66"; #use SNMP_util "0.71"; use locales_mrtg "0.01"; use Config; #$main::SNMPDEBUG =0; } #Doesn't seem to work very well with the win32 port of GD #use strict; if($main::OS eq 'UNIX') { my($i) = 0; my($name); foreach $name (split(/ /, $Config{sig_name})) { $main::signo{$name} = $i; $main::signame[$i++] = $name; } } $main::DEBUG=1; sub END { local($?, $!); unlink ${main::Cleanfile} if($main::Cleanfile); } sub main { my ($router, $target ,$gdstyles, $neweventcounter, $eventcounter, $newevents, $neweventstype); # unbuffer stdout to see everything immediately $|=1 if $main::DEBUG; print "\nMRTG - Network Status Imager loading & initializing...\n\n" if $main::DEBUG; my ($routers, $cfg, $rcfg, $cfgfile) = readcfg(); $target = cfgcheck($routers, $cfg, $rcfg); print "Locking Config Files...\n"; # Check the config and create the target object # lets make sure that there are not two mrtg-nsi's running in parallel. # so we lock on the cfg file. Nothing fancy, just a lockfile # my $lockfile = $cfgfile."_l"; my $templock = $cfgfile."_l_" . $$ ; if ($main::OS eq 'VMS' || $main::OS eq 'NT') { # too sad NT and VMS can't do links we'll do the diletants lock if (-e $lockfile && not unlink $lockfile){ my($lockage) = time()-(stat($lockfile))[9]; die ("ERROR: I guess another mrtg-nsi is running. A lockfile ($lockfile) aged $lockage seconds is hanging around and I can't remove it because another process is still using it."); } open (LOCK, ">$lockfile") or die "ERROR: Can't create lockfile $lockfile\n"; print LOCK "$$\n"; close LOCK; open (LOCK, "<$lockfile") or die "ERROR: Can't open lockfile $lockfile for owner check\n"; my($read)=<LOCK>; chomp($read); die "ERROR: Someone else just got the lockfile $lockfile\n" unless $$ == $read; } else { # now, lets do it the UNIX way ... Daves work ... open(LOCK,">$templock") || die "Can't create templock $templock"; $main::Cleanfile = $templock; if (!link($templock,$lockfile)) { # Lock file exists - deal with it. my($nlink,$lockage) = (stat($lockfile))[3,9]; $lockage = time() - $lockage; if ($nlink < 2 || $lockage > 30*60) { #lockfile is alone and old unlink($lockfile) || do{ unlink $templock; die "ERROR: Can't unlink stale lockfile ($lockfile). Permissions?\n"}; link($templock,$lockfile) || do{ unlink $templock; die "ERROR: Can't create lockfile ($lockfile).\n". "Permission problem or another mrtg locking succesfully?\n"}; } else { unlink $templock; die ("ERROR: I guess another mrtg is running. A lockfile ($lockfile) aged\n". "$lockage seconds is hanging around. If you are sure that no other mrtg\n". "is running you can remove the lockfile\n"); } } } #Read the messages my($msg) = readmsgfile($$cfg{'msgfile'}); open (BACKGROUNDIMG,"<$$cfg{'statusmapbackground'}") || die "ERROR: Can't open StatusMapBackGround\n"; my($ImageData) = newFromGif GD::Image(BACKGROUNDIMG) || die "ERROR: GD::newFromGif\n"; close BACKGROUNDIMG; #Allocate colors for this image... my %defcolors = (#Color allocation table 'black', "0,0,0", 'red', "255,0,0", 'green', "0,255,0", 'blue', "0,0,255", 'yellow', "255,250,205", 'white', "255,0,0" ); %colors = (); while(($color, $cvalue) = each(%defcolors)){ #Try to allocate our color if($ImageData->colorAllocate(split(/,/,$cvalue)) ne "-1"){ $colors{$color} = $ImageData->colorAllocate(split(/,/,$cvalue)); }else{ #Didn't work, we'll have to match the closest then $colors{$color} = $ImageData->colorClosest(split(/,/,$cvalue)); } } #Define our linestyles $$gdstyles{'linestylec1'}{'style'} = "$colors{'yellow'},$colors{'yellow'},$colors{'yellow'},$colors{'yellow'},$colors{'blue'},$colors{'blue'},$colors{'blue'},$colors{'blue'},gdTransparent,gdTransparent"; $$gdstyles{'linestylew1'}{'style'} = "$colors{'red'},$colors{'red'},$colors{'red'},$colors{'red'},$colors{'blue'},$colors{'blue'},$colors{'blue'},$colors{'blue'},gdTransparent,gdTransparent"; $$gdstyles{'linestylea1'}{'style'} = "$colors{'red'},$colors{'red'},$colors{'blue'},$colors{'red'},$colors{'red'},$colors{'red'},$colors{'blue'},$colors{'blue'},gdTransparent,gdTransparent,gdTransparent,gdTransparent,gdTransparent,gdTransparent,gdTransparent,gdTransparent,gdTransparent"; drawtext($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, "cool", "cool", "", "always", "1", "baxter.x", "baxter.y", "baxtersprings", "black",); $neweventcounter = 0; foreach $router (@$routers) { my($savetz) = $ENV{'TZ'}; if ($$rcfg{'timezone'}{$router} ne '') { $ENV{'TZ'} = $$rcfg{'timezone'}{$router} } print "Imaging node: $router\n"; # set the locale my($LOC); if( $$cfg{'language'} && defined($lang2tran::LOCALE{"\L$$cfg{'language'}\E"})) { $LOC=$lang2tran::LOCALE{"\L$$cfg{'language'}\E"}; } else { $LOC=$lang2tran::LOCALE{'default'}; }; #Node test... if($$cfg{'testnodelocations'} =~ /y/i){ action_draw_crosshair($ImageData, $cfg, $rcfg, $routers, $router, $$rcfg{'nodecenterx'}{$router},$$rcfg{'nodecentery'}{$router},$black); next; #Normal node processing }else{ my ($incurrent, $outcurrent, $inlast, $outlast) = getnodevalues($$rcfg{'node'}{$router}, $router, $rcfg, $cfg); #DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- #if ($router =~ /NewportNewsEmailX400Kirchdorf/i){ #$inlast = 0;$incurrent = 50; #$inlast = 5000;$incurrent = 100; #} #DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- DEBUG --- my ($nodeinstatus,$nodeoutstatus) = getnodestatus($incurrent,$outcurrent,$$rcfg{'node'}{$router}, $router, $rcfg, $cfg); my ($nodeinlaststatus,$nodeoutlaststatus) = getnodestatus($inlast,$outlast,$$rcfg{'node'}{$router}, $router, $rcfg, $cfg); print "NodeStatus-Old: $nodeinlaststatus($inlast)/$nodeoutlaststatus($outlast)\n"; print "NodeStatus-New: $nodeinstatus($incurrent)/$nodeoutstatus($outcurrent)\n"; #Generate events for the log and status-email my $ineventid = ""; my $outeventid = ""; my $ineventtype = ""; my $outeventtype = ""; #Cool event (in) if($nodeinstatus eq "cool" && $nodeinlaststatus eq "alarm" && defined $$rcfg{'nodeincoolmsgid'}{$router}){$ineventid = lc($$rcfg{'nodeincoolmsgid'}{$router});$ineventtype = "Cool";}; #Cool event (in) if($nodeinstatus eq "warning" && $nodeinlaststatus eq "alarm" && defined $$rcfg{'nodeincoolmsgid'}{$router}){$ineventid = lc($$rcfg{'nodeincoolmsgid'}{$router});$ineventtype = "Cool";}; #Warning event (in) if($nodeinstatus eq "warning" && $nodeinlaststatus eq "cool" && defined $$rcfg{'nodeinwarningmsgid'}{$router}){$ineventid = lc($$rcfg{'nodeinwarningmsgid'}{$router});$ineventtype = "Warn";}; #Alarm event (in) if($nodeinstatus eq "alarm" && ($nodeinlaststatus eq "cool" || $nodeinlaststatus eq "warning") && defined $$rcfg{'nodeinalarmmsgid'}{$router}){$ineventid = lc($$rcfg{'nodeinalarmmsgid'}{$router});$ineventtype = "Alarm";}; #Cool event (out) if($nodeoutstatus eq "cool" && $nodeoutlaststatus eq "alarm" && defined $$rcfg{'nodeoutcoolmsgid'}{$router}){$outeventid = lc($$rcfg{'nodeoutcoolmsgid'}{$router});$outeventtype = "Cool";}; #Cool event (out) if($nodeoutstatus eq "warning" && $nodeoutlaststatus eq "alarm" && defined $$rcfg{'nodeoutcoolmsgid'}{$router}){$outeventid = lc($$rcfg{'nodeoutcoolmsgid'}{$router});$outeventtype = "Cool";}; #Warning event (out) if($nodeoutstatus eq "warning" && $nodeoutlaststatus eq "cool" && defined $$rcfg{'nodeoutwarningmsgid'}{$router}){$outeventid = lc($$rcfg{'nodeoutwarningmsgid'}{$router});$outeventtype = "Warn";}; #Alarm event (out) if($nodeoutstatus eq "alarm" && ($nodeoutlaststatus eq "cool" || $nodeoutlaststatus eq "warning") && defined $$rcfg{'nodeoutalarmmsgid'}{$router}){$outeventid = lc($$rcfg{'nodeoutalarmmsgid'}{$router});$outeventtype = "Cool";}; #Log events (in) if($ineventid ne ""){ $newevents[$neweventcounter] = $$msg{$ineventid}; #Translate variables in the event message $newevents[$neweventcounter] = transeventvar($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $newevents[$neweventcounter]); #Anybody needs to know about this? if($$rcfg{'email'}{lc($ineventtype)}{$router}){ $neweventstype[$neweventcounter] = "$ineventtype/e"; sendmail($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $newevents[$neweventcounter],$neweventstype[$neweventcounter],$$rcfg{'nodestatusemailtarget'}{$router}); }else{ $neweventstype[$neweventcounter] = $ineventtype; } $neweventcounter++; } #Log events (out) if($outeventid ne ""){ $newevents[$neweventcounter] = $$msg{$outeventid}; $neweventstype[$neweventcounter] = $outeventtype; #Translate variables in the event message $newevents[$neweventcounter] = transeventvar($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $newevents[$neweventcounter]); #Anybody needs to know about this? if($$rcfg{'email'}{lc($outeventtype)}{$router}){ $neweventstype[$neweventcounter] = "$outeventtype/e"; sendmail($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $newevents[$neweventcounter],$neweventstype[$neweventcounter],$$rcfg{'nodestatusemailtarget'}{$router}); }else{ $neweventstype[$neweventcounter] = $outeventtype; } $neweventcounter++; } #Main action loop, the right sequencing is important because of overlappling graphics in the status map for ($actioncounter = 0; $actioncounter <= $$rcfg{maxaction}{$router}; $actioncounter++){ if (exists $$rcfg{"action.$actioncounter"}{$router}) { my $action = $$rcfg{"action.$actioncounter"}{$router}; my @acfunctelements = split(/\(/,$action); my $acfunc = $acfunctelements[0]; #Cleanup the function name $acfunc=~s/\s/ /g; $acfunc=~s/^ *//g; $acfunc=~s/ *$//g; $acfunc=lc($acfunc); my @acfunctelements = split(/[\(\)]/,$action); my @acargs = split(/,/,$acfunctelements[1]); #Cleanup the functions arguments and put them in parethesis... foreach $acarg (@acargs){ $acarg=~s/\s/ /g; $acarg=~s/^ *//g; $acarg=~s/ *$//g; $acarg=lc($acarg); $acarg="\"$acarg\","; } #Execute Action eval("$acfunc(\$ImageData, \$gdstyles, \$cfg, \$rcfg, \$routers, \$router, \$msg, \"$nodeinstatus\", \"$nodeoutstatus\", \"$incurrent\" , \"$outcurrent\", @acargs);"); die "* Problem with action statement: $acfunc(\$ImageData, \$gdstyles, \$cfg, \$rcfg, \$routers, \$router, \$msg, \"$nodeinstatus\", \"$nodeoutstatus\", \"$incurrent\" , \"$outcurrent\", @acargs);\n" if $@; } } } #put TZ things back in shape ... if ($savetz) {$ENV{'TZ'} = $savetz;} else {delete $ENV{'TZ'}}; } #If there are no events, don't do anything if ($neweventcounter > 0){ #Open current log file and get the old log entries open (LOGFILE,"<$$cfg{'workdir'}\\mrtg-nsi.log") || print "WARNING: Couldn't open eventlog file for reading: $$cfg{'workdir'}//mrtg-nsi.log\n"; my @oldeventloglines = <LOGFILE>; close LOGFILE; #Open eventlog again and add new events open (LOGFILE,">$$cfg{'workdir'}\\mrtg-nsi.log") || die "ERROR: Couldn't open eventlog file for writing: $$cfg{'workdir'}//mrtg-nsi.log\n"; open (HTMLLOG,">$$cfg{'eventlog'}") || die "ERROR: Couldn't open eventlog file for writing: $$cfg{'eventlog'}\n"; #Add header to the html-log print HTMLLOG "<html>\n"; print HTMLLOG "\n"; print HTMLLOG "<head>\n"; print HTMLLOG "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n"; print HTMLLOG "<meta http-equiv=\"Refresh\" CONTENT=\"60\">\n"; print HTMLLOG "<title>Home Page</title>\n"; print HTMLLOG "</head>\n"; print HTMLLOG "\n"; print HTMLLOG "<body topmargin=\"1\" leftmargin=\"1\" bordercolor=\"#FFFFFF\" bgcolor=\"#FFFFFF\">\n"; print HTMLLOG "\n"; print HTMLLOG "<p><strong><font face=\"Arial\" size=\"5\">Network Status Imager: Event Log</font><font\n"; print HTMLLOG "face=\"Arial\"><br>\n"; print HTMLLOG "</font></strong><font face=\"Arial\" size=\"1\">NSI v1.0 for MRTG, Created by Mac\n"; print HTMLLOG "Kloberg <a href=\"mailto:mac.kloberg\@lam.liebherr.com\">&lt;mac.kloberg\@lam.liebherr.com&gt;</a> <a\n"; print HTMLLOG "href=\"mailto:mac\@nacs.net\">&lt;mac\@nacs.net&gt;</a>)<br>\n"; print HTMLLOG "Credits to Tobias Oetiker <a href=\"mailto:oetiker\@ee.ethz.ch\">&lt;oetiker\@ee.ethz.ch&gt;</a> and Dave Rand <a\n"; print HTMLLOG "href=\"mailto:dlr\@bungi.com\">&lt;dlr\@bungi.com&gt;</a>.<br>\n"; print HTMLLOG "Sofware distributed under the GNU copyleft."; print HTMLLOG "<br>\n"; print HTMLLOG "</font></p>\n"; print HTMLLOG "\n"; print HTMLLOG "<table border=\"1\" cellpadding=\"0\" cellspacing=\"0\" width=\"575\" bgcolor=\"#C0C0C0\">\n"; print HTMLLOG " <tr>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"65\"><strong><font size=\"2\">Date</font></strong></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"44\"><strong><font size=\"2\">Time</font></strong></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"46\" bgcolor=\"#C0C0C0\" align=\"left\"><strong><font size=\"2\">Type</font></strong></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"420\" <font size=\"2\"><strong> <font size=\"2\">Event</font></strong></td>\n"; print HTMLLOG " </tr>\n"; print HTMLLOG "</table>\n"; print HTMLLOG "\n"; print HTMLLOG "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"1575\"> \n"; for ($logfileeventcounter = 0; $logfileeventcounter <= $$cfg{'eventlogmax'}; $logfileeventcounter++){ #Add new events if($logfileeventcounter eq 0){ for ($neweventlogcounter = 0; $neweventlogcounter < $neweventcounter; $neweventlogcounter++){ my $shortdatestr = &shortdatestr(time); print LOGFILE "$shortdatestr - $neweventstype[$neweventlogcounter] - $newevents[$neweventlogcounter]\n"; my($htmldate,,$htmltime) = split(/ - /,$shortdatestr); print HTMLLOG " <tr>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"56\"><font size=\"2\">$htmldate</font></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"9\"><font size=\"2\">-</font></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"44\"><font size=\"2\">$htmltime</font></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"46\" bgcolor=\"#C0C0C0\" align=\"left\"><font size=\"2\">$neweventstype[$neweventlogcounter]</font></td>\n"; if($neweventstype[$neweventlogcounter] =~ /cool.*/i){ print HTMLLOG " <td valign=\"top\" nowrap width=\"5\" bgcolor=\"#00FF00\"><strong><font size=\"2\"></font></strong></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"1415\" bgcolor=\"#00FF00\"><strong><font size=\"2\">$newevents[$neweventlogcounter]\n"; } if($neweventstype[$neweventlogcounter] =~ /warn.*/i){ print HTMLLOG " <td valign=\"top\" nowrap width=\"5\" bgcolor=\"#C0C0C0\"><strong><font size=\"2\"></font></strong></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"1415\" bgcolor=\"#C0C0C0\"><strong><font size=\"2\">$newevents[$neweventlogcounter]\n"; } if($neweventstype[$neweventlogcounter] =~ /alarm.*/i){ print HTMLLOG " <td valign=\"top\" nowrap width=\"5\" bgcolor=\"#FF0000\"><strong><font size=\"2\"></font></strong></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"1415\" bgcolor=\"#FF0000\"><strong><font size=\"2\">$newevents[$neweventlogcounter]\n"; } print HTMLLOG " </font></strong></td>\n"; print HTMLLOG " </tr>\n"; } } #Add old events if($logfileeventcounter > 0 && $oldeventloglines[$logfileeventcounter-1] ne ""){ print LOGFILE "$oldeventloglines[$logfileeventcounter-1]"; #print "Writing oldevent ($logfileeventcounter): $oldeventloglines[$logfileeventcounter-1]<br>"; my($htmldate,$htmltime,$htmleventtype,$htmlevent) = split(/ - /,$oldeventloglines[$logfileeventcounter-1]); print HTMLLOG " <tr>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"56\"><font size=\"2\">$htmldate</font></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"9\"><font size=\"2\">-</font></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"44\"><font size=\"2\">$htmltime</font></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"46\" bgcolor=\"#C0C0C0\" align=\"left\"><font size=\"2\">$htmleventtype</font></td>\n"; if($htmleventtype =~ /cool.*/i){ print HTMLLOG " <td valign=\"top\" nowrap width=\"5\" bgcolor=\"#00FF00\"><strong><font size=\"2\"></font></strong></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"1415\" bgcolor=\"#00FF00\"><strong><font size=\"2\">$htmlevent\n"; } if($htmleventtype =~ /warn.*/i){ print HTMLLOG " <td valign=\"top\" nowrap width=\"5\" bgcolor=\"#C0C0C0\"><strong><font size=\"2\"></font></strong></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"1415\" bgcolor=\"#C0C0C0\"><strong><font size=\"2\">$htmlevent\n"; } if($htmleventtype =~ /alarm.*/i){ print HTMLLOG " <td valign=\"top\" nowrap width=\"5\" bgcolor=\"#FF0000\"><strong><font size=\"2\"></font></strong></td>\n"; print HTMLLOG " <td valign=\"top\" nowrap width=\"1415\" bgcolor=\"#FF0000\"><strong><font size=\"2\">$htmlevent\n"; } print HTMLLOG " </font></strong></td>\n"; print HTMLLOG " </tr>\n"; } } print HTMLLOG "</table>\n"; print HTMLLOG "</body>\n"; print HTMLLOG "</html>\n"; close HTMLLOG; close LOGFILE; } #Finally, timestamp the image my($ImgSizeX,$ImgSizeY) = $ImageData->getBounds; $Today=&datestr(time); my $stampstring = "Network Status Imager for MRTG - $Today"; my $stringwidth = GD::Font::width(gdSmallFont) * length($stampstring); $ImageData->string(gdSmallFont,$ImgSizeX - $stringwidth - 3,$ImgSizeY - 13,"$stampstring",$colors{'black'}); #Write the whole thing to the status map open (STATUSMAP,">$$cfg{'workdir'}\\\\$$cfg{statusmapimagename}") || die "ERROR: Couldn't write to status map image $$cfg{'workdir'}\\\\$$cfg{statusmapimagename}"; binmode STATUSMAP; print STATUSMAP $ImageData->gif; close STATUSMAP; # OK we are done, remove the lock files ... print "Removing Lockfiles\n"; close LOCK; unlink ($templock, $lockfile); print "\nMRTG - Network Status Imager unloading, gone and done...\n\n" if $main::DEBUG; } main; exit(0); sub readcfg { my ($first,$second,$key); my (%seen); my (@routers); my (%rcfg,%cfg,%pre,%post,%deflt,%defaulted); my ($cfgfile) = pop(@ARGV); open (CFG, $cfgfile) || do { print "ERROR: unable to open config file: $cfgfile\n\n"; &printusage }; while (<CFG>) { s/\s+$//g; #remove whitespace at the end of the line s/\s/ /g; #replace whitespace by space next if /^\s*\#/; #ignore comment lines next if /^\s*$/; #ignore empty lines # oops spelling error s/^supress/suppress/gi; #Trashcan leading zeros in action statements s/^action\.0+/action\./gi; #Also lets record the number of the highest action given for later if ($first =~ /^action.+/){ $actionnumber = $first; $actionnumber =~ s/action\.//gi; if($actionnumber > $rcfg{'maxaction'}{$second}){ $rcfg{'maxaction'}{$second} = $actionnumber; } } # append mode if ($first && /^\s+(.*\S)\s*$/) { if ($second eq '^') { $pre{$first} .= " $1"; next; } if ($second eq '$' ) { $post{$first} .= " $1"; next; } if ($second eq '_') { $deflt{$first} .= " $1"; next; } if ($second) { $rcfg{$first}{$second} .= " $1"; } else { $cfg{$first} .= " $1"; } next; } if ($first && $second && $post{$first} && ($second !~ /^[\$^_]$/)) { if ($defaulted{$first}{$second}) { $rcfg{$first}{$second} = $post{$first}; delete $defaulted{$first}{$second}; } else { $rcfg{$first}{$second} .= " $post{$first}" } } if ($first && exists $deflt{$first} && ($second eq '_')) { &quickcheck($first,$second,$deflt{$first},$.) } elsif ($first && $second && ($second !~ /^[\$^_]$/)) { &quickcheck($first,$second,$rcfg{$first}{$second},$.) } elsif ($first && ($second !~ /^[\$^_]$/)) { &quickcheck($first,0,$cfg{$first},$.) } if (/^([A-Za-z0-9\.]+)\[(\S+)\]\s*:\s*(.*\S?)\s*$/) { print "readcfg: rcfg $1 $2 = $3\n" if $main::DEBUG > 1; $first = lc($1); $second = lc($2); if ($second eq '^') { if ($3 ne '') {$pre{$first}=$3} else {delete $pre{$first}}; next; } if ($second eq '$') { if ($3 ne '') {$post{$first}=$3} else {delete $post{$first}}; next; } if ($second eq '_') { if ($3 ne '') {$deflt{$first}=$3} else {delete $deflt{$first}}; next; } push (@routers, $second) unless grep (/^$second$/, @routers); # make sure that default tags spring into existance upon first # call of a router foreach $key (keys %deflt) { if (! exists $rcfg{$key}{$second}) { $rcfg{$key}{$second} = $deflt{$key}; $defaulted{$key}{$second} = 1; } } # make sure that prefix-only tags spring into existance upon first # call of a router foreach $key (keys %pre) { if (! exists $rcfg{$key}{$second}) { delete $defaulted{$key}{$second} if $defaulted{$key}{$second}; $rcfg{$key}{$second} = "$pre{$key} "; } } if ($seen{$first}{$second}) { die ("\nLine $. in CFG file contains a duplicate definition for\n". "$first\[$second]. First definition is on line $seen{$first}{$second}\n") } else { $seen{$first}{$second} = $.; } if ($defaulted{$first}{$second}) { $rcfg{$first}{$second} = ''; delete $defaulted{$first}{$second}; } $rcfg{$first}{$second} .= $3; next; } if (/^(\S+):\s*(.*\S)\s*$/) { $first = lc($1); $cfg{$first} = $2; $second = ''; next; } die ( "\nLine $. in CFG file does not make sense\n" ); } # append $ stuff to the very last tag in cfg file if necessary if ($first && $second && $post{$first} && ($second !~ /^[\$^_]$/)) { if ($defaulted{$first}{$second}) { $rcfg{$first}{$second} = $post{$first}; delete $defaulted{$first}{$second}; } else { $rcfg{$first}{$second} .= " $post{$first}" } } #Tobi, I don't know how you did this, but this is something else: #Get highest action number for the last line in the config file... if ($first =~ /^action.+/){ $actionnumber = $first; $actionnumber =~ s/action\.//gi; if($actionnumber > $rcfg{'maxaction'}{$second}){ $rcfg{'maxaction'}{$second} = $actionnumber; } } #check the last input line if ($first && exists $deflt{$first} && ($second eq '_')) { &quickcheck($first,$second,$deflt{$first},$.) } elsif ($first && $second) { &quickcheck($first,$second,$rcfg{$first}{$second},$.) } elsif ($first) { &quickcheck($first,0,$cfg{$first},$.) } close (CFG); (\@routers, \%cfg, \%rcfg, $cfgfile); } sub cfgcheck { my ($routers, $cfg, $rcfg) = @_; my ($rou, $confname, $one_option); my %node; my $error="no"; my(@known_options) = qw(alarmifnull); if (! $$cfg{workdir}) { warn ("\nERROR: \"WorkDir\" not specified\n"); $error = "yes"; } foreach $rou (@$routers) { if ($$rcfg{'directory'}{$rou}) { # They specified a directory for this router. Append the # pathname seperator to it (so that it can either be present or # absent, and the rules for including it are the same). $$rcfg{'directory'}{$rou} .= ${main::SL}; # remove any stray spaces ... $$rcfg{'directory'}{$rou} =~ s/\s//g; } # Configure e-mail notification for this node if (defined($$rcfg{'nodestatusemail'}{$rou})){ if($$rcfg{'nodestatusemailtarget'}{$rou} ne ""){ if($$rcfg{'nodestatusemail'}{$rou} =~ /[^cwa *]/i ){ warn ("\nERROR: NodeStatusEmail[$rou]: \"$$rcfg{'nodestatusemail'}{$rou}\" contains invalid options [cwa].\n"); $error="yes"; }else{ if($$rcfg{'nodestatusemail'}{$rou} =~ /c/i ){ $$rcfg{'email'}{'cool'}{$rou} = 1; } if($$rcfg{'nodestatusemail'}{$rou} =~ /w/i ){ $$rcfg{'email'}{'warn'}{$rou} = 1; } if($$rcfg{'nodestatusemail'}{$rou} =~ /a/i ){ $$rcfg{'email'}{'alarm'}{$rou} = 1; } } }else{ warn ("\nERROR: NodeStatusEmail[$rou]: \"$$rcfg{'nodestatusemail'}{$rou}\" is given but no NodeStatusEmailTarget[$rou] was found.\n"); $error="yes"; } } if (exists $$rcfg{"options"}{$rou}) { foreach $one_option (split /[,\s]+/, lc($$rcfg{"options"}{$rou})) { if (grep {$one_option eq $_} @known_options) { $$rcfg{'options'}{$one_option}{$rou} = 1; } else { warn ("\nERROR: Option[$rou]: \"$one_option\" is unknown\n"); $error="yes"; } } } if ($error eq "yes") { die ("\n\nABORT: Please fix the error(s) in your config file\n\n"); } } \%node; } sub quickcheck { my ($first,$second,$arg,$line) = @_; my %rules = (# General CFG 'workdir' => ['$arg && (-d $arg)','"Directory $arg does not exist"'], 'eventlog' => ['$arg','"Eventlog path is missing"'], 'eventlogmax' => ['$arg =~ /\d+/','"You must specify a value"'], 'icondir' => ['$arg && (-d $arg)','"Directory $arg does not exist"'], 'statusmapbackground' => ['$arg && (-f $arg)','"Image file $arg does not exist"'], 'statusmapimagename' => ['$arg','"Target image name is missing"'], 'imgsourcedir' => ['$arg && (-d $arg)','"Directory $arg does not exist"'], 'msgfile' => ['$arg && (-f $arg)','"Message file $arg does not exist"'], 'statusemailorigin' => ['$arg =~ /\w+/','"You must specify something for this option"'], 'refresh' => ['int($arg) >= 300', '"$arg should be 300 seconds or more"'], 'interval' => ['int($arg) >= 5','"$arg should be more than 5 Minutes"'], 'testnodelocations' => ['$arg =~ /[ynYN]/','"This option is either y or n"'], #Nodes CFG 'node[]' => ['$arg =~ /\w+/','"You must specify something for this option"'], 'nodecenterx[]' => ['int($arg) >= 0', '"$arg <-- Value cannot be negative"'], 'nodecentery[]' => ['int($arg) >= 0', '"$arg <-- Value cannot be negative"'], 'nodealarmthreshhold[]' => ['$arg =~ /\d+/','"You must specify a value"'], 'nodewarningthreshhold[]' => ['$arg =~ /\d+/','"You must specify a value"'], 'nodeincoolmsgid[]' => ['$arg =~ /\w+/','"You must specify something for this option"'], 'nodeinwarningmsgid[]' => ['$arg =~ /\w+/','"You must specify something for this option"'], 'nodeinalarmmsgid[]' => ['$arg =~ /\w+/','"You must specify something for this option"'], 'nodeoutcoolmsgid[]' => ['$arg =~ /\w+/','"You must specify something for this option"'], 'nodeoutwarningmsgid[]' => ['$arg =~ /\w+/','"You must specify something for this option"'], 'nodeoutalarmmsgid[]' => ['$arg =~ /\w+/','"You must specify something for this option"'], 'nodestatusemail[]' => ['$arg =~ /\w+/','"You must specify something for this option"'], 'nodestatusemailtarget[]' => ['$arg =~ /\w+/','"You must specify something for this option"'], 'options[]' => ['1','"Internal Error"'], 'action[]' => ['$arg =~ /\w+/','"You must specify something for this option"'], ); my $braces = $second ? '[]':''; #The actions are different from the other options if ($first =~ /^action.+/){ if ($first =~ /action.\d*/) { return 1; } }elsif (exists $rules{$first.$braces}) { if (eval($rules{$first.$braces}[0])) { return 1; } else { if ($second) { die "\nCFG Error in \"$first\[$second\]\", line $line: ". eval($rules{$first.$braces}[1])."\n\n"; } else { die "\nCFG Error in \"$first\", line $line: ". eval($rules{$first.$braces}[1])."\n\n"; } } } die "\nCFG Error: Unknown Option \"$first\" on line $line or above.\n". " Check readme.html for Help\n\n"; } sub readmsgfile { my ($msgfile) = @_; my ($first,$second,$key); my (%seen); my (%rmsg,%msg,%pre,%post); open (MSGFILE, $msgfile) || do { print "ERROR: unable to open message file: $msgfile\n\n"}; while (<MSGFILE>) { s/\s+$//g; #remove whitespace at the end of the line s/\s/ /g; #replace whitespace by space next if /^\s*\#/; #ignore comment lines next if /^\s*$/; #ignore empty lines # append mode if ($first && /^\s+(.*\S)\s*$/) { if ($second eq '^') { $pre{$first} .= " $1"; next; } if ($second eq '$' ) { $post{$first} .= " $1"; next; } if ($second) { $rmsg{$first}{$second} .= " $1"; } else { $msg{$first} .= " $1"; } next; } if (/^(\S+):\s*(.*\S)\s*$/) { $first = lc($1); $msg{$first} = $2; $second = ''; next; } die ( "\nLine $. in MSGFILE file does not make sense\n" ); } close (MSGFILE); (\%msg); } sub action_draw_crosshair { #This one draws a crosshair symbol my($ImageData, $cfg, $rcfg, $routers, $router, $cox, $coy,$color) = @_; $cox = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, $cox); $cox = $cox + nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, $$rcfg{'nodelabeloffsetx'}{$router}); $coy = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, $coy); $coy = $coy + nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, $$rcfg{'nodelabeloffsety'}{$router}); #Draw the crosshair... $ImageData->arc($cox,$coy,30,30,0,360,$color); $ImageData->arc($cox,$coy,20,20,0,360,$color); $ImageData->arc($cox,$coy,10,10,0,360,$color); $ImageData->line($cox-17,$coy,$cox+17,$coy,$color); $ImageData->line($cox,$coy-17,$cox,$coy+17,$color); } sub datestr { my ($time) = shift(@_) || return 0; my ($wday) = ('Sunday','Monday','Tuesday','Wednesday', 'Thursday','Friday','Saturday')[(localtime($time))[6]]; my ($month) = ('January','February' ,'March' ,'April' , 'May' , 'June' , 'July' , 'August' , 'September' , 'October' , 'November' , 'December' )[(localtime($time))[4]]; my ($mday,$year,$hour,$min,$sec) = (localtime($time))[3,5,2,1,0]; if ($min<10) {$min = "0$min";} if ($sec<10) {$sec = "0$sec";} return "$wday, $month $mday, ".($year+1900)." - $hour:$min:$sec"; } sub shortdatestr { my ($time) = shift(@_) || return 0; my ($mday,$month,$year,$hour,$min,$sec) = (localtime($time))[3,4,5,2,1,0]; $month++; if ($min<10) {$min = "0$min";} if ($sec<10) {$sec = "0$sec";} return "$month/$mday/".($year+1900)." - $hour:$min:$sec"; } sub nsi_eval { #Replace references to other nodes and evaluate expressions my($ImageData, $cfg, $rcfg, $routers, $router, $evali) = @_; #Replace .xy-references to other nodes foreach $eval_node (@$routers) { my $lceval_node = lc($eval_node); #Replace "node.x" $evali =~ s/[\W]$lceval_node\.x/$$rcfg{'nodecenterx'}{$eval_node}/gie; $evali =~ s/^$lceval_node\.x/$$rcfg{'nodecenterx'}{$eval_node}/gie; #Replace "node.y" $evali =~ s/[\W]$lceval_node\.y/$$rcfg{'nodecentery'}{$eval_node}/gie; $evali =~ s/^$lceval_node\.y/$$rcfg{'nodecentery'}{$eval_node}/gie; } #If something else expanded from the nodecenter, evaluate that too... $evali = lc($evali); foreach $eval_node (@$routers) { my $lceval_node = lc($eval_node); #Replace "node.x" $evali =~ s/[\W]$lceval_node\.x/$$rcfg{'nodecenterx'}{$eval_node}/gie; $evali =~ s/^$lceval_node\.x/$$rcfg{'nodecenterx'}{$eval_node}/gie; #Replace "node.y" $evali =~ s/[\W]$lceval_node\.y/$$rcfg{'nodecentery'}{$eval_node}/gie; $evali =~ s/^$lceval_node\.y/$$rcfg{'nodecentery'}{$eval_node}/gie; } #Evaluate and format the expression $evali = sprintf("%.0f",eval($evali)); return $evali; } sub getnodevalues { my ($target, $rou, $rcfg, $cfg) = @_; my $period = 0; my $lastperiod = 0; my $incurrent=0; my $outcurrent=0; my $inlast = 0; my $outlast = 0; open (LOG, "<$$cfg{'workdir'}\\\\$target.log") or die "ERROR: Can't open .log file for this node: $target\n"; my($counterline,$line,$lastline) = <LOG>; ($period,$incurrent,$outcurrent)=split(/\D/,$line); ($lastperiod,$inlast,$outlast)=split(/\D/,$lastline); close LOG; #Check the period (if we're too far out, we've probably lost contact with the node) $time = time unless defined $time; my($timediff)=$time - $period; #Give it 2 more minutes, then report the node as down if($timediff > $$cfg{'interval'} * 60 + 120){ $incurrent = -1; $outcurrent = -1; } ($incurrent, $outcurrent, $inlast, $outlast); } sub getnodestatus{ my ($incurrent,$outcurrent,$target, $router, $rcfg, $cfg) = @_; my $nodeinstatus = "cool"; my $nodeoutstatus = "cool"; #Node down? if($incurrent eq -1){ $nodeinstatus = "alarm"; $nodeoutstatus = "alarm"; }else{ #Which direction are we looking? if($$rcfg{'nodealarmthreshhold'}{$router} >= $$rcfg{'nodewarningthreshhold'}{$router}){ #Straight forward if($incurrent > $$rcfg{'nodewarningthreshhold'}{$router}){ $nodeinstatus = "warning"; } if($outcurrent > $$rcfg{'nodewarningthreshhold'}{$router}){ $nodeoutstatus = "warning"; } if($incurrent > $$rcfg{'nodealarmthreshhold'}{$router}){ $nodeinstatus = "alarm"; } if($outcurrent > $$rcfg{'nodealarmthreshhold'}{$router}){ $nodeoutstatus = "alarm"; } }else{ #Backwards if($incurrent < $$rcfg{'nodewarningthreshhold'}{$router}){ $nodeinstatus = "warning"; } if($outcurrent < $$rcfg{'nodewarningthreshhold'}{$router}){ $nodeoutstatus = "warning"; } if($incurrent < $$rcfg{'nodealarmthreshhold'}{$router}){ $nodeinstatus = "alarm"; } if($outcurrent < $$rcfg{'nodealarmthreshhold'}{$router}){ $nodeoutstatus = "alarm"; } } } #Check for nulls if($$rcfg{'options'}{'alarmifnull'}{$router}){ if($incurrent eq "0"){ $nodeinstatus = "alarm"; } if($outcurrent eq "0"){ $nodeoutstatus = "alarm"; } } ($nodeinstatus,$nodeoutstatus); } sub drawnodeline{ my ($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, $msg, $nodeinstatus, $nodeoutstatus, $incurrent, $outcurrent, $direction, $cond, $source, $destination, $style) = @_; #Expand our numeric arguments my $sourcex = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$source.x"); my $sourcey = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$source.y"); my $destinationx = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$destination.x"); my $destinationy = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$destination.y"); my $absnodestatus = "$direction$cond"; my $absnodeinstatus = "in$nodeinstatus"; my $absnodeoutstatus = "out$nodeoutstatus"; #Draw something depending on the node's status if ($absnodestatus eq $absnodeinstatus || $absnodestatus =~ /always/i){ $ImageData->setStyle(split(/,/,$$gdstyles{$style}{'style'})); #$ImageData->setStyle($$gdstyles{$style}{'style'}); $ImageData->line($sourcex,$sourcey,$destinationx,$destinationy,gdStyled); } } sub copyimage{ my ($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, $msg, $nodeinstatus, $nodeoutstatus, $incurrent, $outcurrent, $direction, $cond, $image, $coordx, $coordy) = @_; #Expand our numeric arguments my $coordx = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordx"); my $coordy = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordy"); my $absnodestatus = "$direction$cond"; my $absnodeinstatus = "in$nodeinstatus"; my $absnodeoutstatus = "out$nodeoutstatus"; #Draw something depending on the node's status if ($absnodestatus eq $absnodeinstatus || $absnodestatus =~ /always/i){ open (SRCIMG,"<$$cfg{'icondir'}\\\\$image") || die "ERROR: Can't open source image for copy: $$cfg{'icondir'}\\\\$image\n"; my($srcImageData) = newFromGif GD::Image(SRCIMG) || die "ERROR: GD::newFromGif\n"; close SRCIMG; my($srcImgDataSizeX,$srcImgDataSizeY) = $srcImageData->getBounds; $ImageData->copy($srcImageData,$coordx,$coordy,0,0,$srcImgDataSizeX,$srcImgDataSizeY); } } sub multicopyimage{ my ($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, $msg, $nodeinstatus, $nodeoutstatus, $incurrent, $outcurrent, $direction, $cond, $image, $coordx, $coordy, $howoften, $minoften, $maxoften, $stepsize, $angle) = @_; #Expand our numeric arguments print "Coordinates: $coordx/$coordy\n"; my $coordx = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordx"); my $coordy = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordy"); my $howoften = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$howoften"); print "Coordinates: $coordx/$coordy\n"; if ($howoften < $minoften){ $howoften = $minoften; } if ($howoften > $maxoften){ $howoften = $maxoften; } my $absnodestatus = "$direction$cond"; my $absnodeinstatus = "in$nodeinstatus"; my $absnodeoutstatus = "out$nodeoutstatus"; #Draw something depending on the node's status if ($absnodestatus eq $absnodeinstatus || $absnodestatus =~ /always/i){ open (SRCIMG,"<$$cfg{'icondir'}\\\\$image") || die "ERROR: Can't open source image for copy: $$cfg{'icondir'}\\\\$image\n"; my($srcImageData) = newFromGif GD::Image(SRCIMG) || die "ERROR: GD::newFromGif\n"; close SRCIMG; my($srcImgDataSizeX,$srcImgDataSizeY) = $srcImageData->getBounds; my $rad = ($angle * 3.141592654) / 180; if ($stepsize >= 0){ for($multicounter = 0; $multicounter < $howoften; $multicounter++){ my $hyp = $multicounter * $stepsize; my $a = sprintf("%.0f",sin($rad) * $hyp); my $b = sprintf("%.0f",cos($rad) * $hyp); #print "Angle: $angle, Rad: $rad, a: $a, b: $b\n"; $ImageData->copy($srcImageData,$coordx + $b,$coordy - $a,0,0,$srcImgDataSizeX,$srcImgDataSizeY); } }else{ $stepsize = abs($stepsize); for($multicounter = $howoften - 1; $multicounter >= 0; $multicounter--){ my $hyp = $multicounter * $stepsize; my $a = sprintf("%.0f",sin($rad) * $hyp); my $b = sprintf("%.0f",cos($rad) * $hyp); #print "Angle: $angle, Rad: $rad, a: $a, b: $b\n"; $ImageData->copy($srcImageData,$coordx + $b,$coordy - $a,0,0,$srcImgDataSizeX,$srcImgDataSizeY); } } } } sub drawtext{ my ($ImageData, $gdstyles, $cfg, $rcfg, $routers, $router, $msg, $nodeinstatus, $nodeoutstatus, $incurrent, $outcurrent, $direction, $cond, $font, $coordx, $coordy, $textid, $color) = @_; #Expand our numeric arguments my $coordx = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordx"); my $coordy = nsi_eval($ImageData, $cfg, $rcfg, $routers, $router, "$coordy"); my $absnodestatus = "$direction$cond"; my $absnodeinstatus = "in$nodeinstatus"; my $absnodeoutstatus = "out$nodeoutstatus"; #Draw something depending on the node's status if ($absnodestatus eq $absnodeinstatus || $absnodestatus =~ /always/i){ if(!defined($$msg{$textid})){ $$msg{$textid} = "MSG not defined!"; } if($font eq 1){$ImageData->string(gdTinyFont,$coordx,$coordy,$$msg{$textid},$colors{$color});} if($font eq 2){$ImageData->string(gdSmallFont,$coordx,$coordy,$$msg{$textid},$colors{$color});} if($font eq 3){$ImageData->string(gdMediumBoldFont,$coordx,$coordy,$$msg{$textid},$colors{$color});} if($font eq 4){$ImageData->string(gdLargeFont,$coordx,$coordy,$$msg{$textid},$colors{$color});} } } sub transeventvar{ my ($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $transstring) = @_; my @transsplit = split(/\$/,$transstring); my $maxelements = $transsplit; print "MAXELEMNTS: $transstring\n"; for ($transcounter = 0; $transcounter <= $maxelements; $transcounter++){ $transstring =~ s/\$NodeWarningThreshhold/$$rcfg{nodewarningthreshhold}{$router}/i; $transstring =~ s/\$NodeAlarmThreshhold/$$rcfg{nodealarmthreshhold}{$router}/i; $transstring =~ s/\$NodeIn/$incurrent/i; $transstring =~ s/\$NodeOut/$outcurrent/i; } return $transstring; } sub sendmail{ my ($cfg, $rcfg, $routers, $router, $incurrent, $outcurrent, $event, $eventtype, $address) = @_; print "Sending e-mail to: $address from $$cfg{'statusemailorigin'}\n"; my $smtp = Net::SMTP->new('hampton.lam.liebherr.com'); # connect to an SMTP server foreach $target (split(/;/,$address)){ $smtp->mail( $$cfg{'statusemailorigin'} ); # use the sender's address here $smtp->to($target); # recipient's address $smtp->data(); # Start the mail # Send the header. $smtp->datasend("To: $address\n"); $smtp->datasend("From: $$cfg{'statusemailorigin'}\n"); $smtp->datasend("Subject: $eventtype on Node \"$router\"\n"); $smtp->datasend("\n"); # Send the body. $smtp->datasend("$event\n"); $smtp->datasend("\n"); $smtp->datasend("\n"); $smtp->datasend("*******************************************************\n"); $smtp->datasend("*** This was an automated network status update ***\n"); $smtp->datasend("*** message generated by: ***\n"); $smtp->datasend("*** NSI v1.0 for MRTG, Created by Mac Kloberg ***\n"); $smtp->datasend("*** <mac.kloberg\@lam.liebherr.com> <mac\@nacs.net> ***\n"); $smtp->datasend("*******************************************************\n"); $smtp->dataend(); # Finish sending the mail } $smtp->quit; # Close the SMTP connection }