;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Copyright IBM Corporation 1988,1991 - All Rights Reserved ;; ;; For full copyright information see:'andrew/config/COPYRITE' ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;; ;;;;;; ;;;;;; LIBRARY OF FLAMES FUNCTIONS FOR PROCESSING MAIL/BBOARDS ;;;;;; ;;;;;; (authors: ghoti+, bobg+ nsb+) (4/27/88) ;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; $Disclaimer: ;;Permission to use, copy, modify, and distribute this software and its ;;documentation for any purpose is hereby granted without fee, ;;provided that the above copyright notice appear in all copies and that ;;both that copyright notice, this permission notice, and the following ;;disclaimer appear in supporting documentation, and that the names of ;;IBM, Carnegie Mellon University, and other copyright holders, not be ;;used in advertising or publicity pertaining to distribution of the software ;;without specific, written prior permission. ;; ;;IBM, CARNEGIE MELLON UNIVERSITY, AND THE OTHER COPYRIGHT HOLDERS ;;DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ;;ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT ;;SHALL IBM, CARNEGIE MELLON UNIVERSITY, OR ANY OTHER COPYRIGHT HOLDER ;;BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY ;;DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ;;WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ;;ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE ;;OF THIS SOFTWARE. ;; $ (load "elilib") ; flist is a list of strings, each of which is the name of a ; msg directory. Adds the msg to each dir in flist, stopping ; (possibly after some appends) as soon as an error occurs. ; Returns T on success, NIL on any error. (defun add-to-folders (msg flist) (cond ((null flist) T) ((appendmsgtodir msg (car flist)) (add-to-folders msg (cdr flist))) (T NIL))) ;;;;; (>> returns T/NIL <<) (defun create-folders (msg creats) ;;;;; LIST creats (cond ((NULL creats) T) ((createfolderfrommessage (car creats) msg) (create-folders msg (cdr creats))) (T NIL))) ;;;;; (>> returns T/NIL <<) (defun ensure-folders-exist (msg flist) ;;;;; MESSAGE msg ;;;;; LIST flist (cond ((null flist) T) ((findfolder (car flist) "w") (ensure-folders-exist msg (cdr flist))) ((createfolderfrommessage (car flist) msg) (ensure-folders-exist msg (cdr flist))) (T NIL))) (defun post-by-keyword (msg default biglist) (post-to-list msg (map-heads-keys-folders msg biglist) default NIL NIL NIL T NIL)) (defun map-heads-keys-folders (msg biglist) (cond ((null biglist) NIL) (T (append (let* ((ca (car biglist)) (cda (cdr ca))) (mhkf msg (car ca) (car cda) (car (cdr cda)) NIL)) (map-heads-keys-folders msg (cdr biglist)))))) ;;;;; (>> returns LIST <<) (defun mhkf (msg hlist klist flist ans) ;;;;; MESSAGE msg ;;;;; LIST hlist ;;;;; LIST klist ;;;;; LIST flist ;;;;; LIST ans (cond ((null hlist) ans) ((any-pat-in-any-str (map-strlist-to-lowercase klist) (map-strlist-to-lowercase (only-strings (apply 'append (mapcar '(lambda (x) (getheadercontents msg x)) hlist))))) (append ans flist)) (T ans))) ;;;;; (>> returns LIST <<) (defun validate-folder-list (flist) ;;;;; LIST flist (validate-folder-list-aux flist NIL NIL NIL)) ;;;;; (>> returns LIST <<) (defun validate-folder-list-aux (flist adds errs creats) ;;;;; LIST flist ;;;;; LIST adds ;;;;; LIST errs ;;;;; LIST creats (cond ((null flist) (list (remove-duplicates adds) (remove-duplicates errs) (remove-duplicates creats))) (T (let* ((foo (findfolder (car flist) "w")) (bar (findfolder (car flist) "c"))) (cond ((null bar) (validate-folder-list-aux (cdr flist) adds (append (list (car flist)) errs) creats)) ((null foo) (validate-folder-list-aux (cdr flist) adds errs (append (list bar) creats))) (T (validate-folder-list-aux (cdr flist) (append (list foo) adds) errs creats))))))) (defun multi-getheadercontents (msg hnamelist) (do ((hdrs hnamelist (cdr hdrs)) (result nil (append result (getheadercontents msg (car hdrs))))) ((null hdrs) result))) (defun process-mapped-mailbox (msg pathroot prefix headernamelist defaultfolder rejto rejcc rejstr) (process-mapped-restricted-mailbox msg pathroot prefix headernamelist defaultfolder rejto rejcc rejstr NIL)) (defun process-mapped-restricted-mailbox (msg pathroot prefix headernamelist defaultfolder rejto rejcc rejstr restrictions) (post-to-list msg (mapcar '(lambda (x) (strcat pathroot x)) (extract-liberally prefix (multi-getheadercontents msg headernamelist))) defaultfolder rejto rejcc rejstr T restrictions)) (defun standard-mapping (msg treeroot defaultfolder rejto rejcc rejstr) (process-mapped-restricted-mailbox msg (strcat (findfolder treeroot "w") "/") (strcat (getparameter "uid") ; the first thing in this strcat used to be "\\{" (let ((suffix (getparameter "uidsuffix"))) (cond ((eq suffix "+") "\\+") (T suffix)))) '("to" "cc" "resent-to" "resent-cc" "received") (findfolder defaultfolder "w") rejto rejcc rejstr NIL)) ; This routine applies the restrictions to the unvalidated folder list. ; It rejects the message and returns T if the restrictions apply. ; If no restrictions apply, it returns NIL. ; A restriction list is a list of lists, each of which is a list of patterns, ; a list of authorized users, and a rejection text. For example, ; ((("^official" "^university") ("nsb" "jr") ; "You are not authorized to post on this. Send mail to nsb for more details.") ; (("^org") NIL "You don't post to org through this mailbox")) (defun apply-restrictions (msg flist rejto rejcc restricts) (cond ((null restricts) NIL) ; no restrictions apply, obviously ((apply-single-restriction msg flist rejto rejcc (car restricts)) T) (T (apply-restrictions msg flist rejto rejcc (cdr restricts))))) (defun apply-single-restriction (msg flist rejto rejcc restriction) (cond ((and (any-pat-in-any-str (car restriction) flist) (not (a-pat-in-any-str (getauthsender msg) ; this should be (strcat "\\{" (getauthsender msg)) (car (cdr restriction))))) (reject-from-message msg rejto rejcc (car (cdr (cdr restriction))) NIL)) (T NIL))) ;;;;; (>> returns T/NIL <<) (defun post-to-list (msg flist default rejto rejcc rejstr allowcreats restricts) (cond ((apply-restrictions msg flist rejto rejcc restricts) T) (T (let* ((vlist (validate-folder-list flist)) (def-folder (findfolder default "w")) (adds (car vlist)) (errs (car (cdr vlist))) (creats (car (cdr (cdr vlist)))) (result "")) (cond ((and (null flist) (null def-folder)) NIL) ((null flist) (appendmsgtodir msg def-folder)) ((and errs (null rejstr)) NIL) (errs (reject-from-message msg rejto rejcc rejstr errs)) ((null creats) (add-to-folders msg adds)) ((null allowcreats) (reject-from-message msg rejto rejcc (strcat rejstr " (creation not permitted) ") creats)) ((ensure-folders-exist msg creats) (add-to-folders msg (append creats adds))) (T NIL)))))) (defun reject-from-message (msg rejto rejcc rejstr flist) (let* ((x (replyaddr msg "sender")) (repaddr (cond (rejto rejto) (x x) (T "postman+")))) (rejectmessage msg repaddr rejcc (strcat (cond (rejstr rejstr) (T "Message rejected with no reason specified: ")) NEWLINE-TAB (cond (flist (list-to-str flist NEWLINE-TAB)) (T "")))))) (defun extract-liberally (pattern strs) (remove-duplicates (do ((refs strs (cdr refs)) (result nil (append result (extract-liberally-onestr pattern (car refs))))) ((null refs) result)))) (defun last-list-elt (l) (cond ((null l) nil) ((null (cdr l)) (car l)) (t (last-list-elt (cdr l))))) (defun extract-liberally-onestr (pattern str) (let* ((decomp (re-strdecompose+ (strcat pattern &END-OF-EXTRACT-PATTERN) str))) (cond (decomp (cons (last-list-elt (car (cdr decomp))) (extract-liberally-onestr pattern (car (cdr (cdr decomp)))))) (T NIL)))) ; This pattern gets concatenated onto the end of the ; pattern passed to extract-liberally. It matches ; one or more non-terminator characters within a subexpression ; (so we can get at the matched portion with re-strdecompose+) (setq &END-OF-EXTRACT-PATTERN "([^]\n ,@:)}>%;!\"]+)") (setq NEWLINE-TAB "\n\t") (defun only-strings (lis) (cond ((null lis) nil) ((stringp (car lis)) (cons (car lis) (only-strings (cdr lis)))) (T (only-strings (cdr lis))))) (defun map-strlist-to-lowercase (strlist) (mapcar '(lambda (x) (lcstring x)) strlist))