Skip to content

Instantly share code, notes, and snippets.

@pclouds
Created August 9, 2017 14:49
Show Gist options
  • Save pclouds/f6f5750498470c0594db8f63e3c96e2a to your computer and use it in GitHub Desktop.
Save pclouds/f6f5750498470c0594db8f63e3c96e2a to your computer and use it in GitHub Desktop.
#!/usr/bin/env gosh
(use srfi-8)
(use srfi-39)
(use srfi-60)
(use rfc.base64)
(use rfc.http)
(use sxml.ssax)
(use sxml.sxpath)
(use gauche.net)
(use gauche.parseopt)
(define *user-agent* "noip.scm/0.1 pclouds@gmail.com")
(define *username* (make-parameter #f))
(define *password* (make-parameter #f))
(define (get-credential)
(with-output-to-string
(lambda ()
(with-input-from-string
(format "username=~a&pass=~a" (*username*) (*password*))
base64-encode))))
(define (get-visible-address)
(receive (code header body)
(http-get "ip1.dynupdate.no-ip.com:8245" "/")
(unless (string=? code "200")
(error "failed to get visible address" code header body))
(inet-string->address body)))
(define (get-interface-address name)
(let ([sock (make-socket AF_INET SOCK_DGRAM)])
(if (logtest (socket-ioctl sock SIOCGIFFLAGS name) IFF_UP)
(sockaddr-addr (socket-ioctl sock SIOCGIFADDR name))
#f)))
(define (%sxml->hosts sxml)
(map (lambda (domain)
(let ([domain-name (car ((sxpath "/@name" '()) domain))])
(map (lambda (host-name)
(cons (cadr host-name)
(cadr domain-name)))
((sxpath "/host/@name" '()) domain))))
((sxpath "//domain" '()) sxml)))
(define (sxml->hosts sxml)
(apply append (%sxml->hosts sxml)))
(define (get-hosts)
(let* ([uri (format "/settings.php?requestL=~a" (get-credential))])
(receive (code header body)
(http-get "dynupdate.no-ip.com" uri)
(unless (string=? code "200")
(error "failed to get host list" code header body))
(let ([sxml (ssax:xml->sxml (open-input-string body) '())])
(sxml->hosts body)))))
(define (update-host host secure :optional (address #f))
(let ([uri (if address
(format "/nic/update?hostname=~a&myip=~a"
host
(inet-address->string address AF_INET))
(format "/nic/update?hostname=~a"
host))])
(receive (code headers body)
(http-get "dynupdate.no-ip.com" uri
:secure secure
:auth-user (*username*)
:auth-password (*password*))
(unless (string=? code "200")
(error "failed to update host" code header body))
(print body))))
(define (main args)
(let-args (cdr args)
([username "u|username=s"]
[host "h|host=s"]
[all-hosts "all-hosts"]
[secure "secure"])
(parameterize ([http-user-agent *user-agent*]
[*username* username]
[*password* (begin
(display "Enter password:")
(without-echoing #f read-line))])
(update-host host secure))))
;(display (inet-address->string (get-visible-address) AF_INET))
;(display (inet-address->string (get-interface-address "eth0") AF_INET))
;; (display "\n")
;(update-host '("pclouds" . "noip.me") 123)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment