diff --git a/src/lib/maildir.nim b/src/lib/maildir.nim index e94114a..cd08383 100644 --- a/src/lib/maildir.nim +++ b/src/lib/maildir.nim @@ -1,6 +1,7 @@ # vim: set et nosta sw=4 ts=4 : # -# A class that represents an individual Maildir. +# A class that represents an individual Maildir, and a Nessage class to nanage +# files underneath them. # ############################################################# @@ -9,6 +10,8 @@ import std/os, + std/osproc, + std/posix, std/streams, std/strformat, std/times @@ -17,6 +20,16 @@ import util +############################################################# +# C O N S T A N T S +############################################################# + +const + OWNERDIRPERMS = { fpUserExec, fpUserWrite, fpUserRead } + OWNERFILEPERMS = { fpUserWrite, fpUserRead } + BUFSIZE = 8192 # reading and writing buffer size + + ############################################################# # T Y P E S ############################################################# @@ -32,9 +45,11 @@ type Maildir* = ref object # An email message, under a specific Maildir. # type Message* = ref object - dir: Maildir - path: string - stream: FileStream + basename: string + dir: Maildir + headers: seq[ tuple[ header: string, value: seq[string] ] ] + path: string + stream: FileStream ############################################################# @@ -50,28 +65,88 @@ proc newMaildir*( path: string ): Maildir = result.tmp = path & "/tmp" if not dirExists( path ): - let perms = { fpUserExec, fpUserWrite, fpUserRead } debug "Creating new maildir at {path}.".fmt try: for p in [ result.path, result.cur, result.new, result.tmp ]: p.createDir - p.setFilePermissions( perms ) + p.setFilePermissions( OWNERDIRPERMS ) except CatchableError as err: deferral "Unable to create Maildir: ({err.msg}), deferring delivery.".fmt +proc subDir*( dir: Maildir, path: string ): Maildir = + ## Creates a new Maildir relative to an existing one. + result = newMaildir( dir.path & "/" & path ) + + proc newMessage*( dir: Maildir ): Message = ## Create and return a Message - an open FileStream under a specific Maildir ## (in tmp) result = new Message let now = getTime() + var hostname = newString(256) + discard getHostname( cstring(hostname), cint(256) ) + result.dir = dir - result.path = dir.path & dir.tmp & '/' & $now.toUnixFloat() + result.basename = $now.toUnixFloat() & '.' & $getCurrentProcessID() & '.' & $hostname + result.path = result.dir.tmp & "/" & result.basename + result.headers = @[] + + try: + debug "Opening new message at {result.path}.".fmt + result.stream = openFileStream( result.path, fmWrite ) + result.path.setFilePermissions( OWNERFILEPERMS ) + except CatchableError as err: + deferral "Unable to write file {result.path}: {err.msg}".fmt +proc save*( msg: Message, dir=msg.dir ) = + ## Move the message from tmp to new. Defaults to its current + ## maildir, but can be provided a different one. + msg.stream.close() + let newpath = dir.new & "/" & msg.basename + debug "Moving message to {newpath}.".fmt + msg.path.moveFile( newpath ) + msg.dir = dir + msg.path = newpath -# make new message (tmp) -# save message (move from tmp to new) + +proc delete*( msg: Message ) = + ## Remove a message from disk. + msg.stream.close() + debug "Removing message at {msg.path}.".fmt + msg.path.removeFile + msg.path = "" + + +proc writeStdin*( msg: Message ) = + ## Streams stdin to the message file, returning how + ## many bytes were written. + let input = stdin.newFileStream() + var buf = input.readStr( BUFSIZE ) + var total = buf.len + msg.stream.write( buf ) + + while buf != "" and buf.len == BUFSIZE: + buf = input.readStr( BUFSIZE ) + total = total + buf.len + msg.stream.write( buf ) + msg.stream.flush() + msg.stream.close() + debug "Wrote {total} bytes from stdin".fmt + + +# FIXME: filter through external program +# - open new message +# - stream current message to new +# - remove current +# - return new +# +# FIXME: header parsing to tuples +# - open file +# - skip lines that don't match headers +# - unwrap multiline headers +# - store header, add value to seq of strings diff --git a/src/sieb.nim b/src/sieb.nim index 9cf03fe..4fbe979 100644 --- a/src/sieb.nim +++ b/src/sieb.nim @@ -1,8 +1,7 @@ # vim: set et nosta sw=4 ts=4 : import - std/os, - std/streams + std/os import lib/config, @@ -19,15 +18,11 @@ let conf = get_config( opts.config ) default = newMaildir( home & "Maildir" ) +let dest = default.subDir( ".wooo" ) -echo repr default.newMessage +let msg = default.newMessage +msg.writeStdin() +# msg.filter() +msg.save( dest ) -# let input = stdin.newFileStream() -# var buf = input.readStr( 8192 ) -# var message = buf -# while buf != "": -# buf = input.readStr( 8192 ) -# message = message & buf - -# echo message