Skip to content

Download whole directory as a zip file (Apache2)

zipscriptIf you’re hosting many little files but don’t want to setup GIT/rsync/FTP etc. for other people, Apache and CGI may just suit you perfectly. Or any other webserver out there which is able to handle CGI.

This little bash script can be copied into the according directory hosting the file and replaces the default “Index of” view on Apache with my alternative. The script prints out file and folder sizes, fulltext filenames and ZIP download buttons. Additionally, the content of a README file inside the directory is displayed on top of the file tree.

export Filename="$(pwd|sed -e 's,.*/,,').zip"
if test "$QUERY_STRING" == zip; then
 echo Content-type: application/zip
 echo "Content-Disposition: attachment; filename=$Filename"
 zip -9Dx index.cgi - *
elif test "$QUERY_STRING" == fullzip; then
 echo Content-type: application/zip
 echo "Content-Disposition: attachment; filename=$Filename"
 cd .. ; zip -9rx *index.cgi - "$(echo "$Filename"|sed -e s/.zip$//)"
 echo "Content-type: text/html; charset=utf-8"
 echo "<HTML><HEAD><TITLE>Index of: "$(pwd|sed -e 's,.*/,,')""
 echo "</TITLE></HEAD><BODY><A HREF="..">Go up</A> |"
 echo "<A HREF="./?zip">ZIP of current dir</A> |"
 echo "<A HREF="./?fullzip">ZIP of all subdirs</A><BR>"
 cat README|sed '{:q;N;s/n/<BR>/g;t q}'
 echo "<h2>Index of: "$(pwd|sed -e 's,.*/,,')"</h2><UL>"
 for N in *; do
 if [ $N != "index.cgi" ]
 echo "<LI><A HREF="$N">$N</A> ($(du -hs "$N"|cut -f1))</LI>"
 echo "</UL></BODY></HTML>"

The Apache config just needs this afterwards:

<Directory /var/www/html>;
 DirectoryIndex index.cgi
 AddHandler cgi-script .cgi
 Options +ExecCGI

It is also possible to just add +FollowSymLinks in the Apache config and automatically populate symlinks pointing to the actual index.cgi file:

for N in $(find . -type d); do ln -s /source/index.cgi $N/index.cgi; done

However I am using SUExec and it doesn’t work with that – logically. I had to copy the index.cgi into every directory and set the rights accordingly:

for N in $(find . -type d); do cp /source/index.cgi $N/index.cgi; done
for N in $(find . -type d); do chmod +x $N/index.cgi; done
for N in $(find . -type d); do chown user:users $N/index.cgi; done

Adding this into a cronjob would make perfect sense, if the directories change very often.

Credit go to the Linux Gazette for the basic idea. Here in action.

This Post Has 0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

Back To Top