Some random code of mine you may find useful or amusing. All
this code is either GPLed
Although some bits of this code are updated rather frequently,
no effort is made to keep everything up to date, thus a lot of
what follows may suffer from byte decay, a desease more
common than tooth decay.
MetaFS is a library to
transparently associate arbitrary meta-data information to
Demyltify is a milter library
for Common Lisp. It doesn't require any external library because it
speaks the (undocumented) Sendmail/milter protocol. The code
is heavily commented so its use should be fairly
(let ((message-counter 0)
(defclass my-context (milter-context)
((byte-count :accessor ctx-byte-count)))
(defmethod handle-event ((e event-body) (ctx my-context))
(incf (ctx-byte-count ctx) (length (event-body-data e)))
(defmethod handle-event ((e event-mail) (ctx my-context))
(setf (ctx-byte-count ctx) 0)
(defmethod handle-event ((e event-end-of-message) (ctx my-context))
(incf byte-counter (ctx-byte-count ctx))
(format t "~
~:R message of ~A byte~:P~%~
the messages seen so far total ~A byte~:P~%~
for an average of ~A byte~:P per message~%"
message-counter (ctx-byte-count ctx)
(round byte-counter message-counter))
(setf demyltify:*required-events* '(:mail :body))
(start-milter 20025 :context-class 'my-context))
Tested on SBCL, CMUCL and CLISP. Requires net4cl.
smta.lisp is a simple and lean SMTP
server written in CL. At the moment it's a very early stage
draft, but somehow promising.
basically a rewrite of spmr with a
substantial refactoring of the code and a new client/server
design that makes it quite efficient.
CLPMR provides the same functionalities as procmail
but with much more flexibility and simplicity due to the fact
that the language you describe the rules with is Lisp and not
some obscure sequence of characters looking like line noise.
Using Lisp, it means that the implementation of things like
mailing list servers and document servers becomes trivial and
you don't even need external programs
(see this example). MIME
content is handled natively as well.
To compile CLPMR you need a handful of Common Lisp libraries
from this page
smtp4cl and sclf)
and SBCL or CMUCL. It doesn't depend on external C libraries.
BINGE is a FFI
generator for Common Lisp. It parses C source files (header
or code, it doesn't mind) and spits out a FFI for your Lisp
system of choice. Functions, global variables, types and
symbolic constants can be easily extracted just naming them.
It's written in a modular way so that adding a new FFI API is
a matter of few hours. Back-ends for SBCL, CMUCL, LispWorks,
UFFI and CLISP are provided.
It comes with a suite of
regression tests and
depends on NPG.
is a Naïve Parser Generator. It's a
small compiler of backtracking recursive descendant parsers
that accepts grammars in an extended BNF notation of arbitrary
complexity (excluding indirect left recursive rules).
It doesn't produce any file, it just compiles the grammar
internally, ready to be used. A couple of examples are
included: a VS-Cobol II and a Python grammar (both far from
termcap.lisp is a termcap library
for CL. All capabilities are accessible through
getcap primitive. Some other common
primitives are provided (goto, put); see the end of the file.
asdfa.lisp, a few
extensions to ASDF. This code adds five operations:
Watch out that the
pack-op which creates
an archive (by default a tar archive) of all the files in the
tag-op which creates an Emacs/Vi tags
stat-op which prints some figures about
the system files (from Unix
make-exe-op which writes an executable file
containing all the necessary modules required to run the
system (it works on SBCL and CMUCL, but for the latter you
may need my
revert-op which removes the files produced by
another operation; by default it reverts the compilation,
which means the x86f/fasl files
make-exe-op was broken until
CLUSR is a
little program to batch-download fax and voice messages from
an US Robotics Message Modem and forward them via e-mail to
interested parties in a neat MIME attachment. The program
itself is small but makes use of a number of external
MArch is a program that saves email going
through a mail server into a database. It plugs in the
mail delivery system as a milter.
MIME4CL is a MIME library for Common Lisp. It
allows you to craft MIME compliant messages or to parse and
handle them within your program. It doesn't impose arbitrary
limits on the size of the mime messages as long as some
cautions are observed:
If, on the other hand, you prefer to work all in memory, set
*LAZY-MIME-DECODE* to NIL. This will revert to the old
- Don't remove the files mime objects are parsed from as
long as you need to access their mime bodies. Bodies are
not read in memory because they can be very big.
- When creating MIME objects, try, when possible, to use
files as mime body.
CLTIO is a
termio library for Common Lisp. It's a FFI to the Unix/Posix
library. Actually it's a UFFI module automatically generated
by BINGE starting
SMTP4CL is a SMTP client library to send messages
to an MTA (Mail transport Agent). It
NET4CL is a
collection of network functions, mostly encapsulation of
existing functions to uniform the interface between different
Lisp systems. Some other code in this page depends on it.
Currently only CMUCL and SBCL are supported.
GTKA is a small collection of
functions that helped me writing code with CLG. You
probably don't need it for anything but to compile other code
from this page.
TIFF4CL is a library
to read TIFF file tags leaving the actual image data alone.
To compile this library you need ie3fp.
CL-USER> (with-open-file (stream #P"./sample.tiff"
:element-type '(unsigned-byte 8))
(tiff::print-tiff-tags (tiff:parse-tiff stream)))
COMPRESSION = :JPEG
ORIENTATION = 1
X-RESOLUTION = 72
Y-RESOLUTION = 72
RESOLUTION-UNIT = :INCH
JPEG-INTERCHANGE-FORMAT = 7060
JPEG-INTERCHANGE-FORMAT-LENGTH = 9665
Y-CB-CR-POSITIONING = :COSITED
MAKE = "Panasonic"
MODEL = "DMC-FZ7"
ORIENTATION = 1
X-RESOLUTION = 72
Y-RESOLUTION = 72
RESOLUTION-UNIT = :INCH
SOFTWARE = "Ver.1.0 "
DATE-TIME = "2008:09:12 14:10:48"
Y-CB-CR-POSITIONING = :COSITED
EXPOSURE-TIME = 1/100
F-NUMBER = 4
EXPOSURE-PROGRAM = :NORMAL
ISO-SPEED-RATINGS = 80
EXIF-VERSION = (2 . 20)
DATE-TIME-ORIGINAL = "2008:09:12 14:10:48"
DATE-TIME-DIGITIZED = "2008:09:12 14:10:48"
COMPONENTS-CONFIGURATION = #(1 2 3 0)
COMPRESSED-BITS-PER-PIXEL = 4
EXPOSURE-BIAS-VALUE = 0
MAX-APERTURE-VALUE = 3
METERING-MODE = :PATTERN
LIGHT-SOURCE = NIL
FLASH = (:FLASH-DISABLED)
FOCAL-LENGTH = 12
FLASHPIX-VERSION = (1 . 0)
COLOR-SPACE = 1
PIXEL-X-DIMENSION = 2816
PIXEL-Y-DIMENSION = 2112
SENSING-METHOD = :ONE-CHIP-COLOR-AREA
FILE-SOURCE = :DSC
SCENE-TYPE = :DIRECT
CUSTOM-RENDERED = NIL
EXPOSURE-MODE = :AUTO
WHITE-BALANCE = :AUTO
DIGITAL-ZOOM-RATIO = NIL
FOCAL-LENGTH-IN-35MM-FILM = 72
SCENE-CAPTURE-TYPE = :STANDARD
GAIN-CONTROL = NIL
CONTRAST = :NORMAL
SATURATION = :NORMAL
SHARPNESS = :NORMAL
IE3FP is a library to
code and decode floating point numbers in IEEE 754 binary
CL-USER> (format nil "~32B" (ie3fp:encode-ieee-float -123.456))
CL-USER> (ie3fp:decode-ieee-float #B11000010111101101110100101111001)
SCLF is a
collection of functions and macros, too small or too unrelated
to deserve an own package. You need them to compile some code
on this page.
To properly indent the macros defined in SCLF you may want
to add the following lines to your
(defun cl-indent-be (path state indent-point sexp-column normal-indent)
(let ((sexp-start (cadr state))
(lambda (var-indent val-indent)
(let ((i 0))
(while (< (point) current-position)
(while (forward-comment 1))
(cond ((and (= 1 (logand i 1))
(looking-at "[\t\n ]*\\s("))
(throw 'return 2))
(t (setq i (1+ i))
(if (= 1 (logand i 1))
(let ((tag (symbol-at-point)))
(cond ((eq tag 'be)
(funcall calculate-indentation 4 6))
((eq tag 'be*)
(funcall calculate-indentation 5 7))
(put 'be 'common-lisp-indent-function 'cl-indent-be)
(put 'be* 'common-lisp-indent-function 'cl-indent-be)
(put 'awhen 'lisp-indent-function 1)
(put 'gcase 'lisp-indent-function 1)
(put 'acase 'lisp-indent-function 1)
(put 'acond 'lisp-indent-function 1)
(put 'until 'lisp-indent-function 1)
is a collection of functions and macros that happened to pop
up here and there in my web-based programs written on AServe.
You need them to compile some other code from this page.
CLOT is a simple
library to plot data sets in charts of different types.
Currently it supports bar, histogram, line, and pie charts,
all with some optional graphic decorations.
Cobstor is a tool and an
API to seamlessly access legacy Cobol application files from
Common Lisp. The design is client/server; those familiar with
IPC architectures such as Corba or Java Beans, should
understand cobstor in no time.
Lisp proxy stubs talk via a simple IPC layer to Cobol agents
which in turn access the database for you. All you need is
the Cobol record declaration (the copy file, in Cobol
speak) and cobstor will automatically generate the Cobol agent
and the Lisp proxy for you.
It's been developed on CMUCL+AcuCobol but it should be easily
portable to other Lisp systems that support MOP, and Cobol
systems with socket primitives.
is a simple FFI interface to the
that lets Common Lisp programs translate byte sequences
from/to different character sets, like this:
(cliconv:iconv (map '(vector (unsigned-byte 8)) #'char-code
"François, piña, böse, skøl")
This package uses UFFI, so it should be fairly portable.
is a currency conversion library based on AllegroServe. It
works with multiple rate providers and currently two are
implemented: WebserviceX and the ECB (European Central Bank).
CL-USER> (asdf:oos 'asdf:load-op :currensea)
CL-USER> (currency:get-quote "USD")
CL-USER> (currency:exchange-rate "JPY" "USD")
CL-USER> (currency:convert-currency 10000 "BMD" "CNY")
can produce spreadsheets
in OpenDocument format (those suitable
for OpenOffice and other popular office
programs). It can produce multiple page sheets but cells
can't contain formulas (I've no need for those, yet). This
package depends on SCLF.
Here is an example:
(a b c)
(1.2 3.4 5.6)
("foo" "bar" "baz"))))
is a hack at a library that speaks to
MDM) is a meta-data
manager in general, and a picture manager in particular,
written to archive, sort and ultimately make sense of my
increasingly messy collection of photographs.
finddup-20120706.src.tbz finds duplicate
files in directory trees. It reports files containing the
same data but are not the same inode.
bencode-20130318.src.tbz is a CL library
and an Elisp module to handle bencoded files, such as
BitTorrent files. The Emacs library can only show files, it
can't create them.
I use it like this:
(local-set-key "\C-c\C-t" 'dired-view-torrent)))
mark-selection.scm is a
Script-Fu module for Gimp to quickly highlight spots
of an image for didascalic purposes as in
this sample image. (The three
spots have been chosen randomly and therefore don't show
frame.scm is a Script-Fu module
for Gimp to
prepare my photographs for Internet publishing. It adds some
new commands you will find under
The following code samples have been tested under Scsh 0.5.3.
ppplog.scm is an example of use for
SCSH as report language. This scsh script prints some
statistics taken from the ppp.log files (the user-land ppp
daemon of FreeBSD). It prints, sorted by day, the on-line
time, input and output traffic. Something like this:
24/9 01:59:57 12M 8M
25/9 00:26:10 3M 2M
26/9 01:02:01 13M 1M
27/9 02:18:18 14M 4M
28/9 00:31:47 5M 2M
29/9 00:54:41 8M 3M
of messing around with a brain damaged syntax akin at the
anachronistic sendmail cf files,
I eventually decided to write an MDA (Mail Delivery Agent)
that would let me sieve and handle my incoming mail from the
comfort of the Scheme language, with all the expressiveness of
Scheme and with the power of a real programming
language. If you want to be able to deal with mime files you
need mpack as well.
Here is an example of rules file.
All you need to do is to redirect your e-mail to spmr.
Something like this in your
.forward file will do:
where spmr is the trampoline program.
Note that the trampoline program improves dramatically
performances on heavy e-mail traffic, avoiding to run multiple
SCSH instances concurrently, which has the potential risk of
clogging the system.
spmr.image should be installed in the same
place as the trampoline.
Some functions to generate
business cards in postscript. This requires fps 1.0 and
a patch to correct a bug triggered by
my code. You can start from this example
to find out how to use the library.
An utility to help
keeping tidy your FreeBSD distfiles directory.
It removes (or shows) the outdated distribution files.
An utility to find
system installation problems, such as missing shared libraries
and stray cat pages (pun intended). It walks through
your search path, or a list of directories you supply. It's
useful if you sometimes removed packages without taking care
of broken dependencies. It has been written for FreeBSD but
its usefulness is not limited to that OS.
An utility to find broken
symbolic links. It checks, possibly recursively, a list of
files or your current directory for broken symbolic links.
update-cvs.scm is a script to
keep up to date the source code kept under CVS by someone
It fully exploits the available bandwidth by executing
parallel cvs commands up to
Hitting the INFO key (normally Ctrl-T, see
you get a neat summary of what's going on.
Extract all the e-mail
addresses from files (HTML pages). Any unethical use of
this script, such as the building of spam lists, will be
punished in the afterlife.
Convert to tar (but can be anything)
from any other inferior archive format. Aka, yet
another trivial example of Scsh use in everyday life.
Create an ISO-9660 image from
a list of directories. It asks interactively some details
guessing some defaults and proposes you to burn the image
right away. It needs cdrtools and mkisofs.
Some syntactic sugar for Scsh (or
One of the features in the wish list of Arc that I found
cool was the square bracket sexp that expands to a single
argument lambda expression. So that one can do things like:
(map [/ _ 2] '(2 4 6 8 10))
(cond ((regexp-exec re str) => [match:substring _ 1]) ...)
(map (lambda (x) (/ x 2)) '(2 4 6 8 10))
(cond ((regexp-exec re str) => (lambda (m) (match:substring m 1))) ...)
Disclaimer: I am not advocating Perl-ish syntactic crypticism.
This has been written just as a funny exercise in Scsh
Here is a less heretic approach for those using
(defun lisp-insert-lambda ()
"Insert lambda form at point asking for variables."
(insert "(lambda (" (read-string "Variables: ") ") ")
(save-excursion (insert ")")))
(local-set-key "\C-cl" 'lisp-insert-lambda)))
Patches to the FreeBSD
system. Some Scheme code for FreeBSD is available elsewhere on
The following code is made for the Sawfish Window manager.
A poor man's dock for WindowMaker dockable
Some simple input/output utilities.
A few functions to change the LCD
back light intensity of a Sony Vaio. Under FreeBSD you need to
install the sjog package, because this code
setbrightness. I recommend to bind
increase-brightness to the
Super-Button5-Click event. Tested on a
A Ctrl-Alt-Del mapping for Sawfish for
those of us stuck with the MS look'n'feel-sick.
doesn't work with file names having a leading space.
Here's how to get around the problem:
(defun dired-count-spaces-before-filename ()
(let* ((ls (shell-command-to-string "ls -ld"))
(pos (- (length ls) 2)))
(assert (= ?. (aref ls pos)))
(setq pos (1- pos))
(while (char-equal ?\ (aref ls pos))
(setq pos (1- pos)))
(- (length ls) pos 3)))
(let ((spaces (dired-count-spaces-before-filename))
(when (char-equal ?+ (aref re (1- (length re))))
(concat (substring re 0 (1- (length re)))
(make-string (1- spaces) ?\ )))))
Don't forget to check if
might help with special characters, as well.
A script to reset a Cisco
EPC3208G cable modem. If your Internet connection keeps dying
on you, you may want to reset your cable modem once in a
while. With this script you don't need to bother firing your
web browser. You can even do it from a cron job. It works
through the HTTP protocol as I'm not even sure that router has
SNMP. For more on its use, just run it without arguments.
A little fan controller
for the DIYer in you.
is a collection of programs to use
an IgorPlug-USB on FreeBSD and
possibly other operating systems. This device is a universal
infrared receiver with a USB interface. If you can't be
bothered with electronic DIY, or you are not fluent with
Slovenian-English, you may
find ready made USB dongles for few
euros on eBay.
Igorplug was written mainly because LIRC, which supports
this device, is too Linux-centric and thus is poorly
supported under *BSD. This program doesn't work with LIRC.
Igorplug intends to be a replacement for LIRC, but is
limited to this device; you may notice that most of what you
need is already implemented.
Igorplug is not much documented but it should be quite
straightforward to use.
There is also a C library and a Common Lisp library in case
the programs above aren't enough for your needs.
igor_broadcast broadcasts the received
infrared sequences via UDP to a specific host and port.
igor_echo prints on standard output the IR
sequences it receives from a device. This is useful to
compile a configuration file for the following programs.
igor_inject converts IR sequences into
X-events and sends them to a specific window or any
window currently in focus. This uses a configuration
file containing the association of sequences and events.
igor_pty converts IR sequences into
keystrokes that are sent to a child program, which is
specified as argument. This uses a configuration file
containing the association of sequences and keystrokes.
A tiny little patch
0.2, a netgraph based packet mangler
for FreeBSD. The original
0.2 version worked only on FreeBSD up to 5.2. The author,
Dominik Łupiński, discontinued the project and authorised me
to publish this patched
A simple file concatenation utility
similar to cat(1) but suitable to incrementally copy
log files. It concatenates two or more files avoiding to
replicate footer and header of adjacent files. That
is, if a file ends with the same data at the beginning of the
next one, only one copy of this repeated data is guaranteed to
be present in the output.
abcd + cdef = abcdef.
If the option
-o is given, files are concatenated
after the end of the first (modifying it).
Software for the Thomson
(RCA outside Germany) Lyra MP3 player.
All the photographs on these pages are copyright Walter
C. Pelissero. All rights are reserved. No copy, manipulation or
transfer, beside for the sake of personal view of the page where
they appear on, is allowed. Also the direct linking of web pages to
the single photograph image is forbidden.
Copyright © Walter C. Pelissero, all rights reserved
If you need to have them, much higher resolution hard copies are
available on request.
Last modified: Sat Jun 21 11:37:52 CEST 2014