2 Before you start making additions to (Heirloom mailx and) S-nail,
3 subscribe to the development mailing list at
4 <https://lists.sourceforge.net/lists/listinfo/nail-devel>
5 to coordinate your efforts with the maintainer and other people.
7 Backward-compatibility breakers
8 -------------------------------
10 - Recipients specified on the command line should be added to those
11 specified in the message when the -t option is set.
13 - The -q option makes me sad as it doesn't use *indentprefix* for the
14 quoted file. So either there should be -Q which does so, or -q should be
15 changed. Also see ~R below.
16 [Note: i think i go for the latter. Please complain.]
18 - At least optionally disallow silent discarding of invalid addresses,
19 i.e., cause sending to be aborted if not all recipient addresses pass the
22 - Ditto if a resource file can't be found that has been explicitly set via
23 environment variables there should be some feedback.
25 - I.e., it is fine to be silent unless an error occurs, but then please
26 report errors and offer (in interactive mode) the possibility to act at
29 -- While there. There should be some kind of "verbose" switch that - in
30 interactive mode - also gives *positive* feedback, as in "added
31 attachment X, charset Y", but without giving details about protocol
34 [It is terrible that there is almost no feedback in the UI. When
35 i temporarily implemented a sorted cmdtab i've often used wrong commands,
36 but got no feedback at all! E.g., wanted to "undelete 14", first did "u
37 14", then "und 14" and then realized my fault and did "undelete 14".
40 - [v13:started] IIRC some error messages go to STDOUT, some to STDERR.
43 - POSIX says that, when written to DEAD: "If the file exists, the message
44 shall be written to replace the contents of the file". This is mentioned
45 for ASYNCHRONOUS EVENTS, but it's the only description of what should be
46 done in which way to DEAD. savedeadletter() yet appends. See ZOMBIE ,)
48 - Furthermore, *all* file operations yet append, even recipient target
49 files are appended. I don't know if this is really desirable behaviour,
50 but i have not thought about that for real. Maybe this should be at
53 - POP3 APOP availability is promoted by servers which support it.
54 The *pop3-use-apop* and *pop3-use-apop-user@host* variables should thus
55 be dropped. To support broken servers XY-no-apop-XY may be offered
58 - Maybe we should not use pipes to pagers at all.
59 This would also (beside getting rid of longjumps that cross allocations
60 afaik etc.) make it possible to honour the *crt* variable in respect
61 to what really is displayed, not in respect to message size.
62 It irritates me that a message with 5 visible lines but 115 header lines
63 goes through the pager, even if i have *crt=*.
64 P.S.: we could simply count the headers in addition?
66 - I'm in doubt wether the WANT_JUNK and WANT_SCORE features should
68 From a glance (also see
69 <http://article.gmane.org/gmane.mail.nail.devel/1568>) it doesn't look
70 promising, and i think it would be better if we could hook ourselfs
71 into SpamAssassin or similar software, than sitting on top of a small
72 locale, isolated closed-source database.
74 - The IMAP cache is file-based, which is quite nice, since a filesystem
75 is a database. On the other hand it may be better if we could hook
76 into sqlite3, which is available almost everywhere by default, with
77 a clearly documented DB content (so that users can use sqlite3(1) to
78 dig into it). (And just in case S-nail will ever be able to read news
79 and/or have MTA functionality.)
80 One question would be wether compression should be applied.
82 - We should possibly get away of using command line utilities for
83 compression. (At least optionally?) Instead we should link against
84 zlib(3), bz2lib(3) and lzma(3), if found. Or we may use dlopen(3)
85 instead, if found, to avoid linking (though those libraries don't need
86 much linker work unless actually used afaik, 'should look in detail).
87 We should also drop lzw.c, it is used for the Junk DB and the IMAP
93 - We need a "void" box that can be jumped to, i.e., a state in which no box
96 - (schdir(): realpath() local files before leaving CWD.., 2013-01-08)
97 did a first step to avoid "getting stuck" when the current folder becomes
99 That is however only a command-specific workaround for a deeper design
102 -- When a MBOX mailbox is removed while it is opened then changing the
103 folder is not possible. (At least when the only mail that was present
104 therein has been "move"d off that MBOX.) While trying this i got
105 a deallocation abort trap in lex.c:commands():385:
108 Note that Berkeley Mail (NetBSD mail(1) that is) seems to have the same
109 problem in respect to not allowing a hard-change, but only allows an exit
110 (not a quit thus). The error may still exist even there, it maybe that
111 it simply doesn't show up because a stack buffer is used ...
113 In interactive mode, dump the temporary file to the TMPDIR and inform the
114 user; it's up to him to decide what should happen.
116 Otherwise it must be possible to switch the folder (to the *void* one)
119 -- Also, when the folder is modified concurrently we should bail, or, in an
120 interactive session, prompt the user what to do.
122 - IDNA decoding. It may be that this will never be supported. But
123 wouldn't it be nice for at least viewing messages?
127 - Make it possible to reply to/save/write/xy part X.Y[.Z] by allowing its
128 specification directly, as in, e.g., ':w 1.2'. If doing so on an
129 embedded message/rfc822, e.g., a message embedded in a digest, it should
130 be possible to reply to the very message in respect to its header fields,
131 but (optionally?) keep the original Cc:'d. (Parts by Martin Neitzel)
133 -- In general i like the possibility of mutt(1) to toggle in between header
134 and header-ignore mode with a simple switch (h), and that *this toggle
135 is used when replying*. Yes i know mutt(1) sucks beside that in respect
136 to base64, MBOX, QP for CRLF files etc.
138 -- Also, mutt(1) quotes all text parts of a message, not only the first
139 one! This should at least be optionally available.
141 - If pipes fail for part viewers then at least the usual PART X.Y should be
142 shown, maybe even including some error message.
143 I had 'set pipe-text/html="lynx -dump -force_html /dev/stdin"' but NetBSD
144 does not have lynx(1), and i thought i've found a S-nail(1) bug.
147 = Update: (Change "Part X:" display message.., 2012-12-20) did one step,
148 but we need to rewrite the entire layers to handle that the separating
149 newline in between messages is considered to be part of it.
151 - I want to have a ~R tilde command that works like ~r except it performs
152 quoting of the input just as ~m does. Also see -q above.
154 - Offer the possibility to work with certificate fingerprints instead of
155 full certificates, in equal spirit to the current maintainers S-Postman
156 and Mercurial. S-nail(1) could simply offer something in equal spirit to
157 the formers --fingerprint, so that no other tool is necessary for
158 certificate management (for at least secure transport).
160 - It would be nice if it would be possible to define a format string for
161 *quote*, like 'set quote="format=some formats"'.
162 In general the current approach is somewhat messy IMO. I.e., it would
163 make more sense to act rather like mutt(1) and as written elsewhere in
164 this document, i.e., have some toggles that act on the display and use it
165 for multiple modes (show/reply/forward etc.)
166 Otherwise introduce commands which include all the headers plus, e.g.,
167 "hreply" or "freply", and then the ditto series, i.e., "hReply" ...
169 -- This would also mean that interactive message editing would work
172 - Deal with faulty message selection that may occur when selecting threads
173 via & (when at least mixed with other selectors).
175 -- Also the thread sort doesn't get
184 The current sort fails to recognize that F and the thread starting at
185 B are related, which results in a mess.
187 - Command line editing should gain possibility of context sensitive tab
190 -- Note that the TTY is sick. If ^C on input it simply jumps to next
191 input, instead of saying "Interrupted, one more to die hard" or
192 something (talking about ~@ charset selection prompts in particular).
194 - For those who use S-nail(1) only with a MTA it may be desirable to have
195 some "smopts" expansion mechanism in equal spirit to NetBSD mailx(1).
197 - While talking about NetBSD mailx(1), the author can imagine that being
198 able to use the optional -H:xy stuff is sometimes nice.
200 - Check against RFC 5322.
201 Rework all the header parsing code. Actually understand the content,
202 classify the stuff so that it matches what is defined in RFC dependent on
203 header field. Place the result in objects that know what they represent.
204 See the name extraction topic below.
206 - Also check against newest POSIX.
207 Maybe add a bash(1)ish POSIXLY_CORRECT (or so) variable? Though..
209 - Maybe there should be an additional ZOMBIE directive that is served in
210 equal spirit to DEAD, but that could be a valid MBOX... ?
211 What i want is a *real* resend, best if possible from command line.
212 Meaning, also the possibility to postpone a message. In general.
214 - POP3 doesn't support "newmail" for real. If implemented, should it sync?
215 Look at POP3 impl. in general..
217 - Having a newsreader would be a really cool thing.
219 - There should be a way to ignore the From_ line, as opposed to the From:
220 line, i.e., distinctively.
222 - There should be a variable that controls wether leading and trailing
223 empty lines of parts and/or messages as such should be printed or not.
225 - RFC 2387: multipart/related.
227 - Rewrite the make system again. makeconfig -> configure. Write the
228 Makefile anew, so that it doesn't contain any variables no more, i.e.,
229 fixate the first command line, so that a later 'make' recompiles
230 everything the very identical way. Also the manual, the resource file
231 etc., all that should be created by the first run.
233 - rfc2384.txt etc. I.e., Much better URL support.
235 - printhead()/hprf(): support %n newline format (%t tab?).
236 Make it possible to use the *datefield* algorithm for plain From_ derived
237 dates (needs a From_ parser, i.e., strptime()-alike).
238 Once we have that, rename *datefield-markout-older* to
239 *date-markout-older* ??
240 Note that NetBSD's mail(1) has some other nice things.
241 Note also that our code is quite unflexible.
243 -- NetBSD's mail(1) has nice *indentprefix* and *indentpostscript*
244 variables (though prefix and appendix or prefix and suffix, but..).
245 Note that our code is quite unflexible.
247 - The "top" command should honour ignoretab, or there should be a very
248 special "top" ignoretab. It simply doesn't make sense to "top" 5 lines
249 when all that you get are Received: lines...
251 - In the very end it is not that hard to add (optional) MTA
252 functionality at a most simple level.
253 Use sqlite for aliases (and possibly cache), then.
259 + [v13:messed up] Use NetBSD KNF in respect to parens for return+.
260 + [v13:started] Add C99-likeish typedefs and use them everywhere.
261 + [v13:started] Don't use magic constants/values.
262 + [v13:started] Use const arguments whenever possible. Yet started, but
263 with ugly casts at some places because this is a can of worms.
264 + Inline functions? [Restrict pointers?]
265 + [v13:started] Document the functions in the interface declarators.
266 + [v13:started] Resort the functions and where they are implemented.
267 + Make more use of struct str, and offer more support functions for it.
268 + Make more use of value carriers in the call stack. There are functions
269 with an incredible amount of arguments, needlessly.
270 ++ E.g., use a struct readlinectx.
271 + Ftemp(): offer an operation mode enum that includes "do-unlink".
272 In general: now there is O_CLOEXEC etc. ...
273 + Lazy install sigchild handler etc.
275 - [v13:started] Improve name extraction rules. And field parsing. There
276 are structured and unstructured fields. There are quoted pairs and
277 comments etc. Rewrite the entire parsing mechanism to comply to RFC
278 5322, and try to merge all those many subparsers around in the codebase,
279 and accordingly. So much duplicated work ...
280 Name parsing has been improved a bit for v13, but it's still broken.
281 yankword(), *extract(), etc.: RFC 5322 says that comments in address
282 fields SHOULD NOT be used (mutt(1) maps them to full name-addr forms if
283 approbiate, even if that actually changes content!!?), and that full
284 name-addr SHOULD be used. Our functions are yet quite silly (i.e.,
285 leading comments remain, as in "(bier2) <a2@b2.de>", unless the address
286 doesn't come in angle brackets, trailing go away, as in "<a6@b6.de>
287 (bier6)", that becomes "<a6@b6.de>").
289 (co$mm1) abc@däf.de (cö,mm,2) ('c'o"m"m.3)
290 Should eventually become
291 co$mm1 cö,mm,2 'c'o"m"m.3 <abc@xn--df-via.de>
292 on the display, or, with IDNA decoding (and thus rather unlikely)
293 co$mm1 cö,mm,2 'c'o"m"m.3 <abc@däf.de>
294 It should NOT become this mutt(1)ism:
295 "co$mm1 cö,mm,2 'c'omm.3" <abc@däf.de>
298 - Think about a name bypass hashmap cache, and whenever we have to skin or
299 nalloc() or whatever, look in there. Maybe even an additional link for
300 non GFULL(/GSKIN) and fully skinned struct name objects.
301 The amount of duplicated work in this codebase is frustrating, but the
302 real healing would make necessary a complete rewrite of the name handling!
303 Such a cache would work without touching the current code flow ... or
304 allow a smooth transition to a new one anyway.
306 - Think about a value() cache. (Yet added boption() and soption() stubs.)
308 - Think about replacing the IMAP cache with an SQLITE3 interface.
309 Or rewrite it. Error handling etc. etc. is peculiar.
311 - Check all Popen() calls, i've had the impressions that Popen() doesn't
312 close all resources on failure. Also, Popen() callers often do a lot of
313 work in respect to signals. Try to find a solution that all problems are
314 encapsulaten in Popen(), at least better than today.
316 - is_myname() shows it, others too - there are variables which are
317 interpreted, and those should be interpreted once they are assigned, not
318 over and over again. Even better: lazy evalution -- use a special lookup
319 method for those. The mentioned method should indeed even go away?
321 - The current codebase assumes that in multibyte encodings plain ASCII
322 characters can be tested "as-is". This assumption is wrong for some
323 encodings that use U+001B (escape) or another ASCII thing to introduce
324 shift states. The only real solution to this problem would be to rewrite
325 the entire codebase and use UTF-8 everywhere.
326 Unfortunately there is no standard way to do that.
328 - The char classification stuff can be improved; currently each character
329 has exactly one classification bit set, even if multiple would apply
330 (e.g., HT=\t == CNTRL|SPACE|ASCII|BLANK). This would allow better
331 testing using our own classification functions in quite some places.
333 - The quoted-printable Content-Transfer-Encoding: supports soft linebreaks;
334 it happens that a lot of mailers (Apple Mail?, Microsoft Word, Yahoo!
335 Webmail) create HTML parts which solely consist of a single line,
336 created via soft linebreaks.
337 To handle such mess we need to be able to break out of the input-line ==
338 output line relationship that is still fixated in the codebase.
339 I.e., it is not even sufficient to convert "rest" into an array, but best
340 would be if we would be able to sequentially work what we have, and
341 detect when it is safe to "dump that out".
343 - I want a clean PTF interface for the actual layers. There should be no
344 switch() statements around that test for the type of BOX that is
345 currently open. Especially important for possible NEWS support, but the
346 code is a mess in general...
348 - I hate longjmp()s and signals. I suspect some pitfalls in the codebase.
349 All that stuff should at least be collected in a single place.
351 I would like to see that compilation with a C++ compiler is possible,
352 though that would be a long way and be especially problematic due to the
353 (C ish) way enums are used.
355 - I never used anything but the *datefield* option, and it would really be
356 nice if the date strings would be parsed off into some 16 byte or what
357 storage when about to producing the summary, so that it would be directly
358 available and there would be no need to reread the mail. Moreover, or
359 even more than that - the m_date field exists and should possibly simply
360 be init, at least in these cases. (P.S.: this doesn't contradict the
361 statement somewhere else in this file that the structure should be
362 slacked; simply use multiple thereof or so)
364 - All error messages should not go to stderr but instead we should add our
365 own n_warn() family and use that. In the background we should have
366 a ring of error messages (oldest fall off), and a command that is capable
367 to display the ring. The command loop should recognize whenever an error
368 happened during the last command, and print something like "XY errors
369 occurred", followed by a (truncated as necessary) error report.
370 It simply doesn't make any sense to print errors on stderr if normal
371 output goes to stdout and scrolls it off the screen.
373 - Dramatically pimp the cc-test.sh script, and recognize and report
374 compilation errors, too.
375 WE NEED MORE AUTOMATIZED TESTING!
380 - Drop the restriction that environment variables cannot be modified
381 from within interactive S-nail(1), check carefully what depends on
382 that (findmail() looks for MAIL, be aware of -u interaction etc.).
383 Drop tempdir, myname and homedir variables and always use functions to
384 look the values up (just make them function local variables where
386 If necessary, add more hooks in vars.c:_check_special_vars() (or
387 finally implement the value cache for real).
388 Drop main.c:_setup_vars(), then.
390 - If we do link against OpenSSL, try to compile a test program and use
391 the OpenSSL version of MD5 if possible.
393 I think this is the right time to change our config/make system so that
394 the Makefile is generated with only those files which are actually
395 needed. Move the Makefile vars to user.conf.
397 (Possibly drop usage of compressions tools and link against the
398 compression libraries. Maybe dlopen() them? Otherwise leave that for
401 - Make *password* and *password-USER@HOST* global, introduce
402 *PROTOCOL-password* and *PROTOCOL-password-USER@HOST*.
403 Drop *smtp-auth-(user|pass...)*.
404 Then, drop smtp_auth_var(), and change lookup_password_for_token() to
405 work like (PROTOCOL, user,host|TOKEN) -- *password* is a global override,
406 only if that is not set lookup protocol specific.
407 Use that single function from everywhere.
409 - Change **use-starttls* to the opposite. I.e., CAPA or whatever, if TLS
410 is supported, use automatically. *UNLESS* explicitly disabled.
412 - Add a global *keepalive*, add *keepalive-USER@HOST*. Add and use
413 a generic, single function to get the value for either protocol.
415 - NOTE: we do not really support IPv6 sofar in that we are not prepared to
416 deal with IPv6 addresses.
417 Introduce an URI abstraction structure in 14.4, and start using it, i.e.,
418 _pop3_user() and, very important, sopen().
419 Note this shit software use a lot of places which mess around...
420 But be careful and test it, buddy.
422 - The account command involves a lot of code but it's only difference to
423 define is that a "fi" is executed. If we would have the possibility to
424 explicitly jump to VOID boxes, we could use QUIT->FOLDER instead of
425 FOLDER[OK? -> QUIT], and then it'd be up to the use to simply use a "fi"
426 at the end of a define. Or so.
428 -- If *folder* is set to an IMAP box, and we're about to "mbox" data to
429 there, and we're currently on a POP3 server, and the connection fails,
430 we're completely lost and cannot even interrupt...
432 - mutt(1) dotlock ..., "mbox" command doesn'T work?
434 - ARGH! Should `folders' auto-login if *folder* is an IMAP account that is
435 not active? Why does _expand() use *mailname* to expand `@', not
436 getfold() (care: res may point into cbuf, savestr() or so!).
437 Why does demail() etc. treat *mailname* as a file (more or less), why do
438 we need *mailname* at all; we should have Folder objects, multiple of
439 which concurrently, one the active; a Folder may not become *folder*
440 unless it has write (store) capabilities). Maybe then `mbox' works fine
441 if connected to a POP3 server with a *MBOX* on an IMAP account that yet
442 never was connected and needs to read a password on the terminal before
443 the login works ... note the latter situation yet kills us since i think
444 INT is blocked during all that ;-((
446 Release S-nail v20 on 2018-03-25, the 40th anniversary of Mail.
447 With a clean, conforming and efficient codebase, then.
449 vim:set fenc=utf-8 syntax=txt ts=2 sts=0 sw=2 et tw=75: