-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
1,077 additions
and
990 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
Copyright (C) 2007 Brian Jiang | ||
|
||
Author: Brian Jiang <[email protected]> | ||
Version: 1.0 | ||
|
||
This library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
|
||
This library is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
Lesser General Public License for more details. | ||
|
||
You can receive a copy of the GNU Lesser General Public License from | ||
http://www.gnu.org/ | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,183 +1,183 @@ | ||
;; -*- MODE: LISP -*- | ||
;; | ||
;; Brian Jiang (brianjcj AT gmail.com) | ||
;; 2007-11 | ||
;; | ||
;; TelnetLib | ||
;; ========= | ||
;; In our ordinary work, we often write some automatically scripts | ||
;; which login in the server to run some commands and performce some | ||
;; actions based on the result of the commands. In this case, a telnet | ||
;; client library will be very helpful. Such a library is very handy | ||
;; in Perl, Python and Ruby. But I googled it a lot and failed to find | ||
;; one in Common Lisp. So I decided to port the Telnetlib from Python | ||
;; to Common Lisp. Why port from Python? Because I am more familiar | ||
;; with Python and have use its TelnetLib before :-) | ||
;; | ||
;; The functionality of this library is almost the same as Python's | ||
;; one. But the interface is a little different. | ||
|
||
|
||
;; Supported Lisp implementations | ||
;; ============================== | ||
;; - SBCL | ||
;; - LispWorks | ||
;; - Allegro CL | ||
;; - CLISP | ||
;; | ||
;; TelnetLib also supports other Lisp implementations (require USOCKET | ||
;; and FLEXI-STREAMS) . But I have never done any testing for them. | ||
|
||
;; Testing: | ||
;; -------- | ||
;; TelnetLib has been tested in following environment: | ||
;; - sbcl-1.0.11-x86-linux | ||
;; - LispWorks in Windows XP | ||
;; - Allegro CL in Windows XP | ||
;; - CLISP 2.43 in Linux | ||
;; - CLISP 2.41 in Windows XP | ||
;; | ||
;; But it failed in sbcl-1.0.9 in Windows XP. Error occurs | ||
;; when writing the socket stream. | ||
|
||
|
||
;; Library Dependency | ||
;; ================== | ||
;; For SBCL, LispWorks, Allegro CL and CLISP, it only depends on | ||
;; CL-PPCRE. | ||
;; For other Lisp implementations, USOCKET and FLEXI-STREAMS (to | ||
;; set the external-format) are also required. | ||
|
||
;; Known Problem | ||
;; ============= | ||
;; Don't work well when telent localhost. It seems it is due to the process/thread | ||
;; schedule mechanism. Will try to fix it in the future. | ||
|
||
;; How to use it | ||
;; ============= | ||
|
||
;; Export functions/macros: | ||
;; ------------------------ | ||
(defun open-telnet-session (host &optional port)...) | ||
(defun close-telnet-session (tn)....) | ||
(defmacro with-telnet-session ((tn host &optional port) &body body)....) | ||
(defun set-telnet-session-option (tn | ||
&key (remove-return-char nil r-r-c-p) | ||
(debug-on nil debug-on-p) | ||
(char-callback nil char-callback-p) | ||
(option-callback nil option-callback-p) | ||
(sb-option-callback nil sb-option-callback-p))...) | ||
(defun peek-available-data (tn &optional block-read)....) | ||
(defun read-available-data (tn &optional block-read).... | ||
(defun read-until (tn str &key (timeout 600) case-insensitive-mode)....) | ||
(defun read-until-2 (tn strings &key (timeout 600) case-insensitive-mode)....) | ||
(defun read-until-2-ind (tn strings &key (timeout 600) case-insensitive-mode)....) | ||
(defun expect (tn regexp &optional (timeout 600))....) | ||
(defun format-tn (tn control-string &rest format-arguments)....) | ||
(defun write-ln (tn str)....) | ||
(defun write-ln-crlr (tn str)....) | ||
|
||
|
||
;; Example: | ||
;; -------- | ||
(defun example-1 () | ||
(with-telnet-session (tn "202.38.33.94") | ||
|
||
(set-telnet-session-option tn :remove-return-char t) | ||
|
||
(read-until tn "ogin:") | ||
(write-ln tn "brianjcj") | ||
|
||
(read-until tn "assword:") | ||
(write-ln tn "abcdefg12") | ||
(read-until tn ">") | ||
|
||
(format-tn tn "~A~%" "pwd") ;; stupid demo :-) | ||
(read-until tn ">") | ||
|
||
(write-ln tn "cmd1") | ||
(read-until-2 tn (list "Done." "Error" "Pending.") | ||
:case-insensitive-mode t) | ||
(read-until tn ">") | ||
|
||
|
||
(write-ln tn "cmd2") | ||
(expect tn | ||
(cl-ppcre:create-scanner | ||
"OK\|NO" | ||
:case-insensitive-mode t)) | ||
(read-until tn ">") | ||
|
||
|
||
(write-ln tn "cmd3") | ||
(expect tn "Done\|Try later.") | ||
(read-until tn ">") | ||
|
||
(write-ln tn-vmap "unload testci") | ||
(case (read-until-2-ind tn (list "Please confirm (" "has not been loaded yet")) | ||
((0) | ||
(read-until tn *prompt*) | ||
(sleep *rest-time*) | ||
(write-ln tn "Y") | ||
(read-until tn *prompt*)) | ||
((1) | ||
(read-until tn-vmap *prompt*))) | ||
|
||
(write-ln tn "exit") | ||
|
||
(loop until (eof tn) do | ||
(read-available-data tn t)) | ||
|
||
)) | ||
|
||
(defun example-2 () | ||
|
||
(with-telnet-session (tn "202.38.33.94") | ||
|
||
(set-telnet-session-option tn :char-callback nil) | ||
|
||
|
||
(princ (read-until tn "ogin:")) | ||
(write-ln tn "brianjcj") | ||
|
||
(princ (read-until tn "PassWord:" | ||
:case-insensitive-mode t)) | ||
(write-ln tn "zaq12WSX") | ||
(princ (read-until tn ">")) | ||
|
||
|
||
(write-ln tn "ls") | ||
(princ (read-until tn ">")) | ||
|
||
(write-ln tn "cmd1") | ||
(princ (expect tn "Done\|Error")) | ||
(princ (read-until tn ">")) | ||
|
||
(write-ln tn "cmd2") | ||
(princ (read-until-2 | ||
tn | ||
(list "OK." "Try again" "Later.") | ||
:timeout 10)) | ||
(princ (read-until tn ">")) | ||
|
||
|
||
(write-ln tn "cmd3") | ||
(princ (read-until-2 | ||
tn (list "Right" "Wrong") | ||
:timeout 10 :case-insensitive-mode t)) | ||
(princ (read-until tn ">")) | ||
|
||
(write-ln tn "cmd4") | ||
(princ (expect | ||
tn | ||
(cl-ppcre:create-scanner | ||
"Right\|Wrong" | ||
:case-insensitive-mode t))) | ||
(princ (read-until tn ">")) | ||
|
||
(write-ln tn "exit") | ||
|
||
(loop until (eof tn) do | ||
(princ (read-available-data tn t))) | ||
|
||
)) | ||
;; -*- MODE: LISP -*- | ||
;; | ||
;; Brian Jiang (brianjcj AT gmail.com) | ||
;; 2007-11 | ||
;; | ||
;; TelnetLib | ||
;; ========= | ||
;; In our ordinary work, we often write some automatically scripts | ||
;; which login in the server to run some commands and performce some | ||
;; actions based on the result of the commands. In this case, a telnet | ||
;; client library will be very helpful. Such a library is very handy | ||
;; in Perl, Python and Ruby. But I googled it a lot and failed to find | ||
;; one in Common Lisp. So I decided to port the Telnetlib from Python | ||
;; to Common Lisp. Why port from Python? Because I am more familiar | ||
;; with Python and have use its TelnetLib before :-) | ||
;; | ||
;; The functionality of this library is almost the same as Python's | ||
;; one. But the interface is a little different. | ||
|
||
|
||
;; Supported Lisp implementations | ||
;; ============================== | ||
;; - SBCL | ||
;; - LispWorks | ||
;; - Allegro CL | ||
;; - CLISP | ||
;; | ||
;; TelnetLib also supports other Lisp implementations (require USOCKET | ||
;; and FLEXI-STREAMS) . But I have never done any testing for them. | ||
|
||
;; Testing: | ||
;; -------- | ||
;; TelnetLib has been tested in following environment: | ||
;; - sbcl-1.0.11-x86-linux | ||
;; - LispWorks in Windows XP | ||
;; - Allegro CL in Windows XP | ||
;; - CLISP 2.43 in Linux | ||
;; - CLISP 2.41 in Windows XP | ||
;; | ||
;; But it failed in sbcl-1.0.9 in Windows XP. Error occurs | ||
;; when writing the socket stream. | ||
|
||
|
||
;; Library Dependency | ||
;; ================== | ||
;; For SBCL, LispWorks, Allegro CL and CLISP, it only depends on | ||
;; CL-PPCRE. | ||
;; For other Lisp implementations, USOCKET and FLEXI-STREAMS (to | ||
;; set the external-format) are also required. | ||
|
||
;; Known Problem | ||
;; ============= | ||
;; Don't work well when telent localhost. It seems it is due to the process/thread | ||
;; schedule mechanism. Will try to fix it in the future. | ||
|
||
;; How to use it | ||
;; ============= | ||
|
||
;; Export functions/macros: | ||
;; ------------------------ | ||
(defun open-telnet-session (host &optional port)...) | ||
(defun close-telnet-session (tn)....) | ||
(defmacro with-telnet-session ((tn host &optional port) &body body)....) | ||
(defun set-telnet-session-option (tn | ||
&key (remove-return-char nil r-r-c-p) | ||
(debug-on nil debug-on-p) | ||
(char-callback nil char-callback-p) | ||
(option-callback nil option-callback-p) | ||
(sb-option-callback nil sb-option-callback-p))...) | ||
(defun peek-available-data (tn &optional block-read)....) | ||
(defun read-available-data (tn &optional block-read).... | ||
(defun read-until (tn str &key (timeout 600) case-insensitive-mode)....) | ||
(defun read-until-2 (tn strings &key (timeout 600) case-insensitive-mode)....) | ||
(defun read-until-2-ind (tn strings &key (timeout 600) case-insensitive-mode)....) | ||
(defun expect (tn regexp &optional (timeout 600))....) | ||
(defun format-tn (tn control-string &rest format-arguments)....) | ||
(defun write-ln (tn str)....) | ||
(defun write-ln-crlr (tn str)....) | ||
|
||
|
||
;; Example: | ||
;; -------- | ||
(defun example-1 () | ||
(with-telnet-session (tn "202.38.33.94") | ||
|
||
(set-telnet-session-option tn :remove-return-char t) | ||
|
||
(read-until tn "ogin:") | ||
(write-ln tn "brianjcj") | ||
|
||
(read-until tn "assword:") | ||
(write-ln tn "abcdefg12") | ||
(read-until tn ">") | ||
|
||
(format-tn tn "~A~%" "pwd") ;; stupid demo :-) | ||
(read-until tn ">") | ||
|
||
(write-ln tn "cmd1") | ||
(read-until-2 tn (list "Done." "Error" "Pending.") | ||
:case-insensitive-mode t) | ||
(read-until tn ">") | ||
|
||
|
||
(write-ln tn "cmd2") | ||
(expect tn | ||
(cl-ppcre:create-scanner | ||
"OK\|NO" | ||
:case-insensitive-mode t)) | ||
(read-until tn ">") | ||
|
||
|
||
(write-ln tn "cmd3") | ||
(expect tn "Done\|Try later.") | ||
(read-until tn ">") | ||
|
||
(write-ln tn-vmap "unload testci") | ||
(case (read-until-2-ind tn (list "Please confirm (" "has not been loaded yet")) | ||
((0) | ||
(read-until tn *prompt*) | ||
(sleep *rest-time*) | ||
(write-ln tn "Y") | ||
(read-until tn *prompt*)) | ||
((1) | ||
(read-until tn-vmap *prompt*))) | ||
|
||
(write-ln tn "exit") | ||
|
||
(loop until (eof tn) do | ||
(read-available-data tn t)) | ||
|
||
)) | ||
|
||
(defun example-2 () | ||
|
||
(with-telnet-session (tn "202.38.33.94") | ||
|
||
(set-telnet-session-option tn :char-callback nil) | ||
|
||
|
||
(princ (read-until tn "ogin:")) | ||
(write-ln tn "brianjcj") | ||
|
||
(princ (read-until tn "PassWord:" | ||
:case-insensitive-mode t)) | ||
(write-ln tn "zaq12WSX") | ||
(princ (read-until tn ">")) | ||
|
||
|
||
(write-ln tn "ls") | ||
(princ (read-until tn ">")) | ||
|
||
(write-ln tn "cmd1") | ||
(princ (expect tn "Done\|Error")) | ||
(princ (read-until tn ">")) | ||
|
||
(write-ln tn "cmd2") | ||
(princ (read-until-2 | ||
tn | ||
(list "OK." "Try again" "Later.") | ||
:timeout 10)) | ||
(princ (read-until tn ">")) | ||
|
||
|
||
(write-ln tn "cmd3") | ||
(princ (read-until-2 | ||
tn (list "Right" "Wrong") | ||
:timeout 10 :case-insensitive-mode t)) | ||
(princ (read-until tn ">")) | ||
|
||
(write-ln tn "cmd4") | ||
(princ (expect | ||
tn | ||
(cl-ppcre:create-scanner | ||
"Right\|Wrong" | ||
:case-insensitive-mode t))) | ||
(princ (read-until tn ">")) | ||
|
||
(write-ln tn "exit") | ||
|
||
(loop until (eof tn) do | ||
(princ (read-available-data tn t))) | ||
|
||
)) |
Oops, something went wrong.