ÿØÿà JFIF    ÿÛ „ !.%+&8&+/1555$;@;4?.451 4,$,44444444444414444444444444444444444444444444444444ÿÀ  á á" ÿÄ     ÿÄ ?    !1AQaq"2‘¡±ÁðBRbrÑá#‚’¢²3S CñÿÄ   ÿÄ !    !1QAa‘2ÿÚ   ? 5˜Z¯V¦cø)›t/? z¨±>Õ5€¶‹Á¤·¼z¼Ü¬+ñ®v¤¨_ˆR­BFn©—˜ý®ç̝P8gýt·ÉSTŦˆìät?þé¼íìN/Þa)ì–í6ô… Ï¿øÃj´¿KÇü]ÿ ªô¹-eKànëÕHTx}ýSÜ›ÿ ”7Ø×&µ<¦  ¥ÑO¶[Ù¯ä¨ÞÃÿ PZ-¬;#õ|•oaÿ ©CìÞz3˜öː/¤­ñTûIØ}š^ mÓ%ªxˆ¥ÉŸu=Z+ISe¿45™¼u;ú&WØ÷€æßQ™®{|íx*TC“#ZŠìZ§²‹ 6pv…³¿¡äª*áZÐ%ÒOáˆo"x«OHk w±æ+¬V(kMúŸ5Vö«$ ÁrÏbàb57/luR ¸ÑÛj Òµì`Мq­û žICÀÊ•©4€Âcà¨Ï€O´<èÐ:›ù(Ë^L8þ‘ÍÌ#¸Ð_Ì©ÙK(Öz 4¬û+¸;ü’V’84‘¬ÃŽ:[â‡ÔÌáõp¢~§ªlæ£ö{®G>J¼"°‡7¯ÆÉèßû ‹É‹§ÁòÃýâßî ^ƾÙõ‹×óH#«LP½ïX=xÑÍ$|W?•~• îëÔ©ª‹ {ÝT…Kÿ ”hûâá)J*ö˜–ÔU;iÇ€/ ÆþjóZ\ýwØ=Ìm ºèËL9 ýèÆð/¨’¥öo=nË.%Îì ŽÕ¯È|{Oj²ƒE6e/ßdÄõ²Ìâ1O®ò×TsəԸhOMýíMˆ¿¼H˜l²,7Â¥#MF/Úf°Ö½± ¸–dr‹NýÊ íjqx{œÉ ä-È ¦ øÄër¨q°ð †nцýÑÄÆ’mä…n<0È™;ÁÝá¯ÁZƒ7FÀmì­ É&9ˆîéi¶ùN§Y• ÃZãAâ?•‡©‰ , ó¾IŸŠc1 4â&y­&pŠ­6;M À 0¹qç»p.á …ŸÅáK@%6·y6ƒ‰3?”úºŽ‰éX5ªPT §µ!=Mž«Ú½‹ÅgÂSâÉaþÓoö–¯ÁÔìR>5éÿ üs¶ÆUcÌ kÇR ]ÿ ù¬¼«VŽ;Â|‡~¢¦”ÏŰæ {L™Õ°Óv¹ò¸írޡעCÃ!íVÕ {¶»sŒNPg/ "uÕbkm²“$ďå¿é¹§°½æz¯6 †s¿!s–wÚÝ“™Œ °.ûj>·+™Òa…©Œ&rÝÎtÛë긪Ît’LAVp%c Úý[ÄzJ¾ÇàXXç@˜ó<êL]·T˜¾¥1Ó©V‡g´æ½¦Ý@¹óø!_@´ÞâSÁ —S3™•& ]@JHÚý©ZŽ €×æÔr»Áf!‡yÞ4Mv*èÓã_{‘åóUuљØ«Oïé*®EvÑ Œ÷‡U \"㪒ÍK+À 4“M¡ï:0¥5í!'<@î´”>Ç»&Z–ïCCV˜Ì5Šo&îhè.žû |ÓK©h$s6KìŒëã)¹hI¦GïOåóI;ììü#É$Š0…Ææ¥TØ.5­¾gn´ “ÂÖ\:hœ89G)J@„}œ:’Ò{/Š"¦_Æ×7Æ3VÇŠÊa]ÚŒÙ€Ä–=®uÁßâACZƒ§§£ Qnâ:«,×{tyø¬iÛcœÜÄ€H½ÄÍCk´÷šß .W'b¤Íåh]÷€=,Žv×cÚEÚHXJX¶îo¨FÒtèöŸ>ªª6[J®Fµ£sGÁeqõfe\íjÒÐïÄÐGˆe1Ø‹.Ø”‘Ëuø Y­ˆÜ ŽG|zùªüMpDnQWÄ”%JŠ™)â*p@Örš«ÕT2Ð%ˆG#ª„ ·¤!°ŸOTÂT¸aÚ%4&h™LµšØüÐ.F¿²ÐÞ_Ç‚¾ÅÃaÜ÷09Æ q€öy˜v‡85õN÷]¬äѼóS{°_MެúÔ#°Ç¸0åÞè2ëôPcvÆw9®ií1Ä8F™˜à‰´+‰Ik1òÝ7“Ñ×ÒsÝ\x‚h`ÞÑ`ó"|µEcý£n˜h`}GÞ !±ù²Ápü²ß6 0ïi󜵩SÈÇ7˜-ÕURO˜¦´f$ªž-Í6(œ}<„ éc øs]ŽŽ„*—¾ ìdŽ„)méª\¿êÎIg¾ØÞ~I#C/¼¼´EÁÈŽi8“©õådô·>euä ƒ'Ê×लR1ÉJE1ÐAát`t;ÇР%Ý<‡¥„ÍÆ`×Oyó)õiI€ñQaŸ4Ûù\áàaÃÔ¹HÃu¹*k€¦<„e S‡&õÏ B!ŽhüÞ`yj}mªf×\¿ Ç~æ­9‡û\՞Ǖg²1Žû5V7 !àöšm° c`ܬøÇìµÒ'P"?…´Ö,"§^•õލsÔ)6˜sæéÍR¼ ò|Sl”‹7 nPW Gòú÷½§O¯‡„l¡kSÞŒr½PÊ@æ¢pŽ-mÿ #Ÿ˜Àº¶Áä¦;ïÔæ$1££`“Õ>„—·ž)ßð³ñ#Ï Ô$¶œ‰ÊE‹À;÷º ¯«P:Ñ”8–IÊtpÞ3ª“>ê“þës4ò2OÏÕ­±zô†Õ§‰.÷ä¸;¿˜“'œ›žª}«Œ{ª±Ì 9ÔóÞÕ‡0 $íWV3Üì¬ —@kÝ4@¿r¼±½¬™›?øØæ´'Áé®CË3-g$˜ö‡×auÚi´Žp/êÛ æF›Ú2v‹ã¿¿,nB1̨ƃqÞa5͝@&Æû“él÷ \C²½UÍc ¯k×¢U ÖéQå™—-r wô ÞÏ<Ò=&=ÿ Ôê Òêˈt,i—;LîÜ á¸*ÚÃ1$êL•LÍ <É)ýÐà’ ;F™{ƒ™˜€&'}‚ãÄK`¡ÞT@I;®žZóè‚s’7®°›+§O­Åq©é»²9<Ô J ¼9O’HL»Ùïì¸rk¼Ž_ý‘TŸu[²ßÚŒ·ü÷B%¯E ŸÔX5êO´ Ç•€’I0 ÉJX` ñ¹õ%;µŸD‘«´€àwÒ™U ûئžÖö\×®×´8 ½‡ºÐÆÓ§?Àkmœ=;d5*@-ì0F Rªýš[Ü6âö̃ڸr*KA9· u*µæ£?U¸Âêí†8@¦X4 e-ò„0s{ HâUpU?¼mñRa°®a%Ð'tÉ×’\¾ÊÉ]t›h>·(Ë@R¼¡Ãt h}’O÷au<+nT…Ö…MӐ??Óe95 q>í/;&JSû °¯ÊéÞ øƒ*Ã2½Ài&:nôUl=¾¿5eˆ3”ñc|Ú2V”>„»&eE;«ÚäC p¢Û úy 9š[ŒÌx¼擼A&DåÒ¯ˆ¤ÀÌ;"˜ ÏQä¸åhÊ}Ûq«Û0WžÒ|»€ø®öCm5•\ÇÀ§Pe3£]0ÃàLDÉ‰1øªxjgwT‚÷¿LΨK‹›ùs—xˆÜ±µ kæ¸f‰‰ÜGk/LÛØ6d9ò¶ùA{ƒA3š/¬D¬khÓk‰`˜"㯒r¿±Óã jx‡°e}<Ñø\3y:'À•/h½Í€Ç4~g ?Û(¼]v‘ªlKÎâ~?O‚W%{Ì:“'©úNq¾›úo(X’¥¯ˆ nFê{Ç€ü?º'ë ø‹ì Þ09ŒÌç9Æ —ËC`j@ÓÄ(+a‹un¸#ÂꟋ{K`‘ÑÍÍ'à´»/Û,KW;Þ4²þð ï Nm|~fGÏ(…³Ã)«1ö­Õ ¥‡¨©ƒÃ™ü-s=à=U66Ï«Ýc蓦W¹íž®›nÔ%êÇìŒ<#Ü×84ån®Ð ÒåOC` ñânÑs‡¢ç 1õ%Îhì½Ã½® e:ݼUZo™`  ÅZŸŒÊ«ê1ÏÄo$q¹Þ€©ˆhÐÉä¯ñ[!…Ú˜àJ:x2$Íß&PåT£6ç— ‡Í*4Ýšçjÿ ‰É nófÐ ó(L5C•åÆ\rMÒ@ò }y-W}™üýVù—ú¢=Ù”c®‘< M ž ´Phr ¦©TD ‘ù.$´÷O‡‘V2Æò.=IUŒ=ž‡â¬i™aþÓåÙ?òUø'ØÖ•.~* šTŒ!•-×áºTâ®ä#õü'´ eýlYÅÓeÕKÂrT"CÚ@u!Óxƒ{š3€}1¿(r}%«nËamjÑ%ÑNEò v ˜à  σöK³,*º.àzù¨™Ó ÚçâU¦*¿ 9{%Ö¹ njûdaXöb) kÛÆ±ûÓ\°M7ˆÂ=û›ç¿Ã‚­V»Cg–8ÙêE- j)k$º`Ã-ùEýeBÆÇ]c¡°ñty&Òd0nõ'¡W+ƒ*|–øµFa\GQªEAÔp5\Ǽ·¼Ç8·õ -â§Ú[ ‡ uZeÖ 3}×d'+¹:ð+K†Û®s!Ï$úe€<Û”x)1»a­¡LC]¸µík…ÚàA»AYº{†ªS[¦5HÒ7ù --,ísòDØ€èk ÞÀîÜ ò@â( ËNˆë›4ô½•/¦o‡€Û7 ê•ÆêòðÜy'Án½µ á˜ݦ ndeo…[ì¶Ê,¥R³Ä=À±—–ß;£™´ñSâ*g§”ïaið‘Jå~™ÓÞ ß³Õ¢»8x埒²52>AÊb&-÷\7´éÄù€T˜,w;3{ï˜k…à¹ÄqÀ«œ{€\ ˆ¾[´¨јr &Úé„Ívˆ±8†¿]|¬ņ4I×pÞS1ÈÖz‰#Ìv‡G!YNògñ:màTz¢Ý1ô©^O=~ë|5Bã™ç•¼µõ•bÆ@úÕS¬ÈŒ#¬zünrŸ û” Z²•èðV"ÁHÚý©wÝ €7¼Ìu1hÑa3Éä û f$o¿É ™Ú›ÝçnpÒ3äÌ3†Í§,Äï]$‰/pê †«À¼¸e9­Æê_C]žƒ·ý·frÁN«, E=›Çq -‰öŒ:aÏ¿±í&£Í:-} 84‘ÿ eƒQÑeëSsuiA ³g㟥ú£?ÿ ʼn*”“÷aühe:ÊWa@ÒÞk±eØ] F Ô—r.åä˜ @ö¥ªZoÐýYL·¥S²G/‡ñ <~*ZÆ´è>JlòàÛÆ½ÿ 窘ìGN¢:I®KšJp/`íIÁÀõ#Ä-€ö­šµŒoF4|ÆQØÆ@Ì|£Ô…¢À{9˜è½Üó›€ôYÒÎYsið;ís¤€à²ˆ‚4qÉVŒI$ ‰"° æµ8cXGjœˏ¡Aâý•ËÜ¢ûï e·çLx']á"oÅÎê3¯Ç—¹”ó0nå‚âg{Œñ> S´˜îè°g238‚ãköÝfÚd´6Ò€;ò÷±¢™¼›º ¢Æ'¥Ðx'e¬ç ]bÈÆV¢ó‹kýBO ðÊâ$Ÿ!×T 3Mýמ žìٍàÌü‘8÷€àæØ8æ©6‰©L´«…oãpð„~Çk‰!ñ;‹”ÛžÍ àž±z Ÿôû øŸÝužÏ;ÿ #|u6™Þ¬ÚˆÐõA4¶â|ôl|Ê2ŽÇ¤ÝÅÇY.<#Aí.k§hóF‚”Y; M½Ö4hŸ4&›­¿tès´%FìL¥£Ãk‰ÇT¤haÁ¤ÚxfÉ`ÑìË›>i 3t‚:,–+^÷´–{Û–Nxi"x‘Ûg î¨>¥Õ܁ùZH,2Û“:8xÊ¢Çí9.É-Ìâã-=çjwµS˜dütžçwýGòú®®ûº_ˆýx$–¡ãøO EÚÛÏ÷R„×w+3£Á£öUMyR²¹âŒ°š›¸Ñãò9§Ó_Dl+Ùßc›úšGÅÌc†Ž!Ko=¶.‘Îÿ c²(2®V mª.ÿ ¹B›¹å ù„öŸSV>™ü¯$y:G¢Z×àøúdî¹û­·ýÇ´:•c LÍõi_‹ö+ÎæGÊè>OŠ•äž´§Þ{X}¨1ÚTc›»Qþ•êô°t¿OP?eæ~É{5]•ÙR£r5†nZ\ã@ &îJõ ¾àC°þV>fé¥/ü5ñÊIº_é5 ;e­h<@ Ä&æÃëE%;X,ÒãÆÞ`Oò¦kŸm#˜!ÀyÄ¢| óLšò¥Ä` ¶R=|ÈCâh5ò3DˆïF†ðÒ#ÅìÛœ?¸yhBãœí ZxßÎÄhºRK„`Þödvײ™ÀÈÑÒgŒuY w³%†ƒÓzõ ÖÏp‚dH®¦A´ù§»ÓÇMæ~)ˆð‡û:ù&Ä •vGD´À n ݇¼Ö8Fö óáà£~Ë¥x`oK|Ä?fxiØü%pìR>éò+Û±éÎ>núlFŤ'tq8LZÏvÃ?„¡ß±È⽆¯³íü@x|PöUäèØã¡ð‚ŒAìÏ"vÍwóŸÍ{ ý0.z È•Ö{,N¡£¡ŸKÕÙž>Ýœþ ÍÀ°<×EA!Å‚D™IúOÍ¡>ôG}Â` ÍßkÜL™Ž Þð™ {IøF²¹òQ3&!ÃÂÞz.d&Ï-sH¸,Ôõ˜ŽP€ 77ˆÝ¼ÊëÜw =cÕ Ú,ØÐ5ÎYÐ)ì´öœgŒ[¤ßv㙑8心>h]§µháYš£²ºÑ.{Ï7Sð•?´~×SÃKýJÛ˜ ™Íäiúu<µX¶1õ^kâçIÑ£sZ4h>j*ÔšD:4­¿_ ÷¸ Õxæÿ ¸?Mù _•­ÊÐ ä ÷ý ÑwL œ­ïnTkÛUÍN©ë:¦fV ¶ÜÔÜMªÅâA½–¿R×TXš-%iTÊT•‡Ù‚JôϐZxWÑè‰f‰òG º ×Õû2aZ7OU3[“×AT–ÞŒ…-‘¤”Ì ì&(ˆ¿­•ƒkï’:ðY¦W‘ Å)“†‘˜³Åtcø˜ñTÂwÚÇ4|üLÇªí–v- qˆèU qPE.†â‘˜µ Æ,ÐÅs]8¾„oúÑ i>ÜxxÈó)ƒ ´æÁâØ$À‰vžŸf$Ž |ãw;ÀÁIJ»b` {¦Ó¤Ú$©YÀ‘n@Óïž«9J¼êG m¤ ܯ¹ÌW4€ÐÒÅÛ‡#褕Ÿn-?í|с¥÷Ú¹¬'´ÞÜ9ÓK `hê£SÄSà?7—Wí_´…óB›»:=Ãïq`<8ñÓŒÑlú2d¬ê³£hÖ[l|$vÝro~'R®‰§°ñmY ͧäP |PUª¹·:3Œ[Û{Xÿ ºâ@‚W–Äé u‚ ¯´*=íή.pûÒdt @G‰¬ s¸ ëÉücr ÞæÑ¨Ê@>¤¢Ö±. Þ'¯°ÌME[YéïĵÂCå½ Ué©Áû'Ê9%eÔðNU”ë‘ÌsD3/®+UI˜9h.WC”빓$#:pz:YÓ ¿xž* ³$Í +$kñAŠ‹†¢ Uê>¸)_š¬÷©ßAÂÔb9ÇU ¯¾á•9¯ÏÏ÷O÷¼¼Fähal1‰3Ì[Ïr•´UCksNÐ] R‘¸¥H+§Šé†c©vÖÞ0iÓ76s†î!§=ß ¼~Ô'°Ãmäoäš³ªøi1úÉ)³yV8 CLÄØÁ‘WYïi€H6ÖÑiámø^ÈY´°Ñ7¥Û*—Ñ©L«Qƒï—Ùrÿ ›£Ð*š¸ˆL©ˆ$ˆ ÷¾D§9È®«qbqC)–ˆïv´çñsÑVT­Ø, <àïºÀO«Jý·õ àfPìð .wFšir´þ’2_Y *Æ€x\« ì€9š@ Ž|F⇥ˆkZ@hÖÄ0t¿-<“‹qµ¾*ZL¤Ú)&BJpÓF5=$„at*Zš$’ÑtdûÝRI1 2މ$€$I$#‰SÞ’Hë¬ï;Á$¡t$’`<(ñÇt)$‡Ð.Êf¢X’Kt=Éé$‚ˆªè¢oÝëòI%Rgcª÷ŠyI%¡‰ÿ !ñ)´õ $¤ Ô’IIGÿÙ#!/usr/bin/perl -w #------------------------------------------------------------------------ # # $Sendmail: Parse_conf.pm,v 8.17.1.9 2024-06-16 21:07:57 cowboy Exp $ # # Parse and update /etc/mail/sendmail.conf # # Copyright (c) 2001-2010 Richard Nelson. All Rights Reserved. # # Notes (to all): # # Notes (to self): # #------------------------------------------------------------------------ # # Package/Module declaration package Parse_conf; require Exporter; @ISA = qw(Exporter); #@EXPORT = qw(read_conf write_conf); @EXPORT_OK = qw(read_conf write_conf get_value); $VERSION = '2.0000'; # # Initialization of the perl environment use strict; # be kosher #use warnings; # Not needed here use Cwd; # provide cwd() use Env; # A few environmental references use integer; # Peformance use Sys::Hostname; # make sure we have a valid hostname use Getopt::Long; # parameter handling use FileHandle; # I/O # Local libraries - for Debian Sendmail Perl helper functions # BEGIN { $main::my_path = substr($0,$[,rindex($0,'/')) }; use lib ('.', substr($0,$[,rindex($0,'/')), "/usr/share/sendmail"); require Parse_mc; # Version of this program #($main::MYNAME = $main::0) =~ s|.*/||; #$main::Author = "Richard Nelson"; #$main::AuthorMail = "cowboy\@debian.org"; #$main::Version = '$Revision: 1.00 $ '; $Parse_conf::program_name = 'Parse_conf.pm'; $Parse_conf::program_version = '8.17.1.9'; $Parse_conf::program_date = '2024-06-16 21:07:57 cowboy'; $Parse_conf::debug = 0; my $interp_pgm = "$^X"; my $interp_vrm = $]; $interp_vrm = ("$^V" | '000') if (defined $^V); my $current_time = scalar localtime; my $user = getlogin || (getpwuid($<))[0] || "Unknown!!"; my $hostname = hostname(); my $directory = getcwd(); $Parse_conf::Conffile = "/etc/mail/sendmail.conf"; my $debug; # #------------------------------------------------------------------------------ # Global variables #------------------------------------------------------------------------------ my %parm_def = ( 'DAEMON_NETMODE' => 'Static' ,'DAEMON_NETIF' => 'eth0' ,'DAEMON_MODE' => 'Daemon' ,'DAEMON_RUNASUSER' => 'No' ,'DAEMON_PARMS' => '' ,'DAEMON_HOSTSTATS' => 'No' ,'DAEMON_MAILSTATS' => 'No' ,'QUEUE_MODE' => '${DAEMON_MODE}' ,'QUEUE_INTERVAL' => '10m' ,'QUEUE_PARMS' => '' ,'MSP_MODE' => 'Cron' ,'MSP_INTERVAL' => '20m' ,'MSP_PARMS' => '' ,'MSP_MAILSTATS' => '${DAEMON_MAILSTATS}' ,'MISC_PARMS' => '' ,'CRON_MAILTO' => 'root' ,'CRON_PARMS' => '' ,'HANDS_OFF' => 'No' ,'LOG_CMDS' => 'No' ,'AGE_DATA' => '' ); my %parameter = %parm_def; my %parm_kw = ( 'DAEMON_NETMODE' => ['static', 'dynamic'] ,'DAEMON_MODE' => ['daemon', 'inetd','none'] ,'QUEUE_MODE' => ['daemon', 'cron', 'none'] ,'MSP_MODE' => ['daemon', 'cron', 'none'] ); my %parm_bool = ( 'HANDS_OFF' => 1 ,'DAEMON_RUNASUSER' => 1 ,'DAEMON_HOSTSTATS' => 1 ,'DAEMON_MAILSTATS' => 1 ,'MSP_MAILSTATS' => 1 ,'LOG_CMDS' => 1 ); my %parm_dependant = ( ); my %parm_deprecated = ( 'DAEMON_STATS' => 'DAEMON_MAILSTATS' ,'MSP_STATS' => 'MSP_MAILSTATS' ); my %parm_hidden = ( 'DAEMON_RUNASUSER' => 1 ,'prefix' => 1 ,'exec_prefix' => 1 ,'bindir' => 1 ,'sbindir' => 1 ,'libexecdir' => 1 ,'datadir' => 1 ,'sysconfdir' => 1 ,'sharedstatedir' => 1 ,'localstatedir' => 1 ,'libdir' => 1 ,'MTA_DAEMON' => 1 ,'MTA_COMMAND' => 1 ,'MTA_L' => 1 ,'MTA_L_QUEUE' => 1 ,'MTA_ROOT' => 1 ,'MTA_PIDFILE' => 1 ,'MSP_DAEMON' => 1 ,'MSP_COMMAND' => 1 ,'MSP_L' => 1 ,'MSP_L_QUEUE' => 1 ,'MSP_ROOT' => 1 ,'MSP_PIDFILE' => 1 ); # #------------------------------------------------------------------------------ # Finally, some code (almost) #------------------------------------------------------------------------------ 1; # return (true); # #------------------------------------------------------------------------------ # Read /etc/mail/sendmail.conf #------------------------------------------------------------------------------ sub read_conf { my ($input_file) = @_; $input_file ||= $Parse_conf::Conffile; $debug = $main::debug || $Parse_conf::debug; # Update defaults according to current environment &update_defaults; # Read /etc/mail/sendmail.conf (if extant) &read_config($input_file); # Update old values to new format &update_values; # Make sure things are kosher my $ok = &validate_config; if (! $ok) { die "Terminating due to configuration error."; }; }; # #------------------------------------------------------------------------------ # [Re]write /etc/mail/sendmail.conf #------------------------------------------------------------------------------ sub write_conf { my ($output_file) = @_; $debug = $main::debug || $Parse_conf::debug; &write_config($output_file); }; # #------------------------------------------------------------------------ # Update default settings according to current environment #------------------------------------------------------------------------ sub update_defaults { my ($class, $flags, $files, $options); my ($ok, $stats); my $file; # Read the mc/m4 files &Parse_mc::read_dbs('', ''); # Obtain entry for HOST_STATUS_DIRECTORY ($class, $flags, $files, $options) = &Parse_mc::entry_dbs('confHOST_STATUS_DIRECTORY'); $file = @{$files}[0]; if ( $file ne '-' and -d $file ) { $parameter{'DAEMON_HOSTSTATS'} = 'Yes'; } else { $parameter{'DAEMON_HOSTSTATS'} = 'No'; }; # Obtain entry for STATUS_FILE ($class, $flags, $files, $options) = &Parse_mc::entry_dbs('STATUS_FILE'); $file = @{$files}[0]; if ( $file ne '-' and -e $file ) { $parameter{'DAEMON_MAILSTATS'} = 'Yes'; } else { $parameter{'DAEMON_MAILSTATS'} = 'No'; }; # Obtain entry for MSP_STATUS_FILE ($class, $flags, $files, $options) = &Parse_mc::entry_dbs('MSP_STATUS_FILE'); $file = @{$files}[0]; if ( $file ne '-' and -e $file ) { $parameter{'MSP_MAILSTATS'} = 'Yes'; } else { $parameter{'MSP_MAILSTATS'} = 'No'; }; }; # #------------------------------------------------------------------------ # Update old settings according to current format #------------------------------------------------------------------------ sub update_values { my ($ok, $var); # Add m(inutes) to {queue,msp}_interval if needed $parameter{'QUEUE_INTERVAL'} =~ s/^(p?\d+)$/$1m/; $parameter{'MSP_INTERVAL'} =~ s/^(p?\d+)$/$1m/; # Also update the queue aging data ($ok, $var) = &get_value('AGE_DATA'); my $tmpval = eval $var; if ($@) { warn $@; } else { $var = $tmpval; }; if (not defined $var) { $tmpval = '""'; } elsif (not ref $var) { $tmpval = "$var"; } elsif (@{$var} == 0) { $tmpval = '""'; } else { $tmpval = '['; foreach my $entry (@{$var}) { foreach my $ndx ($[ .. $#{$entry}) { @{$entry}[$ndx] =~ s/'/\\'/g; }; @{$entry}[0] =~ s/^(\d+)$/$1m/; $tmpval .= "['" . join("', '", @{$entry}) . "'],"; }; $tmpval .= ']'; $parameter{'AGE_DATA'} = $tmpval; }; # Set any dependant fields here... }; # #------------------------------------------------------------------------ # Obtain parameter name #------------------------------------------------------------------------ sub get_name { my ($name, $quiet) = @_; # Handle deprecated/renamed variables if ( exists($parm_deprecated{$name}) ) { print STDERR "$name is deprecated." if ($debug and ! $quiet); if ( $parm_deprecated{$name} ) { print STDERR " Please use $parm_deprecated{$name} instead.\n" if ($debug and ! $quiet); $name = $parm_deprecated{$name}; } else { print STDERR " It will be ignored.\n" if ($debug and ! $quiet); }; }; return $name; }; # #------------------------------------------------------------------------ # Obtain value directly, or indirectly #------------------------------------------------------------------------ sub get_value { my ($name) = @_; my $ok = 1; my $value = ''; if ( ! exists($parameter{$name}) ) { print STDERR "Variable $name not defined...\n"; return ($ok, $value); }; $name = get_name($name, ''); $value = $parameter{$name}; my $tval = $value; $tval =~ s/^\s*//; my $default = 0; # Dereference loop... keep original value if we get any errors... Dereference:; if ($tval =~ /^\$/) { my @ref_stack = ($name); my %ref_hash = ($name => 1); while ($tval =~ /^\$/ and $ok) { my $start = 1; my $del = 1; my $char = substr($tval, 1, 1); if ( $char eq '{' or $char eq '(' ) { $start += 1; $del += 2; }; my $ref = get_name(substr($tval, $start, length($tval)-$del), ''); push @ref_stack, $ref; if (exists($ref_hash{$ref})) { print STDERR "Go directly to jail; do not pass go, ", "do not collect \$200\n"; print STDERR " Reference loop: ", join('->', @ref_stack, '...'),"\n"; $ok = 0; } else { $ref_hash{$ref} = 1; if (lc $ref eq 'default') { $tval = $parm_def{$name}; print STDERR "Setting $name to default value: ", "$parm_def{$name}.\n" if ($debug); } elsif (exists($parameter{$ref})) { $tval = $parameter{$ref}; print STDERR "Setting $name to value of $ref: $tval.\n" if ($debug); } else { print STDERR "Can not deference $ref, it doesn't exist.\n"; $ok = 0; }; }; }; }; if ( $ok ) { # Check keyword parms for valid values if (exists $parm_kw{$name}) { my @ltval = split(/\s/,$tval); my $ltval = lc(@ltval[$[]); my $found = ""; foreach my $value (@{$parm_kw{$name}}) { if ($value eq $ltval) { $found = 1; $tval = ucfirst($ltval); }; }; if ( ! $found ) { $default += 1; if ( $default > 1 ) { print STDERR "Can not resolve $name, value=$value.\n"; $ok = 0; } else { print STDERR "Illegal value($tval) for $name.\n", " Valid values are: ", join(', ', @{$parm_kw{$name}}), "\n", " Set to default: $parm_def{$name}.\n"; $tval = $parm_def{$name}; goto Dereference; }; }; } # Check boolean parms for valid values elsif (exists $parm_bool{$name}) { my @ltval = split(/\s/,$tval); my $ltval = lc(@ltval[$[]); $ltval =~ s/^[ty1].*/1/; $ltval =~ s/^[fn0].*/0/; if ($ltval eq '0' or $ltval eq '1') { $tval = ucfirst($ltval); } else { $default += 1; if ( $default > 1 ) { print STDERR "Can not resolve $name, value=$value.\n"; $ok = 0; } else { print STDERR "Illegal value($tval) for $name.\n", " Valid values are: T[rue],Y[es],1,", " F[alse],N[o],0\n", " Set to default: $parm_def{$name}.\n"; $tval = $parm_def{$name}; goto Dereference; }; }; }; }; $value = $tval if $ok; print STDERR "get_value : $name => $value\n" if ($debug); return ($ok, $value); }; # #------------------------------------------------------------------------ # Read input configuration file (if no input, just use defaults) #------------------------------------------------------------------------ sub read_config { my ($input_file) = @_; @ARGV = split(' ', $input_file); return if (! -r $input_file); my $savename = ''; my $parmname = ''; my $parmval = ''; my $parmref = ''; my $defname = ''; my $defval = ''; my $tmpval = ''; print STDOUT "Reading configuration from ", join(',',@ARGV), ".\n"; line: while () { next line if /^$/; # skip empty lines chomp; # drop tailing \n if (s/\\$//) { $_ .= <>; redo unless eof(); }; # check commented lines for default parameter values # a bit of a kluge, but it works out nicely if (/^#\s*([\w_]+)="([^"]*)"/) { $defname = get_name($1, 1); $defval = $2; print STDERR "Default: $defname => $defval.\n" if ($debug); next line; }; # Skip any comments next line if /^#/; # skip comments # Process assignment statements if (/^\s*([\w_]+)="([^"]*)"/) { $savename = $1; $parmname = get_name($savename, ''); $parmval = $2; print STDERR "Value : $savename => $parmval.\n" if ($debug); # Do we know about this parameter? # NOTE: keep, even if we don't know about it to prevent # problems with up/down grades (not loose anything) if ( ! exists($parm_def{$parmname}) and ! exists($parm_hidden{$parmname}) ) { print STDERR "$parmname is a user defined parameter.\n" if ($debug); }; # Note if value is default, if so, we'll change it to # the current default - maybe counterintuitive, oh well # it does help with migration if ($parmname eq $defname and $parmval eq $defval) { print STDERR "$parmname is the default value: $defval.\n" if ($debug); $parmval = $parm_def{$parmname}; }; # Finally, assign value if (exists $parm_kw{$savename} or exists $parm_bool{$savename}) { $parmval = ucfirst($parmval); }; if ($savename eq $parmname) { $parameter{$parmname} = $parmval; } else { $parameter{$savename} = $parmval; }; }; }; }; # #------------------------------------------------------------------------ # Validate current configuration #------------------------------------------------------------------------ sub validate_config { my $valid = 1; print STDOUT "Validating configuration.\n"; # Really, we only care about the some of the variables - those # that have defaults... the rest, well, so what ! foreach my $val (sort keys %parm_def) { my ($ok, $value) = &get_value($val, 1); if (! $ok) { $valid = 0; }; }; if (! $valid ) { print STDERR "\nOne or more errors were encountered!\n\n"; }; return ($valid); }; # #------------------------------------------------------------------------ # Write updated configuration file #------------------------------------------------------------------------ sub write_config { my ($database_file) = @_; my $ofh = new FileHandle; # Make sure things are kosher my $result = &validate_config; if (! $result) { die "Terminating due to configuration error."; }; $database_file = $database_file || $Parse_conf::Conffile; my $caller = "$main::program_name" if ($main::program_name); $caller .= " $main::program_version" if ($main::program_version); $caller .= " $main::program_date" if ($main::program_date); print STDOUT "Writing configuration to $database_file.\n"; $database_file = '&STDOUT' if ($database_file eq '-'); unless ( open($ofh, ">$database_file") ) { warn("Could not open $database_file($!), using STDOUT\n"); open($ofh, ">&STDOUT"); }; $database_file = '-' if ($database_file eq '&STDOUT'); # print $ofh <<"EOT"; #################################################################### ##### This file is automagically generated -- edit at your own risk ##### ##### file: ${database_file} ##### generated via: (${interp_pgm} ${interp_vrm}) ##### ${caller} ##### ${Parse_conf::program_name} ${Parse_conf::program_version} ${Parse_conf::program_date} ##### by: ${user}\@${hostname} ##### on: ${current_time} ##### in: ${directory} ##### input files: #EOT # foreach my $file ( split(' ', $input_file) ) { # print $ofh <<"EOT"; ##### ${file} #EOT # }; # print $ofh <<"EOT"; ##### #################################################################### print $ofh <<"EOT"; #------------------------------------------------------------------------------ # # $database_file # # Copyright (c) 2001-2010 Richard Nelson. All Rights Reserved. # Version: ${main::program_version} # Time-stamp: <${main::program_date}> # # Parameter file for sendmail (sourced by /usr/share/sendmail/sendmail) # Make all changes herein, instead of altering /etc/init.d/sendmail. # # After making changes here, you'll need to run /usr/sbin/sendmailconfig # or ${main::program_name} to have the changes take effect - # If you change DAEMON_MODE, QUEUE_MODE, or QUEUE_INTERVAL, you'll also # need to run /etc/init.d/sendmail restart. # # Changes made herein will be kept across upgrades - except for comments! # Some comment lines have special significance ... # # **** **** **** **** DO NOT EDIT THE COMMENTS **** **** **** **** # # Supported parameters (and defaults) are listed herein. # # Notes: # * This setup allows sendmail to run in several modes: # - listener and queue runner..DAEMON_MODE="daemon".QUEUE_MODE="daemon" # - listener only..............DAEMON_MODE="daemon".QUEUE_MODE="none" # - queue runner only..........DAEMON_MODE="none"...QUEUE_MODE="daemon" # - *NOTHING* ?!?..............DAEMON_MODE="none"...QUEUE_MODE="none" # # * You can also run the listener from inetd: # - listener and queue runner..DAEMON_MODE="inetd"..QUEUE_MODE="daemon" # - listener only..............DAEMON_MODE="inetd"..QUEUE_MODE="none" # # * You can also run the queue runner from cron: # - listener and queue runner..DAEMON_MODE="....."..QUEUE_MODE="cron" # - queue runner only..........DAEMON_MODE="none"...QUEUE_MODE="cron" # # * _PARMS entries herein are shown in precedence order, any later _PARMS # field will, if applicable, override any previous _PARMS fields. # # * Values *MUST* be surrounded with double quotes ("), single quotes # will *NOT* work ! # #------------------------------------------------------------------------------ # SMTP Listener Configuration # # DAEMON_NETMODE="$parm_def{'DAEMON_NETMODE'}"; Keyword SMTP network mode # static: Do not monitor any network interfaces for changes # dynamic: Monitor one or more interfaces for changes # DAEMON_NETMODE="$parameter{'DAEMON_NETMODE'}"; # # DAEMON_NETIF="$parm_def{'DAEMON_NETIF'}"; string SMTP interface(s) # This parameter defines the network interface(s) that the daemon # will monitor for status changes (via ppp, dhcp, ifup/down hooks). # # NOTES: # 1) Only list more than one interfaces if they only used for fallback, # otherwise the daemon will wind up ping-ponging between interfaces. # 2) Do not use 'lo' unless your daemon only listens on the localhost. # DAEMON_NETIF="$parameter{'DAEMON_NETIF'}"; # # DAEMON_MODE="$parm_def{'DAEMON_MODE'}"; Keyword SMTP listener # daemon: Run as standalone daemon # inetd: Run from inet supervisor (forks for each mail) # none: No listener (ie, nullclient/smarthost) # # NOTE: If you choose "none", mail will build up in the MSP queues # and you will not receive any mail from external sites. # DAEMON_MODE="$parameter{'DAEMON_MODE'}"; # # DAEMON_PARMS="$parm_def{'DAEMON_PARMS'}"; String Listener parms # Any parameters here will be ignored when run from cron. # Note that {QUEUE,MISC,CRON}_PARMS, if applicable, will override # anything declared herein. # DAEMON_PARMS="$parameter{'DAEMON_PARMS'}"; # # DAEMON_HOSTSTATS="$parm_def{'DAEMON_HOSTSTATS'}"; Boolean Listener stats # This parameter determines whether or not host stats are collected # and available for the \`hoststat\` command to display. There will # be a (minor) performance hit, as files will be created/updated for each # sendmail delivery attempt. The files are fixed in size, and small, # but there can be many of them. # DAEMON_HOSTSTATS="$parameter{'DAEMON_HOSTSTATS'}"; # # DAEMON_MAILSTATS="$parm_def{'DAEMON_MAILSTATS'}"; Boolean Listener stats # This parameter determines whether or not mailer stats are collected # and available for the \`mailstats\` command to display. There will # be a (minor) performance hit, as this file will be updated for each # item coming into, or out of, sendmail. The file is fixed in size, # and small, so there's no need to rotate it. # DAEMON_MAILSTATS="$parameter{'DAEMON_MAILSTATS'}"; # #------------------------------------------------------------------------------ # SMTP MTA Queue Runner Configuration # # QUEUE_MODE="$parm_def{'QUEUE_MODE'}"; Keyword SMTP queue runner # daemon: Run as standalone daemon # cron: Run from crontab # none: No queue runner (ie, nullclient/smarthost) # QUEUE_MODE="$parameter{'QUEUE_MODE'}"; # # QUEUE_INTERVAL="$parm_def{'QUEUE_INTERVAL'}"; Timespec (p?digits+w|d|h|m|s) # Interval at which to run the MTA queues. What interval should you use? # The amount of time that is acceptable before retrying delivery on # mail that couldn't be delivered in one run, or how long an item can # set in the queue before having the first delivery attempt done. # # NOTE: To use persistent queue-runners use this form: p120m # # NOTE: If you leave this field blank, You get *NO* queue runners !!! # QUEUE_INTERVAL="$parameter{'QUEUE_INTERVAL'}"; # # QUEUE_PARMS="$parm_def{'QUEUE_PARMS'}"; String queue parameters # Any parameters here are also used when run from cron. # Note that MISC_PARMS and CRON_PARMS, if applicable, will override # anything declared herein. # QUEUE_PARMS="$parameter{'QUEUE_PARMS'}"; # #------------------------------------------------------------------------------ # SMTP - MSP Queue Runner Configuration # # MSP_MODE="$parm_def{'MSP_MODE'}"; Keyword MSP queue runner mode # daemon: Run as standalone daemon # cron: Run from crontab # none: No queue runner (ie, nullclient/smarthost) # # NOTE: If QUEUE_MODE="cron" & MSP_MODE="none", the MSP queue will # be run as part of the MTA queue running process. # MSP_MODE="$parameter{'MSP_MODE'}"; # # MSP_INTERVAL="$parm_def{'MSP_INTERVAL'}"; Timespec (digits+w|d|h|m|s) # Interval at which to run the MSP queues. What interval should you use? # The amount of time that is acceptable before retrying delivery on # mail that couldn't be accepted by the MTA, and was therefore left # in the message submission queue. The MTA shouldn't be down that often # so this can be larger than QUEUE_INTERVAL. # # NOTE: If you leave this field blank, The MSP queue will *NOT* be run !!! # MSP_INTERVAL="$parameter{'MSP_INTERVAL'}"; # # MSP_PARMS="$parm_def{'MSP_PARMS'}"; String queue parameters # Any parameters here are also used when run from cron. # Note that MISC_PARMS and CRON_PARMS, if applicable, will override # anything declared herein. # MSP_PARMS="$parameter{'MSP_PARMS'}"; # # MSP_MAILSTATS="$parm_def{'MSP_MAILSTATS'}"; Boolean Listener stats # This parameter determines whether or not mailer stats are collected # and available for the \`mailstats\` command to display. There will # be a (minor) performance hit, as this file will be updated for each # item coming into, or out of, sendmail. The file is fixed in size, # and small, so there's no need to rotate it. # MSP_MAILSTATS="$parameter{'MSP_MAILSTATS'}"; # #------------------------------------------------------------------------------ # Miscellaneous Confguration # # MISC_PARMS="$parm_def{'MISC_PARMS'}"; String miscellaneous parameters # Miscellaneous parameters - applied to any sendmail invocation. # Any parameters here are also used when run from cron. # Applied after {DAEMON,QUEUE}_PARMS, and can therefore override them # if need be (in which case why did use them?) # Note that CRON_PARMS, if applicable, will override anything # declared herein. # # Here is where'd you setup and debugging or special parms that you # want shared betwixt the possibly separate listener/queue-runner # processes. # MISC_PARMS="$parameter{'MISC_PARMS'}"; # #------------------------------------------------------------------------------ # Cron Job Configuration # # CRON_MAILTO="$parm_def{'CRON_MAILTO'}"; String cronjob output # Recipient of *rare* cronjob output. Some cronjobs will be running # under user `mail`, so any problems encountered would probably be missed # so define a user who actually (hopefully) checks email now and again. # CRON_MAILTO="$parameter{'CRON_MAILTO'}"; # # CRON_PARMS="$parm_def{'CRON_PARMS'}"; String cron specific parmeters # Cron parameters - applied *only* when sendmail queue running is done # via a cronjob. Applied after QUEUE_PARMS and MISC_PARMS, and can # therefore override them if need be. # CRON_PARMS="$parameter{'CRON_PARMS'}"; # #------------------------------------------------------------------------------ # Other stuff # LOG_CMDS="$parm_def{'LOG_CMDS'}"; Binary command logging flag # Will cause syslog entries for many of the sendmail related commands # like runq, mailq, etc - you'll also see cron jobs (if enabled). # LOG_CMDS="$parameter{'LOG_CMDS'}"; # # HANDS_OFF="$parm_def{'HANDS_OFF'}"; Binary Do *NOT* touch the configuration # Set this *ONLY* if you are going to be fully responsible for the entire # setup of sendmail - the directories, permissions, databases, etc. With # this variable set to "Yes", nothing will be done for you during updates. # # In other words, "The blood be upon your hands" if you set this... # My ability to help with problems will be greatly reduced ! # # "Well, a pet peeve of mine is people who directly edit the # .cf file instead of using the m4 configuration files. # Don't do it! [laughs] I treat the .cf file as a binary # file - you should too." # -- Eric Allman 1999/10/18 # http://www.dotcomeon.com/allman_sendmail_qa.html # HANDS_OFF="$parameter{'HANDS_OFF'}"; # #------------------------------------------------------------------------------ # Queue Aging Configuration # # Why would you want to age your queues? On every queue-run interval, # sendmail will try *every* file in the queue... If a site is down # for a while, considerable time can be wasted each interval in retrying # it. The scheme supported allows aging by time, and can move the older # files to another (less frequently run queue), thereby reducing overal # system impact - and providing better mail throughput. # # Note that this support is completely separate from QUEUE_MODE=cron, # you can age queues even if you're running QUEUE_MODE=daemon. # # There are four parts to the queue aging support, and these parts # may be repeated, to operate on multiple queues. # # 1. Interval at which to age the queues (in minutes). # What interval should you use? Roughly twice the normal queue # interval, so that messages are tried twice in each successively # slower queue. # # NOTE: some values just wont work, due to crontab pecularities # a value of 90 minutes will actually be run at every x:30 ! # Please check /etc/cron.d/sendmail to make sure it is doing what # you thought it should ! # # 2. Criteria (optional and defaults to interval). This is the # specification of which files to move. It defaults moving # files whose age in the queues exceeds the interval. # This field, if specified can be very complex - supporting # aging by just about anything! see qtool(8) for details. # # 3. To queue. This is the queue to which files will be moved. # It may be fully qualified, or relative to /var/spool/mqueue. # # 4. From queue. This is the queue from which files will be moved. # It may be fully qualified, or relative to /var/spool/mqueue. # # Samples: # AGE_DATA="[['25m', '', 'hourly', 'main']]"; # Every 25 minutes, move any file older than 25 minutes from # /var/spool/mqueue/main to /var/spool/mqueue/hourly # # AGE_DATA="[['25m', '', 'hourly', 'main'],\\ # ['120m', '', 'daily', 'hourly']]"; # Same as the above, but also move files from the hourly queue # to the daily queue after 120 minutes in the hourly queue. # # AGE_DATA="[['25m',\\ # '-e \\'\$msg{message}[0] == /Deferred: 452 4.2.2 Over quota/\\'',\\ # 'overquota', 'main']]"; # Every 25 minutes, move all files deferred because of quota # violations from /var/spool/mqueue/main to # /var/spool/mqueue/overquota where they can be processed on # a different interval, or by some other means. # # If the above samples suggest Perl arrays, well, they are... # # AGE_DATA="$parm_def{'AGE_DATA'}"; Perl array Queue aging data # EOT my ($ok, $var) = &get_value('AGE_DATA'); my $tmpval = eval $var; if ($@) { warn $@; } else { $var = $tmpval; }; if (not defined $var) { print $ofh 'AGE_DATA="";',"\n"; } elsif (not ref $var) { print $ofh 'AGE_DATA="',$var,'";',"\n"; } elsif (@{$var} == 0) { print $ofh 'AGE_DATA="";',"\n"; } else { print $ofh 'AGE_DATA="[\\',"\n"; foreach my $entry (@{$var}) { foreach my $ndx ($[ .. $#{$entry}) { @{$entry}[$ndx] =~ s/'/\\'/g; }; print $ofh "['",join("', '",@{$entry}),"'],\\\n"; }; print $ofh ']";',"\n"; }; print $ofh <<"EOT"; # #------------------------------------------------------------------------------ # Dependant variables (set according to other variables) # EOT foreach my $key (sort keys %parm_dependant) { my ($ok, $value); # Don't evaluate value, just stuff it... next if ( ! $parameter{$key} ); ($ok, $value) = (1, $parameter{$key}); print $ofh "$key=",'"',$value,'";',"\n"; }; print $ofh <<"EOT"; # #------------------------------------------------------------------------------ # Hidden variables (the blood be upon your hands) # EOT foreach my $key (sort keys %parm_hidden) { my ($ok, $value); # Don't evaluate value, just stuff it... next if ( ! $parameter{$key} ); ($ok, $value) = (1, $parameter{$key}); print $ofh "$key=",'"',$value,'";',"\n"; }; print $ofh <<"EOT"; # #------------------------------------------------------------------------------ # Deprecated variables (kept for reference) # EOT foreach my $key (sort keys %parm_deprecated) { my ($ok, $value); # Don't evaluate value, just stuff it... if ( $parm_deprecated{$key} ) { ($ok, $value) = (1, join('','${', $parm_deprecated{$key}, '}')); } elsif ( $parameter{$key} ) { ($ok, $value) = (1, $parameter{$key}); }; print $ofh "$key=",'"',$value,'";',"\n"; }; print $ofh <<"EOT"; # #------------------------------------------------------------------------------ # Unknown variables (kept for reference) # EOT foreach my $key (sort keys %parameter) { if (! exists($parm_def{$key}) and ! exists($parm_deprecated{$key})) { # Don't evaluate value, just stuff it... my ($ok, $value) = (1, $parameter{$key}); print $ofh "$key=",'"',$value,'";',"\n"; }; }; print $ofh <<"EOT"; #------------------------------------------------------------------------------ # EOT close($ofh); if ( $database_file eq $Parse_conf::Conffile ) { chown '0', '0', "$database_file"; chmod 0644, "$database_file"; }; }; __END__