; ; SANS security digests ; (defun nndoc-sans-security-type-p nil "Decide whether an article is a SANS Security digest" (let ((case-fold-search nil)) (not (not (and (re-search-forward "^From: The SANS Institute" nil t) (re-search-forward "^[ \t]*@RISK: The Consensus Security Vulnerability Alert" nil t)) ))) ) (defun nndoc-sans-security-article-begin nil "Find the beginning of a SANS security article" (let ((case-fold-search nil)) (if first (and ; (re-search-forward "^Table of Contents" nil t) (re-search-forward "^Part I --? Critical Vulnerabilities" nil t) (re-search-forward "^PART I \\(- \\)?Critical Vulnerabilities$" nil t) (re-search-forward "^ *(?1) [A-Z]+" nil t) (progn (beginning-of-line) t)) (if (or (re-search-forward "^*\\{15,\\}\n+(?[0-9]+)" nil t) (re-search-forward "^[-_]\\{60,\\}\n+" nil t)) (progn (beginning-of-line) t)) ))) (defun nndoc-sans-security-body-begin nil "Find the beginning of a SANS security body" (beginning-of-line) ) (defun nndoc-generate-sans-security-head (article) "Generate headers for a SANS security article" (let ((entry (cdr (assq article nndoc-dissection-alist))) (subject "Couldn't find subject")) (save-excursion (set-buffer nndoc-current-buffer) (save-restriction (narrow-to-region (car entry) (nth 3 entry)) (goto-char (point-min)) (while (and (not (equal (point) (point-max))) (looking-at "^[-_*]*$")) (forward-line 1)) ; Following test is a huge kludge (if (looking-at "^[a-z ]+\n\\*\\{27,\\}$") (forward-line 3)) (cond ((looking-at "^ *(?[0-9]+) \\(.*\\)$") (setq subject (match-string 1))) ((re-search-forward "^Title: \\(.*\\)$" nil t) (setq subject (match-string 1))) ; ; Lots of special cases ; ((re-search-forward "^\\(Summary of the vulnerabilities reported this week*\\):$" nil t) (setq subject (match-string 1))) ((re-search-forward "^Table of Contents:$" nil t) (setq subject (match-string 0))) ((re-search-forward "^\\*+ .*sponsored .* \\*+$" nil t) (setq subject "Advertisement")) ((re-search-forward "^PART [IVX]+ .* Vulnerabilities$" nil t) (setq subject (match-string 0))) ))) (insert "Subject: " subject "\n") )) (defun nndoc-transform-sans-security-article (article) "Transform a SANS security article so that it matches nndoc expectations." (goto-char (point-min)) (while (eq (following-char) ?\n) (delete-char 1)) (if (looking-at "^(?[0-9]+) ") (progn (insert "Subject: ") (end-of-line) (insert "\n")) (if (re-search-forward "^Title: " nil t) (let ((here (point)) (subjstart (point)) subject) (end-of-line) (setq subject (buffer-substring here (point))) (forward-char 1) (while (not (looking-at "^Description:")) (setq here (point)) (end-of-line) (setq subject (concat subject " " (buffer-substring here (point)))) (forward-char 1)) (setq here (point)) (goto-char subjstart) (beginning-of-line) (delete-region (point) here) (goto-char (point-min)) (insert "Subject: " subject "\n\n") )) )) (nndoc-add-type '(sans-security (article-begin-function . nndoc-sans-security-article-begin) (article-transform-function . nndoc-transform-sans-security-article) (head-end . "\n") (body-begin-function . nndoc-sans-security-body-begin) (body-end . "^[-*_]\\{10,\\}$") (file-end . "^(c) 20[0-9][0-9]. +All rights reserved.") (generate-head-function . nndoc-generate-sans-security-head) ))