--- a/lisp/clhs.lisp Mon May 20 11:51:14 2019 -0400
+++ b/lisp/clhs.lisp Mon May 20 11:51:40 2019 -0400
@@ -104,10 +104,7 @@
;;;; User Interface -----------------------------------------------------------
-(defmacro define-string (var string)
- `(defparameter ,var (format nil ,string)))
-
-(define-string *documentation*
+(adopt:define-string *documentation*
"Look up SYMBOL in the Common Lisp HyperSpec and open its page in a web browser.~@
~@
The first time the program is run it will create a cache of all symbols in ~
@@ -115,7 +112,7 @@
faster.")
(defparameter *examples*
- '((".Look up STRING in the HyperSpec and open it in the default browser:" .
+ '(("Look up STRING in the HyperSpec and open it in the default browser:" .
"clhs string")
("Look up MAKE-ARRAY in a local copy of the HyperSpec and open it in lynx:" .
"clhs --url file:///home/sjl/doc/hyperspec/ --open lynx make-array")))
--- a/lisp/genpass.lisp Mon May 20 11:51:14 2019 -0400
+++ b/lisp/genpass.lisp Mon May 20 11:51:40 2019 -0400
@@ -7,10 +7,15 @@
(in-package :genpass)
-;;;; Functionality ------------------------------------------------------------
+;;;; Configuration ------------------------------------------------------------
(defparameter *passphrase-sep* " ")
(defparameter *words* nil)
+(defparameter *version* "0.0.1")
+(defparameter *random-path* "/dev/urandom")
+(defparameter *wordlist-path* "/usr/share/dict/words")
+
+;;;; Functionality ------------------------------------------------------------
(defmacro -<> (value &body forms)
(reduce (lambda (val expression)
(subst val '<> expression))
@@ -26,13 +31,13 @@
(unless *words*
(setf *words*
(iterate
- (for line :in-file "/usr/share/dict/words" :using #'read-line)
+ (for line :in-file *wordlist-path* :using #'read-line)
(when (every #'safep line)
(collect line :result-type vector)))))
*words*)
(defun random-unsigned-byte-32 ()
- (with-open-file (urandom "/dev/urandom" :element-type '(unsigned-byte 8))
+ (with-open-file (urandom *random-path* :element-type '(unsigned-byte 8))
(logior (ash (read-byte urandom) 0)
(ash (read-byte urandom) 8)
(ash (read-byte urandom) 16)
@@ -63,7 +68,7 @@
(finding candidate :such-that (<= (length candidate) length))))
(defun random-garbage (length)
- (with-open-file (urandom "/dev/urandom" :element-type '(unsigned-byte 8))
+ (with-open-file (urandom *random-path* :element-type '(unsigned-byte 8))
(-<> urandom
(series:scan-stream <> #'read-byte)
(series:map-fn t #'code-char <>)
@@ -99,34 +104,56 @@
. "genpass --words 6 --smush")))
-(defparameter *help*
+(defparameter *option-help*
(adopt:make-option 'help
:help "Display help and exit."
:long "help"
:short #\h
:reduce (constantly t)))
-(defparameter *length*
+(defparameter *option-version*
+ (adopt:make-option 'version
+ :help "Display version information and exit."
+ :long "version"
+ :reduce (constantly t)))
+
+(defparameter *option-random-path*
+ (adopt:make-option 'random-path
+ :help (format nil "Path to the source of randomness (default ~A)." *random-path*)
+ :long "random-path"
+ :parameter "PATH"
+ :initial-value *random-path*
+ :reduce #'adopt:last))
+
+(defparameter *option-wordlist-path*
+ (adopt:make-option 'wordlist-path
+ :help (format nil "Path to the list of words (default ~A)." *wordlist-path*)
+ :long "words-path"
+ :parameter "PATH"
+ :initial-value *wordlist-path*
+ :reduce #'adopt:last))
+
+(defparameter *option-length*
(adopt:make-option 'length
:help "Ensure password is no longer than N characters (default 40)."
:long "length"
:short #\l
:parameter "N"
:initial-value 40
- :reduce #'adopt:newest
+ :reduce #'adopt:last
:key #'parse-integer))
-(defparameter *words*
+(defparameter *option-words*
(adopt:make-option 'words
:help "If non-zero, generate passphrases of N words instead of opaque strings (default 4)."
:long "words"
:short #\w
:parameter "N"
:initial-value 4
- :reduce #'adopt:newest
+ :reduce #'adopt:last
:key #'parse-integer))
-(defparameter *no-words*
+(defparameter *option-no-words*
(adopt:make-option 'no-words
:result-key 'words
:help "Shorthand for --words=0."
@@ -134,7 +161,7 @@
:short #\W
:reduce (constantly 0)))
-(defparameter *smart*
+(defparameter *option-smart*
(adopt:make-option 'smart
:help "Smart mode (the default). Generate as with --words, but add a number on the end to satisfy the red tape on many sites."
:long "smart"
@@ -142,7 +169,7 @@
:initial-value t
:reduce (constantly t)))
-(defparameter *no-smart*
+(defparameter *option-no-smart*
(adopt:make-option 'no-smart
:result-key 'smart
:help "Turn off smart mode."
@@ -150,14 +177,14 @@
:short #\S
:reduce (constantly nil)))
-(defparameter *smush*
+(defparameter *option-smush*
(adopt:make-option 'smush
:help "Don't include spaces in passphrases."
:long "smush"
:short #\m
:reduce (constantly t)))
-(defparameter *no-smush*
+(defparameter *option-no-smush*
(adopt:make-option 'no-smush :result-key 'smush
:help "Include spaces in passphrases (the default)."
:long "no-smush"
@@ -165,24 +192,42 @@
:reduce (constantly nil)))
-(defparameter *password-options*
+(defparameter *group-password-options*
(adopt:make-group 'password-options
:title "Password Options"
:help "The format of generated passwords can be customized in a number of ways."
- :options (list *length*
- *words* *no-words*
- *smart* *no-smart*
- *smush* *no-smush*)))
+ :options (list *option-length*
+ *option-words* *option-no-words*
+ *option-smart* *option-no-smart*
+ *option-smush* *option-no-smush*)))
+(defparameter *group-data-sources*
+ (adopt:make-group 'data-source-options
+ :title "Data Sources"
+ :options (list *option-random-path*
+ *option-wordlist-path*)))
+
+
+(adopt:define-string *help-text*
+ "This utility generates random passwords for use with a password ~
+ manager like password-store.~@
+ ~@
+ By default genpass will generate long passphrases of several random ~
+ words. This is done so that they're not absolutely miserable to type ~
+ on the rare occasions that you're trying to log in on someone else's ~
+ machine by reading the password off of your phone.")
(defparameter *ui*
(adopt:make-interface
:name "genpass"
:usage "[OPTIONS]"
- :summary "Generate a random password."
- :help "Generate a random password."
+ :summary "generate a random password"
+ :help *help-text*
:examples *examples*
- :contents (list *help* *password-options*)))
+ :contents (list *option-help*
+ *option-version*
+ *group-password-options*
+ *group-data-sources*)))
(defun toplevel ()
@@ -190,10 +235,16 @@
(multiple-value-bind (arguments options) (adopt:parse-options *ui*)
(when (gethash 'help options)
(adopt:print-help-and-exit *ui*))
+ (when (gethash 'version options)
+ (write-line *version*)
+ (adopt:exit))
(when arguments
(error "Unrecognized command line arguments: ~S" arguments))
- (run (gethash 'length options)
- (gethash 'words options)
- (gethash 'smart options)
- (gethash 'smush options)))
+ (let ((*wordlist-path* (gethash 'wordlist-path options))
+ (*random-path* (gethash 'random-path options)))
+ (run (gethash 'length options)
+ (gethash 'words options)
+ (gethash 'smart options)
+ (gethash 'smush options))))
(error (c) (adopt:print-error-and-exit c))))
+
--- a/vim/custom-dictionary.utf-8.add Mon May 20 11:51:14 2019 -0400
+++ b/vim/custom-dictionary.utf-8.add Mon May 20 11:51:40 2019 -0400
@@ -283,3 +283,4 @@
schemaless
virtualization
rebasing
+destructure