Annotation of 43BSD/contrib/emacs/lisp/rnews.el, revision 1.1

1.1     ! root        1: ;;; Netnews reader for gnu emacs
        !             2: ;; Copyright (C) 1985 Free Software Foundation
        !             3: 
        !             4: ;; This file is part of GNU Emacs.
        !             5: 
        !             6: ;; GNU Emacs is distributed in the hope that it will be useful,
        !             7: ;; but WITHOUT ANY WARRANTY.  No author or distributor
        !             8: ;; accepts responsibility to anyone for the consequences of using it
        !             9: ;; or for whether it serves any particular purpose or works at all,
        !            10: ;; unless he says so in writing.  Refer to the GNU Emacs General Public
        !            11: ;; License for full details.
        !            12: 
        !            13: ;; Everyone is granted permission to copy, modify and redistribute
        !            14: ;; GNU Emacs, but only under the conditions described in the
        !            15: ;; GNU Emacs General Public License.   A copy of this license is
        !            16: ;; supposed to have been given to you along with GNU Emacs so you
        !            17: ;; can know your rights and responsibilities.  It should be in a
        !            18: ;; file named COPYING.  Among other things, the copyright notice
        !            19: ;; and this notice must be preserved on all copies.
        !            20: 
        !            21: 
        !            22: ;;; Created Sun Mar 10,1985 at 21:35:01 ads and sundar
        !            23: ;;; Should do the point pdl stuff sometime
        !            24: ;;; finito except pdl.... Sat Mar 16,1985 at 06:43:44
        !            25: ;;; lets keep the summary stuff out until we get it working ..
        !            26: ;;; sundar              Wed Apr 10,1985 at 16:32:06
        !            27: ;;; hack slash maim. mly Thu 18 Apr, 1985 06:11:14
        !            28: ;;; news-add-news-group / 'stead of . bug tower Mon Mar  3 15:39:44 EST 1986
        !            29: ;;; news-mail-reply from anywhere in buffer tower Wed Mar 12 11:15:03 EST 1986
        !            30: ;;; modified to correct reentrance bug, to not bother with groups that
        !            31: ;;;   received no new traffic since last read completely, to find out
        !            32: ;;;   what traffic a group has available much more quickly when
        !            33: ;;;   possible, to do some completing reads for group names - should
        !            34: ;;;   be much faster...
        !            35: ;;;      KING@KESTREL, Thu Mar 13 09:03:28 1986
        !            36: ;;; fixed doc error   tower Sun Mar 16 14:25:43 EST 1986
        !            37: (require 'mail-utils)
        !            38: 
        !            39: ;Now in paths.el.
        !            40: ;(defvar news-path "/usr/spool/news/"
        !            41: ;  "The root directory below which all news files are stored.")
        !            42: ;(defvar news-inews-program "inews"
        !            43: ;  "Function to post news.")
        !            44: 
        !            45: (defvar news-startup-file "$HOME/.newsrc" "Contains ~/.newsrc")
        !            46: (defvar news-certification-file "$HOME/.news-dates" "Contains ~/.news-dates")
        !            47: 
        !            48: ;;; random headers that we decide to ignore.
        !            49: (defvar news-ignored-headers
        !            50:   "^Path:\\|^Posting-Version:\\|^Article-I.D.:\\|^Followup-To:\\|^Expires:\\|^Date-Received:\\|^Organization:\\|^References:\\|^Control:\\|^Xref:\\|^Lines:\\|^Posted:\\|^Relay-Version:\\|^Message-ID:\\|^Nf-ID:"
        !            51:   "All random fields within the header of a message.")
        !            52: 
        !            53: (defvar news-mode-map nil)
        !            54: (defvar news-read-first-time-p t)
        !            55: ;; Contains the (dotified) news groups of which you are a member. 
        !            56: (defvar news-user-group-list nil)
        !            57: 
        !            58: (defvar news-current-news-group nil)
        !            59: (defvar news-current-group-begin nil)
        !            60: (defvar news-current-group-end  nil)
        !            61: (defvar news-current-certifications nil
        !            62:        "An assoc list of a group name and the time at which it is
        !            63: known that the grop had no new traffic")
        !            64: (defvar news-current-certifiable nil
        !            65:        "The time when the directory we are now working on was written")
        !            66: 
        !            67: 
        !            68: (defvar news-message-filter nil
        !            69:   "User specifiable filter function that will be called during
        !            70: formatting of the news file")
        !            71: 
        !            72: ;(defvar news-mode-group-string "Starting-Up"
        !            73: ;  "Mode line group name info is held in this variable")
        !            74: (defvar news-list-of-files nil
        !            75:   "Global variable in which we store the list of files
        !            76: associated with the current newsgroup")
        !            77: (defvar news-list-of-files-possibly-bogus nil
        !            78:   "variable indicating we only are guessing at which files are available.
        !            79: Not currently used.")
        !            80: 
        !            81: ;; association list in which we store lists of the form
        !            82: ;; (pointified-group-name (first last old-last))
        !            83: (defvar news-group-article-assoc nil)
        !            84:   
        !            85: (defvar news-current-message-number 0 "Displayed Article Number")
        !            86: (defvar news-total-current-group 0 "Total no of messages in group")
        !            87: 
        !            88: (defvar news-unsubscribe-groups ())
        !            89: (defvar news-point-pdl () "List of visited news messages.")
        !            90: (defvar news-no-jumps-p t)
        !            91: (defvar news-buffer () "Buffer into which news files are read.")
        !            92: 
        !            93: (defmacro caar (x) (list 'car (list 'car x)))
        !            94: (defmacro cadr (x) (list 'car (list 'cdr x)))
        !            95: (defmacro cdar (x) (list 'cdr (list 'car x)))
        !            96: (defmacro caddr (x) (list 'car (list 'cdr (list 'cdr x))))
        !            97: (defmacro cadar (x) (list 'car (list 'cdr (list 'car x))))
        !            98: (defmacro caadr (x) (list 'car (list 'car (list 'cdr x))))
        !            99: (defmacro cdadr (x) (list 'cdr (list 'car (list 'cdr x))))
        !           100: 
        !           101: (defmacro news-wins (pfx index)
        !           102:   (` (file-exists-p (concat (, pfx) "/" (int-to-string (, index))))))
        !           103: 
        !           104: (defvar news-max-plausible-gap 2
        !           105:        "* In an rnews directory, the maximum possible gap size.
        !           106: A gap is a sequence of missing messages between two messages that exist.
        !           107: An empty file does not contribute to a gap -- it ends one.")
        !           108: 
        !           109: (defun news-find-first-and-last (prefix base)
        !           110:   (and (news-wins prefix base)
        !           111:        (cons (news-find-first-or-last prefix base -1)
        !           112:             (news-find-first-or-last prefix base 1))))
        !           113: 
        !           114: (defmacro // (a1 a2)
        !           115: ;;; a form of / that guarantees that (/ -1 2) = 0
        !           116:   (if (zerop (/ -1 2))
        !           117:       (` (/ (, a1) (, a2)))
        !           118:     (` (if (< (, a1) 0)
        !           119:           (- (/ (- (, a1)) (, a2)))
        !           120:         (/ (, a1) (, a2))))))
        !           121: 
        !           122: (defun news-find-first-or-last (pfx base dirn)
        !           123:   ;; first use powers of two to find a plausible cieling
        !           124:   (let ((original-dir dirn))
        !           125:     (while (news-wins pfx (+ base dirn))
        !           126:       (setq dirn (* dirn 2)))
        !           127:     (setq dirn (// dirn 2))
        !           128:     ;;; Then use a binary search to find the high water mark
        !           129:     (let ((offset (// dirn 2)))
        !           130:       (while (/= offset 0)
        !           131:        (if (news-wins pfx (+ base dirn offset))
        !           132:            (setq dirn (+ dirn offset)))
        !           133:        (setq offset (// offset 2))))
        !           134:     ;;; If this high-water mark is bogus, recurse.
        !           135:     (let ((offset (* news-max-plausible-gap original-dir)))
        !           136:       (while (and (/= offset 0) (not (news-wins pfx (+ base dirn offset))))
        !           137:        (setq offset (- offset original-dir)))
        !           138:       (if (= offset 0)
        !           139:          (+ base dirn)
        !           140:        (news-find-first-or-last pfx (+ base dirn offset) original-dir)))))
        !           141: 
        !           142: (defun rnews ()
        !           143:   "Read netnews for groups for which you are a member and add or delete groups.
        !           144: You can reply to articles posted and send articles to any group.
        !           145:   Type Help m once reading news to get a list of rnews commands."
        !           146:   (interactive)
        !           147:   (let ((last-buffer (buffer-name)))
        !           148:     (switch-to-buffer (setq news-buffer (get-buffer-create "*news*")))
        !           149:     (news-mode)
        !           150:     (setq news-buffer-save last-buffer)
        !           151:     (setq buffer-read-only nil)
        !           152:     (erase-buffer)
        !           153:     (setq buffer-read-only t)
        !           154:     (set-buffer-modified-p t)
        !           155:     (sit-for 0)
        !           156:     (message "Getting new net news...")
        !           157:     (news-set-mode-line)
        !           158:     (news-get-certifications)
        !           159:     (news-get-new-news)))
        !           160: 
        !           161: (defun news-group-certification (group)
        !           162:   (cdr-safe (assoc group news-current-certifications)))
        !           163: 
        !           164: 
        !           165: (defun news-set-current-certifiable ()
        !           166:   ;;; Record the date that corresponds to the directory you are about to check
        !           167:   (let ((file (concat news-path
        !           168:                      (string-subst-char ?/ ?. news-current-news-group))))
        !           169:     (setq news-current-certifiable
        !           170:          (nth 5 (file-attributes
        !           171:                  (or (file-symlink-p file) file))))))
        !           172: 
        !           173: (defun news-get-certifications ()
        !           174:   ;;; Read the certified-read file from last session
        !           175:   (save-excursion
        !           176:     (save-window-excursion
        !           177:       (setq news-current-certifications
        !           178:            (car-safe
        !           179:             (condition-case var
        !           180:                 (let*
        !           181:                     ((file (substitute-in-file-name news-certification-file))
        !           182:                      (buf (find-file-noselect file)))
        !           183:                   (and (file-exists-p file)
        !           184:                        (progn
        !           185:                          (switch-to-buffer buf 'norecord)
        !           186:                          (unwind-protect
        !           187:                              (read-from-string (buffer-string))
        !           188:                            (kill-buffer buf)))))
        !           189:               (error nil)))))))
        !           190: 
        !           191: (defun news-write-certifications ()
        !           192:   ;;; Write a certification file.  This is an assoc list of group names with
        !           193:   ;;;doubletons that represent mod times of the directory when group is read
        !           194:   ;;;completely.
        !           195:   (save-excursion
        !           196:     (save-window-excursion
        !           197:       (with-output-to-temp-buffer
        !           198:          "*CeRtIfIcAtIoNs*"
        !           199:          (print news-current-certifications))
        !           200:       (let ((buf (get-buffer "*CeRtIfIcAtIoNs*")))
        !           201:        (switch-to-buffer buf)
        !           202:        (write-file (substitute-in-file-name news-certification-file))
        !           203:        (kill-buffer buf)))))
        !           204: 
        !           205: (defun news-set-current-group-certification ()
        !           206:   (let ((cgc (assoc news-current-news-group news-current-certifications)))
        !           207:     (if cgc (setcdr cgc news-current-certifiable)
        !           208:       (push (cons news-current-news-group news-current-certifiable)
        !           209:            news-current-certifications))))
        !           210: 
        !           211: (defun news-set-minor-modes ()
        !           212:   "Creates a minor mode list that has group name, total articles,
        !           213: and attribute for current article."
        !           214:   (setq minor-modes (list (cons 'foo
        !           215:                                (concat news-current-message-number
        !           216:                                        "/"
        !           217:                                        news-total-current-group
        !           218:                                        (news-get-attribute-string))))))
        !           219: 
        !           220: (defun news-set-message-counters ()
        !           221:   "Scan through current news-groups filelist to figure out how many messages
        !           222: are there. Set counters for use with minor mode display."
        !           223:     (if (null news-list-of-files)
        !           224:        (setq news-current-message-number 0)))
        !           225: 
        !           226: (if news-mode-map
        !           227:     nil
        !           228:   (setq news-mode-map (make-keymap))
        !           229:   (suppress-keymap news-mode-map)
        !           230:   (define-key news-mode-map "." 'beginning-of-buffer)
        !           231:   (define-key news-mode-map " " 'scroll-up)
        !           232:   (define-key news-mode-map "\177" 'scroll-down)
        !           233:   (define-key news-mode-map "n" 'news-next-message)
        !           234:   (define-key news-mode-map "c" 'news-make-link-to-message)
        !           235:   (define-key news-mode-map "p" 'news-previous-message)
        !           236:   (define-key news-mode-map "j" 'news-goto-message)
        !           237:   (define-key news-mode-map "q" 'news-exit)
        !           238:   (define-key news-mode-map "e" 'news-exit)
        !           239:   (define-key news-mode-map "\ej" 'news-goto-news-group)
        !           240:   (define-key news-mode-map "\en" 'news-next-group)
        !           241:   (define-key news-mode-map "\ep" 'news-previous-group)
        !           242:   (define-key news-mode-map "l" 'news-list-news-groups)
        !           243:   (define-key news-mode-map "?" 'describe-mode)
        !           244:   (define-key news-mode-map "g" 'news-get-new-news)
        !           245:   (define-key news-mode-map "f" 'news-reply)
        !           246:   (define-key news-mode-map "m" 'news-mail-other-window)
        !           247:   (define-key news-mode-map "a" 'news-post-news)
        !           248:   (define-key news-mode-map "r" 'news-mail-reply)
        !           249:   (define-key news-mode-map "o" 'news-save-item-in-file)
        !           250:   (define-key news-mode-map "t" 'news-show-all-headers)
        !           251:   (define-key news-mode-map "x" 'news-force-update)
        !           252:   (define-key news-mode-map "A" 'news-add-news-group)
        !           253:   (define-key news-mode-map "u" 'news-unsubscribe-current-group)
        !           254:   (define-key news-mode-map "U" 'news-unsubscribe-group))
        !           255: 
        !           256: (defun news-mode ()
        !           257:   "News Mode is used by M-x rnews for editing News files.
        !           258: All normal editing commands are turned off.
        !           259: Instead, these commands are available:
        !           260: 
        !           261: .      move point to front of this news article (same as Meta-<).
        !           262: Space  scroll to next screen of this news article.
        !           263: Delete  scroll down previous page of this news article.
        !           264: n      move to next news article, possibly next group.
        !           265: p      move to previous news article, possibly previous group.
        !           266: j      jump to news article specified by numeric position.
        !           267: M-j     jump to news group.
        !           268: M-n     goto next news group.
        !           269: M-p     goto previous news group.
        !           270: l       list all the news groups with current status.
        !           271: ?       print this help message.
        !           272: g       get new net news.
        !           273: f       post follow-up article to the net.
        !           274: a       post a news article.
        !           275: A       add a newsgroup. 
        !           276: o      save the current article in the named file (append if file exists).
        !           277: c       \"copy\" (actually link) current or prefix-arg msg to file.
        !           278:        warning: target directory and message file must be on same device
        !           279:                (UNIX magic)
        !           280: t       show all the headers this news article originally had.
        !           281: q      quit reading news after updating .newsrc file.
        !           282: e      exit updating .newsrc file.
        !           283: m      mail a news article.  Same as C-x 4 m.
        !           284: x       update last message seen to be the current message.
        !           285: r      reply to this news article.  Like m but initializes some fields.
        !           286: u       unsubscribe from current newsgroup.
        !           287: U       unsubscribe from specified newsgroup."
        !           288:   (interactive)
        !           289:   (kill-all-local-variables)
        !           290:   (make-local-variable 'news-read-first-time-p)
        !           291:   (setq news-read-first-time-p t)
        !           292:   (make-local-variable 'news-current-news-group)
        !           293: ;  (setq news-current-news-group "??")
        !           294:   (make-local-variable 'news-current-group-begin)
        !           295:   (setq news-current-group-begin 0)
        !           296:   (make-local-variable 'news-current-message-number)
        !           297:   (setq news-current-message-number 0)
        !           298:   (make-local-variable 'news-total-current-group)
        !           299:   (make-local-variable 'news-buffer-save)
        !           300:   (make-local-variable 'version-control)
        !           301:   (setq version-control 'never)
        !           302:   (make-local-variable 'news-point-pdl)
        !           303: ;  This breaks it.  I don't have time to figure out why. -- RMS
        !           304: ;  (make-local-variable 'news-group-article-assoc)
        !           305:   (setq major-mode 'news-mode)
        !           306:   (setq mode-name "NEWS")
        !           307:   (news-set-mode-line)
        !           308:   (set-syntax-table text-mode-syntax-table)
        !           309:   (use-local-map news-mode-map)
        !           310:   (setq local-abbrev-table text-mode-abbrev-table)
        !           311:   (run-hooks 'news-mode-hook))
        !           312: 
        !           313: (defun string-subst-char (new old string)
        !           314:   (let (index)
        !           315:     (setq old (regexp-quote (char-to-string old))
        !           316:          string (substring string 0))
        !           317:     (while (setq index (string-match old string))
        !           318:       (aset string index new)))
        !           319:   string)
        !           320: 
        !           321: ;;; update read message number
        !           322: (defmacro news-update-message-read (ngroup nno)
        !           323:   (list 'setcar
        !           324:        (list 'cdadr
        !           325:              (list 'assoc ngroup 'news-group-article-assoc))
        !           326:        nno))
        !           327: 
        !           328: (defun news-parse-range (number-string)
        !           329:   "Parse string representing range of numbers of he form <a>-<b>
        !           330: to a list (a . b)"
        !           331:   (let ((n (string-match "-" number-string)))
        !           332:     (if n
        !           333:        (cons (string-to-int (substring number-string 0 n))
        !           334:              (string-to-int (substring number-string (1+ n))))
        !           335:       (setq n (string-to-int number-string))
        !           336:       (cons n n))))
        !           337: 
        !           338: ;(defun is-in (elt lis)
        !           339: ;  (catch 'foo
        !           340: ;    (while lis
        !           341: ;      (if (equal (car lis) elt)
        !           342: ;        (throw 'foo t)
        !           343: ;      (setq lis (cdr lis))))))
        !           344: 
        !           345: 
        !           346: (defun news-get-new-news ()
        !           347:   "Get new netnews if there is any for the current user."
        !           348:   (interactive)
        !           349:   (if (not (null news-user-group-list))
        !           350:        (news-update-newsrc-file))
        !           351:   (setq news-group-article-assoc ())
        !           352:   (setq news-user-group-list ())
        !           353:   (message "Looking up .newsrc file...")
        !           354:   (let ((file (substitute-in-file-name news-startup-file))
        !           355:        (temp-user-groups ()))
        !           356:     (save-excursion
        !           357:       (let ((newsrcbuf (find-file-noselect file))
        !           358:            start end endofline tem)
        !           359:        (set-buffer newsrcbuf)
        !           360:        (goto-char 0)
        !           361:        (while (search-forward ": " nil t)
        !           362:          (setq end (point))
        !           363:          (beginning-of-line)
        !           364:          (setq start (point))
        !           365:          (end-of-line)
        !           366:          (setq endofline (point))
        !           367:          (setq tem (buffer-substring start (- end 2)))
        !           368:          (let ((range (news-parse-range
        !           369:                         (buffer-substring end endofline))))
        !           370: 
        !           371: ;          (if (is-in tem temp-user-groups)
        !           372: ;              (progn
        !           373: ;                (setq temp-user-groups (delq tem temp-user-groups))
        !           374: ;                (setq news-group-article-assoc 
        !           375: ;                      (delq (assoc tem news-group-article-assoc)
        !           376: ;                      news-group-article-assoc))
        !           377: ;                (message "Subscribed to the same group twice?")))
        !           378: 
        !           379:            (setq temp-user-groups (cons tem temp-user-groups)
        !           380:                  news-group-article-assoc
        !           381:                    (cons (list tem (list (car range)
        !           382:                                          (cdr range)
        !           383:                                          (cdr range)))
        !           384:                          news-group-article-assoc))))
        !           385:        (kill-buffer newsrcbuf)))      
        !           386:     (setq temp-user-groups (nreverse temp-user-groups))
        !           387:     (message "Prefrobnicating...")
        !           388:     (switch-to-buffer news-buffer)
        !           389:     (setq news-user-group-list temp-user-groups)
        !           390:     (while (and temp-user-groups
        !           391:                (not (news-read-files-into-buffer
        !           392:                       (car temp-user-groups) nil)))
        !           393:       (setq temp-user-groups (cdr temp-user-groups)))
        !           394:     (if (null temp-user-groups)
        !           395:        (message "No news is good news.")
        !           396:       (message ""))))
        !           397: 
        !           398: (defun news-list-news-groups ()
        !           399:   "Display all the news groups to which you belong."
        !           400:   (interactive)
        !           401:   (if (null news-user-group-list)
        !           402:       (message "No user groups read yet!")
        !           403:     (let ((buffer-read-only ()))
        !           404:       (setq mode-line-format "--%%--[q: to goback, space: scroll-forward, delete:scroll-backward] %M --%--")
        !           405:       (local-set-key " " 'scroll-up)
        !           406:       (local-set-key "\177" 'scroll-down)
        !           407:       (local-set-key "q" 'news-get-back)
        !           408:       (goto-char 0)
        !           409:       (save-excursion
        !           410:         (erase-buffer)
        !           411:        (insert
        !           412:          "News Group        Msg No.       News Group        Msg No.\n")
        !           413:        (insert
        !           414:          "-------------------------       -------------------------\n")
        !           415:        (let ((temp news-user-group-list)
        !           416:              (flag nil))
        !           417:          (while temp
        !           418:            (let ((item (assoc (car temp) news-group-article-assoc)))
        !           419:              (insert (car item))
        !           420:              (indent-to (if flag 52 20))
        !           421:              (insert (int-to-string (cadr (cadr item))))
        !           422:              (if flag
        !           423:                  (insert "\n")
        !           424:                  (indent-to 33))
        !           425:              (setq temp (cdr temp) flag (not flag)))))))))
        !           426: 
        !           427: (defun news-get-back ()
        !           428:   "Called when you quit from seeing the news groups list."
        !           429:   (interactive)
        !           430:   (let ((buffer-read-only ()))
        !           431:     (erase-buffer)
        !           432:     (local-set-key "q" 'news-exit)
        !           433:     (news-set-mode-line)
        !           434:     (news-read-in-file
        !           435:       (concat news-path
        !           436:              (string-subst-char ?/ ?. news-current-news-group)
        !           437:              "/" (int-to-string news-current-message-number)))))
        !           438: 
        !           439: (defun strcpyn (str1 str2 len)
        !           440:   (if (string= str2 "")
        !           441:       str1
        !           442:     (while (>= len 0)
        !           443:       (aset str1 len (aref str2 len))
        !           444:       (setq len (1- len)))
        !           445:     str1))
        !           446: 
        !           447: ;; Mode line hack
        !           448: (defun news-set-mode-line ()
        !           449:   "Set mode line string to something useful."
        !           450:   (let ((tem (1- (length news-current-news-group)))
        !           451:        (idx 0)
        !           452:        (buffer-modified-p ()))
        !           453:     (setq mode-line-format 
        !           454:          (concat "--%1*%1*-NEWS: "
        !           455:                  (if (> tem 15)
        !           456:                      news-current-news-group
        !           457:                    (let ((string (make-string 16 ? )))
        !           458:                      (setq idx 0)
        !           459:                      (while (<= idx tem)
        !           460:                        (aset string idx (aref news-current-news-group idx))
        !           461:                        (setq idx (1+ idx)))
        !           462:                      string))
        !           463:                  " ["
        !           464:                  (if (integerp news-current-message-number)
        !           465:                      (int-to-string news-current-message-number)
        !           466:                   "??")
        !           467:                 "/"
        !           468:                 (if (integerp news-current-group-end)
        !           469:                     (int-to-string news-current-group-end)
        !           470:                   news-current-group-end)
        !           471:                 "] %M ----%3p-%-"))
        !           472:     (set-buffer-modified-p t)
        !           473:     (sit-for 0)))
        !           474: 
        !           475: (defun news-goto-news-group (gp)
        !           476:   "Takes a string and goes to that news group."
        !           477:   (interactive (list (completing-read "NewsGroup: "
        !           478:                                      news-group-article-assoc)))
        !           479:   (message "Jumping to news group %s..." gp)
        !           480:   (news-select-news-group gp)
        !           481:   (message "Jumping to news group %s... done." gp))
        !           482: 
        !           483: (defun news-select-news-group (gp)
        !           484:   (let ((grp (assoc gp news-group-article-assoc)))
        !           485:     (if (null grp)
        !           486:        (error "No more news groups")
        !           487:       (progn
        !           488:        (news-update-message-read news-current-news-group
        !           489:                                  (cdar news-point-pdl))
        !           490:        (news-read-files-into-buffer  (car grp) nil)
        !           491:        (news-set-mode-line)))))
        !           492: 
        !           493: (defun news-goto-message (arg)
        !           494:   "Goes to the article ARG in current newsgroup."
        !           495:   (interactive "p")
        !           496:   (if (null current-prefix-arg)
        !           497:       (setq arg (read-no-blanks-input "Go to article: " "")))
        !           498:   (news-select-message arg))
        !           499: 
        !           500: (defun news-select-message (arg)
        !           501:   (if (stringp arg) (setq arg (string-to-int arg)))
        !           502:   (let ((file (concat news-path
        !           503:                      (string-subst-char ?/ ?. news-current-news-group)
        !           504:                      "/" arg)))
        !           505:     (if (file-exists-p file)
        !           506:        (let ((buffer-read-only ()))
        !           507:          (if (= arg 
        !           508:                 (or (cadr (memq (cdar news-point-pdl) news-list-of-files))
        !           509:                     0))
        !           510:              (setcdr (car news-point-pdl) arg))
        !           511:          (setq news-current-message-number arg)
        !           512:          (news-read-in-file file)
        !           513:          (news-set-mode-line))
        !           514:       (error "Article %d nonexistent" arg))))
        !           515: 
        !           516: (defun news-force-update ()
        !           517:   "updates the position of last article read in the current news group"
        !           518:   (interactive)
        !           519:   (setcdr (car news-point-pdl) news-current-message-number)
        !           520:   (message "Updated to %d" news-current-message-number))
        !           521: 
        !           522: (defun news-next-message (arg)
        !           523:   "Move ARG messages forward within one newsgroup.
        !           524: Negative ARG moves backward.
        !           525: If ARG is 1 or -1, moves to next or previous newsgroup if at end."
        !           526:   (interactive "p")
        !           527:   (let ((no (+ arg news-current-message-number)))
        !           528:     (if (or (< no news-current-group-begin) 
        !           529:            (> no news-current-group-end))
        !           530:        (cond ((= arg 1)
        !           531:               (news-set-current-group-certification)
        !           532:               (news-next-group)
        !           533:               (while (null news-list-of-files)
        !           534:                 (news-next-group)))
        !           535:              ((= arg -1)
        !           536:               (news-previous-group)
        !           537:               (while (null news-list-of-files)
        !           538:                 (news-previous-group)))
        !           539:              (t (error "Article out of range")))
        !           540:       (let ((plist (news-get-motion-lists
        !           541:                     news-current-message-number
        !           542:                     news-list-of-files)))
        !           543:        (if (< arg 0)
        !           544:            (news-select-message (nth (1- (- arg)) (car (cdr plist))))
        !           545:          (news-select-message (nth (1- arg) (car plist))))))))
        !           546: 
        !           547: (defun news-previous-message (arg)
        !           548:   "Move ARG messages backward in current newsgroup.
        !           549: With no arg or arg of 1, move one message
        !           550: and move to previous newsgroup if at beginning.
        !           551: A negative ARG means move forward."
        !           552:   (interactive "p")
        !           553:   (news-next-message (- arg)))
        !           554: 
        !           555: (defun news-move-to-group (arg)
        !           556:   "Given arg move forward or backward to a new newsgroup."
        !           557:   (let ((cg news-current-news-group))
        !           558:     (let ((plist (news-get-motion-lists cg news-user-group-list))
        !           559:          ngrp)
        !           560:       (if (< arg 0)
        !           561:          (or (setq ngrp (nth (1- (- arg)) (cadr plist)))
        !           562:              (error "No more news groups"))
        !           563:        (or (setq ngrp (nth arg (car plist)))
        !           564:            (error "No previous news groups")))
        !           565:       (news-select-news-group ngrp))))
        !           566: 
        !           567: (defun news-next-group ()
        !           568:   "Moves to the next user group."
        !           569:   (interactive)
        !           570: ;  (message "Moving to next group...")
        !           571:   (news-move-to-group 0))
        !           572: ;  (message "Moving to next group... done.")
        !           573: 
        !           574: (defun news-previous-group ()
        !           575:   "Moves to the previous user group."
        !           576:   (interactive)
        !           577: ;  (message "Moving to previous group...")
        !           578:   (news-move-to-group -1))
        !           579: ;  (message "Moving to previous group... done.")
        !           580: 
        !           581: (defun news-get-motion-lists (arg listy)
        !           582:   "Given a msgnumber/group this will return a list of two lists;
        !           583: one for moving forward and one for moving backward."
        !           584:   (let ((temp listy)
        !           585:        (result ()))
        !           586:     (catch 'out
        !           587:       (while temp
        !           588:        (if (equal (car temp) arg)
        !           589:            (throw 'out (cons (cdr temp) (list result)))
        !           590:          (setq result (nconc (list (car temp)) result))
        !           591:          (setq temp (cdr temp)))))))
        !           592: 
        !           593: ;; miscellaneous io routines
        !           594: (defun news-read-in-file (filename)
        !           595:   (erase-buffer)
        !           596:   (let ((start (point)))
        !           597:   (insert-file-contents filename)
        !           598:   (news-convert-format)
        !           599:   (goto-char start)
        !           600:   (forward-line 1)
        !           601:   (if (eobp)
        !           602:       (message "(Empty file?)")
        !           603:     (goto-char start))))
        !           604: 
        !           605: (defun news-convert-format ()
        !           606:   (save-excursion
        !           607:     (save-restriction
        !           608:       (let* ((start (point))
        !           609:             (end (condition-case ()
        !           610:                      (progn (search-forward "\n\n") (point))
        !           611:                    (error nil)))
        !           612:             has-from has-date)
        !           613:        (cond (end
        !           614:              (narrow-to-region start end)
        !           615:              (goto-char start)
        !           616:              (setq has-from (search-forward "\nFrom:" nil t))
        !           617:              (cond ((and (not has-from) has-date)
        !           618:                     (goto-char start)
        !           619:                     (search-forward "\nDate:")
        !           620:                     (beginning-of-line)
        !           621:                     (kill-line) (kill-line)))
        !           622:              (news-delete-headers start)
        !           623:              (goto-char start)))))))
        !           624: 
        !           625: (defun news-show-all-headers ()
        !           626:   "Redisplay current news item with all original headers"
        !           627:   (interactive)
        !           628:   (let (news-ignored-headers)
        !           629:     (news-get-back)))
        !           630: 
        !           631: (defun news-delete-headers (pos)
        !           632:   (goto-char pos)
        !           633:   (and (stringp news-ignored-headers)
        !           634:        (while (re-search-forward news-ignored-headers nil t)
        !           635:         (beginning-of-line)
        !           636:         (delete-region (point)
        !           637:                        (progn (re-search-forward "\n[^ \t]")
        !           638:                               (forward-char -1)
        !           639:                               (point))))))
        !           640: 
        !           641: (defun news-exit ()
        !           642:   "Quit news reading session and update the newsrc file."
        !           643:   (interactive)
        !           644:   (if (y-or-n-p "Do you really wanna quit reading news ? ")
        !           645:       (progn (message "Updating .newsrc...")
        !           646:             (news-update-newsrc-file)
        !           647:             (news-write-certifications)
        !           648:             (message "Updating .newsrc... done")
        !           649:             (message "Now do some real work")
        !           650:             (and (fboundp 'bury-buffer) (bury-buffer (current-buffer)))
        !           651:             (switch-to-buffer news-buffer-save)
        !           652:             (setq news-user-group-list ()))
        !           653:     (message "")))
        !           654: 
        !           655: (defun news-update-newsrc-file ()
        !           656:   "Updates the newsrc file in the users home dir."
        !           657:   (let ((newsrcbuf (find-file-noselect
        !           658:                     (substitute-in-file-name news-startup-file)))
        !           659:        (tem news-user-group-list)
        !           660:        group)
        !           661:     (save-excursion
        !           662:       (if (not (null news-current-news-group))
        !           663:          (news-update-message-read news-current-news-group
        !           664:                                (cdar news-point-pdl)))
        !           665:       (switch-to-buffer newsrcbuf)
        !           666:       (while tem
        !           667:        (setq group (assoc (car tem)
        !           668:                           news-group-article-assoc))
        !           669:        (if (= (cadr (cadr group)) (caddr (cadr group)))
        !           670:            nil
        !           671:          (goto-char 0)
        !           672:          (if (search-forward (concat (car group) ": ") nil t)
        !           673:              (kill-line nil)
        !           674:            (insert (car group) ": \n") (backward-char 1))
        !           675:          (insert (int-to-string (car (cadr group))) "-"
        !           676:                  (int-to-string (cadr (cadr group)))))
        !           677:        (setq tem (cdr tem)))
        !           678:      (while news-unsubscribe-groups
        !           679:        (setq group (assoc (car news-unsubscribe-groups)
        !           680:                          news-group-article-assoc))
        !           681:        (goto-char 0)
        !           682:        (if (search-forward (concat (car group) ": ") nil t)
        !           683:           (progn
        !           684:              (backward-char 2)
        !           685:              (kill-line nil)
        !           686:              (insert "! " (int-to-string (car (cadr group)))
        !           687:                      "-" (int-to-string (cadr (cadr group))))))
        !           688:        (setq news-unsubscribe-groups (cdr news-unsubscribe-groups)))
        !           689:      (save-buffer)
        !           690:      (kill-buffer (current-buffer)))))
        !           691: 
        !           692: 
        !           693: (defun news-unsubscribe-group (group)
        !           694:   "Removes you from newgroup GROUP."
        !           695:   (interactive (list (completing-read  "Unsubscribe from group: "
        !           696:                                      news-group-article-assoc)))
        !           697:   (news-unsubscribe-internal group))
        !           698: 
        !           699: (defun news-unsubscribe-current-group ()
        !           700:   "Removes you from the newsgroup you are now reading."
        !           701:   (interactive)
        !           702:   (if (y-or-n-p "Do you really want to unsubscribe from this group ? ")
        !           703:       (news-unsubscribe-internal news-current-news-group)))
        !           704: 
        !           705: (defun news-unsubscribe-internal (group)
        !           706:   (let ((tem (assoc group news-group-article-assoc)))
        !           707:     (if tem
        !           708:        (progn
        !           709:          (setq news-unsubscribe-groups (cons group news-unsubscribe-groups))
        !           710:          (news-update-message-read group (cdar news-point-pdl))
        !           711:          (if (equal group news-current-news-group)
        !           712:              (news-next-group))
        !           713:          (message "Member-p of %s ==> nil" group))
        !           714:       (error "No such group: %s" group))))
        !           715: 
        !           716: (defun news-save-item-in-file (file)
        !           717:   "Save the current article that is being read by appending to a file."
        !           718:   (interactive "FSave item in file: ")
        !           719:   (append-to-file (point-min) (point-max) file))
        !           720: 
        !           721: (defun news-get-pruned-list-of-files (gp-list end-file-no)
        !           722:   "Given a news group it does an ls to give all files in the news group.
        !           723: The arg must be in slashified format."
        !           724:   (let
        !           725:       ((answer
        !           726:        (and
        !           727:         (not (and end-file-no
        !           728:                   (equal (news-set-current-certifiable)
        !           729:                     (news-group-certification gp-list))
        !           730:                   (setq news-list-of-files nil
        !           731:                         news-list-of-files-possibly-bogus t)))
        !           732:         (let* ((file-directory (concat news-path
        !           733:                                        (string-subst-char ?/ ?. gp-list)))
        !           734:                tem
        !           735:                (last-winner
        !           736:                 (and end-file-no
        !           737:                      (news-wins file-directory end-file-no)
        !           738:                      (news-find-first-or-last file-directory end-file-no 1))))
        !           739:           (setq news-list-of-files-possibly-bogus t news-list-of-files nil)
        !           740:           (if last-winner
        !           741:               (progn
        !           742:                 (setq news-list-of-files-possibly-bogus t
        !           743:                       news-current-group-end last-winner)
        !           744:                 (while (> last-winner end-file-no)
        !           745:                   (push last-winner news-list-of-files)
        !           746:                   (setq last-winner (1- last-winner)))
        !           747:                 news-list-of-files)
        !           748:             (if (not (file-directory-p file-directory))
        !           749:                 nil
        !           750:               (setq news-list-of-files
        !           751:                     (setq tem (directory-files file-directory)))
        !           752:               (while tem
        !           753:                 (if (or (not (string-match "^[0-9]*$" (car tem)))
        !           754:                                        ; dont get confused by directories that look like numbers
        !           755:                         (file-directory-p
        !           756:                          (concat file-directory "/" (car tem)))
        !           757:                         (<= (string-to-int (car tem)) end-file-no))
        !           758:                     (setq news-list-of-files
        !           759:                           (delq (car tem) news-list-of-files)))
        !           760:                 (setq tem (cdr tem)))
        !           761:               (if (null news-list-of-files)
        !           762:                   (progn (setq news-current-group-end 0)
        !           763:                          nil)
        !           764:                 (setq news-list-of-files
        !           765:                       (mapcar 'string-to-int news-list-of-files))
        !           766:                 (setq news-list-of-files (sort news-list-of-files '<))
        !           767:                 (setq news-current-group-end
        !           768:                       (elt news-list-of-files
        !           769:                            (1- (length news-list-of-files))))
        !           770:                 news-list-of-files)))))))
        !           771:     (or answer (progn (news-set-current-group-certification) nil))))
        !           772: 
        !           773: (defun news-read-files-into-buffer (group reversep)
        !           774:   (let* ((files-start-end (cadr (assoc group news-group-article-assoc)))
        !           775:         (start-file-no (car files-start-end))
        !           776:         (end-file-no (cadr files-start-end))
        !           777:         (buffer-read-only nil))
        !           778: 
        !           779:     (setq news-current-news-group group)
        !           780:     (setq news-current-message-number nil)
        !           781:     (setq news-current-group-end nil)
        !           782:     (news-set-mode-line)
        !           783:     (news-get-pruned-list-of-files group end-file-no)
        !           784:     (news-set-mode-line)
        !           785:     ;; should be a lot smarter than this if we have to move
        !           786:     ;; around correctly.
        !           787:     (setq news-point-pdl (list (cons (car files-start-end)
        !           788:                                     (cadr files-start-end))))
        !           789:     (if (null news-list-of-files)
        !           790:        (progn (erase-buffer)
        !           791:               (setq news-current-group-end end-file-no)
        !           792:               (setq news-current-group-begin end-file-no)
        !           793:               (setq news-current-message-number end-file-no)
        !           794:               (news-set-mode-line)
        !           795: ;             (message "No new articles in " group " group.")
        !           796:               nil)
        !           797:       (setq news-current-group-begin (car news-list-of-files))
        !           798:       (if reversep
        !           799:          (setq news-current-message-number news-current-group-end)
        !           800:        (if (> (car news-list-of-files) end-file-no)
        !           801:            (setcdr (car news-point-pdl) (car news-list-of-files)))
        !           802:        (setq news-current-message-number news-current-group-begin))
        !           803:       (news-set-message-counters)
        !           804:       (news-set-mode-line)
        !           805:       (news-read-in-file (concat news-path
        !           806:                                 (string-subst-char ?/ ?. group)
        !           807:                                 "/"
        !           808:                                 (int-to-string
        !           809:                                   news-current-message-number)))
        !           810:       (news-set-message-counters)
        !           811:       (news-set-mode-line)
        !           812:       t)))
        !           813: 
        !           814: 
        !           815: ;;; Replying and posting news items are done by these functions.
        !           816: ;;; imported from rmail and modified to work with rnews ...
        !           817: ;;; Mon Mar 25,1985 at 03:07:04 ads@mit-hermes.
        !           818: ;;; this is done so that rnews can operate independently from rmail.el and sendmail and
        !           819: ;;; dosen't have to autoload these functions.
        !           820: 
        !           821: ;;;>> Nuked by Mly to autoload those functions again, as the duplication of
        !           822: ;;;>>  code was making maintenance too difficult.
        !           823: 
        !           824: (defvar news-reply-mode-map () "Mode map used by news-reply.")
        !           825: 
        !           826: (or news-reply-mode-map
        !           827:     (progn (setq news-reply-mode-map (make-keymap))
        !           828:           (define-key news-reply-mode-map "\C-c?" 'describe-mode)
        !           829:           (define-key news-reply-mode-map "\C-ct" 'mail-to)
        !           830:           (define-key news-reply-mode-map "\C-cb" 'mail-bcc)
        !           831:           (define-key news-reply-mode-map "\C-cc" 'mail-cc)
        !           832:           (define-key news-reply-mode-map "\C-cs" 'mail-subject)
        !           833:           (define-key news-reply-mode-map "\C-cy" 'mail-yank-original)
        !           834:           (define-key news-reply-mode-map "\C-c\C-c" 'news-inews)
        !           835:           (define-key news-reply-mode-map "\C-c\C-s" 'news-inews)))
        !           836: 
        !           837: (defun news-reply-mode ()
        !           838:   "Major mode for editing news to be posted on netnews.
        !           839: Like Text Mode but with these additional commands:
        !           840: \\{news-reply-mode-map}"
        !           841:   (interactive)
        !           842:   ;; require...
        !           843:   (or (fboundp 'mail-setup) (load "sendmail"))
        !           844:   (kill-all-local-variables)
        !           845:   (make-local-variable 'mail-reply-buffer)
        !           846:   (setq mail-reply-buffer nil)
        !           847:   (set-syntax-table text-mode-syntax-table)
        !           848:   (use-local-map news-reply-mode-map)
        !           849:   (setq local-abbrev-table text-mode-abbrev-table)
        !           850:   (setq major-mode 'news-reply-mode)
        !           851:   (setq mode-name "News")
        !           852:   (make-local-variable 'paragraph-separate)
        !           853:   (make-local-variable 'paragraph-start)
        !           854:   (setq paragraph-start (concat "^" mail-header-separator "$\\|"
        !           855:                                paragraph-start))
        !           856:   (setq paragraph-separate (concat "^" mail-header-separator "$\\|"
        !           857:                                   paragraph-separate))
        !           858:   (run-hooks 'text-mode-hook 'news-reply-mode-hook))
        !           859: 
        !           860: (defun news-setup (to subject in-reply-to newsgroups replybuffer)
        !           861:   (setq mail-reply-buffer replybuffer)
        !           862:   (let ((mail-setup-hook nil))
        !           863:     (if (null to)
        !           864:        ;; this hack is needed so that inews wont be confused by 
        !           865:        ;; the fcc: and bcc: fields
        !           866:        (let ((mail-self-blind nil)
        !           867:              (mail-archive-file-name nil))
        !           868:          (mail-setup to subject in-reply-to nil replybuffer)
        !           869:          (beginning-of-line)
        !           870:          (kill-line 1)
        !           871:          (goto-char (point-max)))
        !           872:       (mail-setup to subject in-reply-to nil replybuffer))
        !           873:     (goto-char (point-max))
        !           874:     (if (let ((case-fold-search t))
        !           875:          (re-search-backward "^Subject:" (point-min) t))
        !           876:        (progn (beginning-of-line)
        !           877:               (insert "Newsgroups: " (or newsgroups "") "\n")
        !           878:               (if (not newsgroups)
        !           879:                   (backward-char 1)
        !           880:                 (goto-char (point-max)))))
        !           881:     (run-hooks 'news-setup-hook)))
        !           882:    
        !           883: (defun news-inews ()
        !           884:   "Send a news message using inews."
        !           885:   (interactive)
        !           886:   (let* (newsgroups subject
        !           887:         (case-fold-search nil))
        !           888:     (save-restriction
        !           889:       (goto-char (point-min))
        !           890:       (search-forward (concat "\n" mail-header-separator "\n"))
        !           891:       (narrow-to-region (point-min) (point))
        !           892:       (setq newsgroups (mail-fetch-field "newsgroups")
        !           893:            subject (mail-fetch-field "subject")))
        !           894:     (widen)
        !           895:     (goto-char (point-min))
        !           896:     (search-forward (concat "\n" mail-header-separator "\n"))
        !           897:     (message "Posting to the net...")
        !           898:     (call-process-region (point) (point-max) 
        !           899:                         news-inews-program nil 0 nil
        !           900:                         "-t" subject
        !           901:                         "-n" newsgroups)
        !           902:     (message "Posting to the net... done")
        !           903:     (set-buffer-modified-p nil)
        !           904:     (delete-windows-on (current-buffer))
        !           905:     (and (fboundp 'bury-buffer) (bury-buffer (current-buffer)))))
        !           906:                       
        !           907: (defun news-mail-reply ()
        !           908:   "Mail a reply to the author of the current article.
        !           909: While composing the reply, use \\[mail-yank-original] to yank the original message into it."
        !           910:   (interactive)
        !           911:   (let (from cc subject date to reply-to
        !           912:             (buffer (current-buffer)))
        !           913:     (save-restriction
        !           914:       (narrow-to-region (point-min) (progn (goto-line (point-min))
        !           915:                                           (search-forward "\n\n")
        !           916:                                           (- (point) 2)))
        !           917:       (setq from (mail-fetch-field "from")
        !           918:            subject (mail-fetch-field "subject")
        !           919:            reply-to (mail-fetch-field "reply-to")
        !           920:            date (mail-fetch-field "date"))
        !           921:       (setq to from)
        !           922:       (pop-to-buffer "*mail*")
        !           923:       (mail nil
        !           924:            (if reply-to reply-to to)
        !           925:            subject
        !           926:            (let ((stop-pos (string-match "  *at \\|  *@ \\| *(\\| *<" from)))
        !           927:              (concat (if stop-pos (substring from 0 stop-pos) from)
        !           928:                      "'s message of "
        !           929:                      date))
        !           930:            nil
        !           931:           buffer))))
        !           932:   
        !           933: (defun news-reply ()
        !           934:   "Compose and send a reply to the current article to the net.
        !           935: While composing the reply, use \\[mail-yank-original] to yank the original message into it."
        !           936:   (interactive)
        !           937:   (if (y-or-n-p "Are you sure you want to reply to the net? ")
        !           938:       (let (from cc subject date to newsgroups
        !           939:                 (buffer (current-buffer)))
        !           940:        (save-restriction
        !           941:          (narrow-to-region (point-min) (progn (search-forward "\n\n")
        !           942:                                               (- (point) 2)))
        !           943:          (setq from (mail-fetch-field "from")
        !           944:                subject (mail-fetch-field "subject")
        !           945:                date (mail-fetch-field "date")
        !           946:                newsgroups (mail-fetch-field "newsgroups"))
        !           947:          (pop-to-buffer "*post-news*")
        !           948:          (news-reply-mode)
        !           949:          (erase-buffer)
        !           950:          (news-setup
        !           951:           nil
        !           952:           subject
        !           953:           (let ((stop-pos (string-match "  *at \\|  *@ \\| *(\\| *<" from)))
        !           954:             (concat (if stop-pos (substring from 0 stop-pos) from)
        !           955:                     "'s message of "
        !           956:                     date))
        !           957:           newsgroups
        !           958:           buffer)))
        !           959:     (message "")))
        !           960: 
        !           961: (defun news-post-news ()
        !           962:   "Begin editing a news article to be posted."
        !           963:   (interactive)
        !           964:   (pop-to-buffer "*post-news*")
        !           965:   (news-reply-mode)
        !           966:   (erase-buffer)
        !           967:   (news-setup () () () () ()))
        !           968:  
        !           969: (defun news-add-news-group (gp)
        !           970:   "Add you to news group named GROUP (a string)."
        !           971: ; (completing-read ...)
        !           972:   (interactive "sAdd news group: ")
        !           973:   (let ((file-dir (concat news-path (string-subst-char ?/ ?. gp))))
        !           974:     (save-excursion
        !           975:      (if (null (assoc gp news-group-article-assoc))
        !           976:         (let ((newsrcbuf (find-file-noselect
        !           977:                           (substitute-in-file-name news-startup-file))))
        !           978:           (if (file-directory-p file-dir)
        !           979:               (progn
        !           980:                 (switch-to-buffer newsrcbuf)
        !           981:                 (end-of-buffer)
        !           982:                 (insert (string-subst-char ?. ?\ gp) ": 1-1\n")
        !           983:                 (save-buffer)
        !           984:                 (kill-buffer (current-buffer))
        !           985:                 (message "Added %s to your current list of newsgroups." gp))
        !           986:            (message "Newsgroup %s doesn't exist." gp)))
        !           987:        (message "Already subscribed to group %s." gp)))))
        !           988: 
        !           989: (defun news-mail-other-window ()
        !           990:   "Send mail in another window.
        !           991: While composing the message, use \\[mail-yank-original] to yank the
        !           992: original message into it."
        !           993:   (interactive)
        !           994:   (mail-other-window nil nil nil nil nil (current-buffer)))
        !           995: 
        !           996: (defun news-make-link-to-message (number newname)
        !           997:        "Forges a link to an rnews message numbered number (current if no arg)
        !           998: Good for hanging on to a message that might or might not be
        !           999: automatically deleted."
        !          1000:   (interactive "P
        !          1001: FName to link to message: ")
        !          1002:   (add-name-to-file
        !          1003:    (concat news-path
        !          1004:           (string-subst-char ?/ ?. news-current-news-group)
        !          1005:           "/" (if number
        !          1006:                   (prefix-numeric-value number)
        !          1007:                 news-current-message-number))
        !          1008:    newname))
        !          1009: 
        !          1010: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.