<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BBBlog &#187; scripting</title>
	<atom:link href="http://bbbart.eu/blog/category/scripting/feed/" rel="self" type="application/rss+xml" />
	<link>http://bbbart.eu/blog</link>
	<description>news, diary, journal, whatever</description>
	<lastBuildDate>Sun, 12 Dec 2010 20:08:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Passing Command Line Arguments to a LaTeX Document</title>
		<link>http://bbbart.eu/blog/passing-command-line-arguments-to-a-latex-document/</link>
		<comments>http://bbbart.eu/blog/passing-command-line-arguments-to-a-latex-document/#comments</comments>
		<pubDate>Mon, 06 Apr 2009 13:30:57 +0000</pubDate>
		<dc:creator>Bart Van Loon</dc:creator>
				<category><![CDATA[Open Source Adventures]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://bbbart.eu/blog/?p=189</guid>
		<description><![CDATA[Some time ago, someone asked me if I knew a way to pass command line arguments to LaTeX documents. My first response was that this ought to be impossible; being a compiler, LaTeX cannot in any way alter it&#8217;s input files. But command line parameters can alter the output without touching the input of course. [...]]]></description>
			<content:encoded><![CDATA[<p>Some time ago, someone asked me if I knew a way to pass command line arguments to <a href="http://www.latex-project.org/">LaTeX</a> documents. My first response was that this ought to be impossible; being a compiler, LaTeX cannot in any way alter it&#8217;s input files. But command line parameters can alter the output without touching the input of course.</p>
<p>This has kept me thinking for a while, and at the end I came up with some kind of a solution.</p>
<p>Let&#8217;s take a simple LaTeX file:<br />
<code type="tex"><br />
\documentclass{article}<br />
\begin{document}<br />
\someinput{}<br />
\end{document}<br />
</code><br />
and call it <code>test.tex</code>.</p>
<p>We will define the output of <code>\someinput{}</code> as a command line parameter at LaTeX invocation, as follows:<br />
<code type="tcsh"><br />
echo '\\newcommand{\\someinput}{hello world} \\input test' | latex<br />
</code></p>
<p>Result: <code>test.dvi</code> containing the text &#8220;hello world&#8221;. Admitted, it&#8217;s not the easiest solution, but it does make LaTeX useful inside simple batch jobs!</p>
<p>For more advanced LaTeX templating, I advise using <a href="http://perl.org">Perl</a> and <a href="http://search.cpan.org/~mjd/Text-Template-1.45/lib/Text/Template.pm">Text::Template</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bbbart.eu/blog/passing-command-line-arguments-to-a-latex-document/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gettext management</title>
		<link>http://bbbart.eu/blog/gettext-management/</link>
		<comments>http://bbbart.eu/blog/gettext-management/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 18:15:17 +0000</pubDate>
		<dc:creator>Bart Van Loon</dc:creator>
				<category><![CDATA[Open Source Adventures]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://bbbart.eu/blog/?p=177</guid>
		<description><![CDATA[Anybody remember gettext? A couple of years ago I investigated the localisation system for a project and actually came to like it pretty much. Managing your .po and .mo files can be a hassle though. That&#8217;s why I created these two scripts to help me handle them: #!/usr/local/bin/bash function createpot { # create new .po [...]]]></description>
			<content:encoded><![CDATA[<p>
Anybody remember <a href="http://www.gnu.org/software/gettext/">gettext</a>?<br />
A couple of years ago I investigated the localisation system for a project and actually came to like it pretty much.<br />
Managing your .po and .mo files can be a hassle though.<br />
That&#8217;s why I created these two scripts to help me handle them:
</p>
<p><code type="sh"><br />
#!/usr/local/bin/bash</p>
<p>function createpot {<br />
	# create new .po templates (.pot)<br />
	local POT=$1<br />
	touch ./locale/${locale}.UTF-8/LC_MESSAGES/${POT}.pot</p>
<p>    xgettext --default-domain=${DOMAIN} \<br />
        --output-dir="./locale/${locale}.UTF-8/LC_MESSAGES/" --language PHP \<br />
        --force-po --indent --strict --no-wrap \<br />
        --copyright-holder='inGen cvba' \<br />
        --msgid-bugs-address='bart@inGen.be' --output=${POT}.pot \<br />
        --add-location ${phpfile} </p>
<p>	chmod -f g+rw ./locale/${locale}.UTF-8/LC_MESSAGES/${POT}.pot<br />
}</p>
<p>function updatepo {<br />
	# update the original with the new potfile<br />
	local PO=$1<br />
	touch ./locale/${locale}.UTF-8/LC_MESSAGES/${PO}.po<br />
	touch ./locale/${locale}.UTF-8/LC_MESSAGES/${PO}.pot</p>
<p>    msgmerge --update --backup=simple --force-po --indent --strict \<br />
        --no-wrap --quiet --add-location \<br />
        ./locale/${locale}.UTF-8/LC_MESSAGES/${PO}.po \<br />
		./locale/${locale}.UTF-8/LC_MESSAGES/${PO}.pot </p>
<p>	chmod -f g+rw ./locale/${locale}.UTF-8/LC_MESSAGES/${PO}.po<br />
}</p>
<p>function mergepot {<br />
	# merge the original po with the new pot<br />
	local PO=$1<br />
	local POT=$2<br />
	touch ./locale/${locale}.UTF-8/LC_MESSAGES/${PO}.po<br />
	touch ./locale/${locale}.UTF-8/LC_MESSAGES/${POT}.pot</p>
<p>    msgcat --output-file=./locale/${locale}.UTF-8/LC_MESSAGES/${POT}.pot \<br />
        --to-code=UTF-8 --use-first --force-po --indent --add-location \<br />
        --strict --sort-output \<br />
        ./locale/${locale}.UTF-8/LC_MESSAGES/${PO}.po \<br />
        ./locale/${locale}.UTF-8/LC_MESSAGES/${POT}.pot</p>
<p>	rm -f ./locale/${locale}.UTF-8/LC_MESSAGES/${PO}.po<br />
	chmod -f g+rw ./locale/${locale}.UTF-8/LC_MESSAGES/${POT}.pot<br />
}</p>
<p>function backuppo {<br />
	# do a real backup of the existing pofiles<br />
    cp ./locale/${locale}.UTF-8/LC_MESSAGES/${DOMAIN}.po \<br />
        ./locale/${locale}.UTF-8/LC_MESSAGES/pobackup/<br />
}</p>
<p>for locale in nl_BE fr_BE en_GB<br />
do<br />
	# generate .po messages<br />
	for phpfile in index.php<br />
	do<br />
		# the domain is the basename of the file<br />
		DOMAIN=`basename $phpfile .php`</p>
<p>		backuppo<br />
		createpot ${DOMAIN}<br />
		updatepo ${DOMAIN}<br />
	done<br />
done<br />
</code></p>
<p>
and
</p>
<p><code type="sh"><br />
#!/usr/local/bin/bash</p>
<p># generate .mo messages of al .po files<br />
for lang in nl_BE fr_BE en_GB<br />
do<br />
	for pofile in ./locale/${lang}.UTF-8/LC_MESSAGES/*.po<br />
	do<br />
		rm -f ${profile/po/mo}<br />
		msgfmt ${pofile} -o ${pofile/po/mo} --strict --check --use-fuzzy<br />
		chmod -f g+r ${pofile/po/mo}<br />
	done<br />
done<br />
</code></p>
<p>
These scripts will not setup the working environment nor generate full headers for new .po files.<br />
You will have to do this manually.<br />
A corresponding working environment for the scripts in their posted configuration looks like this:
</p>
<pre>
.
|-- images
|   `-- favicon.ico
|-- includes
|   `-- accept-to-gettext.inc
|-- index.php
|-- locale
|   |-- en_GB.UTF-8
|   |   `-- LC_MESSAGES
|   |       |-- index.mo
|   |       |-- index.po
|   |       |-- index.pot
|   |       |-- index.po~
|   |       `-- pobackup
|   |           `-- index.po
|   |-- fr_BE.UTF-8
|   |   `-- LC_MESSAGES
|   |       |-- index.mo
|   |       |-- index.po
|   |       |-- index.pot
|   |       |-- index.po~
|   |       `-- pobackup
|   |           `-- index.po
|   `-- nl_BE.UTF-8
|       `-- LC_MESSAGES
|           |-- index.mo
|           |-- index.po
|           |-- index.pot
|           |-- index.po~
|           `-- pobackup
|               `-- index.po
|-- makemo
|-- makepo
`-- styles
    `-- index.css
</pre>
<p>
Mind the <a href="http://grep.be/data/accept-to-gettext.inc">accept-to-gettext.inc</a> file, a great script written by <a href="http://grep.be/">Wouter Verhelst</a> to convert information in HTTP &#8216;Accept-*&#8217; headers to <a href="http://www.gnu.org/software/gettext/">gettext</a> language identifiers.</p>
]]></content:encoded>
			<wfw:commentRss>http://bbbart.eu/blog/gettext-management/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>pyfconfig &#8212; how to get ifconfig data without regular expressions</title>
		<link>http://bbbart.eu/blog/pyfconfig-how-to-get-ifconfig-data-without-regular-expressions/</link>
		<comments>http://bbbart.eu/blog/pyfconfig-how-to-get-ifconfig-data-without-regular-expressions/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 18:49:02 +0000</pubDate>
		<dc:creator>Bart Van Loon</dc:creator>
				<category><![CDATA[Open Source Adventures]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://bbbart.eu/blog/?p=169</guid>
		<description><![CDATA[After reading this post about ifconfig output parsing by Kris, I remembered I once needed a cross-platform way to get the IP address of an interface in Python. Of course I could just parse the output of `ifconfig`, but I really don&#8217;t like such ugly hacks. I guess I&#8217;ve got too many (bad) experiences with [...]]]></description>
			<content:encoded><![CDATA[<p>
After reading <a href="http://www.krisbuytaert.be/blog/node/730">this post<br />
about ifconfig output parsing by Kris</a>, I remembered I once needed a<br />
cross-platform way to get the IP address of an interface in Python.
</p>
<p>
Of course I could just parse the output of `ifconfig`, but I really don&#8217;t like<br />
such ugly hacks. I guess I&#8217;ve got too many (bad) experiences with <a href="http://search.cpan.org/dist/libwww-perl/">libwww-perl</a> scripts I wrote<br />
for web harvesting various stuff. Basically, this is output parsing too, as<br />
HTML is generally the result of some server side script. Each time the webpage<br />
changed the way it looked (non-CSS changes) or worked, my scripts started to<br />
fail.
</p>
<p>
That&#8217;s when I decided I&#8217;ll always try to avoid such clumsy dependencies on<br />
third party software.
</p>
<p>
So, back to the Python question. I set out for <a href="http://coding.derkeiler.com/Archive/Python/comp.lang.python/2007-03/msg00421.html">a<br />
short adventure on comp.lang.python</a> and came up with a <a href="http://coding.derkeiler.com/Archive/Python/comp.lang.python/2007-03/msg00409.html">solution</a><br />
after some fiddling: pyfconfig, a cross platform Python module to query for the<br />
IP address of an interface.  Tested on FreeBSD x86, GNU/Linux x86 and GNU/Linux<br />
x86_64, with Python 2.4 and Python 2.5. Works just fine.
</p>
<p><code type="c"><br />
#include "Python.h"</p>
<p>#include <sys/types.h><br />
#include <sys/socket.h><br />
#include <netdb.h><br />
#include <netinet/in.h><br />
#include <unistd.h><br />
#include <arpa/inet.h><br />
#include <stdio.h><br />
#include <ifaddrs.h><br />
#include <string.h></p>
<p>// parameters: string (interface name)<br />
// output: string (ip address of interface in decimal notation)<br />
PyObject * ipaddr(PyObject *self, PyObject *args) {</p>
<p>    char ip[ 200 ];<br />
    char *itf;</p>
<p>    if (! PyArg_ParseTuple(args, "s", &#038;itf)) {<br />
        PyErr_SetString(PyExc_Exception, "no interface given!");<br />
        return NULL;<br />
    }</p>
<p>    struct ifaddrs *ifa = NULL, *ifp = NULL;</p>
<p>    if (getifaddrs (&#038;ifp) < 0) {<br />
        perror ("getifaddrs");<br />
        return NULL;<br />
    }</p>
<p>    for (ifa = ifp; ifa; ifa = ifa->ifa_next) {<br />
        socklen_t salen;</p>
<p>        if (ifa->ifa_addr->sa_family == AF_INET)<br />
        salen = sizeof (struct sockaddr_in);<br />
        else if (ifa->ifa_addr->sa_family == AF_INET6)<br />
        salen = sizeof (struct sockaddr_in6);<br />
        else<br />
        continue;</p>
<p>        if (strncmp(ifa->ifa_name, itf, sizeof(itf))) {<br />
        continue;<br />
        }</p>
<p>        if (getnameinfo (ifa->ifa_addr, salen, ip, sizeof (ip), NULL, 0, NI_NUMERICHOST) < 0) {<br />
            perror ("getnameinfo");<br />
            continue;<br />
        }<br />
        break;<br />
    }</p>
<p>    freeifaddrs (ifp);</p>
<p>    return Py_BuildValue("s", ip);<br />
}</p>
<p>static PyMethodDef pyfconfig_methods[] = {<br />
    {"ipaddr", (PyCFunction)ipaddr, METH_VARARGS, "ipaddr(string)\n"},<br />
    {NULL, NULL, 0, NULL}<br />
};</p>
<p>DL_EXPORT(void) initpyfconfig(void) {<br />
    Py_InitModule3("pyfconfig", pyfconfig_methods, "Provides a function to get an ip address of a certain interface.\n");<br />
}<br />
</code></p>
<p>
Compile with <code>gcc -fPIC -shared -Wl -soname pyfconfig.so -o pyfconfig.so -I/usr/include/python2.5/ pyfconfig.c</code> (for Python 2.5) and after an<br />
import pyfconfig, pyfconfig.ipaddr('lo') should return '127.0.0.1' (YMMV).</p>
<p>
No dependency on the output formatting of ifconfig. Less bugs.</p>
]]></content:encoded>
			<wfw:commentRss>http://bbbart.eu/blog/pyfconfig-how-to-get-ifconfig-data-without-regular-expressions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Poor man&#8217;s NTP</title>
		<link>http://bbbart.eu/blog/poor-mans-ntp/</link>
		<comments>http://bbbart.eu/blog/poor-mans-ntp/#comments</comments>
		<pubDate>Wed, 13 Aug 2008 07:07:44 +0000</pubDate>
		<dc:creator>Bart Van Loon</dc:creator>
				<category><![CDATA[Open Source Adventures]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://bbbart.eu/blog/?p=167</guid>
		<description><![CDATA[Yesterday I had to quickly (more or less) synchronize the clocks of a handful of computers I was working on. I didn&#8217;t have the time to work out an NTP based solution, so I came up with the following simple trick: for i in `seq 1 6` do ssh root@192.168.1.20${i} date `date +%m%d%H%M%Y.%S` done Needless [...]]]></description>
			<content:encoded><![CDATA[<p>
Yesterday I had to quickly (more or less) synchronize the clocks of a handful of computers I was working on. I didn&#8217;t have the time to work out an <a href="http://ntp.org">NTP</a> based solution, so I came up with the following simple trick:</p>
<p><code type="sh"><br />
for i in `seq 1 6`<br />
do<br />
        ssh root@192.168.1.20${i} date `date +%m%d%H%M%Y.%S`<br />
done<br />
</code></p>
<p>
Needless to say&#8230; it worked. :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://bbbart.eu/blog/poor-mans-ntp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[office] scantopdf revisited</title>
		<link>http://bbbart.eu/blog/office-scantopdf-revisited/</link>
		<comments>http://bbbart.eu/blog/office-scantopdf-revisited/#comments</comments>
		<pubDate>Sun, 13 Jul 2008 15:48:19 +0000</pubDate>
		<dc:creator>Bart Van Loon</dc:creator>
				<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://bbbart.eu/blog/?p=166</guid>
		<description><![CDATA[At the airport. Bored. Started hacking up my scantopdf script to cater for multiple page documents and a simple scanner. #!/bin/sh # scans an A4 image and saves it as a pdf file with given filename # supports multiple page documents colourmode="Gray" depth=8 resolution=300 while getopts cd:r: option do case $option in c) colourmode="Color";; d) [...]]]></description>
			<content:encoded><![CDATA[<p>
At the airport. Bored. Started hacking up <a href="http://bbbart.eu/blog/office-scantopdf/" title="[office] scantopdf">my<br />
scantopdf script</a> to cater for multiple page documents and a simple scanner.
</p>
<p><code type="sh"><br />
#!/bin/sh</p>
<p># scans an A4 image and saves it as a pdf file with given filename<br />
# supports multiple page documents</p>
<p>colourmode="Gray"<br />
depth=8<br />
resolution=300</p>
<p>while getopts cd:r: option<br />
do<br />
    case $option in<br />
        c)  colourmode="Color";;<br />
        d)  depth=${OPTARG};;<br />
        r)  resolution=${OPTARG};;<br />
        ?)  printf "Usage: %s [-c] [-d depth] [-r resolution] filename.pdf [number of pages]\n" $0<br />
            exit 2;;<br />
    esac<br />
done</p>
<p>shift $(($OPTIND - 1))</p>
<p>filename=$1</p>
<p>numpages=$2<br />
if [ -z ${numpages} ]<br />
then<br />
    numpages=1<br />
fi</p>
<p>getpdf() {<br />
    /usr/bin/scanimage --mode=${colourmode} --depth=${depth} \<br />
                                   --resolution ${resolution} -x 215 -y 297 \<br />
        | /usr/bin/pnmtops -noshowpage -equalpixels -dpi=${resolution} \<br />
        | /usr/bin/ps2pdf -sPAPERSIZE=a4 - "$*"<br />
}</p>
<p>TMPDIR=$(/usr/bin/mktemp -d)</p>
<p>currentpage=0<br />
while [ ${currentpage} -lt ${numpages} ]<br />
do<br />
    currentpage=$((currentpage+1))<br />
    echo "Please insert page ${currentpage}/${numpages}."<br />
    read -p "Press enter to continue..."<br />
    echo "Scanning..."<br />
    getpdf ${TMPDIR}/page${currentpage}.pdf<br />
    echo "Ready!"<br />
done</p>
<p>/usr/bin/pdftk ${TMPDIR}/*pdf cat output ${filename}</p>
<p>echo "Result is ${filename}. Individual pages can be found in ${TMPDIR}."<br />
</code></p>
<p>
It depends on some external tools though and I don&#8217;t really like the way their<br />
paths are hard-coded now, but it&#8217;s useful as is, still (and very easy to<br />
change). Make sure you have <a href="http://www.accesspdf.com/pdftk/">pdftk</a>, <a href="http://www.sane-project.org/">scanimage</a>, <a href="http://netpbm.sourceforge.net/">netpnm</a> and <a href="http://ghostscript.com/">ghostscript</a> installed or it won&#8217;t work for<br />
you.
</p>
<p>
Curious if it will work when I return to the office. :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://bbbart.eu/blog/office-scantopdf-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[sysadmin] vhostlist</title>
		<link>http://bbbart.eu/blog/sysadmin-vhostlist/</link>
		<comments>http://bbbart.eu/blog/sysadmin-vhostlist/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 15:34:30 +0000</pubDate>
		<dc:creator>Bart Van Loon</dc:creator>
				<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://bbbart.eu/blog/?p=138</guid>
		<description><![CDATA[On our public web server, we are hosting a lot of stuff. Currently, we have over one hundred virtual hosts defined in Apache. One day, I realised that I didn&#8217;t have an overview any more of all these deployments. That&#8217;s when I decided to write a simple script to produce me a list of all [...]]]></description>
			<content:encoded><![CDATA[<p>
On <a href="http://zeropoint.it">our</a> public web server, we are hosting a<br />
lot of stuff. Currently, we have over one hundred virtual hosts defined in<br />
Apache.
</p>
<p>
One day, I realised that I didn&#8217;t have an overview any more of all these<br />
deployments. That&#8217;s when I decided to write a simple script to produce me a<br />
list of all virtual hosts (and aliases) in HTML. As it&#8217;s all about file<br />
parsing, and I got a bit bored of Perl, I decided to write it in AWK and wrap<br />
it in sh so it can be installed as a CGI script on the same web server.
</p>
<p><code type="sh"><br />
#!/bin/sh</p>
<p>echo 'Content-Type: text/html; charset=iso-8859-1'<br />
echo 'Cache-Control: no-cache'<br />
echo 'Cache-Control: no-store'<br />
echo 'Pragma: no-cache'<br />
echo 'Expires: Thu, 01 Dec 1994 16:00:00 GMT'<br />
echo</p>
<p>echo '< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd">'<br />
awk 'BEGIN {print "<html><head></head><body><br />
<h1>Virtual Hosts configured on mars</h1>
<ol>"} /^[ \t]*Server(Name|Alias)/ { $1=""; split($0, domains); for (i=0; i<length (domains); i++) { printf("
<li><a href=\"http://%s\">%s</a></li>
<p>\n", domains[i+1], domains[i+1])}} END { print "</ol>
<p></body></html>"}' /etc/apache2/vhosts.d/*<br />
</code></p>
<p>
It&#8217;s still really basic, but it serves it&#8217;s purpose. Wished feature is to show<br />
a difference between ServerName&#8217;s and ServerAlias&#8217;es. This is left as an<br />
exercise to the reader.</p>
]]></content:encoded>
			<wfw:commentRss>http://bbbart.eu/blog/sysadmin-vhostlist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[sysadmin] cupsquota.sh</title>
		<link>http://bbbart.eu/blog/sysadmin-cupsquota-sh/</link>
		<comments>http://bbbart.eu/blog/sysadmin-cupsquota-sh/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 20:57:32 +0000</pubDate>
		<dc:creator>Bart Van Loon</dc:creator>
				<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://bbbart.eu/blog/?p=142</guid>
		<description><![CDATA[Sometimes I want to know how many pages some user printed on some printer on the network from some host on the network. This script tells me just that. #!/bin/sh # script to calculate some statistics from a cups page_log # # takes two (optional) arguments: a cups page_log and a username # # page_log [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes I want to know how many pages some user printed on some printer on<br />
the network from some host on the network. This script tells me just that.</p>
<p><code type="sh"><br />
#!/bin/sh</p>
<p># script to calculate some statistics from a cups page_log<br />
#<br />
# takes two (optional) arguments: a cups page_log and a username<br />
#<br />
# page_log is expected to be in the following format:<br />
#<br />
# samsung sven 279 [23/Nov/2007:18:44:01 +0100] 1 1 - localhost<br />
# samsung sven 280 [23/Nov/2007:20:09:55 +0100] 1 1 - localhost<br />
# HP loes 281 [25/Nov/2007:16:21:18 +0100] 1 1 - localhost<br />
# HP loes 281 [25/Nov/2007:16:21:25 +0100] 2 1 - localhost<br />
# HP loes 281 [25/Nov/2007:16:21:30 +0100] 3 1 - localhost<br />
# HP loes 281 [25/Nov/2007:16:21:34 +0100] 4 1 - localhost<br />
# HP loes 281 [25/Nov/2007:16:21:41 +0100] 5 1 - localhost<br />
# HP loes 281 [25/Nov/2007:16:21:46 +0100] 6 1 - localhost<br />
# HP loes 281 [25/Nov/2007:16:21:49 +0100] 7 1 - localhost<br />
# samsung loes 282 [25/Nov/2007:23:43:22 +0100] 1 1 - localhost<br />
# samsung sven 283 [28/Nov/2007:18:15:30 +0100] 1 1 - localhost<br />
# samsung sven 283 [28/Nov/2007:18:15:32 +0100] 2 1 - localhost<br />
# samsung sven 284 [28/Nov/2007:18:17:42 +0100] 1 1 - localhost<br />
# samsung sven 284 [28/Nov/2007:18:17:46 +0100] 2 1 - localhost<br />
# samsung loes 285 [30/Nov/2007:09:02:14 +0100] 1 1 - localhost<br />
# samsung sven 286 [30/Nov/2007:14:29:33 +0100] 1 1 - localhost<br />
# samsung sven 286 [30/Nov/2007:14:29:36 +0100] 2 1 - localhost<br />
# samsung loes 287 [30/Nov/2007:18:24:37 +0100] 1 1 - localhost</p>
<p>if [ $# -eq 0 ]<br />
then<br />
    USERNAME=${USER}<br />
    PAGELOG=/var/log/cups/page_log<br />
elif [ $# -eq 1 ]<br />
then<br />
    if [ -f $1 ]<br />
    then<br />
        USERNAME=${USER}<br />
        PAGELOG=$1<br />
    else<br />
        USERNAME=$1<br />
        PAGELOG=/var/log/cups/page_log<br />
    fi<br />
elif [ $# -eq 2 ]<br />
then<br />
    if [ -f $1 ]<br />
    then<br />
        PAGELOG=$1<br />
        USERNAME=$2<br />
    else<br />
        PAGELOG=$2<br />
        USERNAME=$1<br />
    fi<br />
else<br />
    echo "Usage:"<br />
    echo "$0 [<username>] [
<page_log>]"<br />
    exit 1<br />
fi</p>
<p>/usr/bin/awk -v username=${USERNAME} '<br />
BEGIN {<br />
    pagecount = 0<br />
    pagenum = 0<br />
    if (!username) {<br />
        username = ENVIRON["USER"]<br />
    }<br />
}</p>
<p>$2 ~ username {<br />
    if ( $6 !~ "total"  ) { # HACK :-(<br />
        if ( $6 == 1 ) {<br />
            pagecount += pagenum<br />
        }<br />
        pagenum = $6<br />
    }<br />
}</p>
<p>END {<br />
    printf "%s has printed %d pages in total\n", username, pagecount<br />
}<br />
' ${PAGELOG}<br />
</code></p>
<p>It&#8217;s an <a href="http://www.gnu.org/software/gawk/manual/gawk.html">awk</a><br />
program with a bourne shell wrapper to calculate the total amount of pages a<br />
user has printed on a host using <a href="http://www.cups.org/">cups</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bbbart.eu/blog/sysadmin-cupsquota-sh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[office] scantopdf</title>
		<link>http://bbbart.eu/blog/office-scantopdf/</link>
		<comments>http://bbbart.eu/blog/office-scantopdf/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 10:17:20 +0000</pubDate>
		<dc:creator>Bart Van Loon</dc:creator>
				<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://bbbart.eu/blog/?p=143</guid>
		<description><![CDATA[Another addition to my [office] collection of scripts. And again one which deals with a scanner. scantopdf scans an A4 paper from any SANE device and stores it as a PDf with a given filename. #!/bin/sh # scans an A4 image and saves it as a pdf file with given filename colourmode="Gray" depth=8 resolution=300 while [...]]]></description>
			<content:encoded><![CDATA[<p>Another addition to my [office] collection of scripts. And again one which<br />
deals with a scanner. scantopdf scans an A4 paper from any SANE device and<br />
stores it as a PDf with a given filename.</p>
<p><code type="sh"><br />
#!/bin/sh</p>
<p># scans an A4 image and saves it as a pdf file with given filename</p>
<p>colourmode="Gray"<br />
depth=8<br />
resolution=300</p>
<p>while getopts cd:r: option<br />
do<br />
    case $option in<br />
        c)  colourmode="Color";;<br />
        d)  depth=${OPTARG};;<br />
        r)  resolution=${OPTARG};;<br />
        ?)  printf "Usage: %s [-c] [-d depth] [-r resolution] filename.pdf\n" $0<br />
            exit 2;;<br />
    esac<br />
done</p>
<p>shift $(($OPTIND - 1))</p>
<p>/usr/bin/scanimage --mode=${colourmode} --depth=${depth} \<br />
                                --resolution ${resolution} -x 215 -y 297 \<br />
	| /usr/bin/pnmtops -noshowpage -equalpixels -dpi=${resolution} \<br />
	| /usr/bin/ps2pdf -sPAPERSIZE=a4 - "$*"<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://bbbart.eu/blog/office-scantopdf/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[office] copymachine</title>
		<link>http://bbbart.eu/blog/office-copymachine/</link>
		<comments>http://bbbart.eu/blog/office-copymachine/#comments</comments>
		<pubDate>Mon, 28 Jan 2008 21:39:28 +0000</pubDate>
		<dc:creator>Bart Van Loon</dc:creator>
				<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://bbbart.eu/blog/?p=144</guid>
		<description><![CDATA[At the office, we have a scanner attached to a desktop (elisa), published as a :net device by SANE. Additionally, a network printer (gutenberg) is attached to the network. This script allows anyone on the network to combine both as a (basic) copymachine. #!/bin/sh colourmode="Gray" depth=8 resolution=300 printername="samsung" copies=1 while getopts cd:r:P:n: option do case [...]]]></description>
			<content:encoded><![CDATA[<p>At the office, we have a scanner attached to a desktop (elisa), published as a<br />
:net device by <a href="http://www.sane-project.org/">SANE</a>. Additionally,<br />
a network printer (gutenberg) is attached to the network. This script allows<br />
anyone on the network to combine both as a (basic) copymachine. </p>
<p><code type="sh"><br />
#!/bin/sh</p>
<p>colourmode="Gray"<br />
depth=8<br />
resolution=300<br />
printername="samsung"<br />
copies=1</p>
<p>while getopts cd:r:P:n: option<br />
do<br />
	case $option in<br />
		c)	colourmode="Color";;<br />
		d) 	depth=$OPTARG;;<br />
		r)	resolution=$OPTARG;;<br />
		P)	printername="$OPTARG";;<br />
		n) 	copies="$OPTARG";;<br />
		?)	printf "Usage: %s [-c] [-d depth] [-r resolution] [-P printername] [-n copies]\n" $0<br />
			exit 2;;<br />
	esac<br />
done</p>
<p>/usr/bin/scanimage --mode $colourmode --depth $depth \<br />
                                   --resolution $resolution -x 215 -y 297 \<br />
	| /usr/bin/pnmtops -noshowpage -equalpixels -dpi=$resolution \<br />
	| /usr/bin/lpr -P $printername -# $copies<br />
</code></p>
<p>Remember it&#8217;s statically configured for A4 papersize (215mm x 297mm).</p>
]]></content:encoded>
			<wfw:commentRss>http://bbbart.eu/blog/office-copymachine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[office] dvitopdf.sh</title>
		<link>http://bbbart.eu/blog/office-dvitopdf-sh/</link>
		<comments>http://bbbart.eu/blog/office-dvitopdf-sh/#comments</comments>
		<pubDate>Mon, 28 Jan 2008 20:08:29 +0000</pubDate>
		<dc:creator>Bart Van Loon</dc:creator>
				<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://bbbart.eu/blog/?p=145</guid>
		<description><![CDATA[At our office we tend to document almost everything with LaTeX. This script is one which has saved us a lot of time already with creating high quality PDF documents. Basically, it&#8217;s just an alias to simplify creating prepress quality A4 PDFs of a DVI file, typically created with LaTeX and hyperref with the dvipdfm [...]]]></description>
			<content:encoded><![CDATA[<p>
At <a href="http://zeropoint.it">our office</a> we tend to document almost<br />
everything with <a href="http://www.latex-project.org/">LaTeX</a>. This script<br />
is one which has saved us a lot of time already with creating high quality PDF<br />
documents.
</p>
<p>
Basically, it&#8217;s just an alias to simplify creating prepress quality A4 PDFs of<br />
a DVI file, typically created with LaTeX and hyperref with the dvipdfm driver.
</p>
<p><code type="sh"><br />
# creates a pdf from a given dvi file on an a4 page<br />
# all parameters are passed to dvipdft<br />
/usr/bin/dvipdft -p a4 -D "/bin/cat %i | /usr/bin/gs -q -dCompatibilityLevel=1.2 -dUseFlateCompression=true -dSAFER -sDEVICE=pdfwrite -sOutputFile=%o -sPAPERSIZE=a4 -dPDFSETTINGS=/prepress - -c quit" $@<br />
</code></p>
<p>
It&#8217;s the &#8220;prepress&#8221; setting at the end which guarantees the quality of the<br />
output.</p>
]]></content:encoded>
			<wfw:commentRss>http://bbbart.eu/blog/office-dvitopdf-sh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

