Created
August 9, 2017 14:49
-
-
Save pclouds/f6f5750498470c0594db8f63e3c96e2a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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