Skip to content

Instantly share code, notes, and snippets.

@seven1m
Created May 9, 2010 13:33
Show Gist options
  • Save seven1m/395153 to your computer and use it in GitHub Desktop.
Save seven1m/395153 to your computer and use it in GitHub Desktop.
; my first clojure program -- pings a subnet looking for existing hosts
; usage (you'll need a clj repl script):
; clj pingdom.clj 192.168.2
; clj pingdom.clj --used 10.0.0
;
(ns pingdom
(:use [clojure.contrib.shell-out :only (sh)])
(:use [clojure.contrib.str-utils :only (re-split str-join)])
(:use [clojure.contrib.string :only (replace-first-re)]))
(def *default-subnet* "192.168.1")
(def *ping-cmd* {:mac "ping -c 1 -W 5 -s 1 ",
:nix "ping -c 1 -w 5 -s 1 "})
(defn platform []
(let [os-name (System/getProperty "os.name")]
(cond
(.startsWith os-name "Mac") :mac
(or (.startsWith os-name "Linux") (re-find #"nix" os-name)) :nix
:else :other)))
(defn ping [ip]
(let [cmd ((platform) *ping-cmd*)
args (re-split #"\s+" (str cmd ip))]
(apply sh args)))
(defn host-exists? [ip]
(let [ping-results (ping ip)]
(not (re-find #"100(\.0)?% packet loss" ping-results))))
(defn ping-ips [subnet]
(let [subnet-with-dot (replace-first-re #"\.?$" "." subnet)
ips (map #(str subnet-with-dot %) (range 1 255))
futures (map #(future {:ip %, :exists (host-exists? %)}) ips)]
(map deref (doall futures))))
(defn available-ips [subnet]
(map :ip (remove :exists (ping-ips subnet))))
(defn used-ips [subnet]
(map :ip (filter :exists (ping-ips subnet))))
(defn get-subnet-from-args [args default]
(or
(first (filter #(re-find #"^\d" %) args))
default))
(defn get-options-from-args [args]
(filter #(re-find #"^\-" %) args))
(defn options-include? [options & args]
(some #((set options) %) options))
(let [args *command-line-args*
subnet (get-subnet-from-args args *default-subnet*)
options (get-options-from-args args)]
(if (options-include? options "-u" "--used")
(println (str "Used IPs:\n"
(str-join "\n" (used-ips subnet))))
(println (str "Available IPs\n"
(str-join "\n" (available-ips subnet))))))
(shutdown-agents)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment