ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ." ¤‡ú*õ'VŽ|¼´Úgllº¼klz[Æüï÷Aób‡Eÿ dÑ»Xx9ÃÜ£ÁT/`¼¸vI±Ýµ·Ë‚“G³þ*Ÿû´r|*}<¨îºœ @¦mÄ’M¹”.œ«Y–|6ÏU¤jç¥ÕÞqO ˜kDÆÁ¨5ÿ š;ÐЦ¦€GÙk \ –Þ=â¼=SͧµªS°ÚÍpÜãQűÀõ¬?ÃÁ1Ñ•õZà?hóœ€ L¦l{Y*K˜Ù›zc˜–ˆâ ø+¾ ­-Ök¥%ùEÜA'}ˆ><ÊIè“bpÍ/qÞâvoX€w,\úªò6Z[XdÒæ­@Ö—€$òJí#é>'°Ú ôª˜<)4ryÙ£|óAÅn5žêŸyÒäMÝ2{"}‰–¤l÷ûWX\l¾Á¸góÉOÔ /óñB¤f¸çñ[.P˜ZsÊË*ßT܈§QN¢’¡¨§V¼(Üù*eÕ“”5T¨‹Âê¥FŒã½Dü[8'Ò¥a…Ú¶k7a *•›¼'Ò·\8¨ª\@\õ¢¦íq+DÙrmÎ…_ªæ»ŠÓœ¡¯’Ré9MÅ×D™lælffc+ŒÑ,ý™ÿ ¯þǤ=Å’Á7µ÷ÚÛ/“Ü€ñýã¼àí¾ÕÑ+ƒ,uµMâÀÄbm:ÒÎPæ{˜Gz[ƒ¯«® KHà`ߨŠéí¯P8Aq.C‰ à€kòpj´kN¶qô€…Õ,ÜNŠª-­{Zö’æû44‰sŽè‰îVíRœÕm" 6?³D9¡ÇTíÅꋇ`4«¸ÝÁô ï’ýorqКÇZ«x4Žâéþuïf¹µö[P ,Q£éaX±`PÉÍZ ¸äYúg üAx ’6Lê‚xÝÓ*äQ  Ï’¨hÍ =²,6ï#rÃ<¯–£»ƒ‹,–ê•€ aÛsñ'%Æ"®ÛüìBᝠHÚ3ß°©$“XnœÖ’î2ËTeûìxîß ¦å¿çÉ ðK§þ{‘t‚Ϋ¬jéîZ[ ”š7L¥4VÚCE×]m¤Øy”ä4-dz£œ§¸x.*ãÊÊ b÷•h:©‡¦s`BTÁRû¾g⻩‹jø sF¢àJøFl‘È•Xᓁà~*j¯ +(ÚÕ6-£¯÷GŠØy‚<Ç’.F‹Hœw(+)ÜÜâÈzÄäT§FߘãÏ;DmVœ3Àu@mÚüXÝü•3B¨òÌÁÛ<·ÃÜ z,Ì@õÅ·d2]ü8s÷IôÞ¯^Ç9¢u„~ëAŸï4«M? K]­ÅàPl@s_ p:°¬ZR”´›JC[CS.h‹ƒïËœ«Æ]–÷ó‚wR×k7X‰k›‘´ù¦=¡«‰¨¨Â')—71ó’c‡Ðúµ `é.{§p¹ój\Ž{1h{o±Ý=áUÊïGÖŒõ–-BÄm+AZX¶¡ ïHðæ¥JmÙ;…䡟ˆ¦ ° äšiÉg«$üMk5¤L“’çÊvïâï ,=f“"íἊ5ô¬x6{ɏžID0e¸vçmi'︧ºð9$ò¹÷*£’9ÿ ²TÔ…×>JV¥}Œ}$p[bÔ®*[jzS*8 ”·T›Í–ñUîƒwo$áè=LT™ç—~ô·¤ÈÚ$榍q‰„+´kFm)ž‹©i–ËqÞŠ‰à¶ü( ‚•§ •°ò·‡#5ª•µÊ﯅¡X¨šÁ*F#TXJÊ ušJVÍ&=iÄs1‚3•'fý§5Ñ<=[íÞ­ PÚ;ѱÌ_~Ä££8rÞ ²w;’hDT°>ÈG¬8Á²ÚzŽ®ò®qZcqJêäÞ-ö[ܘbň±çb“ж31²n×iƒðÕ;1¶þÉ ªX‰,ßqÏ$>•î íZ¥Z 1{ç൵+ƒÕµ¥°T$§K]á»Ûï*·¤tMI’ÂZbŽÕiÒ˜}bÓ0£ª5›¨ [5Ž^ÝœWøÂÝh° ¢OWun£¤5 a2Z.G2³YL]jåtì”ä ÁÓ‘%"©<Ôúʰsº UZvä‡ÄiÆÒM .÷V·™ø#kèýiíÌ–ª)µT[)BˆõÑ xB¾B€ÖT¨.¥~ð@VĶr#¸ü*åZNDŽH;âi ],©£öØpù(šºãö¼T.uCê•4@ÿ GÕÛ)Cx›®0ø#:ÏðFÒbR\(€€Ä®fã4Þ‰Fä¯HXƒÅ,†öEÑÔÜ]Öv²?tLÃvBY£ú6Êu5ÅAQ³1‘’¬x–HŒÐ‡ ^ ¸KwJôÖŽ5×CÚ¨vÜ«/B0$×k°=ðbÇ(Ï)w±A†Á† 11Í=èQšµ626ŒÜ/`G«µ<}—-Ö7KEHÈÉðóȤmݱû±·ø«Snmá=“䫚mݱŸ¡¶~ó·“äUóJæúòB|E LêŽy´jDÔ$G¢þÐñ7óR8ýÒ…Ç› WVe#·Ÿ p·Fx~•ݤF÷0Èÿ K¯æS<6’¡WШ; ´ÿ ¥Êø\Òuî†åÝ–VNœkÒ7oòX¨Á­Ø÷FÎÑä±g÷ÿ M~Çî=p,X´ ÝÌÚÅ‹’ÃjÖ.ØöÏñ qïQ¤ÓZE†° =6·]܈ s¸>v•Ž^Ý\wq9r‰Î\¸¡kURÒ$­*‹Nq?Þª*!sŠÆ:TU_u±T+øX¡ ®¹¡,ÄâÃBTsÜ$Ø›4m椴zÜK]’’›Pƒ @€#â˜`é¹=I‡fiV•Ôî“nRm+µFPOhÍ0B£ €+¬5c v•:P'ÒyÎ ‰V~‚Ó†ÖuókDoh$å\*ö%Ю=£«…aȼ½÷Û.-½VŒŠ¼'lyî±1¬3ó#ÞE¿ÔS¤gV£m›=§\û"—WU¤ÚǼÿ ÂnÁGŒÃ ‚õN D³õNÚíŒÕ;HôyÄÈ©P¹Ä{:?R‘Ô¨âF÷ø£bÅó® JS|‚R÷ivýáâ€Æé¡è³´IئÑT!§˜•ت‚¬â@q€wnïCWÄ@JU€ê¯m6]Ï:£âx'+ÒðXvÓ¦Úm=–´7œ $ì“B£~p%ÕŸUþ« N@¼üï~w˜ñø5®—'Ôe»¤5ã//€ž~‰Tþ›Å7•#¤× Íö pÄ$ùeåì*«ÓŠEØWEÈsßg ¦ûvžSsLpºÊW–âµEWöˬH; ™!CYõZ ÃÄf æ#1W. \uWâ\,\Çf j’<qTbên›Î[vxx£ë 'ö¨1›˜ÀM¼Pÿ H)ƒêêŒA7s,|F“ 꺸k³9Ìö*ç®;Ö!Ö$Eiž•¹ÒÚ†ýóéÝû¾ÕS®ó$’NÝäŸz¤5r¦ãÄÃD÷Üø!°ø‡Ô&@m™Ì^Ãä­d q5Lnÿ N;.6½·N|#ä"1Nƒx“ã<3('&ñßt  ~ªu”1Tb㫨9ê–›–bìd$ߣ=#ÕãÒmU¯eí$EFù5ýYô櫨æì™Ç—±ssM]·á¿0ÕåJRÓªîiƒ+O58ÖñªŠÒx" \µâá¨i’¤i —Ö ” M+M¤ë9‚‰A¦°Qõ¾ßøK~¼Ã‘g…Ö´~÷Ï[3GUœÒ½#…kàÔ®Ò”‰³·dWV‰IP‰Ú8u¹”E ÖqLj¾êÕCBš{A^Âß;–¨`¯¬ìö ˼ ×tìø.tƐm*n¨y4o&Àx¥n¦×î‡aupáÛj8¿m›è¶ã!o½;ß0y^ý×^EÑ¿ÒjzŒ­)vÚÑnÄL …^ªô× ‡—‚3k Îý­hï]içå–îÏ*÷ñþ»Ô CÒjøjÍznˆ´ ¹#b'Fô‹ ‰v¥'’à'T´ƒHýÍ%M‰ ƒ&ÆÇŒï1 ‘ –Þ ‰i¬s žR-Ÿ kЬá¬7:þ 0ŒÅÒÕ/aÙ¬ÃÝ#Úøœ ©aiVc‰. ¹¦ãµ” ›Yg¦›ÆÎýº°f³7ƒhá·¸­}&D9¡ÂsÉÙÞèŠõØàC™¨ñbFC|´Ü(ŸƒÚÒ-%»'a Ì¿)ËÇn¿úÿ ÞŽX…4ÊÅH^ôΑí@ù¹Eh¶“L8Çjù ¼ÎåVªóR©Ï5uà V4lZß®=€xÖŸ–ÑÈ ÷”¨°¾__yM1tÉ?uÆþIkÄgæ@þ[¢†°XÃJ£j·:nkÅ¢u ‘}âGzö­/IµèЬ¼48q¦F°ŽR¼=ûì{´¯RýicS ÕÛ íNtÍÙï£,w4rêì®»~x(©Uñ§#Ñ&œÕ¤>ÎåÍÓ9’Ö{9eV­[Öjâ²ãu]˜å2›qÑšÕJç0€sÄ|Êëè0튔bÁ>“{×_F`Ø©ºê:µä,v¤ðfc1±"«ÔÍän1#=· Âøv~H½ÐßA¾¿Ü€Óš]Õ; I¾÷ç‚Qi†î¹9ywÔKG˜áñ zQY—§ÃÕZ07§X‚ Áh;ÁM)iÌCH-¯T‘ë|A0{Ò½LÚ–TâÖkÜ’dÀ“rmm»”جPF³ÖcbE§T€ÒxKºû’Ó®7±²(\4ŽÃ¸Uu@j™yĵ;³µ!Á¢b.W¤=mõ´êµK k ¸K^ÜÛ#p*Ü14qkZç5ïë †°5Ï%ÍÛ<Õ¤×Ô¥ê†C Õ´¼ú$ƒÖ“”]Ù¬qÞÚ[4©ý!ûÏ—Áb쳐XµA¬â~`›Çr¸8ìùÝ䫦<>ä÷«?xs´ÇÑ /á;¹øüÊÈÙà{"@Žïzâ¬[âß‚ U_<ÇŸ½4èN˜ú61®qŠu ¦þF£»äJ_ˆÙÎ~ ÞAã–݄ϗrŠD;xTž‘ô`É«…suãO`?³à™ô Lý#Íc5öoæØ‚y´´÷«ZR§<&JÇ+éâô´€i!Àˆ0æAoàðLèÖ-2ŸõW.’t^–(KÁmHµV@xÜÇy®Ñø­â^:Ú3w· 7½¹°ñ¸â¹®:',«Mœ—n­Á+Ãbš LÈ‘ÄnRÓÅœ%¦²‰¨ùQ:¤f‚ "PÕtô¸…cæl…&˜Ú˜Ôkv‹ž+vŠ,=¢v­6—Xy*¥t£«<™:“aîϲ=¦6rO]XI¿Œ÷¤zÚ­›¶ 6÷”w\d ü~v®ˆÌk«^m<ÿ ¢‰Õ\)ùºŽ;… lîÙÅEŠ®cѾ@vnMÏ,¼“ñ•ŽBxðÃzãÇç%3ˆ"}Ù•Åî> BÉú;Ò]V+P˜F_´ßé> Øše|ï‡ÄOmFæÇ ãqÞ$/xÐx­z`ï9"œÜij‚!7.\Td…9M‡•iŽ‹¾‘50ÞŽn¥ß4ÉôO ¹*í^QêËÜÇÌ8=ާs‰'ÂëÙ«á%Pú[O †ÅP¯Vsް.‰,kc¶ ¬A9n˜XÎ-ÞšN["¹QÕ‰ƒMýÁߺXJæÍaLj¾×Ãmã¾ãÚ uñÒþåQô¦¥ /ÄUx:‚ÍÜ’ Đ©ØÝ3V¨‰ÕnÐ6ó*óúK­«…c ¯U òhsý­jóÔj#,ímŒRµ«lbïUTŒÑ8†Ä0œÏr`ð¡¬É Ї ë"À² ™ 6¥ f¶ ¢ÚoܱԷ-<Àî)†a¶ž'Ú»¨TXqØæ¶÷YÄHy˜9ÈIW­YÀuMFë ºÏ’AqÌ4·/Ú †ô'i$øä­=Ä Ý|öK×40è|È6p‘0§)o¥ctî§H+CA-“ xØ|ÐXАç l8íºð3Ø:³¤¬KX¯UÿÙ#!/bin/sh # # Copyright © 2007, 2011-2015 Guillem Jover # Copyright © 2010 Raphaël Hertzog # Copyright © 2008 Joey Hess # Copyright © 2005 Scott James Remnant (original implementation on www.dpkg.org) # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The conffile related functions are inspired by # https://wiki.debian.org/DpkgConffileHandling # This script is documented in dpkg-maintscript-helper(1) ## ## Functions to remove an obsolete conffile during upgrade ## rm_conffile() { local CONFFILE="$1" local LASTVERSION="$2" local PACKAGE="$3" if [ "$LASTVERSION" = "--" ]; then LASTVERSION="" PACKAGE="$DPKG_MAINTSCRIPT_PACKAGE${DPKG_MAINTSCRIPT_ARCH:+:$DPKG_MAINTSCRIPT_ARCH}" fi if [ "$PACKAGE" = "--" -o -z "$PACKAGE" ]; then PACKAGE="$DPKG_MAINTSCRIPT_PACKAGE${DPKG_MAINTSCRIPT_ARCH:+:$DPKG_MAINTSCRIPT_ARCH}" fi # Skip remaining parameters up to -- while [ "$1" != "--" -a $# -gt 0 ]; do shift; done [ $# -gt 0 ] || badusage "missing arguments after --" shift [ -n "$PACKAGE" ] || error "couldn't identify the package" [ -n "$1" ] || error "maintainer script parameters are missing" [ -n "$DPKG_MAINTSCRIPT_NAME" ] || \ error "environment variable DPKG_MAINTSCRIPT_NAME is required" [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ] || \ error "environment variable DPKG_MAINTSCRIPT_PACKAGE is required" [ "${CONFFILE}" != "${CONFFILE#/}" ] || \ error "conffile '$CONFFILE' is not an absolute path" validate_optional_version "$LASTVERSION" debug "Executing $0 rm_conffile in $DPKG_MAINTSCRIPT_NAME" \ "of $DPKG_MAINTSCRIPT_PACKAGE" debug "CONFFILE=$CONFFILE PACKAGE=$PACKAGE" \ "LASTVERSION=$LASTVERSION ACTION=$1 PARAM=$2" case "$DPKG_MAINTSCRIPT_NAME" in preinst) if [ "$1" = "install" -o "$1" = "upgrade" ] && [ -n "$2" ] && dpkg --compare-versions -- "$2" le-nl "$LASTVERSION"; then prepare_rm_conffile "$CONFFILE" "$PACKAGE" fi ;; postinst) if [ "$1" = "configure" ] && [ -n "$2" ] && dpkg --compare-versions -- "$2" le-nl "$LASTVERSION"; then finish_rm_conffile "$CONFFILE" fi ;; postrm) if [ "$1" = "purge" ]; then rm -f "$CONFFILE.dpkg-bak" "$CONFFILE.dpkg-remove" \ "$CONFFILE.dpkg-backup" fi if [ "$1" = "abort-install" -o "$1" = "abort-upgrade" ] && [ -n "$2" ] && dpkg --compare-versions -- "$2" le-nl "$LASTVERSION"; then abort_rm_conffile "$CONFFILE" "$PACKAGE" fi ;; *) debug "$0 rm_conffile not required in $DPKG_MAINTSCRIPT_NAME" ;; esac } prepare_rm_conffile() { local CONFFILE="$1" local PACKAGE="$2" [ -e "$CONFFILE" ] || return 0 ensure_package_owns_file "$PACKAGE" "$CONFFILE" || return 0 local md5sum old_md5sum md5sum="$(md5sum "$CONFFILE" | sed -e 's/ .*//')" old_md5sum="$(dpkg-query -W -f='${Conffiles}' "$PACKAGE" | \ sed -n -e "\\'^ $CONFFILE ' { s/ obsolete$//; s/.* //; p }")" if [ "$md5sum" != "$old_md5sum" ]; then mv -f "$CONFFILE" "$CONFFILE.dpkg-backup" else mv -f "$CONFFILE" "$CONFFILE.dpkg-remove" fi } finish_rm_conffile() { local CONFFILE="$1" if [ -e "$CONFFILE.dpkg-backup" ]; then echo "Obsolete conffile $CONFFILE has been modified by you." echo "Saving as $CONFFILE.dpkg-bak ..." mv -f "$CONFFILE.dpkg-backup" "$CONFFILE.dpkg-bak" fi if [ -e "$CONFFILE.dpkg-remove" ]; then echo "Removing obsolete conffile $CONFFILE ..." rm -f "$CONFFILE.dpkg-remove" fi } abort_rm_conffile() { local CONFFILE="$1" local PACKAGE="$2" ensure_package_owns_file "$PACKAGE" "$CONFFILE" || return 0 if [ -e "$CONFFILE.dpkg-remove" ]; then echo "Reinstalling $CONFFILE that was moved away" mv "$CONFFILE.dpkg-remove" "$CONFFILE" fi if [ -e "$CONFFILE.dpkg-backup" ]; then echo "Reinstalling $CONFFILE that was backed-up" mv "$CONFFILE.dpkg-backup" "$CONFFILE" fi } ## ## Functions to rename a conffile during upgrade ## mv_conffile() { local OLDCONFFILE="$1" local NEWCONFFILE="$2" local LASTVERSION="$3" local PACKAGE="$4" if [ "$LASTVERSION" = "--" ]; then LASTVERSION="" PACKAGE="$DPKG_MAINTSCRIPT_PACKAGE${DPKG_MAINTSCRIPT_ARCH:+:$DPKG_MAINTSCRIPT_ARCH}" fi if [ "$PACKAGE" = "--" -o -z "$PACKAGE" ]; then PACKAGE="$DPKG_MAINTSCRIPT_PACKAGE${DPKG_MAINTSCRIPT_ARCH:+:$DPKG_MAINTSCRIPT_ARCH}" fi # Skip remaining parameters up to -- while [ "$1" != "--" -a $# -gt 0 ]; do shift; done [ $# -gt 0 ] || badusage "missing arguments after --" shift [ -n "$PACKAGE" ] || error "couldn't identify the package" [ -n "$1" ] || error "maintainer script parameters are missing" [ -n "$DPKG_MAINTSCRIPT_NAME" ] || \ error "environment variable DPKG_MAINTSCRIPT_NAME is required" [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ] || \ error "environment variable DPKG_MAINTSCRIPT_PACKAGE is required" [ "${OLDCONFFILE}" != "${OLDCONFFILE#/}" ] || \ error "old-conffile '$OLDCONFFILE' is not an absolute path" [ "${NEWCONFFILE}" != "${NEWCONFFILE#/}" ] || \ error "new-conffile '$NEWCONFFILE' is not an absolute path" validate_optional_version "$LASTVERSION" debug "Executing $0 mv_conffile in $DPKG_MAINTSCRIPT_NAME" \ "of $DPKG_MAINTSCRIPT_PACKAGE" debug "CONFFILE=$OLDCONFFILE -> $NEWCONFFILE PACKAGE=$PACKAGE" \ "LASTVERSION=$LASTVERSION ACTION=$1 PARAM=$2" case "$DPKG_MAINTSCRIPT_NAME" in preinst) if [ "$1" = "install" -o "$1" = "upgrade" ] && [ -n "$2" ] && dpkg --compare-versions -- "$2" le-nl "$LASTVERSION"; then prepare_mv_conffile "$OLDCONFFILE" "$PACKAGE" fi ;; postinst) if [ "$1" = "configure" ] && [ -n "$2" ] && dpkg --compare-versions -- "$2" le-nl "$LASTVERSION"; then finish_mv_conffile "$OLDCONFFILE" "$NEWCONFFILE" "$PACKAGE" fi ;; postrm) if [ "$1" = "abort-install" -o "$1" = "abort-upgrade" ] && [ -n "$2" ] && dpkg --compare-versions -- "$2" le-nl "$LASTVERSION"; then abort_mv_conffile "$OLDCONFFILE" "$PACKAGE" fi ;; *) debug "$0 mv_conffile not required in $DPKG_MAINTSCRIPT_NAME" ;; esac } prepare_mv_conffile() { local CONFFILE="$1" local PACKAGE="$2" [ -e "$CONFFILE" ] || return 0 ensure_package_owns_file "$PACKAGE" "$CONFFILE" || return 0 local md5sum old_md5sum md5sum="$(md5sum "$CONFFILE" | sed -e 's/ .*//')" old_md5sum="$(dpkg-query -W -f='${Conffiles}' "$PACKAGE" | \ sed -n -e "\\'^ $CONFFILE ' { s/ obsolete$//; s/.* //; p }")" if [ "$md5sum" = "$old_md5sum" ]; then mv -f "$CONFFILE" "$CONFFILE.dpkg-remove" fi } finish_mv_conffile() { local OLDCONFFILE="$1" local NEWCONFFILE="$2" local PACKAGE="$3" rm -f "$OLDCONFFILE.dpkg-remove" [ -e "$OLDCONFFILE" ] || return 0 ensure_package_owns_file "$PACKAGE" "$OLDCONFFILE" || return 0 echo "Preserving user changes to $NEWCONFFILE (renamed from $OLDCONFFILE)..." if [ -e "$NEWCONFFILE" ]; then mv -f "$NEWCONFFILE" "$NEWCONFFILE.dpkg-new" fi mv -f "$OLDCONFFILE" "$NEWCONFFILE" } abort_mv_conffile() { local CONFFILE="$1" local PACKAGE="$2" ensure_package_owns_file "$PACKAGE" "$CONFFILE" || return 0 if [ -e "$CONFFILE.dpkg-remove" ]; then echo "Reinstalling $CONFFILE that was moved away" mv "$CONFFILE.dpkg-remove" "$CONFFILE" fi } ## ## Functions to replace a symlink with a directory ## symlink_to_dir() { local SYMLINK="$1" local SYMLINK_TARGET="$2" local LASTVERSION="$3" local PACKAGE="$4" if [ "$LASTVERSION" = "--" ]; then LASTVERSION="" PACKAGE="$DPKG_MAINTSCRIPT_PACKAGE${DPKG_MAINTSCRIPT_ARCH:+:$DPKG_MAINTSCRIPT_ARCH}" fi if [ "$PACKAGE" = "--" -o -z "$PACKAGE" ]; then PACKAGE="$DPKG_MAINTSCRIPT_PACKAGE${DPKG_MAINTSCRIPT_ARCH:+:$DPKG_MAINTSCRIPT_ARCH}" fi # Skip remaining parameters up to -- while [ "$1" != "--" -a $# -gt 0 ]; do shift; done [ $# -gt 0 ] || badusage "missing arguments after --" shift [ -n "$DPKG_MAINTSCRIPT_NAME" ] || \ error "environment variable DPKG_MAINTSCRIPT_NAME is required" [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ] || \ error "environment variable DPKG_MAINTSCRIPT_PACKAGE is required" [ -n "$PACKAGE" ] || error "cannot identify the package" [ -n "$SYMLINK" ] || error "symlink parameter is missing" [ "${SYMLINK#/}" = "$SYMLINK" ] && \ error "symlink pathname is not an absolute path" [ "${SYMLINK%/}" = "$SYMLINK" ] || \ error "symlink pathname ends with a slash" [ -n "$SYMLINK_TARGET" ] || error "original symlink target is missing" [ -n "$1" ] || error "maintainer script parameters are missing" validate_optional_version "$LASTVERSION" debug "Executing $0 symlink_to_dir in $DPKG_MAINTSCRIPT_NAME" \ "of $DPKG_MAINTSCRIPT_PACKAGE" debug "SYMLINK=$SYMLINK -> $SYMLINK_TARGET PACKAGE=$PACKAGE" \ "LASTVERSION=$LASTVERSION ACTION=$1 PARAM=$2" case "$DPKG_MAINTSCRIPT_NAME" in preinst) if [ "$1" = "install" -o "$1" = "upgrade" ] && [ -n "$2" ] && [ -h "$SYMLINK" ] && symlink_match "$SYMLINK" "$SYMLINK_TARGET" && dpkg --compare-versions -- "$2" le-nl "$LASTVERSION"; then mv -f "$SYMLINK" "${SYMLINK}.dpkg-backup" fi ;; postinst) # We cannot bail depending on the version, as here we only # know what was the last configured version, and we might # have been unpacked, then upgraded with an unpack and thus # never been configured before. if [ "$1" = "configure" ] && [ -h "${SYMLINK}.dpkg-backup" ] && symlink_match "${SYMLINK}.dpkg-backup" "$SYMLINK_TARGET" then rm -f "${SYMLINK}.dpkg-backup" fi ;; postrm) if [ "$1" = "purge" ] && [ -h "${SYMLINK}.dpkg-backup" ]; then rm -f "${SYMLINK}.dpkg-backup" fi if [ "$1" = "abort-install" -o "$1" = "abort-upgrade" ] && [ -n "$2" ] && [ ! -e "$SYMLINK" ] && [ -h "${SYMLINK}.dpkg-backup" ] && symlink_match "${SYMLINK}.dpkg-backup" "$SYMLINK_TARGET" && dpkg --compare-versions -- "$2" le-nl "$LASTVERSION"; then echo "Restoring backup of $SYMLINK ..." mv "${SYMLINK}.dpkg-backup" "$SYMLINK" fi ;; *) debug "$0 symlink_to_dir not required in $DPKG_MAINTSCRIPT_NAME" ;; esac } ## ## Functions to replace a directory with a symlink ## dir_to_symlink() { local PATHNAME="${1%/}" local SYMLINK_TARGET="$2" local LASTVERSION="$3" local PACKAGE="$4" if [ "$LASTVERSION" = "--" ]; then LASTVERSION="" PACKAGE="$DPKG_MAINTSCRIPT_PACKAGE${DPKG_MAINTSCRIPT_ARCH:+:$DPKG_MAINTSCRIPT_ARCH}" fi if [ "$PACKAGE" = "--" -o -z "$PACKAGE" ]; then PACKAGE="$DPKG_MAINTSCRIPT_PACKAGE${DPKG_MAINTSCRIPT_ARCH:+:$DPKG_MAINTSCRIPT_ARCH}" fi # Skip remaining parameters up to -- while [ "$1" != "--" -a $# -gt 0 ]; do shift; done [ $# -gt 0 ] || badusage "missing arguments after --" shift [ -n "$DPKG_MAINTSCRIPT_NAME" ] || \ error "environment variable DPKG_MAINTSCRIPT_NAME is required" [ -n "$DPKG_MAINTSCRIPT_PACKAGE" ] || \ error "environment variable DPKG_MAINTSCRIPT_PACKAGE is required" [ -n "$PACKAGE" ] || error "cannot identify the package" [ -n "$PATHNAME" ] || error "directory parameter is missing" [ "${PATHNAME#/}" = "$PATHNAME" ] && \ error "directory parameter is not an absolute path" [ -n "$SYMLINK_TARGET" ] || error "new symlink target is missing" [ -n "$1" ] || error "maintainer script parameters are missing" validate_optional_version "$LASTVERSION" debug "Executing $0 dir_to_symlink in $DPKG_MAINTSCRIPT_NAME" \ "of $DPKG_MAINTSCRIPT_PACKAGE" debug "PATHNAME=$PATHNAME SYMLINK_TARGET=$SYMLINK_TARGET" \ "PACKAGE=$PACKAGE LASTVERSION=$LASTVERSION ACTION=$1 PARAM=$2" case "$DPKG_MAINTSCRIPT_NAME" in preinst) if [ "$1" = "install" -o "$1" = "upgrade" ] && [ -n "$2" ] && [ ! -h "$PATHNAME" ] && [ -d "$PATHNAME" ] && dpkg --compare-versions -- "$2" le-nl "$LASTVERSION"; then prepare_dir_to_symlink "$PACKAGE" "$PATHNAME" fi ;; postinst) # We cannot bail depending on the version, as here we only # know what was the last configured version, and we might # have been unpacked, then upgraded with an unpack and thus # never been configured before. if [ "$1" = "configure" ] && [ -d "${PATHNAME}.dpkg-backup" ] && [ ! -h "$PATHNAME" ] && [ -d "$PATHNAME" ] && [ -f "$PATHNAME/.dpkg-staging-dir" ]; then finish_dir_to_symlink "$PATHNAME" "$SYMLINK_TARGET" fi ;; postrm) if [ "$1" = "purge" ] && [ -d "${PATHNAME}.dpkg-backup" ]; then rm -rf "${PATHNAME}.dpkg-backup" fi if [ "$1" = "abort-install" -o "$1" = "abort-upgrade" ] && [ -n "$2" ] && [ -d "${PATHNAME}.dpkg-backup" ] && [ \( ! -h "$PATHNAME" -a -d "$PATHNAME" -a \ -f "$PATHNAME/.dpkg-staging-dir" \) -o \ \( -h "$PATHNAME" -a \ \( "$(readlink "$PATHNAME")" = "$SYMLINK_TARGET" -o \ "$(readlink -f "$PATHNAME")" = "$SYMLINK_TARGET" \) \) ] && dpkg --compare-versions -- "$2" le-nl "$LASTVERSION"; then abort_dir_to_symlink "$PATHNAME" fi ;; *) debug "$0 dir_to_symlink not required in $DPKG_MAINTSCRIPT_NAME" ;; esac } prepare_dir_to_symlink() { local PACKAGE="$1" local PATHNAME="$2" local LINE # If there are conffiles we should not perform the switch. dpkg-query -W -f='${Conffiles}\n' "$PACKAGE" | while read -r LINE; do case "$LINE" in "$PATHNAME"/*) error "directory '$PATHNAME' contains conffiles," \ "cannot switch to symlink" ;; esac done # If there are locally created files or files owned by another package # we should not perform the switch. export DPKG_MAINTSCRIPT_HELPER_INTERNAL_API="$version" find "$PATHNAME" -print0 | \ xargs -0 -n1 "$0" _internal_pkg_must_own_file "$PACKAGE" || \ error "directory '$PATHNAME' contains files not owned by" \ "package $PACKAGE, cannot switch to symlink" unset DPKG_MAINTSCRIPT_HELPER_INTERNAL_API # At this point, we know that the directory either contains no files, # or only non-conffiles owned by the package. # # To do the switch we cannot simply replace it with the final symlink # just yet, because dpkg needs to remove any file present in the old # package that have disappeared in the new one, and we do not want to # lose files resolving to the same pathname in the symlink target. # # We cannot replace the directory with a staging symlink either, # because dpkg will update symlinks to their new target. # # So we need to create a staging directory, to avoid removing files # from other packages, and to trap any new files in the directory # to move them to their correct place later on. mv -f "$PATHNAME" "${PATHNAME}.dpkg-backup" mkdir "$PATHNAME" # Mark it as a staging directory, so that we can track things. touch "$PATHNAME/.dpkg-staging-dir" } finish_dir_to_symlink() { local PATHNAME="$1" local SYMLINK_TARGET="$2" # Move the contents of the staging directory to the symlink target, # as those are all new files installed between this package being # unpacked and configured. local ABS_SYMLINK_TARGET if [ "${SYMLINK_TARGET#/}" = "$SYMLINK_TARGET" ]; then ABS_SYMLINK_TARGET="$(dirname "$PATHNAME")/$SYMLINK_TARGET" else ABS_SYMLINK_TARGET="$SYMLINK_TARGET" fi rm "$PATHNAME/.dpkg-staging-dir" find "$PATHNAME" -mindepth 1 -maxdepth 1 -print0 | \ xargs -0 -i% mv -f "%" "$ABS_SYMLINK_TARGET/" # Remove the staging directory. rmdir "$PATHNAME" # Do the actual switch. ln -s "$SYMLINK_TARGET" "$PATHNAME" # We are left behind the old files owned by this package in the backup # directory, just remove it. rm -rf "${PATHNAME}.dpkg-backup" } abort_dir_to_symlink() { local PATHNAME="$1" echo "Restoring backup of $PATHNAME ..." if [ -h "$PATHNAME" ]; then rm -f "$PATHNAME" else # The staging directory must be empty, as no other package # should have been unpacked in between. rm -f "$PATHNAME/.dpkg-staging-dir" rmdir "$PATHNAME" fi mv "${PATHNAME}.dpkg-backup" "$PATHNAME" } # Common functions validate_optional_version() { local VERSION="$1" if [ -z "$VERSION" ]; then return fi if ! VERSIONCHECK=$(dpkg --validate-version -- "$VERSION" 2>&1); then error "$VERSIONCHECK" fi } ensure_package_owns_file() { local PACKAGE="$1" local FILE="$2" if ! dpkg-query -L "$PACKAGE" | grep -F -q -x "$FILE"; then debug "File '$FILE' not owned by package " \ "'$PACKAGE', skipping $command" return 1 fi return 0 } internal_pkg_must_own_file() { local PACKAGE="$1" local FILE="$2" if [ "$DPKG_MAINTSCRIPT_HELPER_INTERNAL_API" != "$version" ]; then error "internal API used by external command" fi if ! ensure_package_owns_file "$PACKAGE" "$FILE"; then error "file '$FILE' not owned by package '$PACKAGE'" fi return 0 } symlink_match() { local SYMLINK="$1" local SYMLINK_TARGET="$2" [ "$(readlink "$SYMLINK")" = "$SYMLINK_TARGET" ] || \ [ "$(readlink -f "$SYMLINK")" = "$SYMLINK_TARGET" ] } # Standard ANSI colors and attributes. COLOR_NORMAL='' COLOR_RESET='' COLOR_BOLD='' COLOR_BLACK='' COLOR_RED='' COLOR_GREEN='' COLOR_YELLOW='' COLOR_BLUE='' COLOR_MAGENTA='' COLOR_CYAN='' COLOR_WHITE='' COLOR_BOLD_BLACK='' COLOR_BOLD_RED='' COLOR_BOLD_GREEN='' COLOR_BOLD_YELLOW='' COLOR_BOLD_BLUE='' COLOR_BOLD_MAGENTA='' COLOR_BOLD_CYAN='' COLOR_BOLD_WHITE='' setup_colors() { : "${DPKG_COLORS=auto}" case "$DPKG_COLORS" in auto) if [ -t 1 ]; then USE_COLORS=yes else USE_COLORS=no fi ;; always) USE_COLORS=yes ;; *) USE_COLORS=no ;; esac if [ $USE_COLORS = yes ]; then COLOR_PROG="$COLOR_BOLD" COLOR_INFO="$COLOR_GREEN" COLOR_NOTICE="$COLOR_YELLOW" COLOR_WARN="$COLOR_BOLD_YELLOW" COLOR_ERROR="$COLOR_BOLD_RED" else COLOR_RESET="" fi FMT_PROG="$COLOR_PROG$PROGNAME$COLOR_RESET" } debug() { if [ -n "$DPKG_DEBUG" ]; then echo "DEBUG: $FMT_PROG: $*" >&2 fi } error() { echo "$FMT_PROG: ${COLOR_ERROR}error${COLOR_RESET}: $*" >&2 exit 1 } warning() { echo "$FMT_PROG: ${COLOR_WARN}warning${COLOR_RESET}: $*" >&2 } usage() { cat < ... -- ... Commands: supports Returns 0 (success) if the given command is supported, 1 otherwise. rm_conffile [ []] Remove obsolete conffile. Must be called in preinst, postinst and postrm. mv_conffile [ []] Rename a conffile. Must be called in preinst, postinst and postrm. symlink_to_dir [ []] Replace a symlink with a directory. Must be called in preinst, postinst and postrm. dir_to_symlink [ []] Replace a directory with a symlink. Must be called in preinst, postinst and postrm. help Display this usage information. END } badusage() { echo "$FMT_PROG: ${COLOR_ERROR}error${COLOR_RESET}: $1" >&2 echo >&2 echo "Use '$PROGNAME help' for program usage information." >&2 exit 1 } # Main code set -e PROGNAME=$(basename "$0") version="1.19.7" setup_colors command="$1" [ $# -gt 0 ] || badusage "missing command" shift case "$command" in supports) case "$1" in rm_conffile|mv_conffile|symlink_to_dir|dir_to_symlink) code=0 ;; *) code=1 ;; esac if [ -z "$DPKG_MAINTSCRIPT_NAME" ]; then warning "environment variable DPKG_MAINTSCRIPT_NAME missing" code=1 fi if [ -z "$DPKG_MAINTSCRIPT_PACKAGE" ]; then warning "environment variable DPKG_MAINTSCRIPT_PACKAGE missing" code=1 fi exit $code ;; rm_conffile) rm_conffile "$@" ;; mv_conffile) mv_conffile "$@" ;; symlink_to_dir) symlink_to_dir "$@" ;; dir_to_symlink) dir_to_symlink "$@" ;; _internal_pkg_must_own_file) # This is an internal command, must not be used outside this program. internal_pkg_must_own_file "$@" ;; --help|help|-?) usage ;; --version) cat <<-END Debian $PROGNAME version $version. This is free software; see the GNU General Public License version 2 or later for copying conditions. There is NO warranty. END ;; *) badusage "command $command is unknown Hint: upgrading dpkg to a newer version might help." esac exit 0