docs/master

view ch03.roff @ 19:ab5253e48c74

Wrote about the directory split. style: New macro for env vars.
author markus schnalke <meillo@marmaro.de>
date Tue, 24 Apr 2012 18:02:08 +0200
parents db3567c9cc3f
children 7a100c80fa91
line source
1 .H0 "Work Report
2 .P
3 foo
4 .P
5 bar
7 .H1 "Removal of Code Relicts
8 .P
9 The code base of mmh originates in the late 70s, had been extensively
10 worked on in the mid 80s, and had been partly reorganized and extended
11 in the 90s. Relicts of all those times had gathered in the code base.
12 My goal was to remove any ancient code parts. One part of the task was
13 converting obsolete code constructs to standard constructs, the other part
14 was dropping obsolete functions.
15 .P
16 As I'm not even thirty years old and have no more than seven years of
17 Unix experience, I needed to learn about the history in retroperspective.
18 Older people likely have used those ancient constructs themself
19 and have suffered from their incompatiblities and have longed for
20 standardization. Unfortunately, I have only read that others had done so.
21 This put me in a much more difficult positions when working on the old
22 code. I needed to recherche what other would have known by heart from
23 experience. All my programming experience comes from a time past ANSI C
24 and past POSIX. Although I knew about the times before, I took the
25 current state implicitely for granted most of the time.
26 .P
27 Being aware of
28 these facts, I rather let people with more historic experience solve the
29 task of converting the ancient code constructs to standardized ones.
30 Luckily, Lyndon Nerenberg focused on this task at the nmh project.
31 He converted large parts of the code to POSIX constructs, removing
32 the conditionals compilation for now standardized features.
33 I'm thankful for this task being solved. I only pulled the changes into
34 mmh.
35 .P
36 The other task of dropping ancient functionality to remove old code,
37 I did myself, though. My position to strip mmh to the bare minimum of
38 frequently used features is much more revolutional than the nmh community
39 sees it. Without the need to justify my decisions, I was able to quickly
40 remove code I considered ancient. The need to discuss my decisions with
41 peers likely would have slowed this process down. Of course, I did research
42 if a particular feature really should be dropped. Having not had any
43 contact to this feature within my computer life was a first indicator to
44 drop it, but I also asked others and searched the literature for modern
45 usage of the feature. If it appeared to be truly ancient, I dropped it.
46 The reason for dropping is always part of the commit message in the
47 version control system. Thus, it is easy for others to check their
48 view on the topic with mine and possibly to argue for reinclusion.
50 .U2 "MMDF maildrop support
51 .P
52 I did drop any support for the MMDF maildrop format. This type of format
53 is conceptionally similar to the mbox format, but uses four bytes with
54 value 1 (\fL^A^A^A^A\fP) as message delimiter,
55 instead of the string ``\fLFrom\ \fP''.
56 Due to the similarity and mbox being the de-facto standard maildrop
57 format on Unix, but also due to the larger influence of Sendmail than MMDF,
58 the MMDF maildrop format had vanished.
59 .P
60 The simplifications within the code were only moderate. Switches could
61 be removed from tools like
62 .L packf ,
63 which generate packed mailboxes. Only one packed mailbox format remained:
64 mbox.
65 The most important changes affect the equally named mail parsing routine in
66 .L sbr/m_getfld.c .
67 The direct MMDF code had been removed, but as now only one packed mailbox
68 format is left, code structure simplifications are likely possible.
69 The reason why they are still outstanding is the heavily optimized code
70 of
71 .Fu m_getfld() .
72 Changes beyond a small local scope \(en
73 which restructuring in its core is \(en cause a high risk of damaging
74 the intricate workings of the optimized code. This problem is know
75 to the developers of nmh, too. They also avoid touching this minefield
76 if possible.
78 .U2 "UUCP Bang Paths
79 .P
80 More questionably than the former topic is the removal of support for the
81 UUCP bang path address style. However, the user may translate the bang
82 paths on retrieval to Internet addresses and the other way on posting
83 messages. The former can be done my an MDA like procmail; the latter
84 by a sendmail wrapper. This would ensure that any address handling would
85 work as expected. However, it might just work well without any
86 such modifications, as mmh does not touch addresses much, in general.
87 But I can't ensure as I have never used an environment with bang paths.
88 Also, the behavior might break at any point in further development.
90 .U2 "Hardcopy terminal support
91 .P
92 More of a funny anecdote is the remaining of a check for printing to a
93 hardcopy terminal until Spring 2012, when I finally removed it.
94 I surely would be very happy to see such a terminal in action, maybe
95 actually being able to work on it, but I fear my chances are null.
96 .P
97 The check only prevented a pager to be placed between the outputting
98 program (\c
99 .Pn mhl )
100 and the terminal. This could have been ensured with
101 the
102 .Sw \-nomoreproc
103 at the command line statically, too.
105 .U2 "Removed support for header fields
106 .P
107 The `Encrypted' header had been introduced by RFC\^822, but already
108 marked legacy in RFC 2822. It was superseded by FIXME.
109 Mmh does no more support this header.
110 .P
111 `Content-MD5' headers were introduced by RFC\^1864. They provide only
112 a verification of data corruption during the transfer. By no means can
113 they ensure verbatim end-to-end delivery of the contents. This is clearly
114 stated in the RFC. The proper approach to provide verificationability
115 of content in an end-to-end relationship is the use of digital cryptography
116 (RFCs FIXME). On the other hand, transfer protocols should ensure the
117 integrity of the transmission. In combinations these two approaches
118 make the `Content-MD5' header field useless. In consequence, I removed
119 the support for it. By this removal, MD5 computation is not needed
120 anywhere in mmh. Hence, over 500 lines of code were removed by this one
121 change. Even if the `Content-MD5' header field is useful sometimes,
122 I value its usefulnes less than the improvement in maintainability, caused
123 by the removal.
126 .H1 "Draft and Trash Folders
127 .U2 "Draft Folder
128 .P
129 Historically, MH provided exactly one draft message, named
130 .Fn draft
131 and
132 being located in the MH directory. When starting to compose another message
133 before the former one was sent, the user had been questioned wether to use,
134 refile or replace the old draft. Working on multiple drafts at the same time
135 was impossible. One could only work on them in alteration by refiling the
136 previous one to some directory and fetching some other one for reediting.
137 This manual draft management needed to be done each time the user wanted
138 to switch between editing one draft to editing another.
139 .P
140 To allow true parallel editing of drafts, in a straight forward way, the
141 draft folder facility exists. It had been introduced already in July 1984
142 by Marshall T. Rose. The facility was deactivated by default.
143 Even in nmh, the draft folder facility remained deactivated by default.
144 At least, Richard Coleman added the man page
145 .Mp mh-draft(5)
146 to document
147 the feature well.
148 .P
149 The only advantage of not using the draft folder facility is the static
150 name of the draft file. This could be an issue for MH frontends like mh-e.
151 But as they likely want to provide working on multiple drafts in parallel,
152 the issue is only concerning compatibility. The aim of nmh to stay compatible
153 prevented the default activation of the draft folder facility.
154 .P
155 On the other hand, a draft folder is the much more natural concept than
156 a draft message. MH's mail storage consists of folders and messages,
157 the messages named with ascending numbers. A draft message breaks with this
158 concept by introducing a message in a file named
159 .Fn draft .
160 This draft
161 message is special. It can not be simply listed with the available tools,
162 but instead requires special switches. I.e. corner-cases were
163 introduced. A draft folder, in contrast, does not introduce such
164 corner-cases. The available tools can operate on the messages within that
165 folder like on any messages within any mail folders. The only difference
166 is the fact that the default folder for
167 .Pn send
168 is the draft folder,
169 instead of the current folder, like for all other tools.
170 .P
171 The trivial part of the change was activating the draft folder facility
172 by default and setting a default name for this folder. Obviously, I chose
173 the name
174 .Fn +drafts .
175 This made the
176 .Sw \-draftfolder
177 and
178 .Sw \-draftmessage
179 switches useless, and I could remove them.
180 The more difficult but also the part that showed the real improvement,
181 was updating the tools to the new concept.
182 .Sw \-draft
183 switches could
184 be dropped, as operating on a draft message became indistinguishable to
185 operating on any other message for the tools.
186 .Pn comp
187 still has its
188 .Sw \-use
189 switch for switching between its two modes: (1) Compose a new
190 draft, possibly by taking some existing message as a form. (2) Modify
191 an existing draft. In either case, the behavior of
192 .Pn comp is
193 deterministic. There is no more need to query the user. I consider this
194 a major improvement. By making
195 .Pn send
196 simply operate on the current
197 message in the draft folder by default, with message and folder both
198 overridable by specifying them on the command line, it is now possible
199 to send a draft anywhere within the storage by simply specifying its folder
200 and name.
201 .P
202 All theses changes converted special cases to regular cases, thus
203 simplifying the tools and increasing the flexibility.
205 .U2 "Trash Folder
206 .P
207 Similar to the situation for drafts is the situation for removed messages.
208 Historically, a message was deleted by renaming. A specific
209 \fIbackup prefix\fP, often comma (\c
210 .Fn , )
211 or hash (\c
212 .Fn # ),
213 being prepended to the file name. Thus, MH wouldn't recognize the file
214 as a message anymore, as only files whose name consists of digits only
215 are treated as messages. The removed messages remained as files in the
216 same directory and needed some maintenance job to truly delete them after
217 some grace time. Usually, by running a command similar to
218 .DS
219 find /home/user/Mail \-ctime +7 \-name ',*' | xargs rm
220 .DE
221 in a cron job. Within the grace time interval
222 the original message could be restored by stripping the
223 the backup prefix from the file name. If however, the last message of
224 a folder is been removed \(en say message
225 .Fn 6
226 becomes file
227 .Fn ,6
228 \(en and a new message enters the same folder, thus the same
229 numbered being given again \(en in our case
230 .Fn 6
231 \(en, if that one
232 is removed too, then the backup of the former message gets overwritten.
233 Thus, the ability to restore removed messages does not only depend on
234 the ``sweeping cron job'' but also on the removing of further messages.
235 This is undesireable, because the real mechanism is hidden from the user
236 and the concequences of further removals are not always obvious.
237 Further more, the backup files are scattered within the whole mail
238 storage, instead of being collected at one place.
239 .P
240 To improve the situation, the profile entry
241 .Pe rmmproc
242 (previously named
243 .Pe Delete-Prog )
244 was introduced, very early.
245 It could be set to any command, which would care for the mail removal
246 instead of taking the default action, described above.
247 Refiling the to-be-removed files to some wastebin folder was a common
248 example. Nmh's man page
249 .Mp rmm(1)
250 proposes
251 .Cl "refile +d
252 to move messages to the wastebin and
253 .Cl "rm `mhpath +d all`
254 the empty the wastebin.
255 Managing the message removal this way is a sane approach. It keeps
256 the removed messages in one place, makes it easy to remove the backup
257 files, and, most important, enables the user to use the tools of MH
258 itself to operate on the removed messages. One can
259 .Pn scan
260 them,
261 .Pn show
262 them, and restore them with
263 .Pn refile .
264 There's no more
265 need to use
266 .Pn mhpath
267 to switch over from MH tools to Unix tools \(en MH can do it all itself.
268 .P
269 This apporach matches perfect with the concepts of MH, thus making
270 it powerful. Hence, I made it the default. And even more, I also
271 removed the old backup prefix approach, as it is clearly less powerful.
272 Keeping unused alternative in the code is a bad choice as they likely
273 gather bugs, by not being constantly tested. Also, the increased code
274 size and more conditions crease the maintenance costs. By strictly
275 converting to the trash folder approach, I simplified the code base.
276 .Pn rmm
277 calls
278 .Pn refile
279 internally to move the to-be-removed
280 message to the trash folder (\c
281 .Fn +trash
282 by default). Messages
283 there can be operated on like on any other message in the storage.
284 The sweep clean, one can use
285 .Cl "rmm \-unlink +trash a" ,
286 where the
287 .Sw \-unlink
288 switch causes the files to be truly unliked instead
289 of moved to the trash folder.
292 .H1 "MH Directory Split
293 .P
294 In MH and nmh, a personal setup had consisted of two parts:
295 The MH profile, named
296 .Fn \&.mh_profile
297 and being located directly in the user's home directory.
298 And the MH directory, where all his mail messages and also his personal
299 forms, scan formats, other configuration files are stored. The location
300 of this directory could be user-chosen. The default was to name it
301 .Fn Mail
302 and have it directly in the home directory.
303 .P
304 I've never liked the data storage and the configuration to be intermixed.
305 They are different kinds of data. One part, are the messages,
306 which are the data to operate on. The other part, are the personal
307 configuration files, which are able to change the behavior of the operations.
308 The actual operations are defined in the profile, however.
309 .P
310 When storing data, one should try to group data by its type.
311 There's sense in the Unix file system hierarchy, where configuration
312 file are stored separate (\c
313 .Fn /etc )
314 to the programs (\c
315 .Fn /bin
316 and
317 .Fn /usr/bin )
318 to their sources (\c
319 .Fn /usr/src ).
320 Such separation eases the backup management, for instance.
321 .P
322 In mmh, I've reorganized the file locations.
323 Still there are two places:
324 There's the mail storage directory, which, like in MH, contains all the
325 messages, but, unlike in MH, nothing else.
326 Its location still is user-chosen, with the default name
327 .Fn Mail ,
328 in the user's home directory. This is much similar to the case in nmh.
329 The configuration files, however, are grouped together in the new directory
330 .Fn \&.mmh
331 in the user's home directory.
332 The user's profile now is a file, named
333 .Fn profile ,
334 in this mmh directory.
335 Consistently, the context file and all the personal forms, scan formats,
336 and the like, are also there.
337 .P
338 The naming changed with the relocation.
339 The directory where everything, except the profile, had been stored (\c
340 .Fn $HOME/Mail ),
341 used to be called \fIMH directory\fP. Now, this directory is called the
342 user's \fImail storage\fP. The name \fImmh directory\fP is now given to
343 the new directory
344 (\c
345 .Fn $HOME/.mmh ),
346 containing all the personal configuration files.
347 .P
348 The separation of the files by type of content is logical and convenient.
349 There are no functional differences as any possible setup known to me
350 can be implemented with both approaches, although likely a bit easier
351 with the new approach. The main goal of the change had been to provide
352 sensible storage locations for any type of personal mmh file.
353 .P
354 In order for one user to have multiple MH setups, he can use the
355 environment variable
356 .Ev MH
357 the point to a different profile file.
358 The MH directory (mail storage plus personal configuration files) is
359 defined by the
360 .Pe Path
361 profile entry.
362 The context file could be defined by the
363 .Pe context
364 profile entry or by the
365 .Ev MHCONTEXT
366 environment variable.
367 The latter is useful to have a distinct context (e.g. current folders)
368 in each terminal window, for instance.
369 In mmh, there are three environment variables now.
370 .Ev MMH
371 may be used to change the location of the mmh directory.
372 .Ev MMHP
373 and
374 .Ev MMHC
375 change the profile and context files, respectively.
376 Besides providing a more consistent feel (which simply is the result
377 of being designed anew), the set of personal configuration files can
378 be chosen independently from the profile (including mail storage location)
379 and context, now. Being it relevant for practical use or not, it
380 de-facto is an improvement. However, the main achievement is the
381 split between mail storage and personal configuration files.
384 .H1 "Path Notations
385 .P
386 foo
388 .H1 "Attachments
389 .P
390 foo
392 .H1 "Blind Carbon Copies
393 .P
394 foo
396 .H1 "Good Defaults
397 .P
398 foo
400 .H1 "Modularization
401 .P
402 foo
404 .H1 "Code style
405 .P
406 foo