diff -uNr mutt-1.4.orig/ChangeLog.nntp mutt-1.4/ChangeLog.nntp --- mutt-1.4.orig/ChangeLog.nntp Thu Jan 1 01:00:00 1970 +++ mutt-1.4/ChangeLog.nntp Sun Nov 3 21:57:20 2002 @@ -0,0 +1,422 @@ +* Wed May 29 2002 Vsevolod Volkov +- update to 1.4 + +* Thu May 2 2002 Vsevolod Volkov +- update to 1.3.99 + +* Wed Mar 13 2002 Vsevolod Volkov +- update to 1.3.28 +- fixed SIGSEGV in , , , + functions +- fixed message about nntp reconnect +- fixed function using browser +- added support of Followup-To: poster +- added %n (new articles) in group_index_format +- posting articles without inews by default + +* Wed Jan 23 2002 Vsevolod Volkov +- update to 1.3.27 + +* Fri Jan 18 2002 Vsevolod Volkov +- update to 1.3.26 + +* Thu Jan 3 2002 Vsevolod Volkov +- update to 1.3.25 +- accelerated speed of access to news->newsgroups hash (by ) +- added default content disposition + +* Mon Dec 3 2001 Vsevolod Volkov +- update to 1.3.24 + +* Fri Nov 9 2001 Vsevolod Volkov +- update to 1.3.23.2 +- fixed segfault if mutt_conn_find() returns null + +* Wed Oct 31 2001 Vsevolod Volkov +- update to 1.3.23.1 +- added support of LISTGROUP command +- added support for servers with broken overview +- disabled function on news server +- fixed error storing bad authentication information + +* Wed Oct 10 2001 Vsevolod Volkov +- update to 1.3.23 +- fixed typo in buffy.c +- added substitution of %s parameter in $inews variable + +* Fri Aug 31 2001 Vsevolod Volkov +- update to 1.3.22.1 +- update to 1.3.22 + +* Thu Aug 23 2001 Vsevolod Volkov +- update to 1.3.21 + +* Wed Jul 25 2001 Vsevolod Volkov +- update to 1.3.20 +- removed 'server-hook', use 'account-hook' instead +- fixed error opening NNTP server without newsgroup using -f option + +* Fri Jun 8 2001 Vsevolod Volkov +- update to 1.3.19 + +* Sat May 5 2001 Vsevolod Volkov +- update to 1.3.18 +- fixed typo in nntp_attempt_features() +- changed algorithm of XGTITLE command testing +- disabled writing of NNTP password in debug file +- fixed reading and writing of long newsrc lines +- changed checking of last line while reading lines from server +- fixed possible buffer overrun in nntp_parse_newsrc_line() +- removed checking of XHDR command +- compare NNTP return codes without trailing space + +* Thu Mar 29 2001 Vsevolod Volkov +- update to 1.3.17 +- support for 'LIST NEWSGROUPS' command to read descriptions + +* Fri Mar 2 2001 Vsevolod Volkov +- update to 1.3.16 + +* Wed Feb 14 2001 Vsevolod Volkov +- update to 1.3.15 + +* Sun Jan 28 2001 Vsevolod Volkov +- update to 1.3.14 +- show number of tagged messages patch from Felix von Leitner + +* Sun Dec 31 2000 Vsevolod Volkov +- update to 1.3.13 + +* Sat Dec 30 2000 Vsevolod Volkov +- Fixed problem if last article in group is deleted + +* Fri Dec 22 2000 Vsevolod Volkov +- Fixed checking of XGTITLE command on some servers + +* Mon Dec 18 2000 Vsevolod Volkov +- Added \r in AUTHINFO commands + +* Mon Nov 27 2000 Vsevolod Volkov +- update to 1.3.12 + +* Wed Nov 1 2000 Vsevolod Volkov +- update to 1.3.11 +- fixed error opening newsgroup from mutt started with -g or -G + +* Thu Oct 12 2000 Vsevolod Volkov +- update to 1.3.10 +- hotkey 'G' (get-message) replaced with '^G' + +* Thu Sep 21 2000 Vsevolod Volkov +- update to 1.3.9 +- changed delay displaying error messages from 1 to 2 seconds +- fixed error compiling with nntp and without imap + +* Wed Sep 6 2000 Vsevolod Volkov +- fixed catchup in index +- fixed nntp_open_mailbox() + +* Sat Sep 2 2000 Vsevolod Volkov +- functions and disabled +- format of news mailbox names changed to url form +- option nntp_attempts removed +- option reconnect_news renamed to nntp_reconnect +- default value of nntp_poll changed from 30 to 60 +- error handling improved + +* Wed Aug 30 2000 Vsevolod Volkov +- update to 1.3.8 +- new option show_only_unread +- add newsgroup completion + +* Fri Aug 4 2000 Vsevolod Volkov +- update to 1.3.7 + +* Sat Jul 29 2000 Vsevolod Volkov +- update to 1.3.6 + +* Sun Jul 9 2000 Vsevolod Volkov +- update to 1.3.5 +- authentication code update +- fix for changing to newsgroup from mailbox with read messages +- socket code optimization + +* Wed Jun 21 2000 Vsevolod Volkov +- update to 1.3.4 + +* Wed Jun 14 2000 Vsevolod Volkov +- don't substitute current newsgroup with deleted new messages + +* Mon Jun 12 2000 Vsevolod Volkov +- update to 1.3.3 +- fix for substitution of newsgroup after reconnection +- fix for loading newsgroups with very long names +- fix for loading more than 32768 newsgroups + +* Wed May 24 2000 Vsevolod Volkov +- update to 1.3.2 + +* Sat May 20 2000 Vsevolod Volkov +- update to 1.3.1 + +* Fri May 12 2000 Vsevolod Volkov +- update to 1.3 + +* Thu May 11 2000 Vsevolod Volkov +- update to 1.2 + +* Thu May 4 2000 Vsevolod Volkov +- update to 1.1.14 + +* Sun Apr 23 2000 Vsevolod Volkov +- update to 1.1.12 + +* Fri Apr 7 2000 Vsevolod Volkov +- add substitution of newsgroup with new messages by default + +* Wed Apr 5 2000 Vsevolod Volkov +- add attach message from newsgroup +- add one-line help in newsreader mode +- disable 'change-dir' command in newsgroups browser +- add -G option + +* Tue Apr 4 2000 Vsevolod Volkov +- get default newsserver name from file /etc/nntpserver +- use case insensitive server names +- add print-style sequence %s to $newsrc +- add -g option + +* Sat Apr 1 2000 Vsevolod Volkov +- remove 'X-FTN-Origin' header processing + +* Thu Mar 30 2000 Vsevolod Volkov +- update to 1.1.11 +- update to 1.1.10 + +* Thu Mar 23 2000 Vsevolod Volkov +- fix mutt_select_newsserver() +- remove 'toggle-mode' function +- add 'change-newsgroup' function + +* Wed Mar 22 2000 Vsevolod Volkov +- fix server-hook + +* Tue Mar 21 2000 Vsevolod Volkov +- fix error 'bounce' function after 'post' +- add 'forward to newsgroup' function + +* Mon Mar 20 2000 Vsevolod Volkov +- 'forward' function works in newsreader mode +- add 'post' and 'followup' functions to pager and attachment menu +- fix active descriptions and allowed flag reload + +* Tue Mar 14 2000 Vsevolod Volkov +- update to 1.1.9 +- remove deleted newsgroups from list + +* Mon Mar 13 2000 Vsevolod Volkov +- update .newsrc in browser + +* Sun Mar 12 2000 Vsevolod Volkov +- reload .newsrc if externally modified +- fix active cache update + +* Sun Mar 5 2000 Vsevolod Volkov +- update to 1.1.8 + +* Sat Mar 4 2000 Vsevolod Volkov +- patch *.update_list_file is not required +- count lines when loading descriptions +- remove cache of unsubscribed newsgroups + +* Thu Mar 2 2000 Vsevolod Volkov +- load list of newsgroups from cache faster + +* Wed Mar 1 2000 Vsevolod Volkov +- update to 1.1.7 + +* Tue Feb 29 2000 Vsevolod Volkov +- fix unread messages in browser +- fix newsrc_gen_entries() + +* Mon Feb 28 2000 Vsevolod Volkov +- fix mutt_newsgroup_stat() +- fix nntp_delete_cache() +- fix nntp_get_status() +- fix check_children() +- fix nntp_fetch_headers() + +* Fri Feb 25 2000 Vsevolod Volkov +- update to 1.1.5 + +* Thu Feb 24 2000 Vsevolod Volkov +- fix updating new messages in cache + +* Mon Feb 21 2000 Vsevolod Volkov +- change default cache filenames +- fix updating new messages in cache + +* Fri Feb 18 2000 Vsevolod Volkov +- fix segmentation fault in news groups browser + +* Tue Feb 15 2000 Vsevolod Volkov +- update to 1.1.4 + +* Thu Feb 10 2000 Vsevolod Volkov +- update to 1.1.3 + +* Sun Jan 30 2000 Vsevolod Volkov +- add X-Comment-To editing +- add my_hdr support for Newsgroups:, Followup-To: and X-Comment-To: headers +- add variables $ask_followup_to and $ask_x_comment_to + +* Fri Jan 28 2000 Vsevolod Volkov +- update to 1.1.2 + +* Wed Aug 23 2000 Andrej Gritsenko +- nntp.c: inserted server hook when opened a newsgroup - for + difference between mail and news reader environment +- parse.c: `X-FTN-Origin:' processed for bad Fido gates + +* Tue Aug 22 2000 Vsevolod Volkov +- browser.c, complete.c: newsgroup completion patch + +* Wed Dec 22 1999 Andrej Gritsenko +- send.c: fixed bug with `Subject:' on followup + +* Sat Dec 18 1999 Andrej Gritsenko +- updated to 1.1.1 + +* Tue Oct 26 1999 Andrej Gritsenko +- updated to 1.1 + +* Mon Jun 14 1999 Andrej Gritsenko +- sendlib.c: use $mime_subject for news articles only + +* Fri Jun 11 1999 Edouard G. Parmelan +- nntp.c: bugfix with number of new articles + +* Thu Jun 10 1999 Andrej Gritsenko +- nntp.c: fixed incomplete creating of index file + +* Wed Jun 9 1999 Andrej Gritsenko +- updated to 0.96.3 +- doc/manual*: documentation updated + +* Sun Feb 21 1999 Andrej Gritsenko +- browser.c, newsrc.c, nntp.c: couple of fixes + +* Wed Dec 16 1998 Andrej Gritsenko +- curs_main.c, newsrc.c, nntp.c: fixes on number of read + articles + +* Tue Dec 15 1998 Vikas Agnihotri +- nntp.c: fix with gone cache files + +* Tue Dec 15 1998 Andrej Gritsenko +- newsrc.c, nntp.c: fixes on number of read articles + +* Mon Dec 14 1998 Andrej Gritsenko +- browser.c, newsrc.c, nntp.c, nntp.h: changed then simplified + nntp_parse_xover() + +* Mon Dec 14 1998 Vikas Agnihotri +- browser.c: cosmetic patch +- nntp.c: say "Fetching %s from server..." + +* Sun Dec 13 1998 Andrej Gritsenko +- commands.c, newsrc.c, nntp.c, nntp.h: don't save newsrc file + so often (noted by Vikas Agnihotri) + +* Sat Dec 12 1998 Andrej Gritsenko +- browser.c, functions.h, nntp.c, nntp.h: fixed incorrect first + active loading + +* Wed Dec 9 1998 Vikas Agnihotri +- nntp.c: fixed bug in `reconstruct-thread' function +- curs_main.c, nntp.c: fixed the bug in non-XOVER case of get + headers + +* Tue Dec 8 1998 Andrej Gritsenko +- nntp.c: fixed error in getting status of article + +* Tue Dec 8 1998 Vikas Agnihotri +- mutt.h, pattern.c: added `~w' search pattern + +* Tue Dec 8 1998 Andrej Gritsenko +- nntp.c: bugfix when get children + +* Tue Dec 8 1998 Vikas Agnihotri +- newsrc.c: bugfix in mutt_newsgroup_catchup() + +* Tue Dec 8 1998 Andrej Gritsenko +- browser.c: bugfix in _mutt_select_file() + +* Sat Dec 5 1998 Andrej Gritsenko +- browser.c, newsrc.c, nntp.c, nntp.h: fix the sorting of + newsgroups in browser (from Vikas Agnihotri) + +* Fri Dec 4 1998 Vikas Agnihotri +- OPS, curs_main.c, functions.h, nntp.c, nntp.h: new functions: + `get-children' and `reconstruct-thread' + +* Thu Dec 3 1998 Vikas Agnihotri +- OPS, curs_main.c, functions.h, nntp.c, nntp.h: new functions: + `get-message' and `get-parent' + +* Wed Dec 2 1998 Vikas Agnihotri +- OPS, compose.c, curs_main.c, functions.h, parse.c, send.c, + sendlib.c: added `Followup-To:' field editing + +* Wed Dec 2 1998 Vikas Agnihotri +- OPS, browser.c, functions.h: new `load-active' function + +* Tue Dec 1 1998 Andrej Gritsenko +- browser.c: added option for blank %s in $group_index_format +- hdrline.c, lib.c, mutt.h, parse.c: added %g and %W parameters + to $pager_format +- hook.c, newsrc.c, nntp.c, sendlib.c: some small bugfixes + +* Mon Nov 30 1998 Andrej Gritsenko +- send.c: bugfix in `Followup-To:' field + +* Sun Nov 29 1998 Vikas Agnihotri +- compose.c, lib.c, parse.c, protos.h: remove white spaces from + `Newsgroup:' field to prevent a unnecessary rejection of article + +* Sat Nov 28 1998 Vikas Agnihotri +- newsrc.c: fixed bug in catchup + +* Sat Nov 28 1998 Vikas Agnihotri +- browser.c: make indicator advance when (un)subscribe + +* Sat Nov 28 1998 Andrej Gritsenko +- newsrc.c: fixed segmentation fault in newsrc_update_line() + +* Sat Nov 28 1998 Andrej Gritsenko +- OPS, browser.c, functions.h, init.h, mutt.h, mx.c, newsrc.c, + nntp.c, nntp.h: corrected reading of newsrc file and added new + `catchup' function + +* Thu Nov 26 1998 Andrej Gritsenko +- browser.c, newsrc.c: implementation of `(un)subscribe-pattern' + functions from Vikas Agnihotri +- globals.h, init.h, nntp.h, nntp.c: added variable $nntp_poll + to avoid of polling newsserver on each keypressing + +* Thu Nov 26 1998 Andrej Gritsenko +- nntp.c, socket.c: fixed parsing of long XOVER lines +- send.c: removed silly ask for newsgroup name (noted by Vikas + Agnihotri) + +* Wed Nov 25 1998 +- commands.c: bugfix in mutt_update_list_file() + +* Wed Nov 25 1998 Andrej Gritsenko +- updated to mutt-0.94.17 +- init.c, nntp.c, nntp.h, parse.c, send.c: couple of bugfixes + from Vikas Agnihotri + +* Sat Nov 21 1998 Andrej Gritsenko +- [mutt-0.94.13] couple of files: pre-alpha version of patch, + partially based on code that written by Brandon Long diff -uNr mutt-1.4.orig/Makefile.am mutt-1.4/Makefile.am --- mutt-1.4.orig/Makefile.am Sun Nov 3 21:42:52 2002 +++ mutt-1.4/Makefile.am Sun Nov 3 21:57:20 2002 @@ -68,7 +68,8 @@ EXTRA_mutt_SOURCES = account.c md5c.c mutt_sasl.c mutt_socket.c mutt_ssl.c \ mutt_tunnel.c pop.c pop_auth.c pop_lib.c pgp.c pgpinvoke.c pgpkey.c \ pgplib.c sha1.c pgpmicalg.c gnupgparse.c resize.c dotlock.c remailer.c \ - browser.h mbyte.h remailer.h url.h mutt_ssl_nss.c pgppacket.c + browser.h mbyte.h remailer.h url.h mutt_ssl_nss.c pgppacket.c \ + nntp.c newsrc.c EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h account.h \ attach.h buffy.h charset.h compress.h copy.h dotlock.h functions.h \ @@ -77,6 +78,7 @@ mutt_regex.h mutt_sasl.h mutt_socket.h mutt_ssl.h mutt_tunnel.h \ mx.h pager.h pgp.h pop.h protos.h reldate.h rfc1524.h rfc2047.h \ rfc2231.h rfc822.h sha1.h sort.h mime.types VERSION prepare \ + nntp.h ChangeLog.nntp \ _regex.h OPS.MIX README.SECURITY remailer.c remailer.h browser.h \ mbyte.h lib.h extlib.c pgpewrap.c pgplib.h Muttrc.head Muttrc \ makedoc.c stamp-doc-rc README.SSL \ diff -uNr mutt-1.4.orig/Muttrc mutt-1.4/Muttrc --- mutt-1.4.orig/Muttrc Sun Nov 3 21:42:52 2002 +++ mutt-1.4/Muttrc Sun Nov 3 21:57:20 2002 @@ -185,6 +185,28 @@ # editing the body of an outgoing message. # # +# set ask_follow_up=no +# +# Name: ask_follow_up +# Type: boolean +# Default: no +# +# +# If set, Mutt will prompt you for follow-up groups before editing +# the body of an outgoing message. +# +# +# set ask_x_comment_to=no +# +# Name: ask_x_comment_to +# Type: boolean +# Default: no +# +# +# If set, Mutt will prompt you for x-comment-to field before editing +# the body of an outgoing message. +# +# # set attach_format="%u%D%I %t%4n %T%.40d%> [%.7m/%.10M, %.6e%?C?, %C?, %s] " # # Name: attach_format @@ -308,6 +330,17 @@ # bouncing messages. Postfix users may wish to unset this variable. # # +# set catchup_newsgroup=ask-yes +# +# Name: catchup_newsgroup +# Type: quadoption +# Default: ask-yes +# +# +# If this variable is set, Mutt will mark all articles in newsgroup +# as read when you quit the newsgroup (catchup newsgroup). +# +# # set charset="" # # Name: charset @@ -734,6 +767,19 @@ # resulting in two copies of the same email for you. # # +# set followup_to_poster=ask-yes +# +# Name: followup_to_poster +# Type: quadoption +# Default: ask-yes +# +# +# If this variable is set and the keyword "poster" is present in +# Followup-To header, follow-up to newsgroup function is not +# permitted. The message will be mailed to the submitter of the +# message via mail. +# +# # set force_name=no # # Name: force_name @@ -818,6 +864,28 @@ # "Franklin" to "Franklin, Steve". # # +# set group_index_format="%4C %M%N %5s %-45.45f %d" +# +# Name: group_index_format +# Type: string +# Default: "%4C %M%N %5s %-45.45f %d" +# +# +# This variable allows you to customize the newsgroup browser display to +# your personal taste. This string is similar to ``index_format'', but +# has its own set of printf()-like sequences: +# +# %C current newsgroup number +# %d description of newsgroup (becomes from server) +# %f newsgroup name +# %M - if newsgroup not allowed for direct post (moderated for example) +# %N N if newsgroup is new, u if unsubscribed, blank otherwise +# %n number of new articles in newsgroup +# %s number of unread articles in newsgroup +# %>X right justify the rest of the string and pad with character "X" +# %|X pad to the end of the line with character "X" +# +# # set hdrs=yes # # Name: hdrs @@ -1187,6 +1255,7 @@ # %E number of messages in current thread # %f entire From: line (address + real name) # %F author name, or recipient name if the message is from you +# %g newsgroup name (if compiled with nntp support) # %i message-id of the current message # %l number of lines in the message # %L If an address in the To or CC header field matches an address @@ -1204,6 +1273,7 @@ # %T the appropriate character from the $to_chars string # %u user (login) name of the author # %v first name of the author, or the recipient if the message is from you +# %W name of organization of author (`organization:' field) # %y `x-label:' field, if present # %Y `x-label' field, if present, and (1) not at part of a thread tree, # (2) at the top of a thread, or (3) `x-label' is different from @@ -1227,6 +1297,22 @@ # See also: ``$to_chars''. # # +# set inews="" +# +# Name: inews +# Type: path +# Default: "" +# +# +# If set, specifies the program and arguments used to deliver news posted +# by Mutt. Otherwise, mutt posts article using current connection to +# news server. The following printf-style sequence is understood: +# +# %s newsserver name +# +# Example: set inews="/usr/local/bin/inews -hS" +# +# # set ispell="/usr/bin/ispell" # # Name: ispell @@ -1496,6 +1582,18 @@ # be attached to the newly composed message if this option is set. # # +# set mime_subject=yes +# +# Name: mime_subject +# Type: boolean +# Default: yes +# +# +# If unset, 8-bit ``subject:'' line in article header will not be +# encoded according to RFC2047 to base64. This is useful when message +# is Usenet article, because MIME for news is nonstandard feature. +# +# # set mix_entry_format="%4n %c %-16s %a" # # Name: mix_entry_format @@ -1550,6 +1648,118 @@ # escape sequences see the section on ``$index_format''. # # +# set news_cache_dir="~/.mutt" +# +# Name: news_cache_dir +# Type: path +# Default: "~/.mutt" +# +# +# This variable pointing to directory where Mutt will save cached news +# articles headers in. If unset, headers will not be saved at all +# and will be reloaded each time when you enter to newsgroup. +# +# +# set news_server="" +# +# Name: news_server +# Type: string +# Default: "" +# +# +# This variable specifies domain name or address of NNTP server. It +# defaults to the newsserver specified in the environment variable +# $NNTPSERVER or contained in the file /etc/nntpserver. You can also +# specify username and an alternative port for each newsserver, ie: +# +# [nntp[s]://][username[:password]@]newsserver[:port] +# +# +# set newsrc="~/.newsrc" +# +# Name: newsrc +# Type: path +# Default: "~/.newsrc" +# +# +# The file, containing info about subscribed newsgroups - names and +# indexes of read articles. The following printf-style sequence +# is understood: +# +# %s newsserver name +# +# +# set nntp_context=1000 +# +# Name: nntp_context +# Type: number +# Default: 1000 +# +# +# This variable defines number of articles which will be in index when +# newsgroup entered. If active newsgroup have more articles than this +# number, oldest articles will be ignored. Also controls how many +# articles headers will be saved in cache when you quit newsgroup. +# +# +# set nntp_load_description=yes +# +# Name: nntp_load_description +# Type: boolean +# Default: yes +# +# +# This variable controls whether or not descriptions for each newsgroup +# must be loaded when newsgroup is added to list (first time list +# loading or new newsgroup adding). +# +# +# set nntp_user="" +# +# Name: nntp_user +# Type: string +# Default: "" +# +# +# Your login name on the NNTP server. If unset and NNTP server requires +# authentification, Mutt will prompt you for your account name when you +# connect to newsserver. +# +# +# set nntp_pass="" +# +# Name: nntp_pass +# Type: string +# Default: "" +# +# +# Your password for NNTP account. +# +# +# set nntp_poll=60 +# +# Name: nntp_poll +# Type: number +# Default: 60 +# +# +# The time in seconds until any operations on newsgroup except post new +# article will cause recheck for new news. If set to 0, Mutt will +# recheck newsgroup on each operation in index (stepping, read article, +# etc.). +# +# +# set nntp_reconnect=ask-yes +# +# Name: nntp_reconnect +# Type: quadoption +# Default: ask-yes +# +# +# Controls whether or not Mutt will try to reconnect to newsserver when +# connection lost. +# +# # set pager="builtin" # # Name: pager @@ -2293,6 +2503,19 @@ # string after the inclusion of a message which is being replied to. # # +# set post_moderated=ask-yes +# +# Name: post_moderated +# Type: quadoption +# Default: ask-yes +# +# +# If set to yes, Mutt will post article to newsgroup that have +# not permissions to posting (e.g. moderated). Note: if newsserver +# does not support posting to that newsgroup or totally read-only, that +# posting will not have an effect. +# +# # set postpone=ask-yes # # Name: postpone @@ -2802,6 +3025,41 @@ # shell from /etc/passwd is used. # # +# set save_unsubscribed=no +# +# Name: save_unsubscribed +# Type: boolean +# Default: no +# +# +# When set, info about unsubscribed newsgroups will be saved into +# ``newsrc'' file and into cache. +# +# +# set show_new_news=yes +# +# Name: show_new_news +# Type: boolean +# Default: yes +# +# +# If set, newsserver will be asked for new newsgroups on entering +# the browser. Otherwise, it will be done only once for a newsserver. +# Also controls whether or not number of new articles of subscribed +# newsgroups will be then checked. +# +# +# set show_only_unread=no +# +# Name: show_only_unread +# Type: boolean +# Default: no +# +# +# If set, only subscribed newsgroups that contain unread articles +# will be displayed in browser. +# +# # set sig_dashes=yes # # Name: sig_dashes @@ -3285,6 +3543,18 @@ # command. # # +# set use_ipv6=yes +# +# Name: use_ipv6 +# Type: boolean +# Default: yes +# +# +# When set, Mutt will look for IPv6 addresses of hosts it tries to +# contact. If this option is unset, Mutt will restrict itself to IPv4 addresses. +# Normally, the default should work. +# +# # set user_agent=yes # # Name: user_agent @@ -3387,3 +3657,14 @@ # messages to be sent. Exim users may wish to use this. # # +# set x_comment_to=no +# +# Name: x_comment_to +# Type: boolean +# Default: no +# +# +# If set, Mutt will add ``X-Comment-To:'' field (that contains full +# name of original article author) to article that followuped to newsgroup. +# +# diff -uNr mutt-1.4.orig/Muttrc.head mutt-1.4/Muttrc.head --- mutt-1.4.orig/Muttrc.head Sun Nov 3 21:42:51 2002 +++ mutt-1.4/Muttrc.head Thu Jan 1 01:00:00 1970 @@ -1,43 +0,0 @@ -# -# System configuration file for Mutt -# - -# default list of header fields to weed when displaying -# -ignore "from " received content- mime-version status x-status message-id -ignore sender references return-path lines - -# imitate the old search-body function -macro index \eb '/~b ' 'search in message bodies' - -# simulate the old url menu -macro index \cb |urlview\n 'call urlview to extract URLs out of a message' -macro pager \cb |urlview\n 'call urlview to extract URLs out of a message' - -# Show documentation when pressing F1 -macro generic "!less /usr/local/doc/mutt/manual.txt\n" "Show Mutt documentation" -macro index "!less /usr/local/doc/mutt/manual.txt\n" "Show Mutt documentation" -macro pager "!less /usr/local/doc/mutt/manual.txt\n" "Show Mutt documentation" - -# Use folders which match on \\.gz$ as gzipped folders: -# open-hook \\.gz$ "gzip -cd %f > %t" -# close-hook \\.gz$ "gzip -c %t > %f" -# append-hook \\.gz$ "gzip -c %t >> %f" - -# open-hook \\.bz2$ "bzip2 -cd %f > %t" -# close-hook \\.bz2$ "bzip2 -c %t > %f" -# append-hook \\.bz2$ "bzip2 -c %t >> %f" - -# If Mutt is unable to determine your site's domain name correctly, you can -# set the default here. -# -# set hostname=cs.hmc.edu - -# If your sendmail supports the -B8BITMIME flag, enable the following -# -# set use_8bitmime - -## -## More settings -## - diff -uNr mutt-1.4.orig/OPS mutt-1.4/OPS --- mutt-1.4.orig/OPS Sun Nov 3 21:42:52 2002 +++ mutt-1.4/OPS Sun Nov 3 21:57:20 2002 @@ -7,13 +7,15 @@ OP_BROWSER_NEW_FILE "select a new file in this directory" OP_BROWSER_VIEW_FILE "view file" OP_BROWSER_TELL "display the currently selected file's name" -OP_BROWSER_SUBSCRIBE "subscribe to current mailbox (IMAP only)" -OP_BROWSER_UNSUBSCRIBE "unsubscribe to current mailbox (IMAP only)" +OP_CATCHUP "mark all articles in newsgroup as read" +OP_BROWSER_SUBSCRIBE "subscribe to current (IMAP/NNTP only)" +OP_BROWSER_UNSUBSCRIBE "unsubscribe to current (IMAP/NNTP only)" OP_BROWSER_TOGGLE_LSUB "toggle view all/subscribed mailboxes (IMAP only)" OP_CHANGE_DIRECTORY "change directories" OP_CHECK_NEW "check mailboxes for new mail" OP_COMPOSE_ATTACH_FILE "attach a file(s) to this message" OP_COMPOSE_ATTACH_MESSAGE "attach message(s) to this message" +OP_COMPOSE_ATTACH_NEWS_MESSAGE "attach newsmessage(s) to this message" OP_COMPOSE_EDIT_BCC "edit the BCC list" OP_COMPOSE_EDIT_CC "edit the CC list" OP_COMPOSE_EDIT_DESCRIPTION "edit attachment description" @@ -24,7 +26,10 @@ OP_COMPOSE_EDIT_HEADERS "edit the message with headers" OP_COMPOSE_EDIT_MESSAGE "edit the message" OP_COMPOSE_EDIT_MIME "edit attachment using mailcap entry" +OP_COMPOSE_EDIT_NEWSGROUPS "edit the newsgroups list" OP_COMPOSE_EDIT_REPLY_TO "edit the Reply-To field" +OP_COMPOSE_EDIT_FOLLOWUP_TO "edit the Followup-To field" +OP_COMPOSE_EDIT_X_COMMENT_TO "edit the X-Comment-To field" OP_COMPOSE_EDIT_SUBJECT "edit the subject of this message" OP_COMPOSE_EDIT_TO "edit the TO list" OP_CREATE_MAILBOX "create a new mailbox (IMAP only)" @@ -84,8 +89,13 @@ OP_FILTER "filter attachment through a shell command" OP_FIRST_ENTRY "move to the first entry" OP_FLAG_MESSAGE "toggle a message's 'important' flag" +OP_FOLLOWUP "followup to newsgroup" +OP_FORWARD_TO_GROUP "forward to newsgroup" OP_FORWARD_MESSAGE "forward a message with comments" OP_GENERIC_SELECT_ENTRY "select the current entry" +OP_GET_CHILDREN "get all children of the current message" +OP_GET_MESSAGE "get message with Message-Id" +OP_GET_PARENT "get parent of the current message" OP_GROUP_REPLY "reply to all recipients" OP_HALF_DOWN "scroll down 1/2 page" OP_HALF_UP "scroll up 1/2 page" @@ -93,13 +103,17 @@ OP_JUMP "jump to an index number" OP_LAST_ENTRY "move to the last entry" OP_LIST_REPLY "reply to specified mailing list" +OP_LOAD_ACTIVE "load active file from NNTP server" OP_MACRO "execute a macro" OP_MAIL "compose a new mail message" OP_MAIN_BREAK_THREAD "break the thread in two" OP_MAIN_CHANGE_FOLDER "open a different folder" OP_MAIN_CHANGE_FOLDER_READONLY "open a different folder in read only mode" +OP_MAIN_CHANGE_GROUP "open a different newsgroup" +OP_MAIN_CHANGE_GROUP_READONLY "open a different newsgroup in read only mode" OP_MAIN_CLEAR_FLAG "clear a status flag from a message" OP_MAIN_DELETE_PATTERN "delete messages matching a pattern" +OP_RECONSTRUCT_THREAD "reconstruct thread containing current message" OP_MAIN_IMAP_FETCH "force retrieval of mail from IMAP server" OP_MAIN_FETCH_MAIL "retrieve mail from POP server" OP_MAIN_FIRST_MESSAGE "move to the first message" @@ -134,6 +148,7 @@ OP_PAGER_SKIP_QUOTED "skip beyond quoted text" OP_PAGER_TOP "jump to the top of the message" OP_PIPE "pipe message/attachment to a shell command" +OP_POST "post message to newsgroup" OP_PREV_ENTRY "move to the previous entry" OP_PREV_LINE "scroll up one line" OP_PREV_PAGE "move to the previous page" @@ -159,17 +174,21 @@ OP_SIG_SEARCH "search signatures matching a pattern" OP_SORT "sort messages" OP_SORT_REVERSE "sort messages in reverse order" +OP_SUBSCRIBE_PATTERN "subscribe to newsgroups matching a pattern" OP_TAG "tag the current entry" OP_TAG_PREFIX "apply next function to tagged messages" OP_TAG_SUBTHREAD "tag the current subthread" OP_TAG_THREAD "tag the current thread" OP_TOGGLE_NEW "toggle a message's 'new' flag" +OP_TOGGLE_READ "toggle view of read messages" OP_TOGGLE_WRITE "toggle whether the mailbox will be rewritten" OP_TOGGLE_MAILBOXES "toggle whether to browse mailboxes or all files" OP_TOP_PAGE "move to the top of the page" +OP_UNCATCHUP "mark all articles in newsgroup as unread" OP_UNDELETE "undelete the current entry" OP_UNDELETE_THREAD "undelete all messages in thread" OP_UNDELETE_SUBTHREAD "undelete all messages in subthread" +OP_UNSUBSCRIBE_PATTERN "unsubscribe from newsgroups matching a pattern" OP_VERSION "show the Mutt version number and date" OP_VIEW_ATTACH "view attachment using mailcap entry if necessary" OP_VIEW_ATTACHMENTS "show MIME attachments" diff -uNr mutt-1.4.orig/PATCHES mutt-1.4/PATCHES --- mutt-1.4.orig/PATCHES Sun Nov 3 21:42:52 2002 +++ mutt-1.4/PATCHES Sun Nov 3 21:57:20 2002 @@ -1,0 +1,1 @@ +vvv.nntp diff -uNr mutt-1.4.orig/acconfig.h mutt-1.4/acconfig.h --- mutt-1.4.orig/acconfig.h Tue Jan 15 23:08:12 2002 +++ mutt-1.4/acconfig.h Sun Nov 3 21:57:20 2002 @@ -14,6 +14,9 @@ */ #undef HOMESPOOL +/* Compiling with newsreading support with NNTP */ +#undef USE_NNTP + /* program to use for shell commands */ #define EXECSHELL "/bin/sh" diff -uNr mutt-1.4.orig/account.c mutt-1.4/account.c --- mutt-1.4.orig/account.c Thu Apr 26 15:36:33 2001 +++ mutt-1.4/account.c Sun Nov 3 21:57:20 2002 @@ -44,6 +44,11 @@ user = PopUser; #endif +#ifdef USE_NNTP + if (a1->type == M_ACCT_TYPE_NNTP && NntpUser) + user = NntpUser; +#endif + if (a1->flags & a2->flags & M_ACCT_USER) return (!strcmp (a1->user, a2->user)); if (a1->flags & M_ACCT_USER) @@ -113,6 +118,16 @@ } #endif +#ifdef USE_NNTP + if (account->type == M_ACCT_TYPE_NNTP) + { + if (account->flags & M_ACCT_SSL) + url->scheme = U_NNTPS; + else + url->scheme = U_NNTP; + } +#endif + url->host = account->host; if (account->flags & M_ACCT_PORT) url->port = account->port; @@ -138,6 +153,10 @@ else if ((account->type == M_ACCT_TYPE_POP) && PopUser) strfcpy (account->user, PopUser, sizeof (account->user)); #endif +#ifdef USE_NNTP + else if ((account->type == M_ACCT_TYPE_NNTP) && NntpUser) + strfcpy (account->user, NntpUser, sizeof (account->user)); +#endif /* prompt (defaults to unix username), copy into account->user */ else { @@ -167,6 +186,10 @@ else if ((account->type == M_ACCT_TYPE_POP) && PopPass) strfcpy (account->pass, PopPass, sizeof (account->pass)); #endif +#ifdef USE_NNTP + else if ((account->type == M_ACCT_TYPE_NNTP) && NntpPass) + strfcpy (account->pass, NntpPass, sizeof (account->pass)); +#endif else { snprintf (prompt, sizeof (prompt), _("Password for %s@%s: "), diff -uNr mutt-1.4.orig/account.h mutt-1.4/account.h --- mutt-1.4.orig/account.h Tue Jan 2 10:34:30 2001 +++ mutt-1.4/account.h Sun Nov 3 21:57:20 2002 @@ -28,6 +28,7 @@ { M_ACCT_TYPE_NONE = 0, M_ACCT_TYPE_IMAP, + M_ACCT_TYPE_NNTP, M_ACCT_TYPE_POP }; diff -uNr mutt-1.4.orig/attach.h mutt-1.4/attach.h --- mutt-1.4.orig/attach.h Tue Sep 11 13:20:34 2001 +++ mutt-1.4/attach.h Sun Nov 3 21:57:20 2002 @@ -30,5 +30,5 @@ void mutt_attach_bounce (FILE *, HEADER *, ATTACHPTR **, short, BODY *); void mutt_attach_resend (FILE *, HEADER *, ATTACHPTR **, short, BODY *); -void mutt_attach_forward (FILE *, HEADER *, ATTACHPTR **, short, BODY *); +void mutt_attach_forward (FILE *, HEADER *, ATTACHPTR **, short, BODY *, int); void mutt_attach_reply (FILE *, HEADER *, ATTACHPTR **, short, BODY *, int); diff -uNr mutt-1.4.orig/browser.c mutt-1.4/browser.c --- mutt-1.4.orig/browser.c Sun Nov 3 21:42:52 2002 +++ mutt-1.4/browser.c Sun Nov 3 22:00:14 2002 @@ -27,6 +27,9 @@ #ifdef USE_IMAP #include "imap.h" #endif +#ifdef USE_NNTP +#include "nntp.h" +#endif #include #include @@ -44,6 +47,19 @@ { NULL } }; +#ifdef USE_NNTP +static struct mapping_t FolderNewsHelp[] = { + { N_("Exit"), OP_EXIT }, + { N_("List"), OP_TOGGLE_MAILBOXES }, + { N_("Subscribe"), OP_BROWSER_SUBSCRIBE }, + { N_("Unsubscribe"), OP_BROWSER_UNSUBSCRIBE }, + { N_("Catchup"), OP_CATCHUP }, + { N_("Mask"), OP_ENTER_MASK }, + { N_("Help"), OP_HELP }, + { NULL } +}; +#endif + typedef struct folder_t { struct folder_file *ff; @@ -109,9 +125,17 @@ case SORT_ORDER: return; case SORT_DATE: +#ifdef USE_NNTP + if (option (OPTNEWS)) + return; +#endif f = browser_compare_date; break; case SORT_SIZE: +#ifdef USE_NNTP + if (option (OPTNEWS)) + return; +#endif f = browser_compare_size; break; case SORT_SUBJECT: @@ -299,8 +323,106 @@ return (src); } +#ifdef USE_NNTP +static const char * +newsgroup_format_str (char *dest, size_t destlen, char op, const char *src, + const char *fmt, const char *ifstring, const char *elsestring, + unsigned long data, format_flag flags) +{ + char fn[SHORT_STRING], tmp[SHORT_STRING]; + FOLDER *folder = (FOLDER *) data; + + switch (op) + { + case 'C': + snprintf (tmp, sizeof (tmp), "%%%sd", fmt); + snprintf (dest, destlen, tmp, folder->num + 1); + break; + + case 'f': + strncpy (fn, folder->ff->name, sizeof(fn) - 1); + snprintf (tmp, sizeof (tmp), "%%%ss", fmt); + snprintf (dest, destlen, tmp, fn); + break; + + case 'N': + snprintf (tmp, sizeof (tmp), "%%%sc", fmt); + if (folder->ff->nd->subscribed) + snprintf (dest, destlen, tmp, ' '); + else + snprintf (dest, destlen, tmp, folder->ff->new ? 'N' : 'u'); + break; + + case 'M': + snprintf (tmp, sizeof (tmp), "%%%sc", fmt); + if (folder->ff->nd->deleted) + snprintf (dest, destlen, tmp, 'D'); + else + snprintf (dest, destlen, tmp, folder->ff->nd->allowed ? ' ' : '-'); + break; + + case 's': + if (flags & M_FORMAT_OPTIONAL) + { + if (folder->ff->nd->unread != 0) + mutt_FormatString (dest, destlen, ifstring, newsgroup_format_str, + data, flags); + else + mutt_FormatString (dest, destlen, elsestring, newsgroup_format_str, + data, flags); + } + else if (Context && Context->data == folder->ff->nd) + { + snprintf (tmp, sizeof (tmp), "%%%sd", fmt); + snprintf (dest, destlen, tmp, Context->unread); + } + else + { + snprintf (tmp, sizeof (tmp), "%%%sd", fmt); + snprintf (dest, destlen, tmp, folder->ff->nd->unread); + } + break; + + case 'n': + if (Context && Context->data == folder->ff->nd) + { + snprintf (tmp, sizeof (tmp), "%%%sd", fmt); + snprintf (dest, destlen, tmp, Context->new); + } + else if (option (OPTMARKOLD) && + folder->ff->nd->lastCached >= folder->ff->nd->firstMessage && + folder->ff->nd->lastCached <= folder->ff->nd->lastMessage) + { + snprintf (tmp, sizeof (tmp), "%%%sd", fmt); + snprintf (dest, destlen, tmp, folder->ff->nd->lastMessage - folder->ff->nd->lastCached); + } + else + { + snprintf (tmp, sizeof (tmp), "%%%sd", fmt); + snprintf (dest, destlen, tmp, folder->ff->nd->unread); + } + break; + + case 'd': + if (folder->ff->nd->desc != NULL) + { + snprintf (tmp, sizeof (tmp), "%%%ss", fmt); + snprintf (dest, destlen, tmp, folder->ff->nd->desc); + } + else + { + snprintf (tmp, sizeof (tmp), "%%%ss", fmt); + snprintf (dest, destlen, tmp, ""); + } + break; + } + return (src); +} +#endif /* USE_NNTP */ + static void add_folder (MUTTMENU *m, struct browser_state *state, - const char *name, const struct stat *s, int new) + const char *name, const struct stat *s, + void *data, int new) { if (state->entrylen == state->entrymax) { @@ -329,6 +451,10 @@ #ifdef USE_IMAP (state->entry)[state->entrylen].imap = 0; #endif +#ifdef USE_NNTP + if (option (OPTNEWS)) + (state->entry)[state->entrylen].nd = (NNTP_DATA *) data; +#endif (state->entrylen)++; } @@ -344,9 +470,35 @@ menu->data = state->entry; } +/* get list of all files/newsgroups with mask */ static int examine_directory (MUTTMENU *menu, struct browser_state *state, char *d, const char *prefix) { +#ifdef USE_NNTP + if (option (OPTNEWS)) + { + LIST *tmp; + NNTP_DATA *data; + NNTP_SERVER *news = CurrentNewsSrv; + +/* mutt_buffy_check (0); */ + init_state (state, menu); + + for (tmp = news->list; tmp; tmp = tmp->next) + { + if (!(data = (NNTP_DATA *)tmp->data)) + continue; + if (prefix && *prefix && strncmp (prefix, data->group, + strlen (prefix)) != 0) + continue; + if (!((regexec (Mask.rx, data->group, 0, NULL, 0) == 0) ^ Mask.not)) + continue; + add_folder (menu, state, data->group, NULL, data, data->new); + } + } + else +#endif /* USE_NNTP */ + { struct stat s; DIR *dp; struct dirent *de; @@ -411,60 +563,95 @@ tmp = Incoming; while (tmp && mutt_strcmp (buffer, tmp->path)) tmp = tmp->next; - add_folder (menu, state, de->d_name, &s, (tmp) ? tmp->new : 0); + add_folder (menu, state, de->d_name, &s, NULL, (tmp) ? tmp->new : 0); + } + closedir (dp); } - closedir (dp); browser_sort (state); return 0; } +/* get list of mailboxes/subscribed newsgroups */ static int examine_mailboxes (MUTTMENU *menu, struct browser_state *state) { struct stat s; char buffer[LONG_STRING]; - BUFFY *tmp = Incoming; - if (!Incoming) - return (-1); - mutt_buffy_check (0); +#ifdef USE_NNTP + if (option (OPTNEWS)) + { + LIST *tmp; + NNTP_DATA *data; + NNTP_SERVER *news = CurrentNewsSrv; - init_state (state, menu); +/* mutt_buffy_check (0); */ + init_state (state, menu); - do - { -#ifdef USE_IMAP - if (mx_is_imap (tmp->path)) + for (tmp = news->list; tmp; tmp = tmp->next) { - add_folder (menu, state, tmp->path, NULL, tmp->new); - continue; + if ((data = (NNTP_DATA *) tmp->data) != NULL && (data->new || + (data->subscribed && (!option (OPTSHOWONLYUNREAD) || data->unread)))) + add_folder (menu, state, data->group, NULL, data, data->new); } + } + else #endif -#ifdef USE_POP - if (mx_is_pop (tmp->path)) + { + BUFFY *tmp = Incoming; + + if (!Incoming) + return (-1); + mutt_buffy_check (0); + + init_state (state, menu); + + do { - add_folder (menu, state, tmp->path, NULL, tmp->new); - continue; - } +#ifdef USE_IMAP + if (mx_is_imap (tmp->path)) + { + add_folder (menu, state, tmp->path, NULL, NULL, tmp->new); + continue; + } #endif - if (lstat (tmp->path, &s) == -1) - continue; +#ifdef USE_POP + if (mx_is_pop (tmp->path)) + { + add_folder (menu, state, tmp->path, NULL, NULL, tmp->new); + continue; + } +#endif +#ifdef USE_NNTP + if (mx_is_nntp (tmp->path)) + { + add_folder (menu, state, tmp->path, NULL, NULL, tmp->new); + continue; + } +#endif + if (lstat (tmp->path, &s) == -1) + continue; - if ((! S_ISREG (s.st_mode)) && (! S_ISDIR (s.st_mode)) && - (! S_ISLNK (s.st_mode))) - continue; + if ((! S_ISREG (s.st_mode)) && (! S_ISDIR (s.st_mode)) && + (! S_ISLNK (s.st_mode))) + continue; - strfcpy (buffer, NONULL(tmp->path), sizeof (buffer)); - mutt_pretty_mailbox (buffer); + strfcpy (buffer, NONULL(tmp->path), sizeof (buffer)); + mutt_pretty_mailbox (buffer); - add_folder (menu, state, buffer, &s, tmp->new); + add_folder (menu, state, buffer, &s, NULL, tmp->new); + } + while ((tmp = tmp->next)); } - while ((tmp = tmp->next)); browser_sort (state); return 0; } int select_file_search (MUTTMENU *menu, regex_t *re, int n) { +#ifdef USE_NNTP + if (option (OPTNEWS)) + return (regexec (re, ((struct folder_file *) menu->data)[n].desc, 0, NULL, 0)); +#endif return (regexec (re, ((struct folder_file *) menu->data)[n].name, 0, NULL, 0)); } @@ -475,7 +662,13 @@ folder.ff = &((struct folder_file *) menu->data)[num]; folder.num = num; - mutt_FormatString (s, slen, NONULL(FolderFormat), folder_format_str, +#ifdef USE_NNTP + if (option (OPTNEWS)) + mutt_FormatString (s, slen, NONULL(GroupFormat), newsgroup_format_str, + (unsigned long) &folder, M_FORMAT_ARROWCURSOR); + else +#endif + mutt_FormatString (s, slen, NONULL(FolderFormat), folder_format_str, (unsigned long) &folder, M_FORMAT_ARROWCURSOR); } @@ -495,7 +688,18 @@ menu->top = 0; menu->tagged = 0; - + +#ifdef USE_NNTP + if (option (OPTNEWS)) + { + if (buffy) + snprintf (title, titlelen, _("Subscribed newsgroups")); + else + snprintf (title, titlelen, _("Newsgroups on server [%s]"), + CurrentNewsSrv->conn->account.host); + } + else +#endif if (buffy) snprintf (title, titlelen, _("Mailboxes [%d]"), mutt_buffy_check (0)); else @@ -551,6 +755,31 @@ if (!folder) strfcpy (LastDirBackup, LastDir, sizeof (LastDirBackup)); +#ifdef USE_NNTP + if (option (OPTNEWS)) + { + if (*f) + strfcpy (prefix, f, sizeof (prefix)); + else + { + LIST *list; + + /* default state for news reader mode is browse subscribed newsgroups */ + buffy = 0; + for (list = CurrentNewsSrv->list; list; list = list->next) + { + NNTP_DATA *data = (NNTP_DATA *) list->data; + + if (data && data->subscribed) + { + buffy = 1; + break; + } + } + } + } + else +#endif if (*f) { mutt_expand_path (f, flen); @@ -639,6 +868,9 @@ menu->tag = file_tag; menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_FOLDER, +#ifdef USE_NNTP + (option (OPTNEWS)) ? FolderNewsHelp : +#endif FolderHelp); init_menu (&state, menu, title, sizeof (title), buffy, FolderColumns); @@ -777,7 +1009,11 @@ } } +#ifdef USE_NNTP + if (buffy || option (OPTNEWS)) /* news have not path */ +#else if (buffy) +#endif { strfcpy (f, state.entry[menu->current].name, flen); mutt_expand_path (f, flen); @@ -835,14 +1071,6 @@ break; #ifdef USE_IMAP - case OP_BROWSER_SUBSCRIBE: - imap_subscribe (state.entry[menu->current].name, 1); - break; - - case OP_BROWSER_UNSUBSCRIBE: - imap_subscribe (state.entry[menu->current].name, 0); - break; - case OP_BROWSER_TOGGLE_LSUB: if (option (OPTIMAPLSUB)) { @@ -913,6 +1141,11 @@ case OP_CHANGE_DIRECTORY: +#ifdef USE_NNTP + if (option (OPTNEWS)) + break; +#endif + strfcpy (buf, LastDir, sizeof (buf)); #ifdef USE_IMAP if (!state.imap_browse) @@ -1163,6 +1396,190 @@ else mutt_error _("Error trying to view file"); } + break; + +#ifdef USE_NNTP + case OP_CATCHUP: + case OP_UNCATCHUP: + if (option (OPTNEWS)) + { + struct folder_file *f = &state.entry[menu->current]; + NNTP_DATA *nd; + + if (i == OP_CATCHUP) + nd = mutt_newsgroup_catchup (CurrentNewsSrv, f->name); + else + nd = mutt_newsgroup_uncatchup (CurrentNewsSrv, f->name); + + if (nd) + { +/* FOLDER folder; + struct folder_file ff; + char buffer[_POSIX_PATH_MAX + SHORT_STRING]; + + folder.ff = &ff; + folder.ff->name = f->name; + folder.ff->st = NULL; + folder.ff->is_new = nd->new; + folder.ff->nd = nd; + safe_free ((void **) &f->desc); + mutt_FormatString (buffer, sizeof (buffer), NONULL(GroupFormat), + newsgroup_format_str, (unsigned long) &folder, + M_FORMAT_ARROWCURSOR); + f->desc = safe_strdup (buffer); */ + if (menu->current + 1 < menu->max) + menu->current++; + menu->redraw = REDRAW_MOTION_RESYNCH; + } + } + break; + + case OP_LOAD_ACTIVE: + if (!option (OPTNEWS)) + break; + + { + LIST *tmp; + NNTP_DATA *data; + + for (tmp = CurrentNewsSrv->list; tmp; tmp = tmp->next) + { + if ((data = (NNTP_DATA *)tmp->data)) + data->deleted = 1; + } + } + nntp_get_active (CurrentNewsSrv); + + destroy_state (&state); + if (buffy) + examine_mailboxes (menu, &state); + else + examine_directory (menu, &state, NULL, NULL); + init_menu (&state, menu, title, sizeof (title), buffy, 1); + break; +#endif /* USE_NNTP */ + +#if defined USE_IMAP || defined USE_NNTP + case OP_BROWSER_SUBSCRIBE: + case OP_BROWSER_UNSUBSCRIBE: +#endif +#ifdef USE_NNTP + case OP_SUBSCRIBE_PATTERN: + case OP_UNSUBSCRIBE_PATTERN: + if (option (OPTNEWS)) + { + regex_t *rx = (regex_t *) safe_malloc (sizeof (regex_t)); + char *s = buf; + int j = menu->current; + NNTP_DATA *nd; + NNTP_SERVER *news = CurrentNewsSrv; + + if (i == OP_SUBSCRIBE_PATTERN || i == OP_UNSUBSCRIBE_PATTERN) + { + char tmp[STRING]; + int err; + + buf[0] = 0; + if (i == OP_SUBSCRIBE_PATTERN) + snprintf (tmp, sizeof (tmp), _("Subscribe pattern: ")); + else + snprintf (tmp, sizeof (tmp), _("Unsubscribe pattern: ")); + if (mutt_get_field (tmp, buf, sizeof (buf), 0) != 0 || !buf[0]) + { + FREE (&rx); + break; + } + + if ((err = REGCOMP (rx, s, REG_NOSUB)) != 0) + { + regerror (err, rx, buf, sizeof (buf)); + regfree (rx); + safe_free ((void **) &rx); + mutt_error ("%s", buf); + break; + } + menu->redraw = REDRAW_FULL; + j = 0; + } + else if (!state.entrylen) + { + mutt_error _("No newsgroups match the mask"); + break; + } + + for ( ; j < state.entrylen; j++) + { + struct folder_file *f = &state.entry[j]; + + if (i == OP_BROWSER_SUBSCRIBE || i == OP_BROWSER_UNSUBSCRIBE || + regexec (rx, f->name, 0, NULL, 0) == 0) + { + if (i == OP_BROWSER_SUBSCRIBE || i == OP_SUBSCRIBE_PATTERN) + nd = mutt_newsgroup_subscribe (news, f->name); + else + nd = mutt_newsgroup_unsubscribe (news, f->name); +/* if (nd) + { + FOLDER folder; + char buffer[_POSIX_PATH_MAX + SHORT_STRING]; + + folder.name = f->name; + folder.f = NULL; + folder.new = nd->new; + folder.nd = nd; + safe_free ((void **) &f->desc); + mutt_FormatString (buffer, sizeof (buffer), NONULL(GroupFormat), + newsgroup_format_str, (unsigned long) &folder, + M_FORMAT_ARROWCURSOR); + f->desc = safe_strdup (buffer); + } */ + } + if (i == OP_BROWSER_SUBSCRIBE || i == OP_BROWSER_UNSUBSCRIBE) + { + if (menu->current + 1 < menu->max) + menu->current++; + menu->redraw = REDRAW_MOTION_RESYNCH; + break; + } + } + if (i == OP_SUBSCRIBE_PATTERN) + { + LIST *grouplist = NULL; + + if (news) + grouplist = news->list; + for (; grouplist; grouplist = grouplist->next) + { + nd = (NNTP_DATA *) grouplist->data; + if (nd && nd->group && !nd->subscribed) + { + if (regexec (rx, nd->group, 0, NULL, 0) == 0) + { + mutt_newsgroup_subscribe (news, nd->group); + add_folder (menu, &state, nd->group, NULL, nd, nd->new); + } + } + } + init_menu (&state, menu, title, sizeof (title), buffy, 1); + } + mutt_newsrc_update (news); + nntp_clear_cacheindex (news); + if (i != OP_BROWSER_SUBSCRIBE && i != OP_BROWSER_UNSUBSCRIBE) + regfree (rx); + safe_free ((void **) &rx); + } +#ifdef USE_IMAP + else +#endif /* USE_IMAP && USE_NNTP */ +#endif /* USE_NNTP */ +#ifdef USE_IMAP + { + if (i == OP_BROWSER_SUBSCRIBE) + imap_subscribe (state.entry[menu->current].name, 1); + else + imap_subscribe (state.entry[menu->current].name, 0); + } +#endif /* USE_IMAP */ } } diff -uNr mutt-1.4.orig/browser.h mutt-1.4/browser.h --- mutt-1.4.orig/browser.h Mon Aug 21 17:42:20 2000 +++ mutt-1.4/browser.h Sun Nov 3 21:57:20 2002 @@ -20,6 +20,10 @@ #ifndef _BROWSER_H #define _BROWSER_H 1 +#ifdef USE_NNTP +#include "nntp.h" +#endif + struct folder_file { mode_t mode; @@ -38,14 +42,17 @@ unsigned selectable : 1; unsigned inferiors : 1; #endif +#ifdef USE_NNTP + NNTP_DATA *nd; +#endif unsigned tagged : 1; }; struct browser_state { struct folder_file *entry; - short entrylen; /* number of real entries */ - short entrymax; /* max entry */ + unsigned int entrylen; /* number of real entries */ + unsigned int entrymax; /* max entry */ #ifdef USE_IMAP short imap_browse; char *folder; diff -uNr mutt-1.4.orig/buffy.c mutt-1.4/buffy.c --- mutt-1.4.orig/buffy.c Mon Mar 25 12:30:08 2002 +++ mutt-1.4/buffy.c Sun Nov 3 21:57:20 2002 @@ -257,6 +257,9 @@ #ifdef USE_POP if (!Context || Context->magic != M_POP) #endif +#ifdef USE_NNTP + if (!Context || Context->magic != M_NNTP) +#endif /* check device ID and serial number instead of comparing paths */ if (!Context || !Context->path || stat (Context->path, &contex_sb) != 0) { @@ -278,6 +281,11 @@ tmp->magic = M_POP; else #endif +#ifdef USE_NNTP + if ((tmp->magic == M_NNTP) || mx_is_nntp (tmp->path)) + tmp->magic = M_NNTP; + else +#endif if (stat (tmp->path, &sb) != 0 || sb.st_size == 0 || (!tmp->magic && (tmp->magic = mx_get_magic (tmp->path)) <= 0)) { @@ -294,25 +302,21 @@ /* check to see if the folder is the currently selected folder * before polling */ if (!Context || !Context->path || -#if defined USE_IMAP || defined USE_POP - (( + ( + (0 #ifdef USE_IMAP - tmp->magic == M_IMAP + || tmp->magic == M_IMAP #endif #ifdef USE_POP -#ifdef USE_IMAP - || -#endif - tmp->magic == M_POP + || tmp->magic == M_POP #endif - ) ? mutt_strcmp (tmp->path, Context->path) : +#ifdef USE_NNTP + || tmp->magic == M_NNTP #endif - (sb.st_dev != contex_sb.st_dev || sb.st_ino != contex_sb.st_ino) -#if defined USE_IMAP || defined USE_POP - ) -#endif - ) - + ) ? mutt_strcmp (tmp->path, Context->path) : + (sb.st_dev != contex_sb.st_dev || sb.st_ino != contex_sb.st_ino) + ) + ) { switch (tmp->magic) { @@ -380,6 +384,11 @@ case M_POP: break; #endif + +#ifdef USE_NNTP + case M_NNTP: + break; +#endif } } #ifdef BUFFY_SIZE diff -uNr mutt-1.4.orig/commands.c mutt-1.4/commands.c --- mutt-1.4.orig/commands.c Sun Nov 3 21:42:52 2002 +++ mutt-1.4/commands.c Sun Nov 3 21:57:20 2002 @@ -26,6 +26,7 @@ #include "copy.h" #include "mx.h" #include "pager.h" +#include "rfc1524.h" #include #include #include @@ -791,6 +792,131 @@ return -1; } +int mutt_update_list_file (char *filename, char *section, char *key, char *line) +{ + FILE *ifp; + FILE *ofp; + char buf[HUGE_STRING]; + char oldfile[_POSIX_PATH_MAX]; + char *c; + int ext = 0, done = 0, r = 0; + + snprintf (oldfile, sizeof(oldfile), "%s.bak", filename); + dprint (1, (debugfile, "Renaming %s to %s\n", filename, oldfile)); + + /* if file not exist, create it */ + if ((ifp = safe_fopen (filename, "a"))) + fclose (ifp); + if (_mutt_rename_file (filename, oldfile, 1)) + { + mutt_perror _("Unable to create backup file"); + return (-1); + } + dprint (1, (debugfile, "Opening %s\n", oldfile)); + if (!(ifp = safe_fopen (oldfile, "r"))) + { + mutt_perror _("Unable to open backup file for reading"); + return (-1); + } + dprint (1, (debugfile, "Opening %s\n", filename)); + if (!(ofp = fopen (filename, "w"))) + { + fclose (ifp); + mutt_perror _("Unable to open new file for writing"); + return (-1); + } + if (mx_lock_file (filename, fileno (ofp), 1, 0, 1)) + { + fclose (ofp); + fclose (ifp); + mutt_error (_("Unable to lock %s, old file saved as %s"), filename, oldfile); + return (-1); + } + + if (section) + { + while (r != EOF && !done && fgets (buf, sizeof (buf), ifp)) + { + r = fputs (buf, ofp); + c = buf; + while (*c && *c != '\n') c++; + c[0] = 0; /* strip EOL */ + if (!strncmp (buf, "#: ", 3) && !mutt_strcasecmp (buf+3, section)) + done++; + } + if (r != EOF && !done) + { + snprintf (buf, sizeof(buf), "#: %s\n", section); + r = fputs (buf, ofp); + } + done = 0; + } + + while (r != EOF && fgets (buf, sizeof (buf), ifp)) + { + if (ext) + { + c = buf; + while (*c && (*c != '\r') && (*c != '\n')) c++; + c--; + if (*c != '\\') ext = 0; + } + else if ((section && !strncmp (buf, "#: ", 3))) + { + if (!done && line) + { + fputs (line, ofp); + fputc ('\n', ofp); + } + r = fputs (buf, ofp); + done++; + break; + } + else if (key && !strncmp (buf, key, strlen(key)) && + (!*key || buf[strlen(key)] == ' ')) + { + c = buf; + ext = 0; + while (*c && (*c != '\r') && (*c != '\n')) c++; + c--; + if (*c == '\\') ext = 1; + if (!done && line) + { + r = fputs (line, ofp); + if (*key) + r = fputc ('\n', ofp); + done++; + } + } + else + { + r = fputs (buf, ofp); + } + } + + while (r != EOF && fgets (buf, sizeof (buf), ifp)) + r = fputs (buf, ofp); + + /* If there wasn't a line to replace, put it on the end of the file */ + if (r != EOF && !done && line) + { + fputs (line, ofp); + r = fputc ('\n', ofp); + } + mx_unlock_file (filename, fileno (ofp), 0); + fclose (ofp); + fclose (ifp); + if (r != EOF) + { + unlink (oldfile); + return 0; + } + unlink (filename); + mutt_error (_("Cannot write new %s, old file saved as %s"), filename, + oldfile); + return (-1); +} + void mutt_version (void) { diff -uNr mutt-1.4.orig/complete.c mutt-1.4/complete.c --- mutt-1.4.orig/complete.c Wed Nov 7 11:22:08 2001 +++ mutt-1.4/complete.c Sun Nov 3 21:57:20 2002 @@ -21,6 +21,9 @@ #include "mailbox.h" #include "imap.h" #endif +#ifdef USE_NNTP +#include "nntp.h" +#endif #include #include @@ -44,9 +47,71 @@ char filepart[_POSIX_PATH_MAX]; #ifdef USE_IMAP char imap_path[LONG_STRING]; +#endif dprint (2, (debugfile, "mutt_complete: completing %s\n", s)); +#ifdef USE_NNTP + if (option (OPTNEWS)) + { + LIST *l = CurrentNewsSrv->list; + + strfcpy (filepart, s, sizeof (filepart)); + + /* + * special case to handle when there is no filepart yet. + * find the first subscribed newsgroup + */ + if ((len = mutt_strlen (filepart)) == 0) + { + for (; l; l = l->next) + { + NNTP_DATA *data = (NNTP_DATA *)l->data; + + if (data && data->subscribed) + { + strfcpy (filepart, data->group, sizeof (filepart)); + init++; + l = l->next; + break; + } + } + } + + for (; l; l = l->next) + { + NNTP_DATA *data = (NNTP_DATA *)l->data; + + if (data && data->subscribed && + mutt_strncmp (data->group, filepart, len) == 0) + { + if (init) + { + for (i = 0; filepart[i] && data->group[i]; i++) + { + if (filepart[i] != data->group[i]) + { + filepart[i] = 0; + break; + } + } + filepart[i] = 0; + } + else + { + strfcpy (filepart, data->group, sizeof (filepart)); + init = 1; + } + } + } + + strcpy (s, filepart); + + return (init ? 0 : -1); + } +#endif + +#ifdef USE_IMAP /* we can use '/' as a delimiter, imap_complete rewrites it */ if (*s == '=' || *s == '+' || *s == '!') { diff -uNr mutt-1.4.orig/compose.c mutt-1.4/compose.c --- mutt-1.4.orig/compose.c Sun Nov 3 21:42:52 2002 +++ mutt-1.4/compose.c Sun Nov 3 21:57:20 2002 @@ -26,10 +26,15 @@ #include "mailbox.h" #include "sort.h" #include "charset.h" +#include "mx.h" #ifdef MIXMASTER #include "remailer.h" #endif + +#ifdef USE_NNTP +#include "nntp.h" +#endif #include #include @@ -63,12 +68,18 @@ HDR_PGPSIGINFO, #endif +#ifdef USE_NNTP + HDR_NEWSGROUPS, + HDR_FOLLOWUPTO, + HDR_XCOMMENTTO, +#endif + HDR_ATTACH = (HDR_FCC + 5) /* where to start printing the attachments */ }; -#define HDR_XOFFSET 10 -#define TITLE_FMT "%10s" /* Used for Prompts, which are ASCII */ +#define HDR_XOFFSET 14 +#define TITLE_FMT "%14s" /* Used for Prompts, which are ASCII */ #define W (COLS - HDR_XOFFSET) static char *Prompts[] = @@ -80,6 +91,15 @@ "Subject: ", "Reply-To: ", "Fcc: " +#ifdef HAVE_PGP + ,"" + ,"" +#endif +#ifdef USE_NNTP + ,"Newsgroups: " + ,"Followup-To: " + ,"X-Comment-To: " +#endif }; static struct mapping_t ComposeHelp[] = { @@ -94,6 +114,19 @@ { NULL } }; +#ifdef USE_NNTP +static struct mapping_t ComposeNewsHelp[] = { + { N_("Send"), OP_COMPOSE_SEND_MESSAGE }, + { N_("Abort"), OP_EXIT }, + { "Newsgroups", OP_COMPOSE_EDIT_NEWSGROUPS }, + { "Subj", OP_COMPOSE_EDIT_SUBJECT }, + { N_("Attach file"), OP_COMPOSE_ATTACH_FILE }, + { N_("Descrip"), OP_COMPOSE_EDIT_DESCRIPTION }, + { N_("Help"), OP_HELP }, + { NULL } +}; +#endif + static void snd_entry (char *b, size_t blen, MUTTMENU *menu, int num) { mutt_FormatString (b, blen, NONULL (AttachFormat), mutt_attach_fmt, @@ -108,7 +141,7 @@ static void redraw_pgp_lines (int pgp) { - mvaddstr (HDR_PGP, 0, " PGP: "); + mvaddstr (HDR_PGP, 0, " PGP: "); if ((pgp & (PGPENCRYPT | PGPSIGN)) == (PGPENCRYPT | PGPSIGN)) addstr (_("Sign, Encrypt")); else if (pgp & PGPENCRYPT) @@ -122,7 +155,7 @@ move (HDR_PGPSIGINFO, 0); clrtoeol (); if (pgp & PGPSIGN) - printw ("%s%s", _(" sign as: "), PgpSignAs ? PgpSignAs : _("")); + printw (" %s%s", _(" sign as: "), PgpSignAs ? PgpSignAs : _("")); } static int pgp_send_menu (int bits, int *redraw) @@ -258,9 +291,28 @@ static void draw_envelope (HEADER *msg, char *fcc) { draw_envelope_addr (HDR_FROM, msg->env->from); +#ifdef USE_NNTP + if (!option (OPTNEWSSEND)) + { +#endif draw_envelope_addr (HDR_TO, msg->env->to); draw_envelope_addr (HDR_CC, msg->env->cc); draw_envelope_addr (HDR_BCC, msg->env->bcc); +#ifdef USE_NNTP + } + else + { + mvprintw (HDR_TO, 0, TITLE_FMT , Prompts[HDR_NEWSGROUPS - 1]); + mutt_paddstr (W, NONULL (msg->env->newsgroups)); + mvprintw (HDR_CC, 0, TITLE_FMT , Prompts[HDR_FOLLOWUPTO - 1]); + mutt_paddstr (W, NONULL (msg->env->followup_to)); + if (option (OPTXCOMMENTTO)) + { + mvprintw (HDR_BCC, 0, TITLE_FMT , Prompts[HDR_XCOMMENTTO - 1]); + mutt_paddstr (W, NONULL (msg->env->x_comment_to)); + } + } +#endif mvprintw (HDR_SUBJECT, 0, TITLE_FMT, Prompts[HDR_SUBJECT - 1]); mutt_paddstr (W, NONULL (msg->env->subject)); draw_envelope_addr (HDR_REPLYTO, msg->env->reply_to); @@ -506,6 +558,12 @@ /* Sort, SortAux could be changed in mutt_index_menu() */ int oldSort, oldSortAux; struct stat st; +#ifdef USE_NNTP + int news = 0; /* is it a news article ? */ + + if (option (OPTNEWSSEND)) + news++; +#endif mutt_attach_init (msg->content); idx = mutt_gen_attach_list (msg->content, -1, idx, &idxlen, &idxmax, 0, 1); @@ -517,10 +575,18 @@ menu->make_entry = snd_entry; menu->tag = mutt_tag_attach; menu->data = idx; +#ifdef USE_NNTP + if (news) + menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_COMPOSE, ComposeNewsHelp); + else +#endif menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_COMPOSE, ComposeHelp); while (loop) { +#ifdef USE_NNTP + unset_option (OPTNEWS); /* for any case */ +#endif switch (op = mutt_menuLoop (menu)) { case OP_REDRAW: @@ -532,14 +598,81 @@ menu->redraw = edit_address_list (HDR_FROM, &msg->env->from); break; case OP_COMPOSE_EDIT_TO: - menu->redraw = edit_address_list (HDR_TO, &msg->env->to); +#ifdef USE_NNTP + if (!news) +#endif + menu->redraw = edit_address_list (HDR_TO, &msg->env->to); break; case OP_COMPOSE_EDIT_BCC: - menu->redraw = edit_address_list (HDR_BCC, &msg->env->bcc); +#ifdef USE_NNTP + if (!news) +#endif + menu->redraw = edit_address_list (HDR_BCC, &msg->env->bcc); break; case OP_COMPOSE_EDIT_CC: - menu->redraw = edit_address_list (HDR_CC, &msg->env->cc); +#ifdef USE_NNTP + if (!news) +#endif + menu->redraw = edit_address_list (HDR_CC, &msg->env->cc); + break; +#ifdef USE_NNTP + case OP_COMPOSE_EDIT_NEWSGROUPS: + if (news) + { + if (msg->env->newsgroups) + strfcpy (buf, msg->env->newsgroups, sizeof (buf)); + else + buf[0] = 0; + if (mutt_get_field ("Newsgroups: ", buf, sizeof (buf), 0) == 0 && buf[0]) + { + safe_free ((void **) &msg->env->newsgroups); + mutt_remove_trailing_ws (buf); + msg->env->newsgroups = safe_strdup (mutt_skip_whitespace (buf)); + move (HDR_TO, HDR_XOFFSET); + clrtoeol (); + if (msg->env->newsgroups) + printw ("%-*.*s", W, W, msg->env->newsgroups); + } + } + break; + + case OP_COMPOSE_EDIT_FOLLOWUP_TO: + if (news) + { + buf[0] = 0; + if (msg->env->followup_to) + strfcpy (buf, msg->env->followup_to, sizeof (buf)); + if (mutt_get_field ("Followup-To: ", buf, sizeof (buf), 0) == 0 && buf[0]) + { + safe_free ((void **) &msg->env->followup_to); + mutt_remove_trailing_ws (buf); + msg->env->followup_to = safe_strdup (mutt_skip_whitespace (buf)); + move (HDR_CC, HDR_XOFFSET); + clrtoeol(); + if (msg->env->followup_to) + printw ("%-*.*s", W, W, msg->env->followup_to); + } + } break; + + case OP_COMPOSE_EDIT_X_COMMENT_TO: + if (news && option (OPTXCOMMENTTO)) + { + buf[0] = 0; + if (msg->env->x_comment_to) + strfcpy (buf, msg->env->x_comment_to, sizeof (buf)); + if (mutt_get_field ("X-Comment-To: ", buf, sizeof (buf), 0) == 0 && buf[0]) + { + safe_free ((void **) &msg->env->x_comment_to); + msg->env->x_comment_to = safe_strdup (buf); + move (HDR_BCC, HDR_XOFFSET); + clrtoeol(); + if (msg->env->x_comment_to) + printw ("%-*.*s", W, W, msg->env->x_comment_to); + } + } + break; +#endif case OP_COMPOSE_EDIT_SUBJECT: if (msg->env->subject) strfcpy (buf, msg->env->subject, sizeof (buf)); @@ -695,6 +828,9 @@ break; case OP_COMPOSE_ATTACH_MESSAGE: +#ifdef USE_NNTP + case OP_COMPOSE_ATTACH_NEWS_MESSAGE: +#endif { char *prompt; HEADER *h; @@ -702,7 +838,22 @@ fname[0] = 0; prompt = _("Open mailbox to attach message from"); +#ifdef USE_NNTP + unset_option (OPTNEWS); + if (op == OP_COMPOSE_ATTACH_NEWS_MESSAGE) + { + if (!(CurrentNewsSrv = mutt_select_newsserver (NewsServer))) + break; + + prompt = _("Open newsgroup to attach message from"); + set_option (OPTNEWS); + } +#endif + if (Context) +#ifdef USE_NNTP + if ((op == OP_COMPOSE_ATTACH_MESSAGE) ^ (Context->magic == M_NNTP)) +#endif { strfcpy (fname, NONULL (Context->path), sizeof (fname)); mutt_pretty_mailbox (fname); @@ -711,6 +862,11 @@ if (mutt_enter_fname (prompt, fname, sizeof (fname), &menu->redraw, 1) == -1 || !fname[0]) break; +#ifdef USE_NNTP + if (option (OPTNEWS)) + nntp_expand_path (fname, sizeof (fname), &CurrentNewsSrv->conn->account); + else +#endif mutt_expand_path (fname, sizeof (fname)); #ifdef USE_IMAP if (!mx_is_imap (fname)) @@ -718,6 +874,9 @@ #ifdef USE_POP if (!mx_is_pop (fname)) #endif +#ifdef USE_NNTP + if (!mx_is_nntp (fname) && !option (OPTNEWS)) +#endif /* check to make sure the file exists and is readable */ if (access (fname, R_OK) == -1) { diff -uNr mutt-1.4.orig/configure.in mutt-1.4/configure.in --- mutt-1.4.orig/configure.in Sun Nov 3 21:42:52 2002 +++ mutt-1.4/configure.in Sun Nov 3 21:57:20 2002 @@ -457,6 +457,14 @@ ]) AM_CONDITIONAL(BUILD_IMAP, test x$need_imap = xyes) +AC_ARG_ENABLE(nntp, [ --enable-nntp Enable NNTP support], +[ if test x$enableval = xyes ; then + AC_DEFINE(USE_NNTP) + MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS nntp.o newsrc.o" + need_socket="yes" + fi +]) + dnl -- end socket dependencies -- if test "$need_socket" = "yes" diff -uNr mutt-1.4.orig/curs_main.c mutt-1.4/curs_main.c --- mutt-1.4.orig/curs_main.c Sun Nov 3 21:42:52 2002 +++ mutt-1.4/curs_main.c Sun Nov 3 21:57:20 2002 @@ -18,6 +18,7 @@ #include "mutt.h" #include "mutt_curses.h" +#include "mx.h" #include "mutt_menu.h" #include "mailbox.h" #include "mapping.h" @@ -33,6 +34,10 @@ #include "imap.h" #endif +#ifdef USE_NNTP +#include "nntp.h" +#endif + #ifdef HAVE_PGP @@ -405,12 +410,27 @@ { NULL } }; +#ifdef USE_NNTP +struct mapping_t IndexNewsHelp[] = { + { N_("Quit"), OP_QUIT }, + { N_("Del"), OP_DELETE }, + { N_("Undel"), OP_UNDELETE }, + { N_("Save"), OP_SAVE }, + { N_("Post"), OP_POST }, + { N_("Followup"), OP_FOLLOWUP }, + { N_("Catchup"), OP_CATCHUP }, + { N_("Help"), OP_HELP }, + { NULL } +}; +#endif + /* This function handles the message index window as well as commands returned * from the pager (MENU_PAGER). */ int mutt_index_menu (void) { char buf[LONG_STRING], helpstr[SHORT_STRING]; + int flags; int op = OP_NULL; int done = 0; /* controls when to exit the "event" loop */ int i = 0, j; @@ -432,7 +452,11 @@ menu->make_entry = index_make_entry; menu->color = index_color; menu->current = ci_first_message (); - menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_MAIN, IndexHelp); + menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_MAIN, +#ifdef USE_NNTP + (Context && (Context->magic == M_NNTP)) ? IndexNewsHelp : +#endif + IndexHelp); if (!attach_msg) mutt_buffy_check(1); /* force the buffy check after we enter the folder */ @@ -633,6 +657,9 @@ mutt_curs_set (1); /* fallback from the pager */ } +#ifdef USE_NNTP + unset_option (OPTNEWS); /* for any case */ +#endif switch (op) { @@ -683,6 +710,120 @@ menu_current_bottom (menu); break; +#ifdef USE_NNTP + case OP_GET_MESSAGE: + case OP_GET_PARENT: + CHECK_MSGCOUNT; + if (Context->magic == M_NNTP) + { + HEADER *h; + + if (op == OP_GET_MESSAGE) + { + buf[0] = 0; + if (mutt_get_field (_("Enter Message-Id: "), buf, sizeof (buf), 0) != 0 + || !buf[0]) + break; + } + else + { + LIST *ref = CURHDR->env->references; + if (!ref) + { + mutt_error _("Article has no parent reference!"); + break; + } + strfcpy (buf, ref->data, sizeof (buf)); + } + if (!Context->id_hash) + Context->id_hash = mutt_make_id_hash (Context); + if ((h = hash_find (Context->id_hash, buf))) + { + if (h->virtual != -1) + { + menu->current = h->virtual; + menu->redraw = REDRAW_MOTION_RESYNCH; + } + else if (h->collapsed) + { + mutt_uncollapse_thread (Context, h); + mutt_set_virtual (Context); + menu->current = h->virtual; + menu->redraw = REDRAW_MOTION_RESYNCH; + } + else + mutt_error _("Message not visible in limited view."); + } + else + { + if (nntp_check_msgid (Context, buf) == 0) + { + h = Context->hdrs[Context->msgcount-1]; + mutt_sort_headers (Context, 0); + menu->current = h->virtual; + menu->redraw = REDRAW_FULL; + } + else + mutt_error (_("Article %s not found on server"), buf); + } + } + break; + + case OP_GET_CHILDREN: + case OP_RECONSTRUCT_THREAD: + CHECK_MSGCOUNT; + if (Context->magic == M_NNTP) + { + HEADER *h; + int old = CURHDR->index, i; + + if (!CURHDR->env->message_id) + { + mutt_error _("No Message-Id. Unable to perform operation"); + break; + } + + if (!Context->id_hash) + Context->id_hash = mutt_make_id_hash (Context); + strfcpy (buf, CURHDR->env->message_id, sizeof (buf)); + + if (op == OP_RECONSTRUCT_THREAD) + { + LIST *ref = CURHDR->env->references; + while (ref) + { + nntp_check_msgid (Context, ref->data); + /* the last msgid in References is the root message */ + if (!ref->next) + strfcpy (buf, ref->data, sizeof (buf)); + ref = ref->next; + } + } + mutt_message _("Check for children of message..."); + if (nntp_check_children (Context, buf) == 0) + { + mutt_sort_headers (Context, (op == OP_RECONSTRUCT_THREAD)); + h = hash_find (Context->id_hash, buf); + /* if the root message was retrieved, move to it */ + if (h) + menu->current = h->virtual; + else /* try to restore old position */ + for (i = 0; i < Context->msgcount; i++) + if (Context->hdrs[i]->index == old) + { + menu->current = Context->hdrs[i]->virtual; + /* As an added courtesy, recenter the menu + * with the current entry at the middle of the screen */ + menu_check_recenter (menu); + menu_current_middle (menu); + } + } + menu->redraw = REDRAW_FULL; + mutt_clear_error (); + } + break; +#endif + case OP_JUMP: CHECK_MSGCOUNT; @@ -778,11 +919,33 @@ break; case OP_MAIN_LIMIT: + case OP_TOGGLE_READ: CHECK_MSGCOUNT; menu->oldcurrent = (Context->vcount && menu->current >= 0 && menu->current < Context->vcount) ? CURHDR->index : -1; - if (mutt_pattern_func (M_LIMIT, _("Limit to messages matching: ")) == 0) + if (op == OP_TOGGLE_READ) + { + char buf[LONG_STRING]; + + if (!Context->pattern || strncmp (Context->pattern, "!~R!~D~s", 8) != 0) + { + snprintf (buf, sizeof (buf), "!~R!~D~s%s", + Context->pattern ? Context->pattern : ".*"); + set_option (OPTHIDEREAD); + } + else + { + strfcpy (buf, Context->pattern + 8, sizeof(buf)); + if (!*buf || strncmp (buf, ".*", 2) == 0) + snprintf (buf, sizeof(buf), "~A"); + unset_option (OPTHIDEREAD); + } + FREE (&Context->pattern); + Context->pattern = safe_strdup (buf); + } + if ((op == OP_TOGGLE_READ && mutt_pattern_func (M_LIMIT, NULL) == 0) || + mutt_pattern_func (M_LIMIT, _("Limit to messages matching: ")) == 0) { if (menu->oldcurrent >= 0) { @@ -980,20 +1143,43 @@ break; case OP_MAIN_CHANGE_FOLDER: - - if (attach_msg) - op = OP_MAIN_CHANGE_FOLDER_READONLY; - - /* fallback to the readonly case */ - case OP_MAIN_CHANGE_FOLDER_READONLY: +#ifdef USE_NNTP + case OP_MAIN_CHANGE_GROUP: + case OP_MAIN_CHANGE_GROUP_READONLY: +#endif + + if (attach_msg || option (OPTREADONLY) || +#ifdef USE_NNTP + op == OP_MAIN_CHANGE_GROUP_READONLY || +#endif + op == OP_MAIN_CHANGE_FOLDER_READONLY) + flags = M_READONLY; + else + flags = 0; - if ((op == OP_MAIN_CHANGE_FOLDER_READONLY) || option (OPTREADONLY)) + if (flags) cp = _("Open mailbox in read-only mode"); else cp = _("Open mailbox"); buf[0] = '\0'; +#ifdef USE_NNTP + unset_option (OPTNEWS); + if (op == OP_MAIN_CHANGE_GROUP || + op == OP_MAIN_CHANGE_GROUP_READONLY) + { + set_option (OPTNEWS); + if (!(CurrentNewsSrv = mutt_select_newsserver (NewsServer))) + break; + if (flags) + cp = _("Open newsgroup in read-only mode"); + else + cp = _("Open newsgroup"); + nntp_buffy (buf); + } + else +#endif mutt_buffy (buf, sizeof (buf)); if (mutt_enter_fname (cp, buf, sizeof (buf), &menu->redraw, 1) == -1) @@ -1004,6 +1190,14 @@ break; } +#ifdef USE_NNTP + if (option (OPTNEWS)) + { + unset_option (OPTNEWS); + nntp_expand_path (buf, sizeof (buf), &CurrentNewsSrv->conn->account); + } + else +#endif mutt_expand_path (buf, sizeof (buf)); if (mx_get_magic (buf) <= 0) { @@ -1039,15 +1233,18 @@ mutt_folder_hook (buf); - if ((Context = mx_open_mailbox (buf, - (option (OPTREADONLY) || op == OP_MAIN_CHANGE_FOLDER_READONLY) ? - M_READONLY : 0, NULL)) != NULL) + if ((Context = mx_open_mailbox (buf, flags, NULL)) != NULL) { menu->current = ci_first_message (); } else menu->current = 0; +#ifdef USE_NNTP + /* mutt_buffy_check() must be done with mail-reader mode! */ + menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_MAIN, + (Context && (Context->magic == M_NNTP)) ? IndexNewsHelp : IndexHelp); +#endif mutt_clear_error (); mutt_buffy_check(1); /* force the buffy check after we have changed the folder */ @@ -1422,6 +1619,15 @@ } #endif +#ifdef USE_NNTP + if (Context->magic == M_NNTP) + { + mutt_flushinp (); + mutt_error _("Can't change 'important' flag on NNTP server."); + break; + } +#endif + if (tag) { for (j = 0; j < Context->vcount; j++) @@ -1767,6 +1973,17 @@ } break; +#ifdef USE_NNTP + case OP_CATCHUP: + if (Context && Context->magic == M_NNTP) + { + if (mutt_newsgroup_catchup (CurrentNewsSrv, + ((NNTP_DATA *)Context->data)->group)) + menu->redraw = REDRAW_INDEX | REDRAW_STATUS; + } + break; +#endif + case OP_DISPLAY_ADDRESS: CHECK_MSGCOUNT; @@ -1801,6 +2018,15 @@ } #endif +#ifdef USE_NNTP + if (Context->magic == M_NNTP) + { + mutt_flushinp (); + mutt_error _("Can't edit message on newsserver."); + break; + } +#endif + mutt_edit_message (Context, tag ? NULL : CURHDR); menu->redraw = REDRAW_FULL; @@ -1955,6 +2181,37 @@ menu->redraw = REDRAW_FULL; break; + +#ifdef USE_NNTP + case OP_POST: + case OP_FOLLOWUP: + case OP_FORWARD_TO_GROUP: + + CHECK_ATTACH; + if (op != OP_FOLLOWUP || !CURHDR->env->followup_to || + mutt_strcasecmp (CURHDR->env->followup_to, "poster") || + query_quadoption (OPT_FOLLOWUPTOPOSTER,_("Reply by mail as poster prefers?")) != M_YES) + { + if (Context && Context->magic == M_NNTP && + !((NNTP_DATA *)Context->data)->allowed && + query_quadoption (OPT_TOMODERATED, _("Posting to this group not allowed, may be moderated. Continue?")) != M_YES) + break; + if (op == OP_POST) + ci_send_message (SENDNEWS, NULL, NULL, Context, NULL); + else + { + CHECK_MSGCOUNT; + if (op == OP_FOLLOWUP) + ci_send_message (SENDNEWS|SENDREPLY, NULL, NULL, Context, + tag ? NULL : CURHDR); + else + ci_send_message (SENDNEWS|SENDFORWARD, NULL, NULL, Context, + tag ? NULL : CURHDR); + } + menu->redraw = REDRAW_FULL; + break; + } +#endif case OP_REPLY: @@ -2081,6 +2338,12 @@ if (!attach_msg) imap_logout_all (); #endif +#ifdef USE_NNTP + /* Close all open NNTP connections */ + if (!attach_msg) + nntp_logout_all (); +#endif + mutt_menuDestroy (&menu); return (close); diff -uNr mutt-1.4.orig/doc/manual.sgml mutt-1.4/doc/manual.sgml --- mutt-1.4.orig/doc/manual.sgml Sun Nov 3 21:42:51 2002 +++ mutt-1.4/doc/manual.sgml Sun Nov 3 21:57:20 2002 @@ -723,6 +723,17 @@ See also the quad-option. +Reading news via NNTP