Mercurial > docs > master
view ch03.roff @ 17:b3c37947764e
Several minor text improvements.
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Sun, 22 Apr 2012 17:16:30 +0200 |
parents | 81f703140554 |
children | db3567c9cc3f |
line wrap: on
line source
.H0 "Work Report .P foo .P bar .H1 "Removal of Code Relicts .P The code base of mmh originates in the late 70s, had been extensively worked on in the mid 80s, and had been partly reorganized and extended in the 90s. Relicts of all those times had gathered in the code base. My goal was to remove any ancient code parts. One part of the task was converting obsolete code constructs to standard constructs, the other part was dropping obsolete functions. .P As I'm not even thirty years old and have no more than seven years of Unix experience, I needed to learn about the history in retroperspective. Older people likely have used those ancient constructs themself and have suffered from their incompatiblities and have longed for standardization. Unfortunately, I have only read that others had done so. This put me in a much more difficult positions when working on the old code. I needed to recherche what other would have known by heart from experience. All my programming experience comes from a time past ANSI C and past POSIX. Although I knew about the times before, I took the current state implicitely for granted most of the time. .P Being aware of these facts, I rather let people with more historic experience solve the task of converting the ancient code constructs to standardized ones. Luckily, Lyndon Nerenberg focused on this task at the nmh project. He converted large parts of the code to POSIX constructs, removing the conditionals compilation for now standardized features. I'm thankful for this task being solved. I only pulled the changes into mmh. .P The other task of dropping ancient functionality to remove old code, I did myself, though. My position to strip mmh to the bare minimum of frequently used features is much more revolutional than the nmh community sees it. Without the need to justify my decisions, I was able to quickly remove code I considered ancient. The need to discuss my decisions with peers likely would have slowed this process down. Of course, I did research if a particular feature really should be dropped. Having not had any contact to this feature within my computer life was a first indicator to drop it, but I also asked others and searched the literature for modern usage of the feature. If it appeared to be truly ancient, I dropped it. The reason for dropping is always part of the commit message in the version control system. Thus, it is easy for others to check their view on the topic with mine and possibly to argue for reinclusion. .U2 "MMDF maildrop support .P I did drop any support for the MMDF maildrop format. This type of format is conceptionally similar to the mbox format, but uses four bytes with value 1 (\fL^A^A^A^A\fP) as message delimiter, instead of the string ``\fLFrom\0\fP''. Due to the similarity and mbox being the de-facto standard maildrop format on Unix, but also due to the larger influence of Sendmail than MMDF, the MMDF maildrop format had vanished. .P The simplifications within the code were only moderate. Switches could be removed from tools like .L packf , which generate packed mailboxes. Only one packed mailbox format remained: mbox. The most important changes affect the equally named mail parsing routine in .L sbr/m_getfld.c . The direct MMDF code had been removed, but as now only one packed mailbox format is left, code structure simplifications are likely possible. The reason why they are still outstanding is the heavily optimized code of \fLm_getfld()\fP. Changes beyond a small local scope \(en which restructuring in its core is \(en cause a high risk of damaging the intricate workings of the optimized code. This problem is know to the developers of nmh, too. They also avoid touching this minefield if possible. .U2 "UUCP Bang Paths .P More questionably than the former topic is the removal of support for the UUCP bang path address style. However, the user may translate the bang paths on retrieval to Internet addresses and the other way on posting messages. The former can be done my an MDA like procmail; the latter by a sendmail wrapper. This would ensure that any address handling would work as expected. However, it might just work well without any such modifications, as mmh does not touch addresses much, in general. But I can't ensure as I have never used an environment with bang paths. Also, the behavior might break at any point in further development. .U2 "Hardcopy terminal support .P More of a funny anecdote is the remaining of a check for printing to a hardcopy terminal until Spring 2012, when I finally removed it. I surely would be very happy to see such a terminal in action, maybe actually being able to work on it, but I fear my chances are null. .P The check only prevented a pager to be placed between the outputting program (\fLmhl\fP) and the terminal. This could have been ensured with the \fL-nomoreproc\fP at the command line statically, too. .U2 "Removed support for header fields .P The `Encrypted' header had been introduced by RFC\^822, but already marked legacy in RFC 2822. It was superseded by FIXME. Mmh does no more support this header. .P `Content-MD5' headers were introduced by RFC\^1864. They provide only a verification of data corruption during the transfer. By no means can they ensure verbatim end-to-end delivery of the contents. This is clearly stated in the RFC. The proper approach to provide verificationability of content in an end-to-end relationship is the use of digital cryptography (RFCs FIXME). On the other hand, transfer protocols should ensure the integrity of the transmission. In combinations these two approaches make the `Content-MD5' header field useless. In consequence, I removed the support for it. By this removal, MD5 computation is not needed anywhere in mmh. Hence, over 500 lines of code were removed by this one change. Even if the `Content-MD5' header field is useful sometimes, I value its usefulnes less than the improvement in maintainability, caused by the removal. .H1 "Draft and Trash Folders .U2 "Draft Folder .P Historically, MH provided exactly one draft message, named `\fLdraft\fP' and being located in the MH directory. When starting to compose another message before the former one was sent, the user had been questioned wether to use, refile or replace the old draft. Working on multiple drafts at the same time was impossible. One could only work on them in alteration by refiling the previous one to some directory and fetching some other one for reediting. This manual draft management needed to be done each time the user wanted to switch between editing one draft to editing another. .P To allow true parallel editing of drafts, in a straight forward way, the draft folder facility exists. It had been introduced already in July 1984 by Marshall T. Rose. The facility was deactivated by default. Even in nmh, the draft folder facility remained deactivated by default. At least, Richard Coleman added the man page \fImh-draft(5)\fP to document the feature well. .P The only advantage of not using the draft folder facility is the static name of the draft file. This could be an issue for MH frontends like mh-e. But as they likely want to provide working on multiple drafts in parallel, the issue is only concerning compatibility. The aim of nmh to stay compatible prevented the default activation of the draft folder facility. .P On the other hand, a draft folder is the much more natural concept than a draft message. MH's mail storage consists of folders and messages, the messages named with ascending numbers. A draft message breaks with this concept by introducing a message in a file named ``\fLdraft\fP''. This draft message is special. It can not be simply listed with the available tools, but instead requires special switches. I.e. corner-cases were introduced. A draft folder, in contrast, does not introduce such corner-cases. The available tools can operate on the messages within that folder like on any messages within any mail folders. The only difference is the fact that the default folder for \fLsend\fP is the draft folder, instead of the current folder, like for all other tools. .P The trivial part of the change was activating the draft folder facility by default and setting a default name for this folder. Obviously, I chose the name ``\fL+drafts\fP''. This made the \fL\-draftfolder\fP and \fL\-draftmessage\fP switches useless, and I could remove them. The more difficult but also the part that showed the real improvement, was updating the tools to the new concept. \fL\-draft\fP switches could be dropped, as operating on a draft message became indistinguishable to operating on any other message for the tools. \fLcomp\fP still has its \fL\-use\fP switch for switching between its two modes: (1) Compose a new draft, possibly by taking some existing message as a form. (2) Modify an existing draft. In either case, the behavior of \fLcomp\fP is deterministic. There is no more need to query the user. I consider this a major improvement. By making \fLsend\fP simply operate on the current message in the draft folder by default, with message and folder both overridable by specifying them on the command line, it is now possible to send a draft anywhere within the storage by simply specifying its folder and name. .P All theses changes converted special cases to regular cases, thus simplifying the tools and increasing the flexibility. .U2 "Trash Folder .P Similar to the situation for drafts is the situation for removed messages. Historically, a message was deleted by renaming. A specific \fIbackup prefix\fP, often comma (\fL,\fP) or hash (\fL#\fP), being prepended to the file name. Thus, MH wouldn't recognize the file as a message anymore, as only files whose name consists of digits only are treated as messages. The removed messages remained as files in the same directory and needed some maintenance job to truly delete them after some grace time. Usually, by running a command similar to .DS find /home/user/Mail \-ctime +7 \-name ',*' | xargs rm .DE in a cron job. Within the grace time interval the original message could be restored by stripping the the backup prefix from the file name. If however, the last message of a folder is been removed \(en say message `\fL6\fP' becomes file `\fL,6\fP' \(en and a new message enters the same folder, thus the same numbered being given again \(en in our case `\fL6\fP' \(en, if that one is removed too, then the backup of the former message gets overwritten. Thus, the ability to restore removed messages does not only depend on the ``sweeping cron job'' but also on the removing of further messages. This is undesireable, because the real mechanism is hidden from the user and the concequences of further removals are not always obvious. Further more, the backup files are scattered within the whole mail storage, instead of being collected at one place. .P To improve the situation, the profile entry \fIrmmproc\fP (previously named \fIDelete-Prog\fP) was introduced, very early. It could be set to any command, which would care for the mail removal instead of taking the default action, described above. Refiling the to-be-removed files to some wastebin folder was a common example. Nmh's man page for \fLrmm(1)\fP proposes `\fLrefile +d\fP' to move messages to the wastebin and `\fLrm `mhpath +d all`\fP' the empty the wastebin. Managing the message removal this way is a sane approach. It keeps the removed messages in one place, makes it easy to remove the backup files, and, most important, enables the user to use the tools of MH itself to operate on the removed messages. One can \fLscan\fP them, \fLshow\fP them, and restore them with \fLrefile(1)\fP. There's no more need to use \fLmhpath\fP to switch over from MH tools to Unix tools \(en MH can do it all itself. .P This apporach is matches perfect with the concepts of MH, thus making it powerful. Hence, I made it the default. And even more, I also removed the old backup prefix approach, as it is clearly less powerful. Keeping unused alternative in the code is a bad choice as they likely gather bugs, by not being constantly tested. Also, the increased code size and more conditions crease the maintenance costs. By strictly converting to the trash folder approach, I simplified the code base. \fLrmm(1)\fP calls \fLrefile(1)\fP internally to move the to-be-removed message to the trash folder (`\fL+trash\fP' by default). Messages there can be operated on like on any other message in the storage. The sweep clean, one can use `\fLrmm \-unlink +trash a\fP', where the `\fL\-unlink\fP' switch causes the files to be truly unliked instead of moved to the trash folder. .H1 "MH Directory Split .P .H1 "Path Notations .P foo .H1 "Attachments .P foo .H1 "Blind Carbon Copies .P foo .H1 "Good Defaults .P foo .H1 "Modularization .P foo .H1 "Code style .P foo