| 
					
				 | 
			
			
				@@ -1,6 +1,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-(ql:quickload "cl-store") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;;(ql:quickload "cl-store") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(ql:quickload "yason") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (ql:quickload "cl-ppcre") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (ql:quickload "unix-opts") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(ql:quickload "ironclad") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ;;; Features 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ;;; - Import records from old .txt format 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -57,8 +59,47 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (defun reload () 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   (load "~/Repos/fin-lisp/fin-lisp.lisp")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun wfile (file-content file-path) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (alexandria:write-string-into-file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   (concatenate 'string file-content) file-path :if-exists :overwrite 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+						:if-does-not-exist :create)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;;;;;;;;;;;;;;;;;;;;;;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;; Encryption stuff ;;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;;;;;;;;;;;;;;;;;;;;;;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;; See: https://www.cliki.net/Ironclad 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;; Return cipher when provided key 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun get-cipher (key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (ironclad:make-cipher 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   :blowfish 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   :mode :ecb 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   :key (ironclad:ascii-string-to-byte-array key))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;; First serialize the file, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;; then encrypt it from disk 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun encrypt-records (key filename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (let ((cipher (get-cipher key)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(file-content (uiop:read-file-string filename))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (let ((content (ironclad:ascii-string-to-byte-array file-content))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (ironclad:encrypt-in-place cipher content) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (wfile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       (write-to-string (ironclad:octets-to-integer content)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       (concatenate 'string filename ".enc"))))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun decrypt-records (key filename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (let ((cipher (get-cipher key)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(file-content (uiop:read-file-string filename))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (let ((content (ironclad:integer-to-octets (parse-integer file-content)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (ironclad:decrypt-in-place cipher content) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      (coerce (mapcar #'code-char (coerce content 'list)) 'string)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;; End Encryption Stuff ;;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (defun reset-records () 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  (setf *records* (make-hash-table :test 'equalp))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (setf *records* (make-hash-table :test 'equal))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ;; Called like: (add-month '202107) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (defun add-month (month-key) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -97,17 +138,20 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       (format t "~a : ~a~C" exp-key (gethash exp-key month-hash) #\linefeed)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ;;; Dump all records. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-;;; This will also be used for data serialization at some point 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (defun dump-records () 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   (let ((record-key-list (loop for key being the hash-keys of *records* collect key))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     (dolist (month-key record-key-list) (dump-month month-key)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-(defun serialize-records (filename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  (cl-store:store *records* filename)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun serialize-records (key filename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (with-open-file (stream filename 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			  :direction :output 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			  :if-exists :overwrite 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			  :if-does-not-exist :create) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    (yason:encode *records* stream)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  (encrypt-records key filename)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-(defun deserialize-records (filename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ;(setf *records* (cl-store:restore (pathname filename)))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  (setf *records* (cl-store:restore filename))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(defun deserialize-records (key filename) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ;; Import records from old perl version (plaintext file) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (defun import-records (filename) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -168,7 +212,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 "Invalid month")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     (if (string= answer "3") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	(generic-handler 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	 (serialize-records (prompt-read "Enter filename")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	 (serialize-records (prompt-read "Enter encryption key") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			    (prompt-read "Enter filename")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	 "Serialization error or invalid filename")) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     (if (string= answer "4") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	(generic-handler 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -202,5 +247,5 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     (when-option (matches :interactive-mode) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       (progn 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	(interactive-mode) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	(quit))))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	(quit)))))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		  
			 |