client.scm.in 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #!@GUILE@ \
  2. -e main
  3. !#
  4. ;;; client.scm -- An example of an RPC call over a SSH tunnel.
  5. ;; Copyright (C) 2015 Artyom V. Poptsov <poptsov.artyom@gmail.com>
  6. ;;
  7. ;; This program is free software: you can redistribute it and/or
  8. ;; modify it under the terms of the GNU General Public License as
  9. ;; published by the Free Software Foundation, either version 3 of the
  10. ;; License, or (at your option) any later version.
  11. ;;
  12. ;; This program is distributed in the hope that it will be useful, but
  13. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. ;; General Public License for more details.
  16. ;;
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with this program. If not, see
  19. ;; <http://www.gnu.org/licenses/>.
  20. ;;; Commentary:
  21. ;; A demo program that makes an RPC call over a SSH tunnel. For simplicity
  22. ;; the program uses ssh-agent for authentication.
  23. ;;
  24. ;; The basic code for the RPC call is taken from Guile-RPC documentation.
  25. ;;; Code:
  26. (use-modules (ice-9 getopt-long)
  27. ;; RPC
  28. (rpc rpc)
  29. (rpc xdr)
  30. (rpc xdr types)
  31. ;; Guile-SSH
  32. (ssh session)
  33. (ssh auth)
  34. (ssh tunnel))
  35. (define result-type
  36. (make-xdr-struct-type (list xdr-integer ;; `integer_part'
  37. xdr-unsigned-integer))) ;; `decimal_part'
  38. (define invoke-split-number
  39. (make-synchronous-rpc-call 80000 0 ;; program and version
  40. 1 ;; procedure number
  41. xdr-double ;; argument type
  42. result-type))
  43. (define (print-help-and-exit)
  44. "Print information about program usage."
  45. (display "\
  46. Usage: rrepl.scm [options] <host>
  47. Connect to a remote REPL (RREPL) using an ssh-agent for authentication.
  48. Options:
  49. --user, -u <user> User name.
  50. --port, -p <port> SSH port number (default: 22)
  51. --help, -h Print this message and exit.
  52. ")
  53. (exit))
  54. (define (main args)
  55. "Entry point of the program."
  56. (let* ((options-spec '((user (single-char #\u) (value #t))
  57. (port (single-char #\p) (value #t))
  58. (help (single-char #\h) (value #f))))
  59. (options (getopt-long args options-spec))
  60. (user (option-ref options 'user (getenv "USER")))
  61. (port (option-ref options 'port "22"))
  62. (help-needed? (option-ref options 'help #f))
  63. (args (option-ref options '() #f)))
  64. (and (or help-needed?
  65. (not args)
  66. (null? args))
  67. (print-help-and-exit))
  68. ;; Make a new SSH session, connect it and authenticate the user.
  69. (let* ((host (car args))
  70. (session (make-session #:user user
  71. #:host host
  72. #:port (string->number port)
  73. #:log-verbosity 'nolog)))
  74. (connect! session)
  75. (userauth-agent! session)
  76. ;; Make a new SSH tunnel.
  77. (let ((tunnel (make-tunnel session
  78. #:port 12345
  79. ;; Guile-RPC server listens on localhost.
  80. #:host "127.0.0.1"
  81. ;; Guile-RPC server port.
  82. #:host-port 6666)))
  83. ;; Make an RPC call using the SSH tunnel.
  84. (call-with-ssh-forward tunnel
  85. (lambda (socket)
  86. (display (invoke-split-number 3.14 #x7777 socket))
  87. (newline)))))))
  88. ;;; client.scm ends here.