From c113de23613952ed67a3bca79363b30ab7e406c3 Mon Sep 17 00:00:00 2001 From: Gerd Moellmann Date: Tue, 19 Sep 2000 13:40:08 +0000 Subject: [PATCH] *** empty log message *** --- etc/ChangeLog | 4 + etc/splash.xpm | 294 ++ lisp/ChangeLog | 13 + lisp/gnus/ChangeLog | 9616 +++++++++++++++++++++++++++++--------- lisp/gnus/binhex.el | 306 ++ lisp/gnus/flow-fill.el | 98 + lisp/gnus/format-spec.el | 71 + lisp/gnus/gnus-load.el | 103 - lisp/gnus/gnus-ml.el | 165 + lisp/gnus/gnus-mlspl.el | 210 + lisp/gnus/gnus-mule.el | 216 - lisp/gnus/ietf-drums.el | 249 + lisp/gnus/imap.el | 2560 ++++++++++ lisp/gnus/mail-parse.el | 70 + lisp/gnus/mail-prsvr.el | 44 + lisp/gnus/mail-source.el | 736 +++ lisp/gnus/mailcap.el | 944 ++++ lisp/gnus/mm-bodies.el | 258 + lisp/gnus/mm-decode.el | 835 ++++ lisp/gnus/mm-encode.el | 168 + lisp/gnus/mm-partial.el | 152 + lisp/gnus/mm-util.el | 500 ++ lisp/gnus/mm-uu.el | 250 + lisp/gnus/mm-view.el | 279 ++ lisp/gnus/mml.el | 871 ++++ lisp/gnus/nnimap.el | 1332 ++++++ lisp/gnus/nnslashdot.el | 564 +++ lisp/gnus/nnultimate.el | 452 ++ lisp/gnus/nnwarchive.el | 752 +++ lisp/gnus/qp.el | 146 + lisp/gnus/rfc1843.el | 183 + lisp/gnus/rfc2045.el | 40 + lisp/gnus/rfc2047.el | 432 ++ lisp/gnus/rfc2104.el | 104 + lisp/gnus/rfc2231.el | 208 + lisp/gnus/time-date.el | 132 + lisp/gnus/utf7.el | 179 + lisp/gnus/uudecode.el | 207 + lisp/gnus/webmail.el | 1086 +++++ 39 files changed, 22360 insertions(+), 2469 deletions(-) create mode 100644 etc/splash.xpm create mode 100644 lisp/gnus/binhex.el create mode 100644 lisp/gnus/flow-fill.el create mode 100644 lisp/gnus/format-spec.el delete mode 100644 lisp/gnus/gnus-load.el create mode 100644 lisp/gnus/gnus-ml.el create mode 100644 lisp/gnus/gnus-mlspl.el delete mode 100644 lisp/gnus/gnus-mule.el create mode 100644 lisp/gnus/ietf-drums.el create mode 100644 lisp/gnus/imap.el create mode 100644 lisp/gnus/mail-parse.el create mode 100644 lisp/gnus/mail-prsvr.el create mode 100644 lisp/gnus/mail-source.el create mode 100644 lisp/gnus/mailcap.el create mode 100644 lisp/gnus/mm-bodies.el create mode 100644 lisp/gnus/mm-decode.el create mode 100644 lisp/gnus/mm-encode.el create mode 100644 lisp/gnus/mm-partial.el create mode 100644 lisp/gnus/mm-util.el create mode 100644 lisp/gnus/mm-uu.el create mode 100644 lisp/gnus/mm-view.el create mode 100644 lisp/gnus/mml.el create mode 100644 lisp/gnus/nnimap.el create mode 100644 lisp/gnus/nnslashdot.el create mode 100644 lisp/gnus/nnultimate.el create mode 100644 lisp/gnus/nnwarchive.el create mode 100644 lisp/gnus/qp.el create mode 100644 lisp/gnus/rfc1843.el create mode 100644 lisp/gnus/rfc2045.el create mode 100644 lisp/gnus/rfc2047.el create mode 100644 lisp/gnus/rfc2104.el create mode 100644 lisp/gnus/rfc2231.el create mode 100644 lisp/gnus/time-date.el create mode 100644 lisp/gnus/utf7.el create mode 100644 lisp/gnus/uudecode.el create mode 100644 lisp/gnus/webmail.el diff --git a/etc/ChangeLog b/etc/ChangeLog index 73719775ff1..7e61a883957 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,7 @@ +2000-09-19 Gerd Moellmann + + * splash.xpm: New file. + 2000-09-11 Dave Love * gnus.xbm, gnus.xpm, gnus-pointer.xpm, gnus-pointer.xbm: New diff --git a/etc/splash.xpm b/etc/splash.xpm new file mode 100644 index 00000000000..7c95976b57d --- /dev/null +++ b/etc/splash.xpm @@ -0,0 +1,294 @@ +/* XPM */ +static char * emacs1_xpm[] = { +"271 273 18 1", +" c None", +". c #BF9900", +"+ c #FFCC00", +"@ c #000000", +"# c #AA8800", +"$ c #7F6600", +"% c #3F3300", +"& c #554400", +"* c #1D1700", +"= c #725B00", +"- c #C79F00", +"; c #957700", +"> c #2A2200", +", c #392D00", +"' c #E3B500", +") c #151100", +"! c #6A5500", +"~ c #8E7100", +" ", +" ", +" ... ", +" ..........++++++ ", +" .............+++++++ ", +" ................++++++ ", +" ..................++++++ ", +" ....................+++++++ ", +" ......................+++++++ ", +" ........................+++++++ ", +" .........................++++++ ", +" ..... ...........................++++++ ", +" ........... ............................+++++++ ", +" ............... ..............................+++++++ ", +" .................. ........... ...............................+++++++ ", +" .................... ............... ...............................+++++++ ", +" ...................... .................... ................................++++++++ ", +" ....................... ........................ .................................+++++++ ", +" ......................... ............................ ..................................++++++++ ", +" ........................... .............................. ...................................+++++++ ", +" ............................. ................................ ....................................+++++++ ", +" ............................... .................................. .......++++++.......................+++++++ ", +" ................................ ................................... ...... +++++++ ....................+++++++ ", +" .................................. ..................................... ..... ++++++ .................+++++++ ", +" .................................... ...................................... ...... +++++ ................+++++++ ", +" ............................................................................. ...... ++++++ ...............+++++++ ", +" .............................................................................. ...... ++++++ ...............+++++++ ", +" ................................................................................ ...... +++++ ..............+++++++ ", +" .. .................................................................................. ....... ++++++ ..............+++++++ ", +" .... .................................................................................... ....... ++++++ .............+++++++ ", +" ....... ..............++++.................................................................... ...... +++++++ ............++++++++ ", +" ......... .............++++++++................................................................... ....... +++++++ ...........++++++++ ", +" ........... .............++++++++++++.................................................................. ....... ++++++ ...........++++++++ ", +" .......... .............++++++++++++++.................................................................. ...... +++++++ ...........++++++++ ", +" ........... ............++++++++++++++++++.......................++++++++++................................ ..... ++++++ ..........++++++++ ", +" ............ ............++++++++++++++++++++....................+++++++++++++++.............................. .... +++++ ..........+++++++ ", +" ............ ..............+++++++++++++++++++++.................+++++++++++++++++++++.......................... .. .. +++ ..........+++++++ ", +" ............. ..............+++++++++++++++++++++++...............+++++++++++++++++++++++.......................... . .. .. ++ ..........+++++++ ", +" ............. ...............++++++++++ +++++++++++++.............+++++++++++++++++++++++++.......................... .. ... ++ ..........+++++++ ", +" ............. ................+++++++++ +++++++++++............++++++++++++++++++++++++++.......................... ... .... ..........++++++++ ", +" ................ ..................+++++++ +++++++++++..........++++++++++++++++++++++++++++.......................... ... ..... ..........++++++++ ", +" .....................................++++++ +++++++++++.........+++++++++++++++++++++++++++++.......................... .... .... ..........++++++++ ", +" ....................................++++++ +++++++++........+++++++++++++++++++++++++++++++......................... ..... ..... ..........++++++++ ", +" .................................+++++++ +++++++++.......+++++++ ++++++++++++++.......................... ..... .... ..........+++++++ ", +" ................................+++++++ ++++++++......+++++ ++++++++++++.......................... ...... ..... ..........+++++++ ", +" ...............................++++++++ ++++++++....+++++ ++++++++++.......................... ...... ..... + ..........+++++++ ", +" +..............................++++++++ +.++++...+++++ ++++++++++........................... ....... .... +++ ..........+++++++ ", +" +.............................++++++++ ...+++..++++++ ++++++++++........................... ...... + ..... ++++ .........++++++++ ", +" +++...........................+++++++++ ....++++++++++ ++++++++++............................ ........++ ..... +++ .........++++++++ ", +" +++..........................+++++++++ ....+++++++++ ++++++++++............................... ...........++ ...... ++++ .........++++++++ ", +" +++.........................+++++++++ .... +++++++++ ++++++++++................................................++ ... ...... +++++ .........+++++++ ", +" ++++........................+++++++++ .... +++++++ +++++++++...............................................++ .... ....... +++++ .........+++++++ ", +" ++++.......................++++++++ ..... +++++++ +++++++++..............................................++ ..... ....... +++++ .........+++++++ ", +" ++++++....................+++++++++ ..... + +++++ +++++++++............................................++ ...... ......... +++++ .........+++++++ ", +" ++++++...................+++++++++ ......++ ++++ +++++++++...........................................++ ....... .......... ++++ .........+++++++ ", +" +++++++.................+++++++++ ..... +++ +++ +++++++++.........................................+++ ......... .............. +++++ ........++++++++ ", +" +++++++...............+++++++++ ..... ++++ ++ +++++++++........................................++ ............................... ++++ .........+++++++ ", +" ++++++++............++++++++++ ..... ++++ + +++++++++.......................................++ ...............................+++++ .........+++++++ ", +" ++++++++++.......+++++++++++ ......+++++ +++++++++.....................................+++ ..............................+++++ .........+++++++ ", +" ++++++++++++++++++++++++++ .....+++++ +++++++++....................................++ ...............................+++++ ........++++++++ ", +" +++++++++++++++++++++++++ .....+++++ +++++++++..................................+++ ..............................+++++ ........+++++++ ", +" +++++++++++++++++++++++ ..... +++++ +++++++++...............................++++ ..............................++++++ ........+++++++ ", +" +++++++++++++++++++++ .... +++++ +++++++++.............................+++++ .............................+++++++ ........+++++++ ", +" +++++++++++++++++++ .... ++++++ +++++++++...........................++++++ ..............................++++++ .......++++++++ ", +" +++++++++++++++++ .... ++++++ +++++++++.........................++++++ .............................+++++++ ........+++++++ ", +" +++++++++++++++ ..... +++++ ... +++++++++.......................+++++++ .............................+++++++ ........+++++++ ", +" +++++++++++ .... +++++ ...... +++++++++....................+++++++++ ............................++++++++ ....... +++++++ ", +" +++ .... +++++ ....... +++++++++..................+++++++++ ..........................+++++++++ .......+++++++ ", +" .....++++++ .......... +++++++++++.............+++++++++++ .........................++++++++++ .......+++++++ ", +" .... +++++ ............ ++++++++++++++....+++++++++++++++ .......................++++++++++ ....... +++++++ ", +" .... +++++ ............. ++++++++++++++++++++++++++++++ .....................++++++++++++ ....... ++++++ ", +" .....+++++ ............... ++++++++++++++++++++++++++++ ...................++++++++++++ ....... ++++++ ", +" .... +++++ . ................ ++++++++++++++++++++++++++ +................+++++++++++++ .......+++++++ ", +" .... +++++ .... ................. ++++++++++++++++++++++++ ++..............+++++++++++++ ...... +++++++ ", +" .....+++++ ..... ................... ++++++++++++++++++++++ +++++.........+++++++++++++++ ....... ++++++ ", +" .... +++++ ..... .................... +++++++++++++++++++ ++++++++..++++++++++++++++++ ....... ++++++ ", +" .... +++++ ..... .................... ++++++++++++++++ +++++++++++++++++++++++++++ ...... +++++++ ", +" .....+++++ ....... ...................... +++++++++++ ++++++++++++++++++++++++++ ...... ++++++ ", +" .... ++++ ....... ....................... ++++++++++++++++++++++++ ...... ++++++ ", +" .... +++++ ....... ....................... ++++++++++++++++++++++ ....... ++++++ ", +" .....+++++ ........ +++ ......................... ++++++++++++++++++++ ...... +++++++ ", +" .... ++++ ........ ++++ ......................... ++++++++++++++++++ ...... ++++++ ", +" .... +++++ ........ +++++ ....................... +++++++++++++++ ...... ++++++ ", +" ..... ++++ .........+++++ +..................... ++++++++++++ ..... ++++++ ", +" .... ++++ ..........+++++ ++.................... +++++++ ...... ++++++ ", +" .....+++++ ..........++++++ +++++.................. ...... ++++++ ", +" .... ++++ ...........+++++ +++++++.................. ...... ++++++ ", +" .....++++ ...........+++++ +++++++.................. ...... +++++ ", +" .....++++ ...........++++++ +++++++++................. ...... ++++++ ", +" .....++++ ...........++++++ +++++++++++................ ...... ++++++ ", +" .....++++ ............+++++++ ++++++++++............... ...... ++++++ ", +" ......++++ ............+++++++ +++++++++............... ...... +++++ ", +" .....++++ ............+++++++ ++++++++.............. ...... ++++++ ", +" ......+++ ............+++++++++ +++++++.............. ...... +++++ ", +" ......+++ .............+++++++++ +++++++............. ...... +++++ ", +" ........+ .............+++++++++ ++++++............. ..... ++++++ ", +" ........+ ..............+++++++++ +++++............. ...... +++++ ", +" ........+ ...............+++++++++ +++++............. ..... +++++ ", +" ........... ...............+++++++++ +++++............ ..... ++++++ ", +" ............... ..................++++++++ ++++............ ...... +++++ ", +" ......................................++++++++ ++++........... ..... +++++ ", +" .....................................++++++++ +++........... ..... ++++ ", +" ....................................+++++++++ ++++.......... .... +++++ ", +" ...................................+++++++++ +++.......... ..... +++++ ", +" ...................................+++++++++ +++.......... ..... +++++ ", +" .................................+++++++++ +++.......... ..... ++++ ", +" ................................+++++++++ ++.......... .... +++++ ", +" ................................+++++++++ ++.......... + ..... +++++ ", +" ..............................++++++++++ +.......... +++ ..... +++++ ", +" .............................++++++++++ +.........+ +++ ..... ++++ ", +" ............................++++++++++ +.........+ +++ .... +++++ ", +" ...........................+++++++++ +.........+ ++++ ..... +++++ ", +" .........................++++++++++ +........++ ++++ .. ..... ++++++ ", +" ......................+++++++++++ +........++ +++++ ... ...... +++++ ", +" +...................++++++++++++ +........+ +++++ ... ...... +++++ ", +" ++................+++++++++++++ +.......++ ++++++ .... ..... ++++++ ", +" +++............++++++++++++++ +......+++ ++++++ .... ...... ++++++ ", +" ++++.........+++++++++++++++ +......+++ ++++++ ..... ...... ++++++ ", +" ++++++..+++++++++++++++++++ +.....+++ ++++++ .... ...... ++++++ ", +" +++++++++++++++++++++++++ +.....+++ +++++++ ..... ...... ++++++ ", +" ++++++++++++++++++++++++ +.....+++ ++++++ ..... ...... +++++++ ", +" +++++++++++++++++++++ +....++++ +++++++ ...... ...... +++++++ ", +" ++++++++++++++++++ +....+++ ++++++ ....... ....... ++++++ ", +" ++++++++++++++ +...++++ ++++++ ....... ...... +++++++ ", +" +++++++++++ ++..++++ +++++++ ....... ...... +++++++ ", +" ++++ +++++++ ++++++ ....... ...... ++++++ ", +" ++++++ ++++++ ....... ....... ++++++ ", +" ++++++ ++++++ ...... ...... +++++++ ", +" +++++ ++++++ ....... ...... +++++++ ", +" +++++ +++++ ...... ...... ++++++ ", +" +++++ ++++++ ...... ...... ++++++ ", +" +++++ +++++ ...... ...... ++++++ ", +" ++++ ++++++ ...... ...... ++++++ ", +" ++ +++++ ...... ...... ++++++ ", +" ++++++ ...... ...... ++++++ ", +" +++++ ..... ...... +++++ ", +" ++++++ ...... ...... ++++++ ", +" ++++++ ..... ...... ++++++ ", +" +++++ ...... ....... ++++++ ", +" ++++++ ..... ....... ++++++ ", +" +++++ ...... ...... +++++++ ", +" ++++++ ...... ...... ++++++ ", +" . +++++ ...... ...... ++++++ ", +" . ++++++ ...... ....... ++++++ ", +" . +++++ ...... .......+++++++ ", +" .. ++++++ ...... ...... +++++++ ", +" ... ++++++ ...... ...... ++++++ ", +" ... ++++++ ...... ....... ++++++ ", +" .... ++++++ ...... .......+++++++ ", +" .... +++++++ ...... .......+++++++ ", +" .... + + +++++++ ...... ...... +++++++ ", +" .....+ +++ +++++++ ...... ...... ++++++ ", +" ......+ +++++ ++++++++ ....... ...... ++++++ ", +" ......+ +++++ ++++++++ ....... ....... ++++++ ", +" .......+ +++++++ +++++++++ ....... .......+++++++ ", +" .......++ ++++++++ .. ++++++++++ ....... ...... +++++++ ", +" ........++ +++++++++....++++++++++ ........ ...... ++++++ ", +" ........+ +++++++++......+++++++++........ ...... ++++++ ", +" .........+ +++++++++......++++++++ ........ ...... ++++++ ", +" .........++ +++++++++.......+++++++......... ...... ++++++ ", +" .........++ ++++++++.........+++++......... ...... +++++++ ", +" .........+++ ++++++++........................ ...... +++++++ ", +" .........+++ ++++++++....................... ...... ++++++ ", +" ..........+++ ++++++++....................... ...... ++++++ ", +" .........++++ +++++++++....................... ...... ++++++ ", +" .........+++++ ++++++++....................... ....... ++++++ ", +" ..........++++ +++++++++...................... ....... ++++++ ", +" .........+++++ +++++++++...................... ...... +++++++ ", +" .........+++++ ++++++++....................... ...... +++++++ ", +" .........+++++ +++++++++...................... ....... +++++++ ", +" .........+++++ ++++++++....................... ....... +++++++ ", +" .........+++++ ++++++++....................... ....... +++++++ ", +" .........+++++ ++++++++....................... ....... +++++++ ", +" ..........+++++ ++++++++....................... ....... ++++++ ", +" .........+++++ +++++++........................ ...... ++++++ ", +" .........+++++ ++++++++....................... ...... +++++++ ", +" @@@ ..........++++ +++++++......... .............. ..... ++++++ ", +" @@@@@@ .........+++++ +++++++ ........ ............ ..... ++++++ ", +" @@@@@@@@ .........+++++ +++++++........ .......... .... +++++ ", +" @@@@@@@@@@@@ @@@@ @@@@@@@@@@ @@@@@@@@ ..........++++ +++++++ ....... ....... .... +++++ ", +" @@@@@@@@@@@@ @@@@@ @@@@@@@@@@ @@@@@ .........+++++ ++++++ ........ ..... ... +++ ", +" @@@@@@@ @@@@@@ @@@@@ @@@@@ .........+++++ +++++++ ....... ... +++ ", +" @@@@@ @@@@@@ @@ @@@@@ .........+++++ +++++++........ .. ++ ", +" @@@@@ @@@@@@ @@ @@@@@ ..........+++++ +++++++ ....... . ++ @@@ ", +" @@@@@ @@@@@@@ @@@ @@@@@ .........+++++ +++++++....... + @@@@ ", +" @@@@@@ @@@@@@@@ @@@ @@@@@ .........+++++ ++++++ ....... + @@@@ ", +" @@@@@ @@@@@@@@ @@ @@@@@ ..........+++++ +++++++ ...... @@@@@ ", +" @@@@@ @@@ @@@@@ @@ @@@@ @@@@@ .....#$%%@@&&# @@@*&=-++....... @@ @@@ @@@@@ @@@@ ", +" @@@@@ @@@ @@@@@ @@@ @@@@@@@@@@ @@@@@ ....;>@@@@@@@@@@ @@@@@@@@@@@, ....... @@@@@ @@@@@@@ @@@@@@@ @@@@@@@@@ @@@@@@@ @@@@@@@@@@ ", +" @@@@@@ @@ @@@@@ @@@ @@@@@ @@@@@ @@@@@ ....&@@@@@@@&,@@@@ @@@@@ &,@@@@@@%..... @@@@@@@ @@@@@@@@@@ @@@@@@@@@@ @@@@@ @@@@@ @@@@@@@@@@@@@@@ @@@@@@ @@@@@@ ", +" @@@@@ @@@ @@@@@ @@ @@@@ @@@@ @@@@@ ....%@@@@@,-++#@@@@@ @@@@@ +++'&@@@@@%.... @@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@ @@@@ @@@@@ @@@@@@@@@@@@@@@@ @@@@@ @@@@@ ", +" @@@@@ @@@ @@@@@ @@ @@@@ @@@@@ @@@@@ ...%@@@@@&++++ @@@@@ @@@@@ +++++&@@@@@%... @@@@@@@ @@@@@@@@ @@@@@@ @@@@ @@@@@ @@@@@@ @@@@@ @@@@@ ", +" @@@@@@ @@ @@@@@ @@@ @@@@@ @@@@ @@@@@ ...$@@@@@)++++ @@@@@@ @@@@@ +++++'@@@@@@;. @@@@@@ @@@@@@ @@@@@@ @@@@ @@@@@ @@@@@@ @@@@@ @@@@@ ", +" @@@@@ @@ @@@@@ @@@ @@@@ @@@@@ @@@@@ ....)@@@@@-++++ @@@@@ @@@@@ ++++++ @@@@@>. @@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@ @@@ @@@@@ @@ @@@@@ @@@@@ @@@@@ ...!@@@@@*++++ @@@@@ @@@@@ ++++++ ;@@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@@@@ @@@@@@ @@@@@ @@@@@ ", +" @@@@@ @@@ @@@@@ @@ @@@@@ @@@@@ @@@@@ ....%@@@@@&+++ @@@@@@ +++++ .@@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@@@@ @@@@@@ @@@@@ @@@@@ ", +" @@@@@@ @@ @@@@@ @@@ @@@@@ @@@@@@ @@@@@ .....@@@@@@~+++ @@@@@@ ++++ ..)@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@ @@@ @@@@@ @@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@ ....;@@@@@@#++ @@@@@@ +++++ ..%@@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@ @@@ @@@@@ @@ @@@@@@@@@@@@@@@@@@@@@@ @@@@@ .....$@@@@@@#+ @@@@@@ ++++ ..%@@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@ @@ @@@@@ @@ @@@@@@ @@@@@%.....$@@@@@@#+ @@@@@@ ++++ ...%@@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@@ @@@ @@@@@ @@@ @@@@@@ @@@@@%.....$@@@@@@~ @@@@@@ +++ ...%@@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@ @@@ @@@@@ @@@ @@@@@ @@@@@%.....$@@@@@@ @@@@@@ ++++ ...%@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@@@@ @@@@@@@@ @@@@@ @@@@@%......@@@@@@ @@@@@@ ++++ ...@@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@@@@ @@@@@@@@ @@@@@ @@@@@%......,@@@@@@ @@@@@@ +++ ...#@@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@@@@@ @@@@@ @@@@@ ", +" @@@@@@@@ @@@@@@@ @@@@@@ @@@@@%.....+~@@@@@@ @@@@@ +++ ...$@@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@@@ @@@@@@@ @@@@@@ @@@@@%.....+'@@@@@@@ @@@@@@'++ ...>@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@@@@@ @@@@@ @@@@@ ", +" @@@@@@ @@@@@@ @@@@@@ @@ @@@@@%....+++~@@@@@@@ @ @@@@@&+ ..$@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@@ @ @@@@@@ @@@@@ @@@@@ ", +" @@@@@@ @@@@@@ @@@@@@@ @@@@ $@@@@@%...+++++ @@@@@@@ @@@ @@@@@& ..$)@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@@@ @@@ @@@@@@@ @@@@@ @@@@@ ", +" @@@@@ @@@@@ @@@@@@@@@@@@@@@@@ %@@@@@@!$+++++ @@@@@@@@@@@@@@@@ @@@@@ $%@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@@@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@ @@@@@ ", +" @@@@ @@@@@ @@@@@@@@@@@@@ @@@@@@@@@@@@#+++ @@@@@@@@@@@@@ @@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@@@ ", +" @@@@ @@@@ @@@@@@@@ @@@@@@@@@@@@#++ @@@@@@@ @@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@ @@@@@@ @@@@@@@@ ", +" .........+++++ $$. ", +" ..........+++++ ... ", +" ..........+++++ .. ", +" .........+++++ . ", +" ..........++++ ", +" ..........+++++ ", +" ..........+++++ ", +" ..........++++ ", +" ..........+++++ ", +" @@@@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@@.$@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@ ", +" @@@@@@@@@@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@@.$@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@ ", +" @@@@@@@@ @@@@@ @@@@@@@ @@@@%%%.;%%=@@@@@@@ @@@ @@@@@@ @@@ ", +" @@@@@@ @@@@ @@@@@@@@ @@@!......++&@@@@@ @@@ @@@@@ @@@ ", +" @@@@@@ @@@ @@@@@@@@@ @@@$.....+++&@@@@@ @@@ @@@@@ @@@ ", +" @@@@@@ @@@ @@@@@@@@@ .@@@$.....+++&@@@@@ @@@ @@@@@ @@ ", +" @@@@@@ @@@ @@@ @@@@@@ ..@@@$....++++&@@@@@ @@@ @@@@@ @@ ", +" @@@@@@ @@@ @@@ @@@@@@ ...@@@$...+++++ @@@@@ @@@ @@@@@ ", +" @@@@@@ @@@ @@@ @@@@@@ ...@@@$...++++ @@@@@ @@@ @@@@@ @@ @@@@ @ @@@@ ", +" @@@@@@ @@@ @@@@@@ ....@@@$..+++++ @@@@@ @@@ @@@@@ @@@@ @@@@@@@@ @@@@@@@ @@@@@@@@@@@@ @@@@@@@@@ @@@@@@@@@@@@ ", +" @@@@@@ @@@ @@@@@@ .....@@@$.+++++ @@@@@ @@@ @@@@@ @@ @@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@ @@@@@ @@@@@@@ @@@@@@ @@@@ @@@@@ @@@@@ ", +" @@@@@@ @@@ @@@@@@ .....@@@$.++++ @@@@@ @@@ @@@@@ @@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@ @@@@@ @@@@@@ @@@@@ @@@@@ @@@@@ @@@ ", +" @@@@@@ @@@ @@@@@@ ......@@@$+++++ @@@@@ @@@ @@@@@ @@ @@@@@@ @@@@@@@@@ @@@@@@ @@@@@ @@@@@ @@@@@ @@@@@ @@@@ @@@ ", +" @@@@@@@ @@@ @@@@@@ ......@@@#++++ @@@@@ @@@ @@@@@ @@ @@@@@ @@@@@@ @@@@@ @@@@@@ @@@@@ @@@@@ @@@@@ @@@@@ @@@ ", +" @@@@@@@ @@@ @@@@@@)......@@@#+++ @@@@@ @@@ @@@@@@@@@@@@@@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@ @@@@@ @@@@@ @@@ ", +" @@@@@@@ @@@ @@@@@@!.....@@@#+++ @@@@@ @@@ @@@@@@@@@@@@@@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@ @@@@ @@@@@@ ", +" @@@@@@@ @@@@@@@@@@@@@@ @@@ @@@@@@@#....@@@#++ @@@@@ @@@ @@@@@@@@@@@@@@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@@ ", +" @@@@@@@ @@@@@@@@@@@@@@ @@@ @@@@@@>....@@@#+ @@@@@ @@@ @@@@@ @@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@@ ", +" @@@@@@ @@@@@@@ @@@ @@@@@@!...@@@#+ @@@@@ @@@ @@@@@ @@ @@@@@ @@@@@ @@@@@@ @@@@@@@@@@ @@@@@@ @@@@@@@@@ ", +" @@@@@@ @@@@@ @@@ @@@@@@@#.+@@@# @@@@@ @@@ @@@@@ @@ @@@@@ @@@@@ @@@@@@ @@@@@@@ @@@@@@ @@@@@@ @@@@@@@@@ ", +" @@@@@@ @@@@@ @@@ @@@@@@>++@@@ @@@@@ @@@ @@@@@ @@ @@@@@ @@@@@ @@@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@@@@@ ", +" @@@@@@ @@@@@ @@@ >@@@@@@~+@@@ @@@@@ @@@ @@@@@ @@@@@ @@@@@ @@@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@@@@ ", +" @@@@@@ @@@@@ @@@ .;@@@@@@@'@@@ @@@@@ @@@ @@@@@ @@@@@ @@@@@ @@@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@@@ ", +" @@@@@@ @@@@@ @@@ ..&@@@@@@,@@@ @@@@@@ @@@ @@@@@ @@@@@ @@@@@ @@@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@@ @@@@@ @@@ ...)@@@@@@@@@ @@@@@@ @@ @@@@@ @@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@ ", +" @@@@@@ @@@@@ @@@ ....;@@@@@@@@@ @@@@@@ @@@ @@@@@ @@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@ @@ @@@@@@ ", +" @@@@@@ @@@@@ @@@ .....=@@@@@@@@ @@@@@@ @@@ @@@@@ @@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@@ @@ @@@@@ ", +" @@@@@@ @@@@@ @@@ .....++*@@@@@@@ @@@@@@@ @@@ @@@@@ @@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@ @ @@ @@@@@ ", +" @@@@@@@ @@@@@ @@@ .....++#@@@@@@@ @@@@@@@ @@@@ @@@@@ @@@ @@@@@ @@@@@ @@@@@@ @@@@@@ @@@@@@@@ @@@@@@@ @@@ @@@ @@@@ ", +" @@@@@@@@@@ @@@@@ @@@@ ....++++&@@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@ @@@@ @@@@@@ @@@@@@ @@@@@@ @@@@@@@@@@@ @@@@@@ @@@@@@@@@@@@@@@@ @@@@ @@@@@ ", +" @@@@@@@@@@@@@@@@@ @@@@@@@@@@ ....+++++ @@@@@ @@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@ @@@@@@@@ @@@@@@@@@@@@@ @@@@@@@@@@@@@ ", +" @@@@@@@@@@@ @@@@@@@@@@ ....+++++ @@@@@ @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@@ ", +" ...+++++ ", +" ...+++++ ", +" ...++++ ", +" ...+++++ ", +" .. ++++ ", +" ..++++ ", +" .. ++++ ", +" . ++++ ", +" +++ ", +" . +++ ", +" +++ ", +" ++ ", +" ++ ", +" ++ ", +" + ", +" ", +" + ", +" ", +" ", +" ", +" "}; diff --git a/lisp/ChangeLog b/lisp/ChangeLog index faabcbd7430..436816a381d 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,18 @@ 2000-09-19 Gerd Moellmann + * gnus/: Update to emacs-21-branch of the Gnus CVS repository. + * gnus/binhex.el, gnus/flow-fill.el, gnus/format-spec.el + * gnus/gnus-ml.el, gnus/gnus-mlspl.el, gnus/ietf-drums.el, + * gnus/imap.el, gnus/mail-parse.el, gnus/mail-prsvr.el, + * gnus/mail-source.el, gnus/mailcap.el, gnus/mm-bodies.el, + * gnus/mm-decode.el, gnus/mm-encode.el, gnus/mm-partial.el, + * gnus/mm-util.el, gnus/mm-uu.el, gnus/mm-view.el, + * gnus/mml.el, gnus/nnimap.el, gnus/nnslashdot.el, + * gnus/nnultimate.el, gnus/nnwarchive.el, gnus/qp.el, + * gnus/rfc1843.el, gnus/rfc2045.el, gnus/rfc2047.el, + * gnus/rfc2104.el, gnus/rfc2231.el, gnus/time-date.el, + * gnus/utf7.el, gnsu/uudecode.el, gnus/webmail.el: New files. + * startup.el (fancy-splash-text): New variable. (fancy-splash-delay, fancy-splash-image): New user-options. (fancy-splash-insert, fancy-splash-head, fancy-splash-tail) diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 2cedb272a88..b81160b20de 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3730 +1,9046 @@ -2000-06-19 Gerd Moellmann +2000-09-14 Dave Love - * gnus-uu.el (gnus-uu-default-view-rules): Don't use `xv'. + * gnus.el (gnus-charset): + * mm-decode.el (mime-display): + * imap.el (imap) : Add :version. + +2000-09-13 Gerd Moellmann + + * parse-time.el: Fix author's mail address. + + * earcon.el, flow-fill.el, gnus-cite.el, gnus-gl.el, gnus-ml.el: + * gnus-mlspl.el, gnus-nocem.el, gnus-range.el, gnus-salt.el: + * gnus-setup.el, gnus-soup.el, gnus-undo.el, gnus-vm.el: + * messcompat.el, nnbabyl.el, nndir.el, nneething.el: + * nngateway.el, nnheaderxm.el, nnkiboze.el, nnlistserv.el: + * nnmbox.el, nnmh.el, nnoo.el, nnsoup.el, nnspool.el, rfc2045.el: + * rfc2231.el, uudecode.el: Fix copyright notice. + + * nnweb.el (toplevel): To make the file bootstrap in Emacs, + require `w3' at load-time only if not running in batch mode. + +2000-09-13 Dave Love + + * gnus-ems.el (gnus-ems-redefine): Don't alias + gnus-summary-set-display-table. + + * message.el (message-user-agent): Don't wrap ignore-errors around + it. + + * mm-encode.el (mm-insert-multipart-headers): Avoid redundant + `format'. + (mm-content-transfer-encoding): Don't use cadar. + + * uudecode.el (uudecode-decoder-program) + (uudecode-decoder-switches): Customize. + + * gnus-score.el (gnus-home-score-file): Improve custom type. + + * gnus-cus.el (gnus-custom-mode): Conditionally set local + variables for Emacs 21. + (gnus-group-customize): Disable undo while laying out the buffer. + +2000-09-13 ShengHuo ZHU + + * gnus-util.el (gnus-write-active-file): Bind + coding-system-for-write. + + * nnmail.el (nnmail-get-new-mail): Don't test nnmail-spool-file. + + * gnus-cache.el (gnus-jog-cache): Temporarily disable mail-sources. + * gnus-kill.el (gnus-batch-score): Ditto. + * gnus-move.el (gnus-change-server): Ditto. + * nnkiboze.el (nnkiboze-generate-groups): Ditto. + +2000-09-12 Simon Josefsson + + * gnus-sum.el (gnus-update-read-articles): Undo + `gnus-request-set-mark' operation. + +2000-09-11 Dave Love + + * Changelog: Use iso-2022 coding. + + * gnus-msg.el (gnus-msg-mail): New function. + (gnus-user-agent): New mail agent. + +2000-09-10 Dave Love + + * message.el: Require mail-abbrevs for XEmacs for a problem with + keybinding despite the autoloads for it. + +2000-09-08 Simon Josefsson + + * imap.el (imap-kerberos4-open): Erase more (fixes race condition?). + + * nnimap.el (nnimap-request-update-info-internal): Remove tick + marks from dormant articles. (See nnimap-request-set-mark.) + (nnimap-retrieve-headers-progress): Demule. + (nnimap-open-server): Call nnoo-change-server twice, once for + getting the nnimap-server-buffer and once for letting n-c-s set + the variables in that buffer. + +2000-09-08 David Edmondson + + * gnus.el (gnus-short-group-name): Guess separator. + +2000-09-06 Francis Litterio + + * gnus-group.el (gnus-group-insert-group-line): Fix. + +2000-09-04 Dave Love + + * mm-decode.el (mime-display) : Add `multimedia' group. + (mm-get-image): Avoid the losing `make-glyph' from W3. + +2000-09-03 Simon Josefsson + + * gnus-sum.el (gnus-summary-delete-article): Check server. + +2000-09-01 Simon Josefsson + + * imap.el (imap-parse-flag-list): Rewrite. + + * nnimap.el (nnimap-retrieve-headers-from-file): Ignore errors. + + * imap.el (imap-parse-flag-list): Hack. + +2000-08-29 Dave Love + + * gnus-mlspl.el (gnus-group-split-fancy): Eschew mapcon. + + * gnus-agent.el (gnus-agent-union): new function. + (gnus-agent-fetch-headers): Use it. + + * gnus.el (gnus-group-startup-message): Specify foreground and + background for xpm image. Centre image vertically. + From Katsumi Yamaoka with mods. + +2000-08-25 ShengHuo ZHU + + * message.el (message-send-mail): Narrow-to-headers. + +2000-08-24 Dave Love + + * gnus-art.el (gnus-insert-mime-button): Fix help-echo for Emacs + 21. + +2000-08-21 Dave Love + + * nnimap.el (nnimap-request-newgroups): Eschew member-if. + +2000-08-21 ShengHuo ZHU + + * gnus-topic.el (gnus-topic-hide-topic): Use find-topology if + permanent is used. + (gnus-topic-show-topic): Read topic when to show permanent hidden + topic. + (gnus-topic-remove-topic): Revert to the old behavior, not using + hide. + +2000-08-21 Dave Love + + * gnus-ems.el (gnus-add-minor-mode): Add &rest arg. + (gnus-xemacs): Use featurep. + + * mm-util.el (mm-read-charset): Maybe use builtin. + (mm-replace-chars-in-string): Maybe use subst-char-in-string. + (mm-multibyte-p, mm-with-unibyte-current-buffer) + (mm-with-unibyte): Use featurep, not string-match. + (mm-with-unibyte-buffer): Simplify. + (mm-quote-arg): Maybe use shell-quote-argument. + + * mml.el (mml-make-string): Deleted (unused). + + * gnus.el (gnus-mode-line-buffer-identification): Supply + definition for Emacs 21. + + * gnus-salt.el: Small doc fixes. + (gnus-pick-mode, gnus-binary-mode): Supply a toggle-func arg to + gnus-add-minor-mode. + + * gnus-topic.el (gnus-topic-mode): Supply a toggle-func arg to + gnus-add-minor-mode. + +2000-08-20 Simon Josefsson + + * nnimap.el (nnimap-before-find-minmax-bugworkaround): New + function, thanks to Lloyd Zusman for debugging. + (nnimap-request-group): + (nnimap-request-list): + (nnimap-retrieve-groups): + (nnimap-request-newgroups): Use it. + + * nnimap.el (nnimap-request-article-part): Less verbose. + +2000-08-18 Dave Love + + * gnus-score.el (gnus-score-find-score-files-function): Fix doc, + custom type. + + * nnheader.el (nnheader-replace-chars-in-string): Use + subst-char-in-string if available. + + * gnus-art.el (gnus-read-save-file-name, gnus-plain-save-name) + (gnus-request-article-this-buffer): Use expand-file-name. + (gnus-mime-view-part-as-type): Simplify interactive spec. + (gnus-mime-button-map): Define it all in defvar. + +2000-08-17 Dave Love + + * gnus-group.el (gnus-group-running-xemacs): Deleted. + + * gnus-demon.el (gnus-demon): Bind use-dialog-box and + last-nonmenu-event. + + * uudecode.el (char-int): Use defalias, not fset. + + * score-mode.el: Don't require easymenu. Require mm-util. + (score-mode-coding-system): Use mm-auto-save-coding-system. + + * nneething.el (nneething-create-mapping): Don't use cadar & al. + (nneething-file-name): Use expand-file-name, not concat. + +2000-08-16 ShengHuo ZHU + + * nnslashdot.el (nnslashdot-threaded-retrieve-headers): + Failure proof for email addresses. + (nnslashdot-sane-retrieve-headers): Ditto. + +2000-08-14 Lars Magne Ingebrigtsen + + * message.el (message-send-mail): Only insert courtesy message + when text/plain. + +2000-08-14 Jesper Harder + + * message.el (message-cancel-news): Copy the From header from the + original article. + +2000-08-14 Lars Magne Ingebrigtsen + + * gnus-async.el (gnus-asynchronous): Removed. + +2000-08-14 ShengHuo ZHU + + * mail-source.el (mail-source-fetch-maildir): Use MMDF mail + format. + +2000-08-14 Rod Whitby + + * nnmail.el (nnmail-expiry-target-group): Fixed. + +2000-08-14 Rod Whitby + + * nnmail.el (nnmail-expiry-target-group): Fix the call to + gnus-request-accept-article so that body encoding is *not* done. + Encoding is not done on incoming mail, so why should it be done on + expired mail? + + +2000-08-14 Rod Whitby + + * nnml.el (nnml-request-expire-articles): Fix the calls to + nnml-request-article (the filename was being passed instead of the + article number) and nnmail-expiry-target-group + (nnml-current-directory is changed by nnml-request-accept-article, + causing it to be incorrect for the next article to be expired). + +2000-08-14 Rod Whitby + + * gnus-sum.el (gnus-summary-expire-articles): Fix the handling of + expiry-target group parameters. + +2000-08-13 Lars Magne Ingebrigtsen + + * gnus-topic.el (gnus-topic-select-group): Touch the dribble + buffer. + (gnus-topic-hide-topic): Take a PERMANENT parameter. + (gnus-topic-show-topic): Ditto. + + * gnus-dup.el (gnus-dup-suppress-articles): Do auto-expiry. + +2000-08-12 John H. Palmieri + + * mail-source.el (mail-source-incoming-file-prefix): New + variable. + +2000-08-12 Lars Magne Ingebrigtsen + + * gnus-start.el (gnus-check-first-time-used): Clean up a bit. + + * mailcap.el (mailcap-maybe-eval): Be even more warning. + +2000-08-11 Florian Weimer + + * message.el (message-syntax-checks): New check quotin-style: + Text must be written below quoted text. + (message-check-news-body-syntax): Check it. + +2000-08-11 Simon Josefsson + + * imap.el (imap-authenticator-alist): Fix typo. + (imap-gssapi-open): Copy krb4 fixes for modern imtest's, thanks to + Jonas Oberg for debugging. + +2000-08-11 Simon Josefsson + + * gnus-async.el (gnus-asynchronous): Disable by default. + +2000-08-10 Lars Magne Ingebrigtsen + + * mm-view.el (mm-inline-text): Bind fill-column. + + * nnvirtual.el (nnvirtual-request-expire-articles): Return the + list of unexpired articles. + + * gnus-group.el (gnus-group-expire-articles-1): Return the list of + un-expired articles. + + * gnus-sum.el (gnus-summary-reparent-thread): Narrow to the + headers. + + * gnus-topic.el (gnus-topic-kill-group): Move up one line so that + we update the right topic.. + + * mm-decode.el (mm-display-external): Put point at start. + +2000-08-10 Kai Gro,A_(Bjohann + + * nnmail.el (nnmail-expiry-target): More explicit documentation. + + * gnus-cus.el (gnus-group-parameters): Add parameter `expiry-wait'. + +2000-08-09 Simon Josefsson + + * imap.el (imap-parse-body): + (imap-parse-string-list): Add bug workarounds for Stalker + Communigate Pro 3.0 server. + (imap-body-lines): Remove bogus comment. + + * imap.el (imap-range-to-message-set): Move from nnimap.el. + + * nnimap.el (nnimap-retrieve-which-headers): + (nnimap-retrieve-headers-from-server): + (nnimap-request-set-mark): + (nnimap-request-expire-articles): Use `i-r-t-m-set' instead. + +2000-08-08 ShengHuo ZHU + + * message.el (message-dont-reply-to-names): + rmail-dont-reply-to-names may not be defined. + +2000-08-07 ShengHuo ZHU + + * gnus-group.el (gnus-group-iterate): Uncompiled function should + not use pop. + +2000-07-19 Dave Love + + * gnus-ems.el: Defalias some dummy funcs to `ignore'. + (gnus-x-splash): Use expand-file-name. Remove redundant facep + check. + (gnus-article-display-xface): Special-case for dark backgrounds. + +2000-07-19 Kim-Minh Kaplan + + * imap.el (imap-calculate-literal-size-first): New variable. + (imap-local-variables): Add it. + (imap-kerberos4-open): Set it. + (imap-send-command): Use it. + +2000-07-17 ShengHuo ZHU + + * mailcap.el (mailcap-mimetypes-parsed-p): New variable. + (mailcap-parse-mimetypes): Use it. + (mailcap-extension-to-mime): Parse mimetype. + (mailcap-mime-types): Ditto. + * mml.el (mml-minibuffer-read-type): Ditto. + +2000-07-16 ShengHuo ZHU + + * nndoc.el (nndoc-type-alist): Add outlook. + (nndoc-outlook-type-p): New function. + (nndoc-outlook-article-begin): Ditto. + +2000-07-16 Daiki Ueno + + * gnus-sum.el (gnus-restore-hidden-threads-configuration): Save + excursion. + +2000-07-15 Simon Josefsson + + * gnus-cus.el (gnus-group-parameters, banner): Type is regexp. + + * imap.el (imap): + (imap-kerberos4-program): + (imap-gssapi-program): + (imap-ssl-program): Customization. + (imap-shell-program): + (imap-shell-host): New variables. + (imap-streams): + (imap-stream-alist): Add shell. + (imap-shell-p): + (imap-shell-open): New functions. + (imap-open): Don't call authenticator if preauth. + (imap-authenticate): Return t if already authenticated. + +2000-07-14 Simon Josefsson + + * gnus.el (gnus-invalid-group-regexp): New variable. + (gnus-read-group): Use it. + +2000-07-14 ShengHuo ZHU + + * gnus-agent.el (gnus-agent-fetch-group-1): mark-below, + expunge-below and orphan-score are "group variables". + +2000-07-13 Simon Josefsson + + * gnus-srvr.el (gnus-browse-read-group): Don't pass fully + qualified group names to `gnus-group-read-ephemeral-group'. + +2000-07-12 ShengHuo ZHU + + * gnus-sum.el: `W t' is toggle-header in info. + +2000-07-12 ShengHuo ZHU + + * gnus-art.el (article-de-base64-unreadable): Typo. + +2000-07-12 Simon Josefsson + + * gnus-agent.el (require): Require timer. + +2000-07-11 ShengHuo ZHU + + * message.el (message-bounce): Call mime-to-mml. + +2000-07-11 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-request-close): New function. + +2000-07-05 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-threaded-retrieve-headers): Get the + right line number for the article. + +2000-07-11 ShengHuo ZHU + + * nnslashdot.el (nnslashdot-threaded-retrieve-headers): Save point. + * webmail.el (webmail-fetch): Bind + url-http-silence-on-insecure-redirection. + +2000-07-10 ShengHuo ZHU + + * nnslashdot.el (nnslashdot-threaded-retrieve-headers): Use + unibyte. + (nnslashdot-sane-retrieve-headers): Ditto. + (nnslashdot-request-article): Ditto. + +2000-07-10 William M. Perry + + * mailcap.el (mailcap-parse-mimetype-file): + +2000-07-08 ShengHuo ZHU + + * nnweb.el (nnweb-insert): Stricter test. + * webmail.el (webmail-refresh-redirect): Ditto. + +2000-07-06 ShengHuo ZHU + + * mm-decode.el (mm-dissect-multipart): Match the EOL of boundary. + +2000-07-05 ShengHuo ZHU + + * nnheader.el (nnheader-insert-nov): Remove EOLs of all fields. + +2000-07-05 Dave Love + + * utf7.el: Doc and header fixes. + + * gnus-sum.el: Doc fixes. + + * gnus-util.el (gnus-point-at-eol, gnus-point-at-bol): Use + defalias, not fset. + + * flow-fill.el (fill-flowed-point-at-eol) + (fill-flowed-point-at-bol): Use defalias, not fset. + + * gnus-art.el: Don't alias article-mime-decode-quoted-printable. + (gnus-Plain-save-name): Delete -- apparently bogus. + +2000-07-03 Lars Magne Ingebrigtsen + + * nnsoup.el: Use expand-file-name throughout. + +2000-07-03 Kjetil Torgrim Homme + + * nnmail.el (nnmail-read-incoming-hook): New example. + +2000-07-03 Lars Magne Ingebrigtsen + + * mm-view.el (mm-inline-text): Check whether the text has already + been decoded. + +2000-07-04 ShengHuo ZHU + + * nnslashdot.el (nnslashdot-sid-strip): To strip or not to strip? + +2000-07-03 Stainless Steel Rat + + * gnus-sum.el (gnus-recenter): Fix horizontal recenter. + +2000-07-03 Simon Josefsson + + * gnus-sum.el (gnus-update-marks): Don't propagate download and + unsend flags. + +2000-07-03 Simon Josefsson + + * nnimap.el (nnimap-open-connection): Don't look up virtual server + name in authinfo (.authinfo now support ports, no need for the + hack). + (nnimap-split-find-rule): Fix. + (nnimap-open-connection): Look for nnimap-server-address in authinfo. + +2000-07-03 Paul Stodghill + + * message.el (message-unquote-tokens): Remove all quotes. + +2000-07-03 Julien Gilles + + * gnus-ml.el: New file. + +2000-07-02 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-request-close): New function. + + * gnus-start.el (gnus-clear-system): Clear nnmail-split-history. + +2000-07-02 Lars Magne Ingebrigtsen + + * gnus.el: Gnus v5.8.7 is released. + +2000-05-19 Lars Magne Ingebrigtsen + + * mm-decode.el (mm-insert-part): Characters doubly decoded. + +2000-07-01 Shenghuo ZHU + + * message.el (message-do-fcc): Encode MIME. + +2000-06-28 Simon Josefsson + + * nnimap.el (nnimap-split-rule): Update doc with extended syntax. + (nnimap-assoc-match): New function. + (nnimap-split-find-rule): Support extended syntax. + +2000-06-28 Simon Josefsson + + * nnimap.el (nnimap-open-connection): Use port stuff. + + * gnus-util.el (gnus-netrc-machine): Add defaultport parameter, + document port and defaultport. + +2000-06-27 Paul Stodghill + + * gnus-agent.el (gnus-agent-synchronize): Kill flags buffer. + +2000-06-26 Dave Love + + * mm-decode.el (mm-image-fit-p): Use `image-size' in Emacs. + + * message.el: Remove unnecessary `require'ments. Defvar + gnus-list-identifiers when compiling. Don't try to autoload + variable `gnus-list-identifiers'. Autoload + gnus-group-name-charset. + (message-fetch-field): Don't assume `format' removes text + properties. + (message-strip-list-identifiers, message-reply, message-followup): + Require gnus-sum. + (message-mode): Tidy XEmacs conditionals. + (message-replace-chars-in-string): Use subst-char-in-string when + available. + + * gnus-art.el (gnus-article-edit-exit): Don't assume `format' + removes text properties. + + * gnus-srvr.el (gnus-browse-group-name): Likewise. + + * gnus-msg.el (gnus-copy-article-buffer): Likewise. + + * gnus-score.el (gnus-summary-score-entry): Likewise. + +2000-06-26 Katsumi Yamaoka + + * nnimap.el (nnimap-request-post): Fix parenthesis. + +2000-06-26 Paul Stodghill + + * message.el (message-unquote-tokens): New function. + + * gnus-msg.el (gnus-inews-do-gcc): Unquote gcc tokens. + + * nnimap.el (nnimap-request-post): Ditto. + +2000-06-21 Simon Josefsson + + * gnus.el (gnus-asynchronous): Removed (defined in gnus-async.el). + + * nnimap.el (nnimap-callback): Update for IMAP4rev1 servers (see + patch commited 2000-04-02). + +2000-06-20 Simon Josefsson + + * imap.el (imap-mailbox-examine-1): New function. + (imap-message-copyuid-1): + (imap-message-appenduid-1): Use it, instead of + `imap-mailbox-examine' which would utf-7 encode mailbox name + twice. + +2000-06-19 Dave Love + + * mm-uu.el Don't require message. Require cl when compiling. + +2000-06-17 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-local-variables): gnus-orphan-score is + a local variable. + * gnus-sum.el (gnus-orphan-score): Move here. + +2000-06-10 Shenghuo ZHU + + * message.el (message-forward): Remove show-mml condition. + (message-forward-ignored-headers): Remove X-Gnus headers. + +2000-06-08 Simon Josefsson + + * gnus-cus.el (gnus-extra-group-parameters): Add uidvalidity. + +2000-06-08 Urban Engberg + + * gnus-demon.el (gnus-demon-scan-mail): Bind nnmail-fetched-sources. + +2000-06-08 Shenghuo ZHU + + * message.el (message-syntax-checks): Add type. + +2000-06-07 Dave Love + + * mm-view.el (mm-inline-image-emacs): Don't specify string for + put-image. + (mm-inline-image): Defalias, not fset. + + * gnus.el (gnus-group-startup-message): Don't specify string for + insert-image. + + * gnus-ems.el (gnus-add-minor-mode): Make it an alias if + add-minor-mode is available. + (gnus-article-display-xface): Don't specify string for + insert-image. + +2000-06-06 Shenghuo ZHU + + * gnus-topic.el (gnus-topic-remove-topic): Set hidden. + (gnus-topic-insert-topic-line): Use shownp. + (gnus-topic-hide-topic): Don't use hidden. + (gnus-topic-show-topic): Don't use hidden. + +2000-06-06 Shenghuo ZHU + + * gnus-cache.el (gnus-cache-possibly-enter-article): Bind coding + system. + * gnus-soup.el (gnus-soup-write-prefixes): Ditto. + * gnus-start.el (gnus-slave-save-newsrc): Ditto. + * gnus-util.el (gnus-output-to-rmail): Ditto. + (gnus-output-to-mail): Ditto. + (gnus-write-buffer): Ditto. + * gnus-uu.el (gnus-uu-save-article): Ditto. + +2000-06-04 Shenghuo ZHU + + * message.el (message-read-from-minibuffer): Typo. + +2000-06-03 Shenghuo ZHU + + * gnus-art.el (article-decode-charset): Override non-MIME forward + charset. + +2000-06-02 Shenghuo ZHU + + * mml.el (mml-quote-region): Correct the regexp. + * gnus-msg.el (gnus-summary-reply): mml-quote it. + +2000-06-02 Shenghuo ZHU + + * message.el (message-forward): Insert raw text. + * mml.el (mml-parse-1): Get raw text in unibyte mode. + (mml-generate-mime-1): Insert raw text in unibyte mode. + +2000-06-01 Florian Weimer + + * mm-bodies.el (mm-body-encoding): Always encoded if + `mm-use-ultra-safe-encoding' is set. + +2000-05-31 Shenghuo ZHU + + * mml.el (ange-ftp-name-format): Typo. + +2000-05-30 Simon Josefsson + + * gnus-start.el (gnus-get-unread-articles): If + `gnus-activate-group' and/or `gnus-check-server' return nil, don't + try to do anything on that server. + +2000-05-25 Simon Josefsson + + * gnus-group.el (gnus-group-nnimap-edit-acl): Help text updated + from latest draft. + +2000-05-08 Simon Josefsson + + * gnus-group.el (gnus-group-expire-articles-1): Make sure server + is open. + +2000-05-24 Dave Love + + * mml.el (mml-parse-file-name): Fix ange-ftp part. + +2000-05-22 Didier Verna + + * gnus.el (gnus-redefine-select-method-widget): new function, call + it once. Add an "other" entry for unknown but editable backend + name symbols. + * gnus-start.el (gnus-declare-backend): use it. + +2000-05-19 Dave Love + + * gnus-art.el (gnus-article-next-page): Revert last change. + +2000-05-19 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-open-history): Open history in binary mode. + +2000-05-19 Dave Love + + * gnus-art.el (gnus-mime-externalize-part): Bind mm-inlined-types, + not mm-inline-large-images. + +2000-05-19 Shenghuo ZHU + + * mml.el (mml-parse-1): Don't test multiple-charsets within mml tag. + +2000-05-18 Dave Love + + * gnus-art.el: Use defalias, not fset. + (gnus-article-x-face-command): Don't test for xbm. + (gnus-article-next-page): Redisplay before testing point in window. + +2000-05-17 Shenghuo ZHU + + * gnus-group.el (gnus-group-mode-map): Add M-SPACE. + * mml.el (mml-mode-map): Comment out mml-narrow-to-part. + +2000-05-17 Jim Davidson + + * gnus-sum.el (gnus-summary-save-article-rmail): Use + gnus-summary-save-in-rmail. + * message.el (message-output): Ditto. + +2000-05-18 Katsumi Yamaoka + + * gnus-art.el (gnus-emphasize-whitespace-regexp): Doc fix. + +2000-05-17 Shenghuo ZHU + + * rfc2047.el (rfc2047-encode-message-header): Encode if the method + is a charset. + * message.el (message-send-news): Check group name charset. + * gnus-msg.el (gnus-post-news): Decode group name. + (gnus-inews-do-gcc): Encode group name. + +2000-05-17 Karl Kleinpaste + + * gnus-art.el (gnus-emphasize-whitespace-regexp): New variable. + * gnus-util.el (gnus-put-text-property-excluding-newlines): Use it. + +2000-05-17 Shenghuo ZHU + + * gnus-group.el (gnus-group-mark-line-p): New function. + (gnus-group-goto-group): New parameter. + (gnus-group-remove-mark): Use it. + * gnus-topic.el (gnus-topic-move-group): Ditto. + (gnus-topic-remove-group): Ditto. + +2000-05-17 Shenghuo ZHU + + * gnus-group.el (gnus-group-list-dormant): New function. + +2000-05-17 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-synchronize): Use + nnheader-insert-file-contents. + (gnus-agent-save-active-1): Ditto. + (gnus-agent-write-active): Ditto. + (gnus-agent-expire): Ditto. + * gnus-cache.el (gnus-cache-read-active): Ditto. + * gnus-start.el (gnus-master-read-slave-newsrc): Ditto. + * gnus-sum.el (gnus-summary-import-article): Ditto. + + * gnus-agent.el (gnus-agent-write-servers): Bind coding-system. + (gnus-agent-save-group-info): Ditto. + (gnus-agent-save-alist): Ditto. + * gnus-util.el (gnus-make-directory): Ditto. + + * gnus-agent.el (gnus-agent-save-group-info): Disable multibyte. + +2000-05-16 Shenghuo ZHU + + * mml.el (mml-generate-mime-preprocess-function): New variable. + (mml-generate-mime-postprocess-function): New variable. + (mml-generate-mime-1): Use them. + +2000-05-16 Shenghuo ZHU + + * gnus-group.el (gnus-group-apropos): Group name charset. + * gnus-sum.el (gnus-set-mode-line): Ditto. + * gnus-group.el (gnus-group-decoded-name): New function. + (gnus-group-edit-group): Use it. + * gnus-cus.el (gnus-group-customize): Use it. + +2000-05-16 Karl Kleinpaste + + * gnus-util.el (gnus-put-text-property-excluding-newlines): Improve. + +2000-05-16 Shenghuo ZHU + + * gnus-group.el (gnus-group-name-charset-method-alist): New variable. + (gnus-group-name-charset-group-alist): Ditto. + (gnus-group-name-charset): New function. + (gnus-group-name-decode): New function. + (gnus-group-insert-group-line): Use them. + (gnus-group-prepare-flat-list-dead): Ditto. + (gnus-group-list-active): Ditto. + (gnus-group-describe-all-groups): Ditto. + (gnus-group-prepare-flat-list-dead-predicate): Ditto. + * gnus-srvr.el: (gnus-browse-foreign-server): Decode group name and + add gnus-group property. + (gnus-browse-group-name): Read gnus-group property. + +2000-05-16 Shenghuo ZHU + + * nnfolder.el (nnfolder-possibly-change-group): Use + file-name-coding-system instead of pathname-coding-system. + * nnmail.el (nnmail-find-file): Ditto. + (nnmail-write-region): Ditto. + * nnmh.el (nnmh-retrieve-headers): Ditto. + (nnmh-request-article): Ditto. + (nnmh-request-group): Ditto. + (nnmh-request-list): Ditto. + (nnmh-possibly-change-directory): Ditto. + (nnmh-active-number): Ditto. + * nnml.el (nnml-possibly-change-directory): Ditto. + (nnml-request-list): Ditto. + (nnml-request-article): Ditto. + (nnml-retrieve-headers): Ditto. + +2000-05-16 Simon Josefsson + + * nnimap.el (nnimap-request-accept-article): Don't unselect + mailbox if no mailbox is selected. + +2000-05-15 Per Abrahamsen + + * gnus-art.el (gnus-button-url-regexp): Revert earlier change. + Recognize domain names starting with `www.' as starting an URL. + +2000-05-15 Shenghuo ZHU + + * mail-source.el (mail-source-fetch-maildir): Insert "From ". + (mail-source-keyword-map): Add "subdirs" for maildir. + +2000-05-14 Shenghuo ZHU + + * nnmail.el (nnmail-scan-directory-mail-source-once): New variable. + (nnmail-get-new-mail): Use it. + * gnus-start.el (gnus-get-unread-articles): Ditto. + +2000-05-14 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-edit-article): Better support for + nndraft:drafts. + * nndraft.el (nndraft-request-replace-article): New function, + bind nnmail-file-coding-system. + +2000-05-14 Dave Love + + * nnheader.el: Replace uses of `fset' with `defalias'. + (jka-compr-compression-info-list): Only defvar when compiling. + +2000-05-14 Shenghuo ZHU + + * webmail.el (webmail-netaddress-article): Refresh redirect. + +2000-05-13 Shenghuo ZHU + + * mm-view.el (mm-inline-text): w3 might not recognize utf-8. + +2000-05-13 Shenghuo ZHU + + * webmail.el: Translate   to SP. + +2000-05-13 Robin S. Socha + + * message.el (message-bounce): Doc typo. + +2000-05-13 Shenghuo ZHU + + * gnus-soup.el (gnus-soup-encoding-type): u is USENET news format. + (gnus-soup-store): Ditto. + (gnus-soup-send-packet): Ditto. + * nnsoup.el (nnsoup-replies-format-type): Ditto. + (nnsoup-dissect-buffer): Ditto. + (nnsoup-narrow-to-article): Ditto. + (nnsoup-make-active): Ditto + +2000-05-13 Shenghuo ZHU + + * message.el (message-mode): Two parameters for local-variable-p. + +2000-05-13 Shenghuo ZHU + + * message.el (message-strip-list-identifiers): New function. + (message-reply): Use it and use message-strip-subject-re. + (message-followup): Ditto. + * gnus-art.el (article-hide-list-identifiers): Remove more. + * gnus-sum.el (gnus-summary-remove-list-identifiers): Ditto. + +2000-05-13 Shenghuo ZHU + + * gnus-uu.el (gnus-uu-digest-mail-forward): Bind + mail-parset-charset and use non-numeric argument. + +2000-05-12 Shenghuo ZHU + + * mml.el (mml-buffer-list): New variable. + (mml-generate-new-buffer): New function. + (mml-destroy-buffers): Ditto. + (mml-insert-mime): Use them. + * gnus-msg.el (gnus-setup-message): mml-buffer leaks. + * gnus-sum.el (gnus-summary-edit-article): Ditto. + * message.el (message-mode): Ditto. + * gnus-uu.el (gnus-uu-digest-headers): Keep MIME headers. + (gnus-uu-save-article): Support show-as-mml. + * message.el (message-forward): Ditto. + +2000-05-12 Shenghuo ZHU + + * nndoc.el (nndoc-type-alist): mime-digest head-begin. + (nndoc-mime-digest-type-p): Locate article head precisely. + * mml.el (mml-generate-default-type): New variable. + (mml-generate-mime-1): Use it. + (mml-insert-mime-headers): Use it. + * gnus-uu.el (gnus-uu-digest-buffer): New variable. + (gnus-uu-digest-mail-forward): Use it and call message-forward + with argument digest. + (gnus-uu-save-article): Support message-forward-as-mime. + * message.el (message-forward): Add parameter digest. + * mm-decode.el (mm-dissect-default-type): New variable. + (mm-dissect-buffer): Use it. + +2000-05-11 Shenghuo ZHU + + * mml.el (mml-parse-singlepart-with-multiple-charsets): Set space, + newline and paragraph to nil when got a non-ascii character. Test + paragraph before newline. + +2000-05-10 Shenghuo ZHU + + * qp.el (quoted-printable-encode-region): Bind tab-width to 1. Set + limit to 76. + +2000-05-10 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-sid-strip): New function. + (nnslashdot-threaded-retrieve-headers): New format. + (nnslashdot-sane-retrieve-headers): Ditto. + (nnslashdot-request-article): Ditto. + (nnslashdot-threaded-retrieve-headers): Thread properly. + (nnslashdot-request-article): Be more lenient. + (nnslashdot-threaded-retrieve-headers): Regexp search. + +2000-05-09 Shenghuo ZHU + + * gnus-sum.el (gnus-with-article): Define it before use it. + +2000-05-09 Shenghuo ZHU + + * message.el (message-supersede): Use mime-to-mml. + * mm-decode.el (mm-insert-part): Test the buffer if no encoding. + +2000-05-09 Katsumi Yamaoka + + * gnus-group.el (gnus-group-list-cached): Don't use + `subst-char-in-string'. 2000-05-08 Dave Love - * pop3.el: Import changes from current Gnus. - (pop3-open-server): Bind coding systems before creating buffer and - fix creating its name. - (pop3-string-to-list): Function deleted. Change callers to use - split-string. + * pop3.el (pop3-open-server): Fix creating name of trace buffer. + +2000-05-08 Shenghuo ZHU + + * mm-decode.el (mm-interactively-view-part): Append %s if the + method is a single word. + * nnwarchive.el (nnwarchive-type-definition): Typo. + +2000-05-07 Shenghuo ZHU + + * gnus-group.el (gnus-group-prepare-flat-list-dead-predicate): New + function. + (gnus-group-prepare-flat-predicate): Use it. + (gnus-group-list-cached): List dead groups. + +2000-05-07 Shenghuo ZHU + + * gnus-art.el (article-decode-charset): Don't decode message with + format. + +2000-05-07 Florian Weimer + + * mailcap.el (mailcap-maybe-eval): Honor user request not to + evaluate the Lisp code. + +2000-05-06 Shenghuo ZHU + + * gnus-art.el (article-wash-html): New function. + (gnus-article-wash-html): Bind. + (gnus-article-make-menu-bar): Menu item. + * gnus-sum.el (gnus-summary-wash-map): Bind 'h'. + (gnus-summary-make-menu-bar): Menu item. + * gnus.el: Autoload. + +2000-05-06 Florian Weimer + + * gnus-uu.el (gnus-uu-unshar-warning): New variable. + (gnus-uu-unshar-article): Use it. + + * mailcap.el (mailcap-maybe-eval-warning): New variable. + (mailcap-maybe-eval): Use it. + + * gnus-msg.el (gnus-group-posting-charset-alist): Speling mistake + in docstring. + + * mml.el (mml-generate-mime-1): Small comment. + +2000-05-05 Shenghuo ZHU + + * gnus-art.el (article-de-base64-unreadable): New function. + (gnus-article-de-base64-unreadable): Bind. + (gnus-article-make-menu-bar): Menu item. + * gnus-sum.el (gnus-summary-wash-map): Bind '6' and 'Z'. + (gnus-summary-make-menu-bar): Menu item. + * gnus.el: Autoload. + +2000-05-05 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-show-article): Remove en/disable multibyte. + (gnus-summary-select-article): Add en/disable multibyte. + +2000-05-05 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-edit-article): Enable multibyte. + (gnus-summary-edit-article): New feature: editing raw articles. + +2000-05-05 Shenghuo ZHU + + * rfc2047.el (rfc2047-encode-region): Insert a space before encoding. + Emacs MULE can not encode adjacent iso-2022-jp and cn-gb-2312. + * gnus-msg.el (gnus-summary-mail-forward): Use unibyte buffer. + Emacs MULE can not copy some 8bit characters in multibyte buffers. + * mm-decode.el (mm-insert-part): Ditto. + +2000-05-04 Shenghuo ZHU + + * nndoc.el (nndoc-type-alist): Extend forward regexp. + (nndoc-forward-type-p): Ditto. + +2000-05-04 Shenghuo ZHU + + * mm-util.el (mm-with-unibyte-current-buffer): Set the default + value of enable-multibyte-characters. + +2000-05-04 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-show-article): En/disable multibyte. + +2000-05-03 Dave Love + + * gnus-ems.el (gnus-article-xface-ring-internal) + (gnus-article-xface-ring-size): New variable. + (gnus-article-display-xface): Use them to cache data. Don't try + to use XPM. Set up binary coding for PBM's sake. + +2000-05-03 Shenghuo ZHU + + * gnus-msg.el (gnus-inews-do-gcc): Set mail-parse-charset. + * gnus-int.el (gnus-request-accept-article): Ditto. + (gnus-request-replace-article): Ditto. + * mm-util.el (mm-mime-mule-charset-alist): Add a fake mule-charset. + +2000-05-03 Shenghuo ZHU + + * rfc2047.el (rfc2047-encode): Test the validity of coding-system. + +2000-05-03 Shenghuo ZHU + + * rfc2047.el (rfc2047-encode-message-header): Encode field by + field. + * mml.el (mml-to-mime): Use message-default-charset. + (mml-preview): Narrow to headers. + * message.el (message-send-mail): Use message-default-charset. + (message-send-news): Narrow to headers; + use message-default-charset. + +2000-05-03 Shenghuo ZHU + + * mm-bodies.el (mm-decode-content-transfer-encoding): A better junk + detect. + * mml.el (mml-parse-singlepart-with-multiple-charsets): Save + restriction. + (mml-parse-1): Warning message. + (mml-preview): Disable multibyte. + +2000-05-03 Dave Love + + * gnus.el (gnus-group-startup-message): Add newline before image. + +2000-05-02 Shenghuo ZHU + + * rfc2047.el (rfc2047-encode-message-header): Check the coding-system. + * message.el (message-send-mail): Use unibyte-buffer. + (message-send-mail): Ditto. + +2000-05-01 Lars Magne Ingebrigtsen + + * gnus.el: Gnus v5.8.6 is released. + +2000-05-01 Shenghuo ZHU + + * mml.el (mml-parse-1): Set no-markup-p and warn to nil. + +2000-04-28 Shenghuo ZHU + + * rfc2047.el (rfc2047-q-encoding-alist): Encode HTAB. + +2000-04-28 Shenghuo ZHU + + * message.el (message-send-mail-partially): Use forward-line. + +2000-04-28 Shenghuo ZHU + + * gnus-art.el (gnus-mime-button-menu): Use call-interactively. + +2000-04-28 Shenghuo ZHU + + * mml.el (mml-generate-mime-1): Ignore 0x1b. + (mml-insert-mime): No markup only for text/plain. + (mime-to-mml): Remove MIME headers. + +2000-04-28 Shenghuo ZHU + + * mml.el (mml-preview): Set gnus-newsgroup-charset. + * rfc2047.el (rfc2047-encode-message-header): Encode non-ascii + as 8-bit. + +2000-04-28 Dave Love + + * gnus.el (gnus-group-startup-message): Maybe use image in Emacs + 21. + + * mailcap.el (mailcap-parse-mailcaps): Revert last change to + search order. Use parse-colon-path and remove some redundancy. + Doc fix. + (mailcap-parse-mimetypes): Code consistently with + mailcap-parse-mailcaps. Doc fix. + + * gnus-start.el (gnus-unload): Iterate over `features', not + `load-history'. + +2000-04-28 Shenghuo ZHU + + * mml.el (mml-parse-1): Don't create blank parts. + (mml-read-part): Fix mml tag. + (mml-insert-mime): Convert message/rfc822. + (mml-insert-mml-markup): Add mmlp parameter. + +2000-04-28 Shenghuo ZHU + + * message.el (message-send-mail-partially): Remove CTE. + +2000-04-28 Shenghuo ZHU + + * mm-view.el (mm-inline-image): Fset it. + +2000-04-28 Shenghuo ZHU + + * nndoc.el (nndoc-type-alist): Change forward regexp. + +2000-04-27 Shenghuo ZHU + + * message.el (message-send-mail-partially-limit): Change the + default value. + +2000-04-27 Erik Toubro Nielsen + + * gnus-util.el (gnus-extract-address-components): Name might be + "". + +2000-04-27 Shenghuo ZHU + + * gnus-msg.el (gnus-summary-mail-forward): Use ARG. + (gnus-summary-post-forward): Ditto. + * message.el (message-forward-show-mml): New variable. + (message-forward): Use it. + * mml.el (mml-parse-1): Add tag mml. + (mml-read-part): Ditto. + (mml-generate-mime): Support reentance. + (mml-generate-mime-1): Support mml tag. + +2000-04-27 Dave Love + + * gnus-art.el: Don't bother to require custom, browse-url. + (gnus-article-x-face-command): Include gnus-article-display-xface. + + * gnus-ems.el: Assume only (X)Emacs 20+. Simplify XEmacs checks. + Use defalias, not fset. + (gnus-article-display-xface): New function. + + * mm-view.el (mm-inline-image-emacs): Use put-image, remove-images. + + * mm-decode.el: Small doc fixes. Require cl when compiling. + (mm-xemacs-p): Deleted. + (mm-get-image-emacs, mm-get-image-xemacs): Deleted. + (mm-get-image): Amalgamate Emacs and XEmacs code here; for Emacs, + use create-image and don't special-case xbm. + (mm-valid-image-format-p): Use display-graphic-p. + +2000-04-27 Shenghuo ZHU + + * message.el (message-send-mail-partially-limit): New variable. + (message-send-mail-partially): New function. + (message-send-mail): Use it. + * mm-bodies.el (mm-decode-content-transfer-encoding): Remove + all blank lines inside of base64. + * mm-partial.el (mm-inline-partial): Add an option. Remove tail + blank lines. + +2000-04-27 Shenghuo ZHU + + * mml.el (mml-insert-tag): Match more special characters. + +2000-04-27 Shenghuo ZHU + + * gnus-msg.el (gnus-bug): Avoid attaching the external buffer. + +2000-04-27 Shenghuo ZHU + + * mm-decode.el (mm-inline-media-tests): Add message/partial. + (mm-inlined-types): Ditto. + * mm-partial.el: New file. + +2000-04-27 Dave Love + + * mailcap.el (mailcap-mime-data): Fix octet-stream syntax -- might + matter in Emacs 21. + +2000-04-26 Florian Weimer + + * mm-bodies.el (mm-encode-body): Remove reference to + mm-default-charset in comment. + +2000-04-24 Bj,Av(Brn Torkelsson + + * rfc2047.el (rfc2047-encode-message-header): Fixing typo. + +2000-04-26 Shenghuo ZHU + + * gnus-draft.el (gnus-draft-send): Move gnus-draft-setup inside of + let. + +2000-04-26 Pavel Janik ml. + + * gnus-draft.el (gnus-draft-setup): Fix comments. + +2000-04-26 Shenghuo ZHU + + * nnmbox.el (nnmbox-create-mbox): Use nnmbox-file-coding-system, + if nnmbox-file-coding-system-for-write is nil. + +2000-04-26 Shenghuo ZHU + + * gnus-msg.el (gnus-configure-posting-styles): Just remove the + header if nil. + +2000-04-26 Shenghuo ZHU + + * mm-view.el (mm-inline-text): Insert directly if decoded. + * mml.el (autoload): Typo. + +2000-04-26 Shenghuo ZHU + + * mml.el (mml-preview): Set up posting-charset. + * gnus-msg.el (gnus-group-posting-charset-alist): Add koi8-r. + +2000-04-25 Shenghuo ZHU + + * webmail.el: Fix yahoo mail. + +2000-04-25 Shenghuo ZHU + + * rfc2047.el (rfc2047-dissect-region): Don't include LWS ahead of + word if not necessary. + (rfc2047-encode-region): Put space between encoded words. + +2000-04-24 Shenghuo ZHU + + * gnus-util.el (gnus-netrc-machine): Another default to nntp. + +2000-04-24 Shenghuo ZHU + + * gnus-draft.el (gnus-draft-setup): Restore mml only when + required. + (gnus-draft-edit-message): Require restoration. + +2000-04-24 Shenghuo ZHU + + * gnus-score.el (gnus-score-headers): Copy gnus-newsgrou-scored + back. + +2000-04-24 Shenghuo ZHU + + * gnus-art.el (gnus-treat-article): Make sure that the summary + buffer is live. + +2000-04-24 Shenghuo ZHU + + * mailcap.el (mailcap-parse-mailcaps): Reorder. + (mailcap-parse-mailcap): Backwards parsing. + (mailcap-possible-viewers): Remove nreverse. + (mailcap-mime-info): Ditto. + (mailcap-add-mailcap-entry): Keep alternative viewer. + +2000-04-24 Lars Magne Ingebrigtsen + + * gnus.el: Gnus v5.8.5 is released. + +2000-04-24 Lars Magne Ingebrigtsen + + * rfc2047.el (rfc2047-header-encoding-alist): Doc fix. + + * gnus-util.el (gnus-netrc-machine): Default to nntp. + + * mml.el (mml-generate-mime-1): Force 8bit on message/rfc822. + +2000-04-24 Shenghuo ZHU + + * mm-view.el (mm-inline-message): Disable prepare-hook. + +2000-04-23 Lars Magne Ingebrigtsen + + * gnus.el: Fix copyright statements. + + * gnus-sum.el (gnus-alter-articles-to-read-function): New + variable. + (gnus-articles-to-read): Use it. + + * message.el (message-get-reply-headers): Bind free variable. + +2000-04-23 Shenghuo ZHU + + * message.el (message-get-reply-headers): Fix to-address. + +2000-04-23 Shenghuo ZHU + + * webmail.el: Hotmail fix. Add a debug function. + +2000-04-23 Lars Magne Ingebrigtsen + + * gnus-sum.el (t): M-down and M-up. + +2000-04-22 Kai Gro,A_(Bjohann + + * gnus-sum.el: Doc fix. + +2000-04-22 Shenghuo ZHU + + * nnwarchive.el (nnwarchive-egroups-article): Remove < and >. + +2000-04-22 Lars Magne Ingebrigtsen + + * nnweb.el (nnweb-dejanews-create-mapping): Remove the context + string. + (nnweb-request-group): Don't scan twice. + (nnweb-request-scan): Don't nix out the hashtb. + + * message.el (message-get-reply-headers): Return a value. + +2000-04-22 David Aspinwall + + * gnus-art.el (gnus-button-url-regexp): New value to match naked + urls. + +2000-04-22 Lars Magne Ingebrigtsen + + * gnus-cache.el (gnus-summary-insert-cached-articles): Reverse the + order messages are inserted. + + * mml.el (mml-generate-mime-1): rfc2047-encode the heads of + message/rfc822 parts. + + * gnus-art.el (gnus-article-read-summary-keys): Check for + numerical values. + + * message.el (message-get-headers): Made into own function. + (message-reply): Use it. + (message-get-reply-headers): Renamed. + (message-widen-reply): New command. + +2000-04-21 Shenghuo ZHU + + * nntp.el (nntp-retrieve-data): Report the error and return nil. + +2000-04-21 Shenghuo ZHU + + * mm-bodies.el (mm-decode-content-transfer-encoding): Don't remove + non-base64 text at the end if not found. + +2000-03-01 Simon Josefsson + + * gnus-sum.el (gnus-read-move-group-name): + (gnus-summary-move-article): Use `gnus-group-method' to find out + what method the manually entered group belong to. + `gnus-group-name-to-method' doesn't return any method parameters + and `gnus-find-method-for-group' uses `gnus-group-name-to-method' + for new groups so they wouldn't work. + +2000-04-22 Lars Magne Ingebrigtsen + + * gnus-msg.el (gnus-configure-posting-styles): Allow nil values to + override. + +2000-04-21 Kai Gro,A_(Bjohann + + * nnmail.el (nnmail-cache-insert): Does some stuff that is + probably good to do, or something. I dunno. I just write these + ChangeLog entries, and my name is Lars. + +1999-12-06 Hrvoje Niksic + + * message.el (message-caesar-region): Use translate-region. + +2000-04-21 Mike Fabian + + * gnus-group.el (gnus-group-catchup-current): Doc fix. + +2000-04-21 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-setup-buffer): Don't kill local + variables, because that makes Emacs flash. + + * gnus-group.el (gnus-group-insert-group-line): Don't call + gnus-group-add-icon unconditionally. + + * gnus-group.el (gnus-group-glyph-directory): Don't depend on + xmas. + (gnus-group-glyph-directory): Removed. + +2000-04-21 Jaap-Henk Hoepman + + * gnus-msg.el (gnus-inews-insert-archive-gcc): Don't do stuff if + gnus-newsgroup-name is "". + +2000-04-21 Florian Weimer + + * mm-util.el (mm-mime-mule-charset-alist): Add support for UTF-8 + in conjunction with MULE-UCS. + +1999-12-13 Per Abrahamsen + + * rfc2047.el (rfc2047-fold-region): Don't use the same break twice. + +1999-12-21 Jan Vroonhof + + * message.el (message-shorten-references): Only cater to broken + INN for news. This caters for broken smtpd. + +2000-04-21 Lars Magne Ingebrigtsen + + * mailcap.el (mailcap-mime-info): Use the first match; not the + last. + + * gnus-agent.el (gnus-category-kill): Save the category list. + +2000-04-21 Chris Brierley + + * gnus-sum.el (gnus-summary-move-article): Do something or other. + +2000-04-21 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-add-icon): Fixed indentation. + +2000-04-21 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-add-icon): Fixed indentation. + +2000-04-21 Shenghuo ZHU + + * gnus-group.el (gnus-group-prepare-flat-predicate): New function. + (gnus-group-list-cached): Use it. + +2000-04-21 Lars Magne Ingebrigtsen + + * gnus.el: Update all the copyright notices. + +2000-04-21 Vladimir Volovich + + * mm-bodies.el (mm-decode-content-transfer-encoding): Remove + non-base64 text at the end. + +2000-04-21 Katsumi Yamaoka + + * mm-bodies.el (mm-body-charset-encoding-alist): defcustomized. + +2000-04-21 Lars Magne Ingebrigtsen + + * nnheader.el: Don't autoload cancel-function-timers. + + * message.el (message-fetch-field): Fold case. + +2000-04-21 + + * message.el (message-forward-before-signature): New variable. + +2000-04-21 Alexandre Oliva + + * gnus-mlspl.el: Fix stuff. + +2000-04-21 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-update-article-line): Don't hide + subjects when unthreaded. + +2000-04-21 David S. Goldberg + + * gnus-art.el (gnus-boring-article-headers): Work on long CCs as + well. + +2000-04-21 Rui Zhu + + * gnus-art.el (gnus-article-mode): Fix variable name. + +2000-04-21 Lars Magne Ingebrigtsen + + * mm-view.el: Fix autoload. + + * flow-fill.el (flow-fill): Fix provide. + + * gnus-draft.el (gnus-draft-send): Bind message-setup-hook to + nil. + +2000-04-21 Shenghuo ZHU + + * gnus-win.el (gnus-configure-windows): Revert to switch-to-buffer. + +2000-04-21 Katsumi Yamaoka + + * gnus-util.el (gnus-netrc-machine): Didn't work. + +2000-04-20 Shenghuo ZHU + + * gnus-draft.el (gnus-draft-setup): Restore to mml. + +2000-04-21 Lars Magne Ingebrigtsen + + * flow-fill.el: Renamed from fill-flowed. + + * message.el (message-forward-ignored-headers): Default to + removing CTE. + +2000-04-21 + + * message.el (message-mode): Don't fill headers. + +2000-04-21 Lars Magne Ingebrigtsen + + * message.el (message-pipe-buffer-body): Use shell + +2000-02-21 Yoshiki Hayashi + + * nnvirtual.el (nnvirtual-request-article): + Bind gnus-override-method to nil. + (nnvirtual-request-update-mark): Don't update mark when + article is not there. + +2000-04-20 Shenghuo ZHU + + * mm-uu.el (mm-uu-dissect): Check forwarded message. + +2000-04-20 Lars Magne Ingebrigtsen + + * gnus-util.el (gnus-parse-netrc): Allow "port". + (gnus-netrc-machine): Take a port param. + (gnus-netrc-machine): + + * gnus-art.el (gnus-request-article-this-buffer): Allow + re-selecting referenced articles. + + * message.el (message-cancel-news): Allow editing. + (message-cancel-message): Add newline. + +2000-04-20 William M. Perry + + * mm-view.el (mm-inline-image-emacs): New function. + +2000-04-20 Lars Magne Ingebrigtsen + + * mail-source.el (mail-source-delete-incoming): Change default in + cvs. + +2000-04-20 Kim-Minh Kaplan + + * gnus-art.el (gnus-mime-view-part-as-type-internal): New + function. + +2000-04-20 Lars Magne Ingebrigtsen + + * nnml.el (nnml-request-expire-articles): Use it. + + * nnmail.el (nnmail-expiry-target): New variable. + (nnmail-expiry-target-group): New function. + +2000-04-20 Emerick Rogul + + * message.el (message-forward): Add non-MIME separators. + +2000-04-20 Lars Magne Ingebrigtsen + + * message.el (message-generate-headers): Respect the syntax check + spec. + + * gnus-sum.el (gnus-remove-thread-1): Show thread. + (gnus-remove-thread): Don't show all threads. + +2000-04-20 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v5.8.4 is released. + +2000-04-19 Dave Love + + * mailcap.el (mailcap-parse-mimetypes): Add ...mime.types. + +2000-04-18 Shenghuo ZHU + + * nnwarchive.el (nnwarchive-type-definition): New egroups html. + (nnwarchive-egroups-*): Ditto. + (nnwarchive-url): Unibyte buffer and single line cookie. + +2000-04-14 Shenghuo ZHU + + * mm-util.el (mm-char-or-char-int-p): New alias. + * nnweb.el (nnweb-decode-entities): Check the validity of numeric + entities. + +1999-11-30 Daiki Ueno + + * lisp/imap.el (imap-body-lines): Check Content-Type: of the + article case insensitively. + +2000-04-10 Shenghuo ZHU + + * mail-source.el (mail-source-fetch-webmail): Use the default + password provided in mail-sources; use webmail:subtype:user as + the key. + +2000-04-10 John Wiegley + + * mail-source.el (mail-source-fetch-webmail): Use + mail-source-password-cache. + +2000-04-09 Shenghuo ZHU + + * webmail.el: Add netscape mail and fix HotMail mail. + +2000-04-08 Simon Josefsson + + * imap.el (imap-kerberos4-open): Work with recent `imtest's. + +2000-04-02 Simon Josefsson + + * nnimap.el (nnimap-request-article): Use BODY.PEEK[] instead of + RFC822.PEEK if server support IMAP4rev1. + (nnimap-request-body): Use BODY.PEEK[TEXT] instead of + RFC822.TEXT.PEEK if server support IMAP4rev1. + (nnimap-request-head): Use BODY.PEEK[HEADER] instead of + RFC822.HEADER if server support IMAP4rev1. + (nnimap-request-article-part): Support bodydetail in response + data. + +2000-03-11 Simon Josefsson + + * fill-flowed.el: New file. + + * mm-decode.el (mm-dissect-singlepart): Create a MIME handle for + text/plain parts with `format' parameters. + + * mm-view.el (autoload): Autoload fill-flowed. + (mm-inline-text): For "plain" parts with a format=flowed + parameter, call `fill-flowed'. + +2000-03-21 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-request-list): Fudge new-style + slashdot ids. + +2000-03-20 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-request-list): Use the new slashdot + format. + +2000-03-16 Simon Josefsson + + * imap.el: GSSAPI support, support kerberos 4 with Cyrus v1.6.x + `imtest' too. + (imap-kerberos4-program): Renamed from `imap-imtest-program'. + (imap-gssapi-program): New variable. + (imap-streams): Add gssapi. + (imap-stream-alist): Ditto. + (imap-authenticators): Ditto. + (imap-authenticator-alist): Ditto. + (imap-kerberos4-stream-p): Rename from `imap-kerberos4s-p'. + (imap-kerberos4-open): Loop over imtest programs, support Cyrus + 1.6.x `imtest' syntax. + (imap-gssapi-stream-p): New function. + (imap-gssapi-open): Ditto. + (imap-gssapi-auth-p): Ditto. + (imap-gssapi-auth): Ditto. + (imap-kerberos4-auth-p): Renamed from `imap-kerberos4a-p'. + (imap-send-command): Use buffer-local `imap-client-eol' value. + + * nnimap.el (nnimap-retrieve-headers-progress): Fold continuation + lines and turn TAB into SPC before parsing. + +2000-03-15 Simon Josefsson + + * nnheader.el (nnheader-group-pathname): Make sure to return a + directory. + * nnmail.el (nnmail-group-pathname): Ditto. + +2000-02-08 Per Abrahamsen + + * nnmail.el (nnmail-fix-eudora-headers): Fix `In-Reply-To' too, it + might split in the middle of a message-id. + +2000-03-13 Lars Magne Ingebrigtsen + + * gnus-srvr.el (gnus-server-kill-server): Offer to kill all the + groups from the server. + + * gnus-sum.el (gnus-summary-save-parts): Fix interactive spec. + (gnus-summary-toggle-header): Update the wash status. + + * gnus-uu.el ((gnus-uu-extract-map "X" gnus-summary-mode-map)): + Moved here. + + * gnus-agent.el (gnus-agent-save-group-info): Respect old + setting. + + * nnmail.el (nnmail-get-active): Use it. + (nnmail-parse-active): New function. + + * mm-view.el (mm-inline-text): Support the new version of + vcard.el. + + * gnus-sum.el (gnus-summary-move-article): Only delete article + when moving junk. + (gnus-deaden-summary): Bury the buffer. + + * nnmail.el (nnmail-group-pathname): Ditto. + + * nnheader.el (nnheader-group-pathname): Use expand-file-name. + +2000-03-13 Christoph Rohland + + * rfc2047.el (rfc2047-encode-message-header): Encode no matter + whether Mule. + +2000-03-10 Lars Magne Ingebrigtsen + + * message.el (message-send-mail): Protect against unloaded Gnus. + + * gnus-topic.el (gnus-topic-update-topic-line): Don't update the + parent. + (gnus-topic-update-topic-line): Yes, do. + (gnus-topic-goto-missing-group): Tally the correct number of + unread articles before inserting the topic line. + +2000-03-01 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-retrieve-headers): Ignore errors. + +2000-02-13 Lars Magne Ingebrigtsen + + * mm-decode.el (mm-dissect-buffer): Ditto. + + * gnus-art.el (article-decode-charset): Strip CTE. + + * ietf-drums.el (ietf-drums-strip): New function. + + * gnus-sum.el (gnus-summary-move-article): Don't use the prefix + when prompting in read-only groups. + +2000-02-23 Simon Josefsson + + * imap.el (imap-send-command): Change EOL-chars when + `imap-client-eol' differs from default, not only for kerberos4. + (imap-mailbox-status): Get encoded mailbox's status. + +2000-02-19 Simon Josefsson + + * mail-source.el (mail-source-fetch-imap): Copy `imap-password' + into `mail-source-password-cache'. + +2000-02-17 Florian Weimer + + * mm-util.el (mm-mime-charset): Check for presence of + `coding-system-get' and `get-charset-property' (recent XEmacs has + the former, but not the latter). + +2000-01-28 Dave Love + + * message.el (message-check-news-header-syntax): Fix typo + `newsgroyps'. + (message-talkative-question): Put temp buffer in fundamental-mode. + (message-recover): Use fundamental-mode in the right buffer. + + * nnmail.el (nnmail-split-history): Use fundamental-mode in the + right buffer. + +2000-01-26 Shenghuo ZHU + + * qp.el (quoted-printable-decode-region): Add charset parameter. + (quoted-printable-decode-string): Ditto. + + * gnus-art.el (article-de-quoted-unreadable): Use it. + +2000-01-21 Simon Josefsson + + * nnimap.el (nnimap-split-predicate): New variable. + (nnimap-split-articles): Use it. + +2000-01-20 Simon Josefsson + + * utf7.el: Change email address. + +2000-01-18 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-catchup): Purge split history. + +2000-01-14 Shenghuo ZHU + + * nnmail.el (nnmail-generate-active): Support extended group name. + (nnmail-get-active): Ditto. + +2000-01-13 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-write-active): Since no prefix in + group names, don't remove anything. + +2000-01-13 Shenghuo ZHU + + * webmail.el (webmail-my-deja-open): My-deja changes. + +2000-01-13 Simon Josefsson + + * nnimap.el (nnimap-retrieve-headers-progress): Create xref field. + +2000-01-10 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-fetch-headers): Translate full path. + +2000-01-09 Shenghuo ZHU + + * gnus.el (gnus-other-frame): Fix typo. + +1999-06-25 Andreas Jaeger + + * gnus-cus.el (gnus-group-customize): Fix typo. + +2000-01-08 Lars Magne Ingebrigtsen + + * nnweb.el (nnweb-insert): Simplified. + +2000-01-06 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-mode-map): "e" is + gnus-summary-edit-article. + +2000-01-06 Jari Aalto + + * mailcap.el (mailcap-mime-extensions): Add .diff. + +2000-01-06 Kim-Minh Kaplan + + * mm-decode.el (mm-mailcap-command): handle "%%" and the case where + there is no "%s" in the method. + +2000-01-08 Kim-Minh Kaplan + + * gnus-sum.el (gnus-summary-select-article): Return 'old. + +2000-01-06 Lars Magne Ingebrigtsen + + * nnfolder.el (nnfolder-read-folder): Use nnfolder-save-buffer. + + * gnus.el: Really always pop up a new frame. + + * parse-time.el (parse-time-rules): Allow 100-110 to be + 2000-2010. + + * time-date.el (date-to-time): Don't use timezone. + +2000-01-06 Dave Love + + * time-date.el: Add keywords. + (date-to-time): Add autoload cookie. Canonicalize with + timezone-make-date-arpa-standard. + (time-to-seconds): Avoid caddr. + (safe-date-to-time): Add autoload cookie. + +2000-01-05 BrYan P. Johnson + + * gnus-group.el (gnus-group-line-format-alist): Added %E for + eyecandy. + (gnus-group-insert-group-line): Now groks %E and inserts icon in + group line using gnus-group-add-icon. + (gnus-group-icons): Added customize group. + (gnus-group-icon-list): Added variable. + (gnus-group-glyph-directory): Added variable. + (gnus-group-icon-cache): Added variable. + (gnus-group-running-xemacs): Added variable. + (gnus-group-add-icon): Added function. Add an icon to the current + line according to gnus-group-icon-list. + (gnus-group-icon-create-glyph): Added function. + +2000-01-05 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-select-article): Return whether we + selected something new. + (gnus-summary-search-article): Start searching at the window + point. + + * gnus-group.el (gnus-fetch-group): Complete over + gnus-active-hashtb. + +2000-01-05 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v5.8.3 is released. + +2000-01-05 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-preserve-marks): New variable. + (gnus-summary-move-article): Use it. + (gnus-group-charset-alist): Added more entries. + +2000-01-03 Lars Magne Ingebrigtsen + + * mm-decode.el (mm-inline-override-types): Removed duplicate. + + * gnus-uu.el (gnus-uu-mark-over): Use gnus-summary-default-score + as the default score. + + * gnus-score.el (gnus-score-delta-default): Changed name. + +2000-01-04 Simon Josefsson + + * imap.el (imap-parse-literal): + (imap-parse-flag-list): Don't care about props. + (imap-parse-string): Handle quoted characters. + +2000-01-02 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-goto-unread): Doc fix. + (gnus-summary-mark-article): Doc fix. + (gnus-summary-mark-forward): Doc fix. + (t): Changed keystroke for gnus-summary-customize-parameters. + + * gnus-art.el (gnus-article-mode-map): Use gnus-article-edit for + "e". + (gnus-article-mode-map): No, don't. + + * gnus-sum.el (gnus-summary-next-subject): Don't show the thread + of the final article. + + * mm-decode.el (mm-interactively-view-part): Error on no method. + +2000-01-02 Stefan Monnier + + * gnus-score.el (gnus-score-insert-help): Something. + + * gnus-art.el (gnus-button-alist): Exclude < from + + * nnwarchive.el: Changed file perms. + +1999-12-19 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-delete-groups): New command. + (gnus-group-delete-group): Extra no-prompt parameters. + +1999-12-14 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-request-article): Translate
into +

. + +1999-12-28 Shenghuo ZHU + + * webmail.el (webmail-hotmail-article): Don't insert message id. + +1999-12-28 Kai.Grossjohann@CS.Uni-Dortmund.DE (Kai Gro,A_(Bjohann) + + * nnimap.el (nnimap-split-fancy): New variable. + (nnimap-split-fancy): New function. + +1999-12-28 Simon Josefsson + + (nnimap-split-rule): Document symbol value. + +1999-12-28 Simon Josefsson + + * nnimap.el (nnimap-retrieve-headers-progress): Let + `nnheader-parse-head' parse article. + (nnimap-retrieve-headers-from-server): Don't request ENVELOPE, + request headers needed by `nnheader-parse-head'. + +1999-12-23 Florian Weimer + + * gnus-msg.el (gnus-group-posting-charset-alist): Correct default + value (crosspostings are handled), improve documentation. + + * nnultimate.el: Declare file coding system as iso-8859-1. + + * message.el: Dito. + + * gnus-cite.el: Dito. + + * gnus-spec.el: Dito. + +1999-12-21 Florian Weimer + + * gnus-msg.el (gnus-group-posting-charset-alist): New layout. + (gnus-setup-message): No longer make `message-posting-charset' + buffer-local. + (gnus-setup-posting-charset): Reflect the new layout of + `gnus-group-posting-charset-alist' and `message-posting-charset'. + + * message.el (message-send-mail): Bind `message-this-is-mail' and + `message-posting-charset'. + (message-send-news): Dito, and honour new layout of + `message-posting-charset'. + (message-encode-message-body): Ignore `message-posting-charset'. + + * mm-bodies.el (mm-body-encoding): Consider + `message-posting-charset' when deciding whether to use 8bit. + + * rfc2047.el (rfc2047-encode-message-header): Back out change. + (rfc2047-encodable-p): Now solely for headers; use + `message-posting-charset'. + +1999-12-20 Shenghuo ZHU + + * nnwarchive.el (nnwarchive-type-definition): Set default value. + +1999-12-19 Shenghuo ZHU + + * nnagent.el (nnagent-server-opened): Optional. + (nnagent-status-message): Optional. + +1999-12-19 Simon Josefsson + + * gnus-cite.el (gnus-article-toggle-cited-text): Restore beg and + end (referenced by instructions in + `gnus-cited-opened-text-button-line-format-alist'). + +1999-12-18 Simon Josefsson + + * imap.el (imap-starttls-open): Typo. + +1999-12-18 Shenghuo ZHU + + * mm-util.el (mm-charset-after): Non-MULE case. + * mail-prsvr.el (mail-parse-mule-charset): New variable. + * rfc2047.el (rfc2047-dissect-region): Bind it. + +1999-12-18 Florian Weimer + + * mml.el (mml-generate-multipart-alist): Correct default value. + + * mm-encode.el (mm-use-ultra-safe-encoding): New variable. + (mm-safer-encoding): New function. + (mm-content-transfer-encoding): Use both. + + * mm-bodies.el (mm-body-encoding): Use mm-use-ultra-safe-encoding. + * qp.el (quoted-printable-encode-region): Dito. + +1999-12-18 Shenghuo ZHU + + * webmail.el (webmail-hotmail-article): Snarf the raw file. + +1999-12-18 Victor S. Miller + + * webmail.el (webmail-hotmail-list): raw=0. + +1999-12-18 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-enter-history): Back-compatible in + group name. + +1999-12-18 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-expire): Convert to symbol if stringp. + +1999-12-18 Simon Josefsson + + * imap.el: Don't autoload digest-md5. + (imap-starttls-open): Bind coding-system-for-{read,write}. + (imap-starttls-p): Check if we can find starttls.el. + (imap-digest-md5-p): Check if we can find digest-md5.el. + +1999-11-30 Daiki Ueno + + * imap.el: Require `digest-md5' when compiling; add autoload + settings for `digest-md5-parse-digest-challenge', + `digest-md5-digest-response', `starttls-open-stream' and + `starttls-negotiate'. + (imap-authenticators): Add `digest-md5'. + (imap-authenticator-alist): Setup for `digest-md5'. + (imap-digest-md5-p): New function. + (imap-digest-md5-auth): New function. + (imap-stream-alist): Add STARTTLS entry. + (imap-starttls-p): New function. + (imap-starttls-open): New function. + +1999-12-18 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-enter-history): Bad group name. + +1999-12-17 Shenghuo ZHU + + * rfc2047.el (rfc2047-dissect-region): Use mapcar instead of + string-to-x function. + +1999-12-17 Shenghuo ZHU + + * rfc2047.el (rfc2047-fold-region): Fold a line more than once. + +1999-12-17 Shenghuo ZHU + + * webmail.el: Enhance hotmail-snarf. + +1999-12-17 Shenghuo ZHU + + * rfc2047.el (rfc2047-dissect-region): Rewrite. + +1999-12-16 Shenghuo ZHU + + * webmail.el (webmail-hotmail-list): Search no-error. + +1999-12-15 Shenghuo ZHU + + * nnwarchive.el: Support nov-is-evil. + * gnus-bcklg.el (gnus-backlog-request-article): Buffer is optional. + Set it if non-nil. + * gnus-agent.el (gnus-agent-fetch-articles): Use it. + +1999-12-15 Shenghuo ZHU + + * nnagent.el (nnagent-server-opened): Redefine. + (nnagent-status-message): Ditto. + +1999-12-14 Shenghuo ZHU + + * rfc1843.el (rfc1843-decode-region): Use + buffer-substring-no-properties. + * gnus-art.el (article-decode-HZ): New function. + +1999-12-14 Shenghuo ZHU + + * nnheader.el (nnheader-translate-file-chars): Only in full path. + +1999-12-14 Shenghuo ZHU + + * mm-util.el (mm-find-charset-region): mail-parse-charset is a + MIME charset not a MULE charset. + +1999-12-14 Shenghuo ZHU + + * gnus-ems.el: Translate more ugly characters. + * nnheader.el (nnheader-translate-file-chars): Don't translate + the second ':'. + +1999-12-14 Shenghuo ZHU + + * gnus-art.el (gnus-request-article-this-buffer): Use all refer + method if cannot find the article. + +1999-12-14 Shenghuo ZHU + + * gnus-art.el (gnus-request-article-this-buffer): Don't use refer + method if overrided. + +1999-12-13 Shenghuo ZHU + + * mail-source.el (mail-source-fetch-webmail): Parameter + dontexpunge. + +1999-12-13 Shenghuo ZHU + + * webmail.el: Support my-deja. Better error report. + +1999-12-13 Shenghuo ZHU + + * nnslashdot.el (nnslashdot-date-to-date): Error proof when input + is bad. + * gnus-sum.el (gnus-list-of-unread-articles): When (car read) + is not 1. + +1999-12-13 Shenghuo ZHU + + * nnslashdot.el (nnslashdot-request-article): A space. + +1999-12-13 Shenghuo ZHU + + * nnagent.el: Support different backend with same name. + +1999-12-13 Shenghuo ZHU + + * nnslashdot.el (nnslashdot-threaded-retrieve-headers): Support + archived group. + (nnslashdot-sane-retrieve-headers): Ditto. + (nnslashdot-request-article): Ditto. + +1999-12-13 Shenghuo ZHU + + * nnweb.el (nnweb-insert): Narrow to point. + +1999-12-13 Shenghuo ZHU + + * nnweb.el (nnweb-insert): Follow refresh url. + * nnslashdot.el: Use it. + +1999-12-13 Shenghuo ZHU + + * nnweb.el (nnweb-decode-entities): Decode numerical entities. + (nnweb-decode-entities-string): New function. + + * nnwarchive.el (nnwarchive-decode-entities-string): Rename to + nnweb-* and move to nnweb.el. + * nnwarchive.el: Use nnweb-decode-entities, etc. + * webmail.el: Ditto. + + * nnslashdot.el: Use nnweb-decode-entities-string. + (nnslashdot-decode-entities): Remove. + +1999-12-13 Eric Marsden + + * nnslashdot.el: Decode entities. + +1999-12-12 Dave Love + + * gnus-agent.el (gnus-category-edit-groups) + (gnus-category-edit-score, gnus-category-edit-predicate): Replace + expansion of setf, fixed. + +1999-12-12 Shenghuo ZHU + + * gnus-agent.el: Revoke last Dave Love's patch, because of + incompatibility of XEmacs. + +1999-12-12 Shenghuo ZHU + + * mm-uu.el: Change headers. + * rfc1843.el: Ditto. + * uudecode.el: Ditto. + +1999-12-07 Dave Love + + * gnus-agent.el (gnus-category-edit-predicate) + (gnus-category-edit-score, gnus-category-edit-score): Expand setf + inside backquote to avoid it at runtime. + +1999-12-07 Dave Love + + * binhex.el: Require cl when compiling. + +1999-12-04 Dave Love + + * gnus-cus.el (gnus-group-parameters): Allow nil for banner. + +1999-12-04 Dave Love + + * mm-util.el (mm-delete-duplicates): New function. + (mm-write-region): Use it. + + * mml.el (mml-minibuffer-read-type): Use mm-delete-duplicates. + + * mailcap.el (mailcap-mime-types): Require mm-util. Use + mm-delete-duplicates. + + * imap.el (imap-open, imap-debug): Avoid mapc. + + * nnvirtual.el (nnvirtual-create-mapping): Likewise. + + * gnus-sum.el (gnus-summary-exit-no-update): Avoid copy-list. + (gnus-multi-decode-encoded-word-string): Avoid mapc. + + * gnus-start.el (gnus-site-init-file): Avoid ignore-errors at + runtime. + + * gnus.el (gnus-select-method): Likewise. + + * nnheader.el (nnheader-nov-read-integer): Likewise. + + * mm-view.el (mm-inline-message): Require cl when compiling. + Avoid ignore-errors at runtime. + (mm-inline-text): Avoid mapc. + +1999-12-12 Shenghuo ZHU + + * gnus-art.el (article-decode-charset): Widen is bad. + +1999-12-12 Shenghuo ZHU + + * mm-util.el (mm-charset-after): `charset-after' may not be defined. + +1999-12-12 Florian Weimer + + * rfc2047.el (rfc2047-encodable-p): New parameter header used to + indicate that only US-ASCII is permitted. + (rfc2047-encode-message-header): Use it. Now, Gnus should never + use unencoded 8-bit characters in message headers. + +1999-12-12 Shenghuo ZHU + + * ietf-drums.el (ietf-drums-narrow-to-header): Make it work with + CRLF. + +1999-12-11 Shenghuo ZHU + + * webmail.el: Require url-cookie. + +1999-12-11 Shenghuo ZHU + + * nnwarchive.el (nnwarchive-make-caesar-translation-table): A + new function to make modified caesar table. + (nnwarchive-from-r13): Use it. + (nnwarchive-mail-archive-article): Improved. + +1999-12-11 Shenghuo ZHU + + * webmail.el (webmail-url): Use mm-with-unibyte-current-buffer. + +1999-12-10 Shenghuo ZHU + + * nnweb.el (nnweb-request-article): Return cons. + +1999-12-10 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-setup-default-charset): Typo. + +1999-12-10 Shenghuo ZHU + + * mm-util.el (mm-with-unibyte): New macro. + * nnweb.el (nnweb-init): Use it. + +1999-12-09 Shenghuo ZHU + + * mm-util.el (mm-charset-after): New function. + (mm-find-mime-charset-region): Set charsets after + delete-duplicates and use find-coding-systems-region. + (mm-find-charset-region): Remove composition. + + * mm-bodies.el (mm-encode-body): Use mm-charset-after. + + * mml.el (mml-parse-singlepart-with-multiple-charsets): Ditto. + +1999-12-09 Shenghuo ZHU + + * mm-util.el (mm-find-mime-charset-region): Revoke last change. + * mml.el (mml-confirmation-set): New variable. + (mml-parse-1): Ask user to confirm. + +1999-12-09 Simon Josefsson + + * gnus-start.el (gnus-get-unread-articles): Make sure all methods + are scanned when we have directory mail-sources (the mail source + is modified in that case, so we must scan it for all + groups/methods). + +1999-12-09 Shenghuo ZHU + + * nnml.el (nnml-request-move-article): Save nnml-current-directory + and nnml-article-file-alist. + +1999-12-09 Shenghuo ZHU + + * gnus-group.el (gnus-group-get-new-news-this-group): Binding + nnmail-fetched-sources. + +1999-12-09 Shenghuo ZHU + + * mm-util.el (mm-find-charset-region): Use the last charset. + +1999-12-08 Per Abrahamsen + + * gnus.el (gnus-select-method): Made the option list prettier. + +1999-12-08 Florian Weimer + + * gnus-msg.el (gnus-group-posting-charset-alist): Use iso-8859-1 + for the `de' newsgroups hierarchy, as it is common practice there. + + +1999-12-07 Shenghuo ZHU + + * nnwarchive.el (nnwarchive-mail-archive-article): Fix + buffer-string arguments. Fix references. + +1999-12-07 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-confirmation-function): New variable. + (gnus-agent-batch-fetch): Use it. + (gnus-agent-fetch-session): Use it. + +1999-12-07 Shenghuo ZHU + + * mm-util.el (mm-find-mime-charset-region): Delete nil. + +1999-12-07 Shenghuo ZHU + + * mm-util.el (mm-find-charset-region): Don't capitalize. Delete + nil. + +1999-12-07 Per Abrahamsen + + * nnslashdot.el (nnslashdot-request-list): There were two + top-level body-forms. Put a `progn' around them. + + * gnus.el (gnus-select-method): Use `condition-case' + instead of `ignore-errors', since cl may not be loaded when the + form is evaluated. + +1999-12-06 Shenghuo ZHU + + * nnwarchive.el: Support www.mail-archive.com. + +1999-12-06 Shenghuo ZHU + + * nnmail.el (nnmail-get-new-mail): Remove fetched sources before + do anything. + +1999-12-06 Simon Josefsson + + * utf7.el: New file, written by Jon K Hellan. + + * imap.el (imap-use-utf7): Renamed from `imap-utf7-p', change + default to t. + +1999-12-06 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-request-delete-group): New function. + + * gnus-sum.el (gnus-summary-refer-article): Work for lists with + current. + (gnus-refer-article-methods): New function. + (gnus-summary-refer-article): Use it. + +1999-11-13 Simon Josefsson + + * nnimap.el (nnimap-retrieve-groups): Return active format. + + * nnimap.el (nnimap-replace-in-string): Removed. + (nnimap-request-list): + (nnimap-retrieve-groups): + (nnimap-request-newgroups): Quote group instead of escaping SPC. + +1999-12-05 Simon Josefsson + + * imap.el: Use format-spec for ssl program. + * imap.el (imap-ssl-arguments): Removed. + (imap-ssl-open-{1,2}): Removed. + +1999-12-04 Per Abrahamsen + + * gnus-start.el (gnus-site-init-file): Use `condition-case' + instead of `ignore-errors', since cl may not be loaded when the + form is evaluated. + +1999-12-04 Shenghuo ZHU + + * mm-bodies.el (mm-8bit-char-regexps): Removed. + (mm-7bit-chars): New variable. + (mm-body-7-or-8): Use it in both cases. + +1999-12-04 Michael Welsh Duggan + + * gnus-start.el (gnus-site-init-file): Don't use cl macros in + defcustom definitions. + +1999-12-04 Simon Josefsson + + * mm-decode.el (mm-display-part): Let mm-display-external return + inline or external. + (mm-display-external): For copiousoutput methods, insert output in + buffer. + +1999-12-04 Shenghuo ZHU + + * nntp.el (nntp-retrieve-headers-with-xover): Goto the end of + buffer. + +1999-12-04 Lars Magne Ingebrigtsen + + * gnus-audio.el: An M too far. + + * gnus-msg.el (gnus-setup-message): One backtick too many. + + * gnus-art.el (gnus-mime-view-part-as-type): mailcap-mime-types is + a function, not a variable. + +1999-12-04 Max Froumentin + + * gnus-score.el (gnus-score-body): Widen before requesting. + +1999-12-04 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-prepare-flat): Comment fix. + +1999-12-04 Shenghuo ZHU + + * mail-source.el (mail-source-fetch-webmail): Bind + mail-source-string. + +1999-12-04 Matt Swift + + * gnus-uu.el (gnus-uu-mark-by-regexp): Doc fix. + (gnus-uu-unmark-by-regexp): Ditto. + + * gnus-group.el (gnus-group-catchup-current): Would bug out on + dead groups. + +1999-12-04 Lars Magne Ingebrigtsen + + * gnus-msg.el (gnus-setup-message): Allow the charset setting to + do their real thing. + + * nnmh.el (nnmh-be-safe): Doc fix. + + * gnus-sum.el (gnus-summary-exit): Write cache active file. + + * nntp.el (nntp-retrieve-headers-with-xover): Make sure the entire + status line has arrived before we count it. + + * mailcap.el (mailcap-mime-data): Removed save-file from audio/*. + + * gnus-sum.el (gnus-thread-header): Fixed after indent. + Whitespace problems. + + * gnus-win.el (gnus-configure-windows): Error fix. + + * gnus-demon.el (gnus-demon-add-nntp-close-connection): Add the + right function. + + * gnus.el: Fixed all the doc strings to match the FSF convetions. + Indent all functions. Fix all comments to match the comment + conventions. Double-space after full stop. + +1999-12-04 YAMAMOTO Kouji + + * nnmail.el (nnmail-split-it): I redefined nnmail-split-fancy's + value to divide received mails into my favorite groups and I met + an error. It takes place if the length of a element "VALUE" in + nnmail-split-fancy is less than two. + +1999-10-10 Robert Bihlmeyer + + * mml.el (mml-insert-part): New function. + +1999-12-02 Dave Love + + * mm-decode.el: Customize. + +1999-12-03 Dave Love + + * nnslashdot.el, nnultimate.el: Don't lose at compile time when + the W3 stuff isn't available. + +1999-12-03 Dave Love + + * imap.el, mailcap.el, nnvirtual.el, rfc2104.el: Don't require cl + at runtime. + +1999-12-04 Dan Christensen + + * gnus-score.el (gnus-score-headers): Fix orphan scoring. + +1999-12-01 Andrew Innes + + * nnmbox.el (nnmbox-read-mbox): Count messages correctly, and + don't be fooled by "From nobody" lines added by respooling. + + * pop3.el (pop3-movemail): Write crashbox in binary. + (pop3-get-message-count): New function. + + * mail-source.el (mail-source-primary-source): New variable. + (mail-source-report-new-mail-interval): New variable. + (mail-source-idle-time-delay): New variable. + (mail-source-new-mail-available): New internal variable. + (mail-source-fetch-pop): Clear new mail flag, when mail from + primary source has been fetched. + (mail-source-check-pop): New function. + (mail-source-new-mail-p): New function. + (mail-source-start-idle-timer): New function. + (mail-source-report-new-mail): New function. + (mail-source-report-new-mail): New internal variable. + (mail-source-report-new-mail-timer): New internal variable. + (mail-source-report-new-mail-idle-timer): New internal variables. + +1999-12-04 Andreas Schwab + + * gnus-cus.el (gnus-group-customize): Customize fix. + +1999-12-04 Andrea Arcangeli + + * message.el (message-send-mail-with-sendmail): Use + message-make-address. + +1999-12-03 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v5.8.2 is released. + +1999-12-03 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v5.8.1 is released. + +1999-11-11 Hrvoje Niksic + + * mml.el (mml-insert-tag): Don't close the tag. + (mml-insert-empty-tag): New function. + (mml-attach-file): Use mml-insert-empty-tag instead of + mml-insert-tag. + (mml-attach-buffer): Ditto. + (mml-attach-external): Ditto. + (mml-insert-multipart): Ditto. + +1999-12-03 Shenghuo ZHU + + * nnfolder.el (nnfolder-request-article): Return -1 if not find + the article number. + +1999-12-03 Shenghuo ZHU + + * gnus.el (gnus-find-method-for-group): The method of a new group + is not the native one. + +1999-12-03 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-button-embedded-url): Always call browse-url. + +1999-12-02 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-retrieve-headers): Use + mm-with-unibyte-current-buffer. + (nnultimate-request-article): Ditto. + +1999-12-02 Shenghuo ZHU + + * nntp.el (nntp-retrieve-groups): Set to process buffer. + +1999-12-02 Shenghuo ZHU + + * mm-util.el (mm-with-unibyte-current-buffer): New macro. + * nnweb.el (nnweb-retrieve-headers): Use it. + (nnweb-request-article): Use it. + + * nnweb.el (nnweb-dejanews-create-mapping): Set a default date in + case matching failed. + +1999-12-02 John Wiegley + + * mail-source.el (mail-source-keyword-map): Add backslash to + Delete-flag. + +1999-12-02 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-group-charset-alist): Default nnweb groups to + Latin-1. + (gnus-group-charset-alist): No, don't. + + * nnweb.el (nnweb-init): Make the buffer unibyte. + +1999-12-01 Shenghuo ZHU + + * mail-source.el (mail-source-set-common-1): Fix to get the + default value. + +1999-12-02 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-read-groups): Unibyte. + + * nnultimate.el (nnultimate-request-list): Use unibyte. + + * gnus-uu.el (gnus-uu-grab-articles): Bind + gnus-display-mime-function to nil. + + * message.el (message-send-mail-with-sendmail): Use the + user-mail-address variable. + + * gnus-art.el (gnus-ignored-headers): More headers. + + * message.el (message-shorten-1): Use list. + +1999-12-01 Lars Magne Ingebrigtsen + + * gnus-msg.el (gnus-configure-posting-styles): Ignore nil + signatures. + + * nnweb.el (nnweb-dejanews-create-mapping): Get the data. + (nnweb-dejanews-create-mapping): Do the properish date. + +1999-12-01 Shenghuo ZHU + + * mail-source.el (mail-source-common-keyword-map): New variable. + (mail-source-bind-common): New macro. + (mail-source-fetch): Support plugged mail source. + * gnus-int.el (gnus-request-scan): Use them. + +1999-12-01 Lars Magne Ingebrigtsen + + * mm-view.el (mm-inline-message): Check whether charset is a + string. + + * nnslashdot.el (nnslashdot-request-post): Insert

's. + + * message.el (message-mode-map): Changed keystroke for + message-yank-buffer. + +1999-11-26 Hrvoje Niksic + + * message.el (message-shorten-references): Cut references to 31 + elements, then either fold them or shorten them to 988 characters. + (message-shorten-1): New function. + (message-cater-to-broken-inn): New variable. + +1999-12-01 Eric Marsden + + * nnslashdot.el (nnslashdot-lose): New function. + +1999-12-01 Lars Magne Ingebrigtsen + + * mm-view.el (mm-inline-message): Not the right type of charset is + being fetched here. Let the group charset rule. + (mm-inline-message): Ignore us-ascii. + +1999-11-24 Carsten Leonhardt + + * mail-source.el (mail-source-fetch-maildir): work around the + ommitted "file-regular-p" in efs/ange-ftp + +1999-12-01 Lars Magne Ingebrigtsen + + * mml.el (mml-generate-mime-1): Don't insert extra empty line. + (mml-generate-mime-1): Use the encoding param. + + * gnus-sum.el (gnus-summary-show-article): Don't bind gnus-visual. + + * gnus-cache.el (gnus-cache-possibly-enter-article): Require + gnus-art before binding its variables. + + * gnus-art.el (gnus-article-prepare-display): Run the prepare + after the MIME. + +1999-12-01 Rupa Schomaker + + * message.el (message-clone-locals): Use it. + + * gnus-msg.el (gnus-configure-posting-styles): Make + user-mail-address local. + +1999-11-20 Simon Josefsson + + * gnus-start.el (gnus-get-unread-articles): Scan each method only + once. + +1999-12-01 Lars Magne Ingebrigtsen + + * message.el (message-generate-new-buffer-clone-locals): Use varstr. + (message-clone-locals): Ditto. + + * gnus-sum.el (gnus-summary-enter-digest-group): Have the digest + group inherit reply-to or from. + +1999-12-01 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-show-article): Support numbered ARG + for charset. + (gnus-summary-show-article-charset-alist): New variable. + + * mm-bodies.el (mm-decode-string): Support gnus-all and + gnus-unknown. + (mm-decode-body): Ditto. + * rfc2047.el (rfc2047-decode): Ditto. + +1999-12-01 Lars Magne Ingebrigtsen + + * mail-source.el (mail-source-delete-incoming): Change default to + t. + +1999-12-01 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.99 is released. + +1999-12-01 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-refer-article): Wrong interactive + spec. + + * gnus-msg.el (gnus-configure-posting-styles): Eval `eval'. + (gnus-configure-posting-styles): No, don't. + (gnus-configure-posting-styles): Allow overriding files. + + * gnus-art.el (gnus-header-button-alist): Use browse-url + directly. + + * mm-decode.el (mm-inline-media-tests): Check feature vcard. + + * gnus-msg.el (gnus-summary-yank-message): New command and + keystroke. + + * message.el (message-yank-buffer): New command. + (message-buffers): New function. + + * gnus-sum.el (gnus-summary-catchup-and-goto-next-group): Select + next group in a more normal fasion. + + * mml.el (mml-boundary-function): New variable. + (mml-compute-boundary): Use it. + + * nnmh.el (nnmh-active-number): Skip past files that have buffers + that exist for them. + + * gnus-async.el (gnus-async-prefetch-next): Cancel timers. + (gnus-async-timer): New variable. + +1999-11-30 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-request-list): Be more lenient with + root addresses. + +1999-11-28 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-treatment-function-alist): Do + gnus-treat-capitalize-sentences. + +1999-11-30 Shenghuo ZHU + + * webmail.el (webmail-hotmail-article): Hotmail changes the + format. + +1999-11-29 Simon Josefsson + + * mm-decode.el (mm-display-external): For `copiousoutput' methods, + switch to buffer after calling program. + (mm-display-external): Use `shell-command-switch' instead of "-c". + +1999-11-27 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-possibly-change-server): Don't always + read groups file. + + * nnslashdot.el (nnslashdot-request-article): Convert

to +

. + +1999-11-24 Lars Magne Ingebrigtsen + + * message.el (message-mode): Doc fix. + +1999-11-24 Shenghuo ZHU + + * gnus-art.el (article-emphasize): Check group variable. + * rfc1843.el (rfc1843-decode-article-body): Ditto. + +1999-11-24 Shenghuo ZHU + + * mm-decode.el (mm-save-part-to-file): Inhibit jka-compr for any + type. + +1999-11-23 Shenghuo ZHU + + * webmail.el: Support www.netaddress.com, i.e. usa.net. + +1999-11-23 Hrvoje Niksic + + * mml.el (mml-quote-region): Insert ! after the hash. + +1999-11-23 Shenghuo ZHU + + * gnus-group.el (gnus-group-warchive-address-history): Change to + nil. + +1999-11-23 Shenghuo ZHU + + * webmail.el: Support mail.yahoo.com. + + * mail-source.el (mail-source-fetch-webmail): Add password check. + (mail-source-keyword-map): Use `subtype'. + +1999-11-22 Shenghuo ZHU + + * mail-source.el (mail-source-keyword-map): Add webmail. + (mail-source-fetcher-alist): Ditto. + (mail-source-fetch-webmail): New function. + * webmail.el: New file. + +1999-11-21 Shenghuo ZHU + + * nnwarchive.el (nnwarchive-request-group): Print 0 if it is nil. + +1999-11-21 Shenghuo ZHU + + * mailcap.el (mailcap-parse-mailcap): Don't skip double semicolon. + +1999-11-20 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-request-list): Add fetch-time slot. + (nnultimate-prune-days): New function. + (nnultimate-create-mapping): Use it. + (nnultimate-request-group): Only fetch the groups list if it has + not been done before. + (nnultimate-retrieve-headers): Don't write groups. + (nnultimate-create-mapping): Off-by-one error. + +1999-11-19 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-sane-retrieve-headers): Fix to match + threaded subjects. + +1999-11-20 Shenghuo ZHU + + * nnwarchive.el: Lots of changes make agent happy. + +1999-11-19 Shenghuo ZHU + + * gnus-start.el (gnus-get-unread-articles): Assert group is in + hashtb. + +1999-11-19 Shenghuo ZHU + + * mm-decode.el (mm-display-external): Write region with binary + mode. + +1999-11-18 Shenghuo ZHU + + * nnweb.el (nnweb-dejanews-create-mapping): Bind `text'. + +1999-11-18 Shenghuo ZHU + + * mm-uu.el (mm-uu-dissect): Use fake charset `gnus-decoded'. + (mm-uu-test): Now it is in restricted region. + + * gnus-art.el (article-decode-charset): Don't mm-uu-test. + + * mm-view.el (mm-view-message): Fix buffer leak. + (mm-inline-message): Support 'gnus-decoded. + + * mm-bodies.el (mm-decode-body): Ditto. + + * rfc2047.el (rfc2047-decode-region): Ditto. + +1999-11-18 Matthias Andree + + * imap.el (require): Added autoload for base64-encode-string. + +1999-11-17 Per Abrahamsen + + * gnus.el (gnus-refer-article-method): Made list value + customizable. + +1999-11-17 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-recenter): set-window-start with + NOFORCE in Emacs case. + +1999-11-17 Shenghuo ZHU + + * gnus-art.el (gnus-request-article-this-buffer): Set + gnus-newsgroup-name. + +1999-11-17 Simon Josefsson + + * gnus-start.el (gnus-get-unread-articles): Check server before + scanning. + +1999-11-16 Lars Magne Ingebrigtsen + + * gnus.el (gnus-valid-select-methods): nnslashdot is news. + + * nnslashdot.el (nnslashdot-login-name): New variable. + (nnslashdot-password): Ditto. + (nnslashdot-request-post): New function. + + * gnus-art.el (gnus-treat-buttonize): More testing. + + * mm-encode.el: Another CVS test. + + * gnus-art.el (gnus-treat-emphasize): Change default. + (gnus-treat-buttonize): Ditto. + (gnus-treat-buttonize): This is a test. + + * gnus-sum.el (gnus-build-old-threads): Bind mail-parse-charset. + (gnus-build-sparse-threads): Ditto. + (gnus-build-all-threads): Ditto. + + * nnheader.el (make-full-mail-header): Make into a subst. + + * gnus.el (gnus-refer-article-method): Doc fix. + + * gnus-sum.el: Do not accept a prefix. + (gnus-summary-refer-article): Accept a list of select methods. + +1999-11-11 Matt Pharr + + * message.el (message-forward): Pay attention to prefix argument + again and forward all headers when it is set, regardless of the + value of message-forward-ignored-headers. + +1999-11-15 Lars Magne Ingebrigtsen + + * gnus-ems.el: Check for cygwin32. + +1999-11-14 Shenghuo ZHU + + * mm-decode.el (mm-display-external): Use 'non-viewer. + +1999-11-14 Shenghuo ZHU + + * nntp.el (nntp-retrieve-groups): Erase nntp-sever-buffer before + nntp-inhibit-erase. + +1999-11-13 Simon Josefsson + + * gnus-start.el (gnus-get-unread-articles): Use + nnfoo-retrieve-groups to find new news, if available. + (gnus-read-active-file-2): New function. + (gnus-get-unread-articles): Use it. + (gnus-read-active-file-1): Ditto. + +1999-11-13 Lars Magne Ingebrigtsen + + * mm-util.el (mm-find-mime-charset-region): Make sure + find-coding-systems-for-charsets is fbound. + + * gnus-ems.el: Typo fix. + +1999-11-13 Florian Weimer + + * mm-util.el (mm-find-mime-charset-region): Use UTF-8 if + it's available and makes sense. + +1999-11-12 Fabrice POPINEAU + + * gnus-score.el (gnus-score-save): Translate score file. + +1999-11-13 Simon Josefsson + + * mail-source.el (mail-source-keyword-map): For IMAP mail source, + added fetchflag and dontexpunge keywords. + (mail-source-fetch-imap): Use them. + +1999-11-12 Per Abrahamsen + + * gnus-start.el (gnus-level-subscribed, gnus-level-unsubscribed, + gnus-level-zombie, gnus-level-killed): Changed from `defcustom' to + `defconst'. + + * gnus-cus.el (gnus-group-parameters): Changed from `defcustom' to + `defconst'. + Mention that it is both for group and topic parameters. + (gnus-extra-topic-parameters): New constant, including `subscribe' + parameter. + (gnus-extra-group-parameters): New constant. + (gnus-group-customize): Use them. + + * gnus.el (gnus-select-method): Added default value and tag. + (gnus-refer-article-method): Added `DejaNews' customization option. + +1999-11-12 Lars Magne Ingebrigtsen + + * gnus-int.el (gnus-server-opened): Ignore denied servers. + + * gnus-ems.el (gnus-mule-max-width-function): New backquote + syntax. + + * nndoc.el (nndoc-mime-digest-type-p): Reinstated. + + * nnslashdot.el (nnslashdot-group-number): Changed default. + + * nnweb.el (nnweb-dejanews-create-mapping): Work with new deja. + (nnweb-dejanews-wash-article): Removed. + (nnweb-type-definition): Fetch by id. + + * gnus-msg.el (gnus-configure-posting-styles): Don't insert unless + we mean it. + + * nnslashdot.el (nnslashdot-group-number): Doc fix. + (nnslashdot-request-list): Use Ultramode as well. + (nnslashdot-date-to-date): Be more lenient. + (nnslashdot-threaded): New function. + +1999-11-11 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-mime-internalize-part): Doc fix. + +1999-11-11 Steinar Bang + + * nnweb.el (nnweb-type-definition): /=dnc + +1999-11-11 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-retrieve-headers): Work with american + dates. + (nnultimate-retrieve-headers): Wrong ordering. + +1999-11-11 Matt Pharr + + * message.el (message-forward-as-mime): New variable. + +1999-11-11 Lars Magne Ingebrigtsen + + * gnus-util.el (gnus-dd-mmm): Beware buggy dates. + +1999-11-10 Shenghuo ZHU + + * mail-source.el (mail-source-movemail-and-remove): New function. + (mail-source-keyword-map): Add `function' for `maildir'. + (mail-source-fetch-maildir): Use it. + +1999-11-10 Shenghuo ZHU + + * nnwarchive.el: New file. + * gnus-group.el (gnus-group-make-warchive-group): New function. + * gnus.el (gnus-valid-select-methods): Add `nnwarchive'. + +1999-11-10 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-retrieve-headers): Work for multi-page + subjects. + +1999-11-10 Rajappa Iyer + + * gnus-salt.el (gnus-pick-article-or-thread): Don't move point. + +1999-11-10 Lars Magne Ingebrigtsen + + * nnultimate.el (nnultimate-open-server): Do address. + (nnultimate-forum-table-p): New function. + + * nnweb.el (nnweb-insert-html): Renamed. + (nnweb-insert): New function. + + * nnultimate.el (nnultimate-insert-html): New function. + + * nnslashdot.el (nnslashdot-retrieve-headers): Don't do anything + if nov is evil. + (nnslashdot-retrieve-headers): use the sane version instead. + +1999-11-09 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-request-article): Fold case. + + * nnultimate.el: New file. + + * nnslashdot.el (nnslashdot-retrieve-headers): Skip the article + unless wanted. + + * gnus-start.el (gnus-active-to-gnus-format): Catch errors. + (gnus-read-active-file-1): Separated into own function. + (gnus-read-active-file): Catch quits. + + * nnslashdot.el (nnslashdot-request-article): Search better on + first article. + (nnslashdot-request-list): Fold case. + (nnslashdot-retrieve-headers): Ditto. + +1999-11-08 Lars Magne Ingebrigtsen + + * gnus.el: Autoload gnus-subscribe-topics. + +1999-11-07 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-save-group-info): Remove backslash + before dot. + * gnus-util.el (gnus-write-active-file): Ditto. + +1999-11-07 Shenghuo ZHU + + * nnheader.el (nnheader-replace-duplicate-chars-in-string): New + function. + * gnus-cache.el (gnus-cache-file-name): Use it. + * gnus-agent.el (gnus-agent-group-path): Use it. + * nnmail.el (nnmail-group-pathname): Use it. + +1999-11-07 Shenghuo ZHU + + * gnus-start.el (gnus-active-to-gnus-format): Don't insert backslash + if cooked. + * gnus-util.el (gnus-write-active-file): Write cooked active file. + * gnus-agent.el (gnus-agent-save-group-info): Ditto. + * gnus.el (gnus-short-group-name): "..." proof. + +1999-11-07 Shenghuo ZHU + + * gnus-srvr.el (gnus-browse-foreign-server): Keep using `read' to + support nnslashdot. + +1999-11-08 Lars Magne Ingebrigtsen + + * nnslashdot.el (nnslashdot-retrieve-headers): Don't fetch too + many articles. + (nnslashdot-generate-active): New function. + (nnslashdot-request-newgroups): Use it. + + * gnus-start.el (gnus-active-to-gnus-format): Intern strings group + names. + + * nnslashdot.el (nnslashdot-request-newgroups): New function. + (nnslashdot-request-list): Not moderated. + +1999-11-07 Simon Josefsson + + * nnimap.el (nnimap-open-server): Remove error signal if + nnimap-server-buffer is nil (the check should've been `boundp'). + + * imap.el (imap-log): + * nnimap.el (nnimap-debug): Disable debugging by default. + +1999-11-07 Lars Magne Ingebrigtsen + + * gnus-start.el (gnus-subscribe-newsgroup-method): Doc fix. + + * gnus-topic.el (gnus-subscribe-topic): New function. + + * nnslashdot.el (nnslashdot-request-list): Give out extended group + names. + + * gnus-start.el (gnus-ignored-newsgroups): Disregard bogus chars + if starting with a quote. + +1999-11-07 Shenghuo ZHU + + * gnus-srvr.el (gnus-browse-foreign-server): Support backslash in + group name. + +1999-11-07 Lars Magne Ingebrigtsen + + * nnslashdot.el: New file. + + * nnheader.el (nnheader-insert-header): New function. + + * gnus-art.el (gnus-mime-internalize-part): Bind + mm-inlined-types. + + * nndraft.el (nndraft-request-expire-articles): Do all the backup + files. + +1999-10-29 David S. Goldberg + + * emacs-mime.texi (Customization): Document mm-inline-override-types + +1999-10-29 David S. Goldberg + + * emacs-mime.texi (Customization): Document mm-inline-override-types + +1999-10-29 David S. Goldberg + + * emacs-mime.texi (Customization): Document mm-inline-override-types + +1999-11-07 Lars Magne Ingebrigtsen + + * gnus-topic.el (gnus-topic-goto-missing-topic): Work even in + empty buffers. + +1999-11-06 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-mode-map): Use the summary article + edit. + +1999-11-06 Jens-Ulrik Petersen + + * gnus-group.el (gnus-group-read-ephemeral-group): Doc fix. + +1999-11-06 Lars Magne Ingebrigtsen + + * gnus-uu.el (gnus-uu-mark-thread): Don't move point around. + +1999-10-07 Katsumi Yamaoka + + * gnus-art.el (gnus-treat-predicate): Examine whether the argument + is list or not before condition. + +1999-10-07 Yoshiki Hayashi + + * gnus-art.el (gnus-treat-predicate): Work for (typep "something"). + +1999-11-06 Kevin the Bandicoot + + * gnus-art.el (gnus-emphasis-alist): New value. + +1999-11-06 Shenghuo ZHU + + * gnus-srvr.el (gnus-browse-foreign-server): Use both `read' and + `buffer-substring'. + +1999-11-06 Lars Magne Ingebrigtsen + + * gnus-art.el (article-date-ut): Keep the updated timer. + (gnus-emphasis-underline-italic): Doc fix. + + * gnus-msg.el (gnus-post-method): Doc fix. + (gnus-post-method): Change default. + +1999-11-06 Francisco Solsona + + * message.el (message-newline-and-reformat): Improvements. + +1999-11-06 Lars Magne Ingebrigtsen + + * message.el (message-newline-and-reformat): Don't insert too many + newlines. + (message-newline-and-reformat): Work even if not sc. + + * mm-view.el (mm-inline-message): Insert a delimiter at the end. + + * mm-decode.el (mm-inline-media-tests): Only if diff mode. + +1999-11-06 Toby Speight + + * mm-view.el (mm-display-patch-inline): New function. + +1999-11-06 Robert Bihlmeyer + + * mm-view.el (mm-display-patch-inline): New function. + +1999-11-06 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-read-move-group-name): Subscribe to the + group. + + * message.el (message-forward): Narrow to the right header. + + * gnus-sum.el (gnus-summary-limit-to-age): Protect against bogus + dates. + + * gnus-msg.el (gnus-configure-posting-styles): Use the + user-full-name function. + + * mm-bodies.el (mm-body-encoding): Use the choosing function. + (mm-body-charset-encoding-alist): Default to nil. + + * message.el (message-elide-ellipsis): Fix typo. + (message-elide-region): Ditto. + (message-elide-region): Don't insert a newline first. + +1999-11-05 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-cut-thread): Also cut for numberp + gnus-fetch-old-headers. + (gnus-cut-threads): Ditto. + (gnus-summary-initial-limit): Ditto. + (gnus-summary-limit-children): Ditto. + + * gnus-msg.el (gnus-configure-posting-styles): Allow `header' + matches. + +1999-11-06 Simon Josefsson + + * gnus-art.el (article-decode-encoded-words): + (gnus-mime-display-single): Don't assume gnus-summary-buffer is + live. + + * gnus.el (gnus-read-method): Add methods from + `gnus-opened-servers' to completion. Map entered method/address + into existing methods if possible. + + * gnus-group.el (gnus-group-make-group): Simplify method. + + * gnus-srvr.el (gnus-browse-unsubscribe-group): Simplify method. + + * mml.el (mml-preview): Remove mail-header-separator before + encoding. + +1999-11-05 Lars Magne Ingebrigtsen + + * message.el (message-read-from-minibuffer): New function. + +1999-11-05 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.98 is released. + +1999-11-05 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-expire): Remove bad line in NOV. + +1999-11-04 Shenghuo ZHU + + * mml.el (mml-generate-mime-1): Read attached binary file in + binary mode. + +1999-11-03 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-toggle-header): Fix arg bug. + +1999-11-03 Shenghuo ZHU + + * mailcap.el (mailcap-viewer-lessp): Fix bug. + +1999-11-02 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-search-article): Fix loop search bug. + +1999-10-31 Shenghuo ZHU + + * gnus-art.el (gnus-article-mime-match-handle-first): New function. + (gnus-article-mime-match-handle-function): New variable. + (gnus-article-view-part): Make `b' customizable. + +1999-10-29 Shenghuo ZHU + + * gnus-sum.el (gnus-article-get-xrefs): Test eobp. + +1999-09-27 Hrvoje Niksic + + * mm-decode.el (mm-attachment-override-types): Exclude text/plain. + +1999-10-27 Shenghuo ZHU + + * mm-decode.el (mm-dissect-buffer): CTE may come without CTL. + +1999-10-26 Shenghuo ZHU + + * gnus-srvr.el (gnus-browse-foreign-server): Use + `buffer-substring' instead of `read'. + +1999-10-23 Simon Josefsson + + * nnimap.el, imap.el, rfc2104.el: New files. + + * gnus.el (gnus-valid-select-methods): Add nnimap. + + * gnus-group.el (gnus-group-group-map): Add + gnus-group-nnimap-edit-acl, gnus-group-nnimap-expunge. + (gnus-group-nnimap-expunge): New function. + (gnus-group-nnimap-edit-acl): New function. + + * gnus-agent.el (gnus-agent-group-mode-map): Add + gnus-agent-synchronize. + (gnus-agent-synchronize): New function. + (gnus-agent-fetch-group-1): Check if server is open. + + * nnagent.el (nnagent-request-set-mark): Save marks. + + * mail-source.el (mail-source-keyword-map): New imap mail-source. + (mail-source-fetcher-alist): Map to imap fetcher function. + (mail-source-fetch-imap): New function. + + * gnus-art.el (article-hide-pgp): Hide all headers, not just + Hash:. + +1999-10-22 Shenghuo ZHU + + * gnus-topic.el (gnus-topic-sort-topics-1): New function. + (gnus-topic-sort-topics): New function. + (gnus-topic-make-menu-bar): Add sort-topics. + (gnus-topic-move): New function. + (gnus-topic-move-group): Move the topic if no group selected. + +1999-10-13 Shenghuo ZHU + + * gnus-art.el (gnus-article-setup-buffer): Fix buffer leak. + +1999-10-13 Shenghuo ZHU + + * mm-view.el (mm-inline-message): Fix leaving group bug. + +1999-10-07 Shenghuo ZHU + + * gnus-msg.el (gnus-post-method): Use normal method if current is + not available. + +1999-10-07 Shenghuo ZHU + + * nnmail.el (nnmail-insert-xref): Dealing with empty articles. + (nnmail-insert-lines): Ditto. + +1999-10-07 Shenghuo ZHU + + * nnfolder.el (nnfolder-insert-newsgroup-line): Insert a blank + line. + + * message.el (message-unsent-separator): One more separator. + +1999-10-06 Shenghuo ZHU + + * nnfolder.el (nnfolder-request-move-article): For empty article, + search till (point-max). + (nnfolder-retrieve-headers): Ditto. + (nnfolder-request-accept-article): Ditto. + (nnfolder-save-mail): Ditto. + (nnfolder-insert-newsgroup-line): Ditto. + +1999-10-05 Shenghuo ZHU + + * qp.el (quoted-printable-encode-region): Check eobp. + +1999-10-03 Shenghuo ZHU + + * nntp.el (nntp-retrieve-headers-with-xover): Fix hanging problem. + +1999-10-02 Shenghuo ZHU + + * nntp.el (nntp-send-xover-command): Wait for nothing if not + wait-for-reply. + +1999-09-29 Shenghuo ZHU + + * mm-uu.el (mm-uu-forward-begin-line): Change the regexp. + (mm-uu-forward-end-line): Ditto. + +1999-09-29 Didier Verna + + * binhex.el (binhex-decode-region): don't consider the value of + `enable-multibyte-characters' in XEmacs. + + * gnus-start.el (gnus-read-descriptions-file): ditto. + + * mm-util.el (mm-multibyte-p): ditto. + (mm-with-unibyte-buffer): ditto. + (mm-find-charset-region): use `mm-multibyte-p'. + + * mm-bodies.el (mm-decode-body): ditto. + (mm-decode-string): ditto. + +1999-09-29 Shenghuo ZHU + + * mm-util.el (mm-binary-coding-system): Try binary first. + +1999-09-14 Shenghuo ZHU + + * rfc1843.el (rfc1843-decode-article-body): Don't decode twice. + +1999-09-10 Shenghuo ZHU + + * gnus-art.el (article-make-date-line): Add time-zone in iso8601 + format. + (article-date-ut): Find correct insert position. + +1999-09-03 Shenghuo ZHU + + * mm-uu.el (mm-uu-dissect): Do not dissect quoted-printable + forwarded message. + +1999-09-27 Lars Magne Ingebrigtsen + + * gnus-topic.el (gnus-topic-find-groups): Work for unactivated + groups. + + * message.el (message-resend): Use message mode when prompting. + + * gnus-art.el (article-hide-headers): Mark wash. + (article-emphasize): Ditto. + +1999-09-27 Vladimir Volovich + + * message.el (message-newline-and-reformat): Work for SC. + +1999-09-27 Lars Magne Ingebrigtsen + + * gnus-msg.el (gnus-group-posting-charset-alist): 2047 in de.*. + + * gnus-sum.el (gnus-newsgroup-ignored-charsets): Add x-unknown. + +1999-10-20 David S. Goldberg + + * mm-decode.el mm-inline-override-types: New variable + + * mm-decode.el (mm-inline-override-p): New function + + * mm-decode.el (mm-inlined-p): Use it + +1999-10-20 David S. Goldberg + + * mm-decode.el mm-inline-override-types: New variable + + * mm-decode.el (mm-inline-override-p): New function + + * mm-decode.el (mm-inlined-p): Use it + +1999-09-27 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.97 is released. + +1999-09-01 Brendan Kehoe + + * gnus-sum.el (gnus-summary-catchup-and-goto-next-group): Use + gnus-summary-next-group, not gnus-summary-next-article. Only give + 3 args. + +1999-09-25 Lars Magne Ingebrigtsen + + * gnus-agent.el (gnus-agent-fetch-group-1): Look in the group + buffer for params. + + * message.el (message-forward-ignored-headers): New variable. + + * gnus-art.el (gnus-article-prepare-display): Nix out + gnus-article-wash-types. + + * gnus-agent.el (gnus-agent-create-buffer): New function. + (gnus-agent-fetch-group-1): Use it. + (gnus-agent-start-fetch): Ditto. + + * gnus-sum.el (gnus-summary-exit): Don't use + `gnus-use-adaptive-scoring'. + + * mail-source.el (mail-source-fetch-pop): Only store password when + successful. + + * gnus-nocem.el (gnus-nocem-scan-groups): Message better. + +1999-09-24 Lars Magne Ingebrigtsen + + * message.el (message-reply): Use it. + (message-dont-reply-to-names): New variable. + + * nntp.el (nntp-open-telnet): Don't erase-buffer. + + * mm-util.el (mm-preferred-coding-system): Typo fix. + + * message.el (message-bounce): Work for non-MIME. + + * gnus.el (gnus-short-group-name): Short the right parts of the + name. + +1999-09-24 Johan Kullstam + + * mm-encode.el (mm-qp-or-base64): New version. + +1999-09-10 Shenghuo ZHU + + * gnus-art.el (article-make-date-line): Fix time-zone bug. + +1999-09-09 Shenghuo ZHU + + * gnus-art.el (gnus-article-add-buttons): Don't delete markers out + of restricted region. + (gnus-mime-display-single): Set beg at correct point. + +1999-09-09 Shenghuo ZHU + + * nnmail.el (nnmail-process-maildir-mail-format): Typo. + +1999-09-09 Jens-Ulrik Petersen + + * gnus-msg.el (gnus-configure-posting-styles): Let + `gnus-posting-styles' have its say in posting-style: local + variable `styles' is already bound to `gnus-posting-styles' so + don't rebind it to nil. + +1999-09-24 Robert Bihlmeyer + + * gnus-score.el (gnus-summary-increase-score): Allow editing of + Message-ID. + +1999-09-08 Shenghuo ZHU + + * mm-encode.el (mm-encode-content-transfer-encoding): Fold + quoted-printable-encode-region. + + * qp.el (quoted-printable-encode-region): Assume charset + encoded. Fold every line in the region. + +1999-09-02 Shenghuo ZHU + + * gnus-srvr.el (gnus-browse-foreign-server): Read the first line + of active file. + +1999-09-01 Didier Verna + + * message.el (message-mode): allows whitespaces between multiple + instances of the fill character ">". + +1999-09-24 Kim-Minh Kaplan + + * mm-encode.el (mm-qp-or-base64): Fix. + +1999-09-01 Katsumi Yamaoka + + * message.el (message-send): Too much and. + +1999-09-24 Andreas Schwab + + * gnus-art.el (gnus-mime-view-part-as-type): Renamed. + +1999-08-28 Lars Magne Ingebrigtsen + + * gnus-score.el (gnus-score-headers): Work for nil scores. + +1999-08-27 Lars Magne Ingebrigtsen + + * gnus-cache.el (gnus-cache-write-active): Write full names. + + * gnus-util.el (gnus-write-active-file): Accept full name. + + * mm-decode.el (mm-inlinable-p): Use string-match on the types. + (mm-assoc-string-match): New function. + (mm-display-inline): Use it. + + * gnus-group.el (gnus-group-set-info): Work for nil group params. + + * gnus-msg.el (gnus-configure-posting-styles): Allow eval. + +1999-08-27 Florian Weimer + + * mml.el (mml-generate-multipart-alist): New variable. + +1999-08-27 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-treat-predicate): Work for (not 5). + +1999-08-27 Peter von der Ahe + + * message.el (message-send): More helpful error message if sending + fails + +1999-09-06 Robert Bihlmeyer + + * gnus-score.el (gnus-summary-increase-score): "Lars" was broken + in newer emacsen, where ?r isn't equal 114. + +1999-08-27 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.96 is released. + +1999-08-17 Simon Josefsson + + * gnus-start.el (gnus-groups-to-gnus-format): Only use agent + to get active info if method is covered by agent, otherwise + active info is lost. + +1999-08-17 Simon Josefsson + + * gnus-sum.el (gnus-summary-move-article): Report backend errors. + +1999-08-09 Dave Love + + * mm-util.el: Use `defalias', not `fset' for dummy functions. + +1999-08-09 Simon Josefsson + + * gnus-art.el (gnus-ignored-headers): Remove "X-Pgp-*" + (already matched by "^X-Pgp"), removed duplicate + X-Mailing-List, added several new junk headers. + +1999-08-01 Simon Josefsson + + * gnus-art.el (article-decode-charset): Don't assume + gnus-summary-buffer is live. + +1999-08-27 Florian Weimer + + * gnus-score.el (gnus-home-score-file): Work with absolute path + names. + +1999-07-17 Shenghuo ZHU + + * gnus-sum.el (gnus-articles-to-read): Return cached articles if + nothing else in the group. + +1999-07-16 Shenghuo ZHU + + * gnus-bcklg.el (gnus-backlog-enter-article): Check the size of + the article. + +1999-07-15 Shenghuo ZHU + + * mm-uu.el (mm-uu-dissect): Fix for base64 message. + +1999-07-15 Shenghuo ZHU + + * mm-uu.el (mm-uu-forward-end-line): Support forwarded message + from mutt. + +1999-07-14 Shenghuo ZHU + + * mm-bodies.el (mm-decode-content-transfer-encoding): Delete + whitespace. + +1999-07-14 Shenghuo ZHU + + * mm-util.el (mm-text-coding-system-for-write): New variable. + (mm-append-to-file): New function. + (mm-write-region): New function. + + * gnus-art.el (gnus-output-to-file): Use it. + * gnus-util.el (gnus-output-to-rmail): Ditto. + (gnus-output-to-mail): Ditto. + * gnus-uu.el (gnus-uu-binhex-article): Ditto. + +1999-07-14 Shenghuo ZHU + + * nnmail.el (nnmail-find-file): Use mm-auto-mode-alist. + + * nnheader.el (nnheader-insert-file-contents): Revert and use + mm-insert-file-contents. + (nnheader-find-file-noselect): Use mm-auto-mode-alist. + (nnheader-auto-mode-alist): Removed. + + * mm-util.el (mm-inhibit-file-name-handlers): New variable. + (mm-insert-file-contents): Add a new parameter for inserting + compressed file literally. + + * mml.el (mml-generate-mime-1): Insert non-text literally. + + * gnus.el: Change most mm-insert-file-contents back to nnheader. + +1999-07-13 Hrvoje Niksic + + * gnus-art.el (gnus-unbuttonized-mime-types): Fix docstring. + +1999-08-27 Oleg S. Tihonov + + * gnus-sum.el (gnus-group-charset-alist): Default fido7 to + koi8-r. + +1999-07-11 Shenghuo ZHU + + * mml.el (mml-insert-mime): Decode text. + (mml-to-mime): Narrow to headers-or-head. + +1999-07-11 Shenghuo ZHU + + * mm-view.el (mm-inline-text): Check + w3-meta-content-type-charset-regexp. + +1999-07-10 Simon Josefsson + + * gnus-agent.el (gnus-agent-fetch-group-1): Search topics for + predicate. + +1999-07-10 Alexandre Oliva + + * gnus-mlspl.el: Documentation fixes. + +1999-08-27 Rui Zhu + + * gnus-sum.el (gnus-summary-limit-to-age): Prompt better. + +1999-08-27 Michael Cook + + * gnus-art.el (gnus-article-setup-buffer): Kill all local + variables. + +1999-08-27 Hrvoje Niksic + + * nnmail.el (nnmail-get-new-mail): "Done". + +1999-08-27 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-kill-all-zombies): Only prompt when + interactive. + +1999-07-12 Shenghuo ZHU + + * gnus-art.el (article-decode-charset): Fix broken CT. + +1999-07-12 Shenghuo ZHU + + * gnus-agent.el (gnus-agent-fetch-group-1): Recreate agent + overview buffer if it is killed. + +1999-08-27 Eric Marsden + + * gnus-art.el (article-babel): New version. + +1999-08-27 Jon Kv + + * nnfolder.el (nnfolder-request-list-newsgroups): Faster expiry. + +1999-07-10 Mike McEwan + + * gnus.texi (More Threading): Document new variable + `gnus-sort-gathered-threads-function'. + +1999-07-10 Mike McEwan + + * gnus.texi (More Threading): Document new variable + `gnus-sort-gathered-threads-function'. + +1999-07-11 Andreas Jaeger + + * gnus-uu.el (gnus-uu-digest-mail-forward): Delete file after + usage. + +1999-07-10 Shenghuo ZHU + + * mm-util.el (mm-running-xemacs): Removed. + (mm-coding-system-p): New function. + (mm-binary-coding-system): Safe guess. + (mm-text-coding-system): Ditto. + (mm-auto-save-coding-system): Ditto. + +1999-07-11 Lars Magne Ingebrigtsen + + * mm-encode.el (mm-qp-or-base64): Also consider control chars. + (mm-qp-or-base64): Reversed logic. + + * mm-decode.el (mm-save-part-to-file): Let coding system be + binary. + +1999-07-15 Mike McEwan + + * gnus-agent.el (gnus-agent-fetch-group-1): Allow 'agent-score' to + be set in topic parameters. + +1999-07-10 Mike McEwan + + * gnus-sum.el (gnus-sort-gathered-threads-function): New variable. + (gnus-sort-gathered-threads): Allow the user to specify the + function to use when sorting gathered threads. + + * gnus-agent.el (gnus-agent-get-undownloaded-list): Don't + mark cached articles as `undownloaded'. + +1999-07-20 Peter von der Ahe + + * gnus-sum.el (gnus-summary-exit): Allow gnus-use-adaptive-scoring + to have buffer local values. + +1999-07-25 Matt Pharr + + * gnus-group.el (gnus-group-make-doc-group): Notice when user + types 'g' for 'guess group type. + +1999-07-30 Simon Josefsson + + * nnmail.el (nnmail-remove-list-identifiers): Remove whitespace + after each regexp in nnmail-list-identifiers, not just after last + one. + + * gnus-sum.el (gnus-list-identifiers): New variable. + (gnus-summary-remove-list-identifiers): New function. + (gnus-select-newsgroup): Use it. + (gnus-summary-wash-hide-map): Bind + `gnus-article-hide-list-identifiers' to W W l. + (gnus-summary-make-menu-bar): Add list-identifiers command. + + * gnus-art.el (gnus-treat-strip-list-identifiers): New variable. + (gnus-treatment-function-alist): Add variable. + (article-hide-list-identifiers): New function. + (mapcar): Add function. + (gnus-article-hide): Use it. + +1999-07-10 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.95 is released. + +1999-07-09 Lars Magne Ingebrigtsen + + * mm-decode.el (mm-mailcap-command): New function. + (mm-display-external): Use it. + + * gnus-art.el (article-make-date-line): Work for India. + + * mm-encode.el (mm-qp-or-base64): Typo. + + * gnus-topic.el (gnus-topic-goto-topic): Made into command. + +1999-07-09 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.94 is released. + +1999-07-09 Stainless Steel Rat + + * pop3.el: New version. + +1999-07-09 Lars Magne Ingebrigtsen + + * mm-encode.el (mm-qp-or-base64): New function. + (mm-content-transfer-encoding): Use it. + + * gnus-util.el (gnus-parse-netrc): Allow quoted names. + +1999-07-08 Shenghuo ZHU + + * mm-decode.el (mm-display-external): Fix typo and use 'non-viewer. + + * mailcap.el (mailcap-mailcap-entry-passes-test): Add needsterminal. + +1999-07-09 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-mime-view-part-as-media): New command and + keystroke. + + * mailcap.el (mailcap-mime-types): New function. + + * nnmh.el (nnmh-request-group): Update nnmh-group-alist. + + * message.el (message-goto-eoh): Really go to the end. + +1999-07-09 Puneet Goel + + * message.el (message-make-date): Do the right thing in with + sub-hour time zones. + +1999-07-09 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-make-menu-bar): Removed double bug + report. + +1999-07-08 Shenghuo ZHU + + * nnfolder.el (nnfolder-request-rename-group): Create directory. + +1999-07-08 Shenghuo ZHU + + * mailcap.el (mailcap-parse-mailcap): Skip \;. + (mailcap-parse-mailcap-extras): Fix "nonterminal;" and empty name, + and use t as default value. + +1999-07-07 Shenghuo ZHU + + * gnus-sum.el (gnus-get-newsgroup-headers): Don't assume + gnus-summary-buffer is live. + +1999-07-09 Robert Pluim + + * mm-util.el (mm-enable-multibyte): Check whether var bound. + +1999-07-09 Lars Magne Ingebrigtsen + + * message.el (message-bounce): Do MIME bounces MIMEy. + + * gnus-sum.el (gnus-summary-read-group-1): Update mark positions. + +1999-07-08 Lars Magne Ingebrigtsen + + * mailcap.el (mailcap-mime-extensions): Changed patch to + text/x-patch. + + * mm-decode.el (mm-display-external): Wrong placement of paren. + +1999-07-07 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.93 is released. + +1999-07-08 Alexandre Oliva + + * gnus-cus.el (gnus-group-parameters): New entries for + gnus-group-split. + + * gnus-mlspl.el: Renamed functions and variables so as to + start with gnus-group-split. + * gnus.el: Adjust autoload entries. + +1999-11-30 ??:??:?? Alexandre Oliva + + * gnus-mlspl.el: Removed trailing t from comment and provide. + Renamed functions and variables to start with gnus-mlsplit. + Added autoload comments. + * gnus.el: Added autoload entries. + +1999-07-06 Alexandre Oliva + + * nnmail.el (nnmail-split-it): Search the regexp multiple times, + so that matches excluded by RESTRICTs do not cause the whole split + to be ignored. This also fixes a long-standing bug in which a + split with \N substitutions wouldn't cause cross-posting as + expected. + + * nnmail.el (nnmail-split-fancy): Document RESTRICT clauses. + (nnmail-split-it): Implement them. + + * nnmail.el (nnmail-split-fancy): Document ! splits. + +1999-07-07 Stainless Steel Rat + + * pop3.el: New version. + +1999-07-05 Simon Josefsson + + * gnus-srvr.el (gnus-browse-foreign-server): Use read. + +1999-07-07 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-mime-display-alternative): Do treatment. + +1999-07-06 Shenghuo ZHU + + * gnus-util.el (gnus-write-active-file): Use real name. + + * gnus-agent.el (gnus-agent-expire): Update active file + method by method. + +1999-07-06 Shenghuo ZHU + + * nndraft.el (nndraft-request-article): Use difference + coding-systems for queue and drafts. + + * gnus-sum.el (gnus-summary-setup-default-charset): Special-case + nndraft:drafts. + + * mm-util.el (mm-auto-save-coding-system): New coding system. + + * message.el (message-draft-coding-system): Use it. + +1999-07-06 Shenghuo ZHU + + * mm-uu.el: More customizable and less aggressive. + +1999-07-07 Lars Magne Ingebrigtsen + + * gnus-start.el (gnus-groups-to-gnus-format): Only gnus-active + when plugged. + + * mml.el (mml-generate-mime-1): Don't insert nofile files. + (mml-insert-mml-markup): Accept a nofile. + (mml-insert-mime): Insert nofile. + + * gnus-art.el (gnus-treat-strip-blank-lines): Removed. + + * mm-decode.el (mm-handle-media-type): New function. + (mm-handle-media-supertype): New function. + (mm-handle-media-subtype): New function. + Use new functions throughout. "/")) + +1999-05-18 Katsumi Yamaoka + + * gnus-art.el (gnus-treat-predicate): Typo. + +1999-07-07 Lars Magne Ingebrigtsen + + * gnus-score.el (gnus-summary-score-entry): Made un-interactive. + +1999-07-06 Lars Magne Ingebrigtsen + + * gnus-art.el (article-date-ut): UT! Default it! + +1999-07-06 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.92 is released. + +1999-07-06 Johannes Weinert + + * gnus-sum.el (gnus-summary-catchup-and-exit): Doc fix. + +1999-07-06 Lars Magne Ingebrigtsen + + * nntp.el (nntp-retrieve-groups): Don't do anything when not + connected. + + * gnus-start.el (gnus-active-to-gnus-format): Only save active + when plugged. + + * mm-view.el (mm-inline-message): Ignore remove-spec. + + * gnus-agent.el (gnus-agent-write-active): Check whether orig sym + is bound. + + * gnus-msg.el (gnus-summary-mail-forward): Rename From_ lines. + + * nndoc.el (nndoc-guess-type): Remove blank lines at the start. + + * nnfolder.el (nnfolder-read-folder): Remove blank lines at the + start. + + * message.el (message-fill-yanked-message): Remove `t' arg. + + * gnus-group.el (gnus-group-kill-group): Message killing of + groups. + + * mm-util.el (mm-preferred-coding-system): New function. + (mm-mime-charset): Use it. + + * mml.el (mml-generate-mime-1): Charset-encode message parts. + +1999-07-06 Alexandre Oliva + + * gnus-mlsplt.el: New file. + +1999-07-06 Lars Magne Ingebrigtsen + + * mm-decode.el (mm-inline-Media-tests): Changed from forms to + functions. + (mm-attachment-override-p): Take a handle instead of a type. + (mm-inlined-p): Ditto. + (mm-automatic-display-p): Ditto, + (mm-inlinable-p): Ditto. + + * nndraft.el (nndraft-request-expire-articles): Delete backup + files. + + * mailcap.el (mailcap-parse-mailcap): Regexp-quote stuff. + + * gnus-sum.el (gnus-summary-limit-to-extra): Typo. + +1999-07-06 Alexandre Oliva + + * nnmail.el (nnmail-split-it): Allow .*. + +1999-07-05 Lars Magne Ingebrigtsen + + * mm-decode.el (mm-inline-large-images-p): Renamed. + + * gnus-art.el (article-date-ut): Always look in the current buffer + for the Date header. + + * mml.el (mml-validate): New command. + + * mailcap.el (mailcap-possible-viewers): Revert to string-match + since we are dealing with regexps. + +1999-07-04 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.91 is released. + +1999-07-04 Lars Magne Ingebrigtsen + + * gnus-agent.el (gnus-agent-save-active-1): New function. + (gnus-agent-save-active): use it. + (gnus-agent-save-groups): Ditto. + + * gnus-cache.el (gnus-cache-write-active): Use it. + + * gnus-agent.el (gnus-agent-write-active): Use it. + + * gnus-util.el (gnus-write-active-file): New function. + + * gnus-agent.el (gnus-agent-write-active): New function to keep + lower boundaries and canceled groups. + (gnus-agent-save-groups): Use it. + (gnus-agent-save-active): Use it. + (gnus-agent-save-group-info): Only write active files. + (gnus-agent-expire): Update active file. + + * mm-decode.el (mm-inlinable-part-p): Removed. + (mm-user-display-methods): Default to nil. + (mm-user-display-methods): Removed. + (add-mime-display-method): Removed. + (mm-automatic-display): Renamed. + (mm-automatic-display-p): Use it. + (mm-inlined-types): New variable. + (mm-inlined-p): New function. + + * message.el (message-reply): Bind message-this-is-mail. + +1999-07-03 Lars Magne Ingebrigtsen + + * mm-encode.el (mm-encode-buffer): Check whether we have 7bit. + + * message.el (message-check-news-header-syntax): Protect against + nil froms. + + * mm-util.el (mm-auto-mode-alist): New. + + * mml.el (mml-generate-mime-1): Ditto. + + * gnus.el: Use mm-insert-file-contents throughout instead of + nnheader. + + * mm-util.el (mm-insert-file-contents): New function. + +1999-07-03 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.90 is released. + +1999-07-03 Sven Fischer + + * mailcap.el (mailcap-possible-viewers): Use string=. + +1999-07-01 Shenghuo ZHU + + * mm-uu.el (mm-uu-forward-begin-line): New variable. + (mm-uu-forward-end-line): New variable. + (mm-uu-begin-line): Handle forwarded message. + (mm-uu-identifier-alist): Ditto. + (mm-uu-dissect): Ditto. + +1999-07-02 Shenghuo ZHU + + * nnheader.el (nnheader-file-coding-system): Use raw-text. + * gnus-agent.el (gnus-agent-file-coding-system): Ditto. + * gnus-cache.el (gnus-cache-coding-system): Ditto. + + * nnfolder.el (nnfolder-file-coding-system): Use mm-text-coding-system. + (nnfolder-file-coding-system-for-write): New variable. + (nnfolder-active-file-coding-system): New variable. + (nnfolder-active-file-coding-system-for-write): New variable. + (nnfolder-save-active): New function. + (nnfolder-save-buffer): Use them. + (nnfolder-possibly-change-group): Ditto. + (nnfolder-request-list-newsgroups): Ditto. + (nnfolder-request-create-group): Ditto. + (nnfolder-request-expire-articles): Ditto. + (nnfolder-request-move-article): Ditto. + (nnfolder-request-accept-article): Ditto. + (nnfolder-request-delete-group): Ditto. + (nnfolder-request-rename-group): Ditto. + (nnfolder-possibly-change-folder): Ditto. + (nnfolder-read-folder): Ditto. + (nnfolder-request-list): Remove pathname-coding-system. + (nnfolder-possibly-change-group): Use nnmail-pathname-coding-system. + + * nnmail.el (nnmail-file-coding-system): Use raw-text. + (nnmail-file-coding-system-1): Removed. + (nnmail-find-file): Use nnmail-pathname-coding-system. + (nnmail-write-region): Ditto. + + * nnmbox.el (nnmbox-file-coding-system): New variable. + (nnmbox-file-coding-system-for-write): New variable. + (nnmbox-active-file-coding-system): New variable. + (nnmbox-active-file-coding-system-for-write): New variable. + (nnmbox-save-buffer): New function. + (nnmbox-save-active): New function. + (nnmbox-request-scan): Use them. + (nnmbox-request-expire-articles): Ditto. + (nnmbox-request-move-article): Ditto. + (nnmbox-request-accept-article): Ditto. + (nnmbox-request-replace-article): Ditto. + (nnmbox-request-delete-group): Ditto. + (nnmbox-request-rename-group): Ditto. + (nnmbox-request-create-group): Ditto. + + * mm-util.el (mm-text-coding-system): raw-text or -dos. + (mm-running-ntemacs): Removed. + + * nnml.el (nnml-file-coding-system): Use nnmail-file-coding-system. + +1999-07-02 Shenghuo ZHU + + * nnfolder.el (nnfolder-read-folder): Use nnheader-file-coding-system. + +1999-07-01 Shenghuo ZHU + + * qp.el (quoted-printable-encoding-characters): Support lower case. + +1999-07-01 Shenghuo ZHU + + * rfc2047.el (rfc2047-encode): Fold before B-encoding. + (rfc2047-b-encode-region): Encode line by line. + +1999-07-03 Lars Magne Ingebrigtsen + + * mm-util.el (mm-find-mime-charset-region): Fix. + +1999-06-30 KOSEKI Yoshinori + + * mm-util.el (mm-mime-mule-charset-alist): Fix iso-2022-jp(-2) bug. + (mm-find-mime-charset-region): Ditto. + +1999-07-03 Simon Josefsson + + * gnus-sum.el (gnus-summary-move-article): Fix something or + other. + +1999-06-29 Shenghuo ZHU + + * gnus-sum.el (gnus-newsgroup-ephemeral-charset): New variable. + (gnus-newsgroup-ephemeral-ignored-charsets): New variable. + (gnus-summary-enter-digest-group): Use them. + (gnus-summary-setup-default-charset): Ditto. + +1999-06-15 Shenghuo ZHU + + * gnus-msg.el (gnus-configure-posting-styles): Fix bug when + gnus-newsgroup-name is nil. + +1999-06-15 Shenghuo ZHU + + * rfc2047.el (rfc2047-encode): Chop the tail newline. + +1999-06-15 Shenghuo ZHU + + * gnus-art.el (article-emphasize): Use correct + gnus-article-emphasis-alist. + +1999-06-15 Shenghuo ZHU + + * mm-view.el (mm-inline-text): Fix text/html bug. + +1999-06-28 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.89 is released. + +1999-06-24 Shenghuo ZHU + + * nnmail.el (nnmail-file-coding-system-1): For NTEmacs in Windows. + * message.el (message-draft-coding-system): Ditto. + * mm-util.el (mm-running-ntemacs): Ditto. + +1999-06-23 Shenghuo ZHU + + * mm-view.el (mm-inline-text): Ignore error in w3-region. + +1999-06-23 Shenghuo ZHU + + * mml.el: require mm-decode. + +1999-06-23 Shenghuo ZHU + + * gnus-art.el (gnus-display-mime): Treat as head only if necessary. + +1999-06-23 Shenghuo ZHU + + * mm-view.el (mm-inline-image): Fix image undisplayer. + +1999-06-22 Shenghuo ZHU + + * mml.el (mml-insert-multipart): Error in compeling-read. + (mml-insert-tag): Match tags. + +1999-06-19 Shenghuo ZHU + + * gnus-cache.el (gnus-cache-braid-nov): Fix coding-system bug. + (gnus-cache-braid-heads): Ditto. + (gnus-cache-retrieve-headers): Ditto. + +1999-06-16 Shenghuo ZHU + + * gnus-draft.el (gnus-draft-send): Fix encoding bug. + +1999-06-16 Katsumi Yamaoka + + * gnus-art.el (gnus-article-read-summary-keys): Convert key events + to string under XEmacs. + +1999-06-28 Petersen Jens-Ulrik + + * gnus-start.el (gnus-find-new-newsgroups): Doc fix. + +1999-06-22 Shenghuo ZHU + + * mm-view.el (mm-inline-message): Fix message view bug. + * gnus-art.el (gnus-article-prepare): Ditto. + +1999-06-16 Shenghuo ZHU + + * gnus-cache.el (gnus-cache-possibly-enter-article): Fetch headers. + +1999-06-15 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.88 is released. + +1999-06-15 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-save-parts): Destroy handles after + usage. + + * nnmail.el (nnmail-get-new-mail): Save info. + +1999-06-14 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.87 is released. + +1999-06-14 Lars Magne Ingebrigtsen + + * mail-source.el (mail-source-fetch-file): Use prescript-delay. + (mail-source-run-script): New function. + (mail-source-fetch-pop): Use it. + +1999-06-13 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-setup-highlight-words): Moved here. + +1999-06-13 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.86 is released. + +1999-06-13 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-treat-translate): New variable. + (gnus-treat-predicate): Accept a list of regexps. + (gnus-article-treat-custom): Allow a list of regexps. + +1999-06-09 Markus Rost + + * gnus/gnus-group.el (gnus-permanently-visible-groups): Fix custom + type. + +1999-06-13 Lars Magne Ingebrigtsen + + * gnus-art.el (article-babel): Narrow a bit. + + * gnus-agent.el (gnus-agent-get-undownloaded-list): Was too slow. + +1999-06-12 Simon Josefsson + + (gnus-agent-get-undownloaded-list): Operate on all articles, not + only unread ones. + (gnus-agent-fetch-headers): Fetch headers from unread and marked + articles, not only unread ones. + +1999-06-13 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-limit-to-extra): New command and + keystroke. + + * gnus-art.el (gnus-article-x-face-command): Ditto. + + * gnus-uu.el (gnus-uu-default-view-rules): Default to "display". + + * gnus.el (gnus-method-simplify): Accept server names. + +1999-06-13 Per Abrahamsen + + * gnus-art.el (article-babel-prompt): New function. + (article-babel): New command. + +1999-06-13 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-part-wrapper): Go to part. + + * mml.el (mml-generate-mime-1): Don't insert literally. + + * gnus-util.el (gnus-parse-netrc): Skip lines with #'s. + (gnus-netrc-syntax-table): Removed. + (gnus-parse-netrc): Don't use syntax table; just use whitespace. + +1999-05-05 Shenghuo ZHU + + * mm-view.el (mm-inline-text): Fix charset for text/html. + +1999-05-05 Shenghuo ZHU + + * message.el (message-draft-coding-system): Use emacs-mule-dos. + +1999-06-12 Lars Magne Ingebrigtsen + + * nnmail.el (nnmail-split-incoming): Return the number of split + mails. + (nnmail-process-babyl-mail-format): Ditto. + (nnmail-process-unix-mail-format): Ditto. + (nnmail-process-mmdf-mail-format): Ditto. + (nnmail-process-maildir-mail-format): Ditto. + + * mail-source.el (mail-source-callback): Return the number from + the callback. + + * message.el (message-send-mail): Generate Lines. + + * mail-source.el (mail-source-call-script): New function. + (mail-source-call-script): New function. + +1999-05-02 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-setup-highlight-words): New function. + (gnus-select-newsgroup): Use it. + (gnus-group-highlight-words-alist): New variable. + (gnus-newsgroup-emphasis-alist): New variable. + (gnus-summary-local-variables): Use it. + * gnus-art.el (article-emphasize): Use it. + (gnus-emphasis-highlight-words): New face. + * gnus-cus.el (gnus-group-parameters): New parameter. + +1999-05-02 Shenghuo ZHU + + * gnus-cache.el (gnus-cache-possibly-enter-article): Remove + parameter `headers'. + (gnus-cache-enter-article): Ditto. + (gnus-cache-update-article): Ditto. + * gnus-sum.el (gnus-summary-move-article): Ditto. + (gnus-summary-mark-article-as-unread): Ditto. + (gnus-summary-mark-article): Ditto. + +1999-06-12 Lars Magne Ingebrigtsen + + * gnus-msg.el (gnus-message-insert-stylings): Removed. + (gnus-posting-style-alist): Removed. + (gnus-message-style-insertions): Ditto. + (gnus-configure-posting-styles): Reimplementation. + + * mail-source.el (mail-source-fetch): Error the message. + + * gnus-msg.el (gnus-inews-do-gcc): Do mml and encoding. + +1999-06-12 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.85 is released. + +1999-04-20 Michael Cook + + * gnus-cite.el (gnus-cite-attribution-prefix): Tweak for MS + Outlook citation regex. + +1999-06-12 Lars Magne Ingebrigtsen + + * nndoc.el (nndoc-mime-parts-type-p): Accept space before + semicolon. + +1999-05-24 Simon Josefsson + + * gnus-range.el (gnus-remove-from-range): Document range1 + modification, protect range2. + +1999-05-24 Simon Josefsson + + * gnus-sum.el (gnus-update-marks): Protect lists from + gnus-remove-from-range, don't sort twice. + +1999-05-21 Simon Josefsson + + * gnus-start.el (gnus-read-descriptions-file): Protect if no + function in backend. + +1999-05-15 Simon Josefsson + + * gnus-sum.el (gnus-valid-move-group-p): Check for a + request-accept-article function in the backend instead of using + the 'respool capability. + +1999-04-18 Hrvoje Niksic + + * mm-bodies.el (mm-decode-content-transfer-encoding): Handle + spurious whitespace at eob. + +1999-06-12 Adrian Aichner + + * nnmail.el (nnmail-get-new-mail): Check right variable. + +1999-06-12 Karl Kleinpaste + + * mailcap.el (mailcap-mime-data): Fix rfc822. + +1999-06-12 TOZAWA Akihiko + + * nndoc.el (nndoc-nsmail-type-p): New function. + (nndoc-type-alist): Recognize nsmail. + +1999-05-12 Mike McEwan + + * gnus-art.el (gnus-treatment-function-alist): Display `x-face' + *before* `article-hide-headers' deletes the information. + +1999-05-22 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-save-parts): New command and + keystroke. + (gnus-summary-save-parts-1): New function. + (gnus-summary-iterate): Buggy. + + * mm-decode.el (mm-save-part-to-file): Made into own function. + +1999-05-11 Lars Magne Ingebrigtsen + + * gnus-group.el (gnus-group-set-info): Resist nils. + +1999-05-04 Lars Magne Ingebrigtsen + + * mailcap.el (mailcap-mime-data): Ditto. + + * gnus-uu.el (gnus-uu-default-view-rules): Ditto. + + * gnus-art.el (gnus-article-x-face-command): Default to ee. + +1999-05-02 Gareth Jones + + * gnus-art.el (article-make-date-line): Put X-Sent below Date if + gnus-article-date-lapsed-new-header is t. + +1999-05-01 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.84 is released. + +1999-05-02 Lars Magne Ingebrigtsen + + * gnus-msg.el (gnus-bug-message): Mime change. + +1999-04-22 Simon Josefsson + + * gnus-sum.el (gnus-update-marks): Process null mark lists. + +1999-04-21 Hrvoje Niksic + + * mm-bodies.el (mm-decode-content-transfer-encoding): Recognize + `x-uue'. + +1999-03-04 Aaron M. Ucko + + * mail-source.el (mail-source-fetch-pop): Only prompt for password + when authentication is 'password. + +1999-05-02 + + * gnus-win.el (gnus-configure-windows): Accept a setting. + +1999-04-21 Lars Magne Ingebrigtsen + + * mm-util.el (mm-quote-arg): Moved here. + + * mm-decode.el (mm-quote-arg): Quote more chars. + +1999-04-18 Lars Magne Ingebrigtsen + + * nnheader.el (nnheader-parse-head): Message-ID in In-Reply-To + with newlines would create buggy .nov files. + + * gnus-art.el (gnus-article-date-lapsed-new-header): Default to nil. + + * qp.el (quoted-printable-encode-region): Encode whitespace at the + end of lines. + + * message.el (message-mode): Doc fix. + + * gnus-art.el (article-hide-headers): Delete the hidden headers. + + * gnus-msg.el (gnus-setup-posting-charset): Default group to "". + + * gnus-art.el (article-date-ut): Rewrite. + + * mm-decode.el (mm-preferred-alternative-precedence): Reverse the + order. + + * gnus-msg.el (gnus-message-insert-stylings): Remove duplicate + headers. + + * gnus-art.el (gnus-article-date-lapsed-new-header): Doc fix. + +1999-04-18 Didier Verna + + * gnus-art.el (gnus-article-date-lapsed-new-header): new variable. + (article-date-ut): use it. + +1999-04-18 Lars Magne Ingebrigtsen + + * mail-source.el (mail-source-fetch-pop): Call script + asynchronously. + +1999-04-18 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.83 is released. + +1999-04-18 Lars Magne Ingebrigtsen + + * gnus-draft.el (gnus-draft-mode): Use mml minor mode. + + * gnus-cite.el (gnus-dissect-cited-text): Off-by-one error. + + * gnus-uu.el (gnus-uu-mark-thread): Save hidden threads. + + * gnus-art.el (gnus-mime-inline-part): Don't do a charset param. + + * gnus-msg.el (gnus-bug): Use application/x-emacs-lisp. + + * message.el (message-generate-headers): Accept continuation + headers. + +1999-04-18 Renaud Rioboo + + * gnus-demon.el (gnus-demon-time-to-step): Not strings. + +1999-04-18 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-treatment-function-alist): use + maybe-hide-headers. + + * message.el (message-inhibit-body-encoding): Typo. + (message-resend): Inhibit encoding. + + * gnus-sum.el (gnus-summary-toggle-header): Decode rfc2047. + + * gnus-art.el (article-remove-cr): Use re-search. + + * rfc2231.el (rfc2231-parse-string): Allow broken elm MIME + headers. + + * mm-decode.el (mm-quote-arg): Quote '. + + * gnus-ems.el (gnus-x-splash): Would place splash wrongly. + + * mm-decode.el (mm-insert-part): Use multibyte for text. + + * gnus-start.el (gnus-read-newsrc-file): New variable. + (gnus-read-newsrc-file): Use it. + +1999-04-17 Lars Magne Ingebrigtsen + + * nnvirtual.el (nnvirtual-request-expire-articles): New function. + + * gnus-group.el (gnus-group-expire-articles-1): Made into own + function. + +1999-04-17 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.82 is released. + +1999-04-15 Hrvoje Niksic + + * gnus-sum.el (gnus-group-charset-alist): Include Croatian groups + for iso8859-2. + +1999-04-17 Lars Magne Ingebrigtsen + + * mm-util.el (mm-charset-synonym-alist): Remove iso-2022-jp-2 from + synonym alist. + +1999-04-17 Adam P. Jenkins + + * gnus-sum.el (gnus-summary-local-variables): Mark as global. + +1999-04-17 Ettore Perazzoli + + * mail-source.el (mail-source-fetch): Ask before bugging out. + +1999-03-19 Hrvoje Niksic + + * uudecode.el (uudecode-decode-region-external): Don't assume + uudecode-temporary-file-directory ends with a slash. + +1999-03-18 Simon Josefsson + + * gnus-sum.el (gnus-update-marks): + (gnus-update-read-articles): + (gnus-summary-expire-articles): Check server. + +1999-03-16 Simon Josefsson + + * mml.el (mml-preview): New function. + +1999-04-17 William M. Perry + + * mail-source.el (mail-source-fetch-file): Return the right + value. + +1999-04-17 Lars Magne Ingebrigtsen + + * mml.el (mml-insert-parameter): New function. + (mml-insert-parameter-string): New function. + + * nnmail.el (nnmail-get-new-mail): Say how many new articles. + + * gnus-art.el (gnus-mime-multipart-functions): New variable. + (gnus-mime-display-part): Use it. + + * mm-decode.el (mm-alternative-precedence): Removed. + (mm-discouraged-alternatives): New variable. + (mm-preferred-alternative-precedence): New function. + + * nnmail.el (nnmail-get-new-mail): Use mail-sources. + + * mail-source.el (mail-sources): New variable. + + * gnus-art.el (article-remove-cr): Remove several trailing CRs. + + * mm-decode.el (mm-valid-image-format-p): New function. + (mm-inline-media-tests): Use it. + (mm-valid-and-fit-image-p): New function. + + * gnus-agent.el (gnus-agent-fetch-groups): Error when unplugged. + (gnus-agent-fetch-group): Ditto. + +1999-04-12 Didier Verna + + * nnmail.el (nnmail-article-group): in case of a group name + containing "\\n" constructs, be sure to pass the expanded value to + nn*-save-mail. + +1999-04-17 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.81 is released. + +1999-04-16 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-get-split-value): Reverse result. + +1999-04-03 Lars Magne Ingebrigtsen + + * gnus-start.el (gnus-always-read-dribble-file): Doc fix. + +1999-04-02 Lars Magne Ingebrigtsen + + * mml.el (mml-insert-tag): Insert concluding part. + + * message.el (message-send-mail): Encode later. + (message-send-news): Ditto. + + * nnfolder.el: Don't use mail delim. + +1999-03-28 Lars Magne Ingebrigtsen + + * gnus-cus.el (gnus-group-customize): Put point at min. + + * mm-view.el (mm-inline-text): Allow toggling html. + +1999-03-28 William M. Perry + + * mail-source.el: Added prescript and postscript to file. + +1999-03-28 Lars Magne Ingebrigtsen + + * nnmail.el: Reverted. + + * gnus-msg.el (gnus-setup-posting-charset): Didn't work. + (gnus-setup-posting-charset): Did work. + +1999-03-28 Jae-you Chung + + * gnus.el (gnus-short-group-name): Use + gnus-group-uncollapsed-levels. + +1999-03-28 Lars Magne Ingebrigtsen + + * gnus-cite.el (gnus-dissect-cited-text): Don't remove overlays. + +1999-03-26 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-treat-strip-headers-in-body): New variable. + (article-strip-headers-from-body): New command and keystroke. + +1999-03-14 Lars Magne Ingebrigtsen + + * mail-source.el (mail-source-fetch-pop): Check for symbol first. + + * nnheader.el (nnheader-insert-file-contents): Bind + enable-local-eval to nil. + (nnheader-find-file-noselect): Ditto. + + * nnmail.el (nnmail-article-group): Don't remove long lines. + (nnmail-remove-long-lines): New function. + (nnmail-split-header-length-limit): Removed. + + * mml.el (mml-generate-mime-1): Use unibyte buffers. + + * gnus-group.el (gnus-group-kill-all-zombies): Query user. + +1999-03-06 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-generic-mark): New function. + + * nnmail.el (nnmail-split-header-length-limit): Increased. + (nnmail-article-group): Allow nil. + + * gnus-cite.el (gnus-cite-parse-wrapper): Inhibit point-motion. + + * nndoc.el (nndoc-generate-mime-parts-head): Insert real headers + first. + + * mml.el (mml-minibuffer-read-type): Include types from + mailcap-mime-data. + + * nndraft.el (nndraft-request-article): Would clobber Japanese. + +1999-03-05 Hrvoje Niksic + + * mml.el (mml-insert-tag): New function. + (mml-read-file): Renamed to mml-minibuffer-read-file to avoid + confusion with functions like `mml-read-tag'. + (mml-read-type): Ditto with `mml-minibuffer-read-type'. + (mml-minibuffer-read-description): Ditto with + `mml-minibuffer-read-description'. + (mml-attach-buffer): New function. + (mml-mode-map): New entry for /. + (mml-minibuffer-read-type): Accept DEFAULT. + + * mml.el (mml-quote-region): Narrow the region. + + * message.el (message-mode-menu): message-mime-attach-file is now + mml-attach-file. + +1999-03-05 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-treatment-function-alist): Do emphasis earlier. + +1999-03-05 Robert Bihlmeyer + + * mml.el (mml-attach-buffer): New command. + +1999-02-27 Simon Josefsson -1999-12-19 Dave Love + * gnus-sum.el (gnus-update-marks): Call gnus-remove-from-range + with a proper range. Compress range. - * mail/pop3.el (pop3-movemail-file-coding-system): Doc fix. - (pop3-movemail): Replace binding of - pop3-movemail-file-coding-system. + * gnus-range.el (gnus-remove-from-range): Protect arguments. -1999-10-23 Dave Love +1999-03-05 Lars Magne Ingebrigtsen - * nnvirtual.el (nnvirtual-create-mapping): Don't use mapc. + * mm-decode.el (mm-get-image): Create a temporary file for xbms. -1999-10-19 Dave Love +1999-03-04 Lars Magne Ingebrigtsen - * pop3.el: Merge changes from version `1.3s' which we weren't sent. + * gnus-picon.el (gnus-picons-x-face-file-name): Removed. + (gnus-picons-convert-x-face): Removed. + (gnus-picons-article-display-x-face): Removed. + (gnus-picons-x-face-sentinel): Ditto. + (gnus-picons-display-x-face): Ditto. -1999-10-15 Stefan Monnier +1999-03-04 Lars Magne Ingebrigtsen - * gnus-start.el (gnus-slave-save-newsrc): - * gnus-uu.el (gnus-uu-tmp-dir, gnus-uu-decode-binhex) - (gnus-uu-decode-binhex-view, gnus-uu-digest-mail-forward) - (gnus-uu-initialize): - * nnmail.el (nnmail-make-complex-temp-name, nnmail-get-new-mail): - Use make-temp-file. + * gnus.el: Pterodactyl Gnus v0.80 is released. -1999-09-07 Eli Zaretskii +1999-03-02 Lars Magne Ingebrigtsen - * nnsoup.el (nnsoup-tmp-directory): Use temporary-file-directory. + * gnus-art.el (gnus-mm-display-part): Narrow to the part itself. - * gnus-uu.el (gnus-uu-tmp-dir): Use temporary-file-directory. + * gnus-sum.el (gnus-with-article): Moved here. -1999-08-24 Andreas Schwab + * mail-source.el (mail-source-fetch-pop): Ask for password even + when program. - * gnus-art.el (gnus-emphasis-underline-italic): Doc fix. +1999-02-28 Lars Magne Ingebrigtsen -1999-07-01 Karl Heuer + * gnus-msg.el (gnus-bug): Add description. - * gnus-uu.el (gnus-uu-decode-save-view): Fix typo. + * mml.el (mml-insert-mml-markup): Insert disposition. -1999-06-12 Markus Rost + * message.el (message-send-mail): Always encode mail headers. - * gnus-group.el (gnus-permanently-visible-groups): Fix custom type. +1999-02-28 Lars Magne Ingebrigtsen -1999-04-08 Richard Stallman + * gnus-art.el (gnus-treat-article): Only run the highlight stuff + when requested. - * pop3.el (pop3-read-passwd): Use read-passwd if that is defined. + * nnmail.el (nnmail-current-spool): Removed. - * nnmail.el (nnmail-read-passwd): Use read-passwd if that is defined. + * gnus-salt.el (gnus-tree-inhibit): New varible. -1999-04-07 Richard Stallman + * gnus.el (mm-util): Required. - * gnus-mh.el (gnus-summary-save-in-folder): Use mh-lib-progs. +1999-02-27 paul stevenson -1999-04-06 Richard Stallman + * gnus-sum.el (gnus-summary-toggle-header): Narrow to head first. - * nnlistserv.el: When compiling, ignore errors in nnweb. +1999-02-27 Lars Magne Ingebrigtsen -1999-02-19 Lars Magne Ingebrigtsen + * mail-source.el (mail-source-bind): Doc fix. - * gnus.el: Gnus v5.6.46 is released. +1999-02-26 Lars Magne Ingebrigtsen -1999-02-19 Lars Magne Ingebrigtsen + * message.el (message-mode): Doc fix. - * gnus-mule.el (""): Default to iso-latin-1. + * mm-encode.el (mm-content-transfer-encoding-defaults): Use 8bit + encoding. -1999-01-16 Tom Breton + * gnus.el (gnus-methods-equal-p): Moved here. - * gnus-agent.el (gnus-agent-expire): Fix. + * mail-source.el: pop at 110. -1999-01-16 Remek Trzaska + * pop3.el (pop3-movemail): Use write-region instead of + append-to-file to avoid excessive messaging. - * gnus-ems.el (): Recognize cygwin. +1999-02-27 lantz moore -1998-12-02 Lars Magne Ingebrigtsen + * nnmail.el (nnmail-get-new-mail): honor suffix for spool-files of + type directory. - * nnfolder.el (nnfolder-save-mail): Handle From lines in - headers. +1999-03-04 Robert Bihlmeyer -1998-11-21 Lars Magne Ingebrigtsen + * gnus-art.el (article-hide-boring-headers): Field names must not + contain whitespace. - * message.el (message-ignored-supersedes-headers): Remove - NNTP-Posting-Date. +1999-02-26 Lars Magne Ingebrigtsen -1998-11-19 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.79 is released. - * gnus-uu.el (gnus-quote-arg-for-sh-or-csh): Quote semicolon. +1999-02-26 Lars Magne Ingebrigtsen -1998-11-19 Lars Magne Ingebrigtsen + * gnus-cite.el (gnus-cite-toggle): Don't remove highlighting. - * gnus.el: Gnus v5.6.45 is released. + * mml.el (mml-mode): Don't use add-minor-mode. -1998-11-08 Andrew Innes + * message.el (messgage-inhibit-body-encoding): New variable. + (message-encode-message-body): Use it. - * nntp.el (nntp-request-group): Allow for error codes. +1999-02-26 Lars Magne Ingebrigtsen -1998-10-12 Andrew Innes + * gnus.el: Pterodactyl Gnus v0.78 is released. - * gnus/nntp.el (nntp-possibly-change-group): Allow for unexpected - responses to GROUP command, since this may be called from a timer - with quit inhibited. +1999-02-26 Lars Magne Ingebrigtsen -1998-10-11 Lars Magne Ingebrigtsen + * message.el (message-mode): Switch on MML mode. - * gnus-agent.el (gnus-agent-expire): Check (car expired). + * mml.el: Included commands and functions. + (mml-mode-map): New keymap. -1998-10-02 Lars Magne Ingebrigtsen + * message.el: Removed the insertion commands and functions. - * gnus-cache.el (gnus-cache-generate-active): Ignore directories - that start with a dot. + * gnus-ems.el (gnus-mule-cite-add-face): Removed. -1998-10-01 Lars Magne Ingebrigtsen + * gnus-sum.el (gnus-summary-sort-by-chars): New command and + keystroke. - * nnmail.el (nnmail-article-group): Expand properly. + * gnus-art.el (gnus-narrow-to-page): Revert. - * gnus-group.el (gnus-group-apropos): Also do non-active groups. + * gnus-cite.el (gnus-cite-delete-overlays): New function. + (gnus-cite-parse-maybe): Always reparse. -1998-09-29 Lars Magne Ingebrigtsen + * message.el (message-encode-message-body): Don't insert + "multipart warning". - * gnus-async.el (gnus-make-async-article-function): Don't use - push. + * gnus-art.el (gnus-article-treat-head-custom): New variable. -1998-09-24 Lars Magne Ingebrigtsen +1999-02-25 Miles Bader - * gnus.el: Gnus v5.6.44 is released. + * mail-source.el (mail-source-fetch-pop): Return 1 for success. -1998-09-23 Markus Rost + * nnmail.el: Require mm-util. - * gnus.el: Extend autoloads. +1999-02-26 Justin Sheehy -1998-09-15 Lars Magne Ingebrigtsen + * nnmail.el (nnmail-get-new-mail): Only get mail for the one + group. - * gnus-draft.el (gnus-draft-send): Bind required headers to nil. - (gnus-draft-send): No. +1999-02-26 SeokChan LEE -1998-09-14 Lars Magne Ingebrigtsen + * mm-bodies.el (mm-body-charset-encoding-alist): Add euc-kr. - * message.el (message-fix-before-sending): Comment out invisible - text things. +1999-02-21 Simon Josefsson -1998-09-14 Tatsuya Ichikawa + * gnus-msg.el (gnus-extended-version): Better regexp. - * gnus-agent.el (gnus-agent-file-coding-system): Renamed. +1999-02-25 Didier Verna -1998-09-13 Mike McEwan + * nnmail.el (nnmail-split-it): new syntax: `(! FUNC SPLIT)'. FUNC + is called with the result of SPLIT and should return a new split. - * gnus-agent.el (gnus-agent-expire): Stop expiry barfing on killed - groups. + * gnus.texi: update the doc. -1998-09-13 Lars Magne Ingebrigtsen +1999-02-23 Didier Verna - * gnus-agent.el (gnus-agent-save-group-info): Create proper active - lines. + * gnus-picon.el (gnus-picons-display-bar-p): when picons are + displayed in the article buffer, output bars if + `gnus-picons-display-article-move-p'. -1998-09-10 Lars Magne Ingebrigtsen +1999-02-20 Aaron M. Ucko - * gnus-draft.el (gnus-draft-edit-message): Save the buffer. + * mail-source.el (mail-source-fetch-pop): Typo. -1998-09-06 Lars Magne Ingebrigtsen +1999-02-26 Lars Magne Ingebrigtsen - * gnus.el: Gnus v5.6.43 is released. + * gnus-sum.el (gnus-summary-toggle-header): Save restriction. -1998-09-06 Lars Magne Ingebrigtsen +1999-02-23 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-remove-thread): Unhide threads before - removing. - (gnus-data-compute-positions): Ditto. + * gnus-cite.el (gnus-cite-parse-wrapper): Always parse. -1998-08-31 Shuhei KOBAYASHI +1999-02-21 Lars Magne Ingebrigtsen - * nnmail.el (nnmail-date-to-time): Parse time locally if no - timezone. + * mml.el (mml-insert-buffer): New function. -1998-08-31 Lars Magne Ingebrigtsen + * message.el (message-forward): Insert the buffer in the buffer. - * gnus-srvr.el (gnus-browse-foreign-server): Protect against - out-of-range articles. +1999-02-21 Shenghuo ZHU - * gnus-msg.el (gnus-summary-reply): Don't inhibit posting styles. + * mm-view.el (mm-inline-message): Insert part in narrowed region. -1998-08-30 Lars Magne Ingebrigtsen +1999-02-20 Shenghuo ZHU - * gnus-score.el (gnus-summary-increase-score): Temporary third - majuscle. + * gnus-sum.el (gnus-summary-toggle-header): Save restriction. -1998-08-30 Dan Christensen +1999-02-20 Lars Magne Ingebrigtsen - * gnus-score.el (gnus-summary-increase-score): Score thread on - Message-ID. + * gnus.el: Pterodactyl Gnus v0.77 is released. -1998-08-29 Simon Josefsson +1999-02-20 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-mark-article-as-read): - (gnus-summary-mark-article-as-unread): - (gnus-summary-mark-article): Call gnus-request-update-mark. + * gnus-art.el (gnus-displaying-mime): New variable. + (article-narrow-to-head): New function. -1998-08-29 Mike McEwan + * mail-source.el (mail-source-fetch-pop): Include pre/postscript. + Default to pop instead of pop3. - * gnus-agent.el (gnus-agent-fetch-headers): Cater for when there's - no .agentview, all articles have been expired, or everything bar a - few downloaded arts have been expired. - (gnus-agent-expire): Mark *all* expired articles as read. +1999-02-19 Lars Magne Ingebrigtsen -1998-08-29 Lars Magne Ingebrigtsen + * gnus-art.el (article-hide-pgp): Goto body. - * gnus.el: Gnus v5.6.42 is released. + * gnus-uu.el (gnus-uu-digest-mail-forward): Don't kill buffer. -1998-08-29 Simon Josefsson + * gnus-cite.el: Don't use goto-line. - * gnus-sum.el (gnus-summary-make-menu-bar): Typo. + * gnus-art.el (gnus-article-treat-html): Removed. + (gnus-treat-article): Save restriction. -1998-08-29 Tatsuya Ichikawa +1999-02-17 Per Abrahamsen - * gnus-agent.el: Use nnheader-insert-file-contents. + * message.el (message-send-mail): Don't untabify. + (message-mode): Don't use tabs for indentation. -1998-08-29 Lars Magne Ingebrigtsen +1999-02-19 Lars Magne Ingebrigtsen + + * message.el (message-send-mail): Don't untabify. + + * nnml.el (nnml-save-mail): Typo fix. - * nnvirtual.el (nnvirtual-request-group): Update the right group. +1999-02-19 Per Abrahamsen -1998-08-27 Lars Magne Ingebrigtsen + * message.el (message-cite-function): Add + `message-cite-original-without-signature' customization option. - * gnus-sum.el (gnus-data-compute-positions): Didn't work on hidden - threads. +1999-02-18 Per Abrahamsen - * nnvirtual.el (nnvirtual-request-group): Work when always - updating. - (nnvirtual-always-rescan): Default to t. + * nnmail.el (nnmail-fix-eudora-headers): Mark as option to + `nnmail-prepare-incoming-header-hook'. -1998-08-27 Lars Magne Ingebrigtsen +1999-02-19 Justin Sheehy - * gnus.el: Gnus v5.6.41 is released. + * gnus-util.el (gnus-make-sort-function-1): Typo fix. -1998-08-27 Mike McEwan +1999-02-19 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agent-fetch-group-1): Leave the calculation - of `articles' to `gnus-agent-fetch-headers'. - (gnus-agent-fetch-headers): We only want headers that are after - the last entry in `gnus-group-alist'. + * gnus-group.el (gnus-group-get-new-news): Require nnmail. -1998-08-27 Lars Magne Ingebrigtsen +1999-02-18 Michael Cook - * Makefile.in (warn): New. + * Recognize Microsoft Outlook's cite attribution conventions. - * gnus.el: Removed unreferenced bound variables all over. +1999-02-19 James H. Cloos, Jr. - * gnus-group.el (gnus-update-group-mark-positions): Removed topic. + * gnus-sum.el: Bind M. - * gnus-cus.el (gnus-group-customize): No part. +1999-02-19 Neil Crellin - * gnus-agent.el (gnus-category-line-format-alist): Renamed specs. - (gnus-category-insert-line): Use it. + * mail-source.el (mail-source-fetch-pop): Bind pop3-port. -1998-08-27 Lars Magne Ingebrigtsen +1999-02-15 Didier Verna - * gnus.el: Gnus v5.6.40 is released. + * gnus-picon.el (gnus-group-display-picons): ensures that + `article-goto-body' really goes to the article body. -1998-08-27 Lars Magne Ingebrigtsen +1999-02-19 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agent-mode): Only toggle plugged in group - mode. + * mm-view.el (mm-inline-text): Bind url-standalone-mode. -1998-08-27 Lars Balker Rasmussen + * gnus-msg.el (gnus-summary-mail-forward): Create unique names. - * message.el (message-supersede): Check the right headers. + * mm-view.el (mm-view-message): Enable multibyte. -1998-08-26 Lars Magne Ingebrigtsen +1999-02-11 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-sort-threads): Changed level. + * nnmail.el (nnmail-get-new-mail): Message later. -1998-08-26 Mike McEwan + * mm-util.el (mm-find-charset-region): Revert to checking + multibyte. - * gnus-sum.el (gnus-build-all-threads): `save-excursion' and - `set-buffer' back to `gnus-summary-buffer' in order to access - buffer-local variables. +1999-02-11 Matt Pharr -1998-08-26 Lars Magne Ingebrigtsen + * gnus-msg.el (gnus-bug): Encode environment info as a MIME + attachment. - * gnus-sum.el (gnus-data-compute-positions): More and faster. +1999-02-11 Lars Magne Ingebrigtsen -1998-08-26 Matt Pharr + * gnus.el: Pterodactyl Gnus v0.76 is released. - * message.el (message-wash-subject): Remove more. +1999-02-06 Felix Lee -1998-08-25 Tatsuya Ichikawa + * gnus.el (gnus-group-change-level-function): Typo. - * gnus-cache.el (gnus-cache-overview-coding-system): New - variable. +1999-02-11 Lars Magne Ingebrigtsen -1998-08-25 Albert L. Ting + * gnus-sum.el (gnus-nov-skip-field): Removed. + (gnus-nov-field): Ditto. + (gnus-nov-parse-extra): Ditto. + (gnus-nov-read-integer): Ditto. - * gnus-group.el (gnus-fetch-group-other-frame): New command. +1999-02-05 Katsumi Yamaoka -1998-08-25 Lars Magne Ingebrigtsen + * nnheader.el (nnheader-nov-read-message-id): New macro. + (nnheader-parse-nov): Use it. - * gnus-uu.el (gnus-uu-grab-articles): Check for pseudos. + * gnus-sum.el (gnus-nov-read-message-id): New macro. + (gnus-nov-parse-line): Use it; use `(eobp)' instead of + `(eq (char-after) ?\n)'. - * gnus-art.el (gnus-ignored-headers): More headers. +1999-02-11 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-move-article): Update the right - group. + * gnus.el (gnus-other-frame): Always pop up a new frame. -1998-08-23 Lars Magne Ingebrigtsen +1999-02-10 Shenghuo ZHU - * gnus-art.el (gnus-ignored-headers): More headers. + * gnus-range.el (gnus-range-add): Rewrite. + +1999-02-02 Carsten Leonhardt + + * nnmail.el (nnmail-split-incoming): Added detection of maildir + format. + (nnmail-process-maildir-mail-format): New function. + + * mail-source.el (mail-source-fetch-maildir): New function. + (mail-source-keyword-map): Add default for maildir method. + (mail-source-fetcher-alist): Changed "qmail" to "maildir". + +1999-02-10 Lars Magne Ingebrigtsen + + * mail-source.el (mail-source-fetcher-alist): Remove apop. + + * nndoc.el (nndoc-type-alist): Remove MIME-digest. + (nndoc-mime-digest-type-p): Removed. + +1999-02-09 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-article-read-summary-keys): Set the point + where it is supposed to be. + (gnus-treat-play-sounds): New variable. + + * gnus-sum.el (gnus-newsgroup-ignored-charsets): New variable. + + * gnus-art.el (article-display-x-face): Narrow to head. + (gnus-article-washed-types): New variable. + (article-hide-pgp): Is not a toggle. + (gnus-article-hide-text-type): Save types. + (article-decode-charset): Use it. -1998-08-23 Mike McEwan + * nnmail.el (nnmail-get-new-mail): Ignore procmail. - * gnus-agent.el (gnus-agent-copy-nov-line): Return to beginning of - line before next read. - (gnus-agent-braid-nov): Remove redundant `let'. + * message.el (message-forward-start-separator): Removed. + (message-forward-end-separator): Removed. + (message-signature-before-forwarded-message): Removed. + (message-included-forward-headers): Removed. + (message-check-news-body-syntax): Don't check forward. + (message-forward): Use MIME. -1998-08-22 Lars Magne Ingebrigtsen + * nnvirtual.el (nnvirtual-request-article): Bind + gnus-article-decode-hook to nil. - * gnus-art.el (article-display-x-face): Allow multiple X-Faces - under XEmacs. +1999-02-06 Lars Magne Ingebrigtsen -1998-08-22 Lars Magne Ingebrigtsen + * mml.el (mml-parse-singlepart-with-multiple-charsets): Check for + us-ascii. - * gnus.el: Gnus v5.6.39 is released. +1999-02-04 Lars Magne Ingebrigtsen -1998-08-22 Lars Magne Ingebrigtsen + * format-spec.el (format-spec): Be more robust. - * gnus-art.el (gnus-ignored-headers): Added more headers. + * message.el (message-encode-message-body): Default + mail-parse-charset to mail-parse-charset. -1998-08-21 Lars Magne Ingebrigtsen + * gnus-sum.el (gnus-summary-edit-article-done): Don't encode. + (gnus-summary-edit-article): Bind mail-parse-charset. - * nnweb.el (nnweb-type): Doc fix. + * mml.el (mml-read-tag): Ignore white space after end of tag. - * gnus-sum.el (gnus-summary-set-process-mark): Move to the right + * message.el (message-goto-body): Also work in separatorless + articles. + + * mml.el (mml-translate-from-mime): New function. + (mml-insert-mime): Ditto. + (mml-to-mime): New function. + (mime-to-mml): New name. + + * gnus-sum.el (gnus-summary-edit-article): Always select raw article. -1998-08-20 Lars Magne Ingebrigtsen + * gnus-group.el (gnus-group-catchup-current): Unmark groups. - * nnmail.el (nnmail-spool-file): Allow lists of files. + * gnus-sum.el (gnus-summary-setup-default-charset): Don't + special-case nndraft groups. -1998-08-20 Per Starback +1999-02-03 Lars Magne Ingebrigtsen - * gnus/gnus-start.el (gnus-check-first-time-used): Change current - buffer before creating help group. + * gnus-sum.el (gnus-get-newsgroup-headers): Bind charset. + (gnus-get-newsgroup-headers): Already bound. -1998-08-20 Lars Magne Ingebrigtsen + * message.el (message-encode-message-body): Use posting charset. - * gnus-msg.el (gnus-message-style-insertions): New variable. - (gnus-message-insert-stylings): New function. - (gnus-configure-posting-styles): Use them. + * mm-bodies.el (mm-encode-body): Use MIME charsets. + (mm-body-encoding): Do CTE. + (mm-body-7-or-8): New function. - * gnus-topic.el (gnus-topic-mode): Don't alter summary-exit-hook. + * mm-util.el (mm-mime-charset): Always fall back on alist. + (mm-mime-mule-charset-alist): Include katakana-jisx0201. + (mm-mime-mule-charset-alist): Add arabic-*-column. + (mm-find-mime-charset-region): New function. - * gnus-sum.el (gnus-select-newsgroup): Don't update group. + * format-spec.el (format-spec-make): New function. - * gnus-msg.el (gnus-setup-message): Bind message-mode-hook. - (gnus-inhibit-posting-styles): New variable. - (gnus-summary-reply): Use it. - (gnus-configure-posting-styles): Ditto. + * mail-source.el (format-spec): Required. + (mail-source-fetch-with-program): Removed. + (mail-source-fetch-with-program): New function. - * gnus-group.el (gnus-group-suspend): Don't kill dribble buffer. + * format-spec.el: New file. -1998-08-20 Lars Magne Ingebrigtsen +1999-02-03 Tatsuya Ichikawa - * gnus.el: Gnus v5.6.38 is released. + * mail-source.el (mail-source-fetch-with-program): Take optional + parameter. -1998-08-20 Lars Magne Ingebrigtsen +1999-02-03 Lars Magne Ingebrigtsen - * message.el (message-mail): Doc fix. + * gnus-start.el: Ignore some groups. + (gnus-setup-news): Bind nnmail-fetched-sources. -1998-08-19 Bill Pringlemeir + * message.el (message-send-mail): Remove all tabs. - * messcompat.el (message-send-mail-function): Initialized from - send-mail-function. + * mm-util.el (mm-find-charset-region): Just check whether + find-charset-region is defined. -1998-08-19 Martin Larose +1999-02-02 Lars Magne Ingebrigtsen - * message.el (message-send-coding-system): New variable. + * gnus-group.el (gnus-group-get-new-news): Use + nnmail-fetched-sources. -1998-08-19 Lars Magne Ingebrigtsen + * nnmail.el (nnmail-fetched-sources): New variable. + (nnmail-get-new-mail): Use it. - * gnus-msg.el (gnus-configure-posting-styles): Reinstated most of - old code. + * mail-source.el (mail-source-fetched-sources): New variable. + (mail-source-fetch): Use it. - * gnus-start.el (gnus-save-newsrc-file): Use coding system. +1999-02-02 Mark W. Eichin -1980-06-08 Mike McEwan + * gnus.el (gnus-getenv-nntpserver): if the file that + gnus-nntpserver-file names has a trailing newline, the + string-match will always match, and thus the file will never be + read. (^ matches start of "line", \\` matches start of "buffer", + which is what was intended...) - * gnus-agent.el (gnus-agent-braid-nov): Go to right place. +1999-02-02 Kim-Minh Kaplan -1980-06-08 Shuhei KOBAYASHI + * gnus-picon.el (gnus-picons-parse-filenames): Quote group names. - * gnus-group.el (gnus-group-suspend): Fix. +1999-01-28 Katsumi Yamaoka -1998-08-18 Lars Magne Ingebrigtsen + * gnus-start.el (gnus-read-active-file): Eliminate duplicated + select methods. - * gnus-cite.el (gnus-cited-opened-text-button-line-format-alist): - New n spec. +1999-01-27 Simon Josefsson - * gnus-group.el (gnus-group-suspend): Use mapcar. + * gnus-range.el (gnus-remove-from-range): Sort second argument. -1998-08-17 Lars Magne Ingebrigtsen +1999-02-02 Scott Hofmann - * gnus-ems.el (gnus-add-minor-mode): Set mode var. + * nntp.el: Use mail-source-read-passwd instead of nnmail-read-passwd. - * gnus-start.el (gnus-slave-mode): New function. +1999-02-01 Shenghuo ZHU - * gnus-msg.el (gnus-post-method): Work with current in nndraft. + * gnus-cus.el (gnus-group-parameters): Charset as symbol, and fix + a typo. + * gnus-sum.el (gnus-summary-setup-default-charset): Set nndraft's + charset to nil. + * gnus-agent.el (gnus-agent-queue-setup): Remove charset setting. + * gnus-start.el (gnus-start-draft-setup): Ditto. -1998-08-16 Lars Magne Ingebrigtsen +1999-02-02 Lars Magne Ingebrigtsen - * gnus-art.el (gnus-request-article-this-buffer): Allow recursive - selection of nneething groups. + * mail-source.el (mail-source-fetch-directory): Use the predicate. + (mail-source-value): Don't do variables. - * nneething.el (nneething-address): Renamed from directory. + * nnmail.el (nnmail-get-new-mail): Set the predicate. -1998-08-16 Lars Magne Ingebrigtsen + * gnus-sum.el (gnus-summary-toggle-header): Fix, and bound to t. - * gnus.el: Gnus v5.6.37 is released. +1999-02-01 Michael Cook -1998-08-16 Lars Magne Ingebrigtsen + * Defenestrate spurious ?a. - * gnus.el: Autoload gnus-summary-wide-reply. +1999-02-02 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-get-newsgroup-headers): Return the value of - In-Reply-To. + * mail-source.el (mail-source-fetch-pop): Instead use + :authentication. - * gnus-msg.el (gnus-setup-message): Posting styles have to be - configured in message-mode-hook. +1999-02-01 Tatsuya Ichikawa - * nntp.el (nntp-connection-timeout): Restored. - (nntp-open-connection): Use it. + * lisp/mail-source.el : Support APOP authentication scheme. -1998-08-15 Lars Magne Ingebrigtsen +1999-02-02 Tatsuya Ichikawa - * gnus-group.el (gnus-group-make-useful-group): Doc fix. + * pop3.el (pop3-movemail): Return t. - * gnus-art.el (gnus-article-push-button): Place point where you - click. +1999-02-02 Lars Magne Ingebrigtsen -1998-08-15 Mike McEwan + * rfc2047.el (rfc2047-fold-region): New function. + (rfc2047-encode-message-header): Use it. - * gnus-agent.el (gnus-agent-save-group-info): Update "groups" file - if `nntp-server-list-active-group' is nil. +1999-02-02 Hallvard B. Furuseth -1998-08-15 Lars Magne Ingebrigtsen + * gnus-sum.el (gnus-group-charset-alist): Add more. - * gnus-score.el (gnus-summary-increase-score): Swap t and r. +1999-02-01 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-remove-thread): Didn't work with sparse - threads. + * gnus.el: Pterodactyl Gnus v0.75 is released. -1998-08-14 Fran,Ag(Bois Pinard +1999-02-01 Lars Magne Ingebrigtsen - * nndoc.el (nndoc-generate-mime-parts-head): Use original Subject, - Message-ID, and References in fully blown articles. + * gnus-art.el (article-display-x-face): Don't narrow to head. -1998-08-14 Lars Magne Ingebrigtsen +1999-02-01 Michael Cook - * gnus.el: Gnus v5.6.36 is released. + * gnus-cite.el (gnus-cited-lines-visible): Accept a cons. -1998-08-14 Lars Magne Ingebrigtsen +1999-02-01 Lars Magne Ingebrigtsen - * gnus.el (load): Push onto list. + * mail-source.el (mail-source-fetch-directory): Ignore + directories. - * gnus-group.el (gnus-group-get-new-news-this-group): Store active - info. + * gnus-cus.el (gnus-group-parameters): Addition. -1998-08-14 Lars Magne Ingebrigtsen + * gnus-art.el (article-strip-banner): Do symbolic banners. + (article-strip-banner): New keystroke. - * gnus.el: Gnus v5.6.35 is released. +1999-02-01 Michael Cook -1998-08-14 Lars Magne Ingebrigtsen + * gnus-art.el (article-strip-banner): New command. - * gnus-srvr.el (gnus-server-scan-server): Error better. +1999-02-01 Lars Magne Ingebrigtsen - * nndir.el: Make independent of nnmh. - Revert. + * gnus-art.el (gnus-treat-strip-banners): New variable. - * message.el (message-remove-text-with-property): New function. - (message-fix-before-sending): Check for invisible text. +1999-01-28 Katsumi Yamaoka - * gnus.el (load): Create the Gnus buffer even when no splash. + * mail-source.el (mail-source-read-passwd): Use `read-passwd' if it + has been exist. - * gnus-msg.el (gnus-setup-message): Add buffer to list. +1999-01-28 Shenghuo ZHU - * gnus-win.el (gnus-remove-some-windows): Use new buffer system. - (gnus-delete-windows-in-gnusey-frames): Ditto. + * message.el (message-draft-coding-system): Check coding-system. + * mm-util.el (mm-text-coding-system): Ditto. - * gnus.el (gnus-add-buffer): New function. +1999-01-28 Katsumi Yamaoka -1998-08-13 Lars Magne Ingebrigtsen + * mail-source.el (mail-source-fetch-pop): Save excursion. - * gnus-xmas.el (gnus-buffer-list): Removed. +1999-01-28 Lars Magne Ingebrigtsen - * gnus.el (gnus-buffers): New variable. - (gnus-get-buffer-create): New function; used throughout. - (gnus-buffers): New function. + * mail-source.el (mail-source-movemail-args): Not constant. + (mail-source-movemail-args): Removed. + (mail-source-fetch-with-program): New function. + (mail-source-fetch-pop): Use program and function. + (mail-source-movemail-program): Removed. - * gnus-msg.el (gnus-configure-posting-styles): Go to eoh - reliably. + * gnus-art.el (gnus-treat-date-iso8601): New variable. + (gnus-treat-date-user-defined): New variable. - * message.el (message-goto-eoh): New command. +1999-01-28 Per Abrahamsen -1998-08-13 Simon Josefsson + * nnmail.el (nnmail-fix-eudora-headers): New function. - * gnus-msg.el (gnus-setup-message): use message-setup-hook - instead - (gnus-configure-posting-styles): new posting-style 'body - (gnus-configure-posting-styles): insert headers immediately +1999-01-28 Lars Magne Ingebrigtsen -1998-08-13 Lars Magne Ingebrigtsen + * mm-bodies.el (mm-encode-body): Use mail-parse-charset. - * gnus-score.el (gnus-summary-increase-score): Change thread to - "r". +1999-01-27 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-scroll-down): New command and - keystroke. + * gnus-art.el (gnus-treatment-function-alist): Do + gnus-article-add-buttons-to-head later. + (gnus-treat-capitalize-sentences): New variable. + (article-capitalize-sentences): New command and keystroke. - * gnus-agent.el (gnus-agent-expire): Check that directories - exist. + * gnus-group.el (gnus-group-catchup-current): Do group. -1998-08-12 Simon Josefsson + * message.el (message-default-charset): Add group. - * gnus-cache.el (gnus-uncacheable-groups): doc change - (gnus-cacheable-groups): new variable - (gnus-cache-possibly-enter-article): use it +1999-01-27 Lars Magne Ingebrigtsen -1998-08-12 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.74 is released. - * nntp.el (nntp-encode-text): Too much text. +1999-01-27 Lars Magne Ingebrigtsen -1998-08-12 Matt Pharr + * gnus-art.el (article-fill-long-lines): Renamed. + (article-fill-long-lines): New keystroke. - * message.el (message-make-forward-subject-function): New - variable. - (message-wash-forwarded-subjects): Ditto. +1999-01-26 Lars Magne Ingebrigtsen -1998-08-12 Lars Magne Ingebrigtsen + * gnus-msg.el (gnus-setup-posting-charset): Check for group. - * gnus.el: Gnus v5.6.34 is released. + * gnus-group.el (gnus-group-catchup-current): Skip groups now + displayed. + (gnus-group-catchup-current): Be more robus. -1998-08-12 Lars Magne Ingebrigtsen + * gnus-sum.el (gnus-summary-select-article): Reselect for showing + headers. - * gnus-msg.el (gnus-post-method): Don't use `current' in drafts. +1999-01-25 Dave Love - * gnus-score.el (gnus-summary-increase-score): Changed T to h and - downcase. + * message.el (message-mode-menu): Add message-mime-attach-file. + (message-mode): Doc fix. -1998-08-11 Lars Magne Ingebrigtsen +1999-01-26 Lars Magne Ingebrigtsen - * gnus.el: Gnus v5.6.33 is released. + * nnmail.el (nnmail-check-duplication): Insert the mail source + string. -1998-08-11 Lars Magne Ingebrigtsen + * mail-source.el (mail-source-fetch-pop): Bind mail-source-string. + (mail-source-fetch-directory): Ditto. + (mail-source-fetch-file): Ditto. + (mail-source-string): New variable. - * gnus-group.el (gnus-group-apropos): Check symbol value. + * gnus-start.el (gnus-get-unread-articles): Nix out groups over + the level. - * gnus-cite.el (gnus-cited-closed-text-button-line-format): - Changed. + * rfc2047.el (rfc2047-encodable-p): Convert to MIME charsets + before handling. -1998-08-11 Lars Magne Ingebrigtsen + * mm-util.el (mm-mime-charset): Use the parameters. + (mm-mime-charset): Removed region paremeters. - * gnus.el: Gnus v5.6.32 is released. + * nnmail.el (nnmail-get-new-mail): Don't message the entire + source. -1998-08-11 Lars Magne Ingebrigtsen +1999-01-25 Lloyd Zusman - * nndoc.el (nndoc-type-alist): Do MIME digests before multiparts. + * nnmail.el (nnmail-get-split-group): Quote right. - * gnus.el (gnus-predefined-server-alist): Expand vars. +1999-01-25 Lars Magne Ingebrigtsen -1998-08-09 Dave Love + * mail-source.el (mail-source-movemail): Would kill an arbitrary + buffer. - * gnus-art.el (article-display-x-face): Don't try (and fail) to - display multiple faces. +1999-01-24 Lars Magne Ingebrigtsen -1998-08-11 Lars Magne Ingebrigtsen + * gnus-group.el (gnus-clear-inboxes-moved): Removed. + (gnus-group-mode): Don't hook. - * gnus-art.el (gnus-header-newsgroups-face): Don't bold so much. + * mail-source.el (mail-source-bind): Doc fix. + (mail-source-bind): Take only one param. - * gnus-group.el (gnus-group-rename-group): Remove old group name - from list of killed groups. + * gnus-art.el (gnus-treat-highlight-signature): typep. - * gnus-int.el (gnus-get-function): Error better. + * mail-source.el (mail-source-movemail): Ignore empty file. + (mail-source-callback): Check before deleting. - * gnus-art.el (gnus-article-narrow-to-signature): Inhibit motion - hooks. - (article-hide-pgp): Delete text instead of hiding it. + * message.el (message-mime-attach-file): Include name. - * gnus-group.el (gnus-group-find-new-groups): Ditto. +1999-01-23 Lars Magne Ingebrigtsen - * gnus-start.el (gnus-find-new-newsgroups): Accept C-u C-u as a - total query. + * mm-util.el (mm-read-charset): Return a symbol. -1998-08-10 Lars Magne Ingebrigtsen + * mm-view.el (mm-inline-text): Insert signature separator. - * gnus-art.el (gnus-article-prepare): Place point at the beginning - of the body. + * gnus-art.el (gnus-treat-predicate): New function. + (gnus-treat-article): Allow all types to be checked. - * gnus-cite.el (gnus-cite-attribution-face): Changed to italic. + * gnus-util.el (gnus-or): New function. + (gnus-and): Ditto. - * gnus-art.el (gnus-article-edit-article): Delete "annotation" - text. - (gnus-insert-prev-page-button): Mark as annotation. - (gnus-insert-next-page-button): Ditto. + * gnus-art.el (gnus-mime-display-single): Use override. - * gnus-cite.el (gnus-cited-closed-text-button-line-format): New - variable. - (gnus-cited-closed-text-button-line-format-alist): Ditto. - (gnus-article-toggle-cited-text): Toggle between different - symbols. + * mm-decode.el (mm-attachment-override-types): New variable. + (mm-attachment-override-p): New function. -1998-08-09 Lars Magne Ingebrigtsen + * gnus-picon.el (gnus-group-display-picons): Don't go backward. - * gnus.el (gnus-version): Remove backend info. +1999-01-23 Andrew J. Cosgriff -1998-08-09 Lars Magne Ingebrigtsen + * mm-view.el (mm-inline-text): Do vcards. - * gnus.el: Gnus v5.6.31 is released. +1999-01-23 Lars Magne Ingebrigtsen -1998-08-09 Fran,Ag(Bois Pinard + * gnus.el: Pterodactyl Gnus v0.73 is released. - * nndoc.el: Split MIME multipart messages, maybe recursively. - (nndoc-mime-parts-type-p, nndoc-transform-mime-parts, - nndoc-generate-mime-parts-head, nndoc-dissect-mime-parts, - nndoc-dissect-mime-parts-sub): New functions. +1999-01-23 Lars Magne Ingebrigtsen - * nndoc.el: Quoting boundaries is optional, for multipart digests. + * nnmail.el (nnmail-spool-file): Changed to use mail-source. + (nnmail-crash-box, nnmail-use-procmail, nnmail-procmail-directory, + nnmail-procmail-suffix, nnmail-resplit-incoming): Removed. + (nnmail-movemail-program): Removed. + (nnmail-movemail-args): Removed. + (nnmail-pop-password-required): Ditto. + (nnmail-tmp-directory): Ditto. + (nnmail-delete-incoming): Removed. + (nnmail-pop-password, nnmail-moved-inboxes, + nnmail-internal-password, nnmail-move-inbox): Removed. + (nnmail-read-passwd): Ditto. + (nnmail-get-spool-files): Removed. + (nnmail-resplit-incoming): Reinstated. -1998-08-09 Lars Magne Ingebrigtsen + * mail-source.el: New file. - * gnus-agent.el (gnus-agent-save-group-info): Check whether file - exists. +1999-01-23 James H. Cloos, Jr. - * message.el (message-goto-signature): Return nil if no sig. - (message-delete-not-region): Delete properly if no sig. + * gnus-art.el (gnus-article-mode-map): Bind backspace. -1998-08-09 Simon Josefsson +1999-01-23 Lars Magne Ingebrigtsen - * gnus-srvr.el (gnus-browse-make-menu-bar): select did read + * gnus-art.el (article-make-date-line): Fix iso8601 display. -1998-08-09 Lars Magne Ingebrigtsen +1999-01-20 Lars Magne Ingebrigtsen - * gnus-sum.el (t): Added keystroke for W W C. + * gnus-art.el (gnus-treat-display-smileys): Check xpm. - * gnus-cite.el (gnus-article-hide-citation-maybe): hiden->hidden. + * gnus-picon.el (gnus-group-display-picons): Goto body. -1998-08-09 Lars Magne Ingebrigtsen + * gnus.el: Indented all functions; broke long lines; changed all + instances of illegal/legal to invalid/valid. Yes, I'm bored. - * gnus.el: Gnus v5.6.30 is released. +1999-01-20 Lars Magne Ingebrigtsen -1998-08-09 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.72 is released. - * message.el (message-cite-original-without-signature): Peel off - blank lines. +1999-01-20 Lars Magne Ingebrigtsen - * gnus-art.el (gnus-article-maybe-highlight): Doc fix. + * gnus.el: Cleaned up trailing whitespace. - * gnus-sum.el (gnus-data-enter-list): Threw away all new list data - at the beginning of the buffer. + * mm-util.el (mm-read-charset): Work. -1998-08-07 Gareth Jones +1999-01-17 Matt Armstrong - * gnus-score.el (gnus-summary-increase-score): Don't downcase - before lookin in char-to-header. + * gnus-score.el (gnus-score-find-bnews): Match regexp on the + nnheader-translate-file-chars'd group name. -1998-08-07 Lars Magne Ingebrigtsen +1999-01-20 Lars Magne Ingebrigtsen - * gnus.el (gnus-predefined-server-alist): Too many parentheses. + * message.el (message-encode-message-body): Fold case. -1998-08-06 Lars Magne Ingebrigtsen +1999-01-20 Lars Magne Ingebrigtsen - * gnus.el (gnus-continuum-version): Include quassia. + * mailcap.el (mailcap-add): New function. - * gnus-sum.el (gnus-data-enter-list): Check before entering list. +1999-01-18 Lars Magne Ingebrigtsen -1998-08-06 Francois Felix Ingrand + * gnus-art.el (article-goto-body-goes-to-point-min-p): New variable. + (article-goto-body): Use it. + (gnus-treat-article): Ditto. - * gnus-salt.el (gnus-generate-vertical-tree): Don't go too far to - the left. + * gnus-agent.el (gnus-agent-get-undownloaded-list): Remove the + downloaded articles from the downloadeble list. -1998-08-06 Lars Magne Ingebrigtsen +1999-01-16 Lars Magne Ingebrigtsen - * gnus.el: Gnus v5.6.29 is released. + * message.el (message-encode-message-body): Bind + mail-parse-charset. -1998-08-06 Lars Magne Ingebrigtsen + * mm-util.el (mm-charset-synonym-alist): New variable. + (mm-charset-to-coding-system): Use it. + (mm-charset-coding-system-alist): Removed. + (mm-charset-to-coding-system): Don't use it. + (mm-find-charset-region): Use mail-parse-charset. - * gnus-agent.el (gnus-agent-expire): Check whether (caar - gnus-agent-article-alist) is nil. + * gnus-art.el (gnus-treatment-function-alist): Use + gnus-article-display-picons. + (gnus-treat-display-xface): Only do if we have xface feature. + (gnus-part-display-hook): New function. + (gnus-treat-article): Use it. + (gnus-treat-article): Use gnus-visual. - * gnus.el (gnus-read-method): Allow selecting predefined servers. + * gnus-msg.el (gnus-setup-posting-charset): Check elem. - * gnus-topic.el (gnus-topic-update-topic-line): Compute right - number when inserting missing topic lines. + * gnus-art.el (gnus-mm-display-part): Fix the MIME button after + displaying. - * gnus-start.el (gnus-get-unread-articles): Check that the group - is alive. + * mm-decode.el (mm-insert-part): Use insert-buffer-substring. - * gnus-score.el (gnus-score-load-score-alist): Better error - messaging. + * gnus-score.el (gnus-score-find-bnews): Protect against invalid + regexp file names. -1998-08-04 Kurt Swanson +1999-01-16 Lars Magne Ingebrigtsen - * gnus-salt.el (gnus-pick-mouse-pick-region): Fix picking bug due - to use of gnus-read-event-char. + * gnus.el: Pterodactyl Gnus v0.71 is released. -1998-07-28 Dave Love +1999-01-16 Lars Magne Ingebrigtsen - * gnus-group.el (gnus-group-fetch-faq): Don't mung dots in group - name. + * mm-view.el (mm-inline-image): Don't add a dot. -1998-07-27 Dave Love + * gnus-art.el (gnus-treat-article): New function. - * gnus-topic.el (gnus-topic-mode-map): Provide Emacs tty - alternatives to [tab], [(meta tab)]. + * gnus.el (gnus-article-display-hook): Removed. -1998-08-06 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-article-treat-custom): New variable. - * gnus-start.el (gnus-startup-file-coding-system): New variable. - (gnus-read-init-file): Use it. - (gnus-read-newsrc-el-file): Ditto. + * gnus-start.el (gnus-ignored-newsgroups-has-to-p): Removed. - * gnus-sum.el (gnus-thread-ignore-subject): Changed default. + * gnus-msg.el (gnus-setup-posting-charset): Allow variables and + functions. -1998-08-06 Richard Stallman + * message.el (message-posting-charset): New variable. + (message-send-mail): Use it. - * message.el (sendmail): Required. + * gnus-msg.el (gnus-group-posting-charset-alist): Moved here. + (gnus-setup-posting-charset): New function. + (gnus-setup-message): Use it. -1998-08-06 Lars Magne Ingebrigtsen + * message.el (message-encode-message-body): Just look for + Content-Type before inserting a new one. - * gnus-sum.el (gnus-auto-select-same): Dix fix. +1999-01-15 Lars Magne Ingebrigtsen -1998-08-04 Mike McEwan + * rfc2047.el (rfc2047-default-charset): Removed. - * gnus-sum.el (gnus-select-newsgroup): Set - `gnus-newsgroup-unselected' when selecting specific articles via - SELECT-ARTICLE - there may be more headers to fetch if - `gnus-fetch-old-headers' is non-nil. - (gnus-summary-read-group): pass SELECT-ARTICLE to - `gnus-summary-read-group-1' and reset to nil when going to next group. - (gnus-summary-read-group): Change `select-article' to - `select-articles' for consistency. + * mail-prsvr.el: New file. + (mail-parse-charset): New variable. -1998-08-04 Lars Magne Ingebrigtsen + * gnus-sum.el (gnus-newsgroup-charset): Changed name. + Changed name. - * gnus.el: Gnus v5.6.28 is released. + * gnus.el (gnus-charset): New group. -1998-08-03 Lars Magne Ingebrigtsen + * nnmail.el (nnmail-pathname-coding-system): Default to binary. - * nndoc.el (nndoc-set-delims): Removed article-end. - (nndoc-dissect-buffer): Use eobp. + * gnus-sum.el (gnus-default-charset): Default to nil. + (gnus-newsgroup-iso-8859-1-forced-regexp): Removed. + (gnus-newsgroup-iso-8859-1-forced): Removed. -1998-08-03 Trung Tran-Duc + * mm-util.el (mm-known-charsets): Removed. + (mm-default-coding-system): Removed. + (mm-default-charset): Removed. + (mm-read-charset): New function. - * nntp.el (nntp-open-connection): Bind coding-system-for-write. + * message.el (message-default-charset): Removed. -1998-07-31 Lars Magne Ingebrigtsen + * rfc2047.el (rfc2047-default-charset): Default to nil. - * gnus-group.el (gnus-group-read-ephemeral-group): Make the server - unique. + * mm-util.el (mm-charset-iso-8859-1-forced): Removed. -1998-07-28 Fran,Ag(Bois Pinard +1999-01-15 Lars Magne Ingebrigtsen - * gnus-uu.el (gnus-uu-reginize-string): Consider the number of - parts as part of the fixed subject, instead of a wild quantity. + * gnus.el: Pterodactyl Gnus v0.70 is released. -1998-07-30 Lars Magne Ingebrigtsen +1999-01-15 Lars Magne Ingebrigtsen - * gnus-cache.el (gnus-summary-insert-cached-articles): Sort - articles. + * mm-decode.el (mm-save-part): Use mm-get-part. + (mm-insert-part): New function. + (mm-get-part): Use it. + (mm-get-image): Ditto. + (mm-display-external): Ditto. - * nndir.el (nndir): Use nnml functions. + * mm-view.el (mm-inline-text): Ditto. -1998-07-27 Lars Magne Ingebrigtsen + * gnus-move.el (gnus-move-group-to-server): Protect against nil + ranges. - * gnus.el: Gnus v5.6.27 is released. + * mm-decode.el (mm-display-external): Save the buffer. + (mm-remove-part): Kill it. -1998-07-27 Lars Magne Ingebrigtsen + * qp.el (quoted-printable-decode-region): Do the right thing at eobp. - * gnus-topic.el (gnus-topic-update-unreads): New function. + * nnagent.el (nnagent-request-set-mark): Defined stub. - * gnus-sum.el (gnus-summary-limit): Update mode line. +1999-01-14 Lars Magne Ingebrigtsen - * gnus-soup.el (gnus-soup-add-article): Update mode line. + * gnus-score.el (gnus-score-load-score-alist): Bind + coding-system-for-read. - * gnus-group.el (gnus-group-make-menu-bar): Bug. + * gnus-sum.el (gnus-summary-exit): Do adaptive scoring before + prepare-exit-hook. - * gnus-art.el (gnus-article-make-menu-bar): Menu. + * mm-view.el (mm-setup-w3): Require w3. - * gnus-sum.el (gnus-summary-make-menu-bar): Bug reports. +1999-01-13 Kiyokazu SUTO - * gnus-topic.el (gnus-topic-mode-map): h -> H. + * lisp/nnspool.el (nnspool-retrieve-headers): Protect against empty + body. -1998-07-19 16:59 Simon Josefsson +1999-01-14 Lars Magne Ingebrigtsen - * gnus-util.el (gnus-netrc-syntax-table): @ is whitespace + * mm-encode.el: Ditto. -1998-07-17 Gordon Matzigkeit + * mm-bodies.el (mm-decode-content-transfer-encoding): Message the + error. - * gnus-uu.el (gnus-uu-reginize-string): Simplify by looking - from back to front for part numbers, rather than skipping - leading ``version numbers.'' + * mailcap.el (mailcap-mime-data): SAFER ps. - (gnus-uu-part-number): Make consistent with - gnus-uu-reginize-string. + * message.el (message-encode-message-body): Always insert a + Content-Type header. -1998-07-26 Lars Magne Ingebrigtsen + * mm-decode.el (mm-inline-media-tests): Default all text/* to be + shown inline. - * gnus-art.el (gnus-request-article-this-buffer): Pass along - header. + * mm-view.el (mm-inline-text): Handle all sorts of text. - * gnus-sum.el (gnus-summary-update-article): Don't pass along - iheader to regeneration routine. + * mailcap.el (mailcap-mime-data): non-viewer for viewers that + don't view. -1998-07-27 KOSEKI Yoshinori + * mm-decode.el (mm-display-external): Use it. - * nnmail.el (nnmail-move-inbox): Clear nnmail-internal-password, - when supplied Password is incorrect. + * gnus-art.el (gnus-visible-headers): Added bcc, gcc, fcc. -1998-07-25 Lars Magne Ingebrigtsen + * mm-decode.el (mm-save-part): Removed double code. - * gnus.el: Gnus v5.6.26 is released. +1999-01-12 Dave Love -1998-07-25 Lars Magne Ingebrigtsen + * mm-decode.el (mm-save-part): Avoid doubly-compressed + application/octet-stream .gz & al files with jka-compr. - * gnus-salt.el (gnus-pick-mouse-pick-region): Use - gnus-read-event-char. +1999-01-12 Dave Love -1998-07-25 Lars Magne Ingebrigtsen + * gnus-ems.el (gnus-down-mouse-3): New variable. + * gnus-art.el (gnus-mime-button-map): Use it. + (gnus-mime-button-menu): Set the clicked-on buffer initially. - * gnus.el: Gnus v5.6.25 is released. +1999-01-13 Lars Magne Ingebrigtsen -1998-07-25 Lars Magne Ingebrigtsen + * mailcap.el (mailcap-mime-data): Added ImageMagic and ee. - * gnus-group.el (gnus-group-read-ephemeral-group): Ditto. +1999-01-12 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-read-group-1): Ditto. + * gnus-picon.el (gnus-picons-kill-buffer): Don't kill article + buffers. - * gnus-group.el (gnus-group-read-group): Accept article list. + * gnus-sum.el (gnus-summary-exit): Destroy all MIME. -1998-07-24 Lars Magne Ingebrigtsen + * gnus-cache.el (gnus-cache-read-active): Reversed check. - * gnus-msg.el (gnus-configure-posting-styles): Quote some. +1999-01-12 Matt Armstrong - * message.el (message-ignored-supersedes-headers): Added X-Trace - and X-Complaints-To. + * mml.el (mml-parameter-string): Strip directory component. - * nnmail.el (gnus-util): Required. +1999-01-12 Lars Magne Ingebrigtsen -1998-07-21 Lars Magne Ingebrigtsen + * gnus.el (gnus-use-demon): Removed. - * gnus.el (gnus-news-group-p): Bogosity in params. +1999-01-12 Katsumi Yamaoka -1998-07-21 Robert Bihlmeyer + * nnmail.el (nnmail-article-group): Don't infloop. - * gnus-util.el (gnus-globalify-regexp): New function. +1999-01-11 Colin Rafferty -1998-07-18 Lars Magne Ingebrigtsen + * gnus-art.el (article-update-date-lapsed): Made it work with + picons, and make it update on all visible frames. + (article-date-ut): Get summary-buffer's current-headers. - * gnus-sum.el (gnus-list-of-unread-articles): Peel off articles - outside active range. +1999-01-12 Lars Magne Ingebrigtsen -1998-07-15 Lars Magne Ingebrigtsen + * gnus-picon.el (gnus-picons-setup-buffer): Don't set major mode. + (gnus-picons-setup-p): New variable. - * nnvirtual.el (nnvirtual-request-type): Handle non-numerical - articles. +1999-01-11 Lars Magne Ingebrigtsen - * gnus.el (gnus-news-group-p): Do something sensible with negative - articlies. + * nnmail.el (nnmail-split-header-length-limit): Lowered to 512. -1998-07-15 Lars Magne Ingebrigtsen +1999-01-04 Lars Magne Ingebrigtsen - * gnus-salt.el (gnus-tree-minimize-window): Allow numbers. + * gnus-sum.el (gnus-summary-exit-no-update): Don't use run-hooks. + (gnus-summary-exit-no-update): Use mapcar. -1998-07-15 Lars Magne Ingebrigtsen +1999-01-02 Simon Josefsson - * gnus-agent.el (gnus-agent-expire): Ignored ticks. + * gnus-agent.el (gnus-category-write): Make directory. -1998-07-15 Hallvard B. Furuseth +1998-09-26 Simon Josefsson - * nntp.el (nntp-send-authinfo): Message better and stuff. + * gnus-sum.el (gnus-update-read-articles): + (gnus-update-marks): Request backend update of mark. -1998-07-15 Lars Magne Ingebrigtsen +1999-01-03 Lars Magne Ingebrigtsen - * gnus.el (gnus-message-archive-group): Allow sexp. + * mm-bodies.el (mm-body-encoding): Use mm-find. -1998-07-15 Lars Magne Ingebrigtsen +1999-01-03 Kim-Minh Kaplan - * gnus-sum.el (gnus-select-newsgroup): Accept select-articles - para, + * gnus-picon.el (gnus-article-display-picons): Fix. -1998-07-13 Mike McEwan +1999-01-03 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-select-newsgroup): Don't call the Agent to - mark articles as read until *all* headers have been retrieved. + * gnus.el: Pterodactyl Gnus v0.69 is released. -1998-07-15 Lars Magne Ingebrigtsen +1999-01-03 Lars Magne Ingebrigtsen - * nndir.el (nndir): Use nnml to request article. + * gnus-picon.el (gnus-picons-setup-buffer): Run the hook. -1998-07-11 SL Baur + * gnus-agent.el (gnus-agent-remove-group): New command and + keystroke. - * gnus-topic.el (gnus-topic-mode-map): Use modern key syntax. + * rfc2047.el (rfc2047-decode-region): Check for us-ascii. -1998-07-12 Lars Magne Ingebrigtsen +1999-01-02 Simon Josefsson - * gnus-score.el (gnus-current-home-score-file): New function. + * gnus-agent.el (gnus-agent-write-servers): Make directory. -1998-07-11 Mike McEwan +1998-12-26 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agent-fetch-headers): Note last fetched - headers per sesion to aid expiry in `headers only' groups. + * mm-view.el (mm-inline-text): Bind current id. - * gnus-agent.el (gnus-agent-expire): Update group info to add - expired articles to list of read articles and prevent - re-fetching. + * mm-decode.el (mm-handle-id): New macro. + (mm-make-handle): Accept id. + (mm-dissect-singlepart): Use it. -1998-07-12 Lars Magne Ingebrigtsen +1998-12-23 Matt Pharr - * nnmail.el (nnmail-active-file-coding-system): Changed to - binary. + * message.el (message-cite-original-without-signature): Use + message-signature-separator when searching for signature in + message-cite-original-without-signature. -1998-07-12 Lars Magne Ingebrigtsen +1998-12-24 Simon Josefsson - * gnus-score.el (gnus-score-load-file): Specify which alist to - decay. + * gnus.el (gnus-server-to-method): Check named methods. -1998-07-12 Lars Magne Ingebrigtsen +1998-12-24 Lars Magne Ingebrigtsen - * gnus-start.el (gnus-startup-file-coding-system): New variable. - (gnus-read-newsrc-el-file): Use it. + * mm-view.el (mm-view-message): Goto point-min. -1998-07-11 Lars Magne Ingebrigtsen + * nnmail.el (nnmail-article-group): Don't delete lines, only + shorten them. - * gnus.el: Gnus v5.6.24 is released. + * gnus-msg.el (gnus-configure-posting-styles): Also do nil + values. -1998-07-10 Hallvard B. Furuseth + * nnheader.el (nnheader-temp-directory): New variable. + (nnheader-temp-directory): Removed. - * gnus-util.el (gnus-parse-netrc): Allow "default" values. +1998-12-22 Jack Vinson -1998-07-10 Lars Magne Ingebrigtsen + * mailcap.el (mailcap-parse-mailcaps): Add "~/.mailcaps" to the + list of files to check for mailcap entries under windows-nt. - * nntp.el (nntp-server-opened-hook): Doc change. +1998-12-24 Lars Magne Ingebrigtsen -1998-07-10 Fran,Ag(Bois Pinard + * gnus-art.el (gnus-article-maybe-hide-headers): Check whether the + summary buffer exists. - * gnus-sum.el (gnus-summary-respool-trace): New command and - keystroke. +1998-12-22 Aaron M. Ucko -1998-07-10 Lars Magne Ingebrigtsen + * nnsoup.el (nnsoup-store-reply): Remove code to deal with + irrelevant Sun sendmail bug. + (nnsoup-store-reply): Stop mucking with mail-header-separator. - * gnus-util.el (gnus-prin1): Bind print-escape-multibyte to nil. + * message.el (message-send-news): Bind mail-header-separator to + "" when asking backend to post. -1998-07-06 Simon Josefsson +1998-12-22 Karl Kleinpaste - * gnus-range.el (gnus-sorted-complement): Fix comments. + * mm-uu.el (mm-dissect-disposition): New variable. + (mm-uu-dissect): Use it. -1998-07-02 Lars Magne Ingebrigtsen +1998-12-21 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-iterate): New macro. + * mm-view.el (mm-inline-text): Bind url-current-object. - * message.el (message-pop-to-buffer): Clone locals. +1998-12-06 Simon Josefsson - * gnus-msg.el (gnus-posting-styles): Reinstated. - (gnus-posting-style-alist): Ditto. + * gnus-range.el (gnus-remove-from-range): Rewrite. -1998-07-01 Lars Magne Ingebrigtsen +1998-12-09 SL Baur - * gnus-int.el (gnus-get-function): Set funct to nil. + * gnus-picon.el (annotations): Remove bogus require 'xpm. -1998-07-01 Simon Josefsson +1998-12-18 Hrvoje Niksic - * gnus-int.el (gnus-get-function): returned non-nil when - function wasn't bound, if noerror=t + * message.el (message-encode-message-body): Insert `MIME-Version' + instead of `Mime-Version'. -1998-07-01 Lars Magne Ingebrigtsen +1998-12-04 Hrvoje Niksic - * gnus-topic.el (gnus-topic-mode-map): Bind TAB and M-TAB. + * message.el (message-insert-mime-part): Add the attachment + disposition. + (message-insert-mime-part): Make TYPE and DESCRIPTION optional. + (message-mime-query-type): New function. + (message-mime-query-description): Ditto. + (message-mime-query-file): Ditto. + (message-insert-mime-part): Use them. + (message-mime-insert-external): Use the new stuff. - * gnus-sum.el (gnus-build-sparse-threads): Make sure no dates are - nil. - (gnus-summary-limit-mark-excluded-as-read): Use the intersection. +1998-12-19 Lars Magne Ingebrigtsen - * gnus-msg.el (gnus-setup-message): Clone all local variables from - the summary buffer. + * nnmail.el (nnmail-split-header-length-limit): New variable. -1998-07-01 Richard Stallman + * mm-decode.el (mm-dissect-buffer): Check syntax. - * message.el (message-cite-original): Use mail-citation-hook. - (message-cite-function): Ditto. + * rfc2231.el (rfc2231-parse-string): Remove check for syntax. -1998-07-01 Rajappa Iyer + * rfc2047.el (rfc2047-encodable-p): Use mm-find-charset-region. + (rfc2047-dissect-region): Ditto. - * gnus-salt.el (gnus-pick-mode-map): Changed keymap. +1998-12-17 Lars Magne Ingebrigtsen -1998-07-01 Lars Magne Ingebrigtsen + * mm-view.el (mm-view-message): Decode charset. - * gnus.el: Gnus v5.6.23 is released. +1998-12-16 Lars Magne Ingebrigtsen -1998-07-01 Lars Magne Ingebrigtsen + * rfc2231.el (rfc2231-parse-string): Ignore syntactically invalid + CT headers. - * nntp.el (nntp-record-command): Give more precise time info. - (nntp-next-result-arrived-p): Look for the end of error lines. +1998-12-16 Shenghuo ZHU -1998-07-01 Fran,Ag(Bois Pinard + * mm-bodies.el (mm-decode-content-transfer-encoding): Use + mm-uu-*-function. + * mm-uu.el (mm-uu-dissect): Use x-uuencode. - * gnus-util.el (gnus-delete-if): Would do the opposite. +1998-12-16 Lars Magne Ingebrigtsen -1998-07-01 Lars Magne Ingebrigtsen + * message.el (message-send-mail): Do MML first. + (message-send-news): Ditto. - * gnus-sum.el (gnus-build-sparse-threads): Didn't work at all. +1998-12-15 Lars Magne Ingebrigtsen -1998-06-30 Lars Magne Ingebrigtsen + * gnus-picon.el (gnus-picons-face): New face. + (gnus-picons-try-face): Use it. - * nntp.el (nntp-send-authinfo): Store the user name. - (nntp-authinfo-user): New variable. +1998-12-15 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-limit-mark-excluded-as-read): Would - mark some articles as unread. + * gnus.el: Pterodactyl Gnus v0.68 is released. - * gnus-agent.el (gnus-agent-expire): Don't sort lines. +1998-12-15 Lars Magne Ingebrigtsen -1998-06-30 Mike McEwan + * gnus.el: Pterodactyl Gnus v0.67 is released. - * gnus-agent.el (gnus-agent-expire): Use a fresh hash table. +1998-12-15 Lars Magne Ingebrigtsen -1998-06-29 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.66 is released. - * gnus.el: Gnus v5.6.22 is released. +1998-12-13 Lars Magne Ingebrigtsen -1998-06-29 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-insert-mime-button): Decode description. - * gnus-salt.el (gnus-pick-mode-map): Remove gnus-mouse. +1998-12-05 Shenghuo ZHU - * gnus-sum.el (gnus-dependencies-add-header): `debug' left in. - Eh. Eh. + * gnus-art.el (article-decode-encoded-words): Rollback to 0.55. + (gnus-decode-header-methods): Ditto. + (gnus-decode-with-mail-decode-encoded-word-region): Ditto. - * gnus-salt.el (gnus-summary-pick-line-format): Missing %.- +1998-12-13 Lars Magne Ingebrigtsen - * gnus-topic.el (gnus-topic-rename): Fix error message. + * mml.el (mml-insert-mime-headers): Encode description. -1998-06-28 Lars Magne Ingebrigtsen + * nnfolder.el (nnfolder-request-expire-articles): Go to the date + line. - * gnus-spec.el (gnus-face-face-function): Double quoting removed. + * gnus-sum.el (gnus-default-charset): Doc fix. -1998-06-28 Lars Magne Ingebrigtsen +1998-12-09 Shenghuo ZHU - * gnus.el: Gnus v5.6.21 is released. + * mm-decode.el (mm-display-part): Forward a line. -1998-06-28 Lars Magne Ingebrigtsen +1998-12-09 Shenghuo ZHU - * gnus-sum.el (gnus-summary-edit-article-done): Copy the buffer to - a temp buffer before replacing. + * mm-util.el (mm-running-ntemacs): New variable. + (mm-text-coding-system): Ditto. + * nnmail.el (nnmail-incoming-coding-system): Ditto. + (nnmail-split-incoming): Use nnmail-incoming-coding-system. - * gnus-msg.el (gnus-post-news): Treat broken-reply-to in - followups. +1998-12-13 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-goto-subject): Position point. + * gnus-picon.el (gnus-picons-network-display-internal): Don't set + buffer. -1998-06-27 Lars Magne Ingebrigtsen + * message.el (message-insert-headers): New command and keystroke. - * gnus-demon.el (gnus-util): Required. +1998-12-07 Lars Magne Ingebrigtsen - * gnus-score.el (gnus-score-body): Message fix. + * mm-decode.el (mm-inline-media-tests): Recognize x-xbitmap. + (mm-get-image): Ditto. - * gnus-group.el (gnus-group-highlight-line): Use it. + * mm-bodies.el (mm-decode-content-transfer-encoding): Only for + base64, uudecode and binhex. - * gnus-util.el - (gnus-put-text-properties-excluding-characters-with-faces): New - function. +1998-12-06 Shenghuo ZHU -1998-06-27 Lars Magne Ingebrigtsen + * mm-bodies.el (mm-decode-content-transfer-encoding): Replace CRLF + in text/plain. + * mm-uu.el (mm-uu-dissect): Use inline. - * gnus.el: Gnus v5.6.20 is released. +1998-12-07 Lars Magne Ingebrigtsen -1998-06-27 Arne Georg Gleditsch + * mm-view.el (mm-view-message): New function. - * gnus-sum.el (gnus-parent-headers): Check better for headers. + * mm-encode.el (mm-content-transfer-encoding-defaults): Changed to + qp. -1998-06-27 Lars Magne Ingebrigtsen +1998-12-07 Karl Kleinpaste - * message.el (message-check-news-body-syntax): Buggy checksum - check. + * mm-encode.el (mm-content-transfer-encoding-defaults): Add an + entry for message/rfc822 as 8bit. -1998-06-27 Lars Magne Ingebrigtsen +1998-12-07 Lars Magne Ingebrigtsen - * gnus.el: Gnus v5.6.19 is released. + * mailcap.el (mailcap-mime-extensions): Add patch. -1998-06-27 Lars Magne Ingebrigtsen +1998-12-05 Dale Hagglund - * gnus.el: Gnus v5.6.18 is released. + * gnus-sum.el (gnus-summary-display-buttonized): Use prefix + argument to force all multipart/* to look like multipart/mixed. -1998-06-27 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-mime-display-multipart-as-mixed): New + variable. + (gnus-mime-display-part): Use it. - * gnus-soup.el (gnus-soup-save-areas): Made interactive. +1998-12-07 Lars Magne Ingebrigtsen - * nnfolder.el (nnfolder-request-replace-article): Check all X-From - headers. + * gnus-draft.el (gnus-draft-send): Only disable checks for + non-interactive use. + (gnus-draft-send-message): Use it. - * gnus-sum.el (gnus-update-marks): Don't nix out cache lists. +1998-12-06 Lars Magne Ingebrigtsen - * nngateway.el (nngateway-mail2news-header-transformation): - Changed semantics. + * gnus.el: Pterodactyl Gnus v0.65 is released. - * message.el (message-check-news-body-syntax): Don't look at - buffer size to see whether text has been added. +1998-12-06 Lars Magne Ingebrigtsen -1998-06-26 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-article-prepare-display): Don't init w3. - * gnus.el: Gnus v5.6.16 is released. + * mm-view.el (mm-inline-text): Bind url-standalone-mode here. -1998-06-26 Lars Magne Ingebrigtsen +1998-12-05 Lars Magne Ingebrigtsen - * gnus-util.el (gnus-delete-assq): Removed. - (gnus-delete-assoc): Ditto. + * gnus.el: Pterodactyl Gnus v0.64 is released. - * gnus.el: Use throughout. +1998-12-05 Lars Magne Ingebrigtsen - * gnus-util.el (gnus-pull): New macro. + * mm-view.el (mm-setup-w3): Don't load. -1998-06-26 Simon Josefsson + * gnus-msg.el (gnus-setup-message): Set group name. + (gnus-group-mail): Avoid leaking local vars. - * gnus-sum.el (gnus-get-newsgroup-headers): parse Chars: headers + * message.el (message-attach-file): Renamed. + (message-mime-attach-file): Renamed again. -1998-06-26 Lars Magne Ingebrigtsen +1998-12-05 Hrvoje Niksic - * gnus-sum.el (gnus-update-marks): Use it. + * gnus-art.el (article-decode-encoded-words): Bind + rfc2047-default-charset here. - * gnus-util.el (gnus-delete-alist): New function. + * gnus-art.el (gnus-insert-mime-button): Nix slashes in file name. - * gnus-sum.el (gnus-update-marks): Don't save list of cached - articles. +1998-12-05 Lars Magne Ingebrigtsen - * message.el (message-mode-menu): Include kill-buffer. + * gnus-picon.el (gnus-picons-setup-buffer): Run picons hook. + (gnus-picons-setup-hook): New hook. - * nnmail.el (nnmail-purge-split-history): Use it. +1998-12-05 Per Abrahamsen - * gnus-util.el (gnus-delete-if): New function. + * mailcap.el (mailcap-mime-data): Remove "*" from documentation + string. + (mailcap-mime-extensions): Ditto. Made first sentense fit a + line. - * nnmail.el (nnmail-article-group): Use gnus-remove-duplicates. +1998-12-05 Lars Magne Ingebrigtsen -1998-06-26 Richard Stallman + * gnus-art.el (gnus-article-prepare-display): Setup w3. + (gnus-mime-view-part): Ditto. + (gnus-mime-inline-part): Dotii. + (gnus-mime-externalize-part): Daddo. + (gnus-mime-internalize-part): Tutti frutti. + (gnus-widget-press-button): Da da do. - * gnus-util.el (gnus-remove-duplicates): New function. + * mm-view.el (mm-setup-w3): Require url-vars. -1998-06-26 Kevin Christian +1998-12-04 Shenghuo ZHU - * gnus-score.el (gnus-score-string): Do updating of scores after - fuzzies. + * message.el (message-draft-coding-system): Fix for XEmacs-NT. + * mm-util.el (mm-find-charset-region): Ditto. -1998-06-26 Lars Magne Ingebrigtsen +1998-12-05 Lars Magne Ingebrigtsen - * message.el (message-mode): Don't do the intern dance. + * message.el (message-send): Don't encode here. + (message-send-mail): But here. + (message-send-news): And here. -1998-06-26 Richard Stallman +1998-12-04 Lars Magne Ingebrigtsen - * message.el (message-mode): Adaptive fill changes. + * gnus-msg.el (gnus-message-insert-stylings): Don't insert twice. -1998-06-26 Lars Magne Ingebrigtsen +1998-12-04 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-mode-line-format-alist): Allow article - score. + * gnus.el: Pterodactyl Gnus v0.63 is released. - * gnus-score.el (gnus-score-load-file): Would ignore all score - files without un-advanced rules. +1998-12-04 Lars Magne Ingebrigtsen - * gnus-ems.el ((fboundp 'split-string)): Use it where it exists. + * mml.el (mml-base-boundary): Shorten. -1998-06-26 Lars Magne Ingebrigtsen + * message.el (message-insert-mime-part): Use default. - * gnus.el: Gnus v5.6.15 is released. + * gnus-art.el (gnus-insert-mime-button): Bind gnus-tmp-type-long. -1998-06-26 Lars Magne Ingebrigtsen +1998-12-03 Per Abrahamsen - * nnfolder.el (nnfolder-request-replace-article): Delete old - delimiter. + * gnus-art.el (gnus-mime-display-alternative): Use (*) for radio + buttons, not [*]. - * gnus-msg.el (gnus-summary-reply): Use it. +1998-12-04 Hrvoje Niksic - * message.el (message-reply): Removed parameter. - (message-wide-reply): Ditto. + * gnus-art.el (gnus-insert-mime-button): Do proper help-echo. - * gnus-msg.el (gnus-msg-treat-broken-reply-to): New function. +1998-12-04 Hrvoje Niksic - * gnus-art.el (gnus-check-group-server): New function. - (gnus-request-article-this-buffer): Don't try to waken the server - before needing to. + * gnus-art.el (gnus-insert-mime-button): Fix. -1998-06-25 Lars Magne Ingebrigtsen +1998-12-03 Hrvoje Niksic - * gnus-sum.el (gnus-summary-delete-article): Sort the articles - before deleting. + * message.el (message-insert-mime-part): Nicify prompts. + (message-insert-mime-part): Really delete duplicates. + (message-insert-mime-part): Check against common errors. + (message-insert-mime-part): Fix docstring. - * nngateway.el (nngateway-request-post): Return success. +1998-12-04 Lars Magne Ingebrigtsen - * nnheader.el (nnheader-insert-file-contents): Bind more hooks. + * gnus-art.el (gnus-mime-internalize-part): Bugged out. - * gnus-sum.el (gnus-summary-limit-to-age): Reverse logic. +1998-12-03 Hrvoje Niksic - * gnus-score.el (gnus-summary-score-entry): Removed interactive - spec. - ((gnus-summary-score-map "V" gnus-summary-mode-map)): Removed - keystroke. + * gnus-art.el (gnus-mime-button-line-format): Nicify. + (gnus-insert-mime-button): Modify accordingly. - * gnus-art.el (gnus-article-show-summary): Position point. +1998-12-04 Lars Magne Ingebrigtsen - * gnus-cache.el (gnus-cache-update-article): Change group first. + * gnus-art.el (gnus-display-mime): Set window point. - * gnus.el (gnus-short-group-name): Collapse more. + * mm-decode.el (mm-display-external): Only decode when not + saving. + (mm-alternative-precedence): Prefer multiparts. + (mm-inline-media-tests): Inline multiparts. -1998-06-25 Lars Magne Ingebrigtsen + * gnus-picon.el (gnus-picons-next-job-internal): Do bar if asked. + Ignore errors when requiring url. - * gnus.el: Gnus v5.6.14 is released. + * mml.el (mml-quote-region): New command. -1998-06-25 Lars Magne Ingebrigtsen + * message.el (message-cite-original): Use it. + (message-cite-original-without-signature): Ditto. - * gnus-sum.el (gnus-rebuild-thread): Accept a line argument. - (gnus-rebuild-thread): Would skip around a lot when `P'-ing past - the beginning. +1998-12-03 Lars Magne Ingebrigtsen - * gnus-msg.el (gnus-post-method): Present all known servers if - `C-u 0'. + * gnus.el: Pterodactyl Gnus v0.62 is released. - * gnus-salt.el (gnus-pick-mode-map): Reinstated keymap. +1998-12-03 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-build-sparse-threads): Put the proper date - in. + * gnus-art.el (gnus-mime-view-all-parts): Work with multiparts. -1998-06-24 Lars Magne Ingebrigtsen +1998-12-03 Hrvoje Niksic - * gnus.el: Gnus v5.6.13 is released. + * mm-view.el (mm-inline-text): Use `point-min-marker' and + `point-max-marker'. -1998-06-24 Lars Magne Ingebrigtsen +1998-12-03 Lars Magne Ingebrigtsen - * gnus-topic.el (gnus-topic-rename): Disallow "nil". + * mailcap.el (mailcap-mime-extensions): Use image/xpm for xpms. -1998-06-24 Vladimir Alexiev + * gnus-art.el (gnus-mime-display-single): Check for attachment + before other tests. - * nnvirtual.el (nnvirtual-update-xref-header): Regexp-quote group - name. +1998-12-03 Didier Verna + + * gnus-msg.el (gnus-configure-posting-styles): find a + posting-style entry in the group parameters, if any, and honor it + at the end. + +1998-12-03 Felix Lee + + * nntp.el (nntp-after-change-function): Fix. + +1998-12-03 Mike McEwan -1998-06-24 Lars Magne Ingebrigtsen + * mml.el (mml-generate-mime-1): Insert literally. - * gnus-sum.el (gnus-build-sparse-threads): Give all the sparse - articles the date of the current child. +1998-12-03 Lars Magne Ingebrigtsen - * gnus-topic.el (gnus-group-topic-parameters): Didn't compute. + * mml.el (mml-insert-mime-headers): Removed debug. -1998-06-24 Lars Magne Ingebrigtsen +1998-12-02 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-summary-show-article): Destroy parts when + prefixed. - * gnus.el: Gnus v5.6.12 is released. + * mm-encode.el (mm-content-transfer-encoding-defaults): Default + application/emacs-lisp to 8bit. -1998-06-10 Andreas Schwab +1998-12-03 Dale Hagglund - * message.el (message-mail-other-window): Bind message-this-is-mail. - (message-mail-other-frame): Likewise. - (message-news-other-window): Bind message-this-is-news. - (message-news-other-frame): Likewise. + * mm-decode.el (mm-quote-arg): Add quoting of '()', '<>', and '|'. -1998-06-09 Sam Steingold +1998-12-02 Lars Magne Ingebrigtsen - * gnus-uu.el (gnus-uu-default-view-rules): make sed kill ^M only - at the end of line. + * gnus.el: Pterodactyl Gnus v0.61 is released. -1998-06-05 Hrvoje Niksic +1998-12-02 Lars Magne Ingebrigtsen - * nnmail.el (nnmail-get-split-group): Don't regexp-quote - nnmail-procmail-suffix. + * mml.el (mml-parse-1): Skipped parts. + (mml-insert-mime-headers): Nil is a list. + (mml-generate-mime-1): Don't insert literally. + (mml-read-tag): Drop text props. + (mml-read-part): Ditto. + (mml-parse-singlepart-with-multiple-charsets): Ditto. -1998-06-24 Kim-Minh Kaplan +1998-12-02 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-build-get-header): Fix obarray. + * gnus.el: Pterodactyl Gnus v0.60 is released. -1998-06-24 Castor +1998-12-02 Lars Magne Ingebrigtsen - * nntp.el (nntp-open-ssl-stream): + * mml.el (mml-parse-1): Don't throw contents away. -1998-06-24 Lars Magne Ingebrigtsen +1998-12-02 Hrvoje Niksic - * gnus-sum.el (gnus-nov-parse-line): Cleaned up. - (gnus-build-all-threads): Put things in the wrong obarray. + * mml.el (mml-compute-boundary-1): Regexp-quote the boundary. -1998-06-24 Decklin Foster +1998-12-02 Lars Magne Ingebrigtsen - * nngateway.el (nngateway-mail2news-header-transformation): New + * mml.el (mml-parse-singlepart-with-multiple-charsets): New function. + (mml-parse-1): Use it. + +1998-12-01 Shenghuo ZHU -1998-06-24 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-decode-with-mail-decode-encoded-word-region): + Use gnus-newsgroup-default-charset. + (article-decode-encoded-words): Remove charset codes. + * gnus-sum.el (gnus-newsgroup-default-charset): Use + gnus-default-charset. - * message.el (message-shorten-references): New function. - (message-header-format-alist): Use it. +1998-12-02 Lars Magne Ingebrigtsen - * gnus-start.el (gnus-always-read-dribble-file): Customized. + * message.el (message-send-mail): Don't encode here. + (message-send-news): Nor here. + (message-send): ... but here instead. - * message.el (message-generate-new-buffers): Dox fox. + * gnus-picon.el (gnus-picons-display-article-move-p): Changed + default to nil. + (gnus-article-display-picons): Replace From line. + (gnus-group-display-picons): Replace Newsgroups line. + (gnus-picons-display-glyph): Set baseline. + (gnus-group-display-picons): Piconize the entire Newsgroups line. + (gnus-picons-xbm-face): Revert to old, standard colors. -1998-06-23 Lars Magne Ingebrigtsen + * message.el (message-fetch-field): Remove text props. - * gnus-topic.el (gnus-topic-prepare-topic): Respect visible topic - param. - (gnus-topic-hierarchical-parameters): New function. + * gnus-art.el (gnus-article-normalized-header-length): New + variable. + (article-normalize-headers): New command and keystroke. -1998-06-02 Didier Verna + * gnus-picon.el (gnus-picons-xbm-face): Changed colors. - * gnus-picon.el (gnus-get-buffer-name): use get-buffer-create - instead of get-buffer +1998-12-02 Lars Magne Ingebrigtsen -1998-06-03 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.59 is released. - * nnkiboze.el (nnkiboze-request-delete-group): Delete .newsrc - file. +1998-12-02 Lars Magne Ingebrigtsen - * nnmail.el (nnmail-article-group): Nuke looong lines. + * mml.el (mml-insert-mime-headers): Beep at multiple charsets. - * gnus-art.el (gnus-button-alist): Buggy default. + * gnus-art.el (gnus-mime-copy-part): Set buffer-file-name. -1998-06-03 Lars Magne Ingebrigtsen +1998-11-30 Hrvoje Niksic - * gnus.el: Gnus v5.6.11 is released. + * mml.el (mml-generate-mime-1): Handle unquoting end-tags. -1998-06-03 Lars Magne Ingebrigtsen +1998-12-02 Lars Magne Ingebrigtsen - * gnus.el: Checked doc string syntax throughout. + * mm-decode.el (mm-all-images-fit): New variable. + (mm-image-fit-p): Use it. - * message.el (message-subject-re-regexp): Renamed. + * gnus-art.el (gnus-mime-display-single): Use it. + (gnus-mime-internalize-part): New command and keystroke. -1998-06-03 Simon Josefsson + * mm-decode.el (mm-user-automatic-external-display): New + variable. + (mm-automatic-external-display-p): New function. - * message.el (message-ignored-subject-re): New variable. + * gnus-picon.el (gnus-picons-xbm-face): Default to sensible + colors. -1998-06-03 Sam Steingold +1998-12-01 Lars Magne Ingebrigtsen - * gnus-msg.el (gnus-bug-create-help-buffer): New variable. - (gnus-bug): Use it. + * gnus-sum.el (gnus-summary-repair-multipart): Reselect article. -1998-05-07 Hrvoje Niksic + * gnus-art.el (gnus-with-article): Work in the original article + buffer. + (gnus-with-article): Work in read-only groups. - * nnmail.el: (nnmail-get-split-group): Use `regexp-quote' - when file name is a part of pattern. +1998-12-01 Shenghuo ZHU - * nnmail.el (nnmail-crosspost-link-function): Ditto. + * mm-bodies.el (mm-decode-string): Return original string if not + decode. - * gnus-ems.el: Use `symbol-name' instead of `(format "%s" ...)'. +1998-11-30 Shenghuo ZHU - * gnus-score.el (gnus-score-load-file): Use `regexp-quote' - when file name is a part of pattern. + * mm-uu.el (mm-uu-dissect): Use mm-make-handle. -1998-05-06 Hrvoje Niksic +1998-12-01 Francois Pinard - * gnus-cache.el (gnus-cache-generate-active): Use `regexp-quote' - when file name is a part of pattern. + * nndoc.el (nndoc-mime-parts-type-p): Do related. -1998-06-03 Lars Magne Ingebrigtsen +1998-12-01 Lars Magne Ingebrigtsen - * nnfolder.el (nnfolder-delete-mail): Changed parameters. - (nnfolder-request-replace-article): Rename X-From-Line. + * gnus.el: Pterodactyl Gnus v0.58 is released. -1998-06-03 Dan Christensen +1998-11-30 Hrvoje Niksic - * nnfolder.el (nnfolder-adjust-min-active): Work. + * mm-decode.el (mm-get-image): Return a glyph, not an image + specifier. -1998-06-01 Lars Magne Ingebrigtsen +1998-11-29 Hrvoje Niksic - * gnus-sum.el (gnus-summary-limit-to-age): Reversed time and - almost collapsed space! + * rfc2047.el (rfc2047-decode): Bind mm-default-charset. - * nnmail.el (nnmail-days-to-time): Computed wrong time. +1998-12-01 Lars Magne Ingebrigtsen -1998-06-01 Kim-Minh Kaplan + * mail-parse.el (rfc2045): Required. - * gnus-sum.el (gnus-dependencies-add-header): Break loops. +1998-12-01 William M. Perry -1998-06-01 Fabrice POPINEAU + * mm-view.el (mm-inline-text): Remove props. - * gnus-cache.el (gnus-cache-generate-active): Regexp-quote. +1998-12-01 Lars Magne Ingebrigtsen -1998-06-01 Lars Magne Ingebrigtsen + * mm-view.el (mm-setup-w3): Protect url-misc. - * gnus.el: Gnus v5.6.10 is released. + * message.el (message-ignored-resent-headers): Remove + Gnus-Warning. -1998-06-01 Lars Magne Ingebrigtsen + * mml.el (mml-insert-mime-headers): Use encoding. + (mml-parameter-string): Ditto. - * gnus-art.el (gnus-button-alist): Recognize bare mailto buttons - for Gnus. + * rfc2045.el: New file. + (rfc2045-encode-string): New function. - * nntp.el: Replaced all `message' calls. +1998-11-30 Lars Magne Ingebrigtsen -1998-06-01 Wolfgang Rupprecht + * mail-parse.el (mail-header-encode-parameter): New function. - * nntp.el (nntp-encode-text): Removed spurious forward-line. + * rfc2231.el (rfc2231-encode-string): New function. -1998-05-23 Lars Magne Ingebrigtsen +1998-11-30 Shenghuo ZHU - * gnus-agent.el (gnus-agent-fetch-session): Would infloop if - opening failed. + * mm-bodies.el (mm-decode-string): New function. + * mm-view.el (mm-inline-text): Use mm-decode-string. -1998-05-19 Yoshiki Hayashi +1998-11-30 Lars Magne Ingebrigtsen - * nnheader.el (nnheader-translate-file-chars): Don't change - string. + * gnus.el: Pterodactyl Gnus v0.57 is released. -1998-05-19 P. E. Jareth Hein +1998-11-23 Felix Lee - * gnus-util.el (gnus-dd-mmm): New version. + * nntp.el (nntp-async-needs-kluge): new setting. + (nntp-async-timer): new var. + (nntp-async-process-list): new var. + (nntp-async-kluge): new function. + (nntp-async-timer-handler): new function. + (nntp-async-wait): new function. + (nntp-async-stop): new function. + (nntp-after-change-function): renamed, and split apart. + (nntp-async-trigger): new function. + (nntp-do-callback): new function. + (nntp-accept-process-output): add optional timeout arg. -1998-05-19 Lars Magne Ingebrigtsen + * gnus-async.el (gnus-async-request-fetched-article): fixed. + (gnus-async-wait-for-article): new function. + (gnus-async-with-semaphore): s/asynch/async/. - * gnus.el: Changed address. +1998-11-30 Lars Magne Ingebrigtsen -1998-05-12 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-with-article): Don't encode. + (gnus-insert-mime-button): Fall back on filename from C-D. + (gnus-mime-display-single): Have dots right on text/plain + attachments. - * gnus-agent.el (gnus-agent-expire): Delete more. + * mm-decode.el (mm-dissect-buffer): Respect Content-Disposition in + broken parts. -1998-05-10 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-with-article): Flush cache and backlog. - * gnus-group.el (gnus-group-read-ephemeral-group): Don't add - `address'. + * mm-bodies.el (mm-decode-content-transfer-encoding): Also do + binhex. -1998-05-03 Lars Magne Ingebrigtsen + * gnus-sum.el (gnus-summary-reparent-thread): Use new macro. + (gnus-summary-repair-multipart): New command and keystroke. - * nnmail.el (nnmail-within-headers-p): Renamed. + * gnus-art.el (gnus-with-article-buffer): New macro. - * message.el (message-cancel-news): If a Sender header doesn't - exist, compare From against `message-make-from'. +1998-11-29 Shenghuo ZHU -1998-05-03 Lars Balker Rasmussen + * gnus-art.el (gnus-mime-inline-part): Do not get part when + undisplay the part. - * gnus-agent.el (gnus-agent-save-group-info): Fix - re-search-forward params. +1998-11-30 Lars Magne Ingebrigtsen -1998-05-03 Lars Magne Ingebrigtsen + * gnus-util.el (gnus-make-sort-function-1): Allow lambdas. - * gnus-agent.el (gnus-agent-expire): Check for the size. + * mml.el (mml-read-part): Partition right. -1998-05-02 Dan Christensen + * mm-decode.el (mm-handle-set-cache): New macro. + (mm-handle-cache): Ditto. + (mm-make-handle): Ditto. + (mm-dissect-singlepart): Use it. + (mm-get-image): Use the cache. - * nnfolder.el (nnfolder-goto-article): New version. - (nnfolder-read-folder): Fix. +1998-11-29 Lars Magne Ingebrigtsen - * nnmail.el (nnmail-within-headers): New function. + * gnus-art.el (gnus-mime-display-mixed): Rewrite. + (gnus-mime-display-single): Don't insert lines between parts. -1998-05-02 Lars Magne Ingebrigtsen +1998-11-29 Shenghuo ZHU - * nnfolder.el (nnfolder-goto-article): Thinkotypo search arguments. + * nnmail.el (nnmail-file-coding-system-1): New variable. + * nnfolder.el (nnfolder-file-coding-system): Ditto. + (nnfolder-read-folder): Use nnfolder-file-coding-system. + * nnml.el (nnml-file-coding-system): New variable. + (nnml-request-article): Use nnml-file-coding-system. - * nnheader.el (nnheader-find-file-noselect): Also bind - `find-file-hooks' to nil. +1998-11-29 Lars Magne Ingebrigtsen - * nnmail.el (nnmail-process-unix-mail-format): Don't use - `find-file-noselect'. + * gnus.el: Pterodactyl Gnus v0.56 is released. - * gnus-group.el (gnus-group-make-menu-bar): Typo. +1998-11-29 Lars Magne Ingebrigtsen -1998-05-01 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-mime-display-part): New function. + (gnus-mime-display-mixed): Use it. - * gnus.el: Gnus v5.6.9 is released. + * mm-view.el (mm-setup-w3): Don't register. -1998-05-01 Lars Magne Ingebrigtsen + * message.el (message-cite-original): Cite parts. - * nnfolder.el (nnfolder-goto-article): Would infloop. +1998-11-28 Lars Magne Ingebrigtsen -1998-05-01 Lars Magne Ingebrigtsen + * mml.el (mml-parameter-string): New function. + (mml-insert-mime-headers): Separated into new function. - * gnus.el: Gnus v5.6.8 is released. +1998-11-28 Hrvoje Niksic -1998-05-01 Lars Magne Ingebrigtsen + * mml.el (mml-make-boundary): Use `make-string'. - * nntp.el (nntp-request-newgroups): Use format-time-string. +1998-11-27 Hrvoje Niksic - * message.el (message-fetch-field): Inhibit point-motion hooks. + * binhex.el (binhex-insert-char): Ditto. -1998-05-01 Wes Hardaker + * uudecode.el (uudecode-insert-char): Code correctly. - * gnus-score.el (gnus-adaptive-word-no-group-words): New variable. +1998-11-28 Lars Magne Ingebrigtsen -1998-05-01 Lars Magne Ingebrigtsen + * mml.el (mml-generate-mime): Don't generate multiparts for + empties. - * gnus-agent.el (gnus-agent-expire): Put point at the start of the - buffer. + * gnus-art.el (gnus-display-mime): Save excursion. - * gnus-soup.el (gnus-soup-parse-areas): Check whether the file - exists. + * message.el (message-remove-first-header): New function. + (message-encode-message-body): Use it. - * gnus-draft.el (gnus-draft-send): Use meta-information. +1998-11-27 Lars Magne Ingebrigtsen - * nnagent.el (nnagent-request-post): Store meta-information. + * gnus.el: Pterodactyl Gnus v0.55 is released. - * gnus-agent.el (gnus-agent-meta-information-header): New variable. - (gnus-agent-insert-meta-information): New function. +1998-11-27 Lars Magne Ingebrigtsen -1998-05-01 Paul Franklin + * mm-view.el (mm-setup-w3): New function. - * message.el (message-generate-headers): Insert Sender when - required. + * mm-decode.el (mm-content-id-get-contents): New function. + (mm-content-id-get-type): Ditto. + (mm-content-id-get-encoding): Ditto. + (mm-get-handle-by-content-id): Removed. -1998-05-01 Lars Magne Ingebrigtsen +1998-11-25 Colin Rafferty - * gnus-util.el (gnus-dd-mmm): Accept "" dates. + * message.el (message-generate-new-buffers): Fix tag. - * gnus-cite.el (gnus-article-hide-citation): Don't remove button - when hiding. +1998-11-25 Lars Magne Ingebrigtsen - * gnus-msg.el (gnus-post-method): Allow ARG to override - `current'. + * message.el (message-buffer-name): Check for unique first. - * gnus-sum.el (gnus-remove-thread): Remove the dummy root - properly. + * gnus-art.el (gnus-unbuttonized-mime-type-p): use + gnus-inhibit-mime-unbuttonizing. - * nnfolder.el (nnfolder-goto-article): New function. - (nnfolder-retrieve-headers): Use it. - (nnfolder-request-article): Ditto. + * gnus-sum.el (t): Bind M-t. + (gnus-inhibit-unbuttonizing): New variable. + (gnus-summary-toggle-display-buttonized): New command. -1998-04-29 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-display-mime): Select article window. + (article-strip-trailing-space): New command and keystroke. - * gnus.el: Gnus v5.6.7 is released. + * nneething.el (nneething-include-files): New variable. + (nneething-create-mapping): Use it. -1998-04-29 Lars Magne Ingebrigtsen + * nntp.el (nntp-possibly-change-group): Use nntp-send-command. - * gnus-sum.el (gnus-summary-update-info): Bind - gnuis-newsgroup-scored later. - (gnus-summary-prepare-threads): Check some more before inserting - dummy roots. + * nnvirtual.el (nnvirtual-request-update-mark): Only yodate + ayto-expirable marks. - * gnus-cache.el (gnus-cache-enter-article): Update marks - properly. +1998-11-24 Lars Magne Ingebrigtsen - * gnus-xmas.el (gnus-xmas-draft-menu-add): New function. + * gnus-art.el (gnus-mime-view-all-parts): Set buffer. - * nntp.el (nntp-connection-timeout): Removed. + * gnus-sum.el (gnus-summary-display-buttonized): Don't pass on + ARG. - * gnus-move.el (gnus-move-group-to-server): Delete nils. + * gnus-art.el (gnus-article-mode-line-format): Doc fix. - * nntp.el (nntp-close-server): Close more connections. +1998-11-24 Shenghuo ZHU - * gnus-art.el (gnus-button-alist): Accept white space after colons - in things. + * mm-util.el (mm-binary-coding-system): New variable. + (mm-with-unibyte-buffer): Use mm-binary-coding-system. + * mm-decode.el (mm-display-external): Ditto. -1998-04-29 Kurt Swanson +1998-11-24 Lars Magne Ingebrigtsen - * gnus-art.el (article-update-date-lapsed): Bind - `deactivate-mark'. + * gnus.el: Pterodactyl Gnus v0.54 is released. - * gnus-salt.el (gnus-pick-mode-map): Moved keys around to avoid - shadowing. +1998-11-24 Katsumi Yamaoka - * gnus-art.el (gnus-article-read-summary-keys): New version. + * gnus-sum.el (gnus-newsgroup-default-charset-alist): Note fj. - * gnus-sum.el (gnus-summary-make-menu-bar): New for article mode. +1998-11-24 Lars Magne Ingebrigtsen - * gnus-msg.el (gnus-post-method): `current' custom. + * mm-decode.el (mm-save-part): Unquote. -1998-04-29 Lars Magne Ingebrigtsen +1998-11-24 Matt Armstrong - * gnus-sum.el (gnus-summary-set-local-parameters): Ignore - quit-config. - (gnus-select-newsgroup): Use the value of gnus-fetch-old-headers. + * mm-decode.el (mm-save-part): Bind coding system for write. - * message.el (message-post-method): Doc fix. +1998-11-24 Lars Magne Ingebrigtsen - * gnus.el (gnus-directory): dox fix. + * gnus-art.el (gnus-article-mode-line-format): New default. + (gnus-article-mime-part-status): New function. -1998-04-28 Lars Magne Ingebrigtsen + * message.el (message-send-news): Check the body syntax before + encoding. - * gnus-group.el (gnus-group-timestamp): Really get timestamp. + * gnus-art.el (gnus-unbuttonized-mime-type): New function. + (gnus-mime-display-single): Use it. + (gnus-mime-display-alternative): Ditto. - * gnus.el (gnus-group-parameter-value): Use explicit iteration. + * mm-decode.el: Check for whether we are running under a term. -1998-04-28 Hallvard B. Furuseth +1998-11-22 Lars Magne Ingebrigtsen - * gnus-util.el (gnus-alive-p): Check for binding. + * mm-decode.el (mm-preferred-alternative): Default to first + alternative. + (mm-preferred-alternative): No, we dont. -1998-04-28 Lars Magne Ingebrigtsen +1998-11-24 Shenghuo ZHU - * gnus-sum.el (gnus-parent-headers): Don't infloop on nil - References. + * mm-decode.el (mm-display-external): Use binary instead of + no-conversion. + * gnus-agent.el (gnus-agent-file-coding-system): Ditto. + * nnheader.el (nnheader-file-coding-system): Ditto. + * mm-util.el (mm-with-unibyte-buffer): Use binary instead of nil. - * gnus-art.el (gnus-article-mode): Don't kill local vars. +1998-11-23 Shenghuo ZHU - * score-mode.el (score-mode-syntax-table): Change syntax. + * gnus-sum.el (gnus-newsgroup-setup-default-charset): Use group + name without method. -1998-04-27 Lars Magne Ingebrigtsen +1998-11-23 Shenghuo ZHU - * gnus.el: Gnus v5.6.6 is released. + * gnus-sum.el (gnus-newsgroup-default-charset): Rename + coding-system -> default-charset. + (gnus-newsgroup-default-charset-alist): Ditto. + (gnus-summary-local-variables): Ditto. + (gnus-set-global-variables): Ditto. + (gnus-get-newsgroup-headers): Ditto. + (gnus-summary-from-or-to-or-newsgroups): Ditto. + (gnus-get-newsgroup-headers-xover): Ditto. + (gnus-newsgroup-setup-default-charset): Ditto. + (article-decode-mime-words): Ditto. + (article-decode-charset): Ditto. + (article-decode-encoded-words): Ditto. + (article-de-quoted-unreadable): Ditto. + (gnus-mime-view-all-parts): Ditto. + (gnus-mime-externalize-part): Ditto. + (gnus-mm-display-part): Ditto. + (gnus-mime-display-single): Ditto. + (gnus-mime-display-alternative): Ditto. + +1998-11-23 Shenghuo ZHU + + * rfc2047.el (rfc2047-decode-region): Do not decode nil charset. + * gnus-art.el (article-decode-charset): Overlay + rfc2047-default-charset. + * message.el (message-draft-coding-system): New variable. + (message-set-auto-save-file-name): Use message-draft-coding-system. + * nndraft.el (nndraft-request-article): Ditto. + * gnus-start.el (gnus-start-draft-setup): Set charset nil. + * gnus-agent.el (gnus-agent-queue-setup): Ditto. + +1998-11-22 Shenghuo ZHU + + * mm-uu.el (mm-uu-test): New function. + (mm-uu-dissect): Inherit charset and cte from head. + * gnus-art.el (article-decode-charset): Use mm-uu-test. + +1998-11-21 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.53 is released. -1998-04-27 Lars Magne Ingebrigtsen +1998-11-21 Lars Magne Ingebrigtsen - * gnus-art.el (gnus-request-article-this-buffer): Viewing pseudos - in nneething groups bugged. + * mm-decode.el (mm-get-image): New function. + (mm-image-fit-p): New function. - * gnus-sum.el (gnus-summary-prepare-threads): Dummy roots and - dormants and stuff. + * gnus-util.el (gnus-annotation-in-region-p): New definition. -1998-04-26 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-article-insert-newline): New function. + (article-goto-body): New function. - * gnus-cache.el (gnus-cache-file-name): Use FULL. +1998-11-20 Lars Magne Ingebrigtsen - * nnheader.el (nnheader-translate-file-chars): Allow FULL - parameter. + * gnus-art.el (gnus-mime-display-single): Insert blank line before + buttons. - * gnus-cache.el (gnus-cache-file-name): Translate all colons. + * gnus-sum.el (gnus-summary-display-buttonized): New command and + keystroke. -1998-04-26 Justin Sheehy + * gnus-art.el (gnus-mime-display-single): Don't insert a blank + line between parts. - * nntp.el (nntp-rlogin-parameters): Doc fix. + * message.el (message-remove-header): Go to end if wanted. -1998-04-26 Lars Magne Ingebrigtsen +1998-11-20 Karl Kleinpaste - * gnus-art.el (gnus-summary-save-in-mail): Not a command. + * gnus-art.el (gnus-mime-display-alternative): Avoid window + movement with save-window-excursion. -1998-04-26 James Troup +1998-11-20 Shenghuo ZHU - * gnus-sum.el (gnus-summary-expire-articles-now): Work. + * gnus-art.el (gnus-mime-inline-part): Use argument as charset. -1998-04-26 Lars Magne Ingebrigtsen +1998-11-20 Shenghuo ZHU - * gnus-sum.el (gnus-build-sparse-threads): Break loops. - (gnus-summary-print-article): Save excursion to try to preserve - local/bound variable messup. + * mm-bodies.el (mm-decode-body): Remove buffer-file-coding-system. - * gnus-salt.el (gnus-tree-read-summary-keys): Put point in article - buffer. +1998-11-20 Shenghuo ZHU - * gnus-undo.el (gnus-undo): New group. - (gnus-undo-limit): New variable. - (gnus-undo-register-1): Use it. + * gnus-sum.el (gnus-summary-from-or-to-or-newsgroups): Use + gnus-newsgroup-coding-system. + (gnus-get-newsgroup-headers): Ditto. + (gnus-get-newsgroup-headers-xover): Ditto. + (gnus-set-global-variables): Ditto. + * gnus-art.el (article-decode-mime-words): Ditto. + (article-decode-charset): Ditto. + (article-decode-encoded-words): Ditto. + (article-de-quoted-unreadable): Ditto. + (gnus-mime-view-all-parts): Ditto. + (gnus-mime-externalize-part): Ditto. + (gnus-mm-display-part): Ditto. + (gnus-mime-display-alternative): Ditto. + (gnus-mime-display-single): Ditto. + * mm-view.el (mm-inline-text): Use default coding system. - * gnus-sum.el (gnus-summary-update-info): Don't nix out scores. +1998-11-20 Shenghuo ZHU - * gnus-start.el (gnus-active-to-gnus-format): Removed "." from - quoting. + * gnus-sum.el (gnus-newsgroup-coding-system-alist): New variable. + (gnus-newsgroup-iso-8859-1-forced-regexp): New variable. + (gnus-newsgroup-coding-system): New local variable. + (gnus-newsgroup-iso-8859-1-forced): New local variable. + (gnus-summary-local-variables): Add two new local variables. + (gnus-newsgroup-setup-coding-system): New function. + (gnus-select-newsgroup): Setup coding system. + * mm-util.el (mm-charset-iso-8859-1-forced): New variable. + (mm-charset-to-coding-system): Use mm-charset-iso-8859-1-forced. + * gnus-cus.el (gnus-group-parameters): Customizable + iso-8859-1-forced. - * gnus.el (gnus-cache-directory): Moved here. - (gnus-predefined-server-alist): Use. +1998-11-20 Lars Magne Ingebrigtsen - * message.el (message-autosave-directory): Put back in. - (message-set-auto-save-file-name): Use if Gnus isn't running. + * gnus.el: Pterodactyl Gnus v0.52 is released. - * gnus-util.el (gnus-alive-p): Moved here. +1998-11-20 Lars Magne Ingebrigtsen - * message.el (message-autosave-directory): Removed. - (message-set-auto-save-file-name): Don't use it. + * rfc2047.el (rfc2047-encode-message-header): Encode the default + encoding. - * gnus.el: Use gnus-buffer-exists-p throughout. + * gnus-art.el (gnus-mime-display-single): Insert buttons for + undisplayed text types. - * gnus-uu.el (gnus-uu-save-article): Use gnus-kill-buffer. + * mm-decode.el (mm-automatic-display-p): Only prefer inlinable + types. - * message.el (message-make-in-reply-to): Check more for strange - From lines. +1998-11-19 Felix Lee - * gnus-art.el (gnus-article-mode): Don't nix out vars. + * nntp.el (nntp-after-change-function-callback): recover from C-g. -1998-04-26 Frank Bennett +1998-11-19 Felix Lee - * nnmail.el (nnmail-move-inbox): Push error'ed mailboxes onto the - list. + * gnus-async.el (gnus-asynch-obarray): rename to + gnus-async-hashtb, and don't buffer-local it. -1998-04-26 Lars Magne Ingebrigtsen + (gnus-async-article-callback): new function. + (gnus-make-async-article-function): use it. - * gnus-score.el (gnus-score-save): Use it. + (gnus-async-current-prefetch-group): new var. + (gnus-async-current-prefetch-article): new var. + (gnus-async-request-fetched-article): are we fetching it already? - * score-mode.el (score-mode-syntax-table): New table. + (gnus-async-delete-prefected-entry): s/prefected/prefetched/ - * nnmbox.el: Commentary fix. +1998-11-20 Lars Magne Ingebrigtsen -1998-04-26 Richard Stallman + * gnus-sum.el (gnus-summary-show-article): Require. - * message.el (message-mode): New adaptive fill defaults. + * message.el: Provide before hooks. + (message-send-news): Do MIME before headers. -1998-04-26 Jim Radford + * gnus-art.el (gnus-article-check-buffer): New function. + (gnus-article-read-summary-keys): Use it. - * gnus-start.el (gnus-active-to-gnus-format): Groups that start - with dots. + * mm-decode.el (mm-user-automatic-display): Display all inline + images. -1998-04-11 Richard Stallman + * gnus-art.el (gnus-mime-display-single): Don't buttonize so + much. + (gnus-unbuttonized-mime-types): New variable. - * gnus/gnus-art.el (gnus-emphasis-alist): Use nth, not caddr. +1998-11-19 Lars Magne Ingebrigtsen -1998-04-25 Kim-Minh Kaplan + * gnus-sum.el (gnus-inhibit-user-auto-expire): Changed to t. - * gnus-sum.el (gnus-build-sparse-threads): Handle loops. + * mm-decode.el (mm-quote-arg): Quote semicolons. -1998-04-25 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-mime-display-single): Don't display + attachments. + (gnus-mime-externalize-part): New command and keystroke. - * gnus.el (gnus-valid-select-methods): nngateway is post-mail. + * mm-decode.el (mm-dissect-buffer): Pass on the description info. + (mm-alternative-precedence): Changed order. -1998-04-24 Lars Magne Ingebrigtsen +1998-11-07 Simon Josefsson - * gnus.el: Gnus v5.6.5 is released. + * gnus.el (gnus-method-simplify): New function. + (gnus-native-method-p): New function. + (gnus-secondary-method-p): Use gnus-method-equal. -1998-04-24 Lars Magne Ingebrigtsen + * gnus-start.el (gnus-group-change-level): Shorten select method. - * gnus-msg.el (gnus-post-method): Doc fix. - (gnus-post-method): Reversed semantics. +1998-11-19 Lars Magne Ingebrigtsen -1998-04-01 Jan Vroonhof + * gnus.el: Pterodactyl Gnus v0.51 is released. - * gnus-msg.el (gnus-post-method): Customized. Added 'native - option. In the function, added support for new value. +1998-11-19 Lars Magne Ingebrigtsen -1998-04-24 Lars Magne Ingebrigtsen + * gnus.el: Applied patches from 5.6.45. - * nnmbox.el (nnmbox-request-create-group): New function. + * gnus-score.el (gnus-score-find-trace): Print complete file + paths. + (gnus-score-find-trace): Truncate lines. -1998-04-12 Lars Magne Ingebrigtsen + * gnus.el (gnus-message-archive-group): Allow function. - * gnus-agent.el (gnus-agent-save-group-info): Only do those that - are covered. + * message.el (message-encode-message-body): Remove Mime-Version + before inserting. -1998-04-07 Lars Magne Ingebrigtsen + * gnus-cus.el (gnus-group-customize): Optional topic. - * nntp.el (nntp-authinfo-file): Doc fix. + * gnus-sum.el (gnus-summary-customize-parameters): New command and + keystroke. -1998-03-31 Ken Raeburn +1998-11-18 Shenghuo ZHU - * nnml.el (nnml-request-expire-articles): Sort active-articles, - then only expire the intersection of that set with the requested - articles. + * message.el (message-encode-message-body): Rewrite. -1998-04-01 Lars Magne Ingebrigtsen +1998-11-18 Lars Magne Ingebrigtsen - * message.el (message-supersede): Check Sender. - (message-cancel-news): Fix Sender check. + * mml.el (mml-base-boundary): New variable. + (mml-make-boundary): New function. -1998-03-29 Lars Magne Ingebrigtsen + * gnus-cache.el (gnus-cache-coding-system): New variable. + (gnus-cache-request-article): Use it. - * nnkiboze.el (nnkiboze-generate-group): Would mess up newsrs - hashtb. - (nnkiboze-enter-nov): Created bogus Xrefs headers. + * message.el (message-insert-mime-part): Delete duplicates. - * gnus-agent.el (gnus-agent-save-group-info): New function. +1998-11-18 Shenghuo ZHU - * gnus-start.el (gnus-get-unread-articles): Use it. + * gnus-art.el (gnus-mime-display-alternative): Set end of + multipart and display even when nothing is preferred. - * message.el (message-expand-group): Allow completion from in the - middle of strings. - (message-font-lock-keywords): Work when mail-header-separator is - "". +1998-11-18 Lars Magne Ingebrigtsen -1998-03-29 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.50 is released. - * gnus.el: Gnus v5.6.4 is released. +1998-11-18 Lars Magne Ingebrigtsen -1998-03-29 Lars Magne Ingebrigtsen + * mm-decode.el (mm-inline-media-tests): Check that device-type is + fbound. - * nnkiboze.el (nnkiboze-request-delete-group): Would bug out when - deleting files. + * gnus-sum.el (gnus-summary-sort): Didn't do reverse. -1998-03-28 Lars Magne Ingebrigtsen +1998-11-07 Simon Josefsson - * nntp.el (nntp-encode-text): Use `nntp-end-of-line'. + * gnus.el (gnus-similar-server-opened): Compare backend. -1998-03-26 Lars Magne Ingebrigtsen +1998-11-08 Simon Josefsson - * gnus-agent.el (gnus-agent-expire): Check size of history file. + * gnus-topic.el (gnus-topic-expire-articles): New function. + (gnus-topic-mode-map): Bind it. - * message.el (message-mode): Doc fix. + * gnus.texi (Topic Commands): New expiry command. Reordered. -1998-03-23 Mike McEwan +1998-11-10 Miles Bader - * gnus-score.el (gnus-score-default-type): Doc fix. + * gnus-sum.el + (gnus-auto-expirable-marks): New variable. + (gnus-inhibit-user-auto-expire): New variable. + (gnus-summary-mark-article-as-read, gnus-summary-mark-article): + When looking to see if we should expire instead, check + gnus-auto-expirable-marks instead of using a hard-wired list. + (gnus-summary-mark-as-read-forward, + gnus-summary-mark-as-read-backward): + Pass gnus-inhibit-user-auto-expire for the no-expire argument to + gnus-summary-mark-forward, instead of `t'. -1998-03-23 Lars Magne Ingebrigtsen +1998-11-18 Lars Magne Ingebrigtsen - * gnus-int.el (gnus-request-body): Do the same as HEAD. + * mml.el (mml-compute-boundary): New function. + (mml-compute-boundary-1): New function. + (mml-generate-mime-1): Use it. - * gnus-art.el (gnus-article-edit-article-hook): Removed. +1998-11-18 Hrvoje Niksic -1998-03-23 jari aalto + * mml.el (mml-generate-mime-1): Always precede closing boundary + with newline. - * gnus-art.el (gnus-article-edit-article-hook): New hook. +1998-11-18 Lars Magne Ingebrigtsen -1998-03-19 Jan Vroonhof + * mml.el (mml-generate-mime-1): Do right boundaries when several + multiparts. - * nntp.el (nntp-open-rlogin): Wrap in save-excursion + * mm-decode.el (mm-user-automatic-display): Default to inline + jpeg. -1998-03-19 Joe Buehler + * mml.el (mml-generate-mime-1): Encode non-text parts. - * gnus-util.el (gnus-date-iso8601): Use simple string. +1998-11-18 Lars Magne Ingebrigtsen -1998-03-19 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.49 is released. - * gnus.el: Gnus v5.6.3 is released. +1998-11-18 Lars Magne Ingebrigtsen -1998-03-19 Wes Hardaker + * mm-view.el (mm-inline-text): Require w3-vars. - * gnus-win.el (gnus-delete-windows-in-gnusey-frames): Make sure - there are no nil buffers. + * gnus-setup.el (gnus-use-tm): Removed. -1998-03-17 Per Abrahamsen + * gnus-art.el (gnus-article-goto-part): Don't beep. + (gnus-article-view-part): Check return value. + (gnus-mime-display-alternative): Don't display when there is + nothing to display. - * gnus-uu.el (gnus-uu-digest-headers): Add `Content-Type' and - `Content-Transfer-Encoding'. + * mml.el (mml-generate-mime-1): Don't use a unibyte buffer. + (mml-generate-mime-1): Use unibyte for binaries. -1998-03-18 Per Abrahamsen + * gnus-art.el (gnus-display-mime): Call + gnus-article-mime-part-function. + (gnus-mime-part-function): New function. + (gnus-article-mime-part-function): New function. - * message.el (message-header-lines): Added `:format'. + * mml.el (mml-generate-mime-1): Don't insert so many newlines. -1998-03-18 Simon Josefsson +1998-11-16 Lars Magne Ingebrigtsen - * nndoc.el: dummy request-accept-article + * mml.el (mml-generate-mime-1): Do it in unibyte buffers. -1998-03-19 Lars Magne Ingebrigtsen + * message.el (message-font-lock-keywords): Highlight MML. + (message-mml-face): New font. - * gnus-sum.el (gnus-summary-next-subject): Expand threads. +1998-11-16 Shenghuo ZHU - * gnus-agent.el (gnus-agent-group-mode-hook, - gnus-agent-summary-mode-hook): New variables. - (gnus-agent-mode): Run them. + * gnus-art.el (gnus-display-mime): Clean up even when no handles. + (gnus-mm-display-part): Do not select-window if the article window + is not found. -1998-03-14 SL Baur +1998-11-16 Shenghuo ZHU - * gnus-xmas.el (gnus-xmas-group-startup-message): Tell gnus-start - we've already drawn the pretty Gnu graphic. + * gnus-sum.el (gnus-summary-move-article): Use no-encode for B m. -1998-03-19 Lars Magne Ingebrigtsen +1998-11-16 Lars Magne Ingebrigtsen - * gnus-msg.el: Would use nil group names. + * gnus.el: Pterodactyl Gnus v0.48 is released. - * nntp.el (nntp-send-authinfo): Send authinfo to "force"d - servers. +1998-11-15 Lars Magne Ingebrigtsen + + * mm-bodies.el (mm-encode-body): Disbabled for nonmule. - * gnus-util.el (gnus-parse-netrc): Accept the "force" token. + * mm-util.el (mm-find-charset-region): Bogus change for non-Mule. - * message.el (message-cancel-news): Compare Sender header, not - From header. + * message.el (message-cite-original-without-signature): Ditto. + (message-cite-original): Quote parts. -1998-03-17 Lars Magne Ingebrigtsen +1998-11-15 Lars Magne Ingebrigtsen - * gnus-art.el (article-hide-headers): Fold case. + * gnus.el: Pterodactyl Gnus v0.47 is released. -1998-03-14 Lars Magne Ingebrigtsen +1998-11-15 Lars Magne Ingebrigtsen - * gnus-util.el (gnus-horizontal-recenter): New window-end may - return nil. + * message.el (message-encode-message-body): Insert MIME warning. -1998-03-13 Lars Magne Ingebrigtsen + * mml.el (mml-read-tag): Look for #tag. - * gnus-agent.el (gnus-agent-fetch-session): Check whether server - is up before fetching. + * mm-util.el (mm-find-charset-region): Check whether + enable-multibyte-characters is bound. - * gnus-win.el (gnus-window-frame-focus): New variable. - (gnus-configure-windows): Use it. +1998-11-15 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-catchup-and-exit): Don't select next - when in an ephemeral group. + * gnus.el: Pterodactyl Gnus v0.46 is released. - * gnus-agent.el (gnus-agent-expire): Message end. - (gnus-agent-expire-all): New variable. - (gnus-agent-expire): Use it. +1998-11-15 Lars Magne Ingebrigtsen -1998-03-13 Shenghuo ZHU + * message.el (message-encode-message-body): Insert headers at the + right spot. - * gnus-agent.el (gnus-agent-high-scored-p): Wrong value. +1998-11-15 Lars Magne Ingebrigtsen -1998-03-13 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.45 is released. - * nnvirtual.el (nnvirtual-request-group): Force updating of info. +1998-11-15 Lars Magne Ingebrigtsen -1998-03-08 Lars Magne Ingebrigtsen + * nndraft.el (nndraft-save-mime-part): Removed. + (nndraft-get-mime-part): Ditto. - * nnmail.el (nnmail-delete-incoming): Changed default. + * message.el (message-format-mime-old): Removed. + (message-encode-message-body): Removed. + (message-encode-message-body): Renamed. -1998-03-08 Lars Magne Ingebrigtsen +1998-11-14 Lars Magne Ingebrigtsen - * gnus.el: Gnus v5.6.2 is released. + * gnus-sum.el (gnus-get-newsgroup-headers): Translate \r's. -1998-03-08 Lars Magne Ingebrigtsen + * message.el (message-format-mime): Check message-mime-part. - * gnus-picon.el (gnus-get-buffer-name): Look in the assoc for the + * mm-encode.el (mm-mime-file-types): Removed. + (mm-default-file-encoding): New definition. + +1998-11-14 Shenghuo ZHU + + * mm-view.el (mm-inline-image): Use mm-insert-inline. + * gnus-art.el (gnus-mm-display-part): Go to correct position. + +1998-11-14 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.44 is released. + +1998-11-14 Lars Magne Ingebrigtsen + + * message.el (message-format-mime): New function. + + * nndraft.el (nndraft-save-mime-part): New function. + (nndraft-get-mime-part): New function. + + * mm-encode.el (mm-default-file-encoding): New function. + (mm-content-transfer-encoding): New function. + (mm-encode-buffer): New function. + + * message.el: New command. + (message-mime-part): New variable. + (message-insert-mime-part): New command. + + * mm-encode.el (mm-encode-content-transfer-encoding): New + function. + + * mm-util.el (mm-content-transfer-encoding-defaults): New variable. + (mm-mime-file-types): Taken from TM. - * nntp.el (nntp-wait-for): Check more for dead connections. +1998-11-14 Lars Magne Ingebrigtsen - * gnus-eform.el (gnus-edit-form-buffer): Moved back here. + * gnus.el: Pterodactyl Gnus v0.43 is released. - * gnus-win.el (gnus-window-to-buffer-helper): Return nil when - buffers don't exist. +1998-11-07 Karl Kleinpaste - * nndraft.el (nndraft-request-restore-buffer): Remove Xref header, - not Xrefs. + * gnus-cus.el (gnus-score-customize): Add "Extra" element. + * gnus-score.el (gnus-score-default-header): Ditto. + (gnus-header-index): Ditto. + (gnus-summary-increase-score): Ditto, & process "extra" requests. + (gnus-summary-header): Handle extra headers. + (gnus-summary-score-entry): Ditto, & provide new score element. + (gnus-summary-score-effect): Ditto. + (gnus-score-string): Avoid "extra" string sort, & modify match in + "extra" case. + * gnus-sum.el (gnus-make-score-map): Add "extra" element. -1998-03-08 Lars Magne Ingebrigtsen +1998-11-13 Lars Magne Ingebrigtsen - * gnus.el: Gnus v5.6.1 is released. + * message.el (message-resend): Bind message-required-mail-headers + to nil. -1998-03-07 Lars Magne Ingebrigtsen + * mm-view.el (mm-inline-text): Bind w3-strict-width. - * gnus.el (gnus-edit-form-buffer): Moved here. + * nngateway.el (require): Require cl. - * gnus-agent.el (gnus-agent-expire-old): Removed. - (gnus-agent-expire-directory): Ditto. - (gnus-agent-expire-group): Even more ditto. + * gnus-art.el (gnus-button-alist): Exclude more chars from news: + things. -1998-03-07 Lars Magne Ingebrigtsen +1998-11-11 Shenghuo ZHU - * gnus.el: Quassia Gnus v0.37 is released. + * gnus-agent.el (gnus-agent-fetch-headers): Create directory even + when no articles. -1998-03-07 Lars Magne Ingebrigtsen +1998-11-13 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agent-expire-days): New variable. - (gnus-agent-expire): New function. + * message.el (message-ignored-resent-headers): Remove X-Gnus. -1998-03-07 Lars Magne Ingebrigtsen +1998-11-10 Colin Rafferty - * gnus.el: Quassia Gnus v0.36 is released. + * gnus-sum.el (gnus-ignored-from-addresses): Only quote + user-mail-address if non-nil. -1998-03-07 Lars Magne Ingebrigtsen +1998-11-13 Lars Magne Ingebrigtsen - * nntp.el (nntp-wait-for): Reversed logic. + * gnus-util.el (gnus-make-sort-function): Do `reverse'. + (gnus-make-sort-function-1): Ditto. -1998-03-07 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-mm-display-part): Switch to mm in right + window. - * gnus.el: Quassia Gnus v0.35 is released. +1998-11-12 Lars Magne Ingebrigtsen -1998-03-07 Lars Magne Ingebrigtsen + * mm-util.el (mm-with-unibyte-buffer): Ditto. - * gnus-picon.el (gnus-picons-x-face-sentinel): Check whether - gnus-picons-x-face-file-name exists. + * binhex.el (binhex-decode-region): Quote. - * gnus-art.el (gnus-article-read-summary-keys): Move window point - in the summary buffer. +1998-11-10 Lars Magne Ingebrigtsen - * nndoc.el (nndoc-type-alist): Allow spaces around separator. + * gnus-art.el (article-decode-charset): Don't downcase charset. - * gnus-sum.el (gnus-summary-edit-parameters): Interactive. + * gnus-sum.el (gnus-get-newsgroup-headers-xover): Translate CR's. -1998-03-07 Wes Hardaker +1998-11-08 Lars Magne Ingebrigtsen - * gnus-art.el (gnus-article-prepare): Mark articles as - downloadable. + * gnus.el: Pterodactyl Gnus v0.42 is released. -1998-03-04 Ken Raeburn +1998-11-08 Shenghuo ZHU - * gnus-int.el (gnus-get-function): New version, caches symbol - names. + * gnus-art.el (gnus-display-mime): Add id for alternative part. -1998-03-06 Ken Raeburn +1998-11-08 Simon Josefsson - * nnml.el (nnml-article-to-file): Build pathname using - expand-file-name. (Thanks, Colin Rafferty, for catching - this.) + * nntp.el (nntp-send-mode-reader): Revert. -1998-02-28 Ken Raeburn +1998-11-08 Shenghuo ZHU - * nnml.el (nnml-article-to-file): Don't add extra "/" when - building pathname. + * gnus-agent.el (gnus-agent-fetch-articles): Use with-temp-buffer. - * nnheader.el (nnheader-file-to-number): Check value of - nnheader-numerical-short-files instead of checking if jka-compr is - loaded. +1998-11-07 Shenghuo ZHU -1998-03-03 Dave Love + * message.el (message-make-date): Fix for negative time zones. - * nnheader.el (nnheader-parse-head): Fix in-reply-to code. Return - nil consistently if not found. +1998-11-08 Lars Magne Ingebrigtsen -1998-03-07 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.41 is released. - * nntp.el: Check whether the connection died. +1998-11-08 Hrvoje Niksic -1998-03-01 Kim-Minh Kaplan + * mm-decode.el (mm-dissect-multipart): Quote regexp. - * gnus.texi (Easy Picons): Removed references to - `gnus-group-display-picons'. - (Hard Picons): Ditto. +1998-10-29 Sudish Joseph -1998-03-02 Lars Magne Ingebrigtsen + * gnus.el (gnus-short-group-name): When shortening foreign select + methods, do not scan for plusses beyond the first colon. - * gnus-sum.el (gnus-summary-exit-no-update): Run - gnus-summary-prepare-exit-hook here as well. +1998-11-07 Mike McEwan -1998-02-28 Lars Magne Ingebrigtsen + * gnus-agent.el (gnus-agent-save-group-info): Cater for group info + lines where `group' is the last thing on the line. - * nntp.el (nntp-authinforc-file): Changed default. - (nntp-authinfo-file): Changed name. - (nntp-record-commands): New variable. - (nntp-record-command): New function. +1998-11-08 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agent-group-path): Use real name of group. + * gnus-art.el (gnus-article-view-part): Do alternative. + (gnus-mime-display-alternative): Insert marker. - * gnus-sum.el (gnus-summary-insert-subject): Don't allow nil - articles. - (gnus-summary-read-group): Respect backward movement. +1998-11-07 Lars Magne Ingebrigtsen -1998-03-01 Kim-Minh Kaplan + * mm-decode.el (mm-dissect-multipart): Quote regexp. - * gnus-win.el (gnus-window-to-buffer): change "*Picons*" to - `gnus-picons-buffer'. - (gnus-window-to-buffer-helper): Support dynamic picon buffer - name (i.e a symbol that names a function to be called). - (gnus-configure-frame): Use it. - (gnus-delete-windows-in-gnusey-frames): Use it. - (gnus-all-windows-visible-p): Use it. - (gnus-remove-some-windows): Use it. + * nnmail.el (nnmail-expired-article-p): Protect against bogus + dates. - * gnus-picon.el (gnus-get-buffer-name): Use it. - (gnus-picons-kill-buffer): New function. - (gnus-picons-setup-buffer): New function. - (gnus-picons-set-buffer): Use them. - (gnus-picons-display-x-face): Put back the `buf' binding: it is - needed when `gnus-picons-display-where' is not set to article. - Also move the X-Face to the left, near the address. It seems more - logical. + * gnus-cus.el (gnus-topic): Required. -1998-02-28 Lars Magne Ingebrigtsen + * nnheader.el (nnheader-parse-nov): Parse extra. + (nnheader-nov-parse-extra): New macro. - * gnus.el: Quassia Gnus v0.34 is released. +1998-10-31 Lars Magne Ingebrigtsen -1998-02-28 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-article-view-part): Internal move. - * gnus.el: Quassia Gnus v0.33 is released. +1998-10-28 Per Abrahamsen -1998-02-28 Lars Magne Ingebrigtsen + * gnus-cus-new.el (gnus-custom-topic): New free variable. + (gnus-group-customize): Support editing topic parameters. - * gnus-picon.el (gnus-picons-display-x-face): `buf' -- unbound - var. +1998-10-29 Karl Kleinpaste -1998-02-28 Fran,Ag(Bois Pinard + * gnus-sum.el (gnus-summary-from-or-to-or-newsgroups): Add + indicators. - * gnus: configure'd. +1998-10-29 Lars Magne Ingebrigtsen -1998-02-28 Nelson Jose dos Santos Ferreira + * gnus-art.el (gnus-mm-display-part): Return. + (gnus-article-view-part): Only go if external. + (gnus-article-dumbquotes-map): Do 205. - * nnsoup.el (nnsoup-store-reply): Fix double sep error. + * mm-decode.el (mm-display-part): Return what was done. -1998-02-28 Lasse Rasinen + * message.el (message-buffer-naming-style): New variable. + (message-generate-new-buffers): Extended. + (message-buffer-naming-style): Removed. + (message-buffer-name): Use it. + (message-do-send-housekeeping): Rename new styling. - * gnus-start.el (gnus-ask-server-for-new-groups): Message more. + * gnus-sum.el (gnus-summary-recenter): Allow + gnus-auto-center-summary to be a number. -1998-02-27 Lars Magne Ingebrigtsen +1998-11-04 Shenghuo ZHU - * message.el (message-resend): Allow arbitrary Also's. + * pop3.el (pop3-open-server): Use "binary" instead of + "no-conversion". -1998-02-27 Dave Love +1998-11-01 Shenghuo ZHU - * gnus-sum.el (gnus-simplify-subject-functions): Fix - customization, doc. + * gnus-srvr.el (gnus-browse-foreign-server): Set + gnus-browse-current-method to the result of gnus-server-to-method. -1998-02-25 Dave Love +1998-10-29 Shenghuo ZHU - * gnus-art.el (gnus-article-x-face-command): Replace leading `{'. + * gnus-util.el (gnus-pull): Another optional argument. + * nnweb.el (nnweb-request-delete-group): Delete from + nnweb-group-alist and update active file. -1998-02-23 Lars Magne Ingebrigtsen +1998-10-29 Shenghuo ZHU - * gnus-agent.el (gnus-plugged): New command and keystroke. + * gnus-group.el (gnus-group-make-group): Accept group of new + method. - * gnus-ems.el (gnus-ems-redefine): Define - 'gnus-summary-set-display-table as a function that takes no - params. +1998-10-28 Shenghuo ZHU - * gnus.el (gnus-interactive): Don't use gnus-sum macros. - (gnus-valid-select-methods): Include nnlistserv. + * gnus-agent.el (gnus-agent-fetch-group-1): Update dribble. - * gnus.el: Autoloaded things to make byte-comp silent. +1998-10-27 Shenghuo ZHU -1998-02-23 Lars Magne Ingebrigtsen + * mm-view.el (mm-inline-text): Postion of html portion. - * gnus.el: Quassia Gnus v0.32 is released. +1998-10-29 Lars Magne Ingebrigtsen -1998-02-23 Lars Magne Ingebrigtsen + * nntp.el (nntp-list-active-group): Waited for short strings. + (nntp-send-mode-reader): Ditto. + (nntp-open-connection): Ditto. - * gnus-cite.el (gnus-article-hide-citation-maybe): Wrong - interactive specs. - (gnus-cite-toggle): Maybe parse. + * gnus-int.el (gnus-request-group-articles): New function. -1998-02-23 Rui-Tao Dong ~{6-HpLN~} + * nntp.el (nntp-request-listgroup): New function. + (nntp-request-group-articles): Renamed. - * nnweb.el (nnweb-type-definition): Fixed. +1998-10-27 Karl Kleinpaste -1998-02-22 Lars Magne Ingebrigtsen + * nnheader.el (nnheader-parse-nov): Supply extra. - * gnus-agent.el (gnus-agent-group-path): Translate right chars. - (gnus-agent-toggle-plugged): Allow proper closing. +1998-10-26 Lars Magne Ingebrigtsen - * gnus-srvr.el (gnus-browse-read-group): Allow entering - non-ephemeral groups. + * gnus-art.el (gnus-button-push): Don't go to + gnus-article-buffer. -1998-02-22 Lars Magne Ingebrigtsen + * mm-view.el (mm-inline-image): Add a newline. - * gnus.el: Quassia Gnus v0.31 is released. + * gnus-start.el (gnus-check-first-time-used): Check more. -1998-02-22 Lars Magne Ingebrigtsen +1998-10-26 Francois Felix Ingrand - * gnus-sum.el (gnus-summary-highlight): Give undownloaded marks a - better face. + * gnus-start.el (gnus-check-first-time-used): Check current. - * gnus-score.el (gnus-score-set): Take optional "warn". - (gnus-summary-score-entry): Use it. +1998-10-26 Lars Magne Ingebrigtsen - * gnus.el: Removed spurious * in defcustoms. + * mm-util.el (mm-find-charset-region): New function. - * gnus-score.el (gnus-score-load-file): Reverse logic. + * ietf-drums.el (ietf-drums-narrow-to-header): Work when no header. - * gnus-cite.el (gnus-article-hide-citation): Use markers to make - things work when wrapping. + * gnus-art.el (gnus-mime-button-menu): Fix. - * gnus-sum.el (gnus-summary-exit): Stop prefetch. +1998-10-26 Michael Welsh Duggan -1998-02-21 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-mime-button-menu): New definition. - * gnus-sum.el (gnus-get-newsgroup-headers): Buggy regexp. +1998-10-26 Lars Magne Ingebrigtsen -1998-02-21 Lars Magne Ingebrigtsen + * gnus-art.el (article-decode-charset): Downcase charset. + (article-decode-charset): Pass on type. + (article-decode-charset): Check nil charsets. + (article-remove-cr): Translate CR to LF. + (gnus-ignored-mime-types): Default to nil. - * gnus.el: Quassia Gnus v0.30 is released. + * nnheader.el (nnheader-insert-nov): Work when not Xref. -1998-02-21 Lars Magne Ingebrigtsen + * gnus-sum.el (gnus-ignored-from-addresses): Default to + user-mail-address. + (gnus-nov-parse-extra): Didn't return right thing. - * gnus-sum.el (gnus-summary-mark-article): Don't do anything if - the mark doesn't change. +1998-10-26 Shenghuo ZHU - * gnus-art.el (gnus-article-prepare): Don't enter article into - cache. + * mm-decode.el (mm-copy-Yo-buffer): Make it works when no header. - * gnus-sum.el (gnus-summary-reparent-thread): Don't mark as read. - (gnus-summary-mark-article): Don't do cache things here. +1998-10-25 Lars Magne Ingebrigtsen - * gnus-util.el (gnus-parse-netrc): Skip past macdefs. + * gnus.el: Pterodactyl Gnus v0.40 is released. -1998-02-20 Lars Magne Ingebrigtsen +1998-10-25 Lars Magne Ingebrigtsen - * gnus-srvr.el (gnus-browse-unsubscribe-group): Wouldn't allow - unsubscription. + * gnus-sum.el (gnus-summary-mark-forward): Show thread. - * gnus-sum.el (gnus-summary-insert-subject): Allow inserting - articles outside limits. + * gnus-start.el (gnus-check-first-time-used): Ignore dribble. - * gnus-start.el (gnus-dribble-enter): Update mode line. + * gnus-agent.el (gnus-agent-fetch-group-1): Bind name. - * gnus-srvr.el (gnus-browse-unsubscribe-group): Allow - unsubscription. + * nnml.el (nnml-possibly-create-directory): Check before making. - * gnus-picon.el (gnus-article-display-picons): Check that the - extents are live first. +1998-10-25 Kai Grossjohann -1998-02-19 Lars Magne Ingebrigtsen + * nnheader.el (nnheader-insert-nov): Don't infloop. - * gnus-group.el (gnus-useful-groups): Include gnus-bug. +1998-10-25 Lars Magne Ingebrigtsen -1998-02-19 Jens-Ulrik Holger Petersen + * gnus-sum.el (gnus-set-mode-line): Check that the spec has been + set up. - * gnus.el (gnus-group-history): Defined twice. +1998-10-25 Joerg Lenneis -1998-02-19 Lars Magne Ingebrigtsen + * nneething.el (nneething-file-name): New definition. - * gnus-sum.el (gnus-get-newsgroup-headers): Just use the header +1998-10-25 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-treatment-function-alist): Fix. + (gnus-summary-save-in-rmail): Use gnus-output-to-rmail. + + * nndoc.el (nndoc-dissect-mime-parts-sub): Recognize first part. + +1998-10-25 Lars Magne Ingebrigtsen + + * gnus.el: Pterodactyl Gnus v0.39 is released. + +1998-10-25 Lars Magne Ingebrigtsen + + * gnus-art.el (gnus-ignored-mime-types): New variable. + (gnus-mime-display-single): Use it. + (gnus-treatment-function-alist): New variable. + + * gnus.el (gnus-mime): New group. + + * gnus-art.el (gnus-mime-display-alternative): Don't destroy + things for other parts. + (gnus-mime-display-alternative): Place point. + + * gnus.el: autoload gnus-uu-post-news. + + * mailcap.el (mailcap-mailcap-entry-passes-test): Also check + needsterm/DISPLAY. + + * mm-decode.el (mm-display-part): Default to inline text/.* + parts. + + * mm-bodies.el (mm-decode-content-transfer-encoding): Default to + 8bit. + + * gnus-art.el (gnus-mime-copy-part): Use normal-mode. + (gnus-mime-display-single): Inline all text parts. + (gnus-article-narrow-to-signature): Removed mime:: stubs. + +1998-10-24 Lars Magne Ingebrigtsen + + * nnml.el (nnml-possibly-create-directory): Rewrite. + (nnml-request-create-group): Change to right server. + + * gnus-sum.el (gnus-set-mode-line): Use truncate-string-to-width. + + * gnus.el: rmail-output-to-rmail-file autoload. + + * gnus-util.el (gnus-output-to-rmail): Didn't work if not in + Gnus. + + * nnheader.el (nnheader-parse-head): Checked wrong variable. + + * gnus-sum.el (gnus-summary-update-mark): Ignore nil'd marks. + +1998-10-21 Shenghuo ZHU + + * gnus-art.el (gnus-mime-display-mixed): Multipart in + mixed part. + +1998-10-21 Shenghuo ZHU + + * gnus-sum.el (gnus-summary-exit): Use mm-destroy-parts. + + * gnus-sum.el (gnus-summary-exit-no-update): Ditto. + +1998-10-20 Shenghuo ZHU + + * mm-uu.el (mm-uu-dissect): Create pseudo multipart head. + +1998-10-24 Lars Magne Ingebrigtsen + + * gnus-sum.el (gnus-valid-move-group-p): Make sure group has a value. - (gnus-summary-exit): Set global vars. -1998-02-17 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-article-hidden-text-p): Return nil when not + hidden. + + * gnus-spec.el (gnus-update-format-specifications): Use the + article mode line spec. - * gnus-sum.el (gnus-summary-stop-page-breaking): Mark page as no - longer broken. - (gnus-summary-exit): Purge the real name. + * gnus-art.el (gnus-insert-mime-button): Put right type. + (gnus-insert-prev-page-button): Ditto. + (gnus-insert-next-page-button): Dutti. -1998-02-17 Lars Magne Ingebrigtsen + * pop3.el: New version installed. - * gnus.el: Quassia Gnus v0.29 is released. +1998-10-24 Shenghuo ZHU -1998-02-17 Lars Magne Ingebrigtsen + * mm-uu.el (mm-uu-dissect): Delete the begining spurious newline + and display last part. - * nnmail.el (nnmail-purge-split-history): List of alists, not - alist. +1998-10-24 Lars Magne Ingebrigtsen -1998-02-16 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.38 is released. - * gnus.el: Quassia Gnus v0.28 is released. +1998-10-24 Lars Magne Ingebrigtsen -1998-02-16 Lars Magne Ingebrigtsen + * gnus-art.el (article-mime-decode-quoted-printable-buffer): + Removed. + (article-de-quoted-unreadable): Narrow to default. - * message.el (message-dont-send): Make sure the article really is - saved. + * qp.el (quoted-printable-encode-region): Encode before QP-ing. - * nnmail.el (nnmail-purge-split-history): Alist; not a list of - alists. + * gnus-art.el (article-decode-charset): Decode even when broken + MIME. -1998-02-16 Hrvoje Niksic + * gnus-sum.el (gnus-summary-from-or-to-or-newsgroups): Return + name. - * message.el (message-kill-to-signature): Do the right thing when - there is no signature. + * gnus-msg.el (gnus-copy-article-buffer): Delete headers. -1998-02-16 Hrvoje Niksic + * gnus-cache.el (gnus-cache-possibly-enter-article): Use + nnheader. - * message.el (message-elide-elipsis): Add type and group. - (message-elide-region): Docfix. + * nnmail.el (nnmail-extra-headers): New variable. -1998-02-16 Lars Magne Ingebrigtsen + * nnheader.el (nnheader-insert-nov): Insert extra. - * gnus-util.el (gnus-run-hooks): Use unwind-protect instead of - save-excursion. + * gnus.el (gnus-summary-line-format): Doc fix. -1998-02-16 Per Abrahamsen + * gnus-sum.el (gnus-get-newsgroup-headers): Parse extra. + (gnus-nov-parse-line): Ditto. + (gnus-nov-parse-extra): New macro. + (gnus-header): New function. + (gnus-update-summary-mark-positions): Change. + (gnus-ignored-from-addresses): New variable. + (gnus-summary-insert-from-or-to): New function. - * nntp.el (nntp-authinforc-file): Customized. + * gnus.el (gnus-extra-headers): New variable. -1998-02-16 Lars Magne Ingebrigtsen + * nnheader.el (make-mail-header): Expand. + (mail-header-extra): New macro. + (mail-header-set-extra): Ditto. + (make-full-mail-header): Expand. - * gnus-nocem.el (gnus-nocem-unwanted-article-p): Don't look if the - hashtable doesn't exist. +1998-10-24 Lars Magne Ingebrigtsen - * gnus-start.el (gnus-ask-server-for-new-groups): Make sure the - killed groups hashtable exists. + * gnus.el: Pterodactyl Gnus v0.37 is released. -1998-02-15 Lars Magne Ingebrigtsen +1998-10-24 Lars Magne Ingebrigtsen - * nntp.el (nntp-authinforc-file): Changed name and default. - (nntp-send-authinfo): Use it. + * mm-bodies.el (mm-decode-body): Check for multibyticity. -1998-02-15 Lars Magne Ingebrigtsen + * mm-util.el (mm-enable-multibyte): Don't always switch multibyte + on. - * gnus.el: Quassia Gnus v0.27 is released. +1998-10-22 Didier Verna -1998-02-15 Lars Magne Ingebrigtsen + * gnus-spec.el (gnus-balloon-face-function): new function + (gnus-parse-format): understand the %< %> specifiers + (gnus-parse-complex-format): ditto. - * gnus.el (gnus-ephemeral-servers): New variable. - * gnus-srvr.el (gnus-server-prepare): Use it. - * gnus-group.el (gnus-group-read-ephemeral-group): Ditto. +1998-10-24 Lars Magne Ingebrigtsen -1998-02-15 Kurt Swanson + * gnus.el: Changed following-char to char-after throughout. - * gnus-art.el (gnus-article-read-summary-keys): Go to top on - some. +1998-10-22 Lars Magne Ingebrigtsen -1998-02-15 SeokChan LEE + * mm-decode.el (mm-display-external): Protect more and message. - * message.el (message-ignored-supersedes-headers): Fix. +1998-10-21 Shenghuo ZHU -1998-02-15 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-mime-display-mixed): Multipart in + mixed part. - * gnus-salt.el (gnus-tree-close): Start killing buffer again. +1998-10-21 Shenghuo ZHU - * gnus-sum.el (gnus-mark-article-as-read): Return t. + * gnus-sum.el (gnus-summary-exit): Use mm-destroy-parts. - * gnus-art.el (gnus-article-edit-mode): Run text mode hook. + * gnus-sum.el (gnus-summary-exit-no-update): Ditto. -1998-02-15 Roland Roberts +1998-10-20 Shenghuo ZHU - * gnus-sum.el (gnus-nov-parse-line): Would bug out on bogus - References headers. + * mm-uu.el (mm-uu-dissect): Create pseudo multipart head. -1998-02-15 Lars Magne Ingebrigtsen +1998-10-21 Hrvoje Niksic - * gnus-art.el (gnus-article-current-summary): New variable. - (gnus-article-mode): Make it local. + * mailcap.el (mailcap-save-binary-file): Use unwind-protect. - * gnus-score.el (gnus-summary-increase-score): Find the right - global score file. + * mm-decode.el (mm-display-external): Set undisplayer to mm + buffer, not the current buffer; use unwind-protect. - * gnus-start.el (gnus-setup-news): Don't find new newsgroups - unless plugged. +1998-10-21 Lars Magne Ingebrigtsen - * message.el (message-mode): Set font-lock things before running - mode hook. + * gnus-sum.el (gnus-summary-exit): Destroy parts. + (gnus-summary-exit-no-update): Ditto. - * gnus-agent.el (gnus-agent-group-path): Respect long file names. +1998-10-21 Lars Magne Ingebrigtsen -1998-02-14 Lars Magne Ingebrigtsen + * mm-decode.el (mm-inline-media-tests): Look for w3. - * gnus-sum.el (gnus-summary-goto-last-article): Force jumping to - articles outside limit. + * mailcap.el (mailcap-mime-data): Inline html. - * gnus-agent.el (gnus-agent-toggle-plugged): un/plug before hook. +1998-10-20 Lars Magne Ingebrigtsen -1998-02-14 Kim-Minh Kaplan + * gnus.el: Pterodactyl Gnus v0.36 is released. - * gnus-xmas.el (gnus-xmas-article-display-xface): t t would make - faces disappear. +1998-10-20 Lars Magne Ingebrigtsen -1998-02-14 Lars Magne Ingebrigtsen + * gnus-art.el (article-translate-strings): + (gnus-article-dumbquotes-map): Don't dot. - * nntp.el (nntp-netrc-file): New variable. + * pop3.el (pop3-open-server): Set point right. -1998-02-14 Lars Magne Ingebrigtsen + * mm-decode.el (mm-dissect-multipart): Dissect hierarchically. + (mm-dissect-buffer): Ditto. + (mm-destroy-part): Ignore non-handles. + (mm-remove-part): Ditto. + (mm-destroy-parts): New function. + (mm-remove-parts): Ditto. - * gnus.el: Quassia Gnus v0.26 is released. + * gnus-art.el (gnus-mm-display-part): Don't move point. -1998-02-14 Lars Magne Ingebrigtsen +1998-10-20 Shenghuo ZHU - * gnus-agent.el (gnus-agent-directory): Translate file chars. + * mm-uu.el : New file. - * gnus-sum.el (gnus-summary-print-article): Don't display all - headers. - (gnus-summary-edit-parameters): New command and keystroke. + * gnus-art.el (gnus-display-mime): Dissect uu stuffs. - * gnus-group.el (gnus-group-rename-group): Mark dribble. + * mm-bodies.el (mm-decode-content-transfer-encoding): Encoding as + a function. -1998-02-14 Fred Oberhauser +1998-10-20 Lars Magne Ingebrigtsen - * nnmail.el (nnmail-process-babyl-mail-format): Fix point - movement. + * mm-decode.el (mm-display-external): Check before selecting. -1998-02-14 Lars Magne Ingebrigtsen +1998-09-26 Shenghuo ZHU - * gnus.el (gnus-group-get-parameter): Dix fix. + * gnus-sum.el (gnus-multi-decode-encoded-word-string): Rewrite. -1998-02-14 Kim-Minh Kaplan + * gnus-sum.el (gnus-decode-encoded-word-methods): New variable. - * gnus-picon.el: Updated documentation. + * gnus-sum.el (gnus-decode-encoded-word-methods-cache): New + variable. -1998-02-14 Joev Dubach + * gnus-sum.el (gnus-encoded-word-method-alist): Deleted. - * nntp.el (nntp-send-authinfo-from-file): Doc fix. + * gnus-art.el (gnus-decode-header-methods): New variable. -1998-01-11 Ken Raeburn + * gnus-art.el (gnus-decode-header-methods-cache): New variable. - * nnagent.el (nnagent-request-update-info): New no-op fn. + * gnus-art.el (gnus-multi-decode-header): New function. -1998-02-14 Lars Magne Ingebrigtsen +1998-10-20 Lars Magne Ingebrigtsen - * gnus-srvr.el (gnus-browse-unsubscribe-group): Wouldn't allow - subscription of visited groups. + * gnus.el: Pterodactyl Gnus v0.35 is released. - * gnus-util.el (gnus-run-hooks): New function. - Use it everywhere. +1998-10-20 Lars Magne Ingebrigtsen - * nntp.el (nntp-authinfo-password): New variable. - (nntp-send-authinfo): Cache authinfo password. + * uudecode.el (uudecode-decode-region-external): Insert + literally. - * gnus-sum.el (gnus-summary-mark-article-as-unread): Don't do - anything if the mark doesn't change. + * mm-bodies.el (mm-decode-body): Optional encoding. -1998-01-17 Simon Josefsson +1998-10-20 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-work-articles): change buffer - before looking at marked articles - (gnus-summary-work-articles): better check of marked articles + * gnus-ems.el (gnus-mouse-3): New variable. -1998-02-14 Lars Magne Ingebrigtsen + * binhex.el (binhex-decode-region-external): Don't use -internally. - * nntp.el (nntp-send-authinfo): Use new .netrc functionality. +1998-10-16 Simon Josefsson - * gnus-util.el (gnus-netrc-syntax-table): New variable. - (gnus-parse-netrc): New function. - (gnus-netrc-machine): Ditto. - (gnus-netrc-get): Ditto. + * mailcap.el (mailcap-parse-mailcaps): Only open regular + files. - * gnus-draft.el (gnus-draft-make-menu-bar): Added deletion. +1998-09-27 Simon Josefsson - * gnus.el (gnus-expert-user): Dix fox. + * gnus-group.el (gnus-add-marked-articles): Request backend update + of flags. - * nnmail.el (nnmail-article-group): Remove duplicates from split. +1998-09-26 Simon Josefsson - * message.el (message-check-news-header-syntax): Check more on - Message-ID. + * gnus-sum.el (gnus-update-read-articles): + (gnus-update-marks): Request backend update of mark. - * nnmh.el: Don't call nnmail-activate. +1998-09-26 Simon Josefsson - * gnus.el: User-variabelize all custom vars. + * gnus.texi (Optional Backend Functions): New item, + nnchoke-request-set-mark. -1998-02-13 Lars Magne Ingebrigtsen +1998-09-26 Simon Josefsson - * gnus.el: Quassia Gnus v0.25 is released. + * gnus-range.el (gnus-remove-from-range): Don't add stuff in + list to range. -1998-02-13 Lars Magne Ingebrigtsen +1998-10-20 Simon Josefsson - * nndoc.el (nndoc-type-alist): Allow blank lines to separate - headers from bodies. + * gnus-sum.el (gnus-summary-exit-no-update): Don't expire. - * gnus-art.el (gnus-article-edit): Restore Date header. +1998-10-14 SL Baur - * gnus-async.el (gnus-asynch-obarray): New variable. - (gnus-async-prefetched-article-entry): Use it. - (gnus-async-set-buffer): Use it. + * gnus-sum.el: Move gnus-save-hidden-threads above where it is + first used. - * nnmh.el (nnmh-active-number): Create parent dirs. +1998-10-10 SL Baur - * nntp.el (nntp-last-command): New variable. - (nntp-handle-authinfo): New function. + * mm-view.el: Require mm-decode for macros. - * gnus-sum.el (gnus-summary-exit): Call purging function. + * mm-decode.el (mm-handle-type): Move macro declarations above the + place where they are used. -1998-02-13 Fran,Ag(Bois Pinard +1998-10-18 Kurt Swanson - * nnmail.el (nnmail-get-new-mail): Don't clear split-history. - (nnmail-purge-split-history): New function. + * gnus-msg.el (gnus-summary-mail-forward): Erase old forward + buffer. -1998-02-13 Lars Magne Ingebrigtsen +1998-10-20 Katsumi Yamaoka - * nntp.el (nntp-telnet-shell-prompt): Renamed. + * nnagent.el (nnagent-open-server): Error message. -1998-02-13 Sam Falkner +1998-10-20 Joerg Lenneis - * nntp.el (nntp-open-telnet-envuser): New variable. + * nnheader.el (nnheader-article-p): Recognize lower-case headers. -1998-02-13 Lars Magne Ingebrigtsen +1998-10-19 Hrvoje Niksic - * message.el (message-send-mail-function): Added smtpmail-send-it. + * score-mode.el (gnus-score-mode-map): Ditto. -1998-02-11 Dave Love + * message.el (message-mode-map): Ditto. - * gnus-art.el (gnus-button-url): Don't lose in Emacs 20 with - browse-url-browser-function an alist, not a function. - (gnus-button-embedded-url): Likewise. + * gnus-uu.el (gnus-uu-post-news): Ditto. -1998-02-13 Lars Magne Ingebrigtsen + * gnus-kill.el (gnus-kill-file-mode-map): Ditto. - * gnus-cite.el (gnus-cite-localize): New function. - (gnus-cite-close): Renamed. - (gnus-cite-parse-maybe): Use it. + * gnus-eform.el (gnus-edit-form-mode-map): Ditto. - * gnus-sum.el (gnus-summary-move-article): Move back to summary - buffer. + * gnus-art.el (gnus-article-edit-mode-map): Use + `set-keymap-parent' rather than `copy-keymap'. - * nnfolder.el (nnfolder-request-accept-article): Save excursion. - (nnfolder-request-move-article): Ditto. +1998-10-18 Hrvoje Niksic - * nntp.el (nntp-find-connection): Don't message. + * gnus-art.el (gnus-mime-button-commands): New variable. + (gnus-mime-button-map): Initialize it from + `gnus-mime-button-commands'. + (gnus-mime-button-menu): New function. + (gnus-insert-mime-button): Use `gnus-mime-button-map'. -1998-02-13 MORIOKA Tomohiko +1998-10-11 Hrvoje Niksic - * message.el (message-send-mail-with-qmail): Fix. + * message.el (message-insert-to): Make `nobody' and `poster' + synonymous to `never' and `always' in Mail-Copies-To. + (message-reply): Ditto. + (message-followup): Ditto. -1998-02-13 Per Abrahamsen +1998-10-20 Lars Magne Ingebrigtsen - * gnus-draft.el (gnus-draft-make-menu-bar): Added missing commands. + * mailcap.el (mailcap-mime-data): Save sound. -1998-01-06 Per Abrahamsen +1998-09-24 Hrvoje Niksic - * gnus/gnus-cus.el (gnus-score-parameters): Make `files' and - `exclude-files' widgets inline. + * message.el (message-ignored-supersedes-headers): Include + `NNTP-Posting-Date'. -1998-02-13 Lars Magne Ingebrigtsen +1998-10-19 Jonas Steverud - * gnus-sum.el (gnus-article-mark): Dox dox. + * gnus-art.el (gnus-article-dumbquotes-table): New variable. -1998-02-11 Lars Magne Ingebrigtsen +1998-10-19 Lars Magne Ingebrigtsen - * gnus.el: Quassia Gnus v0.24 is released. + * mm-bodies.el (mm-decode-content-transfer-encoding): Use + uudecode. -1998-02-10 Lars Magne Ingebrigtsen +1998-10-18 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agent-fetch-session): Reversed reversal. + * mm-decode.el (mm-display-external): Don't switch on save. - * gnus-topic.el (gnus-topic-rename): Check whether the new name - exists. +1998-10-18 Andy Piper -1998-02-10 dave edmondson + * nnmail.el (nnmail-movemail-args): New variable. - * message.el (message-font-lock-keywords): Allow : as a citation - ending. +1998-10-18 Lars Magne Ingebrigtsen -1998-02-10 Lars Magne Ingebrigtsen + * gnus-art.el (article-translate-strings): - * message.el (message-send): Removed dead code. +1998-10-18 Lars Magne Ingebrigtsen -1998-02-09 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-article-view-part): Use it. + (gnus-mm-display-part): New function. + (article-de-quoted-unreadable): Yse mm-default-coding-system. - * message.el (message-fill-header): Fill to column 990. + * mm-decode.el (mm-handle-displayed-p): New function. - * gnus-score.el (gnus-score-load-file): Exclude all excluded - files. + * gnus-art.el (gnus-mime-copy-part): Create better names. + (gnus-mime-button-line-format): Include dots spec. -1998-02-09 jari aalto +1998-10-15 Matt Pharr - * gnus-art.el (gnus-article-time-format): Extended variable. + * gnus-msg.el (gnus-summary-mail-forward): Erase contents of old + forward buffer first. -1998-02-09 Lars Magne Ingebrigtsen +1998-10-17 Lars Magne Ingebrigtsen - * gnus-art.el (article-make-date-line): Make 8601 Dates. - (article-date-iso8601): New command and keystroke. + * gnus-util.el (gnus-set-window-start): New function. -1998-02-08 Lars Magne Ingebrigtsen + * message.el (message-send): Don't check changed. - * message.el (message-ignored-mail-headers): Remove Xrefs. +1998-10-12 Lars Magne Ingebrigtsen - * nndoc.el (nndoc-open-document-hook): New variable. + * gnus-art.el (gnus-article-setup-buffer): Set params. -1998-02-08 Istvan Marko + * mm-decode.el (mm-user-display-methods): Inline + "message/delivery-status". - * gnus-agent.el (gnus-unplugged): Typo fix. +1998-10-11 Lars Magne Ingebrigtsen -1998-02-08 Kurt Swanson + * message.el (message-auto-save-directory): Rename. + (message-mode): Dof fix. - * gnus-score.el (gnus-score-thread-simplify): New variable. + * gnus-art.el (gnus-summary-save-in-pipe): Default to "cat". + (gnus-summary-save-in-pipe): No, check gnus-last-shell-command. -1998-02-08 Lars Magne Ingebrigtsen + * nndoc.el (nndoc-mime-parts-type-p): Be a bit more forgiving. - * gnus-uu.el (gnus-uu-post-encode-mime): Call mmencode with - correct params. + * message.el (message-make-date): Avoid locale. -1998-02-08 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-article-edit-done): Allow update before doing + cache. - * gnus.el: Quassia Gnus v0.23 is released. + * mm-decode.el (mm-display-inline): Goto point-min. -1998-02-08 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-article-prepare-display): Not read-only. - * gnus-group.el (gnus-update-group-mark-positions): Bind `topic'. + * mm-decode.el (mm-display-external): Reverse before sorting. - * message.el (message-expand-group): Added doc string. + * gnus-draft.el (gnus-draft-send): Allow mail. - * nntp.el (nntp-wait-for): Don't change limit until after - accepting output. +1999-11-30 -SL Baur -1998-02-08 Richard Hoskins + * message.el (message-check): Move message-check macro above where + it is first used. - * message.el (message-kill-to-signature): Don't kill the - delimiter. + * gnus-art.el (article-hide-pgp): Hide the PGP 5/GNUPG Hash: line. -1998-02-08 Lars Magne Ingebrigtsen +1998-10-11 Lloyd Zusman - * gnus-sum.el (gnus-summary-prepared-hook): New hook. - (gnus-summary-read-group-1): Use it. + * gnus-sum.el (gnus-summary-make-menu-bar): Fix. - * message.el (message-cite-original-without-signature): New - function. - (message-cite-function): Added to custom. +1998-10-11 Lars Magne Ingebrigtsen -1998-01-13 Per Abrahamsen + * gnus.el: Pterodactyl Gnus v0.34 is released. - * gnus/message.el (message-cite-original): Don't quote signature. +1998-10-11 Lars Magne Ingebrigtsen -1998-02-08 Lars Magne Ingebrigtsen + * mm-decode.el (mm-inline-media-tests): delivery-status. - * gnus-group.el (gnus-group-unsubscribe-group): Protest against - empty group names. + * mm-view.el (mm-inline-text): Provide default. -1998-02-02 Lars Magne Ingebrigtsen +1998-10-11 Lloyd Zusman - * gnus-draft.el (gnus-draft-setup): Associate with drafts group. + * mailcap.el (mailcap-possible-viewers): Fix nils. - * message.el (message-header-format-alist): Fill references. +1998-10-11 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-category-read): Changed default. - (gnus-agent-handle-level): New variable. - (gnus-agent-fetch-session): Use it. + * gnus-art.el (gnus-article-edit-exit): Don't do updates. + (article-update-date-lapsed): Record the buffer. + (article-update-date-lapsed): Do all windows that display article + buffers. - * gnus-art.el (article-strip-all-blank-lines): New command and - keystroke. + * nnml.el (nnml-generate-nov-databases-1): Ditto. -1998-02-01 Lars Magne Ingebrigtsen + * gnus-score.el (gnus-score-score-files-1): Ignore dotted files. - * gnus-msg.el (gnus-inews-reject-message): Removed function. - (gnus-sent-message-ids-file): Removed. - (gnus-sent-message-ids-length): Ditto. + * gnus-art.el (gnus-insert-mime-button): Mark buttons as + annoations. - * gnus-xmas.el (gnus-xmas-summary-set-display-table): Ditto. + * gnus-msg.el (gnus-summary-mail-forward): Decode properly. - * gnus-sum.el (gnus-simplify-subject-fuzzy): Respect - `gnus-simplify-ignored-prefixes'. - (gnus-summary-set-display-table): Keep TAB. +1998-10-11 Lars Magne Ingebrigtsen -1998-01-15 + * gnus-agent.el (gnus-category-add): Change default category to + 'false. - * gnus-art.el (gnus-request-article-this-buffer): Put it into the - backlog. + * nnvirtual.el (nnvirtual-update-read-and-marked): Don't nix out + scores. -1998-01-12 Lars Magne Ingebrigtsen + * gnus-draft.el (gnus-draft-send): Check server more. - * gnus-sum.el (gnus-get-newsgroup-headers): Use the longest ID. + * gnus-art.el (gnus-article-view-part): New command and keystroke. + (gnus-article-goto-part): New function. - * nnheader.el (nnheader-parse-head): Ditto. + * mm-view.el (mm-inline-text): Insert richtext properly. -1998-01-08 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-insert-mime-button): Store handle in alist. - * gnus-start.el (gnus-1): Use gnus-alive-p. +1998-10-03 Lars Magne Ingebrigtsen -1998-01-06 Lars Magne Ingebrigtsen + * parse-time.el (parse-time-rules): Accept dates far into the past + and the future, and parse single-digit numbers as years. - * gnus-art.el (gnus-article-prepare): Bind coding systems. +1998-10-02 Lars Magne Ingebrigtsen -1998-01-06 Lars Magne Ingebrigtsen + * mm-decode.el (mm-display-external): Chop off directories. - * gnus.el: Quassia Gnus v0.22 is released. +1998-10-01 Lars Magne Ingebrigtsen -1998-01-06 Lars Magne Ingebrigtsen + * uudecode.el (uu-decode-region-external): Use + insert-file-contents-literally. - * message.el (message-kill-to-signature): Don't use mark. + * gnus-cache.el (gnus-cache-generate-active): Translate _ to :. -1998-01-06 Russ Allbery +1998-10-01 Shenghuo ZHU - * message.el (message-kill-to-signature): New command and keystroke. + * uudecode.el: New file. -1998-01-06 Lars Magne Ingebrigtsen + * mm-bodies.el (mm-decode-content-transfer-encoding): Do + x-uuencode. - * gnus-sum.el (gnus-summary-print-article): New defaults for - headers and stuff. +1998-10-01 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agent-batch): New command. + * gnus-art.el (gnus-mime-display-alternative): Set faces. - * nnoo.el (nnoo-execute): Copy vars from parent into child. - (nnoo-parent-function): Ditto. + * message.el (message-fetch-field): Unfold properly. - * gnus-draft.el (gnus-draft-setup): Removed message. + * mm-bodies.el (mm-decode-content-transfer-encoding): Replace CRLF + in text/plain. - * gnus-start.el (gnus-read-descriptions-file): Naked muleism. +1998-09-30 Lars Magne Ingebrigtsen -1998-01-05 Lars Magne Ingebrigtsen + * gnus-sum.el (gnus-summary-first-unread-subject): New command. + (gnus-auto-select-first): Removed. + (gnus-auto-select-first): Extended. + (gnus-summary-read-group-1): Use new value. - * nnml.el (nnml-generate-nov-databases-1): Fix lower bound on - empty groups. +1998-09-29 Lars Magne Ingebrigtsen -1998-01-04 Lars Magne Ingebrigtsen + * message.el (message-fix-before-sending): Space. - * gnus.el: Quassia Gnus v0.21 is released. + * nnmail.el (nnmail-find-file): Don't erase. -1998-01-04 Lars Magne Ingebrigtsen +1998-10-01 Shenghuo ZHU - * gnus.el: Quassia Gnus v0.20 is released. + * gnus-agent.el (gnus-agent-fetch-headers): Do not decode headers. -1997-12-10 Per Abrahamsen +1998-10-01 Shenghuo ZHU - * gnus/gnus-msg.el (gnus-inews-insert-mime-headers): Added - documentation. - (gnus-inews-insert-mime-headers): Made it work with Emacs MULE. - (gnus-inews-insert-mime-headers): Added as option to - `message-header-hook'. + * gnus-soup.el (gnus-soup-add-article): Do not decode headers. -1997-12-22 Per Abrahamsen +1998-10-01 Shenghuo ZHU - * gnus/gnus-art.el (gnus-button-alist): Assume msg-id after "in - message". + * gnus-soup.el (gnus-soup-pack-packet): Pack only if necesary. -1997-12-22 Simon Josefsson +1998-09-26 Shenghuo ZHU - * nnmail.el (nnmail-get-new-mail): Make nnmail-tmp-directory + * mm-util.el (mm-with-unibyte-buffer): Make it work in XEmacs + 20.4. -1997-12-28 Per Abrahamsen +1998-09-29 Lars Magne Ingebrigtsen - * gnus/gnus-group.el (gnus-group-fetch-faq): Convert `.' in group - name to `/'. + * gnus-art.el (gnus-mime-view-all-parts): New command and + keystroke. -1998-01-04 Lars Magne Ingebrigtsen + * mm-decode.el (mm-display-external): Translate slashes. - * nndraft.el (nndraft-request-associate-buffer): Open the damn - server first. Sheesh. + * nnmail.el (nnmail-find-file): Restrict auto-mode-alist. - * gnus-draft.el (gnus-draft-send): Bind message-send-hook to nil. + * nndraft.el (nndraft-retrieve-headers): Don't copy so much. - * gnus-sum.el (gnus-summary-catchup): Don't nix out downloadable. - (gnus-summary-highlight): Highlight down/un as unread. + * mm-decode.el (mm-quote-arg): Quote spaces. + (mm-display-external): Quote args. -1998-01-04 Kim-Minh Kaplan +1998-09-25 Lars Magne Ingebrigtsen - * gnus-start.el (gnus-strip-killed-list): Fix syntax. + * mm-decode.el (mm-inlinable-part-p): New function. -1998-01-04 Lars Magne Ingebrigtsen +1998-09-26 Simon Josefsson - * nnsoup.el (nnsoup-store-reply): Bind mail-header-separator to - "". + * mm-util.el (mm-disable-multibyte): New function. - * gnus-xmas.el (gnus-xmas-agent-server-menu-add): New. +1998-09-24 Lars Magne Ingebrigtsen - * nnoo.el (nnoo-change-server): Get the right values. + * gnus.el: Pterodactyl Gnus v0.33 is released. -1998-01-04 Aki Vehtari +1998-09-24 Lars Magne Ingebrigtsen - * gnus-art.el (gnus-signature-limit): Add default values for - choices suggested by Per Abrahamsen . - (gnus-prompt-before-saving): Add :value t for sexp tag. - (gnus-split-methods): Add default values for choices. + * gnus-art.el (gnus-insert-mime-button): Get buffer size. - * gnus-score.el (gnus-home-score-file): Add non-nil default for - function. - (gnus-home-adapt-file): Ditto. + * mm-decode.el (mm-display-external): Don't switch for externals. + (mm-dissect-multipart): Don't include end-sep. - * gnus-sum.el (gnus-move-split-methods): Add default values for - choices. + * mm-util.el (mm-get-coding-system-list): New function. + (mm-coding-system-list): New variable. - * nnmail.el (nnmail-list-identifiers): Add default values for - choices suggested by Per Abrahamsen . +1998-09-24 ZHU Shenghuo -1998-01-04 Lars Magne Ingebrigtsen + * gnus-cus.el (gnus-group-parameters): Add charset as a parameter - * gnus.el: Quassia Gnus v0.19 is released. +1998-09-24 ZHU Shenghuo -1998-01-04 Felix Lee + * gnus-cus.el (gnus-group-customize): Use variable as cons not as + group - * nntp.el (nntp-open-rlogin): Use a list of parameters. +1998-09-24 ZHU Shenghuo -1998-01-04 Lars Magne Ingebrigtsen + * mm-decode.el (mm-interactively-view-part): Typo. - * gnus-agent.el (gnus-agent-fetch-groups): New command. +1998-09-24 ZHU Shenghuo - * gnus-sum.el (gnus-summary-print-article): Changed order of - parameters. + * mm-decode.el (mm-dissect-multipart): Display last part when the + article has no close-delimiter -1998-01-04 Michael R. Cook +1998-09-24 ZHU Shenghuo - * gnus-sum.el (gnus-summary-print-article): Use process/prefix. + * mm-decode.el (mm-dissect-buffer): Display parts which have no + content-type. -1998-01-04 Lars Magne Ingebrigtsen +1998-09-24 ZHU Shenghuo - * gnus-uu.el: Changed spurious defconsts to defvars. + * gnus-art.el (gnus-display-mime): Typo. - * nnmail.el (nnmail-get-spool-files): Quote group name. +1998-09-24 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agent-fetch-group-1): Fetch ticked articles. - (gnus-agent-fetch-group-1): Never mind. + * gnus.el: Pterodactyl Gnus v0.32 is released. -1997-12-20 Pete Ware +1998-09-24 Lars Magne Ingebrigtsen - * message.el (message-rename-buffer): Check for nil dirs. + * gnus-kill.el (gnus-batch-score): Protect against errors. -1997-12-19 Lars Magne Ingebrigtsen + * gnus-art.el: Protect against broken headers. - * nnml.el (nnml-request-create-group): Check for files. + * mm-decode.el (mm-display-external): Respect needsterm. + (mm-display-external): Create buffer for external commands. -1997-12-19 Hrvoje Niksic +1998-09-24 Lars Magne Ingebrigtsen - * message.el (message-mode): Fixed font-lock. + * mailcap.el (mailcap-mime-info): Return the proper viewer. -1997-12-19 Lars Magne Ingebrigtsen + * mm-decode.el (mm-display-external): Use file name. - * gnus-cache.el (gnus-cache-read-active): Check for empty files. +1998-09-22 Markus Rost -1997-12-14 Lars Magne Ingebrigtsen + * gnus-util.el (gnus-output-to-rmail): adjust to + `rmail-output-to-rmail-file' - * gnus-uu.el (gnus-uu-save-article): Quote all lines beginning - with a dash. +1998-09-23 Lars Magne Ingebrigtsen -1997-12-10 SL Baur + * gnus-util.el (gnus-output-to-rmail): Reinstated function. - * gnus-start.el (gnus-read-descriptions-file): Really bind and gag - Mule. + * gnus-sum.el (gnus-select-newsgroup): Set global variables before + headers. -1997-12-05 Danny Siu + * gnus-art.el (article-decode-charset): Fold case. - * nndoc.el (nndoc-babyl-body-begin): quote the regexp for the - string "*** EOOH ***" properly. - (nndoc-babyl-head-begin): Same as above. +1998-09-17 Simon Josefsson -1997-12-14 Lars Magne Ingebrigtsen + * mailcap.el (mailcap-save-binary-file): Goto point-min. - * gnus-uu.el (gnus-uu-pre-uudecode-hook): New hook. +1998-09-23 Aaron M. Ucko - * gnus-sum.el (gnus-summary-read-group-1): Set mode line after - configuring. + * nnmail.el (nnmail-check-duplication): Enter into duplicate list + after being stored. -1997-12-14 Wes Hardaker +1998-09-15 Kurt Swanson - * gnus-score.el (gnus-adaptive-word-minimum): New variable. - (gnus-score-adaptive): Use it. + * gnus-salt.el (gnus-pick-setup-message): Return from whence ye + come. -1997-12-14 Roland B. Roberts +1998-09-23 Lars Magne Ingebrigtsen - * gnus-group.el: Fixed hardcoded levels. + * gnus-ems.el (gnus-widget-button-keymap): New variable. -1997-12-06 Lars Magne Ingebrigtsen +1998-09-20 ZHU Shenghuo - * gnus.el: Quassia Gnus v0.18 is released. + * gnus-art.el (gnus-mime-inline-part): remove part if necessary -1997-12-06 Kim-Minh Kaplan +1998-09-23 Matt Armstrong - * gnus-picon.el (gnus-picons-remove): Race condition. + * gnus-art.el (article-decode-charset): Narrow to the correct + region. -1997-12-06 Christian von Roques + * mm-bodies.el: Fix autoload. - * gnus-start.el (gnus-read-descriptions-file): Fix - enable-multibyte-characters. +1998-09-22 Lee Willis -1997-12-05 Dave Love + * gnus-art.el (gnus-mime-button-line-format): Doc fix. - * gnus-nocem.el (gnus-nocem-message-wanted-p): Fix paren typpo. - (gnus-nocem-issuers): Allow sexp alternative in :type for alists. +1998-09-22 Lars Magne Ingebrigtsen -1997-12-05 Dave Love + * rfc2047.el (rfc2047-decode): Use rfc2047-default-charset. - * gnus-art.el (gnus-visible-headers): Add X-sent:. +1998-09-19 Lars Magne Ingebrigtsen -1997-12-06 Lars Balker Rasmussen + * gnus-art.el (gnus-insert-mime-button): Specify keymap. + (gnus-article-add-button): Ditto. - * gnus-art.el (article-make-date-line): Don't add extra newlines. + * gnus-sum.el (gnus-summary-insert-pseudos): Use mm. -1997-11-27 MORIOKA Tomohiko + * gnus-art.el (gnus-article-prepare-display): Make article mode. + (gnus-article-prepare-display): Bind url-standalone-mode. - * nnmail.el (nnmail-file-coding-system): Use `raw-text' in - default. + * mm-decode.el (mm-remove-part): Also delete directory. + (mm-display-external): Create a private sub-dir. - * nnheader.el (nnheader-file-coding-system): Use `raw-text' in - default. + * mailcap.el (mailcap-binary-suffixes): New variable. + (mailcap-command-p): Use it. -1997-12-06 Kim-Minh Kaplan +1998-09-16 Lars Magne Ingebrigtsen - * nnml.el (nnml-parse-head): Out-of-bounds fix. + * nnmbox.el (nnmbox-request-group): Change server. + (nnmbox-possibly-change-newsgroup): Enable multibyte. - * nndraft.el (nndraft-request-associate-buffer): Get proper file - name. + * message.el (message-encode-message-body): Don't stomp MIME + headers. -1997-12-06 Gary D. Foster + * gnus-sum.el (gnus-summary-edit-article-done): Don't encode + unless useful. + (gnus-summary-exit): Check for a live article buffer. + (gnus-summary-exit-no-update): Ditto. - * gnus-group.el: Added backspace. + * gnus-int.el (gnus-request-replace-article): Accept no-encode + param. -1997-11-27 Lars Magne Ingebrigtsen + * gnus-sum.el (gnus-article-decoded-p): New variable. - * gnus-agent.el (gnus-summary-set-agent-mark): Remove marks - properly. + * mm-decode.el (mm-display-external): Use no-conv. -1997-11-27 Christoph Wedler + * rfc2047.el (rfc2047-q-encode-region): Bound properly. + (rfc2047-charset-encoding-alist): Use B encoding for koi8-r. - * smiley.el (smiley-buffer): Provide `help-echo'. + * gnus-art.el (gnus-article-mode-map): Bind button2 to + mouse-click. -1997-11-27 Lars Magne Ingebrigtsen +1998-09-15 Lars Magne Ingebrigtsen - * gnus-util.el (gnus-output-to-rmail): Always save buffer. + * gnus-agent.el (gnus-agent-expire): Protect against nil infos. - * nntp.el (nntp-close-server): Don't sleep for me, Argentina. - (nntp-request-close): You neither. +1998-09-14 Lars Magne Ingebrigtsen -1997-11-19 Per Abrahamsen + * gnus.el: Pterodactyl Gnus v0.31 is released. - * message.el (message-header-lines): New widget. - (message-default-headers): Use it. - (message-default-mail-headers): Use it. - (message-default-news-headers): Use it. +1998-09-14 Lars Magne Ingebrigtsen -1997-11-24 Andreas Jaeger + * gnus-sum.el (gnus-summary-exit): Destroy MIME. - * gnus-start.el (gnus-read-descriptions-file): Add missing quote. + * mm-decode.el (mm-display-part): Accept no-default. -1997-11-26 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-insert-mime-button): buffer-size doesn't take + a parameter. - * nnweb.el (nnweb-type-definition): Rescued dejanewsold. + * gnus-sum.el (gnus-summary-insert-line): Don't exclude faces. + (gnus-summary-prepare-threads): Ditto. - * gnus-mh.el (gnus-summary-save-in-folder): Reverted to old - version. + * gnus.el (gnus-article-mode-map): Make sparse keymap. - * gnus-sum.el (gnus-kill-or-deaden-summary): Save excursion. + * gnus-art.el (gnus-mime-button-line-format-alist): Allow a %d spec. + (gnus-mime-button-line-format): Doc fix. + (gnus-insert-mime-button): Use it. + (gnus-article-add-button): Use widget-convert-button. - * gnus.el: Only require gnus-load in Emacsen 19. + * gnus.el ((featurep 'gnus-xmas)): Defalias gnus-decode-rfc1522 to + ignore. - * gnus-start.el (gnus-setup-news): Always push archive server. + * mm-decode.el (mm-alternative-precedence): Ditto. - * gnus-sum.el (gnus-read-header): Would bug out on sparse - articles. +1998-09-14 Conrad Sauerwald -1997-11-26 Kurt Swanson + * mm-decode.el (mm-user-automatic-display): Use enriched. - * gnus-ems.el (gnus-mule-cite-add-face): Work. +1998-09-14 Paul Fisher -1997-11-26 Lars Magne Ingebrigtsen + * mm-decode.el (mm-dissect-multipart): Have the part start on the + right place. - * gnus.el: Quassia Gnus v0.17 is released. +1998-09-14 Lars Magne Ingebrigtsen -1997-11-26 Lars Magne Ingebrigtsen + * gnus-msg.el (gnus-inews-add-send-actions): Mark silently. - * gnus-sum.el (gnus-summary-move-article): Don't work on canceled - articles. + * gnus-art.el (article-update-date-lapsed): Only update header if + buffer is dispalyed in frame. + (gnus-article-prepare-display): New function. + (gnus-article-prepare): Use it. - * gnus-start.el (gnus-subscribe-hierarchical-interactive): Use - `read-char-exclusive'. +1998-09-14 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-mode): Localize - gnus-summary-dummy-line-format. + * gnus-art.el (gnus-mime-inline-part): New command and keystroke. - * nnml.el (nnml-open-nov): Check that the file exists before - inserting it. + * mm-view.el (mm-insert-inline): New function. - * gnus-art.el (article-date-ut): Insert a newline if needed. + * mm-decode.el (mm-pipe-part): Bugged. - * gnus-score.el (gnus-score-edit-current-scores): Protect against - nil score files. + * gnus-agent.el (gnus-agent-send-mail): Don't encode. - * gnus-start.el (gnus-newsrc-parse-options): Be more correct -- - match only hierarchies. - (gnus-gnus-to-quick-newsrc-format): Changed warning. + * mm-bodies.el (mm-encode-body): Move over the body. -1997-11-26 Greg Klanderman + * nnmbox.el (nnmbox-read-mbox): Enable multibyte. - * messagexmas.el (message-xmas-maybe-fontify): New definition. + * rfc2047.el (rfc2047-q-encode-region): Would bug out. -1997-11-26 Lars Magne Ingebrigtsen +1998-09-13 Francois Pinard - * gnus-start.el (gnus-setup-news): Protect against nil - gnus-message-archive-method. + * nndoc.el: Make nndoc-dissection-alist simpler for MIME, adjust all + related functions. Handle message/rfc822 parts. Display subject on + multipart summary lines. Display name on sub-parts when available. -1997-11-26 Christoph Wedler +1998-09-14 Hallvard B. Furuseth - * gnus-art.el (gnus-article-edit-done): Update headers "Lines:", - "Content-Length:" and "X-Content-Length:" when present. + * mailcap.el (mailcap-command-p): New version. -1997-11-26 Lars Magne Ingebrigtsen +1998-09-13 Mike McEwan - * nnmail.el (nnmail-process-unix-mail-format): Pop to the right - buffer on error. - (nnmail-process-mmdf-mail-format): Ditto. + * gnus-agent.el (gnus-agent-expire): Stop expiry barfing on killed + groups. -1997-11-26 Joe Reiss +1998-09-13 Lars Magne Ingebrigtsen - * gnus-art.el (gnus-summary-save-in-rmail): Return the name of the - file. + * message.el (message-make-date): Remove weekday name. -1997-11-26 Alastair Burt + * mm-decode.el (mm-dissect-buffer): Protect against broken + headers. - * smiley.el: Balloon help, etc. + * mailcap.el (mailcap-command-in-path-p): New function. + (mailcap-command-p): Renamed. -1997-11-26 Lars Magne Ingebrigtsen +1998-09-13 Hallvard B. Furuseth - * gnus-util.el (gnus-kill-all-overlays): Remove check for XEmacs. + * rfc2047.el (eval): Autoload. -1997-09-30 Dave Love +1998-09-13 Lars Magne Ingebrigtsen - * message.el: Don't require rmail. + * gnus-sum.el (gnus-decode-encoded-word-functions): New variable. + (gnus-multi-decode-encoded-word-string): New function. + (gnus-encoded-word-method-alist): New variable. + (gnus-decode-encoded-word-functions): Removed. -1997-11-26 Kurt Swanson +1998-09-13 Shenghuo ZHU - * gnus-group.el (gnus-group-setup-buffer): set-buffer. + * gnus-int.el (gnus-request-replace-article): Replace + message-narrow-to-headers with message-narrow-to-head -1997-11-26 Lars Magne Ingebrigtsen +1998-09-13 Lars Magne Ingebrigtsen - * gnus-score.el (gnus-score-load-file): Don't create empty score - files when doing decays. + * drums.el (drums-quote-string): Reversed match. -1997-11-26 Renaud Rioboo + * message.el (message-make-date): Use weekday name. - * nnmail.el (nnmail-move-inbox): Only bind default-directory when - calling external function. +1998-09-11 Lars Magne Ingebrigtsen -1997-11-26 IWAMURO Motonori + * gnus.el: Pterodactyl Gnus v0.30 is released. - * gnus-kill.el (gnus-batch-score): Newsrc thinko. +1998-09-13 Lars Magne Ingebrigtsen -1997-11-26 Lars Magne Ingebrigtsen + * gnus-art.el (article-decode-encoded-words): Use it. + (gnus-decode-header-function): New variable. - * nnheader.el (nnheader-parse-head): Would break on Message-ID's - that spanned several lines. + * gnus-sum.el (gnus-nov-parse-line): Use it. + (gnus-decode-encoded-word-function): New variable. - * gnus-util.el (gnus-date-iso8601): Didn't pick out the date - header. + * gnus-msg.el (gnus-copy-article-buffer): Decode the right + buffer. - * gnus-demon.el (gnus-demon-scan-mail): Clean inboxes. + * gnus-art.el (gnus-insert-mime-button): Use widget. + (gnus-widget-press-button): New function. + (gnus-article-prev-button): Removed. + (gnus-article-next-button): Ditto. + (gnus-article-add-button): Ditto. -1997-11-25 Christoph Wedler + * gnus.el (gnus-article-mode-map): Inherit from widget. + (gnus-article-mode-map): No, don't. - * gnus-picon.el (gnus-picons-x-face-sentinel): Would bug out in - headers with two X-Face lines. + * mm-decode.el (mm-dissect-buffer): Store Content-ID things. + (mm-content-id-alist): New variable. + (mm-get-content-id): New function. -1997-11-26 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-request-article-this-buffer): Only decode + articles if we are fetching to the article buffer. - * gnus-sum.el (gnus-summary-update-info): Would use wrong group - name. +1998-09-13 Shenghuo ZHU -1997-11-26 Hrvoje Niksic + * gnus-sum.el (gnus-summary-move-article): Don't decode accepting + articles. - * gnus-spec.el (gnus-compile): Avoid multiple `c*addr's. - (gnus-compile): Require `bytecomp'. +1998-09-13 Lars Magne Ingebrigtsen -1997-11-25 Hrvoje Niksic + * mm-util.el (mm-mime-charset): Try to use safe-charsets. + (mm-default-mime-charset): New variable. - * gnus-util.el (gnus-prin1): Bind `print-readably' to t. + * rfc2047.el (rfc2047-dissect-region): Dissect using tspecials. - * gnus-xmas.el (gnus-xmas-kill-all-overlays): New function. - (gnus-xmas-define): Use it. + * drums.el (drums-quote-string): Reversed test. - * gnus-art.el (gnus-stop-date-timer): Use `nnheader-cancel-timer'. +1998-09-12 Lars Magne Ingebrigtsen - * message.el (message-header-lines): Specify format. + * mm-util.el (mm-insert-rfc822-headers): Possibly not quote + string. - * gnus-xmas.el (gnus-xmas-move-overlay): Use BUFFER. - (gnus-byte-code): Use `indirect-function'. + * drums.el (drums-quote-string): New function. - * gnus-cite.el (gnus-cite-add-face): Would assign free variable. + * rfc2047.el (rfc2047-encode-message-header): Goto point-min. + (rfc2047-b-encode-region): Chop lines. + (rfc2047-q-encode-region): Ditto. -1997-11-26 Lars Magne Ingebrigtsen +1998-09-12 Lars Magne Ingebrigtsen - * gnus-art.el (gnus-stop-date-timer): Cancel instead of delete. - (gnus-start-date-timer): Use the numerical prefix. + * gnus.el: Pterodactyl Gnus v0.29 is released. -1997-11-25 Lars Magne Ingebrigtsen +1998-09-12 Istvan Marko - * gnus-draft.el (gnus-group-send-drafts): Activate group first. + * mm-decode.el (mm-save-part): Message right. -1997-11-25 Dan Christensen +1998-09-12 Lars Magne Ingebrigtsen - * gnus-group.el (gnus-group-process-prefix): Skip topics. + * drums.el (drums-parse-address): Returned a list instead of a + string. + (drums-remove-whitespace): Skip comments. + (drums-parse-addresses): Didn't work. -1997-11-25 Lars Magne Ingebrigtsen +1998-09-12 Lars Magne Ingebrigtsen - * gnus-move.el (gnus-move-group-to-server): Protect agains - nil-ness. + * gnus.el: Pterodactyl Gnus v0.28 is released. -1997-11-25 Lars Magne Ingebrigtsen +1998-09-12 Lars Magne Ingebrigtsen - * gnus.el: Quassia Gnus v0.16 is released. + * gnus-art.el (gnus-mime-button-map): Use the article keymap as a + starting point. + (article-decode-encoded-words): Rename. -1997-11-25 Lars Magne Ingebrigtsen + * message.el (message-narrow-to-headers-or-head): New function. - * gnus-sum.el (gnus-read-header): Remove thread entry before - rebuilding. + * gnus-int.el (gnus-request-accept-article): Narrow to the right + region. - * gnus-cite.el (gnus-cite-add-face): Keep track of all overlays. + * message.el (message-send-news): Encode body after checking + syntax. - * gnus-art.el (article-update-date-lapsed): New function. - (gnus-start-date-timer): New command. - (article-date-ut): Put the face in the right place. - (article-date-ut): Would move around. + * gnus-art.el (gnus-mime-button-line-format): Allow descriptions. - * gnus-group.el (gnus-group-read-ephemeral-group): Accept server - names. + * mm-decode.el (mm-save-part): Use Content-Disposition filename. - * gnus-srvr.el (gnus-browse-foreign-server): Use proper server - names. + * gnus-art.el (gnus-display-mime): Respect disposition. - * gnus.el (gnus-group-prefixed-name): Give the right result for - native groups. + * mm-decode.el (mm-preferred-alternative): Respect disposition. - * nnheader.el (nnheader-directory-files): New function. + * gnus-art.el (article-strip-multiple-blank-lines): Don't delete + text with annotations. - * nnmh.el (nnmh-request-list-1): Reversed check. + * message.el (message-make-date): Fix sign for negative time + zones. - * nnfolder.el (nnfolder-delete-mail): Would skip backwards one - line too much. + * mm-view.el (mm-inline-image): Insert a space at the end of the + image. -1997-11-25 SeokChan LEE + * mail-parse.el: New file. - * message.el (message-ignored-supersedes-headers): Typo. + * rfc2231.el: New file. -1997-11-24 Lars Magne Ingebrigtsen + * drums.el (drums-content-type-get): Removed. + (drums-parse-content-type): Ditto. - * gnus.el: Quassia Gnus v0.15 is released. + * mailcap.el (mailcap-mime-data): Use symbols instead of strings. -1997-11-24 Lars Magne Ingebrigtsen +1998-09-11 Lars Magne Ingebrigtsen - * gnus-ems.el: Also check major version names. + * gnus.el: Pterodactyl Gnus v0.27 is released. -1997-10-05 SL Baur +1998-09-11 Lars Magne Ingebrigtsen- - * message.el (require 'rmail): Put guard around. - * nnbabyl.el (require 'rmail): Ditto. + * mm-decode.el (mm-alternative-precedence): New variable. + (mm-preferred-alternative): New function. -1997-11-24 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-mime-copy-part): New command. - * message.el (message-reply): Respect Mail-Copies-To even when - `to-address'. + * mm-decode.el (mm-get-part): New function. -1997-11-24 Thor Kristoffersen + * mm-view.el: New file. - * nntp.el (nntp-request-close): Sleep one second. + * mm-decode.el (mm-dissect-buffer): Downcase cte. + (mm-display-part): Default to mailcap-save-binary-file. -1997-11-24 Lars Magne Ingebrigtsen +1998-09-11 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-read-group-1): Update marks when not - entering group. + * gnus.el: Pterodactyl Gnus v0.26 is released. - * gnus-start.el (gnus-setup-news): Get correct value of archive - server. +1998-09-11 Lars Magne Ingebrigtsen -1997-10-08 Robert Bihlmeyer + * mm-decode.el (mm-interactively-view-part): New function. - * message.el (message-make-organization): Don't let the - environment variable override a user-set organization. + * gnus-art.el (gnus-mime-view-part): New command. -1997-11-24 Lars Magne Ingebrigtsen + * mm-decode.el (mm-last-shell-command): New variable. - * nnml.el (nnml-open-nov): Don't use find-file. + * mailcap.el (mailcap-mime-info): Allow returning all matches. - * gnus-sum.el (gnus-last-newsgroup-variables-set): New variable. - (gnus-set-global-variables): Don't do to much; gets run off of - pre-command-hook. - Got rid of gnus-set-global-variables throughout. - (gnus-summary-exit): Update adaptive scoring here. - (gnus-summary-isearch-article): Widen. + * mm-decode.el (mm-save-part): New function. - * nnml.el (nnml-parse-head): Work in empty buffers. + * gnus-art.el (article-decode-charset): Protect against buggy + content-types. + (gnus-mime-pipe-part): New command. + (gnus-mime-save-part): New command. + (gnus-mime-button-map): New keymap. + (gnus-mime-button-line-format): New variable. + (gnus-insert-mime-button): New function. + (gnus-display-mime): Use it. -1997-10-14 Hrvoje Niksic + * gnus-util.el (gnus-dd-mmm): Removed length spec. - * gnus-xmas.el (gnus-xmas-group-startup-message): Check for image - formats correctly. - (gnus-xmas-modeline-glyph): Ditto. + * mm-decode.el (mm-inline-text): Decode charsets. -1997-11-24 Hrvoje Niksic + * gnus-art.el (gnus-article-save): Comment fix. - * gnus-spec.el (gnus-compile): Work under XEmacs. + * gnus-int.el (gnus-start-news-server): When in batch, don't + prompt. -1997-11-24 Lars Magne Ingebrigtsen + * gnus-cache.el (gnus-cache-possibly-enter-article): Don't + decode. - * nnoo.el (nnoo-change-server): Push the right parent packend onto - the alist. + * mm-decode.el (mm-inline-media-tests): Add audio. + (mm-inline-audio): New function. -1997-11-23 Lars Magne Ingebrigtsen +1998-09-11 Katsumi Yamaoka - * gnus.el: Quassia Gnus v0.14 is released. + * gnus-art.el (article-make-date-line): Didn't work. -1997-11-23 Lars Magne Ingebrigtsen + * parse-time.el (parse-time-string): One too many nils. - * gnus-start.el (gnus-read-descriptions-file): Make sure Mule is - bound. And gagged. +1998-09-11 Lars Magne Ingebrigtsen - * message.el (message-send-mail-with-mh): Use - `mh-new-draft-name'. + * gnus.el: Pterodactyl Gnus v0.25 is released. - * nnfolder.el (nnfolder-read-folder): Save new buffers. +1998-09-11 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-make-menu-bar): Removed "write to - file". + * gnus-art.el (article-remove-trailing-blank-lines): Don't remove + annotations. - * gnus-util.el (gnus-byte-code): Use indirect-function. + * gnus.el ((featurep 'gnus-xmas)): New + 'gnus-annotation-in-region-p alias. - * nntp.el (nntp-open-telnet): Also accept 201. +1998-09-10 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-reparent-thread): Update thread. + * mm-util.el (mm-with-unibyte-buffer): New function. - * gnus-score.el (gnus-all-score-files): Don't do anything unless - GROUP. + * gnus-uu.el (gnus-quote-arg-for-sh-or-csh): Renamed. - * nnmail.el (nnmail-split-it): Save-excursion. - (nnmail-group-pathname): Translate file chars. + * mm-decode.el (mm-inline-media-tests): New variable. -1997-11-23 Gunnar Horrigmo + * gnus-sum.el (gnus-summary-exit): Destroy handles. - * gnus-sum.el (gnus-summary-exit): Don't skip if group - disappeared. + * gnus-art.el (gnus-article-mime-handles): New variable. -1997-11-23 Lars Magne Ingebrigtsen + * drums.el (drums-narrow-to-header): New function. - * nnfolder.el (nnfolder-normalize-buffer): New function. - (nnfolder-save-mail): Use it. - (nnfolder-request-replace-article): Ditto. + * gnus-art.el (article-decode-charset): Use it. -1997-11-19 Per Abrahamsen + * drums.el (drums-content-type-get): New function. - * message.el (message-header-lines): New widget. - (message-default-headers): Use it. - (message-default-mail-headers): Use it. - (message-default-news-headers): Use it. + * mm-util.el (mm-content-type-charset): Removed. -1997-11-23 Lars Magne Ingebrigtsen + * drums.el (drums-syntax-table): @ is word. + (drums-parse-content-type): New function. - * gnus-win.el (gnus-remove-some-windows): Also delete dead summary - windows. + * parse-time.el (parse-time-rules): Parse "Wed, 29 Apr 98 0:26:01 + EDT" times. - * gnus-score.el (gnus-score-adaptive): Check whether functions are - bound. + * gnus-util.el (gnus-date-get-time): Use safe date. -1997-11-23 Hallvard B. Furuseth + * gnus-sum.el (gnus-show-mime): Removed. + (gnus-summary-toggle-mime): Removed. - * gnus-sum.el (gnus-summary-limit-include-thread): Interactive - fix. + * gnus-art.el (gnus-strict-mime): Removed. + (gnus-article-prepare): Don't do MIME. + (gnus-decode-encoded-word-method): Removed. + (gnus-show-mime-method): Removed. -1997-11-23 Lars Magne Ingebrigtsen +1998-09-10 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-reparent-thread): Insert Message-ID in - proper place. + * gnus.el: Pterodactyl Gnus v0.24 is released. -1997-11-22 Lars Magne Ingebrigtsen +1998-09-10 Lars Magne Ingebrigtsen - * gnus-cus.el (gnus-group-parameters): Add visible. + * gnus-sum.el (gnus-summary-show-article): Don't decode chars if + PREFIX. -1997-11-22 Kim-Minh Kaplan + * parse-time.el (parse-time-rules): Accept times that look like + "h:mm". - * message.el (message-setup): Add a newline, if necessary. + * message.el (message-make-date): Use zone properly. -1997-11-22 Lars Magne Ingebrigtsen + * gnus.el: Autoload gnus-batch. - * gnus-mh.el (gnus-summary-save-in-folder): Fix for default. + * gnus-art.el (article-de-quoted-unreadable): Do not do + gnus-article-decode-rfc1522. -1997-11-22 Didier Verna + * gnus-msg.el (gnus-inews-do-gcc): Use it. - * gnus-sum.el (gnus-summary-remove-bookmark): Interactive spec. + * gnus-int.el (gnus-request-accept-article): Accept a no-encode + param. -1997-11-17 Lars Magne Ingebrigtsen + * message.el (message-encode-message-body): Check for us-ascii. - * gnus-art.el (article-display-x-face): Fold case. + * gnus-msg.el (gnus-extended-version): Move Gnus version comments + to the left. -1997-11-13 Kenichi Handa +1998-09-09 Lars Magne Ingebrigtsen - * gnus/gnus-start.el (gnus-read-descriptions-file): Decode - description if necessary. + * gnus-art.el (article-decode-charset): Rename. - * gnus/nntp.el (nntp-coding-system-for-read): Set default value to - binary. - (nntp-coding-system-for-write): Likewise. +1998-09-09 Lars Magne Ingebrigtsen -1997-11-13 seokchan lee + * gnus.el: Pterodactyl Gnus v0.23 is released. - * message.el (message-ignored-supersedes-headers): Ignore more - headers. +1998-09-09 Lars Magne Ingebrigtsen -1997-11-13 Lars Magne Ingebrigtsen + * gnus-util.el (gnus-parent-id): Ditto. + (gnus-put-text-property-excluding-newlines): Ditto. - * message.el (message-separator-face): Lightened up. - (message-header-other-face): Ditto. + * gnus-sum.el (gnus-dependencies-add-header): Make into subst. -1997-11-13 jari aalto +1998-09-08 Karl Kleinpaste - * nnmail.el (nnmail-process-mmdf-mail-format): Pop to buffer. + * message.el (message-generate-headers): Generate User-Agent + instead of X-Mailer & X-Newsreader. -1997-11-13 Lars Magne Ingebrigtsen + * gnus-msg.el (gnus-extended-version): Reformat for USEFOR + User-Agent header format. - * gnus-start.el (gnus-start-draft-setup): Always create group. +1998-09-09 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agent-fetch-headers): Translate file chars. + * gnus.el: Pterodactyl Gnus v0.22 is released. -1997-11-06 Lars Magne Ingebrigtsen +1998-09-09 Lars Magne Ingebrigtsen - * gnus.el: Quassia Gnus v0.13 is released. + * mm-util.el (mm-multibyte-p): Typo. -1997-11-06 Lars Magne Ingebrigtsen +1998-09-09 Lars Magne Ingebrigtsen - * nnlistserv.el: New backend. + * gnus.el: Pterodactyl Gnus v0.21 is released. -1997-11-06 Stefan Waldherr +1998-09-08 Hrvoje Niksic - * nnweb.el (nnweb-dejanewsold-search): New function. + * gnus-art.el (article-treat-dumbquotes): Handle \224 correctly. -1997-11-06 Lars Magne Ingebrigtsen +1998-09-09 Lars Magne Ingebrigtsen - * gnus-topic.el (gnus-topic-change-level): Really delete multiple - instances. + * mm-util.el (mm-multibyte-p): New function. -1997-11-05 Lars Magne Ingebrigtsen +1998-09-08 Lars Magne Ingebrigtsen - * gnus-topic.el (gnus-topic-update-topic-line): Possibly fix nil - numbers. + * gnus.el: Pterodactyl Gnus v0.20 is released. - * gnus-sum.el (gnus-summary-show-article): New command and - keystroke. +1998-09-08 Lars Magne Ingebrigtsen -1997-11-04 Lars Magne Ingebrigtsen + * rfc2047.el (rfc2047-decode-region): Only decode when in + multibyte. - * gnus-score.el (gnus-score-adaptive): Use the home score file. + * nnheader.el (nnheader-pathname-coding-system): Changed to binary. -1997-10-25 Lars Magne Ingebrigtsen + * gnus-int.el (gnus-request-replace-article): Encode. + (gnus-request-accept-article): Encode. - * gnus-art.el (gnus-article-save): Hide headers in the right - buffer. + * gnus-art.el (gnus-request-article-this-buffer): Decode charsets + here. - * gnus-picon.el (gnus-picons-xbm-face): New face. + * gnus.el (gnus-article-display-hook): Take the charset functions + out. -1997-10-25 Lars Balker Rasmussen + * time-date.el (safe-date-to-time): New function. - * gnus-art.el (gnus-article-fill-paragraph): New command and - keystroke. + * gnus-util.el (gnus-dd-mmm): Protect against bogus dates. -1997-10-16 Colin Rafferty +1998-09-08 Lars Magne Ingebrigtsen - * message.el (message-make-fqdn): Made certain that user-mail is - not nil. + * gnus.el: Pterodactyl Gnus v0.19 is released. -1997-10-25 David S. Goldberg +1998-09-08 Lars Magne Ingebrigtsen - * gnus-art.el (article-hide-boring-headers): Use many-to. + * mm-util.el (mm-mime-charset): New function. -1997-10-24 Lars Magne Ingebrigtsen + * gnus-draft.el (gnus-draft-edit-message): Delete article. - * gnus-picon.el (gnus-picons-display-pairs): Don't add two bars. - (gnus-picons-try-face): Set the foreground color on the bar. - (gnus-picons-group-exluded-groups): New variable. - (gnus-group-display-picons): Use it. +1998-09-08 Lars Magne Ingebrigtsen -1997-10-13 Lars Magne Ingebrigtsen + * gnus.el: Pterodactyl Gnus v0.18 is released. - * gnus-agent.el (gnus-agent-group-path): Translate file chars. - (gnus-agent-batch-fetch): New command. - (gnus-agent-fetch-group): Message. +1998-09-08 Lars Magne Ingebrigtsen -1997-10-12 ISO-2022-JP + * message.el (message-send-and-exit): Return t on success. + (message-make-date): Make a proper time zone. - * gnus-agent.el (gnus-agent-article-file-coding-system): New - variable. + * gnus-draft.el (gnus-draft-send): Only remove article if the + sending is successful. -1997-10-12 Lars Magne Ingebrigtsen + * drums.el (drums-get-comment): Return the last comment. + (drums-parse-address): Parse old-style From headers. - * dgnushack.el (lpath): Reversed. +1998-09-07 SL Baur - * gnus-msg.el (gnus-summary-cancel-article): Use sym prefix. + * gnus-sum.el (gnus-data-compute-positions): Move below + `gnus-save-hidden-threads' so the former is correctly detected as + a macro. - * gnus-art.el (article-translate-characters): New function. - (article-treat-dumbquotes): New command and keystroke. +1998-09-06 Dave Love -1997-10-05 Lars Magne Ingebrigtsen + * gnus/nnweb.el (require): Wrap requirement of w3 and url in + ignore-errors too, eval'd when compile. Require w3 stuff at load + time for nicer failure if it's not available. - * gnus-art.el (gnus-button-alist): No ' and " in News:. +1998-09-08 Lars Magne Ingebrigtsen - * gnus-msg.el (gnus-inews-insert-archive-gcc): Comp warn. + * time-date.el (time-to-seconds): Renamed. -1997-10-04 Lars Magne Ingebrigtsen + * parse-time.el (parse-time-string): Downcase before handling. + (parse-time-rules): Times without seconds have 0 seconds. - * gnus.el: Quassia Gnus v0.12 is released. + * rfc2047.el (rfc2047-encode-region): New version. + (rfc2047-dissect-region): New function. -1997-10-04 Lars Magne Ingebrigtsen +1998-09-07 Lars Magne Ingebrigtsen - * gnus.el (gnus-plugged): Moved here. + * message.el (message-make-date): Use symbolic zone. - * nnmail.el (nnmail-delete-incoming): Changed default to nil. +1998-09-07 Lars Magne Ingebrigtsen - * gnus-int.el (gnus-request-scan): Don't do anything if - unplugged. + * time-date.el (parse-time): Always use parse-time. -1997-10-03 Lars Magne Ingebrigtsen + * parse-time.el (parse-time-syntax): Use vectors. - * gnus-art.el (gnus-ignored-headers): Doc fix. +1998-09-06 Lars Magne Ingebrigtsen - * gnus-demon.el (gnus-demon-add-nntp-close-connection): New - function. - (gnus-demon-nntp-close-connection): Ditto. + * gnus.el: Pterodactyl Gnus v0.17 is released. - * nntp.el (nntp-last-command-time): New variable. - (nntp-retrieve-data): Use it. +1998-09-06 Lars Magne Ingebrigtsen - * message.el (message-news-p): Messages with Posted-To aren't - news. - (message-mode): Heed message-yank-prefix when filling. + * time-date.el: Renamed from "date". - * nndraft.el (nndraft-request-restore-buffer): Remove Xrefs and - Lines headers. + * gnus.el: Removed all timezone dependencies. - * nntp.el (nntp-encode-text): Encode according to RFC977. + * score-mode.el: Removed. + (gnus-score-edit-insert-date): Use date. -1997-10-01 Lars Magne Ingebrigtsen + * date.el (float-to-time): New function. - * gnus-msg.el (gnus-inews-insert-archive-gcc): gcc-self didn't - work if `gnus-message-archive-method' was nil. + * nnspool.el (nnspool-seconds-since-epoch): Removed. - * nnmail.el (nnmail-article-group): Allow \\1 substitution. + * date.el (time-to-float): New function. -1997-09-27 Lars Magne Ingebrigtsen + * message.el (message-make-date): Use format-time-string. + (message-make-expires): Use make-date. - * gnus-salt.el (gnus-pick-mouse-pick-region): Use it. + * gnus-util.el (gnus-dd-mmm): Use date. + (gnus-sortable-date): Ditto. - * gnus-xmas.el (gnus-xmas-window-edges): New function. + * message.el (message-make-date): Take an optional time. - * gnus-score.el (gnus-score-edit-current-scores): Don't select - window. + * gnus: Applied patches from 5.6.43. -1997-09-27 Hallvard B. Furuseth + * date.el (if): Use parse-time. - * messcompat.el ((boundp 'mail-mode-hook)): Check. + * gnus-score.el (gnus-summary-score-entry): Make into a command + again. -1997-09-27 Lars Magne Ingebrigtsen + * gnus-group.el (gnus-group-get-new-news-this-group): Only call if + gnus-agent. - * nndraft.el (nndraft-possibly-change-group): Always open server. + * gnus.el (gnus-agent-meta-information-header): Moved here. - * gnus-sum.el (gnus-summary-pop-article): Force. +1998-09-05 Mike McEwan - * gnus-art.el (gnus-article-prepare): Push the article onto the - history. + * gnus-agent.el (gnus-agent-scoreable-headers): New variable. + (gnus-agent-fetch-group-1): Score article headers using normal + group score files if the download score rule of a category/group + is `file'. + (gnus-agent-fetch-group-1): Don't parse the entire .overview when + deciding what articles to download. + (gnus-agent-fetch-group-1): Don't push headers through scoring and + predicate processing if predicate is `true' or `false'. - * gnus-sum.el (gnus-summary-pop-article): Pop to the right - article. +1998-09-06 Lars Magne Ingebrigtsen - * gnus-demon.el (gnus-demon-scan-news): Save excursion. + * gnus-score.el (gnus-score-load-score-alist): Bind coding system. -1997-09-27 Hallvard B. Furuseth + * gnus-art.el (gnus-article-setup-buffer): Enable multibyte. - * gnus-cache.el (gnus-summary-limit-include-cached): New command - and keystroke. + * score-mode.el (score-mode-coding-system): New variable. + (gnus-score-edit-exit): Use it. -1997-09-27 Lars Magne Ingebrigtsen +1998-09-04 Jason R Mastaler - * gnus-uu.el (gnus-uu-invert-processable): Make interactive. + * drums.el: Corrected typo. -1997-09-27 Kim-Minh Kaplan +1998-09-06 Hallvard B. Furuseth - * gnus-picon.el: Doc fixes. + * mm-bodies.el (mm-body-encoding): Faster version. -1997-09-23 Hrvoje Niksic +1998-09-06 Lars Magne Ingebrigtsen - * gnus.el: Removed definition of `custom-face-lookup'. + * gnus-art.el (gnus-article-decode-charset): Only decode text + things. -1997-09-27 Lars Magne Ingebrigtsen + * message.el (message-output): Use rmail. - * nndraft.el: Would block nnmh. + * rfc2047.el (rfc2047-encoded-word-regexp): Allow spaces in the + word part. - * gnus-sum.el (gnus-mark-article-as-unread): Don't allow marking - negative articles. + * mm-util.el (mm-charset-to-coding-system): Use + rfc2047-default-charset. + (mm-known-charsets): New variable. - * gnus-group.el (gnus-fetch-group): Use `gnus-no-server'. + * message.el (message-caesar-region): Bugged out. - * gnus-agent.el (gnus-agent-with-fetch): Moved. +1998-09-06 Mike McEwan - * gnus-sum.el (gnus-nov-read-integer): Really skip to next field. + * gnus-agent.el (gnus-agent-fetch-group-1): Allow lists when + specifying `agent-predicate' in a group's parameters. -1997-09-27 Lars Magne Ingebrigtsen +1998-09-05 Lars Magne Ingebrigtsen - * gnus.el: Quassia Gnus v0.11 is released. + * gnus.el: Pterodactyl Gnus v0.16 is released. -1997-09-27 Lars Magne Ingebrigtsen +1998-09-05 Lars Magne Ingebrigtsen - * message.el (message-send): Post without asking. - (message-mode): Modify paragraphs-start and paragraph-separate. - (message-newline-and-reformat): New command and keystroke. + * nnmail.el (nnmail-expired-article-p): Use predicate. -1997-09-25 Lars Magne Ingebrigtsen + * date.el (time-less-p): Renamed. - * nnmail.el (nnmail-activate): Init server buffer. + * gnus-art.el (gnus-article-decode-charset): Really fetch headers + from the headers. -1997-09-24 Lars Magne Ingebrigtsen + * rfc2047.el (rfc2047-decode-region): Use the mm decoding + functions. - * gnus-draft.el (gnus-draft-setup): Inexplicable binding problem - worked around. + * gnus-group.el (gnus-group-sort-selected-flat): Didn't work at + all. + (gnus-group-sort-selected-groups-by-alphabet): Changed interface + to all functions. - * nnsoup.el (nnsoup-always-save): Renamed. +1998-09-05 Lars Magne Ingebrigtsen -1997-09-24 Nelson Jose dos Santos Ferreira + * gnus.el: Pterodactyl Gnus v0.15 is released. - * nnsoup.el (nnsoup-commit-reply-now): New variable. - (nnsoup-store-reply): Use it. +1998-09-05 Lars Magne Ingebrigtsen -1997-09-24 Lars Magne Ingebrigtsen + * date.el: New file. - * gnus-ems.el (gnus-deactivate-mark): New alias. + * gnus-util.el (gnus-encode-date): Removed. + (gnus-time-less): Ditto. -1997-09-23 Lars Magne Ingebrigtsen + * nnmail.el (nnmail-date-to-time): Removed. + (nnmail-time-less): Ditto. + (nnmail-days-to-time): Ditto. + (nnmail-time-since): Ditto. - * gnus.el: Win-away! + * drums.el: New file. - * gnus-msg.el (gnus-setup-message): Don't trust make-symbol. +1998-09-04 Lars Magne Ingebrigtsen -1997-09-23 Lars Magne Ingebrigtsen + * message.el (message-encode-message-body): Encode headers with + body encoding. - * gnus.el: Quassia Gnus v0.10 is released. + * rfc2047.el (rfc2047-default-charset): Renamed. + (rfc2047-encodable-p): Use it. -1997-09-23 Lars Magne Ingebrigtsen +1998-09-03 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-read-all-headers): New function. - (gnus-select-newsgroup): Use it. - (gnus-summary-refer-thread): Ditto. - (gnus-refer-thread-limit): New variable. - (gnus-summary-refer-thread): Use it. + * gnus-msg.el (gnus-post-method): Peel off real info from opened + servers. - * gnus-nocem.el (gnus-nocem-message-wanted-p): New function. - (gnus-nocem-check-article): Use it. - (gnus-nocem-issuers): Dox ofx. + * gnus-util.el (gnus-output-to-rmail): Removed. - * dgnushack.el (dgnushack-compile): Check for cus-edit. + * gnus-art.el (gnus-summary-save-in-rmail): Use + gnus-output-to-rmailrmail-output-to-rmail-file. - * message.el (message-included-forward-headers): Include Mime - headers. - (message-send): Allow posting without confirming from Agent. + * rfc2047.el (rfc2047-decode-region): Fold case. + (rfc2047-decode): Use decode-string. -1997-09-22 Lars Magne Ingebrigtsen + * mm-util.el: Provide mm-char-int. - * dgnushack.el (byte-compile-warnings): Don't warn about obsolete - variables. +1998-09-03 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-refer-thread): New command and - keystroke. - (gnus-summary-limit-include-thread): New command and keystroke. - (gnus-summary-articles-in-thread): New function. - (gnus-articles-in-thread): Renamed. + * gnus.el: Pterodactyl Gnus v0.14 is released. -1997-09-21 Lars Magne Ingebrigtsen +1998-09-03 Lars Magne Ingebrigtsen - * gnus.el: Quassia Gnus v0.9 is released. + * mm-bodies.el (mm-body-encoding): Go through the buffer to make + sure we have 7bit. -1997-09-21 Lars Magne Ingebrigtsen +1998-09-02 Lars Magne Ingebrigtsen - * gnus.el (gnus-splash-face): ForestGreen everywhere. + * gnus-msg.el (gnus-post-method): Use opened servers, and remove + ducplicates. + (gnus-inews-insert-mime-headers): Removed. - * gnus-sum.el (gnus-simplify-subject-fully): Use new variable. - (gnus-general-simplify-subject): Ditto. + * message.el (message-caesar-region): Protect against MULE chars. -1997-09-21 Kurt Swanson +1998-09-02 Hallvard B. Furuseth - * gnus-sum.el (gnus-simplify-subject-functions): New variable. - (gnus-simplify-whitespace): New function. + * mm-util.el (if): fset the right function. - * gnus-util.el (gnus-map-function): New function. +1998-09-02 Lars Magne Ingebrigtsen -1997-09-21 Michelangelo Grigni + * gnus-art.el (gnus-article-decode-charset): Use real + read-coding-system. - * gnus-score.el (gnus-score-regexp-bad-p): New function. +1998-09-01 Lars Magne Ingebrigtsen -1997-09-21 Lars Magne Ingebrigtsen + * mm-bodies.el (mm-decode-body): Protect against malformed + base64. + (mm-decode-body): Check that buffer-file-coding-system is + non-nil. - * gnus-score.el (gnus-summary-lower-score): Use sym pref. - (gnus-summary-increase-score): Use it. +1998-09-01 Lars Magne Ingebrigtsen - * gnus.el (gnus-current-prefix-symbol): New variable. - (gnus-current-prefix-symbols): New variable. + * gnus.el: Pterodactyl Gnus v0.13 is released. - * gnus-score.el (gnus-summary-increase-score): Take symbolic - prefix. +1998-09-01 Lars Magne Ingebrigtsen - * gnus.el (gnus-interactive): Removed. - (gnus-interactive): Renamed from gnus-interactive-1. - (gnus-symbolic-argument): New command. + * gnus-util.el (gnus-strip-whitespace): Already defined. + Removed. - * gnus-draft.el (gnus-draft-send-message): Disable message - checks. - (gnus-draft-send): Ditto. - (gnus-draft-setup): Don't save buffer. + * gnus-art.el (gnus-article-decode-charset): Strip whitespace. - * dgnushack.el (dgnushack-compile): Warn people about Custom. + * gnus-util.el (gnus-strip-whitespace): New function. - * gnus-group.el (gnus-group-iterate): Use gensymmed variables. + * mm-util.el (mm-content-type-charset): Downcase. - * pop3.el (pop3-md5): `with-temp-buffer' doesn't exist in Emacs - 19.34. +1998-09-01 Lars Magne Ingebrigtsen - * nneething.el (nneething-directory): Defvarred. + * gnus-art.el (gnus-article-decode-charset): Accept a prefix. + (gnus-article-decode-charset): Don't fetch all headers. - * message.el: Autoloaded nndraft things. - (message-set-auto-save-file-name): Use it. + * mm-util.el (mm-read-coding-system): New function. - * dgnushack.el (dgnushack-compile): Warn about things. + * mm-bodies.el (mm-decode-body): Check the right charset. - * gnus-art.el: Autoload w3-region. + * gnus-sum.el (gnus-summary-mode-line-format): Ditto. - * gnus-vm.el (gnus-summary-save-in-vm): Simplified. + * gnus-art.el (gnus-article-mode-line-format): Use short group + format. - * gnus.el: Changed `compiled-function-p' to `byte-code-function-p' - throughout. +1998-09-01 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-edit-article): Supply additional - param. + * gnus.el: Pterodactyl Gnus v0.12 is released. - * gnus-group.el (gnus-group-iterate): Undo bogus change. +1998-09-01 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agentize): Just call gnus-open-agent - directly. + * mm-bodies.el (mm-decode-body): Don't do charset unless MULE. - * gnus.el (gnus-interactive): New macro. - (gnus-interactive-1): New function. + * gnus-art.el (gnus-article-decode-charset): Supply cte. + (gnus-article-decode-charset): Always run. - * gnus-sum.el (gnus-fetch-old-headers): Allow `invisible'. - (gnus-cut-thread): Use it. - (gnus-cut-threads): Ditto. - (gnus-summary-initial-limit): Ditto. - (gnus-summary-limit-children): Ditto. + * mm-bodies.el (mm-decode-body): Decode cte. - * gnus-art.el (gnus-article-edit-done): Accept a prefix arg. - (gnus-boring-article-headers): Allow `long-to' param. - (article-hide-boring-headers): Use it. +1998-09-01 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-edit-article-done): Accept a - no-highlight param. + * gnus.el: Pterodactyl Gnus v0.11 is released. - * nntp.el (nntp-rlogin-program): New variable. - (nntp-open-rlogin): Use it. +1998-08-31 Lars Magne Ingebrigtsen + + * message.el (message-encode-message-body): Ditto. - * nnvirtual.el (nnvirtual-request-post): New function. + * gnus-art.el (gnus-article-decode-mime-words): New command and + keystroke. + (gnus-article-decode-charset): Ditto. + (gnus-article-decode-charset): Only work under MULE. - * gnus-msg.el (gnus-message-group-art): New variable. + * mm-util.el (mm-content-type-charset): New function. - * gnus-draft.el (gnus-draft-setup): Don't use message-setup. + * nnmail.el (nnmail-delete-incoming): Changed to nil. - * nndraft.el (nndraft): Allow editing articles. + * message.el (message-send-mail): Insert MIME headers. + (message-check-news-body-syntax): Don't warn for escape sequences. + (message-check-news-body-syntax): Insert MIME headers. - * gnus-ems.el (gnus-x-splash): Ditto. + * mm-bodies.el (mm-body-encoding): New function. - * gnus.el (gnus-splash-face): Darker face. + * message.el (message-encode-message-body): New function. - * gnus-draft.el (gnus-draft-setup): Clobbered variables. + * mm-bodies.el: New file. -1997-09-20 Lars Magne Ingebrigtsen + * mm-util.el (mm-narrow-to-head): New function. - * gnus.el: Quassia Gnus v0.8 is released. + * rfc2047.el (rfc2047-encode): Use it. -1997-09-20 Lars Magne Ingebrigtsen + * mm-util.el: Provide mm-encode-coding-region. - * gnus-start.el (gnus-setup-news-hook): New hook. + * gnus-sum.el (gnus-summary-mode): Enable multibyte. - * gnus-agent.el (gnus-agentize): Really set up queue group. - (gnus-open-agent): Setup queue here. + * gnus-util.el (gnus-set-work-buffer): Enable multibyte. -1997-09-20 Matt Simmons + * mm-util.el (mm-enable-multibyte): New function. - * message.el (message-set-auto-save-file-name): Make things work - without drafts. + * message.el (message-set-work-buffer): Set multibyte. -1997-09-20 Lars Magne Ingebrigtsen + * gnus.el (gnus-continuum-version): Be valid forever and ever. - * nnmh.el (nnmh-request-list-1): Check for links to ".". + * gnus-util.el (gnus-point-at-eol): Removed. + (gnus-point-at-bol): Ditto. - * nndraft.el (nndraft-possibly-change-group): New function. +1998-08-31 Didier Verna - * gnus-agent.el (gnus-agent-queue-setup): New function. + * gnus-msg.el (gnus-group-mail): make it behave like + gnus-group-post-news with regards to the prefix (this enables the + use of posting styles). -1997-09-18 Lars Magne Ingebrigtsen +1998-08-31 Lars Magne Ingebrigtsen - * gnus.el: Quassia Gnus v0.7 is released. + * gnus.el (gnus-article-display-hook): Added + gnus-article-decode-rfc1522 to hook. -1997-09-18 Lars Magne Ingebrigtsen +1998-08-31 Lars Magne Ingebrigtsen - * gnus-msg.el (gnus-setup-message): Slap a progn around forms. + * gnus.el: Pterodactyl Gnus v0.10 is released. - * nndraft.el (nndraft-articles): Make sure directory exists. +1998-08-31 Lars Magne Ingebrigtsen - * message.el (message-mode): Don't delete article. + * nnfolder.el (nnfolder-delete-mail): Narrow to mail and allow + hook to be run. - * nnmh.el (nnmh-request-accept-article): Don't save when - noinsert. +1998-08-30 Lars Magne Ingebrigtsen -1997-09-17 Lars Magne Ingebrigtsen + * rfc2047.el (rfc2047-encodable-p): Use find-charset-region. - * nndraft.el (nndraft-directory): Changed defaults. + * mm-util.el (mm-charsets-in-region): Removed. - * gnus-agent.el (gnus-agent-fetch-session): Bind command method. + * rfc2047.el: Renamed file. -1997-09-17 Lars Magne Ingebrigtsen + * gnus-msg.el (gnus-copy-article-buffer): Multibyte. - * gnus.el: Quassia Gnus v0.6 is released. + * message.el (message-mode): Set multibyte. -1997-08-17 SL Baur + * mm-util.el (mm-charsets-in-region): Copied here. - * dgnushack.el (dgnushack-compile): Ignore .el files beginning - with an `=' character. + * gnus-util.el: Removed gnus-truncate-string. -1997-09-17 Lars Magne Ingebrigtsen + * gnus-art.el (gnus-article-decode-mime-words): Use 1522. - * gnus-sum.el (gnus-build-sparse-threads): Allow display of looped - References. + * rfc1522.el (rfc1522-unencoded-charsets): New variable. + (rfc1522-encodable-p): New function. + (rfc1522-encode-message-header): Use it. - * gnus-agent.el (gnus-agent-fetch-group-1): Separated out into - function. +1998-08-30 Lars Magne Ingebrigtsen - * message.el (message-delete-not-region): New command and - keystroke. + * gnus.el: Pterodactyl Gnus v0.9 is released. -1997-09-16 Lars Magne Ingebrigtsen +1998-08-30 Lars Magne Ingebrigtsen - * nndraft.el (nndraft-directory): Changed value. + * mm-util.el: Shadow encode-coding-string. - * message.el (message-kill-buffer): Disassociate draft. - (message-mode): Use kill hook to disassociate. - (message-disassociate-draft): Double-check. + * rfc1522.el (rfc1522-narrow-to-field): Copied here. - * gnus-agent.el (gnus-agentize): Don't set twice. + * mm-util.el: New file. - * gnus-art.el (gnus-article-prepare): Go to the right line before - marking. + * mm-decode.el: Somewhat depleted. + * mm-encode.el: Ditto. - * gnus-start.el: Renamed the drafts group. + * rfc1522.el: New file. - * gnus-agent.el (gnus-agent-lib-file): Changed name of directory. + * mm-util.el (mm-replace-chars-in-string): Copied here. - * gnus-draft.el (gnus-draft-mode): Simplify. + * mm-encode.el (mm-q-encode-region): New function. -1997-09-16 Lars Magne Ingebrigtsen + * qp.el (quoted-printable-encode-region): Take an optional CLASS + param. - * gnus.el: Quassia Gnus v0.5 is released. + * mm-encode.el (mm-encode-word-region): Downcase. -1997-09-15 Lars Magne Ingebrigtsen +1998-08-30 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-alter-header-function): New variable. - (gnus-nov-parse-line): Use it. - (gnus-get-newsgroup-headers): Ditto. + * gnus.el: Pterodactyl Gnus v0.8 is released. - * gnus-draft.el (gnus-group-send-drafts): Don't send when - unplugged. +1998-08-30 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-read-group): Don't show-all when - skipping groups. + * message.el (message-send-mail): Encode headers. - * gnus-start.el (gnus-start-draft-setup): Changed name. + * qp.el (quoted-printable-encode-region): Encode 8-bit words. + (quoted-printable-encode-region): Upcase. -1997-09-15 Lars Magne Ingebrigtsen + * message.el (message-default-charset): New variable. - * gnus.el: Quassia Gnus v0.4 is released. + * qp.el (quoted-printable-encode-region): Optional param FOLD. -1997-09-15 Lars Magne Ingebrigtsen + * message.el (message-narrow-to-field): Changed name. - * gnus-sum.el (gnus-summary-goto-article): Accept Message-ID's. + * mm-encode.el: New file. -1997-09-14 Lars Magne Ingebrigtsen + * message.el (message-narrow-to-header): New function. - * gnus-sum.el (gnus-group-make-articles-read): No params. + * gnus-art.el (gnus-article-decode-mime-words): Place point in the + right buffer. - * nndraft.el (nndraft-status-string): Fix. +1998-08-30 Lars Magne Ingebrigtsen - * gnus-draft.el (gnus-group-send-drafts): New command. + * gnus.el: Pterodactyl Gnus v0.7 is released. - * gnus-sum.el (gnus-compute-read-articles): Separated. - (gnus-update-read-articles): Allow computation. +1998-08-30 Lars Magne Ingebrigtsen - * nndraft.el (nndraft-articles): New function. + * gnus.el: Remove autoload for + gnus-article-mime-decode-quoted-printable. - * message.el (message-send): Disabled test. + * mm-decode.el (mm-charset-to-coding-system): Allow iso-8859-1 to + be decoded in non-MULE Emacsen. -1997-09-14 Lars Magne Ingebrigtsen +1998-08-30 Lars Magne Ingebrigtsen - * gnus.el: Quassia Gnus v0.3 is released. + * mm-decode.el: Check for coding-system-list. -1997-09-14 Lars Magne Ingebrigtsen +1998-08-30 Lars Magne Ingebrigtsen - * gnus-agent.el (gnus-agent-short-article): New variables. + * gnus.el: Pterodactyl Gnus v0.6 is released. - * message.el (message-set-auto-save-file-name): Use drafts. +1998-08-30 Lars Magne Ingebrigtsen - * nndraft.el (nndraft-request-expire-articles): Use it. + * nnheader.el (fboundp): Protect code-coding-string. - * nnmh.el (nnmh-deletable-article-p): Change. - (nnmh-allow-delete-final): New variable. + * gnus-art.el (gnus-article-mode): Check that set-buffer-multibyte + is available. - * gnus-msg.el (gnus-summary-send-draft): Removed. +1998-08-30 Lars Magne Ingebrigtsen - * gnus.el (gnus-article-mark-lists): Save unsendable marks. + * gnus.el: Pterodactyl Gnus v0.5 is released. - * gnus-sum.el (gnus-newsgroup-unsendable): New variable. +1998-08-30 Lars Magne Ingebrigtsen - * gnus-draft.el: New file. + * gnus-art.el (gnus-article-mode): Make article buffer multibyte. + (gnus-hack-decode-rfc1522): Removed. - * gnus-sum.el (gnus-unsendable-mark): New variable. + * mm-decode.el (mm-charset-coding-system-alist): Check better. - * nndraft.el (nndraft-execute-nnmh-command): Cleanup. +1998-08-30 Lars Magne Ingebrigtsen - * message.el (message-send-news): Use `gnus-request-post'. + * gnus.el: Gnus v0.4 is released. - * gnus-agent.el (gnus-agentize): New command. +1998-08-29 Lars Magne Ingebrigtsen - * gnus-bcklg.el (gnus-backlog-remove-article): Remove the ident - from the list. + * gnus-art.el (gnus-article-decode-mime-words): New command and + keystroke. -1997-09-14 Lars Magne Ingebrigtsen + * qp.el (quoted-printable-decode-region): Don't use hexl. - * gnus.el: Quassia Gnus v0.2 is released. + * gnus-sum.el (gnus-parse-headers-hook): Default to nil. + (gnus-structured-field-decoder): Removed. + (gnus-unstructured-field-decoder): Ditto. -1997-09-14 Lars Magne Ingebrigtsen + * mm-decode.el: New file. - * gnus-score.el (gnus-score-headers): Make sure the summary buffer - exists. + * qp.el: New file. -1997-09-13 Greg Stark + * gnus-art.el (article-mime-decode-quoted-printable): Removed. - * gnus-ems.el (gnus-x-splash): New function. + * gnus-ems.el (fboundp): Removed gnus-split-string. -1997-09-13 Lars Magne Ingebrigtsen + * gnus.el (gnus-splash-face): Doc fix. - * gnus-start.el (gnus-1): Use it. + * gnus-ems.el (fboundp): Don't bind mail-file-babyl-p. - * gnus-ems.el (gnus-decode-coding-string): New alias. + * gnus-art.el (article-mime-decode-quoted-printable): Don't use + hexl. - * message.el (message-unix-mail-delimiter): Dox fox. + * nnheader.el (nnheader-temp-write): Removed. - * nnmh.el (nnmh-request-list-1): Don't use coding system. +1998-08-29 Lars Magne Ingebrigtsen - * gnus-sum.el (gnus-summary-catchup): Reverse logic. + * gnus.el: Gnus v0.3 is released. -1997-09-13 Lars Magne Ingebrigtsen +1998-08-29 Lars Magne Ingebrigtsen - * gnus.el: Quassia Gnus v0.1 is released. + * gnus.el: Gnus v0.2 is released. ;; Local Variables: -;; coding: iso-2022-7bit-unix +;; coding: iso-2022-7bit ;; End: diff --git a/lisp/gnus/binhex.el b/lisp/gnus/binhex.el new file mode 100644 index 00000000000..200d571a4b0 --- /dev/null +++ b/lisp/gnus/binhex.el @@ -0,0 +1,306 @@ +;;; binhex.el -- elisp native binhex decode +;; Copyright (c) 1998 Free Software Foundation, Inc. + +;; Author: Shenghuo Zhu +;; Create Date: Oct 1, 1998 +;; Keywords: binhex news + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(eval-when-compile (require 'cl)) + +(if (not (fboundp 'char-int)) + (fset 'char-int 'identity)) + +(defvar binhex-decoder-program "hexbin" + "*Non-nil value should be a string that names a uu decoder. +The program should expect to read binhex data on its standard +input and write the converted data to its standard output.") + +(defvar binhex-decoder-switches '("-d") + "*List of command line flags passed to the command named by binhex-decoder-program.") + +(defconst binhex-alphabet-decoding-alist + '(( ?\! . 0) ( ?\" . 1) ( ?\# . 2) ( ?\$ . 3) ( ?\% . 4) ( ?\& . 5) + ( ?\' . 6) ( ?\( . 7) ( ?\) . 8) ( ?\* . 9) ( ?\+ . 10) ( ?\, . 11) + ( ?\- . 12) ( ?0 . 13) ( ?1 . 14) ( ?2 . 15) ( ?3 . 16) ( ?4 . 17) + ( ?5 . 18) ( ?6 . 19) ( ?8 . 20) ( ?9 . 21) ( ?@ . 22) ( ?A . 23) + ( ?B . 24) ( ?C . 25) ( ?D . 26) ( ?E . 27) ( ?F . 28) ( ?G . 29) + ( ?H . 30) ( ?I . 31) ( ?J . 32) ( ?K . 33) ( ?L . 34) ( ?M . 35) + ( ?N . 36) ( ?P . 37) ( ?Q . 38) ( ?R . 39) ( ?S . 40) ( ?T . 41) + ( ?U . 42) ( ?V . 43) ( ?X . 44) ( ?Y . 45) ( ?Z . 46) ( ?\[ . 47) + ( ?\` . 48) ( ?a . 49) ( ?b . 50) ( ?c . 51) ( ?d . 52) ( ?e . 53) + ( ?f . 54) ( ?h . 55) ( ?i . 56) ( ?j . 57) ( ?k . 58) ( ?l . 59) + ( ?m . 60) ( ?p . 61) ( ?q . 62) ( ?r . 63))) + +(defun binhex-char-map (char) + (cdr (assq char binhex-alphabet-decoding-alist))) + +;;;###autoload +(defconst binhex-begin-line + "^:...............................................................$") +(defconst binhex-body-line + "^[^:]...............................................................$") +(defconst binhex-end-line ":$") + +(defvar binhex-temporary-file-directory + (cond ((fboundp 'temp-directory) (temp-directory)) + ((boundp 'temporary-file-directory) temporary-file-directory) + ("/tmp/"))) + +(if (string-match "XEmacs" emacs-version) + (defalias 'binhex-insert-char 'insert-char) + (defun binhex-insert-char (char &optional count ignored buffer) + (if (or (null buffer) (eq buffer (current-buffer))) + (insert-char char count) + (with-current-buffer buffer + (insert-char char count))))) + +(defvar binhex-crc-table + [0 4129 8258 12387 16516 20645 24774 28903 + 33032 37161 41290 45419 49548 53677 57806 61935 + 4657 528 12915 8786 21173 17044 29431 25302 + 37689 33560 45947 41818 54205 50076 62463 58334 + 9314 13379 1056 5121 25830 29895 17572 21637 + 42346 46411 34088 38153 58862 62927 50604 54669 + 13907 9842 5649 1584 30423 26358 22165 18100 + 46939 42874 38681 34616 63455 59390 55197 51132 + 18628 22757 26758 30887 2112 6241 10242 14371 + 51660 55789 59790 63919 35144 39273 43274 47403 + 23285 19156 31415 27286 6769 2640 14899 10770 + 56317 52188 64447 60318 39801 35672 47931 43802 + 27814 31879 19684 23749 11298 15363 3168 7233 + 60846 64911 52716 56781 44330 48395 36200 40265 + 32407 28342 24277 20212 15891 11826 7761 3696 + 65439 61374 57309 53244 48923 44858 40793 36728 + 37256 33193 45514 41451 53516 49453 61774 57711 + 4224 161 12482 8419 20484 16421 28742 24679 + 33721 37784 41979 46042 49981 54044 58239 62302 + 689 4752 8947 13010 16949 21012 25207 29270 + 46570 42443 38312 34185 62830 58703 54572 50445 + 13538 9411 5280 1153 29798 25671 21540 17413 + 42971 47098 34713 38840 59231 63358 50973 55100 + 9939 14066 1681 5808 26199 30326 17941 22068 + 55628 51565 63758 59695 39368 35305 47498 43435 + 22596 18533 30726 26663 6336 2273 14466 10403 + 52093 56156 60223 64286 35833 39896 43963 48026 + 19061 23124 27191 31254 2801 6864 10931 14994 + 64814 60687 56684 52557 48554 44427 40424 36297 + 31782 27655 23652 19525 15522 11395 7392 3265 + 61215 65342 53085 57212 44955 49082 36825 40952 + 28183 32310 20053 24180 11923 16050 3793 7920]) + +(defun binhex-update-crc (crc char &optional count) + (if (null count) (setq count 1)) + (while (> count 0) + (setq crc (logxor (logand (lsh crc 8) 65280) + (aref binhex-crc-table + (logxor (logand (lsh crc -8) 255) + char))) + count (1- count))) + crc) + +(defun binhex-verify-crc (buffer start end) + (with-current-buffer buffer + (let ((pos start) (crc 0) (last (- end 2))) + (while (< pos last) + (setq crc (binhex-update-crc crc (char-after pos)) + pos (1+ pos))) + (if (= crc (binhex-string-big-endian (buffer-substring last end))) + nil + (error "CRC error"))))) + +(defun binhex-string-big-endian (string) + (let ((ret 0) (i 0) (len (length string))) + (while (< i len) + (setq ret (+ (lsh ret 8) (char-int (aref string i))) + i (1+ i))) + ret)) + +(defun binhex-string-little-endian (string) + (let ((ret 0) (i 0) (shift 0) (len (length string))) + (while (< i len) + (setq ret (+ ret (lsh (char-int (aref string i)) shift)) + i (1+ i) + shift (+ shift 8))) + ret)) + +(defun binhex-header (buffer) + (with-current-buffer buffer + (let ((pos (point-min)) len) + (vector + (prog1 + (setq len (char-int (char-after pos))) + (setq pos (1+ pos))) + (buffer-substring pos (setq pos (+ pos len))) + (prog1 + (setq len (char-int (char-after pos))) + (setq pos (1+ pos))) + (buffer-substring pos (setq pos (+ pos 4))) + (buffer-substring pos (setq pos (+ pos 4))) + (binhex-string-big-endian + (buffer-substring pos (setq pos (+ pos 2)))) + (binhex-string-big-endian + (buffer-substring pos (setq pos (+ pos 4)))) + (binhex-string-big-endian + (buffer-substring pos (setq pos (+ pos 4)))))))) + +(defvar binhex-last-char) +(defvar binhex-repeat) + +(defun binhex-push-char (char &optional count ignored buffer) + (cond + (binhex-repeat + (if (eq char 0) + (binhex-insert-char (setq binhex-last-char 144) 1 + ignored buffer) + (binhex-insert-char binhex-last-char (- char 1) + ignored buffer) + (setq binhex-last-char nil)) + (setq binhex-repeat nil)) + ((= char 144) + (setq binhex-repeat t)) + (t + (binhex-insert-char (setq binhex-last-char char) 1 ignored buffer)))) + +(defun binhex-decode-region (start end &optional header-only) + "Binhex decode region between START and END. +If HEADER-ONLY is non-nil only decode header and return filename." + (interactive "r") + (let ((work-buffer nil) + (counter 0) + (bits 0) (tmp t) + (lim 0) inputpos + (non-data-chars " \t\n\r:") + file-name-length data-fork-start + header + binhex-last-char binhex-repeat) + (unwind-protect + (save-excursion + (goto-char start) + (when (re-search-forward binhex-begin-line end t) + (if (and (not (string-match "XEmacs\\|Lucid" emacs-version)) + (boundp 'enable-multibyte-characters)) + (let ((multibyte + (default-value 'enable-multibyte-characters))) + (setq-default enable-multibyte-characters nil) + (setq work-buffer (generate-new-buffer " *binhex-work*")) + (setq-default enable-multibyte-characters multibyte)) + (setq work-buffer (generate-new-buffer " *binhex-work*"))) + (buffer-disable-undo work-buffer) + (beginning-of-line) + (setq bits 0 counter 0) + (while tmp + (skip-chars-forward non-data-chars end) + (setq inputpos (point)) + (end-of-line) + (setq lim (point)) + (while (and (< inputpos lim) + (setq tmp (binhex-char-map (char-after inputpos)))) + (setq bits (+ bits tmp) + counter (1+ counter) + inputpos (1+ inputpos)) + (cond ((= counter 4) + (binhex-push-char (lsh bits -16) 1 nil work-buffer) + (binhex-push-char (logand (lsh bits -8) 255) 1 nil + work-buffer) + (binhex-push-char (logand bits 255) 1 nil + work-buffer) + (setq bits 0 counter 0)) + (t (setq bits (lsh bits 6))))) + (if (null file-name-length) + (with-current-buffer work-buffer + (setq file-name-length (char-after (point-min)) + data-fork-start (+ (point-min) + file-name-length 22)))) + (if (and (null header) + (with-current-buffer work-buffer + (>= (buffer-size) data-fork-start))) + (progn + (binhex-verify-crc work-buffer + 1 data-fork-start) + (setq header (binhex-header work-buffer)) + (if header-only (setq tmp nil counter 0)))) + (setq tmp (and tmp (not (eq inputpos end))))) + (cond + ((= counter 3) + (binhex-push-char (logand (lsh bits -16) 255) 1 nil + work-buffer) + (binhex-push-char (logand (lsh bits -8) 255) 1 nil + work-buffer)) + ((= counter 2) + (binhex-push-char (logand (lsh bits -10) 255) 1 nil + work-buffer)))) + (if header-only nil + (binhex-verify-crc work-buffer + data-fork-start + (+ data-fork-start (aref header 6) 2)) + (or (markerp end) (setq end (set-marker (make-marker) end))) + (goto-char start) + (insert-buffer-substring work-buffer + data-fork-start (+ data-fork-start + (aref header 6))) + (delete-region (point) end))) + (and work-buffer (kill-buffer work-buffer))) + (if header (aref header 1)))) + +(defun binhex-decode-region-external (start end) + "Binhex decode region between START and END using external decoder." + (interactive "r") + (let ((cbuf (current-buffer)) firstline work-buffer status + (file-name (concat binhex-temporary-file-directory + (binhex-decode-region start end t) + ".data"))) + (save-excursion + (goto-char start) + (when (re-search-forward binhex-begin-line nil t) + (let ((cdir default-directory) default-process-coding-system) + (unwind-protect + (progn + (set-buffer (setq work-buffer + (generate-new-buffer " *binhex-work*"))) + (buffer-disable-undo work-buffer) + (insert-buffer-substring cbuf firstline end) + (cd binhex-temporary-file-directory) + (apply 'call-process-region + (point-min) + (point-max) + binhex-decoder-program + nil + nil + nil + binhex-decoder-switches)) + (cd cdir) (set-buffer cbuf))) + (if (and file-name (file-exists-p file-name)) + (progn + (goto-char start) + (delete-region start end) + (let (format-alist) + (insert-file-contents-literally file-name))) + (error "Can not binhex"))) + (and work-buffer (kill-buffer work-buffer)) + (ignore-errors + (if file-name (delete-file file-name)))))) + +(provide 'binhex) + +;;; binhex.el ends here diff --git a/lisp/gnus/flow-fill.el b/lisp/gnus/flow-fill.el new file mode 100644 index 00000000000..2a2db62c8b2 --- /dev/null +++ b/lisp/gnus/flow-fill.el @@ -0,0 +1,98 @@ +;;; flow-fill.el --- interprete RFC2646 "flowed" text + +;; Copyright (C) 2000 Free Software Foundation, Inc. + +;; Author: Simon Josefsson +;; Keywords: mail + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This implement decoding of RFC2646 formatted text, including the +;; quoted-depth wins rules. + +;; Theory of operation: search for lines ending with SPC, save quote +;; length of line, remove SPC and concatenate line with the following +;; line if quote length of following line matches current line. + +;; When no further concatenations are possible, we've found a +;; paragraph and we let `fill-region' fill the long line into several +;; lines with the quote prefix as `fill-prefix'. + +;; Todo: encoding + +;; History: + +;; 2000-02-17 posted on ding mailing list +;; 2000-02-19 use `point-at-{b,e}ol' in XEmacs +;; 2000-03-11 no compile warnings for point-at-bol stuff +;; 2000-03-26 commited to gnus cvs + +;;; Code: + +(eval-and-compile + (defalias 'fill-flowed-point-at-bol + (if (fboundp 'point-at-bol) + 'point-at-bol + 'line-beginning-position)) + + (defalias 'fill-flowed-point-at-eol + (if (fboundp 'point-at-eol) + 'point-at-eol + 'line-end-position))) + +(defun fill-flowed (&optional buffer) + (save-excursion + (set-buffer (or (current-buffer) buffer)) + (goto-char (point-min)) + (while (re-search-forward " $" nil t) + (when (save-excursion + (beginning-of-line) + (looking-at "^\\(>*\\)\\( ?\\)")) + (let ((quote (match-string 1))) + (if (string= quote "") + (setq quote nil)) + (when (and quote (string= (match-string 2) "")) + (save-excursion + ;; insert SP after quote for pleasant reading of quoted lines + (beginning-of-line) + (when (> (skip-chars-forward ">") 0) + (insert " ")))) + (while (and (save-excursion + (backward-char 3) + (looking-at "[^-][^-] ")) + (save-excursion + (unless (eobp) + (forward-char 1) + (if quote + (looking-at (format "^\\(%s\\)\\([^>]\\)" quote)) + (looking-at "^ ?"))))) + (save-excursion + (replace-match (if (string= (match-string 2) " ") + "" "\\2"))) + (backward-delete-char -1) + (end-of-line)) + (let ((fill-prefix (when quote (concat quote " ")))) + (fill-region (fill-flowed-point-at-bol) + (fill-flowed-point-at-eol) + 'left 'nosqueeze))))))) + +(provide 'flow-fill) + +;;; flow-fill.el ends here diff --git a/lisp/gnus/format-spec.el b/lisp/gnus/format-spec.el new file mode 100644 index 00000000000..6cd39ede721 --- /dev/null +++ b/lisp/gnus/format-spec.el @@ -0,0 +1,71 @@ +;;; format-spec.el --- functions for formatting arbitrary formatting strings +;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; Keywords: tools + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(eval-when-compile (require 'cl)) + +(defun format-spec (format specification) + "Return a string based on FORMAT and SPECIFICATION. +FORMAT is a string containing `format'-like specs like \"bash %u %k\", +while SPECIFICATION is an alist mapping from format spec characters +to values." + (with-temp-buffer + (insert format) + (goto-char (point-min)) + (while (search-forward "%" nil t) + (cond + ;; Quoted percent sign. + ((eq (char-after) ?%) + (delete-char 1)) + ;; Valid format spec. + ((looking-at "\\([-0-9.]*\\)\\([a-zA-Z]\\)") + (let* ((num (match-string 1)) + (spec (string-to-char (match-string 2))) + (val (cdr (assq spec specification)))) + (delete-region (1- (match-beginning 0)) (match-end 0)) + (unless val + (error "Invalid format character: %s" spec)) + (insert (format (concat "%" num "s") val)))) + ;; Signal an error on bogus format strings. + (t + (error "Invalid format string")))) + (buffer-string))) + +(defun format-spec-make (&rest pairs) + "Return an alist suitable for use in `format-spec' based on PAIRS. +PAIRS is a list where every other element is a character and a value, +starting with a character." + (let (alist) + (while pairs + (unless (cdr pairs) + (error "Invalid list of pairs")) + (push (cons (car pairs) (cadr pairs)) alist) + (setq pairs (cddr pairs))) + (nreverse alist))) + +(provide 'format-spec) + +;;; format-spec.el ends here diff --git a/lisp/gnus/gnus-load.el b/lisp/gnus/gnus-load.el deleted file mode 100644 index 978f272a331..00000000000 --- a/lisp/gnus/gnus-load.el +++ /dev/null @@ -1,103 +0,0 @@ -;;; gnus-load.el --- automatically extracted custom dependencies -;; -;;; Code: - -(put 'nnmail 'custom-loads '("nnmail")) -(put 'gnus-article-emphasis 'custom-loads '("gnus-art")) -(put 'gnus-article-headers 'custom-loads '("gnus-sum" "gnus-art")) -(put 'nnmail-procmail 'custom-loads '("nnmail")) -(put 'gnus-score-kill 'custom-loads '("gnus-kill")) -(put 'gnus-visual 'custom-loads '("smiley" "gnus" "gnus-picon" "gnus-art" "earcon")) -(put 'gnus-score-expire 'custom-loads '("gnus-score" "gnus-kill")) -(put 'gnus-summary-maneuvering 'custom-loads '("gnus-sum")) -(put 'gnus-start 'custom-loads '("gnus" "gnus-util" "gnus-start" "gnus-int" "gnus-group")) -(put 'gnus-extract-view 'custom-loads '("gnus-uu" "gnus-sum")) -(put 'gnus-various 'custom-loads '("gnus-sum")) -(put 'gnus-article-washing 'custom-loads '("gnus-art")) -(put 'gnus-score-files 'custom-loads '("gnus-score")) -(put 'message-news 'custom-loads '("message")) -(put 'gnus-thread 'custom-loads '("gnus-sum")) -(put 'languages 'custom-loads '("cus-edit")) -(put 'development 'custom-loads '("cus-edit")) -(put 'gnus-treading 'custom-loads '("gnus-sum")) -(put 'nnmail-various 'custom-loads '("nnmail")) -(put 'extensions 'custom-loads '("wid-edit")) -(put 'message-various 'custom-loads '("message")) -(put 'gnus-summary-exit 'custom-loads '("gnus-sum")) -(put 'news 'custom-loads '("message" "gnus")) -(put 'gnus 'custom-loads '("nnmail" "gnus" "gnus-win" "gnus-uu" "gnus-eform" "gnus-dup" "gnus-demon" "gnus-cache" "gnus-async" "gnus-art")) -(put 'gnus-summary-visual 'custom-loads '("gnus-sum")) -(put 'gnus-group-listing 'custom-loads '("gnus-group")) -(put 'gnus-score 'custom-loads '("gnus" "gnus-nocem")) -(put 'gnus-group-select 'custom-loads '("gnus-sum")) -(put 'message-buffers 'custom-loads '("message")) -(put 'gnus-threading 'custom-loads '("gnus-sum")) -(put 'gnus-score-decay 'custom-loads '("gnus-score")) -(put 'help 'custom-loads '("cus-edit")) -(put 'gnus-nocem 'custom-loads '("gnus-nocem")) -(put 'gnus-cite 'custom-loads '("gnus-cite")) -(put 'gnus-demon 'custom-loads '("gnus-demon")) -(put 'gnus-message 'custom-loads '("message")) -(put 'gnus-score-default 'custom-loads '("gnus-sum" "gnus-score")) -(put 'nnmail-duplicate 'custom-loads '("nnmail")) -(put 'message-interface 'custom-loads '("message")) -(put 'nnmail-files 'custom-loads '("nnmail")) -(put 'gnus-edit-form 'custom-loads '("gnus-eform")) -(put 'emacs 'custom-loads '("cus-edit")) -(put 'gnus-summary-mail 'custom-loads '("gnus-sum")) -(put 'gnus-topic 'custom-loads '("gnus-topic")) -(put 'wp 'custom-loads '("cus-edit")) -(put 'gnus-summary-choose 'custom-loads '("gnus-sum")) -(put 'widget-browse 'custom-loads '("wid-browse")) -(put 'external 'custom-loads '("cus-edit")) -(put 'message-headers 'custom-loads '("message")) -(put 'message-forwarding 'custom-loads '("message")) -(put 'message-faces 'custom-loads '("message")) -(put 'environment 'custom-loads '("cus-edit")) -(put 'gnus-article-mime 'custom-loads '("gnus-sum" "gnus-art")) -(put 'gnus-duplicate 'custom-loads '("gnus-dup")) -(put 'nnmail-retrieve 'custom-loads '("nnmail")) -(put 'widgets 'custom-loads '("wid-edit" "wid-browse")) -(put 'earcon 'custom-loads '("earcon")) -(put 'hypermedia 'custom-loads '("wid-edit")) -(put 'gnus-group-levels 'custom-loads '("gnus-group")) -(put 'gnus-summary-format 'custom-loads '("gnus-sum")) -(put 'gnus-files 'custom-loads '("nnmail" "gnus")) -(put 'gnus-windows 'custom-loads '("gnus-win")) -(put 'gnus-article-buttons 'custom-loads '("gnus-art")) -(put 'gnus-summary 'custom-loads '("gnus" "gnus-sum")) -(put 'gnus-article-hiding 'custom-loads '("gnus-sum" "gnus-art")) -(put 'gnus-group 'custom-loads '("gnus" "gnus-topic")) -(put 'gnus-article-various 'custom-loads '("gnus-sum" "gnus-art")) -(put 'gnus-summary-marks 'custom-loads '("gnus-sum")) -(put 'gnus-article-saving 'custom-loads '("gnus-art")) -(put 'nnmail-expire 'custom-loads '("nnmail")) -(put 'message-mail 'custom-loads '("message")) -(put 'faces 'custom-loads '("wid-edit" "cus-edit" "message" "gnus")) -(put 'gnus-summary-various 'custom-loads '("gnus-sum")) -(put 'applications 'custom-loads '("cus-edit")) -(put 'gnus-extract-archive 'custom-loads '("gnus-uu")) -(put 'message 'custom-loads '("message")) -(put 'message-sending 'custom-loads '("message")) -(put 'editing 'custom-loads '("cus-edit")) -(put 'gnus-score-adapt 'custom-loads '("gnus-score")) -(put 'message-insertion 'custom-loads '("message")) -(put 'gnus-extract-post 'custom-loads '("gnus-uu")) -(put 'mail 'custom-loads '("message" "gnus")) -(put 'gnus-summary-sort 'custom-loads '("gnus-sum")) -(put 'customize 'custom-loads '("wid-edit" "custom" "cus-face" "cus-edit")) -(put 'nnmail-split 'custom-loads '("nnmail")) -(put 'gnus-asynchronous 'custom-loads '("gnus-async")) -(put 'gnus-article-highlight 'custom-loads '("gnus-art")) -(put 'gnus-extract 'custom-loads '("gnus-uu")) -(put 'gnus-article 'custom-loads '("gnus-cite" "gnus-art")) -(put 'gnus-group-foreign 'custom-loads '("gnus-group")) -(put 'programming 'custom-loads '("cus-edit")) -(put 'nnmail-prepare 'custom-loads '("nnmail")) -(put 'picons 'custom-loads '("gnus-picon")) -(put 'gnus-article-signature 'custom-loads '("gnus-art")) -(put 'gnus-group-various 'custom-loads '("gnus-group")) - -(provide 'gnus-load) - -;;; gnus-load.el ends here diff --git a/lisp/gnus/gnus-ml.el b/lisp/gnus/gnus-ml.el new file mode 100644 index 00000000000..3e0f878dc97 --- /dev/null +++ b/lisp/gnus/gnus-ml.el @@ -0,0 +1,165 @@ +;;; gnus-ml.el --- Mailing list minor mode for Gnus + +;; Copyright (C) 2000 Free Software Foundation, Inc. + +;; Author: Julien Gilles +;; Keywords: news + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; implement (small subset of) RFC 2369 + +;;; Code: + +(require 'gnus) +(eval-when-compile (require 'cl)) + +;;; Mailing list minor mode + +(defvar gnus-mailing-list-mode nil + "Minor mode for providing mailing-list commands.") + +(defvar gnus-mailing-list-mode-map nil) + +(unless gnus-mailing-list-mode-map + (setq gnus-mailing-list-mode-map (make-sparse-keymap)) + + (gnus-define-keys gnus-mailing-list-mode-map + "\C-nh" gnus-mailing-list-help + "\C-ns" gnus-mailing-list-subscribe + "\C-nu" gnus-mailing-list-unsubscribe + "\C-np" gnus-mailing-list-post + "\C-no" gnus-mailing-list-owner + "\C-na" gnus-mailing-list-archive + )) + +(defun gnus-mailing-list-make-menu-bar () + (unless (boundp 'gnus-mailing-list-menu) + (easy-menu-define + gnus-mailing-list-menu gnus-mailing-list-mode-map "" + '("Mailing-Lists" + ["Get help" gnus-mailing-list-help t] + ["Subscribe" gnus-mailing-list-subscribe t] + ["Unsubscribe" gnus-mailing-list-unsubscribe t] + ["Post a message" gnus-mailing-list-post t] + ["Mail to owner" gnus-mailing-list-owner t] + ["Browse archive" gnus-mailing-list-archive t])))) + +(defun turn-on-gnus-mailing-list-mode () + (when (gnus-group-get-parameter group 'to-list) + (gnus-mailing-list-mode 1))) + +(defun gnus-mailing-list-mode (&optional arg) + "Minor mode for providing mailing-list commands. + +\\{gnus-mailing-list-mode-map}" + (interactive "P") + (when (eq major-mode 'gnus-summary-mode) + (when (set (make-local-variable 'gnus-mailing-list-mode) + (if (null arg) (not gnus-mailing-list-mode) + (> (prefix-numeric-value arg) 0))) + ;; Set up the menu. + (when (gnus-visual-p 'mailing-list-menu 'menu) + (gnus-mailing-list-make-menu-bar)) + (gnus-add-minor-mode 'gnus-mailing-list-mode " Mailing-List" gnus-mailing-list-mode-map) + (gnus-run-hooks 'gnus-mailing-list-mode-hook)))) + +;;; Commands + +(defun gnus-mailing-list-help () + "Get help from mailing list server." + (interactive) + (cond (list-help (gnus-mailing-list-message list-help)) + (t (display-message 'no-log "no list-help in this group")))) + +(defun gnus-mailing-list-subscribe () + "Subscribe" + (interactive) + (cond (list-subscribe (gnus-mailing-list-message list-subscribe)) + (t (display-message 'no-log "no list-subscribe in this group")))) + + +(defun gnus-mailing-list-unsubscribe () + "Unsubscribe" + (interactive) + (cond (list-unsubscribe (gnus-mailing-list-message list-unsubscribe)) + (t (display-message 'no-log "no list-unsubscribe in this group")))) + +(defun gnus-mailing-list-post () + "Post message (really useful ?)" + (interactive) + (cond (list-post (gnus-mailing-list-message list-post)) + (t (display-message 'no-log "no list-post in this group"))) + ) + +(defun gnus-mailing-list-owner () + "Mail to the owner" + (interactive) + (cond (list-owner (gnus-mailing-list-message list-owner)) + (t (display-message 'no-log "no list-owner in this group"))) + ) + +(defun gnus-mailing-list-archive () + "Browse archive" + (interactive) + (cond (list-archive (gnus-mailing-list-message list-archive)) + (t (display-message 'no-log "no list-owner in this group"))) + ) + +;;; Utility functions + +(defun gnus-xmas-mailing-list-menu-add () + (gnus-xmas-menu-add mailing-list + gnus-mailing-list-menu)) + +(add-hook 'gnus-mailing-list-mode-hook 'gnus-xmas-mailing-list-menu-add) + +(defun gnus-mailing-list-message (address) + "" + (let ((mailto "") + (to ()) + (subject "None") + (body "") + ) + (cond + ((string-match "]*\\)>" address) + (let ((args (match-string 1 address))) + (cond ; with param + ((string-match "\\(.*\\)\\?\\(.*\\)" args) + (setq mailto (match-string 1 args)) + (let ((param (match-string 2 args))) + (if (string-match "subject=\\([^&]*\\)" param) + (setq subject (match-string 1 param))) + (if (string-match "body=\\([^&]*\\)" param) + (setq body (match-string 1 param))) + (if (string-match "to=\\([^&]*\\)" param) + (push (match-string 1 param) to)) + )) + (t (setq mailto args))))) ; without param + + ; other case +;; Keywords: news, mail + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +(require 'gnus) +(require 'gnus-sum) +(require 'gnus-group) +(require 'nnmail) + +(defvar gnus-group-split-updated-hook nil + "Hook called just after nnmail-split-fancy is updated by gnus-group-split-update.") + +(defvar gnus-group-split-default-catch-all-group "mail.misc" + "Group used by gnus-group-split and gnus-group-split-update as default catch-all group.") + +;;;###autoload +(defun gnus-group-split-setup (&optional auto-update catch-all) + "Set up the split for nnmail-split-fancy. +Sets things up so that nnmail-split-fancy is used for mail +splitting, and defines the variable nnmail-split-fancy according with +group parameters. + +If AUTO-UPDATE is non-nil (prefix argument accepted, if called +interactively), it makes sure nnmail-split-fancy is re-computed before +getting new mail, by adding gnus-group-split-update to +nnmail-pre-get-new-mail-hook." + (interactive "P") + (setq nnmail-split-methods 'nnmail-split-fancy) + (when catch-all + (setq gnus-group-split-default-catch-all-group catch-all)) + (gnus-group-split-update) + (when auto-update + (add-hook 'nnmail-pre-get-new-mail-hook 'gnus-group-split-update))) + +;;;###autoload +(defun gnus-group-split-update (&optional catch-all) + "Computes nnmail-split-fancy from group params. +It does this by calling \(gnus-group-split-fancy nil nil DEFAULTGROUP)." + (interactive) + (setq nnmail-split-fancy + (gnus-group-split-fancy + nil nil (or catch-all gnus-group-split-default-catch-all-group))) + (run-hooks 'gnus-group-split-updated-hook)) + +;;;###autoload +(defun gnus-group-split () + "Uses information from group parameters in order to split mail. +See gnus-group-split-fancy for more information. + +If no group is defined as catch-all, the value of +gnus-group-split-default-catch-all-group is used. + +gnus-group-split is a valid value for nnmail-split-methods." + (let (nnmail-split-fancy) + (gnus-group-split-update + gnus-group-split-default-catch-all-group) + (nnmail-split-fancy))) + +;;;###autoload +(defun gnus-group-split-fancy + (&optional groups no-crosspost catch-all) + "Uses information from group parameters in order to split mail. It +can be embedded into nnmail-split-fancy lists with the SPLIT + +\(: gnus-group-split-fancy GROUPS NO-CROSSPOST CATCH-ALL\) + +GROUPS may be a regular expression or a list of group names, that will +be used to select candidate groups. If it is ommited or nil, all +existing groups are considered. + +if NO-CROSSPOST is ommitted or nil, a & split will be returned, +otherwise, a | split, that does not allow crossposting, will be +returned. + +if CATCH-ALL is not nil, and there is no selected group whose +SPLIT-REGEXP matches the empty string, nor is there a selected group +whose SPLIT-SPEC is 'catch-all, this group name will be appended to +the returned SPLIT list, as the last element in a '| SPLIT. + +For each selected group, a SPLIT is composed like this: if SPLIT-SPEC +is specified, this split is returned as-is (unless it is nil: in this +case, the group is ignored). Otherwise, if TO-ADDRESS, TO-LIST and/or +EXTRA-ALIASES are specified, a regexp that matches any of them is +constructed (extra-aliases may be a list). Additionally, if +SPLIT-REGEXP is specified, the regexp will be extended so that it +matches this regexp too, and if SPLIT-EXCLUDE is specified, RESTRICT +clauses will be generated. + +For example, given the following group parameters: + +nnml:mail.bar: +\((to-address . \"bar@femail.com\") + (split-regexp . \".*@femail\\\\.com\")) +nnml:mail.foo: +\((to-list . \"foo@nowhere.gov\") + (extra-aliases \"foo@localhost\" \"foo-redist@home\") + (split-exclude \"bugs-foo\" \"rambling-foo\") + (admin-address . \"foo-request@nowhere.gov\")) +nnml:mail.others: +\((split-spec . catch-all)) + +Calling (gnus-group-split-fancy nil nil \"mail.misc\") returns: + +\(| (& (any \"\\\\(bar@femail\\\\.com\\\\|.*@femail\\\\.com\\\\)\" + \"mail.bar\") + (any \"\\\\(foo@nowhere\\\\.gov\\\\|foo@localhost\\\\|foo-redist@home\\\\)\" + - \"bugs-foo\" - \"rambling-foo\" \"mail.foo\")) + \"mail.others\")" + (let* ((newsrc (cdr gnus-newsrc-alist)) + split) + (dolist (info newsrc) + (let ((group (gnus-info-group info)) + (params (gnus-info-params info))) + ;; For all GROUPs that match the specified GROUPS + (when (or (not groups) + (and (listp groups) + (memq group groups)) + (and (stringp groups) + (string-match groups group))) + (let ((split-spec (assoc 'split-spec params)) group-clean) + ;; Remove backend from group name + (setq group-clean (string-match ":" group)) + (setq group-clean + (if group-clean + (substring group (1+ group-clean)) + group)) + (if split-spec + (when (setq split-spec (cdr split-spec)) + (if (eq split-spec 'catch-all) + ;; Emit catch-all only when requested + (when catch-all + (setq catch-all group-clean)) + ;; Append split-spec to the main split + (push split-spec split))) + ;; Let's deduce split-spec from other params + (let ((to-address (cdr (assoc 'to-address params))) + (to-list (cdr (assoc 'to-list params))) + (extra-aliases (cdr (assoc 'extra-aliases params))) + (split-regexp (cdr (assoc 'split-regexp params))) + (split-exclude (cdr (assoc 'split-exclude params)))) + (when (or to-address to-list extra-aliases split-regexp) + ;; regexp-quote to-address, to-list and extra-aliases + ;; and add them all to split-regexp + (setq split-regexp + (concat + "\\(" + (mapconcat + 'identity + (append + (and to-address (list (regexp-quote to-address))) + (and to-list (list (regexp-quote to-list))) + (and extra-aliases + (if (listp extra-aliases) + (mapcar 'regexp-quote extra-aliases) + (list extra-aliases))) + (and split-regexp (list split-regexp))) + "\\|") + "\\)")) + ;; Now create the new SPLIT + (push (append + (list 'any split-regexp) + ;; Generate RESTRICTs for SPLIT-EXCLUDEs. + (if (listp split-exclude) + (let ((seq split-exclude) + res) + (while seq + (push (cons '- (pop seq)) + res)) + (apply #'nconc (nreverse res))) + (list '- split-exclude)) + (list group-clean)) + split) + ;; If it matches the empty string, it is a catch-all + (when (string-match split-regexp "") + (setq catch-all nil))))))))) + ;; Add catch-all if not crossposting + (if (and catch-all no-crosspost) + (push split catch-all)) + ;; Move it to the tail, while arranging that SPLITs appear in the + ;; same order as groups. + (setq split (reverse split)) + ;; Decide whether to accept cross-postings or not. + (push (if no-crosspost '| '&) split) + ;; Even if we can cross-post, catch-all should not get + ;; cross-posts. + (if (and catch-all (not no-crosspost)) + (setq split (list '| split catch-all))) + split)) + +(provide 'gnus-mlspl) diff --git a/lisp/gnus/gnus-mule.el b/lisp/gnus/gnus-mule.el deleted file mode 100644 index 371b3dc8b17..00000000000 --- a/lisp/gnus/gnus-mule.el +++ /dev/null @@ -1,216 +0,0 @@ -;;; gnus-mule.el --- Provide multilingual environment to GNUS - -;; Copyright (C) 1995,1997 Free Software Foundation, Inc. -;; Copyright (C) 1995 Electrotechnical Laboratory, JAPAN. - -;; Keywords: gnus, mule - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) -;; any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - -;;; Commentary: - -;; This package enables Gnus to code convert automatically -;; accoding to a coding system specified for each news group. -;; If you want to specify some coding system for a specific news -;; group, add the fllowing line in your .emacs: -;; (gnus-mule-add-group "xxx.yyy.zzz" 'some-coding-system) - -;; By default, only few news groups are registered as the target of -;; code conversion. So, each regional users had better set an -;; appropriate coding system for as below: -;; (gnus-mule-add-group "" 'iso-2022-jp) ;; the case for Japanese - -(require 'nntp) - -(defvar gnus-newsgroup-coding-systems nil - "Assoc list of news groups vs corresponding coding systems. -Each element is has the form (PATTERN CODING-FOR-READ . CODING-FOR-POST), -where, -PATTERN is a regular expression matching news group names, -CODING-FOR-READ is a coding system of articles of the news groups, and -CODING-FOR-POST is a coding system to be encoded for posting articles -to the news groups.") - -;;;###autoload -(defun gnus-mule-add-group (name coding-system) - "Specify that articles of news group NAME are encoded in CODING-SYSTEM. -All news groups deeper than NAME are also the target. -If CODING-SYSTEM is a cons, the car and cdr part are regarded as -coding-system for reading and writing respectively." - (if (not (consp coding-system)) - (setq coding-system (cons coding-system coding-system))) - (setq name (concat "^" (regexp-quote name))) - (let ((group (assoc name gnus-newsgroup-coding-systems))) - (if group - (setcdr group coding-system) - (setq gnus-newsgroup-coding-systems - (cons (cons name coding-system) gnus-newsgroup-coding-systems))))) - -(defun gnus-mule-get-coding-system (group) - "Return the coding system for news group GROUP." - (let ((groups gnus-newsgroup-coding-systems) - (len -1) - coding-system) - ;; Find an entry which matches GROUP the best (i.e. longest). - (while groups - (if (and (string-match (car (car groups)) group) - (> (match-end 0) len)) - (setq len (match-end 0) - coding-system (cdr (car groups)))) - (setq groups (cdr groups))) - coding-system)) - -;; Flag to indicate if article buffer is already decoded or not.") -(defvar gnus-mule-article-decoded nil) -;; Coding system for reading articles of the current news group. -(defvar gnus-mule-coding-system nil) -;;(make-variable-buffer-local 'gnus-mule-coding-system) -(defvar gnus-mule-subject nil) -(defvar gnus-mule-decoded-subject nil) -(defvar gnus-mule-original-subject nil) - -;; Encode (if ENCODING is t) or decode (if ENCODING is nil) the -;; region from START to END by CODING-SYSTEM. -(defun gnus-mule-code-convert1 (start end coding-system encoding) - (if (< start end) - (save-excursion - (if encoding - (encode-coding-region start end coding-system) - (decode-coding-region start end coding-system))))) - -;; Encode (if ENCODING is t) or decode (if ENCODING is nil) the -;; current buffer by CODING-SYSTEM. Try not to move positions of -;; (window-start) and (point). -(defun gnus-mule-code-convert (coding-system encoding) - (if coding-system - (let ((win (get-buffer-window (current-buffer)))) - (if win - ;; We should keep (point) and (window-start). - (save-window-excursion - (select-window win) - (if encoding - ;; Simple way to assure point is on valid character boundary. - (beginning-of-line)) - (gnus-mule-code-convert1 (point-min) (window-start) - coding-system encoding) - (gnus-mule-code-convert1 (window-start) (point) - coding-system encoding) - (gnus-mule-code-convert1 (point) (point-max) - coding-system encoding) - (if (not (pos-visible-in-window-p)) - ;; point went out of window, move to the bottom of window. - (move-to-window-line -1))) - ;; No window for the buffer, no need to worry about (point) - ;; and (windos-start). - (gnus-mule-code-convert1 (point-min) (point-max) - coding-system encoding)) - ))) - -;; Set `gnus-mule-coding-system' to the coding system articles of the -;; current news group is encoded. This function is set in -;; `gnus-parse-headers-hook'. -(defun gnus-mule-select-coding-system () - (if (gnus-buffer-live-p gnus-summary-buffer) - (save-excursion - (set-buffer gnus-summary-buffer) - (let ((coding-system - (gnus-mule-get-coding-system gnus-newsgroup-name))) - (setq gnus-mule-coding-system - (if (and coding-system (coding-system-p (car coding-system))) - (car coding-system))))) - 'binary)) - -;; Decode the current article. This function is set in -;; `gnus-show-traditional-method'. -(defun gnus-mule-decode-article () - (gnus-mule-code-convert gnus-mule-coding-system nil) - (setq gnus-mule-article-decoded t)) - -(defun gnus-mule-toggle-article-format () - "Toggle decoding/encoding of the current article buffer." - (interactive) - (let ((buf (get-buffer gnus-article-buffer))) - (if (and gnus-mule-coding-system buf) - (save-excursion - (set-buffer buf) - (let ((modif (buffer-modified-p)) - buffer-read-only) - (gnus-mule-code-convert gnus-mule-coding-system - gnus-mule-article-decoded) - (setq gnus-mule-article-decoded (not gnus-mule-article-decoded)) - (set-buffer-modified-p modif)))))) - -;; Encode a news article before sending it. -(defun gnus-mule-message-send-news-function () - (let ((groups (message-fetch-field "newsgroups")) - (idx 0) - coding-system coding-system-list group-list) - (if (not groups) - ;; We are not sending the current buffer via news. - nil - (while (string-match "[^ ,]+" groups idx) - (setq idx (match-end 0)) - (setq coding-system - (cdr (gnus-mule-get-coding-system - (substring groups (match-beginning 0) idx)))) - (if (not (memq coding-system coding-system-list)) - (setq coding-system-list (cons coding-system coding-system-list)))) - (if (> (length coding-system-list) 1) - (setq coding-system (read-coding-system "Coding system: "))) - (if coding-system - (encode-coding-region (point-min) (point-max) coding-system))))) - -;; Encode a mail message before sending it. -(defun gnus-mule-message-send-mail-function () - (let ((coding (if enable-multibyte-characters - (select-message-coding-system)))) - (if coding - (encode-coding-region (point-min) (point-max) coding)))) - -;;;###autoload -(defun gnus-mule-initialize () - "Do several settings for GNUS to enable automatic code conversion." - ;; Convenient key definitions - (define-key gnus-article-mode-map "z" 'gnus-mule-toggle-article-format) - (define-key gnus-summary-mode-map "z" 'gnus-mule-toggle-article-format) - ;; Hook definition - (add-hook 'gnus-parse-headers-hook 'gnus-mule-select-coding-system) - (add-hook 'message-send-news-hook - 'gnus-mule-message-send-news-function) - (add-hook 'message-send-mail-hook - 'gnus-mule-message-send-mail-function) - (setq nnheader-file-coding-system 'binary - nnmail-file-coding-system 'binary) - ) - -(gnus-mule-add-group "" 'iso-latin-1) -(gnus-mule-add-group "fj" 'iso-2022-7bit) -(gnus-mule-add-group "tnn" 'iso-2022-7bit) -(gnus-mule-add-group "japan" 'iso-2022-7bit) -(gnus-mule-add-group "pin" 'iso-2022-7bit) -(gnus-mule-add-group "han" 'euc-kr) -(gnus-mule-add-group "alt.chinese.text" 'chinese-hz) -(gnus-mule-add-group "alt.hk" 'chinese-hz) -(gnus-mule-add-group "alt.chinese.text.big5" 'chinese-big5) -(gnus-mule-add-group "soc.culture.vietnamese" '(nil . vietnamese-viqr)) -(gnus-mule-add-group "relcom" 'cyrillic-koi8) -(gnus-mule-add-group "tw." 'chinese-big5) - -(provide 'gnus-mule) - -;; gnus-mule.el ends here diff --git a/lisp/gnus/ietf-drums.el b/lisp/gnus/ietf-drums.el new file mode 100644 index 00000000000..853c208768b --- /dev/null +++ b/lisp/gnus/ietf-drums.el @@ -0,0 +1,249 @@ +;;; ietf-drums.el --- Functions for parsing RFC822bis headers +;; Copyright (C) 1998, 1999, 2000 +;; Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; DRUMS is an IETF Working Group that works (or worked) on the +;; successor to RFC822, "Standard For The Format Of Arpa Internet Text +;; Messages". This library is based on +;; draft-ietf-drums-msg-fmt-05.txt, released on 1998-08-05. + +;;; Code: + +(require 'time-date) +(require 'mm-util) + +(defvar ietf-drums-no-ws-ctl-token "\001-\010\013\014\016-\037\177" + "US-ASCII control characters excluding CR, LF and white space.") +(defvar ietf-drums-text-token "\001-\011\013\014\016-\177" + "US-ASCII characters exlcuding CR and LF.") +(defvar ietf-drums-specials-token "()<>[]:;@\\,.\"" + "Special characters.") +(defvar ietf-drums-quote-token "\\" + "Quote character.") +(defvar ietf-drums-wsp-token " \t" + "White space.") +(defvar ietf-drums-fws-regexp + (concat "[" ietf-drums-wsp-token "]*\n[" ietf-drums-wsp-token "]+") + "Folding white space.") +(defvar ietf-drums-atext-token "-^a-zA-Z0-9!#$%&'*+/=?_`{|}~" + "Textual token.") +(defvar ietf-drums-dot-atext-token "-^a-zA-Z0-9!#$%&'*+/=?_`{|}~." + "Textual token including full stop.") +(defvar ietf-drums-qtext-token + (concat ietf-drums-no-ws-ctl-token "\041\043-\133\135-\177") + "Non-white-space control characaters, plus the rest of ASCII excluding backslash and doublequote.") +(defvar ietf-drums-tspecials "][()<>@,;:\\\"/?=" + "Tspecials.") + +(defvar ietf-drums-syntax-table + (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table))) + (modify-syntax-entry ?\\ "/" table) + (modify-syntax-entry ?< "(" table) + (modify-syntax-entry ?> ")" table) + (modify-syntax-entry ?@ "w" table) + (modify-syntax-entry ?/ "w" table) + (modify-syntax-entry ?= " " table) + (modify-syntax-entry ?* " " table) + (modify-syntax-entry ?\; " " table) + (modify-syntax-entry ?\' " " table) + table)) + +(defun ietf-drums-token-to-list (token) + "Translate TOKEN into a list of characters." + (let ((i 0) + b e c out range) + (while (< i (length token)) + (setq c (mm-char-int (aref token i))) + (incf i) + (cond + ((eq c (mm-char-int ?-)) + (if b + (setq range t) + (push c out))) + (range + (while (<= b c) + (push (mm-make-char 'ascii b) out) + (incf b)) + (setq range nil)) + ((= i (length token)) + (push (mm-make-char 'ascii c) out)) + (t + (when b + (push (mm-make-char 'ascii b) out)) + (setq b c)))) + (nreverse out))) + +(defsubst ietf-drums-init (string) + (set-syntax-table ietf-drums-syntax-table) + (insert string) + (ietf-drums-unfold-fws) + (goto-char (point-min))) + +(defun ietf-drums-remove-comments (string) + "Remove comments from STRING." + (with-temp-buffer + (let (c) + (ietf-drums-init string) + (while (not (eobp)) + (setq c (char-after)) + (cond + ((eq c ?\") + (forward-sexp 1)) + ((eq c ?\() + (delete-region (point) (progn (forward-sexp 1) (point)))) + (t + (forward-char 1)))) + (buffer-string)))) + +(defun ietf-drums-remove-whitespace (string) + "Remove whitespace from STRING." + (with-temp-buffer + (ietf-drums-init string) + (let (c) + (while (not (eobp)) + (setq c (char-after)) + (cond + ((eq c ?\") + (forward-sexp 1)) + ((eq c ?\() + (forward-sexp 1)) + ((memq c '(? ?\t ?\n)) + (delete-char 1)) + (t + (forward-char 1)))) + (buffer-string)))) + +(defun ietf-drums-get-comment (string) + "Return the first comment in STRING." + (with-temp-buffer + (ietf-drums-init string) + (let (result c) + (while (not (eobp)) + (setq c (char-after)) + (cond + ((eq c ?\") + (forward-sexp 1)) + ((eq c ?\() + (setq result + (buffer-substring + (1+ (point)) + (progn (forward-sexp 1) (1- (point)))))) + (t + (forward-char 1)))) + result))) + +(defun ietf-drums-strip (string) + "Remove comments and whitespace from STRING." + (ietf-drums-remove-whitespace (ietf-drums-remove-comments string))) + +(defun ietf-drums-parse-address (string) + "Parse STRING and return a MAILBOX / DISPLAY-NAME pair." + (with-temp-buffer + (let (display-name mailbox c display-string) + (ietf-drums-init string) + (while (not (eobp)) + (setq c (char-after)) + (cond + ((or (eq c ? ) + (eq c ?\t)) + (forward-char 1)) + ((eq c ?\() + (forward-sexp 1)) + ((eq c ?\") + (push (buffer-substring + (1+ (point)) (progn (forward-sexp 1) (1- (point)))) + display-name)) + ((looking-at (concat "[" ietf-drums-atext-token "@" "]")) + (push (buffer-substring (point) (progn (forward-sexp 1) (point))) + display-name)) + ((eq c ?<) + (setq mailbox + (ietf-drums-remove-whitespace + (ietf-drums-remove-comments + (buffer-substring + (1+ (point)) + (progn (forward-sexp 1) (1- (point)))))))) + (t (error "Unknown symbol: %c" c)))) + ;; If we found no display-name, then we look for comments. + (if display-name + (setq display-string + (mapconcat 'identity (reverse display-name) " ")) + (setq display-string (ietf-drums-get-comment string))) + (if (not mailbox) + (when (string-match "@" display-string) + (cons + (mapconcat 'identity (nreverse display-name) "") + (ietf-drums-get-comment string))) + (cons mailbox display-string))))) + +(defun ietf-drums-parse-addresses (string) + "Parse STRING and return a list of MAILBOX / DISPLAY-NAME pairs." + (with-temp-buffer + (ietf-drums-init string) + (let ((beg (point)) + pairs c) + (while (not (eobp)) + (setq c (char-after)) + (cond + ((memq c '(?\" ?< ?\()) + (forward-sexp 1)) + ((eq c ?,) + (push (ietf-drums-parse-address (buffer-substring beg (point))) + pairs) + (forward-char 1) + (setq beg (point))) + (t + (forward-char 1)))) + (push (ietf-drums-parse-address (buffer-substring beg (point))) + pairs) + (nreverse pairs)))) + +(defun ietf-drums-unfold-fws () + "Unfold folding white space in the current buffer." + (goto-char (point-min)) + (while (re-search-forward ietf-drums-fws-regexp nil t) + (replace-match " " t t)) + (goto-char (point-min))) + +(defun ietf-drums-parse-date (string) + "Return an Emacs time spec from STRING." + (apply 'encode-time (parse-time-string string))) + +(defun ietf-drums-narrow-to-header () + "Narrow to the header section in the current buffer." + (narrow-to-region + (goto-char (point-min)) + (if (re-search-forward "^\r?$" nil 1) + (match-beginning 0) + (point-max))) + (goto-char (point-min))) + +(defun ietf-drums-quote-string (string) + "Quote string if it needs quoting to be displayed in a header." + (if (string-match (concat "[^" ietf-drums-atext-token "]") string) + (concat "\"" string "\"") + string)) + +(provide 'ietf-drums) + +;;; ietf-drums.el ends here diff --git a/lisp/gnus/imap.el b/lisp/gnus/imap.el new file mode 100644 index 00000000000..8cb3ed8ac6c --- /dev/null +++ b/lisp/gnus/imap.el @@ -0,0 +1,2560 @@ +;;; imap.el --- imap library +;; Copyright (C) 1998, 1999, 2000 +;; Free Software Foundation, Inc. + +;; Author: Simon Josefsson +;; Keywords: mail + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; imap.el is a elisp library providing an interface for talking to +;; IMAP servers. +;; +;; imap.el is roughly divided in two parts, one that parses IMAP +;; responses from the server and storing data into buffer-local +;; variables, and one for utility functions which send commands to +;; server, waits for an answer, and return information. The latter +;; part is layered on top of the previous. +;; +;; The imap.el API consist of the following functions, other functions +;; in this file should not be called directly and the result of doing +;; so are at best undefined. +;; +;; Global commands: +;; +;; imap-open, imap-opened, imap-authenticate, imap-close, +;; imap-capability, imap-namespace, imap-error-text +;; +;; Mailbox commands: +;; +;; imap-mailbox-get, imap-mailbox-map, imap-current-mailbox, +;; imap-current-mailbox-p, imap-search, imap-mailbox-select, +;; imap-mailbox-examine, imap-mailbox-unselect, imap-mailbox-expunge +;; imap-mailbox-close, imap-mailbox-create, imap-mailbox-delete +;; imap-mailbox-rename, imap-mailbox-lsub, imap-mailbox-list +;; imap-mailbox-subscribe, imap-mailbox-unsubscribe, imap-mailbox-status +;; imap-mailbox-acl-get, imap-mailbox-acl-set, imap-mailbox-acl-delete +;; +;; Message commands: +;; +;; imap-fetch-asynch, imap-fetch, +;; imap-current-message, imap-list-to-message-set, +;; imap-message-get, imap-message-map +;; imap-message-envelope-date, imap-message-envelope-subject, +;; imap-message-envelope-from, imap-message-envelope-sender, +;; imap-message-envelope-reply-to, imap-message-envelope-to, +;; imap-message-envelope-cc, imap-message-envelope-bcc +;; imap-message-envelope-in-reply-to, imap-message-envelope-message-id +;; imap-message-body, imap-message-flag-permanent-p +;; imap-message-flags-set, imap-message-flags-del +;; imap-message-flags-add, imap-message-copyuid +;; imap-message-copy, imap-message-appenduid +;; imap-message-append, imap-envelope-from +;; imap-body-lines +;; +;; It is my hope that theese commands should be pretty self +;; explanatory for someone that know IMAP. All functions have +;; additional documentation on how to invoke them. +;; +;; imap.el support RFC1730/2060 (IMAP4/IMAP4rev1), implemented IMAP +;; extensions are RFC2195 (CRAM-MD5), RFC2086 (ACL), RFC2342 +;; (NAMESPACE), RFC2359 (UIDPLUS), the IMAP-part of RFC2595 (STARTTLS) +;; (with use of external library starttls.el and program starttls) and +;; the GSSAPI / kerberos V4 sections of RFC1731 (with use of external +;; program `imtest'). It also take advantage the UNSELECT extension +;; in Cyrus IMAPD. +;; +;; Without the work of John McClary Prevost and Jim Radford this library +;; would not have seen the light of day. Many thanks. +;; +;; This is a transcript of short interactive session for demonstration +;; purposes. +;; +;; (imap-open "my.mail.server") +;; => " *imap* my.mail.server:0" +;; +;; The rest are invoked with current buffer as the buffer returned by +;; `imap-open'. It is possible to do all without this, but it would +;; look ugly here since `buffer' is always the last argument for all +;; imap.el API functions. +;; +;; (imap-authenticate "myusername" "mypassword") +;; => auth +;; +;; (imap-mailbox-lsub "*") +;; => ("INBOX.sentmail" "INBOX.private" "INBOX.draft" "INBOX.spam") +;; +;; (imap-mailbox-list "INBOX.n%") +;; => ("INBOX.namedroppers" "INBOX.nnimap" "INBOX.ntbugtraq") +;; +;; (imap-mailbox-select "INBOX.nnimap") +;; => "INBOX.nnimap" +;; +;; (imap-mailbox-get 'exists) +;; => 166 +;; +;; (imap-mailbox-get 'uidvalidity) +;; => "908992622" +;; +;; (imap-search "FLAGGED SINCE 18-DEC-98") +;; => (235 236) +;; +;; (imap-fetch 235 "RFC822.PEEK" 'RFC822) +;; => "X-Sieve: cmu-sieve 1.3^M\nX-Username: ^M\r...." +;; +;; Todo: +;; +;; o Parse UIDs as strings? We need to overcome the 28 bit limit somehow. +;; o Don't use `read' at all (important places already fixed) +;; o Accept list of articles instead of message set string in most +;; imap-message-* functions. +;; +;; Revision history: +;; +;; - 19991218 added starttls/digest-md5 patch, +;; by Daiki Ueno +;; NB! you need SLIM for starttls.el and digest-md5.el +;; - 19991023 commited to pgnus +;; + +;;; Code: + +(eval-when-compile (require 'cl)) +(eval-and-compile + (autoload 'open-ssl-stream "ssl") + (autoload 'base64-decode-string "base64") + (autoload 'base64-encode-string "base64") + (autoload 'starttls-open-stream "starttls") + (autoload 'starttls-negotiate "starttls") + (autoload 'digest-md5-parse-digest-challenge "digest-md5") + (autoload 'digest-md5-digest-response "digest-md5") + (autoload 'digest-md5-digest-uri "digest-md5") + (autoload 'digest-md5-challenge "digest-md5") + (autoload 'rfc2104-hash "rfc2104") + (autoload 'md5 "md5") + (autoload 'utf7-encode "utf7") + (autoload 'utf7-decode "utf7") + (autoload 'format-spec "format-spec") + (autoload 'format-spec-make "format-spec")) + +;; User variables. + +(defgroup imap nil + "Low-level IMAP issues." + :version "21.1" + :group 'mail) + +(defcustom imap-kerberos4-program '("imtest -m kerberos_v4 -u %l -p %p %s" + "imtest -kp %s %p") + "List of strings containing commands for Kerberos 4 authentication. +%s is replaced with server hostname, %p with port to connect to, and +%l with the value of `imap-default-user'. The program should accept +IMAP commands on stdin and return responses to stdout. Each entry in +the list is tried until a successful connection is made." + :group 'imap + :type '(repeat string)) + +(defcustom imap-gssapi-program '("imtest -m gssapi -u %l -p %p %s") + "List of strings containing commands for GSSAPI (krb5) authentication. +%s is replaced with server hostname, %p with port to connect to, and +%l with the value of `imap-default-user'. The program should accept +IMAP commands on stdin and return responses to stdout. Each entry in +the list is tried until a successful connection is made." + :group 'imap + :type '(repeat string)) + +(defcustom imap-ssl-program '("openssl s_client -ssl3 -connect %s:%p" + "openssl s_client -ssl2 -connect %s:%p" + "s_client -ssl3 -connect %s:%p" + "s_client -ssl2 -connect %s:%p") + "A string, or list of strings, containing commands for SSL connections. +Within a string, %s is replaced with the server address and %p with +port number on server. The program should accept IMAP commands on +stdin and return responses to stdout. Each entry in the list is tried +until a successful connection is made." + :group 'imap + :type '(choice string + (repeat string))) + +(defcustom imap-shell-program '("ssh %s imapd" + "rsh %s imapd" + "ssh %g ssh %s imapd" + "rsh %g rsh %s imapd") + "A list of strings, containing commands for IMAP connection. +Within a string, %s is replaced with the server address, %p with port +number on server, %g with `imap-shell-host', and %l with +`imap-default-user'. The program should read IMAP commands from stdin +and write IMAP response to stdout. Each entry in the list is tried +until a successful connection is made." + :group 'imap + :type '(repeat string)) + +(defvar imap-shell-host "gateway" + "Hostname of rlogin proxy.") + +(defvar imap-default-user (user-login-name) + "Default username to use.") + +(defvar imap-error nil + "Error codes from the last command.") + +;; Various variables. + +(defvar imap-fetch-data-hook nil + "Hooks called after receiving each FETCH response.") + +(defvar imap-streams '(gssapi kerberos4 starttls ssl network shell) + "Priority of streams to consider when opening connection to server.") + +(defvar imap-stream-alist + '((gssapi imap-gssapi-stream-p imap-gssapi-open) + (kerberos4 imap-kerberos4-stream-p imap-kerberos4-open) + (ssl imap-ssl-p imap-ssl-open) + (network imap-network-p imap-network-open) + (shell imap-shell-p imap-shell-open) + (starttls imap-starttls-p imap-starttls-open)) + "Definition of network streams. + +(NAME CHECK OPEN) + +NAME names the stream, CHECK is a function returning non-nil if the +server support the stream and OPEN is a function for opening the +stream.") + +(defvar imap-authenticators '(gssapi + kerberos4 + digest-md5 + cram-md5 + login + anonymous) + "Priority of authenticators to consider when authenticating to server.") + +(defvar imap-authenticator-alist + '((gssapi imap-gssapi-auth-p imap-gssapi-auth) + (kerberos4 imap-kerberos4-auth-p imap-kerberos4-auth) + (cram-md5 imap-cram-md5-p imap-cram-md5-auth) + (login imap-login-p imap-login-auth) + (anonymous imap-anonymous-p imap-anonymous-auth) + (digest-md5 imap-digest-md5-p imap-digest-md5-auth)) + "Definition of authenticators. + +(NAME CHECK AUTHENTICATE) + +NAME names the authenticator. CHECK is a function returning non-nil if +the server support the authenticator and AUTHENTICATE is a function +for doing the actuall authentification.") + +(defvar imap-use-utf7 t + "If non-nil, do utf7 encoding/decoding of mailbox names. +Since the UTF7 decoding currently only decodes into ISO-8859-1 +characters, you may disable this decoding if you need to access UTF7 +encoded mailboxes which doesn't translate into ISO-8859-1.") + +;; Internal constants. Change theese and die. + +(defconst imap-default-port 143) +(defconst imap-default-ssl-port 993) +(defconst imap-default-stream 'network) +(defconst imap-coding-system-for-read 'binary) +(defconst imap-coding-system-for-write 'binary) +(defconst imap-local-variables '(imap-server + imap-port + imap-client-eol + imap-server-eol + imap-auth + imap-stream + imap-username + imap-password + imap-current-mailbox + imap-current-target-mailbox + imap-message-data + imap-capability + imap-namespace + imap-state + imap-reached-tag + imap-failed-tags + imap-tag + imap-process + imap-calculate-literal-size-first + imap-mailbox-data)) + +;; Internal variables. + +(defvar imap-stream nil) +(defvar imap-auth nil) +(defvar imap-server nil) +(defvar imap-port nil) +(defvar imap-username nil) +(defvar imap-password nil) +(defvar imap-calculate-literal-size-first nil) +(defvar imap-state 'closed + "IMAP state. +Valid states are `closed', `initial', `nonauth', `auth', `selected' +and `examine'.") + +(defvar imap-server-eol "\r\n" + "The EOL string sent from the server.") + +(defvar imap-client-eol "\r\n" + "The EOL string we send to the server.") + +(defvar imap-current-mailbox nil + "Current mailbox name.") + +(defvar imap-current-target-mailbox nil + "Current target mailbox for COPY and APPEND commands.") + +(defvar imap-mailbox-data nil + "Obarray with mailbox data.") + +(defvar imap-mailbox-prime 997 + "Length of imap-mailbox-data.") + +(defvar imap-current-message nil + "Current message number.") + +(defvar imap-message-data nil + "Obarray with message data.") + +(defvar imap-message-prime 997 + "Length of imap-message-data.") + +(defvar imap-capability nil + "Capability for server.") + +(defvar imap-namespace nil + "Namespace for current server.") + +(defvar imap-reached-tag 0 + "Lower limit on command tags that have been parsed.") + +(defvar imap-failed-tags nil + "Alist of tags that failed. +Each element is a list with four elements; tag (a integer), response +state (a symbol, `OK', `NO' or `BAD'), response code (a string), and +human readable response text (a string).") + +(defvar imap-tag 0 + "Command tag number.") + +(defvar imap-process nil + "Process.") + +(defvar imap-continuation nil + "Non-nil indicates that the server emitted a continuation request. +The actually value is really the text on the continuation line.") + +(defvar imap-log nil + "Name of buffer for imap session trace. +For example: (setq imap-log \"*imap-log*\")") + +(defvar imap-debug nil ;"*imap-debug*" + "Name of buffer for random debug spew. +For example: (setq imap-debug \"*imap-debug*\")") + + +;; Utility functions: + +(defsubst imap-disable-multibyte () + "Enable multibyte in the current buffer." + (when (fboundp 'set-buffer-multibyte) + (set-buffer-multibyte nil))) + +(defun imap-read-passwd (prompt &rest args) + "Read a password using PROMPT. +If ARGS, PROMPT is used as an argument to `format'." + (let ((prompt (if args + (apply 'format prompt args) + prompt))) + (funcall (if (or (fboundp 'read-passwd) + (and (load "subr" t) + (fboundp 'read-passwd)) + (and (load "passwd" t) + (fboundp 'read-passwd))) + 'read-passwd + (autoload 'ange-ftp-read-passwd "ange-ftp") + 'ange-ftp-read-passwd) + prompt))) + +(defsubst imap-utf7-encode (string) + (if imap-use-utf7 + (and string + (condition-case () + (utf7-encode string t) + (error (message + "imap: Could not UTF7 encode `%s', using it unencoded..." + string) + string))) + string)) + +(defsubst imap-utf7-decode (string) + (if imap-use-utf7 + (and string + (condition-case () + (utf7-decode string t) + (error (message + "imap: Could not UTF7 decode `%s', using it undecoded..." + string) + string))) + string)) + +(defsubst imap-ok-p (status) + (if (eq status 'OK) + t + (setq imap-error status) + nil)) + +(defun imap-error-text (&optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (nth 3 (car imap-failed-tags)))) + + +;; Server functions; stream stuff: + +(defun imap-kerberos4-stream-p (buffer) + (imap-capability 'AUTH=KERBEROS_V4 buffer)) + +(defun imap-kerberos4-open (name buffer server port) + (let ((cmds imap-kerberos4-program) + cmd done) + (while (and (not done) (setq cmd (pop cmds))) + (message "Opening Kerberos 4 IMAP connection with `%s'..." cmd) + (erase-buffer) + (let* ((port (or port imap-default-port)) + (coding-system-for-read imap-coding-system-for-read) + (coding-system-for-write imap-coding-system-for-write) + (process (start-process + name buffer shell-file-name shell-command-switch + (format-spec + cmd + (format-spec-make + ?s server + ?p (number-to-string port) + ?l imap-default-user)))) + response) + (when process + (with-current-buffer buffer + (setq imap-client-eol "\n" + imap-calculate-literal-size-first t) + (while (and (memq (process-status process) '(open run)) + (goto-char (point-min)) + ;; cyrus 1.6.x (13? < x <= 22) queries capabilities + (or (while (looking-at "^C:") + (forward-line)) + t) + ;; cyrus 1.6 imtest print "S: " before server greeting + (or (not (looking-at "S: ")) + (forward-char 3) + t) + (not (and (imap-parse-greeting) + ;; success in imtest < 1.6: + (or (re-search-forward + "^__\\(.*\\)__\n" nil t) + ;; success in imtest 1.6: + (re-search-forward + "^\\(Authenticat.*\\)" nil t)) + (setq response (match-string 1))))) + (accept-process-output process 1) + (sit-for 1)) + (and imap-log + (with-current-buffer (get-buffer-create imap-log) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert-buffer-substring buffer))) + (erase-buffer) + (message "Kerberos 4 IMAP connection: %s" (or response "failed")) + (if (and response (let ((case-fold-search nil)) + (not (string-match "failed" response)))) + (setq done process) + (if (memq (process-status process) '(open run)) + (imap-send-command-wait "LOGOUT")) + (delete-process process) + nil))))) + done)) + +(defun imap-gssapi-stream-p (buffer) + (imap-capability 'AUTH=GSSAPI buffer)) + +(defun imap-gssapi-open (name buffer server port) + (let ((cmds imap-gssapi-program) + cmd done) + (while (and (not done) (setq cmd (pop cmds))) + (message "Opening GSSAPI IMAP connection with `%s'..." cmd) + (let* ((port (or port imap-default-port)) + (coding-system-for-read imap-coding-system-for-read) + (coding-system-for-write imap-coding-system-for-write) + (process (start-process + name buffer shell-file-name shell-command-switch + (format-spec + cmd + (format-spec-make + ?s server + ?p (number-to-string port) + ?l imap-default-user)))) + response) + (when process + (with-current-buffer buffer + (setq imap-client-eol "\n") + (while (and (memq (process-status process) '(open run)) + (goto-char (point-min)) + ;; cyrus 1.6.x (13? < x <= 22) queries capabilities + (or (while (looking-at "^C:") + (forward-line)) + t) + ;; cyrus 1.6 imtest print "S: " before server greeting + (or (not (looking-at "S: ")) + (forward-char 3) + t) + (not (and (imap-parse-greeting) + ;; success in imtest 1.6: + (re-search-forward + "^\\(Authenticat.*\\)" nil t) + (setq response (match-string 1))))) + (accept-process-output process 1) + (sit-for 1)) + (and imap-log + (with-current-buffer (get-buffer-create imap-log) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert-buffer-substring buffer))) + (erase-buffer) + (message "GSSAPI IMAP connection: %s" (or response "failed")) + (if (and response (let ((case-fold-search nil)) + (not (string-match "failed" response)))) + (setq done process) + (if (memq (process-status process) '(open run)) + (imap-send-command-wait "LOGOUT")) + (delete-process process) + nil))))) + done)) + +(defun imap-ssl-p (buffer) + nil) + +(defun imap-ssl-open (name buffer server port) + "Open a SSL connection to server." + (let ((cmds (if (listp imap-ssl-program) imap-ssl-program + (list imap-ssl-program))) + cmd done) + (while (and (not done) (setq cmd (pop cmds))) + (message "imap: Opening SSL connection with `%s'..." cmd) + (let* ((port (or port imap-default-ssl-port)) + (coding-system-for-read imap-coding-system-for-read) + (coding-system-for-write imap-coding-system-for-write) + (ssl-program-name shell-file-name) + (ssl-program-arguments + (list shell-command-switch + (format-spec cmd (format-spec-make + ?s server + ?p (number-to-string port))))) + process) + (when (setq process (ignore-errors (open-ssl-stream + name buffer server port))) + (with-current-buffer buffer + (goto-char (point-min)) + (while (and (memq (process-status process) '(open run)) + (goto-char (point-max)) + (forward-line -1) + (not (imap-parse-greeting))) + (accept-process-output process 1) + (sit-for 1)) + (and imap-log + (with-current-buffer (get-buffer-create imap-log) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert-buffer-substring buffer))) + (erase-buffer) + (when (memq (process-status process) '(open run)) + (setq done process)))))) + (if done + (progn + (message "imap: Opening SSL connection with `%s'...done" cmd) + done) + (message "imap: Failed opening SSL connection") + nil))) + +(defun imap-network-p (buffer) + t) + +(defun imap-network-open (name buffer server port) + (let* ((port (or port imap-default-port)) + (coding-system-for-read imap-coding-system-for-read) + (coding-system-for-write imap-coding-system-for-write) + (process (open-network-stream name buffer server port))) + (when process + (while (and (memq (process-status process) '(open run)) + (goto-char (point-min)) + (not (imap-parse-greeting))) + (accept-process-output process 1) + (sit-for 1)) + (and imap-log + (with-current-buffer (get-buffer-create imap-log) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert-buffer-substring buffer))) + (when (memq (process-status process) '(open run)) + process)))) + +(defun imap-shell-p (buffer) + nil) + +(defun imap-shell-open (name buffer server port) + (let ((cmds imap-shell-program) + cmd done) + (while (and (not done) (setq cmd (pop cmds))) + (message "imap: Opening IMAP connection with `%s'..." cmd) + (setq imap-client-eol "\n") + (let* ((port (or port imap-default-port)) + (coding-system-for-read imap-coding-system-for-read) + (coding-system-for-write imap-coding-system-for-write) + (process (start-process + name buffer shell-file-name shell-command-switch + (format-spec + cmd + (format-spec-make + ?s server + ?g imap-shell-host + ?p (number-to-string port) + ?l imap-default-user))))) + (when process + (while (and (memq (process-status process) '(open run)) + (goto-char (point-min)) + (not (imap-parse-greeting))) + (accept-process-output process 1) + (sit-for 1)) + (erase-buffer) + (and imap-log + (with-current-buffer (get-buffer-create imap-log) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert-buffer-substring buffer))) + (when (memq (process-status process) '(open run)) + (setq done process))))) + (if done + (progn + (message "imap: Opening IMAP connection with `%s'...done" cmd) + done) + (message "imap: Failed opening IMAP connection") + nil))) + +(defun imap-starttls-p (buffer) + (and (condition-case () + (require 'starttls) + (error nil)) + (imap-capability 'STARTTLS buffer))) + +(defun imap-starttls-open (name buffer server port) + (let* ((port (or port imap-default-port)) + (coding-system-for-read imap-coding-system-for-read) + (coding-system-for-write imap-coding-system-for-write) + (process (starttls-open-stream name buffer server port))) + (when process + (while (and (memq (process-status process) '(open run)) + (goto-char (point-min)) + (not (imap-parse-greeting))) + (accept-process-output process 1) + (sit-for 1)) + (and imap-log + (with-current-buffer (get-buffer-create imap-log) + (buffer-disable-undo) + (goto-char (point-max)) + (insert-buffer-substring buffer))) + (let ((imap-process process)) + (unwind-protect + (progn + (set-process-filter imap-process 'imap-arrival-filter) + (when (and (eq imap-stream 'starttls) + (imap-ok-p (imap-send-command-wait "STARTTLS"))) + (starttls-negotiate imap-process))) + (set-process-filter imap-process nil))) + (when (memq (process-status process) '(open run)) + process)))) + +;; Server functions; authenticator stuff: + +(defun imap-interactive-login (buffer loginfunc) + "Login to server in BUFFER. +LOGINFUNC is passed a username and a password, it should return t if +it where sucessful authenticating itself to the server, nil otherwise. +Returns t if login was successful, nil otherwise." + (with-current-buffer buffer + (make-variable-buffer-local 'imap-username) + (make-variable-buffer-local 'imap-password) + (let (user passwd ret) + ;; (condition-case () + (while (or (not user) (not passwd)) + (setq user (or imap-username + (read-from-minibuffer + (concat "IMAP username for " imap-server ": ") + (or user imap-default-user)))) + (setq passwd (or imap-password + (imap-read-passwd + (concat "IMAP password for " user "@" + imap-server ": ")))) + (when (and user passwd) + (if (funcall loginfunc user passwd) + (progn + (setq ret t + imap-username user) + (if (and (not imap-password) + (y-or-n-p "Store password for this session? ")) + (setq imap-password passwd))) + (message "Login failed...") + (setq passwd nil) + (sit-for 1)))) + ;; (quit (with-current-buffer buffer + ;; (setq user nil + ;; passwd nil))) + ;; (error (with-current-buffer buffer + ;; (setq user nil + ;; passwd nil)))) + ret))) + +(defun imap-gssapi-auth-p (buffer) + (imap-capability 'AUTH=GSSAPI buffer)) + +(defun imap-gssapi-auth (buffer) + (eq imap-stream 'gssapi)) + +(defun imap-kerberos4-auth-p (buffer) + (imap-capability 'AUTH=KERBEROS_V4 buffer)) + +(defun imap-kerberos4-auth (buffer) + (eq imap-stream 'kerberos4)) + +(defun imap-cram-md5-p (buffer) + (imap-capability 'AUTH=CRAM-MD5 buffer)) + +(defun imap-cram-md5-auth (buffer) + "Login to server using the AUTH CRAM-MD5 method." + (imap-interactive-login + buffer + (lambda (user passwd) + (imap-ok-p + (imap-send-command-wait + (list + "AUTHENTICATE CRAM-MD5" + (lambda (challenge) + (let* ((decoded (base64-decode-string challenge)) + (hash (rfc2104-hash 'md5 64 16 passwd decoded)) + (response (concat user " " hash)) + (encoded (base64-encode-string response))) + encoded)))))))) + +(defun imap-login-p (buffer) + (not (imap-capability 'X-LOGIN-CMD-DISABLED buffer))) + +(defun imap-login-auth (buffer) + "Login to server using the LOGIN command." + (imap-interactive-login buffer + (lambda (user passwd) + (imap-ok-p (imap-send-command-wait + (concat "LOGIN \"" user "\" \"" + passwd "\"")))))) + +(defun imap-anonymous-p (buffer) + t) + +(defun imap-anonymous-auth (buffer) + (with-current-buffer buffer + (imap-ok-p (imap-send-command-wait + (concat "LOGIN anonymous \"" (concat (user-login-name) "@" + (system-name)) "\""))))) + +(defun imap-digest-md5-p (buffer) + (and (condition-case () + (require 'digest-md5) + (error nil)) + (imap-capability 'AUTH=DIGEST-MD5 buffer))) + +(defun imap-digest-md5-auth (buffer) + "Login to server using the AUTH DIGEST-MD5 method." + (imap-interactive-login + buffer + (lambda (user passwd) + (let ((tag + (imap-send-command + (list + "AUTHENTICATE DIGEST-MD5" + (lambda (challenge) + (digest-md5-parse-digest-challenge + (base64-decode-string challenge)) + (let* ((digest-uri + (digest-md5-digest-uri + "imap" (digest-md5-challenge 'realm))) + (response + (digest-md5-digest-response + user passwd digest-uri))) + (base64-encode-string response 'no-line-break)))) + ))) + (if (not (eq (imap-wait-for-tag tag) 'INCOMPLETE)) + nil + (setq imap-continuation nil) + (imap-send-command-1 "") + (imap-ok-p (imap-wait-for-tag tag))))))) + +;; Server functions: + +(defun imap-open-1 (buffer) + (with-current-buffer buffer + (erase-buffer) + (setq imap-current-mailbox nil + imap-current-message nil + imap-state 'initial + imap-process (condition-case () + (funcall (nth 2 (assq imap-stream + imap-stream-alist)) + "imap" buffer imap-server imap-port) + ((error quit) nil))) + (when imap-process + (set-process-filter imap-process 'imap-arrival-filter) + (set-process-sentinel imap-process 'imap-sentinel) + (while (and (eq imap-state 'initial) + (memq (process-status imap-process) '(open run))) + (message "Waiting for response from %s..." imap-server) + (accept-process-output imap-process 1)) + (message "Waiting for response from %s...done" imap-server) + (and (memq (process-status imap-process) '(open run)) + imap-process)))) + +(defun imap-open (server &optional port stream auth buffer) + "Open a IMAP connection to host SERVER at PORT returning a buffer. +If PORT is unspecified, a default value is used (143 except +for SSL which use 993). +STREAM indicates the stream to use, see `imap-streams' for available +streams. If nil, it choices the best stream the server is capable of. +AUTH indicates authenticator to use, see `imap-authenticators' for +available authenticators. If nil, it choices the best stream the +server is capable of. +BUFFER can be a buffer or a name of a buffer, which is created if +necessery. If nil, the buffer name is generated." + (setq buffer (or buffer (format " *imap* %s:%d" server (or port 0)))) + (with-current-buffer (get-buffer-create buffer) + (if (imap-opened buffer) + (imap-close buffer)) + (mapcar 'make-variable-buffer-local imap-local-variables) + (imap-disable-multibyte) + (buffer-disable-undo) + (setq imap-server (or server imap-server)) + (setq imap-port (or port imap-port)) + (setq imap-auth (or auth imap-auth)) + (setq imap-stream (or stream imap-stream)) + (when (let ((imap-stream (or imap-stream imap-default-stream))) + (imap-open-1 buffer)) + ;; Choose stream. + (let (stream-changed) + (when (null imap-stream) + (let ((streams imap-streams)) + (while (setq stream (pop streams)) + (if (funcall (nth 1 (assq stream imap-stream-alist)) buffer) + (setq stream-changed (not (eq (or imap-stream + imap-default-stream) + stream)) + imap-stream stream + streams nil))) + (unless imap-stream + (error "Couldn't figure out a stream for server")))) + (when stream-changed + (message "Reconnecting with %s..." imap-stream) + (imap-close buffer) + (imap-open-1 buffer) + (setq imap-capability nil))) + (if (imap-opened buffer) + ;; Choose authenticator + (when (and (null imap-auth) (not (eq imap-state 'auth))) + (let ((auths imap-authenticators)) + (while (setq auth (pop auths)) + (if (funcall (nth 1 (assq auth imap-authenticator-alist)) + buffer) + (setq imap-auth auth + auths nil))) + (unless imap-auth + (error "Couldn't figure out authenticator for server")))))) + (when (imap-opened buffer) + (setq imap-mailbox-data (make-vector imap-mailbox-prime 0)) + buffer))) + +(defun imap-opened (&optional buffer) + "Return non-nil if connection to imap server in BUFFER is open. +If BUFFER is nil then the current buffer is used." + (and (setq buffer (get-buffer (or buffer (current-buffer)))) + (buffer-live-p buffer) + (with-current-buffer buffer + (and imap-process + (memq (process-status imap-process) '(open run)))))) + +(defun imap-authenticate (&optional user passwd buffer) + "Authenticate to server in BUFFER, using current buffer if nil. +It uses the authenticator specified when opening the server. If the +authenticator requires username/passwords, they are queried from the +user and optionally stored in the buffer. If USER and/or PASSWD is +specified, the user will not be questioned and the username and/or +password is remembered in the buffer." + (with-current-buffer (or buffer (current-buffer)) + (if (not (eq imap-state 'nonauth)) + (or (eq imap-state 'auth) + (eq imap-state 'select) + (eq imap-state 'examine)) + (make-variable-buffer-local 'imap-username) + (make-variable-buffer-local 'imap-password) + (if user (setq imap-username user)) + (if passwd (setq imap-password passwd)) + (if (funcall (nth 2 (assq imap-auth imap-authenticator-alist)) buffer) + (setq imap-state 'auth))))) + +(defun imap-close (&optional buffer) + "Close connection to server in BUFFER. +If BUFFER is nil, the current buffer is used." + (with-current-buffer (or buffer (current-buffer)) + (and (imap-opened) + (not (imap-ok-p (imap-send-command-wait "LOGOUT"))) + (message "Server %s didn't let me log out" imap-server)) + (when (and imap-process + (memq (process-status imap-process) '(open run))) + (delete-process imap-process)) + (setq imap-current-mailbox nil + imap-current-message nil + imap-process nil) + (erase-buffer) + t)) + +(defun imap-capability (&optional identifier buffer) + "Return a list of identifiers which server in BUFFER support. +If IDENTIFIER, return non-nil if it's among the servers capabilities. +If BUFFER is nil, the current buffer is assumed." + (with-current-buffer (or buffer (current-buffer)) + (unless imap-capability + (unless (imap-ok-p (imap-send-command-wait "CAPABILITY")) + (setq imap-capability '(IMAP2)))) + (if identifier + (memq (intern (upcase (symbol-name identifier))) imap-capability) + imap-capability))) + +(defun imap-namespace (&optional buffer) + "Return a namespace hierarchy at server in BUFFER. +If BUFFER is nil, the current buffer is assumed." + (with-current-buffer (or buffer (current-buffer)) + (unless imap-namespace + (when (imap-capability 'NAMESPACE) + (imap-send-command-wait "NAMESPACE"))) + imap-namespace)) + +(defun imap-send-command-wait (command &optional buffer) + (imap-wait-for-tag (imap-send-command command buffer) buffer)) + + +;; Mailbox functions: + +(defun imap-mailbox-put (propname value &optional mailbox buffer) + (with-current-buffer (or buffer (current-buffer)) + (if imap-mailbox-data + (put (intern (or mailbox imap-current-mailbox) imap-mailbox-data) + propname value) + (error "Imap-mailbox-data is nil, prop %s value %s mailbox %s buffer %s" + propname value mailbox (current-buffer))) + t)) + +(defsubst imap-mailbox-get-1 (propname &optional mailbox) + (get (intern-soft (or mailbox imap-current-mailbox) imap-mailbox-data) + propname)) + +(defun imap-mailbox-get (propname &optional mailbox buffer) + (let ((mailbox (imap-utf7-encode mailbox))) + (with-current-buffer (or buffer (current-buffer)) + (imap-mailbox-get-1 propname (or mailbox imap-current-mailbox))))) + +(defun imap-mailbox-map-1 (func &optional mailbox-decoder buffer) + (with-current-buffer (or buffer (current-buffer)) + (let (result) + (mapatoms + (lambda (s) + (push (funcall func (if mailbox-decoder + (funcall mailbox-decoder (symbol-name s)) + (symbol-name s))) result)) + imap-mailbox-data) + result))) + +(defun imap-mailbox-map (func &optional buffer) + "Map a function across each mailbox in `imap-mailbox-data', returning a list. +Function should take a mailbox name (a string) as +the only argument." + (imap-mailbox-map-1 func 'imap-utf7-decode buffer)) + +(defun imap-current-mailbox (&optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (imap-utf7-decode imap-current-mailbox))) + +(defun imap-current-mailbox-p-1 (mailbox &optional examine) + (and (string= mailbox imap-current-mailbox) + (or (and examine + (eq imap-state 'examine)) + (and (not examine) + (eq imap-state 'selected))))) + +(defun imap-current-mailbox-p (mailbox &optional examine buffer) + (with-current-buffer (or buffer (current-buffer)) + (imap-current-mailbox-p-1 (imap-utf7-encode mailbox) examine))) + +(defun imap-mailbox-select-1 (mailbox &optional examine) + "Select MAILBOX on server in BUFFER. +If EXAMINE is non-nil, do a read-only select." + (if (imap-current-mailbox-p-1 mailbox examine) + imap-current-mailbox + (setq imap-current-mailbox mailbox) + (if (imap-ok-p (imap-send-command-wait + (concat (if examine "EXAMINE" "SELECT") " \"" + mailbox "\""))) + (progn + (setq imap-message-data (make-vector imap-message-prime 0) + imap-state (if examine 'examine 'selected)) + imap-current-mailbox) + ;; Failed SELECT/EXAMINE unselects current mailbox + (setq imap-current-mailbox nil)))) + +(defun imap-mailbox-select (mailbox &optional examine buffer) + (with-current-buffer (or buffer (current-buffer)) + (imap-utf7-decode + (imap-mailbox-select-1 (imap-utf7-encode mailbox) examine)))) + +(defun imap-mailbox-examine-1 (mailbox &optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (imap-mailbox-select-1 mailbox 'exmine))) + +(defun imap-mailbox-examine (mailbox &optional buffer) + "Examine MAILBOX on server in BUFFER." + (imap-mailbox-select mailbox 'exmine buffer)) + +(defun imap-mailbox-unselect (&optional buffer) + "Close current folder in BUFFER, without expunging articles." + (with-current-buffer (or buffer (current-buffer)) + (when (or (eq imap-state 'auth) + (and (imap-capability 'UNSELECT) + (imap-ok-p (imap-send-command-wait "UNSELECT"))) + (and (imap-ok-p + (imap-send-command-wait (concat "EXAMINE \"" + imap-current-mailbox + "\""))) + (imap-ok-p (imap-send-command-wait "CLOSE")))) + (setq imap-current-mailbox nil + imap-message-data nil + imap-state 'auth) + t))) + +(defun imap-mailbox-expunge (&optional buffer) + "Expunge articles in current folder in BUFFER. +If BUFFER is nil the current buffer is assumed." + (with-current-buffer (or buffer (current-buffer)) + (when (and imap-current-mailbox (not (eq imap-state 'examine))) + (imap-ok-p (imap-send-command-wait "EXPUNGE"))))) + +(defun imap-mailbox-close (&optional buffer) + "Expunge articles and close current folder in BUFFER. +If BUFFER is nil the current buffer is assumed." + (with-current-buffer (or buffer (current-buffer)) + (when (and imap-current-mailbox + (imap-ok-p (imap-send-command-wait "CLOSE"))) + (setq imap-current-mailbox nil + imap-message-data nil + imap-state 'auth) + t))) + +(defun imap-mailbox-create-1 (mailbox) + (imap-ok-p (imap-send-command-wait (list "CREATE \"" mailbox "\"")))) + +(defun imap-mailbox-create (mailbox &optional buffer) + "Create MAILBOX on server in BUFFER. +If BUFFER is nil the current buffer is assumed." + (with-current-buffer (or buffer (current-buffer)) + (imap-mailbox-create-1 (imap-utf7-encode mailbox)))) + +(defun imap-mailbox-delete (mailbox &optional buffer) + "Delete MAILBOX on server in BUFFER. +If BUFFER is nil the current buffer is assumed." + (let ((mailbox (imap-utf7-encode mailbox))) + (with-current-buffer (or buffer (current-buffer)) + (imap-ok-p + (imap-send-command-wait (list "DELETE \"" mailbox "\"")))))) + +(defun imap-mailbox-rename (oldname newname &optional buffer) + "Rename mailbox OLDNAME to NEWNAME on server in BUFFER. +If BUFFER is nil the current buffer is assumed." + (let ((oldname (imap-utf7-encode oldname)) + (newname (imap-utf7-encode newname))) + (with-current-buffer (or buffer (current-buffer)) + (imap-ok-p + (imap-send-command-wait (list "RENAME \"" oldname "\" " + "\"" newname "\"")))))) + +(defun imap-mailbox-lsub (&optional root reference add-delimiter buffer) + "Return a list of subscribed mailboxes on server in BUFFER. +If ROOT is non-nil, only list matching mailboxes. If ADD-DELIMITER is +non-nil, a hierarchy delimiter is added to root. REFERENCE is a +implementation-specific string that has to be passed to lsub command." + (with-current-buffer (or buffer (current-buffer)) + ;; Make sure we know the hierarchy separator for root's hierarchy + (when (and add-delimiter (null (imap-mailbox-get-1 'delimiter root))) + (imap-send-command-wait (concat "LIST \"" reference "\" \"" + (imap-utf7-encode root) "\""))) + ;; clear list data (NB not delimiter and other stuff) + (imap-mailbox-map-1 (lambda (mailbox) + (imap-mailbox-put 'lsub nil mailbox))) + (when (imap-ok-p + (imap-send-command-wait + (concat "LSUB \"" reference "\" \"" (imap-utf7-encode root) + (and add-delimiter (imap-mailbox-get-1 'delimiter root)) + "%\""))) + (let (out) + (imap-mailbox-map-1 (lambda (mailbox) + (when (imap-mailbox-get-1 'lsub mailbox) + (push (imap-utf7-decode mailbox) out)))) + (nreverse out))))) + +(defun imap-mailbox-list (root &optional reference add-delimiter buffer) + "Return a list of mailboxes matching ROOT on server in BUFFER. +If ADD-DELIMITER is non-nil, a hierarchy delimiter is added to +root. REFERENCE is a implementation-specific string that has to be +passed to list command." + (with-current-buffer (or buffer (current-buffer)) + ;; Make sure we know the hierarchy separator for root's hierarchy + (when (and add-delimiter (null (imap-mailbox-get-1 'delimiter root))) + (imap-send-command-wait (concat "LIST \"" reference "\" \"" + (imap-utf7-encode root) "\""))) + ;; clear list data (NB not delimiter and other stuff) + (imap-mailbox-map-1 (lambda (mailbox) + (imap-mailbox-put 'list nil mailbox))) + (when (imap-ok-p + (imap-send-command-wait + (concat "LIST \"" reference "\" \"" (imap-utf7-encode root) + (and add-delimiter (imap-mailbox-get-1 'delimiter root)) + "%\""))) + (let (out) + (imap-mailbox-map-1 (lambda (mailbox) + (when (imap-mailbox-get-1 'list mailbox) + (push (imap-utf7-decode mailbox) out)))) + (nreverse out))))) + +(defun imap-mailbox-subscribe (mailbox &optional buffer) + "Send the SUBSCRIBE command on the mailbox to server in BUFFER. +Returns non-nil if successful." + (with-current-buffer (or buffer (current-buffer)) + (imap-ok-p (imap-send-command-wait (concat "SUBSCRIBE \"" + (imap-utf7-encode mailbox) + "\""))))) + +(defun imap-mailbox-unsubscribe (mailbox &optional buffer) + "Send the SUBSCRIBE command on the mailbox to server in BUFFER. +Returns non-nil if successful." + (with-current-buffer (or buffer (current-buffer)) + (imap-ok-p (imap-send-command-wait (concat "UNSUBSCRIBE " + (imap-utf7-encode mailbox) + "\""))))) + +(defun imap-mailbox-status (mailbox items &optional buffer) + "Get status items ITEM in MAILBOX from server in BUFFER. +ITEMS can be a symbol or a list of symbols, valid symbols are one of +the STATUS data items -- ie 'messages, 'recent, 'uidnext, 'uidvalidity +or 'unseen. If ITEMS is a list of symbols, a list of values is +returned, if ITEMS is a symbol only it's value is returned." + (with-current-buffer (or buffer (current-buffer)) + (when (imap-ok-p + (imap-send-command-wait (list "STATUS \"" + (imap-utf7-encode mailbox) + "\" " + (format "%s" + (if (listp items) + items + (list items)))))) + (if (listp items) + (mapcar (lambda (item) + (imap-mailbox-get item mailbox)) + items) + (imap-mailbox-get items mailbox))))) + +(defun imap-mailbox-acl-get (&optional mailbox buffer) + "Get ACL on mailbox from server in BUFFER." + (let ((mailbox (imap-utf7-encode mailbox))) + (with-current-buffer (or buffer (current-buffer)) + (when (imap-ok-p + (imap-send-command-wait (list "GETACL \"" + (or mailbox imap-current-mailbox) + "\""))) + (imap-mailbox-get-1 'acl (or mailbox imap-current-mailbox)))))) + +(defun imap-mailbox-acl-set (identifier rights &optional mailbox buffer) + "Change/set ACL for IDENTIFIER to RIGHTS in MAILBOX from server in BUFFER." + (let ((mailbox (imap-utf7-encode mailbox))) + (with-current-buffer (or buffer (current-buffer)) + (imap-ok-p + (imap-send-command-wait (list "SETACL \"" + (or mailbox imap-current-mailbox) + "\" " + identifier + " " + rights)))))) + +(defun imap-mailbox-acl-delete (identifier &optional mailbox buffer) + "Removes any pair for IDENTIFIER in MAILBOX from server in BUFFER." + (let ((mailbox (imap-utf7-encode mailbox))) + (with-current-buffer (or buffer (current-buffer)) + (imap-ok-p + (imap-send-command-wait (list "DELETEACL \"" + (or mailbox imap-current-mailbox) + "\" " + identifier)))))) + + +;; Message functions: + +(defun imap-current-message (&optional buffer) + (with-current-buffer (or buffer (current-buffer)) + imap-current-message)) + +(defun imap-list-to-message-set (list) + (mapconcat (lambda (item) + (number-to-string item)) + (if (listp list) + list + (list list)) + ",")) + +(defun imap-range-to-message-set (range) + (mapconcat + (lambda (item) + (if (consp item) + (format "%d:%d" + (car item) (cdr item)) + (format "%d" item))) + (if (and (listp range) (not (listp (cdr range)))) + (list range) ;; make (1 . 2) into ((1 . 2)) + range) + ",")) + +(defun imap-fetch-asynch (uids props &optional nouidfetch buffer) + (with-current-buffer (or buffer (current-buffer)) + (imap-send-command (format "%sFETCH %s %s" (if nouidfetch "" "UID ") + (if (listp uids) + (imap-list-to-message-set uids) + uids) + props)))) + +(defun imap-fetch (uids props &optional receive nouidfetch buffer) + "Fetch properties PROPS from message set UIDS from server in BUFFER. +UIDS can be a string, number or a list of numbers. If RECEIVE +is non-nil return theese properties." + (with-current-buffer (or buffer (current-buffer)) + (when (imap-ok-p (imap-send-command-wait + (format "%sFETCH %s %s" (if nouidfetch "" "UID ") + (if (listp uids) + (imap-list-to-message-set uids) + uids) + props))) + (if (or (null receive) (stringp uids)) + t + (if (listp uids) + (mapcar (lambda (uid) + (if (listp receive) + (mapcar (lambda (prop) + (imap-message-get uid prop)) + receive) + (imap-message-get uid receive))) + uids) + (imap-message-get uids receive)))))) + +(defun imap-message-put (uid propname value &optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (if imap-message-data + (put (intern (number-to-string uid) imap-message-data) + propname value) + (error "Imap-message-data is nil, uid %s prop %s value %s buffer %s" + uid propname value (current-buffer))) + t)) + +(defun imap-message-get (uid propname &optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (get (intern-soft (number-to-string uid) imap-message-data) + propname))) + +(defun imap-message-map (func propname &optional buffer) + "Map a function across each mailbox in `imap-message-data', returning a list." + (with-current-buffer (or buffer (current-buffer)) + (let (result) + (mapatoms + (lambda (s) + (push (funcall func (get s 'UID) (get s propname)) result)) + imap-message-data) + result))) + +(defmacro imap-message-envelope-date (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (elt (imap-message-get ,uid 'ENVELOPE) 0))) + +(defmacro imap-message-envelope-subject (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (elt (imap-message-get ,uid 'ENVELOPE) 1))) + +(defmacro imap-message-envelope-from (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (elt (imap-message-get ,uid 'ENVELOPE) 2))) + +(defmacro imap-message-envelope-sender (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (elt (imap-message-get ,uid 'ENVELOPE) 3))) + +(defmacro imap-message-envelope-reply-to (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (elt (imap-message-get ,uid 'ENVELOPE) 4))) + +(defmacro imap-message-envelope-to (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (elt (imap-message-get ,uid 'ENVELOPE) 5))) + +(defmacro imap-message-envelope-cc (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (elt (imap-message-get ,uid 'ENVELOPE) 6))) + +(defmacro imap-message-envelope-bcc (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (elt (imap-message-get ,uid 'ENVELOPE) 7))) + +(defmacro imap-message-envelope-in-reply-to (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (elt (imap-message-get ,uid 'ENVELOPE) 8))) + +(defmacro imap-message-envelope-message-id (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (elt (imap-message-get ,uid 'ENVELOPE) 9))) + +(defmacro imap-message-body (uid &optional buffer) + `(with-current-buffer (or ,buffer (current-buffer)) + (imap-message-get ,uid 'BODY))) + +(defun imap-search (predicate &optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (imap-mailbox-put 'search 'dummy) + (when (imap-ok-p (imap-send-command-wait (concat "UID SEARCH " predicate))) + (if (eq (imap-mailbox-get-1 'search imap-current-mailbox) 'dummy) + (error "Missing SEARCH response to a SEARCH command") + (imap-mailbox-get-1 'search imap-current-mailbox))))) + +(defun imap-message-flag-permanent-p (flag &optional mailbox buffer) + "Return t iff FLAG can be permanently (between IMAP sessions) saved on articles, in MAILBOX on server in BUFFER." + (with-current-buffer (or buffer (current-buffer)) + (or (member "\\*" (imap-mailbox-get 'permanentflags mailbox)) + (member flag (imap-mailbox-get 'permanentflags mailbox))))) + +(defun imap-message-flags-set (articles flags &optional silent buffer) + (when (and articles flags) + (with-current-buffer (or buffer (current-buffer)) + (imap-ok-p (imap-send-command-wait + (concat "UID STORE " articles + " FLAGS" (if silent ".SILENT") " (" flags ")")))))) + +(defun imap-message-flags-del (articles flags &optional silent buffer) + (when (and articles flags) + (with-current-buffer (or buffer (current-buffer)) + (imap-ok-p (imap-send-command-wait + (concat "UID STORE " articles + " -FLAGS" (if silent ".SILENT") " (" flags ")")))))) + +(defun imap-message-flags-add (articles flags &optional silent buffer) + (when (and articles flags) + (with-current-buffer (or buffer (current-buffer)) + (imap-ok-p (imap-send-command-wait + (concat "UID STORE " articles + " +FLAGS" (if silent ".SILENT") " (" flags ")")))))) + +(defun imap-message-copyuid-1 (mailbox) + (if (imap-capability 'UIDPLUS) + (list (nth 0 (imap-mailbox-get-1 'copyuid mailbox)) + (string-to-number (nth 2 (imap-mailbox-get-1 'copyuid mailbox)))) + (let ((old-mailbox imap-current-mailbox) + (state imap-state) + (imap-message-data (make-vector 2 0))) + (when (imap-mailbox-examine-1 mailbox) + (prog1 + (and (imap-fetch "*" "UID") + (list (imap-mailbox-get-1 'uidvalidity mailbox) + (apply 'max (imap-message-map + (lambda (uid prop) uid) 'UID)))) + (if old-mailbox + (imap-mailbox-select old-mailbox (eq state 'examine)) + (imap-mailbox-unselect))))))) + +(defun imap-message-copyuid (mailbox &optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (imap-message-copyuid-1 (imap-utf7-decode mailbox)))) + +(defun imap-message-copy (articles mailbox + &optional dont-create no-copyuid buffer) + "Copy ARTICLES (a string message set) to MAILBOX on server in +BUFFER, creating mailbox if it doesn't exist. If dont-create is +non-nil, it will not create a mailbox. On success, return a list with +the UIDVALIDITY of the mailbox the article(s) was copied to as the +first element, rest of list contain the saved articles' UIDs." + (when articles + (with-current-buffer (or buffer (current-buffer)) + (let ((mailbox (imap-utf7-encode mailbox))) + (if (let ((cmd (concat "UID COPY " articles " \"" mailbox "\"")) + (imap-current-target-mailbox mailbox)) + (if (imap-ok-p (imap-send-command-wait cmd)) + t + (when (and (not dont-create) + (imap-mailbox-get-1 'trycreate mailbox)) + (imap-mailbox-create-1 mailbox) + (imap-ok-p (imap-send-command-wait cmd))))) + (or no-copyuid + (imap-message-copyuid-1 mailbox))))))) + +(defun imap-message-appenduid-1 (mailbox) + (if (imap-capability 'UIDPLUS) + (imap-mailbox-get-1 'appenduid mailbox) + (let ((old-mailbox imap-current-mailbox) + (state imap-state) + (imap-message-data (make-vector 2 0))) + (when (imap-mailbox-examine-1 mailbox) + (prog1 + (and (imap-fetch "*" "UID") + (list (imap-mailbox-get-1 'uidvalidity mailbox) + (apply 'max (imap-message-map + (lambda (uid prop) uid) 'UID)))) + (if old-mailbox + (imap-mailbox-select old-mailbox (eq state 'examine)) + (imap-mailbox-unselect))))))) + +(defun imap-message-appenduid (mailbox &optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (imap-message-appenduid-1 (imap-utf7-encode mailbox)))) + +(defun imap-message-append (mailbox article &optional flags date-time buffer) + "Append ARTICLE (a buffer) to MAILBOX on server in BUFFER. +FLAGS and DATE-TIME is currently not used. Return a cons holding +uidvalidity of MAILBOX and UID the newly created article got, or nil +on failure." + (let ((mailbox (imap-utf7-encode mailbox))) + (with-current-buffer (or buffer (current-buffer)) + (and (let ((imap-current-target-mailbox mailbox)) + (imap-ok-p + (imap-send-command-wait + (list "APPEND \"" mailbox "\" " article)))) + (imap-message-appenduid-1 mailbox))))) + +(defun imap-body-lines (body) + "Return number of lines in article by looking at the mime bodystructure BODY." + (if (listp body) + (if (stringp (car body)) + (cond ((and (string= (upcase (car body)) "TEXT") + (numberp (nth 7 body))) + (nth 7 body)) + ((and (string= (upcase (car body)) "MESSAGE") + (numberp (nth 9 body))) + (nth 9 body)) + (t 0)) + (apply '+ (mapcar 'imap-body-lines body))) + 0)) + +(defun imap-envelope-from (from) + "Return a from string line." + (and from + (concat (aref from 0) + (if (aref from 0) " <") + (aref from 2) + "@" + (aref from 3) + (if (aref from 0) ">")))) + + +;; Internal functions. + +(defun imap-send-command-1 (cmdstr) + (setq cmdstr (concat cmdstr imap-client-eol)) + (and imap-log + (with-current-buffer (get-buffer-create imap-log) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert cmdstr))) + (process-send-string imap-process cmdstr)) + +(defun imap-send-command (command &optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (if (not (listp command)) (setq command (list command))) + (let ((tag (setq imap-tag (1+ imap-tag))) + cmd cmdstr) + (setq cmdstr (concat (number-to-string imap-tag) " ")) + (while (setq cmd (pop command)) + (cond ((stringp cmd) + (setq cmdstr (concat cmdstr cmd))) + ((bufferp cmd) + (let ((eol imap-client-eol) + (calcfirst imap-calculate-literal-size-first) + size) + (with-current-buffer cmd + (if calcfirst + (setq size (buffer-size))) + (when (not (equal eol "\r\n")) + ;; XXX modifies buffer! + (goto-char (point-min)) + (while (search-forward "\r\n" nil t) + (replace-match eol))) + (if (not calcfirst) + (setq size (buffer-size)))) + (setq cmdstr + (concat cmdstr (format "{%d}" size)))) + (unwind-protect + (progn + (imap-send-command-1 cmdstr) + (setq cmdstr nil) + (if (not (eq (imap-wait-for-tag tag) 'INCOMPLETE)) + (setq command nil);; abort command if no cont-req + (let ((process imap-process) + (stream imap-stream) + (eol imap-client-eol)) + (with-current-buffer cmd + (and imap-log + (with-current-buffer (get-buffer-create + imap-log) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert-buffer-substring cmd))) + (process-send-region process (point-min) + (point-max))) + (process-send-string process imap-client-eol)))) + (setq imap-continuation nil))) + ((functionp cmd) + (imap-send-command-1 cmdstr) + (setq cmdstr nil) + (unwind-protect + (if (not (eq (imap-wait-for-tag tag) 'INCOMPLETE)) + (setq command nil);; abort command if no cont-req + (setq command (cons (funcall cmd imap-continuation) + command))) + (setq imap-continuation nil))) + (t + (error "Unknown command type")))) + (if cmdstr + (imap-send-command-1 cmdstr)) + tag))) + +(defun imap-wait-for-tag (tag &optional buffer) + (with-current-buffer (or buffer (current-buffer)) + (while (and (null imap-continuation) + (< imap-reached-tag tag)) + (or (and (not (memq (process-status imap-process) '(open run))) + (sit-for 1)) + (accept-process-output imap-process 1))) + (or (assq tag imap-failed-tags) + (if imap-continuation + 'INCOMPLETE + 'OK)))) + +(defun imap-sentinel (process string) + (delete-process process)) + +(defun imap-find-next-line () + "Return point at end of current line, taking into account literals. +Return nil if no complete line has arrived." + (when (re-search-forward (concat imap-server-eol "\\|{\\([0-9]+\\)}" + imap-server-eol) + nil t) + (if (match-string 1) + (if (< (point-max) (+ (point) (string-to-number (match-string 1)))) + nil + (goto-char (+ (point) (string-to-number (match-string 1)))) + (imap-find-next-line)) + (point)))) + +(defun imap-arrival-filter (proc string) + "IMAP process filter." + (with-current-buffer (process-buffer proc) + (goto-char (point-max)) + (insert string) + (and imap-log + (with-current-buffer (get-buffer-create imap-log) + (imap-disable-multibyte) + (buffer-disable-undo) + (goto-char (point-max)) + (insert string))) + (let (end) + (goto-char (point-min)) + (while (setq end (imap-find-next-line)) + (save-restriction + (narrow-to-region (point-min) end) + (delete-backward-char (length imap-server-eol)) + (goto-char (point-min)) + (unwind-protect + (cond ((eq imap-state 'initial) + (imap-parse-greeting)) + ((or (eq imap-state 'auth) + (eq imap-state 'nonauth) + (eq imap-state 'selected) + (eq imap-state 'examine)) + (imap-parse-response)) + (t + (message "Unknown state %s in arrival filter" + imap-state))) + (delete-region (point-min) (point-max)))))))) + + +;; Imap parser. + +(defsubst imap-forward () + (or (eobp) (forward-char))) + +;; number = 1*DIGIT +;; ; Unsigned 32-bit integer +;; ; (0 <= n < 4,294,967,296) + +(defsubst imap-parse-number () + (when (looking-at "[0-9]+") + (prog1 + (string-to-number (match-string 0)) + (goto-char (match-end 0))))) + +;; literal = "{" number "}" CRLF *CHAR8 +;; ; Number represents the number of CHAR8s + +(defsubst imap-parse-literal () + (when (looking-at "{\\([0-9]+\\)}\r\n") + (let ((pos (match-end 0)) + (len (string-to-number (match-string 1)))) + (if (< (point-max) (+ pos len)) + nil + (goto-char (+ pos len)) + (buffer-substring pos (+ pos len)))))) + +;; string = quoted / literal +;; +;; quoted = DQUOTE *QUOTED-CHAR DQUOTE +;; +;; QUOTED-CHAR = / +;; "\" quoted-specials +;; +;; quoted-specials = DQUOTE / "\" +;; +;; TEXT-CHAR = + +(defsubst imap-parse-string () + (cond ((eq (char-after) ?\") + (forward-char 1) + (let ((p (point)) (name "")) + (skip-chars-forward "^\"\\\\") + (setq name (buffer-substring p (point))) + (while (eq (char-after) ?\\) + (setq p (1+ (point))) + (forward-char 2) + (skip-chars-forward "^\"\\\\") + (setq name (concat name (buffer-substring p (point))))) + (forward-char 1) + name)) + ((eq (char-after) ?{) + (imap-parse-literal)))) + +;; nil = "NIL" + +(defsubst imap-parse-nil () + (if (looking-at "NIL") + (goto-char (match-end 0)))) + +;; nstring = string / nil + +(defsubst imap-parse-nstring () + (or (imap-parse-string) + (and (imap-parse-nil) + nil))) + +;; astring = atom / string +;; +;; atom = 1*ATOM-CHAR +;; +;; ATOM-CHAR = +;; +;; atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards / +;; quoted-specials +;; +;; list-wildcards = "%" / "*" +;; +;; quoted-specials = DQUOTE / "\" + +(defsubst imap-parse-astring () + (or (imap-parse-string) + (buffer-substring (point) + (if (re-search-forward "[(){ \r\n%*\"\\]" nil t) + (goto-char (1- (match-end 0))) + (end-of-line) + (point))))) + +;; address = "(" addr-name SP addr-adl SP addr-mailbox SP +;; addr-host ")" +;; +;; addr-adl = nstring +;; ; Holds route from [RFC-822] route-addr if +;; ; non-NIL +;; +;; addr-host = nstring +;; ; NIL indicates [RFC-822] group syntax. +;; ; Otherwise, holds [RFC-822] domain name +;; +;; addr-mailbox = nstring +;; ; NIL indicates end of [RFC-822] group; if +;; ; non-NIL and addr-host is NIL, holds +;; ; [RFC-822] group name. +;; ; Otherwise, holds [RFC-822] local-part +;; ; after removing [RFC-822] quoting +;; +;; addr-name = nstring +;; ; If non-NIL, holds phrase from [RFC-822] +;; ; mailbox after removing [RFC-822] quoting +;; + +(defsubst imap-parse-address () + (let (address) + (when (eq (char-after) ?\() + (imap-forward) + (setq address (vector (prog1 (imap-parse-nstring) + (imap-forward)) + (prog1 (imap-parse-nstring) + (imap-forward)) + (prog1 (imap-parse-nstring) + (imap-forward)) + (imap-parse-nstring))) + (when (eq (char-after) ?\)) + (imap-forward) + address)))) + +;; address-list = "(" 1*address ")" / nil +;; +;; nil = "NIL" + +(defsubst imap-parse-address-list () + (if (eq (char-after) ?\() + (let (address addresses) + (imap-forward) + (while (and (not (eq (char-after) ?\))) + ;; next line for MS Exchange bug + (progn (and (eq (char-after) ? ) (imap-forward)) t) + (setq address (imap-parse-address))) + (setq addresses (cons address addresses))) + (when (eq (char-after) ?\)) + (imap-forward) + (nreverse addresses))) + (assert (imap-parse-nil)))) + +;; mailbox = "INBOX" / astring +;; ; INBOX is case-insensitive. All case variants of +;; ; INBOX (e.g. "iNbOx") MUST be interpreted as INBOX +;; ; not as an astring. An astring which consists of +;; ; the case-insensitive sequence "I" "N" "B" "O" "X" +;; ; is considered to be INBOX and not an astring. +;; ; Refer to section 5.1 for further +;; ; semantic details of mailbox names. + +(defsubst imap-parse-mailbox () + (let ((mailbox (imap-parse-astring))) + (if (string-equal "INBOX" (upcase mailbox)) + "INBOX" + mailbox))) + +;; greeting = "*" SP (resp-cond-auth / resp-cond-bye) CRLF +;; +;; resp-cond-auth = ("OK" / "PREAUTH") SP resp-text +;; ; Authentication condition +;; +;; resp-cond-bye = "BYE" SP resp-text + +(defun imap-parse-greeting () + "Parse a IMAP greeting." + (cond ((looking-at "\\* OK ") + (setq imap-state 'nonauth)) + ((looking-at "\\* PREAUTH ") + (setq imap-state 'auth)) + ((looking-at "\\* BYE ") + (setq imap-state 'closed)))) + +;; response = *(continue-req / response-data) response-done +;; +;; continue-req = "+" SP (resp-text / base64) CRLF +;; +;; response-data = "*" SP (resp-cond-state / resp-cond-bye / +;; mailbox-data / message-data / capability-data) CRLF +;; +;; response-done = response-tagged / response-fatal +;; +;; response-fatal = "*" SP resp-cond-bye CRLF +;; ; Server closes connection immediately +;; +;; response-tagged = tag SP resp-cond-state CRLF +;; +;; resp-cond-state = ("OK" / "NO" / "BAD") SP resp-text +;; ; Status condition +;; +;; resp-cond-bye = "BYE" SP resp-text +;; +;; mailbox-data = "FLAGS" SP flag-list / +;; "LIST" SP mailbox-list / +;; "LSUB" SP mailbox-list / +;; "SEARCH" *(SP nz-number) / +;; "STATUS" SP mailbox SP "(" +;; [status-att SP number *(SP status-att SP number)] ")" / +;; number SP "EXISTS" / +;; number SP "RECENT" +;; +;; message-data = nz-number SP ("EXPUNGE" / ("FETCH" SP msg-att)) +;; +;; capability-data = "CAPABILITY" *(SP capability) SP "IMAP4rev1" +;; *(SP capability) +;; ; IMAP4rev1 servers which offer RFC 1730 +;; ; compatibility MUST list "IMAP4" as the first +;; ; capability. + +(defun imap-parse-response () + "Parse a IMAP command response." + (let (token) + (case (setq token (read (current-buffer))) + (+ (setq imap-continuation + (or (buffer-substring (min (point-max) (1+ (point))) + (point-max)) + t))) + (* (case (prog1 (setq token (read (current-buffer))) + (imap-forward)) + (OK (imap-parse-resp-text)) + (NO (imap-parse-resp-text)) + (BAD (imap-parse-resp-text)) + (BYE (imap-parse-resp-text)) + (FLAGS (imap-mailbox-put 'flags (imap-parse-flag-list))) + (LIST (imap-parse-data-list 'list)) + (LSUB (imap-parse-data-list 'lsub)) + (SEARCH (imap-mailbox-put + 'search + (read (concat "(" (buffer-substring (point) (point-max)) ")")))) + (STATUS (imap-parse-status)) + (CAPABILITY (setq imap-capability + (read (concat "(" (upcase (buffer-substring + (point) (point-max))) + ")")))) + (ACL (imap-parse-acl)) + (t (case (prog1 (read (current-buffer)) + (imap-forward)) + (EXISTS (imap-mailbox-put 'exists token)) + (RECENT (imap-mailbox-put 'recent token)) + (EXPUNGE t) + (FETCH (imap-parse-fetch token)) + (t (message "Garbage: %s" (buffer-string))))))) + (t (let (status) + (if (not (integerp token)) + (message "Garbage: %s" (buffer-string)) + (case (prog1 (setq status (read (current-buffer))) + (imap-forward)) + (OK (progn + (setq imap-reached-tag (max imap-reached-tag token)) + (imap-parse-resp-text))) + (NO (progn + (setq imap-reached-tag (max imap-reached-tag token)) + (save-excursion + (imap-parse-resp-text)) + (let (code text) + (when (eq (char-after) ?\[) + (setq code (buffer-substring (point) + (search-forward "]"))) + (imap-forward)) + (setq text (buffer-substring (point) (point-max))) + (push (list token status code text) + imap-failed-tags)))) + (BAD (progn + (setq imap-reached-tag (max imap-reached-tag token)) + (save-excursion + (imap-parse-resp-text)) + (let (code text) + (when (eq (char-after) ?\[) + (setq code (buffer-substring (point) + (search-forward "]"))) + (imap-forward)) + (setq text (buffer-substring (point) (point-max))) + (push (list token status code text) imap-failed-tags) + (error "Internal error, tag %s status %s code %s text %s" + token status code text)))) + (t (message "Garbage: %s" (buffer-string)))))))))) + +;; resp-text = ["[" resp-text-code "]" SP] text +;; +;; text = 1*TEXT-CHAR +;; +;; TEXT-CHAR = + +(defun imap-parse-resp-text () + (imap-parse-resp-text-code)) + +;; resp-text-code = "ALERT" / +;; "BADCHARSET [SP "(" astring *(SP astring) ")" ] / +;; "NEWNAME" SP string SP string / +;; "PARSE" / +;; "PERMANENTFLAGS" SP "(" +;; [flag-perm *(SP flag-perm)] ")" / +;; "READ-ONLY" / +;; "READ-WRITE" / +;; "TRYCREATE" / +;; "UIDNEXT" SP nz-number / +;; "UIDVALIDITY" SP nz-number / +;; "UNSEEN" SP nz-number / +;; resp-text-atom [SP 1*] +;; +;; resp_code_apnd = "APPENDUID" SPACE nz_number SPACE uniqueid +;; +;; resp_code_copy = "COPYUID" SPACE nz_number SPACE set SPACE set +;; +;; set = sequence-num / (sequence-num ":" sequence-num) / +;; (set "," set) +;; ; Identifies a set of messages. For message +;; ; sequence numbers, these are consecutive +;; ; numbers from 1 to the number of messages in +;; ; the mailbox +;; ; Comma delimits individual numbers, colon +;; ; delimits between two numbers inclusive. +;; ; Example: 2,4:7,9,12:* is 2,4,5,6,7,9,12,13, +;; ; 14,15 for a mailbox with 15 messages. +;; +;; sequence-num = nz-number / "*" +;; ; * is the largest number in use. For message +;; ; sequence numbers, it is the number of messages +;; ; in the mailbox. For unique identifiers, it is +;; ; the unique identifier of the last message in +;; ; the mailbox. +;; +;; flag-perm = flag / "\*" +;; +;; flag = "\Answered" / "\Flagged" / "\Deleted" / +;; "\Seen" / "\Draft" / flag-keyword / flag-extension +;; ; Does not include "\Recent" +;; +;; flag-extension = "\" atom +;; ; Future expansion. Client implementations +;; ; MUST accept flag-extension flags. Server +;; ; implementations MUST NOT generate +;; ; flag-extension flags except as defined by +;; ; future standard or standards-track +;; ; revisions of this specification. +;; +;; flag-keyword = atom +;; +;; resp-text-atom = 1* + +(defun imap-parse-resp-text-code () + (when (eq (char-after) ?\[) + (imap-forward) + (cond ((search-forward "PERMANENTFLAGS " nil t) + (imap-mailbox-put 'permanentflags (imap-parse-flag-list))) + ((search-forward "UIDNEXT " nil t) + (imap-mailbox-put 'uidnext (read (current-buffer)))) + ((search-forward "UNSEEN " nil t) + (imap-mailbox-put 'unseen (read (current-buffer)))) + ((looking-at "UIDVALIDITY \\([0-9]+\\)") + (imap-mailbox-put 'uidvalidity (match-string 1))) + ((search-forward "READ-ONLY" nil t) + (imap-mailbox-put 'read-only t)) + ((search-forward "NEWNAME " nil t) + (let (oldname newname) + (setq oldname (imap-parse-string)) + (imap-forward) + (setq newname (imap-parse-string)) + (imap-mailbox-put 'newname newname oldname))) + ((search-forward "TRYCREATE" nil t) + (imap-mailbox-put 'trycreate t imap-current-target-mailbox)) + ((looking-at "APPENDUID \\([0-9]+\\) \\([0-9]+\\)") + (imap-mailbox-put 'appenduid + (list (match-string 1) + (string-to-number (match-string 2))) + imap-current-target-mailbox)) + ((looking-at "COPYUID \\([0-9]+\\) \\([0-9,:]+\\) \\([0-9,:]+\\)") + (imap-mailbox-put 'copyuid (list (match-string 1) + (match-string 2) + (match-string 3)) + imap-current-target-mailbox)) + ((search-forward "ALERT] " nil t) + (message "Imap server %s information: %s" imap-server + (buffer-substring (point) (point-max))))))) + +;; mailbox-list = "(" [mbx-list-flags] ")" SP +;; (DQUOTE QUOTED-CHAR DQUOTE / nil) SP mailbox +;; +;; mbx-list-flags = *(mbx-list-oflag SP) mbx-list-sflag +;; *(SP mbx-list-oflag) / +;; mbx-list-oflag *(SP mbx-list-oflag) +;; +;; mbx-list-oflag = "\Noinferiors" / flag-extension +;; ; Other flags; multiple possible per LIST response +;; +;; mbx-list-sflag = "\Noselect" / "\Marked" / "\Unmarked" +;; ; Selectability flags; only one per LIST response +;; +;; QUOTED-CHAR = / +;; "\" quoted-specials +;; +;; quoted-specials = DQUOTE / "\" + +(defun imap-parse-data-list (type) + (let (flags delimiter mailbox) + (setq flags (imap-parse-flag-list)) + (when (looking-at " NIL\\| \"\\\\?\\(.\\)\"") + (setq delimiter (match-string 1)) + (goto-char (1+ (match-end 0))) + (when (setq mailbox (imap-parse-mailbox)) + (imap-mailbox-put type t mailbox) + (imap-mailbox-put 'list-flags flags mailbox) + (imap-mailbox-put 'delimiter delimiter mailbox))))) + +;; msg_att ::= "(" 1#("ENVELOPE" SPACE envelope / +;; "FLAGS" SPACE "(" #(flag / "\Recent") ")" / +;; "INTERNALDATE" SPACE date_time / +;; "RFC822" [".HEADER" / ".TEXT"] SPACE nstring / +;; "RFC822.SIZE" SPACE number / +;; "BODY" ["STRUCTURE"] SPACE body / +;; "BODY" section ["<" number ">"] SPACE nstring / +;; "UID" SPACE uniqueid) ")" +;; +;; date_time ::= <"> date_day_fixed "-" date_month "-" date_year +;; SPACE time SPACE zone <"> +;; +;; section ::= "[" [section_text / (nz_number *["." nz_number] +;; ["." (section_text / "MIME")])] "]" +;; +;; section_text ::= "HEADER" / "HEADER.FIELDS" [".NOT"] +;; SPACE header_list / "TEXT" +;; +;; header_fld_name ::= astring +;; +;; header_list ::= "(" 1#header_fld_name ")" + +(defsubst imap-parse-header-list () + (when (eq (char-after) ?\() + (let (strlist) + (while (not (eq (char-after) ?\))) + (imap-forward) + (push (imap-parse-astring) strlist)) + (imap-forward) + (nreverse strlist)))) + +(defsubst imap-parse-fetch-body-section () + (let ((section + (buffer-substring (point) (1- (re-search-forward "[] ]" nil t))))) + (if (eq (char-before) ? ) + (prog1 + (mapconcat 'identity (cons section (imap-parse-header-list)) " ") + (search-forward "]" nil t)) + section))) + +(defun imap-parse-fetch (response) + (when (eq (char-after) ?\() + (let (uid flags envelope internaldate rfc822 rfc822header rfc822text + rfc822size body bodydetail bodystructure) + (while (not (eq (char-after) ?\))) + (imap-forward) + (let ((token (read (current-buffer)))) + (imap-forward) + (cond ((eq token 'UID) + (setq uid (ignore-errors (read (current-buffer))))) + ((eq token 'FLAGS) + (setq flags (imap-parse-flag-list))) + ((eq token 'ENVELOPE) + (setq envelope (imap-parse-envelope))) + ((eq token 'INTERNALDATE) + (setq internaldate (imap-parse-string))) + ((eq token 'RFC822) + (setq rfc822 (imap-parse-nstring))) + ((eq token 'RFC822.HEADER) + (setq rfc822header (imap-parse-nstring))) + ((eq token 'RFC822.TEXT) + (setq rfc822text (imap-parse-nstring))) + ((eq token 'RFC822.SIZE) + (setq rfc822size (read (current-buffer)))) + ((eq token 'BODY) + (if (eq (char-before) ?\[) + (push (list + (upcase (imap-parse-fetch-body-section)) + (and (eq (char-after) ?<) + (buffer-substring (1+ (point)) + (search-forward ">" nil t))) + (progn (imap-forward) + (imap-parse-nstring))) + bodydetail) + (setq body (imap-parse-body)))) + ((eq token 'BODYSTRUCTURE) + (setq bodystructure (imap-parse-body)))))) + (when uid + (setq imap-current-message uid) + (imap-message-put uid 'UID uid) + (and flags (imap-message-put uid 'FLAGS flags)) + (and envelope (imap-message-put uid 'ENVELOPE envelope)) + (and internaldate (imap-message-put uid 'INTERNALDATE internaldate)) + (and rfc822 (imap-message-put uid 'RFC822 rfc822)) + (and rfc822header (imap-message-put uid 'RFC822.HEADER rfc822header)) + (and rfc822text (imap-message-put uid 'RFC822.TEXT rfc822text)) + (and rfc822size (imap-message-put uid 'RFC822.SIZE rfc822size)) + (and body (imap-message-put uid 'BODY body)) + (and bodydetail (imap-message-put uid 'BODYDETAIL bodydetail)) + (and bodystructure (imap-message-put uid 'BODYSTRUCTURE bodystructure)) + (run-hooks 'imap-fetch-data-hook))))) + +;; mailbox-data = ... +;; "STATUS" SP mailbox SP "(" +;; [status-att SP number +;; *(SP status-att SP number)] ")" +;; ... +;; +;; status-att = "MESSAGES" / "RECENT" / "UIDNEXT" / "UIDVALIDITY" / +;; "UNSEEN" + +(defun imap-parse-status () + (let ((mailbox (imap-parse-mailbox))) + (when (and mailbox (search-forward "(" nil t)) + (while (not (eq (char-after) ?\))) + (let ((token (read (current-buffer)))) + (cond ((eq token 'MESSAGES) + (imap-mailbox-put 'messages (read (current-buffer)) mailbox)) + ((eq token 'RECENT) + (imap-mailbox-put 'recent (read (current-buffer)) mailbox)) + ((eq token 'UIDNEXT) + (imap-mailbox-put 'uidnext (read (current-buffer)) mailbox)) + ((eq token 'UIDVALIDITY) + (and (looking-at " \\([0-9]+\\)") + (imap-mailbox-put 'uidvalidity (match-string 1) mailbox) + (goto-char (match-end 1)))) + ((eq token 'UNSEEN) + (imap-mailbox-put 'unseen (read (current-buffer)) mailbox)) + (t + (message "Unknown status data %s in mailbox %s ignored" + token mailbox)))))))) + +;; acl_data ::= "ACL" SPACE mailbox *(SPACE identifier SPACE +;; rights) +;; +;; identifier ::= astring +;; +;; rights ::= astring + +(defun imap-parse-acl () + (let ((mailbox (imap-parse-mailbox)) + identifier rights acl) + (while (eq (char-after) ?\ ) + (imap-forward) + (setq identifier (imap-parse-astring)) + (imap-forward) + (setq rights (imap-parse-astring)) + (setq acl (append acl (list (cons identifier rights))))) + (imap-mailbox-put 'acl acl mailbox))) + +;; flag-list = "(" [flag *(SP flag)] ")" +;; +;; flag = "\Answered" / "\Flagged" / "\Deleted" / +;; "\Seen" / "\Draft" / flag-keyword / flag-extension +;; ; Does not include "\Recent" +;; +;; flag-keyword = atom +;; +;; flag-extension = "\" atom +;; ; Future expansion. Client implementations +;; ; MUST accept flag-extension flags. Server +;; ; implementations MUST NOT generate +;; ; flag-extension flags except as defined by +;; ; future standard or standards-track +;; ; revisions of this specification. + +(defun imap-parse-flag-list () + (let (flag-list start) + (when (eq (char-after) ?\() + (imap-forward) + (while (and (not (eq (char-before) ?\))) + (setq start (point)) + (> (skip-chars-forward "^ )" (gnus-point-at-eol)) 0)) + (push (buffer-substring start (point)) flag-list) + (imap-forward)) + (nreverse flag-list)))) + +;; envelope = "(" env-date SP env-subject SP env-from SP env-sender SP +;; env-reply-to SP env-to SP env-cc SP env-bcc SP +;; env-in-reply-to SP env-message-id ")" +;; +;; env-bcc = "(" 1*address ")" / nil +;; +;; env-cc = "(" 1*address ")" / nil +;; +;; env-date = nstring +;; +;; env-from = "(" 1*address ")" / nil +;; +;; env-in-reply-to = nstring +;; +;; env-message-id = nstring +;; +;; env-reply-to = "(" 1*address ")" / nil +;; +;; env-sender = "(" 1*address ")" / nil +;; +;; env-subject = nstring +;; +;; env-to = "(" 1*address ")" / nil + +(defun imap-parse-envelope () + (when (eq (char-after) ?\() + (imap-forward) + (vector (prog1 (imap-parse-nstring);; date + (imap-forward)) + (prog1 (imap-parse-nstring);; subject + (imap-forward)) + (prog1 (imap-parse-address-list);; from + (imap-forward)) + (prog1 (imap-parse-address-list);; sender + (imap-forward)) + (prog1 (imap-parse-address-list);; reply-to + (imap-forward)) + (prog1 (imap-parse-address-list);; to + (imap-forward)) + (prog1 (imap-parse-address-list);; cc + (imap-forward)) + (prog1 (imap-parse-address-list);; bcc + (imap-forward)) + (prog1 (imap-parse-nstring);; in-reply-to + (imap-forward)) + (prog1 (imap-parse-nstring);; message-id + (imap-forward))))) + +;; body-fld-param = "(" string SP string *(SP string SP string) ")" / nil + +(defsubst imap-parse-string-list () + (cond ((eq (char-after) ?\();; body-fld-param + (let (strlist str) + (imap-forward) + (while (setq str (imap-parse-string)) + (push str strlist) + ;; buggy stalker communigate pro 3.0 doesn't print SPC + ;; between body-fld-param's sometimes + (or (eq (char-after) ?\") + (imap-forward))) + (nreverse strlist))) + ((imap-parse-nil) + nil))) + +;; body-extension = nstring / number / +;; "(" body-extension *(SP body-extension) ")" +;; ; Future expansion. Client implementations +;; ; MUST accept body-extension fields. Server +;; ; implementations MUST NOT generate +;; ; body-extension fields except as defined by +;; ; future standard or standards-track +;; ; revisions of this specification. + +(defun imap-parse-body-extension () + (if (eq (char-after) ?\() + (let (b-e) + (imap-forward) + (push (imap-parse-body-extension) b-e) + (while (eq (char-after) ?\ ) + (imap-forward) + (push (imap-parse-body-extension) b-e)) + (assert (eq (char-after) ?\))) + (imap-forward) + (nreverse b-e)) + (or (imap-parse-number) + (imap-parse-nstring)))) + +;; body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang +;; *(SP body-extension)]] +;; ; MUST NOT be returned on non-extensible +;; ; "BODY" fetch +;; +;; body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang +;; *(SP body-extension)]] +;; ; MUST NOT be returned on non-extensible +;; ; "BODY" fetch + +(defsubst imap-parse-body-ext () + (let (ext) + (when (eq (char-after) ?\ );; body-fld-dsp + (imap-forward) + (let (dsp) + (if (eq (char-after) ?\() + (progn + (imap-forward) + (push (imap-parse-string) dsp) + (imap-forward) + (push (imap-parse-string-list) dsp) + (imap-forward)) + (assert (imap-parse-nil))) + (push (nreverse dsp) ext)) + (when (eq (char-after) ?\ );; body-fld-lang + (imap-forward) + (if (eq (char-after) ?\() + (push (imap-parse-string-list) ext) + (push (imap-parse-nstring) ext)) + (while (eq (char-after) ?\ );; body-extension + (imap-forward) + (setq ext (append (imap-parse-body-extension) ext))))) + ext)) + +;; body = "(" body-type-1part / body-type-mpart ")" +;; +;; body-ext-1part = body-fld-md5 [SP body-fld-dsp [SP body-fld-lang +;; *(SP body-extension)]] +;; ; MUST NOT be returned on non-extensible +;; ; "BODY" fetch +;; +;; body-ext-mpart = body-fld-param [SP body-fld-dsp [SP body-fld-lang +;; *(SP body-extension)]] +;; ; MUST NOT be returned on non-extensible +;; ; "BODY" fetch +;; +;; body-fields = body-fld-param SP body-fld-id SP body-fld-desc SP +;; body-fld-enc SP body-fld-octets +;; +;; body-fld-desc = nstring +;; +;; body-fld-dsp = "(" string SP body-fld-param ")" / nil +;; +;; body-fld-enc = (DQUOTE ("7BIT" / "8BIT" / "BINARY" / "BASE64"/ +;; "QUOTED-PRINTABLE") DQUOTE) / string +;; +;; body-fld-id = nstring +;; +;; body-fld-lang = nstring / "(" string *(SP string) ")" +;; +;; body-fld-lines = number +;; +;; body-fld-md5 = nstring +;; +;; body-fld-octets = number +;; +;; body-fld-param = "(" string SP string *(SP string SP string) ")" / nil +;; +;; body-type-1part = (body-type-basic / body-type-msg / body-type-text) +;; [SP body-ext-1part] +;; +;; body-type-basic = media-basic SP body-fields +;; ; MESSAGE subtype MUST NOT be "RFC822" +;; +;; body-type-msg = media-message SP body-fields SP envelope +;; SP body SP body-fld-lines +;; +;; body-type-text = media-text SP body-fields SP body-fld-lines +;; +;; body-type-mpart = 1*body SP media-subtype +;; [SP body-ext-mpart] +;; +;; media-basic = ((DQUOTE ("APPLICATION" / "AUDIO" / "IMAGE" / +;; "MESSAGE" / "VIDEO") DQUOTE) / string) SP media-subtype +;; ; Defined in [MIME-IMT] +;; +;; media-message = DQUOTE "MESSAGE" DQUOTE SP DQUOTE "RFC822" DQUOTE +;; ; Defined in [MIME-IMT] +;; +;; media-subtype = string +;; ; Defined in [MIME-IMT] +;; +;; media-text = DQUOTE "TEXT" DQUOTE SP media-subtype +;; ; Defined in [MIME-IMT] + +(defun imap-parse-body () + (let (body) + (when (eq (char-after) ?\() + (imap-forward) + (if (eq (char-after) ?\() + (let (subbody) + (while (and (eq (char-after) ?\() + (setq subbody (imap-parse-body))) + ;; buggy stalker communigate pro 3.0 insert a SPC between + ;; parts in multiparts + (when (and (eq (char-after) ?\ ) + (eq (char-after (1+ (point))) ?\()) + (imap-forward)) + (push subbody body)) + (imap-forward) + (push (imap-parse-string) body);; media-subtype + (when (eq (char-after) ?\ );; body-ext-mpart: + (imap-forward) + (if (eq (char-after) ?\();; body-fld-param + (push (imap-parse-string-list) body) + (push (and (imap-parse-nil) nil) body)) + (setq body + (append (imap-parse-body-ext) body)));; body-ext-... + (assert (eq (char-after) ?\))) + (imap-forward) + (nreverse body)) + + (push (imap-parse-string) body);; media-type + (imap-forward) + (push (imap-parse-string) body);; media-subtype + (imap-forward) + ;; next line for Sun SIMS bug + (and (eq (char-after) ? ) (imap-forward)) + (if (eq (char-after) ?\();; body-fld-param + (push (imap-parse-string-list) body) + (push (and (imap-parse-nil) nil) body)) + (imap-forward) + (push (imap-parse-nstring) body);; body-fld-id + (imap-forward) + (push (imap-parse-nstring) body);; body-fld-desc + (imap-forward) + (push (imap-parse-string) body);; body-fld-enc + (imap-forward) + (push (imap-parse-number) body);; body-fld-octets + + ;; ok, we're done parsing the required parts, what comes now is one + ;; of three things: + ;; + ;; envelope (then we're parsing body-type-msg) + ;; body-fld-lines (then we're parsing body-type-text) + ;; body-ext-1part (then we're parsing body-type-basic) + ;; + ;; the problem is that the two first are in turn optionally followed + ;; by the third. So we parse the first two here (if there are any)... + + (when (eq (char-after) ?\ ) + (imap-forward) + (let (lines) + (cond ((eq (char-after) ?\();; body-type-msg: + (push (imap-parse-envelope) body);; envelope + (imap-forward) + (push (imap-parse-body) body);; body + ;; buggy stalker communigate pro 3.0 doesn't print + ;; number of lines in message/rfc822 attachment + (if (eq (char-after) ?\)) + (push 0 body) + (imap-forward) + (push (imap-parse-number) body))) ;; body-fld-lines + ((setq lines (imap-parse-number)) ;; body-type-text: + (push lines body)) ;; body-fld-lines + (t + (backward-char))))) ;; no match... + + ;; ...and then parse the third one here... + + (when (eq (char-after) ?\ );; body-ext-1part: + (imap-forward) + (push (imap-parse-nstring) body);; body-fld-md5 + (setq body (append (imap-parse-body-ext) body)));; body-ext-1part.. + + (assert (eq (char-after) ?\))) + (imap-forward) + (nreverse body))))) + +(when imap-debug ; (untrace-all) + (require 'trace) + (buffer-disable-undo (get-buffer-create imap-debug)) + (mapcar (lambda (f) (trace-function-background f imap-debug)) + '( + imap-read-passwd + imap-utf7-encode + imap-utf7-decode + imap-error-text + imap-kerberos4s-p + imap-kerberos4-open + imap-ssl-p + imap-ssl-open + imap-network-p + imap-network-open + imap-interactive-login + imap-kerberos4a-p + imap-kerberos4-auth + imap-cram-md5-p + imap-cram-md5-auth + imap-login-p + imap-login-auth + imap-anonymous-p + imap-anonymous-auth + imap-open-1 + imap-open + imap-opened + imap-authenticate + imap-close + imap-capability + imap-namespace + imap-send-command-wait + imap-mailbox-put + imap-mailbox-get + imap-mailbox-map-1 + imap-mailbox-map + imap-current-mailbox + imap-current-mailbox-p-1 + imap-current-mailbox-p + imap-mailbox-select-1 + imap-mailbox-select + imap-mailbox-examine-1 + imap-mailbox-examine + imap-mailbox-unselect + imap-mailbox-expunge + imap-mailbox-close + imap-mailbox-create-1 + imap-mailbox-create + imap-mailbox-delete + imap-mailbox-rename + imap-mailbox-lsub + imap-mailbox-list + imap-mailbox-subscribe + imap-mailbox-unsubscribe + imap-mailbox-status + imap-mailbox-acl-get + imap-mailbox-acl-set + imap-mailbox-acl-delete + imap-current-message + imap-list-to-message-set + imap-fetch-asynch + imap-fetch + imap-message-put + imap-message-get + imap-message-map + imap-search + imap-message-flag-permanent-p + imap-message-flags-set + imap-message-flags-del + imap-message-flags-add + imap-message-copyuid-1 + imap-message-copyuid + imap-message-copy + imap-message-appenduid-1 + imap-message-appenduid + imap-message-append + imap-body-lines + imap-envelope-from + imap-send-command-1 + imap-send-command + imap-wait-for-tag + imap-sentinel + imap-find-next-line + imap-arrival-filter + imap-parse-greeting + imap-parse-response + imap-parse-resp-text + imap-parse-resp-text-code + imap-parse-data-list + imap-parse-fetch + imap-parse-status + imap-parse-acl + imap-parse-flag-list + imap-parse-envelope + imap-parse-body-extension + imap-parse-body + ))) + +(provide 'imap) + +;;; imap.el ends here diff --git a/lisp/gnus/mail-parse.el b/lisp/gnus/mail-parse.el new file mode 100644 index 00000000000..d0ce7da9ed7 --- /dev/null +++ b/lisp/gnus/mail-parse.el @@ -0,0 +1,70 @@ +;;; mail-parse.el --- Interface functions for parsing mail +;; Copyright (C) 1998, 1999, 2000 +;; Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; This file contains wrapper functions for a wide range of mail +;; parsing functions. The idea is that there are low-level libraries +;; that impement according to various specs (RFC2231, DRUMS, USEFOR), +;; but that programmers that want to parse some header (say, +;; Content-Type) will want to use the latest spec. +;; +;; So while each low-level library (rfc2231.el, for instance) decodes +;; faithfully according to that (proposed) standard, this library is +;; the interface library. If some later RFC supersedes RFC2231, one +;; would just have to write a new low-level library, adjust the +;; aliases in this library, and the users and programmers won't notice +;; any changes. + +;;; Code: + +(require 'mail-prsvr) +(require 'ietf-drums) +(require 'rfc2231) +(require 'rfc2047) +(require 'rfc2045) + +(defalias 'mail-header-parse-content-type 'rfc2231-parse-string) +(defalias 'mail-header-parse-content-disposition 'rfc2231-parse-string) +(defalias 'mail-content-type-get 'rfc2231-get-value) +(defalias 'mail-header-encode-parameter 'rfc2045-encode-string) + +(defalias 'mail-header-remove-comments 'ietf-drums-remove-comments) +(defalias 'mail-header-remove-whitespace 'ietf-drums-remove-whitespace) +(defalias 'mail-header-strip 'ietf-drums-strip) +(defalias 'mail-header-get-comment 'ietf-drums-get-comment) +(defalias 'mail-header-parse-address 'ietf-drums-parse-address) +(defalias 'mail-header-parse-addresses 'ietf-drums-parse-addresses) +(defalias 'mail-header-parse-date 'ietf-drums-parse-date) +(defalias 'mail-narrow-to-head 'ietf-drums-narrow-to-header) +(defalias 'mail-quote-string 'ietf-drums-quote-string) + +(defalias 'mail-header-narrow-to-field 'rfc2047-narrow-to-field) +(defalias 'mail-encode-encoded-word-region 'rfc2047-encode-region) +(defalias 'mail-encode-encoded-word-buffer 'rfc2047-encode-message-header) +(defalias 'mail-encode-encoded-word-string 'rfc2047-encode-string) +(defalias 'mail-decode-encoded-word-region 'rfc2047-decode-region) +(defalias 'mail-decode-encoded-word-string 'rfc2047-decode-string) + +(provide 'mail-parse) + +;;; mail-parse.el ends here diff --git a/lisp/gnus/mail-prsvr.el b/lisp/gnus/mail-prsvr.el new file mode 100644 index 00000000000..2566abc2446 --- /dev/null +++ b/lisp/gnus/mail-prsvr.el @@ -0,0 +1,44 @@ +;;; mail-prsvr.el --- Interface variables for parsing mail +;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(defvar mail-parse-charset nil + "Default charset used by low-level libraries. +This variable should never be set. Instead, it should be bound by +functions that wish to call mail-parse functions and let them know +what the desired charset is to be.") + +(defvar mail-parse-mule-charset nil + "Default MULE charset used by low-level libraries. +This variable should never be set.") + +(defvar mail-parse-ignored-charsets nil + "Ignored charsets used by low-level libraries. +This variable should never be set. Instead, it should be bound by +functions that wish to call mail-parse functions and let them know +what the desired charsets is to be ignored.") + +(provide 'mail-prsvr) + +;;; mail-prsvr.el ends here diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el new file mode 100644 index 00000000000..f2a431dc265 --- /dev/null +++ b/lisp/gnus/mail-source.el @@ -0,0 +1,736 @@ +;;; mail-source.el --- functions for fetching mail +;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; Keywords: news, mail + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(eval-when-compile (require 'cl)) +(eval-and-compile + (autoload 'pop3-movemail "pop3") + (autoload 'pop3-get-message-count "pop3")) +(require 'format-spec) + +(defgroup mail-source nil + "The mail-fetching library." + :group 'gnus) + +(defcustom mail-sources nil + "*Where the mail backends will look for incoming mail. +This variable is a list of mail source specifiers." + :group 'mail-source + :type 'sexp) + +(defcustom mail-source-primary-source nil + "*Primary source for incoming mail. +If non-nil, this maildrop will be checked periodically for new mail." + :group 'mail-source + :type 'sexp) + +(defcustom mail-source-crash-box "~/.emacs-mail-crash-box" + "File where mail will be stored while processing it." + :group 'mail-source + :type 'file) + +(defcustom mail-source-directory "~/Mail/" + "Directory where files (if any) will be stored." + :group 'mail-source + :type 'directory) + +(defcustom mail-source-default-file-modes 384 + "Set the mode bits of all new mail files to this integer." + :group 'mail-source + :type 'integer) + +(defcustom mail-source-delete-incoming nil + "*If non-nil, delete incoming files after handling." + :group 'mail-source + :type 'boolean) + +(defcustom mail-source-incoming-file-prefix "Incoming" + "Prefix for file name for storing incoming mail" + :group 'mail-source + :type 'string) + +(defcustom mail-source-report-new-mail-interval 5 + "Interval in minutes between checks for new mail." + :group 'mail-source + :type 'number) + +(defcustom mail-source-idle-time-delay 5 + "Number of idle seconds to wait before checking for new mail." + :group 'mail-source + :type 'number) + +;;; Internal variables. + +(defvar mail-source-string "" + "A dynamically bound string that says what the current mail source is.") + +(defvar mail-source-new-mail-available nil + "Flag indicating when new mail is available.") + +(eval-and-compile + (defvar mail-source-common-keyword-map + '((:plugged)) + "Mapping from keywords to default values. +Common keywords should be listed here.") + + (defvar mail-source-keyword-map + '((file + (:prescript) + (:prescript-delay) + (:postscript) + (:path (or (getenv "MAIL") + (concat "/usr/spool/mail/" (user-login-name))))) + (directory + (:path) + (:suffix ".spool") + (:predicate identity)) + (pop + (:prescript) + (:prescript-delay) + (:postscript) + (:server (getenv "MAILHOST")) + (:port 110) + (:user (or (user-login-name) (getenv "LOGNAME") (getenv "USER"))) + (:program) + (:function) + (:password) + (:authentication password)) + (maildir + (:path (or (getenv "MAILDIR") "~/Maildir/")) + (:subdirs ("new" "cur")) + (:function)) + (imap + (:server (getenv "MAILHOST")) + (:port) + (:stream) + (:authentication) + (:user (or (user-login-name) (getenv "LOGNAME") (getenv "USER"))) + (:password) + (:mailbox "INBOX") + (:predicate "UNSEEN UNDELETED") + (:fetchflag "\\Deleted") + (:dontexpunge)) + (webmail + (:subtype hotmail) + (:user (or (user-login-name) (getenv "LOGNAME") (getenv "USER"))) + (:password) + (:dontexpunge) + (:authentication password))) + "Mapping from keywords to default values. +All keywords that can be used must be listed here.")) + +(defvar mail-source-fetcher-alist + '((file mail-source-fetch-file) + (directory mail-source-fetch-directory) + (pop mail-source-fetch-pop) + (maildir mail-source-fetch-maildir) + (imap mail-source-fetch-imap) + (webmail mail-source-fetch-webmail)) + "A mapping from source type to fetcher function.") + +(defvar mail-source-password-cache nil) + +(defvar mail-source-plugged t) + +;;; Functions + +(eval-and-compile + (defun mail-source-strip-keyword (keyword) + "Strip the leading colon off the KEYWORD." + (intern (substring (symbol-name keyword) 1)))) + +(eval-and-compile + (defun mail-source-bind-1 (type) + (let* ((defaults (cdr (assq type mail-source-keyword-map))) + default bind) + (while (setq default (pop defaults)) + (push (list (mail-source-strip-keyword (car default)) + nil) + bind)) + bind))) + +(defmacro mail-source-bind (type-source &rest body) + "Return a `let' form that binds all variables in source TYPE. +TYPE-SOURCE is a list where the first element is the TYPE, and +the second variable is the SOURCE. +At run time, the mail source specifier SOURCE will be inspected, +and the variables will be set according to it. Variables not +specified will be given default values. + +After this is done, BODY will be executed in the scope +of the `let' form. + +The variables bound and their default values are described by +the `mail-source-keyword-map' variable." + `(let ,(mail-source-bind-1 (car type-source)) + (mail-source-set-1 ,(cadr type-source)) + ,@body)) + +(put 'mail-source-bind 'lisp-indent-function 1) +(put 'mail-source-bind 'edebug-form-spec '(form body)) + +(defun mail-source-set-1 (source) + (let* ((type (pop source)) + (defaults (cdr (assq type mail-source-keyword-map))) + default value keyword) + (while (setq default (pop defaults)) + (set (mail-source-strip-keyword (setq keyword (car default))) + (if (setq value (plist-get source keyword)) + (mail-source-value value) + (mail-source-value (cadr default))))))) + +(eval-and-compile + (defun mail-source-bind-common-1 () + (let* ((defaults mail-source-common-keyword-map) + default bind) + (while (setq default (pop defaults)) + (push (list (mail-source-strip-keyword (car default)) + nil) + bind)) + bind))) + +(defun mail-source-set-common-1 (source) + (let* ((type (pop source)) + (defaults mail-source-common-keyword-map) + (defaults-1 (cdr (assq type mail-source-keyword-map))) + default value keyword) + (while (setq default (pop defaults)) + (set (mail-source-strip-keyword (setq keyword (car default))) + (if (setq value (plist-get source keyword)) + (mail-source-value value) + (if (setq value (assq keyword defaults-1)) + (mail-source-value (cadr value)) + (mail-source-value (cadr default)))))))) + +(defmacro mail-source-bind-common (source &rest body) + "Return a `let' form that binds all common variables. +See `mail-source-bind'." + `(let ,(mail-source-bind-common-1) + (mail-source-set-common-1 source) + ,@body)) + +(put 'mail-source-bind-common 'lisp-indent-function 1) +(put 'mail-source-bind-common 'edebug-form-spec '(form body)) + +(defun mail-source-value (value) + "Return the value of VALUE." + (cond + ;; String + ((stringp value) + value) + ;; Function + ((and (listp value) + (functionp (car value))) + (eval value)) + ;; Just return the value. + (t + value))) + +(defun mail-source-fetch (source callback) + "Fetch mail from SOURCE and call CALLBACK zero or more times. +CALLBACK will be called with the name of the file where (some of) +the mail from SOURCE is put. +Return the number of files that were found." + (mail-source-bind-common source + (if (or mail-source-plugged plugged) + (save-excursion + (let ((function (cadr (assq (car source) mail-source-fetcher-alist))) + (found 0)) + (unless function + (error "%S is an invalid mail source specification" source)) + ;; If there's anything in the crash box, we do it first. + (when (file-exists-p mail-source-crash-box) + (message "Processing mail from %s..." mail-source-crash-box) + (setq found (mail-source-callback + callback mail-source-crash-box))) + (+ found + (condition-case err + (funcall function source callback) + (error + (unless (yes-or-no-p + (format "Mail source error (%s). Continue? " err)) + (error "Cannot get new mail.")) + 0)))))))) + +(defun mail-source-make-complex-temp-name (prefix) + (let ((newname (make-temp-name prefix)) + (newprefix prefix)) + (while (file-exists-p newname) + (setq newprefix (concat newprefix "x")) + (setq newname (make-temp-name newprefix))) + newname)) + +(defun mail-source-callback (callback info) + "Call CALLBACK on the mail file, and then remove the mail file. +Pass INFO on to CALLBACK." + (if (or (not (file-exists-p mail-source-crash-box)) + (zerop (nth 7 (file-attributes mail-source-crash-box)))) + (progn + (when (file-exists-p mail-source-crash-box) + (delete-file mail-source-crash-box)) + 0) + (prog1 + (funcall callback mail-source-crash-box info) + (when (file-exists-p mail-source-crash-box) + ;; Delete or move the incoming mail out of the way. + (if mail-source-delete-incoming + (delete-file mail-source-crash-box) + (let ((incoming + (mail-source-make-complex-temp-name + (expand-file-name + mail-source-incoming-file-prefix + mail-source-directory)))) + (unless (file-exists-p (file-name-directory incoming)) + (make-directory (file-name-directory incoming) t)) + (rename-file mail-source-crash-box incoming t))))))) + +(defun mail-source-movemail (from to) + "Move FROM to TO using movemail." + (if (not (file-writable-p to)) + (error "Can't write to crash box %s. Not moving mail" to) + (let ((to (file-truename (expand-file-name to))) + errors result) + (setq to (file-truename to) + from (file-truename from)) + ;; Set TO if have not already done so, and rename or copy + ;; the file FROM to TO if and as appropriate. + (cond + ((file-exists-p to) + ;; The crash box exists already. + t) + ((not (file-exists-p from)) + ;; There is no inbox. + (setq to nil)) + ((zerop (nth 7 (file-attributes from))) + ;; Empty file. + (setq to nil)) + (t + ;; If getting from mail spool directory, use movemail to move + ;; rather than just renaming, so as to interlock with the + ;; mailer. + (unwind-protect + (save-excursion + (setq errors (generate-new-buffer " *mail source loss*")) + (let ((default-directory "/")) + (setq result + (apply + 'call-process + (append + (list + (expand-file-name "movemail" exec-directory) + nil errors nil from to))))) + (when (file-exists-p to) + (set-file-modes to mail-source-default-file-modes)) + (if (and (not (buffer-modified-p errors)) + (zerop result)) + ;; No output => movemail won. + t + (set-buffer errors) + ;; There may be a warning about older revisions. We + ;; ignore that. + (goto-char (point-min)) + (if (search-forward "older revision" nil t) + t + ;; Probably a real error. + (subst-char-in-region (point-min) (point-max) ?\n ?\ ) + (goto-char (point-max)) + (skip-chars-backward " \t") + (delete-region (point) (point-max)) + (goto-char (point-min)) + (when (looking-at "movemail: ") + (delete-region (point-min) (match-end 0))) + (unless (yes-or-no-p + (format "movemail: %s (%d return). Continue? " + (buffer-string) result)) + (error "%s" (buffer-string))) + (setq to nil))))))) + (when (and errors + (buffer-name errors)) + (kill-buffer errors)) + ;; Return whether we moved successfully or not. + to))) + +(defun mail-source-movemail-and-remove (from to) + "Move FROM to TO using movemail, then remove FROM if empty." + (or (not (mail-source-movemail from to)) + (not (zerop (nth 7 (file-attributes from)))) + (delete-file from))) + +(defvar mail-source-read-passwd nil) +(defun mail-source-read-passwd (prompt &rest args) + "Read a password using PROMPT. +If ARGS, PROMPT is used as an argument to `format'." + (let ((prompt + (if args + (apply 'format prompt args) + prompt))) + (unless mail-source-read-passwd + (if (or (fboundp 'read-passwd) (load "passwd" t)) + (setq mail-source-read-passwd 'read-passwd) + (unless (fboundp 'ange-ftp-read-passwd) + (autoload 'ange-ftp-read-passwd "ange-ftp")) + (setq mail-source-read-passwd 'ange-ftp-read-passwd))) + (funcall mail-source-read-passwd prompt))) + +(defun mail-source-fetch-with-program (program) + (zerop (call-process shell-file-name nil nil nil + shell-command-switch program))) + +(defun mail-source-run-script (script spec &optional delay) + (when script + (if (and (symbolp script) (fboundp script)) + (funcall script) + (mail-source-call-script + (format-spec script spec)))) + (when delay + (sleep-for delay))) + +(defun mail-source-call-script (script) + (let ((background nil)) + (when (string-match "& *$" script) + (setq script (substring script 0 (match-beginning 0)) + background 0)) + (call-process shell-file-name nil background nil + shell-command-switch script))) + +;;; +;;; Different fetchers +;;; + +(defun mail-source-fetch-file (source callback) + "Fetcher for single-file sources." + (mail-source-bind (file source) + (mail-source-run-script + prescript (format-spec-make ?t mail-source-crash-box) + prescript-delay) + (let ((mail-source-string (format "file:%s" path))) + (if (mail-source-movemail path mail-source-crash-box) + (prog1 + (mail-source-callback callback path) + (mail-source-run-script + postscript (format-spec-make ?t mail-source-crash-box))) + 0)))) + +(defun mail-source-fetch-directory (source callback) + "Fetcher for directory sources." + (mail-source-bind (directory source) + (let ((found 0) + (mail-source-string (format "directory:%s" path))) + (dolist (file (directory-files + path t (concat (regexp-quote suffix) "$"))) + (when (and (file-regular-p file) + (funcall predicate file) + (mail-source-movemail file mail-source-crash-box)) + (incf found (mail-source-callback callback file)))) + found))) + +(defun mail-source-fetch-pop (source callback) + "Fetcher for single-file sources." + (mail-source-bind (pop source) + (mail-source-run-script + prescript + (format-spec-make ?p password ?t mail-source-crash-box + ?s server ?P port ?u user) + prescript-delay) + (let ((from (format "%s:%s:%s" server user port)) + (mail-source-string (format "pop:%s@%s" user server)) + result) + (when (eq authentication 'password) + (setq password + (or password + (cdr (assoc from mail-source-password-cache)) + (mail-source-read-passwd + (format "Password for %s at %s: " user server))))) + (when server + (setenv "MAILHOST" server)) + (setq result + (cond + (program + (mail-source-fetch-with-program + (format-spec + program + (format-spec-make ?p password ?t mail-source-crash-box + ?s server ?P port ?u user)))) + (function + (funcall function mail-source-crash-box)) + ;; The default is to use pop3.el. + (t + (let ((pop3-password password) + (pop3-maildrop user) + (pop3-mailhost server) + (pop3-port port) + (pop3-authentication-scheme + (if (eq authentication 'apop) 'apop 'pass))) + (save-excursion (pop3-movemail mail-source-crash-box)))))) + (if result + (progn + (when (eq authentication 'password) + (unless (assoc from mail-source-password-cache) + (push (cons from password) mail-source-password-cache))) + (prog1 + (mail-source-callback callback server) + ;; Update display-time's mail flag, if relevant. + (if (equal source mail-source-primary-source) + (setq mail-source-new-mail-available nil)) + (mail-source-run-script + postscript + (format-spec-make ?p password ?t mail-source-crash-box + ?s server ?P port ?u user)))) + ;; We nix out the password in case the error + ;; was because of a wrong password being given. + (setq mail-source-password-cache + (delq (assoc from mail-source-password-cache) + mail-source-password-cache)) + 0)))) + +(defun mail-source-check-pop (source) + "Check whether there is new mail." + (mail-source-bind (pop source) + (let ((from (format "%s:%s:%s" server user port)) + (mail-source-string (format "pop:%s@%s" user server)) + result) + (when (eq authentication 'password) + (setq password + (or password + (cdr (assoc from mail-source-password-cache)) + (mail-source-read-passwd + (format "Password for %s at %s: " user server)))) + (unless (assoc from mail-source-password-cache) + (push (cons from password) mail-source-password-cache))) + (when server + (setenv "MAILHOST" server)) + (setq result + (cond + ;; No easy way to check whether mail is waiting for these. + (program) + (function) + ;; The default is to use pop3.el. + (t + (let ((pop3-password password) + (pop3-maildrop user) + (pop3-mailhost server) + (pop3-port port) + (pop3-authentication-scheme + (if (eq authentication 'apop) 'apop 'pass))) + (save-excursion (pop3-get-message-count)))))) + (if result + ;; Inform display-time that we have new mail. + (setq mail-source-new-mail-available (> result 0)) + ;; We nix out the password in case the error + ;; was because of a wrong password being given. + (setq mail-source-password-cache + (delq (assoc from mail-source-password-cache) + mail-source-password-cache))) + result))) + +(defun mail-source-new-mail-p () + "Handler for `display-time' to indicate when new mail is available." + ;; Only report flag setting; flag is updated on a different schedule. + mail-source-new-mail-available) + + +(defvar mail-source-report-new-mail nil) +(defvar mail-source-report-new-mail-timer nil) +(defvar mail-source-report-new-mail-idle-timer nil) + +(eval-when-compile (require 'timer)) + +(defun mail-source-start-idle-timer () + ;; Start our idle timer if necessary, so we delay the check until the + ;; user isn't typing. + (unless mail-source-report-new-mail-idle-timer + (setq mail-source-report-new-mail-idle-timer + (run-with-idle-timer + mail-source-idle-time-delay + nil + (lambda () + (setq mail-source-report-new-mail-idle-timer nil) + (mail-source-check-pop mail-source-primary-source)))) + ;; Since idle timers created when Emacs is already in the idle + ;; state don't get activated until Emacs _next_ becomes idle, we + ;; need to force our timer to be considered active now. We do + ;; this by being naughty and poking the timer internals directly + ;; (element 0 of the vector is nil if the timer is active). + (aset mail-source-report-new-mail-idle-timer 0 nil))) + +(defun mail-source-report-new-mail (arg) + "Toggle whether to report when new mail is available. +This only works when `display-time' is enabled." + (interactive "P") + (if (not mail-source-primary-source) + (error "Need to set `mail-source-primary-source' to check for new mail.")) + (let ((on (if (null arg) + (not mail-source-report-new-mail) + (> (prefix-numeric-value arg) 0)))) + (setq mail-source-report-new-mail on) + (and mail-source-report-new-mail-timer + (cancel-timer mail-source-report-new-mail-timer)) + (and mail-source-report-new-mail-idle-timer + (cancel-timer mail-source-report-new-mail-idle-timer)) + (setq mail-source-report-new-mail-timer nil) + (setq mail-source-report-new-mail-idle-timer nil) + (if on + (progn + (require 'time) + (setq display-time-mail-function #'mail-source-new-mail-p) + ;; Set up the main timer. + (setq mail-source-report-new-mail-timer + (run-at-time t (* 60 mail-source-report-new-mail-interval) + #'mail-source-start-idle-timer)) + ;; When you get new mail, clear "Mail" from the mode line. + (add-hook 'nnmail-post-get-new-mail-hook + 'display-time-event-handler) + (message "Mail check enabled")) + (setq display-time-mail-function nil) + (remove-hook 'nnmail-post-get-new-mail-hook + 'display-time-event-handler) + (message "Mail check disabled")))) + +(defun mail-source-fetch-maildir (source callback) + "Fetcher for maildir sources." + (mail-source-bind (maildir source) + (let ((found 0) + mail-source-string) + (unless (string-match "/$" path) + (setq path (concat path "/"))) + (dolist (subdir subdirs) + (when (file-directory-p (concat path subdir)) + (setq mail-source-string (format "maildir:%s%s" path subdir)) + (dolist (file (directory-files (concat path subdir) t)) + (when (and (not (file-directory-p file)) + (not (if function + (funcall function file mail-source-crash-box) + (let ((coding-system-for-write + mm-text-coding-system) + (coding-system-for-read + mm-text-coding-system)) + (with-temp-file mail-source-crash-box + (insert-file-contents file) + (goto-char (point-min)) +;;; ;; Unix mail format +;;; (unless (looking-at "\n*From ") +;;; (insert "From maildir " +;;; (current-time-string) "\n")) +;;; (while (re-search-forward "^From " nil t) +;;; (replace-match ">From ")) + ;; MMDF mail format + (insert "\001\001\001\001\n") + (goto-char (point-max)) + (insert "\n\n")) + (delete-file file))))) + (incf found (mail-source-callback callback file)))))) + found))) + +(eval-and-compile + (autoload 'imap-open "imap") + (autoload 'imap-authenticate "imap") + (autoload 'imap-mailbox-select "imap") + (autoload 'imap-mailbox-unselect "imap") + (autoload 'imap-mailbox-close "imap") + (autoload 'imap-search "imap") + (autoload 'imap-fetch "imap") + (autoload 'imap-close "imap") + (autoload 'imap-error-text "imap") + (autoload 'imap-message-flags-add "imap") + (autoload 'imap-list-to-message-set "imap") + (autoload 'nnheader-ms-strip-cr "nnheader")) + +(defun mail-source-fetch-imap (source callback) + "Fetcher for imap sources." + (mail-source-bind (imap source) + (let ((from (format "%s:%s:%s" server user port)) + (found 0) + (buf (get-buffer-create (generate-new-buffer-name " *imap source*"))) + (mail-source-string (format "imap:%s:%s" server mailbox)) + remove) + (if (and (imap-open server port stream authentication buf) + (imap-authenticate + user (or (cdr (assoc from mail-source-password-cache)) + password) buf) + (imap-mailbox-select mailbox nil buf)) + (let (str (coding-system-for-write 'binary)) + (with-temp-file mail-source-crash-box + ;; remember password + (with-current-buffer buf + (when (or imap-password + (assoc from mail-source-password-cache)) + (push (cons from imap-password) mail-source-password-cache))) + ;; if predicate is nil, use all uids + (dolist (uid (imap-search (or predicate "1:*") buf)) + (when (setq str (imap-fetch uid "RFC822.PEEK" 'RFC822 nil buf)) + (push uid remove) + (insert "From imap " (current-time-string) "\n") + (save-excursion + (insert str "\n\n")) + (while (re-search-forward "^From " nil t) + (replace-match ">From ")) + (goto-char (point-max)))) + (nnheader-ms-strip-cr)) + (incf found (mail-source-callback callback server)) + (when (and remove fetchflag) + (imap-message-flags-add + (imap-list-to-message-set remove) fetchflag nil buf)) + (if dontexpunge + (imap-mailbox-unselect buf) + (imap-mailbox-close buf)) + (imap-close buf)) + (imap-close buf) + ;; We nix out the password in case the error + ;; was because of a wrong password being given. + (setq mail-source-password-cache + (delq (assoc from mail-source-password-cache) + mail-source-password-cache)) + (error (imap-error-text buf))) + (kill-buffer buf) + found))) + +(eval-and-compile + (autoload 'webmail-fetch "webmail")) + +(defun mail-source-fetch-webmail (source callback) + "Fetch for webmail source." + (mail-source-bind (webmail source) + (let ((mail-source-string (format "webmail:%s:%s" subtype user)) + (webmail-newmail-only dontexpunge) + (webmail-move-to-trash-can (not dontexpunge))) + (when (eq authentication 'password) + (setq password + (or password + (cdr (assoc (format "webmail:%s:%s" subtype user) + mail-source-password-cache)) + (mail-source-read-passwd + (format "Password for %s at %s: " user subtype)))) + (when (and password + (not (assoc (format "webmail:%s:%s" subtype user) + mail-source-password-cache))) + (push (cons (format "webmail:%s:%s" subtype user) password) + mail-source-password-cache))) + (webmail-fetch mail-source-crash-box subtype user password) + (mail-source-callback callback (symbol-name subtype))))) + +(provide 'mail-source) + +;;; mail-source.el ends here diff --git a/lisp/gnus/mailcap.el b/lisp/gnus/mailcap.el new file mode 100644 index 00000000000..e913573566f --- /dev/null +++ b/lisp/gnus/mailcap.el @@ -0,0 +1,944 @@ +;;; mailcap.el --- Functions for displaying MIME parts +;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + +;; Author: William M. Perry +;; Lars Magne Ingebrigtsen +;; Keywords: news, mail + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(eval-when-compile (require 'cl)) +(require 'mail-parse) +(require 'mm-util) + +(defvar mailcap-parse-args-syntax-table + (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table))) + (modify-syntax-entry ?' "\"" table) + (modify-syntax-entry ?` "\"" table) + (modify-syntax-entry ?{ "(" table) + (modify-syntax-entry ?} ")" table) + table) + "A syntax table for parsing sgml attributes.") + +(defvar mailcap-mime-data + '(("application" + ("x-x509-ca-cert" + (viewer . ssl-view-site-cert) + (test . (fboundp 'ssl-view-site-cert)) + (type . "application/x-x509-ca-cert")) + ("x-x509-user-cert" + (viewer . ssl-view-user-cert) + (test . (fboundp 'ssl-view-user-cert)) + (type . "application/x-x509-user-cert")) + ("octet-stream" + (viewer . mailcap-save-binary-file) + (non-viewer . t) + (type . "application/octet-stream")) + ("dvi" + (viewer . "open %s") + (type . "application/dvi") + (test . (eq (mm-device-type) 'ns))) + ("dvi" + (viewer . "xdvi %s") + (test . (eq (mm-device-type) 'x)) + ("needsx11") + (type . "application/dvi")) + ("dvi" + (viewer . "dvitty %s") + (test . (not (getenv "DISPLAY"))) + (type . "application/dvi")) + ("emacs-lisp" + (viewer . mailcap-maybe-eval) + (type . "application/emacs-lisp")) + ("x-tar" + (viewer . mailcap-save-binary-file) + (non-viewer . t) + (type . "application/x-tar")) + ("x-latex" + (viewer . tex-mode) + (test . (fboundp 'tex-mode)) + (type . "application/x-latex")) + ("x-tex" + (viewer . tex-mode) + (test . (fboundp 'tex-mode)) + (type . "application/x-tex")) + ("latex" + (viewer . tex-mode) + (test . (fboundp 'tex-mode)) + (type . "application/latex")) + ("tex" + (viewer . tex-mode) + (test . (fboundp 'tex-mode)) + (type . "application/tex")) + ("texinfo" + (viewer . texinfo-mode) + (test . (fboundp 'texinfo-mode)) + (type . "application/tex")) + ("zip" + (viewer . mailcap-save-binary-file) + (non-viewer . t) + (type . "application/zip") + ("copiousoutput")) + ("pdf" + (viewer . "acroread %s") + (type . "application/pdf")) + ("postscript" + (viewer . "open %s") + (type . "application/postscript") + (test . (eq (mm-device-type) 'ns))) + ("postscript" + (viewer . "ghostview -dSAFER %s") + (type . "application/postscript") + (test . (eq (mm-device-type) 'x)) + ("needsx11")) + ("postscript" + (viewer . "ps2ascii %s") + (type . "application/postscript") + (test . (not (getenv "DISPLAY"))) + ("copiousoutput"))) + ("audio" + ("x-mpeg" + (viewer . "maplay %s") + (type . "audio/x-mpeg")) + (".*" + (viewer . "showaudio") + (type . "audio/*"))) + ("message" + ("rfc-*822" + (viewer . mm-view-message) + (test . (and (featurep 'gnus) + (gnus-alive-p))) + (type . "message/rfc822")) + ("rfc-*822" + (viewer . vm-mode) + (test . (fboundp 'vm-mode)) + (type . "message/rfc822")) + ("rfc-*822" + (viewer . w3-mode) + (test . (fboundp 'w3-mode)) + (type . "message/rfc822")) + ("rfc-*822" + (viewer . view-mode) + (test . (fboundp 'view-mode)) + (type . "message/rfc822")) + ("rfc-*822" + (viewer . fundamental-mode) + (type . "message/rfc822"))) + ("image" + ("x-xwd" + (viewer . "xwud -in %s") + (type . "image/x-xwd") + ("compose" . "xwd -frame > %s") + (test . (eq (mm-device-type) 'x)) + ("needsx11")) + ("x11-dump" + (viewer . "xwud -in %s") + (type . "image/x-xwd") + ("compose" . "xwd -frame > %s") + (test . (eq (mm-device-type) 'x)) + ("needsx11")) + ("windowdump" + (viewer . "xwud -in %s") + (type . "image/x-xwd") + ("compose" . "xwd -frame > %s") + (test . (eq (mm-device-type) 'x)) + ("needsx11")) + (".*" + (viewer . "aopen %s") + (type . "image/*") + (test . (eq (mm-device-type) 'ns))) + (".*" + (viewer . "display %s") + (type . "image/*") + (test . (eq (mm-device-type) 'x)) + ("needsx11")) + (".*" + (viewer . "ee %s") + (type . "image/*") + (test . (eq (mm-device-type) 'x)) + ("needsx11"))) + ("text" + ("plain" + (viewer . w3-mode) + (test . (fboundp 'w3-mode)) + (type . "text/plain")) + ("plain" + (viewer . view-mode) + (test . (fboundp 'view-mode)) + (type . "text/plain")) + ("plain" + (viewer . fundamental-mode) + (type . "text/plain")) + ("enriched" + (viewer . enriched-decode-region) + (test . (fboundp 'enriched-decode)) + (type . "text/enriched")) + ("html" + (viewer . mm-w3-prepare-buffer) + (test . (fboundp 'w3-prepare-buffer)) + (type . "text/html"))) + ("video" + ("mpeg" + (viewer . "mpeg_play %s") + (type . "video/mpeg") + (test . (eq (mm-device-type) 'x)) + ("needsx11"))) + ("x-world" + ("x-vrml" + (viewer . "webspace -remote %s -URL %u") + (type . "x-world/x-vrml") + ("description" + "VRML document"))) + ("archive" + ("tar" + (viewer . tar-mode) + (type . "archive/tar") + (test . (fboundp 'tar-mode))))) + "The mailcap structure is an assoc list of assoc lists. +1st assoc list is keyed on the major content-type +2nd assoc list is keyed on the minor content-type (which can be a regexp) + +Which looks like: +----------------- + ((\"application\" + (\"postscript\" . )) + (\"text\" + (\"plain\" . ))) + +Where is another assoc list of the various information +related to the mailcap RFC. This is keyed on the lowercase +attribute name (viewer, test, etc). This looks like: + ((viewer . viewerinfo) + (test . testinfo) + (xxxx . \"string\")) + +Where viewerinfo specifies how the content-type is viewed. Can be +a string, in which case it is run through a shell, with +appropriate parameters, or a symbol, in which case the symbol is +funcall'd, with the buffer as an argument. + +testinfo is a list of strings, or nil. If nil, it means the +viewer specified is always valid. If it is a list of strings, +these are used to determine whether a viewer passes the 'test' or +not.") + +(defvar mailcap-download-directory nil + "*Where downloaded files should go by default.") + +(defvar mailcap-temporary-directory + (cond ((fboundp 'temp-directory) (temp-directory)) + ((boundp 'temporary-file-directory) temporary-file-directory) + ("/tmp/")) + "*Where temporary files go.") + +;;; +;;; Utility functions +;;; + +(defun mailcap-generate-unique-filename (&optional fmt) + "Generate a unique filename in mailcap-temporary-directory." + (if (not fmt) + (let ((base (format "mailcap-tmp.%d" (user-real-uid))) + (fname "") + (x 0)) + (setq fname (format "%s%d" base x)) + (while (file-exists-p + (expand-file-name fname mailcap-temporary-directory)) + (setq x (1+ x) + fname (concat base (int-to-string x)))) + (expand-file-name fname mailcap-temporary-directory)) + (let ((base (concat "mm" (int-to-string (user-real-uid)))) + (fname "") + (x 0)) + (setq fname (format fmt (concat base (int-to-string x)))) + (while (file-exists-p + (expand-file-name fname mailcap-temporary-directory)) + (setq x (1+ x) + fname (format fmt (concat base (int-to-string x))))) + (expand-file-name fname mailcap-temporary-directory)))) + +(defun mailcap-save-binary-file () + (goto-char (point-min)) + (unwind-protect + (let ((file (read-file-name + "Filename to save as: " + (or mailcap-download-directory "~/"))) + (require-final-newline nil)) + (write-region (point-min) (point-max) file)) + (kill-buffer (current-buffer)))) + +(defvar mailcap-maybe-eval-warning + "*** WARNING *** + +This MIME part contains untrusted and possibly harmful content. +If you evaluate the Emacs Lisp code contained in it, a lot of nasty +things can happen. Please examine the code very carefully before you +instruct Emacs to evaluate it. You can browse the buffer containing +the code using \\[scroll-other-window]. + +If you are unsure what to do, please answer \"no\"." + "Text of warning message displayed by `mailcap-maybe-eval'. +Make sure that this text consists only of few text lines. Otherwise, +Gnus might fail to display all of it.") + +(defun mailcap-maybe-eval () + "Maybe evaluate a buffer of emacs lisp code." + (let ((lisp-buffer (current-buffer))) + (goto-char (point-min)) + (when + (save-window-excursion + (delete-other-windows) + (let ((buffer (get-buffer-create (generate-new-buffer-name + "*Warning*")))) + (unwind-protect + (with-current-buffer buffer + (insert (substitute-command-keys + mailcap-maybe-eval-warning)) + (goto-char (point-min)) + (display-buffer buffer) + (yes-or-no-p "This is potentially dangerous emacs-lisp code, evaluate it? ")) + (kill-buffer buffer)))) + (eval-buffer (current-buffer))) + (when (buffer-live-p lisp-buffer) + (with-current-buffer lisp-buffer + (emacs-lisp-mode))))) + + +;;; +;;; The mailcap parser +;;; + +(defun mailcap-replace-regexp (regexp to-string) + ;; Quiet replace-regexp. + (goto-char (point-min)) + (while (re-search-forward regexp nil t) + (replace-match to-string t nil))) + +(defvar mailcap-parsed-p nil) + +(defun mailcap-parse-mailcaps (&optional path force) + "Parse out all the mailcaps specified in a path string PATH. +Components of PATH are separated by the `path-separator' character +appropriate for this system. If FORCE, re-parse even if already +parsed. If PATH is omitted, use the value of environment variable +MAILCAPS if set; otherwise (on Unix) use the path from RFC 1524, plus +/usr/local/etc/mailcap." + (interactive (list nil t)) + (when (or (not mailcap-parsed-p) + force) + (cond + (path nil) + ((getenv "MAILCAPS") (setq path (getenv "MAILCAPS"))) + ((memq system-type '(ms-dos ms-windows windows-nt)) + (setq path '("~/.mailcap" "~/mail.cap" "~/etc/mail.cap"))) + (t (setq path + ;; This is per RFC 1524, specifically + ;; with /usr before /usr/local. + '("~/.mailcap" "/etc/mailcap" "/usr/etc/mailcap" + "/usr/local/etc/mailcap")))) + (let ((fnames (reverse + (if (stringp path) + (parse-colon-path path) + path))) + fname) + (while fnames + (setq fname (car fnames)) + (if (and (file-readable-p fname) + (file-regular-p fname)) + (mailcap-parse-mailcap fname)) + (setq fnames (cdr fnames)))) + (setq mailcap-parsed-p t))) + +(defun mailcap-parse-mailcap (fname) + ;; Parse out the mailcap file specified by FNAME + (let (major ; The major mime type (image/audio/etc) + minor ; The minor mime type (gif, basic, etc) + save-pos ; Misc saved positions used in parsing + viewer ; How to view this mime type + info ; Misc info about this mime type + ) + (with-temp-buffer + (insert-file-contents fname) + (set-syntax-table mailcap-parse-args-syntax-table) + (mailcap-replace-regexp "#.*" "") ; Remove all comments + (mailcap-replace-regexp "\\\\[ \t]*\n" " ") ; And collapse spaces + (mailcap-replace-regexp "\n+" "\n") ; And blank lines + (goto-char (point-max)) + (skip-chars-backward " \t\n") + (delete-region (point) (point-max)) + (while (not (bobp)) + (skip-chars-backward " \t\n") + (beginning-of-line) + (setq save-pos (point) + info nil) + (skip-chars-forward "^/; \t\n") + (downcase-region save-pos (point)) + (setq major (buffer-substring save-pos (point))) + (skip-chars-forward " \t") + (setq minor "") + (when (eq (char-after) ?/) + (forward-char) + (skip-chars-forward " \t") + (setq save-pos (point)) + (skip-chars-forward "^; \t\n") + (downcase-region save-pos (point)) + (setq minor + (cond + ((eq ?* (or (char-after save-pos) 0)) ".*") + ((= (point) save-pos) ".*") + (t (regexp-quote (buffer-substring save-pos (point))))))) + (skip-chars-forward " \t") + ;;; Got the major/minor chunks, now for the viewers/etc + ;;; The first item _must_ be a viewer, according to the + ;;; RFC for mailcap files (#1343) + (setq viewer "") + (when (eq (char-after) ?\;) + (forward-char) + (skip-chars-forward " \t") + (setq save-pos (point)) + (skip-chars-forward "^;\n") + ;; skip \; + (while (eq (char-before) ?\\) + (backward-delete-char 1) + (forward-char) + (skip-chars-forward "^;\n")) + (if (eq (or (char-after save-pos) 0) ?') + (setq viewer (progn + (narrow-to-region (1+ save-pos) (point)) + (goto-char (point-min)) + (prog1 + (read (current-buffer)) + (goto-char (point-max)) + (widen)))) + (setq viewer (buffer-substring save-pos (point))))) + (setq save-pos (point)) + (end-of-line) + (unless (equal viewer "") + (setq info (nconc (list (cons 'viewer viewer) + (cons 'type (concat major "/" + (if (string= minor ".*") + "*" minor)))) + (mailcap-parse-mailcap-extras save-pos (point)))) + (mailcap-mailcap-entry-passes-test info) + (mailcap-add-mailcap-entry major minor info)) + (beginning-of-line))))) + +(defun mailcap-parse-mailcap-extras (st nd) + ;; Grab all the extra stuff from a mailcap entry + (let ( + name ; From name= + value ; its value + results ; Assoc list of results + name-pos ; Start of XXXX= position + val-pos ; Start of value position + done ; Found end of \'d ;s? + ) + (save-restriction + (narrow-to-region st nd) + (goto-char (point-min)) + (skip-chars-forward " \n\t;") + (while (not (eobp)) + (setq done nil) + (setq name-pos (point)) + (skip-chars-forward "^ \n\t=;") + (downcase-region name-pos (point)) + (setq name (buffer-substring name-pos (point))) + (skip-chars-forward " \t\n") + (if (not (eq (char-after (point)) ?=)) ; There is no value + (setq value t) + (skip-chars-forward " \t\n=") + (setq val-pos (point)) + (if (memq (char-after val-pos) '(?\" ?')) + (progn + (setq val-pos (1+ val-pos)) + (condition-case nil + (progn + (forward-sexp 1) + (backward-char 1)) + (error (goto-char (point-max))))) + (while (not done) + (skip-chars-forward "^;") + (if (eq (char-after (1- (point))) ?\\ ) + (progn + (subst-char-in-region (1- (point)) (point) ?\\ ? ) + (skip-chars-forward ";")) + (setq done t)))) + (setq value (buffer-substring val-pos (point)))) + (setq results (cons (cons name value) results)) + (skip-chars-forward " \";\n\t")) + results))) + +(defun mailcap-mailcap-entry-passes-test (info) + ;; Return t iff a mailcap entry passes its test clause or no test + ;; clause is present. + (let (status ; Call-process-regions return value + (test (assq 'test info)) ; The test clause + ) + (setq status (and test (split-string (cdr test) " "))) + (if (and (or (assoc "needsterm" info) + (assoc "needsterminal" info) + (assoc "needsx11" info)) + (not (getenv "DISPLAY"))) + (setq status nil) + (cond + ((and (equal (nth 0 status) "test") + (equal (nth 1 status) "-n") + (or (equal (nth 2 status) "$DISPLAY") + (equal (nth 2 status) "\"$DISPLAY\""))) + (setq status (if (getenv "DISPLAY") t nil))) + ((and (equal (nth 0 status) "test") + (equal (nth 1 status) "-z") + (or (equal (nth 2 status) "$DISPLAY") + (equal (nth 2 status) "\"$DISPLAY\""))) + (setq status (if (getenv "DISPLAY") nil t))) + (test nil) + (t nil))) + (and test (listp test) (setcdr test status)))) + +;;; +;;; The action routines. +;;; + +(defun mailcap-possible-viewers (major minor) + ;; Return a list of possible viewers from MAJOR for minor type MINOR + (let ((exact '()) + (wildcard '())) + (while major + (cond + ((equal (car (car major)) minor) + (setq exact (cons (cdr (car major)) exact))) + ((and minor (string-match (car (car major)) minor)) + (setq wildcard (cons (cdr (car major)) wildcard)))) + (setq major (cdr major))) + (nconc exact wildcard))) + +(defun mailcap-unescape-mime-test (test type-info) + (let (save-pos save-chr subst) + (cond + ((symbolp test) test) + ((and (listp test) (symbolp (car test))) test) + ((or (stringp test) + (and (listp test) (stringp (car test)) + (setq test (mapconcat 'identity test " ")))) + (with-temp-buffer + (insert test) + (goto-char (point-min)) + (while (not (eobp)) + (skip-chars-forward "^%") + (if (/= (- (point) + (progn (skip-chars-backward "\\\\") + (point))) + 0) ; It is an escaped % + (progn + (delete-char 1) + (skip-chars-forward "%.")) + (setq save-pos (point)) + (skip-chars-forward "%") + (setq save-chr (char-after (point))) + (cond + ((null save-chr) nil) + ((= save-chr ?t) + (delete-region save-pos (progn (forward-char 1) (point))) + (insert (or (cdr (assq 'type type-info)) "\"\""))) + ((= save-chr ?M) + (delete-region save-pos (progn (forward-char 1) (point))) + (insert "\"\"")) + ((= save-chr ?n) + (delete-region save-pos (progn (forward-char 1) (point))) + (insert "\"\"")) + ((= save-chr ?F) + (delete-region save-pos (progn (forward-char 1) (point))) + (insert "\"\"")) + ((= save-chr ?{) + (forward-char 1) + (skip-chars-forward "^}") + (downcase-region (+ 2 save-pos) (point)) + (setq subst (buffer-substring (+ 2 save-pos) (point))) + (delete-region save-pos (1+ (point))) + (insert (or (cdr (assoc subst type-info)) "\"\""))) + (t nil)))) + (buffer-string))) + (t (error "Bad value to mailcap-unescape-mime-test. %s" test))))) + +(defvar mailcap-viewer-test-cache nil) + +(defun mailcap-viewer-passes-test (viewer-info type-info) + ;; Return non-nil iff the viewer specified by VIEWER-INFO passes its + ;; test clause (if any). + (let* ((test-info (assq 'test viewer-info)) + (test (cdr test-info)) + (otest test) + (viewer (cdr (assoc 'viewer viewer-info))) + (default-directory (expand-file-name "~/")) + status parsed-test cache result) + (if (setq cache (assoc test mailcap-viewer-test-cache)) + (cadr cache) + (setq + result + (cond + ((not test-info) t) ; No test clause + ((not test) nil) ; Already failed test + ((eq test t) t) ; Already passed test + ((and (symbolp test) ; Lisp function as test + (fboundp test)) + (funcall test type-info)) + ((and (symbolp test) ; Lisp variable as test + (boundp test)) + (symbol-value test)) + ((and (listp test) ; List to be eval'd + (symbolp (car test))) + (eval test)) + (t + (setq test (mailcap-unescape-mime-test test type-info) + test (list shell-file-name nil nil nil + shell-command-switch test) + status (apply 'call-process test)) + (= 0 status)))) + (push (list otest result) mailcap-viewer-test-cache) + result))) + +(defun mailcap-add-mailcap-entry (major minor info) + (let ((old-major (assoc major mailcap-mime-data))) + (if (null old-major) ; New major area + (setq mailcap-mime-data + (cons (cons major (list (cons minor info))) + mailcap-mime-data)) + (let ((cur-minor (assoc minor old-major))) + (cond + ((or (null cur-minor) ; New minor area, or + (assq 'test info)) ; Has a test, insert at beginning + (setcdr old-major (cons (cons minor info) (cdr old-major)))) + ((and (not (assq 'test info)) ; No test info, replace completely + (not (assq 'test cur-minor)) + (equal (assq 'viewer info) ; Keep alternative viewer + (assq 'viewer cur-minor))) + (setcdr cur-minor info)) + (t + (setcdr old-major (cons (cons minor info) (cdr old-major)))))) + ))) + +(defun mailcap-add (type viewer &optional test) + "Add VIEWER as a handler for TYPE. +If TEST is not given, it defaults to t." + (let ((tl (split-string type "/"))) + (when (or (not (car tl)) + (not (cadr tl))) + (error "%s is not a valid MIME type" type)) + (mailcap-add-mailcap-entry + (car tl) (cadr tl) + `((viewer . ,viewer) + (test . ,(if test test t)) + (type . ,type))))) + +;;; +;;; The main whabbo +;;; + +(defun mailcap-viewer-lessp (x y) + ;; Return t iff viewer X is more desirable than viewer Y + (let ((x-wild (string-match "[*?]" (or (cdr-safe (assq 'type x)) ""))) + (y-wild (string-match "[*?]" (or (cdr-safe (assq 'type y)) ""))) + (x-lisp (not (stringp (or (cdr-safe (assq 'viewer x)) "")))) + (y-lisp (not (stringp (or (cdr-safe (assq 'viewer y)) ""))))) + (cond + ((and x-wild (not y-wild)) + nil) + ((and (not x-wild) y-wild) + t) + ((and (not y-lisp) x-lisp) + t) + (t nil)))) + +(defun mailcap-mime-info (string &optional request) + "Get the MIME viewer command for STRING, return nil if none found. +Expects a complete content-type header line as its argument. + +Second argument REQUEST specifies what information to return. If it is +nil or the empty string, the viewer (second field of the mailcap +entry) will be returned. If it is a string, then the mailcap field +corresponding to that string will be returned (print, description, +whatever). If a number, then all the information for this specific +viewer is returned. If `all', then all possible viewers for +this type is returned." + (let ( + major ; Major encoding (text, etc) + minor ; Minor encoding (html, etc) + info ; Other info + save-pos ; Misc. position during parse + major-info ; (assoc major mailcap-mime-data) + minor-info ; (assoc minor major-info) + test ; current test proc. + viewers ; Possible viewers + passed ; Viewers that passed the test + viewer ; The one and only viewer + ctl) + (save-excursion + (setq ctl (mail-header-parse-content-type (or string "text/plain"))) + (setq major (split-string (car ctl) "/")) + (setq minor (cadr major) + major (car major)) + (when (setq major-info (cdr (assoc major mailcap-mime-data))) + (when (setq viewers (mailcap-possible-viewers major-info minor)) + (setq info (mapcar (lambda (a) (cons (symbol-name (car a)) + (cdr a))) + (cdr ctl))) + (while viewers + (if (mailcap-viewer-passes-test (car viewers) info) + (setq passed (cons (car viewers) passed))) + (setq viewers (cdr viewers))) + (setq passed (sort passed 'mailcap-viewer-lessp)) + (setq viewer (car passed)))) + (when (and (stringp (cdr (assq 'viewer viewer))) + passed) + (setq viewer (car passed))) + (cond + ((and (null viewer) (not (equal major "default")) request) + (mailcap-mime-info "default" request)) + ((or (null request) (equal request "")) + (mailcap-unescape-mime-test (cdr (assq 'viewer viewer)) info)) + ((stringp request) + (if (or (eq request 'test) (eq request 'viewer)) + (mailcap-unescape-mime-test + (cdr-safe (assoc request viewer)) info))) + ((eq request 'all) + passed) + (t + ;; MUST make a copy *sigh*, else we modify mailcap-mime-data + (setq viewer (copy-sequence viewer)) + (let ((view (assq 'viewer viewer)) + (test (assq 'test viewer))) + (if view (setcdr view (mailcap-unescape-mime-test (cdr view) info))) + (if test (setcdr test (mailcap-unescape-mime-test (cdr test) info)))) + viewer))))) + +;;; +;;; Experimental MIME-types parsing +;;; + +(defvar mailcap-mime-extensions + '(("" . "text/plain") + (".abs" . "audio/x-mpeg") + (".aif" . "audio/aiff") + (".aifc" . "audio/aiff") + (".aiff" . "audio/aiff") + (".ano" . "application/x-annotator") + (".au" . "audio/ulaw") + (".avi" . "video/x-msvideo") + (".bcpio" . "application/x-bcpio") + (".bin" . "application/octet-stream") + (".cdf" . "application/x-netcdr") + (".cpio" . "application/x-cpio") + (".csh" . "application/x-csh") + (".css" . "text/css") + (".dvi" . "application/x-dvi") + (".diff" . "text/x-patch") + (".el" . "application/emacs-lisp") + (".eps" . "application/postscript") + (".etx" . "text/x-setext") + (".exe" . "application/octet-stream") + (".fax" . "image/x-fax") + (".gif" . "image/gif") + (".hdf" . "application/x-hdf") + (".hqx" . "application/mac-binhex40") + (".htm" . "text/html") + (".html" . "text/html") + (".icon" . "image/x-icon") + (".ief" . "image/ief") + (".jpg" . "image/jpeg") + (".macp" . "image/x-macpaint") + (".man" . "application/x-troff-man") + (".me" . "application/x-troff-me") + (".mif" . "application/mif") + (".mov" . "video/quicktime") + (".movie" . "video/x-sgi-movie") + (".mp2" . "audio/x-mpeg") + (".mp3" . "audio/x-mpeg") + (".mp2a" . "audio/x-mpeg2") + (".mpa" . "audio/x-mpeg") + (".mpa2" . "audio/x-mpeg2") + (".mpe" . "video/mpeg") + (".mpeg" . "video/mpeg") + (".mpega" . "audio/x-mpeg") + (".mpegv" . "video/mpeg") + (".mpg" . "video/mpeg") + (".mpv" . "video/mpeg") + (".ms" . "application/x-troff-ms") + (".nc" . "application/x-netcdf") + (".nc" . "application/x-netcdf") + (".oda" . "application/oda") + (".patch" . "text/x-patch") + (".pbm" . "image/x-portable-bitmap") + (".pdf" . "application/pdf") + (".pgm" . "image/portable-graymap") + (".pict" . "image/pict") + (".png" . "image/png") + (".pnm" . "image/x-portable-anymap") + (".ppm" . "image/portable-pixmap") + (".ps" . "application/postscript") + (".qt" . "video/quicktime") + (".ras" . "image/x-raster") + (".rgb" . "image/x-rgb") + (".rtf" . "application/rtf") + (".rtx" . "text/richtext") + (".sh" . "application/x-sh") + (".sit" . "application/x-stuffit") + (".snd" . "audio/basic") + (".src" . "application/x-wais-source") + (".tar" . "archive/tar") + (".tcl" . "application/x-tcl") + (".tcl" . "application/x-tcl") + (".tex" . "application/x-tex") + (".texi" . "application/texinfo") + (".tga" . "image/x-targa") + (".tif" . "image/tiff") + (".tiff" . "image/tiff") + (".tr" . "application/x-troff") + (".troff" . "application/x-troff") + (".tsv" . "text/tab-separated-values") + (".txt" . "text/plain") + (".vbs" . "video/mpeg") + (".vox" . "audio/basic") + (".vrml" . "x-world/x-vrml") + (".wav" . "audio/x-wav") + (".wrl" . "x-world/x-vrml") + (".xbm" . "image/xbm") + (".xpm" . "image/xpm") + (".xwd" . "image/windowdump") + (".zip" . "application/zip") + (".ai" . "application/postscript") + (".jpe" . "image/jpeg") + (".jpeg" . "image/jpeg")) + "An assoc list of file extensions and corresponding MIME content-types.") + +(defvar mailcap-mimetypes-parsed-p nil) + +(defun mailcap-parse-mimetypes (&optional path force) + "Parse out all the mimetypes specified in a unix-style path string PATH. +Components of PATH are separated by the `path-separator' character +appropriate for this system. If PATH is omitted, use the value of +environment variable MIMETYPES if set; otherwise use a default path. +If FORCE, re-parse even if already parsed." + (interactive (list nil t)) + (when (or (not mailcap-mimetypes-parsed-p) + force) + (cond + (path nil) + ((getenv "MIMETYPES") (setq path (getenv "MIMETYPES"))) + ((memq system-type '(ms-dos ms-windows windows-nt)) + (setq path '("~/mime.typ" "~/etc/mime.typ"))) + (t (setq path + ;; mime.types seems to be the normal name, definitely so + ;; on current GNUish systems. The search order follows + ;; that for mailcap. + '("~/.mime.types" + "/etc/mime.types" + "/usr/etc/mime.types" + "/usr/local/etc/mime.types" + "/usr/local/www/conf/mime.types" + "~/.mime-types" + "/etc/mime-types" + "/usr/etc/mime-types" + "/usr/local/etc/mime-types" + "/usr/local/www/conf/mime-types")))) + (let ((fnames (reverse (if (stringp path) + (parse-colon-path path) + path))) + fname) + (while fnames + (setq fname (car fnames)) + (if (and (file-readable-p fname)) + (mailcap-parse-mimetype-file fname)) + (setq fnames (cdr fnames)))) + (setq mailcap-mimetypes-parsed-p t))) + +(defun mailcap-parse-mimetype-file (fname) + ;; Parse out a mime-types file + (let (type ; The MIME type for this line + extns ; The extensions for this line + save-pos ; Misc. saved buffer positions + ) + (with-temp-buffer + (insert-file-contents fname) + (mailcap-replace-regexp "#.*" "") + (mailcap-replace-regexp "\n+" "\n") + (mailcap-replace-regexp "[ \t]+$" "") + (goto-char (point-max)) + (skip-chars-backward " \t\n") + (delete-region (point) (point-max)) + (goto-char (point-min)) + (while (not (eobp)) + (skip-chars-forward " \t\n") + (setq save-pos (point)) + (skip-chars-forward "^ \t\n") + (downcase-region save-pos (point)) + (setq type (buffer-substring save-pos (point))) + (while (not (eolp)) + (skip-chars-forward " \t") + (setq save-pos (point)) + (skip-chars-forward "^ \t\n") + (setq extns (cons (buffer-substring save-pos (point)) extns))) + (while extns + (setq mailcap-mime-extensions + (cons + (cons (if (= (string-to-char (car extns)) ?.) + (car extns) + (concat "." (car extns))) type) + mailcap-mime-extensions) + extns (cdr extns))))))) + +(defun mailcap-extension-to-mime (extn) + "Return the MIME content type of the file extensions EXTN." + (mailcap-parse-mimetypes) + (if (and (stringp extn) + (not (eq (string-to-char extn) ?.))) + (setq extn (concat "." extn))) + (cdr (assoc (downcase extn) mailcap-mime-extensions))) + +(defvar mailcap-binary-suffixes + (if (memq system-type '(ms-dos windows-nt)) + '(".exe" ".com" ".bat" ".cmd" ".btm" "") + '(""))) + +(defun mailcap-command-p (command) + "Say whether COMMAND is in the exec path. +The path of COMMAND will be returned iff COMMAND is a command." + (let ((path (if (file-name-absolute-p command) '(nil) exec-path)) + file dir) + (catch 'found + (while (setq dir (pop path)) + (let ((suffixes mailcap-binary-suffixes)) + (while suffixes + (when (and (file-executable-p + (setq file (expand-file-name + (concat command (pop suffixes)) + dir))) + (not (file-directory-p file))) + (throw 'found file)))))))) + +(defun mailcap-mime-types () + "Return a list of MIME media types." + (mailcap-parse-mimetypes) + (mm-delete-duplicates (mapcar 'cdr mailcap-mime-extensions))) + +(provide 'mailcap) + +;;; mailcap.el ends here diff --git a/lisp/gnus/mm-bodies.el b/lisp/gnus/mm-bodies.el new file mode 100644 index 00000000000..f90f74c3cd9 --- /dev/null +++ b/lisp/gnus/mm-bodies.el @@ -0,0 +1,258 @@ +;;; mm-bodies.el --- Functions for decoding MIME things +;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; MORIOKA Tomohiko +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(eval-and-compile + (or (fboundp 'base64-decode-region) + (require 'base64)) + (autoload 'binhex-decode-region "binhex")) + +(require 'mm-util) +(require 'rfc2047) +(require 'qp) +(require 'uudecode) + +;; 8bit treatment gets any char except: 0x32 - 0x7f, CR, LF, TAB, BEL, +;; BS, vertical TAB, form feed, and ^_ +(defvar mm-7bit-chars "\x20-\x7f\r\n\t\x7\x8\xb\xc\x1f") + +(defcustom mm-body-charset-encoding-alist + '((iso-2022-jp . 7bit) + (iso-2022-jp-2 . 7bit)) + "Alist of MIME charsets to encodings. +Valid encodings are `7bit', `8bit', `quoted-printable' and `base64'." + :type '(repeat (cons (symbol :tag "charset") + (choice :tag "encoding" + (const 7bit) + (const 8bit) + (const quoted-printable) + (const base64)))) + :group 'mime) + +(defun mm-encode-body () + "Encode a body. +Should be called narrowed to the body that is to be encoded. +If there is more than one non-ASCII MULE charset, then list of found +MULE charsets are returned. +If successful, the MIME charset is returned. +If no encoding was done, nil is returned." + (if (not (featurep 'mule)) + ;; In the non-Mule case, we search for non-ASCII chars and + ;; return the value of `mail-parse-charset' if any are found. + (save-excursion + (goto-char (point-min)) + (if (re-search-forward "[^\x0-\x7f]" nil t) + (or mail-parse-charset + (mm-read-charset "Charset used in the article: ")) + ;; The logic in `mml-generate-mime-1' confirms that it's OK + ;; to return nil here. + nil)) + (save-excursion + (goto-char (point-min)) + (let ((charsets (mm-find-mime-charset-region (point-min) (point-max))) + charset) + (cond + ;; No encoding. + ((null charsets) + nil) + ;; Too many charsets. + ((> (length charsets) 1) + charsets) + ;; We encode. + (t + (let ((charset (car charsets)) + start) + (when (or t + ;; We always decode. + (not (mm-coding-system-equal + charset buffer-file-coding-system))) + (while (not (eobp)) + (if (eq (mm-charset-after) 'ascii) + (when start + (save-restriction + (narrow-to-region start (point)) + (mm-encode-coding-region start (point) charset) + (goto-char (point-max))) + (setq start nil)) + (unless start + (setq start (point)))) + (forward-char 1)) + (when start + (mm-encode-coding-region start (point) charset) + (setq start nil))) + charset))))))) + +(defun mm-body-encoding (charset &optional encoding) + "Do Content-Transfer-Encoding and return the encoding of the current buffer." + (let ((bits (mm-body-7-or-8))) + (cond + ((and (not mm-use-ultra-safe-encoding) (eq bits '7bit)) + bits) + ((and (not mm-use-ultra-safe-encoding) + (or (eq t (cdr message-posting-charset)) + (memq charset (cdr message-posting-charset)) + (eq charset mail-parse-charset))) + bits) + (t + (let ((encoding (or encoding + (cdr (assq charset mm-body-charset-encoding-alist)) + (mm-qp-or-base64)))) + (when mm-use-ultra-safe-encoding + (setq encoding (mm-safer-encoding encoding))) + (mm-encode-content-transfer-encoding encoding "text/plain") + encoding))))) + +(defun mm-body-7-or-8 () + "Say whether the body is 7bit or 8bit." + (cond + ((not (featurep 'mule)) + (if (save-excursion + (goto-char (point-min)) + (skip-chars-forward mm-7bit-chars) + (eobp)) + '7bit + '8bit)) + (t + ;; Mule version + (if (and (null (delq 'ascii + (mm-find-charset-region (point-min) (point-max)))) + ;;!!!The following is necessary because the function + ;;!!!above seems to return the wrong result under + ;;!!!Emacs 20.3. Sometimes. + (save-excursion + (goto-char (point-min)) + (skip-chars-forward mm-7bit-chars) + (eobp))) + '7bit + '8bit)))) + +;;; +;;; Functions for decoding +;;; + +(defun mm-decode-content-transfer-encoding (encoding &optional type) + (prog1 + (condition-case error + (cond + ((eq encoding 'quoted-printable) + (quoted-printable-decode-region (point-min) (point-max))) + ((eq encoding 'base64) + (base64-decode-region + (point-min) + ;; Some mailers insert whitespace + ;; junk at the end which + ;; base64-decode-region dislikes. + ;; Also remove possible junk which could + ;; have been added by mailing list software. + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "^[\t ]*\r?\n" nil t) + (delete-region (match-beginning 0) (match-end 0))) + (goto-char (point-max)) + (when (re-search-backward "^[A-Za-z0-9+/]+=*[\t ]*$" nil t) + (forward-line) + (delete-region (point) (point-max))) + (point-max)))) + ((memq encoding '(7bit 8bit binary)) + ;; Do nothing. + ) + ((null encoding) + ;; Do nothing. + ) + ((memq encoding '(x-uuencode x-uue)) + (funcall mm-uu-decode-function (point-min) (point-max))) + ((eq encoding 'x-binhex) + (funcall mm-uu-binhex-decode-function (point-min) (point-max))) + ((functionp encoding) + (funcall encoding (point-min) (point-max))) + (t + (message "Unknown encoding %s; defaulting to 8bit" encoding))) + (error + (message "Error while decoding: %s" error) + nil)) + (when (and + (memq encoding '(base64 x-uuencode x-uue x-binhex)) + (equal type "text/plain")) + (goto-char (point-min)) + (while (search-forward "\r\n" nil t) + (replace-match "\n" t t))))) + +(defun mm-decode-body (charset &optional encoding type) + "Decode the current article that has been encoded with ENCODING. +The characters in CHARSET should then be decoded." + (if (stringp charset) + (setq charset (intern (downcase charset)))) + (if (or (not charset) + (eq 'gnus-all mail-parse-ignored-charsets) + (memq 'gnus-all mail-parse-ignored-charsets) + (memq charset mail-parse-ignored-charsets)) + (setq charset mail-parse-charset)) + (save-excursion + (when encoding + (mm-decode-content-transfer-encoding encoding type)) + (when (featurep 'mule) + (let ((mule-charset (mm-charset-to-coding-system charset))) + (if (and (not mule-charset) + (listp mail-parse-ignored-charsets) + (memq 'gnus-unknown mail-parse-ignored-charsets)) + (setq mule-charset + (mm-charset-to-coding-system mail-parse-charset))) + (when (and charset mule-charset + ;; buffer-file-coding-system + ;;Article buffer is nil coding system + ;;in XEmacs + (mm-multibyte-p) + (or (not (eq mule-charset 'ascii)) + (setq mule-charset mail-parse-charset)) + (not (eq mule-charset 'gnus-decoded))) + (mm-decode-coding-region (point-min) (point-max) mule-charset)))))) + +(defun mm-decode-string (string charset) + "Decode STRING with CHARSET." + (when (stringp charset) + (setq charset (intern (downcase charset)))) + (when (or (not charset) + (eq 'gnus-all mail-parse-ignored-charsets) + (memq 'gnus-all mail-parse-ignored-charsets) + (memq charset mail-parse-ignored-charsets)) + (setq charset mail-parse-charset)) + (or + (when (featurep 'mule) + (let ((mule-charset (mm-charset-to-coding-system charset))) + (if (and (not mule-charset) + (listp mail-parse-ignored-charsets) + (memq 'gnus-unknown mail-parse-ignored-charsets)) + (setq mule-charset + (mm-charset-to-coding-system mail-parse-charset))) + (when (and charset mule-charset + (mm-multibyte-p) + (or (not (eq mule-charset 'ascii)) + (setq mule-charset mail-parse-charset))) + (mm-decode-coding-string string mule-charset)))) + string)) + +(provide 'mm-bodies) + +;; mm-bodies.el ends here diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el new file mode 100644 index 00000000000..69f0d1898ad --- /dev/null +++ b/lisp/gnus/mm-decode.el @@ -0,0 +1,835 @@ +;;; mm-decode.el --- Functions for decoding MIME things +;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; MORIOKA Tomohiko +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(require 'mail-parse) +(require 'mailcap) +(require 'mm-bodies) +(eval-when-compile (require 'cl)) + +(eval-and-compile + (autoload 'mm-inline-partial "mm-partial")) + +(defgroup mime-display () + "Display of MIME in mail and news articles." + :link '(custom-manual "(emacs-mime)Customization") + :version "21.1" + :group 'mail + :group 'news + :group 'multimedia) + +;;; Convenience macros. + +(defmacro mm-handle-buffer (handle) + `(nth 0 ,handle)) +(defmacro mm-handle-type (handle) + `(nth 1 ,handle)) +(defsubst mm-handle-media-type (handle) + (if (stringp (car handle)) + (car handle) + (car (mm-handle-type handle)))) +(defsubst mm-handle-media-supertype (handle) + (car (split-string (mm-handle-media-type handle) "/"))) +(defsubst mm-handle-media-subtype (handle) + (cadr (split-string (mm-handle-media-type handle) "/"))) +(defmacro mm-handle-encoding (handle) + `(nth 2 ,handle)) +(defmacro mm-handle-undisplayer (handle) + `(nth 3 ,handle)) +(defmacro mm-handle-set-undisplayer (handle function) + `(setcar (nthcdr 3 ,handle) ,function)) +(defmacro mm-handle-disposition (handle) + `(nth 4 ,handle)) +(defmacro mm-handle-description (handle) + `(nth 5 ,handle)) +(defmacro mm-handle-cache (handle) + `(nth 6 ,handle)) +(defmacro mm-handle-set-cache (handle contents) + `(setcar (nthcdr 6 ,handle) ,contents)) +(defmacro mm-handle-id (handle) + `(nth 7 ,handle)) +(defmacro mm-make-handle (&optional buffer type encoding undisplayer + disposition description cache + id) + `(list ,buffer ,type ,encoding ,undisplayer + ,disposition ,description ,cache ,id)) + +(defcustom mm-inline-media-tests + '(("image/jpeg" + mm-inline-image + (lambda (handle) + (mm-valid-and-fit-image-p 'jpeg handle))) + ("image/png" + mm-inline-image + (lambda (handle) + (mm-valid-and-fit-image-p 'png handle))) + ("image/gif" + mm-inline-image + (lambda (handle) + (mm-valid-and-fit-image-p 'gif handle))) + ("image/tiff" + mm-inline-image + (lambda (handle) + (mm-valid-and-fit-image-p 'tiff handle)) ) + ("image/xbm" + mm-inline-image + (lambda (handle) + (mm-valid-and-fit-image-p 'xbm handle))) + ("image/x-xbitmap" + mm-inline-image + (lambda (handle) + (mm-valid-and-fit-image-p 'xbm handle))) + ("image/xpm" + mm-inline-image + (lambda (handle) + (mm-valid-and-fit-image-p 'xpm handle))) + ("image/x-pixmap" + mm-inline-image + (lambda (handle) + (mm-valid-and-fit-image-p 'xpm handle))) + ("image/bmp" + mm-inline-image + (lambda (handle) + (mm-valid-and-fit-image-p 'bmp handle))) + ("text/plain" mm-inline-text identity) + ("text/enriched" mm-inline-text identity) + ("text/richtext" mm-inline-text identity) + ("text/x-patch" mm-display-patch-inline + (lambda (handle) + (locate-library "diff-mode"))) + ("text/html" + mm-inline-text + (lambda (handle) + (locate-library "w3"))) + ("text/x-vcard" + mm-inline-text + (lambda (handle) + (or (featurep 'vcard) + (locate-library "vcard")))) + ("message/delivery-status" mm-inline-text identity) + ("message/rfc822" mm-inline-message identity) + ("message/partial" mm-inline-partial identity) + ("text/.*" mm-inline-text identity) + ("audio/wav" mm-inline-audio + (lambda (handle) + (and (or (featurep 'nas-sound) (featurep 'native-sound)) + (device-sound-enabled-p)))) + ("audio/au" + mm-inline-audio + (lambda (handle) + (and (or (featurep 'nas-sound) (featurep 'native-sound)) + (device-sound-enabled-p)))) + ("application/pgp-signature" ignore identity) + ("multipart/alternative" ignore identity) + ("multipart/mixed" ignore identity) + ("multipart/related" ignore identity)) + "Alist of media types/tests saying whether types can be displayed inline." + :type '(repeat (list (string :tag "MIME type") + (function :tag "Display function") + (function :tag "Display test"))) + :group 'mime-display) + +(defcustom mm-inlined-types + '("image/.*" "text/.*" "message/delivery-status" "message/rfc822" + "message/partial" + "application/pgp-signature") + "List of media types that are to be displayed inline." + :type '(repeat string) + :group 'mime-display) + +(defcustom mm-automatic-display + '("text/plain" "text/enriched" "text/richtext" "text/html" + "text/x-vcard" "image/.*" "message/delivery-status" "multipart/.*" + "message/rfc822" "text/x-patch" "application/pgp-signature") + "A list of MIME types to be displayed automatically." + :type '(repeat string) + :group 'mime-display) + +(defcustom mm-attachment-override-types '("text/x-vcard") + "Types to have \"attachment\" ignored if they can be displayed inline." + :type '(repeat string) + :group 'mime-display) + +(defcustom mm-inline-override-types nil + "Types to be treated as attachments even if they can be displayed inline." + :type '(repeat string) + :group 'mime-display) + +(defcustom mm-automatic-external-display nil + "List of MIME type regexps that will be displayed externally automatically." + :type '(repeat string) + :group 'mime-display) + +(defcustom mm-discouraged-alternatives nil + "List of MIME types that are discouraged when viewing multipart/alternative. +Viewing agents are supposed to view the last possible part of a message, +as that is supposed to be the richest. However, users may prefer other +types instead, and this list says what types are most unwanted. If, +for instance, text/html parts are very unwanted, and text/richtext are +somewhat unwanted, then the value of this variable should be set +to: + + (\"text/html\" \"text/richtext\")" + :type '(repeat string) + :group 'mime-display) + +(defvar mm-tmp-directory + (cond ((fboundp 'temp-directory) (temp-directory)) + ((boundp 'temporary-file-directory) temporary-file-directory) + ("/tmp/")) + "Where mm will store its temporary files.") + +(defcustom mm-inline-large-images nil + "If non-nil, then all images fit in the buffer." + :type 'boolean + :group 'mime-display) + +;;; Internal variables. + +(defvar mm-dissection-list nil) +(defvar mm-last-shell-command "") +(defvar mm-content-id-alist nil) + +;; According to RFC2046, in particular, in a digest, the default +;; Content-Type value for a body part is changed from "text/plain" to +;; "message/rfc822". +(defvar mm-dissect-default-type "text/plain") + +;;; The functions. + +(defun mm-dissect-buffer (&optional no-strict-mime) + "Dissect the current buffer and return a list of MIME handles." + (save-excursion + (let (ct ctl type subtype cte cd description id result) + (save-restriction + (mail-narrow-to-head) + (when (or no-strict-mime + (mail-fetch-field "mime-version")) + (setq ct (mail-fetch-field "content-type") + ctl (ignore-errors (mail-header-parse-content-type ct)) + cte (mail-fetch-field "content-transfer-encoding") + cd (mail-fetch-field "content-disposition") + description (mail-fetch-field "content-description") + id (mail-fetch-field "content-id")))) + (when cte + (setq cte (mail-header-strip cte))) + (if (or (not ctl) + (not (string-match "/" (car ctl)))) + (mm-dissect-singlepart + (list mm-dissect-default-type) + (and cte (intern (downcase (mail-header-remove-whitespace + (mail-header-remove-comments + cte))))) + no-strict-mime + (and cd (ignore-errors (mail-header-parse-content-disposition cd))) + description) + (setq type (split-string (car ctl) "/")) + (setq subtype (cadr type) + type (pop type)) + (setq + result + (cond + ((equal type "multipart") + (let ((mm-dissect-default-type (if (equal subtype "digest") + "message/rfc822" + "text/plain"))) + (cons (car ctl) (mm-dissect-multipart ctl)))) + (t + (mm-dissect-singlepart + ctl + (and cte (intern (downcase (mail-header-remove-whitespace + (mail-header-remove-comments + cte))))) + no-strict-mime + (and cd (ignore-errors (mail-header-parse-content-disposition cd))) + description id)))) + (when id + (when (string-match " *<\\(.*\\)> *" id) + (setq id (match-string 1 id))) + (push (cons id result) mm-content-id-alist)) + result)))) + +(defun mm-dissect-singlepart (ctl cte &optional force cdl description id) + (when (or force + (if (equal "text/plain" (car ctl)) + (assoc 'format ctl) + t)) + (let ((res (mm-make-handle + (mm-copy-to-buffer) ctl cte nil cdl description nil id))) + (push (car res) mm-dissection-list) + res))) + +(defun mm-remove-all-parts () + "Remove all MIME handles." + (interactive) + (mapcar 'mm-remove-part mm-dissection-list) + (setq mm-dissection-list nil)) + +(defun mm-dissect-multipart (ctl) + (goto-char (point-min)) + (let* ((boundary (concat "\n--" (mail-content-type-get ctl 'boundary))) + (close-delimiter (concat (regexp-quote boundary) "--[ \t]*$")) + start parts + (end (save-excursion + (goto-char (point-max)) + (if (re-search-backward close-delimiter nil t) + (match-beginning 0) + (point-max))))) + (setq boundary (concat (regexp-quote boundary) "[ \t]*$")) + (while (re-search-forward boundary end t) + (goto-char (match-beginning 0)) + (when start + (save-excursion + (save-restriction + (narrow-to-region start (point)) + (setq parts (nconc (list (mm-dissect-buffer t)) parts))))) + (forward-line 2) + (setq start (point))) + (when start + (save-excursion + (save-restriction + (narrow-to-region start end) + (setq parts (nconc (list (mm-dissect-buffer t)) parts))))) + (nreverse parts))) + +(defun mm-copy-to-buffer () + "Copy the contents of the current buffer to a fresh buffer." + (save-excursion + (let ((obuf (current-buffer)) + beg) + (goto-char (point-min)) + (search-forward-regexp "^\n" nil t) + (setq beg (point)) + (set-buffer (generate-new-buffer " *mm*")) + (insert-buffer-substring obuf beg) + (current-buffer)))) + +(defun mm-display-part (handle &optional no-default) + "Display the MIME part represented by HANDLE. +Returns nil if the part is removed; inline if displayed inline; +external if displayed external." + (save-excursion + (mailcap-parse-mailcaps) + (if (mm-handle-displayed-p handle) + (mm-remove-part handle) + (let* ((type (mm-handle-media-type handle)) + (method (mailcap-mime-info type))) + (if (mm-inlined-p handle) + (progn + (forward-line 1) + (mm-display-inline handle) + 'inline) + (when (or method + (not no-default)) + (if (and (not method) + (equal "text" (car (split-string type)))) + (progn + (forward-line 1) + (mm-insert-inline handle (mm-get-part handle)) + 'inline) + (mm-display-external + handle (or method 'mailcap-save-binary-file))))))))) + +(defun mm-display-external (handle method) + "Display HANDLE using METHOD." + (let ((outbuf (current-buffer))) + (mm-with-unibyte-buffer + (if (functionp method) + (let ((cur (current-buffer))) + (if (eq method 'mailcap-save-binary-file) + (progn + (set-buffer (generate-new-buffer "*mm*")) + (setq method nil)) + (mm-insert-part handle) + (let ((win (get-buffer-window cur t))) + (when win + (select-window win))) + (switch-to-buffer (generate-new-buffer "*mm*"))) + (buffer-disable-undo) + (mm-set-buffer-file-coding-system mm-binary-coding-system) + (insert-buffer-substring cur) + (goto-char (point-min)) + (message "Viewing with %s" method) + (let ((mm (current-buffer)) + (non-viewer (assq 'non-viewer + (mailcap-mime-info + (mm-handle-media-type handle) t)))) + (unwind-protect + (if method + (funcall method) + (mm-save-part handle)) + (when (and (not non-viewer) + method) + (mm-handle-set-undisplayer handle mm))))) + ;; The function is a string to be executed. + (mm-insert-part handle) + (let* ((dir (make-temp-name (expand-file-name "emm." mm-tmp-directory))) + (filename (mail-content-type-get + (mm-handle-disposition handle) 'filename)) + (mime-info (mailcap-mime-info + (mm-handle-media-type handle) t)) + (needsterm (or (assoc "needsterm" mime-info) + (assoc "needsterminal" mime-info))) + (copiousoutput (assoc "copiousoutput" mime-info)) + file buffer) + ;; We create a private sub-directory where we store our files. + (make-directory dir) + (set-file-modes dir 448) + (if filename + (setq file (expand-file-name (file-name-nondirectory filename) + dir)) + (setq file (make-temp-name (expand-file-name "mm." dir)))) + (let ((coding-system-for-write mm-binary-coding-system)) + (write-region (point-min) (point-max) file nil 'nomesg)) + (message "Viewing with %s" method) + (cond (needsterm + (unwind-protect + (start-process "*display*" nil + "xterm" + "-e" shell-file-name + shell-command-switch + (mm-mailcap-command + method file (mm-handle-type handle))) + (mm-handle-set-undisplayer handle (cons file buffer))) + (message "Displaying %s..." (format method file)) + 'external) + (copiousoutput + (with-current-buffer outbuf + (forward-line 1) + (mm-insert-inline + handle + (unwind-protect + (progn + (call-process shell-file-name nil + (setq buffer + (generate-new-buffer "*mm*")) + nil + shell-command-switch + (mm-mailcap-command + method file (mm-handle-type handle))) + (if (buffer-live-p buffer) + (save-excursion + (set-buffer buffer) + (buffer-string)))) + (progn + (ignore-errors (delete-file file)) + (ignore-errors (delete-directory + (file-name-directory file))) + (ignore-errors (kill-buffer buffer)))))) + 'inline) + (t + (unwind-protect + (start-process "*display*" + (setq buffer + (generate-new-buffer "*mm*")) + shell-file-name + shell-command-switch + (mm-mailcap-command + method file (mm-handle-type handle))) + (mm-handle-set-undisplayer handle (cons file buffer))) + (message "Displaying %s..." (format method file)) + 'external))))))) + +(defun mm-mailcap-command (method file type-list) + (let ((ctl (cdr type-list)) + (beg 0) + (uses-stdin t) + out sub total) + (while (string-match "%{\\([^}]+\\)}\\|%s\\|%t\\|%%" method beg) + (push (substring method beg (match-beginning 0)) out) + (setq beg (match-end 0) + total (match-string 0 method) + sub (match-string 1 method)) + (cond + ((string= total "%%") + (push "%" out)) + ((string= total "%s") + (setq uses-stdin nil) + (push (mm-quote-arg file) out)) + ((string= total "%t") + (push (mm-quote-arg (car type-list)) out)) + (t + (push (mm-quote-arg (or (cdr (assq (intern sub) ctl)) "")) out)))) + (push (substring method beg (length method)) out) + (if uses-stdin + (progn + (push "<" out) + (push (mm-quote-arg file) out))) + (mapconcat 'identity (nreverse out) ""))) + +(defun mm-remove-parts (handles) + "Remove the displayed MIME parts represented by HANDLES." + (if (and (listp handles) + (bufferp (car handles))) + (mm-remove-part handles) + (let (handle) + (while (setq handle (pop handles)) + (cond + ((stringp handle) + ;; Do nothing. + ) + ((and (listp handle) + (stringp (car handle))) + (mm-remove-parts (cdr handle))) + (t + (mm-remove-part handle))))))) + +(defun mm-destroy-parts (handles) + "Remove the displayed MIME parts represented by HANDLES." + (if (and (listp handles) + (bufferp (car handles))) + (mm-destroy-part handles) + (let (handle) + (while (setq handle (pop handles)) + (cond + ((stringp handle) + ;; Do nothing. + ) + ((and (listp handle) + (stringp (car handle))) + (mm-destroy-parts (cdr handle))) + (t + (mm-destroy-part handle))))))) + +(defun mm-remove-part (handle) + "Remove the displayed MIME part represented by HANDLE." + (when (listp handle) + (let ((object (mm-handle-undisplayer handle))) + (ignore-errors + (cond + ;; Internally displayed part. + ((mm-annotationp object) + (delete-annotation object)) + ((or (functionp object) + (and (listp object) + (eq (car object) 'lambda))) + (funcall object)) + ;; Externally displayed part. + ((consp object) + (ignore-errors (delete-file (car object))) + (ignore-errors (delete-directory (file-name-directory (car object)))) + (ignore-errors (kill-buffer (cdr object)))) + ((bufferp object) + (when (buffer-live-p object) + (kill-buffer object))))) + (mm-handle-set-undisplayer handle nil)))) + +(defun mm-display-inline (handle) + (let* ((type (mm-handle-media-type handle)) + (function (cadr (mm-assoc-string-match mm-inline-media-tests type)))) + (funcall function handle) + (goto-char (point-min)))) + +(defun mm-assoc-string-match (alist type) + (dolist (elem alist) + (when (string-match (car elem) type) + (return elem)))) + +(defun mm-inlinable-p (handle) + "Say whether HANDLE can be displayed inline." + (let ((alist mm-inline-media-tests) + (type (mm-handle-media-type handle)) + test) + (while alist + (when (string-match (caar alist) type) + (setq test (caddar alist) + alist nil) + (setq test (funcall test handle))) + (pop alist)) + test)) + +(defun mm-automatic-display-p (handle) + "Say whether the user wants HANDLE to be displayed automatically." + (let ((methods mm-automatic-display) + (type (mm-handle-media-type handle)) + method result) + (while (setq method (pop methods)) + (when (and (not (mm-inline-override-p handle)) + (string-match method type) + (mm-inlinable-p handle)) + (setq result t + methods nil))) + result)) + +(defun mm-inlined-p (handle) + "Say whether the user wants HANDLE to be displayed automatically." + (let ((methods mm-inlined-types) + (type (mm-handle-media-type handle)) + method result) + (while (setq method (pop methods)) + (when (and (not (mm-inline-override-p handle)) + (string-match method type) + (mm-inlinable-p handle)) + (setq result t + methods nil))) + result)) + +(defun mm-attachment-override-p (handle) + "Say whether HANDLE should have attachment behavior overridden." + (let ((types mm-attachment-override-types) + (type (mm-handle-media-type handle)) + ty) + (catch 'found + (while (setq ty (pop types)) + (when (and (string-match ty type) + (mm-inlinable-p handle)) + (throw 'found t)))))) + +(defun mm-inline-override-p (handle) + "Say whether HANDLE should have inline behavior overridden." + (let ((types mm-inline-override-types) + (type (mm-handle-media-type handle)) + ty) + (catch 'found + (while (setq ty (pop types)) + (when (string-match ty type) + (throw 'found t)))))) + +(defun mm-automatic-external-display-p (type) + "Return the user-defined method for TYPE." + (let ((methods mm-automatic-external-display) + method result) + (while (setq method (pop methods)) + (when (string-match method type) + (setq result t + methods nil))) + result)) + +(defun mm-destroy-part (handle) + "Destroy the data structures connected to HANDLE." + (when (listp handle) + (mm-remove-part handle) + (when (buffer-live-p (mm-handle-buffer handle)) + (kill-buffer (mm-handle-buffer handle))))) + +(defun mm-handle-displayed-p (handle) + "Say whether HANDLE is displayed or not." + (mm-handle-undisplayer handle)) + +;;; +;;; Functions for outputting parts +;;; + +(defun mm-get-part (handle) + "Return the contents of HANDLE as a string." + (mm-with-unibyte-buffer + (mm-insert-part handle) + (buffer-string))) + +(defun mm-insert-part (handle) + "Insert the contents of HANDLE in the current buffer." + (let ((cur (current-buffer))) + (save-excursion + (if (member (mm-handle-media-supertype handle) '("text" "message")) + (with-temp-buffer + (insert-buffer-substring (mm-handle-buffer handle)) + (mm-decode-content-transfer-encoding + (mm-handle-encoding handle) + (mm-handle-media-type handle)) + (let ((temp (current-buffer))) + (set-buffer cur) + (insert-buffer-substring temp))) + (mm-with-unibyte-buffer + (insert-buffer-substring (mm-handle-buffer handle)) + (mm-decode-content-transfer-encoding + (mm-handle-encoding handle) + (mm-handle-media-type handle)) + (let ((temp (current-buffer))) + (set-buffer cur) + (insert-buffer-substring temp))))))) + +(defvar mm-default-directory nil) + +(defun mm-save-part (handle) + "Write HANDLE to a file." + (let* ((name (mail-content-type-get (mm-handle-type handle) 'name)) + (filename (mail-content-type-get + (mm-handle-disposition handle) 'filename)) + file) + (when filename + (setq filename (file-name-nondirectory filename))) + (setq file + (read-file-name "Save MIME part to: " + (expand-file-name + (or filename name "") + (or mm-default-directory default-directory)))) + (setq mm-default-directory (file-name-directory file)) + (when (or (not (file-exists-p file)) + (yes-or-no-p (format "File %s already exists; overwrite? " + file))) + (mm-save-part-to-file handle file)))) + +(defun mm-save-part-to-file (handle file) + (mm-with-unibyte-buffer + (mm-insert-part handle) + (let ((coding-system-for-write 'binary) + ;; Don't re-compress .gz & al. Arguably we should make + ;; `file-name-handler-alist' nil, but that would chop + ;; ange-ftp, which is reasonable to use here. + (inhibit-file-name-operation 'write-region) + (inhibit-file-name-handlers + (cons 'jka-compr-handler inhibit-file-name-handlers))) + (write-region (point-min) (point-max) file)))) + +(defun mm-pipe-part (handle) + "Pipe HANDLE to a process." + (let* ((name (mail-content-type-get (mm-handle-type handle) 'name)) + (command + (read-string "Shell command on MIME part: " mm-last-shell-command))) + (mm-with-unibyte-buffer + (mm-insert-part handle) + (shell-command-on-region (point-min) (point-max) command nil)))) + +(defun mm-interactively-view-part (handle) + "Display HANDLE using METHOD." + (let* ((type (mm-handle-media-type handle)) + (methods + (mapcar (lambda (i) (list (cdr (assoc 'viewer i)))) + (mailcap-mime-info type 'all))) + (method (completing-read "Viewer: " methods))) + (when (string= method "") + (error "No method given")) + (if (string-match "^[^% \t]+$" method) + (setq method (concat method " %s"))) + (mm-display-external (copy-sequence handle) method))) + +(defun mm-preferred-alternative (handles &optional preferred) + "Say which of HANDLES are preferred." + (let ((prec (if preferred (list preferred) + (mm-preferred-alternative-precedence handles))) + p h result type handle) + (while (setq p (pop prec)) + (setq h handles) + (while h + (setq handle (car h)) + (setq type (mm-handle-media-type handle)) + (when (and (equal p type) + (mm-automatic-display-p handle) + (or (stringp (car handle)) + (not (mm-handle-disposition handle)) + (equal (car (mm-handle-disposition handle)) + "inline"))) + (setq result handle + h nil + prec nil)) + (pop h))) + result)) + +(defun mm-preferred-alternative-precedence (handles) + "Return the precedence based on HANDLES and `mm-discouraged-alternatives'." + (let ((seq (nreverse (mapcar #'mm-handle-media-type + handles)))) + (dolist (disc (reverse mm-discouraged-alternatives)) + (dolist (elem (copy-sequence seq)) + (when (string-match disc elem) + (setq seq (nconc (delete elem seq) (list elem)))))) + seq)) + +(defun mm-get-content-id (id) + "Return the handle(s) referred to by ID." + (cdr (assoc id mm-content-id-alist))) + +(defun mm-get-image (handle) + "Return an image instance based on HANDLE." + (let ((type (mm-handle-media-subtype handle)) + spec) + ;; Allow some common translations. + (setq type + (cond + ((equal type "x-pixmap") + "xpm") + ((equal type "x-xbitmap") + "xbm") + (t type))) + (or (mm-handle-cache handle) + (mm-with-unibyte-buffer + (mm-insert-part handle) + (prog1 + (setq spec + (ignore-errors + ;; Avoid testing `make-glyph' since W3 may define + ;; a bogus version of it. + (if (fboundp 'create-image) + (create-image (buffer-string) (intern type) 'data-p) + (cond + ((equal type "xbm") + ;; xbm images require special handling, since + ;; the only way to create glyphs from these + ;; (without a ton of work) is to write them + ;; out to a file, and then create a file + ;; specifier. + (let ((file (make-temp-name + (expand-file-name "emm.xbm" + mm-tmp-directory)))) + (unwind-protect + (progn + (write-region (point-min) (point-max) file) + (make-glyph (list (cons 'x file)))) + (ignore-errors + (delete-file file))))) + (t + (make-glyph + (vector (intern type) :data (buffer-string)))))))) + (mm-handle-set-cache handle spec)))))) + +(defun mm-image-fit-p (handle) + "Say whether the image in HANDLE will fit the current window." + (let ((image (mm-get-image handle))) + (if (fboundp 'glyph-width) + ;; XEmacs' glyphs can actually tell us about their width, so + ;; lets be nice and smart about them. + (or mm-inline-large-images + (and (< (glyph-width image) (window-pixel-width)) + (< (glyph-height image) (window-pixel-height)))) + (let* ((size (image-size image)) + (w (car size)) + (h (cdr size))) + (or mm-inline-large-images + (and (< h (1- (window-height))) ; Don't include mode line. + (< w (window-width)))))))) + +(defun mm-valid-image-format-p (format) + "Say whether FORMAT can be displayed natively by Emacs." + (cond + ;; Handle XEmacs + ((fboundp 'valid-image-instantiator-format-p) + (valid-image-instantiator-format-p format)) + ;; Handle Emacs 21 + ((fboundp 'image-type-available-p) + (and (display-graphic-p) + (image-type-available-p format))) + ;; Nobody else can do images yet. + (t + nil))) + +(defun mm-valid-and-fit-image-p (format handle) + "Say whether FORMAT can be displayed natively and HANDLE fits the window." + (and window-system + (mm-valid-image-format-p format) + (mm-image-fit-p handle))) + +(provide 'mm-decode) + +;;; mm-decode.el ends here diff --git a/lisp/gnus/mm-encode.el b/lisp/gnus/mm-encode.el new file mode 100644 index 00000000000..0b809816118 --- /dev/null +++ b/lisp/gnus/mm-encode.el @@ -0,0 +1,168 @@ +;;; mm-encode.el --- Functions for encoding MIME things +;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; MORIOKA Tomohiko +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(require 'mail-parse) +(require 'mailcap) + +(defvar mm-content-transfer-encoding-defaults + '(("text/x-patch" 8bit) + ("text/.*" qp-or-base64) + ("message/rfc822" 8bit) + ("application/emacs-lisp" 8bit) + ("application/x-patch" 8bit) + (".*" qp-or-base64)) + "Alist of regexps that match MIME types and their encodings. +If the encoding is `qp-or-base64', then either quoted-printable +or base64 will be used, depending on what is more efficient.") + +(defvar mm-use-ultra-safe-encoding nil + "If non-nil, use encodings aimed at Procrustean bed survival. + +This means that textual parts are encoded as quoted-printable if they +contain lines longer than 76 characters or starting with \"From \" in +the body. Non-7bit encodings (8bit, binary) are generally disallowed. +This is to reduce the probability that a broken MTA or MDA changes the +message. + +This variable should never be set directly, but bound before a call to +`mml-generate-mime' or similar functions.") + +(defun mm-insert-rfc822-headers (charset encoding) + "Insert text/plain headers with CHARSET and ENCODING." + (insert "MIME-Version: 1.0\n") + (insert "Content-Type: text/plain; charset=" + (mail-quote-string (downcase (symbol-name charset))) "\n") + (insert "Content-Transfer-Encoding: " + (downcase (symbol-name encoding)) "\n")) + +(defun mm-insert-multipart-headers () + "Insert multipart/mixed headers." + (let ((boundary "=-=-=")) + (insert "MIME-Version: 1.0\n") + (insert "Content-Type: multipart/mixed; boundary=\"" boundary "\"\n") + boundary)) + +(defun mm-default-file-encoding (file) + "Return a default encoding for FILE." + (if (not (string-match "\\.[^.]+$" file)) + "application/octet-stream" + (mailcap-extension-to-mime (match-string 0 file)))) + +(defun mm-safer-encoding (encoding) + "Return a safer but similar encoding." + (cond + ((memq encoding '(7bit 8bit quoted-printable)) 'quoted-printable) + ;; The remaing encodings are binary and base64 (and perhaps some + ;; non-standard ones), which are both turned into base64. + (t 'base64))) + +(defun mm-encode-content-transfer-encoding (encoding &optional type) + (cond + ((eq encoding 'quoted-printable) + (quoted-printable-encode-region (point-min) (point-max) t)) + ((eq encoding 'base64) + (when (equal type "text/plain") + (goto-char (point-min)) + (while (search-forward "\n" nil t) + (replace-match "\r\n" t t))) + (condition-case error + (base64-encode-region (point-min) (point-max)) + (error + (message "Error while decoding: %s" error) + nil))) + ((memq encoding '(7bit 8bit binary)) + ;; Do nothing. + ) + ((null encoding) + ;; Do nothing. + ) + ((functionp encoding) + (ignore-errors (funcall encoding (point-min) (point-max)))) + (t + (message "Unknown encoding %s; defaulting to 8bit" encoding)))) + +(defun mm-encode-buffer (type) + "Encode the buffer which contains data of TYPE. +The encoding used is returned." + (let* ((mime-type (if (stringp type) type (car type))) + (encoding + (or (and (listp type) + (cadr (assq 'encoding type))) + (mm-content-transfer-encoding mime-type))) + (bits (mm-body-7-or-8))) + ;; We force buffers that are 7bit to be unencoded, no matter + ;; what the preferred encoding is. + (when (eq bits '7bit) + (setq encoding bits)) + (mm-encode-content-transfer-encoding encoding mime-type) + encoding)) + +(defun mm-insert-headers (type encoding &optional file) + "Insert headers for TYPE." + (insert "Content-Type: " type) + (when file + (insert ";\n\tname=\"" (file-name-nondirectory file) "\"")) + (insert "\n") + (insert (format "Content-Transfer-Encoding: %s\n" encoding)) + (insert "Content-Disposition: inline") + (when file + (insert ";\n\tfilename=\"" (file-name-nondirectory file) "\"")) + (insert "\n") + (insert "\n")) + +(defun mm-content-transfer-encoding (type) + "Return a CTE suitable for TYPE to encode the current buffer." + (let ((rules mm-content-transfer-encoding-defaults)) + (catch 'found + (while rules + (when (string-match (caar rules) type) + (throw 'found + (let ((encoding + (if (eq (cadr (car rules)) 'qp-or-base64) + (mm-qp-or-base64) + (cadr (car rules))))) + (if mm-use-ultra-safe-encoding + (mm-safer-encoding encoding) + encoding)))) + (pop rules))))) + +(defun mm-qp-or-base64 () + (save-excursion + (let ((limit (min (point-max) (+ 2000 (point-min)))) + (n8bit 0)) + (goto-char (point-min)) + (skip-chars-forward "\x20-\x7f\r\n\t" limit) + (while (< (point) limit) + (incf n8bit) + (forward-char 1) + (skip-chars-forward "\x20-\x7f\r\n\t" limit)) + (if (< (* 6 n8bit) (- limit (point-min))) + 'quoted-printable + 'base64)))) + +(provide 'mm-encode) + +;;; mm-encode.el ends here diff --git a/lisp/gnus/mm-partial.el b/lisp/gnus/mm-partial.el new file mode 100644 index 00000000000..27189c937d3 --- /dev/null +++ b/lisp/gnus/mm-partial.el @@ -0,0 +1,152 @@ +;;; mm-partial.el --- showing message/partial +;; Copyright (C) 2000 Free Software Foundation, Inc. + +;; Author: Shenghuo Zhu +;; Keywords: message partial + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 2, or (at your +;; option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(eval-when-compile + (require 'cl)) + +(require 'gnus-sum) +(require 'mm-util) +(require 'mm-decode) + +(defun mm-partial-find-parts (id &optional art) + (let ((headers (save-excursion + (set-buffer gnus-summary-buffer) + gnus-newsgroup-headers)) + phandles header) + (while (setq header (pop headers)) + (unless (eq (aref header 0) art) + (mm-with-unibyte-buffer + (gnus-request-article-this-buffer (aref header 0) + gnus-newsgroup-name) + (when (search-forward id nil t) + (let ((nhandles (mm-dissect-buffer)) nid) + (if (consp (car nhandles)) + (mm-destroy-parts nhandles) + (setq nid (cdr (assq 'id + (cdr (mm-handle-type nhandles))))) + (if (not (equal id nid)) + (mm-destroy-parts nhandles) + (push nhandles phandles)))))))) + phandles)) + +;;;###autoload +(defun mm-inline-partial (handle &optional no-display) + "Show the partial part of HANDLE. +This function replaces the buffer of HANDLE with a buffer contains +the entire message. +If NO-DISPLAY is nil, display it. Otherwise, do nothing after replacing." + (let ((id (cdr (assq 'id (cdr (mm-handle-type handle))))) + phandles + (b (point)) (n 1) total + phandle nn ntotal + gnus-displaying-mime handles buffer) + (unless (mm-handle-cache handle) + (unless id + (error "Can not find message/partial id.")) + (setq phandles + (sort (cons handle + (mm-partial-find-parts + id + (save-excursion + (set-buffer gnus-summary-buffer) + (gnus-summary-article-number)))) + #'(lambda (a b) + (let ((anumber (string-to-number + (cdr (assq 'number + (cdr (mm-handle-type a)))))) + (bnumber (string-to-number + (cdr (assq 'number + (cdr (mm-handle-type b))))))) + (< anumber bnumber))))) + (setq gnus-article-mime-handles + (append (if (listp (car gnus-article-mime-handles)) + gnus-article-mime-handles + (list gnus-article-mime-handles)) + phandles)) + (save-excursion + (set-buffer (generate-new-buffer "*mm*")) + (while (setq phandle (pop phandles)) + (setq nn (string-to-number + (cdr (assq 'number + (cdr (mm-handle-type phandle)))))) + (setq ntotal (string-to-number + (cdr (assq 'total + (cdr (mm-handle-type phandle)))))) + (if ntotal + (if total + (unless (eq total ntotal) + (error "The numbers of total are different.")) + (setq total ntotal))) + (unless (< nn n) + (unless (eq nn n) + (error "Missing part %d" n)) + (mm-insert-part phandle) + (goto-char (point-max)) + (when (not (eq 0 (skip-chars-backward "\r\n"))) + ;; remove tail blank spaces except one + (if (looking-at "\r?\n") + (goto-char (match-end 0))) + (delete-region (point) (point-max))) + (setq n (+ n 1)))) + (unless total + (error "Don't known the total number of")) + (if (<= n total) + (error "Missing part %d" n)) + (kill-buffer (mm-handle-buffer handle)) + (setcar handle (current-buffer)) + (mm-handle-set-cache handle t))) + (unless no-display + (save-excursion + (save-restriction + (narrow-to-region b b) + (mm-insert-part handle) + (let (gnus-article-mime-handles) + (run-hooks 'gnus-article-decode-hook) + (gnus-article-prepare-display) + (setq handles gnus-article-mime-handles)) + (when handles + ;; It is in article buffer. + (setq gnus-article-mime-handles + (nconc (if (listp (car gnus-article-mime-handles)) + gnus-article-mime-handles + (list gnus-article-mime-handles)) + (if (listp (car handles)) + handles (list handles))))) + (mm-handle-set-undisplayer + handle + `(lambda () + (let (buffer-read-only) + (condition-case nil + ;; This is only valid on XEmacs. + (mapcar (lambda (prop) + (remove-specifier + (face-property 'default prop) (current-buffer))) + '(background background-pixmap foreground)) + (error nil)) + (delete-region ,(point-min-marker) ,(point-max-marker)))))))))) + +;; mm-partial.el ends here diff --git a/lisp/gnus/mm-util.el b/lisp/gnus/mm-util.el new file mode 100644 index 00000000000..aa70484d8aa --- /dev/null +++ b/lisp/gnus/mm-util.el @@ -0,0 +1,500 @@ +;;; mm-util.el --- Utility functions for MIME things +;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; MORIOKA Tomohiko +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(require 'mail-prsvr) + +(defvar mm-mime-mule-charset-alist + '((us-ascii ascii) + (iso-8859-1 latin-iso8859-1) + (iso-8859-2 latin-iso8859-2) + (iso-8859-3 latin-iso8859-3) + (iso-8859-4 latin-iso8859-4) + (iso-8859-5 cyrillic-iso8859-5) + ;; Non-mule (X)Emacs uses the last mule-charset for 8bit characters. + ;; The fake mule-charset, gnus-koi8-r, tells Gnus that the default + ;; charset is koi8-r, not iso-8859-5. + (koi8-r cyrillic-iso8859-5 gnus-koi8-r) + (iso-8859-6 arabic-iso8859-6) + (iso-8859-7 greek-iso8859-7) + (iso-8859-8 hebrew-iso8859-8) + (iso-8859-9 latin-iso8859-9) + (viscii vietnamese-viscii-lower) + (iso-2022-jp latin-jisx0201 japanese-jisx0208 japanese-jisx0208-1978) + (euc-kr korean-ksc5601) + (cn-gb-2312 chinese-gb2312) + (cn-big5 chinese-big5-1 chinese-big5-2) + (tibetan tibetan) + (thai-tis620 thai-tis620) + (iso-2022-7bit ethiopic arabic-1-column arabic-2-column) + (iso-2022-jp-2 latin-iso8859-1 greek-iso8859-7 + latin-jisx0201 japanese-jisx0208-1978 + chinese-gb2312 japanese-jisx0208 + korean-ksc5601 japanese-jisx0212 + katakana-jisx0201) + (iso-2022-int-1 latin-iso8859-1 greek-iso8859-7 + latin-jisx0201 japanese-jisx0208-1978 + chinese-gb2312 japanese-jisx0208 + korean-ksc5601 japanese-jisx0212 + chinese-cns11643-1 chinese-cns11643-2) + (iso-2022-int-1 latin-iso8859-1 latin-iso8859-2 + cyrillic-iso8859-5 greek-iso8859-7 + latin-jisx0201 japanese-jisx0208-1978 + chinese-gb2312 japanese-jisx0208 + korean-ksc5601 japanese-jisx0212 + chinese-cns11643-1 chinese-cns11643-2 + chinese-cns11643-3 chinese-cns11643-4 + chinese-cns11643-5 chinese-cns11643-6 + chinese-cns11643-7) + (utf-8 unicode-a unicode-b unicode-c unicode-d unicode-e)) + "Alist of MIME-charset/MULE-charsets.") + +(eval-and-compile + (mapcar + (lambda (elem) + (let ((nfunc (intern (format "mm-%s" (car elem))))) + (if (fboundp (car elem)) + (defalias nfunc (car elem)) + (defalias nfunc (cdr elem))))) + '((decode-coding-string . (lambda (s a) s)) + (encode-coding-string . (lambda (s a) s)) + (encode-coding-region . ignore) + (coding-system-list . ignore) + (decode-coding-region . ignore) + (char-int . identity) + (device-type . ignore) + (coding-system-equal . equal) + (annotationp . ignore) + (set-buffer-file-coding-system . ignore) + (make-char + . (lambda (charset int) + (int-to-char int))) + (read-coding-system + . (lambda (prompt) + "Prompt the user for a coding system." + (completing-read + prompt (mapcar (lambda (s) (list (symbol-name (car s)))) + mm-mime-mule-charset-alist)))) + (read-charset + . (lambda (prompt) + "Return a charset." + (intern + (completing-read + prompt + (mapcar (lambda (e) (list (symbol-name (car e)))) + mm-mime-mule-charset-alist) + nil t))))))) + +(eval-and-compile + (defalias 'mm-char-or-char-int-p + (cond + ((fboundp 'char-or-char-int-p) 'char-or-char-int-p) + ((fboundp 'char-valid-p) 'char-valid-p) + (t 'identity)))) + +(defvar mm-coding-system-list nil) +(defun mm-get-coding-system-list () + "Get the coding system list." + (or mm-coding-system-list + (setq mm-coding-system-list (mm-coding-system-list)))) + +(defvar mm-charset-synonym-alist + '((big5 . cn-big5) + (gb2312 . cn-gb-2312) + (x-ctext . ctext)) + "A mapping from invalid charset names to the real charset names.") + +(defun mm-coding-system-p (sym) + "Return non-nil if SYM is a coding system." + (or (and (fboundp 'coding-system-p) (coding-system-p sym)) + (memq sym (mm-get-coding-system-list)))) + +(defvar mm-binary-coding-system + (cond + ((mm-coding-system-p 'binary) 'binary) + ((mm-coding-system-p 'no-conversion) 'no-conversion) + (t nil)) + "100% binary coding system.") + +(defvar mm-text-coding-system + (or (if (memq system-type '(windows-nt ms-dos ms-windows)) + (and (mm-coding-system-p 'raw-text-dos) 'raw-text-dos) + (and (mm-coding-system-p 'raw-text) 'raw-text)) + mm-binary-coding-system) + "Text-safe coding system (For removing ^M).") + +(defvar mm-text-coding-system-for-write nil + "Text coding system for write.") + +(defvar mm-auto-save-coding-system + (cond + ((mm-coding-system-p 'emacs-mule) + (if (memq system-type '(windows-nt ms-dos ms-windows)) + (if (mm-coding-system-p 'emacs-mule-dos) + 'emacs-mule-dos mm-binary-coding-system) + 'emacs-mule)) + ((mm-coding-system-p 'escape-quoted) 'escape-quoted) + (t mm-binary-coding-system)) + "Coding system of auto save file.") + +;;; Internal variables: + +;;; Functions: + +(defun mm-mule-charset-to-mime-charset (charset) + "Return the MIME charset corresponding to MULE CHARSET." + (let ((alist mm-mime-mule-charset-alist) + out) + (while alist + (when (memq charset (cdar alist)) + (setq out (caar alist) + alist nil)) + (pop alist)) + out)) + +(defun mm-charset-to-coding-system (charset &optional lbt) + "Return coding-system corresponding to CHARSET. +CHARSET is a symbol naming a MIME charset. +If optional argument LBT (`unix', `dos' or `mac') is specified, it is +used as the line break code type of the coding system." + (when (stringp charset) + (setq charset (intern (downcase charset)))) + (setq charset + (or (cdr (assq charset mm-charset-synonym-alist)) + charset)) + (when lbt + (setq charset (intern (format "%s-%s" charset lbt)))) + (cond + ;; Running in a non-MULE environment. + ((null (mm-get-coding-system-list)) + charset) + ;; ascii + ((eq charset 'us-ascii) + 'ascii) + ;; Check to see whether we can handle this charset. + ((memq charset (mm-get-coding-system-list)) + charset) + ;; Nope. + (t + nil))) + +(if (fboundp 'subst-char-in-string) + (defsubst mm-replace-chars-in-string (string from to) + (subst-char-in-string from to string)) + (defun mm-replace-chars-in-string (string from to) + "Replace characters in STRING from FROM to TO." + (let ((string (substring string 0)) ;Copy string. + (len (length string)) + (idx 0)) + ;; Replace all occurrences of FROM with TO. + (while (< idx len) + (when (= (aref string idx) from) + (aset string idx to)) + (setq idx (1+ idx))) + string))) + +(defsubst mm-enable-multibyte () + "Enable multibyte in the current buffer." + (when (and (fboundp 'set-buffer-multibyte) + (boundp 'enable-multibyte-characters) + (default-value 'enable-multibyte-characters)) + (set-buffer-multibyte t))) + +(defsubst mm-disable-multibyte () + "Disable multibyte in the current buffer." + (when (fboundp 'set-buffer-multibyte) + (set-buffer-multibyte nil))) + +(defun mm-preferred-coding-system (charset) + ;; A typo in some Emacs versions. + (or (get-charset-property charset 'prefered-coding-system) + (get-charset-property charset 'preferred-coding-system))) + +(defun mm-charset-after (&optional pos) + "Return charset of a character in current buffer at position POS. +If POS is nil, it defauls to the current point. +If POS is out of range, the value is nil. +If the charset is `composition', return the actual one." + (let ((charset (cond + ((fboundp 'charset-after) + (charset-after pos)) + ((fboundp 'char-charset) + (char-charset (char-after pos))) + ((< (mm-char-int (char-after pos)) 128) + 'ascii) + (mail-parse-mule-charset ;; cached mule-charset + mail-parse-mule-charset) + ((boundp 'current-language-environment) + (let ((entry (assoc current-language-environment + language-info-alist))) + (setq mail-parse-mule-charset + (or (car (last (assq 'charset entry))) + 'latin-iso8859-1)))) + (t ;; figure out the charset + (setq mail-parse-mule-charset + (or (car (last (assq mail-parse-charset + mm-mime-mule-charset-alist))) + 'latin-iso8859-1)))))) + (if (eq charset 'composition) + (let ((p (or pos (point)))) + (cadr (find-charset-region p (1+ p)))) + charset))) + +(defun mm-mime-charset (charset) + "Return the MIME charset corresponding to the MULE CHARSET." + (if (and (fboundp 'coding-system-get) (fboundp 'get-charset-property)) + ;; This exists in Emacs 20. + (or + (and (mm-preferred-coding-system charset) + (coding-system-get + (mm-preferred-coding-system charset) 'mime-charset)) + (and (eq charset 'ascii) + 'us-ascii) + (mm-preferred-coding-system charset) + (mm-mule-charset-to-mime-charset charset)) + ;; This is for XEmacs. + (mm-mule-charset-to-mime-charset charset))) + +(defun mm-delete-duplicates (list) + "Simple substitute for CL `delete-duplicates', testing with `equal'." + (let (result head) + (while list + (setq head (car list)) + (setq list (delete head list)) + (setq result (cons head result))) + (nreverse result))) + +(defun mm-find-mime-charset-region (b e) + "Return the MIME charsets needed to encode the region between B and E." + (let ((charsets (mapcar 'mm-mime-charset + (delq 'ascii + (mm-find-charset-region b e))))) + (when (memq 'iso-2022-jp-2 charsets) + (setq charsets (delq 'iso-2022-jp charsets))) + (setq charsets (mm-delete-duplicates charsets)) + (if (and (> (length charsets) 1) + (fboundp 'find-coding-systems-region) + (memq 'utf-8 (find-coding-systems-region b e))) + '(utf-8) + charsets))) + +(defsubst mm-multibyte-p () + "Say whether multibyte is enabled." + (or (featurep 'xemacs) + (and (boundp 'enable-multibyte-characters) + enable-multibyte-characters))) + +(defmacro mm-with-unibyte-buffer (&rest forms) + "Create a temporary buffer, and evaluate FORMS there like `progn'. +See also `with-temp-file' and `with-output-to-string'." + (let ((temp-buffer (make-symbol "temp-buffer")) + (multibyte (make-symbol "multibyte"))) + `(if (or (string-match "XEmacs\\|Lucid" emacs-version) + (not (boundp 'enable-multibyte-characters))) + (with-temp-buffer ,@forms) + (let ((,multibyte (default-value 'enable-multibyte-characters)) + ,temp-buffer) + (unwind-protect + (progn + (setq-default enable-multibyte-characters nil) + (setq ,temp-buffer + (get-buffer-create (generate-new-buffer-name " *temp*"))) + (unwind-protect + (with-current-buffer ,temp-buffer + (let ((buffer-file-coding-system mm-binary-coding-system) + (coding-system-for-read mm-binary-coding-system) + (coding-system-for-write mm-binary-coding-system)) + ,@forms)) + (and (buffer-name ,temp-buffer) + (kill-buffer ,temp-buffer)))) + (setq-default enable-multibyte-characters ,multibyte)))))) +(put 'mm-with-unibyte-buffer 'lisp-indent-function 0) +(put 'mm-with-unibyte-buffer 'edebug-form-spec '(body)) + +(defmacro mm-with-unibyte-current-buffer (&rest forms) + "Evaluate FORMS there like `progn' in current buffer." + (let ((multibyte (make-symbol "multibyte"))) + `(if (or (featurep 'xemacs) + (not (fboundp 'set-buffer-multibyte))) + (progn + ,@forms) + (let ((,multibyte (default-value 'enable-multibyte-characters))) + (unwind-protect + (let ((buffer-file-coding-system mm-binary-coding-system) + (coding-system-for-read mm-binary-coding-system) + (coding-system-for-write mm-binary-coding-system)) + (set-buffer-multibyte nil) + (setq-default enable-multibyte-characters nil) + ,@forms) + (setq-default enable-multibyte-characters ,multibyte) + (set-buffer-multibyte ,multibyte)))))) +(put 'mm-with-unibyte-current-buffer 'lisp-indent-function 0) +(put 'mm-with-unibyte-current-buffer 'edebug-form-spec '(body)) + +(defmacro mm-with-unibyte (&rest forms) + "Set default `enable-multibyte-characters' to `nil', eval the FORMS." + (let ((multibyte (make-symbol "multibyte"))) + `(if (or (featurep 'xemacs) + (not (boundp 'enable-multibyte-characters))) + (progn ,@forms) + (let ((,multibyte (default-value 'enable-multibyte-characters))) + (unwind-protect + (progn + (setq-default enable-multibyte-characters nil) + ,@forms) + (setq-default enable-multibyte-characters ,multibyte)))))) +(put 'mm-with-unibyte 'lisp-indent-function 0) +(put 'mm-with-unibyte 'edebug-form-spec '(body)) + +(defun mm-find-charset-region (b e) + "Return a list of charsets in the region." + (cond + ((and (mm-multibyte-p) + (fboundp 'find-charset-region)) + ;; Remove composition since the base charsets have been included. + (delq 'composition (find-charset-region b e))) + ((not (boundp 'current-language-environment)) + (save-excursion + (save-restriction + (narrow-to-region b e) + (goto-char (point-min)) + (skip-chars-forward "\0-\177") + (if (eobp) + '(ascii) + (delq nil (list 'ascii + (or (car (last (assq mail-parse-charset + mm-mime-mule-charset-alist))) + 'latin-iso8859-1))))))) + (t + ;; We are in a unibyte buffer, so we futz around a bit. + (save-excursion + (save-restriction + (narrow-to-region b e) + (goto-char (point-min)) + (let ((entry (assoc current-language-environment + language-info-alist))) + (skip-chars-forward "\0-\177") + (if (eobp) + '(ascii) + (delq nil (list 'ascii + (or (car (last (assq 'charset entry))) + 'latin-iso8859-1)))))))))) + +(if (fboundp 'shell-quote-argument) + (defalias 'mm-quote-arg 'shell-quote-argument) + (defun mm-quote-arg (arg) + "Return a version of ARG that is safe to evaluate in a shell." + (let ((pos 0) new-pos accum) + ;; *** bug: we don't handle newline characters properly + (while (setq new-pos (string-match "[]*[;!'`\"$\\& \t{} |()<>]" arg pos)) + (push (substring arg pos new-pos) accum) + (push "\\" accum) + (push (list (aref arg new-pos)) accum) + (setq pos (1+ new-pos))) + (if (= pos 0) + arg + (apply 'concat (nconc (nreverse accum) (list (substring arg pos)))))))) + +(defun mm-auto-mode-alist () + "Return an `auto-mode-alist' with only the .gz (etc) thingies." + (let ((alist auto-mode-alist) + out) + (while alist + (when (listp (cdar alist)) + (push (car alist) out)) + (pop alist)) + (nreverse out))) + +(defvar mm-inhibit-file-name-handlers + '(jka-compr-handler) + "A list of handlers doing (un)compression (etc) thingies.") + +(defun mm-insert-file-contents (filename &optional visit beg end replace + inhibit) + "Like `insert-file-contents', q.v., but only reads in the file. +A buffer may be modified in several ways after reading into the buffer due +to advanced Emacs features, such as file-name-handlers, format decoding, +find-file-hooks, etc. +If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers. + This function ensures that none of these modifications will take place." + (let ((format-alist nil) + (auto-mode-alist (if inhibit nil (mm-auto-mode-alist))) + (default-major-mode 'fundamental-mode) + (enable-local-variables nil) + (after-insert-file-functions nil) + (enable-local-eval nil) + (find-file-hooks nil) + (inhibit-file-name-operation (if inhibit + 'insert-file-contents + inhibit-file-name-operation)) + (inhibit-file-name-handlers + (if inhibit + (append mm-inhibit-file-name-handlers + inhibit-file-name-handlers) + inhibit-file-name-handlers))) + (insert-file-contents filename visit beg end replace))) + +(defun mm-append-to-file (start end filename &optional codesys inhibit) + "Append the contents of the region to the end of file FILENAME. +When called from a function, expects three arguments, +START, END and FILENAME. START and END are buffer positions +saying what text to write. +Optional fourth argument specifies the coding system to use when +encoding the file. +If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers." + (let ((coding-system-for-write + (or codesys mm-text-coding-system-for-write + mm-text-coding-system)) + (inhibit-file-name-operation (if inhibit + 'append-to-file + inhibit-file-name-operation)) + (inhibit-file-name-handlers + (if inhibit + (append mm-inhibit-file-name-handlers + inhibit-file-name-handlers) + inhibit-file-name-handlers))) + (append-to-file start end filename))) + +(defun mm-write-region (start end filename &optional append visit lockname + coding-system inhibit) + + "Like `write-region'. +If INHIBIT is non-nil, inhibit mm-inhibit-file-name-handlers." + (let ((coding-system-for-write + (or coding-system mm-text-coding-system-for-write + mm-text-coding-system)) + (inhibit-file-name-operation (if inhibit + 'write-region + inhibit-file-name-operation)) + (inhibit-file-name-handlers + (if inhibit + (append mm-inhibit-file-name-handlers + inhibit-file-name-handlers) + inhibit-file-name-handlers))) + (write-region start end filename append visit lockname))) + +(provide 'mm-util) + +;;; mm-util.el ends here diff --git a/lisp/gnus/mm-uu.el b/lisp/gnus/mm-uu.el new file mode 100644 index 00000000000..d5d0500585e --- /dev/null +++ b/lisp/gnus/mm-uu.el @@ -0,0 +1,250 @@ +;;; mm-uu.el -- Return uu stuffs as mm handles +;; Copyright (c) 1998, 1999, 2000 Free Software Foundation, Inc. + +;; Author: Shenghuo Zhu +;; Keywords: postscript uudecode binhex shar forward news + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. +;; +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + + +;;; Code: + +(eval-when-compile (require 'cl)) +(require 'mail-parse) +(require 'nnheader) +(require 'mm-decode) +(require 'mailcap) + +(eval-and-compile + (autoload 'binhex-decode-region "binhex") + (autoload 'binhex-decode-region-external "binhex") + (autoload 'uudecode-decode-region "uudecode") + (autoload 'uudecode-decode-region-external "uudecode")) + +(defun mm-uu-copy-to-buffer (from to) + "Copy the contents of the current buffer to a fresh buffer." + (save-excursion + (let ((obuf (current-buffer))) + (set-buffer (generate-new-buffer " *mm-uu*")) + (insert-buffer-substring obuf from to) + (current-buffer)))) + +;;; postscript + +(defconst mm-uu-postscript-begin-line "^%!PS-") +(defconst mm-uu-postscript-end-line "^%%EOF$") + +(defconst mm-uu-uu-begin-line "^begin[ \t]+[0-7][0-7][0-7][ \t]+") +(defconst mm-uu-uu-end-line "^end[ \t]*$") + +(defcustom mm-uu-decode-function 'uudecode-decode-region + "*Function to uudecode. +Internal function is done in elisp by default, therefore decoding may +appear to be horribly slow . You can make Gnus use the external Unix +decoder, such as uudecode." + :type '(choice (item :tag "internal" uudecode-decode-region) + (item :tag "external" uudecode-decode-region-external)) + :group 'gnus-article-mime) + +(defconst mm-uu-binhex-begin-line + "^:...............................................................$") +(defconst mm-uu-binhex-end-line ":$") + +(defcustom mm-uu-binhex-decode-function 'binhex-decode-region + "*Function to binhex decode. +Internal function is done in elisp by default, therefore decoding may +appear to be horribly slow . You can make Gnus use the external Unix +decoder, such as hexbin." + :type '(choice (item :tag "internal" binhex-decode-region) + (item :tag "external" binhex-decode-region-external)) + :group 'gnus-article-mime) + +(defconst mm-uu-shar-begin-line "^#! */bin/sh") +(defconst mm-uu-shar-end-line "^exit 0\\|^$") + +;;; Thanks to Edward J. Sabol and +;;; Peter von der Ah\'e +(defconst mm-uu-forward-begin-line "^-+ \\(Start of \\)?Forwarded message") +(defconst mm-uu-forward-end-line "^-+ End \\(of \\)?forwarded message") + +(defvar mm-uu-begin-line nil) + +(defconst mm-uu-identifier-alist + '((?% . postscript) (?b . uu) (?: . binhex) (?# . shar) + (?- . forward))) + +(defvar mm-dissect-disposition "inline" + "The default disposition of uu parts. +This can be either \"inline\" or \"attachment\".") + +(defun mm-uu-configure-p (key val) + (member (cons key val) mm-uu-configure-list)) + +(defun mm-uu-configure (&optional symbol value) + (if symbol (set-default symbol value)) + (setq mm-uu-begin-line nil) + (mapcar '(lambda (type) + (if (mm-uu-configure-p type 'disabled) + nil + (setq mm-uu-begin-line + (concat mm-uu-begin-line + (if mm-uu-begin-line "\\|") + (symbol-value + (intern (concat "mm-uu-" (symbol-name type) + "-begin-line"))))))) + '(uu postscript binhex shar forward))) + +(defcustom mm-uu-configure-list nil + "A list of mm-uu configuration. +To disable dissecting shar codes, for instance, add +`(shar . disabled)' to this list." + :type '(repeat (cons + (choice (item postscript) + (item uu) + (item binhex) + (item shar) + (item forward)) + (choice (item disabled)))) + :group 'gnus-article-mime + :set 'mm-uu-configure) + +(mm-uu-configure) + +;;;### autoload + +(defun mm-uu-dissect () + "Dissect the current buffer and return a list of uu handles." + (let (text-start start-char end-char + type file-name end-line result text-plain-type + start-char-1 end-char-1 + (case-fold-search t)) + (save-excursion + (save-restriction + (mail-narrow-to-head) + (goto-char (point-max))) + (forward-line) + ;;; gnus-decoded is a fake charset, which means no further + ;;; decoding. + (setq text-start (point) + text-plain-type '("text/plain" (charset . gnus-decoded))) + (while (re-search-forward mm-uu-begin-line nil t) + (setq start-char (match-beginning 0)) + (setq type (cdr (assq (aref (match-string 0) 0) + mm-uu-identifier-alist))) + (setq file-name + (if (and (eq type 'uu) + (looking-at "\\(.+\\)$")) + (and (match-string 1) + (let ((nnheader-file-name-translation-alist + '((?/ . ?,) (? . ?_) (?* . ?_) (?$ . ?_)))) + (nnheader-translate-file-chars (match-string 1)))))) + (forward-line);; in case of failure + (setq start-char-1 (point)) + (setq end-line (symbol-value + (intern (concat "mm-uu-" (symbol-name type) + "-end-line")))) + (when (and (re-search-forward end-line nil t) + (not (eq (match-beginning 0) (match-end 0)))) + (setq end-char-1 (match-beginning 0)) + (forward-line) + (setq end-char (point)) + (when (cond + ((eq type 'binhex) + (setq file-name + (ignore-errors + (binhex-decode-region start-char end-char t)))) + ((eq type 'forward) + (save-excursion + (goto-char start-char-1) + (looking-at "[\r\n]*[a-zA-Z][a-zA-Z0-9-]*:"))) + (t t)) + (if (> start-char text-start) + (push + (mm-make-handle (mm-uu-copy-to-buffer text-start start-char) + text-plain-type) + result)) + (push + (cond + ((eq type 'postscript) + (mm-make-handle (mm-uu-copy-to-buffer start-char end-char) + '("application/postscript"))) + ((eq type 'forward) + (mm-make-handle (mm-uu-copy-to-buffer start-char-1 end-char-1) + '("message/rfc822" (charset . gnus-decoded)))) + ((eq type 'uu) + (mm-make-handle (mm-uu-copy-to-buffer start-char end-char) + (list (or (and file-name + (string-match "\\.[^\\.]+$" + file-name) + (mailcap-extension-to-mime + (match-string 0 file-name))) + "application/octet-stream")) + 'x-uuencode nil + (if (and file-name (not (equal file-name ""))) + (list mm-dissect-disposition + (cons 'filename file-name))))) + ((eq type 'binhex) + (mm-make-handle (mm-uu-copy-to-buffer start-char end-char) + (list (or (and file-name + (string-match "\\.[^\\.]+$" file-name) + (mailcap-extension-to-mime + (match-string 0 file-name))) + "application/octet-stream")) + 'x-binhex nil + (if (and file-name (not (equal file-name ""))) + (list mm-dissect-disposition + (cons 'filename file-name))))) + ((eq type 'shar) + (mm-make-handle (mm-uu-copy-to-buffer start-char end-char) + '("application/x-shar")))) + result) + (setq text-start end-char)))) + (when result + (if (> (point-max) (1+ text-start)) + (push + (mm-make-handle (mm-uu-copy-to-buffer text-start (point-max)) + text-plain-type) + result)) + (setq result (cons "multipart/mixed" (nreverse result)))) + result))) + +;;;### autoload +(defun mm-uu-test () + "Check whether the current buffer contains uu stuffs." + (save-excursion + (goto-char (point-min)) + (let (type end-line result + (case-fold-search t)) + (while (and mm-uu-begin-line + (not result) (re-search-forward mm-uu-begin-line nil t)) + (forward-line) + (setq type (cdr (assq (aref (match-string 0) 0) + mm-uu-identifier-alist))) + (setq end-line (symbol-value + (intern (concat "mm-uu-" (symbol-name type) + "-end-line")))) + (if (and (re-search-forward end-line nil t) + (not (eq (match-beginning 0) (match-end 0)))) + (setq result t))) + result))) + +(provide 'mm-uu) + +;;; mm-uu.el ends here diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el new file mode 100644 index 00000000000..45ed4d2a7e2 --- /dev/null +++ b/lisp/gnus/mm-view.el @@ -0,0 +1,279 @@ +;;; mm-view.el --- Functions for viewing MIME objects +;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(eval-when-compile (require 'cl)) +(require 'mail-parse) +(require 'mailcap) +(require 'mm-bodies) +(require 'mm-decode) + +(eval-and-compile + (autoload 'gnus-article-prepare-display "gnus-art") + (autoload 'vcard-parse-string "vcard") + (autoload 'vcard-format-string "vcard") + (autoload 'fill-flowed "flow-fill") + (autoload 'diff-mode "diff-mode")) + +;;; +;;; Functions for displaying various formats inline +;;; +(defun mm-inline-image-emacs (handle) + (let ((b (point-marker)) + buffer-read-only) + (insert "\n") + (put-image (mm-get-image handle) b) + (mm-handle-set-undisplayer + handle + `(lambda () (remove-images ,b (1+ ,b)))))) + +(defun mm-inline-image-xemacs (handle) + (let ((b (point)) + (annot (make-annotation (mm-get-image handle) nil 'text)) + buffer-read-only) + (insert "\n") + (mm-handle-set-undisplayer + handle + `(lambda () + (let (buffer-read-only) + (delete-annotation ,annot) + (delete-region ,(set-marker (make-marker) b) + ,(set-marker (make-marker) (point)))))) + (set-extent-property annot 'mm t) + (set-extent-property annot 'duplicable t))) + +(eval-and-compile + (if (string-match "XEmacs" (emacs-version)) + (defalias 'mm-inline-image 'mm-inline-image-xemacs) + (defalias 'mm-inline-image 'mm-inline-image-emacs))) + +(defvar mm-w3-setup nil) +(defun mm-setup-w3 () + (unless mm-w3-setup + (require 'w3) + (w3-do-setup) + (require 'url) + (require 'w3-vars) + (require 'url-vars) + (setq mm-w3-setup t))) + +(defun mm-inline-text (handle) + (let ((type (mm-handle-media-subtype handle)) + text buffer-read-only) + (cond + ((equal type "html") + (mm-setup-w3) + (setq text (mm-get-part handle)) + (let ((b (point)) + (url-standalone-mode t) + (url-current-object + (url-generic-parse-url (format "cid:%s" (mm-handle-id handle)))) + (width (window-width)) + (charset (mail-content-type-get + (mm-handle-type handle) 'charset))) + (save-excursion + (insert text) + (save-restriction + (narrow-to-region b (point)) + (goto-char (point-min)) + (if (or (and (boundp 'w3-meta-content-type-charset-regexp) + (re-search-forward + w3-meta-content-type-charset-regexp nil t)) + (and (boundp 'w3-meta-charset-content-type-regexp) + (re-search-forward + w3-meta-charset-content-type-regexp nil t))) + (setq charset (or (w3-coding-system-for-mime-charset + (buffer-substring-no-properties + (match-beginning 2) + (match-end 2))) + charset))) + (delete-region (point-min) (point-max)) + (insert (mm-decode-string text charset)) + (save-window-excursion + (save-restriction + (let ((w3-strict-width width) + ;; Don't let w3 set the global version of + ;; this variable. + (fill-column fill-column) + (url-standalone-mode t)) + (condition-case var + (w3-region (point-min) (point-max)) + (error))))) + (mm-handle-set-undisplayer + handle + `(lambda () + (let (buffer-read-only) + (if (functionp 'remove-specifier) + (mapcar (lambda (prop) + (remove-specifier + (face-property 'default prop) + (current-buffer))) + '(background background-pixmap foreground))) + (delete-region ,(point-min-marker) + ,(point-max-marker))))))))) + ((or (equal type "enriched") + (equal type "richtext")) + (save-excursion + (mm-with-unibyte-buffer + (mm-insert-part handle) + (save-window-excursion + (enriched-decode (point-min) (point-max)) + (setq text (buffer-string))))) + (mm-insert-inline handle text)) + ((equal type "x-vcard") + (mm-insert-inline + handle + (concat "\n-- \n" + (if (fboundp 'vcard-pretty-print) + (vcard-pretty-print (mm-get-part handle)) + (vcard-format-string + (vcard-parse-string (mm-get-part handle) + 'vcard-standard-filter)))))) + (t + (let ((b (point)) + (charset (mail-content-type-get + (mm-handle-type handle) 'charset))) + (if (or (eq charset 'gnus-decoded) + ;; This is probably not entirely correct, but + ;; makes rfc822 parts with embedded multiparts work. + (eq mail-parse-charset 'gnus-decoded)) + (mm-insert-part handle) + (insert (mm-decode-string (mm-get-part handle) charset))) + (when (and (equal type "plain") + (equal (cdr (assoc 'format (mm-handle-type handle))) + "flowed")) + (save-restriction + (narrow-to-region b (point)) + (goto-char b) + (fill-flowed) + (goto-char (point-max)))) + (save-restriction + (narrow-to-region b (point)) + (set-text-properties (point-min) (point-max) nil) + (mm-handle-set-undisplayer + handle + `(lambda () + (let (buffer-read-only) + (delete-region ,(point-min-marker) + ,(point-max-marker))))))))))) + +(defun mm-insert-inline (handle text) + "Insert TEXT inline from HANDLE." + (let ((b (point))) + (insert text) + (mm-handle-set-undisplayer + handle + `(lambda () + (let (buffer-read-only) + (delete-region ,(set-marker (make-marker) b) + ,(set-marker (make-marker) (point)))))))) + +(defun mm-inline-audio (handle) + (message "Not implemented")) + +(defun mm-view-sound-file () + (message "Not implemented")) + +(defun mm-w3-prepare-buffer () + (require 'w3) + (let ((url-standalone-mode t)) + (w3-prepare-buffer))) + +(defun mm-view-message () + (mm-enable-multibyte) + (let (handles) + (let (gnus-article-mime-handles) + ;; Double decode problem may happen. See mm-inline-message. + (run-hooks 'gnus-article-decode-hook) + (gnus-article-prepare-display) + (setq handles gnus-article-mime-handles)) + (when handles + (setq gnus-article-mime-handles + (nconc gnus-article-mime-handles + (if (listp (car handles)) + handles (list handles)))))) + (fundamental-mode) + (goto-char (point-min))) + +(defun mm-inline-message (handle) + (let ((b (point)) + (charset (mail-content-type-get + (mm-handle-type handle) 'charset)) + gnus-displaying-mime handles) + (when (and charset + (stringp charset)) + (setq charset (intern (downcase charset))) + (when (eq charset 'us-ascii) + (setq charset nil))) + (save-excursion + (save-restriction + (narrow-to-region b b) + (mm-insert-part handle) + (let (gnus-article-mime-handles + ;; disable prepare hook + gnus-article-prepare-hook + (gnus-newsgroup-charset + (or charset gnus-newsgroup-charset))) + (run-hooks 'gnus-article-decode-hook) + (gnus-article-prepare-display) + (setq handles gnus-article-mime-handles)) + (goto-char (point-max)) + (unless (bolp) + (insert "\n")) + (insert "----------\n\n") + (when handles + (setq gnus-article-mime-handles + (nconc gnus-article-mime-handles + (if (listp (car handles)) + handles (list handles))))) + (mm-handle-set-undisplayer + handle + `(lambda () + (let (buffer-read-only) + (condition-case nil + ;; This is only valid on XEmacs. + (mapcar (lambda (prop) + (remove-specifier + (face-property 'default prop) (current-buffer))) + '(background background-pixmap foreground)) + (error nil)) + (delete-region ,(point-min-marker) ,(point-max-marker))))))))) + +(defun mm-display-patch-inline (handle) + (let (text) + (with-temp-buffer + (mm-insert-part handle) + (diff-mode) + (font-lock-fontify-buffer) + (when (fboundp 'extent-list) + (map-extents (lambda (ext ignored) + (set-extent-property ext 'duplicable t) + nil) + nil nil nil nil nil 'text-prop)) + (setq text (buffer-string))) + (mm-insert-inline handle text))) + +(provide 'mm-view) + +;; mm-view.el ends here diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el new file mode 100644 index 00000000000..86faed8aa53 --- /dev/null +++ b/lisp/gnus/mml.el @@ -0,0 +1,871 @@ +;;; mml.el --- A package for parsing and validating MML documents +;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;;; Code: + +(require 'mm-util) +(require 'mm-bodies) +(require 'mm-encode) +(require 'mm-decode) +(eval-when-compile 'cl) + +(eval-and-compile + (autoload 'message-make-message-id "message") + (autoload 'gnus-setup-posting-charset "gnus-msg") + (autoload 'message-fetch-field "message") + (autoload 'message-posting-charset "message")) + +(defvar mml-generate-multipart-alist nil + "*Alist of multipart generation functions. +Each entry has the form (NAME . FUNCTION), where +NAME is a string containing the name of the part (without the +leading \"/multipart/\"), +FUNCTION is a Lisp function which is called to generate the part. + +The Lisp function has to supply the appropriate MIME headers and the +contents of this part.") + +(defvar mml-syntax-table + (let ((table (copy-syntax-table emacs-lisp-mode-syntax-table))) + (modify-syntax-entry ?\\ "/" table) + (modify-syntax-entry ?< "(" table) + (modify-syntax-entry ?> ")" table) + (modify-syntax-entry ?@ "w" table) + (modify-syntax-entry ?/ "w" table) + (modify-syntax-entry ?= " " table) + (modify-syntax-entry ?* " " table) + (modify-syntax-entry ?\; " " table) + (modify-syntax-entry ?\' " " table) + table)) + +(defvar mml-boundary-function 'mml-make-boundary + "A function called to suggest a boundary. +The function may be called several times, and should try to make a new +suggestion each time. The function is called with one parameter, +which is a number that says how many times the function has been +called for this message.") + +(defvar mml-confirmation-set nil + "A list of symbols, each of which disables some warning. +`unknown-encoding': always send messages contain characters with +unknown encoding; `use-ascii': always use ASCII for those characters +with unknown encoding; `multipart': always send messages with more than +one charsets.") + +(defvar mml-generate-mime-preprocess-function nil + "A function called before generating a mime part. +The function is called with one parameter, which is the part to be +generated.") + +(defvar mml-generate-mime-postprocess-function nil + "A function called after generating a mime part. +The function is called with one parameter, which is the generated part.") + +(defvar mml-generate-default-type "text/plain") + +(defvar mml-buffer-list nil) + +(defun mml-generate-new-buffer (name) + (let ((buf (generate-new-buffer name))) + (push buf mml-buffer-list) + buf)) + +(defun mml-destroy-buffers () + (let (kill-buffer-hook) + (mapcar 'kill-buffer mml-buffer-list) + (setq mml-buffer-list nil))) + +(defun mml-parse () + "Parse the current buffer as an MML document." + (goto-char (point-min)) + (let ((table (syntax-table))) + (unwind-protect + (progn + (set-syntax-table mml-syntax-table) + (mml-parse-1)) + (set-syntax-table table)))) + +(defun mml-parse-1 () + "Parse the current buffer as an MML document." + (let (struct tag point contents charsets warn use-ascii no-markup-p raw) + (while (and (not (eobp)) + (not (looking-at "<#/multipart"))) + (cond + ((looking-at "<#multipart") + (push (nconc (mml-read-tag) (mml-parse-1)) struct)) + ((looking-at "<#external") + (push (nconc (mml-read-tag) (list (cons 'contents (mml-read-part)))) + struct)) + (t + (if (or (looking-at "<#part") (looking-at "<#mml")) + (setq tag (mml-read-tag) + no-markup-p nil + warn nil) + (setq tag (list 'part '(type . "text/plain")) + no-markup-p t + warn t)) + (setq raw (cdr (assq 'raw tag)) + point (point) + contents (if raw + (mm-with-unibyte-current-buffer + (mml-read-part (eq 'mml (car tag)))) + (mml-read-part (eq 'mml (car tag)))) + charsets (if raw nil + (mm-find-mime-charset-region point (point)))) + (when (and (not raw) (memq nil charsets)) + (if (or (memq 'unknown-encoding mml-confirmation-set) + (y-or-n-p + "Warning: You message contains characters with unknown encoding. Really send?")) + (if (setq use-ascii + (or (memq 'use-ascii mml-confirmation-set) + (y-or-n-p "Use ASCII as charset?"))) + (setq charsets (delq nil charsets)) + (setq warn nil)) + (error "Edit your message to remove those characters"))) + (if (or raw + (eq 'mml (car tag)) + (< (length charsets) 2)) + (if (or (not no-markup-p) + (string-match "[^ \t\r\n]" contents)) + ;; Don't create blank parts. + (push (nconc tag (list (cons 'contents contents))) + struct)) + (let ((nstruct (mml-parse-singlepart-with-multiple-charsets + tag point (point) use-ascii))) + (when (and warn + (not (memq 'multipart mml-confirmation-set)) + (not + (y-or-n-p + (format + "Warning: Your message contains more than %d parts. Really send? " + (length nstruct))))) + (error "Edit your message to use only one charset")) + (setq struct (nconc nstruct struct))))))) + (unless (eobp) + (forward-line 1)) + (nreverse struct))) + +(defun mml-parse-singlepart-with-multiple-charsets + (orig-tag beg end &optional use-ascii) + (save-excursion + (save-restriction + (narrow-to-region beg end) + (goto-char (point-min)) + (let ((current (or (mm-mime-charset (mm-charset-after)) + (and use-ascii 'us-ascii))) + charset struct space newline paragraph) + (while (not (eobp)) + (setq charset (mm-mime-charset (mm-charset-after))) + (cond + ;; The charset remains the same. + ((eq charset 'us-ascii)) + ((or (and use-ascii (not charset)) + (eq charset current)) + (setq space nil + newline nil + paragraph nil)) + ;; The initial charset was ascii. + ((eq current 'us-ascii) + (setq current charset + space nil + newline nil + paragraph nil)) + ;; We have a change in charsets. + (t + (push (append + orig-tag + (list (cons 'contents + (buffer-substring-no-properties + beg (or paragraph newline space (point)))))) + struct) + (setq beg (or paragraph newline space (point)) + current charset + space nil + newline nil + paragraph nil))) + ;; Compute places where it might be nice to break the part. + (cond + ((memq (following-char) '(? ?\t)) + (setq space (1+ (point)))) + ((and (eq (following-char) ?\n) + (not (bobp)) + (eq (char-after (1- (point))) ?\n)) + (setq paragraph (point))) + ((eq (following-char) ?\n) + (setq newline (1+ (point))))) + (forward-char 1)) + ;; Do the final part. + (unless (= beg (point)) + (push (append orig-tag + (list (cons 'contents + (buffer-substring-no-properties + beg (point))))) + struct)) + struct)))) + +(defun mml-read-tag () + "Read a tag and return the contents." + (let (contents name elem val) + (forward-char 2) + (setq name (buffer-substring-no-properties + (point) (progn (forward-sexp 1) (point)))) + (skip-chars-forward " \t\n") + (while (not (looking-at ">")) + (setq elem (buffer-substring-no-properties + (point) (progn (forward-sexp 1) (point)))) + (skip-chars-forward "= \t\n") + (setq val (buffer-substring-no-properties + (point) (progn (forward-sexp 1) (point)))) + (when (string-match "^\"\\(.*\\)\"$" val) + (setq val (match-string 1 val))) + (push (cons (intern elem) val) contents) + (skip-chars-forward " \t\n")) + (forward-char 1) + (skip-chars-forward " \t\n") + (cons (intern name) (nreverse contents)))) + +(defun mml-read-part (&optional mml) + "Return the buffer up till the next part, multipart or closing part or multipart. +If MML is non-nil, return the buffer up till the correspondent mml tag." + (let ((beg (point)) (count 1)) + ;; If the tag ended at the end of the line, we go to the next line. + (when (looking-at "[ \t]*\n") + (forward-line 1)) + (if mml + (progn + (while (and (> count 0) (not (eobp))) + (if (re-search-forward "<#\\(/\\)?mml." nil t) + (setq count (+ count (if (match-beginning 1) -1 1))) + (goto-char (point-max)))) + (buffer-substring-no-properties beg (if (> count 0) + (point) + (match-beginning 0)))) + (if (re-search-forward + "<#\\(/\\)?\\(multipart\\|part\\|external\\|mml\\)." nil t) + (prog1 + (buffer-substring-no-properties beg (match-beginning 0)) + (if (or (not (match-beginning 1)) + (equal (match-string 2) "multipart")) + (goto-char (match-beginning 0)) + (when (looking-at "[ \t]*\n") + (forward-line 1)))) + (buffer-substring-no-properties beg (goto-char (point-max))))))) + +(defvar mml-boundary nil) +(defvar mml-base-boundary "-=-=") +(defvar mml-multipart-number 0) + +(defun mml-generate-mime () + "Generate a MIME message based on the current MML document." + (let ((cont (mml-parse)) + (mml-multipart-number mml-multipart-number)) + (if (not cont) + nil + (with-temp-buffer + (if (and (consp (car cont)) + (= (length cont) 1)) + (mml-generate-mime-1 (car cont)) + (mml-generate-mime-1 (nconc (list 'multipart '(type . "mixed")) + cont))) + (buffer-string))))) + +(defun mml-generate-mime-1 (cont) + (save-restriction + (narrow-to-region (point) (point)) + (if mml-generate-mime-preprocess-function + (funcall mml-generate-mime-preprocess-function cont)) + (cond + ((or (eq (car cont) 'part) (eq (car cont) 'mml)) + (let ((raw (cdr (assq 'raw cont))) + coded encoding charset filename type) + (setq type (or (cdr (assq 'type cont)) "text/plain")) + (if (and (not raw) + (member (car (split-string type "/")) '("text" "message"))) + (with-temp-buffer + (cond + ((cdr (assq 'buffer cont)) + (insert-buffer-substring (cdr (assq 'buffer cont)))) + ((and (setq filename (cdr (assq 'filename cont))) + (not (equal (cdr (assq 'nofile cont)) "yes"))) + (mm-insert-file-contents filename)) + ((eq 'mml (car cont)) + (insert (cdr (assq 'contents cont)))) + (t + (save-restriction + (narrow-to-region (point) (point)) + (insert (cdr (assq 'contents cont))) + ;; Remove quotes from quoted tags. + (goto-char (point-min)) + (while (re-search-forward + "<#!+/?\\(part\\|multipart\\|external\\|mml\\)" nil t) + (delete-region (+ (match-beginning 0) 2) + (+ (match-beginning 0) 3)))))) + (cond + ((eq (car cont) 'mml) + (let ((mml-boundary (funcall mml-boundary-function + (incf mml-multipart-number))) + (mml-generate-default-type "text/plain")) + (mml-to-mime)) + (let ((mm-7bit-chars (concat mm-7bit-chars "\x1b"))) + ;; ignore 0x1b, it is part of iso-2022-jp + (setq encoding (mm-body-7-or-8)))) + ((string= (car (split-string type "/")) "message") + (let ((mm-7bit-chars (concat mm-7bit-chars "\x1b"))) + ;; ignore 0x1b, it is part of iso-2022-jp + (setq encoding (mm-body-7-or-8)))) + (t + (setq charset (mm-encode-body)) + (setq encoding (mm-body-encoding + charset (cdr (assq 'encoding cont)))))) + (setq coded (buffer-string))) + (mm-with-unibyte-buffer + (cond + ((cdr (assq 'buffer cont)) + (insert-buffer-substring (cdr (assq 'buffer cont)))) + ((and (setq filename (cdr (assq 'filename cont))) + (not (equal (cdr (assq 'nofile cont)) "yes"))) + (let ((coding-system-for-read mm-binary-coding-system)) + (mm-insert-file-contents filename nil nil nil nil t))) + (t + (insert (cdr (assq 'contents cont))))) + (setq encoding (mm-encode-buffer type) + coded (buffer-string)))) + (mml-insert-mime-headers cont type charset encoding) + (insert "\n") + (mm-with-unibyte-current-buffer + (insert coded)))) + ((eq (car cont) 'external) + (insert "Content-Type: message/external-body") + (let ((parameters (mml-parameter-string + cont '(expiration size permission))) + (name (cdr (assq 'name cont)))) + (when name + (setq name (mml-parse-file-name name)) + (if (stringp name) + (mml-insert-parameter + (mail-header-encode-parameter "name" name) + "access-type=local-file") + (mml-insert-parameter + (mail-header-encode-parameter + "name" (file-name-nondirectory (nth 2 name))) + (mail-header-encode-parameter "site" (nth 1 name)) + (mail-header-encode-parameter + "directory" (file-name-directory (nth 2 name)))) + (mml-insert-parameter + (concat "access-type=" + (if (member (nth 0 name) '("ftp@" "anonymous@")) + "anon-ftp" + "ftp"))))) + (when parameters + (mml-insert-parameter-string + cont '(expiration size permission)))) + (insert "\n\n") + (insert "Content-Type: " (cdr (assq 'type cont)) "\n") + (insert "Content-ID: " (message-make-message-id) "\n") + (insert "Content-Transfer-Encoding: " + (or (cdr (assq 'encoding cont)) "binary")) + (insert "\n\n") + (insert (or (cdr (assq 'contents cont)))) + (insert "\n")) + ((eq (car cont) 'multipart) + (let* ((type (or (cdr (assq 'type cont)) "mixed")) + (mml-generate-default-type (if (equal type "digest") + "message/rfc822" + "text/plain")) + (handler (assoc type mml-generate-multipart-alist))) + (if handler + (funcall (cdr handler) cont) + ;; No specific handler. Use default one. + (let ((mml-boundary (mml-compute-boundary cont))) + (insert (format "Content-Type: multipart/%s; boundary=\"%s\"\n" + type mml-boundary)) + ;; Skip `multipart' and `type' elements. + (setq cont (cddr cont)) + (while cont + (insert "\n--" mml-boundary "\n") + (mml-generate-mime-1 (pop cont))) + (insert "\n--" mml-boundary "--\n"))))) + (t + (error "Invalid element: %S" cont))) + (if mml-generate-mime-postprocess-function + (funcall mml-generate-mime-postprocess-function cont)))) + +(defun mml-compute-boundary (cont) + "Return a unique boundary that does not exist in CONT." + (let ((mml-boundary (funcall mml-boundary-function + (incf mml-multipart-number)))) + ;; This function tries again and again until it has found + ;; a unique boundary. + (while (not (catch 'not-unique + (mml-compute-boundary-1 cont)))) + mml-boundary)) + +(defun mml-compute-boundary-1 (cont) + (let (filename) + (cond + ((eq (car cont) 'part) + (with-temp-buffer + (cond + ((cdr (assq 'buffer cont)) + (insert-buffer-substring (cdr (assq 'buffer cont)))) + ((and (setq filename (cdr (assq 'filename cont))) + (not (equal (cdr (assq 'nofile cont)) "yes"))) + (mm-insert-file-contents filename)) + (t + (insert (cdr (assq 'contents cont))))) + (goto-char (point-min)) + (when (re-search-forward (concat "^--" (regexp-quote mml-boundary)) + nil t) + (setq mml-boundary (funcall mml-boundary-function + (incf mml-multipart-number))) + (throw 'not-unique nil)))) + ((eq (car cont) 'multipart) + (mapcar 'mml-compute-boundary-1 (cddr cont)))) + t)) + +(defun mml-make-boundary (number) + (concat (make-string (% number 60) ?=) + (if (> number 17) + (format "%x" number) + "") + mml-base-boundary)) + +(defun mml-insert-mime-headers (cont type charset encoding) + (let (parameters disposition description) + (setq parameters + (mml-parameter-string + cont '(name access-type expiration size permission))) + (when (or charset + parameters + (not (equal type mml-generate-default-type))) + (when (consp charset) + (error + "Can't encode a part with several charsets.")) + (insert "Content-Type: " type) + (when charset + (insert "; " (mail-header-encode-parameter + "charset" (symbol-name charset)))) + (when parameters + (mml-insert-parameter-string + cont '(name access-type expiration size permission))) + (insert "\n")) + (setq parameters + (mml-parameter-string + cont '(filename creation-date modification-date read-date))) + (when (or (setq disposition (cdr (assq 'disposition cont))) + parameters) + (insert "Content-Disposition: " (or disposition "inline")) + (when parameters + (mml-insert-parameter-string + cont '(filename creation-date modification-date read-date))) + (insert "\n")) + (unless (eq encoding '7bit) + (insert (format "Content-Transfer-Encoding: %s\n" encoding))) + (when (setq description (cdr (assq 'description cont))) + (insert "Content-Description: " + (mail-encode-encoded-word-string description) "\n")))) + +(defun mml-parameter-string (cont types) + (let ((string "") + value type) + (while (setq type (pop types)) + (when (setq value (cdr (assq type cont))) + ;; Strip directory component from the filename parameter. + (when (eq type 'filename) + (setq value (file-name-nondirectory value))) + (setq string (concat string "; " + (mail-header-encode-parameter + (symbol-name type) value))))) + (when (not (zerop (length string))) + string))) + +(defun mml-insert-parameter-string (cont types) + (let (value type) + (while (setq type (pop types)) + (when (setq value (cdr (assq type cont))) + ;; Strip directory component from the filename parameter. + (when (eq type 'filename) + (setq value (file-name-nondirectory value))) + (mml-insert-parameter + (mail-header-encode-parameter + (symbol-name type) value)))))) + +(defvar ange-ftp-name-format) +(defvar efs-path-regexp) +(defun mml-parse-file-name (path) + (if (if (boundp 'efs-path-regexp) + (string-match efs-path-regexp path) + (if (boundp 'ange-ftp-name-format) + (string-match (car ange-ftp-name-format) path))) + (list (match-string 1 path) (match-string 2 path) + (substring path (1+ (match-end 2)))) + path)) + +(defun mml-insert-buffer (buffer) + "Insert BUFFER at point and quote any MML markup." + (save-restriction + (narrow-to-region (point) (point)) + (insert-buffer-substring buffer) + (mml-quote-region (point-min) (point-max)) + (goto-char (point-max)))) + +;;; +;;; Transforming MIME to MML +;;; + +(defun mime-to-mml () + "Translate the current buffer (which should be a message) into MML." + ;; First decode the head. + (save-restriction + (message-narrow-to-head) + (mail-decode-encoded-word-region (point-min) (point-max))) + (let ((handles (mm-dissect-buffer t))) + (goto-char (point-min)) + (search-forward "\n\n" nil t) + (delete-region (point) (point-max)) + (if (stringp (car handles)) + (mml-insert-mime handles) + (mml-insert-mime handles t)) + (mm-destroy-parts handles)) + (save-restriction + (message-narrow-to-head) + ;; Remove them, they are confusing. + (message-remove-header "Content-Type") + (message-remove-header "MIME-Version") + (message-remove-header "Content-Transfer-Encoding"))) + +(defun mml-to-mime () + "Translate the current buffer from MML to MIME." + (message-encode-message-body) + (save-restriction + (message-narrow-to-headers-or-head) + (let ((mail-parse-charset message-default-charset)) + (mail-encode-encoded-word-buffer)))) + +(defun mml-insert-mime (handle &optional no-markup) + (let (textp buffer mmlp) + ;; Determine type and stuff. + (unless (stringp (car handle)) + (unless (setq textp (equal (mm-handle-media-supertype handle) "text")) + (save-excursion + (set-buffer (setq buffer (mml-generate-new-buffer " *mml*"))) + (mm-insert-part handle) + (if (setq mmlp (equal (mm-handle-media-type handle) + "message/rfc822")) + (mime-to-mml))))) + (if mmlp + (mml-insert-mml-markup handle nil t t) + (unless (and no-markup + (equal (mm-handle-media-type handle) "text/plain")) + (mml-insert-mml-markup handle buffer textp))) + (cond + (mmlp + (insert-buffer buffer) + (goto-char (point-max)) + (insert "<#/mml>\n")) + ((stringp (car handle)) + (mapcar 'mml-insert-mime (cdr handle)) + (insert "<#/multipart>\n")) + (textp + (let ((text (mm-get-part handle)) + (charset (mail-content-type-get + (mm-handle-type handle) 'charset))) + (insert (mm-decode-string text charset))) + (goto-char (point-max))) + (t + (insert "<#/part>\n"))))) + +(defun mml-insert-mml-markup (handle &optional buffer nofile mmlp) + "Take a MIME handle and insert an MML tag." + (if (stringp (car handle)) + (insert "<#multipart type=" (mm-handle-media-subtype handle) + ">\n") + (if mmlp + (insert "<#mml type=" (mm-handle-media-type handle)) + (insert "<#part type=" (mm-handle-media-type handle))) + (dolist (elem (append (cdr (mm-handle-type handle)) + (cdr (mm-handle-disposition handle)))) + (insert " " (symbol-name (car elem)) "=\"" (cdr elem) "\"")) + (when (mm-handle-disposition handle) + (insert " disposition=" (car (mm-handle-disposition handle)))) + (when buffer + (insert " buffer=\"" (buffer-name buffer) "\"")) + (when nofile + (insert " nofile=yes")) + (when (mm-handle-description handle) + (insert " description=\"" (mm-handle-description handle) "\"")) + (insert ">\n"))) + +(defun mml-insert-parameter (&rest parameters) + "Insert PARAMETERS in a nice way." + (dolist (param parameters) + (insert ";") + (let ((point (point))) + (insert " " param) + (when (> (current-column) 71) + (goto-char point) + (insert "\n ") + (end-of-line))))) + +;;; +;;; Mode for inserting and editing MML forms +;;; + +(defvar mml-mode-map + (let ((map (make-sparse-keymap)) + (main (make-sparse-keymap))) + (define-key map "f" 'mml-attach-file) + (define-key map "b" 'mml-attach-buffer) + (define-key map "e" 'mml-attach-external) + (define-key map "q" 'mml-quote-region) + (define-key map "m" 'mml-insert-multipart) + (define-key map "p" 'mml-insert-part) + (define-key map "v" 'mml-validate) + (define-key map "P" 'mml-preview) + ;;(define-key map "n" 'mml-narrow-to-part) + (define-key main "\M-m" map) + main)) + +(easy-menu-define + mml-menu mml-mode-map "" + '("MML" + ("Attach" + ["File" mml-attach-file t] + ["Buffer" mml-attach-buffer t] + ["External" mml-attach-external t]) + ("Insert" + ["Multipart" mml-insert-multipart t] + ["Part" mml-insert-part t]) + ;;["Narrow" mml-narrow-to-part t] + ["Quote" mml-quote-region t] + ["Validate" mml-validate t] + ["Preview" mml-preview t])) + +(defvar mml-mode nil + "Minor mode for editing MML.") + +(defun mml-mode (&optional arg) + "Minor mode for editing MML. + +\\{mml-mode-map}" + (interactive "P") + (if (not (set (make-local-variable 'mml-mode) + (if (null arg) (not mml-mode) + (> (prefix-numeric-value arg) 0)))) + nil + (set (make-local-variable 'mml-mode) t) + (unless (assq 'mml-mode minor-mode-alist) + (push `(mml-mode " MML") minor-mode-alist)) + (unless (assq 'mml-mode minor-mode-map-alist) + (push (cons 'mml-mode mml-mode-map) + minor-mode-map-alist))) + (run-hooks 'mml-mode-hook)) + +;;; +;;; Helper functions for reading MIME stuff from the minibuffer and +;;; inserting stuff to the buffer. +;;; + +(defun mml-minibuffer-read-file (prompt) + (let ((file (read-file-name prompt nil nil t))) + ;; Prevent some common errors. This is inspired by similar code in + ;; VM. + (when (file-directory-p file) + (error "%s is a directory, cannot attach" file)) + (unless (file-exists-p file) + (error "No such file: %s" file)) + (unless (file-readable-p file) + (error "Permission denied: %s" file)) + file)) + +(defun mml-minibuffer-read-type (name &optional default) + (mailcap-parse-mimetypes) + (let* ((default (or default + (mm-default-file-encoding name) + ;; Perhaps here we should check what the file + ;; looks like, and offer text/plain if it looks + ;; like text/plain. + "application/octet-stream")) + (string (completing-read + (format "Content type (default %s): " default) + (mapcar + 'list + (mm-delete-duplicates + (nconc + (mapcar 'cdr mailcap-mime-extensions) + (apply + 'nconc + (mapcar + (lambda (l) + (delq nil + (mapcar + (lambda (m) + (let ((type (cdr (assq 'type (cdr m))))) + (if (equal (cadr (split-string type "/")) + "*") + nil + type))) + (cdr l)))) + mailcap-mime-data)))))))) + (if (not (equal string "")) + string + default))) + +(defun mml-minibuffer-read-description () + (let ((description (read-string "One line description: "))) + (when (string-match "\\`[ \t]*\\'" description) + (setq description nil)) + description)) + +(defun mml-quote-region (beg end) + "Quote the MML tags in the region." + (interactive "r") + (save-excursion + (save-restriction + ;; Temporarily narrow the region to defend from changes + ;; invalidating END. + (narrow-to-region beg end) + (goto-char (point-min)) + ;; Quote parts. + (while (re-search-forward + "<#!*/?\\(multipart\\|part\\|external\\|mml\\)" nil t) + ;; Insert ! after the #. + (goto-char (+ (match-beginning 0) 2)) + (insert "!"))))) + +(defun mml-insert-tag (name &rest plist) + "Insert an MML tag described by NAME and PLIST." + (when (symbolp name) + (setq name (symbol-name name))) + (insert "<#" name) + (while plist + (let ((key (pop plist)) + (value (pop plist))) + (when value + ;; Quote VALUE if it contains suspicious characters. + (when (string-match "[\"'\\~/*;() \t\n]" value) + (setq value (prin1-to-string value))) + (insert (format " %s=%s" key value))))) + (insert ">\n")) + +(defun mml-insert-empty-tag (name &rest plist) + "Insert an empty MML tag described by NAME and PLIST." + (when (symbolp name) + (setq name (symbol-name name))) + (apply #'mml-insert-tag name plist) + (insert "<#/" name ">\n")) + +;;; Attachment functions. + +(defun mml-attach-file (file &optional type description) + "Attach a file to the outgoing MIME message. +The file is not inserted or encoded until you send the message with +`\\[message-send-and-exit]' or `\\[message-send]'. + +FILE is the name of the file to attach. TYPE is its content-type, a +string of the form \"type/subtype\". DESCRIPTION is a one-line +description of the attachment." + (interactive + (let* ((file (mml-minibuffer-read-file "Attach file: ")) + (type (mml-minibuffer-read-type file)) + (description (mml-minibuffer-read-description))) + (list file type description))) + (mml-insert-empty-tag 'part 'type type 'filename file + 'disposition "attachment" 'description description)) + +(defun mml-attach-buffer (buffer &optional type description) + "Attach a buffer to the outgoing MIME message. +See `mml-attach-file' for details of operation." + (interactive + (let* ((buffer (read-buffer "Attach buffer: ")) + (type (mml-minibuffer-read-type buffer "text/plain")) + (description (mml-minibuffer-read-description))) + (list buffer type description))) + (mml-insert-empty-tag 'part 'type type 'buffer buffer + 'disposition "attachment" 'description description)) + +(defun mml-attach-external (file &optional type description) + "Attach an external file into the buffer. +FILE is an ange-ftp/efs specification of the part location. +TYPE is the MIME type to use." + (interactive + (let* ((file (mml-minibuffer-read-file "Attach external file: ")) + (type (mml-minibuffer-read-type file)) + (description (mml-minibuffer-read-description))) + (list file type description))) + (mml-insert-empty-tag 'external 'type type 'name file + 'disposition "attachment" 'description description)) + +(defun mml-insert-multipart (&optional type) + (interactive (list (completing-read "Multipart type (default mixed): " + '(("mixed") ("alternative") ("digest") ("parallel") + ("signed") ("encrypted")) + nil nil "mixed"))) + (or type + (setq type "mixed")) + (mml-insert-empty-tag "multipart" 'type type) + (forward-line -1)) + +(defun mml-insert-part (&optional type) + (interactive + (list (mml-minibuffer-read-type ""))) + (mml-insert-tag 'part 'type type 'disposition "inline") + (forward-line -1)) + +(defun mml-preview (&optional raw) + "Display current buffer with Gnus, in a new buffer. +If RAW, don't highlight the article." + (interactive "P") + (let ((buf (current-buffer)) + (message-posting-charset (or (gnus-setup-posting-charset + (save-restriction + (message-narrow-to-headers-or-head) + (message-fetch-field "Newsgroups"))) + message-posting-charset))) + (switch-to-buffer (get-buffer-create + (concat (if raw "*Raw MIME preview of " + "*MIME preview of ") (buffer-name)))) + (erase-buffer) + (insert-buffer buf) + (if (re-search-forward + (concat "^" (regexp-quote mail-header-separator) "\n") nil t) + (replace-match "\n")) + (mml-to-mime) + (if raw + (mm-disable-multibyte) + (let ((gnus-newsgroup-charset (car message-posting-charset))) + (run-hooks 'gnus-article-decode-hook) + (let ((gnus-newsgroup-name "dummy")) + (gnus-article-prepare-display)))) + (fundamental-mode) + (setq buffer-read-only t) + (goto-char (point-min)))) + +(defun mml-validate () + "Validate the current MML document." + (interactive) + (mml-parse)) + +(provide 'mml) + +;;; mml.el ends here diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el new file mode 100644 index 00000000000..f5a8091a8f5 --- /dev/null +++ b/lisp/gnus/nnimap.el @@ -0,0 +1,1332 @@ +;;; nnimap.el --- imap backend for Gnus +;; Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + +;; Author: Simon Josefsson +;; Jim Radford +;; Keywords: mail + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Todo, major things: +;; +;; o Fix Gnus to view correct number of unread/total articles in group buffer +;; o Fix Gnus to handle leading '.' in group names (fixed?) +;; o Finish disconnected mode (moving articles between mailboxes unplugged) +;; o Sieve +;; o MIME (partial article fetches) +;; o Split to other backends, different split rules for different +;; servers/inboxes +;; +;; Todo, minor things: +;; +;; o Don't require half of Gnus -- backends should be standalone +;; o Verify that we don't use IMAP4rev1 specific things (RFC2060 App B) +;; o Dont uid fetch 1,* in nnimap-retrive-groups (slow) +;; o Split up big fetches (1,* header especially) in smaller chunks +;; o What do I do with gnus-newsgroup-*? +;; o Tell Gnus about new groups (how can we tell?) +;; o Respooling (fix Gnus?) (unnecessery?) +;; o Add support for the following: (if applicable) +;; request-list-newsgroups, request-regenerate +;; list-active-group, +;; request-associate-buffer, request-restore-buffer, +;; o Do The Right Thing when UIDVALIDITY changes (what's the right thing?) +;; o Support RFC2221 (Login referrals) +;; o IMAP2BIS compatibility? (RFC2061) +;; o ACAP stuff (perhaps a different project, would be nice to ACAPify +;; .newsrc.eld) +;; o What about Gnus's article editing, can we support it? NO! +;; o Use \Draft to support the draft group?? +;; o Duplicate suppression + +;;; Code: + +(eval-and-compile + (require 'imap)) + +(require 'nnoo) +(require 'nnmail) +(require 'nnheader) +(require 'mm-util) +(require 'gnus) +(require 'gnus-range) +(require 'gnus-start) +(require 'gnus-int) + +(nnoo-declare nnimap) + +(defconst nnimap-version "nnimap 0.131") + +(defvoo nnimap-address nil + "Address of physical IMAP server. If nil, use the virtual server's name.") + +(defvoo nnimap-server-port nil + "Port number on physical IMAP server. +If nil, defaults to 993 for SSL connections and 143 otherwise.") + +;; Splitting variables + +(defvar nnimap-split-crosspost t + "If non-nil, do crossposting if several split methods match the mail. +If nil, the first match found will be used.") + +(defvar nnimap-split-inbox nil + "*Name of mailbox to split mail from. + +Mail is read from this mailbox and split according to rules in +`nnimap-split-rules'. + +This can be a string or a list of strings.") + +(defvar nnimap-split-rule nil + "*Mail will be split according to theese rules. + +Mail is read from mailbox(es) specified in `nnimap-split-inbox'. + +If you'd like, for instance, one mail group for mail from the +\"gnus-imap\" mailing list, one group for junk mail and leave +everything else in the incoming mailbox, you could do something like +this: + +(setq nnimap-split-rule '((\"INBOX.gnus-imap\" \"From:.*gnus-imap\") + (\"INBOX.junk\" \"Subject:.*buy\"))) + +As you can see, `nnimap-split-rule' is a list of lists, where the first +element in each \"rule\" is the name of the IMAP mailbox, and the +second is a regexp that nnimap will try to match on the header to find +a fit. + +The second element can also be a function. In that case, it will be +called narrowed to the headers with the first element of the rule as +the argument. It should return a non-nil value if it thinks that the +mail belongs in that group. + +This variable can also have a function as its value, the function will +be called with the headers narrowed and should return a group where it +thinks the article should be splitted to. See `nnimap-split-fancy'. + +To allow for different split rules on different virtual servers, and +even different split rules in different inboxes on the same server, +the syntax of this variable have been extended along the lines of: + +(setq nnimap-split-rule + '((\"my1server\" (\".*\" ((\"ding\" \"ding@gnus.org\") + (\"junk\" \"From:.*Simon\"))) + (\"my2server\" (\"INBOX\" nnimap-split-fancy)) + (\"my[34]server\" (\".*\" ((\"private\" \"To:.*Simon\") + (\"junk\" my-junk-func))))) + +The virtual server name is in fact a regexp, so that the same rules +may apply to several servers. In the example, the servers +\"my3server\" and \"my4server\" both use the same rules. Similarly, +the inbox string is also a regexp. The actual splitting rules are as +before, either a function, or a list with group/regexp or +group/function elements.") + +(defvar nnimap-split-predicate "UNSEEN UNDELETED" + "The predicate used to find articles to split. +If you use another IMAP client to peek on articles but always would +like nnimap to split them once it's started, you could change this to +\"UNDELETED\". Other available predicates are available in +RFC2060 section 6.4.4.") + +(defvar nnimap-split-fancy nil + "Like `nnmail-split-fancy', which see.") + +;; Authorization / Privacy variables + +(defvoo nnimap-auth-method nil + "Obsolete.") + +(defvoo nnimap-stream nil + "How nnimap will connect to the server. + +The default, nil, will try to use the \"best\" method the server can +handle. + +Change this if + +1) you want to connect with SSL. The SSL integration with IMAP is + brain-dead so you'll have to tell it specifically. + +2) your server is more capable than your environment -- i.e. your + server accept Kerberos login's but you haven't installed the + `imtest' program or your machine isn't configured for Kerberos. + +Possible choices: kerberos4, ssl, network") + +(defvoo nnimap-authenticator nil + "How nnimap authenticate itself to the server. + +The default, nil, will try to use the \"best\" method the server can +handle. + +There is only one reason for fiddling with this variable, and that is +if your server is more capable than your environment -- i.e. you +connect to a server that accept Kerberos login's but you haven't +installed the `imtest' program or your machine isn't configured for +Kerberos. + +Possible choices: kerberos4, cram-md5, login, anonymous.") + +(defvoo nnimap-directory (nnheader-concat gnus-directory "overview/") + "Directory to keep NOV cache files for nnimap groups. +See also `nnimap-nov-file-name'.") + +(defvoo nnimap-nov-file-name "nnimap." + "NOV cache base filename. +The group name and `nnimap-nov-file-name-suffix' will be appended. A +typical complete file name would be +~/News/overview/nnimap.pdc.INBOX.ding.nov, or +~/News/overview/nnimap/pdc/INBOX/ding/nov if +`nnmail-use-long-file-names' is nil") + +(defvoo nnimap-nov-file-name-suffix ".novcache" + "Suffix for NOV cache base filename.") + +(defvoo nnimap-nov-is-evil nil + "If non-nil, nnimap will never generate or use a local nov database for this backend. +Using nov databases will speed up header fetching considerably. +Unlike other backends, you do not need to take special care if you +flip this variable.") + +(defvoo nnimap-expunge-on-close 'always ; 'ask, 'never + "Whether to expunge a group when it is closed. +When a IMAP group with articles marked for deletion is closed, this +variable determine if nnimap should actually remove the articles or +not. + +If always, nnimap always perform a expunge when closing the group. +If never, nnimap never expunges articles marked for deletion. +If ask, nnimap will ask you if you wish to expunge marked articles. + +When setting this variable to `never', you can only expunge articles +by using `G x' (gnus-group-nnimap-expunge) from the Group buffer.") + +(defvoo nnimap-list-pattern "*" + "A string LIMIT or list of strings with mailbox wildcards used to limit available groups. +See below for available wildcards. + +The LIMIT string can be a cons cell (REFERENCE . LIMIT), where +REFERENCE will be passed as the first parameter to LIST/LSUB. The +semantics of this are server specific, on the University of Washington +server you can specify a directory. + +Example: + '(\"INBOX\" \"mail/*\" (\"~friend/mail/\" . \"list/*\")) + +There are two wildcards * and %. * matches everything, % matches +everything in the current hierarchy.") + +(defvoo nnimap-news-groups nil + "IMAP support a news-like mode, also known as bulletin board mode, where replies is sent via IMAP instead of SMTP. + +This variable should contain a regexp matching groups where you wish +replies to be stored to the mailbox directly. + +Example: + '(\"^[^I][^N][^B][^O][^X].*$\") + +This will match all groups not beginning with \"INBOX\". + +Note that there is nothing technically different between mail-like and +news-like mailboxes. If you wish to have a group with todo items or +similar which you wouldn't want to set up a mailing list for, you can +use this to make replies go directly to the group.") + +(defvoo nnimap-server-address nil + "Obsolete. Use `nnimap-address'.") + +(defcustom nnimap-authinfo-file "~/.authinfo" + "Authorization information for IMAP servers. In .netrc format." + :type + '(choice file + (repeat :tag "Entries" + :menu-tag "Inline" + (list :format "%v" + :value ("" ("login" . "") ("password" . "")) + (string :tag "Host") + (checklist :inline t + (cons :format "%v" + (const :format "" "login") + (string :format "Login: %v")) + (cons :format "%v" + (const :format "" "password") + (string :format "Password: %v"))))))) + +(defcustom nnimap-prune-cache t + "If non-nil, nnimap check whether articles still exist on server before using data stored in NOV cache." + :type 'boolean) + +(defvar nnimap-request-list-method 'imap-mailbox-list + "Method to use to request a list of all folders from the server. +If this is 'imap-mailbox-lsub, then use a server-side subscription list to +restrict visible folders.") + +;; Internal variables: + +(defvar nnimap-debug nil + "Name of buffer to record debugging info. +For example: (setq nnimap-debug \"*nnimap-debug*\")") +(defvar nnimap-current-move-server nil) +(defvar nnimap-current-move-group nil) +(defvar nnimap-current-move-article nil) +(defvar nnimap-length) +(defvar nnimap-progress-chars '(?| ?/ ?- ?\\)) +(defvar nnimap-progress-how-often 20) +(defvar nnimap-counter) +(defvar nnimap-callback-callback-function nil + "Gnus callback the nnimap asynchronous callback should call.") +(defvar nnimap-callback-buffer nil + "Which buffer the asynchronous article prefetch callback should work in.") +(defvar nnimap-server-buffer-alist nil) ;; Map server name to buffers. +(defvar nnimap-current-server nil) ;; Current server +(defvar nnimap-server-buffer nil) ;; Current servers' buffer + + + +(nnoo-define-basics nnimap) + +;; Utility functions: + +(defsubst nnimap-get-server-buffer (server) + "Return buffer for SERVER, if nil use current server." + (cadr (assoc (or server nnimap-current-server) nnimap-server-buffer-alist))) + +(defun nnimap-possibly-change-server (server) + "Return buffer for SERVER, changing the current server as a side-effect. +If SERVER is nil, uses the current server." + (setq nnimap-current-server (or server nnimap-current-server) + nnimap-server-buffer (nnimap-get-server-buffer nnimap-current-server))) + +(defun nnimap-verify-uidvalidity (group server) + "Verify stored uidvalidity match current one in GROUP on SERVER." + (let* ((gnusgroup (gnus-group-prefixed-name + group (gnus-server-to-method + (format "nnimap:%s" server)))) + (new-uidvalidity (imap-mailbox-get 'uidvalidity)) + (old-uidvalidity (gnus-group-get-parameter gnusgroup 'uidvalidity))) + (if old-uidvalidity + (if (not (equal old-uidvalidity new-uidvalidity)) + nil ;; uidvalidity clash + (gnus-group-set-parameter gnusgroup 'uidvalidity new-uidvalidity) + t) + (gnus-group-add-parameter gnusgroup (cons 'uidvalidity new-uidvalidity)) + t))) + +(defun nnimap-before-find-minmax-bugworkaround () + "Function called before iterating through mailboxes with +`nnimap-find-minmax-uid'." + ;; XXX this is for UoW imapd problem, it doesn't notice new mail in + ;; currently selected mailbox without a re-select/examine. + (or (null (imap-current-mailbox nnimap-server-buffer)) + (imap-mailbox-unselect nnimap-server-buffer))) + +(defun nnimap-find-minmax-uid (group &optional examine) + "Find lowest and highest active article nummber in GROUP. +If EXAMINE is non-nil the group is selected read-only." + (with-current-buffer nnimap-server-buffer + (when (imap-mailbox-select group examine) + (let (minuid maxuid) + (when (> (imap-mailbox-get 'exists) 0) + (imap-fetch "1,*" "UID" nil 'nouidfetch) + (imap-message-map (lambda (uid Uid) + (setq minuid (if minuid (min minuid uid) uid) + maxuid (if maxuid (max maxuid uid) uid))) + 'UID)) + (list (imap-mailbox-get 'exists) minuid maxuid))))) + +(defun nnimap-possibly-change-group (group &optional server) + "Make GROUP the current group, and SERVER the current server." + (when (nnimap-possibly-change-server server) + (with-current-buffer nnimap-server-buffer + (if (or (null group) (imap-current-mailbox-p group)) + imap-current-mailbox + (if (imap-mailbox-select group) + (if (or (nnimap-verify-uidvalidity + group (or server nnimap-current-server)) + (zerop (imap-mailbox-get 'exists group)) + (yes-or-no-p + (format + "nnimap: Group %s is not uidvalid. Continue? " group))) + imap-current-mailbox + (imap-mailbox-unselect) + (error "nnimap: Group %s is not uid-valid." group)) + (nnheader-report 'nnimap (imap-error-text))))))) + +(defun nnimap-replace-whitespace (string) + "Return STRING with all whitespace replaced with space." + (when string + (while (string-match "[\r\n\t]+" string) + (setq string (replace-match " " t t string))) + string)) + +;; Required backend functions + +(defun nnimap-retrieve-headers-progress () + "Hook to insert NOV line for current article into `nntp-server-buffer'." + (and (numberp nnmail-large-newsgroup) + (zerop (% (incf nnimap-counter) nnimap-progress-how-often)) + (> nnimap-length nnmail-large-newsgroup) + (nnheader-message 6 "nnimap: Retrieving headers... %c" + (nth (/ (% nnimap-counter + (* (length nnimap-progress-chars) + nnimap-progress-how-often)) + nnimap-progress-how-often) + nnimap-progress-chars))) + (with-current-buffer nntp-server-buffer + (let (headers lines chars uid mbx) + (with-current-buffer nnimap-server-buffer + (setq uid imap-current-message + mbx imap-current-mailbox + headers (nnimap-demule + (if (imap-capability 'IMAP4rev1) + ;; xxx don't just use car? alist doesn't contain + ;; anything else now, but it might... + (nth 2 (car (imap-message-get uid 'BODYDETAIL))) + (imap-message-get uid 'RFC822.HEADER))) + lines (imap-body-lines (imap-message-body imap-current-message)) + chars (imap-message-get imap-current-message 'RFC822.SIZE))) + (nnheader-insert-nov + (with-temp-buffer + (buffer-disable-undo) + (insert headers) + (nnheader-ms-strip-cr) + (nnheader-fold-continuation-lines) + (subst-char-in-region (point-min) (point-max) ?\t ? ) + (let ((head (nnheader-parse-head 'naked))) + (mail-header-set-number head uid) + (mail-header-set-chars head chars) + (mail-header-set-lines head lines) + (mail-header-set-xref + head (format "%s %s:%d" (system-name) mbx uid)) + head)))))) + +(defun nnimap-retrieve-which-headers (articles fetch-old) + "Get a range of articles to fetch based on ARTICLES and FETCH-OLD." + (with-current-buffer nnimap-server-buffer + (if (numberp (car-safe articles)) + (imap-search + (concat "UID " + (imap-range-to-message-set + (gnus-compress-sequence + (append (gnus-uncompress-sequence + (and fetch-old + (cons (if (numberp fetch-old) + (max 1 (- (car articles) fetch-old)) + 1) + (1- (car articles))))) + articles))))) + (mapcar (lambda (msgid) + (imap-search + (format "HEADER Message-Id %s" msgid))) + articles)))) + +(defun nnimap-group-overview-filename (group server) + "Make pathname for GROUP on SERVER." + (let ((dir (file-name-as-directory (expand-file-name nnimap-directory))) + (file (nnheader-translate-file-chars + (concat nnimap-nov-file-name + (if (equal server "") + "unnamed" + server) "." group nnimap-nov-file-name-suffix) t))) + (if (or nnmail-use-long-file-names + (file-exists-p (concat dir file))) + (concat dir file) + (concat dir (mm-encode-coding-string + (nnheader-replace-chars-in-string file ?. ?/) + nnmail-pathname-coding-system))))) + +(defun nnimap-retrieve-headers-from-file (group server) + (with-current-buffer nntp-server-buffer + (let ((nov (nnimap-group-overview-filename group server))) + (when (file-exists-p nov) + (mm-insert-file-contents nov) + (set-buffer-modified-p nil) + (let ((min (ignore-errors (goto-char (point-min)) + (read (current-buffer)))) + (max (ignore-errors (goto-char (point-max)) + (forward-line -1) + (read (current-buffer))))) + (if (and (numberp min) (numberp max)) + (cons min max) + ;; junk, remove it, it's saved later + (erase-buffer) + nil)))))) + +(defun nnimap-retrieve-headers-from-server (articles group server) + (with-current-buffer nnimap-server-buffer + (let ((imap-fetch-data-hook '(nnimap-retrieve-headers-progress)) + (nnimap-length (gnus-range-length articles)) + (nnimap-counter 0)) + (imap-fetch (imap-range-to-message-set articles) + (concat "(UID RFC822.SIZE BODY " + (let ((headers + (append '(Subject From Date Message-Id + References In-Reply-To Xref) + (copy-sequence + nnmail-extra-headers)))) + (if (imap-capability 'IMAP4rev1) + (format "BODY.PEEK[HEADER.FIELDS %s])" headers) + (format "RFC822.HEADER.LINES %s)" headers))))) + (and (numberp nnmail-large-newsgroup) + (> nnimap-length nnmail-large-newsgroup) + (nnheader-message 6 "nnimap: Retrieving headers...done"))))) + +(defun nnimap-use-nov-p (group server) + (or gnus-nov-is-evil nnimap-nov-is-evil + (unless (and (gnus-make-directory + (file-name-directory + (nnimap-group-overview-filename group server))) + (file-writable-p + (nnimap-group-overview-filename group server))) + (message "nnimap: Nov cache not writable, %s" + (nnimap-group-overview-filename group server))))) + +(deffoo nnimap-retrieve-headers (articles &optional group server fetch-old) + (when (nnimap-possibly-change-group group server) + (with-current-buffer nntp-server-buffer + (erase-buffer) + (if (nnimap-use-nov-p group server) + (nnimap-retrieve-headers-from-server + (gnus-compress-sequence articles) group server) + (let (uids cached low high) + (when (setq uids (nnimap-retrieve-which-headers articles fetch-old) + low (car uids) + high (car (last uids))) + (if (setq cached (nnimap-retrieve-headers-from-file group server)) + (progn + ;; fetch articles with uids before cache block + (when (< low (car cached)) + (goto-char (point-min)) + (nnimap-retrieve-headers-from-server + (cons low (1- (car cached))) group server)) + ;; fetch articles with uids after cache block + (when (> high (cdr cached)) + (goto-char (point-max)) + (nnimap-retrieve-headers-from-server + (cons (1+ (cdr cached)) high) group server)) + (when nnimap-prune-cache + ;; remove nov's for articles which has expired on server + (goto-char (point-min)) + (dolist (uid (gnus-set-difference articles uids)) + (when (re-search-forward (format "^%d\t" uid) nil t) + (gnus-delete-line))))) + ;; nothing cached, fetch whole range from server + (nnimap-retrieve-headers-from-server + (cons low high) group server)) + (when (buffer-modified-p) + (nnmail-write-region + 1 (point-max) (nnimap-group-overview-filename group server) + nil 'nomesg)) + (nnheader-nov-delete-outside-range low high)))) + 'nov))) + +(defun nnimap-open-connection (server) + (if (not (imap-open nnimap-address nnimap-server-port nnimap-stream + nnimap-authenticator nnimap-server-buffer)) + (nnheader-report 'nnimap "Can't open connection to server %s" server) + (unless (or (imap-capability 'IMAP4 nnimap-server-buffer) + (imap-capability 'IMAP4rev1 nnimap-server-buffer)) + (imap-close nnimap-server-buffer) + (nnheader-report 'nnimap "Server %s is not IMAP4 compliant" server)) + (let* ((list (gnus-parse-netrc nnimap-authinfo-file)) + (port (if nnimap-server-port + (int-to-string nnimap-server-port) + "imap")) + (alist (gnus-netrc-machine list (or nnimap-server-address + nnimap-address server) + port "imap")) + (user (gnus-netrc-get alist "login")) + (passwd (gnus-netrc-get alist "password"))) + (if (imap-authenticate user passwd nnimap-server-buffer) + (prog1 + (push (list server nnimap-server-buffer) + nnimap-server-buffer-alist) + (nnimap-possibly-change-server server)) + (imap-close nnimap-server-buffer) + (kill-buffer nnimap-server-buffer) + (nnheader-report 'nnimap "Could not authenticate to %s" server))))) + +(deffoo nnimap-open-server (server &optional defs) + (nnheader-init-server-buffer) + (if (nnimap-server-opened server) + t + (unless (assq 'nnimap-server-buffer defs) + (push (list 'nnimap-server-buffer (concat " *nnimap* " server)) defs)) + ;; translate `nnimap-server-address' to `nnimap-address' in defs + ;; for people that configured nnimap with a very old version + (unless (assq 'nnimap-address defs) + (if (assq 'nnimap-server-address defs) + (push (list 'nnimap-address + (cadr (assq 'nnimap-server-address defs))) defs) + (push (list 'nnimap-address server) defs))) + (nnoo-change-server 'nnimap server defs) + (with-current-buffer (get-buffer-create nnimap-server-buffer) + (nnoo-change-server 'nnimap server defs)) + (or (and nnimap-server-buffer + (imap-opened nnimap-server-buffer)) + (nnimap-open-connection server)))) + +(deffoo nnimap-server-opened (&optional server) + "Whether SERVER is opened. +If SERVER is the current virtual server, and the connection to the +physical server is alive, this function return a non-nil value. If +SERVER is nil, it is treated as the current server." + ;; clean up autologouts?? + (and (or server nnimap-current-server) + (nnoo-server-opened 'nnimap (or server nnimap-current-server)) + (imap-opened (nnimap-get-server-buffer server)))) + +(deffoo nnimap-close-server (&optional server) + "Close connection to server and free all resources connected to it. +Return nil if the server couldn't be closed for some reason." + (let ((server (or server nnimap-current-server))) + (when (or (nnimap-server-opened server) + (imap-opened (nnimap-get-server-buffer server))) + (imap-close (nnimap-get-server-buffer server)) + (kill-buffer (nnimap-get-server-buffer server)) + (setq nnimap-server-buffer nil + nnimap-current-server nil + nnimap-server-buffer-alist + (delq server nnimap-server-buffer-alist))) + (nnoo-close-server 'nnimap server))) + +(deffoo nnimap-request-close () + "Close connection to all servers and free all resources that the backend have reserved. +All buffers that have been created by that +backend should be killed. (Not the nntp-server-buffer, though.) This +function is generally only called when Gnus is shutting down." + (mapcar (lambda (server) (nnimap-close-server (car server))) + nnimap-server-buffer-alist) + (setq nnimap-server-buffer-alist nil)) + +(deffoo nnimap-status-message (&optional server) + "This function returns the last error message from server." + (when (nnimap-possibly-change-server server) + (nnoo-status-message 'nnimap server))) + +(defun nnimap-demule (string) + (funcall (if (and (fboundp 'string-as-multibyte) + (subrp (symbol-function 'string-as-multibyte))) + 'string-as-multibyte + 'identity) + (or string ""))) + +(defun nnimap-callback () + (remove-hook 'imap-fetch-data-hook 'nnimap-callback) + (with-current-buffer nnimap-callback-buffer + (insert + (with-current-buffer nnimap-server-buffer + (nnimap-demule + (if (imap-capability 'IMAP4rev1) + ;; xxx don't just use car? alist doesn't contain + ;; anything else now, but it might... + (nth 2 (car (imap-message-get (imap-current-message) 'BODYDETAIL))) + (imap-message-get (imap-current-message) 'RFC822))))) + (nnheader-ms-strip-cr) + (funcall nnimap-callback-callback-function t))) + +(defun nnimap-request-article-part (article part prop &optional + group server to-buffer detail) + (when (nnimap-possibly-change-group group server) + (let ((article (if (stringp article) + (car-safe (imap-search + (format "HEADER Message-Id %s" article) + nnimap-server-buffer)) + article))) + (when article + (gnus-message 10 "nnimap: Fetching (part of) article %d..." article) + (if (not nnheader-callback-function) + (with-current-buffer (or to-buffer nntp-server-buffer) + (erase-buffer) + (let ((data (imap-fetch article part prop nil + nnimap-server-buffer))) + (insert (nnimap-demule (if detail + (nth 2 (car data)) + data)))) + (nnheader-ms-strip-cr) + (gnus-message 10 "nnimap: Fetching (part of) article %d...done" + article) + (if (bobp) + (nnheader-report 'nnimap "No such article: %s" + (imap-error-text nnimap-server-buffer)) + (cons group article))) + (add-hook 'imap-fetch-data-hook 'nnimap-callback) + (setq nnimap-callback-callback-function nnheader-callback-function + nnimap-callback-buffer nntp-server-buffer) + (imap-fetch-asynch article part nil nnimap-server-buffer) + (cons group article)))))) + +(deffoo nnimap-asynchronous-p () + t) + +(deffoo nnimap-request-article (article &optional group server to-buffer) + (if (imap-capability 'IMAP4rev1 nnimap-server-buffer) + (nnimap-request-article-part + article "BODY.PEEK[]" 'BODYDETAIL group server to-buffer 'detail) + (nnimap-request-article-part + article "RFC822.PEEK" 'RFC822 group server to-buffer))) + +(deffoo nnimap-request-head (article &optional group server to-buffer) + (if (imap-capability 'IMAP4rev1 nnimap-server-buffer) + (nnimap-request-article-part + article "BODY.PEEK[HEADER]" 'BODYDETAIL group server to-buffer 'detail) + (nnimap-request-article-part + article "RFC822.HEADER" 'RFC822.HEADER group server to-buffer))) + +(deffoo nnimap-request-body (article &optional group server to-buffer) + (if (imap-capability 'IMAP4rev1 nnimap-server-buffer) + (nnimap-request-article-part + article "BODY.PEEK[TEXT]" 'BODYDETAIL group server to-buffer 'detail) + (nnimap-request-article-part + article "RFC822.TEXT.PEEK" 'RFC822.TEXT group server to-buffer))) + +(deffoo nnimap-request-group (group &optional server fast) + (nnimap-request-update-info-internal + group + (gnus-get-info (gnus-group-prefixed-name + group (gnus-server-to-method (format "nnimap:%s" server)))) + server) + (when (nnimap-possibly-change-group group server) + (nnimap-before-find-minmax-bugworkaround) + (let (info) + (cond (fast group) + ((null (setq info (nnimap-find-minmax-uid group t))) + (nnheader-report 'nnimap "Could not get active info for %s" + group)) + (t + (nnheader-insert "211 %d %d %d %s\n" (or (nth 0 info) 0) + (max 1 (or (nth 1 info) 1)) + (or (nth 2 info) 0) group) + (nnheader-report 'nnimap "Group %s selected" group) + t))))) + +(defun nnimap-close-group (group &optional server) + (with-current-buffer nnimap-server-buffer + (when (and (imap-opened) + (nnimap-possibly-change-group group server)) + (case nnimap-expunge-on-close + ('always (imap-mailbox-expunge) + (imap-mailbox-close)) + ('ask (if (and (imap-search "DELETED") + (gnus-y-or-n-p (format + "Expunge articles in group `%s'? " + imap-current-mailbox))) + (progn (imap-mailbox-expunge) + (imap-mailbox-close)) + (imap-mailbox-unselect))) + (t (imap-mailbox-unselect))) + (not imap-current-mailbox)))) + +(defun nnimap-pattern-to-list-arguments (pattern) + (mapcar (lambda (p) + (cons (car-safe p) (or (cdr-safe p) p))) + (if (and (listp pattern) + (listp (cdr pattern))) + pattern + (list pattern)))) + +(deffoo nnimap-request-list (&optional server) + (when (nnimap-possibly-change-server server) + (with-current-buffer nntp-server-buffer + (erase-buffer)) + (gnus-message 5 "nnimap: Generating active list%s..." + (if (> (length server) 0) (concat " for " server) "")) + (nnimap-before-find-minmax-bugworkaround) + (with-current-buffer nnimap-server-buffer + (dolist (pattern (nnimap-pattern-to-list-arguments nnimap-list-pattern)) + (dolist (mbx (funcall nnimap-request-list-method + (cdr pattern) (car pattern))) + (or (member "\\NoSelect" (imap-mailbox-get 'list-flags mbx)) + (let ((info (nnimap-find-minmax-uid mbx 'examine))) + (when info + (with-current-buffer nntp-server-buffer + (insert (format "\"%s\" %d %d y\n" + mbx (or (nth 2 info) 0) + (max 1 (or (nth 1 info) 1))))))))))) + (gnus-message 5 "nnimap: Generating active list%s...done" + (if (> (length server) 0) (concat " for " server) "")) + t)) + +(deffoo nnimap-request-post (&optional server) + (let ((success t)) + (dolist (mbx (message-unquote-tokens + (message-tokenize-header + (message-fetch-field "Newsgroups") ", ")) success) + (let ((to-newsgroup (gnus-group-prefixed-name mbx gnus-command-method))) + (or (gnus-active to-newsgroup) + (gnus-activate-group to-newsgroup) + (if (gnus-y-or-n-p (format "No such group: %s. Create it? " + to-newsgroup)) + (or (and (gnus-request-create-group + to-newsgroup gnus-command-method) + (gnus-activate-group to-newsgroup nil nil + gnus-command-method)) + (error "Couldn't create group %s" to-newsgroup))) + (error "No such group: %s" to-newsgroup)) + (unless (nnimap-request-accept-article mbx (nth 1 gnus-command-method)) + (setq success nil)))))) + +;; Optional backend functions + +(deffoo nnimap-retrieve-groups (groups &optional server) + (when (nnimap-possibly-change-server server) + (gnus-message 5 "nnimap: Checking mailboxes...") + (with-current-buffer nntp-server-buffer + (erase-buffer) + (nnimap-before-find-minmax-bugworkaround) + (dolist (group groups) + (gnus-message 7 "nnimap: Checking mailbox %s" group) + (or (member "\\NoSelect" + (imap-mailbox-get 'list-flags group nnimap-server-buffer)) + (let ((info (nnimap-find-minmax-uid group 'examine))) + (insert (format "\"%s\" %d %d y\n" group + (or (nth 2 info) 0) + (max 1 (or (nth 1 info) 1)))))))) + (gnus-message 5 "nnimap: Checking mailboxes...done") + 'active)) + +(deffoo nnimap-request-update-info-internal (group info &optional server) + (when (nnimap-possibly-change-group group server) + (when info;; xxx what does this mean? should we create a info? + (with-current-buffer nnimap-server-buffer + (gnus-message 5 "nnimap: Updating info for %s..." + (gnus-info-group info)) + + (when (nnimap-mark-permanent-p 'read) + (let (seen unseen) + ;; read info could contain articles marked unread by other + ;; imap clients! we correct this + (setq seen (gnus-uncompress-range (gnus-info-read info)) + unseen (imap-search "UNSEEN UNDELETED") + seen (gnus-set-difference seen unseen) + ;; seen might lack articles marked as read by other + ;; imap clients! we correct this + seen (append seen (imap-search "SEEN")) + ;; remove dupes + seen (sort seen '<) + seen (gnus-compress-sequence seen t) + ;; we can't return '(1) since this isn't a "list of ranges", + ;; and we can't return '((1)) since g-list-of-unread-articles + ;; is buggy so we return '((1 . 1)). + seen (if (and (integerp (car seen)) + (null (cdr seen))) + (list (cons (car seen) (car seen))) + seen)) + (gnus-info-set-read info seen))) + + (mapcar (lambda (pred) + (when (and (nnimap-mark-permanent-p (cdr pred)) + (member (nnimap-mark-to-flag (cdr pred)) + (imap-mailbox-get 'flags))) + (gnus-info-set-marks + info + (nnimap-update-alist-soft + (cdr pred) + (gnus-compress-sequence + (imap-search (nnimap-mark-to-predicate (cdr pred)))) + (gnus-info-marks info)) + t))) + gnus-article-mark-lists) + + ;; nnimap mark dormant article as ticked too (for other clients) + ;; so we remove that mark for gnus since we support dormant + (gnus-info-set-marks + info + (nnimap-update-alist-soft + 'tick + (gnus-remove-from-range + (cdr-safe (assoc 'tick (gnus-info-marks info))) + (cdr-safe (assoc 'dormant (gnus-info-marks info)))) + (gnus-info-marks info)) + t) + + (gnus-message 5 "nnimap: Updating info for %s...done" + (gnus-info-group info)) + + info)))) + +(deffoo nnimap-request-type (group &optional article) + (if (and nnimap-news-groups (string-match nnimap-news-groups group)) + 'news + 'mail)) + +(deffoo nnimap-request-set-mark (group actions &optional server) + (when (nnimap-possibly-change-group group server) + (with-current-buffer nnimap-server-buffer + (let (action) + (gnus-message 7 "nnimap: Setting marks in %s..." group) + (while (setq action (pop actions)) + (let ((range (nth 0 action)) + (what (nth 1 action)) + (cmdmarks (nth 2 action)) + marks) + ;; cache flags are pointless on the server + (setq cmdmarks (delq 'cache cmdmarks)) + ;; flag dormant articles as ticked + (if (memq 'dormant cmdmarks) + (setq cmdmarks (cons 'tick cmdmarks))) + ;; remove stuff we are forbidden to store + (mapcar (lambda (mark) + (if (imap-message-flag-permanent-p + (nnimap-mark-to-flag mark)) + (setq marks (cons mark marks)))) + cmdmarks) + (when (and range marks) + (cond ((eq what 'del) + (imap-message-flags-del + (imap-range-to-message-set range) + (nnimap-mark-to-flag marks nil t))) + ((eq what 'add) + (imap-message-flags-add + (imap-range-to-message-set range) + (nnimap-mark-to-flag marks nil t))) + ((eq what 'set) + (imap-message-flags-set + (imap-range-to-message-set range) + (nnimap-mark-to-flag marks nil t))))))) + (gnus-message 7 "nnimap: Setting marks in %s...done" group)))) + nil) + +(defun nnimap-split-fancy () + "Like nnmail-split-fancy, but uses nnimap-split-fancy." + (let ((nnmail-split-fancy nnimap-split-fancy)) + (nnmail-split-fancy))) + +(defun nnimap-split-to-groups (rules) + ;; tries to match all rules in nnimap-split-rule against content of + ;; nntp-server-buffer, returns a list of groups that matched. + (with-current-buffer nntp-server-buffer + ;; Fold continuation lines. + (goto-char (point-min)) + (while (re-search-forward "\\(\r?\n[ \t]+\\)+" nil t) + (replace-match " " t t)) + (if (functionp rules) + (funcall rules) + (let (to-groups regrepp) + (catch 'split-done + (dolist (rule rules to-groups) + (let ((group (car rule)) + (regexp (cadr rule))) + (goto-char (point-min)) + (when (and (if (stringp regexp) + (progn + (setq regrepp (string-match "\\\\[0-9&]" group)) + (re-search-forward regexp nil t)) + (funcall regexp group)) + ;; Don't enter the article into the same group twice. + (not (assoc group to-groups))) + (push (if regrepp + (nnmail-expand-newtext group) + group) + to-groups) + (or nnimap-split-crosspost + (throw 'split-done to-groups)))))))))) + +(defun nnimap-assoc-match (key alist) + (let (element) + (while (and alist (not element)) + (if (string-match (car (car alist)) key) + (setq element (car alist))) + (setq alist (cdr alist))) + element)) + +(defun nnimap-split-find-rule (server inbox) + (if (and (listp nnimap-split-rule) (listp (car nnimap-split-rule)) + (list (cdar nnimap-split-rule)) (listp (cadar nnimap-split-rule))) + ;; extended format + (cadr (nnimap-assoc-match inbox (cdr (nnimap-assoc-match + server nnimap-split-rule)))) + nnimap-split-rule)) + +(defun nnimap-split-find-inbox (server) + (if (listp nnimap-split-inbox) + nnimap-split-inbox + (list nnimap-split-inbox))) + +(defun nnimap-split-articles (&optional group server) + (when (nnimap-possibly-change-server server) + (with-current-buffer nnimap-server-buffer + (let (rule inbox removeorig (inboxes (nnimap-split-find-inbox server))) + ;; iterate over inboxes + (while (and (setq inbox (pop inboxes)) + (nnimap-possibly-change-group inbox));; SELECT + ;; find split rule for this server / inbox + (when (setq rule (nnimap-split-find-rule server inbox)) + ;; iterate over articles + (dolist (article (imap-search nnimap-split-predicate)) + (when (nnimap-request-head article) + ;; copy article to right group(s) + (setq removeorig nil) + (dolist (to-group (nnimap-split-to-groups rule)) + (if (imap-message-copy (number-to-string article) + to-group nil 'nocopyuid) + (progn + (message "IMAP split moved %s:%s:%d to %s" server inbox + article to-group) + (setq removeorig t) + ;; Add the group-art list to the history list. + (push (list (cons to-group 0)) nnmail-split-history)) + (message "IMAP split failed to move %s:%s:%d to %s" server + inbox article to-group))) + ;; remove article if it was successfully copied somewhere + (and removeorig + (imap-message-flags-add (format "%d" article) + "\\Seen \\Deleted"))))) + (when (imap-mailbox-select inbox);; just in case + ;; todo: UID EXPUNGE (if available) to remove splitted articles + (imap-mailbox-expunge) + (imap-mailbox-close))) + t)))) + +(deffoo nnimap-request-scan (&optional group server) + (nnimap-split-articles group server)) + +(deffoo nnimap-request-newgroups (date &optional server) + (when (nnimap-possibly-change-server server) + (with-current-buffer nntp-server-buffer + (gnus-message 5 "nnimap: Listing subscribed mailboxes%s%s..." + (if (> (length server) 0) " on " "") server) + (erase-buffer) + (nnimap-before-find-minmax-bugworkaround) + (dolist (pattern (nnimap-pattern-to-list-arguments + nnimap-list-pattern)) + (dolist (mbx (imap-mailbox-lsub "*" (car pattern) nil + nnimap-server-buffer)) + (or (catch 'found + (dolist (mailbox (imap-mailbox-get 'list-flags mbx + nnimap-server-buffer)) + (if (string= (downcase mailbox) "\\noselect") + (throw 'found t))) + nil) + (let ((info (nnimap-find-minmax-uid mbx 'examine))) + (when info + (insert (format "\"%s\" %d %d y\n" + mbx (or (nth 2 info) 0) + (max 1 (or (nth 1 info) 1))))))))) + (gnus-message 5 "nnimap: Listing subscribed mailboxes%s%s...done" + (if (> (length server) 0) " on " "") server)) + t)) + +(deffoo nnimap-request-create-group (group &optional server args) + (when (nnimap-possibly-change-server server) + (or (imap-mailbox-status group 'uidvalidity nnimap-server-buffer) + (imap-mailbox-create group nnimap-server-buffer)))) + +(defun nnimap-time-substract (time1 time2) + "Return TIME for TIME1 - TIME2." + (let* ((ms (- (car time1) (car time2))) + (ls (- (nth 1 time1) (nth 1 time2)))) + (if (< ls 0) + (list (- ms 1) (+ (expt 2 16) ls)) + (list ms ls)))) + +(defun nnimap-date-days-ago (daysago) + "Return date, in format \"3-Aug-1998\", for DAYSAGO days ago." + (let ((date (format-time-string "%d-%b-%Y" + (nnimap-time-substract + (current-time) + (days-to-time daysago))))) + (if (eq ?0 (string-to-char date)) + (substring date 1) + date))) + +(defun nnimap-request-expire-articles-progress () + (gnus-message 5 "nnimap: Marking article %d for deletion..." + imap-current-message)) + +;; Notice that we don't actually delete anything, we just mark them deleted. +(deffoo nnimap-request-expire-articles (articles group &optional server force) + (let ((artseq (gnus-compress-sequence articles))) + (when (and artseq (nnimap-possibly-change-group group server)) + (with-current-buffer nnimap-server-buffer + (if force + (and (imap-message-flags-add + (imap-range-to-message-set artseq) "\\Deleted") + (setq articles nil)) + (let ((days (or (and nnmail-expiry-wait-function + (funcall nnmail-expiry-wait-function group)) + nnmail-expiry-wait))) + (cond ((eq days 'immediate) + (and (imap-message-flags-add + (imap-range-to-message-set artseq) "\\Deleted") + (setq articles nil))) + ((numberp days) + (let ((oldarts (imap-search + (format "UID %s NOT SINCE %s" + (imap-range-to-message-set artseq) + (nnimap-date-days-ago days)))) + (imap-fetch-data-hook + '(nnimap-request-expire-articles-progress))) + (and oldarts + (imap-message-flags-add + (imap-range-to-message-set + (gnus-compress-sequence oldarts)) + "\\Deleted") + (setq articles (gnus-set-difference + articles oldarts))))))))))) + ;; return articles not deleted + articles) + +(deffoo nnimap-request-move-article (article group server + accept-form &optional last) + (when (nnimap-possibly-change-server server) + (save-excursion + (let ((buf (get-buffer-create " *nnimap move*")) + (nnimap-current-move-article article) + (nnimap-current-move-group group) + (nnimap-current-move-server nnimap-current-server) + result) + (and (nnimap-request-article article group server) + (save-excursion + (set-buffer buf) + (buffer-disable-undo (current-buffer)) + (insert-buffer-substring nntp-server-buffer) + (setq result (eval accept-form)) + (kill-buffer buf) + result) + (nnimap-request-expire-articles (list article) group server t)) + result)))) + +(deffoo nnimap-request-accept-article (group &optional server last) + (when (nnimap-possibly-change-server server) + (let (uid) + (if (setq uid + (if (string= nnimap-current-server nnimap-current-move-server) + ;; moving article within same server, speed it up... + (and (nnimap-possibly-change-group + nnimap-current-move-group) + (imap-message-copy (number-to-string + nnimap-current-move-article) + group 'dontcreate nil + nnimap-server-buffer)) + ;; turn into rfc822 format (\r\n eol's) + (with-current-buffer (current-buffer) + (goto-char (point-min)) + (while (search-forward "\n" nil t) + (replace-match "\r\n"))) + ;; this 'or' is for Cyrus server bug + (or (null (imap-current-mailbox nnimap-server-buffer)) + (imap-mailbox-unselect nnimap-server-buffer)) + (imap-message-append group (current-buffer) nil nil + nnimap-server-buffer))) + (cons group (nth 1 uid)) + (nnheader-report 'nnimap (imap-error-text nnimap-server-buffer)))))) + +(deffoo nnimap-request-delete-group (group force &optional server) + (when (nnimap-possibly-change-server server) + (with-current-buffer nnimap-server-buffer + (if force + (or (null (imap-mailbox-status group 'uidvalidity)) + (imap-mailbox-delete group)) + ;; UNSUBSCRIBE? + t)))) + +(deffoo nnimap-request-rename-group (group new-name &optional server) + (when (nnimap-possibly-change-server server) + (imap-mailbox-rename group new-name nnimap-server-buffer))) + +(defun nnimap-expunge (mailbox server) + (when (nnimap-possibly-change-group mailbox server) + (imap-mailbox-expunge nnimap-server-buffer))) + +(defun nnimap-acl-get (mailbox server) + (when (nnimap-possibly-change-server server) + (imap-mailbox-acl-get mailbox nnimap-server-buffer))) + +(defun nnimap-acl-edit (mailbox method old-acls new-acls) + (when (nnimap-possibly-change-server (cadr method)) + (unless (imap-capability 'ACL nnimap-server-buffer) + (error "Your server does not support ACL editing")) + (with-current-buffer nnimap-server-buffer + ;; delete all removed identifiers + (mapcar (lambda (old-acl) + (unless (assoc (car old-acl) new-acls) + (or (imap-mailbox-acl-delete (car old-acl) mailbox) + (error "Can't delete ACL for %s" (car old-acl))))) + old-acls) + ;; set all changed acl's + (mapcar (lambda (new-acl) + (let ((new-rights (cdr new-acl)) + (old-rights (cdr (assoc (car new-acl) old-acls)))) + (unless (and old-rights new-rights + (string= old-rights new-rights)) + (or (imap-mailbox-acl-set (car new-acl) new-rights mailbox) + (error "Can't set ACL for %s to %s" (car new-acl) + new-rights))))) + new-acls) + t))) + + +;;; Internal functions + +;; +;; This is confusing. +;; +;; mark => read, tick, draft, reply etc +;; flag => "\\Seen", "\\Flagged", "\\Draft", "gnus-expire" etc +;; predicate => "SEEN", "FLAGGED", "DRAFT", "KEYWORD gnus-expire" etc +;; +;; Mark should not really contain 'read since it's not a "mark" in the Gnus +;; world, but we cheat. Mark == gnus-article-mark-lists + '(read . read). +;; + +(defconst nnimap-mark-to-predicate-alist + (mapcar + (lambda (pair) ; cdr is the mark + (or (assoc (cdr pair) + '((read . "SEEN") + (tick . "FLAGGED") + (draft . "DRAFT") + (reply . "ANSWERED"))) + (cons (cdr pair) + (format "KEYWORD gnus-%s" (symbol-name (cdr pair)))))) + (cons '(read . read) gnus-article-mark-lists))) + +(defun nnimap-mark-to-predicate (pred) + "Convert a Gnus mark (a symbol such as read, tick, expire) to a IMAP predicate. +This is a string such as \"SEEN\", \"FLAGGED\", \"KEYWORD gnus-expire\", +to be used within a IMAP SEARCH query." + (cdr (assq pred nnimap-mark-to-predicate-alist))) + +(defconst nnimap-mark-to-flag-alist + (mapcar + (lambda (pair) + (or (assoc (cdr pair) + '((read . "\\Seen") + (tick . "\\Flagged") + (draft . "\\Draft") + (reply . "\\Answered"))) + (cons (cdr pair) + (format "gnus-%s" (symbol-name (cdr pair)))))) + (cons '(read . read) gnus-article-mark-lists))) + +(defun nnimap-mark-to-flag-1 (preds) + (if (and (not (null preds)) (listp preds)) + (cons (nnimap-mark-to-flag (car preds)) + (nnimap-mark-to-flag (cdr preds))) + (cdr (assoc preds nnimap-mark-to-flag-alist)))) + +(defun nnimap-mark-to-flag (preds &optional always-list make-string) + "Convert a Gnus mark (a symbol such as read, tick, expire) to a IMAP flag. +This is a string such as \"\\Seen\", \"\\Flagged\", \"gnus-expire\", to +be used in a STORE FLAGS command." + (let ((result (nnimap-mark-to-flag-1 preds))) + (setq result (if (and (or make-string always-list) + (not (listp result))) + (list result) + result)) + (if make-string + (mapconcat (lambda (flag) + (if (listp flag) + (mapconcat 'identity flag " ") + flag)) + result " ") + result))) + +(defun nnimap-mark-permanent-p (mark &optional group) + "Return t iff MARK can be permanently (between IMAP sessions) saved on articles, in GROUP." + (imap-message-flag-permanent-p (nnimap-mark-to-flag mark))) + +(defun nnimap-remassoc (key alist) + "Delete by side effect any elements of LIST whose car is `equal' to KEY. +The modified LIST is returned. If the first member +of LIST has a car that is `equal' to KEY, there is no way to remove it +by side effect; therefore, write `(setq foo (remassoc key foo))' to be +sure of changing the value of `foo'." + (when alist + (if (equal key (caar alist)) + (cdr alist) + (setcdr alist (nnimap-remassoc key (cdr alist))) + alist))) + +(defun nnimap-update-alist-soft (key value alist) + (if value + (cons (cons key value) (nnimap-remassoc key alist)) + (nnimap-remassoc key alist))) + +(when nnimap-debug + (require 'trace) + (buffer-disable-undo (get-buffer-create nnimap-debug)) + (mapcar (lambda (f) (trace-function-background f nnimap-debug)) + '( + nnimap-possibly-change-server + nnimap-verify-uidvalidity + nnimap-find-minmax-uid + nnimap-before-find-minmax-bugworkaround + nnimap-possibly-change-group + ;;nnimap-replace-whitespace + nnimap-retrieve-headers-progress + nnimap-retrieve-which-headers + nnimap-group-overview-filename + nnimap-retrieve-headers-from-file + nnimap-retrieve-headers-from-server + nnimap-retrieve-headers + nnimap-open-connection + nnimap-open-server + nnimap-server-opened + nnimap-close-server + nnimap-request-close + nnimap-status-message + ;;nnimap-demule + nnimap-request-article-part + nnimap-request-article + nnimap-request-head + nnimap-request-body + nnimap-request-group + nnimap-close-group + nnimap-pattern-to-list-arguments + nnimap-request-list + nnimap-request-post + nnimap-retrieve-groups + nnimap-request-update-info-internal + nnimap-request-type + nnimap-request-set-mark + nnimap-split-to-groups + nnimap-split-find-rule + nnimap-split-find-inbox + nnimap-split-articles + nnimap-request-scan + nnimap-request-newgroups + nnimap-request-create-group + nnimap-time-substract + nnimap-date-days-ago + nnimap-request-expire-articles-progress + nnimap-request-expire-articles + nnimap-request-move-article + nnimap-request-accept-article + nnimap-request-delete-group + nnimap-request-rename-group + gnus-group-nnimap-expunge + gnus-group-nnimap-edit-acl + gnus-group-nnimap-edit-acl-done + nnimap-group-mode-hook + nnimap-mark-to-predicate + nnimap-mark-to-flag-1 + nnimap-mark-to-flag + nnimap-mark-permanent-p + nnimap-remassoc + nnimap-update-alist-soft + ))) + +(provide 'nnimap) + +;;; nnimap.el ends here diff --git a/lisp/gnus/nnslashdot.el b/lisp/gnus/nnslashdot.el new file mode 100644 index 00000000000..37629277350 --- /dev/null +++ b/lisp/gnus/nnslashdot.el @@ -0,0 +1,564 @@ +;;; nnslashdot.el --- interfacing with Slashdot +;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; Keywords: news + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Note: You need to have `url' and `w3' installed for this +;; backend to work. + +;;; Code: + +(eval-when-compile (require 'cl)) + +(require 'nnoo) +(require 'message) +(require 'gnus-util) +(require 'gnus) +(require 'nnmail) +(require 'mm-util) +(eval-when-compile + (ignore-errors + (require 'nnweb))) +;; Report failure to find w3 at load time if appropriate. +(eval '(require 'nnweb)) + +(nnoo-declare nnslashdot) + +(defvoo nnslashdot-directory (nnheader-concat gnus-directory "slashdot/") + "Where nnslashdot will save its files.") + +(defvoo nnslashdot-active-url "http://slashdot.org/search.pl?section=&min=%d" + "Where nnslashdot will fetch the active file from.") + +(defvoo nnslashdot-comments-url "http://slashdot.org/comments.pl?sid=%s&threshold=%d&commentsort=%d&mode=flat&startat=%d" + "Where nnslashdot will fetch comments from.") + +(defvoo nnslashdot-article-url + "http://slashdot.org/article.pl?sid=%s&mode=nocomment" + "Where nnslashdot will fetch the article from.") + +(defvoo nnslashdot-threshold -1 + "The article threshold.") + +(defvoo nnslashdot-threaded t + "Whether the nnslashdot groups should be threaded or not.") + +(defvoo nnslashdot-group-number 0 + "The number of non-fresh groups to keep updated.") + +(defvoo nnslashdot-login-name "" + "The login name to use when posting.") + +(defvoo nnslashdot-password "" + "The password to use when posting.") + +;;; Internal variables + +(defvar nnslashdot-groups nil) +(defvar nnslashdot-buffer nil) +(defvar nnslashdot-headers nil) + +;;; Interface functions + +(nnoo-define-basics nnslashdot) + +(deffoo nnslashdot-retrieve-headers (articles &optional group server fetch-old) + (nnslashdot-possibly-change-server group server) + (condition-case why + (unless gnus-nov-is-evil + (if nnslashdot-threaded + (nnslashdot-threaded-retrieve-headers articles group) + (nnslashdot-sane-retrieve-headers articles group))) + (search-failed (nnslashdot-lose why)))) + +(deffoo nnslashdot-threaded-retrieve-headers (articles group) + (let ((last (car (last articles))) + (did nil) + (start 1) + (sid (caddr (assoc group nnslashdot-groups))) + (first-comments t) + (startats '(1)) + headers article subject score from date lines parent point s) + (save-excursion + (set-buffer nnslashdot-buffer) + (let ((case-fold-search t)) + (erase-buffer) + (when (= start 1) + (nnweb-insert (format nnslashdot-article-url + (nnslashdot-sid-strip sid)) t) + (goto-char (point-min)) + (search-forward "Posted by ") + (when (looking-at "]+>\\([^<]+\\)") + (setq from (nnweb-decode-entities-string (match-string 1)))) + (search-forward " on ") + (setq date (nnslashdot-date-to-date + (buffer-substring (point) (1- (search-forward "<"))))) + (setq lines (/ (- (point) + (progn (forward-line 1) (point))) + 60)) + (push + (cons + 1 + (make-full-mail-header + 1 group from date + (concat "<" (nnslashdot-sid-strip sid) "%1@slashdot>") + "" 0 lines nil nil)) + headers)) + (while (and (setq start (pop startats)) + (< start last)) + (setq point (goto-char (point-max))) + (nnweb-insert + (format nnslashdot-comments-url + (nnslashdot-sid-strip sid) + nnslashdot-threshold 0 start) + t) + (when first-comments + (setq first-comments nil) + (goto-char (point-max)) + (while (re-search-backward "startat=\\([0-9]+\\)" nil t) + (setq s (string-to-number (match-string 1))) + (unless (memq s startats) + (push s startats))) + (setq startats (sort startats '<))) + (goto-char point) + (while (re-search-forward + "<\\(b\\|H4\\)>\\([^<]+\\).*score:\\([^)]+\\))" + nil t) + (setq article (string-to-number (match-string 1)) + subject (match-string 3) + score (match-string 5)) + (when (string-match "^Re: *" subject) + (setq subject (concat "Re: " (substring subject (match-end 0))))) + (setq subject (nnweb-decode-entities-string subject)) + (forward-line 1) + (if (looking-at + "by ]+>\\([^<]+\\)[ \t\n]*.*(\\([^)]+\\))") + (progn + (goto-char (- (match-end 0) 5)) + (setq from (concat + (nnweb-decode-entities-string (match-string 1)) + " <" (match-string 2) ">"))) + (setq from "") + (when (looking-at "by \\(.+\\) on ") + (goto-char (- (match-end 0) 5)) + (setq from (nnweb-decode-entities-string (match-string 1))))) + (search-forward " on ") + (setq date + (nnslashdot-date-to-date + (buffer-substring (point) (progn (end-of-line) (point))))) + (setq lines (/ (abs (- (search-forward ""))) + 70)) + (forward-line 4) + (setq parent + (if (looking-at ".*cid=\\([0-9]+\\)") + (match-string 1) + nil)) + (setq did t) + (push + (cons + (1+ article) + (make-full-mail-header + (1+ article) + (concat subject " (" score ")") + from date + (concat "<" (nnslashdot-sid-strip sid) "%" + (number-to-string (1+ article)) + "@slashdot>") + (if parent + (concat "<" (nnslashdot-sid-strip sid) "%" + (number-to-string (1+ (string-to-number parent))) + "@slashdot>") + "") + 0 lines nil nil)) + headers))))) + (setq nnslashdot-headers (sort headers 'car-less-than-car)) + (save-excursion + (set-buffer nntp-server-buffer) + (erase-buffer) + (mm-with-unibyte-current-buffer + (dolist (header nnslashdot-headers) + (nnheader-insert-nov (cdr header))))) + 'nov)) + +(deffoo nnslashdot-sane-retrieve-headers (articles group) + (let ((last (car (last articles))) + (did nil) + (start (max (1- (car articles)) 1)) + (sid (caddr (assoc group nnslashdot-groups))) + headers article subject score from date lines parent point) + (save-excursion + (set-buffer nnslashdot-buffer) + (erase-buffer) + (when (= start 1) + (nnweb-insert (format nnslashdot-article-url + (nnslashdot-sid-strip sid)) t) + (goto-char (point-min)) + (search-forward "Posted by ") + (when (looking-at "]+>\\([^<]+\\)") + (setq from (nnweb-decode-entities-string (match-string 1)))) + (search-forward " on ") + (setq date (nnslashdot-date-to-date + (buffer-substring (point) (1- (search-forward "<"))))) + (forward-line 2) + (setq lines (count-lines (point) + (re-search-forward + "A href=\"\\(http://slashdot.org\\)?/article"))) + (push + (cons + 1 + (make-full-mail-header + 1 group from date (concat "<" (nnslashdot-sid-strip sid) + "%1@slashdot>") + "" 0 lines nil nil)) + headers)) + (while (or (not article) + (and did + (< article last))) + (when article + (setq start (1+ article))) + (setq point (goto-char (point-max))) + (nnweb-insert + (format nnslashdot-comments-url (nnslashdot-sid-strip sid) + nnslashdot-threshold 4 start) + t) + (goto-char point) + (while (re-search-forward + "<\\(b\\|H4\\)>\\([^<]+\\).*score:\\([^)]+\\))" + nil t) + (setq article (string-to-number (match-string 1)) + subject (match-string 3) + score (match-string 5)) + (when (string-match "^Re: *" subject) + (setq subject (concat "Re: " (substring subject (match-end 0))))) + (setq subject (nnweb-decode-entities-string subject)) + (forward-line 1) + (if (looking-at + "by ]+>\\([^<]+\\)[ \t\n]*.*(\\([^)]+\\))") + (progn + (goto-char (- (match-end 0) 5)) + (setq from (concat + (nnweb-decode-entities-string (match-string 1)) + " <" (match-string 2) ">"))) + (setq from "") + (when (looking-at "by \\(.+\\) on ") + (goto-char (- (match-end 0) 5)) + (setq from (nnweb-decode-entities-string (match-string 1))))) + (search-forward " on ") + (setq date + (nnslashdot-date-to-date + (buffer-substring (point) (progn (end-of-line) (point))))) + (setq lines (/ (abs (- (search-forward ""))) + 70)) + (forward-line 2) + (setq parent + (if (looking-at ".*cid=\\([0-9]+\\)") + (match-string 1) + nil)) + (setq did t) + (push + (cons + (1+ article) + (make-full-mail-header + (1+ article) (concat subject " (" score ")") + from date + (concat "<" (nnslashdot-sid-strip sid) "%" + (number-to-string (1+ article)) + "@slashdot>") + (if parent + (concat "<" (nnslashdot-sid-strip sid) "%" + (number-to-string (1+ (string-to-number parent))) + "@slashdot>") + "") + 0 lines nil nil)) + headers)))) + (setq nnslashdot-headers + (sort headers (lambda (s1 s2) (< (car s1) (car s2))))) + (save-excursion + (set-buffer nntp-server-buffer) + (erase-buffer) + (mm-with-unibyte-current-buffer + (dolist (header nnslashdot-headers) + (nnheader-insert-nov (cdr header))))) + 'nov)) + +(deffoo nnslashdot-request-group (group &optional server dont-check) + (nnslashdot-possibly-change-server nil server) + (let ((elem (assoc group nnslashdot-groups))) + (cond + ((not elem) + (nnheader-report 'nnslashdot "Group does not exist")) + (t + (nnheader-report 'nnslashdot "Opened group %s" group) + (nnheader-insert + "211 %d %d %d %s\n" (cadr elem) 1 (cadr elem) + (prin1-to-string group)))))) + +(deffoo nnslashdot-close-group (group &optional server) + (nnslashdot-possibly-change-server group server) + (when (gnus-buffer-live-p nnslashdot-buffer) + (save-excursion + (set-buffer nnslashdot-buffer) + (kill-buffer nnslashdot-buffer))) + t) + +(deffoo nnslashdot-request-article (article &optional group server buffer) + (nnslashdot-possibly-change-server group server) + (let (contents) + (condition-case why + (save-excursion + (set-buffer nnslashdot-buffer) + (let ((case-fold-search t)) + (goto-char (point-min)) + (when (and (stringp article) + (string-match "%\\([0-9]+\\)@" article)) + (setq article (string-to-number (match-string 1 article)))) + (when (numberp article) + (if (= article 1) + (progn + (re-search-forward "Posted by *<[^>]+>[^>]*<[^>]+> *on ") + (search-forward "
") + (setq contents + (buffer-substring + (point) + (progn + (re-search-forward + "

.*A href=\"\\(http://slashdot.org\\)?/article") + (match-beginning 0))))) + (search-forward (format "" (1- article))) + (setq contents + (buffer-substring + (re-search-forward "]+>") + (search-forward ""))))))) + (search-failed (nnslashdot-lose why))) + + (when contents + (save-excursion + (set-buffer (or buffer nntp-server-buffer)) + (erase-buffer) + (mm-with-unibyte-current-buffer + (insert contents) + (goto-char (point-min)) + (while (re-search-forward "\\(
\r?\\)+" nil t) + (replace-match "

" t t)) + (goto-char (point-min)) + (insert "Content-Type: text/html\nMIME-Version: 1.0\n") + (insert "Newsgroups: " (caddr (assoc group nnslashdot-groups)) + "\n") + (let ((header (cdr (assq article nnslashdot-headers)))) + (nnheader-insert-header header)) + (nnheader-report 'nnslashdot "Fetched article %s" article)) + (cons group article))))) + +(deffoo nnslashdot-close-server (&optional server) + (when (and (nnslashdot-server-opened server) + (gnus-buffer-live-p nnslashdot-buffer)) + (save-excursion + (set-buffer nnslashdot-buffer) + (kill-buffer nnslashdot-buffer))) + (nnoo-close-server 'nnslashdot server)) + +(deffoo nnslashdot-request-list (&optional server) + (nnslashdot-possibly-change-server nil server) + (let ((number 0) + sid elem description articles gname) + (condition-case why + ;; First we do the Ultramode to get info on all the latest groups. + (progn + (mm-with-unibyte-buffer + (nnweb-insert "http://slashdot.org/slashdot.xml" t) + (goto-char (point-min)) + (while (search-forward "" nil t) + (narrow-to-region (point) (search-forward "")) + (goto-char (point-min)) + (re-search-forward "\\([^<]+\\)") + (setq description + (nnweb-decode-entities-string (match-string 1))) + (re-search-forward "\\([^<]+\\)") + (setq sid (match-string 1)) + (string-match "/\\([0-9/]+\\)\\(.shtml\\|$\\)" sid) + (setq sid (concat "00/" (match-string 1 sid))) + (re-search-forward "\\([^<]+\\)") + (setq articles (string-to-number (match-string 1))) + (setq gname (concat description " (" sid ")")) + (if (setq elem (assoc gname nnslashdot-groups)) + (setcar (cdr elem) articles) + (push (list gname articles sid) nnslashdot-groups)) + (goto-char (point-max)) + (widen))) + ;; Then do the older groups. + (while (> (- nnslashdot-group-number number) 0) + (mm-with-unibyte-buffer + (let ((case-fold-search t)) + (nnweb-insert (format nnslashdot-active-url number) t) + (goto-char (point-min)) + (while (re-search-forward + "article.pl\\?sid=\\([^&]+\\).*\\([^<]+\\)" + nil t) + (setq sid (match-string 1) + description + (nnweb-decode-entities-string (match-string 2))) + (forward-line 1) + (when (re-search-forward "\\([0-9]+\\)" nil t) + (setq articles (string-to-number (match-string 1)))) + (setq gname (concat description " (" sid ")")) + (if (setq elem (assoc gname nnslashdot-groups)) + (setcar (cdr elem) articles) + (push (list gname articles sid) nnslashdot-groups))))) + (incf number 30))) + (search-failed (nnslashdot-lose why))) + (nnslashdot-write-groups) + (nnslashdot-generate-active) + t)) + +(deffoo nnslashdot-request-newgroups (date &optional server) + (nnslashdot-possibly-change-server nil server) + (nnslashdot-generate-active) + t) + +(deffoo nnslashdot-request-post (&optional server) + (nnslashdot-possibly-change-server nil server) + (let ((sid (nnslashdot-sid-strip (message-fetch-field "newsgroups"))) + (subject (message-fetch-field "subject")) + (references (car (last (split-string + (message-fetch-field "references"))))) + body quoted pid) + (string-match "%\\([0-9]+\\)@slashdot" references) + (setq pid (match-string 1 references)) + (message-goto-body) + (narrow-to-region (point) (progn (message-goto-signature) (point))) + (goto-char (point-min)) + (while (not (eobp)) + (if (looking-at "> ") + (progn + (delete-region (point) (+ (point) 2)) + (unless quoted + (insert "

\n")) + (setq quoted t)) + (when quoted + (insert "
\n") + (setq quoted nil))) + (forward-line 1)) + (goto-char (point-min)) + (while (re-search-forward "^ *\n" nil t) + (replace-match "

\n")) + (widen) + (when (message-goto-signature) + (forward-line -1) + (insert "

\n") + (while (not (eobp)) + (end-of-line) + (insert "
") + (forward-line 1))) + (message-goto-body) + (setq body (buffer-substring (point) (point-max))) + (erase-buffer) + (nnweb-fetch-form + "http://slashdot.org/comments.pl" + `(("sid" . ,sid) + ("pid" . ,pid) + ("rlogin" . "userlogin") + ("unickname" . ,nnslashdot-login-name) + ("upasswd" . ,nnslashdot-password) + ("postersubj" . ,subject) + ("op" . "Submit") + ("postercomment" . ,body) + ("posttype" . "html"))))) + +(deffoo nnslashdot-request-delete-group (group &optional force server) + (nnslashdot-possibly-change-server group server) + (setq nnslashdot-groups (delq (assoc group nnslashdot-groups) + nnslashdot-groups)) + (nnslashdot-write-groups)) + +(deffoo nnslashdot-request-close () + (setq nnslashdot-headers nil + nnslashdot-groups nil)) + +(nnoo-define-skeleton nnslashdot) + +;;; Internal functions + +(defun nnslashdot-possibly-change-server (&optional group server) + (nnslashdot-init server) + (when (and server + (not (nnslashdot-server-opened server))) + (nnslashdot-open-server server)) + (unless nnslashdot-groups + (nnslashdot-read-groups))) + +(defun nnslashdot-read-groups () + (let ((file (expand-file-name "groups" nnslashdot-directory))) + (when (file-exists-p file) + (mm-with-unibyte-buffer + (insert-file-contents file) + (goto-char (point-min)) + (setq nnslashdot-groups (read (current-buffer))))))) + +(defun nnslashdot-write-groups () + (with-temp-file (expand-file-name "groups" nnslashdot-directory) + (prin1 nnslashdot-groups (current-buffer)))) + +(defun nnslashdot-init (server) + "Initialize buffers and such." + (unless (file-exists-p nnslashdot-directory) + (gnus-make-directory nnslashdot-directory)) + (unless (gnus-buffer-live-p nnslashdot-buffer) + (setq nnslashdot-buffer + (save-excursion + (nnheader-set-temp-buffer + (format " *nnslashdot %s*" server)))))) + +(defun nnslashdot-date-to-date (sdate) + (condition-case err + (let ((elem (delete "" (split-string sdate)))) + (concat (substring (nth 0 elem) 0 3) " " + (substring (nth 1 elem) 0 3) " " + (substring (nth 2 elem) 0 2) " " + (substring (nth 3 elem) 1 6) " " + (format-time-string "%Y") " " + (nth 4 elem))) + (error ""))) + +(defun nnslashdot-generate-active () + (save-excursion + (set-buffer nntp-server-buffer) + (erase-buffer) + (dolist (elem nnslashdot-groups) + (insert (prin1-to-string (car elem)) + " " (number-to-string (cadr elem)) " 1 y\n")))) + +(defun nnslashdot-lose (why) + (error "Slashdot HTML has changed; please get a new version of nnslashdot")) + +;(defun nnslashdot-sid-strip (sid) +; (if (string-match "^00/" sid) +; (substring sid (match-end 0)) +; sid)) + +(defalias 'nnslashdot-sid-strip 'identity) + +(provide 'nnslashdot) + +;;; nnslashdot.el ends here diff --git a/lisp/gnus/nnultimate.el b/lisp/gnus/nnultimate.el new file mode 100644 index 00000000000..734ab7129a6 --- /dev/null +++ b/lisp/gnus/nnultimate.el @@ -0,0 +1,452 @@ +;;; nnultimate.el --- interfacing with the Ultimate Bulletin Board system +;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. + +;; Author: Lars Magne Ingebrigtsen +;; Keywords: news + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Note: You need to have `url' and `w3' installed for this +;; backend to work. + +;;; Code: + +(eval-when-compile (require 'cl)) + +(require 'nnoo) +(require 'message) +(require 'gnus-util) +(require 'gnus) +(require 'nnmail) +(require 'mm-util) +(eval-when-compile + (ignore-errors + (require 'nnweb))) +;; Report failure to find w3 at load time if appropriate. +(eval '(require 'nnweb)) + +(nnoo-declare nnultimate) + +(defvoo nnultimate-directory (nnheader-concat gnus-directory "ultimate/") + "Where nnultimate will save its files.") + +(defvoo nnultimate-address "" + "The address of the Ultimate bulletin board.") + +;;; Internal variables + +(defvar nnultimate-groups-alist nil) +(defvoo nnultimate-groups nil) +(defvoo nnultimate-headers nil) +(defvoo nnultimate-articles nil) + +;;; Interface functions + +(nnoo-define-basics nnultimate) + +(deffoo nnultimate-retrieve-headers (articles &optional group server fetch-old) + (nnultimate-possibly-change-server group server) + (unless gnus-nov-is-evil + (let* ((last (car (last articles))) + (did nil) + (start 1) + (entry (assoc group nnultimate-groups)) + (sid (nth 2 entry)) + (topics (nth 4 entry)) + (mapping (nth 5 entry)) + (old-total (or (nth 6 entry) 1)) + (furl "forumdisplay.cgi?action=topics&number=%d&DaysPrune=1000") + (furls (list (concat nnultimate-address (format furl sid)))) + headers article subject score from date lines parent point + contents tinfo fetchers map elem a href garticles topic old-max + inc datel table string current-page total-contents pages + farticles forum-contents parse furl-fetched mmap farticle) + (setq map mapping) + (while (and (setq article (car articles)) + map) + (while (and map + (or (> article (caar map)) + (< (cadar map) (caar map)))) + (pop map)) + (when (setq mmap (car map)) + (setq farticle -1) + (while (and article + (<= article (nth 1 mmap))) + ;; Do we already have a fetcher for this topic? + (if (setq elem (assq (nth 2 mmap) fetchers)) + ;; Yes, so we just add the spec to the end. + (nconc elem (list (cons article + (+ (nth 3 mmap) (incf farticle))))) + ;; No, so we add a new one. + (push (list (nth 2 mmap) + (cons article + (+ (nth 3 mmap) (incf farticle)))) + fetchers)) + (pop articles) + (setq article (car articles))))) + ;; Now we have the mapping from/to Gnus/nnultimate article numbers, + ;; so we start fetching the topics that we need to satisfy the + ;; request. + (if (not fetchers) + (save-excursion + (set-buffer nntp-server-buffer) + (erase-buffer)) + (setq nnultimate-articles nil) + (mm-with-unibyte-buffer + (dolist (elem fetchers) + (setq pages 1 + current-page 1 + total-contents nil) + (while (<= current-page pages) + (erase-buffer) + (setq subject (nth 2 (assq (car elem) topics))) + (setq href (nth 3 (assq (car elem) topics))) + (if (= current-page 1) + (nnweb-insert href) + (string-match "\\.html$" href) + (nnweb-insert (concat (substring href 0 (match-beginning 0)) + "-" (number-to-string current-page) + (match-string 0 href)))) + (goto-char (point-min)) + (setq contents + (ignore-errors (w3-parse-buffer (current-buffer)))) + (setq table (nnultimate-find-forum-table contents)) + (setq string (mapconcat 'identity (nnweb-text table) "")) + (when (string-match "topic is \\([0-9]\\) pages" string) + (setq pages (string-to-number (match-string 1 string))) + (setcdr table nil) + (setq table (nnultimate-find-forum-table contents))) + (setq contents (cdr (nth 2 (car (nth 2 table))))) + (setq total-contents (nconc total-contents contents)) + (incf current-page)) + ;;(setq total-contents (nreverse total-contents)) + (dolist (art (cdr elem)) + (if (not (nth (1- (cdr art)) total-contents)) + () ;(debug) + (push (list (car art) + (nth (1- (cdr art)) total-contents) + subject) + nnultimate-articles))))) + (setq nnultimate-articles + (sort nnultimate-articles 'car-less-than-car)) + ;; Now we have all the articles, conveniently in an alist + ;; where the key is the Gnus article number. + (dolist (articlef nnultimate-articles) + (setq article (nth 0 articlef) + contents (nth 1 articlef) + subject (nth 2 articlef)) + (setq from (mapconcat 'identity + (nnweb-text (car (nth 2 contents))) + " ") + datel (nnweb-text (nth 2 (car (cdr (nth 2 contents)))))) + (while datel + (when (string-match "Posted" (car datel)) + (setq date (substring (car datel) (match-end 0)) + datel nil)) + (pop datel)) + (setq date (delete "" (split-string date "[- \n\t\r    ]"))) + (if (or (member "AM" date) + (member "PM" date)) + (setq date (format "%s %s %s %s" + (car (rassq (string-to-number (nth 0 date)) + parse-time-months)) + (nth 1 date) (nth 2 date) (nth 3 date))) + (setq date (format "%s %s %s %s" + (car (rassq (string-to-number (nth 1 date)) + parse-time-months)) + (nth 0 date) (nth 2 date) (nth 3 date)))) + (push + (cons + article + (make-full-mail-header + article subject + from (or date "") + (concat "<" (number-to-string sid) "%" + (number-to-string article) + "@ultimate>") + "" 0 + (/ (length (mapconcat + 'identity + (nnweb-text + (cdr (nth 2 (nth 1 (nth 2 contents))))) + "")) + 70) + nil nil)) + headers)) + (setq nnultimate-headers (sort headers 'car-less-than-car)) + (save-excursion + (set-buffer nntp-server-buffer) + (mm-with-unibyte-current-buffer + (erase-buffer) + (dolist (header nnultimate-headers) + (nnheader-insert-nov (cdr header)))))) + 'nov))) + +(deffoo nnultimate-request-group (group &optional server dont-check) + (nnultimate-possibly-change-server nil server) + (when (not nnultimate-groups) + (nnultimate-request-list)) + (unless dont-check + (nnultimate-create-mapping group)) + (let ((elem (assoc group nnultimate-groups))) + (cond + ((not elem) + (nnheader-report 'nnultimate "Group does not exist")) + (t + (nnheader-report 'nnultimate "Opened group %s" group) + (nnheader-insert + "211 %d %d %d %s\n" (cadr elem) 1 (cadr elem) + (prin1-to-string group)))))) + +(deffoo nnultimate-request-close () + (setq nnultimate-groups-alist nil + nnultimate-groups nil)) + +(deffoo nnultimate-request-article (article &optional group server buffer) + (nnultimate-possibly-change-server group server) + (let ((contents (cdr (assq article nnultimate-articles)))) + (setq contents (cddr (nth 2 (nth 1 (nth 2 (car contents)))))) + (when contents + (save-excursion + (set-buffer (or buffer nntp-server-buffer)) + (erase-buffer) + (nnweb-insert-html (cons 'p (cons nil (list contents)))) + (goto-char (point-min)) + (insert "Content-Type: text/html\nMIME-Version: 1.0\n") + (let ((header (cdr (assq article nnultimate-headers)))) + (mm-with-unibyte-current-buffer + (nnheader-insert-header header))) + (nnheader-report 'nnultimate "Fetched article %s" article) + (cons group article))))) + +(deffoo nnultimate-request-list (&optional server) + (nnultimate-possibly-change-server nil server) + (mm-with-unibyte-buffer + (nnweb-insert + (if (string-match "/$" nnultimate-address) + (concat nnultimate-address "Ultimate.cgi") + nnultimate-address)) + (let ((contents (nth 2 (car (nth 2 + (nnultimate-find-forum-table + (w3-parse-buffer (current-buffer))))))) + sid elem description articles a href group forum + a1 a2) + (dolist (row contents) + (setq row (nth 2 row)) + (when (setq a (nnweb-parse-find 'a row)) + (setq group (car (last (nnweb-text a))) + href (cdr (assq 'href (nth 1 a)))) + (setq description (car (last (nnweb-text (nth 1 row))))) + (setq a1 (car (last (nnweb-text (nth 2 row))))) + (setq a2 (car (last (nnweb-text (nth 3 row))))) + (when (string-match "^[0-9]+$" a1) + (setq articles (string-to-number a1))) + (when (and a2 (string-match "^[0-9]+$" a2)) + (setq articles (max articles (string-to-number a2)))) + (when href + (string-match "number=\\([0-9]+\\)" href) + (setq forum (string-to-number (match-string 1 href))) + (if (setq elem (assoc group nnultimate-groups)) + (setcar (cdr elem) articles) + (push (list group articles forum description nil nil nil nil) + nnultimate-groups)))))) + (nnultimate-write-groups) + (nnultimate-generate-active) + t)) + +(deffoo nnultimate-request-newgroups (date &optional server) + (nnultimate-possibly-change-server nil server) + (nnultimate-generate-active) + t) + +(nnoo-define-skeleton nnultimate) + +;;; Internal functions + +(defun nnultimate-prune-days (group time) + "Compute the number of days to fetch info for." + (let ((old-time (nth 7 (assoc group nnultimate-groups)))) + (if (null old-time) + 1000 + (- (time-to-days time) (time-to-days old-time))))) + +(defun nnultimate-create-mapping (group) + (let* ((entry (assoc group nnultimate-groups)) + (sid (nth 2 entry)) + (topics (nth 4 entry)) + (mapping (nth 5 entry)) + (old-total (or (nth 6 entry) 1)) + (current-time (current-time)) + (furl + (concat "forumdisplay.cgi?action=topics&number=%d&DaysPrune=" + (number-to-string + (nnultimate-prune-days group current-time)))) + (furls (list (concat nnultimate-address (format furl sid)))) + contents forum-contents furl-fetched a subject href + garticles topic tinfo old-max inc parse) + (mm-with-unibyte-buffer + (while furls + (erase-buffer) + (nnweb-insert (pop furls)) + (goto-char (point-min)) + (setq parse (w3-parse-buffer (current-buffer))) + (setq contents + (cdr (nth 2 (car (nth 2 (nnultimate-find-forum-table + parse)))))) + (setq forum-contents (nconc contents forum-contents)) + (unless furl-fetched + (setq furl-fetched t) + ;; On the first time through this loop, we find all the + ;; forum URLs. + (dolist (a (nnweb-parse-find-all 'a parse)) + (let ((href (cdr (assq 'href (nth 1 a))))) + (when (and href + (string-match "forumdisplay.*startpoint" href)) + (push href furls)))) + (setq furls (nreverse furls)))) + ;; The main idea here is to map Gnus article numbers to + ;; nnultimate article numbers. Say there are three topics in + ;; this forum, the first with 4 articles, the seconds with 2, + ;; and the third with 1. Then this will translate into 7 Gnus + ;; article numbers, where 1-4 comes from the first topic, 5-6 + ;; from the second and 7 from the third. Now, then next time + ;; the group is entered, there's 2 new articles in topic one + ;; and 1 in topic three. Then Gnus article number 8-9 be 5-6 + ;; in topic one and 10 will be the 2 in topic three. + (dolist (row (reverse forum-contents)) + (setq row (nth 2 row)) + (when (setq a (nnweb-parse-find 'a row)) + (setq subject (car (last (nnweb-text a))) + href (cdr (assq 'href (nth 1 a)))) + (let ((artlist (nreverse (nnweb-text row))) + art) + (while (and (not art) + artlist) + (when (string-match "^[0-9]+$" (car artlist)) + (setq art (1+ (string-to-number (car artlist))))) + (pop artlist)) + (setq garticles art)) + (when garticles + (string-match "/\\([0-9]+\\).html" href) + (setq topic (string-to-number (match-string 1 href))) + (if (setq tinfo (assq topic topics)) + (progn + (setq old-max (cadr tinfo)) + (setcar (cdr tinfo) garticles)) + (setq old-max 0) + (push (list topic garticles subject href) topics) + (setcar (nthcdr 4 entry) topics)) + (when (not (= old-max garticles)) + (setq inc (- garticles old-max)) + (setq mapping (nconc mapping + (list + (list + old-total (1- (incf old-total inc)) + topic (1+ old-max))))) + (incf old-max inc) + (setcar (nthcdr 5 entry) mapping) + (setcar (nthcdr 6 entry) old-total)))))) + (setcar (nthcdr 7 entry) current-time) + (setcar (nthcdr 1 entry) (1- old-total)) + (nnultimate-write-groups) + mapping)) + +(defun nnultimate-possibly-change-server (&optional group server) + (nnultimate-init server) + (when (and server + (not (nnultimate-server-opened server))) + (nnultimate-open-server server)) + (unless nnultimate-groups-alist + (nnultimate-read-groups) + (setq nnultimate-groups (cdr (assoc nnultimate-address + nnultimate-groups-alist))))) + +(deffoo nnultimate-open-server (server &optional defs connectionless) + (nnheader-init-server-buffer) + (if (nnultimate-server-opened server) + t + (unless (assq 'nnultimate-address defs) + (setq defs (append defs (list (list 'nnultimate-address server))))) + (nnoo-change-server 'nnultimate server defs))) + +(defun nnultimate-read-groups () + (setq nnultimate-groups-alist nil) + (let ((file (expand-file-name "groups" nnultimate-directory))) + (when (file-exists-p file) + (mm-with-unibyte-buffer + (insert-file-contents file) + (goto-char (point-min)) + (setq nnultimate-groups-alist (read (current-buffer))))))) + +(defun nnultimate-write-groups () + (setq nnultimate-groups-alist + (delq (assoc nnultimate-address nnultimate-groups-alist) + nnultimate-groups-alist)) + (push (cons nnultimate-address nnultimate-groups) + nnultimate-groups-alist) + (with-temp-file (expand-file-name "groups" nnultimate-directory) + (prin1 nnultimate-groups-alist (current-buffer)))) + +(defun nnultimate-init (server) + "Initialize buffers and such." + (unless (file-exists-p nnultimate-directory) + (gnus-make-directory nnultimate-directory))) + +(defun nnultimate-generate-active () + (save-excursion + (set-buffer nntp-server-buffer) + (erase-buffer) + (dolist (elem nnultimate-groups) + (insert (prin1-to-string (car elem)) + " " (number-to-string (cadr elem)) " 1 y\n")))) + +(defun nnultimate-find-forum-table (contents) + (catch 'found + (nnultimate-find-forum-table-1 contents))) + +(defun nnultimate-find-forum-table-1 (contents) + (dolist (element contents) + (unless (stringp element) + (when (and (eq (car element) 'table) + (nnultimate-forum-table-p element)) + (throw 'found element)) + (when (nth 2 element) + (nnultimate-find-forum-table-1 (nth 2 element)))))) + +(defun nnultimate-forum-table-p (parse) + (when (not (apply 'gnus-or + (mapcar + (lambda (p) + (nnweb-parse-find 'table p)) + (nth 2 parse)))) + (let ((href (cdr (assq 'href (nth 1 (nnweb-parse-find 'a parse 20))))) + case-fold-search) + (when (and href (string-match + "postings\\|forumdisplay\\|Forum[0-9]+/HTML\\|getbio" + href)) + t)))) + +(provide 'nnultimate) + +;; Local Variables: +;; coding: iso-8859-1 +;; End: + +;;; nnultimate.el ends here diff --git a/lisp/gnus/nnwarchive.el b/lisp/gnus/nnwarchive.el new file mode 100644 index 00000000000..5103b551bfb --- /dev/null +++ b/lisp/gnus/nnwarchive.el @@ -0,0 +1,752 @@ +;;; nnwarchive.el --- interfacing with web archives +;; Copyright (C) 1999, 2000 Free Software Foundation, Inc. + +;; Author: Shenghuo Zhu +;; Keywords: news egroups mail-archive + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 2, or (at your +;; option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to the +;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, +;; Boston, MA 02111-1307, USA. + +;;; Commentary: + +;; Note: You need to have `url' (w3 0.46) or greater version +;; installed for this backend to work. + +;; Todo: +;; 1. To support more web archives. +;; 2. Generalize webmail to other MHonArc archive. + +;;; Code: + +(eval-when-compile (require 'cl)) + +(require 'nnoo) +(require 'message) +(require 'gnus-util) +(require 'gnus) +(require 'gnus-bcklg) +(require 'nnmail) +(require 'mm-util) +(require 'mail-source) +(eval-when-compile + (ignore-errors + (require 'w3) + (require 'url) + (require 'w3-forms) + (require 'nnweb))) +;; Report failure to find w3 at load time if appropriate. +(eval '(progn + (require 'w3) + (require 'url) + (require 'w3-forms) + (require 'nnweb))) + +(nnoo-declare nnwarchive) + +(defvar nnwarchive-type-definition + '((egroups + (address . "www.egroups.com") + (open-url + "http://www.egroups.com/login.cgi?&login_email=%s&login_password=%s" + nnwarchive-login nnwarchive-passwd) + (list-url + "http://www.egroups.com/mygroups") + (list-dissect . nnwarchive-egroups-list) + (list-groups . nnwarchive-egroups-list-groups) + (xover-url + "http://www.egroups.com/messages/%s/%d" group aux) + (xover-last-url + "http://www.egroups.com/messages/%s/" group) + (xover-page-size . 13) + (xover-dissect . nnwarchive-egroups-xover) + (article-url + "http://www.egroups.com/message/%s/%d?source=1" group article) + (article-dissect . nnwarchive-egroups-article) + (authentication . t) + (article-offset . 0) + (xover-files . nnwarchive-egroups-xover-files)) + (mail-archive + (address . "www.mail-archive.com") + (open-url) + (list-url + "http://www.mail-archive.com/lists.html") + (list-dissect . nnwarchive-mail-archive-list) + (list-groups . nnwarchive-mail-archive-list-groups) + (xover-url + "http://www.mail-archive.com/%s/mail%d.html" group aux) + (xover-last-url + "http://www.mail-archive.com/%s/maillist.html" group) + (xover-page-size) + (xover-dissect . nnwarchive-mail-archive-xover) + (article-url + "http://www.mail-archive.com/%s/msg%05d.html" group article1) + (article-dissect . nnwarchive-mail-archive-article) + (xover-files . nnwarchive-mail-archive-xover-files) + (authentication) + (article-offset . 1)))) + +(defvar nnwarchive-default-type 'egroups) + +(defvoo nnwarchive-directory (nnheader-concat gnus-directory "warchive/") + "Where nnwarchive will save its files.") + +(defvoo nnwarchive-type nil + "The type of nnwarchive.") + +(defvoo nnwarchive-address "" + "The address of nnwarchive.") + +(defvoo nnwarchive-login nil + "Your login name for the group.") + +(defvoo nnwarchive-passwd nil + "Your password for the group.") + +(defvoo nnwarchive-groups nil) + +(defvoo nnwarchive-headers-cache nil) + +(defvoo nnwarchive-authentication nil) + +(defvoo nnwarchive-nov-is-evil nil) + +(defconst nnwarchive-version "nnwarchive 1.0") + +;;; Internal variables + +(defvoo nnwarchive-open-url nil) +(defvoo nnwarchive-open-dissect nil) + +(defvoo nnwarchive-list-url nil) +(defvoo nnwarchive-list-dissect nil) +(defvoo nnwarchive-list-groups nil) + +(defvoo nnwarchive-xover-files nil) +(defvoo nnwarchive-xover-url nil) +(defvoo nnwarchive-xover-last-url nil) +(defvoo nnwarchive-xover-dissect nil) +(defvoo nnwarchive-xover-page-size nil) + +(defvoo nnwarchive-article-url nil) +(defvoo nnwarchive-article-dissect nil) +(defvoo nnwarchive-xover-files nil) +(defvoo nnwarchive-article-offset 0) + +(defvoo nnwarchive-buffer nil) + +(defvoo nnwarchive-keep-backlog 300) +(defvar nnwarchive-backlog-articles nil) +(defvar nnwarchive-backlog-hashtb nil) + +(defvoo nnwarchive-headers nil) + + +;;; Interface functions + +(nnoo-define-basics nnwarchive) + +(defun nnwarchive-set-default (type) + (let ((defs (cdr (assq type nnwarchive-type-definition))) + def) + (dolist (def defs) + (set (intern (concat "nnwarchive-" (symbol-name (car def)))) + (cdr def))))) + +(defmacro nnwarchive-backlog (&rest form) + `(let ((gnus-keep-backlog nnwarchive-keep-backlog) + (gnus-backlog-buffer + (format " *nnwarchive backlog %s*" nnwarchive-address)) + (gnus-backlog-articles nnwarchive-backlog-articles) + (gnus-backlog-hashtb nnwarchive-backlog-hashtb)) + (unwind-protect + (progn ,@form) + (setq nnwarchive-backlog-articles gnus-backlog-articles + nnwarchive-backlog-hashtb gnus-backlog-hashtb)))) +(put 'nnwarchive-backlog 'lisp-indent-function 0) +(put 'nnwarchive-backlog 'edebug-form-spec '(form body)) + +(defun nnwarchive-backlog-enter-article (group number buffer) + (nnwarchive-backlog + (gnus-backlog-enter-article group number buffer))) + +(defun nnwarchive-get-article (article &optional group server buffer) + (if (numberp article) + (if (nnwarchive-backlog + (gnus-backlog-request-article group article + (or buffer nntp-server-buffer))) + (cons group article) + (let (contents) + (save-excursion + (set-buffer nnwarchive-buffer) + (goto-char (point-min)) + (let ((article1 (- article nnwarchive-article-offset))) + (nnwarchive-url nnwarchive-article-url)) + (setq contents (funcall nnwarchive-article-dissect group article))) + (when contents + (save-excursion + (set-buffer (or buffer nntp-server-buffer)) + (erase-buffer) + (insert contents) + (nnwarchive-backlog-enter-article group article (current-buffer)) + (nnheader-report 'nnwarchive "Fetched article %s" article) + (cons group article))))) + nil)) + +(deffoo nnwarchive-retrieve-headers (articles &optional group server fetch-old) + (nnwarchive-possibly-change-server group server) + (if (or gnus-nov-is-evil nnwarchive-nov-is-evil) + (with-temp-buffer + (with-current-buffer nntp-server-buffer + (erase-buffer)) + (let ((buf (current-buffer)) b e) + (dolist (art articles) + (nnwarchive-get-article art group server buf) + (setq b (goto-char (point-min))) + (if (search-forward "\n\n" nil t) + (forward-char -1) + (goto-char (point-max))) + (setq e (point)) + (with-current-buffer nntp-server-buffer + (insert (format "221 %d Article retrieved.\n" art)) + (insert-buffer-substring buf b e) + (insert ".\n")))) + 'headers) + (setq nnwarchive-headers (cdr (assoc group nnwarchive-headers-cache))) + (save-excursion + (set-buffer nnwarchive-buffer) + (erase-buffer) + (funcall nnwarchive-xover-files group articles)) + (save-excursion + (set-buffer nntp-server-buffer) + (erase-buffer) + (let (header) + (dolist (art articles) + (if (setq header (assq art nnwarchive-headers)) + (nnheader-insert-nov (cdr header)))))) + (let ((elem (assoc group nnwarchive-headers-cache))) + (if elem + (setcdr elem nnwarchive-headers) + (push (cons group nnwarchive-headers) nnwarchive-headers-cache))) + 'nov)) + +(deffoo nnwarchive-request-group (group &optional server dont-check) + (nnwarchive-possibly-change-server nil server) + (when (and (not dont-check) nnwarchive-list-groups) + (funcall nnwarchive-list-groups (list group)) + (nnwarchive-write-groups)) + (let ((elem (assoc group nnwarchive-groups))) + (cond + ((not elem) + (nnheader-report 'nnwarchive "Group does not exist")) + (t + (nnheader-report 'nnwarchive "Opened group %s" group) + (nnheader-insert + "211 %d %d %d %s\n" (or (cadr elem) 0) 1 (or (cadr elem) 0) + (prin1-to-string group)) + t)))) + +(deffoo nnwarchive-request-article (article &optional group server buffer) + (nnwarchive-possibly-change-server group server) + (nnwarchive-get-article article group server buffer)) + +(deffoo nnwarchive-close-server (&optional server) + (when (and (nnwarchive-server-opened server) + (gnus-buffer-live-p nnwarchive-buffer)) + (save-excursion + (set-buffer nnwarchive-buffer) + (kill-buffer nnwarchive-buffer))) + (nnwarchive-backlog + (gnus-backlog-shutdown)) + (nnoo-close-server 'nnwarchive server)) + +(deffoo nnwarchive-request-list (&optional server) + (nnwarchive-possibly-change-server nil server) + (save-excursion + (set-buffer nnwarchive-buffer) + (erase-buffer) + (if nnwarchive-list-url + (nnwarchive-url nnwarchive-list-url)) + (if nnwarchive-list-dissect + (funcall nnwarchive-list-dissect)) + (nnwarchive-write-groups) + (nnwarchive-generate-active)) + t) + +(deffoo nnwarchive-open-server (server &optional defs connectionless) + (nnoo-change-server 'nnwarchive server defs) + (nnwarchive-init server) + (when nnwarchive-authentication + (setq nnwarchive-login + (or nnwarchive-login + (read-string + (format "Login at %s: " server) + user-mail-address))) + (setq nnwarchive-passwd + (or nnwarchive-passwd + (mail-source-read-passwd + (format "Password for %s at %s: " + nnwarchive-login server))))) + (unless nnwarchive-groups + (nnwarchive-read-groups)) + (save-excursion + (set-buffer nnwarchive-buffer) + (erase-buffer) + (if nnwarchive-open-url + (nnwarchive-url nnwarchive-open-url)) + (if nnwarchive-open-dissect + (funcall nnwarchive-open-dissect))) + t) + +(nnoo-define-skeleton nnwarchive) + +;;; Internal functions + +(defun nnwarchive-possibly-change-server (&optional group server) + (nnwarchive-init server) + (when (and server + (not (nnwarchive-server-opened server))) + (nnwarchive-open-server server))) + +(defun nnwarchive-read-groups () + (let ((file (expand-file-name (concat "groups-" nnwarchive-address) + nnwarchive-directory))) + (when (file-exists-p file) + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (setq nnwarchive-groups (read (current-buffer))))))) + +(defun nnwarchive-write-groups () + (with-temp-file (expand-file-name (concat "groups-" nnwarchive-address) + nnwarchive-directory) + (prin1 nnwarchive-groups (current-buffer)))) + +(defun nnwarchive-init (server) + "Initialize buffers and such." + (let ((type (intern server)) (defs nnwarchive-type-definition) def) + (cond + ((equal server "") + (setq type nnwarchive-default-type)) + ((assq type nnwarchive-type-definition) t) + (t + (setq type nil) + (while (setq def (pop defs)) + (when (equal (cdr (assq 'address (cdr def))) server) + (setq defs nil) + (setq type (car def)))) + (unless type + (error "Undefined server %s" server)))) + (setq nnwarchive-type type)) + (unless (file-exists-p nnwarchive-directory) + (gnus-make-directory nnwarchive-directory)) + (unless (gnus-buffer-live-p nnwarchive-buffer) + (setq nnwarchive-buffer + (save-excursion + (nnheader-set-temp-buffer + (format " *nnwarchive %s %s*" nnwarchive-type server))))) + (nnwarchive-set-default nnwarchive-type)) + +(defun nnwarchive-encode-www-form-urlencoded (pairs) + "Return PAIRS encoded for forms." + (mapconcat + (function + (lambda (data) + (concat (w3-form-encode-xwfu (car data)) "=" + (w3-form-encode-xwfu (cdr data))))) + pairs "&")) + +(defun nnwarchive-fetch-form (url pairs) + (let ((url-request-data (nnwarchive-encode-www-form-urlencoded pairs)) + (url-request-method "POST") + (url-request-extra-headers + '(("Content-type" . "application/x-www-form-urlencoded")))) + (nnweb-insert url)) + t) + +(defun nnwarchive-eval (expr) + (cond + ((consp expr) + (cons (nnwarchive-eval (car expr)) (nnwarchive-eval (cdr expr)))) + ((symbolp expr) + (eval expr)) + (t + expr))) + +(defun nnwarchive-url (xurl) + (mm-with-unibyte-current-buffer + (let ((url-confirmation-func 'identity) + (url-cookie-multiple-line nil)) + (cond + ((eq (car xurl) 'post) + (pop xurl) + (nnwarchive-fetch-form (car xurl) (nnwarchive-eval (cdr xurl)))) + (t + (nnweb-insert (apply 'format (nnwarchive-eval xurl)))))))) + +(defun nnwarchive-generate-active () + (save-excursion + (set-buffer nntp-server-buffer) + (erase-buffer) + (dolist (elem nnwarchive-groups) + (insert (prin1-to-string (car elem)) + " " (number-to-string (or (cadr elem) 0)) " 1 y\n")))) + +(defun nnwarchive-paged (articles) + (let (art narts next) + (while (setq art (pop articles)) + (when (and (>= art (or next 0)) + (not (assq art nnwarchive-headers))) + (push art narts) + (setq next (+ art nnwarchive-xover-page-size)))) + narts)) + +;; egroups + +(defun nnwarchive-egroups-list-groups (groups) + (save-excursion + (let (articles) + (set-buffer nnwarchive-buffer) + (dolist (group groups) + (erase-buffer) + (nnwarchive-url nnwarchive-xover-last-url) + (goto-char (point-min)) + (when (re-search-forward "of \\([0-9]+\\)[ \t\n\r]*" nil t) + (setq articles (string-to-number (match-string 1)))) + (let ((elem (assoc group nnwarchive-groups))) + (if elem + (setcar (cdr elem) articles) + (push (list group articles "") nnwarchive-groups))) + (setq nnwarchive-headers (cdr (assoc group nnwarchive-headers-cache))) + (nnwarchive-egroups-xover group) + (let ((elem (assoc group nnwarchive-headers-cache))) + (if elem + (setcdr elem nnwarchive-headers) + (push (cons group nnwarchive-headers) nnwarchive-headers-cache))))))) + +(defun nnwarchive-egroups-list () + (let ((case-fold-search t) + group description elem articles) + (goto-char (point-min)) + (while + (re-search-forward "href=\"/group/\\([^/\"\> ]+\\)" nil t) + (setq group (match-string 1) + description (match-string 2)) + (if (setq elem (assoc group nnwarchive-groups)) + (setcar (cdr elem) 0) + (push (list group articles description) nnwarchive-groups)))) + t) + +(defun nnwarchive-egroups-xover (group) + (let (article subject from date) + (goto-char (point-min)) + (while (re-search-forward + "
]+>\\([^<]+\\)<" + nil t) + (setq group (match-string 1) + article (string-to-number (match-string 2)) + subject (match-string 3)) + (forward-line 1) + (unless (assq article nnwarchive-headers) + (if (looking-at "]+>]+>\\([^<]+\\)") + (setq from (match-string 1))) + (forward-line 1) + (if (looking-at "]+>]+>\\([^<]+\\)") + (setq date (identity (match-string 1)))) + (push (cons + article + (make-full-mail-header + article + (nnweb-decode-entities-string subject) + (nnweb-decode-entities-string from) + date + (concat "<" group "%" + (number-to-string article) + "@egroup.com>") + "" + 0 0 "")) nnwarchive-headers)))) + nnwarchive-headers) + +(defun nnwarchive-egroups-article (group articles) + (goto-char (point-min)) + (if (search-forward "

" nil t)
+      (delete-region (point-min) (point)))
+  (goto-char (point-max))
+  (if (search-backward "
" nil t) + (delete-region (point) (point-max))) + (goto-char (point-min)) + (while (re-search-forward "]+>\\([^<]+\\)" nil t) + (replace-match "\\1")) + (nnweb-decode-entities) + (buffer-string)) + +(defun nnwarchive-egroups-xover-files (group articles) + (let (aux auxs) + (setq auxs (nnwarchive-paged (sort articles '<))) + (while (setq aux (pop auxs)) + (goto-char (point-max)) + (nnwarchive-url nnwarchive-xover-url)) + (if nnwarchive-xover-dissect + (nnwarchive-egroups-xover group)))) + +;; mail-archive + +(defun nnwarchive-mail-archive-list-groups (groups) + (save-excursion + (let (articles) + (set-buffer nnwarchive-buffer) + (dolist (group groups) + (erase-buffer) + (nnwarchive-url nnwarchive-xover-last-url) + (goto-char (point-min)) + (when (re-search-forward "msg\\([0-9]+\\)\\.html" nil t) + (setq articles (1+ (string-to-number (match-string 1))))) + (let ((elem (assoc group nnwarchive-groups))) + (if elem + (setcar (cdr elem) articles) + (push (list group articles "") nnwarchive-groups))) + (setq nnwarchive-headers (cdr (assoc group nnwarchive-headers-cache))) + (nnwarchive-mail-archive-xover group) + (let ((elem (assoc group nnwarchive-headers-cache))) + (if elem + (setcdr elem nnwarchive-headers) + (push (cons group nnwarchive-headers) + nnwarchive-headers-cache))))))) + +(defun nnwarchive-mail-archive-list () + (let ((case-fold-search t) + group description elem articles) + (goto-char (point-min)) + (while (re-search-forward "\\([^>]+\\)<" nil t) + (setq group (match-string 1) + description (match-string 2)) + (forward-line 1) + (setq articles 0) + (if (setq elem (assoc group nnwarchive-groups)) + (setcar (cdr elem) articles) + (push (list group articles description) nnwarchive-groups)))) + t) + +(defun nnwarchive-mail-archive-xover (group) + (let (article subject from date) + (goto-char (point-min)) + (while (re-search-forward + "]*HREF=\"msg\\([0-9]+\\)\\.html[^>]+>\\([^<]+\\)<" + nil t) + (setq article (1+ (string-to-number (match-string 1))) + subject (match-string 2)) + (forward-line 1) + (unless (assq article nnwarchive-headers) + (if (looking-at "