File Coverage

blib/lib/Maildir/Lite.pm
Criterion Covered Total %
statement 138 238 57.9
branch 54 114 47.3
condition 6 9 66.6
subroutine 16 22 72.7
pod 13 18 72.2
total 227 401 56.6


line stmt bran cond sub pod time code
1             require 5.008008;
2             package Maildir::Lite;
3              
4 3     3   164619 use strict;
  3         8  
  3         118  
5 3     3   2925 use Sys::Hostname 'hostname';
  3         3914  
  3         199  
6 3     3   2426 use File::Sync 'fsync';
  3         25007  
  3         528  
7 3     3   34 use Carp;
  3         8  
  3         15372  
8              
9             our $VERSION ='0.02';
10              
11              
12             =head1 NAME
13              
14             Maildir::Lite - A very simple implementation of Maildir
15              
16             =head1 SYNOPSIS
17              
18             Write to a file handle:
19              
20             my $mdir=Maildir::Lite->new(dir=>'/home/d/.maildir');
21             ...
22             # write messages
23             my ($fh,$status)=$mdir->creat_message();
24             die "creat_message failed" if $status;
25              
26             print $fh "Content-Type: text/plain\n"
27             ."Date: $date\n"
28             ."From: $from\n"
29             ."To: $to\n"
30             ."Subject: $subject\n\n"
31             ."$message";
32              
33             die "delivery failed!\n" if $mdir->deliver_message($fh);
34              
35             Write string and deliver message directly:
36              
37             my $status=$mdir->creat_message($email_content);
38             die "creat_message failed" if $status;
39              
40             Read new messages given a file handle:
41              
42             my ($fh,$status)=$mdir->get_next_message("new");
43             unless($status) {
44             while(<$fh>) { # read message
45             ...
46             }
47             }
48             $mdir->act($fh,'S'); # flag message as seen and move to cur
49              
50             Read new messages into an array and flag message as seen while moving it to cur:
51              
52             my ($fh,$status)=$mdir->get_next_message("new",\@lines,'S');
53              
54             =head1 DESCRIPTION
55              
56             This is a simple and very light implementation of Maildir as specified
57             by D. J. Bernstein at L
58              
59             This module provide the user with a simple interface to reading and writing
60             email messages to maildir folders. Some additional useful features are also
61             supported (e.g. support for additional subdirecties and user defined actions
62             for the maildir flags).
63              
64             =cut
65              
66              
67              
68             =head2 Methods
69              
70             =cut
71              
72             =head3 new
73              
74             my $maildir = Maildir::Lite->new();
75              
76             my $maildir = Maildir::Lite->new(create=>1,
77             dir=>'.maildir/', mode=>0750, sort=>'asc');
78              
79              
80             =over 4
81              
82             =item * C - if set to 0, the directory and the subdirectories will
83             not be created and are assumed to exist.
84              
85             =item * C - the maildir directory; it defaults to F<~/.maildir>
86             (if C<$ENV{HOME}> exits).
87              
88             =item * C - the (default 0750) directory permissions of C and
89             sub-directories.
90              
91             =item * C - set unique integer which will be otherwise randomly
92             generated for filennames; it is important that uniq is actually unique.
93              
94             =item * C - the read messege sorting method. See L.
95              
96             =back
97              
98             =cut
99              
100              
101             sub new {
102 3     3 1 1751 my($class,%args)=@_;
103              
104 3 50       17 my $create=exists $args{create} ? $args{create} : 1;
105 3 0       17 my $dir=exists $args{dir} ? $args{dir} :
    50          
106             exists $ENV{HOME} ? "$ENV{HOME}/.maildir" : undef;
107 3 50       15 my $mode=exists $args{mode} ? $args{mode} : 0750;
108 3 50       149 my $uniq=exists $args{uniq} ? $args{uniq} : int(rand(10000));
109 3 100       19 my $sort=exists $args{sort} ? $args{sort} : 'non';
110              
111 3         69 my $self= {
112             __create => $create,
113             __dir => $dir,
114             __uniq => $uniq,
115             __mode => $mode,
116             __message_fh => {}, # keep track of fh/fname based on fileno
117             # for open messages to be written
118             __read_messages => {}, # list of messages to be read
119             __last_sort => undef, #keep track of last sort method
120             __sort => $sort, #current sort method
121             __force_readdir => 0, #force readdir
122             __default_act => 'seen',
123             __folder_actions => {
124             new => { 'default' => \&new_to_cur },
125             tmp => { 'default' => 'close' },
126             cur => { 'default' => 'close' }
127             }
128             };
129              
130 3         12 bless($self,$class);
131 3         15 return $self;
132             }
133              
134             # move file from new to current with changed filename
135             sub new_to_cur {
136 1     1 0 2 my ($path, $filename,$action)=@_;
137 1 50       3 if($action ne 'close') {
138 1         2 my $flag=uc(substr($action,0,1));
139 1         3 my $old="$path/new/$filename";
140 1         3 my $new="$path/cur/$filename:2,$flag";
141              
142 1 50       101 if(rename($old,$new)) {
143 1         2 return 0;
144             } else {
145 0         0 carp("new_to_cur: failed to rename \'$old\' to \'$new\': $!");
146             }
147             }
148 0         0 return -1;
149             }
150              
151             =head3 add_action($folder,$flag,$action)
152              
153             Add a specific C<$action> (function or 'close') to C<$folder> for
154             the C<$flag> flag.
155              
156             For example, if you wish to move files from F to F when given
157             the flag 'T' (or 'trash'):
158              
159             $mdir->add_action('new','trash',\&new_to_trash);
160              
161             Specifiying 'close' closes the file, without appending the info or moving
162             the file.
163              
164             The default action for folder F is to move it to F and append the
165             flag 'S' flag. Reading messages from F or F by default only closes
166             the file.
167              
168             Returns 0 upon success, -1 otherwise.
169              
170             Example of action function:
171              
172             sub new_to_trash {
173             my ($path, $filename,$action)=@_;
174             my $flag=uc(substr($action,0,1));
175              
176             if($flag eq 'T') {
177             if(-d "$path/trash/") {
178             my $old="$path/new/$filename";
179             my $new="$path/trash/$filename:2,$flag";
180              
181             if(rename($old,$new)) {
182             return 0;
183             } else {
184             die("failed to rename \'$old\' to \'$new\'");
185             }
186             } else {
187             die("\'$path/trash\' directory does not exist");
188             }
189             }
190             return -1;
191             }
192              
193             =cut
194              
195              
196             sub add_action {
197 2     2 1 2967 my ($self,$dir,$action,$func) = @_;
198              
199            
200 2 50       24 if(!defined $dir) {
    50          
    50          
201 0         0 carp("add_action: No folder specified");
202 0         0 return -1;
203             } elsif(!defined $action) {
204 0         0 carp("add_action: No action specified");
205 0         0 return -1;
206             } elsif(!defined $func) {
207 0         0 carp("add_action: No function specified");
208 0         0 return -1;
209             }
210              
211 2         12 my $path=$self->{__dir}."/$dir";
212 2         5 my $flag=$action;
213              
214 2 50       76 if(!(-d $path)) {
215 0 0       0 if(!mkdir($path)) {
216 0         0 carp("add_action: mkdir failed to create folder \'$path\': $!");
217 0         0 return -1;
218             }
219             }
220              
221 2 50       9 if($action ne 'default') { $flag=uc(substr($action,0,1)); }
  2         9  
222 2         10 $self->{__folder_actions}->{$dir}->{$flag}=$func;
223              
224 2         8 return 0;
225              
226             }
227              
228              
229             =head3 dir
230              
231             Set the maildir path:
232              
233             $maildir->dir('/tmp/.maildir/');
234              
235             Get the maildir path:
236              
237             $maildir->dir();
238              
239             =cut
240              
241             sub dir {
242 0     0 1 0 my ($self,$dir) = @_;
243              
244 0 0       0 if(defined $dir) { $self->{__dir}=$dir; }
  0         0  
245              
246 0         0 return $self->{__dir};
247             }
248              
249             =head3 mode
250              
251             Set the mode for creating the directory and subdirectories F, F
252             and F:
253              
254             $maildir->mode(0754);
255              
256             Get the mode:
257              
258             $maildir->mode();
259              
260             =cut
261              
262             sub mode {
263 0     0 1 0 my ($self,$mode) = @_;
264              
265 0 0       0 if(defined $mode) { $self->{__mode}=$mode; }
  0         0  
266              
267 0         0 return $self->{__mode};
268             }
269              
270             =head3 mkdir
271              
272             Create the directory and subdirectories F, F and F if they
273             do not already exist:
274              
275             $maildir->mkdir();
276              
277             As above, but create the additional directories F, F:
278              
279             $maildir->mkdir("trash","sent");
280              
281             This subroutine does B need to be explicitly called before creating new
282             messages (unless you want to create folders other than F, F,
283             and F).
284              
285             This subroutine returns 0 if the directories were created (or exist), otherwise
286             it returns -1 and a warning with carp.
287              
288             =cut
289              
290             sub mkdir {
291 10     10 1 40 my ($self,@additional_dir)=@_;
292 10         38 my $mode=$self->{__mode};
293 10         37 my @dirs=("","tmp","cur","new");
294 10         22 push(@dirs,@additional_dir);
295              
296 10 50       39 if(!defined $self->{__dir}) {
297 0         0 carp("mkdir: No directory name given");
298 0         0 return -1;
299             }
300              
301 10 50       47 if($self->{__create}!=1) {
302 0         0 carp("mkdir: The create flag is not 1");
303 0         0 return -1;
304             }
305              
306 10         25 foreach my $path (@dirs) {
307 43         147 $path=$self->{__dir}."/$path";
308 43 100       1072 if(!(-e $path)) {
309 15 50       2009 if(!mkdir($path)) {
310 0         0 carp("mkdir: mkdir failed to create \'$path\': $!");
311 0         0 return -1;
312             }
313             }
314              
315 43 50       748 if(-d $path) {
316 43 50       1141 if(chmod($self->{__mode},$path)!=1) {
317 0         0 carp("mkdir: chmod \'$path\' to ".$self->{__mode}." failed: $!");
318             }
319             } else {
320 0         0 carp("mkdir: \'$path\' is not a directory\n");
321 0         0 return -1;
322             }
323              
324             }
325              
326 10         41 return 0;
327             }
328              
329              
330             # returns a unique filename
331             sub fname {
332 9     9 0 1193 my $self=shift;
333              
334 9         34 my $time=time();
335 9         51 my $hostname=hostname();
336             #replace / with \057 and : with \072
337 9         96 $hostname=~s/\//\\057/g; $hostname=~s/:/\\072/g;
  9         22  
338              
339 9         70 return $time.'.'.($$."_".$self->{__uniq}++).'.'.$hostname;
340             }
341              
342              
343             =head3 creat_message
344              
345             Get a file handle C<$fh> to a unique file in the F subdirectory:
346              
347             my ($fh,$status) = $maildir->creat_message();
348              
349             Write message to unique file in F subdirectory which is then delivered
350             to F:
351              
352             my $status=$maildir->creat_message($message);
353              
354             Return: C<$status> is 0 if success, -1 otherwise.
355             C<$fh> is the filehandle (C if you pass C an argument).
356              
357             =cut
358              
359              
360             sub creat_message {
361 7     7 1 5385 my ($self,$message)=@_;
362 7         14 my ($filename,$fh);
363              
364 7         71 $self->mkdir; #maybe some of the directories were deleted?
365              
366             # make sure that the file does not exist
367 7         29 $filename=$self->fname;
368 7         191 while(-e $self->{__dir}."/tmp/$filename") {
369 0         0 sleep(2);
370 0         0 $filename=$self->fname;
371             }
372              
373 7 50       946 unless(open($fh,">".$self->{__dir}."/tmp/$filename")) {
374 0         0 carp("creat_message: failed to open file \'"
375             .$self->{__dir}."/tmp/$filename\': $!");
376 0         0 return (undef,-1);
377             }
378              
379 7 50       59 if(defined $message) {
    0          
380 7         81 print $fh $message;
381 7 50       49 unless(fsync($fh)) {
382 0         0 carp("creat_message: fsync failed: $!");
383 0         0 return (undef,-1);
384             }
385 7         1687292 close($fh);
386              
387 7         81 return (undef,$self->deliver($filename));
388             } elsif(defined $self->{__message_fh}->{fileno $fh}) {
389 0         0 carp("creat_message: file handle \'"
390             .(fileno $fh)."\' is already defined in table");
391 0         0 return (undef,-1);
392             } else {
393 0         0 $self->{__message_fh}->{fileno $fh}->{'fh'}=$fh;
394 0         0 $self->{__message_fh}->{fileno $fh}->{'filename'}=$filename;
395 0         0 return ($fh,0);
396             }
397            
398             }
399              
400             =head3 deliver_message
401              
402             Given file handle C<$fh>, deliver message and close handle:
403              
404             $maildir->deliver_message($fh);
405              
406             Returns 0 upon success, -1 otherwise.
407              
408             =cut
409              
410             sub deliver_message {
411 0     0 1 0 my ($self,$fh)=@_;
412              
413 0 0       0 if(defined $self->{__message_fh}->{fileno $fh}) {
414 0         0 my $rc=-1;
415 0         0 my $fno=fileno $fh; #need to index the hash __message_fh
416 0 0       0 unless(fsync($fh)) {
417 0         0 carp("deliver_message: fsync failed: $!");
418 0         0 return (undef,-1);
419             }
420 0         0 close($fh);
421              
422 0         0 $rc=$self->deliver($self->{__message_fh}->{$fno}->{'filename'});
423 0         0 delete $self->{__message_fh}->{$fno};
424 0         0 return $rc;
425             }
426            
427 0         0 return -1;
428             }
429              
430             =head3 deliver_all_messages
431              
432             Deliver all messages and close all handles:
433              
434             $maildir->deliver_all_messages();
435              
436             Returns 0 upon success, -1 otherwise.
437              
438             =cut
439              
440             sub deliver_all_messages {
441 0     0 1 0 my $self=shift;
442              
443 0         0 foreach my $fno (keys %{$self->{__message_fh}}) {
  0         0  
444 0 0       0 if($self->deliver_message($self->{__message_fh}->{$fno}->{'fh'})==-1) {
445 0         0 return -1;
446             }
447             }
448 0         0 return 0;
449             }
450              
451              
452              
453             # copy filename from tmp to new and delte from tmp
454             sub deliver {
455 7     7 0 27 my ($self,$filename)=@_;
456              
457 7 50       659 if(!(-e $self->{__dir}."/tmp/$filename")) {
458 0         0 carp("deliver: "
459             ."file \'$filename\' does not exist in subdirectory \'tmp\'");
460 0         0 return -1;
461             }
462              
463 7 50       382 if(-e $self->{__dir}."/new/$filename") {
464 0         0 carp("deliver: "
465             ."file \'$filename\' already exists in subdirectory \'new\'");
466 0         0 return -1;
467             }
468              
469 7 50       631 if(!link($self->{__dir}."/tmp/$filename", $self->{__dir}."/new/$filename")) {
470 0         0 carp("deliver: "
471             ."file \'$filename\' could not be linked from \'tmp\' to \'new\': $!");
472 0         0 return -1;
473             }
474              
475 7 50       693 if(unlink($self->{__dir}."/tmp/$filename")<1) {
476 0         0 carp("deliver: "
477             ."file \'$filename\' could not be unlinked from \'tmp\': $!");
478 0         0 return -1;
479             }
480              
481 7         106 return 0;
482             }
483              
484             =head3 sort
485              
486             Get the current method for sorting messages:
487              
488             my $sort=$maildir->sort();
489              
490             Set the sorting function of method:
491              
492             $maildir->sort('non'); # no specific sorting
493              
494             $maildir->sort('asc'); # sort based on mtime in increasing order
495              
496             $maildir->sort('des'); # sort based on mtime in decreasing order
497              
498             $maildir->sort(\&func); # sort based on user defined function
499              
500             Example of sorting function which sorts according to a line in the
501             message beggining with "sort:" followed by possible spaces and then
502             a digit:
503              
504             sub func {
505             my ($path,@messages)=@_;
506             my %files; my @newmessages;
507              
508             foreach my $file (@messages) {
509             my $f;
510             open($f,"<$path/$file") or return @messages; #don't sort
511             while(my $line=<$f>) {
512             if($line=~m/sort:\s*(\d)+$/) { # string where sort info is
513             $files{$file}=$1;
514             close($f);
515             last;
516             }
517             }
518             }
519              
520             @newmessages= sort { $files{$a} <=> $files{$b}} keys %files;
521              
522             return @newmessages;
523             }
524              
525             =cut
526              
527              
528             sub sort {
529 0     0 1 0 my ($self,$func)=@_;
530 0 0       0 if(defined $func) {
531 0         0 $self->{__last_sort}=$self->{__sort};
532 0         0 $self->{__sort}=$func;
533             }
534 0         0 return $self->{__sort};
535             }
536              
537             # get all the filenames in directory $dir sorted accorting to $self->{__sort}
538             sub get_messages {
539 7     7 0 14 my ($self,$dir)=@_;
540 7         12 my $path;
541             my @messages;
542              
543 7 100 66     110 if(defined $self->{__read_messages}->{$dir}
      66        
544             and ($self->{__last_sort} eq $self->{__sort})
545             and !$self->{__force_readdir}) {
546 4         8 return @{$self->{__read_messages}->{$dir}};
  4         19  
547             } else {
548 3         10 $self->{__force_readdir}=0;
549 3         11 $self->{__last_sort}=$self->{__sort};
550             # and sort:
551             }
552              
553 3 50       15 if(!defined $dir) {
554 0         0 carp("get_messages: get_messages expects a directory to open");
555 0         0 return -1;
556             }
557              
558 3         14 $path=$self->{__dir}."/$dir";
559              
560 3 50       261 unless(opendir(DIR, $path)) {
561 0         0 carp("get_messages: failed to open directory \'$path\': $!");
562 0         0 return -1;
563             }
564              
565 3 100 66     155 @messages=map{ /^(\d[\w.:,_]+)$/ && -f "$path/$1"?$1:() } readdir(DIR);
  13         559  
566              
567 3         133 closedir(DIR);
568              
569 3         25 @{$self->{__read_messages}->{$dir}}=$self->sort_messages($dir,@messages);
  3         22  
570 3         6 return @{$self->{__read_messages}->{$dir}};
  3         12  
571             }
572              
573             # sort default sorting methods (ascending|descending) wased on mtime
574             sub sort_messages {
575 3     3 0 15 my ($self,$dir,@messages)=@_;
576 3         7 my %files;
577             my @newmessages;
578              
579 3 50       48 if($self->{__sort}=~m/asc|des/i) {
    100          
580 0         0 foreach my $m (@messages) {
581 0         0 $files{$m}=(stat($self->{__dir}."/$dir/$m"))[9];
582              
583 0 0       0 if(!(defined $files{$m})) {
584 0         0 carp("sort_messages: ".
585             "stat failed for file \'".$self->{__dir}."/$dir/$m\': $!");
586 0         0 return @messages;
587             }
588             }
589              
590 0 0       0 if($self->{__sort}=~m/asc/i) {
591 0         0 @newmessages= sort { $files{$a} <=> $files{$b}} keys %files;
  0         0  
592             } else {
593 0         0 @newmessages= sort { $files{$b} <=> $files{$a}} keys %files;
  0         0  
594             }
595             } elsif($self->{__sort}=~/non/i) {
596 2         5 @newmessages=@messages;
597             } else {
598 1         5 @newmessages=&{$self->{__sort}}($self->{__dir}."/$dir/",@messages);
  1         7  
599             }
600              
601 3         1121 return @newmessages;
602             }
603              
604             =head3 get_next_message
605              
606             Get the next message (as file handle) from directory F:
607              
608             my ($fh,$status)=$maildir->get_next_message("new");
609              
610             B It is important to I close file handle once finished with
611             L or L.
612              
613             Read lines of next message in array @lines then, close message and
614             execute the action specified for flag 'P' (default for F: move
615             to F and append ':2,P'):
616              
617             my $status=$maildir->get_next_message("new",\@lines,'passed');
618              
619             Return: C<$status> is 0 if success, -1 otherwise.
620             C<$fh> is the filehandle (C if you pass C a
621             second argument).
622              
623             =cut
624              
625             sub get_next_message {
626 7     7 1 34361 my ($self,$dir,$lines,$action)=@_;
627 7         16 my $fh;
628 7         34 $self->get_messages($dir);
629 7         11 my $message=shift(@{$self->{__read_messages}->{$dir}});
  7         26  
630 7 100       28 if(!defined $action) {
631 1         2 $action=$self->{__default_act};
632             }
633              
634 7 50       19 if(!$message) { return (undef,-1); }
  0         0  
635              
636 7 50       990 unless(open($fh,"<".$self->{__dir}."/$dir/$message")) {
637 0         0 carp("get_next_message: "
638             ."failed to open file \'".$self->{__dir}."/$dir/$message\': $!");
639 0         0 return (undef,-1);
640             }
641              
642 7 50       45 if(defined $self->{__message_fh}->{fileno $fh}) {
643 0         0 carp("get_next_message: file handle \'$fh\' is already defined in table");
644 0         0 return (undef,-1);
645             } else {
646 7         37 $self->{__message_fh}->{fileno $fh}->{'fh'}=$fh;
647 7         26 $self->{__message_fh}->{fileno $fh}->{'filename'}=$message;
648 7         23 $self->{__message_fh}->{fileno $fh}->{'dir'}=$dir;
649 7 100       25 if(defined $lines) {
650 6         475 @$lines=<$fh>;
651 6         35 return (undef,$self->act($fh,$action));
652             } else {
653 1         4 return ($fh,0);
654             }
655             }
656             }
657              
658             =head3 force_readdir
659              
660             Force a readdir during the next L. This is
661             useful if you are reading messages from F and then from F as some
662             of the messages will be moved there.
663              
664             $mdir->force_readdir();
665              
666             =cut
667              
668             sub force_readdir {
669 0     0 1 0 my $self=shift;
670 0         0 $self->{__force_readdir}=1;
671             }
672              
673             =head3 close_message
674              
675             Given file handle C<$fh>, close handle:
676              
677             $maildir->close_message($fh);
678              
679             Returns 0 upon success, -1 otherwise.
680              
681             =cut
682              
683             sub close_message {
684 7     7 1 13 my ($self,$fh)=@_;
685              
686 7 50       28 if(defined $self->{__message_fh}->{fileno $fh}) {
687 7         18 my $fno=fileno $fh; #need to index the hash __message_fh
688 7 50       38 unless(fsync($fh)) {
689 0         0 carp("close_message: fsync failed: $!");
690 0         0 return (undef,-1);
691             }
692 7         292 close($fh);
693              
694 7         30 delete $self->{__message_fh}->{$fno};
695 7         21 return 0;
696             }
697            
698 0         0 return -1;
699             }
700              
701             =head3 act
702              
703             Given file handle C<$fh>, and flag ('P','R','S','T','D','F') close message, append
704             the info and execute the specified action for the flag:
705              
706             $maildir->act($fh,'T');
707              
708             Returns 0 upon success, -1 otherwise.
709              
710             =cut
711              
712              
713             sub act {
714 7     7 1 1138 my ($self,$fh,$action)=@_;
715              
716 7 50       26 if(!defined $fh) {
717 0         0 carp("act: No file handle specified!\n");
718 0         0 return -1;
719             }
720 7 50       21 if(!defined $action) {
721 0         0 carp("act: No action specified!\n");
722 0         0 return -1;
723             }
724              
725 7         25 my $filename=$self->{__message_fh}->{fileno $fh}->{'filename'};
726 7         1002 my $dir=$self->{__message_fh}->{fileno $fh}->{'dir'};
727 7         29 my $flag=uc(substr($action,0,1));
728              
729 7         27 my $close_rc=$self->close_message($fh);
730              
731 7 50       28 return $close_rc if $action eq 'close';
732              
733 7 50       29 if(exists $self->{__folder_actions}->{$dir}) {
734 7 100       30 if(exists $self->{__folder_actions}->{$dir}->{$flag}) {
    50          
735 6 50       31 if($self->{__folder_actions}->{$dir}->{$flag} ne 'close') {
736 6         12 &{$self->{__folder_actions}->{$dir}->{$flag}}($self->{__dir},
  6         29  
737             $filename, $action);
738             }
739             } elsif(exists $self->{__folder_actions}->{$dir}->{'default'}) {
740 1 50       5 if($self->{__folder_actions}->{$dir}->{'default'} ne 'close') {
741 1         2 &{$self->{__folder_actions}->{$dir}->{'default'}}($self->{__dir},
  1         4  
742             $filename, $action);
743             }
744             } else {
745 0         0 carp("act: unknown action \'$action\' for directory \'$dir\',"
746             ."closed file");
747             }
748             } else {
749 0         0 carp("act: unknown action \'$action\', closed file");
750             }
751              
752 7         1906 return $close_rc;
753             }
754              
755             =head1 EXAMPLES
756              
757             =head2 Writing messages
758              
759             The example shows the use of this module with L to write messages.
760              
761             #!/usr/bin/perl
762             use strict;
763             use warnings;
764             use MIME::Entity;
765             use Maildir::Lite;
766              
767             my $mdir=Maildir::Lite->new(dir=>'/tmp/.your_mdir');
768              
769             # print message to file handle
770             sub print_message {
771             my ($from,$to,$subj,$message,$fh)=@_;
772             my $date=localtime;
773             my $msg = MIME::Entity->build(
774             Type => 'text/plain',
775             Date => $date,
776             From => $from,
777             To => $to,
778             Subject => $subj,
779             Data => $message);
780              
781             $msg->print($fh);
782             }
783              
784             # write messages to maildir folder
785             sub write_message {
786             my ($from,$to,$subj,$message)=@_;
787             my ($fh,$stat0)=$mdir->creat_message();
788              
789             die "creat_message failed" if $stat0;
790              
791             print_message($from,$to,$subj,$message,$fh);
792              
793             die "delivery failed!\n" if $mdir->deliver_message($fh);
794             }
795              
796             write_message('me@foo.org', 'you@bar.com','Hi!','One line message');
797             write_message('me@foo.org', 'bar@foo.com','Bye!','Who are you?');
798             write_message('me2@food.org', 'bar@beer.org','Hello!','You again?');
799              
800              
801             =head2 Reading messages
802              
803             The example shows the use of this module with L to read messages.
804              
805             #!/usr/bin/perl
806             use strict;
807             use warnings;
808             use MIME::Parser;
809             use Maildir::Lite;
810              
811              
812             my $mdir=Maildir::Lite->new(dir=>'/tmp/.your_mdir');
813             # move file from new to trash with changed filename
814              
815              
816             sub read_from {
817             my $folder=shift;
818             my $i=0;
819              
820             $mdir->force_readdir();
821              
822             print "$folder:\n|".("-"x20)."\n";
823              
824             while(1) {
825             my $parser = new MIME::Parser;
826             $parser->output_under("/tmp");
827              
828             my ($fh,$status)=$mdir->get_next_message($folder);
829             last if $status;
830              
831             my $entity=$parser->parse($fh);
832              
833             print "Message $i:\n".$entity->stringify."\n";
834             $i++;
835              
836             if($mdir->act($fh,'S')) { warn("act failed!\n"); }
837             }
838              
839             print "|".("-"x20)."\n\n";
840             }
841              
842             read_from("cur");
843             read_from("new");
844              
845             read_from("cur"); # to see the force_readdir in action
846             read_from("new");
847              
848             =head1 SEE ALSO
849              
850             There is already an implementation of Maildir, L, which is
851             great, but more bulky and complicated.
852              
853             Maildir specifications at L
854              
855             =head1 VERSION
856              
857             Version 0.01
858              
859             =head1 AUTHOR
860              
861             Deian Stefan, C<< >>
862              
863             L
864              
865             =head1 BUGS
866              
867             Please report any bugs or feature requests to
868             C, or through the web interface at
869             L.
870             I will be notified, and then you'll automatically be notified of progress
871             on your bug as I make changes.
872              
873              
874             =head1 SUPPORT
875              
876             You can find documentation for this module with the perldoc command.
877              
878             perldoc Maildir::Lite
879              
880              
881             You can also look for information at:
882              
883             =over 4
884              
885             =item * RT: CPAN's request tracker
886              
887             L
888              
889             =item * AnnoCPAN: Annotated CPAN documentation
890              
891             L
892              
893             =item * CPAN Ratings
894              
895             L
896              
897             =item * Search CPAN
898              
899             L
900              
901             =back
902              
903              
904             =head1 COPYRIGHT & LICENSE
905              
906             Copyright 2008 Deian Stefan, all rights reserved.
907              
908             This program is free software; you can redistribute it and/or modify it
909             under the same terms as Perl itself.
910              
911              
912             =cut
913              
914             1; # End of Maildir::Lite