Initial revision
authorChris Hanson <org/chris-hanson/cph>
Thu, 14 Jan 1999 21:30:55 +0000 (21:30 +0000)
committerChris Hanson <org/chris-hanson/cph>
Thu, 14 Jan 1999 21:30:55 +0000 (21:30 +0000)
v7/src/edwin/pwedit.scm [new file with mode: 0644]
v7/src/edwin/pwparse.scm [new file with mode: 0644]

diff --git a/v7/src/edwin/pwedit.scm b/v7/src/edwin/pwedit.scm
new file mode 100644 (file)
index 0000000..1e6dfdc
--- /dev/null
@@ -0,0 +1,188 @@
+;;; -*-Scheme-*-
+;;;
+;;; $Id: pwedit.scm,v 1.1 1999/01/14 21:30:55 cph Exp $
+;;;
+;;; Copyright (c) 1999 Massachusetts Institute of Technology
+;;;
+;;; This program is free software; you can redistribute it and/or
+;;; modify it under the terms of the GNU General Public License as
+;;; published by the Free Software Foundation; either version 2 of the
+;;; License, or (at your option) any later version.
+;;;
+;;; This program 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
+;;; General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;;; Password-Database Editor
+
+;;; This program provides editing capabilities for a text-format
+;;; password database.  The primary capability of this program is to
+;;; permit editing a database of passwords without having all of the
+;;; passwords visible on the screen at once.  Instead, the program
+;;; displays a set of key names, and the user selectively reveals the
+;;; password information hidden behind those keys.
+
+(declare (usual-integrations))
+\f
+(define-command view-password-file
+  "Read in a password file and show it in password-view mode."
+  "fView password file"
+  (lambda (pathname)
+    (let ((forms
+          (call-with-temporary-buffer " view-pw-file"
+            (lambda (buffer)
+              (read-buffer buffer pathname #f)
+              (read-pw-forms
+               (make-buffer-input-port (buffer-start buffer)
+                                       (buffer-end buffer)))))))
+      (let ((buffer (new-buffer (pathname->buffer-name pathname))))
+       (insert-pw-forms forms (buffer-start buffer))
+       (set-buffer-major-mode! buffer (ref-mode-object password-view))
+       (set-buffer-point! buffer (buffer-start buffer))
+       (select-buffer buffer)))))
+
+(define-major-mode password-view read-only "Password-View"
+  "Major mode specialized for viewing password files."
+  (lambda (buffer)
+    (set-buffer-read-only! buffer)
+    unspecific))
+
+(define-key 'password-view #\space 'toggle-pw-form)
+(define-key 'password-view button1-down 'mouse-toggle-pw-form)
+
+(define-command toggle-pw-form
+  "Toggle the body of the password form under point."
+  "d"
+  (lambda (point)
+    (if (get-pw-form point)
+       (toggle-pw-body point)
+       (message "No form under point."))))
+
+(define-command mouse-toggle-pw-form
+  "Toggle the body of the password form under mouse."
+  ()
+  (lambda ()
+    ((ref-command toggle-pw-form)
+     (let ((button-event (current-button-event)))
+       (let ((window (button-event/window button-event)))
+        (select-window window)
+        (or (window-coordinates->mark window
+                                      (button-event/x button-event)
+                                      (button-event/y button-event))
+            (buffer-end (window-buffer window))))))))
+     
+\f
+(define (insert-pw-forms pw-forms point)
+  (let ((point (mark-left-inserting-copy point)))
+    (for-each
+     (lambda (form)
+       (let ((type (car form))
+            (body (cdr form))
+            (start (mark-right-inserting-copy point)))
+        (case type
+          ((BLANK)
+           (insert-newline point))
+          ((COMMENT)
+           (for-each (lambda (line)
+                       (insert-string ";" point)
+                       (insert-string line point)
+                       (insert-newline point))
+                     body))
+          ((SHORT LONG)
+           (insert-string (car body) point)
+           (insert-string ":" point)
+           (insert-newline point))
+          (else
+           (error "Unknown form type:" type)))
+        (region-put! start point 'PW-FORM form)
+        (mark-temporary! start)))
+     pw-forms)
+    (mark-temporary! point)))
+
+(define (get-pw-form point)
+  (let ((form (region-get point 'PW-FORM #f)))
+    (and form
+        (memq (car form) '(SHORT LONG))
+        form)))
+\f
+(define (toggle-pw-body point) (modify-pw-body point 'TOGGLE))
+(define (insert-pw-body point) (modify-pw-body point 'INSERT))
+(define (delete-pw-body point) (modify-pw-body point 'DELETE))
+
+(define (modify-pw-body point operation)
+  (with-buffer-open (mark-buffer point)
+    (lambda ()
+      (let ((form
+            (or (get-pw-form point)
+                (error:bad-range-argument point 'INSERT-PW-BODY)))
+           (le (line-end point 0)))
+       (if (eq? 'SHORT (car form))
+           (let ((region (short-pw-body-region point)))
+             (if region
+                 (region-delete! region))
+             (if (or (eq? 'INSERT operation)
+                     (and (eq? 'TOGGLE operation)
+                          (not region)))
+                 (let ((end (mark-left-inserting-copy (line-end point 0))))
+                   (insert-pw-body-spacer end)
+                   (insert-string (cddr form) end)
+                   (mark-temporary! end))))
+           (let ((region (long-pw-body-region point)))
+             (if region
+                 (region-delete! region))
+             (if (or (eq? 'INSERT operation)
+                     (and (eq? 'TOGGLE operation)
+                          (not region)))
+                 (let ((end (mark-left-inserting-copy (line-end point 0))))
+                   (for-each (lambda (line)
+                               (insert-newline end)
+                               (if (pair? line)
+                                   (begin
+                                     (insert-string (car line) end)
+                                     (insert-string ":" end)
+                                     (insert-pw-body-spacer end)
+                                     (insert-string (cdr line) end))
+                                   (insert-string line end)))
+                             (cddr form))
+                   (mark-temporary! end)))))))))
+
+(define (short-pw-body-region point)
+  (let ((end (line-end point 0)))
+    (let ((start (next-specific-property-change* point end 'PW-FORM)))
+      (and start
+          (mark< start end)
+          (make-region start end)))))
+
+(define (long-pw-body-region point)
+  (let ((start (line-end point 0)))
+    (let ((end
+          (let loop ((m start))
+            (let ((m* (mark1+ m)))
+              (if m*
+                  (if (line-blank? m*)
+                      m
+                      (loop (line-end m* 0)))
+                  m)))))
+      (and (mark< start end)
+          (make-region start end)))))
+
+(define (insert-pw-body-spacer point)
+  (insert-string (let ((column (mark-column point)))
+                  (cond ((< column 8) "\t\t")
+                        ((< column 16) "\t")
+                        (else " ")))
+                point))
+
+(define (next-specific-property-change* start end key)
+  (let ((index
+        (next-specific-property-change (mark-group start)
+                                       (mark-index start)
+                                       (mark-index end)
+                                       key)))
+    (and index
+        (make-mark (mark-group start) index))))
\ No newline at end of file
diff --git a/v7/src/edwin/pwparse.scm b/v7/src/edwin/pwparse.scm
new file mode 100644 (file)
index 0000000..a752abe
--- /dev/null
@@ -0,0 +1,176 @@
+;;; -*-Scheme-*-
+;;;
+;;; $Id: pwparse.scm,v 1.1 1999/01/14 21:30:45 cph Exp $
+;;;
+;;; Copyright (c) 1999 Massachusetts Institute of Technology
+;;;
+;;; This program is free software; you can redistribute it and/or
+;;; modify it under the terms of the GNU General Public License as
+;;; published by the Free Software Foundation; either version 2 of the
+;;; License, or (at your option) any later version.
+;;;
+;;; This program 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
+;;; General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with this program; if not, write to the Free Software
+;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+;;;; Password-Database Parser
+
+;;; This program implements I/O for a text-format password database.
+
+(declare (usual-integrations))
+\f
+(define (read-pw-forms port)
+  (parse/neutral port '()))
+
+(define (parse/neutral port forms)
+  (let ((line (read-line port)))
+    (if (eof-object? line)
+       (finish-parsing forms)
+       (dispatch/neutral port line forms))))
+
+(define (finish-parsing forms)
+  (reverse! forms))
+
+(define (dispatch/neutral port line forms)
+  ((dispatch line
+            parse-neutral/blank
+            parse-neutral/comment
+            parse-neutral/short-form
+            parse-neutral/long-form)
+   port line forms))
+
+(define (dispatch line
+                 parse-blank
+                 parse-comment
+                 parse-short-form
+                 parse-long-form)
+  (let ((start (string-find-next-char-in-set line char-set:not-whitespace))
+       (end (string-length line)))
+    (cond ((not start)
+          parse-blank)
+         ((char=? #\; (string-ref line start))
+          parse-comment)
+         (else
+          (let ((colon (substring-find-previous-char line start end #\:)))
+            (if colon
+                (if (substring-find-next-char-in-set line (+ colon 1) end
+                                                     char-set:not-whitespace)
+                    parse-short-form
+                    parse-long-form)
+                parse-long-form))))))
+
+(define (comment-line? line)
+  (let ((start (string-find-next-char-in-set line char-set:not-whitespace)))
+    (and start
+        (char=? #\; (string-ref line start)))))
+
+(define (long-form-separator-line? line)
+  ;; blank
+  (not (string-find-next-char-in-set line char-set:not-whitespace)))
+
+(define (split-colon-line line)
+  (let ((colon (string-find-next-char line #\:)))
+    (if colon
+       (cons (string-trim (string-head line colon))
+             (string-trim (string-tail line (+ colon 1))))
+       (strip-semicolons line))))
+
+(define strip-semicolons
+  (let ((char-set (char-set-invert (char-set #\;))))
+    (lambda (line)
+      (string-trim-left (string-trim line) char-set))))
+\f
+(define (parse-neutral/blank port line forms)
+  line
+  (parse/neutral port (cons '(BLANK) forms)))
+
+(define (parse-neutral/comment port line forms)
+  (let ((finish-comment
+        (lambda (accumulator)
+          (cons (cons 'COMMENT (reverse! (map strip-semicolons accumulator)))
+                forms))))
+    (let loop ((accumulator (list line)))
+      (let ((line (read-line port)))
+       (cond ((eof-object? line)
+              (finish-parsing (finish-comment accumulator)))
+             ((comment-line? line)
+              (loop (cons line accumulator)))
+             (else
+              (dispatch/neutral port
+                                line
+                                (finish-comment accumulator))))))))
+
+(define (parse-neutral/short-form port line forms)
+  (parse/neutral port (cons (cons 'SHORT (split-colon-line line)) forms)))
+
+(define (parse-neutral/long-form port line forms)
+  (let* ((header
+         (string-trim
+          (let ((colon (string-find-previous-char line #\:)))
+            (if colon
+                (string-head line colon)
+                line))))
+        (finish-long-form
+         (lambda (accumulator)
+           (cons (cons* 'LONG
+                        header
+                        (reverse! (map split-colon-line accumulator)))
+                 forms))))
+    (let loop ((accumulator '()))
+      (let ((line (read-line port)))
+       (cond ((eof-object? line)
+              (finish-parsing (finish-long-form accumulator)))
+             ((long-form-separator-line? line)
+              (dispatch/neutral port
+                                line
+                                (finish-long-form accumulator)))
+             (else
+              (loop (cons line accumulator))))))))
+\f
+(define (write-pw-forms forms port)
+  (let ((write-two-part
+        (lambda (line)
+          (write-string (car line) port)
+          (write-char #\: port)
+          (let ((n
+                 (+ (string-length (car line))
+                    1)))
+            (if (< n 8)
+                (write-string "\t\t" port)
+                (write-char (if (< n 16) #\tab #\space) port)))
+          (write-string (cdr line) port))))
+    (for-each (lambda (form)
+               (let ((type (car form))
+                     (body (cdr form)))
+                 (case type
+                   ((BLANK)
+                    (newline port))
+                   ((COMMENT)
+                    (for-each (lambda (line)
+                                (write-char #\; port)
+                                (write-string line port)
+                                (newline port))
+                              body))
+                   ((SHORT)
+                    (write-two-part body)
+                    (newline port))
+                   ((LONG)
+                    (write-string (car body) port)
+                    (write-char #\: port)
+                    (newline port)
+                    (for-each (lambda (line)
+                                (if (pair? line)
+                                    (write-two-part line)
+                                    (begin
+                                      (write-char #\; port)
+                                      (write-string line port)))
+                                (newline port))
+                              (cdr body)))
+                   (else
+                    (error "Illegal form type:" form)))))
+             forms)))
\ No newline at end of file