PostgreSQL’s ~/.pgpass Parser in Common Lisp

Here is a quick and dirty PostgreSQL ~/.pgpass parser, in Common Lisp.

It depends on Split Sequence, conveniently loaded with QuickLisp, like so.

(ql:quickload :split-sequence :silent t)

And here is the actual code. It’s not wrapped in a function, and the other connection parameters are hard coded. This can use some refactoring; particularly with relevance to error handling.

(defvar pguser "user")
(defvar pgdb "database")
(defvar pghost "hostname")
(defvar pgport 5432)

(defvar pgpass
  (handler-case
      (with-open-file 
          (.pgpass "~/.pgpass"
		   :direction :input
		   :if-does-not-exist nil)
	(flet ((wildcard-string= (a b)
		 (or (string= a "*")
		     (string= a (princ-to-string b)))))

	  (loop for line = (read-line .pgpass nil)
	    while line
	    when (destructuring-bind (host port db user passwd)
		   (split-sequence:split-sequence #\: line)
		   (if (and (wildcard-string= host pghost)
			    (wildcard-string= port pgport)
			    (wildcard-string= db pgdb)
			    (wildcard-string= user pguser))
		       passwd))
	    return it)))
    (file-error (e)
		(format *error-output* "Unable to load password file; ~A~%"
			e)
		nil)))

(format t "Password: ~A~%" pgpass)

Licenses

Split-Sequence is part of CL-Utilities and Public Domain.

QuickLisp is licensed under an MIT-style license.

The example code above is © 2015 Johann ‘Myrkraverk’ Oskarsson and licensed under the Two-clause BSD license.

CTemplate Emitter for Stream Output

Google’s CTemplate has very customizable output features, yet it does not come with an emitter (the type of class that actually outputs the template with all the variables filled in) for standard streams.  Hence there is no default way to output to std::cout.

Or I was unable to find one.

Therefore, here is a very simple emitter for stream output.

class StreamEmitter: public ctemplate::ExpandEmitter
{
public:
    StreamEmitter( std::ostream &out ) : sout( out )
    {
    }

    virtual void Emit( char c )
    {
        sout << c;
    }

    virtual void Emit( const std::string &s )
    {
        sout << s;
    }

    virtual void Emit( const char *s )
    {
        sout << s;
    }

    virtual void Emit( const char *s, size_t len )
    {
        sout.write( s, len );
    }

private:
    std::ostream &sout;
};

Then it can be used like this.

// Assume pageDict has been initialized and the variables filled in...

    StreamEmitter coutEmitter( std::cout );

    ctemplate::ExpandTemplate( "template_file", ctemplate::DO_NOT_STRIP, &pageDict, &coutEmitter );

Am I really the only one who wants to emit templates to streams?


Licenese: Three clause BSD (same as CTemplate itself).

The Convoluted Logic of ROT13 in CCL

Playing with CCL, the Mule Code Conversion Language, I decided to write a simple ROT13 algorithm.  This turned out to be tougher than expected since CCL has no concept of the logical and and or operators; what is && and || in C derived languages.

(define-ccl-program my-ccl-rot13
 '(1
   ((loop
     (read r0)
     ;; The convoluted logic of rot13 in CCL.
     (if (r0 >= 110) ; n
       (if (r0 <= 122) ; z
           ((r0 -= 13))) ;; If we are between n-z
         (if (r0 >= 97) ; a
             (if (r0 <= 109) ; m
                 ((r0 += 13))) ;; If we are between a-m
           (if (r0 >= 78) ; N
               (if (r0 <= 90) ; Z
                   ((r0 -= 13))) ;; If we are between N-Z
             (if (r0 >= 65) ; A
                 (if (r0 <= 77); ; M
                     ((r0 += 13))))))) ;; If we are between A-M
     (write r0)
     (repeat)))))

One method to tackle this, as demonstrated above, is to use the if-else construct and carefully order the comparisons.

Now, in order to do something useful with this, we define the function my-rot13-word-at-point.

(defun my-rot13-word-at-point ()
  (interactive)
  (let ((word (word-at-point)))
    (if (stringp word)
	(message (ccl-execute-on-string 'my-ccl-rot13 [0 0 0 0 0 0 0 0 nil]
					word)))))

And now we can do M-x my-rot13-word-at-point and we will see the word (de)cyphered in the echo area.

There is one “bug” so to speak, and that it will potentially display garbage when applied to non-ascii text, such as Japanese.

Finally, these code snippets are GPL 2 or 3 at your convenience.

Illumos: Getting Started with MDB

This is a short introduction to MDB for the Illumos kernel.  Everything we do here is easier and more straight forward to do with DTrace, but that is normal for such a simple example.  We cover how to attach the debugger to a running kernel, set breakpoints and step through the kernel side of an ioctl() call.

To begin with, we will set up serial console for use in VirtualBox on a Windows host, and connect to it with Putty.  You can skip this part if you already have console access to your Illumos box.

Continue reading Illumos: Getting Started with MDB