Compiling Emacs on Mac OS X

30 Sep 2009

This comes up on the emacs mailing list at least once a month. How to compile Emacs on Mac OS X ?

Requirements

To build emacs on Mac OS X, all you need is to install developer tools, if not already installed. This comes with your installation disks or can be downloaded from Apple Developer Connection.

Getting Latest Source

OS X comes with CVS, or use your preferred SCM to download the latest source.

Git
git clone --depth 1 git://git.sv.gnu.org/emacs.git
CVS
cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/emacs co emacs

Building

First you need to run the configure script,

./configure --with-ns

This will configure emacs so that in the end you will get a stand alone application just like any other OS X application.

Next step is actually building the thing,

make
make install

After these steps you will have Emacs.app in the nextstep/ folder. Just copy it to your /Applications folder and you are set.

Fractals in Clojure - Mandelbrot Fractal

29 Sep 2009

In this post we will cover another type of fractal called Mandelbrot. It is named after Benoit Mandelbrot. The cool thing about it is that you can zoom on it forever and at each zoom level you will get a replica of the original image. They also make greate wallpapers.

The algorithm we will use goes like this,

  • We choose a rectangle in a complex plane.
  • We map our image to the complex plane we choose.
  • For each point/pixel we apply z = z^2 + c
  • And calculate how many iterations are required for the point.
  • Paint the point according to it's iteration.

We apply z = z^2 + c until either absolute value of the result is bigger than two or maximum iteration is reached.

 (defn calc-iterations [ p q max-iterations ] 
   (let  [ c (complex p q) ]
     (loop [ z c 
             iterations 0 ]      
       (if  (or (> (abs z ) 2.0 ) (> iterations max-iterations) )
         (if  ( = 0 iterations ) 0 (- iterations 1 ))
         (recur (+ c (* z z) ) (inc iterations)) ))))

For coloring the set it's up to your imagination. Set is colored using iterations, Each iteration is painted using different color. In this function, first 10 iterations are colored black to have a outer shell, last iteration is black to give inner black color, rest of the iterations are calculated using their iteration.

(defn calc-pixel-color [iterations max-iterations]
  (if  (< iterations 10  )
    (new Color 0 0 0 )
    (if  (= iterations max-iterations  )
      (new Color 0 0 0 )
  (let  [ gray (int (/ (* iterations 255) max-iterations )) 
          r    gray
          g    (Math/min (int ( / (* 5 ( * gray gray)) 255)) 255)
          b    (Math/min (int (+ 40 ( / (* 5 (* gray gray)) 255))) 255) ]
    (new Color r g b )))))

Next, we paint on the canvas. We iterate each coordinate convert it to complex plane coordinates then color it based on the iteration.

(defn generate [x y width height max-iterations 
                graphics surface-width surface-height]
  (doseq [i (range surface-width )
          j (range surface-height )]
      (let  [p  ( + x (* width (/ i (float surface-width))))
             q  ( + y (* height (/ j (float surface-height)))) 
             iterations (calc-iterations p q max-iterations) 
             color (calc-pixel-color iterations max-iterations) ]

        (.setColor graphics color)
        (.drawLine graphics i j i j)  )))

We paint the resulting image on to a JLabel and put it in a JFrame.

(draw -2.1 -1.4 3.0 3.1 32 400 400)

mandelbrot

(draw -2.1 -1.4 3.0 3.1 100 400 400)

mandelbrot

Download code

Fractals in Clojure - Fractal Fern

28 Sep 2009

In this post I'm going to show how to draw a type of Fractal called Barnsley's fern.

Basically it goes like this,

  • We start at a point, x=0 y=1 in this case
  • Paint that point on the canvas.
  • Run that point through the transformation function to get the next point.
  • Goto step 2 until desired number of points are painted on the canvas.

This example uses the transformation functions from the Wikipedia article on Iterated function systems.

Transformation

(defn transform-one [ target ] 
  (struct <point> 0 (* 0.16 (:y target))))
(defn transform-two [ target ] 
  (struct <point> 
          (- (* 0.2  (:x target)) (* 0.26 (:y target))) 
          (+ (* 0.23 (:x target)) (* 0.22 (:y target)))))
(defn transform-three [ target ] 
  (struct <point>  
          (+ (* -0.15 (:x target)) (* 0.28 (:y target)))  
          (+ (* 0.26  (:x target)) (* 0.24 (:y target)) 0.44)  ))
(defn transform-four [ target ] 
  (struct <point> 
          (+ (* 0.85   (:x target)) (* 0.04 (:y target)))
          (+ (* -0.004 (:x target)) (* 0.85 (:y target)) 1.6)  ))

(defn transform 
  "Transform point accourding to the percentage."
  [ target ] 
  (let  [ random (new Random) 
          percentage (.nextInt random 100) ] 
    (cond 
     (<= percentage 1 ) (transform-one target)
     (<= percentage 7 ) (transform-two target)
     (<= percentage 14 ) (transform-three target)
     (<= percentage 100 ) (transform-four target) )))

We have four transformations, each transformation is selected at random.

  • Transformation one is selected 1% of the time.
  • Transformation two is selected 7% of the time.
  • Transformation three is selected 7% of the time.
  • Transformation four is selected 85% of the time.

Transformation one draws the stem. Transformation two draws the bottom frond on the left. Transformation three draws the bottom frond on the right. Transformation four generates successive copies of the stem and bottom fronds to make the complete fern.

Fractal Fern

We can call transform repeatedly to get points to draw on the canvas. We can use loop for this but there is better way.

(defn draw-fern [ width height max-points graphics ] 
  (let [ coords  (take max-points (iterate transform (struct <point> 0 1)))]
    (doseq [coord coords]
      (paint-point width height coord graphics )) ))

We use iterate,

user=> (doc iterate)
-------------------------
clojure.core/iterate
([f x])
  Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free
of side-effects

Iterate takes a function and a initial value and returns an infinite sequence of coordinates.

({:x 0, :y 1} {:x 0.28, :y 0.6799999999999999} {:x 0.2652, :y 2.17688} ...

No looping required. It applies the result of each function to the function so that we get a vector of values. Then we take the number of points we want from the sequence.

(defn draw [width height points]
  (let [frame  (new JFrame)
        image  (new BufferedImage width height BufferedImage/TYPE_INT_RGB )
        canvas (proxy [JLabel] []
                 (paint [g]                   
                        (.drawImage g image 0 0 this) ))
        graphics (.createGraphics image)]
    (.setColor graphics Color/green)
    (draw-fern width height points graphics)
    (.add frame canvas)
    (.setSize frame (new Dimension width height))
    (.show frame)))

Next we paint everything on a BufferedImage and paint that on a JLabel, and voila.

400 by 400 10,000 points

Fractal Fern

400 by 400 100,000 points

Fractal Fern

Download code

Multiple Terminals in Emacs

27 Sep 2009

Emacs provides term-mode, which is terminal emulation for emacs. Since term-mode is real terminal emulation it allows you to run any console application you want (even ncurses based ones). But it does not provide a easy way to switch between them if you have multiple buffers open.

(defun na-switch-between-terminals () 
"cycle multiple terminals"
(interactive)
(if (not (eq (or (get-buffer "*terminal*") 
                 (get-buffer "*inferior-lisp*"))  nil ) )
    (progn     
      (setq found nil)
      (bury-buffer)
      (setq head (car (buffer-list)))      
      (while  (eq found nil)        
        (set-buffer head)   
        (if (or (eq major-mode 'term-mode ) 
                (eq major-mode 'inferior-lisp-mode ))
            (setq found t )
          (progn
           (bury-buffer)
           (setq head (car (buffer-list)))))))))

Using this snippet you can cycle between multiple terms in a circular fashion.

A Guide to Raw Traffic in Clojure

25 Sep 2009

This tutorial will cover capturing raw network traffic going via your network interface. We will implement a arp sweeper. Arp is the protocol that is used to find out who uses which IP on the network. So using a arp sweeper you can locate machines on your network pretty quickly.

For this script to work you need libpcap library and jpcap, libpcap's java bindings. libpcap is a packet capture library that allows you to read traffic going through your network card and disassemble captured packets.

Preflight Checks

  • Install libpcap if not installed.
  • Build and install jpcap.
  • Download the script

Code needs to run as root if you want it to capture anything.

Theory

What we are going to do is ask the network, for each IP in the block that who has it.

  • Who has 192.1.1.1?
  • Who has 192.1.1.2?
  • Who has 192.1.1.3?
  • so on...

Then we start listening, machines on the network will respond...

  • 192.1.1.1 is at 00:00:00:00:00:00
  • 192.1.1.2 is at 01:01:01:01:01:01
  • so on...

Code

Let's dissect the code.

 (defn interface-info []
   (doseq [device  (JpcapCaptor/getDeviceList)]
     (let  [name   (.name device)
            mac    (mac-byte-to-string (.mac_address device))
            ip     (interface-ip device)]
       (println (print-device-info name mac) ip))))

interface-info will print name, mac and ip of the all interfaces on your machine. (JpcapCaptor/getDeviceList) returns an array of interfaces. For each device on the machine we query it's name, mac and ip. Note that this will only recognize interface's ipv4 address. But you can easily modify it for ipv6.

(defn mac-byte-to-string [mac-bytes]
  (let [v  (apply vector 
                  (map #(Integer/toHexString (bit-and % 0xff)) mac-bytes))]
    (apply str (interpose ":" v))))

Interfaces mac id is represented as a byte array to visualize it we need to convert it to familiar hex representation.

(defn ipv4? [inet-addrs]
  (if (instance? java.net.Inet4Address inet-addrs)
    true false))

(defn ipv4-addrs [addr-list]
  (filter ipv4? (apply vector (map (fn[i] (.address i)) addr-list))))

Since interface may contain both v4 and v6 IP. We filter only v4 IP's. Now we know all the information about the interface's on the machine we are ready to start capturing some traffic from the network. We first need to open the device for listening.

(defn open-captor [interface]
  (JpcapCaptor/openDevice interface 50 true 0))

This will open the device for listening, 50 bytes will be captured at most using promiscuous mode, which means all packets whether they are meant for your machine or not can be read, and a 0 milisecond timeout.

 (defn arp-sweep [interface]
   (let  [interface (interface-by-name interface)
          captor (open-captor interface)]

     (send-arp-probe captor interface (generateip-ip-list interface))

     (doto (Thread. #(.loopPacket captor -1 (packet-callback)))
       (.start))

     (Thread/sleep 3000)
     (.breakLoop captor)))

This is where the actual scanning takes place. We open the interface for listening. We send arp-request packages for all IP's on the network. Wait for replies on another thread. Since we don't know which machines are on and which ones are off the best we do is wait for a while in this case 3 seconds then assume all responded. 3 seconds is a lot in this case most programs set it well below 1 second.

loopPacket will loop forever waiting for packets, that's why we run it on a separate thread, when it receives a packet it will call our call back function.

 (defn packet-callback []
   (proxy [PacketReceiver] []
     (receivePacket
      [packet]
      (if (instance? ARPPacket packet)
        (let  [src-ip (.getSenderProtocolAddress packet)
               src-mac (.getSenderHardwareAddress packet)] 
          (println (.getHostAddress src-ip) " is at " src-mac))))))

For each packet received we check that if it is a arp packet. Remember we are capturing all traffic going through the device. If it is of type ARPPacket we disassemble it getting it's source IP and MAC which is a machine on the network.

(defn create-arp-request [interface target]
  (let  [broadcast    (into-array (Byte/TYPE) (repeat 6 (byte 255)))
         srcip        (interface-ip interface)
         arp-packet   (ARPPacket.)
         ether-packet (EthernetPacket.)]
    ;;arp
    (set! (.hardtype arp-packet) ARPPacket/HARDTYPE_ETHER)
    (set! (.prototype arp-packet) ARPPacket/PROTOTYPE_IP)
    (set! (.operation arp-packet) ARPPacket/ARP_REQUEST)
    (set! (.hlen arp-packet) 6)
    (set! (.plen arp-packet) 4)
    (set! (.sender_hardaddr arp-packet) (.mac_address interface))
    (set! (.sender_protoaddr arp-packet) (.getAddress srcip))
    (set! (.target_hardaddr arp-packet) broadcast)
    (set! (.target_protoaddr arp-packet) 
          (.getAddress (InetAddress/getByName target)))
    ;;ether
    (set! (.frametype ether-packet) EthernetPacket/ETHERTYPE_ARP)
    (set! (.src_mac ether-packet) (.mac_address interface))
    (set! (.dst_mac ether-packet) broadcast)
    ;;wire
    (set! (.datalink arp-packet) ether-packet)
    arp-packet))

This is our request packet that asks Who has 192.1.1.5?. Two things to note here is that. First it is of type ARPPacket/ARP_REQUEST and we send it to FF:FF:FF:FF:FF:FF which is the broadcast mac address. For more information on the ARP Packet Structure refer to Wikipedia.

 (defn generateip-ip-list [interface]
   (let [ip (.getHostAddress (interface-ip interface))
         block (.substring ip 0 (+ 1 (.lastIndexOf ip ".")))]
     (vec (map #(str block %) (range 1 255)))))

A very quick way to a get list of all IP's on the block. This will return a vector of IP's. Such as [.. 192.1.1.5 192.1.1.6 ..]

That's all after you run the script, you should see a list of machines on your network with their IP's and MAC id's. You can get a list of interfaces available for capture using,

 clojure/(master) $ sudo ~/Projects/scripts/clj arp-sweep.clj  --list
 en0  0:25:0:da:92:84   nil
 vnic0 0:1c:42:0:0:8     #<Inet4Address /10.211.55.2>
 en1  0:25:0:40:a8:cf   #<Inet4Address /192.168.3.13>
 vnic1 0:1c:42:0:0:9     #<Inet4Address /10.37.129.2>
 lo0  0:0:0:0:0:0       #<Inet4Address /127.0.0.1>

Then using any one of the interfaces initiate a scan,

clojure/(master) $ sudo ~/Projects/scripts/clj arp-sweep.clj  --device en1

Git Delete Last Commit

24 Sep 2009

Once in a while late at night when I ran out of coffee, I commit stuff that I shouldn't have. Then I spend the next 10 - 15 minutes googling how to remove the last commit I made. So after third time I wanted to make a record of it so I can refer to it later.

If you have committed junk but not pushed,

git reset --hard HEAD~1

HEAD~1 is a shorthand for the commit before head. Alternatively you can refer to the SHA-1 of the hash you want to reset to. Note that when using --hard any changes to tracked files in the working tree since the commit before head are lost.

If you don't want to wipe out the work you have done, you can use --soft option that will delete the commit but it will leave all your changed files "Changes to be committed", as git status would put it.

Now if you already pushed and someone pulled which is usually my case, you can't use git reset. You can however do a git revert,

git revert HEAD

This will create a new commit that reverses everything introduced by the accidental commit.

Compiling Emacs on Debian

23 Sep 2009

Required Packages

To build Emacs on Debian fire a terminal and install the required packages, using apt-get

build-essential
xorg-dev
libgtk2.0-dev
libjpg-dev 
libgif-dev 
libtiff-dev

Getting Latest Source

Choose your favarite CVS and get the latest source.

Git
git clone --depth 1 git://git.sv.gnu.org/emacs.git
CVS
cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/emacs co emacs

Either one will create a folder named emacs under the current directory. Switch to that directory.

cd emacs/

Building

First you need to run the configure script,

./configure --prefix=/path/to/some/directory/

Now you are ready to build.

make bootstrap
make
make install

If your install location is not in your home directory use,

sudo make install

After make install you should have emacs installed under the directory you specified.