tazpkg rev 627
Add tazpanel files
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sat Jun 29 20:18:19 2013 +0200 (2013-06-29) |
parents | 785703fb2975 |
children | 3a1edf27791c |
files | COPYING Makefile pkgs pkgs.cgi |
line diff
1.1 --- a/COPYING Wed Mar 20 16:50:02 2013 +0000 1.2 +++ b/COPYING Sat Jun 29 20:18:19 2013 +0200 1.3 @@ -2,7 +2,7 @@ 1.4 =============================================================================== 1.5 1.6 1.7 -Copyright (c) 2007-2011 SliTaz GNU/Linux 1.8 +Copyright (c) 2007-2013 SliTaz GNU/Linux 1.9 1.10 1.11 Français
2.1 --- a/Makefile Wed Mar 20 16:50:02 2013 +0000 2.2 +++ b/Makefile Sat Jun 29 20:18:19 2013 +0200 2.3 @@ -68,6 +68,10 @@ 2.4 # Documentation 2.5 install -m 0755 -d $(DESTDIR)$(DOCDIR)/tazpkg 2.6 cp -a doc/* $(DESTDIR)$(DOCDIR)/tazpkg 2.7 + # tazpanel files 2.8 + install -m 0755 -d $(DESTDIR)/var/www/tazpanel/menu.d 2.9 + cp -a pkgs.cgi $(DESTDIR)/var/www/tazpanel 2.10 + cp -a pkgs $(DESTDIR)/var/www/tazpanel/menu.d 2.11 # The i18n files 2.12 install -m 0755 -d $(DESTDIR)$(PREFIX)/share/locale 2.13 cp -a po/mo/* $(DESTDIR)$(PREFIX)/share/locale 2.14 @@ -82,6 +86,8 @@ 2.15 uninstall: 2.16 rm -f $(DESTDIR)$(PREFIX)/bin/tazpkg 2.17 rm -f $(DESTDIR)$(PREFIX)/bin/tazpkg-box 2.18 + rm -f $(DESTDIR)$(PREFIX)/var/www/tazpanel/menu.d/pkgs 2.19 + rm -f $(DESTDIR)$(PREFIX)/var/www/tazpanel/pkgs.cgi 2.20 rm -rf $(DESTDIR)$(PREFIX)/tazpkg-notify 2.21 rm -rf $(DESTDIR)$(DOCDIR)/tazpkg 2.22 rm -f $(DESTDIR)$(SYSCONFDIR)/tazpkg.conf
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/pkgs Sat Jun 29 20:18:19 2013 +0200 3.3 @@ -0,0 +1,14 @@ 3.4 +cat <<EOT 3.5 +<li><a href="/pkgs.cgi">$(gettext 'Packages')</a> 3.6 + <ul> 3.7 + <li><a href="/pkgs.cgi?list"><img 3.8 + src="/styles/default/images/tazpkg.png" />$(gettext 'My packages')</a></li> 3.9 + <li><a href="/pkgs.cgi?recharge"><img 3.10 + src="/styles/default/images/update.png" />$(gettext 'Recharge list')</a></li> 3.11 + <li><a href="/pkgs.cgi?up"><img 3.12 + src="/styles/default/images/update.png" />$(gettext 'Check updates')</a></li> 3.13 + <li><a href="/pkgs.cgi?admin"><img 3.14 + src="/styles/default/images/edit.png" />$(gettext 'Administration')</a></li> 3.15 + </ul> 3.16 +</li> 3.17 +EOT
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/pkgs.cgi Sat Jun 29 20:18:19 2013 +0200 4.3 @@ -0,0 +1,996 @@ 4.4 +#!/bin/sh 4.5 +# 4.6 +# TazPKG CGI interface - Manage packages via a browser 4.7 +# 4.8 +# This CGI interface extensively uses tazpkg to manage packages and have 4.9 +# its own code for some tasks. Please KISS, it is important and keep speed 4.10 +# in mind. Thanks, Pankso. 4.11 +# 4.12 +# (C) 2011 SliTaz GNU/Linux - BSD License 4.13 +# 4.14 + 4.15 +. lib/libtazpanel 4.16 +get_config 4.17 +header 4.18 + 4.19 +# xHTML 5 header with special side bar for categories. 4.20 +TITLE=$(gettext 'TazPanel - Packages') 4.21 +xhtml_header | sed 's/id="content"/id="content-sidebar"/' 4.22 + 4.23 +pkg_info_link() 4.24 +{ 4.25 + echo "$SCRIPT_NAME?info=$1" | sed 's/+/%2B/g' 4.26 +} 4.27 + 4.28 +i18n_desc() { 4.29 + # Display localized short description 4.30 + if [ -e "$LOCALSTATE/packages-desc.$LANG" ]; then 4.31 + LOCDESC=$(grep -e "^$pkg " $LOCALSTATE/packages-desc.$LANG | cut -d' ' -f2) 4.32 + [ "x$LOCDESC" != "x" ] && SHORT_DESC="$LOCDESC" 4.33 + fi 4.34 +} 4.35 + 4.36 +# We need packages information for list and search 4.37 +parse_packages_desc() { 4.38 + IFS="|" 4.39 + cut -f 1,2,3,5 -d "|" | while read PACKAGE VERSION SHORT_DESC WEB_SITE 4.40 + do 4.41 + image=tazpkg-installed.png 4.42 + [ -d $INSTALLED/${PACKAGE% } ] || image=tazpkg.png 4.43 + i18n_desc 4.44 + cat << EOT 4.45 +<tr> 4.46 +<td><input type="checkbox" name="pkg" value="$PACKAGE"> 4.47 + <a href="$(pkg_info_link $PACKAGE)"><img 4.48 + src="$IMAGES/$image"/>$PACKAGE</a></td> 4.49 +<td>$VERSION</td> 4.50 +<td class="desc">$SHORT_DESC</td> 4.51 +<td><a href="$WEB_SITE"><img src="$IMAGES/browser.png"/></a></td> 4.52 +</tr> 4.53 +EOT 4.54 + done 4.55 + unset IFS 4.56 +} 4.57 + 4.58 +# Display a full summary of packages stats 4.59 +packages_summary() { 4.60 + cat << EOT 4.61 +<table class="zebra outbox"> 4.62 +<tbody> 4.63 +<tr><td>$(gettext 'Last recharge:')</td> 4.64 +EOT 4.65 + stat=$(stat -c %y $LOCALSTATE/packages.list | \ 4.66 + sed 's/\(:..\):.*/\1/' | awk '{print $1}') 4.67 + mtime=$(find $LOCALSTATE/packages.list -mtime +10) 4.68 + echo -n "<td>$stat " 4.69 + if [ "$mtime" ]; then 4.70 + gettext '(Older than 10 days)'; echo 4.71 + else 4.72 + gettext '(Not older than 10 days)'; echo 4.73 + fi 4.74 + cat << EOT 4.75 +</td></tr> 4.76 +<tr><td>$(gettext 'Installed packages:')</td> 4.77 + <td>$(ls $INSTALLED | wc -l)</td></tr> 4.78 +<tr><td>$(gettext 'Mirrored packages:')</td> 4.79 + <td>$(cat $LOCALSTATE/packages.list | wc -l)</td></tr> 4.80 +<tr><td>$(gettext 'Upgradeable packages:')</td> 4.81 + <td>$(cat $LOCALSTATE/packages.up | wc -l)</td></tr> 4.82 +<tr><td>$(gettext 'Installed files:')</td> 4.83 + <td>$(cat $INSTALLED/*/files.list | wc -l)</td></tr> 4.84 +<tr><td>$(gettext 'Blocked packages:')</td> 4.85 + <td>$(cat $LOCALSTATE/blocked-packages.list | wc -l)</td></tr> 4.86 +</tbody> 4.87 +</table> 4.88 +EOT 4.89 +} 4.90 + 4.91 +# Parse mirrors list to be able to have an icon and remove link 4.92 +list_mirrors() { 4.93 + while read line 4.94 + do 4.95 + cat << EOT 4.96 +<li> 4.97 + <a href="$SCRIPT_NAME?admin=rm-mirror=$line&file=$(httpd -e $1)"> 4.98 + <img src="$IMAGES/clear.png" title="$(gettext 'Delete')" /> 4.99 + </a> 4.100 + <a href="$SCRIPT_NAME?admin=select-mirror&mirror=$line"> 4.101 + <img src="$IMAGES/start.png" title="$(gettext 'Use as default')" /> 4.102 + </a> 4.103 + <a href="$line">$line</a> 4.104 +</li> 4.105 +EOT 4.106 + done < $1 4.107 +} 4.108 + 4.109 +# Parse repositories list to be able to have an icon and remove link 4.110 +list_repos() { 4.111 + ls $LOCALSTATE/undigest 2> /dev/null | while read repo ; do 4.112 + cat <<EOT 4.113 + <li><a href="$SCRIPT_NAME?admin=rm-repo=$repo"> 4.114 + <img src="$IMAGES/clear.png">$repo</a></li> 4.115 +EOT 4.116 + done 4.117 +} 4.118 + 4.119 +# 4.120 +# xHTML functions 4.121 +# 4.122 + 4.123 +# ENTER will search but user may search for a button, so put one. 4.124 +search_form() { 4.125 + [ -n "$repo" ] || repo="$(GET repo)" 4.126 + [ -n "$repo" ] || repo=Any 4.127 + cat << EOT 4.128 +<div class="search"> 4.129 + <form method="get" action="$SCRIPT_NAME"> 4.130 + <p> 4.131 + <input type="text" name="search" size="20"> 4.132 + <input type="submit" value="$(gettext 'Search')"> 4.133 + <input class="radius" type="submit" name="files" 4.134 + value="$(gettext 'Files')"> 4.135 + <input type="hidden" name="repo" value="$repo" /> 4.136 + </p> 4.137 + </form> 4.138 +</div> 4.139 +EOT 4.140 +} 4.141 + 4.142 +table_head() { 4.143 + cat << EOT 4.144 + <thead> 4.145 + <tr> 4.146 + <td>$(gettext 'Name')</td> 4.147 + <td>$(gettext 'Version')</td> 4.148 + <td>$(gettext 'Description')</td> 4.149 + <td>$(gettext 'Web')</td> 4.150 + </tr> 4.151 + </thead> 4.152 +EOT 4.153 +} 4.154 + 4.155 +sidebar() { 4.156 + [ -n "$repo" ] || repo=Public 4.157 + cat << EOT 4.158 +<div id="sidebar"> 4.159 + <h4>$(gettext 'Categories')</h4> 4.160 + <a class="active_base-system" href="$SCRIPT_NAME?cat=base-system&repo=$repo">$(gettext 'Base-system')</a> 4.161 + <a class="active_x-window" href="$SCRIPT_NAME?cat=x-window&repo=$repo">$(gettext 'X window')</a> 4.162 + <a class="active_utilities" href="$SCRIPT_NAME?cat=utilities&repo=$repo">$(gettext 'Utilities')</a> 4.163 + <a class="active_network" href="$SCRIPT_NAME?cat=network&repo=$repo">$(gettext 'Network')</a> 4.164 + <a class="active_games" href="$SCRIPT_NAME?cat=games&repo=$repo">$(gettext 'Games')</a> 4.165 + <a class="active_graphics" href="$SCRIPT_NAME?cat=graphics&repo=$repo">$(gettext 'Graphics')</a> 4.166 + <a class="active_office" href="$SCRIPT_NAME?cat=office&repo=$repo">$(gettext 'Office')</a> 4.167 + <a class="active_multimedia" href="$SCRIPT_NAME?cat=multimedia&repo=$repo">$(gettext 'Multimedia')</a> 4.168 + <a class="active_development" href="$SCRIPT_NAME?cat=development&repo=$repo">$(gettext 'Development')</a> 4.169 + <a class="active_system-tools" href="$SCRIPT_NAME?cat=system-tools&repo=$repo">$(gettext 'System tools')</a> 4.170 + <a class="active_security" href="$SCRIPT_NAME?cat=security&repo=$repo">$(gettext 'Security')</a> 4.171 + <a class="active_misc" href="$SCRIPT_NAME?cat=misc&repo=$repo">$(gettext 'Misc')</a> 4.172 + <a class="active_meta" href="$SCRIPT_NAME?cat=meta&repo=$repo">$(gettext 'Meta')</a> 4.173 + <a class="active_non-free" href="$SCRIPT_NAME?cat=non-free&repo=$repo">$(gettext 'Non free')</a> 4.174 + <a class="active_all" href="$SCRIPT_NAME?cat=all&repo=$repo">$(gettext 'All')</a> 4.175 +EOT 4.176 + 4.177 + if [ -d $LOCALSTATE/undigest ]; then 4.178 + [ -n "$category" ] || category="base-system" 4.179 + cat << EOT 4.180 + <h4>$(gettext 'Repositories')</h4> 4.181 + <a class="repo_Public" href="$SCRIPT_NAME?repo=Public&cat=$category">$(gettext 'Public')</a> 4.182 +EOT 4.183 + for i in $(ls $LOCALSTATE/undigest); do 4.184 + cat << EOT 4.185 + <a class="repo_$i" href="$SCRIPT_NAME?repo=$i&cat=$category">$i</a> 4.186 +EOT 4.187 + done 4.188 + cat << EOT 4.189 + <a class="repo_Any" href="$SCRIPT_NAME?repo=Any&cat=$category">$(gettext 'Any')</a> 4.190 +EOT 4.191 + fi 4.192 + echo "</div>" 4.193 +} 4.194 + 4.195 +repo_list() { 4.196 + if [ -n "$(ls $LOCALSTATE/undigest/ 2> /dev/null)" ]; then 4.197 + case "$repo" in 4.198 + Public) ;; 4.199 + ""|Any) for i in $LOCALSTATE/undigest/* ; do 4.200 + [ -d "$i" ] && echo "$i$1" 4.201 + done ;; 4.202 + *) echo "$LOCALSTATE/undigest/$repo$1" 4.203 + return ;; 4.204 + esac 4.205 + fi 4.206 + echo "$LOCALSTATE$1" 4.207 +} 4.208 + 4.209 +repo_name() { 4.210 + case "$1" in 4.211 + $LOCALSTATE) echo "Public" ;; 4.212 + $LOCALSTATE/undigest/*) echo ${1#$LOCALSTATE/undigest/} ;; 4.213 + esac 4.214 +} 4.215 + 4.216 +# 4.217 +# Commands 4.218 +# 4.219 + 4.220 +case " $(GET) " in 4.221 + *\ list\ *) 4.222 + # 4.223 + # List installed packages. This is the default because parsing 4.224 + # the full packages.desc can be long and take up some resources 4.225 + # 4.226 + cd $INSTALLED 4.227 + search_form 4.228 + sidebar 4.229 + LOADING_MSG="$(gettext 'Listing packages...')" 4.230 + loading_msg 4.231 + cat << EOT 4.232 +<h2>$(gettext 'My packages')</h2> 4.233 +<form method='get' action='$SCRIPT_NAME'> 4.234 + <input type="hidden" name="do" value="Remove" /> 4.235 +<div id="actions"> 4.236 + <div class="float-left"> 4.237 + $(gettext 'Selection:') 4.238 + <input type="submit" value="$(gettext 'Remove')" /> 4.239 + </div> 4.240 + <div class="float-right"> 4.241 + <a class="button" href="$SCRIPT_NAME?recharge"> 4.242 + <img src="$IMAGES/recharge.png" />$(gettext 'Recharge list')</a> 4.243 + <a class="button" href='$SCRIPT_NAME?up'> 4.244 + <img src="$IMAGES/update.png" />$(gettext 'Check upgrades')</a> 4.245 + </div> 4.246 +</div> 4.247 +EOT 4.248 + cat << EOT 4.249 +<table class="zebra outbox"> 4.250 +$(table_head) 4.251 +<tbody> 4.252 +EOT 4.253 + for pkg in * 4.254 + do 4.255 + . $pkg/receipt 4.256 + echo '<tr>' 4.257 + # Use default tazpkg icon since all packages displayed are 4.258 + # installed 4.259 + colorpkg=$pkg 4.260 + grep -qs "^$pkg$" $LOCALSTATE/blocked-packages.list && 4.261 + colorpkg="<span style='color: red;'>$pkg</span>" 4.262 + i18n_desc 4.263 + cat << EOT 4.264 +<td class="pkg"> 4.265 + <input type="checkbox" name="pkg" value="$pkg" /> 4.266 + <a href="$(pkg_info_link $pkg)"><img 4.267 + src="$IMAGES/tazpkg-installed.png"/>$colorpkg</a></td> 4.268 +<td>$VERSION</td> 4.269 +<td class="desc">$SHORT_DESC</td> 4.270 +<td><a href="$WEB_SITE"><img src="$IMAGES/browser.png"/></a></td> 4.271 +</tr> 4.272 +EOT 4.273 + done 4.274 + cat << EOT 4.275 +</tbody> 4.276 +</table> 4.277 +</form> 4.278 +EOT 4.279 + ;; 4.280 + 4.281 + *\ linkable\ *) 4.282 + # 4.283 + # List linkable packages. 4.284 + # 4.285 + cd $INSTALLED 4.286 + search_form 4.287 + sidebar 4.288 + LOADING_MSG=$(gettext 'Listing linkable packages...') 4.289 + loading_msg 4.290 + cat << EOT 4.291 +<h2>$(gettext 'Linkable packages')</h2> 4.292 + 4.293 +<form method='get' action='$SCRIPT_NAME'> 4.294 + <input type="hidden" name="do" value="Link" /> 4.295 +<div id="actions"> 4.296 + <div class="float-left"> 4.297 + $(gettext 'Selection:') 4.298 + <input type="submit" value="$(gettext 'Link')" /> 4.299 + </div> 4.300 + <div class="float-right"> 4.301 + <a class="button" href="$SCRIPT_NAME?recharge"> 4.302 + <img src="$IMAGES/recharge.png" />$(gettext 'Recharge list')</a> 4.303 + <a class="button" href="$SCRIPT_NAME?up"> 4.304 + <img src="$IMAGES/update.png" />$(gettext 'Check upgrades')</a> 4.305 + </div> 4.306 +</div> 4.307 +EOT 4.308 + cat << EOT 4.309 +<table class="zebra outbox"> 4.310 +$(table_head) 4.311 +<tbody> 4.312 +EOT 4.313 + target=$(readlink $LOCALSTATE/fslink) 4.314 + for pkg in $(ls $target/$INSTALLED) 4.315 + do 4.316 + [ -s $pkg/receipt ] && continue 4.317 + . $target/$INSTALLED/$pkg/receipt 4.318 + i18n_desc 4.319 + cat << EOT 4.320 +<tr> 4.321 + <td class="pkg"> 4.322 + <input type="checkbox" name="pkg" value="$pkg" /> 4.323 + <a href="$(pkg_info_link $pkg)"><img 4.324 + src="$IMAGES/tazpkg.png"/>$pkg</a> 4.325 + </td> 4.326 + <td>$VERSION</td> 4.327 + <td class="desc">$SHORT_DESC</td> 4.328 + <td><a href="$WEB_SITE"><img src="$IMAGES/browser.png"/></a></td> 4.329 +</tr> 4.330 +EOT 4.331 + done 4.332 + cat << EOT 4.333 +</tbody> 4.334 +</table> 4.335 +</form> 4.336 +EOT 4.337 + ;; 4.338 + 4.339 + 4.340 + *\ cat\ *) 4.341 + # 4.342 + # List all available packages by category on mirror. Listing all 4.343 + # packages is too resource intensive and not useful. 4.344 + # 4.345 + cd $LOCALSTATE 4.346 + repo=$(GET repo) 4.347 + category=$(GET cat) 4.348 + [ "$category" == "cat" ] && category="base-system" 4.349 + grep_category=$category 4.350 + [ "$grep_category" == "all" ] && grep_category=".*" 4.351 + search_form 4.352 + sidebar | sed "s/active_$category/active/;s/repo_$repo/active/" 4.353 + LOADING_MSG="$(gettext 'Listing packages...')" 4.354 + loading_msg 4.355 + cat << EOT 4.356 +<h2>$(eval_gettext 'Category: $category')</h2> 4.357 + 4.358 +<form method='get' action='$SCRIPT_NAME'> 4.359 +<div id="actions"> 4.360 +<div class="float-left"> 4.361 + $(gettext 'Selection:') 4.362 + <input type="submit" name="do" value="Install" /> 4.363 + <input type="submit" name="do" value="Remove" /> 4.364 + <input type="hidden" name="repo" value="$repo" /> 4.365 +</div> 4.366 +<div class="float-right"> 4.367 + <a class="button" href="$SCRIPT_NAME?recharge"> 4.368 + <img src="$IMAGES/recharge.png" />$(gettext 'Recharge list')</a> 4.369 + <a class="button" href="$SCRIPT_NAME?up"> 4.370 + <img src="$IMAGES/update.png" />$(gettext 'Check upgrades')</a> 4.371 + <a class="button" href='$SCRIPT_NAME?list'> 4.372 + <img src="$IMAGES/tazpkg.png" />$(gettext 'My packages')</a> 4.373 +</div> 4.374 +</div> 4.375 +EOT 4.376 + for i in $(repo_list ""); do 4.377 + if [ "$repo" != "Public" ]; then 4.378 + Repo_Name="$(repo_name $i)" 4.379 + cat << EOT 4.380 +<h3>$(eval_gettext "Repository: \$Repo_Name")</h3> 4.381 +EOT 4.382 + fi 4.383 + cat << EOT 4.384 +<table class="zebra outbox"> 4.385 +$(table_head) 4.386 +<tbody> 4.387 +EOT 4.388 + grep "| $grep_category |" $i/packages.desc | \ 4.389 + parse_packages_desc 4.390 + cat << EOT 4.391 +</tbody> 4.392 +</table> 4.393 +EOT 4.394 + done 4.395 + echo '</form>' ;; 4.396 + 4.397 + 4.398 + *\ search\ *) 4.399 + # 4.400 + # Search for packages. Here default is to search in packages.desc 4.401 + # and so get result including packages names and descriptions 4.402 + # 4.403 + pkg=$(GET search) 4.404 + repo=$(GET repo) 4.405 + cd $LOCALSTATE 4.406 + search_form 4.407 + sidebar | sed "s/repo_$repo/active/" 4.408 + LOADING_MSG="$(gettext 'Searching packages...')" 4.409 + loading_msg 4.410 + cat << EOT 4.411 +<h2>$(gettext 'Search packages')</h2> 4.412 +<form method="get" action="$SCRIPT_NAME"> 4.413 +<div id="actions"> 4.414 +<div class="float-left"> 4.415 + $(gettext 'Selection:') 4.416 + <input type="submit" name="do" value="Install" /> 4.417 + <input type="submit" name="do" value="Remove" /> 4.418 + <a href="`cat $PANEL/lib/checkbox.js`">$(gettext 'Toogle all')</a> 4.419 +</div> 4.420 +<div class="float-right"> 4.421 + <a class="button" href="$SCRIPT_NAME?recharge"> 4.422 + <img src="$IMAGES/recharge.png" />$(gettext 'Recharge list')</a> 4.423 + <a class="button" href="$SCRIPT_NAME?up"> 4.424 + <img src="$IMAGES/update.png" />$(gettext 'Check upgrades')</a> 4.425 + <a class="button" href='$SCRIPT_NAME?list'> 4.426 + <img src="$IMAGES/tazpkg.png" />$(gettext 'My packages')</a> 4.427 +</div> 4.428 +</div> 4.429 + <input type="hidden" name="repo" value="$repo" /> 4.430 + 4.431 + <table class="zebra outbox"> 4.432 +EOT 4.433 + if [ "$(GET files)" ]; then 4.434 + cat <<EOT 4.435 + <thead> 4.436 + <tr> 4.437 + <td>$(gettext 'Package')</td> 4.438 + <td>$(gettext 'File')</td> 4.439 + </tr> 4.440 + <thead> 4.441 + <tbody> 4.442 +EOT 4.443 + unlzma -c $(repo_list /files.list.lzma) \ 4.444 + | grep -Ei ": .*$(GET search)" | \ 4.445 + while read PACKAGE FILE; do 4.446 + PACKAGE=${PACKAGE%:} 4.447 + image=tazpkg-installed.png 4.448 + [ -d $INSTALLED/$PACKAGE ] || image=tazpkg.png 4.449 + cat << EOT 4.450 +<tr> 4.451 + <td><input type="checkbox" name="pkg" value="$PACKAGE"> 4.452 + <a href="$(pkg_info_link $PACKAGE)"><img src="$IMAGES/$image" />$PACKAGE</a></td> 4.453 + <td>$FILE</td> 4.454 +</tr> 4.455 +EOT 4.456 + done 4.457 + else 4.458 + cat << EOT 4.459 +$(table_head) 4.460 + <tbody> 4.461 +EOT 4.462 + grep -ih $pkg $(repo_list /packages.desc) | \ 4.463 + parse_packages_desc 4.464 + fi 4.465 + cat << EOT 4.466 + </tbody> 4.467 + </table> 4.468 +</form> 4.469 +EOT 4.470 + ;; 4.471 + 4.472 + 4.473 + *\ recharge\ *) 4.474 + # 4.475 + # Lets recharge the packages list 4.476 + # 4.477 + search_form 4.478 + sidebar 4.479 + LOADING_MSG="$(gettext 'Recharging lists...')" 4.480 + loading_msg 4.481 + cat << EOT 4.482 +<h2>$(gettext 'Recharge')</h2> 4.483 + 4.484 +<form method='get' action='$SCRIPT_NAME'> 4.485 +<div id="actions"> 4.486 + <div class="float-left"> 4.487 + <p>$(gettext 'Recharge checks for new or updated packages')</p> 4.488 + </div> 4.489 + <div class="float-right"> 4.490 + <a class="button" href='$SCRIPT_NAME?up'> 4.491 + <img src="$IMAGES/update.png" />$(gettext 'Check upgrades')</a> 4.492 + <a class="button" href='$SCRIPT_NAME?list'> 4.493 + <img src="$IMAGES/tazpkg.png" />$(gettext 'My packages')</a> 4.494 + </div> 4.495 +</div> 4.496 +<div class="wrapper"> 4.497 +<pre> 4.498 +EOT 4.499 + echo $(gettext 'Recharging packages list') | log 4.500 + tazpkg recharge | filter_taztools_msgs 4.501 + cat << EOT 4.502 +</pre> 4.503 +</div> 4.504 +<p>$(gettext "Packages lists are up-to-date. You should check for upgrades \ 4.505 +now.")</p> 4.506 +EOT 4.507 + ;; 4.508 + 4.509 + 4.510 + *\ up\ *) 4.511 + # 4.512 + # Upgrade packages 4.513 + # 4.514 + cd $LOCALSTATE 4.515 + search_form 4.516 + sidebar 4.517 + LOADING_MSG="$(gettext 'Checking for upgrades...')" 4.518 + loading_msg 4.519 + cat << EOT 4.520 +<h2>$(gettext 'Up packages')</h2> 4.521 + 4.522 +<form method="get" action="$SCRIPT_NAME"> 4.523 +<div id="actions"> 4.524 + <div class="float-left"> 4.525 + $(gettext 'Selection:') 4.526 + <input type="submit" name="do" value="Install" /> 4.527 + <input type="submit" name="do" value="Remove" /> 4.528 + <a href="$(cat $PANEL/lib/checkbox.js)">$(gettext 'Toogle all')</a> 4.529 + </div> 4.530 + <div class="float-right"> 4.531 + <a class="button" href="$SCRIPT_NAME?recharge"> 4.532 + <img src="$IMAGES/recharge.png" />$(gettext 'Recharge list')</a> 4.533 + <a class="button" href="$SCRIPT_NAME?list"> 4.534 + <img src="$IMAGES/tazpkg.png" />$(gettext 'My packages')</a> 4.535 + </div> 4.536 +</div> 4.537 +EOT 4.538 + tazpkg up --check >/dev/null 4.539 + cat << EOT 4.540 +<table class="zebra outbox"> 4.541 +$(table_head) 4.542 +<tbody> 4.543 +EOT 4.544 + for pkg in `cat packages.up` 4.545 + do 4.546 + grep -hs "^$pkg |" $LOCALSTATE/packages.desc \ 4.547 + $LOCALSTATE/undigest/*/packages.desc | \ 4.548 + parse_packages_desc 4.549 + done 4.550 + cat << EOT 4.551 +</tbody> 4.552 +</table> 4.553 +</form> 4.554 +EOT 4.555 + ;; 4.556 + 4.557 + 4.558 + *\ do\ *) 4.559 + # 4.560 + # Do an action on one or some packages 4.561 + # 4.562 + opt="" 4.563 + pkgs="" 4.564 + cmdline=$(echo ${QUERY_STRING#do=} | sed s'/&/ /g') 4.565 + cmd=$(echo ${cmdline} | awk '{print $1}') 4.566 + cmdline=${cmdline#*repo=* } 4.567 + pkgs=$(echo $cmdline | sed -e s'/+/ /g' -e s'/pkg=//g' -e s/$cmd//) 4.568 + pkgs="$(httpd -d "$pkgs")" 4.569 + cmd=$(echo $cmd | tr [:upper:] [:lower:]) 4.570 + case $cmd in 4.571 + install) 4.572 + cmd=get-install opt=--forced 4.573 + LOADING_MSG="get-installing packages..." 4.574 + ;; 4.575 + link) 4.576 + opt=$(readlink $LOCALSTATE/fslink) 4.577 + LOADING_MSG="linking packages..." 4.578 + ;; 4.579 + esac 4.580 + search_form 4.581 + sidebar 4.582 + loading_msg 4.583 + cat << EOT 4.584 +<h2>Tazpkg: $cmd</h2> 4.585 + 4.586 +<form method="get" action="$SCRIPT_NAME"> 4.587 +<div id="actions"> 4.588 + <div class="float-left"> 4.589 + <p>$(gettext 'Performing tasks on packages')</p> 4.590 + </div> 4.591 + <div class="float-right"> 4.592 + <p> 4.593 + <a class="button" href="$SCRIPT_NAME?list"> 4.594 + <img src="$IMAGES/tazpkg.png" />$(gettext 'My packages')</a> 4.595 + </p> 4.596 + </div> 4.597 +</div> 4.598 +<div class="box"> 4.599 +$(eval_gettext 'Executing $cmd for: $pkgs') 4.600 +</div> 4.601 +EOT 4.602 + for pkg in $pkgs 4.603 + do 4.604 + echo '<pre>' 4.605 + echo $(gettext 'y') | tazpkg $cmd $pkg $opt 2>/dev/null | filter_taztools_msgs 4.606 + echo '</pre>' 4.607 + done ;; 4.608 + 4.609 + 4.610 + *\ info\ *) 4.611 + # 4.612 + # Packages info 4.613 + # 4.614 + pkg=$(GET info) 4.615 + search_form 4.616 + sidebar 4.617 + if [ -d $INSTALLED/$pkg ]; then 4.618 + . $INSTALLED/$pkg/receipt 4.619 + files=`cat $INSTALLED/$pkg/files.list | wc -l` 4.620 + action="Remove" 4.621 + action_i18n=$(gettext 'Remove') 4.622 + else 4.623 + cd $LOCALSTATE 4.624 + LOADING_MSG=$(gettext 'Getting package info...') 4.625 + loading_msg 4.626 + IFS='|' 4.627 + set -- $(grep -hs "^$pkg |" packages.desc \ 4.628 + undigest/*/packages.desc) 4.629 + unset IFS 4.630 + PACKAGE=$1 4.631 + VERSION="$(echo $2)" 4.632 + SHORT_DESC="$(echo $3)" 4.633 + CATEGORY="$(echo $4)" 4.634 + WEB_SITE="$(echo $5)" 4.635 + action="Install" 4.636 + action_i18n=$(gettext 'Install') 4.637 + temp="$(echo $pkg | sed 's/get-//g')" 4.638 + fi 4.639 + cat << EOT 4.640 +<h2>$(eval_gettext 'Package $PACKAGE')</h2> 4.641 + 4.642 +<div id="actions"> 4.643 + <div class="float-left"> 4.644 + <p> 4.645 +EOT 4.646 + if [ "$temp" != "$pkg" -a "$action" == "Install" ]; then 4.647 + temp="$(echo $pkg | sed 's/get-//g')" 4.648 + echo "<a class='button' href='$SCRIPT_NAME?do=Install&$temp'>$(gettext 'Install (Non Free)')</a>" 4.649 + else 4.650 + echo "<a class='button' href='$SCRIPT_NAME?do=$action&$pkg'>$action_i18n</a>" 4.651 + fi 4.652 + 4.653 + if [ -d $INSTALLED/$pkg ]; then 4.654 + if grep -qs "^$pkg$" $LOCALSTATE/blocked-packages.list; then 4.655 + cat << EOT 4.656 + <a class="button" href="$SCRIPT_NAME?do=Unblock&$pkg">$(gettext 'Unblock')</a> 4.657 +EOT 4.658 + else 4.659 + cat << EOT 4.660 + <a class="button" href='$SCRIPT_NAME?do=Block&$pkg'>$(gettext 'Block')</a> 4.661 +EOT 4.662 + fi 4.663 + cat << EOT 4.664 + <a class="button" href='$SCRIPT_NAME?do=Repack&$pkg'>$(gettext 'Repack')</a> 4.665 +EOT 4.666 + fi 4.667 + i18n_desc 4.668 + cat << EOT 4.669 + </p> 4.670 + </div> 4.671 + <div class="float-right"> 4.672 + <p> 4.673 + <a class="button" href='$SCRIPT_NAME?list'> 4.674 + <img src="$IMAGES/tazpkg.png" />$(gettext 'My packages')</a> 4.675 + </p> 4.676 + </div> 4.677 +</div> 4.678 +<table class="zebra outbox"> 4.679 +<tbody> 4.680 + <tr><td>$(gettext 'Name:')</td><td>$PACKAGE</td></tr> 4.681 + <tr><td>$(gettext 'Version:')</td><td>$VERSION</td></tr> 4.682 + <tr><td>$(gettext 'Description:')</td><td>$SHORT_DESC</td></tr> 4.683 + <tr><td>$(gettext 'Category:')</td><td>$CATEGORY</td></tr> 4.684 +EOT 4.685 + if [ -d $INSTALLED/$pkg ]; then 4.686 + cat << EOT 4.687 + <tr><td>$(gettext 'Maintainer:')</td><td>$MAINTAINER</td></tr> 4.688 + <tr><td>$(gettext 'Website:')</td><td><a href="$WEB_SITE">$WEB_SITE</a></td></tr> 4.689 + <tr><td>$(gettext 'Sizes:')</td><td>$PACKED_SIZE/$UNPACKED_SIZE</td></tr> 4.690 +EOT 4.691 + if [ -n "$DEPENDS" ]; then 4.692 + echo "<tr><td>$(gettext 'Depends:')</td><td>" 4.693 + for i in $DEPENDS; do 4.694 + echo -n "<a href="$(pkg_info_link $i)">$i</a> " 4.695 + done 4.696 + echo "</td></tr>" 4.697 + fi 4.698 + if [ -n "$SUGGESTED" ]; then 4.699 + echo "<tr><td>$(gettext 'Suggested:')</td><td>" 4.700 + for i in $SUGGESTED; do 4.701 + echo -n "<a href="$(pkg_info_link $i)">$i</a> " 4.702 + done 4.703 + echo "</td></tr>" 4.704 + fi 4.705 + [ -n "$TAGS" ] && echo "<tr><td>$(gettext 'Tags:')</td><td>$TAGS</td></tr>" 4.706 + I_FILES=$(cat $INSTALLED/$pkg/files.list | wc -l) 4.707 + cat << EOT 4.708 +</tbody> 4.709 +</table> 4.710 + 4.711 +<p>$(eval_gettext 'Installed files: $I_FILES')</p> 4.712 + 4.713 +<pre>$(cat $INSTALLED/$pkg/files.list)</pre> 4.714 +EOT 4.715 + else 4.716 + cat << EOT 4.717 +<tr><td>$(gettext 'Website:')</td><td><a href="$WEB_SITE">$WEB_SITE</a></td></tr> 4.718 +<tr><td>$(gettext 'Sizes:')</td><td>$(grep -hsA 3 ^$pkg$ packages.txt undigest/*/packages.txt | \ 4.719 + tail -n 1 | sed 's/ *//')</td></tr> 4.720 +</table> 4.721 + 4.722 +<p>$(gettext 'Installed files:')</p> 4.723 + 4.724 +<pre> 4.725 +`unlzma -c files.list.lzma undigest/*/files.list.lzma 2> /dev/null | \ 4.726 + sed "/^$pkg: /!d;s/^$pkg: //"` 4.727 +</pre> 4.728 +EOT 4.729 + fi 4.730 + ;; 4.731 + 4.732 + 4.733 + *\ admin\ * ) 4.734 + # 4.735 + # Tazpkg configuration page 4.736 + # 4.737 + cmd=$(GET admin) 4.738 + case "$cmd" in 4.739 + clean) 4.740 + rm -rf /var/cache/tazpkg/* ;; 4.741 + add-mirror) 4.742 + # Decode url 4.743 + mirror=$(GET mirror) 4.744 + case "$mirror" in 4.745 + http://*|ftp://*) 4.746 + echo "$mirror" >> $(GET file) ;; 4.747 + esac ;; 4.748 + rm-mirror=http://*|rm-mirror=ftp://*) 4.749 + mirror=${cmd#rm-mirror=} 4.750 + sed -i -e "s@$mirror@@" -e '/^$/d' $(GET file) ;; 4.751 + select-mirror*) 4.752 + release=`cat /etc/slitaz-release` 4.753 + mirror="$(GET mirror)packages/$release/" 4.754 + tazpkg setup-mirror $mirror | log 4.755 + ;; 4.756 + add-repo) 4.757 + # Decode url 4.758 + mirror=$(GET mirror) 4.759 + repository=$LOCALSTATE/undigest/$(GET repository) 4.760 + case "$mirror" in 4.761 + http://*|ftp://*) 4.762 + mkdir -p $repository 4.763 + echo "$mirror" > $repository/mirror 4.764 + echo "$mirror" > $repository/mirrors ;; 4.765 + esac ;; 4.766 + rm-repo=*) 4.767 + repository=${cmd#rm-repo=} 4.768 + rm -rf $LOCALSTATE/undigest/$repository ;; 4.769 + esac 4.770 + [ "$cmd" == "$(gettext 'Set link')" ] && 4.771 + [ -d "$(GET link)/$INSTALLED" ] && 4.772 + ln -fs $(GET link) $LOCALSTATE/fslink 4.773 + [ "$cmd" == "$(gettext 'Remove link')" ] && 4.774 + rm -f $LOCALSTATE/fslink 4.775 + cache_files=`find /var/cache/tazpkg -name *.tazpkg | wc -l` 4.776 + cache_size=`du -sh /var/cache/tazpkg` 4.777 + sidebar 4.778 + cat << EOT 4.779 +<h2>$(gettext 'Administration')</h2> 4.780 +<div> 4.781 + <p>$(gettext 'Tazpkg administration and settings')</p> 4.782 +</div> 4.783 +<div id="actions"> 4.784 + <a class="button" href='$SCRIPT_NAME?admin=&action=saveconf'> 4.785 + <img src="$IMAGES/tazpkg.png" />$(gettext 'Save configuration')</a> 4.786 + <a class="button" href='$SCRIPT_NAME?admin=&action=listconf'> 4.787 + <img src="$IMAGES/edit.png" />$(gettext 'List configuration files')</a> 4.788 + <a class="button" href='$SCRIPT_NAME?admin=&action=quickcheck'> 4.789 + <img src="$IMAGES/recharge.png" />$(gettext 'Quick check')</a> 4.790 + <a class="button" href='$SCRIPT_NAME?admin=&action=fullcheck'> 4.791 + <img src="$IMAGES/recharge.png" />$(gettext 'Full check')</a> 4.792 +</div> 4.793 +EOT 4.794 + case "$(GET action)" in 4.795 + saveconf) 4.796 + LOADING_MSG=$(gettext 'Creating the package...') 4.797 + loading_msg 4.798 + echo "<pre>" 4.799 + cd $HOME 4.800 + tazpkg repack-config | filter_taztools_msgs 4.801 + echo -n "$(gettext 'Path:') " && ls $HOME/config-*.tazpkg 4.802 + echo "</pre>" ;; 4.803 + listconf) 4.804 + echo "<h4>$(gettext 'Configuration files')</h4>" 4.805 + echo "<ul>" 4.806 + tazpkg list-config | while read file; do 4.807 + [ "${file:0:1}" == "/" ] || continue 4.808 + if [ -e $file ]; then 4.809 + echo "<li><a href=\"index.cgi?file=$file\">$file</a></li>" 4.810 + else 4.811 + echo "<li>$file</li>" 4.812 + fi 4.813 + done 4.814 + echo "</ul>" 4.815 + echo "</pre>" ;; 4.816 + quickcheck) 4.817 + LOADING_MSG=$(gettext 'Checking packages consistency...') 4.818 + loading_msg 4.819 + echo "<pre>" 4.820 + tazpkg check 4.821 + echo "</pre>" ;; 4.822 + fullcheck) 4.823 + LOADING_MSG=$(gettext 'Full packages check...') 4.824 + loading_msg 4.825 + echo "<pre>" 4.826 + tazpkg check --full 4.827 + echo "</pre>" ;; 4.828 + esac 4.829 + cat << EOT 4.830 +<h3>$(gettext 'Packages cache')</h3> 4.831 + 4.832 +<div> 4.833 + <form method="get" action="$SCRIPT_NAME"> 4.834 + <p> 4.835 + $(eval_gettext 'Packages in the cache: $cache_files ($cache_size)') 4.836 + <input type="hidden" name="admin" value="clean" /> 4.837 + <input type="submit" value="Clean" /> 4.838 + </p> 4.839 + </form> 4.840 +</div> 4.841 + 4.842 +<h3>$(gettext 'Default mirror')</h3> 4.843 + 4.844 +<pre>$(cat /var/lib/tazpkg/mirror)</pre> 4.845 + 4.846 +<h3>$(gettext 'Current mirror list')</h3> 4.847 +EOT 4.848 + for i in $LOCALSTATE/mirrors $LOCALSTATE/undigest/*/mirrors; do 4.849 + [ -s $i ] || continue 4.850 + echo '<div class="box">' 4.851 + if [ $i != $LOCALSTATE/mirrors ]; then 4.852 + Repo_Name="$(repo_name $(dirname $i))" 4.853 + echo "<h4>$(eval_gettext 'Repository: $Repo_Name')</h4>" 4.854 + fi 4.855 + echo "<ul>" 4.856 + list_mirrors $i 4.857 + echo "</ul>" 4.858 + cat << EOT 4.859 +</div> 4.860 +<form method="get" action="$SCRIPT_NAME"> 4.861 + <p> 4.862 + <input type="hidden" name="admin" value="add-mirror" /> 4.863 + <input type="hidden" name="file" value="$i" /> 4.864 + <input type="text" name="mirror" size="60"> 4.865 + <input type="submit" value="Add mirror" /> 4.866 + </p> 4.867 +</form> 4.868 +EOT 4.869 + done 4.870 + echo "<h3>$(gettext 'Private repositories')</h3>" 4.871 + [ -n "$(ls $LOCALSTATE/undigest 2> /dev/null)" ] && cat << EOT 4.872 +<div class="box"> 4.873 + <ul> 4.874 + $(list_repos) 4.875 + </ul> 4.876 +</div> 4.877 +EOT 4.878 + cat << EOT 4.879 +<form method="get" action="$SCRIPT_NAME"> 4.880 + <p> 4.881 + <input type="hidden" name="admin" value="add-repo" /> 4.882 + $(gettext 'Name') <input type="text" name="repository" size="10"> 4.883 + $(gettext 'mirror') 4.884 + <input type="text" name="mirror" value="http://" size="50"> 4.885 + <input type="submit" value="Add repository" /> 4.886 + </p> 4.887 +</form> 4.888 + 4.889 +<h3>$(gettext 'Link to another SliTaz installation')</h3> 4.890 + 4.891 +<p>$(gettext "This link points to the root of another SliTaz installation. \ 4.892 +You will be able to install packages using soft links to it.")</p> 4.893 + 4.894 +<form method="get" action="$SCRIPT_NAME"> 4.895 +<p> 4.896 + <input type="hidden" name="admin" value="add-link" /> 4.897 + <input type="text" name="link" 4.898 + value="$(readlink $LOCALSTATE/fslink 2> /dev/null)" size="50"> 4.899 + <input type="submit" name="admin" value="$(gettext 'Set link')" /> 4.900 + <input type="submit" name="admin" value="$(gettext 'Remove link')" /> 4.901 +</p> 4.902 +</form> 4.903 +EOT 4.904 + version=$(cat /etc/slitaz-release) 4.905 + cat << EOT 4.906 + 4.907 +<h3 id="dvd">$(gettext 'SliTaz packages DVD')</h3> 4.908 + 4.909 +<p>$(eval_gettext "A bootable DVD image of all available packages for the \ 4.910 +\$version version is generated every day. It also contains a copy of the \ 4.911 +website and can be used without an internet connection. This image can be \ 4.912 +installed on a DVD or an USB key.")</p> 4.913 + 4.914 +<div> 4.915 + <form method="post" action='$SCRIPT_NAME?admin&action=dvdimage#dvd'> 4.916 + <p> 4.917 + <a class="button" 4.918 + href='http://mirror.slitaz.org/iso/$version/packages-$version.iso'> 4.919 + <img src="$IMAGES/tazpkg.png" />$(gettext 'Download DVD image')</a> 4.920 + <a class="button" href='$SCRIPT_NAME?admin&action=dvdusbkey#dvd'> 4.921 + <img src="$IMAGES/tazpkg.png" />$(gettext 'Install from DVD/USB key')</a> 4.922 + </p> 4.923 + <div class="box"> 4.924 + $(gettext 'Install from ISO image:') 4.925 + <input type="text" name="dvdimage" size="40" value="/root/packages-$version.iso"> 4.926 + </div> 4.927 + </form> 4.928 +</div> 4.929 +EOT 4.930 + if [ "$(GET action)" == "dvdimage" ]; then 4.931 + dev=$(POST dvdimage) 4.932 + mkdir -p /mnt/packages 2> /dev/null 4.933 + echo "<pre>" 4.934 + mount -t iso9660 -o loop,ro $dev /mnt/packages && 4.935 + /mnt/packages/install.sh && 4.936 + echo "$dev is installed on /mnt/packages" 4.937 + echo "</pre>" 4.938 + fi 4.939 + if [ "$(GET action)" == "dvdusbkey" ]; then 4.940 + mkdir -p /mnt/packages 2> /dev/null 4.941 + for tag in "LABEL=\"packages-$version\" TYPE=\"iso9660\"" \ 4.942 + "LABEL=\"sources-$version\" TYPE=\"iso9660\"" ; do 4.943 + dev=$(blkid | grep "$tag" | cut -d: -f1) 4.944 + [ -n "$dev" ] || continue 4.945 + echo "<pre>" 4.946 + mount -t iso9660 -o ro $dev /mnt/packages && 4.947 + /mnt/packages/install.sh && 4.948 + echo "$dev is installed on /mnt/packages" 4.949 + echo "</pre>" 4.950 + break 4.951 + done 4.952 + fi 4.953 + ;; 4.954 + *) 4.955 + # 4.956 + # Default to summary 4.957 + # 4.958 + search_form 4.959 + sidebar 4.960 + [ -n "$(GET block)" ] && tazpkg block $(GET block) 4.961 + [ -n "$(GET unblock)" ] && tazpkg unblock $(GET unblock) 4.962 + cat << EOT 4.963 +<h2>$(gettext 'Summary')</h2> 4.964 + 4.965 +<div id="actions"> 4.966 + <a class="button" href="$SCRIPT_NAME?list"> 4.967 + <img src="$IMAGES/tazpkg.png" />$(gettext 'My packages')</a> 4.968 +EOT 4.969 + fslink=$(readlink $LOCALSTATE/fslink) 4.970 + [ -n "$fslink" -a -d "$fslink/$INSTALLED" ] && 4.971 + cat << EOT 4.972 + <a class="button" href="$SCRIPT_NAME?linkable"> 4.973 + <img src="$IMAGES/tazpkg.png" />$(gettext 'Linkable packages')</a> 4.974 +EOT 4.975 + cat << EOT 4.976 + <a class="button" href="$SCRIPT_NAME?recharge"> 4.977 + <img src="$IMAGES/recharge.png" />$(gettext 'Recharge list')</a> 4.978 + <a class="button" href="$SCRIPT_NAME?up"> 4.979 + <img src="$IMAGES/update.png" />$(gettext 'Check upgrades')</a> 4.980 + <a class="button" href="$SCRIPT_NAME?admin"> 4.981 + <img src="$IMAGES/edit.png" />$(gettext 'Administration')</a> 4.982 +</div> 4.983 + 4.984 +$(packages_summary) 4.985 + 4.986 + 4.987 +<h3>$(gettext 'Latest log entries')</h3> 4.988 + 4.989 +<pre> 4.990 +`tail -n 5 /var/log/tazpkg.log | fgrep "-" | \ 4.991 + awk '{print $1, $2, $3, $4, $5, $6, $7}'` 4.992 +</pre> 4.993 +EOT 4.994 + ;; 4.995 +esac 4.996 + 4.997 +# xHTML 5 footer 4.998 +xhtml_footer 4.999 +exit 0