ÿØÿà 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_mc.pm,v 8.17.1.9 2024-06-16 21:07:57 cowboy Exp $ # # Parse Sendmail config for databases # # Copyright (c) 2001-2010 Richard Nelson. All Rights Reserved. # # Notes (to all): # * for "define(xxx,...)"; "define(xxx," must be on same line, but the # rest may be split across multiple lines # * assumes makemap dbtype /etc/mail/database < /etc/mail/database # # Notes (to self): # * changes made herein *must* be reflected in # parse_mc,update_mk,update_db,debian.m4 # * userdb can also have multiple databases and then a forward! # * undefine support # * include support (also for OSTYPE, DOMAIN, SITE, etc) # * F and K lines # #------------------------------------------------------------------------ # # Package/Module declaration package Parse_mc; require Exporter; @ISA = qw(Exporter); #@EXPORT = qw(read_mc write_dbs read_dbs); @EXPORT_OK = qw(read_mc write_dbs read_dbs names_dbs restart_dbs entry_dbs format_dbs); $VERSION = '2.0002'; # # 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 # Version of this program #($main::MYNAME = $main::0) =~ s|.*/||; #$main::Author = "Richard Nelson"; #$main::AuthorMail = "cowboy\@debian.org"; #$main::Version = '$Revision: 2.00 $ '; $Parse_mc::program_name = 'Parse_mc.pm'; $Parse_mc::program_version = '8.17.1.9'; $Parse_mc::program_date = '2024-06-16 21:07:57 cowboy'; $Parse_mc::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($<))[$[] || "Unknown!!"; my $hostname = hostname(); my $directory = getcwd(); $Parse_mc::Conffile = "/etc/mail/databases"; $Parse_mc::input_files = "/etc/mail/sendmail.mc"; $Parse_mc::database_file = "/etc/mail/databases"; my $debug; # # List of FEATURE()s, and their default file names (in path ${smdb_loc}) my %smdb_features = ( access_db => 'access' ,authinfo => 'authinfo' ,bitdomain => 'bitdomain' ,domaintable => 'domaintable' ,genericstable => 'genericstable' ,mailertable => 'mailertable' ,use_cw_file => 'use_cw_file' ,use_ct_file => 'use_ct_file' ,uucpdomain => 'uudomain' ,virtusertable => 'virtusertable' ); # List of classes, and a flag to note if it is reasonable to parse it my %smdb_classes = ( '' => 1 # Default, no class ,'-' => 1 # ditto ,bestmx => 0 # Lookup best MX record for host ,btree => 1 # NEWDB ,dbm => 1 # NDBM ,dequote => 0 # Remove quotes ,dnsmap => 0 # DNSMAP ,hash => 1 # NEWDB ,hesiod => 1 # HESIOD ,host => 0 # Internal hostname lookup ,implicit => 0 # Search for alias database ,ldap => 0 # LDAPMAP ,nis => 1 # NIS ,nisplus => 1 # NISPLUS ,null => 0 # Always returns false ,program => 1 # Run an external program ,sequence => 0 # Search a series of maps ,stab => 0 # Internal alias ,switch => 0 # Internal alias auto-build ,text => 1 # Lookup in flat text file ,userdb => 1 # Lookup in userdb ,user => 1 # lookup passwd ,newaliases => 1 # for internal usage (of this script) ); # #------------------------------------------------------------------------------ # Prefill entries based upon Sendmail/Debian defaults # Yeah, this is long winded, but it needs to be said... #------------------------------------------------------------------------------ my $smdb_loc = "/etc/mail/"; my $smdb_type = 'hash'; my %smdb_hash = ( # ----------- Database defaults 'MAIL_SETTINGS_DIR' => ['-','-',["${smdb_loc}"],'-'] ,'DATABASE_MAP_TYPE' => ["${smdb_type}",'-',['-'],'-'] # ----------- General stuff ,'sendmail.cf' => ['m4','-',["${smdb_loc}sendmail.mc"],'-'] ,'ALIAS_FILE' => ['newaliases','-',["${smdb_loc}aliases"],'-'] # ,'CANONIFY_DOMAIN_FILE' => # ['-','-',["${smdb_loc}canonify_domains"],'%[^\\#]'] # ,'EXPOSED_USER_FILE' => # ['-','-',["${smdb_loc}exposed_users"],'%[^\\#]'] ,'HELP_FILE' => ['-','-',["${smdb_loc}helpfile"],'-'] # ,'GENERICS_DOMAIN_FILE' => # ['-','-',["${smdb_loc}generic-domains"],'%[^\\#]'] # ,'MASQUERADE_DOMAIN_FILE' => # ['-,'-',["${smdb_loc}masquerade-domains"],'%[^\\#]'] ,'MSP_STATUS_FILE' => ['-','-',["/var/lib/sendmail/sm-client.st"],'-'] ,'MSP_QUEUE_DIR' => ['-','-',["/var/spool/mqueue-client"],'-'] ,'QUEUE_DIR' => ['-','-',["/var/spool/mqueue"],'-'] # ,'RELAY_DOMAIN_FILE' => # ['-','-',["${smdb_loc}relay-domains"],'%[^\\#]'] ,'STATUS_FILE' => ['-','-',["/var/lib/sendmail/sendmail.st"],'-'] # ,'VIRTUSER_DOMAIN_FILE' => # ['-','-',["${smdb_loc}virtual-domains"],'%[^\\#]'] ,'confCONTROL_SOCKET_NAME' => ['-','-',["/var/run/sendmail/smcontrol"],'-'] ,'confCR_FILE' => ['-','-o',["${smdb_loc}relay-domains"],'%[^\\#]'] ,'confCT_FILE' => ['-','-',["${smdb_loc}trusted-users"],'%[^\\#]'] ,'confCW_FILE' => ['-','-',["${smdb_loc}local-host-names"],'%[^\\#]'] ,'confDEAD_LETTER_DROP' => ['-','-',["/var/lib/sendmail/dead.letter"],'-'] # ,'confDEF_AUTH_INFO' => # Deprecated, use authinfo rules instead # ['-','-',["${smdb_loc}default-auth-info"],'-'] ,'confEBINDIR' => ['-','-',["/usr/libexec/sendmail"],'-'] # ,'confERROR_MESSAGE' => # No default # ['-','-',["${smdb_loc}error-header"],'-'] ,'confHOSTS_FILE' => ['-','-',["/etc/hosts"],'-'] ,'confHOST_STATUS_DIRECTORY' => ['-','-',["/var/lib/sendmail/host_status"],'-'] ,'confPID_FILE' => ['-','-',["/var/run/sendmail/mta/sendmail.pid"],'-'] ,'confSERVICE_SWITCH_FILE' => ['-','-',["${smdb_loc}service.switch"],'-'] # ,'confUSERDB_SPEC' => # ['btree','-o',["${smdb_loc}userdb"],'-'] # ----------- STARTTLS ,'confTO_STARTTLS' => ['-','-',["2m"],'-'] ,'confCACERT' => ['-','-',["${smdb_loc}tls/sendmail-server.crt"],'-'] ,'confCACERT_PATH' => ['-','-',["/etc/ssl/certs"],'-'] ,'confCRL' => ['-','-',[""],'-'] ,'confCLIENT_CERT' => ['-','-',["${smdb_loc}tls/sendmail-client.crt"],'-'] ,'confCLIENT_KEY' => ['-','-',["${smdb_loc}tls/sendmail-common.key"],'-'] ,'confSERVER_CERT' => ['-','-',["${smdb_loc}tls/sendmail-server.crt"],'-'] ,'confSERVER_KEY' => ['-','-',["${smdb_loc}tls/sendmail-common.key"],'-'] ,'confDH_PARAMETERS' => ['-','-',["${smdb_loc}tls/sendmail-common.prm"],'-'] ,'confTLS_SRV_OPTIONS' => ['-','-',["V"],'-'] # ----------- SMTP AUTH (SASL) ,'confTO_AUTH' => ['-','-',["2m"],'-'] ,'confAUTH_MECHANISMS' => ['-','-',["DIGEST-MD5 CRAM-MD5 NTLM LOGIN PLAIN"],"-"] ,'TRUST_AUTH_MECH' => ['-','-',["DIGEST-MD5 CRAM-MD5 NTLM LOGIN PLAIN"],"-"] ,'confAUTH_REALM' => ['-','-',[""],'-'] , ); # # # Private entries $smdb_hash{'databases'} = ['parse_mc','-',["${smdb_loc}sendmail.mc"],'-']; $smdb_hash{'Makefile'} = ['update_mk','-',["${smdb_loc}databases"],'-']; $smdb_hash{'crontab'} = ['update_conf','-',["${smdb_loc}sendmail.conf"],'-']; $smdb_hash{'auth'} = ['update_auth','-',["${smdb_loc}sasl/sasl.m4"],'-']; $smdb_hash{'tls'} = ['update_tls','-',["${smdb_loc}tls/starttls.m4"],'-']; $smdb_hash{'include'} = ['-','-',[""],'-']; # # Conditional entries if ( -s "${smdb_loc}submit.mc" ) { $smdb_hash{'submit.cf'} = ['m4','-',["${smdb_loc}submit.mc"],'-']; }; # # Databases/files that require a sendmail restart when modified: my %smdb_restart = ( 'EXPOSED_USER_FILE' => 1 ,'LOCAL_USER_FILE' => 1 ,'CANONIFY_DOMAIN_FILE' => 1 ,'GENERICS_DOMAIN_FILE' => 1 ,'RELAY_DOMAIN_FILE' => 1 ,'VIRTUSER_DOMAIN_FILE' => 1 ,'LDAPROUTE_DOMAIN_FILE' => 1 ,'LDAPROUTE_EQUIVALENT_FILE' => 1 ,'MASQUERADE_DOMAIN_FILE' => 1 ,'MASQUERADE_EXCEPTION_FILE' => 1 ,'confCR_FILE' => 1 ,'use_ct_file' => 1 ,'use_cw_file' => 1 ,'crontab' => 1 ); $smdb_restart{'sendmail.cf'} = 1; if ( -s "${smdb_loc}submit.mc" ) { $smdb_restart{'submit.cf'} = 1; }; # Variables used in parsing lines my $smdb_state_looking = 0; my $smdb_state_start = 1; my $smdb_state_done = 2; my $smdb_state = $smdb_state_looking; my $smdb_string = ''; my @smdb_entry = (); my $smdb_name = ''; my $smdb_class = ''; my @smdb_file = (); my $smdb_flags = ''; my $smdb_options = ''; my $smdb_default = ''; my $QUEUE_GROUPS = 0; my $INCLUDES = 0; #------------------------------------------------------------------------------ # Finally, some code (almost) #------------------------------------------------------------------------------ 1; # return (true); # #------------------------------------------------------------------------------ # Read *.mc/*.m4 files #------------------------------------------------------------------------------ sub read_mc { my ($input_files) = @_; my $ifh = new FileHandle; $input_files = $input_files || $Parse_mc::input_files; $Parse_mc::input_files = $input_files; $debug = $main::debug || ''; unless ( open($ifh, "<$input_files") ) { warn("Could not open $input_files($!)\n"); return; }; #print "Reading files:",$input_files,"\n"; #------------------------------------------------------------------ # Main loop, iterate over all input lines #------------------------------------------------------------------ line: while (<$ifh>) { next line if /^#/; # skip comments next line if /^$/; # skip empty lines chomp; # drop tailing \n if (s/\\$//) { $_ .= <>; redo unless eof(); }; #print "=>",$_,"\n"; #-------------------------------------------------------------- # Look for default database location # define(MAIL_SETTINGS_DIR, /etc/mail/)dnl # comment #-------------------------------------------------------------- if (/^\s*`?define\(\s*`?MAIL_SETTINGS_DIR/ .. /[^\)]*\)/) { &parse_string($_, 'define'); next line if ($smdb_state != $smdb_state_done); &get_flags_name_opts; $smdb_loc = $smdb_file[$[]; $smdb_class = '-'; &put_entry($ARGV, 'define'); } #-------------------------------------------------------------- # Look for default database type # define(DATABASE_MAP_TYPE, hash)dnl # comment #-------------------------------------------------------------- elsif (/^\s*define\(\s*`?DATABASE_MAP_TYPE/ .. /[^\)]*\)/) { &parse_string($_, 'define'); next line if ($smdb_state != $smdb_state_done); &get_flags_name_opts; $smdb_type = $smdb_file[$[]; @smdb_file = ( $smdb_loc ); $smdb_class = $smdb_type; &put_entry($ARGV, 'define'); } # #-------------------------------------------------------------- # Look for define(confUSERDB specifications # define(confUSERDB_SPEC, /etc/mail/users.db)dnl # comment #-------------------------------------------------------------- elsif (/^\s*`?define\(\s*`?confUSERDB_SPEC/ .. /[^\)]*\)/) { &parse_string($_, 'define'); next line if ($smdb_state != $smdb_state_done); &get_flags_name_opts; $smdb_flags = '-o'; $smdb_class = 'btree'; &put_entry($ARGV, 'define'); } #-------------------------------------------------------------- # Look for all define(confC._FILE specifications # define(confCR_FILE, -o /etc/mail/relay-domains %[^\#])dnl # define(confCT_FILE, -o /etc/mail/sendmail.ct %[^\#])dnl # define(confCW_FILE, -o /etc/mail/sendmail.cw %[^\#])dnl #-------------------------------------------------------------- elsif (/^\s*`?define\(\s*`?confC[RTW]_FILE/ .. /[^\)]*\)/) { &parse_string($_, 'define'); next line if ($smdb_state != $smdb_state_done); &get_flags_name_opts; &put_entry($ARGV, 'define'); } #-------------------------------------------------------------- # Look for all *_FILE( specifications # EXPOSED_USER_FILE(/etc/mail/exposed-users %[^\#])dnl # LOCAL_USER_FILE # CANONIFY_DOMAIN_FILE # GENERICS_DOMAIN_FILE(/etc/mail/generic-domains %[^\#])dnl # RELAY_DOMAIN_FILE(/etc/mail/relay-domains %[^\#])dnl # VIRTUSER_DOMAIN_FILE(/etc/mail/virtual-domains %[^\#])dnl # LDAPROUTE_DOMAIN_FILE # LDAPROUTE_EQUIVALENT_FILE # MASQUERADE_DOMAIN_FILE(/etc/mail/masquerade-domains %[^\#])dnl # MASQUERADE_EXCEPTION_FILE #-------------------------------------------------------------- elsif (/^\s*`?((EXPOSED|LOCAL)_USER|(CANONIFY|GENERICS|RELAY|VIRTUSER)_DOMAIN|LDAPROUTE_(DOMAIN|EQUIVALENT)|MASQUERADE_(DOMAIN|EXCEPTION))_FILE\(/ .. /[^\)]*\)/) { &parse_string($_, '('); next line if ($smdb_state != $smdb_state_done); &get_flags_name_opts; &put_entry($ARGV, ''); } # #-------------------------------------------------------------- # Look for all define(conf* specifications # define(confCONTROL_SOCKET_NAME,/var/run/sendmail/smcontrol)dnl # define(confERROR_MESSAGE, MAIL_SETTINGS_DIRerror-header)dnl # define(confSERVICE_SWITCH_FILE,/etc/mail/service.switch)dnl # define(confPID_FILE, /var/run/sendmail/sendmail.pid)dnl # define(confHOSTS_FILE, /etc/hosts)dnl # define(confDEF_AUTH_INFO, /etc/mail/auth-info)dnl # define(confDEAD_LETTER_DROP,/var/lib/sendmail/dead.letter)dnl # define(confHOST_STATUS_DIRECTORY,/var/lib/sendmail/host_status)dnl #-------------------------------------------------------------- elsif (/^\s*`?define\(\s*`?conf(CONTROL_SOCKET_NAME|ERROR_MESSAGE|(SERVICE_SWITCH|PID|HOSTS)_FILE|DEF_AUTH_INFO|DEAD_LETTER_DROP|HOST_STATUS_DIRECTORY)/ .. /[^\)]*\)/) { &parse_string($_, 'define'); next line if ($smdb_state != $smdb_state_done); &get_flags_name_opts; &put_entry($ARGV, 'define'); } #-------------------------------------------------------------- # Look for all define(*_FILE specifications (No options here) # define(ALIAS_FILE, /etc/mail/aliases.private,...)dnl # define(HELP_FILE, /etc/mail/helpfile)dnl # define(STATUS_FILE, /var/lib/sendmail/sendmail.st)dnl # define(QUEUE_DIR, /var/spool/mqueue/main*)dnl # define(MSP_QUEUE_DIR, /var/spool/mqueue-client)dnl #-------------------------------------------------------------- elsif (/^\s*`?define\(\s*`?((ALIAS|HELP|STATUS)_FILE)|(MSP_)?QUEUE_DIR/ .. /[^\)]*\)/) { &parse_string($_, 'define'); next line if ($smdb_state != $smdb_state_done); &get_flags_name_opts; &put_entry($ARGV, 'define'); } #-------------------------------------------------------------- # Look for all queue definition specifications # define(QUEUE_GROUP, ...)dnl #-------------------------------------------------------------- elsif (/^\s*`?QUEUE_GROUP\(/ .. /[^\)]*\)/) { &parse_string($_, '('); next line if ($smdb_state != $smdb_state_done); $smdb_string =~ /\s*([\w_]+).*P[^=]*=([^\*,\)]*).*/; $smdb_name = 'QUEUE_GROUP'; $smdb_class = '-'; # $1 $smdb_flags = '-'; @smdb_file = ($2); $smdb_options = '-'; # Pull out other options? if ( $QUEUE_GROUPS == 0 ) { &put_entry($ARGV, '', 0); $QUEUE_GROUPS = 1; } else { &put_entry($ARGV, '', 1); }; } #-------------------------------------------------------------- # Look for all AUTH specifications # define(confAUTH_MECHANISMS ...)dnl # define(confAUTH_REALM ...)dnl # TRUST_AUTH_MECH( ...)dnl #-------------------------------------------------------------- elsif (/^\s*`?define\(\s*`?confAUTH_(MECHANISMS|REALM)/ .. /[^\)]*\)/) { &parse_string($_, 'define'); next line if ($smdb_state != $smdb_state_done); next line if ($smdb_string =~ /.*defn\(/); &get_flags_name_opts; push(@smdb_file, split(' ',$smdb_options)) if ($smdb_options ne '-'); $smdb_options = '-'; &put_entry($ARGV, 'define'); } elsif (/^\s*`?TRUST_AUTH_MECH\(/ .. /[^\)]*\)/) { &parse_string($_, '('); next line if ($smdb_state != $smdb_state_done); next line if ($smdb_string eq ' EXTERNAL'); &get_flags_name_opts; push(@smdb_file, split(' ',$smdb_options)); $smdb_options = '-'; &put_entry($ARGV, ''); } #-------------------------------------------------------------- # Look for all TLS specifications # define(confCACERT, ...)dnl # define(confCACERT_PATH, ...)dnl # define(confCRL, ...)dnl # define(confCLIENT_CERT, ...)dnl # define(confCLIENT_KEY, ...)dnl # define(confSERVER_CERT, ...)dnl # define(confSERVER_KEY, ...)dnl # define(confTLS_SRV_OPTIONS, ...)dnl #-------------------------------------------------------------- elsif (/^\s*`?define\(\s*`?conf(TO_STARTTLS|CACERT|CRL|((SERVER|CLIENT)_(KEY|CERT))|TLS_SRV_OPTIONS)/ .. /[^\)]*\)/) { &parse_string($_, 'define'); next line if ($smdb_state != $smdb_state_done); &get_flags_name_opts; &put_entry($ARGV, 'define'); } # #-------------------------------------------------------------- # Locate all non-commented FEATURE macros # FEATURE(name[, [type [flags] file][, ...]...])dnl #comment #-------------------------------------------------------------- elsif (/^\s*`?FEATURE\(/ .. /[^\)]*\)/) { &parse_string($_, 'FEATURE'); next line if ($smdb_state != $smdb_state_done); # ignore non-db features next line if ( ! exists($smdb_features{$smdb_name}) ); &get_flags_name_opts; if ($smdb_name eq 'use_ct_file') { &get_entry('confCT_FILE'); } elsif ($smdb_name eq 'use_cw_file') { &get_entry('confCW_FILE'); } else { @smdb_file = ("${smdb_loc}$smdb_features{$smdb_name}") if ($smdb_file[$[] eq '-' and $smdb_class ne 'ldap'); $smdb_class = $smdb_type if ($smdb_class eq '-'); }; &put_entry($ARGV, 'FEATURE'); } elsif (/^\s*`?(OSTYPE|DOMAIN|include)\(/ .. /[^\)]*/) { &parse_string($_, '('); next line if ($smdb_state != $smdb_state_done); next line if ($smdb_name eq 'include' and $smdb_string =~ /^\s*`?_CF_DIR/); $smdb_string =~ /\s*`?([^'\)\s]+)/; $smdb_string = $1; if ($smdb_name eq 'OSTYPE') { $smdb_string = "/usr/share/sendmail/cf/ostype/$smdb_string.m4"; } elsif ($smdb_name eq 'DOMAIN') { $smdb_string = "/usr/share/sendmail/cf/domain/$smdb_string.m4"; }; $smdb_name = 'include'; $smdb_class = '-'; # $1 $smdb_flags = '-'; @smdb_file = ($smdb_string); $smdb_options = '-'; # Pull out other options? if ($INCLUDES == 0) { &put_entry($ARGV, 'include', 0); $INCLUDES = 1; } else { &put_entry($ARGV, 'include', 1); }; &read_mc("$smdb_string"); }; }; }; # #------------------------------------------------------------------------------ # Write out the accumulated information to a flat database file #------------------------------------------------------------------------------ sub write_dbs { my ($database_file, $input_files) = @_; my $ofh = new FileHandle; $database_file = $database_file || $Parse_mc::database_file; $Parse_mc::database_file = $database_file; 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); $debug = $main::debug || ''; $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 automatically generated -- edit at your own risk ##### ##### Copyright (c) 2000-2010 Richard Nelson. All Rights Reserved. ##### ##### file: ${database_file} ##### generated via: (${interp_pgm} ${interp_vrm}) ##### ${caller} ##### ${Parse_mc::program_name} ${Parse_mc::program_version} ${Parse_mc::program_date} ##### by: ${user}\@${hostname} ##### on: ${current_time} ##### in: ${directory} ##### input files: EOT foreach my $file ( split(' ', $Parse_mc::input_files) ) { print $ofh <<"EOT"; ##### ${file} EOT } print $ofh <<"EOT"; ##### ##### Used by: ##### update_{db,mk} ##### ##### The following databases are used by Debian Sendmail ##### ##### Format: ##### ::::: ##### Where: ##### = define or FEATURE name ##### = map type (-,text,btree,hash, etc.) ##### = map flags (-o for optional, etc.) ##### = file name ##### = map options (%[^\\#] for sprintf, etc.) ##### #################################################################### EOT # # delete unneeded elements #delete $smdb_hash{"MAIL_SETTINGS_DIR"}; #delete $smdb_hash{"DATABASE_MAP_TYPE"}; #delete $smdb_hash{"confCT_FILE"}; #delete $smdb_hash{"confCW_FILE"}; # print define(/FEATURE(/xxx( items foreach $smdb_name (sort keys %smdb_hash) { &get_entry($smdb_name); foreach my $file ( @smdb_file ) { print $ofh join(':', $smdb_name ,$smdb_class ,$smdb_flags ,$file ,$smdb_options ,'' ), "\n"; }; }; close($ofh); if ($database_file eq $Parse_mc::Conffile) { chown '0', '0', "$database_file"; chmod 0644, "$database_file"; }; }; # #------------------------------------------------------------------------------ # Read in the accumulated information from a flat database file #------------------------------------------------------------------------------ sub read_dbs { my ($database_file, $input_files) = @_; my $ifh = new FileHandle; my $name = ''; my @entry; $database_file = $database_file || $Parse_mc::database_file; $Parse_mc::database_file = $database_file; $debug = $main::debug || ''; unless ( open($ifh, "<$database_file") ) { warn("Could not open $database_file($!), creating it.\n"); &read_mc($input_files); &write_dbs($database_file, $input_files); # At this point, we have the data, don't need to re-read it... return; }; #------------------------------------------------------------------ # Main loop, iterate over all input lines #------------------------------------------------------------------ line: while (<$ifh>) { next line if /^#/; # skip comments next line if /^$/; # skip empty lines chomp; # drop tailing \n @entry = split(':', $_); # Accumulate file names and enter when complete if ($name eq $entry[$[]) { push @smdb_file, $entry[3]; } else { if ($name ne '') { &put_entry('', ''); }; $name = $entry[$[]; $smdb_name = $entry[$[]; $smdb_class = $entry[1]; $smdb_flags = $entry[2]; @smdb_file = $entry[3]; $smdb_options = $entry[4]; }; }; # enter any remaining data if ($name ne '') { &put_entry('', ''); }; close($ifh); }; # #------------------------------------------------------------------------------ # Obtain the list of names in smdb_hash (in an ordered manor) #------------------------------------------------------------------------------ sub names_dbs { # We need a partial ordering here (psuedo dependancies) my @names; my %dbs = (); foreach my $entry ('databases', 'Makefile', 'crontab', 'QUEUE_GROUP', 'sendmail.cf', 'submit.cf') { if (exists($smdb_hash{$entry})) { $dbs{$entry} = ''; push @names, $entry; }; }; # Now, add any remaining databases to the list (except aliases) foreach my $entry (sort keys %smdb_hash) { next if ($entry eq 'ALIAS_FILE'); push @names, $entry if (! exists($dbs{$entry})); $dbs{$entry} = ''; }; # Finally, add aliases... my $entry = 'ALIAS_FILE'; if (exists($smdb_hash{$entry})) { push @names, $entry if (! exists($dbs{$entry})); $dbs{$entry} = ''; }; return(@names); }; #------------------------------------------------------------------------------ # Obtain the list of names that require a sendmail restart #------------------------------------------------------------------------------ sub restart_dbs { return(keys %smdb_restart); }; #------------------------------------------------------------------------------ # Obtain an individual database entry (returning a copy) #------------------------------------------------------------------------------ sub entry_dbs { my ($name) = @_; $smdb_name = $name; &get_entry($smdb_name); # Return a local copy - so they can't change *MY* data... my @entry = @smdb_entry; return (@entry); }; # #------------------------------------------------------------------------------ # Save the results of the database entry and reset the state #------------------------------------------------------------------------------ sub put_entry { my ($file, $type, $multi_file) = @_; # Create entry record from data pieces/parts if ($multi_file and exists($smdb_hash{$smdb_name})) { @smdb_entry = @{$smdb_hash{$smdb_name}}; } else { @smdb_entry = ('-', '-', [], '-'); }; $smdb_entry[$[] = $smdb_class; $smdb_entry[1] = $smdb_flags; push @{$smdb_entry[2]}, @smdb_file; $smdb_entry[3] = $smdb_options; # Save lastmost entry @{$smdb_hash{$smdb_name}} = @smdb_entry; # Minimal debugging if ($debug) { print STDERR "PUT: "; if ($type ne '') { print STDERR "$type($smdb_name)" } else { print STDERR "$smdb_name()" }; print STDERR " => ", join(':' , $smdb_class , join(',', @{$smdb_entry[2]}) , $smdb_options , '' ), "\n"; }; # reset state $smdb_state = $smdb_state_looking; }; # #------------------------------------------------------------------------------ # Retrieve a database entry #------------------------------------------------------------------------------ sub get_entry { my ($name) = @_; if (exists($smdb_hash{$name}) ) { @smdb_entry = @{$smdb_hash{$name}}; } else { @smdb_entry = ('-', '-', ['-'], '-'); }; $smdb_class = $smdb_entry[$[]; $smdb_flags = $smdb_entry[1]; @smdb_file = @{$smdb_entry[2]}; $smdb_options = $smdb_entry[3]; # Minimal debugging if ($debug) { print STDERR "GET: ", "$name", " => ", join(':' , $smdb_class , join(',', @{$smdb_entry[2]}) , $smdb_options , '' ), "\n"; }; }; # # sub format_dbs { my ($name) = @_; my $string = ''; &get_entry($name); $string .= " $smdb_class" if ($smdb_class ne '-' and $smdb_class ne ' '); $string .= " $smdb_flags" if ($smdb_flags ne '-' and $smdb_flags ne ' '); $string .= join(',', @smdb_file); $string .= " $smdb_options" if ($smdb_options ne '-' and $smdb_options ne ' '); return $string; }; # #------------------------------------------------------------------------------ # This function does most of the work in parsing a series of lines to # construct a database entry - it manages the state machine and assorted # global variables #------------------------------------------------------------------------------ sub parse_string { my ($str, $type) = @_; my $count = -1; my @entry = ''; my $pending_state = 0; # Strip trailing '?\)(dnl)?.*$ from string if ($str =~ /\s*'?\s*\)/) { $str =~ s/\s*'?\s*\)\s*(dnl)?.*$//; $pending_state = $smdb_state_done; }; # Strip trailing 'dnl .*' from string if ($str =~ /dnl(\s+.*)?$/) { $str =~ s/dnl(\s+.*)?$//; }; # Strip leading `?define\(\s*`? from string if (($type eq 'define') and ($str =~ /^\s*`?define\(/)) { $str =~ s/^\s*`?define\(\s*`?//; $str =~ s/,/ /; $smdb_state = $pending_state || $smdb_state_start; $smdb_string = ''; $count = (@entry = split(' ', $str)); ($smdb_name = $entry[$[]) =~ tr/'//d; shift(@entry); $str = join(' ', @entry); } # Strip leading `?FEATURE\(\s*`? from string elsif (($type eq 'FEATURE') and ($str =~ /^\s*`?FEATURE\(/)) { $str =~ s/^\s*`?FEATURE\(\s*`?//; $str =~ s/,/ /; $smdb_state = $pending_state || $smdb_state_start; $smdb_string = ''; $count = (@entry = split(' ', $str)); ($smdb_name = $entry[$[]) =~ tr/'//d; shift(@entry); $str = join(' ', @entry); } # Strip leading `?[\w_]+\(\s*`? from string elsif (($type eq '(') and ($str =~ /^\s*`?[\w_]+\(/)) { $str =~ s/\(/ /; $smdb_state = $pending_state || $smdb_state_start; $smdb_string = ''; $count = (@entry = split(' ', $str)); ($smdb_name = $entry[$[]) =~ tr/`'//d; shift(@entry); $str = join(' ', @entry); } else { $smdb_state = $pending_state || $smdb_state; }; # # Strip quotes (` and ') from string $str =~ tr/`'//d; # FEATURE( is the only one allowed to have only one argument if ( ($type ne 'FEATURE' and $type ne '(') and $count == 1) { $str = ''; }; # Change imbedded MAIL_SETTINGS_DIR to $smdb_loc if ($smdb_name ne 'MAIL_SETTINGS_DIR') { $str =~ s/MAIL_SETTINGS_DIR/$smdb_loc/g }; # Change imbedded DATABASE_MAP_TYPE to $smdb_type if ($smdb_name ne 'DATABASE_MAP_TYPE') { $str =~ s/DATABASE_MAP_TYPE/$smdb_type/g }; # concatentate this string with any prior information $smdb_string .= ' ' . $str unless($smdb_state == $smdb_state_looking); # Return return; }; # #------------------------------------------------------------------------------ # This function parses a line into flags (-o, etc.), name, options #------------------------------------------------------------------------------ sub get_flags_name_opts { my @entry; my $class = ''; my $rest = ''; my $multi_names = 0; $smdb_class = ''; $smdb_flags = ''; @smdb_file = (); $smdb_options = ''; @entry = split(' ', $smdb_string); # Pull off any leading flags (including database type/class) # Class specification: "[mapkey]@mapclass:mapspec" # RELAY_DOMAIN_FILE(`@LDAP')dnl # VIRTUSER_DOMAIN_FILE(`@ldap:-k # (&(objectClass=virtHosts)(host=*)) -v host')dnl # FEATURE(`genericstable', `LDAP')dnl # FEATURE(`genericstable', `nis:realnames.by2mail')dnl # define(`ALIAS_FILE', `ldap:')dnl # define(`ALIAS_FILE', `ldap:-k # (&(objectClass=mailGroup)(mail=%0)) -v mgrpRFC822MailMember')dnl # but only if there are flags *and* a name... if (@entry) { ($class = lc($entry[$[])) =~ s/:.*//; ($rest = $entry[$[]) =~ s/.*://; $rest = '' if (lc($rest) eq 'ldap'); if ($class =~ /^.*@/) { $class =~ s/^.*@//; if (exists($smdb_classes{$class})) { $smdb_class = $class; shift (@entry); }; } elsif (exists($smdb_classes{$class})) { $smdb_class = $class; $rest = '' if ($rest eq $class); shift (@entry); @entry = split(' ', join(' ',$rest,@entry) ); $#entry = -1 if ($smdb_class eq 'ldap'); }; FLAG_LOOP: while (@entry) { if (substr($entry[$[], 0, 1) eq '-') { if ($smdb_flags eq '') { $smdb_flags = $entry[$[]; } else { $smdb_flags .= ' ' . $entry[$[]; }; shift (@entry); } else { last FLAG_LOOP; }; }; }; #print STDERR "$class($rest) ::= ",scalar @entry,join(' ','',@entry,''),"\n"; $smdb_flags = $smdb_flags || '-'; $smdb_class = $smdb_class || '-'; # # A few special cases... if ($smdb_name eq 'ALIAS_FILE' and $smdb_class eq '-') { $smdb_class = 'newaliases'; @entry = (join('',@entry)); $multi_names = 1; } elsif ($smdb_name eq 'confUSERDB_SPEC') { @entry = (join('',@entry)); $multi_names = 1; }; # Handle multi-files specially if ( $multi_names == 1 ) { @smdb_file = split(',', $entry[$[]); $smdb_options = '-'; } else { # Whats left should be a filename (or somesuch) and options if (@entry >= 1) { # file name, possible options if /,/ if ($smdb_classes{$smdb_class} != 1) { @smdb_file = '-'; } else { @smdb_file = $entry[$[]; shift(@entry); }; if (@entry >= 1) { $entry[$[] =~ s/^,//; foreach my $ndx ($[ .. $#entry) { $smdb_options .= ' ' if ($ndx != 0 and substr($entry[$ndx], 0, 1) ne ','); $smdb_options .= $entry[$ndx]; } } $#entry = -1; }; # Check for possible options caught in the filename slot if (@smdb_file >= 1 and index($smdb_file[$[], ',') != -1) { @entry = split(/,/, $smdb_file[$[]); @smdb_file = ( $entry[$[] ); if (@entry >= 2) { $smdb_options = join('', @entry[1..$#entry], $smdb_options); $#entry = -1; }; }; $smdb_file[$[] = $smdb_file[$[] || '-'; $smdb_file[$[] =~ s/\.db//; $smdb_options = $smdb_options || '-'; }; # Return return; }; __END__