Sync up with gnus-5.6.41
[elisp/gnus.git-] / lisp / gnus-offline.el
1 ;;; gnus-offline.el --- To process mail & news at offline environment.
2
3 ;;; Copyright (C) 1998 Tatsuya Ichikawa
4 ;;;                    Yukihiro Ito
5 ;;; Author: Tatsuya Ichikawa <t-ichi@po.shiojiri.ne.jp>
6 ;;;         Yukihiro Ito <ito@rs.civil.tohoku.ac.jp>
7 ;;;         Hidekazu Nakamura <u90121@uis-inf.co.jp>
8
9 ;;; Version: 1.53
10 ;;; Keywords: news , mail , offline , gnus
11 ;;;
12 ;;; SPECIAL THANKS
13 ;;;    Keiichi Suzuki <kei-suzu@mail.wbs.or.jp>
14 ;;;    KORIYAMA Naohiro <kory@ba2.so-net.or.jp>
15 ;;;    Katsumi Yamaoka <yamaoka@jpl.org>
16
17 ;;; This file is part of Semi-gnus.
18 ;;;
19 ;;; GNU Emacs is free software; you can redistribute it and/or modify
20 ;;; it under the terms of the GNU General Public License as published by
21 ;;; the Free Software Foundation; either version 2, or (at your option)
22 ;;; any later version.
23
24 ;;; GNU Emacs is distributed in the hope that it will be useful,
25 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
26 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 ;;; GNU General Public License for more details.
28
29 ;;; You should have received a copy of the GNU General Public License
30 ;;; along with GNU Emacs; see the file COPYING.  If not, write to the
31 ;;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
32 ;;; Boston, MA 02111-1307, USA.
33 ;;;
34 ;;;; Commentary:
35 ;;; Note.
36 ;;;   This file works only with after version of Emacs 19.30.
37 ;;;   This file needs miee.el and SEMI.
38 ;;;   If you set gnus-offline-drafts-queue-type to 'agent , you don't need 
39 ;;;   miee.el
40 ;;;   You must use Semi-gnus 6.X.X.
41 ;;;
42 ;;; How to use.
43 ;;; put following code in you .emacs , after the setting of Gnus.
44 ;;;
45 ;;;  (setq gnus-offline-connect-program "/dir/program.exe")
46 ;;;  (setq gnus-offline-connect-program-arguments '("-a" "-b"))
47 ;;;  (setq gnus-offline-hangup-program "/dir/program")
48 ;;;  (setq gnus-offline-hangup-program-arguments '("-c" "-d"))
49 ;;;  (setq gnus-offline-mail-spool-directory "your-send-mail-spool-directory")
50 ;;;  (setq gnus-offline-news-spool-directory "your-send-news-spool-directory")
51 ;;;  (autoload 'gnus-offline-setup "gnus-offline")
52 ;;;  (add-hook 'gnus-load-hook 'gnus-offline-setup)
53 ;;;
54 ;;; If you use gnus-agent as souper , put gnus-agent setup code in you .gnus.el
55 ;;;
56 ;;; If you use nnspool as souper , put following code in your .emacs before
57 ;;; gnus-offline setting.
58 ;;;
59 ;;;  (load "miee")
60 ;;;  (message-offline-state)
61 ;;;
62 ;;; Then , put hang.exe in exec-path directory.
63 ;;;
64 ;;; In Gnus group buffer , type g to get all news and mail.
65 ;;; Then send mail and news in spool directory.
66 ;;;
67 ;;; Variables.
68 ;;;  gnus-offline-connect-program     ... Dialup program name.
69 ;;;  gnus-offline-connect-program-arguments
70 ;;;                                   ... List of dialup program arguments.
71 ;;;  gnus-offline-hangup-program      ... Program name that used hanup line.
72 ;;;  gnus-offline-hangup-program-arguments
73 ;;;                                   ... List of hangup program arguments.
74 ;;;  gnus-offline-mail-spool-directory... spool directory sending mail.
75 ;;;  gnus-offline-news-spool-directory... spool directory sending news.
76 ;;;  gnus-offline-mail-treat-environ  ... toggle sending mail online/offline.
77 ;;;  gnus-offline-articles-to-fetch   ... toggle fetch articles.
78 ;;;                                        both->mail->news->both...
79 ;;;  gnus-offline-load-hook           ... hook before gnus-offline load.
80 ;;;  gnus-offline-before-online-hook  ... hook before all online jobs.
81 ;;;  gnus-offline-after-online-hook   ... hook after all online jobs.
82 ;;;  gnus-offline-interval-time       ... Interval time to do all online jobs.
83 ;;;                                        (minutes)
84 ;;;  gnus-offline-MTA-type            ... Type of MTA.
85 ;;;                                        'smtp     ... Use smtp.el.
86 ;;;                                        'sendmail ... Use sendmail.el.
87 ;;;  gnus-offline-drafts-queue-type   ... Method type queuing message to spool.
88 ;;;                                        'miee means queue message to spool
89 ;;;                                         using miee.el.
90 ;;;                                        'agent means queue message to spool
91 ;;;                                         using gnus-agent.el.
92
93 ;;; Code:
94
95 (eval '(run-hooks 'gnus-offline-load-hook))
96
97 (require 'cl)
98 (require 'custom)
99 (require 'pop3-fma)
100
101 (unless (and (condition-case ()
102                  (require 'custom)
103                (file-error nil))
104              (fboundp 'defgroup)
105              (fboundp 'defcustom))
106   (require 'backquote)
107   (defmacro defgroup (&rest args))
108   (defmacro defcustom (symbol value &optional doc &rest args)
109     (` (defvar (, symbol) (, value) (, doc))))
110   )
111 (defgroup gnus-offline nil
112   "Offline backend utility for Gnus."
113   :prefix "gnus-offline-"
114   :group 'mail
115   :group 'news)
116
117 (defconst gnus-offline-version-number "1.53")
118 (defconst gnus-offline-codename
119 ;;  "You may be right"          ; 1.40
120 ;;  "Chilstie Lee"              ; 1.45
121 ;;  "Uptown Girl"               ; 1.46
122 ;;  "Easy money"                ; 1.47
123 ;;  "An Innocent man"           ; 1.48
124 ;;  "Tell her about it"         ; 1.50
125 ;;  "This night"                ; 1.51
126 ;;  "Movin'out"                 ; 1.52
127   "Longest night"               ; 1.53
128 ;;  "Leave a tender moment alone"
129 ;;  "Back in the U.S.S.R"
130 ;;  "Running on ice"
131 ;;  "This is the time"
132 ;;  "A matter of trust"
133 ;;  "Modern Woman"
134 ;;  "Code of silence"
135   )
136
137 (defconst gnus-offline-version (format "Gnus offline backend utiliy v%s"
138                                        gnus-offline-version-number))
139
140 (defcustom gnus-offline-connect-program nil
141   "*Program name to dial-up dialup network.
142 If nil , use auto-dialup if required to connect the Internet."
143   :group 'gnus-offline
144   :type 'string)
145
146 (defcustom gnus-offline-connect-program-arguments nil
147   "*Program arguments of gnus-offline-connect-program."
148   :group 'gnus-offline
149   :type '(repeat (string :tag "Argument")))
150
151 (defcustom gnus-offline-hangup-program nil
152   "*Program name to hang-up dialup network."
153   :group 'gnus-offline
154   :type 'string)
155
156 (defcustom gnus-offline-hangup-program-arguments nil
157   "*Program arguments of gnus-offline-hangup-program."
158   :group 'gnus-offline
159   :type '(repeat (string :tag "Argument")))
160
161 (defcustom gnus-offline-auto-hangup t
162   "*Whether dialup-network automatically hang up when all online jobs has done."
163   :group 'gnus-offline
164   :type 'boolean)
165
166 (defcustom gnus-offline-mail-spool-directory "~/News/mail.out"
167   "*Spool directory sending mail."
168   :group 'gnus-offline
169   :type 'directory)
170
171 (defcustom gnus-offline-news-spool-directory "~/News/news.out"
172   "*Spool directory sending news."
173   :group 'gnus-offline
174   :type 'directory)
175
176 (defcustom gnus-offline-load-hook nil
177   "*Hook to be run after the gnus-offline package has been loaded."
178   :group 'gnus-offline
179   :type 'hook)
180 (defcustom gnus-offline-before-online-hook nil
181   "*Hook to be run before all online jobs."
182   :group 'gnus-offline
183   :type 'hook)
184
185 (defcustom gnus-offline-after-online-hook nil
186   "*Hook to be run after all online jobs."
187   :group 'gnus-offline
188   :type 'hook)
189
190 (defcustom gnus-offline-mail-treat-environ 'offline
191   "*If online , gnus-offline send all mail under online environ.
192 If offline , gnus-offline send all mail temporary to spool dir."
193   :group 'gnus-offline
194   :type '(choice (const offline)
195                  (const online)))
196
197 (defcustom gnus-offline-articles-to-fetch 'both
198   "*If both , gnus-offline fetch mail and news articles.
199 If mail , gnus-offline only fetch mail articles.
200  If news , gnus-offline only fetch news articles."
201   :group 'gnus-offline
202   :type '(choice (const both)
203                  (const mail)
204                  (const news)))
205
206 (defcustom gnus-offline-interval-time 0
207   "*Interval time(minutes) to do online jobs.
208 If set to 0 , timer call is disabled."
209   :group 'gnus-offline
210   :type 'integer)
211
212 (defcustom gnus-offline-mail-group-level 1
213   "*Group level for mail group."
214   :group 'gnus-offline
215   :type 'integer)
216
217 (defcustom gnus-offline-MTA-type 'smtp
218   "*Type of MTA program.
219 smtp means use smtp.el.
220  sendmail means use sendmail.el."
221   :group 'gnus-offline
222   :type '(choice (const smtp)
223                  (const sendmail)))
224
225 (defcustom gnus-offline-drafts-queue-type 'agent
226   "*Type of to queue drafts method.
227 'miee means drafts are queued and sent by miee.el.
228 'agent means drafts are queued and sent by gnus-agent.el"
229   :group 'gnus-offline
230   :type '(choice (const miee)
231                  (const agent)))
232
233 (defcustom gnus-offline-after-empting-spool-hook nil
234   "*Hook to be run before empting spool."
235   :group 'gnus-offline
236   :type 'hook)
237
238 (defcustom gnus-offline-before-empting-spool-hook nil
239   "*Hook to be run after empting spool."
240   :group 'gnus-offline
241   :type 'hook)
242
243 (defcustom gnus-offline-dialup-function 'gnus-offline-connect-server
244   "*Function to dialup."
245   :group 'gnus-offline
246   :type 'function)
247
248 (defcustom gnus-offline-hangup-function 'gnus-offline-hangup-line
249   "*Function to hangup."
250   :group 'gnus-offline
251   :type 'function)
252
253 ;;; Internal variables.
254 (defvar gnus-offline-connected nil
255   "*If value is t , dialup line is connected status.
256 If value is nil , dialup line is disconnected status.")
257
258 (defvar gnus-offline-news-fetch-method nil
259   "*Method to fetch news articles.")
260
261 (defvar gnus-offline-mail-fetch-method nil
262   "*Method to fetch mail articles.")
263
264 (defvar gnus-offline-header-string
265   (format "%s - \"%s\""
266           gnus-offline-version
267           gnus-offline-codename)
268   "*Header string for gnus-offline.")
269
270 (defvar gnus-offline-auto-hangup-indicator "Hup"
271   "*Indicator whether auto hang up is enabled.")
272
273 (defvar gnus-offline-stored-group-level nil
274   "*Mail Group level before changing.")
275
276 (defvar gnus-offline-movemail-arguments nil
277   "*All command line arguments of exec-directory/movemail.")
278
279 ;;; Temporary variable:
280 (defvar string)
281 (defvar hdr)
282 (defvar str)
283 (defvar passwd)
284 (defvar num)
285 (defvar gnus-offline-map (make-sparse-keymap))
286
287 (autoload 'message-offline-state "miee"
288   "Set current status to offline state" t)
289 ;;
290 ;; mode-line control
291 (if (not (member 'gnus-offline-auto-hangup-indicator mode-line-format))
292     (progn
293       (delete "-%-" mode-line-format)
294       (setq-default mode-line-format
295                     (append mode-line-format
296                             (list "--" 'gnus-offline-auto-hangup-indicator
297                                   "-%-")))))
298 (put 'gnus-offline-set-unplugged-state 'menu-enable 'gnus-offline-connected)
299 (add-hook 'gnus-startup-hook 'gnus-offline-setup)
300 ;;; Functions
301 ;;
302 ;; Setting up...
303 ;;
304 (defun gnus-offline-setup ()
305   "*Initialize gnus-offline function"
306   (if (eq system-type 'windows-nt)
307       (define-process-argument-editing "/hang\\.exe\\'"
308         (lambda (x) (general-process-argument-editing-function
309                      x nil t t nil t t))))
310   ;; Initialize Internal Variable
311   (gnus-offline-initialize-variables)
312   
313   ;; Disable fetch mail when startup.
314   (gnus-offline-disable-fetch-mail)
315   
316   ;; To transfer Mail/News function.
317   (cond ((eq gnus-offline-mail-treat-environ 'offline)
318          ;; send mail under online environ.
319          (gnus-offline-set-offline-sendmail-function))
320         ((eq gnus-offline-mail-treat-environ 'online)
321          ;; send mail under offline environ.
322          (gnus-offline-set-online-sendmail-function)))
323
324   ;; always treat news under offline environ.
325   (gnus-offline-set-offline-post-news-function)
326   
327   ;; Spool directory setting - Miee
328   (if (eq gnus-offline-drafts-queue-type 'miee)
329       (progn
330         (if (not (file-exists-p gnus-offline-mail-spool-directory))
331             (make-directory gnus-offline-mail-spool-directory t))
332         (setq sendmail-to-spool-directory gnus-offline-mail-spool-directory)
333         (if (not (file-exists-p gnus-offline-news-spool-directory))
334             (make-directory gnus-offline-news-spool-directory t))
335         (setq news-spool-request-post-directory gnus-offline-news-spool-directory)))
336   
337   ;; When startup ... state is offline.
338   (setq gnus-nntp-service nil
339         gnus-nntp-server nil)
340   
341   ;; Setup needed Hooks
342   (gnus-offline-setup-needed-hooks))
343 ;;
344 ;;
345 (defun gnus-offline-initialize-variables ()
346   "*Initialize gnus-offline internal variable."
347   (if (featurep 'nnmail)
348       (setq gnus-offline-mail-fetch-method 'nnmail))
349   (if (featurep 'gnus-agent)
350       (setq gnus-offline-news-fetch-method 'nnagent))
351   (if (featurep 'nnspool)
352       (setq gnus-offline-news-fetch-method 'nnspool))
353   (if (eq gnus-offline-drafts-queue-type 'miee)
354       (load "miee"))
355   (gnus-offline-define-menu-and-key))
356 ;;
357 ;;
358 (defun gnus-offline-set-offline-sendmail-function ()
359   "*Initialize sendmail-function when unplugged status."
360   (if (eq gnus-offline-drafts-queue-type 'miee)
361       (setq message-send-mail-function 'sendmail-to-spool-in-gnspool-format)
362     (setq message-send-mail-function 'gnus-agent-send-mail)))
363 ;;
364 (defun gnus-offline-set-online-sendmail-function ()
365   "*Initialize sendmail-function when plugged status."
366   (if (eq gnus-offline-MTA-type 'smtp)
367       (setq message-send-mail-function 'message-send-mail-with-smtp)
368     (setq message-send-mail-function 'message-send-mail-with-sendmail)))
369 ;;
370 (defun gnus-offline-set-offline-post-news-function ()
371   "*Initialize sendnews-function when unplugged status."
372   (if (eq gnus-offline-drafts-queue-type 'miee)
373       (setq message-send-news-function 'gnspool-request-post)))
374 ;;
375 (defun gnus-offline-set-online-post-news-function ()
376   "*Initialize sendnews-function when plugged status."
377   (setq message-send-news-function 'message-send-news-with-gnus))
378 ;;
379 (defun gnus-offline-setup-needed-hooks ()
380   "*Initialize needed hooks for gnus-offline."
381   (add-hook 'gnus-group-mode-hook 'gnus-offline-processed-by-timer)
382   (add-hook 'gnus-after-getting-new-news-hook 'gnus-offline-after-get-new-news)
383   (add-hook 'gnus-after-getting-news-hook 'gnus-offline-after-get-new-news)
384   (if (eq gnus-offline-news-fetch-method 'nnspool)
385       (add-hook 'after-getting-news-hook 'gnus-offline-nnspool-hangup-line))
386   (add-hook 'message-send-hook 'gnus-offline-message-add-header)
387   (if (featurep 'pop3-fma)
388       (add-hook 'message-send-hook 'pop3-fma-message-add-header)))
389 ;;
390 ;; Get new news jobs. (gnus-agent and nnspool)
391 ;;
392 (defun gnus-offline-gnus-get-new-news (&optional arg)
393   "*Override function \"gnus-grou-get-new-news\"."
394   (interactive "P")
395   (run-hooks 'gnus-offline-before-online-hook)
396   (if (functionp gnus-offline-dialup-function)
397       (funcall gnus-offline-dialup-function))
398   (gnus-offline-get-new-news-function)
399   (gnus-group-get-new-news arg))
400
401 ;;
402 ;; dialup...
403 ;;
404 (defun gnus-offline-connect-server ()
405   "*Dialup function."
406   ;; Dialup if gnus-offline-connect-program is specified
407   (if (stringp gnus-offline-connect-program)
408       (progn
409         (message "Dialing ...")
410         (apply 'call-process gnus-offline-connect-program nil nil nil
411                gnus-offline-connect-program-arguments)
412         (sleep-for 1)
413         (message "Dialing ... done."))))
414
415 ;;
416 ;; Jobs before get new news , send mail and post news.
417 ;;
418 (defun gnus-offline-get-new-news-function ()
419   "*Prepare to get new news/mail."
420   ;; Set mail group level
421   (if (eq gnus-offline-articles-to-fetch 'mail)
422       (gnus-offline-set-mail-group-level gnus-offline-mail-group-level))
423
424   ;; Re initialize internal variable...if failed.
425   (if (or (not gnus-offline-mail-fetch-method)
426           (not gnus-offline-news-fetch-method))
427       (gnus-offline-initialize-variables))
428
429   ;; Set to online environ.
430   (setq gnus-offline-connected t)
431
432   ;; Set send mail/news functions to online functions.
433   (gnus-offline-set-online-sendmail-function)
434   (gnus-offline-set-online-post-news-function)
435   (message "Set to online status.")
436
437   ;; fetch only news
438   (if (eq gnus-offline-articles-to-fetch 'news)
439       (gnus-offline-disable-fetch-mail))
440
441   ;; fetch both mail and news. or Only mail.
442   (gnus-offline-enable-fetch-news)
443   (if (memq gnus-offline-articles-to-fetch '(both mail))
444       (gnus-offline-enable-fetch-mail))
445
446   ;; fetch only mail for gnus-agent
447   (if (eq gnus-offline-news-fetch-method 'nnagent)
448       (if (eq gnus-offline-articles-to-fetch 'mail)
449           (setq gnus-agent-handle-level gnus-offline-mail-group-level))))
450
451 ;;
452 ;; Change mail group level to handle only mail.
453 ;;
454 (defun gnus-offline-set-mail-group-level (level)
455   "*Set nnm* group level."
456   (switch-to-buffer gnus-group-buffer)
457   (goto-char (point-min))
458   
459   ;; Save current level
460   (if (not gnus-offline-stored-group-level)
461       (while (re-search-forward " nnm" nil t)
462         (setq gnus-offline-stored-group-level
463               (append gnus-offline-stored-group-level
464                       (list (gnus-group-group-level)))))
465     (forward-line 1)
466     (beginning-of-line))
467   ;;
468   (goto-char (point-min))
469   (while (re-search-forward " nnm" nil t)
470     (gnus-group-set-current-level 1 level)
471     (forward-line 1)
472     (beginning-of-line))
473   t)
474 ;;
475 ;; Restore mail group level
476 ;;
477 (defun gnus-offline-restore-mail-group-level ()
478   "*Restore nnm* group level."
479   (switch-to-buffer gnus-group-buffer)
480   (goto-char (point-min))
481   (setq num 0)
482   (while (re-search-forward " nnm" nil t)
483     (gnus-group-set-current-level 1 (nth num gnus-offline-stored-group-level))
484     (forward-line 1)
485     (setq num (+ num 1))
486     (beginning-of-line)))
487 ;;
488 ;; Jobs after getting new news.
489 ;;
490 (defun gnus-offline-after-get-new-news ()
491   "*After getting news and mail jobs."
492   (if (memq gnus-offline-articles-to-fetch '(both mail))
493       (progn
494         ;; Mail/both
495         ;; send mail/news in spool
496         (gnus-offline-empting-spool)
497         (if (eq gnus-offline-articles-to-fetch 'mail)
498             (progn
499               ;; Send only mail and hang up...
500               (if (and gnus-offline-connected
501                        gnus-offline-auto-hangup)
502                   (gnus-offline-set-unplugged-state))
503               ;; Disable fetch mail.
504               (gnus-offline-disable-fetch-mail)
505               (gnus-offline-after-jobs-done)))))
506   
507   ;; News/Both
508   (if (memq gnus-offline-articles-to-fetch '(both news))
509       (progn
510         (if gnus-offline-connected
511             (progn
512               (if (eq gnus-offline-news-fetch-method 'nnagent)
513                   (progn
514                     ;; Get New News (gnus-agent)
515                     (gnus-agent-toggle-plugged t)
516
517                     ;; fetch articles
518                     (gnus-agent-fetch-session)
519
520                     ;; Hang Up line. then set to offline status.
521                     (if (and gnus-offline-connected
522                              gnus-offline-auto-hangup)
523                         (gnus-offline-set-unplugged-state))
524
525                     ;; All online jobs has done.
526                     (gnus-offline-after-jobs-done)))
527               (if (eq gnus-offline-news-fetch-method 'nnspool)
528                   ;; Get New News (nnspool)
529                   (gnspool-get-news)))))))
530 ;;
531 ;; Disable fetch mail
532 ;;
533 (defun gnus-offline-disable-fetch-mail ()
534   "*Set do not fetch mail."
535   (if (eq gnus-offline-mail-fetch-method 'nnmail)
536       (setq nnmail-spool-file nil)))
537 ;;
538 ;; Enable fetch mail
539 ;;
540 (defun gnus-offline-enable-fetch-mail ()
541   "*Set to fetch mail."
542   (if (eq gnus-offline-mail-fetch-method 'nnmail)
543       (progn
544         (setq gnus-offline-mail-fetch-method 'nnmail)
545         (setq nnmail-movemail-program 'pop3-fma-movemail)
546         (setq nnmail-spool-file (append
547                                  pop3-fma-local-spool-file-alist
548                                  (mapcar
549                                   (lambda (spool)
550                                     (car spool))
551                                   pop3-fma-spool-file-alist))))))
552 ;;
553 ;; Enable fetch news
554 ;;
555 (defun gnus-offline-enable-fetch-news ()
556   "*Set to fetch news."
557   (if (eq gnus-offline-news-fetch-method 'nnagent)
558       (progn
559         (setq gnus-agent-handle-level gnus-level-subscribed)
560         (gnus-agent-toggle-plugged t))))
561 \f
562 ;;
563 ;; Add your custom header.
564 ;;
565 (defun gnus-offline-add-custom-header (header string)
566   "*Add X-Gnus-Offline-Backend header to Mail/News message."
567   (let ((delimline
568          (progn (goto-char (point-min))
569                 (re-search-forward
570                  (concat "^" (regexp-quote mail-header-separator) "\n"))
571                 (point-marker))))
572     (goto-char (point-min))
573     (or (re-search-forward (concat "^" header) delimline t)
574         (progn
575           (goto-char delimline)
576           (forward-line -1)
577           (beginning-of-line)
578           (setq hdr (concat header " "))
579           (setq str (concat hdr string))
580           (setq hdr (concat str "\n"))
581           (insert-string hdr)))))
582 ;;
583 ;; Add X-Offline-Backend header.
584 ;;
585 (defun gnus-offline-message-add-header ()
586   "*Add X-Gnus-Offline-Backend header to Mail/News message."
587   (if (eq gnus-offline-mail-treat-environ 'offline)
588       (progn
589         (if (eq gnus-offline-news-fetch-method 'nnagent)
590             (setq str (format "\n                        with %s" nnagent-version)
591                   string (concat gnus-offline-header-string str))
592           (setq str (format "\n                        with %s" nnspool-version)
593                 string (concat gnus-offline-header-string str)))
594         (gnus-offline-add-custom-header "X-Gnus-Offline-Backend:" string))))
595   
596 \f
597 ;;
598 ;; Toggle plugged/unplugged
599 ;;
600 (defun gnus-offline-toggle-plugged (plugged)
601   "*Override function \"Jj\" - gnus-agent-toggle-plugged."
602   (interactive (list (not gnus-offline-connected)))
603   (if plugged
604       (progn
605         (setq gnus-offline-connected plugged)
606         (gnus-agent-toggle-plugged plugged)
607         ;; Set send mail/news function to offline functions.
608         (gnus-offline-set-online-sendmail-function)
609         (gnus-offline-set-online-post-news-function))
610     ;; Set to offline status
611     (gnus-offline-set-unplugged-state)))
612 ;;
613 ;; Function of hang up line.
614 ;;
615 (defun gnus-offline-set-unplugged-state ()
616   "*Set to unplugged state."
617   (interactive)
618   ;; Hang Up Line.
619   (if (functionp gnus-offline-hangup-function)
620       (funcall gnus-offline-hangup-function))
621   (setq gnus-offline-connected nil)
622   (gnus-agent-toggle-plugged nil)
623
624   ;; Set send mail/news function to offline functions.
625   (gnus-offline-set-offline-sendmail-function)
626   (gnus-offline-set-offline-post-news-function)
627   ;;
628   (setenv "MAILHOST" nil))
629 ;;
630 ;; Hangup line function 
631 ;;
632 (defun gnus-offline-hangup-line ()
633   "*Hangup line function."
634   (message "Hang up line ... ")
635   (if (stringp gnus-offline-hangup-program)
636       (apply 'start-process "hup" nil gnus-offline-hangup-program
637              gnus-offline-hangup-program-arguments))
638   (message "Hang up line ... done."))
639 ;;
640 ;; Hang Up line routine whe using nnspool
641 ;;
642 (defun gnus-offline-nnspool-hangup-line ()
643   (if (and gnus-offline-connected
644            gnus-offline-auto-hangup)
645       (gnus-offline-set-unplugged-state))
646   (gnus-offline-after-jobs-done))
647 ;;
648 ;; Function of all jobs has done.
649 ;;
650 (defun gnus-offline-after-jobs-done ()
651   "*Jobs after all online jobs."
652   (run-hooks 'gnus-offline-after-online-hook)
653   (if (eq gnus-offline-articles-to-fetch 'mail)
654       (gnus-offline-restore-mail-group-level))
655   (if (eq gnus-offline-news-fetch-method 'nnagent)
656       (gnus-offline-agent-expire))
657   (ding)
658   (message "All online jobs have done."))
659
660 \f
661 ;;
662 ;; Toggle auto hang up
663 ;;
664 (defun gnus-offline-toggle-auto-hangup ()
665   "*Toggle auto hangup flag."
666   (interactive)
667   (setq string "Auto hang up logic")
668   (if gnus-offline-auto-hangup
669       (progn
670         (setq gnus-offline-auto-hangup nil
671               gnus-offline-auto-hangup-indicator "Con"
672               str "disabled."))
673     (setq gnus-offline-auto-hangup t
674           gnus-offline-auto-hangup-indicator "Hup"
675           str "enabled."))
676   (message (format "%s %s" string str)))
677 ;;
678 ;; Toggle offline/online to send mail.
679 ;;
680 (defun gnus-offline-toggle-on/off-send-mail ()
681   "*Toggel online/offline sendmail."
682   (interactive)
683   (if (eq gnus-offline-mail-treat-environ 'offline)
684       (progn
685         ;; Sending mail under online environ.
686         (gnus-offline-set-online-sendmail-function)
687         (setq gnus-offline-mail-treat-environ 'online)
688         (message "Sending mail immidiately."))
689     ;; Sending mail under offline environ.
690     (gnus-offline-set-offline-sendmail-function)
691     (setq gnus-offline-mail-treat-environ 'offline)
692     (message "Sending mail temporary to spool directory.")))
693 ;;
694 ;; Toggle articles to fetch ... both -> mail -> news -> both
695 ;;
696 (defun gnus-offline-toggle-articles-to-fetch ()
697   "*Set articles to fetch... both(Mail/News) -> mail only -> News only -> both"
698   (interactive)
699   (setq string "Articles fetch from server.")
700   (cond ((eq gnus-offline-articles-to-fetch 'both)
701          (setq gnus-offline-articles-to-fetch 'mail
702                str "Only Mail"))
703         ((eq gnus-offline-articles-to-fetch 'mail)
704            (setq gnus-offline-articles-to-fetch 'news
705                  str "Only News"))
706         (t
707          (setq gnus-offline-articles-to-fetch 'both
708                str "Mail/News both")))
709   (message (format "%s %s" string str)))
710 ;;
711 ;; Toggle movemail program pop3.el -> movemail -> pop3.el
712 ;;
713 (defun gnus-offline-toggle-movemail-program ()
714   "*Toggle movemail program movemail -> pop3.el -> movemail ->..."
715   (interactive)
716   (setq string "Set nnmail-movemail-program")
717   (cond ((eq pop3-fma-movemail-type 'lisp)
718          (setq pop3-fma-movemail-type 'exe
719                str "to movemail"))
720         (t
721          (setq pop3-fma-movemail-type 'lisp
722                str "to pop3.el")))
723   (message (format "%s %s" string str)))
724 ;;
725 ;; Send mail and Post news using Miee or gnus-agent.
726 ;;
727 (defun gnus-offline-empting-spool ()
728   "*Send all drafts on queue."
729   (run-hooks 'gnus-offline-before-empting-spool-hook)
730   (if (eq gnus-offline-drafts-queue-type 'miee)
731       ;; Send queued message by miee.el.
732       (progn
733         (if (eq gnus-offline-mail-treat-environ 'offline)
734             (progn
735               (message "Sending mails in spool ...")
736               ;; Using miee to send mail.
737               (mail-spool-send)
738               (message "Sending mails in spool ... done.")))
739         (message "Posting news in spool ...")
740         ;; Using miee to post news.
741         (if (and (not (stringp msspool-news-server))
742                  (not msspool-news-service))
743             (progn
744               (setq msspool-news-server (nth 1 gnus-select-method))
745               (setq msspool-news-service 119)))
746         (news-spool-post)
747         (message "Posting news in spool ... done."))
748     ;; Send queued message by gnus-agent
749     (message "Sending messages in spool ...")
750     (gnus-group-send-drafts)
751     (message "Sending messages in spool ... done."))
752   ;;
753   (run-hooks 'gnus-offline-after-empting-spool-hook))
754 ;;
755 ;; Set interval time
756 ;;
757 (defun gnus-offline-set-interval-time ()
758   "*Set interval time for gnus-daemon."
759   (interactive)
760   (setq gnus-offline-interval-time
761         (string-to-int (read-from-minibuffer
762                         (format "Interval time (now %s minutes) : "
763                                 gnus-offline-interval-time)
764                         nil)))
765   (if (< gnus-offline-interval-time 2)
766       (progn
767         (message "Retrieving message logic by timer is disabled.")
768         (setq gnus-offline-interval-time 0))
769     (message (format "Interval time set to %d minutes" gnus-offline-interval-time)))
770   (gnus-offline-processed-by-timer))
771 ;;
772 ;; Expire articles using gnus-agent.
773 ;;
774 (defun gnus-offline-agent-expire ()
775   "*Expire expirable article on News group."
776   (interactive)
777   (gnus-agent-expire))
778 ;;
779 ;; Menu.
780 ;;
781 (defun gnus-offline-define-menu-and-key ()
782   "*Set key and menu."
783   (if (eq gnus-offline-drafts-queue-type 'miee)
784       (add-hook 'gnus-group-mode-hook 'gnus-offline-define-menu-on-miee)
785     (add-hook 'gnus-group-mode-hook 'gnus-offline-define-menu-on-agent))
786   (add-hook 'gnus-group-mode-hook
787             '(lambda ()
788                (local-set-key "\C-coh" 'gnus-offline-set-unplugged-state)
789                (local-set-key "\C-com" 'gnus-offline-toggle-movemail-program)
790                (local-set-key "\C-cof" 'gnus-offline-toggle-articles-to-fetch)
791                (local-set-key "\C-coo" 'gnus-offline-toggle-on/off-send-mail)
792                (local-set-key "\C-cox" 'gnus-offline-toggle-auto-hangup)
793                (local-set-key "\C-cos" 'gnus-offline-set-interval-time)
794                (substitute-key-definition
795                 'gnus-group-get-new-news 'gnus-offline-gnus-get-new-news
796                 gnus-group-mode-map)
797                (if (eq gnus-offline-news-fetch-method 'nnagent)
798                    (progn
799                      (substitute-key-definition
800                       'gnus-agent-toggle-plugged 'gnus-offline-toggle-plugged
801                       gnus-agent-group-mode-map)
802                      (local-set-key "\C-coe" 'gnus-offline-agent-expire)))))
803   (if (eq gnus-offline-news-fetch-method 'nnagent)
804       (add-hook 'gnus-summary-mode-hook
805                 '(lambda ()
806                    (substitute-key-definition
807                     'gnus-agent-toggle-plugged 'gnus-offline-toggle-plugged
808                     gnus-agent-summary-mode-map)))))
809
810 (defun gnus-offline-define-menu-on-miee ()
811   "*Set menu bar on MIEE menu."
812   (global-set-key
813    [menu-bar
814     miee
815     gnus-offline-hup-separator]
816    '("--"))
817
818   (global-set-key
819    [menu-bar
820     miee
821     gnus-offline]
822    (cons "Gnus Offline Utility"
823          (make-sparse-keymap "Gnus Offline Utiliry")))
824   
825   (if (featurep 'pop3-fma)
826       (global-set-key
827        [menu-bar
828         miee
829         gnus-offline
830         gnus-offline-toggle-movemail-program]
831        '("Toggle movemail program" .
832          gnus-offline-toggle-movemail-program)))
833   
834   (global-set-key
835    [menu-bar
836     miee
837     gnus-offline
838     gnus-offline-toggle-articles-to-fetch]
839    '("Toggle articles to fetch" .
840      gnus-offline-toggle-articles-to-fetch))
841   
842   (global-set-key
843    [menu-bar
844     miee
845     gnus-offline
846     gnus-offline-toggle-on/off-send-mail]
847    '("Toggle online/offline send mail" .
848      gnus-offline-toggle-on/off-send-mail))
849   
850   (global-set-key
851    [menu-bar
852     miee
853     gnus-offline
854     gnus-offline-toggle-auto-hangup]
855    '("Toggle auto hang up" . gnus-offline-toggle-auto-hangup))
856   
857   (global-set-key
858    [menu-bar
859     miee
860     gnus-offline
861     gnus-offline-expire-separator]
862    '("--"))
863   
864   (if (eq gnus-offline-news-fetch-method 'nnagent)
865       (global-set-key
866        [menu-bar
867         miee
868         gnus-offline
869         gnus-offline-agent-expire]
870        '("Expire articles" . gnus-offline-agent-expire)))
871   
872   (global-set-key
873    [menu-bar
874     miee
875     gnus-offline
876     gnus-offline-set-interval-time]
877    '("Set interval time." . gnus-offline-set-interval-time))
878   
879   (global-set-key
880    [menu-bar
881     miee
882     gnus-offline
883     gnus-offline-hup-separator]
884    '("--"))
885   
886   (global-set-key
887    [menu-bar
888     miee
889     gnus-offline
890     gnus-offline-set-unplugged-state]
891    '("Hang Up Line." . gnus-offline-set-unplugged-state)))
892 ;;
893 ;; define menu without miee.
894 ;;
895 (defun gnus-offline-define-menu-on-agent ()
896   "*Set menu bar on OFFLINE menu."
897   (define-key-after
898     (lookup-key global-map [menu-bar])
899     [offline]
900     (cons "Offline" (make-sparse-keymap "Offline"))
901     'help)               ;; Actually this adds before "Help".
902
903   (if (featurep 'pop3-fma)
904       (global-set-key
905        [menu-bar
906         offline
907         gnus-offline-toggle-movemail-program]
908        '("Toggle movemail program" . gnus-offline-toggle-movemail-program)))
909   
910   (global-set-key
911    [menu-bar
912     offline
913     gnus-offline-toggle-articles-to-fetch]
914    '("Toggle articles to fetch" . gnus-offline-toggle-articles-to-fetch))
915   
916   (global-set-key
917    [menu-bar
918     offline
919     gnus-offline-toggle-on/off-send-mail]
920    '("Toggle online/offline send mail" . gnus-offline-toggle-on/off-send-mail))
921   
922   (global-set-key
923    [menu-bar
924     offline
925     gnus-offline-toggle-auto-hangup]
926    '("Toggle auto hang up" . gnus-offline-toggle-auto-hangup))
927   
928   (global-set-key
929    [menu-bar
930     offline
931     gnus-offline-separator]
932    '("--"))
933   
934   (if (eq gnus-offline-news-fetch-method 'nnagent)
935       (progn
936         (global-set-key
937          [menu-bar
938           offline
939           gnus-offline-agent-expire]
940          '("Expire articles" . gnus-offline-agent-expire))))
941   
942   (global-set-key
943    [menu-bar
944     offline
945     gnus-offline-set-interval-time]
946    '("Set interval time." . gnus-offline-set-interval-time))
947   
948   (global-set-key
949    [menu-bar
950     offline
951     gnus-offline-hup-separator]
952    '("--"))
953   
954   (global-set-key
955    [menu-bar
956     offline
957     gnus-offline-set-unplugged-state]
958    '("Hang Up Line." . gnus-offline-set-unplugged-state)))
959 \f
960 ;;
961 ;; Timer Function
962 (defun gnus-offline-processed-by-timer ()
963   "*Set timer interval."
964   (if (and (> gnus-offline-interval-time 0)
965            (not gnus-offline-connected))
966       ;; Timer call
967       (gnus-demon-add-handler 'gnus-offline-gnus-get-new-news
968                               gnus-offline-interval-time
969                               gnus-offline-interval-time))
970   (if (= gnus-offline-interval-time 0)
971       (gnus-demon-remove-handler 'gnus-offline-gnus-get-new-news t)))
972 ;;
973 ;;
974 (provide 'gnus-offline)
975 ;;; gnus-offline.el ends here