#lang racket/base
(require racket/system
(planet neil/mcfly))
(doc (section "Introduction")
(para "This small package permits determining the hostname in Racket
programs. It does not support multiple names, nor does it distinguish between
network interfaces.")
(para "This package currently relies on the "
(filepath "/bin/hostname")
" program, available on various Unix-like systems, like GNU/Linux
and Mac OS X."))
(doc (section "Interface"))
(define %hostname:null-input-port
(make-input-port 'null
(lambda (s) eof)
(lambda (skip s progress-evt) eof)
void
(lambda () never-evt)
(lambda (k progress-evt done-evt)
(error "no successful peeks!"))))
(define (%hostname:system*/string #:error-name error-name
#:use-exn? use-exn?
#:trim-newline? trim-newline?
#:command command
#:args args)
(let* ((stdout-os (open-output-string))
(stderr-os (open-output-string))
(ok? (parameterize ((current-output-port stdout-os)
(current-error-port stderr-os)
(current-input-port %hostname:null-input-port))
(apply system* command args)))
(stdout-str (get-output-string stdout-os))
(stderr-str (get-output-string stderr-os)))
(if ok?
(if (equal? "" stderr-str)
(if trim-newline?
(regexp-replace #rx"\r?\n$" stdout-str "")
stdout-str)
(if use-exn?
(error error-name
"shell command ~S had stderr ~S and stdout ~S"
(cons command args)
stderr-str
stdout-str)
#f))
(if use-exn?
(error error-name
"shell command ~S failed with stderr ~S and stdout ~S"
(cons command args)
stderr-str
stdout-str)
#f))))
(doc (defproc (get-full-hostname)
(or/c #f string?)
(para "Gets the full hostname (aka, fully-qualified domain name, or FQDN) of the host, or "
(racket #f)
" if unknown.")
(racketinput (get-full-hostname)
#,(racketresult "computer.lan"))))
(provide get-full-hostname)
(define (get-full-hostname)
(or (getenv "HOSTNAME")
(%hostname:system*/string #:error-name 'get-full-hostname
#:use-exn? #f
#:trim-newline? #t
#:command "/bin/hostname"
#:args '("-f"))
(%hostname:system*/string #:error-name 'get-short-hostname
#:use-exn? #f
#:trim-newline? #t
#:command "hostname"
#:args '("-f"))))
(doc (defproc (get-short-hostname)
(or/c #f string?)
(para "Gets the short hostname (i.e., just the hostname of the immediate host, not qualified with any parent domain names), or "
(racket #f)
" if unknown.")
(racketinput (get-short-hostname)
#,(racketresult "computer"))))
(provide get-short-hostname)
(define (get-short-hostname)
(or (%hostname:system*/string #:error-name 'get-short-hostname
#:use-exn? #f
#:trim-newline? #t
#:command "/bin/hostname"
#:args '("-s"))
(%hostname:system*/string #:error-name 'get-short-hostname
#:use-exn? #f
#:trim-newline? #t
#:command "hostname"
#:args '())))
(doc history
(#:planet 1:0 #:date "2012-09-29"
(itemlist
(item "Initial release."))))