From 12fd58606c60d08316078272e1a65b2ed67a25a3 Mon Sep 17 00:00:00 2001 From: Nigel Metheringham Date: Wed, 18 Jul 2007 16:13:33 +0000 Subject: [PATCH] mirmon updates --- icons/bar.gif | Bin 0 -> 40 bytes icons/mirmon.gif | Bin 0 -> 601 bytes icons/mirmon_b.gif | Bin 0 -> 38 bytes icons/mirmon_f.gif | Bin 0 -> 38 bytes icons/mirmon_s.gif | Bin 0 -> 38 bytes icons/mirmon_z.gif | Bin 0 -> 38 bytes icons/mmb01.gif | Bin 0 -> 38 bytes icons/mmb02.gif | Bin 0 -> 45 bytes icons/mmb03.gif | Bin 0 -> 48 bytes icons/mmb04.gif | Bin 0 -> 55 bytes icons/mmb05.gif | Bin 0 -> 59 bytes icons/mmb06.gif | Bin 0 -> 63 bytes icons/mmb07.gif | Bin 0 -> 68 bytes icons/mmb08.gif | Bin 0 -> 71 bytes icons/mmb09.gif | Bin 0 -> 74 bytes icons/mmb10.gif | Bin 0 -> 77 bytes icons/mmb11.gif | Bin 0 -> 81 bytes icons/mmb12.gif | Bin 0 -> 84 bytes icons/mmb13.gif | Bin 0 -> 89 bytes icons/mmb14.gif | Bin 0 -> 92 bytes icons/mmf01.gif | Bin 0 -> 38 bytes icons/mmf02.gif | Bin 0 -> 45 bytes icons/mmf03.gif | Bin 0 -> 48 bytes icons/mmf04.gif | Bin 0 -> 55 bytes icons/mmf05.gif | Bin 0 -> 59 bytes icons/mmf06.gif | Bin 0 -> 63 bytes icons/mmf07.gif | Bin 0 -> 68 bytes icons/mmf08.gif | Bin 0 -> 71 bytes icons/mmf09.gif | Bin 0 -> 74 bytes icons/mmf10.gif | Bin 0 -> 77 bytes icons/mmf11.gif | Bin 0 -> 81 bytes icons/mmf12.gif | Bin 0 -> 84 bytes icons/mmf13.gif | Bin 0 -> 89 bytes icons/mmf14.gif | Bin 0 -> 92 bytes icons/mms01.gif | Bin 0 -> 38 bytes icons/mms02.gif | Bin 0 -> 45 bytes icons/mms03.gif | Bin 0 -> 48 bytes icons/mms04.gif | Bin 0 -> 55 bytes icons/mms05.gif | Bin 0 -> 59 bytes icons/mms06.gif | Bin 0 -> 63 bytes icons/mms07.gif | Bin 0 -> 68 bytes icons/mms08.gif | Bin 0 -> 71 bytes icons/mms09.gif | Bin 0 -> 74 bytes icons/mms10.gif | Bin 0 -> 77 bytes icons/mms11.gif | Bin 0 -> 81 bytes icons/mms12.gif | Bin 0 -> 84 bytes icons/mms13.gif | Bin 0 -> 89 bytes icons/mms14.gif | Bin 0 -> 92 bytes icons/mmsb01.gif | Bin 0 -> 103 bytes icons/mmsb02.gif | Bin 0 -> 105 bytes icons/mmsb03.gif | Bin 0 -> 104 bytes icons/mmsb04.gif | Bin 0 -> 105 bytes icons/mmsb05.gif | Bin 0 -> 105 bytes icons/mmsb06.gif | Bin 0 -> 104 bytes icons/mmsb07.gif | Bin 0 -> 105 bytes icons/mmsb08.gif | Bin 0 -> 103 bytes icons/mmsb09.gif | Bin 0 -> 104 bytes icons/mmsb10.gif | Bin 0 -> 104 bytes icons/mmsb11.gif | Bin 0 -> 103 bytes icons/mmsb12.gif | Bin 0 -> 103 bytes icons/mmsb13.gif | Bin 0 -> 103 bytes icons/mmsb14.gif | Bin 0 -> 103 bytes icons/mmsbf01.gif | Bin 0 -> 112 bytes icons/mmsbf02.gif | Bin 0 -> 114 bytes icons/mmsbf03.gif | Bin 0 -> 113 bytes icons/mmsbf04.gif | Bin 0 -> 113 bytes icons/mmsbf05.gif | Bin 0 -> 111 bytes icons/mmsbf06.gif | Bin 0 -> 112 bytes icons/mmsbf07.gif | Bin 0 -> 112 bytes icons/mmsbf08.gif | Bin 0 -> 111 bytes icons/mmsbf09.gif | Bin 0 -> 112 bytes icons/mmsbf10.gif | Bin 0 -> 113 bytes icons/mmsbf11.gif | Bin 0 -> 112 bytes icons/mmsbf12.gif | Bin 0 -> 111 bytes icons/mmsbf13.gif | Bin 0 -> 112 bytes icons/mmsf01.gif | Bin 0 -> 103 bytes icons/mmsf02.gif | Bin 0 -> 105 bytes icons/mmsf03.gif | Bin 0 -> 104 bytes icons/mmsf04.gif | Bin 0 -> 105 bytes icons/mmsf05.gif | Bin 0 -> 105 bytes icons/mmsf06.gif | Bin 0 -> 104 bytes icons/mmsf07.gif | Bin 0 -> 105 bytes icons/mmsf08.gif | Bin 0 -> 103 bytes icons/mmsf09.gif | Bin 0 -> 104 bytes icons/mmsf10.gif | Bin 0 -> 104 bytes icons/mmsf11.gif | Bin 0 -> 103 bytes icons/mmsf12.gif | Bin 0 -> 103 bytes icons/mmsf13.gif | Bin 0 -> 103 bytes icons/mmsf14.gif | Bin 0 -> 103 bytes icons/mmz01.gif | Bin 0 -> 38 bytes icons/mmz02.gif | Bin 0 -> 45 bytes icons/mmz03.gif | Bin 0 -> 48 bytes icons/mmz04.gif | Bin 0 -> 55 bytes icons/mmz05.gif | Bin 0 -> 59 bytes icons/mmz06.gif | Bin 0 -> 63 bytes icons/mmz07.gif | Bin 0 -> 68 bytes icons/mmz08.gif | Bin 0 -> 71 bytes icons/mmz09.gif | Bin 0 -> 74 bytes icons/mmz10.gif | Bin 0 -> 77 bytes icons/mmz11.gif | Bin 0 -> 81 bytes icons/mmz12.gif | Bin 0 -> 84 bytes icons/mmz13.gif | Bin 0 -> 89 bytes icons/mmz14.gif | Bin 0 -> 92 bytes mirmon/mirmon | 2106 +++++++++++++++++++------------------------- 104 files changed, 902 insertions(+), 1204 deletions(-) create mode 100644 icons/bar.gif create mode 100644 icons/mirmon.gif create mode 100644 icons/mirmon_b.gif create mode 100644 icons/mirmon_f.gif create mode 100644 icons/mirmon_s.gif create mode 100644 icons/mirmon_z.gif create mode 100644 icons/mmb01.gif create mode 100644 icons/mmb02.gif create mode 100644 icons/mmb03.gif create mode 100644 icons/mmb04.gif create mode 100644 icons/mmb05.gif create mode 100644 icons/mmb06.gif create mode 100644 icons/mmb07.gif create mode 100644 icons/mmb08.gif create mode 100644 icons/mmb09.gif create mode 100644 icons/mmb10.gif create mode 100644 icons/mmb11.gif create mode 100644 icons/mmb12.gif create mode 100644 icons/mmb13.gif create mode 100644 icons/mmb14.gif create mode 100644 icons/mmf01.gif create mode 100644 icons/mmf02.gif create mode 100644 icons/mmf03.gif create mode 100644 icons/mmf04.gif create mode 100644 icons/mmf05.gif create mode 100644 icons/mmf06.gif create mode 100644 icons/mmf07.gif create mode 100644 icons/mmf08.gif create mode 100644 icons/mmf09.gif create mode 100644 icons/mmf10.gif create mode 100644 icons/mmf11.gif create mode 100644 icons/mmf12.gif create mode 100644 icons/mmf13.gif create mode 100644 icons/mmf14.gif create mode 100644 icons/mms01.gif create mode 100644 icons/mms02.gif create mode 100644 icons/mms03.gif create mode 100644 icons/mms04.gif create mode 100644 icons/mms05.gif create mode 100644 icons/mms06.gif create mode 100644 icons/mms07.gif create mode 100644 icons/mms08.gif create mode 100644 icons/mms09.gif create mode 100644 icons/mms10.gif create mode 100644 icons/mms11.gif create mode 100644 icons/mms12.gif create mode 100644 icons/mms13.gif create mode 100644 icons/mms14.gif create mode 100644 icons/mmsb01.gif create mode 100644 icons/mmsb02.gif create mode 100644 icons/mmsb03.gif create mode 100644 icons/mmsb04.gif create mode 100644 icons/mmsb05.gif create mode 100644 icons/mmsb06.gif create mode 100644 icons/mmsb07.gif create mode 100644 icons/mmsb08.gif create mode 100644 icons/mmsb09.gif create mode 100644 icons/mmsb10.gif create mode 100644 icons/mmsb11.gif create mode 100644 icons/mmsb12.gif create mode 100644 icons/mmsb13.gif create mode 100644 icons/mmsb14.gif create mode 100644 icons/mmsbf01.gif create mode 100644 icons/mmsbf02.gif create mode 100644 icons/mmsbf03.gif create mode 100644 icons/mmsbf04.gif create mode 100644 icons/mmsbf05.gif create mode 100644 icons/mmsbf06.gif create mode 100644 icons/mmsbf07.gif create mode 100644 icons/mmsbf08.gif create mode 100644 icons/mmsbf09.gif create mode 100644 icons/mmsbf10.gif create mode 100644 icons/mmsbf11.gif create mode 100644 icons/mmsbf12.gif create mode 100644 icons/mmsbf13.gif create mode 100644 icons/mmsf01.gif create mode 100644 icons/mmsf02.gif create mode 100644 icons/mmsf03.gif create mode 100644 icons/mmsf04.gif create mode 100644 icons/mmsf05.gif create mode 100644 icons/mmsf06.gif create mode 100644 icons/mmsf07.gif create mode 100644 icons/mmsf08.gif create mode 100644 icons/mmsf09.gif create mode 100644 icons/mmsf10.gif create mode 100644 icons/mmsf11.gif create mode 100644 icons/mmsf12.gif create mode 100644 icons/mmsf13.gif create mode 100644 icons/mmsf14.gif create mode 100644 icons/mmz01.gif create mode 100644 icons/mmz02.gif create mode 100644 icons/mmz03.gif create mode 100644 icons/mmz04.gif create mode 100644 icons/mmz05.gif create mode 100644 icons/mmz06.gif create mode 100644 icons/mmz07.gif create mode 100644 icons/mmz08.gif create mode 100644 icons/mmz09.gif create mode 100644 icons/mmz10.gif create mode 100644 icons/mmz11.gif create mode 100644 icons/mmz12.gif create mode 100644 icons/mmz13.gif create mode 100644 icons/mmz14.gif diff --git a/icons/bar.gif b/icons/bar.gif new file mode 100644 index 0000000000000000000000000000000000000000..1bb765dc2d1599f7511b42495930d45586b6952e GIT binary patch literal 40 ocmZ?wbh9u|0IX67!2kdN literal 0 HcmV?d00001 diff --git a/icons/mirmon.gif b/icons/mirmon.gif new file mode 100644 index 0000000000000000000000000000000000000000..8932cde7b838f34bd9ddae43cd4f33106fde75b7 GIT binary patch literal 601 zcmZ?wbhEHbOkhx8XklRZ`C8$}RfVr93g4;~zL+a~R#5ojtMGlf!jF9l-zF-oUz6n< zepXudzlrm+x~AC=uUVWp7?_%~b^7$?|HJ{se{8v#MY;KT3_1)z0J4>V^`C-5UrOe@ zj8*G$UhgZ=IbV`{zhd3{n)m+?ED#VC;9)wfqU)d`!gEUF&4UuJ^=lkL8{RGxaC@&; zAi*KT**tjy!;MD8@Z>{G38|3It*Vt_;#m{?o-S9Y^9SOWlY#0B^O literal 0 HcmV?d00001 diff --git a/icons/mirmon_f.gif b/icons/mirmon_f.gif new file mode 100644 index 0000000000000000000000000000000000000000..b1b1f9c41d8e7281ac08c2f4c6237736b4386447 GIT binary patch literal 38 mcmZ?wbh9u|E7q literal 0 HcmV?d00001 diff --git a/icons/mirmon_z.gif b/icons/mirmon_z.gif new file mode 100644 index 0000000000000000000000000000000000000000..677027f92802323b186f007a9e2329f3412035d7 GIT binary patch literal 38 jcmZ?wbh9u|9S{u?VPIly>0jB+%3uuuTH6Hq literal 0 HcmV?d00001 diff --git a/icons/mmb01.gif b/icons/mmb01.gif new file mode 100644 index 0000000000000000000000000000000000000000..9e328d706211470c2912b20d2dea708371ba4cd3 GIT binary patch literal 38 mcmZ?wbh9u||3It*Vt_;#m{?o-S9Y^9SOWlY#0B^O literal 0 HcmV?d00001 diff --git a/icons/mmb02.gif b/icons/mmb02.gif new file mode 100644 index 0000000000000000000000000000000000000000..bebe957375a2e02a7a51f08fb61a1b871dfd8b07 GIT binary patch literal 45 rcmZ?wbh9u|6k=duXkdVV|2iNVB*MVN)059|LiW|8=uM8{3=Gx)thxyp literal 0 HcmV?d00001 diff --git a/icons/mmb03.gif b/icons/mmb03.gif new file mode 100644 index 0000000000000000000000000000000000000000..5b23849a32e971ef3282b8b7d831e754b214e1a6 GIT binary patch literal 48 ucmZ?wbh9u|lwn|DXkdVV|2iNVB*MVN-;>YKaq7IxlmfkI?cVRA4Aub5=n7{5 literal 0 HcmV?d00001 diff --git a/icons/mmb04.gif b/icons/mmb04.gif new file mode 100644 index 0000000000000000000000000000000000000000..dbc19c0a1dc932f737deb283e3a5f9e5c786f220 GIT binary patch literal 55 zcmZ?wbh9u|RAXRaXkdVV|2iNVB*MTX)|1cBaq9UzAMa!3>ZjKxtuGa3Z}ebfum%7& C>@ literal 0 HcmV?d00001 diff --git a/icons/mmb05.gif b/icons/mmb05.gif new file mode 100644 index 0000000000000000000000000000000000000000..29d041133676791bce397a6dc92f7a8eee326c5a GIT binary patch literal 59 zcmZ?wbh9u|G+_7Haq4+oN57Hw`$-b-eq}~ZS4}LgO3qrR Pdfd-Yb9X@)1A{dHIJOie literal 0 HcmV?d00001 diff --git a/icons/mmb08.gif b/icons/mmb08.gif new file mode 100644 index 0000000000000000000000000000000000000000..d6a01c040d1cbe3730322c128a64a4dff68f499b GIT binary patch literal 71 zcmZ?wbh9u|^kZOQXkdVV|2iNVB*MU?)|1cBaq4+oN59eSX?G-E{fbRI)_X5(SL|KwO1tO0!B9Do1- literal 0 HcmV?d00001 diff --git a/icons/mmb11.gif b/icons/mmb11.gif new file mode 100644 index 0000000000000000000000000000000000000000..f539e29d4786d36988cc181d077f6f3bb6d72736 GIT binary patch literal 81 zcmZ?wbh9u|%wb?*XkdVV|2iNVB*MUC(38*5aq4+oN59eSX-5LW^=lQUH{8r9d$DV2 d>WQx0nw^t_7Haq4+oN59eSX-5LW>l=eCiaKvheX(-e gZL5RNBzDjD-B+<~xmE3N)^l m&C6rAS08$+{pzvWSyhvP!5RSeJR%YR literal 0 HcmV?d00001 diff --git a/icons/mmb14.gif b/icons/mmb14.gif new file mode 100644 index 0000000000000000000000000000000000000000..5dd255166982c148bc0071e77f7e68b2440f118d GIT binary patch literal 92 zcmZ?wbh9u|>|$VHXkdVV|2iNVB*MUC-ILGIaq4+oN59eSX-5LW>lX1N IATsa;EQCGXcd$}+1df1kT> M=C)aBwqcBO+40nFKk)R V^cicp7Ol3vn8Vv`8N|R~4FIsy7l;4= literal 0 HcmV?d00001 diff --git a/icons/mmf09.gif b/icons/mmf09.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6b1a29c004672155940ee8493d3abd645c6dfc6 GIT binary patch literal 74 zcmZ?wbh9u|j9_44XkY+={|pQ|AQ~jXz@*ue&(Lw|d0a=o(d}tRjLPR_Os$xBFU=`a YyzcdvrVZYU*Yx&poj2V&n1R6>0QX-RkN^Mx literal 0 HcmV?d00001 diff --git a/icons/mmf10.gif b/icons/mmf10.gif new file mode 100644 index 0000000000000000000000000000000000000000..9c8459791d8078716f8307ac51bc28bb6c51ec70 GIT binary patch literal 77 zcmZ?wbh9u|Ok!YRXkY+={|pQ|AQ~jXz@*cY&(Lw|d0a=o(d}tR0#3h;P5f4P^2XE` bE9-QBguOPIU81w=gWhA6`ON?1SQ)GVe%>5_ literal 0 HcmV?d00001 diff --git a/icons/mmf11.gif b/icons/mmf11.gif new file mode 100644 index 0000000000000000000000000000000000000000..80320fc21b6c5afa93537551aab529abe53a4221 GIT binary patch literal 81 zcmZ?wbh9u|%wb?*XkY+={|pQ|AQ~jXz+}*q&(Lw|d0a=o(d}tR0>brc6{k1c%qV-Y fYia6bMXgDi?VZ%lo$ ia@%dIgU=*(&-dL|v2D3k?Qhn0OC|pZA31qe25SH^mK}ls literal 0 HcmV?d00001 diff --git a/icons/mmf13.gif b/icons/mmf13.gif new file mode 100644 index 0000000000000000000000000000000000000000..e0725c27ba8027bbdfe767e434092b43d49dca25 GIT binary patch literal 89 zcmZ?wbh9u|Y+ztvXkY+={|pQ|AQ~jXz+};r&(Lw|d0a=o(d}tR0>bMXXS(<$xfh+> oxopkLW4BiydaC}oSnktfzAK#hD-zECkXGwIm9$w^lYzk+0Qfp05&!@I literal 0 HcmV?d00001 diff --git a/icons/mmf14.gif b/icons/mmf14.gif new file mode 100644 index 0000000000000000000000000000000000000000..62b9b5f2833a7b9a5c251648b39af0a1de7c7e26 GIT binary patch literal 92 zcmZ?wbh9u|>|$VHXkY+={|pQ|AQ~jXz+~N%&(Lw|d0a=o(d}tR0>bMXXPR`TxEFQq rT$c0l*zMJaHrKT6sQZ53?$gJ*LkZ_Be3YiINSe$MYPYnFiNP8Gd!Hmt literal 0 HcmV?d00001 diff --git a/icons/mms01.gif b/icons/mms01.gif new file mode 100644 index 0000000000000000000000000000000000000000..ae2088028620bfbdb90b4b68db4d54bbb8bd7f2b GIT binary patch literal 38 ncmZ?wbh9u|E7q literal 0 HcmV?d00001 diff --git a/icons/mms02.gif b/icons/mms02.gif new file mode 100644 index 0000000000000000000000000000000000000000..3699b9143ebc0a1d047f575c884b36bc506a6b02 GIT binary patch literal 45 scmZ?wbh9u|6k=duXkY+?{|q`H8YIHN#M6_{a6(^b literal 0 HcmV?d00001 diff --git a/icons/mms08.gif b/icons/mms08.gif new file mode 100644 index 0000000000000000000000000000000000000000..8c2a663490d85034a6360c3e464ad59c08ee43d4 GIT binary patch literal 71 zcmZ?wbh9u|^kZOQXkY+?{|q`H8YIHNq}G$q&~fT{Tt~mr?P+%;Uj2$qJl1+hyVZp literal 0 HcmV?d00001 diff --git a/icons/mms09.gif b/icons/mms09.gif new file mode 100644 index 0000000000000000000000000000000000000000..16384b86c7872890915b8a78c5e0f133a6121456 GIT binary patch literal 74 zcmZ?wbh9u|j9_44XkY+?{|q`H8YIHNq}h|t&~fT{Tt~mr?P*7h%I9TFt(bT(%_&p7 X?)8_Z4c?2_^!9I^H{Cjzfx#L8_Fx&1 literal 0 HcmV?d00001 diff --git a/icons/mms10.gif b/icons/mms10.gif new file mode 100644 index 0000000000000000000000000000000000000000..9e584ae8f2dbc20896c0f99ee3a0fe783df498a6 GIT binary patch literal 77 zcmZ?wbh9u|Ok!YRXkY+?{|q`H8YIHNq|=kn&~fT{Tt~mr?P*5>PQQ&!{8o7K#?%)p a>vVsFy*8O$qOU$A8LR<)-yDDd literal 0 HcmV?d00001 diff --git a/icons/mms11.gif b/icons/mms11.gif new file mode 100644 index 0000000000000000000000000000000000000000..f963fbbffad0f3dfe61e6826758cf30bd50d1f2c GIT binary patch literal 81 zcmZ?wbh9u|%wb?*XkY+?{|q`H8YIHNWYCk(&~fT{Tt~mr?P*5>!u4wvr#IZpD0{JM eY3hlt+?t(}eeZqYJYBap_-vbf+{XY025SJ$R2|j; literal 0 HcmV?d00001 diff --git a/icons/mms12.gif b/icons/mms12.gif new file mode 100644 index 0000000000000000000000000000000000000000..decf883fd70db1ca88478d62e4d1380e08775ddd GIT binary patch literal 84 zcmZ?wbh9u|EMs6{XkY+?{|q`H8YIHNWZaX_&~fT{Tt~mr?P*5>!s{D@EQ&gBOntF( h+ik0Z&m?xw_uW^qZMjwLZ`O88CI1K?IeAtFYXC8q9fAM= literal 0 HcmV?d00001 diff --git a/icons/mms13.gif b/icons/mms13.gif new file mode 100644 index 0000000000000000000000000000000000000000..b022a6f320c44b82dcef4b54579c2b399ccfbd43 GIT binary patch literal 89 zcmZ?wbh9u|Y+ztvXkY+?{|q`H8YIHNWYLq)&~fT{Tt~mr?P*5>!s{Dny7(oz7oFU> nY|YDKw^tu}s{XiG?$cwwE1dZ&63+jSR_i~Nv{_Y?fx#L8_d6mI literal 0 HcmV?d00001 diff --git a/icons/mms14.gif b/icons/mms14.gif new file mode 100644 index 0000000000000000000000000000000000000000..1619a62acfe81b58b96112520afce543c2b41ba1 GIT binary patch literal 92 zcmZ?wbh9u|>|$VHXkY+?{|q`H8YIHNWZjd`&~fT{Tt~mr?P*5>!s{DnnslbP7j^Dj qmhVux3rCk!5RR1pd?KI literal 0 HcmV?d00001 diff --git a/icons/mmsb01.gif b/icons/mmsb01.gif new file mode 100644 index 0000000000000000000000000000000000000000..a07d76fda165ca729291061bb42257f1634384b7 GIT binary patch literal 103 zcmZ?wbh9u|>|$VHSjYed|A8b3>wtJ5aRw%bDftWs&%ToB$-iij*%ux4w{T&3V)A8E yj!9vu+547PAN(eB{YUIN_VtrFn_Vtkh!Bxg-go5PP8HRqCsq}8HN|l;SOWl9@Fl$f literal 0 HcmV?d00001 diff --git a/icons/mmsb02.gif b/icons/mmsb02.gif new file mode 100644 index 0000000000000000000000000000000000000000..e13dbe0a62c8e528ff0ee49be1dd432af0ad3ce0 GIT binary patch literal 105 zcmZ?wbh9u|>|$VHSjYed|A8b3>wtJ5aRw%*o_vNwXS)P?I4@KkUSeIA8GGL_DQQMw z_vI;4uMQ?WyJl25TWjwAmnXBn=InWNa)-6n+8otVjJQ_E|$VHSjYed|A8b3>wtJ5aRw&Go_vN5E&lmQ>6a2R({``D9Xj8vXleP< z8=7u`Gd2`*t>2Qa3JbW;iYCTD4eD|$VHSjYed|A8b3>wtJ5aRw%*o_vOmQ_EZCT-uuupSFALZO8d$MN7+< z-q2hoXxhqYz57en^9Q<*wN@%0Oxlxlp~U6wq_y%zJEg;V0usJvo=w``!Ngz<0L|$VHSjYed|A8b3>wtJ5aRw%*o_vOmQ_tf97TuDHPus0~({a98(NguL zmo=9qGR0iqy-O$O`GeT^tN2xJrijg&Sbl}GdD;C>H}41*nX|$VHSjYed|A8b3>wtJ5aRw&Go_vOmQ_tf%{5!k#Q+Mm$bc{DGTB^SE yvgWeHLx&>2t;@@4t~mSn`+DX{X*1?sC~;w(uBCF>bC;m$?yOB;L)=tZ8LR|$VHSjYed|A8b3>wtJ5aRw%*o_vOmQ_tf%`i)dKo!h2+(=pyOZmIgx z%bLp)4;|9mko(^1c|y=owZhfClxp;2vXJW7h0K2{? A(f|Me literal 0 HcmV?d00001 diff --git a/icons/mmsb08.gif b/icons/mmsb08.gif new file mode 100644 index 0000000000000000000000000000000000000000..e3daf4aae3b62bc9ac93822ee975b07424c13d28 GIT binary patch literal 103 zcmZ?wbh9u|>|$VHSjYed|A8b3>wtJ5aRw%bo_vOmQ_tf%`i*Wk+^9+3;Snzs_O#S% xg_WP?iG3+|O5f`4{d#!G^K#Qf}|$VHSjYed|A8b3>wtJ5aRw&Go_vOmQ_tf%`i*W+3t9BL&oRn0E>&&m zWzA)YhYscKId}j2HR-v}KksLr)S`Bq_lUPp;HtzAFMGrmE>kYLxyVSKmBAVSyg4U* literal 0 HcmV?d00001 diff --git a/icons/mmsb10.gif b/icons/mmsb10.gif new file mode 100644 index 0000000000000000000000000000000000000000..1c018f61162fe0252ece138f7706eecd0ceaf54d GIT binary patch literal 104 zcmZ?wbh9u|>|$VHSjYed|A8b3>wtJ5aRw&Go_vOmQ_tf%`i*W+J0j4*Ul+3|^l7Qr y3M;?N(A($O_E9M(;vU>*>~>)XA9Tj5RsrIXN;Ix8LR<+gC*nu literal 0 HcmV?d00001 diff --git a/icons/mmsb11.gif b/icons/mmsb11.gif new file mode 100644 index 0000000000000000000000000000000000000000..26857fe761153184d2f21a5a6aafe804a989e8cf GIT binary patch literal 103 zcmZ?wbh9u|>|$VHSjYed|A8b3>wtJ5aRw%bo_vOmQ_tf%`i*W+I}#AC(2{gQ^W@T2jTe6Y&f~N^NMuq;uooADH2^<^Bl7?N literal 0 HcmV?d00001 diff --git a/icons/mmsb12.gif b/icons/mmsb12.gif new file mode 100644 index 0000000000000000000000000000000000000000..451b38280002422850751b8552ac8ea5996b8c7a GIT binary patch literal 103 zcmZ?wbh9u|>|$VHSjYed|A8b3>wtJ5aRw%bo_vOmQ_tf%`i*W+I}#9H&v?kAFNVo$ yVU=Iz@qHOS`J1Gtr{2CcfBz;%W9JzcmMMSCJ9_iucOIwZm$K9{cWvcjum%7`(I!j) literal 0 HcmV?d00001 diff --git a/icons/mmsb13.gif b/icons/mmsb13.gif new file mode 100644 index 0000000000000000000000000000000000000000..2631d8c17c1b3b66ba4a68f1f1accc9130c9c9a4 GIT binary patch literal 103 zcmZ?wbh9u|>|$VHSjYed|A8b3>wtJ5aRw%bo_vOmQ_tf%`i*W+I}#9H-#F7@nu>a< yrd8*wXKIDJ&%McIUUu@D-Jjnq&WC+Ie!V%h>cFxKo-I;KPrNW*DYAi!!5RR42`A$K literal 0 HcmV?d00001 diff --git a/icons/mmsb14.gif b/icons/mmsb14.gif new file mode 100644 index 0000000000000000000000000000000000000000..a6549e6a43a48e1f183b155e5f0452a62cce3ba8 GIT binary patch literal 103 zcmZ?wbh9u|>|$VHSjYed|A8b3>wtJ5aRw%bo_vOmQ_tf%`i*W+I}#9H-#F8R@lfYH ymFXRKUv2xa=cwx6hl#UZCBLm^Y`09(&{+L3;Kb~Y;XQKmois~+Mb6`5um%8~XD5mP literal 0 HcmV?d00001 diff --git a/icons/mmsbf01.gif b/icons/mmsbf01.gif new file mode 100644 index 0000000000000000000000000000000000000000..b98b0d4d639962ae04f6aa8efa2bc8a0d38764b5 GIT binary patch literal 112 zcmZ?wbh9u|>|$VHSjYed{~7*+=>Iw(5+u&R|$VHSjYed{~7*+=>Iw(5+u&Rv^rOvuC&M LO*UA>z+epk4aO|$VHSjYed{~7*+=>Iw(5+u&RE|2H9_p0( zxp3jBwQGePCx_1Dtlsxy?f0km7;i;6#`>@=xZ2_qf9mBgM|YQ(?=?KNSP$o2{>9>c KIK_>T!5RQd{VT@+ literal 0 HcmV?d00001 diff --git a/icons/mmsbf04.gif b/icons/mmsbf04.gif new file mode 100644 index 0000000000000000000000000000000000000000..6a8b62e8298141d8c53d1f6c83efb47e5d6be8c9 GIT binary patch literal 113 zcmZ?wbh9u|>|$VHSjYed{~7*+=>Iw(5+u&R|$VHSjYed{~7*+=>Iw(5+u&R|$VHSjYed{~7*+=>Iw(5+u&R7( zE?lU!cJ0g!&$&}>J}dp8a{NpDtB+9!LN1DKNi48D_)fD$&i%-Pk~Ci}_A_%#vRRZ5 J_cJkA0{~|$VHSjYed{~7*+=>Iw(5+u&R85jDKi)^4Rq7Oo zTsU28?b?|eo@*b!eXUX6=Bh2P&d(;zMcy8}GmESk-@j~@ieCJZr_)!{vLQ`_Yum9S IjZ6&I03+Wi=>Px# literal 0 HcmV?d00001 diff --git a/icons/mmsbf08.gif b/icons/mmsbf08.gif new file mode 100644 index 0000000000000000000000000000000000000000..9c70b49ff8f6c334d9cbc7f0807b559dedc759e2 GIT binary patch literal 111 zcmZ?wbh9u|>|$VHSjYed{~7*+=>Iw(5+u&RDqJ*mQ+v z&X}sTR@Z9dP3`F=*K3nFzL$Dsv-N?{$-RC(6*ScFO HtPIuwo{T9J literal 0 HcmV?d00001 diff --git a/icons/mmsbf09.gif b/icons/mmsbf09.gif new file mode 100644 index 0000000000000000000000000000000000000000..67234e3a50ff898b8e1a7052b9b9cdbcbcbd70fa GIT binary patch literal 112 zcmZ?wbh9u|>|$VHSjYed{~7*+=>Iw(5+u&R(fs zY~ggRwQFZ?c&>fi|$VHSjYed{~7*+=>Iw(5+u&R*o2v~{11L>HXmMmwZqpa_xh4xmR_zE Ju`Y}Z)&T0QD4GBO literal 0 HcmV?d00001 diff --git a/icons/mmsbf11.gif b/icons/mmsbf11.gif new file mode 100644 index 0000000000000000000000000000000000000000..151c44b5a7d01b68eebd6688347f3bc09044e65f GIT binary patch literal 112 zcmZ?wbh9u|>|$VHSjYed{~7*+=>Iw(5+u&R!VOxIR&YGa zEb3IRU2C=Rrgr(4y;ombOnbrE{4i$cLsxO*b6uA6PJ9<;ndl`wxx+Rr{Pv8=EFH@x JY+z!r1^_ecD|$VHSjYed{~7*+=>Iw(5+u&R!s{6id-QcR zEYnag)wOQCsl7XT?gK;L=}%XB9jq{abX>yeT-TZYeik0CwzDavm3wY&idp^HvV$#= HmBAVS%~C0* literal 0 HcmV?d00001 diff --git a/icons/mmsbf13.gif b/icons/mmsbf13.gif new file mode 100644 index 0000000000000000000000000000000000000000..563866ebd5b8e63733f2cab6b85452b64bcba758 GIT binary patch literal 112 zcmZ?wbh9u|>|$VHSjYed{~7*+=>Iw(5+u&R!s{DvI!s%l zv?NQ*H|cuON$cZVvY+49-My?cYGsLh(uo<4hssXfdKb>c#p)~bIqHbqR?l~zm~9!C Jtz=@b1^_}KD-8eu literal 0 HcmV?d00001 diff --git a/icons/mmsf01.gif b/icons/mmsf01.gif new file mode 100644 index 0000000000000000000000000000000000000000..3f96f91e8eba690bbf618bd0b280e7d182d51f40 GIT binary patch literal 103 zcmZ?wbh9u|>|$VHSjYed{~7*+X&n#=5@%p?n3B(M@a!v@p8SgjnSIewe+w6uCnjGu y<(L$fn!Rs%^}%m4*MG#WV_!d+v)Sdsg$NN@<$Xuq?Nm`+dSX>kS5q7pgEatJ?j^kd literal 0 HcmV?d00001 diff --git a/icons/mmsf02.gif b/icons/mmsf02.gif new file mode 100644 index 0000000000000000000000000000000000000000..b62e6e06538aa2e0de1f2d71eb84e8e350140a1f GIT binary patch literal 105 zcmZ?wbh9u|>|$VHSjYed{~7*+X&n#=5@%p?>d9v~bhb;Nhx0 zc3++%_3B{4vuj3`v$f{#e|a+NYtEiWCwEwDO+F*9_d~*KqT#EY$fI$yJD3=(0nCyp ADgXcg literal 0 HcmV?d00001 diff --git a/icons/mmsf03.gif b/icons/mmsf03.gif new file mode 100644 index 0000000000000000000000000000000000000000..3ebf5c36b14fc8de1074776b45c5684147c81422 GIT binary patch literal 104 zcmZ?wbh9u|>|$VHSjYed{~7*+X&n#=5@%p??8#^7(Bhw;lzu58Gi~?U+oAK#ik6ly zy`kwAIAcR0*ZM6v%@t=Ke}CKbrOry}WQNnCu2qZmG;VrMReII)@{F23D}yxvX!a(0 literal 0 HcmV?d00001 diff --git a/icons/mmsf04.gif b/icons/mmsf04.gif new file mode 100644 index 0000000000000000000000000000000000000000..94cf762d404e2366f130da047ad7875954aa28a1 GIT binary patch literal 105 zcmZ?wbh9u|>|$VHSjYed{~7*+X&n#=5@%p?>d9y5IJLZG&ZWHx@oBr)-gcaCR|$VHSjYed{~7*+X&n#=5@%p?>d9y5IQ2X(V9_n9__W=+Hy!7j6)ja? zdRcQ>B2&!u-Me&ho|$VHSjYed{~7*+X&n#=5@%p??8#^7IQ2ZP!@sjzKXte6O~-iCqNVCf zFKaGKJaj1X+q%4*=8ChAzprPWls04Dg%TIm=~^n6J$DJ3?#|luHN;JomBAVScqS#3 literal 0 HcmV?d00001 diff --git a/icons/mmsf07.gif b/icons/mmsf07.gif new file mode 100644 index 0000000000000000000000000000000000000000..ddf4a43f9bfe0e64adcce0d8a3d975b793832046 GIT binary patch literal 105 zcmZ?wbh9u|>|$VHSjYed{~7*+X&n#=5@%p?>d9y5IQ2ZPqu)q%)46TBHyz_mDKq@l#A!qekKNM0KL2? A(f|Me literal 0 HcmV?d00001 diff --git a/icons/mmsf08.gif b/icons/mmsf08.gif new file mode 100644 index 0000000000000000000000000000000000000000..4976f10f11d12ab38f0cef18d8661de50a0bc711 GIT binary patch literal 103 zcmZ?wbh9u|>|$VHSjYed{~7*+X&n#=5@%p?=*eg3IQ2ZPqu=Ou!;PBc9Uk#QVNXlF yR#^FIp4gXir}VAv?vLxbEYBIU2Ac9+Fh8SGZM-D-N6gQzdGkwew%BnoSOWl1<0X;+ literal 0 HcmV?d00001 diff --git a/icons/mmsf09.gif b/icons/mmsf09.gif new file mode 100644 index 0000000000000000000000000000000000000000..fb8560f82a84afe934e9fd30c2488a3fe3dd7dd0 GIT binary patch literal 104 zcmZ?wbh9u|>|$VHSjYed{~7*+X&n#=5@%p??8#^7IQ2ZPqu=QEw2(!=`y8W8<5Ja@ zUe;Wec<4~xo^$uVUz48u{PTY1NiAx(d5?Gt1+Gf`@Ulm2;WFi-n~RL(SsAPWzBea* literal 0 HcmV?d00001 diff --git a/icons/mmsf10.gif b/icons/mmsf10.gif new file mode 100644 index 0000000000000000000000000000000000000000..362424fb1177ad6ed66e1922fe0c402331b80442 GIT binary patch literal 104 zcmZ?wbh9u|>|$VHSjYed{~7*+X&n#=5@%p??8#^7IQ2ZPqu=QEv?Br?{B<#lLZ6m; zt+4XTJiaf*CqIs3+pagOw*HL1*(907KK=3Ao_+T|aJFzQ4iO1ja>j_6mBAVSfq^CD literal 0 HcmV?d00001 diff --git a/icons/mmsf11.gif b/icons/mmsf11.gif new file mode 100644 index 0000000000000000000000000000000000000000..4e1b8c022c70837c1754c3ca57c71cb75b79e0ac GIT binary patch literal 103 zcmZ?wbh9u|>|$VHSjYed{~7*+X&n#=5@%p?=*eg3IQ2ZPqu=QEv?BrG3N1+|RPU8~ yt%&l=Jiaf@Cx4T5-`l$D^Y?FJGtV+gG45k1bcBYSOWk-f+O<) literal 0 HcmV?d00001 diff --git a/icons/mmsf12.gif b/icons/mmsf12.gif new file mode 100644 index 0000000000000000000000000000000000000000..0335cff4428b48021c52380f46610ed9b5e2c23e GIT binary patch literal 103 zcmZ?wbh9u|>|$VHSjYed{~7*+X&n#=5@%p?=*eg3IQ2ZPqu=QEv?BrG^^Au+`eK;8 y7FPLX9^aSYlfOxNdg|?K^Y?FJG|$VHSjYed{~7*+X&n#=5@%p?=*eg3IQ2ZPqu=QEv?BrG^^G$frm3ix yYFc%^dZt#m``nvc=4B_Z+5P#=;(XZW|$VHSjYed{~7*+X&n#=5@%p?=*eg3IQ2ZPqu=QEv?BrG^^G%47!P&M yQ<>gz_tmx!dycC9eV91wRr1?v#&*jj4UN?w15V8T7~Uf{-$}FNSL8e{25SJHWhaUN literal 0 HcmV?d00001 diff --git a/icons/mmz01.gif b/icons/mmz01.gif new file mode 100644 index 0000000000000000000000000000000000000000..677027f92802323b186f007a9e2329f3412035d7 GIT binary patch literal 38 jcmZ?wbh9u|9S{u?VPIly>0jB+%3uuuTH6Hq literal 0 HcmV?d00001 diff --git a/icons/mmz02.gif b/icons/mmz02.gif new file mode 100644 index 0000000000000000000000000000000000000000..9c902295cda5fee000f9b1ce28b587a96ac9ed11 GIT binary patch literal 45 ucmZ?wbh9u|6k=duXkY+=|NsB%fM}2i0~1e6zTgSoSC67MIfgSZSOWm%Jqr&2 literal 0 HcmV?d00001 diff --git a/icons/mmz03.gif b/icons/mmz03.gif new file mode 100644 index 0000000000000000000000000000000000000000..22e65e2f1c5ebbfddad6477af92998f1916b3b92 GIT binary patch literal 48 xcmZ?wbh9u|lwn|DXkY+=|NsB%fM}2i0~3EszF^0x^DzI%7p;469m7 IgeZeG0MND(qyPW_ literal 0 HcmV?d00001 diff --git a/icons/mmz06.gif b/icons/mmz06.gif new file mode 100644 index 0000000000000000000000000000000000000000..888692fe2979c082920577817c91862763d54db2 GIT binary patch literal 63 zcmZ?wbh9u|v|?akXkY+=|NsB%fM}2i1Cv}!zF^0x=W-qWr*sx Y@w(Svnl^YZUenvZb>4LAUWHt}2G$s1E& ctgO@h5%$_-c8Sie4|Pd<#kS>EwZB>0EtUKueB|U=8LR=V3?E4V literal 0 HcmV?d00001 diff --git a/icons/mmz13.gif b/icons/mmz13.gif new file mode 100644 index 0000000000000000000000000000000000000000..0ad15635822129f6c75733d0667a56cf8bc437fb GIT binary patch literal 89 zcmZ?wbh9u|Y+ztvXkY+=|NsB%fM}2i1CvEdzF^0x=W-qWMz^OO2?(!moay41RMKWuO$G*Q0DGb%*#H0l literal 0 HcmV?d00001 diff --git a/icons/mmz14.gif b/icons/mmz14.gif new file mode 100644 index 0000000000000000000000000000000000000000..0ce5d1902b6cb5cb99131360d7b93a3b4596b1a4 GIT binary patch literal 92 zcmZ?wbh9u|>|$VHXkY+=|NsB%fM}2i1Cw=2zF^0x=W-qWMz^OO2?(!moN3aT;$GCb rb6L*IW4Biy+FaANqwf2CyH6kM4ketk@KKt+B55*5sNK>wCI)K&1Y9N* literal 0 HcmV?d00001 diff --git a/mirmon/mirmon b/mirmon/mirmon index 8c0b298..39674a7 100755 --- a/mirmon/mirmon +++ b/mirmon/mirmon @@ -1,6 +1,5 @@ -#! /usr/bin/perl -w -# $Cambridge$ -# +#!/usr/bin/perl -w +# $Cambridge$ # Copyright (c) 2003 Henk Penning, all rights reserved. # penning@cs.uu.nl, http://www.cs.uu.nl/staff/henkp.html # Version 1.1 was donated to the Apache Software Foundation 2003 Jan 28 @@ -24,48 +23,40 @@ # DEALINGS IN THE SOFTWARE. # # Thanks to Klaus Heinz for sugestions ao htm_head - -my $PRG = 'mirmon' ; -my $VER = '$Id: mirmon,v 1.37 2006/12/04 15:16:11 henkp Exp henkp $' ; - -use strict ; -use IO::Pipe ; -use IO::Select ; -use Net::hostent ; - -my $DEF_CNF = "/etc/$PRG.conf" ; - -my %CNF = - qw( timeout 300 - max_probes 25 - min_poll 1h - max_poll 4h - min_sync 1d - max_sync 2d - list_style plain - put_histo top - randomize 1 - ) ; - -my @REQ_KEYS = - qw( web_page state countries mirror_list probe - project_name project_url icons - ) ; +my $PRG = 'mirmon'; +my $VER = '$Id: mirmon,v 1.37 2006/12/04 15:16:11 henkp Exp henkp $'; +use strict; +use IO::Pipe; +use IO::Select; +use Net::hostent; +my $DEF_CNF = "/etc/$PRG.conf"; +my %CNF = qw( timeout 300 + max_probes 25 + min_poll 1h + max_poll 4h + min_sync 1d + max_sync 2d + list_style plain + put_histo top + randomize 1 +); +my @REQ_KEYS = qw( web_page state countries mirror_list probe + project_name project_url icons +); my @OPT_KEYS = qw( project_logo min_poll min_sync max_sync list_style htm_top htm_foot - htm_head put_histo - ) ; -my %CNF_KEYS ; for ( @REQ_KEYS, @OPT_KEYS, keys %CNF ) - { $CNF_KEYS { $_ } ++ ; } - -my $TIM_PAT = '^(\d+)([smhd])$' ; -my @LIST_STYLE = qw(plain apache) ; -my @GET_OPTS = qw(all update) ; -my @PUT_HGRAM = qw(top bottom nowhere) ; -my $HIST = 14 ; -my %APA_TYPES = () ; for ( qw(backup ftp http) ) { $APA_TYPES { $_ } ++ ; } - -my $prog = substr($0,rindex($0,'/')+1) ; + htm_head put_histo +); +my %CNF_KEYS; +for ( @REQ_KEYS, @OPT_KEYS, keys %CNF ) { $CNF_KEYS{$_}++; } +my $TIM_PAT = '^(\d+)([smhd])$'; +my @LIST_STYLE = qw(plain apache); +my @GET_OPTS = qw(all update); +my @PUT_HGRAM = qw(top bottom nowhere); +my $HIST = 14; +my %APA_TYPES = (); +for (qw(backup ftp http)) { $APA_TYPES{$_}++; } +my $prog = substr( $0, rindex( $0, '/' ) + 1 ); my $Usage = <= 0 ; - -my %WGT ; -my $GET = IO::Select -> new () ; -my %URL ; -my %RES ; -my %OLD ; -my %LST ; -my %CCS ; -my %HREF ; - +my %opt = (); +Usage() unless GetOptions( \%opt, 'v', 'q', 't=i', 'get=s', 'c=s' ); +Usage("Arg count\n") unless @ARGV >= 0; +my %WGT; +my $GET = IO::Select->new(); +my %URL; +my %RES; +my %OLD; +my %LST; +my %CCS; +my %HREF; # -sub exp_date - { my @day = qw(Sun Mon Tue Wed Thu Fri Sat) ; - my @mon = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) ; - my @gmt = gmtime time + 3600 ; - sprintf "%s, %02d %s %4d %02d:%02d:%02d GMT" - , $day [ $gmt [ 6 ] ] - , $gmt [ 3 ] - , $mon [ $gmt [ 4 ] ] - , $gmt [ 5 ] + 1900 - , @gmt [ 2, 1, 0 ] - ; - } - -sub find_conf - { return $opt{c} if $opt{c} ; - my $HOME = ( getpwuid $< ) [ 7 ] or Error "can get homedir '$<' ($!)" ; - my @LIST = ( "$PRG.conf" , "$HOME/.$PRG.conf" , $DEF_CNF ) ; - for my $conf ( @LIST ) { return $conf if -f $conf ; } - Error sprintf "can't find a config file :\n %s" , join "\n ", @LIST ; - } - -sub show_conf - { print "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n" ; - for my $key ( sort keys %CNF ) - { next if $key =~ m/^_/ ; - print "show_conf : $key = '$CNF{$key}'\n" ; - } - for my $key ( sort keys %HREF ) - { printf "show_conf : for site '%s' use instead\n '%s'\n", - $key, $HREF { $key } if $opt{v} ; - } - printf "show_conf : included '%s'\n", join "', '", @{ $CNF{_include} } ; - print "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" ; - } - -sub get_conf ; - -sub get_conf - { my $FILE = shift ; - - if ( grep $_ eq $FILE, @{ $CNF {_include} } ) - { Error "already included : '$FILE'" ; } - else - { push @{ $CNF {_include} }, $FILE ; } - - open FILE, $FILE or Error "can't open '$FILE' ($!)" ; - my $CONF = join "\n", grep /./, ; - close FILE ; - - $CONF =~ s/\t/ /g ; # replace tabs - $CONF =~ s/^[+ ]+// ; # delete leading space, plus - $CONF =~ s/\n\n\s+/ /g ; # glue continuation lines - $CONF =~ s/\n\n\+\s+//g ; # glue concatenation lines - $CONF =~ s/\n\n\./\n/g ; # glue concatenation lines - - chop $CONF ; - print "--$CONF--\n" if $opt{d} ; - for ( grep ! /^#/, split /\n\n/, $CONF ) - { my ($key,$val) = split ' ', $_, 2 ; - $val = '' unless defined $val ; - print "conf '$FILE' : key '$key', val '$val'\n" if $opt{d} ; - if ( exists $CNF_KEYS { $key } ) - { $CNF { $key } = $val ; } - elsif ( $key eq 'site_url' ) - { my ( $site, $url ) = split ' ' , $val ; - $url .= '/' unless $url =~ m!/$! ; - $HREF { lc $site } = $url ; - printf "config : for site '%s' use instead\n '%s'\n", - $site, $url if $opt{v} ; - } - elsif ( $key eq 'env' ) - { my ( $x, $y ) = split ' ' , $val ; - $ENV { $x } = $y ; - printf "config : setenv '%s'\n '%s'\n", $x, $y if $opt{v} ; - } - elsif ( $key eq 'no_randomize' ) - { $CNF { randomize } = 0 ; } - elsif ( $key eq 'include' ) - { get_conf $val ; } - elsif ( $key eq 'show' ) - { show_conf unless $opt{q} ; } - elsif ( $key eq 'exit' ) - { Error 'exit per config directive' ; } - elsif ( $key eq 'max_age' ) - { $CNF { max_sync } = $val ; } - else - { show_conf ; - Error "unknown keyword '$key' (value '$val')" ; - } - } - } - -sub get_conf_opt - { my $err = '' ; - get_conf find_conf ; - $CNF { timeout } = $opt{t} if $opt{t} ; - for my $key ( @REQ_KEYS ) - { unless ( exists $CNF { $key } ) - { $err .= "$prog error: missing config for '$key'\n" ; } - } - for my $key ( qw(min_poll max_poll max_sync min_sync) ) - { my $max = $CNF { $key } ; - unless ( $max =~ /$TIM_PAT/o ) - { $err .= "$prog error: $key ($max) doesn't match /$TIM_PAT/\n" ; } - } - unless ( grep $CNF { list_style } eq $_, @LIST_STYLE ) - { $err .= sprintf "%s : error: unknown 'list_style' '%s'\n", - $prog, $CNF { list_style } ; - } - unless ( grep $CNF { put_histo } eq $_, @PUT_HGRAM ) - { $err .= sprintf "%s : error: unknown 'put_histo' '%s'\n", - $prog, $CNF { put_histo } ; - } - if ( $opt { get } and not grep $opt { get } eq $_, @GET_OPTS ) - { $err .= sprintf "%s : error: unknown 'get option' '%s'\n", - $prog, $opt { get } ; - } - Error $err if $err ; - $opt{q} = 0 if $opt{v} ; - } - -sub tim_to_s - { my $tim = shift ; - my %tab = ( 's' => 1, 'm' => 60, 'h' => 60 * 60, 'd' => 60 * 60 * 24 ) ; - Error "wrong time '$tim'" unless $tim =~ /$TIM_PAT/o ; - my $m = $1 ; my $u = $2 ; - return $m * $tab { $u } ; - } - -sub aprx_eq { my ( $t1, $t2 ) = @_ ; abs ( $t1 - $t2 ) < 60 ; } -sub aprx_ge { my ( $t1, $t2 ) = @_ ; $t1 > $t2 or aprx_eq $t1, $t2 ; } -sub aprx_le { my ( $t1, $t2 ) = @_ ; $t1 < $t2 or aprx_eq $t1, $t2 ; } -sub aprx_gt { my ( $t1, $t2 ) = @_ ; $t1 > $t2 and not aprx_eq $t1, $t2 ; } -sub aprx_lt { my ( $t1, $t2 ) = @_ ; $t1 < $t2 and not aprx_eq $t1, $t2 ; } - -sub pr_interval - { my $s = shift ; - my ( $magn, $unit ) ; - my $mins = $s / 60 ; my $m = int ( $mins + 0.5 ) ; - my $hours = $s / ( 60 * 60 ) ; my $h = int ( $hours + 0.5 ) ; - - if ( $s < 50 ) - { $magn = $s ; $unit = 'second' ; } - elsif ( $m < 50 ) - { $magn = $m ; $unit = 'minute' ; } - elsif ( $h < 36 ) - { $magn = $h ; $unit = 'hour' ; } - else - { $magn = sprintf "%.1f", $hours / 24 ; $unit = 'day' ; } - - $unit .= 's' unless $magn == 1 ; - - return "$magn $unit" ; - } - -sub max_age1 - { ( tim_to_s $CNF { min_sync } ) + ( tim_to_s $CNF { max_poll } ) ; } -sub max_age2 - { ( tim_to_s $CNF { max_sync } ) + ( tim_to_s $CNF { max_poll } ) ; } - -sub max_vrfy - { ( tim_to_s $CNF { min_poll } ) + ( tim_to_s $CNF { max_poll } ) ; } - -sub age_code - { my $time = shift ; - return 'z' unless $time =~ /^\d+$/ ; - return - ( ( aprx_ge ( $time, $^T - max_age1 ) ) - ? 's' - : ( aprx_ge ( $time, $^T - max_age2 ) ? 'b' : 'f' ) - ) ; - } - -sub err - { my $url = shift ; - my $stat = shift ; - printf "*** %-10s %s\n", $stat, $url unless $opt{q} ; - my ( $time, $vrfy, $hstp, $hsts ) ; - if ( exists $OLD { $url } ) - { $time = $OLD { $url } [ 0 ] ; - $vrfy = $OLD { $url } [ 2 ] ; - $hstp = substr $OLD { $url } [ 3 ], 1 - $HIST ; - $hsts = $OLD { $url } [ 4 ] ; - } - else - { $time = 'undef' ; - $vrfy = 'undef' ; - $hstp = '' ; - $hsts = '' ; - } - $RES { $url } = [ $time, $stat, $vrfy, $hstp . 'f', $hsts, $^T ] ; - } - -sub res - { my $url = shift ; - my $time = shift ; - my $stat = shift ; - my $hstp = - ( exists $OLD { $url } - ? substr ( $OLD { $url } [ 3 ], 1 - $HIST ) - : '' - ) ; - my $hsts = ( exists $OLD { $url } ? $OLD { $url } [ 4 ] : '') ; - printf "result %d %s\n", $time, $url if $opt{v} ; - $RES { $url } = [ $time, $stat, $^T, $hstp . 's', $hsts, $^T ] ; - } - -sub get_state - { my $STT = shift ; - open STT, $STT or Error "can't open '$STT' ($!)" ; - while ( ) - { chop ; - my ( $url, $time, $stat, $vrfy, $hstp, $hsts, $lprb ) = split ' ' ; - $stat =~ s/_/ /g ; - $hstp = '' unless defined $hstp ; - $hsts = '' unless defined $hsts ; - $hsts = '' if $hsts eq 'undef' ; - $lprb = 'undef' unless defined $lprb ; - $OLD { $url } = [ $time, $stat, $vrfy, $hstp, $hsts, $lprb ] ; - } - close STT ; - } - -sub check_hist - { my $time = shift ; - my $hsts = shift ; - printf "check_hist: last '$time' hsts '$hsts'\n" if $opt{d} ; - - my $res = $hsts ; - my ( $stmp, $hist ) ; - - if ( $hsts eq '' ) - { $stmp = 0 ; $hist = '' ; } - else - { ( $stmp, $hist ) = split '-', $hsts ; } - - if ( aprx_le $stmp, $^T - tim_to_s '1d' ) - { $res = sprintf "%s-%s%s" - , $^T - , substr ( $hist, 1 - $HIST ) - , age_code ( $time ) - ; - } - return $res ; - } - -sub put_state - { my $STT = shift ; - my $TMP = "$STT.tmp" ; - open TMP, ">$TMP" or Error "can't write '$TMP' ($!)" ; - for my $url ( sort keys %RES ) - { $RES { $url } [ 4 ] - = check_hist $RES { $url } [ 0 ], $RES { $url } [ 4 ] ; - my @OUT = @{ $RES { $url } } ; - $OUT [ 1 ] =~ s/\s/_/g ; +sub exp_date { + my @day = qw(Sun Mon Tue Wed Thu Fri Sat); + my @mon = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); + my @gmt = gmtime time + 3600; + sprintf "%s, %02d %s %4d %02d:%02d:%02d GMT", $day[ $gmt[6] ], $gmt[3], + $mon[ $gmt[4] ], $gmt[5] + 1900, @gmt[ 2, 1, 0 ]; +} +sub find_conf { + return $opt{c} if $opt{c}; + my $HOME = ( getpwuid $< )[7] or Error "can get homedir '$<' ($!)"; + my @LIST = ( "$PRG.conf", "$HOME/.$PRG.conf", $DEF_CNF ); + for my $conf (@LIST) { return $conf if -f $conf; } + Error sprintf "can't find a config file :\n %s", join "\n ", @LIST; +} +sub show_conf { + print "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n"; + for my $key ( sort keys %CNF ) { + next if $key =~ m/^_/; + print "show_conf : $key = '$CNF{$key}'\n"; + } + for my $key ( sort keys %HREF ) { + printf "show_conf : for site '%s' use instead\n '%s'\n", $key, + $HREF{$key} + if $opt{v}; + } + printf "show_conf : included '%s'\n", join "', '", @{ $CNF{_include} }; + print "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"; +} +sub get_conf; +sub get_conf { + my $FILE = shift; + if ( grep $_ eq $FILE, @{ $CNF{_include} } ) { + Error "already included : '$FILE'"; + } + else { push @{ $CNF{_include} }, $FILE; } + open FILE, $FILE or Error "can't open '$FILE' ($!)"; + my $CONF = join "\n", grep /./, ; + close FILE; + $CONF =~ s/\t/ /g; # replace tabs + $CONF =~ s/^[+ ]+//; # delete leading space, plus + $CONF =~ s/\n\n\s+/ /g; # glue continuation lines + $CONF =~ s/\n\n\+\s+//g; # glue concatenation lines + $CONF =~ s/\n\n\./\n/g; # glue concatenation lines + chop $CONF; + print "--$CONF--\n" if $opt{d}; + for ( grep !/^#/, split /\n\n/, $CONF ) { + my ( $key, $val ) = split ' ', $_, 2; + $val = '' unless defined $val; + print "conf '$FILE' : key '$key', val '$val'\n" if $opt{d}; + if ( exists $CNF_KEYS{$key} ) { $CNF{$key} = $val; } + elsif ( $key eq 'site_url' ) { + my ( $site, $url ) = split ' ', $val; + $url .= '/' unless $url =~ m!/$!; + $HREF{ lc $site } = $url; + printf "config : for site '%s' use instead\n '%s'\n", $site, $url + if $opt{v}; + } + elsif ( $key eq 'env' ) { + my ( $x, $y ) = split ' ', $val; + $ENV{$x} = $y; + printf "config : setenv '%s'\n '%s'\n", $x, $y if $opt{v}; + } + elsif ( $key eq 'no_randomize' ) { $CNF{randomize} = 0; } + elsif ( $key eq 'include' ) { get_conf $val ; } + elsif ( $key eq 'show' ) { show_conf unless $opt{q}; } + elsif ( $key eq 'exit' ) { Error 'exit per config directive'; } + elsif ( $key eq 'max_age' ) { $CNF{max_sync} = $val; } + else { + show_conf; + Error "unknown keyword '$key' (value '$val')"; + } + } +} +sub get_conf_opt { + my $err = ''; + get_conf find_conf; + $CNF{timeout} = $opt{t} if $opt{t}; + for my $key (@REQ_KEYS) { + unless ( exists $CNF{$key} ) { + $err .= "$prog error: missing config for '$key'\n"; + } + } + for my $key (qw(min_poll max_poll max_sync min_sync)) { + my $max = $CNF{$key}; + unless ( $max =~ /$TIM_PAT/o ) { + $err .= "$prog error: $key ($max) doesn't match /$TIM_PAT/\n"; + } + } + unless ( grep $CNF{list_style} eq $_, @LIST_STYLE ) { + $err .= sprintf "%s : error: unknown 'list_style' '%s'\n", $prog, + $CNF{list_style}; + } + unless ( grep $CNF{put_histo} eq $_, @PUT_HGRAM ) { + $err .= sprintf "%s : error: unknown 'put_histo' '%s'\n", $prog, + $CNF{put_histo}; + } + if ( $opt{get} and not grep $opt{get} eq $_, @GET_OPTS ) { + $err .= sprintf "%s : error: unknown 'get option' '%s'\n", $prog, + $opt{get}; + } + Error $err if $err; + $opt{q} = 0 if $opt{v}; +} +sub tim_to_s { + my $tim = shift; + my %tab = ( 's' => 1, 'm' => 60, 'h' => 60 * 60, 'd' => 60 * 60 * 24 ); + Error "wrong time '$tim'" unless $tim =~ /$TIM_PAT/o; + my $m = $1; + my $u = $2; + return $m * $tab{$u}; +} +sub aprx_eq { my ( $t1, $t2 ) = @_; abs( $t1 - $t2 ) < 60; } +sub aprx_ge { my ( $t1, $t2 ) = @_; $t1 > $t2 or aprx_eq $t1, $t2; } +sub aprx_le { my ( $t1, $t2 ) = @_; $t1 < $t2 or aprx_eq $t1, $t2; } +sub aprx_gt { my ( $t1, $t2 ) = @_; $t1 > $t2 and not aprx_eq $t1, $t2; } +sub aprx_lt { my ( $t1, $t2 ) = @_; $t1 < $t2 and not aprx_eq $t1, $t2; } +sub pr_interval { + my $s = shift; + my ( $magn, $unit ); + my $mins = $s / 60; + my $m = int( $mins + 0.5 ); + my $hours = $s / ( 60 * 60 ); + my $h = int( $hours + 0.5 ); + if ( $s < 50 ) { $magn = $s; $unit = 'second'; } + elsif ( $m < 50 ) { $magn = $m; $unit = 'minute'; } + elsif ( $h < 36 ) { $magn = $h; $unit = 'hour'; } + else { $magn = sprintf "%.1f", $hours / 24; $unit = 'day'; } + $unit .= 's' unless $magn == 1; + return "$magn $unit"; +} +sub max_age1 { + ( tim_to_s $CNF {min_sync} ) + ( tim_to_s $CNF {max_poll} ); +} +sub max_age2 { + ( tim_to_s $CNF {max_sync} ) + ( tim_to_s $CNF {max_poll} ); +} +sub max_vrfy { + ( tim_to_s $CNF {min_poll} ) + ( tim_to_s $CNF {max_poll} ); +} +sub age_code { + my $time = shift; + return 'z' unless $time =~ /^\d+$/; + return ( + ( aprx_ge( $time, $^T - max_age1 ) ) + ? 's' + : ( aprx_ge( $time, $^T - max_age2 ) ? 'b' : 'f' ) + ); +} +sub err { + my $url = shift; + my $stat = shift; + printf "*** %-10s %s\n", $stat, $url unless $opt{q}; + my ( $time, $vrfy, $hstp, $hsts ); + if ( exists $OLD{$url} ) { + $time = $OLD{$url}[0]; + $vrfy = $OLD{$url}[2]; + $hstp = substr $OLD{$url}[3], 1 - $HIST; + $hsts = $OLD{$url}[4]; + } + else { + $time = 'undef'; + $vrfy = 'undef'; + $hstp = ''; + $hsts = ''; + } + $RES{$url} = [ $time, $stat, $vrfy, $hstp . 'f', $hsts, $^T ]; +} +sub res { + my $url = shift; + my $time = shift; + my $stat = shift; + my $hstp = ( + exists $OLD{$url} + ? substr( $OLD{$url}[3], 1 - $HIST ) + : '' + ); + my $hsts = ( exists $OLD{$url} ? $OLD{$url}[4] : '' ); + printf "result %d %s\n", $time, $url if $opt{v}; + $RES{$url} = [ $time, $stat, $^T, $hstp . 's', $hsts, $^T ]; +} +sub get_state { + my $STT = shift; + open STT, $STT or Error "can't open '$STT' ($!)"; + while () { + chop; + my ( $url, $time, $stat, $vrfy, $hstp, $hsts, $lprb ) = split ' '; + $stat =~ s/_/ /g; + $hstp = '' unless defined $hstp; + $hsts = '' unless defined $hsts; + $hsts = '' if $hsts eq 'undef'; + $lprb = 'undef' unless defined $lprb; + $OLD{$url} = [ $time, $stat, $vrfy, $hstp, $hsts, $lprb ]; + } + close STT; +} +sub check_hist { + my $time = shift; + my $hsts = shift; + printf "check_hist: last '$time' hsts '$hsts'\n" if $opt{d}; + my $res = $hsts; + my ( $stmp, $hist ); + if ( $hsts eq '' ) { $stmp = 0; $hist = ''; } + else { ( $stmp, $hist ) = split '-', $hsts; } + if ( aprx_le $stmp, $^T - tim_to_s '1d' ) { + $res = sprintf "%s-%s%s", $^T, substr( $hist, 1 - $HIST ), + age_code($time); + } + return $res; +} +sub put_state { + my $STT = shift; + my $TMP = "$STT.tmp"; + open TMP, ">$TMP" or Error "can't write '$TMP' ($!)"; + for my $url ( sort keys %RES ) { + $RES{$url}[4] = check_hist $RES {$url}[0], $RES{$url}[4]; + my @OUT = @{ $RES{$url} }; + $OUT[1] =~ s/\s/_/g; printf TMP "%s %s\n", $url, join ' ', @OUT - or Error "can't print to $TMP ($!)" ; - } - close TMP ; - if ( -z $TMP ) - { Warn "wrote empty state file; keeping previous version" ; } - else - { rename $TMP, $STT or Error "can't rename '$TMP', '$STT' ($!)" ; } - } - -sub get_ccs - { my $CCS = shift ; - open CCS, $CCS or Error "can't open '$CCS' ($!)" ; - while ( ) - { chop ; - next if /^#/ ; - my ( $code, $dash, $reg ) = split ' ', $_, 3 ; - $CCS { lc $code } = lc $reg ; - } - close CCS ; - } - -sub type_site - { my $url = shift ; - my ( $type, $site, $home ) ; - if ( $url =~ m!^(ftp|http)://([^/:]+)(:\d+)?/! ) - { $type = $1 ; $site = $2 ; $home = $& ; } - return $type, $site, $home ; - } - -sub type { my ( $t, $s, $h) = type_site $_[0] ; $t ; } -sub site { my ( $t, $s, $h) = type_site $_[0] ; $s ; } -sub home { my ( $t, $s, $h) = type_site $_[0] ; $h ; } - -sub get_list - { my $LST = shift ; - my ( $reg, $url ) ; - open LST, $LST or Error "can't open '$LST' ($!)" ; - while ( ) - { chop ; - next if /^#/ ; - next if /^\s*$/ ; - if ( $CNF { list_style } eq 'plain' ) - { ( $reg, $url ) = split ' ' ; - unless ( $url =~ m!/$! ) - { print "*** mirmon appended '/' to $url\n" unless $opt{q} ; - $url .= '/' ; - } - } - elsif ( $CNF { list_style } eq 'apache' ) - { my $apache_type ; - ( $apache_type, $reg, $url ) = split ' ' ; - unless ( defined $APA_TYPES { $apache_type } ) - { print "*** strange type : $apache_type\n" unless $opt{q} ; - next ; - } - unless ( $url =~ m!/$! ) - { print "*** missing '/' in $url\n" unless $opt{q} ; - $url .= '/' ; - } - } - - my $site = site $url ; - my $type = type $url ; - - unless ( defined $site ) - { print "*** strange url : '$url'\n" unless $opt{q} ; next ; } - - $LST { $url } = [ $type , $site, $reg ] ; - } - } - -sub url { sprintf '%s', $_[0], $_[1] ; } -sub nam { sprintf '%s', $_[0], $_[1] ; } -sub SMA { sprintf "%s", $_[0] ; } -sub BLD { sprintf "%s", $_[0] ; } -sub NSS { sprintf SMA('%s site%s'), $_[0], ( $_[0] == 1 ? '' : 's' ) ; } -sub TAB { sprintf "%s
", $_[0] ; } -sub TR { sprintf "%s\n", $_[0] ; } -sub TH { sprintf "%s\n", $_[0] ; } -sub TD { sprintf "%s\n", $_[0] ; } -sub TDr { sprintf "%s\n", $_[0] ; } -sub RED { sprintf "%s", $_[0] ; } -sub GRN { sprintf '%s', $_[0] ; } - -sub htmlquote - { my $x = shift ; - $x =~ s/&/&/g ; - $x =~ s//>/g ; - return $x ; - } - -sub diff - { my $time = shift ; - my $max = shift ; - my $res ; - - if ( $time == $^T ) - { $res = BLD 'renewed' ; } - else - { $res = pr_interval $^T - $time ; - $res = BLD RED $res if aprx_lt $time, $max ; - } - return $res ; - } - -sub img_sf_cnt - { sprintf '' - , $CNF { icons }, $_[0], $_[1] ; - } - -sub img_sf { img_sf_cnt $_[0], 1 ; } - -sub show_hist - { my $hst = shift ; - return '' unless $hst =~ m/^[sbfz]+$/ ; - if ( length $hst == $HIST and $hst =~ /^(s*b)s*$/ ) - { return img_sf_cnt 'sb', length $1 ; } - elsif ( length $hst == $HIST and $hst =~ /^(s*f)s*$/ ) - { return img_sf_cnt 'sf', length $1 ; } - elsif ( length $hst == $HIST and $hst =~ /^(s*b)fs*$/ ) - { return img_sf_cnt 'sbf', length $1 ; } - my $res = '' ; - my $cnt = 1 ; - my $prf = substr $hst, 0, 1 ; - $hst = substr $hst, 1 ; - while ( $hst ne '' ) - { if ( substr ( $prf, 0, 1 ) eq substr ( $hst, 0, 1 ) ) - { $cnt ++ ; - $hst = substr $hst, 1 ; - } - else - { $res .= img_sf_cnt $prf, $cnt ; - $prf = substr $hst, 0, 1 ; - $hst = substr $hst, 1 ; - $cnt = 1 ; - } - } - $res .= img_sf_cnt $prf, $cnt if $cnt ; - return $res ; - } - -sub show_hist_age - { my $hsts = shift ; - my $time = shift ; - return '' if $hsts eq '' ; - my ( $t, $h ) = split '-', $hsts ; + or Error "can't print to $TMP ($!)"; + } + close TMP; + if ( -z $TMP ) { Warn "wrote empty state file; keeping previous version"; } + else { rename $TMP, $STT or Error "can't rename '$TMP', '$STT' ($!)"; } +} +sub get_ccs { + my $CCS = shift; + open CCS, $CCS or Error "can't open '$CCS' ($!)"; + while () { + chop; + next if /^#/; + my ( $code, $dash, $reg ) = split ' ', $_, 3; + $CCS{ lc $code } = lc $reg; + } + close CCS; +} +sub type_site { + my $url = shift; + my ( $type, $site, $home ); + if ( $url =~ m!^(ftp|http)://([^/:]+)(:\d+)?/! ) { + $type = $1; + $site = $2; + $home = $&; + } + return $type, $site, $home; +} +sub type { my ( $t, $s, $h ) = type_site $_[0]; $t; } +sub site { my ( $t, $s, $h ) = type_site $_[0]; $s; } +sub home { my ( $t, $s, $h ) = type_site $_[0]; $h; } +sub get_list { + my $LST = shift; + my ( $reg, $url ); + open LST, $LST or Error "can't open '$LST' ($!)"; + while () { + chop; + next if /^#/; + next if /^\s*$/; + if ( $CNF{list_style} eq 'plain' ) { + ( $reg, $url ) = split ' '; + unless ( $url =~ m!/$! ) { + print "*** mirmon appended '/' to $url\n" unless $opt{q}; + $url .= '/'; + } + } + elsif ( $CNF{list_style} eq 'apache' ) { + my $apache_type; + ( $apache_type, $reg, $url ) = split ' '; + unless ( defined $APA_TYPES{$apache_type} ) { + print "*** strange type : $apache_type\n" unless $opt{q}; + next; + } + unless ( $url =~ m!/$! ) { + print "*** missing '/' in $url\n" unless $opt{q}; + $url .= '/'; + } + } + my $site = site $url ; + my $type = type $url ; + unless ( defined $site ) { + print "*** strange url : '$url'\n" unless $opt{q}; + next; + } + $LST{$url} = [ $type, $site, $reg ]; + } +} +sub url { sprintf '%s', $_[0], $_[1]; } +sub nam { sprintf '%s', $_[0], $_[1]; } +sub SMA { sprintf "%s", $_[0]; } +sub BLD { sprintf "%s", $_[0]; } +sub NSS { sprintf SMA('%s site%s'), $_[0], ( $_[0] == 1 ? '' : 's' ); } +sub TAB { sprintf "%s
", $_[0]; } +sub TR { sprintf "%s\n", $_[0]; } +sub TH { sprintf "%s\n", $_[0]; } +sub TD { sprintf "%s\n", $_[0]; } +sub TDr { sprintf "%s\n", $_[0]; } +sub RED { sprintf "%s", $_[0]; } +sub GRN { sprintf '%s', $_[0]; } +sub htmlquote { + my $x = shift; + $x =~ s/&/&/g; + $x =~ s//>/g; + return $x; +} +sub diff { + my $time = shift; + my $max = shift; + my $res; + if ( $time == $^T ) { $res = BLD 'renewed'; } + else { + $res = pr_interval $^T - $time; + $res = BLD RED $res if aprx_lt $time, $max; + } + return $res; +} +sub img_sf_cnt { + sprintf '', $CNF{icons}, $_[0], + $_[1]; +} +sub img_sf { img_sf_cnt $_[0], 1; } +sub show_hist { + my $hst = shift; + return '' unless $hst =~ m/^[sbfz]+$/; + if ( length $hst == $HIST and $hst =~ /^(s*b)s*$/ ) { + return img_sf_cnt 'sb', length $1; + } + elsif ( length $hst == $HIST and $hst =~ /^(s*f)s*$/ ) { + return img_sf_cnt 'sf', length $1; + } + elsif ( length $hst == $HIST and $hst =~ /^(s*b)fs*$/ ) { + return img_sf_cnt 'sbf', length $1; + } + my $res = ''; + my $cnt = 1; + my $prf = substr $hst, 0, 1; + $hst = substr $hst, 1; + while ( $hst ne '' ) { + if ( substr( $prf, 0, 1 ) eq substr( $hst, 0, 1 ) ) { + $cnt++; + $hst = substr $hst, 1; + } + else { + $res .= img_sf_cnt $prf, $cnt; + $prf = substr $hst, 0, 1; + $hst = substr $hst, 1; + $cnt = 1; + } + } + $res .= img_sf_cnt $prf, $cnt if $cnt; + return $res; +} +sub show_hist_age { + my $hsts = shift; + my $time = shift; + return '' if $hsts eq ''; + my ( $t, $h ) = split '-', $hsts; if ( aprx_lt $t, $^T ) { $h .= age_code $time ; } - return show_hist substr $h, - $HIST ; - } - -sub gen_histogram_probes - { my ( $time, $stat, $vrfy, $hstp, $hsts, $lprb ) ; - my %tab = () ; - my %bad = () ; - my $res = '' ; - my $s_cnt = 0 ; - my $f_cnt = 0 ; - my $hr_min ; - my $hr_max ; - return '' unless scalar keys %RES ; - for my $url ( keys %RES ) - { ( $time, $stat, $vrfy, $hstp, $hsts, $lprb ) = @{ $RES { $url } } ; - my $hr = int ( ( $^T - $lprb ) / 3600 + 0.5 ) ; - $hr_min = $hr if ! defined $hr_min or $hr < $hr_min ; - $hr_max = $hr if ! defined $hr_max or $hr > $hr_max ; - if ( $stat eq 'ok' ) - { $tab { $hr } ++ ; $s_cnt ++ ; } - else - { $bad { $hr } ++ ; $f_cnt ++ ; } - } - $res = TR - ( TH ( 'hours ago' ) - . TH ( 'succ' ) - . TH ( 'fail' ) - . TH sprintf - ( '%s %s, %s %s' - , $s_cnt , GRN ( 'successful' ) - , $f_cnt , RED ( 'failed' ) - ) - ) ; - - my $max = 0 ; - for my $x ( keys %tab ) - { my $tot = $tab { $x } + ( $bad { $x } || 0 ) ; - $max = $tot if $max < $tot ; - } ; - - return "
\nnothing yet\n
\n" unless $max ; - - for my $hr ( $hr_min .. $hr_max ) - { my $x = $tab { $hr } || 0 ; - my $y = $bad { $hr } || 0 ; - my $n = int ( $x / $max * $HIST ) ; - my $b = int ( $y / $max * $HIST ) ; - $res .= TR - ( TDr ( $hr ) - . TDr ( $x ) - . TDr ( $y ) - . TD - ( ( $n ? img_sf_cnt ( 's', $n ) : '' ) - . ( $b ? img_sf_cnt ( 'f', $b ) : '' ) - . ( ( $n + $b ) ? '' : ' ' ) - ) - ) ; - } - return "
\n" . TAB ( $res ) . "
\n" ; - } - -sub gen_histogram - { my $MAX_H = max_age1 ; - my $MAX_h = 1 + - ( ( 20 * 3600 <= $MAX_H and $MAX_H <= 36 * 3600 ) - ? int ( $MAX_H / 3600 ) - : 25 - ) ; - my $MAX_O = max_age2 ; - my $MAX_o = int ( $MAX_O / 3600 + 0.5 ) ; - my $H = 18 ; - my %W = ( 'old' => 1, 'ded' => 1, 'bad' => 1 ) ; - my %Wmx = ( 'old' => 5, 'ded' => 3, 'bad' => 3 ) ; - my %tab ; - my %hst ; - my $res ; - for ( my $x = 0 ; $x < $MAX_h ; $x ++ ) { $tab { $x } = 0 ; } - $tab { old } = 0 ; $tab { ded } = 0 ; $tab { bad } = 0 ; - for my $url ( keys %RES ) - { my $time = $RES { $url } [ 0 ] ; - if ( $time =~ /^\d+$/ ) - { my $s = $^T - $time ; - my $hr = int ( $s / $MAX_H * ( $MAX_h - 1 ) + 0.5 ) ; - if ( $s <= $MAX_H ) { $tab { $hr } ++ ; } - elsif ( $s <= $MAX_O ) { $tab { old } ++ ; } - else { $tab { ded } ++ ; } - } - else - { $tab { bad } ++ ; } - } - my $max = 0 ; - for ( grep ! exists $Wmx { $_ }, keys %tab ) - { $max = $tab { $_ } if $tab { $_ } > $max ; } - - my %bad ; - - for my $aux ( keys %Wmx ) - { $bad { $aux } = $tab { $aux } ; - if ( $bad { $aux } > $max ) - { $W { $aux } = $Wmx { $aux } ; - my $d = int ( $bad { $aux } / $W { $aux } ) ; - for ( my $i = 1 ; $i < $W { $aux } ; $i++ ) - { $tab { $aux . $i } = $d ; - if ( $bad { $aux } % $Wmx { $aux } > $i ) - { $tab { $aux . $i } ++ ; - $tab { $aux } -- ; - } - } - $tab { $aux } -= ( $W { $aux } - 1 ) * $d ; - $max = $tab { $aux } if $max < $tab { $aux } ; - } - } - -# if ( $opt{v} ) -# { for my $hr ( keys %tab ) -# { printf "tab '%s' = '%s'\n", $hr, $tab { $hr } ; } -# } - - return 'nothing yet' unless $max ; - $H = $max if 8 <= $max and $max <= 26 ; - for ( keys %tab ) - { $hst { $_ } = int ( $H * $tab { $_ } / $max + 0.5 ) ; } - my @keys = sort { $a <=> $b } grep /^\d+$/, keys %hst ; - my $tab_hr = 0 ; - for my $hr ( @keys ) { $tab_hr += $tab { $hr } ; } - push @keys - , grep ( m/^old/, sort keys %tab ) - , grep ( m/^ded/, sort keys %tab ) - , grep ( m/^bad/, sort keys %tab ) - ; - for ( my $h = $H ; $h > 0 ; $h -- ) - { $res .= "\n" ; - $res .= sprintf "↑\n" - if $h == $H ; - $res .= sprintf '%s' . "\n" - , $H-6, NSS ( $max ) if $h == $H - 3 ; - $res .= sprintf "↓\n" - if $h == 3 ; - for my $x ( @keys ) - { $res .= sprintf "%s\n" - , ( ( $hst { $x } >= $h ) - ? img_sf - ( $x =~ /^\d+$/ - ? 's' - : ( $x =~ /^old/ ? 'b' : ( $x =~ /^ded/ ? 'f' : 'z' ) ) - ) - : ( ( $h == 1 and $hst { $x } == 0 ) - ? sprintf - ( '' - , $CNF { icons } + return show_hist substr $h, -$HIST; +} +sub gen_histogram_probes { + my ( $time, $stat, $vrfy, $hstp, $hsts, $lprb ); + my %tab = (); + my %bad = (); + my $res = ''; + my $s_cnt = 0; + my $f_cnt = 0; + my $hr_min; + my $hr_max; + return '' unless scalar keys %RES; + for my $url ( keys %RES ) { + ( $time, $stat, $vrfy, $hstp, $hsts, $lprb ) = @{ $RES{$url} }; + my $hr = int( ( $^T - $lprb ) / 3600 + 0.5 ); + $hr_min = $hr if !defined $hr_min or $hr < $hr_min; + $hr_max = $hr if !defined $hr_max or $hr > $hr_max; + if ( $stat eq 'ok' ) { $tab{$hr}++; $s_cnt++; } + else { $bad{$hr}++; $f_cnt++; } + } + $res = TR( + TH('hours ago') + . TH('succ') + . TH('fail') + . TH sprintf( '%s %s, %s %s', + $s_cnt, GRN('successful'), $f_cnt, RED('failed') ) + ); + my $max = 0; + for my $x ( keys %tab ) { + my $tot = $tab{$x} + ( $bad{$x} || 0 ); + $max = $tot if $max < $tot; + } + return "
\nnothing yet\n
\n" unless $max; + for my $hr ( $hr_min .. $hr_max ) { + my $x = $tab{$hr} || 0; + my $y = $bad{$hr} || 0; + my $n = int( $x / $max * $HIST ); + my $b = int( $y / $max * $HIST ); + $res .= TR( + TDr($hr) + . TDr($x) + . TDr($y) + . TD( + ( $n ? img_sf_cnt( 's', $n ) : '' ) + . ( $b ? img_sf_cnt( 'f', $b ) : '' ) + . ( ( $n + $b ) ? '' : ' ' ) ) - : '' - ) - ) ; - } - $res .= "\n" ; - } - - my $HR = '
' ; - - $res .= "\n" ; - $res .= sprintf "$HR\n", 1 ; - $res .= sprintf "$HR\n", $MAX_h ; - $res .= sprintf "$HR\n", $W { old } ; - $res .= sprintf "$HR\n", $W { ded } ; - $res .= sprintf "$HR\n", $W { bad } ; - $res .= "\n" ; - - $res .= "\n" ; - $res .= ' age → ' ; - - $res .= "|\n" ; - $res .= sprintf - ( '' - . '←  0 ≤ age ≤ %s  →' - . "\n" - , $MAX_h - 2, pr_interval ( $MAX_H ) - ) - ; - $res .= "|\n" ; - $res .= sprintf - ( '' - . ' %sh < %s ≤ %sh ' - . "\n" - , $W { old }, int($MAX_H/60/60) , BLD ( 'age' ), $MAX_o - ) ; - $res .= sprintf - ( '' - . ' old ' - . "\n" - , $W { ded } - ) ; - $res .= sprintf - ( '' - . ' bad ' - . "\n" - , $W { bad } - ) ; - $res .= "\n" ; - - my $FRMT = ' %s ' ; - - $res .= "\n" ; - $res .= sprintf "$FRMT\n", 1, NSS scalar keys %RES ; - $res .= "|\n" ; + ); + } + return "
\n" . TAB($res) . "
\n"; +} +sub gen_histogram { + my $MAX_H = max_age1; + my $MAX_h = 1 + ( + ( 20 * 3600 <= $MAX_H and $MAX_H <= 36 * 3600 ) + ? int( $MAX_H / 3600 ) + : 25 + ); + my $MAX_O = max_age2; + my $MAX_o = int( $MAX_O / 3600 + 0.5 ); + my $H = 18; + my %W = ( 'old' => 1, 'ded' => 1, 'bad' => 1 ); + my %Wmx = ( 'old' => 5, 'ded' => 3, 'bad' => 3 ); + my %tab; + my %hst; + my $res; + for ( my $x = 0 ; $x < $MAX_h ; $x++ ) { $tab{$x} = 0; } + $tab{old} = 0; + $tab{ded} = 0; + $tab{bad} = 0; + for my $url ( keys %RES ) { + my $time = $RES{$url}[0]; + if ( $time =~ /^\d+$/ ) { + my $s = $^T - $time; + my $hr = int( $s / $MAX_H * ( $MAX_h - 1 ) + 0.5 ); + if ( $s <= $MAX_H ) { $tab{$hr}++; } + elsif ( $s <= $MAX_O ) { $tab{old}++; } + else { $tab{ded}++; } + } + else { $tab{bad}++; } + } + my $max = 0; + for ( grep !exists $Wmx{$_}, keys %tab ) { + $max = $tab{$_} if $tab{$_} > $max; + } + my %bad; + for my $aux ( keys %Wmx ) { + $bad{$aux} = $tab{$aux}; + if ( $bad{$aux} > $max ) { + $W{$aux} = $Wmx{$aux}; + my $d = int( $bad{$aux} / $W{$aux} ); + for ( my $i = 1 ; $i < $W{$aux} ; $i++ ) { + $tab{ $aux . $i } = $d; + if ( $bad{$aux} % $Wmx{$aux} > $i ) { + $tab{ $aux . $i }++; + $tab{$aux}--; + } + } + $tab{$aux} -= ( $W{$aux} - 1 ) * $d; + $max = $tab{$aux} if $max < $tab{$aux}; + } + } + # if ( $opt{v} ) + # { for my $hr ( keys %tab ) + # { printf "tab '%s' = '%s'\n", $hr, $tab { $hr } ; } + # } + return 'nothing yet' unless $max; + $H = $max if 8 <= $max and $max <= 26; + for ( keys %tab ) { $hst{$_} = int( $H * $tab{$_} / $max + 0.5 ); } + my @keys = sort { $a <=> $b } grep /^\d+$/, keys %hst; + my $tab_hr = 0; + for my $hr (@keys) { $tab_hr += $tab{$hr}; } + push @keys, grep ( m/^old/, sort keys %tab ), + grep ( m/^ded/, sort keys %tab ), grep ( m/^bad/, sort keys %tab ); + for ( my $h = $H ; $h > 0 ; $h-- ) { + $res .= "\n"; + $res .= sprintf "↑\n" + if $h == $H; + $res .= sprintf '%s' . "\n", $H - 6, + NSS($max) + if $h == $H - 3; + $res .= sprintf "↓\n" + if $h == 3; + for my $x (@keys) { + $res .= sprintf "%s\n", + ( + ( $hst{$x} >= $h ) + ? img_sf( + $x =~ /^\d+$/ + ? 's' + : ( $x =~ /^old/ ? 'b' : ( $x =~ /^ded/ ? 'f' : 'z' ) ) + ) + : ( + ( $h == 1 and $hst{$x} == 0 ) + ? sprintf( '', + $CNF{icons} ) + : '' + ) + ); + } + $res .= "\n"; + } + my $HR = '
'; + $res .= "\n"; + $res .= sprintf "$HR\n", 1; + $res .= sprintf "$HR\n", $MAX_h; + $res .= sprintf "$HR\n", $W{old}; + $res .= sprintf "$HR\n", $W{ded}; + $res .= sprintf "$HR\n", $W{bad}; + $res .= "\n"; + $res .= "\n"; + $res .= ' age → '; + $res .= "|\n"; + $res .= + sprintf( '' + . '←  0 ≤ age ≤ %s  →' + . "\n", + $MAX_h - 2, pr_interval($MAX_H) ); + $res .= "|\n"; + $res .= sprintf( + '' + . ' %sh < %s ≤ %sh ' + . "\n", + $W{old}, int( $MAX_H / 60 / 60 ), + BLD('age'), $MAX_o + ); + $res .= sprintf( + '' + . ' old ' + . "\n", + $W{ded} + ); + $res .= sprintf( + '' + . ' bad ' + . "\n", + $W{bad} + ); + $res .= "\n"; + my $FRMT = ' %s '; + $res .= "\n"; + $res .= sprintf "$FRMT\n", 1, NSS scalar keys %RES; + $res .= "|\n"; $res .= sprintf "$FRMT\n", $MAX_h - 2, NSS $tab_hr ; - $res .= "|\n" ; - $res .= sprintf "$FRMT\n", $W { old }, NSS $bad { old } ; - $res .= sprintf "$FRMT\n", $W { ded }, NSS $bad { ded } ; - $res .= sprintf "$FRMT\n", $W { bad }, NSS $bad { bad } ; - $res .= "\n" ; - - $res = "\n$res\n
\n" ; - $res = sprintf "%s
\n" - , "\n$res\n" ; - if ( $max == $H ) - { $res .= sprintf "
units %s %s %s %s represent one mirror site.\n" - , img_sf ( 's' ), img_sf ( 'f' ), img_sf ( 'b' ), img_sf ( 'z' ) ; - } - else - { $res .= sprintf - "
each %s %s %s %s unit represents %s mirror sites.\n" - , img_sf ( 's' ) , img_sf ( 'f' ), img_sf ( 'b' ) , img_sf ( 'z' ) - , sprintf ( "%.1f", $max / $H ) - } - return $res ; - } - -sub revdom { my $dom = shift ; join '.', reverse split /\./, $dom ; } - -sub by_type_site - { my $a_type = $a -> [ 0 ] ; - my $b_type = $b -> [ 0 ] ; - my $a_site = $a -> [ 2 ] ; - my $b_site = $b -> [ 2 ] ; - ( revdom $a_site ) cmp ( revdom $b_site ) - or - $a_type cmp $b_type - ; - } - -sub by_CCS { ( $CCS { $a } || $a ) cmp ( $CCS { $b } || $b ) ; } - -sub legend ; - -sub gen_page - { my $PPP = shift ; - my $TMP = "$PPP.tmp" ; - my %tab ; - my $refs ; - for my $url ( keys %LST ) - { my ( $type , $site, $reg ) = @{ $LST { $url } } ; - push @{ $tab { $reg } }, [ $type, $url, $site ] ; - } - - my $bad = 0 ; my $old = 0 ; my $unr = 0 ; - my %stats ; - my @stats ; - my $ok = 0 ; - - for my $url ( keys %RES ) - { my ( $time, $stat, $vrfy ) = @{ $RES { $url } } ; - if ( $stat eq 'ok' ) { $ok ++ ; } else { $stats { $stat } ++ ; } - if ( $time eq 'undef' ) - { $bad ++ ; } - elsif ( 'f' eq age_code $time ) - { $old ++ ; } - if ( $vrfy eq 'undef' or aprx_lt $vrfy, $^T - max_vrfy ) - { $unr ++ ; } - } - - my $STAT = sprintf - "%d bad -- %d older than %s -- %s unreachable for more than %s" - , $bad - , $old - , pr_interval ( max_age2 ) - , $unr - , pr_interval ( max_vrfy ) - ; - - my $PROB = 'last probes : ' ; - push @stats, "$ok were ok" if $ok ; - for my $stat ( sort keys %stats ) - { push @stats, sprintf "%s had %s", $stats { $stat }, RED $stat ; } - $PROB .= join ', ', @stats ; - - for my $reg ( sort keys %tab ) - { $refs .= sprintf " %s \n" - , url "#$reg" - , "$reg" - ; - } - - my $COLS = 5 ; - my $LOGO = $CNF { project_logo } - ? url - ( $CNF { project_url } - , sprintf - ( '%s' - , $CNF { project_logo } - , $CNF { project_name } - ) - ) - : '' - ; - my $HTOP = $CNF{htm_top} ? $CNF{htm_top} . "\n" : '' ; - my $FOOT = $CNF{htm_foot} ? $CNF{htm_foot} . "\n" : '' ; - my $HEAD = $CNF{htm_head} ? $CNF{htm_head} . "\n" : '' ; - my $TITL = url $CNF{project_url}, $CNF{project_name} ; - my $EXPD = exp_date ; - - open PPP, ">$TMP" or Error "can't write $TMP ($!)" ; + $res .= "|\n"; + $res .= sprintf "$FRMT\n", $W{old}, NSS $bad {old}; + $res .= sprintf "$FRMT\n", $W{ded}, NSS $bad {ded}; + $res .= sprintf "$FRMT\n", $W{bad}, NSS $bad {bad}; + $res .= "\n"; + $res = "\n$res\n
\n"; + $res = sprintf "%s
\n", + "\n$res\n"; + if ( $max == $H ) { + $res .= sprintf "
units %s %s %s %s represent one mirror site.\n", + img_sf('s'), img_sf('f'), img_sf('b'), img_sf('z'); + } + else { + $res .= + sprintf "
each %s %s %s %s unit represents %s mirror sites.\n", + img_sf('s'), img_sf('f'), img_sf('b'), img_sf('z'), + sprintf( "%.1f", $max / $H ); + } + return $res; +} +sub revdom { my $dom = shift; join '.', reverse split /\./, $dom; } +sub by_type_site { + my $a_type = $a->[0]; + my $b_type = $b->[0]; + my $a_site = $a->[2]; + my $b_site = $b->[2]; + ( revdom $a_site ) cmp( revdom $b_site ) + or $a_type cmp $b_type; +} +sub by_CCS { ( $CCS{$a} || $a ) cmp( $CCS{$b} || $b ); } +sub legend; +sub gen_page { + my $PPP = shift; + my $TMP = "$PPP.tmp"; + my %tab; + my $refs; + for my $url ( keys %LST ) { + my ( $type, $site, $reg ) = @{ $LST{$url} }; + push @{ $tab{$reg} }, [ $type, $url, $site ]; + } + my $bad = 0; + my $old = 0; + my $unr = 0; + my %stats; + my @stats; + my $ok = 0; + for my $url ( keys %RES ) { + my ( $time, $stat, $vrfy ) = @{ $RES{$url} }; + if ( $stat eq 'ok' ) { $ok++; } + else { $stats{$stat}++; } + if ( $time eq 'undef' ) { $bad++; } + elsif ( 'f' eq age_code $time ) { $old++; } + if ( $vrfy eq 'undef' or aprx_lt $vrfy, $^T - max_vrfy ) { $unr++; } + } + my $STAT = + sprintf "%d bad -- %d older than %s -- %s unreachable for more than %s", + $bad, $old, pr_interval(max_age2), $unr, pr_interval(max_vrfy); + my $PROB = 'last probes : '; + push @stats, "$ok were ok" if $ok; + for my $stat ( sort keys %stats ) { + push @stats, sprintf "%s had %s", $stats{$stat}, RED $stat ; + } + $PROB .= join ', ', @stats; + for my $reg ( sort keys %tab ) { + $refs .= sprintf " %s \n", url "#$reg", + "$reg"; + } + my $COLS = 5; + my $LOGO = + $CNF{project_logo} + ? url( + $CNF{project_url}, + sprintf( + '%s', + $CNF{project_logo}, $CNF{project_name} + ) + ) + : ''; + my $HTOP = $CNF{htm_top} ? $CNF{htm_top} . "\n" : ''; + my $FOOT = $CNF{htm_foot} ? $CNF{htm_foot} . "\n" : ''; + my $HEAD = $CNF{htm_head} ? $CNF{htm_head} . "\n" : ''; + my $TITL = url $CNF{project_url}, $CNF{project_name}; + my $EXPD = exp_date; + open PPP, ">$TMP" or Error "can't write $TMP ($!)"; print PPP '' ; - print PPP "\n" ; - print PPP "\n" ; - print PPP "the status of $CNF{project_name} mirrors\n" ; + . ' Transitional//EN"' . '>'; + print PPP "\n"; + print PPP "\n"; + print PPP "the status of $CNF{project_name} mirrors\n"; printf PPP "%s\n", '' ; - print PPP "\n" ; - print PPP "\n" ; - print PPP $HEAD if $HEAD ; - print PPP "\n" ; - print PPP "\n" ; - print PPP $LOGO ; - - print PPP "

the status of $TITL mirrors

\n" ; - - print PPP "\n" ; - printf PPP "\n" - , scalar gmtime $^T ; - printf PPP "\n" - , scalar gmtime ( $opt{get} ? $^T : ( stat $CNF { state } ) [9] ) ; - print PPP "
date:%s (GMT)
last check:%s (GMT)
\n" ; - - printf PPP "

%s

\n", $HTOP if $HTOP ; - - if ( $CNF { put_histo } eq 'top' ) - { print PPP "

age histogram

\n" ; - - print PPP "
\n" ; - print PPP gen_histogram ; - print PPP "
\n" ; - } - - print PPP "

regions

\n" ; - - print PPP "
\n" ; - print PPP "
\n" ; - printf PPP "%s\n", $refs ; - print PPP "
\n" ; - print PPP "
\n" ; - - print PPP "

report

\n" ; - - my $attr1 = "COLSPAN=$COLS BGCOLOR=\"LIME\"" ; - my $attr2 = 'BGCOLOR="AQUA"' ; - - print PPP "
\n" ; - print PPP "\n" ; - printf PPP "\n" - , scalar keys %LST - , scalar keys %tab - ; - printf PPP "\n", $STAT ; - printf PPP "\n", $PROB ; - print PPP "\n" ; - printf PPP " \n" - , $CNF { project_name } ; - printf PPP " \n", 'type' ; - printf PPP " \n", 'mirror age,
daily stats' ; - printf PPP " \n", 'last probe,
probe stats' ; - printf PPP " \n", 'last stat' ; - print PPP "\n" ; - for my $reg ( sort by_CCS keys %tab ) - { my $itms = $tab { $reg } ; - - my $ccs = exists $CCS { $reg } ? $CCS { $reg } : $reg ; + . 'CONTENT="text/html; charset=ISO-8859-1">'; + print PPP "\n"; + print PPP "\n"; + print PPP $HEAD if $HEAD; + print PPP "\n"; + print PPP "\n"; + print PPP $LOGO; + print PPP "

the status of $TITL mirrors

\n"; + print PPP "
%d sites in %d regions
%s
%s
%s site -- home%s%s%s%s
\n"; + printf PPP "\n", + scalar gmtime $^T; + printf PPP "\n", + scalar gmtime( $opt{get} ? $^T : ( stat $CNF{state} )[9] ); + print PPP "
date:%s (GMT)
last check:%s (GMT)
\n"; + printf PPP "

%s

\n", $HTOP if $HTOP; + if ( $CNF{put_histo} eq 'top' ) { + print PPP "

age histogram

\n"; + print PPP "
\n"; + print PPP gen_histogram; + print PPP "
\n"; + } + print PPP "

regions

\n"; + print PPP "
\n"; + print PPP "
\n"; + printf PPP "%s\n", $refs; + print PPP "
\n"; + print PPP "
\n"; + print PPP "

report

\n"; + my $attr1 = "COLSPAN=$COLS BGCOLOR=\"LIME\""; + my $attr2 = 'BGCOLOR="AQUA"'; + print PPP "
\n"; + print PPP "\n"; + printf PPP "\n", + scalar keys %LST, scalar keys %tab; + printf PPP "\n", $STAT; + printf PPP "\n", $PROB; + print PPP "\n"; + printf PPP " \n", $CNF{project_name}; + printf PPP " \n", 'type'; + printf PPP " \n", 'mirror age,
daily stats'; + printf PPP " \n", 'last probe,
probe stats'; + printf PPP " \n", 'last stat'; + print PPP "\n"; + for my $reg ( sort by_CCS keys %tab ) { + my $itms = $tab{$reg}; + my $ccs = exists $CCS{$reg} ? $CCS{$reg} : $reg; $ccs = nam $reg, - ( scalar @{ $itms } > 6 - ? sprintf "%s  -  %d sites" - , $ccs, scalar @{ $itms } - : $ccs - ) ; - - my $attr3 = "COLSPAN=$COLS BGCOLOR=\"YELLOW\"" ; - printf PPP "\n" ; - - for my $itm ( sort by_type_site @{ $itms } ) - { my ( $type, $url, $site ) = @{ $itm } ; - my ( $time, $stat, $hstp, $hsts, $vrfy ) ; - my ( $pr_time, $pr_last, $pr_hstp, $pr_hsts ) ; - - print PPP "\n" ; - printf PPP - " \n" - . " \n" - , url ( $url , $site ) - , url ( home ( $url ), '@' ) - , $type - ; - - if ( exists $RES { $url } ) - { ( $time, $stat, $vrfy, $hstp, $hsts ) = @{ $RES { $url } } ; - $pr_time = $time =~ /^\d+$/ - ? diff $time, $^T - max_age2 : ' ' ; - $pr_last = $vrfy =~ /^\d+$/ - ? diff $vrfy, $^T - max_vrfy : ' ' ; + ( + scalar @{$itms} > 6 + ? sprintf "%s  -  %d sites", + $ccs, + scalar @{$itms} + : $ccs + ); + my $attr3 = "COLSPAN=$COLS BGCOLOR=\"YELLOW\""; + printf PPP "\n"; + for my $itm ( sort by_type_site @{$itms} ) { + my ( $type, $url, $site ) = @{$itm}; + my ( $time, $stat, $hstp, $hsts, $vrfy ); + my ( $pr_time, $pr_last, $pr_hstp, $pr_hsts ); + print PPP "\n"; + printf PPP " \n" + . " \n", url( $url, $site ), url( home($url), '@' ), + $type; + if ( exists $RES{$url} ) { + ( $time, $stat, $vrfy, $hstp, $hsts ) = @{ $RES{$url} }; + $pr_time = $time =~ /^\d+$/ + ? diff $time, $^T - max_age2 + : ' '; + $pr_last = $vrfy =~ /^\d+$/ + ? diff $vrfy, $^T - max_vrfy + : ' '; $pr_hstp = show_hist $hstp ; - $pr_hsts = show_hist_age $hsts, $time ; - - } - else - { ( $pr_time, $pr_last, $pr_hstp, $pr_hsts, $stat ) = - ( ' ', ' ', '', '', ' ' ) ; - } - - $stat = RED $stat if $stat ne 'ok' ; - printf PPP " \n" - , $pr_time, $pr_hsts ; - printf PPP " \n" - , $pr_last, $pr_hstp ; - printf PPP " \n", $stat ; - print PPP "\n" ; - } - } - print PPP "
%d sites in %d regions
%s
%s
%s site -- home%s%s%s%s
$ccs
%s  %s%s
$ccs
%s  %s%s%s
%s
%s
%s
%s
\n" ; - print PPP "
\n" ; - - if ( $CNF { put_histo } eq 'bottom' ) - { print PPP "

age histogram

\n" ; - - print PPP "
\n" ; - print PPP gen_histogram ; - print PPP "
\n" ; - } - - print PPP legend ; - - print PPP "

probe results

\n" ; - print PPP gen_histogram_probes ; - - print PPP "

software

\n" ; - - print PPP "
\n" ; - my $MIR_IMG = sprintf - 'mirmon' , $CNF { icons } ; - print PPP sprintf "\n" - , 'http://www.cs.uu.nl/people/henkp/mirmon/', $MIR_IMG ; - print PPP "\n" ; - print PPP "
%s$VER
\n" ; - print PPP $FOOT ; - print PPP "\n" ; - print PPP "" ; - - if ( print PPP "\n" ) - { close PPP ; - if ( -z $TMP ) - { Warn "wrote empty html file; keeping previous version" ; } - else - { rename $TMP, $PPP or Error "can't rename $TMP, $PPP ($!)" ; } - } - else - { Error "can't print to $TMP ($!)" ; } - } - -sub legend - { return <%s
%s\n", $pr_time, + $pr_hsts; + printf PPP " %s
%s\n", $pr_last, + $pr_hstp; + printf PPP " %s\n", $stat; + print PPP "\n"; + } + } + print PPP "\n"; + print PPP "
\n"; + if ( $CNF{put_histo} eq 'bottom' ) { + print PPP "

age histogram

\n"; + print PPP "
\n"; + print PPP gen_histogram; + print PPP "
\n"; + } + print PPP legend; + print PPP "

probe results

\n"; + print PPP gen_histogram_probes; + print PPP "

software

\n"; + print PPP "
\n"; + my $MIR_IMG = sprintf 'mirmon', + $CNF{icons}; + print PPP sprintf "\n", + 'http://www.cs.uu.nl/people/henkp/mirmon/', $MIR_IMG; + print PPP "\n"; + print PPP "
%s$VER
\n"; + print PPP $FOOT; + print PPP "\n"; + print PPP ""; + if ( print PPP "\n" ) { + close PPP; + if ( -z $TMP ) { + Warn "wrote empty html file; keeping previous version"; + } + else { rename $TMP, $PPP or Error "can't rename $TMP, $PPP ($!)"; } + } + else { Error "can't print to $TMP ($!)"; } +} +sub legend { + return <legend -

project site -- home

-
project site is an url. The href is the href for the site in the list of mirrors, @@ -993,16 +857,12 @@ pointing to the document root of the site. This pointer is useful if the project site url is invalid, possibly because the mirror site moved the archive.
-

type

-
Indicates the type (ftp or http) of the project site and home urls.
-

mirror age, daily stats

-
The mirror age is based upon the last successful probe.

@@ -1031,7 +891,6 @@ configuration parameters : fresh - 0 @{[$CNF{min_sync}]} + @{[$CNF{max_poll}]} @@ -1040,7 +899,6 @@ configuration parameters : oldish - @{[$CNF{min_sync}]} + @{[$CNF{max_poll}]} @@ -1050,7 +908,6 @@ configuration parameters : old - @{[$CNF{max_sync}]} + @{[$CNF{max_poll}]} ∞ @@ -1065,9 +922,7 @@ configuration parameters :

-

last probe, probe stats

-
Last probe indicates when the last successful probe was made. Probe stats gives the probe history (right is recent). @@ -1075,161 +930,126 @@ A probe is either a success or a failure.
-

last stat

-
Last stat gives the status of the last probe.
- LEGENDA - } - -sub start_date - { my $url = shift ; - my $CMD = shift ; - my $TIMEOUT = $CNF { timeout } ; - my $src = $HREF { lc site $url } || $url ; - $CMD =~ s/%TIMEOUT%/$TIMEOUT/g ; - $CMD =~ s/%URL%/$src/g ; - printf "*** SUBSTITUTE site %s\n+ url %s\n+ %s\n", - site($url), $HREF { lc site $url }, $CMD - if $HREF { lc site $url } and $opt{v} ; - my $WGT = new IO::Pipe ; - my $res = $WGT -> reader ( split ' ', $CMD ) ; - if ( $res ) - { $WGT -> blocking ( 0 ) ; - $GET -> add ( $WGT ) ; - $URL { $WGT } = $url ; - } - else - { err $url, 'no pipe' ; } - } - -sub get_date - { my $WGT = shift ; - my $url = $URL { $WGT } ; - my $time = undef ; - - $WGT -> blocking ( 1 ) ; - unless ( $WGT -> eof () ) { $time = $WGT -> getline () ; } - $GET -> remove ( $WGT ) ; - $WGT -> flush ; - $WGT -> close ; - - return err $url, 'no time' unless defined $time ; - return err $url, "empty" if $time =~ /^\s*$/ ; - - $time = ( split ' ', $time ) [ 0 ] ; - - if ( $time !~ /^\d+$/ ) - { $time = htmlquote $time ; - $time = substr ( $time, 0, 15 ) . '..' if length $time > 15 ; - err $url, "'$time'" ; - } - else - { res $url, $time, 'ok' ; } - } - -sub get_dates - { my $CMD = shift ; - my @QUE ; - my $PAR = $CNF { max_probes } ; - my $cnt_LST = scalar keys %LST ; - for my $url ( sort keys %LST ) - { if ( $opt{get} eq 'all' or ! exists $OLD { $url } ) - { push @QUE, $url ; } - elsif ( $opt{get} eq 'update' ) - { my $stat = $OLD { $url } [ 1 ] ; - my $vrfy = $OLD { $url } [ 2 ] ; - my $lprb = $OLD { $url } [ 5 ] ; - if ( ( $lprb eq 'undef' - or aprx_le $lprb, $^T - tim_to_s $CNF { min_poll } - ) - and ( $stat ne 'ok' - or aprx_le $vrfy, $^T - tim_to_s $CNF { max_poll } - ) - ) - { push @QUE, $url ; } - elsif ( $CNF { randomize } and 0 == int rand $cnt_LST ) - { push @QUE, $url ; } - else - { $RES { $url } = $OLD { $url } ; } - } - else - { Error "unknown opt_get '$opt{get}'" ; } - } - - while ( @QUE ) - { while ( $GET -> count () < $PAR and @QUE ) - { my $url = shift @QUE ; - if ( gethost site $url ) - { start_date $url, $CMD ; } - else - { err $url, 'site not found' ; } - } - - my @can_read = $GET -> can_read ( 0 ) ; - - printf "que %d, get %d, can %d\n", - scalar @QUE, $GET -> count (), scalar @can_read - if $opt{v} ; - - for my $can_read ( @can_read ) - { get_date $can_read ; } - - sleep 1 ; - } - - my $stop = time + $CNF { timeout } + 10 ; - - while ( $GET -> count () and time < $stop ) - { sleep 1 ; - - my @can_read = $GET -> can_read ( 0 ) ; - - printf "wait %2d, get %d, can %d\n", - $stop - scalar time, $GET -> count (), scalar @can_read - if $opt{v} ; - - for my $can_read ( @can_read ) - { get_date $can_read ; } - } - - for my $WGT ( $GET -> handles () ) - { my $url = $URL { $WGT } ; - err $url, 'hangs' ; - } - } - -get_conf_opt ; -get_ccs $CNF { countries } ; -get_state $CNF { state } ; -get_list $CNF { mirror_list } ; - -if ( $opt{get} ) - { get_dates $CNF { probe } ; - put_state $CNF { state } ; - } -else - { %RES = %OLD } - -gen_page $CNF { web_page } ; - +} +sub start_date { + my $url = shift; + my $CMD = shift; + my $TIMEOUT = $CNF{timeout}; + my $src = $HREF{ lc site $url } || $url; + $CMD =~ s/%TIMEOUT%/$TIMEOUT/g; + $CMD =~ s/%URL%/$src/g; + printf "*** SUBSTITUTE site %s\n+ url %s\n+ %s\n", site($url), + $HREF{ lc site $url }, $CMD + if $HREF{ lc site $url } and $opt{v}; + my $WGT = new IO::Pipe; + my $res = $WGT->reader( split ' ', $CMD ); + if ($res) { + $WGT->blocking(0); + $GET->add($WGT); + $URL{$WGT} = $url; + } + else { err $url, 'no pipe'; } +} +sub get_date { + my $WGT = shift; + my $url = $URL{$WGT}; + my $time = undef; + $WGT->blocking(1); + unless ( $WGT->eof() ) { $time = $WGT->getline(); } + $GET->remove($WGT); + $WGT->flush; + $WGT->close; + return err $url, 'no time' unless defined $time; + return err $url, "empty" if $time =~ /^\s*$/; + $time = ( split ' ', $time )[0]; + if ( $time !~ /^\d+$/ ) { + $time = htmlquote $time ; + $time = substr( $time, 0, 15 ) . '..' if length $time > 15; + err $url, "'$time'"; + } + else { res $url, $time, 'ok'; } +} +sub get_dates { + my $CMD = shift; + my @QUE; + my $PAR = $CNF{max_probes}; + my $cnt_LST = scalar keys %LST; + for my $url ( sort keys %LST ) { + if ( $opt{get} eq 'all' or !exists $OLD{$url} ) { push @QUE, $url; } + elsif ( $opt{get} eq 'update' ) { + my $stat = $OLD{$url}[1]; + my $vrfy = $OLD{$url}[2]; + my $lprb = $OLD{$url}[5]; + if ( + ( + $lprb eq 'undef' + or aprx_le $lprb, + $^T - tim_to_s $CNF {min_poll} + ) + and ( + $stat ne 'ok' or aprx_le $vrfy, + $^T - tim_to_s $CNF {max_poll} + ) + ) + { + push @QUE, $url; + } + elsif ( $CNF{randomize} and 0 == int rand $cnt_LST ) { + push @QUE, $url; + } + else { $RES{$url} = $OLD{$url}; } + } + else { Error "unknown opt_get '$opt{get}'"; } + } + while (@QUE) { + while ( $GET->count() < $PAR and @QUE ) { + my $url = shift @QUE; + if ( gethost site $url ) { start_date $url, $CMD; } + else { err $url, 'site not found'; } + } + my @can_read = $GET->can_read(0); + printf "que %d, get %d, can %d\n", scalar @QUE, $GET->count(), + scalar @can_read + if $opt{v}; + for my $can_read (@can_read) { get_date $can_read ; } + sleep 1; + } + my $stop = time + $CNF{timeout} + 10; + while ( $GET->count() and time < $stop ) { + sleep 1; + my @can_read = $GET->can_read(0); + printf "wait %2d, get %d, can %d\n", $stop - scalar time, $GET->count(), + scalar @can_read + if $opt{v}; + for my $can_read (@can_read) { get_date $can_read ; } + } + for my $WGT ( $GET->handles() ) { + my $url = $URL{$WGT}; + err $url, 'hangs'; + } +} +get_conf_opt; +get_ccs $CNF {countries}; +get_state $CNF {state}; +get_list $CNF {mirror_list}; +if ( $opt{get} ) { + get_dates $CNF {probe}; + put_state $CNF {state}; +} +else { %RES = %OLD } +gen_page $CNF {web_page}; __END__ - =pod - =head1 NAME - mirmon - monitor the state of mirrors - =head1 SYNOPSIS - mirmon [ -v ] [ -q ] [ -t timeout ] [ -get opt ] [ -c conf ] - =head1 OPTIONS - option v : be verbose option q : be quiet option t : set timeout [ default 300 ] ; @@ -1241,46 +1061,33 @@ __END__ Documentation : the program contains 'pod' style documentation. Extract the doc with 'pod2text mirmon' or 'pod2html mirmon OUT', etc. ------------------------------------------------------------------- - =head1 USAGE - The program is intended to be run by cron every hour. - 42 * * * * perl /path/to/mirmon -q -get update - It quietly probes a subset of the sites in a given list, writes the results in the 'state' file and generates a web page with the results. The subset contains the sites that are new, bad and/or not probed for a specified time. - When no 'get' option is specified, the program just generates a new web page from the last known state. - The program checks the mirrors by running a (user specified) program on a pipe. A (user specified) number of probes is run in parallel using nonblocking IO. When something can be read from the pipe, it switches the pipe to blocking IO and reads one line from the pipe. Then it flushes and closes the pipe. No attempt is made to kill the probe. - The probe should return something that looks like "1043625600\n", that is, a timestamp followed by a newline. The exit status of the probe is ignored. - =head1 CONFIG FILE - =head2 location - A config file can be specified with the -c option. If -c is not used, the program looks for a config file in -- ./mirmon.conf -- $HOME/.mirmon.conf -- /etc/mirmon.conf - =head2 syntax - A config file looks like this : - +-------------------------------------------------- |# lines that start with '#' are comment |# blank lines are ignored too @@ -1311,252 +1118,159 @@ __END__ |. part2 |. part3 +-------------------------------------------------- - =head1 CONFIG FILE : required entries - =head2 project_name - Specify a short plaintext name for the project. - project_name Apache project_name CTAN - =head2 project_url - Specify an url pointing to the 'home' of the project. - project_url http://www.apache.org/ - =head2 mirror_list - Specify the file containing the mirrors to probe. Two formats are supported : - -- plain : lines like - us http://www.tux.org/ nl http://apache.cs.uu.nl/dist/ - -- apache : lines like those in the apache mirrors.list - ftp us ftp://ftp.tux.org/pub/net/apache/dist/ user@tux.org http nl http://apache.cs.uu.nl/dist/ user@cs.uu.nl - Specify the required format with 'list_style' (see below). The default style is 'plain'. - If the url part of a line doesn't end in a slash ('/'), mirmon adds a slash and issues a warning unless it is in quiet mode. - =head2 web_page - Specify where the html report page is written. - =head2 icons - Specify the directory where the icons can be found. - =head2 probe - Specify the program+args to probe the mirrors. Example: - probe /sw/bin/wget -q -O - -T %TIMEOUT% -t 1 %URL%TIME - Before the program is started, %TIMEOUT% and %URL% are substituted with the proper timeout and url values. - Here it is assumed that each hour the root server writes a timestamp in /path/to/archive/TIME, for instance with a crontab entry like - 42 * * * * perl -e 'printf "%s\n", time' > /path/to/archive/TIME - Mirmon reads one line of output from the probe and interprets the first word on that line as a timestamp ; for example : - 1043625600 1043625600 Mon Jan 27 00:00:00 2003 1043625600 www.apache.org Mon Jan 27 00:00:00 2003 - =head2 state - Specify where the file containing the state is written. The program reads this file on startup and writes the file when mirrors are probed (-get is specified). - =head2 countries - Specify the file containing the country codes; The file should contain lines like - us - united states nl - netherlands - The mirmon package contains a recent ISO list. - =head1 CONFIG FILE : optional entries - =head2 max_probes - Optionally specify the number of parallel probes (default 25). - =head2 timeout - Optionally specify the timeout for the probes (default 300). After the last probe is started, the program waits for + 10 seconds, cleans up and exits. - =head2 project_logo - Optionally specify (the SRC of the IMG of) a logo to be placed top right on the page. - project_logo /icons/apache.gif project_logo http://www.apache.org/icons/... - =head2 htm_head - Optionally specify some HTML to be placed before . - htm_head - =head2 htm_top - Optionally specify some HTML to be placed near the top of the page. The supplied text is placed between

and

. - htm_top testing 1, 2, 3 - =head2 htm_foot - Optionally specify HTML to be placed near the bottom of the page. - htm_foot

- =head2 put_histo top|bottom|nowhere - Optionally specify where the age histogram must be placed. The default is 'top'. - =head2 min_poll