1 ;;; nnsoup.el --- SOUP packet reading access for Gnus
2 ;; Copyright (C) 1995 Free Software Foundation, Inc.
4 ;; Author: Per Abrahamsen <abraham@iesd.auc.dk>
5 ;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
6 ;; Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
7 ;; Keywords: news, mail
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to
23 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
27 ;; For an overview of what the interface functions do, please see the
30 ;; For more information on SOUP, see the comments in the file
40 (defvar nnsoup-directory (expand-file-name "~/SOUP/")
41 "The name of the directory containing the unpacket SOUP packet.")
45 (defconst nnsoup-version "nnsoup 0.0"
48 (defconst nnsoup-areas-file (concat nnsoup-directory "AREAS"))
49 (defconst nnsoup-list-file (concat nnsoup-directory "LIST"))
50 (defconst nnsoup-gnus-file (concat nnsoup-directory "gnus.touched"))
52 (defvar nnsoup-current-group nil)
53 (defvar nnsoup-current-buffer nil)
54 (defvar nnsoup-status-string "")
55 (defvar nnsoup-group-alist nil)
56 (defvar nnsoup-buffer-alist nil)
57 (defconst nnsoup-areas-list nil)
59 ;;; Interface functions
61 (defun nnsoup-retrieve-headers (sequence &optional newsgroup server)
63 (set-buffer nntp-server-buffer)
66 (number (length sequence))
67 beg article art-string start stop)
68 (nnsoup-possibly-change-group newsgroup)
70 (setq article (car sequence))
71 (setq art-string (nnsoup-article-string article))
72 (set-buffer nnsoup-current-buffer)
73 (if (or (search-forward art-string nil t)
75 (search-forward art-string nil t)))
80 (concat "^" rmail-unix-mail-delimiter) nil t)
82 (search-forward "\n\n" nil t)
83 (setq stop (1- (point)))
84 (set-buffer nntp-server-buffer)
85 (insert (format "221 %d Article retrieved.\n" article))
87 (insert-buffer-substring nnsoup-current-buffer start stop)
88 (goto-char (point-max))
90 (setq sequence (cdr sequence)))
92 ;; Fold continuation lines.
94 (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t)
95 (replace-match " " t t))
98 (defun nnsoup-open-server (host &optional service)
99 (setq nnsoup-status-string "")
100 (setq nnsoup-group-alist nil)
101 (nnheader-init-server-buffer))
103 (defun nnsoup-close-server (&optional server)
106 (defun nnsoup-server-opened (&optional server)
107 (and nntp-server-buffer
108 (buffer-name nntp-server-buffer)))
110 (defun nnsoup-status-message (&optional server)
111 nnsoup-status-string)
113 (defun nnsoup-request-article (article &optional newsgroup server buffer)
114 (nnsoup-possibly-change-group newsgroup)
115 (if (stringp article)
118 (set-buffer nnsoup-current-buffer)
120 (if (search-forward (nnsoup-article-string article) nil t)
122 (re-search-backward (concat "^" rmail-unix-mail-delimiter) nil t)
125 (or (and (re-search-forward
126 (concat "^" rmail-unix-mail-delimiter) nil t)
128 (goto-char (point-max)))
130 (let ((nntp-server-buffer (or buffer nntp-server-buffer)))
131 (set-buffer nntp-server-buffer)
133 (insert-buffer-substring nnsoup-current-buffer start stop)
134 (goto-char (point-min))
135 (while (looking-at "From ")
137 (insert "X-From-Line: ")
141 (defun nnsoup-request-group (group &optional server dont-check)
143 (nnsoup-possibly-change-group group)
144 (and (assoc group nnsoup-group-alist)
146 (set-buffer nntp-server-buffer)
150 (nnsoup-request-list)
151 (setq nnsoup-group-alist (nnmail-get-active))
152 (let ((active (assoc group nnsoup-group-alist)))
153 (insert (format "211 %d %d %d %s\n"
154 (1+ (- (cdr (car (cdr active)))
155 (car (car (cdr active)))))
156 (car (car (cdr active)))
157 (cdr (car (cdr active)))
161 (defun nnsoup-close-group (group &optional server)
164 (defun nnsoup-request-list (&optional server)
166 (if (or (file-exists-p nnsoup-gnus-file)
167 (not (file-directory-p nnsoup-directory)))
169 (write-region 1 1 nnsoup-gnus-file)
170 (setq nnsoup-areas-list nil
171 nnsoup-current-group nil
172 nnsoup-current-buffer nil
173 nnsoup-group-alist nil)
174 (let ((buffer (get-file-buffer nnsoup-areas-file))
175 (groups gnus-newsrc-assoc)
178 (setq group (car groups)
180 (if (eq (car (gnus-group-method-name (car group))) 'nnsoup)
182 (setcar (nthcdr 2 group) nil)
183 (setcar (nthcdr 3 group) nil))))
184 (gnus-make-hashtable-from-newsrc-alist)
186 (kill-buffer buffer))
187 (while nnsoup-buffer-alist
188 (setq buffer (nth 1 (car nnsoup-buffer-alist))
189 nnsoup-buffer-alist (cdr nnsoup-buffer-alist))
190 (if (buffer-name buffer)
191 (kill-buffer buffer))))))
192 (nnsoup-find-active))
194 (defun nnsoup-request-newgroups (date &optional server)
195 (nnsoup-request-list server))
197 (defun nnsoup-request-list-newsgroups (&optional server)
198 (nnmail-find-file nnsoup-newsgroups-file))
200 (defun nnsoup-request-post (&optional server)
201 (mail-send-and-exit nil))
203 (fset 'nnsoup-request-post-buffer 'nnmail-request-post-buffer)
205 (defun nnsoup-request-expire-articles (articles newsgroup &optional server force)
206 (setq nnsoup-status-string "nnsoup: expire not possible")
209 (defun nnsoup-request-move-article (article group server accept-form)
210 (setq nnsoup-status-string "nnsoup: move not possible")
213 (defun nnsoup-request-accept-article (group)
214 (setq nnsoup-status-string "nnsoup: accept not possible")
218 ;;; Internal functions.
220 (defun nnsoup-possibly-change-group (group)
221 (or (file-exists-p nnsoup-directory)
222 (make-directory (directory-file-name nnsoup-directory)))
223 (if (not nnsoup-group-alist)
225 (nnsoup-request-list)
226 (setq nnsoup-group-alist (nnmail-get-active))))
228 (if (and (equal group nnsoup-current-group)
229 (buffer-name nnsoup-current-buffer))
231 (if (setq inf (member group nnsoup-buffer-alist))
232 (setq nnsoup-current-buffer (nth 1 inf)))
233 (setq nnsoup-current-group group)
234 (if (not (buffer-name nnsoup-current-buffer))
236 (setq nnsoup-buffer-alist (delq inf nnsoup-buffer-alist))
241 (setq file (nnsoup-group-file group))
242 ;;;; (if (not (file-exists-p file))
243 ;;;; (write-region 1 1 file t 'nomesg))
244 (set-buffer (nnsoup-read-folder file))
245 (setq nnsoup-buffer-alist (cons (list group (current-buffer))
246 nnsoup-buffer-alist))))))
247 (setq nnsoup-current-group group))
249 (defun nnsoup-article-string (article)
250 (concat "\nX-Gnus-Article-Number: " (int-to-string article) " "))
252 (defun nnsoup-read-folder (file)
253 (nnsoup-request-list)
254 (setq nnsoup-group-alist (nnmail-get-active))
257 (setq nnsoup-current-buffer
258 (find-file-noselect file)))
259 (buffer-disable-undo (current-buffer))
260 (let ((delim (concat "^" rmail-unix-mail-delimiter))
263 (goto-char (point-min))
264 (while (re-search-forward delim nil t)
265 (setq start (match-beginning 0))
267 (setq end (or (and (re-search-forward delim nil t)
272 (narrow-to-region start end)
273 (nnmail-insert-lines)
275 (goto-char (point-min))
276 (if (search-forward "\n\n" nil t)
279 (insert (format "X-Gnus-Article-Number: %d %s\n"
280 number (current-time-string))))))
281 (setq number (1+ number))))
283 (set-buffer-modified-p nil)
286 (defun nnsoup-find-active ()
287 (set-buffer nntp-server-buffer)
289 (or nnsoup-areas-list (nnsoup-read-areas))
292 (let ((areas nnsoup-areas-list)
295 (setq area (car areas)
297 (insert (format "%s %s 1 y\n" (aref area 1) (aref area 4)))))
301 (defun nnsoup-read-areas ()
302 (setq nnsoup-areas-list (gnus-soup-parse-areas nnsoup-areas-file))
303 (let ((areas nnsoup-areas-list)
306 (setq area (car areas)
308 (aset area 4 (nnsoup-count-area area)))))
310 (defun nnsoup-count-area (area)
313 (nnsoup-count-mbox (concat nnsoup-directory (aref area 0) ".MSG")))))
315 (defun nnsoup-count-mbox (file)
316 (let ((delete (find-buffer-visiting file))
318 (delim (concat "^" rmail-unix-mail-delimiter)))
320 (set-buffer (find-file-noselect file))
321 (goto-char (point-min))
322 (while (re-search-forward delim nil t)
324 (if delete (kill-buffer delete))
327 (defun nnsoup-group-file (group)
328 (let ((areas nnsoup-areas-list)
331 (setq area (car areas)
333 (if (equal (aref area 1) group)
334 (setq result (concat nnsoup-directory (aref area 0) ".MSG"))))
339 ;;; nnsoup.el ends here