| 1 |
<!-- Automagically generated by the ToDo program on Thu Jun 23 13:18:43 2005 --> |
| 2 |
<todo version="0.1.18"> |
| 3 |
<title> |
| 4 |
Postmaster |
| 5 |
</title> |
| 6 |
<note priority="veryhigh" time="1099264722" done="1099303821"> |
| 7 |
figure out why mailid is assigned twice for mail from:<> |
| 8 |
<comment> |
| 9 |
fixed bug in impatient |
| 10 |
</comment> |
| 11 |
</note> |
| 12 |
<note priority="veryhigh" time="1107927331" done="1107978554"> |
| 13 |
read timeouts currently are behind 'safe' |
| 14 |
<comment> |
| 15 |
fixed |
| 16 |
</comment> |
| 17 |
</note> |
| 18 |
<note priority="veryhigh" time="1108001576" done="1108047273"> |
| 19 |
process crashes when spool file is erased |
| 20 |
<comment> |
| 21 |
fixed |
| 22 |
</comment> |
| 23 |
</note> |
| 24 |
<note priority="veryhigh" time="1108043262" done="1108047347"> |
| 25 |
What SessionState are we in when StartData fails? |
| 26 |
<comment> |
| 27 |
handleDialog will set HaveHelo |
| 28 |
</comment> |
| 29 |
</note> |
| 30 |
<note priority="high" time="1098655722" done="1098737399"> |
| 31 |
Handler needs a Handler(Status|State) field in Target. |
| 32 |
<comment> |
| 33 |
Implemented. We know have 5 handler status |
| 34 |
codes: Ready, Live, Succeeded, Failed, |
| 35 |
FailedPermanently. The Deliver event uses them |
| 36 |
to determine correct SmtpReply. The semantics |
| 37 |
are: If one target is okay, the whole data |
| 38 |
transaction is okay. If all fail permanently, |
| 39 |
the transaction fails permanently. Otherwise the |
| 40 |
transaction falis with a 4xx code. |
| 41 |
</comment> |
| 42 |
</note> |
| 43 |
<note priority="high" time="1098656254" done="1107927357"> |
| 44 |
We need a spooler. |
| 45 |
|
| 46 |
If the external handler returns an error, we cannot |
| 47 |
create a bounce message because we don't have the |
| 48 |
payload anymore! With sendmail as backend, this |
| 49 |
doesn't matter because sendmail does bounce the mail |
| 50 |
in case of an error, but we rather soon need a |
| 51 |
spooler that writes everything to disk, just in |
| 52 |
case. From there, a spool manager could retry |
| 53 |
delivery, etc. |
| 54 |
<comment> |
| 55 |
done |
| 56 |
</comment> |
| 57 |
</note> |
| 58 |
<note priority="high" time="1098658162" done="1099014967"> |
| 59 |
Need combinators to create targets (fwd, alias, etc.) |
| 60 |
<comment> |
| 61 |
done: 'relay' and 'pipe' |
| 62 |
</comment> |
| 63 |
</note> |
| 64 |
<note priority="high" time="1098924318" done="1107739248"> |
| 65 |
smtpdMain has to protect accept with 'bracket' |
| 66 |
<comment> |
| 67 |
accept looks safe now for all practical purposes |
| 68 |
</comment> |
| 69 |
</note> |
| 70 |
<note priority="high" time="1099253001" done="1107978575"> |
| 71 |
Start shells with "set +e". |
| 72 |
<comment> |
| 73 |
we don't start shells anymore |
| 74 |
</comment> |
| 75 |
</note> |
| 76 |
<note priority="high" time="1099253334" done="1107534743"> |
| 77 |
Replace Val with Data.Dynamic |
| 78 |
<comment> |
| 79 |
code moved to MonadEnv module |
| 80 |
</comment> |
| 81 |
</note> |
| 82 |
<note priority="high" time="1099253516" done="1107739100"> |
| 83 |
Model a generic stream processor through a Stream a datatype! |
| 84 |
<comment> |
| 85 |
Unnecessary with the new design. |
| 86 |
</comment> |
| 87 |
</note> |
| 88 |
<note priority="medium" time="1098325598" done="1098585670"> |
| 89 |
Does the eventHandler have to set sessionState? |
| 90 |
<comment> |
| 91 |
No, it does not. handleDialog and handleData set |
| 92 |
the sessionState according to the results of |
| 93 |
smtpdFSM. The user callbacks should not (and in |
| 94 |
fact cannot) interfere. |
| 95 |
</comment> |
| 96 |
</note> |
| 97 |
<note priority="medium" time="1098329354" done="1107739271"> |
| 98 |
Log timeouts where they occur, not in runSmtpd. |
| 99 |
<comment> |
| 100 |
Nope, we use safeWrite combinator now. |
| 101 |
</comment> |
| 102 |
</note> |
| 103 |
<note priority="medium" time="1098329496" done="1098585655"> |
| 104 |
Add "Greeting" event. |
| 105 |
<comment> |
| 106 |
Done. The event is triggered by runSmtpd before |
| 107 |
anything else happens. It can be used to |
| 108 |
initialize the SmtpdState for the rest of the |
| 109 |
session. |
| 110 |
</comment> |
| 111 |
</note> |
| 112 |
<note priority="medium" time="1098713602" done="1098738894"> |
| 113 |
If "greeting" returns failure code, abort the connection. |
| 114 |
<comment> |
| 115 |
Implemented. Anything but 2xx will cause |
| 116 |
runSmtpd to drop the connection. |
| 117 |
</comment> |
| 118 |
</note> |
| 119 |
<note priority="medium" time="1098748188" done="1107978651"> |
| 120 |
Avoid zombie processes by waiting for the child |
| 121 |
|
| 122 |
The changes in commitTarget (safeGetExitCode instead |
| 123 |
of waitForProcess) should fix that. |
| 124 |
|
| 125 |
There remains the case of the process aborting |
| 126 |
abnormally, or the I/O thread that holds the handle |
| 127 |
received an exception. I have a finalizer attached |
| 128 |
to the ExternHandle, which will kill, then wait for |
| 129 |
the child. Will see whether that helps. |
| 130 |
<comment> |
| 131 |
fixed in new architecture |
| 132 |
</comment> |
| 133 |
</note> |
| 134 |
<note priority="medium" time="1098894546" done="1107927427"> |
| 135 |
'smtpdMain' should expect a Socket, not a PortID. |
| 136 |
<comment> |
| 137 |
smtpdServer can run from any socket now |
| 138 |
</comment> |
| 139 |
</note> |
| 140 |
<note priority="medium" time="1098939046" done="1099015643"> |
| 141 |
I need a better shutdown mechanism than fail |
| 142 |
<comment> |
| 143 |
done: reply 221 and 421 will drop the connection |
| 144 |
</comment> |
| 145 |
</note> |
| 146 |
<note priority="medium" time="1098944687" done="1107927451"> |
| 147 |
need debugEH-like wrapper to dump the environment |
| 148 |
<comment> |
| 149 |
isn't trivially possible with Env anymory |
| 150 |
</comment> |
| 151 |
</note> |
| 152 |
<note priority="medium" time="1099011048" done="1107927633"> |
| 153 |
Need CRLF conversion for local mailers. |
| 154 |
|
| 155 |
I have to convert CRLF to LF because some programs, |
| 156 |
like procmail, don't understand CRLF-ended lines. |
| 157 |
This is a job for the dataHandler, obviously. I just |
| 158 |
wonder how to trigger it! For every pipe? Just for |
| 159 |
procmail? Or do nothing and have people call |
| 160 |
|
| 161 |
#! /bin/sh -- |
| 162 |
sed -e 's/^M$//' | /usr/bin/procmail $* |
| 163 |
|
| 164 |
instead? I need a more flexible Target type. There's |
| 165 |
no way around it. Ideally, a Target could be written |
| 166 |
completely outside of Postmaster, then this were the |
| 167 |
user's problem and not mine. That's the way to do |
| 168 |
it. |
| 169 |
<comment> |
| 170 |
no more local mailers |
| 171 |
</comment> |
| 172 |
</note> |
| 173 |
<note priority="medium" time="1099013220" done="1099093120"> |
| 174 |
Need 'closeTarget' to run before 'commitTarget'. |
| 175 |
<comment> |
| 176 |
implemented |
| 177 |
</comment> |
| 178 |
</note> |
| 179 |
<note priority="medium" time="1099252968" done="1107739350"> |
| 180 |
write ts :: EnvT a -> EnvT (Timestamped a) |
| 181 |
<comment> |
| 182 |
Not possible because EnvT is not bound to one variable. |
| 183 |
</comment> |
| 184 |
</note> |
| 185 |
<note priority="medium" time="1107470824" done="1107534805"> |
| 186 |
replace error with fail wherever possible |
| 187 |
<comment> |
| 188 |
done |
| 189 |
</comment> |
| 190 |
</note> |
| 191 |
<note priority="medium" time="1107743614" done="1107978607"> |
| 192 |
smtpd has to check SessionState between lines! |
| 193 |
<comment> |
| 194 |
No, according to the RFC our pipelining is fine. |
| 195 |
</comment> |
| 196 |
</note> |
| 197 |
<note priority="medium" time="1108001616" done="1108052981"> |
| 198 |
don't export feed and other internals in FSM.* |
| 199 |
<comment> |
| 200 |
Well, let's expert feed. Whatever. |
| 201 |
</comment> |
| 202 |
</note> |
| 203 |
<note priority="low" time="1098627718" done="1107927500"> |
| 204 |
Do "performGC >> yield" when resources run out. |
| 205 |
|
| 206 |
Although a Handle is garbage-collected in Haskell, |
| 207 |
it is not clear when the appropriate finalizer will |
| 208 |
be run! Thus, it might be a good idea to trigger an |
| 209 |
explicit garbage collection in case we've received |
| 210 |
an exception which signifies that system resources |
| 211 |
are unavailable. This applies to all kind of |
| 212 |
finalizer-based resource management. The only case |
| 213 |
in which the RTS will run the GC itself is when |
| 214 |
memory runs out. But other resources (file |
| 215 |
descriptors, etc.) don't do that. |
| 216 |
<comment> |
| 217 |
we don't use finalizers anymore |
| 218 |
</comment> |
| 219 |
</note> |
| 220 |
<note priority="low" time="1098732401" done="1107739182"> |
| 221 |
Need a sub-monad class. |
| 222 |
|
| 223 |
I need a class which handles the case where the |
| 224 |
state of the outer monad contains the state of the |
| 225 |
inner monad. The class would contain glue code |
| 226 |
telling me how to get/put the state into the outer |
| 227 |
monads data type, and then a simple 'run' should |
| 228 |
suffice to call all sub-monads. |
| 229 |
|
| 230 |
Declaring "MonadState st" for every contained state |
| 231 |
might do the trick, but I need to allow undecidable |
| 232 |
instances to do that. |
| 233 |
|
| 234 |
instance (MonadState Config m) |
| 235 |
=> MonadReader Callbacks m where |
| 236 |
<comment> |
| 237 |
New design made this unnecessary. |
| 238 |
</comment> |
| 239 |
</note> |
| 240 |
<note priority="low" time="1098754939" done="1107978635"> |
| 241 |
waitForProcess throws exceptions I have to catch |
| 242 |
|
| 243 |
Glynn Clements writes: |
| 244 |
|
| 245 |
> Both [getProcessExitCode and waitForProcess] |
| 246 |
> will throw an exception if the process |
| 247 |
> terminated on a signal. |
| 248 |
|
| 249 |
I've fixed it now, I think. It is horrible: |
| 250 |
'safeWaitForProcess' basically busy-polls the status |
| 251 |
every 1/10 second with a 'timeout' and 'catch' |
| 252 |
wrapped around the whole computation. Processes that |
| 253 |
are terminated by signals will be mapped to "exit 1". |
| 254 |
|
| 255 |
It appears to be robust so far. |
| 256 |
<comment> |
| 257 |
The entire 'extern' stuff is gone. |
| 258 |
</comment> |
| 259 |
</note> |
| 260 |
<note priority="low" time="1099006932" done="1107927587"> |
| 261 |
Batch procmail calls. |
| 262 |
|
| 263 |
Procmail's -d option allows more than one recipient. |
| 264 |
I need to support that in a useful way, but the |
| 265 |
current Target definition doesn't allow me to batch |
| 266 |
it, because -- in the general case -- I cannot batch |
| 267 |
pipe. |
| 268 |
<comment> |
| 269 |
obsolete with spooler |
| 270 |
</comment> |
| 271 |
</note> |
| 272 |
<note priority="low" time="1099253109" done="1107927617"> |
| 273 |
write combinator to catchALL and log all state etc. to disk |
| 274 |
<comment> |
| 275 |
duplicate of #28 |
| 276 |
</comment> |
| 277 |
</note> |
| 278 |
<note priority="verylow" time="1099158901" done="1107739414"> |
| 279 |
Generally prefix internal functions with _. |
| 280 |
<comment> |
| 281 |
Nope. Don't export internal functions. |
| 282 |
</comment> |
| 283 |
</note> |
| 284 |
<note priority="verylow" time="1099253172" done="1107927475"> |
| 285 |
A 'fallback' combinator: "try f e $ either default return" or so |
| 286 |
<comment> |
| 287 |
implemented on top of catch |
| 288 |
</comment> |
| 289 |
</note> |
| 290 |
<note priority="veryhigh" time="1113867878"> |
| 291 |
feeder doesn't flush '(CRLF).CRLF'. |
| 292 |
</note> |
| 293 |
<note priority="veryhigh" time="1113868224"> |
| 294 |
handlePayload loses path to temporary file |
| 295 |
</note> |
| 296 |
<note priority="high" time="1108052773"> |
| 297 |
Handle sha1 collisions in the spool |
| 298 |
</note> |
| 299 |
<note priority="high" time="1108680373"> |
| 300 |
shutdown must be called by bracket |
| 301 |
</note> |
| 302 |
<note priority="medium" time="1098589904"> |
| 303 |
Need combinator to catch and log the usual exceptions. |
| 304 |
</note> |
| 305 |
<note priority="medium" time="1098656105"> |
| 306 |
Add an "InetAddress" type for IPv4 and v6 addresses. |
| 307 |
|
| 308 |
Also, a class interface which allows to convert all |
| 309 |
kinds of IP-address representations hence and forth |
| 310 |
between my type and HostAddr, SockAddr, etc. |
| 311 |
</note> |
| 312 |
<note priority="medium" time="1098726128"> |
| 313 |
Need function to generate received headers |
| 314 |
</note> |
| 315 |
<note priority="medium" time="1100044460"> |
| 316 |
deny private addresses (as mx, too) |
| 317 |
</note> |
| 318 |
<note priority="medium" time="1107998544"> |
| 319 |
Move stuff from IO to FSM.Timeout |
| 320 |
</note> |
| 321 |
<note priority="low" time="1098656192"> |
| 322 |
Find out how RTS settings affect the performance. |
| 323 |
|
| 324 |
Does the event handler benefit from caching? Or do |
| 325 |
we benefit from aggressive GC because it keeps our |
| 326 |
memory footprint small and ensures all finalizers |
| 327 |
are run quickly? (Currently, only ExternalHandle |
| 328 |
depends on finalizers.) |
| 329 |
</note> |
| 330 |
<note priority="low" time="1099252878"> |
| 331 |
Make a prologue file for the haddock index page. |
| 332 |
</note> |
| 333 |
<note priority="low" time="1104539876"> |
| 334 |
Need way to accept _all_ e-mail from trusted peers to avoid bounces. |
| 335 |
</note> |
| 336 |
<note priority="low" time="1119525523"> |
| 337 |
Get rid of bracketOnError in Postmaster.Base. |
| 338 |
</note> |
| 339 |
<note priority="verylow" time="1097188529"> |
| 340 |
Format log messages and map them to priorities. |
| 341 |
</note> |
| 342 |
</todo> |