Unknown@caeco.UUCP (Steve Murphy) (11/15/87)
I got some letters stating that newslist.c had been lost from the original distribution.... There were some bugs in the vn.el package, too, so...... sorry, but I'm reposting this. This time everythings in one file, so if something gets lost, it all gets lost, and you won't know this happened (sigh). Again, to answer some Q's.... this is an imitation of vn -- a news reading program by Mr. McQueer, that I pulled off usenet some time ago. You should set up the NEWSBOX environment variable to point to a directory where news articles are to be saved. The most practical thing to do is put something like this in the .xxxrc (or whatever) file in your home dir: setenv NEWSBOX ~/newsbox (assuming, of course you have a subdir of your home dir called newsbox. Have fun, read the headers, etc. #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./vn.el` then echo "writing ./vn.el" cat > ./vn.el << '\Rogue\Monster\' ;;; USENET news reader for gnu emacs ;; Copyright (C) 1987 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY. No author or distributor ;; accepts responsibility to anyone for the consequences of using it ;; or for whether it serves any particular purpose or works at all, ;; unless he says so in writing. Refer to the GNU Emacs General Public ;; License for full details. ;; Everyone is granted permission to copy, modify and redistribute ;; GNU Emacs, but only under the conditions described in the ;; GNU Emacs General Public License. A copy of this license is ;; supposed to have been given to you along with GNU Emacs so you ;; can know your rights and responsibilities. It should be in a ;; file named COPYING. Among other things, the copyright notice ;; and this notice must be preserved on all copies. ;; written by Steve Murphy, Midvale, Utah, Oct. 1987 ;; Dedicated to Ryan (He and this code share Birthdays) ;; I would suggest that those dissatified with the poor coding, ;; hacked up kloojes, etc. dedicate their energies to fixing it rather ;; than complaining! ;; This is an obvious imitation of vn, written in C by Bob McQueer ;; This 'plagiarism' is actually meant to be a tribute, as vn was/is by far ;; my news reader of choice. ;; I left out some of the functionality, like printing, 'selected' functions, ;; and such-like, because of duplicate functionality in gnu emacs, or ;; just laziness or lack of time. Note the lack of 'digestify'. ;; Also note that sending mail to the author of the current article ;; works, but... when you return things are awry. I believe this to be ;; the fault of rnewspost.el and mail.el. Perhaps I'll post something ;; later on this... ;; the c-code for 'newslist' is part of this package-- I didn't feel expert ;; enough to generate the code in lisp. It was easier for me to come out ;; with a small program that would generate the pages that vn does, showing ;; the article numbers, groups, subject lines, lines, and author. All the ;; data vn-mode needs to update the .newsrc is in the text of the vn buffer. ;; speed is comparable to vn's in generating this list. ;; The concept of 'pages' in vn was lost in the translation--purposely ;; on my part, as I personally like just a long list, and to have as much ;; visible on a page as possible. For those enthusiasts who like it the ;; other way, there are 'narrow' functions that could be put to use, but ;; I didn't feel it was worth it. ;; Two different modes are used, one for paging thru the headers, the other ;; for actually reading the article. The package cleans up after itself, ;; leaving the windows the way they were before the package was invoked. ;; dired and rnews were freely copied here, and several 'autoloads' are ;; included from these sources. Why TOTALLY re-invent the wheel? ;; why did I do it? 1. Someone else indicated a wish for something like this, ;; 2. I wanted it myself, 3. The Challenge of It (why climb Mt. Everest?) ;; and lastly, 4. It was educational. ;; Enjoy. Ps. If the Gnu people want this, they are welcome to it... ;; if they don't.. no sweat, I don't blame them. ;; I'm giving it to them nevertheless, and thus to all who happen on it. (provide 'vn) (require 'mail-utils) (autoload 'rmail-output "rmailout" "Append this message to Unix mail file named FILE-NAME" t) (autoload 'news-convert-format "rnews" "get rid of the headers" t) (autoload 'string-subst-char "rnews" "with args new-char old-char string, replace old-char with new-char in string" t) (autoload 'news-mail-other-window "rnewspost" "Send mail in another window. While composing the message, use \\[mail-yank-original] to yank the original message into it." t) (autoload 'news-caesar-buffer-body "rnews" "rotate the article" t) (autoload 'news-mail-reply "rnewspost" "Mail a reply to the author of the current article. While composing the reply, use \\[mail-yank-original] to yank the original message into it." t) (defvar news-startup-file "$HOME/.newsrc" "Contains ~/.newsrc") (defvar newsbox-dir "$NEWSBOX" "The newsbox directory") (defvar vn-buffer nil "which buffer vn is running in") (defvar vn-read-buffer nil "which buffer the article is read in") (defvar vn-initial-window-config nil "how it was before we mucked..") (defun vn-find-buffer () (let ((blist (buffer-list)) found) (while blist (save-excursion (set-buffer (car blist)) (if (eq major-mode 'vn-mode) (setq found (car blist) blist nil) (setq blist (cdr blist))))) (or found (create-file-buffer "*VN-Buffer*")))) (defun vn-read-find-buffer () (let ((blist (buffer-list)) found) (while blist (save-excursion (set-buffer (car blist)) (if (eq major-mode 'vn-read-mode) (setq found (car blist) blist nil) (setq blist (cdr blist))))) (or found (create-file-buffer "*USENET ARTICLE*")))) (defun vn-readin (buffer) (save-excursion (set-buffer buffer) (let ((buffer-read-only nil)) (widen) (erase-buffer) (call-process "newslist" nil buffer nil) (if (not (zerop (buffer-size))) (goto-char (point-min)))))) (defvar vn-window nil "the window vn is running in") (defun vn () "A half-hearted simulation of vn for emacs. Dired displays a list of unread articles. You can move around in it with the usual commands. Type `h' after entering vn for more info." (interactive) (setq vn-initial-window-config (current-window-configuration)) (switch-to-buffer (vn-noselect)) (setq vn-buffer (current-buffer)) (vn-del-non-groups) (if (zerop (buffer-size)) (progn (kill-buffer (current-buffer)) (set-window-configuration vn-initial-window-config) (message "No News! (Good News?)")) (setq vn-window (selected-window)) (cd (substitute-in-file-name newsbox-dir)))) (defun vn-other-window () "VN simulation for emacs. Like M-x vn but selects in another window." (interactive) (switch-to-buffer-other-window (vn-noselect)) (setq vn-window (selected-window)) (setq vn-buffer (current-buffer))) (defun vn-noselect () "Like M-x vn but returns the vn buffer as value, does not select it." (let ((buffer (vn-find-buffer))) (save-excursion (set-buffer buffer) (vn-readin buffer) (vn-move-to-article) (vn-mode)) buffer)) (defun vn-read-other-window () "VN simulation for emacs. Like M-x vn but selects in another window." (interactive) (switch-to-buffer-other-window (vn-read-noselect)) (setq vn-read-buffer (current-buffer)) (cd (substitute-in-file-name newsbox-dir))) (defun vn-read-noselect () "Like M-x vn but returns the vn read buffer as value, does not select it." (let ((buffer (vn-read-find-buffer))) (save-excursion (set-buffer buffer) (vn-read-mode)) buffer)) (defvar vn-mode-map nil "Local keymap for vn-mode buffers.") (defvar vn-read-mode-map nil "Local keymap for vn-mode buffers.") (if vn-mode-map nil (setq vn-mode-map (make-keymap)) (suppress-keymap vn-mode-map) (define-key vn-mode-map "r" 'vn-read-article) (define-key vn-mode-map " " 'vn-read-article) (define-key vn-mode-map "q" 'vn-quit) (define-key vn-mode-map "k" 'vn-up-article) (define-key vn-mode-map "j" 'vn-down-article) (define-key vn-mode-map "\C-h" 'vn-prev-group) (define-key vn-mode-map "n" 'vn-next-group) (define-key vn-mode-map "\C-m" 'vn-next-page) (define-key vn-mode-map "R" 'vn-read-all-articles) (define-key vn-mode-map "s" 'vn-save-article) (define-key vn-mode-map "S" 'vn-save-all-articles) (define-key vn-mode-map "w" 'vn-update-rc-to-cursor) (define-key vn-mode-map "W" 'vn-update-rc-to-eogroup) (define-key vn-mode-map "\C-w" 'vn-update-rc-all) (define-key vn-mode-map "u" 'vn-unsubscribe-group) (define-key vn-mode-map "h" 'vn-toggle-header-display)) (if vn-read-mode-map nil (setq vn-read-mode-map (make-keymap)) (suppress-keymap vn-read-mode-map) (define-key vn-read-mode-map "n" 'vn-next-article) (define-key vn-read-mode-map "q" 'vn-abort-reading) (define-key vn-read-mode-map "Q" 'vn-abort-reading-next-group) (define-key vn-read-mode-map "r" 'vn-beginning-of-article) (define-key vn-read-mode-map "e" 'vn-end-of-article) (define-key vn-read-mode-map "\C-m" 'vn-scroll-line) (define-key vn-read-mode-map "m" 'news-mail-reply) (define-key vn-read-mode-map "f" 'news-reply) (define-key vn-read-mode-map "s" 'vn-save-this-article) (define-key vn-read-mode-map "p" 'vn-print-this-article) (define-key vn-read-mode-map " " 'vn-next-page) (define-key vn-read-mode-map "z" 'vn-toggle-rot) (define-key vn-read-mode-map "h" 'vn-toggle-header)) ;; vn mode is suitable only for specially formatted data. (put 'vn-mode 'mode-class 'special) (put 'vn-read-mode 'mode-class 'special) (defun vn-mode () "Mode for reading Usenet News in a vn sort of way. \\{vn-mode-map}" (kill-all-local-variables) (setq major-mode 'vn-mode) (setq mode-name "Vn") (setq mode-line-buffer-identification '("Emacs: %17b")) (setq case-fold-search nil) (setq buffer-read-only t) (use-local-map vn-mode-map) (run-hooks 'vn-mode-hook)) (defun vn-read-mode () "Mode for reading Usenet News articles in a vn sort of way. \\{vn-read-mode-map}" (kill-all-local-variables) (setq major-mode 'vn-read-mode) (setq mode-name "Vn-Read") (setq mode-line-buffer-identification '("VN-READ: %17b")) (setq case-fold-search nil) (use-local-map vn-read-mode-map) (run-hooks 'vn-read-mode-hook)) (defun vn-move-to-article () "Move cursor to nearest following article" (if (not (zerop (buffer-size))) (progn (beginning-of-line) (while (and (not (looking-at " [0-9]")) (not (eobp))) (forward-line 1))))) (defun vn-current-group () "return the current group of this article in path format" (save-excursion (let (dirname) (setq dirname (vn-current-group-dot)) (string-subst-char ?/ ?. dirname)))) (defun vn-current-group-dot () "return the current group of this article in dotted notation" (save-excursion (progn (set-buffer vn-buffer) (search-backward "==== Group: ") (skip-chars-forward "^:") (forward-char 2) (let (dirname) (setq dirname (buffer-substring (point) (progn (skip-chars-forward "^ ") (point)))) dirname)))) (defun vn-current-article () "get number of current article" (save-excursion (set-buffer vn-buffer) (skip-chars-forward " ") (let ((beg (point))) (skip-chars-forward "0123456789") (buffer-substring beg (point))))) (defun vn-current-article-file () "return full path of article file" (concat "/usr/spool/news/" (vn-current-group) "/" (vn-current-article))) (defun vn-up-article () "move cursor to previous article line" (interactive) (re-search-backward "^ [0-9]" nil t) (beginning-of-line) ) (defun vn-down-article () "move cursor to next article line (skip group headers)" (interactive) (forward-line) (beginning-of-line) (re-search-forward "^ [0-9]" nil t) (beginning-of-line) ) (defun vn-quit (arg) "end vn session and update .newsrc file" (interactive "nUpdating .newsrc: 0=DO NOT, 1=ALL, 2=TO CURSOR, 3=TO CURSOR GROUP: ") (let ((newsrcbuf (find-file-noselect (substitute-in-file-name news-startup-file)))) (if (equal arg 1) (update-all-groups newsrcbuf)) (if (equal arg 2) (update-all-groups-to-cursor newsrcbuf)) (if (equal arg 3) (update-all-groups-to-eogroup newsrcbuf)) (set-buffer newsrcbuf) (save-buffer) (kill-buffer (current-buffer)) (kill-buffer vn-buffer) (if vn-read-buffer (kill-buffer vn-read-buffer)) (set-window-configuration vn-initial-window-config) )) (defun update-all-groups (newsrcbuf) "update all groups" (vn-add-missing-groups newsrcbuf) (goto-char (point-max)) (forward-line -1) (vn-update-current-group-to-cursor newsrcbuf) (re-search-backward "^.... Group:") (forward-line -1) (while (not (bobp)) (vn-update-current-group-to-cursor newsrcbuf) (re-search-backward "^.... Group:") (forward-line -1)) (vn-unsubscribe-groups newsrcbuf)) (defun update-all-groups-to-cursor (newsrcbuf) "update all groups" (vn-add-missing-groups newsrcbuf) (vn-update-current-group-to-cursor newsrcbuf) (re-search-backward "^.... Group:") (forward-line -1) (while (not (bobp)) (vn-update-current-group-to-cursor newsrcbuf) (re-search-backward "^.... Group:") (forward-line -1)) (vn-unsubscribe-groups newsrcbuf)) (defun update-all-groups-to-eogroup (newsrcbuf) "update all groups" (vn-add-missing-groups newsrcbuf) (beginning-of-line) (if (looking-at "^.... Group:") (forward-line 1)) (if (not (re-search-forward "^.... Group" nil t)) (progn (goto-char (point-max)) (forward-line -1)) (forward-line -1)) (vn-update-current-group-to-cursor newsrcbuf) (re-search-backward "^.... Group:" nil t) (forward-line -1) (while (not (bobp)) (vn-update-current-group-to-cursor newsrcbuf) (re-search-backward "^.... Group:" nil t) (forward-line -1)) (vn-unsubscribe-groups newsrcbuf)) (defun vn-del-non-groups () "delete groups that aren't in active" (save-excursion (if (not (zerop (buffer-size))) (let ((newsrcbuf (find-file-noselect (substitute-in-file-name news-startup-file))) last-art last-group) (goto-char 0) (while (re-search-forward "---- Group:" nil t) (forward-char 1) (setq last-group (buffer-substring (point) (progn (skip-chars-forward "^ ") (point)))) (set-buffer newsrcbuf) (if (re-search-forward (concat last-group ":") nil t) (progn (beginning-of-line) (kill-line 1) (save-buffer) (kill-buffer newsrcbuf))) (set-buffer vn-buffer) (beginning-of-line) (kill-line 1)))))) (defun vn-add-missing-groups (newsrcbuf) "plug in the missing groups" (let (last-art last-group) (save-excursion (goto-char 0) (while (re-search-forward "++++ Group:" nil t) (forward-char 1) (setq last-group (buffer-substring (point) (progn (skip-chars-forward "^ ") (point)))) (set-buffer newsrcbuf) (goto-char (point-max)) (insert last-group) (insert ": 0\n") (set-buffer vn-buffer) (toggle-read-only) (beginning-of-line) (kill-line 1) (toggle-read-only))))) (defun vn-unsubscribe-groups (newsrcbuf) "mark groups unsubscribed" (let (last-art last-group) (save-excursion (goto-char 0) (while (re-search-forward "---- Group:" nil t) (forward-char 1) (setq last-group (buffer-substring (point) (progn (skip-chars-forward "^ ") (point)))) (set-buffer newsrcbuf) (if (re-search-forward (concat last-group ":") nil t) (progn (delete-char -1) (insert "!"))) (set-buffer vn-buffer))))) (defun vn-update-current-group-to-cursor (newsrcbuf) "update the .newsrc file" (let (last-art last-group) (save-excursion (set-buffer vn-buffer) (if (not (bolp)) (beginning-of-line)) (if (not (bobp)) (progn (while (and (looking-at ".... Group:") (not (bobp))) (forward-line -1)) (if (not (bobp)) (progn (setq last-art (vn-current-article)) (setq last-group (vn-current-group-dot)) (message "updating %s-%s" last-group last-art ) (set-buffer newsrcbuf) (goto-char 0) (if (re-search-forward (concat "^" last-group "[:!]") nil t) (progn (forward-char 1) (if (looking-at "0") (progn (delete-char 1) (insert "1-0") (forward-char -3))) (skip-chars-forward "^-") (forward-char 1) (delete-region (point) (progn (end-of-line) (point))) (insert last-art)) (message "Couldn't find %s" (concat last-group)))))))))) (defun vn-prev-group () "jump to first article line in prev. group" (interactive) (search-backward "==== Group: ") (search-backward "==== Group: ") (vn-move-to-article)) (defun vn-next-group () "jump to first article line in next group" (interactive) (search-forward "==== Group: ") (vn-move-to-article)) (defun vn-read-article () "open up another buffer to view article in" (interactive) (beginning-of-line) (toggle-read-only) (delete-char 1) (insert ">") (toggle-read-only) (let ((filename (vn-current-article-file))) (vn-read-other-window) (erase-buffer) (let ((start (point))) (insert-file-contents filename) (if (not vn-header-on) (news-convert-format)) (goto-char start) (forward-line 1)))) (defvar vn-read-sequence nil "indicates we are in read-all mode") (defun vn-read-all-articles () "open up another buffer and view all the articles serially in it from current article to end of group" (interactive) (setq vn-read-sequence t) (vn-read-article)) (defun vn-save-article () "save the current article to a disk file" (interactive) (beginning-of-line) (toggle-read-only) (delete-char 1) (insert ">") (toggle-read-only) (call-interactively 'vn-save-article-2 nil) (beginning-of-line) (toggle-read-only) (delete-char 1) (insert " ") (toggle-read-only)) (defun vn-save-article-2 (file) "save the current article to a disk file" (interactive "FCopy to File Name:") (copy-file (concat "/usr/spool/news/" (vn-current-group) "/" (vn-current-article)) file 1 nil)) (defun vn-save-all-articles (file) "save all the articles from current article in this group to a disk file" (interactive "FSave them (from current article to end of group to file: ") (let ((newsrcbuf (find-file-noselect file)) (curgroup (vn-current-group)) currartfile) (while (and (equal curgroup (vn-current-group)) (not (eobp))) (setq currartfile (vn-current-article-file)) (set-buffer newsrcbuf) (goto-char (point-max)) (insert-file currartfile) (set-buffer vn-buffer) (vn-down-article)) (set-buffer newsrcbuf) (save-buffer) (kill-buffer newsrcbuf))) (defun vn-update-rc-to-cursor () "all articles on or above cursor will be marked as read in the .newsrc file" (interactive) (save-excursion (let ((newsrcbuf (find-file-noselect (substitute-in-file-name news-startup-file)))) (update-all-groups-to-cursor newsrcbuf) (set-buffer newsrcbuf) (save-buffer) (kill-buffer (current-buffer))))) (defun vn-update-rc-to-eogroup () "all articles on or above the current group will be marked as read in the .newsrc file" (interactive) (save-excursion (let ((newsrcbuf (find-file-noselect (substitute-in-file-name news-startup-file)))) (update-all-groups-to-eogroup newsrcbuf) (set-buffer newsrcbuf) (save-buffer) (kill-buffer (current-buffer))))) (defun vn-update-rc-all() "all articles scheduled to be read will be marked as read in the .newsrc file" (interactive) (save-excursion (let ((newsrcbuf (find-file-noselect (substitute-in-file-name news-startup-file)))) (update-all-groups newsrcbuf) (set-buffer newsrcbuf) (save-buffer) (kill-buffer (current-buffer))))) (defun vn-unsubscribe-group () "toggle between subscription/unsubscription of/from current group" (interactive) (save-excursion (if (re-search-backward "^.... Group: " nil t) (progn (re-search-forward "^.... Group: " nil t) (beginning-of-line) (if (looking-at "====") (progn (toggle-read-only) (delete-char 4) (insert "----") (toggle-read-only)) (toggle-read-only) (delete-char 4) (insert "====") (toggle-read-only)))))) (defun vn-toggle-header-display () "Toggle showing ALL the header lines" (interactive) (if vn-header-on (setq vn-header-on nil) (setq vn-header-on t))) ;; ------------reader mode stuff------------------------ (defun vn-next-article () "back to the vn buffer if no further articles" (interactive) (erase-buffer) (set-buffer vn-buffer) (select-window vn-window) (let ((curgroup (vn-current-group))) (beginning-of-line) (toggle-read-only) (delete-char 1) (insert " ") (toggle-read-only) (vn-down-article) (if (and vn-read-sequence (equal curgroup (vn-current-group))) (vn-read-article)))) (defun vn-abort-reading () "back to the buffer, and no other articles" (interactive) (erase-buffer) (setq vn-read-sequence nil) (let ((buffer (vn-find-buffer))) (set-buffer buffer) (select-window vn-window) (beginning-of-line) (toggle-read-only) (delete-char 1) (insert " ") (toggle-read-only) (vn-down-article))) (defun vn-abort-reading-next-group () "back to the buffer, the first article in the next group" (interactive) (erase-buffer) (setq vn-read-sequence nil) (let ((buffer (vn-find-buffer))) (set-buffer buffer) (select-window vn-window) (beginning-of-line) (toggle-read-only) (delete-char 1) (insert " ") (toggle-read-only) (vn-next-group))) (defun vn-beginning-of-article () "back to the beginning of the article..." (interactive) (beginning-of-buffer)) (defun vn-end-of-article () "jump to the end of the article" (interactive) (end-of-buffer)) (defun vn-scroll-line () "scroll line up one" (interactive) (scroll-up 1)) (defun vn-toggle-rot () "caesar en/de code the current article" (interactive) (news-caesar-buffer-body) ) (defvar vn-header-on nil "nil or t, no or yes to verbose header...") (defun vn-toggle-header () "to display those header lines or not to..." (interactive) (if vn-header-on (progn (setq vn-header-on nil) (save-excursion (goto-char (point-min)) (news-convert-format))) (setq vn-header-on t) (set-buffer vn-buffer) (select-window vn-window) (vn-read-article))) (defun vn-next-page () "scroll article/article-list up a page" (interactive) (scroll-up)) (defun vn-save-this-article (file) "save this article by appending to a file" (interactive "FSave item in file:") (append-to-file (point-min) (point-max) file)) \Rogue\Monster\ else echo "will not over write ./vn.el" fi if `test ! -s ./newslist.c` then echo "writing ./newslist.c" cat > ./newslist.c << '\Rogue\Monster\' /* a facility to generate article lists much after the format originating with Bob McQueer's 'vn' package. Written by Steve Murphy of Midvale, Utah Copyright (C) 1987 Free Software Foundation, Inc. NO WARRANTY BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. GENERAL PUBLIC LICENSE TO COPY 1. You may copy and distribute verbatim copies of this source file as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy a valid copyright notice "Copyright (C) 1985 Free Software Foundation, Inc."; and include following the copyright notice a verbatim copy of the above disclaimer of warranty and of this License. You may charge a distribution fee for the physical act of transferring a copy. 2. You may modify your copy or copies of this source file or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains or is a derivative of this program or any part thereof, to be licensed at no charge to all third parties on terms identical to those contained in this License Agreement (except that you may choose to grant more extensive warranty protection to third parties, at your option). c) You may charge a distribution fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 3. You may copy and distribute this program or any portion of it in compiled, executable or object code form under the terms of Paragraphs 1 and 2 above provided that you do the following: a) cause each such copy to be accompanied by the corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) cause each such copy to be accompanied by a written offer, with no time limit, to give any third party free (except for a nominal shipping charge) a machine readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) in the case of a recipient of this program in compiled, executable or object code form (without the corresponding source code) you shall cause copies you distribute to be accompanied by a copy of the written offer of source code which you received along with the copy you received. 4. You may not copy, sublicense, distribute or transfer this program except as expressly provided under this License Agreement. Any attempt otherwise to copy, sublicense, distribute or transfer this program is void and your rights to use the program under this License agreement shall be automatically terminated. However, parties who have received computer software programs from you with this License Agreement will not have their licenses terminated so long as such parties remain in full compliance. 5. If you wish to incorporate parts of this program into other free programs whose distribution conditions are different, write to the Free Software Foundation at 1000 Mass Ave, Cambridge, MA 02138. We have not yet worked out a simple rule that can be stated here, but we will often permit this. We will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software. In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve what you give them. Help stamp out software-hoarding! */ #include <stdio.h> #include <strings.h> struct groupnode { struct groupnode *next,*prev; char name[80]; char status; struct art *arts; struct active { int start,end; } active; struct myrc { int start,end; } myrc; }; struct art { struct art *next; int num; char subj[200]; }; struct groupnode *groups=0,*groupend = 0; struct groupnode *find_gn(name) char *name; { struct groupnode *gnp; for(gnp=groups; gnp; gnp=gnp->next) { if(!strcmp(gnp->name,name)) { return gnp; } } return 0; } ins_gn(gnp) struct groupnode *gnp; { if( !groups ) { groups = groupend = gnp; } else { gnp->prev = groupend; gnp->next = 0; groupend = gnp; gnp->prev->next = gnp; } } main() { FILE *f; char *getenv(); char buff[1000],t[1000]; struct groupnode *gnp; sprintf(buff,"%s/.newsrc",getenv("HOME")); f = fopen(buff,"r"); while (fgets(buff,1000,f)) /* skip options */ { if(!strncmp(buff,"options",7)) continue; else break; } do { int n; gnp = (struct groupnode *)calloc(sizeof(struct groupnode),1); n = sscanf(buff,"%s %d-%d",gnp->name,&gnp->myrc.start, &gnp->myrc.end); if( n < 3 ) gnp->myrc.end = gnp->myrc.start = 0; gnp->active.start = gnp->active.end = -1; gnp->status = gnp->name[strlen(gnp->name)-1]; gnp->name[strlen(gnp->name)-1] = 0; ins_gn(gnp); } while (fgets(buff,1000,f)); fclose(f); strcpy(buff,"/usr/lib/news/active"); f = fopen(buff,"r"); if( !f ) { fprintf(stderr,"Couldn't open %s\n",buff); exit(999); } while (fgets(buff,1000,f)) { int start,end; sscanf(buff,"%s %d %d ",t,&end,&start); gnp = find_gn(t); if( !gnp ) { printf("++++ Group: %s not in .newsrc file...\n",t); gnp = (struct groupnode *)calloc(sizeof(struct groupnode),1); strcpy(gnp->name,t); gnp->status = ':'; gnp->myrc.start = 1; gnp->myrc.end = 0; ins_gn(gnp); } gnp->active.start = start; gnp->active.end = end; } fclose(f); for(gnp=groups; gnp; gnp=gnp->next) { if(gnp->active.start == gnp->active.end && gnp->active.end == -1 ) { printf("---- Group: %s No Longer Exists\n",gnp->name); } } for(gnp=groups; gnp; gnp=gnp->next) { int st,en,i; char *sp,subject[300],from[300],lines[10]; if( gnp->status == ':' && (gnp->myrc.end < gnp->active.end && gnp->active.end > gnp->active.start || gnp->active.end < gnp->myrc.end )) { if( gnp->active.end < gnp->myrc.end ) { gnp->myrc.end = gnp->active.start; /* for those cases when it's pretty obvious that something's out of whack, lets just play it safe and view the whole set again... */ } printf("==== Group: %s =====\n", gnp->name); st = gnp->myrc.end + 1; /* the next one after the last one read */ if( st < gnp->active.start ) st = gnp->active.start; /* active start == first art there */ en = gnp->active.end; sprintf(buff,"/usr/spool/news/%s",gnp->name); while( sp=index( buff,'.' )) { *sp = '/'; } for( i=st; i<= en; i++) { char tb[1000]; strcpy(subject,""); strcpy(from,""); strcpy(lines,""); sprintf(t,"%s/%d",buff,i); f = fopen(t,"r"); if( !f ) continue; while( fgets(tb,1000,f)) { tb[strlen(tb)-1] = 0; /* get rid of the trailing \n */ if( !strncmp(tb,"Subject:",8)) { strcpy(subject,tb+9); } if( !strncmp(tb,"Lines:",6)) { strcpy(lines,tb+7); } if( !strncmp(tb,"From:",5)) { char *tt; tt = index(tb,'('); if( tt ) { strcpy(from,tt); tt = index(from,')'); if(tt) { *(tt+1) = 0; } } else strcpy(from,tb+6); } if(*subject && *from && *lines) break; } fclose(f); printf(" %d: %s ~ %s %s\n", i,subject,lines,from); } } } } \Rogue\Monster\ else echo "will not over write ./newslist.c" fi echo "Finished archive 1 of 1" exit -- Steve Murphy, CAECO, Inc., 7090 South Union Park Avenue, Suite 200, Midvale, UT 84047 (801)255-8880 <WORLD>!{byuadam,utah-cs,nrc-ut,wicat}!caeco!murf