File Coverage

blib/lib/ZConf/Mail.pm
Criterion Covered Total %
statement 51 1412 3.6
branch 0 504 0.0
condition 0 66 0.0
subroutine 17 60 28.3
pod 43 43 100.0
total 111 2085 5.3


line stmt bran cond sub pod time code
1             package ZConf::Mail;
2              
3 1     1   26494 use Email::Simple;
  1         7369  
  1         36  
4 1     1   12 use Email::Simple::Creator;
  1         2  
  1         24  
5 1     1   1967 use Mail::IMAPTalk;
  1         277292  
  1         7  
6 1     1   1044 use Mail::POP3Client;
  1         6781  
  1         83  
7 1     1   1125 use ZConf;
  1         126473  
  1         43  
8 1     1   1010 use Net::SMTP_auth;
  1         28397  
  1         47  
9 1     1   810 use Net::SMTP::TLS;
  1         3261  
  1         28  
10 1     1   719 use Mail::Box::Manager;
  1         340194  
  1         42  
11 1     1   983 use IO::MultiPipe;
  1         11082  
  1         34  
12 1     1   10 use warnings;
  1         1  
  1         27  
13 1     1   5 use strict;
  1         2  
  1         32  
14 1     1   1499 use MIME::Lite;
  1         15575  
  1         38  
15 1     1   895 use File::MimeInfo::Magic;
  1         7493  
  1         75  
16 1     1   1069 use Email::Date;
  1         150685  
  1         120  
17 1     1   17 use Sys::Hostname;
  1         4  
  1         70  
18 1     1   11 use MIME::QuotedPrint;
  1         4  
  1         144  
19 1     1   703351 use Text::Autoformat;
  1         920737  
  1         16631  
20              
21             =head1 NAME
22              
23             ZConf::Mail - Misc mail client functions backed by ZConf.
24              
25             =head1 VERSION
26              
27             Version 2.0.0
28              
29             =cut
30              
31             our $VERSION = '2.0.0';
32              
33              
34             =head1 SYNOPSIS
35              
36             use ZConf::Mail;
37              
38             my $zcmail = ZConf::Mail->new();
39             ...
40              
41             =head1 METHODES
42              
43             Any time you see account name or account, referenced outside of 'createAccount',
44             it means that it should also include the type as well. So for a POP3 account named
45             'test' it would be 'pop3/test'.
46              
47             =head2 new
48              
49             This initiates the module. The one arguement is accepted and it is a hash.
50              
51             =head3 hash keys
52              
53             =head4 zconf
54              
55             This can be allows one to pass ZConf a specific set of arguements to be initialized
56             with.
57              
58             =cut
59              
60             sub new {
61 0     0 1   my %args;
62 0 0         if(defined($_[1])){
63 0           %args= %{$_[1]};
  0            
64             }
65 0           my $method='new';
66            
67 0           my $self={
68             error=>undef,
69             set=>undef,
70             perror=>undef,
71             module=>'ZConf-Mail',
72             };
73 0           bless $self;
74              
75              
76 0 0         if (!defined( $args{zconf} )) {
77 0           $self->{zconf}=ZConf->new({});
78 0 0         if ($self->{zconf}->error) {
79 0           $self->{error}=1;
80 0           $self->{perror}=1;
81 0           $self->{errorString}="It failed with '".$self->{zconf}->{error}."', '".$self->{zconf}->{errorString}."'";
82 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
83 0           return $self;
84             }
85             }else {
86 0           $self->{zconf}=$args{zconf};
87             }
88              
89             #sets $self->{init} to a Perl boolean value...
90             #true=config does exist
91             #false=config does not exist
92 0           $self->{init}=undef;
93              
94 0 0         if ($self->{zconf}->configExists('mail')){
95 0           $self->{init}=1;
96 0           $self->{zconf}->read({config=>'mail'});
97 0 0         if ($self->{zconf}->error) {
98 0           $self->{error}=18;
99 0           $self->{perror}=1;
100 0           $self->{errorString}='Failed to read the ZConf config "mail"';
101 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
102 0           return $self;
103             }
104             }
105              
106             #this defines legal values for later use
107 0           $self->{legal}{pop3}=['user', 'pass', 'auth', 'useSSL',
108             'deliverTo', 'deliverToFolder', 'fetchable',
109             'server', 'port'];
110 0           $self->{legal}{imap}=['user', 'pass', 'useSSL','deliverTo', 'deliverToFolder',
111             'fetchable', 'inbox', 'server', 'port', 'timeout'];
112 0           $self->{legal}{mbox}=['mbox', 'deliverTo', 'deliverToFolder', 'fetchable'];
113 0           $self->{legal}{smtp}=['user', 'pass', 'auth', 'useSSL',
114             'server', 'port', 'name', 'from',
115             'name', 'timeout', 'saveTo', 'saveToFolder',
116             'usePGP', 'pgpType', 'PGPkey', 'PGPdigestAlgo'];
117 0           $self->{legal}{maildir}=['maildir','deliverTo', 'deliverToFolder', 'fetchable'];
118 0           $self->{legal}{exec}=['deliver'];
119 0           $self->{legal}{formatter}=['marginLeft', 'marginRight', 'squeeze', 'ignore', 'justify', 'tabspace'];
120              
121             #this defines the required values for later use
122 0           $self->{required}{pop3}=['user', 'pass', 'auth', 'useSSL',
123             'deliverTo', 'fetchable', 'server', 'port'];
124 0           $self->{required}{imap}=['user', 'pass', 'useSSL',
125             'fetchable', 'inbox', 'server', 'port'];
126 0           $self->{required}{mbox}=['mbox', 'deliverTo', 'fetchable'];
127 0           $self->{required}{smtp}=['user', 'pass', 'auth', 'useSSL',
128             'server', 'port', 'name', 'from',
129             'name', 'timeout', 'saveTo'];
130 0           $self->{required}{maildir}=['maildir','deliverTo', 'fetchable'];
131 0           $self->{required}{exec}=['deliver'];
132              
133             #This contains a list of account types that are fetchable.
134 0           $self->{fetchable}=['pop3', 'imap', 'maildir', 'mbox'];
135              
136             #This contains a list of account types that are deliverable.
137 0           $self->{deliverable}=['exec','imap'];
138              
139             #This contains a list of account types that are sendable.
140             #Listed for possible future purposes.
141 0           $self->{sendable}=['smtp'];
142              
143 0           return $self;
144             }
145              
146             =head2 accountExists
147              
148             Checks to make sure a accont exists. One arguement is taken and that is the account name.
149              
150             if($zcmail->accountExists('pop3/foo)){
151             print "pop3/foo does exist";
152             }
153              
154             =cut
155              
156             sub accountExists{
157 0     0 1   my $self=$_[0];
158 0           my $account=$_[1];
159 0           my $method='accountExists';
160              
161             #blanks any prevous errors
162 0           $self->errorBlank;
163 0 0         if ($self->error) {
164 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
165 0           return undef;
166             }
167              
168             #This implements a simple check to make sure no one passed
169             #'pop3/' or something like that. It also makes sure that
170             #nothing past the account name is refered to.
171 0           my @split=split(/\//, $account);
172 0 0 0       if (!defined($split[1]) || defined($split[3])) {
173 0           $self->{error}=4;
174 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
175 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
176 0           return undef;
177             }
178              
179             #searches and finds any variables for the account
180 0           my @matched=$self->{zconf}->regexVarSearch('mail', '^accounts/'.$account.'/');
181              
182             #If no variables are found, we can assume that it does not exist.
183 0 0         if (!defined($matched[0])) {
184 0           return undef;
185             }
186              
187 0           return 1;
188             }
189              
190             =head2 connectIMAP
191              
192             This connects Mail::IMAPTalk connection to a IMAP account.
193              
194             #connects to the IMAP account 'imap/foo'
195             my $imap=$zcmail->connectIMAP('imap/foo');
196             if($zcmail->error)(
197             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
198             )
199              
200             =cut
201              
202             sub connectIMAP{
203 0     0 1   my $self=$_[0];
204 0           my $account=$_[1];
205 0           my $method='connectIMAP';
206              
207             #blanks any previous errors
208 0           $self->errorBlank;
209 0 0         if ($self->error) {
210 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
211 0           return undef;
212             }
213              
214             #This implements a simple check to make sure no one passed
215             #'pop3/' or something like that.
216 0           my @split=split(/\//, $account);
217 0 0 0       if (!defined($split[1]) || defined($split[3])) {
218 0           $self->{error}=4;
219 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
220 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
221 0           return undef;;
222             }
223              
224             #No need to verify the account exists as $self->getsAccountArgs will do that.
225              
226             #gets the account variables
227 0           my %avars=$self->getAccountArgs($account);
228              
229             #checks to make sure all the required variables are present
230 0           my $requiredInt=0;
231 0           while (defined($self->{required}{$split[0]}[$requiredInt])) {
232 0 0         if (!defined($avars{$self->{required}{imap}[$requiredInt]})) {
233 0           $self->{error}=32;
234 0           $self->{errorString}='"'.$self->{required}{$split[0]}[$requiredInt].
235             '" is undefined for the account "'.$account.'"';
236 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
237 0           return undef;
238             }
239 0           $requiredInt++;
240             }
241              
242             #created outside of the SSL if statement to allow it to be exported SSL if statement
243 0           my $imap;
244              
245 0 0         if (!$avars{useSSL}) {
246 0           $imap=Mail::IMAPTalk->new(Server=>$avars{server},
247             Username=>$avars{user},
248             Password=>$avars{pass},
249             Uid=>0);
250             }else {
251             #creates the socket that will be used connect to IMAP
252 0           my $socket=IO::Socket::SSL->new(PeerAddr=>$avars{server},
253             PeerPort=>$avars{port},
254             Proto=>'tcp');
255              
256             #creates the IMAP connection use to previously created socket
257 0           $imap=Mail::IMAPTalk->new(Socket=>$socket,
258             Username=>$avars{user},
259             Password=>$avars{pass},
260             Uid=>0);
261             }
262              
263             #checks to see if it connected or not
264 0 0         if (!$imap) {
265 0           $self->{error}=9;
266 0           $self->{errorString}='Failed to connect to IMAP server or authenticate';
267 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
268 0           return undef;
269             }
270              
271 0           return $imap;
272             }
273              
274             =head2 connectMaildir
275              
276             Creates a new Mail::Box::Maildir object for accessing the maildir.
277              
278             #connects to the maildir account 'maildir/foo'
279             my $imap=$zcmail->connectMaildir('maildir/foo');
280             if($zcmail->error)(
281             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
282             )
283              
284             =cut
285              
286             sub connectMaildir{
287 0     0 1   my $self=$_[0];
288 0           my $account=$_[1];
289 0           my $method='connectMaildir';
290              
291             #blanks any previous errors
292 0           $self->errorBlank;
293 0 0         if ($self->error) {
294 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
295 0           return undef;
296             }
297              
298             #This implements a simple check to make sure no one passed
299             #'pop3/' or something like that.
300 0           my @split=split(/\//, $account);
301 0 0 0       if (!defined($split[1]) || defined($split[3])) {
302 0           $self->{error}=4;
303 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
304 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
305 0           return undef;
306             }
307              
308             #No need to verify the account exists as $self->getsAccountArgs will do that.
309              
310             #gets the account variables
311 0           my %avars=$self->getsAccontArgs($account);
312              
313             #checks to make sure all the required variables are present
314 0           my $requiredInt=0;
315 0           while (defined($self->{required}{$split[0]}[$requiredInt])) {
316 0 0         if (!defined($avars{$self->{required}{maildir}[$requiredInt]})) {
317 0           $self->{error}=32;
318 0           $self->{errorString}='"'.$self->{required}{$split[0]}[$requiredInt].
319             '" is undefined for the account "'.$account.'"';
320 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
321 0           return undef;
322             }
323 0           $requiredInt++;
324             }
325              
326 0           my $mgr=Mail::Box::Manager->new;
327 0           my $maildir=$mgr->open(folder=>$avars{maildir}, access=>'rw', lock_file=>'NONE');
328              
329             #checks for an error
330 0 0         if (!$maildir) {
331 0           $self->{error}=14;
332 0           $self->{errorString}='Failed to access the maildir, "'.$avars{maildir}.'"';
333 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
334             }
335              
336 0           return $maildir;
337             }
338              
339             =head2 connectMbox
340              
341             Creates a new Mail::Box::Mbox object for accessing the mbox.
342              
343             #connects to the mbox account 'mbox/foo'
344             my $imap=$zcmail->connectMbox('mbox/foo');
345             if($zcmail->error)(
346             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
347             )
348              
349             =cut
350              
351             sub connectMbox{
352 0     0 1   my $self=$_[0];
353 0           my $account=$_[1];
354 0           my $method='connectMbox';
355              
356             #blanks any previous errors
357 0           $self->errorBlank;
358 0 0         if ($self->error) {
359 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
360 0           return undef;
361             }
362              
363             #This implements a simple check to make sure no one passed
364             #'pop3/' or something like that.
365 0           my @split=split(/\//, $account);
366 0 0 0       if (!defined($split[1]) || defined($split[3])) {
367 0           $self->{error}=4;
368 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
369 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
370 0           return undef;
371             }
372              
373             #No need to verify the account exists as $self->getsAccountArgs will do that.
374              
375             #gets the account variables
376 0           my %avars=$self->getAccountArgs($account);
377              
378             #checks to make sure all the required variables are present
379 0           my $requiredInt=0;
380 0           while (defined($self->{required}{$split[0]}[$requiredInt])) {
381 0 0         if (!defined($avars{$self->{required}{mbox}[$requiredInt]})) {
382 0           $self->{error}=32;
383 0           $self->{errorString}='"'.$self->{required}{$split[0]}[$requiredInt].
384             '" is undefined for the account "'.$account.'"';
385 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
386 0           return undef;
387             }
388 0           $requiredInt++;
389             }
390              
391 0           my $mgr=Mail::Box::Manager->new;
392 0           my $mbox=$mgr->open(folder=>$avars{mbox}, access=>'rw', lock_file=>'NONE');
393              
394             #checks for an error
395 0 0         if (!$mbox) {
396 0           $self->{error}=14;
397 0           $self->{errorString}='Failed to access the mbox, "'.$avars{mbox}.'"';
398 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
399             }
400              
401 0           return $mbox;
402             }
403              
404             =head2 connectPOP3
405              
406             This connects Mail::POP3Client connection to a POP3 account.
407              
408             #connects to the mbox account 'pop3/foo'
409             my $imap=$zcmail->connectPOP3('pop3/foo');
410             if($zcmail->error)(
411             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
412             )
413              
414             =cut
415              
416             sub connectPOP3{
417 0     0 1   my $self=$_[0];
418 0           my $account=$_[1];
419 0           my $method='connectPOP3';
420              
421             #blanks any previous errors
422 0           $self->errorBlank;
423 0 0         if ($self->error) {
424 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
425 0           return undef;
426             }
427              
428             #This implements a simple check to make sure no one passed
429             #'pop3/' or something like that.
430 0           my @split=split(/\//, $account);
431 0 0 0       if (!defined($split[1]) || defined($split[3])) {
432 0           $self->{error}=4;
433 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
434 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
435             }
436              
437             #No need to verify the account exists as $self->getsAccountArgs will do that.
438              
439             #gets the account variables
440 0           my %avars=$self->getAccountArgs($account);
441              
442             #checks to make sure all the required variables are present
443 0           my $requiredInt=0;
444 0           while (defined($self->{required}{$split[0]}[$requiredInt])) {
445 0 0         if (!defined($avars{$self->{required}{pop3}[$requiredInt]})) {
446 0           $self->{error}=32;
447 0           $self->{errorString}='"'.$self->{required}{$split[0]}[$requiredInt].
448             '" is undefined for the account "'.$account.'"';
449 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
450 0           return undef;
451             }
452 0           $requiredInt++;
453             }
454              
455             #creates the connection
456 0           my $pop = new Mail::POP3Client( USER=>$avars{user},
457             PASSWORD=>$avars{pass},
458             HOST=>$avars{server},
459             PORT=>$avars{port},
460             USESSL=>$avars{useSSL},
461             AUTH_MODE=>$avars{auth}
462             );
463              
464             #If the state is equal to authorization it means we did not authenticate properly.
465 0 0         if ($pop->State eq 'AUTHORIZATION') {
466 0           $self->{error}=7;
467 0           $self->{errorString}='Failed to authenticate with the server.'.
468             ' Mail::POP3Client->State="'.$pop->State.'"'.
469             ' Mail::POP3Client->Message returned "'.$pop->Message.'"';
470 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
471 0           return undef;
472             }
473              
474             #If the state is it means it failed to connect to the server.
475 0 0         if ($pop->State eq 'DEAD') {
476 0           $self->{error}=8;
477 0           $self->{errorString}='Failed to connect to the server.'.
478             ' Mail::POP3Client->State="'.$pop->State.'"'.
479             ' Mail::POP3Client->Message returned "'.$pop->Message.'"';
480 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
481             }
482              
483 0           return $pop;
484             }
485              
486             =head2 connectSMTP
487              
488             This connects Mail::POP3Client connection to a POP3 account.
489              
490             #connects to the SMTP account 'smtp/foo'
491             my $imap=$zcmail->connectSMTP('smtp/foo');
492             if($zcmail->error)(
493             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
494             )
495              
496             =cut
497              
498             sub connectSMTP{
499 0     0 1   my $self=$_[0];
500 0           my $account=$_[1];
501 0           my $method='connectSMTP';
502              
503             #blanks any previous errors
504 0           $self->errorBlank;
505 0 0         if ($self->error) {
506 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
507 0           return undef;
508             }
509              
510             #This implements a simple check to make sure no one passed
511             #'pop3/' or something like that.
512 0           my @split=split(/\//, $account);
513 0 0 0       if (!defined($split[1]) || defined($split[3])) {
514 0           $self->{error}=4;
515 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
516 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
517 0           return undef;
518             }
519              
520             #No need to verify the account exists as $self->getsAccountArgs will do that.
521              
522             #gets the account variables
523 0           my %avars=$self->getAccountArgs($account);
524              
525             #checks to make sure all the required variables are present
526 0           my $requiredInt=0;
527 0           while (defined($self->{required}{$split[0]}[$requiredInt])) {
528 0 0         if (!defined($avars{$self->{required}{smtp}[$requiredInt]})) {
529 0           $self->{error}=32;
530 0           $self->{errorString}='"'.$self->{required}{$split[0]}[$requiredInt].
531             '" is undefined for the account "'.$account.'"';
532 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
533 0           return undef;
534             }
535 0           $requiredInt++;
536             }
537              
538             #created outside of the SSL if statement to allow it to be exported SSL if statement
539 0           my $smtp;
540              
541             #Unfortunately the error checking can't be moved out from this if statement
542             #as Net::SMTP_auth and Net::SMTP::TLS both work a little different in regards
543             #authentication.
544 0 0         if ($avars{useSSL}) {
545 0           my $smtp=Net::SMTP::TLS->new($avars{server},
546             Port=>$avars{port},
547             User=>$avars{user},
548             Password=>$avars{pass},
549             Timeout=>$avars{timeout});
550 0 0         if (!$smtp) {
551 0           $self->{error}=13;
552 0           $self->{errorString}='Failed to connect to SMTP server';
553 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
554 0           return undef;
555             }
556             }else {
557 0           $smtp=Net::SMTP_auth->new($avars{server}.':'.$avars{port}, Timeout=>$avars{timeout});
558              
559             #error it it did not connect
560 0 0         if (!defined($smtp)) {
561 0           $self->{error}=10;
562 0           $self->{errorString}='Failed to connect to SMTP server, "'
563             .$avars{server}.':'.$avars{port}.'"';
564 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
565 0           return undef;
566             }
567              
568             #authenticate and error if it does not
569 0 0         if (!$smtp->auth($avars{auth}, $avars{user}, $avars{pass})){
570 0           $self->{error}=11;
571 0           $self->{errorString}='Failed to authenticate with the SMTP server.';
572 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
573 0           return undef;
574             }
575             }
576              
577             #sends the from information
578 0 0         if (!$smtp->mail($avars{from})){
579 0           $self->{error}=12;
580 0           $self->{errorString}='Failed to connect to SMTP server';
581 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
582             return undef
583 0           }
584              
585 0           return $smtp;
586             }
587              
588              
589              
590             =head2 createAccount
591              
592             This creates a new account. The only arguement accepted, and required, is a
593             hash. More information can be found below.
594              
595             =head3 args hash
596              
597             The required variables for a account can be found in the VARIABLES section.
598             Those listed below are also required by this function.
599              
600             The two common ones are 'type' and 'account'. You should consult 'VARIABLES'
601             for the various posibilities for each account type.
602              
603             =head4 type
604              
605             This is the type of a account it is. It is always lower case as can be seen
606             in the variables section.
607              
608             =head4 account
609              
610             This is the name of the account. It will be appended after the account type.
611             Thus for the account 'pop3/some account name' it will be 'some account name'.
612              
613             #adds a POP3 server
614             $zcmail->createAccount({type=>'pop3',
615             account=>'some account name',
616             user=>'monkey',
617             pass=>'ape',
618             auth=>'auto',
619             useSSL=>'0',
620             SSLoptions=>'',
621             deliverTo=>'',
622             fetchable=>'0',
623             server=>'127.0.0.1',
624             });
625             if($zcmail->error){
626             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
627             }
628              
629             =cut
630              
631             sub createAccount{
632 0     0 1   my $self=$_[0];
633 0           my %args;
634 0 0         if(defined($_[1])){
635 0           %args= %{$_[1]};
  0            
636             }
637 0           my $method='createAccount';
638              
639             #blanks any previous errors
640 0           $self->errorBlank;
641 0 0         if ($self->error) {
642 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
643 0           return undef;
644             }
645              
646             #make sure the type is defined
647 0 0         if (!defined($args{type})) {
648 0           $self->{error}='2';
649 0           $self->{errorString}='$args{type} is undefined';
650 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
651 0           return undef;
652             }
653              
654             #make sure it is a known type
655 0 0         if (!defined($self->{required}{$args{type}})) {
656 0           $self->{error}='3';
657 0           $self->{errorString}='$args{type}, "'.$args{type}.'", not a valid value';
658 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
659 0           return undef;
660             }
661              
662             #make sure it is a legit account name
663 0 0         if (!$self->{zconf}->setNameLegit($args{account})){
664 0           $self->{error}='3';
665 0           $self->{errorString}='$args{account}, "'.$args{account}.'", not a legit account name';
666 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
667 0           return undef;
668             }
669              
670             #makes sure they are all defined
671 0           my $requiredInt=0;
672 0           while (defined($self->{required}{$args{type}}[$requiredInt])) {
673             #make sure it is defined
674 0 0         if (!defined($args{$self->{required}{$args{type}}[$requiredInt]})) {
675 0           $self->{error}='3';
676 0           $self->{errorString}='$args{'.$self->{required}{$args{type}}[$requiredInt].' is not defined';
677 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
678 0           return undef;
679             }
680              
681 0           $requiredInt++;
682             }
683              
684             #adds them
685 0           $requiredInt=0;
686 0           while (defined($self->{required}{$args{type}}[$requiredInt])) {
687 0           my $variable='accounts/'.$args{type}.'/'.$args{account}.'/'.$self->{required}{$args{type}}[$requiredInt];
688            
689             #sets the value
690             #not doing any error checking as there is no reason to believe it will fail
691 0           $self->{zconf}->setVar('mail', $variable, $args{$self->{required}{$args{type}}[$requiredInt]});
692              
693 0           $requiredInt++;
694             }
695              
696             #saves it
697 0           $self->{zconf}->writeSetFromLoadedConfig({config=>'mail'});
698 0 0         if ($self->{zconf}->{error}) {
699 0           $self->{error}=36;
700 0           $self->{errorString}='ZConf failed to write the set out.';
701 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
702 0           return undef;
703             }
704              
705 0           return 1;
706             }
707              
708             =head2 createEmailSimple
709              
710             Creates a new Email::Simple object.
711              
712             =head3 function args
713              
714             =head4 account
715              
716             This is the account is being setup for. If this is not
717             specified, the default one is used.
718              
719             =head4 to
720              
721             An array of To addresses.
722              
723             =head4 cc
724              
725             An array of CC addresses.
726              
727             =head4 subject
728              
729             The subject of the message.
730              
731             =head4 body
732              
733             The body of the message.
734              
735             =cut
736              
737             sub createEmailSimple{
738 0     0 1   my $self=$_[0];
739 0           my %args;
740 0 0         if(defined($_[1])){
741 0           %args= %{$_[1]};
  0            
742             }
743 0           my $method='createEmailSimple';
744              
745             #blanks any previous errors
746 0           $self->errorBlank;
747 0 0         if ($self->error) {
748 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
749 0           return undef;
750             }
751              
752              
753 0 0         if (!defined($args{account})) {
754 0           $args{account}=$self->defaultSendableGet;
755             }
756              
757             #makes sure the args for the account, subject, and body are defined
758 0 0 0       if (!defined($args{account}) || (!defined($args{subject}) || !defined($args{body}))) {
      0        
759 0           $self->{error}='5';
760 0           $self->{errorString}='A required hash arguement was not defined.';
761 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
762 0           return undef;
763             }
764              
765 0           my %Aargs=$self->getAccountArgs($args{account});
766 0 0         if ($self->{error}) {
767 0           warn('ZConf-Mail createEmailSimple: getAccountArgs errors');
768 0           return undef;
769             }
770            
771             #makes sure that either to or cc is given
772 0 0 0       if (!defined($args{cc}) && !defined($args{to})) {
773 0           warn('ZConf-Mail createEmailSimple:5: Neither to or cc given' );
774 0           $self->{error}=5;
775 0           $self->{errorString}='Neither to or cc given.';
776 0           return undef;
777             }
778              
779 0           my $mail=Email::Simple->create(header=>[Subject=>$args{subject}], body=>$args{body});
780              
781 0 0         if (!$mail) {
782 0           $self->{error}=31;
783 0           $self->{errorString}='Failed to create an Email::Simple object.';
784 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
785 0           return undef;
786             }
787              
788             #process the to stuff
789 0 0         if (defined($args{to})){
790 0           my $to=join(', ', @{$args{to}});
  0            
791 0           $mail->header_set('To'=>$to);
792             }
793              
794             #process the cc stuff
795 0 0         if (defined($args{cc}[0])){
796 0           my $to=join(', ', @{$args{cc}});
  0            
797 0           $mail->header_set('CC'=>$to);
798             }
799              
800 0           my $shost=hostname;
801 0           $shost=~s/\..*//g;
802 0           $mail->header_set('Message-ID'=>'<'.rand().'.'.time().'.ZConf::Mail'.'@'.$shost.'>');
803              
804 0           $mail->header_set('Subject'=>$args{subject});
805              
806 0           $mail->header_set('From'=>$Aargs{name}.' <'.$Aargs{from}.'>');
807              
808 0           return $mail;
809             }
810              
811             =head2 createMimeLite
812              
813             This create a new MIME::Lite object.
814              
815             This will also sign it if needed be.
816              
817             =head3 args hash reference
818              
819             The three following are required.
820              
821             account
822             subject
823             body
824              
825             =head4 account
826              
827             This is the account is being setup for. If no account
828             is specified, the default on is used.
829              
830             =head4 to
831              
832             An array of To addresses.
833              
834             =head4 cc
835              
836             An array of CC addresses.
837              
838             =head4 subject
839              
840             The subject of the message.
841              
842             =head4 body
843              
844             The body of the message.
845              
846             =head4 files
847              
848             An array of files to attach.
849              
850             =head4 in-reply-to
851              
852             This will set the in-reply-to header value.
853              
854             =head4 dontSign
855              
856             If is set to true and the account is set to sign by default, it won't be.
857              
858             =head4 quiet
859              
860             When created, call the quiet method.
861              
862             This defaults to on as it will throw errors when doing GPG signing.
863              
864             =cut
865              
866             sub createMimeLite{
867 0     0 1   my $self=$_[0];
868 0           my %args;
869 0 0         if(defined($_[1])){
870 0           %args= %{$_[1]};
  0            
871             }
872 0           my $method='createMimeLite';
873              
874             #blanks any previous errors
875 0           $self->errorBlank;
876 0 0         if ($self->error) {
877 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
878 0           return undef;
879             }
880              
881 0 0         if (!defined($args{account})) {
882 0           $args{account}=$self->defaultSendableGet;
883             }
884              
885             #makes sure the args for the account, subject, and body are defined
886 0 0 0       if (!defined($args{account}) || (!defined($args{subject}) || !defined($args{body}))) {
      0        
887 0           $self->{error}='5';
888 0           $self->{errorString}='A required hash arguement was not defined.';
889 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
890 0           return undef;
891             }
892              
893 0           my %Aargs=$self->getAccountArgs($args{account});
894 0 0         if ($self->{error}) {
895 0           warn('ZConf-Mail createMimeLite: getAccountArgs errors');
896 0           return undef;
897             }
898              
899             #shut the damn thing up if not told otherwise
900 0 0         if (!defined($args{quiet})) {
901 0           $args{quiet}=1;
902             }
903              
904             #makes sure that either to or cc is given
905 0 0 0       if (!defined($args{cc}[0]) && !defined($args{to}[0])) {
906 0           $self->{error}=5;
907 0           $self->{errorString}='Neither to or cc given.';
908 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
909 0           return undef;
910             }
911              
912             #don't sign it if requested not to
913 0 0 0       if (defined($args{dontSign}) && $args{dontSign}) {
914 0           $Aargs{usePGP}=0;
915             }
916              
917             #sign the message if needed
918 0           my $signed;
919 0 0         if ($Aargs{usePGP}) {
920 0           my $to='';
921 0           $signed=$self->sign($args{account}, $args{body}, $to);
922 0 0         if ($self->{error}) {
923 0           warn('ZConf-Mail createMimeLite: Signing required and sign failed');
924 0           return undef;
925             }
926              
927 0 0         if ($Aargs{pgpType} eq 'clearsign') {
928 0           $args{body}=$signed;
929             }
930            
931 0 0         if ($Aargs{pgpType} eq 'signencrypt') {
932 0           $args{body}='';
933             }
934             }
935              
936 0           my $email=undef;
937              
938 0 0         if ($Aargs{usePGP}) {
939 0 0         if ($Aargs{pgpType} eq 'clearsign') {
940 0           $email=MIME::Lite->new(Type=>'multipart/signed');
941 0 0         if ($args{quiet}) {
942 0           $email->quiet;
943             }
944 0           $email->attach('Content-Type'=>'text/plain', Data=>$signed);
945             }
946              
947 0 0         if ($Aargs{pgpType} eq 'mimesign') {
948 0           $email=MIME::Lite->new(Type=>'multipart/signed');
949 0 0         if ($args{quiet}) {
950 0           $email->quiet;
951             }
952              
953 0           $email->attr('content-type.protocol'=>'application/pgp-signature');
954              
955 0           my $hash='SHA512';
956 0 0         if (defined($Aargs{PGPdigestAlgo})) {
957 0           $hash=$Aargs{PGPdigestAlgo};
958             }
959              
960 0           $email->attr('content-type.micalg'=>'PGP-'.$hash);
961              
962 0           $email->attach('Content-Type'=>'text/plain',
963             Encoding=>'quoted-printable',
964             Data=>$args{body});
965              
966 0           $email->attach(Type=>'application/pgp-signature',
967             Filename=>'signature.asc', Disposition=>'attachment',
968             Encoding=>'7bit',Data=>$signed);
969             }
970              
971 0 0         if ($Aargs{pgpType} eq 'signencrypt') {
972 0           $email=MIME::Lite->new(Type=>'multipart/signed');
973              
974 0           $email->attr('content-type'=>'multipart/encrypted');
975 0           $email->attr('content-type.protocol'=>'application/pgp-encrypted');
976 0           $email->attach('Content-Type'=>'application/pgp-encrypted',
977             Data=>"Version: 1.0\n");
978 0           $email->attach('Content-Type'=>'application/octet-stream',
979             Data=>$signed);
980             }
981             }else {
982 0           $email=MIME::Lite->new(Data=>$args{body});
983 0 0         if ($args{quiet}) {
984 0           $email->quiet;
985             }
986             }
987              
988             #process the to stuff
989 0 0         if (defined($args{to})){
990 0           my $to=join(', ', @{$args{to}});
  0            
991 0           $email->add('To'=>$to);
992             }
993              
994             #process the cc stuff
995 0 0         if (defined($args{cc}[0])){
996 0           my $to=join(', ', @{$args{cc}});
  0            
997 0           $email->add('CC'=>$to);
998             }
999              
1000 0 0         if (defined($args{'in-reply-to'})) {
1001 0           $email->add('In-Reply-To'=>$args{'in-reply-to'});
1002             }
1003              
1004 0           $email->add('Subject'=>$args{subject});
1005              
1006 0           $email->add('From'=>$Aargs{from});
1007              
1008 0           my $shost=hostname;
1009 0           $shost=~s/\..*//g;
1010 0           $email->add('Message-ID'=>'<'.rand().'.'.time().'.ZConf::Mail'.'@'.$shost.'>');
1011              
1012             #attach all the files
1013 0           my $int=0;
1014 0           while ($args{files}[$int]) {
1015 0 0         if (! -e $args{files}[$int]) {
1016 0           $self->{error}=38;
1017 0           $self->{errorString}='"'.$args{files}[0].'" does not exist';
1018 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1019 0           return undef;
1020             }
1021              
1022 0           my $mimetype=mimetype($args{files}[$int]);
1023              
1024 0           $email->attach(Type=>$mimetype, Path=>$args{files}[$int]);
1025              
1026 0           $int++;
1027             }
1028              
1029 0           return $email;
1030             }
1031              
1032             =head2 defaultFetchableGet
1033              
1034             This sets the default sendable email address.
1035              
1036             my $defaultFetchable=$zcmail->defaultFetchableGet;
1037             if(!defined($defaultFetchable)){
1038             print "There is no default sendable account.\n";
1039             }
1040            
1041             print $defaultFetchable."\n";
1042              
1043             =cut
1044              
1045             sub defaultFetchableGet{
1046 0     0 1   my $self=$_[0];
1047 0           my $method='defaultFetchableGet';
1048              
1049             #blanks any previous errors
1050 0           $self->errorBlank;
1051 0 0         if ($self->error) {
1052 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1053 0           return undef;
1054             }
1055              
1056 0           my %var=$self->{zconf}->regexVarGet('mail', '^default/fetchable$');
1057              
1058 0 0         if (!defined($var{'default/fetchable'})) {
1059 0           return undef;
1060             }
1061              
1062 0 0         if ($var{'default/fetchable'} eq '') {
1063 0           return undef;
1064             }
1065              
1066 0           return $var{'default/fetchable'};
1067             }
1068              
1069             =head2 defaultFetchableSet
1070              
1071             This sets the default fetchable account.
1072              
1073             $zcmail->defaultFechableSet('smtp/foo');
1074             if($zcmail->error){
1075             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1076             }
1077              
1078             =cut
1079              
1080             sub defaultFetchableSet{
1081 0     0 1   my $self=$_[0];
1082 0           my $account=$_[1];
1083 0           my $method='defaultFetchableSet';
1084              
1085             #blanks any previous errors
1086 0           $self->errorBlank;
1087 0 0         if ($self->error) {
1088 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1089             }
1090              
1091             #make sure we have a account
1092 0 0         if (!defined($account)) {
1093 0           $self->{errorString}='No account specified.';
1094 0           $self->{error}='5';
1095 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1096 0           return undef;
1097             }
1098            
1099 0           my $fetchable=$self->fetchable($account);
1100 0 0         if ($self->{error}) {
1101 0           warn('ZConf-Mail defaultFetchableSet: fetchable errored');
1102 0           return undef;
1103             }
1104              
1105 0 0         if (!$fetchable) {
1106 0           $self->{error}=24;
1107 0           $self->{errorString}='The account, "'.$account.'", is not sendable.';
1108 0           warn('ZConf-Mail defaultFetchableSet:24: '.$self->{errorString});
1109 0           return undef;
1110             }
1111              
1112             #sets the value
1113             #not doing any error checking as there is no reason to believe it will fail
1114 0           $self->{zconf}->setVar('mail', 'default/fetchable', $account);
1115              
1116             #saves it
1117 0           $self->{zconf}->writeSetFromLoadedConfig({config=>'mail'});
1118 0 0         if ($self->{zconf}->{error}) {
1119 0           $self->{errorString}='ZConf failed to write the set out.';
1120 0           $self->{error}=36;
1121 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1122 0           return undef;
1123             }
1124              
1125 0           return 1;
1126             }
1127              
1128             =head2 defaultSendableGet
1129              
1130             This sets the default sendable email account.
1131              
1132             my $defaultSendable=$zcmail->defaultSendableGet;
1133             if(!defined($defaultSendable)){
1134             print "There is no default sendable account.\n";
1135             }
1136            
1137             print $defaultSendable."\n";
1138              
1139             =cut
1140              
1141             sub defaultSendableGet{
1142 0     0 1   my $self=$_[0];
1143 0           my $method='defaultSendableGet';
1144              
1145             #blanks any previous errors
1146 0           $self->errorBlank;
1147 0 0         if ($self->error) {
1148 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1149 0           return undef;
1150             }
1151              
1152 0           my %var=$self->{zconf}->regexVarGet('mail', '^default/sendable$');
1153              
1154 0 0         if (!defined($var{'default/sendable'})) {
1155 0           return undef;
1156             }
1157              
1158 0 0         if ($var{'default/sendable'} eq '') {
1159 0           return undef;
1160             }
1161              
1162 0           return $var{'default/sendable'};
1163             }
1164              
1165             =head2 defaultSendableSet
1166              
1167             This sets the default sendable email address.
1168              
1169             $zcmail->defaultSendableSet('smtp/foo');
1170             if($zcmail->error){
1171             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1172             }
1173              
1174             =cut
1175              
1176             sub defaultSendableSet{
1177 0     0 1   my $self=$_[0];
1178 0           my $account=$_[1];
1179 0           my $method='defaultSendableSet';
1180              
1181             #blanks any previous errors
1182 0           $self->errorBlank;
1183 0 0         if ($self->error) {
1184 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1185 0           return undef;
1186             }
1187              
1188             #make sure we have a account
1189 0 0         if (!defined($account)) {
1190 0           $self->{errorString}='Account not specified.';
1191 0           $self->{error}='5';
1192 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1193 0           return undef;
1194             }
1195            
1196 0           my $sendable=$self->sendable($account);
1197 0 0         if ($self->{error}) {
1198 0           warn('ZConf-Mail defaultSendableSet: sendable errored');
1199 0           return undef;
1200             }
1201              
1202 0 0         if (!$sendable) {
1203 0           $self->{error}=24;
1204 0           $self->{errorString}='The account, "'.$account.'", is not sendable.';
1205 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1206 0           return undef;
1207             }
1208              
1209             #sets the value
1210             #not doing any error checking as there is no reason to believe it will fail
1211 0           $self->{zconf}->setVar('mail', 'default/sendable', $account);
1212              
1213             #saves it
1214 0           $self->{zconf}->writeSetFromLoadedConfig({config=>'mail'});
1215 0 0         if ($self->{zconf}->{error}) {
1216 0           $self->{errorString}='ZConf failed to write the set out.';
1217 0           $self->{error}=36;
1218 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1219 0           return undef;
1220             }
1221              
1222 0           return 1;
1223             }
1224              
1225             =head2 defaultImapGet
1226              
1227             This gets what the default IMAP account is.
1228              
1229             =cut
1230              
1231             sub defaultImapGet{
1232 0     0 1   my $self=$_[0];
1233 0           my $method='defaultImapGet';
1234              
1235             #blanks any previous errors
1236 0           $self->errorBlank;
1237 0 0         if ($self->error) {
1238 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1239 0           return undef;
1240             }
1241              
1242 0           my %var=$self->{zconf}->regexVarGet('mail', '^default/imap$');
1243              
1244 0 0         if (!defined($var{'default/imap'})) {
1245 0           return undef;
1246             }
1247              
1248 0 0         if ($var{'default/imap'} eq '') {
1249 0           return undef;
1250             }
1251              
1252 0           return $var{'default/imap'};
1253             }
1254              
1255             =head2 defaultImapSet
1256              
1257             This gets what the default IMAP account is.
1258              
1259             =cut
1260              
1261             sub defaultImapSet{
1262 0     0 1   my $self=$_[0];
1263 0           my $account=$_[1];
1264 0           my $method='defaultImapSet';
1265              
1266             #blanks any previous errors
1267 0           $self->errorBlank;
1268 0 0         if ($self->error) {
1269 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1270 0           return undef;
1271             }
1272              
1273             #make sure we have a account
1274 0 0         if (!defined($account)) {
1275 0           $self->{errorString}='Account not specified.';
1276 0           $self->{error}='5';
1277 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1278 0           return undef;
1279             }
1280            
1281 0           my $sendable=$self->sendable($account);
1282 0 0         if ($self->{error}) {
1283 0           warn('ZConf-Mail defaultSendableSet: sendable errored');
1284 0           return undef;
1285             }
1286              
1287             #sets the value
1288             #not doing any error checking as there is no reason to believe it will fail
1289 0           $self->{zconf}->setVar('mail', 'default/imap', $account);
1290              
1291             #saves it
1292 0           $self->{zconf}->writeSetFromLoadedConfig({config=>'mail'});
1293 0 0         if ($self->{zconf}->{error}) {
1294 0           $self->{errorString}='ZConf failed to write the set out.';
1295 0           $self->{error}=36;
1296 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1297 0           return undef;
1298             }
1299              
1300 0           return 1;
1301             }
1302              
1303             =head2 delAccount
1304              
1305             This is used for removed a account. One option is taken and that is the name of the account.
1306              
1307             #removes the account 'mbox/foo'
1308             $zcmail->delAccount('mbox/foo');
1309             if($zcmail->error){
1310             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1311             }
1312              
1313             =cut
1314              
1315             sub delAccount{
1316 0     0 1   my $self=$_[0];
1317 0           my $account=$_[1];
1318 0           my $method='delAccount';
1319              
1320             #blanks any previous errors
1321 0           $self->errorBlank;
1322 0 0         if ($self->error) {
1323 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1324 0           return undef;
1325             }
1326              
1327             #This implements a simple check to make sure no one passed
1328             #'pop3/' or something like that. It also makes sure that
1329             #nothing past the account name is refered to.
1330 0           my @split=split(/\//, $account);
1331 0 0 0       if (!defined($split[1]) || defined($split[3])) {
1332 0           $self->{error}=4;
1333 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
1334 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1335 0           return undef;
1336             }
1337              
1338             #makes sure the account exists
1339 0 0         if (!$self->accountExists($account)) {
1340 0           $self->{error}=6;
1341 0           $self->{errorString}='"'.$account.'" does not exist';
1342 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1343 0           return undef;
1344             }
1345              
1346             #removes the variables
1347             #Off hand I can't think of a reason it should fail at this point.
1348 0           my @deleted=$self->{zconf}->regexVarDel('mail', '^accounts/'.$account.'/');
1349              
1350             #saves it
1351 0           $self->{zconf}->writeSetFromLoadedConfig({config=>'mail'});
1352 0 0         if ($self->{zconf}->{error}) {
1353 0           $self->{error}=36;
1354 0           $self->{errorString}='ZConf failed to write the set out.';
1355 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1356 0           return undef;
1357             }
1358              
1359 0           return 1;
1360             }
1361              
1362             =head2 deliverable
1363              
1364             This checks if a acocunt is deliverable or not.
1365              
1366             #check to see if the account is a account that can be delivered to
1367             if(!zcmail->deliverable('exec/foo')){
1368             print "Not deliverable.";
1369             }
1370              
1371             =cut
1372              
1373             sub deliverable{
1374 0     0 1   my $self=$_[0];
1375 0           my $account=$_[1];
1376 0           my $method='deliverable';
1377              
1378             #blanks any previous errors
1379 0           $self->errorBlank;
1380 0 0         if ($self->error) {
1381 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1382 0           return undef;
1383             }
1384              
1385             #This implements a simple check to make sure no one passed
1386             #'pop3/' or something like that. It also makes sure that
1387             #nothing past the account name is refered to.
1388 0           my @split=split(/\//, $account);
1389 0 0 0       if (!defined($split[1]) || defined($split[3])) {
1390 0           $self->{error}=4;
1391 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
1392 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1393 0           return undef;
1394             }
1395              
1396             #makes sure the account exists
1397 0 0         if (!$self->accountExists($account)) {
1398 0           $self->{error}=6;
1399 0           $self->{errorString}='The account "'.$account.'" does not exist';
1400 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1401 0           return undef;
1402             }
1403              
1404             #checks to make sure that is a account type that is deliverable
1405 0           my $int=0;
1406 0           while(defined($self->{deliverable}[$int])){
1407             #If it is matched set $matched to true.
1408 0 0         if ($self->{deliverable}[$int] eq $split[0]) {
1409 0           return 1;
1410             }
1411              
1412 0           $int++;
1413             }
1414              
1415 0           return undef;
1416             }
1417              
1418             =head2 deliver
1419              
1420             This is a wrapper function to the other deliver functions. This is a
1421             wrapper to the other delivery functions.
1422              
1423             The first arguement is the account. The second is the message. The
1424             third is the a hash that some deliver types optionally use.
1425              
1426             =head3 args hash
1427              
1428             =head4 folder
1429              
1430             This can be used to specify a folder to deliver to. If it is not
1431             defined, it will try to use what ever is the inbox for that account.
1432              
1433             Currently this is only used by IMAP.
1434              
1435             #delivers the mail contained in $mail to 'exec/foo'
1436             $zcmail->deliver('exec/foo', $mail);
1437             if($zcmail->error){
1438             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1439             }
1440              
1441             #delivers the mail contained in $mail to 'imap/foo' to the 'foo.bar'
1442             $zcmail->deliver('imap/foo', $mail, {folder=>'foo.bar'});
1443             if($zcmail->error){
1444             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1445             }
1446              
1447             =cut
1448              
1449             sub deliver{
1450 0     0 1   my $self=$_[0];
1451 0           my $account=$_[1];
1452 0           my $mail=$_[2];
1453 0           my %args;
1454 0 0         if(defined($_[3])){
1455 0           %args= %{$_[3]};
  0            
1456             }
1457 0           my $method='deliver';
1458              
1459             #blanks any previous errors
1460 0           $self->errorBlank;
1461 0 0         if ($self->error) {
1462 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1463 0           return undef;
1464             }
1465              
1466             #makes sure the account can be delivered to
1467 0 0         if (!$self->deliverable($account)) {
1468 0           $self->{error}='15';
1469 0           $self->{errorString}='"'.$account.'" is not deliverable';
1470 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1471 0           return undef;
1472             }
1473              
1474             #delivers it to a exec account
1475 0 0         if ($account =~ /^exec\//) {
1476 0 0         if (!$self->deliverExec($account, $mail)) {
1477 0           warn('ZConf-Mail deliver:'.$self->{error}.': '.$self->{errorString});
1478 0           return undef;
1479             }
1480             }
1481              
1482             #delivers it to a imap account
1483 0 0         if ($account =~ /^imap\//) {
1484 0 0         if (!$self->deliverIMAP($account, $mail, \%args)) {
1485 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1486 0           return undef;
1487             }
1488             }
1489              
1490 0           return 1;
1491             }
1492              
1493             =head2 deliverExec
1494              
1495             This is a delivers to a exec account.
1496              
1497             It is generally not best to call it directly, but to let the deliver
1498             function route it. This allows for more flexible delivery.
1499              
1500             The first arguement is the account. The second is the message. The
1501             third is the a optional args hash.
1502              
1503             #delivers the mail contained in $mail to 'exec/foo'
1504             $zcmail->deliverExec('exec/foo', $mail);
1505             if($zcmail->error){
1506             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1507             }
1508              
1509             =cut
1510              
1511             sub deliverExec{
1512 0     0 1   my $self=$_[0];
1513 0           my $account=$_[1];
1514 0           my $mail=$_[2];
1515 0           my $method='deliverExec';
1516              
1517             #blanks any previous errors
1518 0           $self->errorBlank;
1519 0 0         if ($self->error) {
1520 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1521 0           return undef;
1522             }
1523              
1524             #delivers it to a exec account
1525 0 0         if (!$account =~ /^exec\//) {
1526 0           $self->{error}=19;
1527 0           $self->{errorString}='"'.$account.'" is not a exec account';
1528 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1529 0           return undef;
1530             }
1531              
1532             #Make sure the command is defined.
1533 0 0         if (!defined($self->{zconf}->{conf}{mail}{'accounts/'.$account.'/deliver'})) {
1534 0           $self->{error}=5;
1535 0           $self->{errorString}='"'.$account.'" is missing the variable "deliver"';
1536 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1537 0           return undef;
1538             }
1539              
1540             #sets up the pipe
1541 0           my $pipe=IO::MultiPipe->new;
1542 0           $pipe->set($self->{zconf}->{conf}{mail}{'accounts/'.$account.'/deliver'});
1543 0 0         if ($pipe->{error}) {
1544 0           $self->{error}=20;
1545 0           $self->{errorString}='O::MultiPipe errored. $pipe->{error}="'
1546             .$pipe->{error}.'" $pipe->{errorString}="'
1547             .$pipe->{errorString}.'"';
1548 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1549 0           return undef;
1550             }
1551              
1552             #runs it
1553 0           $pipe->run($mail);
1554 0 0         if ($pipe->{error}) {
1555 0           $self->{error}=20;
1556 0           $self->{errorString}='O::MultiPipe errored. $pipe->{error}="'
1557             .$pipe->{error}.'" $pipe->{errorString}="'
1558             .$pipe->{errorString}.'"';
1559 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1560 0           return undef;
1561             }
1562              
1563 0           return 1;
1564             }
1565              
1566             =head2 deliverIMAP
1567              
1568             This is a delivers to a IMAP account.
1569              
1570             It is generally not best to call it directly, but to let the deliver
1571             function route it. This allows for more flexible delivery.
1572              
1573             #delivers the mail contained in $mail to 'imap/foo' to the inbox
1574             $zcmail->deliverIMAP('imap/foo', $mail);
1575             if($zcmail->error){
1576             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1577             }
1578              
1579             #delivers the mail contained in $mail to 'imap/foo' to the 'foo.bar'
1580             $zcmail->deliverIMAP('imap/foo', $mail, {folder=>'foo.bar'});
1581             if($zcmail->{error}){
1582             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1583             }
1584              
1585             =cut
1586              
1587             sub deliverIMAP{
1588 0     0 1   my $self=$_[0];
1589 0           my $account=$_[1];
1590 0           my $mail=$_[2];
1591 0           my %args;
1592 0 0         if(defined($_[3])){
1593 0           %args= %{$_[3]};
  0            
1594             }
1595 0           my $method='deliverIMAP';
1596              
1597             #blanks any previous errors
1598 0           $self->errorBlank;
1599 0 0         if ($self->error) {
1600 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1601 0           return undef;
1602             }
1603              
1604             #delivers it to a exec account
1605 0 0         if (!$account =~ /^imap\//) {
1606 0           $self->{error}=19;
1607 0           $self->{errorString}='"'.$account.'" is not a IMAP account';
1608 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1609 0           return undef;
1610             }
1611              
1612             #connects to the IMAP server
1613 0           my $imap=$self->connectIMAP($account);
1614 0 0         if ($self->{error}) {
1615 0           warn('ZConf-Mail fetchIMAP:22: Failed to connect to the IMAP server.');
1616 0           return undef;
1617             }
1618              
1619             #make sure we have a folder
1620 0 0         if (!defined($args{folder})) {
1621             #Make sure the command is defined.
1622 0 0         if (!defined($self->{zconf}->{conf}{mail}{'accounts/'.$account.'/inbox'})) {
1623 0           $self->{error}=33;
1624 0           $self->{errorString}='"'.$account.'" is missing the variable "inbox"';
1625 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1626 0           return undef;
1627             }
1628            
1629 0           $args{folder}=$self->{zconf}->{conf}{mail}{'accounts/'.$account.'/inbox'};
1630             }
1631              
1632             #make sure the folder exists
1633 0           my $select=$imap->select($args{folder});
1634 0 0         if (!$select) {
1635 0           $self->{error}=34;
1636 0           $self->{errorString}='Failed to select folder "'.$args{folder}.
1637             '"for account "'.$account.'"';
1638 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1639 0           return undef;
1640             }
1641              
1642 0           my $append=$imap->append($args{folder}, ['Literal', $mail]);
1643 0 0         if (!$append) {
1644 0           $self->{error}=35;
1645 0           $self->{errorString}='Failed to append to folder "'.$args{folder}.
1646             '"for account "'.$account.'"';
1647 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1648 0           return undef;
1649             }
1650              
1651 0           return 1;
1652             }
1653              
1654             =head2 fetch
1655              
1656             This is a wrapper function for the other accounts. The only accepted arg
1657             is account name. If no account is specified, the default one is used.
1658              
1659             It is then delivered to the account specified by variable 'deliverTo' for
1660             the account.
1661              
1662             #fetches the mail for 'pop3/foo'
1663             $zcmail->fetch('pop3/foo');
1664             if($zcmail->error){
1665             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1666             }
1667              
1668             =cut
1669              
1670             sub fetch{
1671 0     0 1   my $self=$_[0];
1672 0           my $account=$_[1];
1673 0           my $method='fetch';
1674              
1675             #blanks any previous errors
1676 0           $self->errorBlank;
1677 0 0         if ($self->error) {
1678 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1679 0           return undef;
1680             }
1681              
1682             #gets the default fetchable account if no account is given
1683 0 0         if (!defined($account)) {
1684 0           $account=$self->defaultFetchableGet;
1685             }
1686              
1687             #if we get to this point it means the account does has not
1688             #been specified and no default account exists
1689 0 0         if (!defined($account)) {
1690 0           $self->{error}=5;
1691 0           $self->{errorString}='No account specified and there is no default fetchable account.';
1692 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1693 0           return undef;
1694             }
1695              
1696 0 0         if (!$self->fetchable($account)) {
1697 0           $self->{error}='15';
1698 0           $self->{errorString}='"'.$account.'" is not fetchable';
1699 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1700 0           return undef;
1701             }
1702              
1703             #used for returning the number fetched
1704 0           my $fetched;
1705              
1706             #Fetches a account if it is a POP3 account.
1707 0 0         if ($account =~ /^pop3\//) {
1708 0           $fetched=$self->fetchPOP3($account);
1709 0 0         if (!defined($fetched)) {
1710 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1711 0           return undef;
1712             }
1713             }
1714              
1715             #Fetches a account if it is a mbox account.
1716 0 0         if ($account =~ /^mbox\//) {
1717 0           $fetched=$self->fetchMbox($account);
1718 0 0         if (!defined($fetched)) {
1719 0           warn('ZConf-Mail fetch:'.$self->{error}.': '.$self->{errorString});
1720 0           return undef;
1721             }
1722             }
1723              
1724             #Fetches a account if it is a maildir account.
1725 0 0         if ($account =~ /^maildir\//) {
1726 0           $fetched=$self->fetchMaildir($account);
1727 0 0         if (!defined($fetched)) {
1728 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1729 0           return undef;
1730             }
1731             }
1732              
1733             #Fetches a account if it is a maildir account.
1734 0 0         if ($account =~ /^imap\//) {
1735 0           $fetched=$self->fetchIMAP($account);
1736 0 0         if (!defined($fetched)) {
1737 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1738 0           return undef;
1739             }
1740             }
1741              
1742 0           return $fetched;
1743             }
1744              
1745             =head2 fetchable
1746              
1747             This checks if a account is fetchable or not. The reason for the existance it
1748             to make some things look neater.
1749              
1750             =cut
1751              
1752             sub fetchable{
1753 0     0 1   my $self=$_[0];
1754 0           my $account=$_[1];
1755 0           my $method='fetchable';
1756              
1757             #blanks any previous errors
1758 0           $self->errorBlank;
1759 0 0         if ($self->error) {
1760 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1761 0           return undef;
1762             }
1763              
1764             #This implements a simple check to make sure no one passed
1765             #'pop3/' or something like that. It also makes sure that
1766             #nothing past the account name is refered to.
1767 0           my @split=split(/\//, $account);
1768 0 0 0       if (!defined($split[1]) || defined($split[3])) {
1769 0           $self->{error}=4;
1770 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
1771 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1772 0           return undef;
1773             }
1774              
1775             #makes sure the account exists
1776 0 0         if (!$self->accountExists($account)) {
1777 0           $self->{error}=6;
1778 0           $self->{errorString}='The account "'.$account.'" does not exist';
1779 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1780 0           return undef;
1781             }
1782              
1783 0           my $int=0;
1784 0           while(defined($self->{fetchable}[$int])){
1785             #If it is matched set $matched to true.
1786 0 0         if ($self->{fetchable}[$int] eq $split[0]) {
1787 0           return $self->{zconf}->{conf}{mail}{'accounts/'.$account.'/fetchable'};
1788             }
1789 0           $int++;
1790             }
1791              
1792             #Returns undef if the account type was not matched.
1793 0           return undef;
1794             }
1795              
1796              
1797             =head2 fetchIMAP
1798              
1799             Fetches the messages from the inbox of a IMAP account.
1800              
1801             my $number=$mail->fetchIMAP('imap/foo');
1802             if($mail->error}){
1803             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1804             }else{
1805             print 'Fetched '.$number."messages.\n";
1806             }
1807              
1808             =cut
1809              
1810             sub fetchIMAP{
1811 0     0 1   my $self=$_[0];
1812 0           my $account=$_[1];
1813 0           my $method='fetchIMAP';
1814              
1815             #blanks any previous errors
1816 0           $self->errorBlank;
1817 0 0         if ($self->error) {
1818 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1819 0           return undef;
1820             }
1821              
1822             #makes sure it is fetchable
1823 0 0         if (!$self->fetchable($account)) {
1824 0           $self->{error}='15';
1825 0           $self->{errorString}='"'.$account.'" is not fetchable';
1826 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1827 0           return undef;
1828             }
1829              
1830             #returns
1831 0 0         if (!defined($self->{zconf}->{conf}{mail}{'accounts/'.$account.'/inbox'})) {
1832 0           $self->{error}=5;
1833 0           $self->{errorString}='No IMAP inbox defined';
1834 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1835 0           return undef;
1836             }
1837              
1838             #connects to the IMAP server
1839 0           my $imap=$self->connectIMAP($account);
1840 0 0         if ($self->{error}) {
1841 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1842 0           return undef;
1843             }
1844              
1845             #selects the proper folder
1846 0 0         if (!$imap->select($self->{zconf}->{conf}{mail}{'accounts/'.$account.'/inbox'})) {
1847             # if (!$imap->select('Inbox')) {
1848 0           $self->{error}=23;
1849 0           $self->{errorString}='Failed to select IMAP folder "'.
1850             $self->{zconf}->{conf}{mail}{'accounts/'.$account.'/inbox'}.'"';
1851 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1852 0           return undef;
1853             }
1854              
1855             #gets the number of messages
1856 0           my $count=$imap->message_count($self->{zconf}->{conf}{mail}{'accounts/'.$account.'/inbox'});
1857              
1858             #processes each one
1859 0           my $countInt=1;
1860 0   0       while ($countInt <= $count && $count > 0) {
1861 0           my $mail=$imap->fetch($countInt, 'rfc822');
1862 0 0         if ($?) {
1863 0           warn('ZConf-Mail fetchImap:22: $imap->fetch('.$countInt.', \'rfc822\') failed');
1864 0           $self->{error}=22;
1865 0           $self->{errorString}='$imap->fetch('.$countInt.', \'rfc822\') failed';
1866 0           return undef;
1867             }
1868              
1869             #delivers the fetched message.
1870 0           $self->deliver($self->{zconf}->{conf}{mail}{'accounts/'.$account.'/deliverTo'},
1871             $mail->{$countInt}{rfc822});
1872 0 0         if ($self->{error}) {
1873 0           warn('ZConf-Mail fetchIMAP:'.$self->{error}.': Delivery error');
1874 0           return undef;
1875             }
1876              
1877             #removes the old one
1878 0 0         if (!$imap->store($countInt, , '+flags', '(\\deleted)')) {
1879 0           $self->{error}=21;
1880 0           $self->{errorString}='$mbox->message('.$countInt.')->delete failed';
1881 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1882 0           return undef;
1883             }
1884 0           $imap->expunge();
1885            
1886 0           $countInt++;
1887             }
1888              
1889 0           return $count;
1890             }
1891              
1892             =head2 fetchMaildir
1893              
1894             Fetches the messages from the inbox of a maildir account.
1895              
1896             my $number=$mail->fetchMaildir('maildir/foo');
1897             if($mail->{error}}){
1898             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1899             }else{
1900             print 'Fetched '.$number."messages.\n";
1901             }
1902              
1903             =cut
1904              
1905             sub fetchMaildir{
1906 0     0 1   my $self=$_[0];
1907 0           my $account=$_[1];
1908 0           my $method='fetchMaildir';
1909              
1910             #blanks any previous errors
1911 0           $self->errorBlank;
1912 0 0         if ($self->error) {
1913 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1914 0           return undef;
1915             }
1916              
1917             #makes sure it is fetchable
1918 0 0         if (!$self->fetchable($account)) {
1919 0           $self->{error}='15';
1920 0           $self->{errorString}='"'.$account.'" is not fetchable';
1921 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1922 0           return undef;
1923             }
1924              
1925 0           my $maildir=$self->connectMaildir($account);
1926              
1927 0 0         if ($self->{error}) {
1928 0           warn('ZConf-Mail fetchMaildir:16: Failed to connect to the maildir.');
1929 0           return undef;
1930             }
1931              
1932             #gets the number of messages
1933 0           my $count=$maildir->nrMessages;
1934             #This is done as the function above returns an extra one.
1935 0           $count--;
1936              
1937             #processes each one
1938 0           my $countInt=0;
1939 0   0       while ($countInt < $count && $count > 0) {
1940 0           my $mail=$maildir->message($countInt)->string;
1941 0 0         if ($?) {
1942 0           $self->{error}=22;
1943 0           $self->{errorString}='$mbox->message('.$countInt.')->print failed';
1944 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1945 0           return undef;
1946             }
1947              
1948             #delivers the fetched message.
1949 0           $self->deliver($self->{zconf}->{conf}{mail}{'accounts/'.$account.'/deliverTo'},
1950             $mail);
1951 0 0         if ($self->{error}) {
1952 0           warn('ZConf-Mail fetchMbox:'.$self->{error}.': Delivery error');
1953 0           return undef;
1954             }
1955              
1956             #removes the old one
1957 0 0         if (!$maildir->message($countInt)->delete) {
1958 0           $self->{error}=21;
1959 0           $self->{errorString}='$mbox->message('.$countInt.')->delete failed';
1960 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
1961 0           return undef;
1962             }
1963            
1964 0           $countInt++;
1965             }
1966              
1967 0           return $count;
1968             }
1969              
1970             =head2 fetchMbox
1971              
1972             Fetches the messages from the inbox of a mbox account.
1973              
1974             my $number=$mail->fetchMbox('mbox/foo');
1975             if($mail->{error}}){
1976             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
1977             }else{
1978             print 'Fetched '.$number."messages.\n";
1979             }
1980              
1981             =cut
1982              
1983             sub fetchMbox{
1984 0     0 1   my $self=$_[0];
1985 0           my $account=$_[1];
1986 0           my $method='fetchMbox';
1987              
1988             #blanks any previous errors
1989 0           $self->errorBlank;
1990 0 0         if ($self->error) {
1991 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
1992 0           return undef;
1993             }
1994              
1995             #makes sure it is fetchable
1996 0 0         if (!$self->fetchable($account)) {
1997 0           $self->{error}='15';
1998 0           $self->{errorString}='"'.$account.'" is not fetchable';
1999 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2000 0           return undef;
2001             }
2002              
2003 0           my $mbox=$self->connectMbox($account);
2004              
2005 0 0         if ($self->{error}) {
2006 0           warn('ZConf-Mail fetchMbox:16: Failed to connect to the mbox.');
2007 0           return undef;
2008             }
2009              
2010             #gets the number of messages
2011 0           my $count=$mbox->nrMessages;
2012             #This is done as the function above returns an extra one.
2013 0           $count--;
2014              
2015             #processes each one
2016 0           my $countInt=0;
2017 0   0       while ($countInt < $count && $count > 0) {
2018              
2019 0           my $mail=$mbox->message($countInt)->string;
2020 0 0         if ($?) {
2021 0           $self->{error}=22;
2022 0           $self->{errorString}='$mbox->message('.$countInt.')->print failed';
2023 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2024 0           return undef;
2025             }
2026              
2027             #delivers the fetched message.
2028 0           $self->deliver($self->{zconf}->{conf}{mail}{'accounts/'.$account.'/deliverTo'},
2029             $mail);
2030 0 0         if ($self->{error}) {
2031 0           warn('ZConf-Mail fetchMbox:'.$self->{error}.': Delivery error');
2032 0           return undef;
2033             }
2034              
2035             #removes the old one
2036 0 0         if (!$mbox->message($countInt)->delete) {
2037 0           $self->{error}=21;
2038 0           $self->{errorString}='$mbox->message('.$countInt.')->delete failed';
2039 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2040 0           return undef;
2041             }
2042            
2043 0           $countInt++;
2044             }
2045              
2046 0           return $count;
2047             }
2048              
2049             =head2 fetchPOP3
2050              
2051             Fetches the messages from the inbox of a POP3 account.
2052              
2053             my $number=$mail->fetchPOP3('pop3/foo');
2054             if($mail->{error}}){
2055             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2056             }else{
2057             print 'Fetched '.$number."messages.\n";
2058             }
2059              
2060             =cut
2061              
2062             sub fetchPOP3{
2063 0     0 1   my $self=$_[0];
2064 0           my $account=$_[1];
2065 0           my $method='fetchPOP3';
2066              
2067             #blanks any previous errors
2068 0           $self->errorBlank;
2069 0 0         if ($self->error) {
2070 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2071 0           return undef;
2072             }
2073              
2074             #makes sure it is fetchable
2075 0 0         if (!$self->fetchable($account)) {
2076 0           $self->{error}='15';
2077 0           $self->{errorString}='"'.$account.'" is not fetchable';
2078 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2079 0           return undef;
2080             }
2081              
2082 0           my $pop=$self->connectPOP3($account);
2083              
2084 0 0         if ($self->{error}) {
2085 0           warn('ZConf-Mail fetchPOP3:16: Failed to connect to the POP3 server.');
2086 0           return undef;
2087             }
2088              
2089             #fetches the messages
2090 0           my $count=$pop->Count();
2091 0           my $countInt=1;
2092 0   0       while ($countInt <= $count && $count > 0) {
2093              
2094 0           my $mail=$pop->Retrieve($countInt);
2095 0 0         if ($?) {
2096 0           $self->{error}=17;
2097 0           $self->{errorString}='$pop->Retrieve failed. $?="'.$?.'"';
2098 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2099 0           return undef;
2100             }
2101              
2102              
2103             #delivers the fetched message.
2104 0           $self->deliver($self->{zconf}->{conf}{mail}{'accounts/'.$account.'/deliverTo'},
2105             $mail);
2106 0 0         if ($self->{error}) {
2107 0           warn('ZConf-Mail fetchPOP3:'.$self->{error}.': Delivery error');
2108 0           return undef;
2109             }
2110              
2111             #removes the old one
2112 0 0         if (!$pop->Delete($countInt)) {
2113 0           $self->{error}=17;
2114 0           $self->{errorString}='$pop->Delete failed. $?="'.$?.'"';
2115 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2116 0           return undef;
2117             }
2118              
2119 0           $countInt++;
2120             }
2121              
2122             #returns the number of fetched messages
2123 0           return $count;
2124             }
2125              
2126             =head2 formatter
2127              
2128             Automatically format a chunk of text against various settings,
2129             primarily line wrapping.
2130              
2131             $text=$zcmail->formatter($text);
2132             if($zcmail->error){
2133             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2134             }
2135              
2136             =cut
2137              
2138             sub formatter{
2139 0     0 1   my $self=$_[0];
2140 0           my $text=$_[1];
2141 0           my $method='formatter';
2142              
2143             #blanks any previous errors
2144 0           $self->errorBlank;
2145 0 0         if ($self->error) {
2146 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2147 0           return undef;
2148             }
2149              
2150 0           my %f=$self->{zconf}->regexVarGet('mail', '^formatter/');
2151              
2152 0 0         if (!defined($f{'formatter/marginLeft'})) {
2153 0           $f{'formatter/marginLeft'}=0;
2154             }
2155              
2156 0 0         if (!defined($f{'formatter/marginRight'})) {
2157 0           $f{'formatter/marginRight'}=72;
2158             }
2159              
2160 0 0         if (!defined($f{'formatter/squeeze'})) {
2161 0           $f{'formatter/squeeze'}=1;
2162             }
2163              
2164 0 0         if (!defined($f{'formatter/ignoree'})) {
2165 0           $f{'formatter/ignore'}='^[ \t]';
2166             }
2167              
2168 0 0         if (!defined($f{'formatter/justify'})) {
2169 0           $f{'formatter/justify'}='left';
2170             }
2171              
2172 0 0         if (!defined($f{'formatter/tabspace'})) {
2173 0           $f{'formatter/tabspace'}='4';
2174             }
2175              
2176 0           my $ignore=$f{'formatter/justify'};
2177              
2178 0           $text=autoformat($text, {left=>$f{'formatter/marginLeft'},
2179             right=>$f{'formatter/marginRight'},
2180             squeeze=>$f{'formatter/squeeze'},
2181             justify=>$f{'formatter/justify'},
2182             ignore=>qr/$ignore/,
2183             all=>1});
2184              
2185 0           return $text;
2186             }
2187              
2188             =head2 formatterGetAll
2189              
2190             Get all options for the formatter.
2191              
2192             my %formatterOptions=$zcmail->formatterGetAll;
2193             if($zcmail->error){
2194             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2195             }else{
2196             print 'marginLeft:'.formatterOptions{marginLeft}."\n".
2197             'marginRight:'.formatterOptions{marginRight}."\n".
2198             'squeeze:'.formatterOptions{squeeze}."\n".
2199             'ignore:'.formatterOptions{ignore}."\n".
2200             'justify:'.formatterOptions{justify}."\n".
2201             'tabspace:'.formatterOptions{tabspace}."\n";
2202             }
2203              
2204             =cut
2205              
2206             sub formatterGetAll{
2207 0     0 1   my $self=$_[0];
2208 0           my $method='formatterGet';
2209              
2210             #blanks any previous errors
2211 0           $self->errorBlank;
2212 0 0         if ($self->error) {
2213 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2214 0           return undef;
2215             }
2216              
2217             #gets all formatter variables that are defined
2218 0           my %returned=$self->{zconf}->regexVarSearch('mail', '^formatter\/');
2219 0 0         if ($self->{zconf}->error) {
2220 0           $self->{error}=36;
2221 0           $self->{errorString}='ZConf errored. error='.$self->{zconf}->error.' errorString='.$self->{zconf}->errorString;
2222 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2223 0           return undef;
2224             }
2225              
2226             #this will be returned
2227 0           my %toreturn;
2228              
2229             #handle the marginLeft value
2230 0 0         if (defined( $returned{'formatter/marginLeft'} )) {
2231 0           $toreturn{'marginLeft'}=$returned{'formatter/marginLeft'};
2232             }else {
2233 0           $toreturn{'marginLeft'}=0;
2234             }
2235              
2236             #handle the marginRight value
2237 0 0         if (defined( $returned{'formatter/marginRight'} )) {
2238 0           $toreturn{'marginRight'}=$returned{'formatter/marginRight'};
2239             }else {
2240 0           $toreturn{'marginRight'}=72;
2241             }
2242              
2243             #handle the squeeze value
2244 0 0         if (defined( $returned{'formatter/squeeze'} )) {
2245 0           $toreturn{'squeeze'}=$returned{'formatter/squeeze'};
2246             }else {
2247 0           $toreturn{'squeeze'}=1;
2248             }
2249              
2250             #handle the ignore value
2251 0 0         if (defined( $returned{'formatter/ignore'} )) {
2252 0           $toreturn{'ignore'}=$returned{'formatter/ignore'};
2253             }else {
2254 0           $toreturn{'ignore'}='^[ \t]';
2255             }
2256              
2257             #handle the justify value
2258 0 0         if (defined( $returned{'formatter/justify'} )) {
2259 0           $toreturn{'justify'}=$returned{'formatter/justify'};
2260             }else {
2261 0           $toreturn{'justify'}='left';
2262             }
2263              
2264             #handle the justify value
2265 0 0         if (defined( $returned{'formatter/tabspace'} )) {
2266 0           $toreturn{'tabspace'}=$returned{'formatter/tabspace'};
2267             }else {
2268 0           $toreturn{'tabspace'}='4';
2269             }
2270              
2271 0           return %toreturn;
2272             }
2273              
2274             =head2 formatterSet
2275              
2276             Set some options for the formatter.
2277              
2278             Two arguments are required.
2279              
2280             The first is the option to operate on.
2281              
2282             The second is the value. A value of undef will result it being removed,
2283             there for the default being used when formatterGetAll is called.
2284              
2285             #set the text justification to the right
2286             $zcmail->formatterSet('justify', 'right');
2287             if($zcmail->error){
2288             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2289             }
2290              
2291             #set the text justification back to the default
2292             $zcmail->formatterSet('justify', undef);
2293             if($zcmail->error){
2294             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2295             }
2296              
2297             =cut
2298              
2299             sub formatterSet{
2300 0     0 1   my $self=$_[0];
2301 0           my $option=$_[1];
2302 0           my $value=$_[2];
2303 0           my $method='formatterGet';
2304              
2305             #blanks any previous errors
2306 0           $self->errorBlank;
2307 0 0         if ($self->error) {
2308 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2309 0           return undef;
2310             }
2311              
2312             #make sure a option is specified
2313 0 0         if (!defined( $option )) {
2314 0           $self->{error}=5;
2315 0           $self->{errorString}='No option specified';
2316 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2317 0           return undef;
2318             }
2319              
2320             #makes sure it is a valid option
2321 0           my $int=0;
2322 0           my $matched=0;
2323 0           while (defined( $self->{legal}{formatter}[$int] )) {
2324 0 0         if ($self->{legal}{formatter}[$int] eq $option) {
2325 0           $matched=1;
2326             }
2327              
2328 0           $int++;
2329             }
2330 0 0         if (!$matched) {
2331 0           $self->{error}=45;
2332 0           $self->{errorString}='"'.$option.'" is not a valid formatter option';
2333 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2334 0           return undef;
2335             }
2336              
2337             #decides what to do with it
2338 0 0         if (!defined($value)) {
2339 0           $self->{zconf}->regexVarDel('mail', '^formatter\/'.$option.'$');
2340 0 0         if ($self->{zconf}->error) {
2341 0           $self->{errorString}='ZConf error. error='.$self->{zconf}->error.' errorString='.$self->{zconf}->errorString;
2342 0           $self->{error}=36;
2343 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2344 0           return undef;
2345             }
2346             }else {
2347 0           $self->{zconf}->setVar('mail', 'formatter/'.$option, $value);
2348 0 0         if ($self->{zconf}->error) {
2349 0           $self->{errorString}='ZConf error. error='.$self->{zconf}->error.' errorString='.$self->{zconf}->errorString;
2350 0           $self->{error}=36;
2351 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2352 0           return undef;
2353             }
2354             }
2355              
2356             #saves it
2357 0           $self->{zconf}->writeSetFromLoadedConfig({config=>'mail'});
2358 0 0         if ($self->{zconf}->error) {
2359 0           $self->{errorString}='ZConf failed to write the set out.';
2360 0           $self->{error}=36;
2361 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2362 0           return undef;
2363             }
2364              
2365 0           return 1;
2366             }
2367              
2368             =head2 getAccounts
2369              
2370             Gets a array of the various accounts.
2371              
2372             my @accounts=$zcmail->getAccounts;
2373             if($zcmail->error){
2374             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2375             }
2376              
2377             =cut
2378              
2379             sub getAccounts{
2380 0     0 1   my $self=$_[0];
2381 0           my $method='getAccounts';
2382              
2383             #blanks any previous errors
2384 0           $self->errorBlank;
2385 0 0         if ($self->error) {
2386 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2387 0           return undef;
2388             }
2389              
2390             #searches the mail config for any thing under 'acounts/'
2391 0           my @matched=$self->{zconf}->regexVarSearch('mail', '^accounts/');
2392              
2393 0           my $matchedInt=0;
2394              
2395 0           my %accountsH;
2396              
2397             #goes through the list and splits it apart...
2398             #A hash is used for this as this operates on every key under a account... this means
2399             #it will be finding multiple hits for each account
2400 0           while (defined($matched[$matchedInt])) {
2401 0           my @split=split(/\//, $matched[$matchedInt],4);
2402 0           $accountsH{$split[1].'/'.$split[2]}='';
2403            
2404 0           $matchedInt++;
2405             }
2406              
2407             #returns a array of the accounts
2408 0           return keys(%accountsH);
2409             }
2410              
2411             =head2 getAccountArgs
2412              
2413             This gets the various variables for a account, with 'accounts/*/*/' removed.
2414              
2415             One arguement is required and that is the account name.
2416              
2417             #get the account args for 'pop3/foo'
2418             my %args=$zcmail->getAccountArgs('pop3/foo');
2419             if($zcmail->error){
2420             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2421             }
2422              
2423             =cut
2424              
2425             sub getAccountArgs{
2426 0     0 1   my $self=$_[0];
2427 0           my $account=$_[1];
2428 0           my $method='getAccountArgs';
2429              
2430             #blanks any previous errors
2431 0           $self->errorBlank;
2432 0 0         if ($self->error) {
2433 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2434 0           return undef;
2435             }
2436              
2437             #This implements a simple check to make sure no one passed
2438             #'pop3/' or something like that. It also makes sure that
2439             #nothing past the account name is refered to.
2440 0           my @split=split(/\//, $account);
2441 0 0 0       if (!defined($split[1]) || defined($split[3])) {
2442 0           $self->{error}=4;
2443 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
2444 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2445 0           return undef;
2446             }
2447              
2448             #
2449 0 0         if (!$self->accountExists($account)) {
2450 0           $self->{error}=6;
2451 0           $self->{errorString}='The account "'.$account.'" does not exist';
2452 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2453 0           return undef;
2454             }
2455              
2456             #gets the variables for the account.
2457 0           my %vars=$self->{zconf}->regexVarGet('mail', '^accounts/'.$account.'/');
2458              
2459 0           my @keys=keys(%vars);
2460 0           my $keysInt=0;
2461 0           while (defined($keys[$keysInt])) {
2462 0           my $newvar=$keys[$keysInt];
2463             #removes the prefixed stuff for the variables for the account
2464 0           $newvar=~s/^accounts\/$account\///;
2465              
2466             #copies it
2467 0           $vars{$newvar}=$vars{$keys[$keysInt]};
2468              
2469             #removes the original
2470 0           delete($vars{$keys[$keysInt]});
2471              
2472 0           $keysInt++;
2473             }
2474              
2475 0           return %vars;
2476             }
2477              
2478             =head2 getSet
2479              
2480             This gets what the current set is.
2481              
2482             my $set=$zcmail->getSet;
2483             if($zcmail->error){
2484             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2485             }
2486              
2487             =cut
2488              
2489             sub getSet{
2490 0     0 1   my $self=$_[0];
2491 0           my $method='getSet';
2492              
2493             #blanks any previous errors
2494 0           $self->errorBlank;
2495 0 0         if ($self->error) {
2496 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2497 0           return undef;
2498             }
2499              
2500 0           my $set=$self->{zconf}->getSet('mail');
2501 0 0         if($self->{zconf}->{error}){
2502 0           $self->{error}=2;
2503 0           $self->{errorString}='ZConf error getting the loaded set the config "mail".'.
2504             ' ZConf error="'.$self->{zconf}->{error}.'" '.
2505             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
2506 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2507 0           return undef;
2508             }
2509              
2510 0           return $set;
2511             }
2512              
2513             =head2 init
2514              
2515             This is used for initiating the config used by ZConf.
2516              
2517             $zcmail->init;
2518             if($zcmail->error){
2519             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2520             }
2521              
2522             =cut
2523              
2524             sub init{
2525 0     0 1   my $self=$_[0];
2526 0           my %args;
2527 0 0         if(defined($_[1])){
2528 0           %args= %{$_[1]};
  0            
2529             }
2530 0           my $method='init';
2531              
2532             #blanks any previous errors
2533 0           $self->errorBlank;
2534 0 0         if ($self->error) {
2535 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2536 0           return undef;
2537             }
2538              
2539             #creates the config if needed
2540 0 0         if (!$self->{zconf}->configExists("mail")){
2541 0 0         if ($self->{zconf}->createConfig('mail')){
2542 0           $self->{error}=8;
2543 0           $self->{errorString}='Could not create the config. $self->{zconf}->{error}="'.
2544             $self->{zconf}->{error}.'" $self->{zconf}->{errorString}="'.
2545             $self->{zconf}->{errorString}.'"';
2546 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2547 0           return undef;
2548             }
2549             }
2550              
2551 0           return 1;
2552             }
2553              
2554             =head2 listSets
2555              
2556             This lists the available sets.
2557              
2558             my @sets=$zcmail->listSets;
2559             if($zcmail->error){
2560             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2561             }
2562              
2563             =cut
2564              
2565             sub listSets{
2566 0     0 1   my $self=$_[0];
2567 0           my $method='listSets';
2568              
2569             #blanks any previous errors
2570 0           $self->errorBlank;
2571 0 0         if ($self->error) {
2572 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2573 0           return undef;
2574             }
2575              
2576 0           my @sets=$self->{zconf}->getAvailableSets('mail');
2577 0 0         if($self->{zconf}->{error}){
2578 0           $self->{error}=2;
2579 0           $self->{errorString}='ZConf error listing sets for the config "mail".'.
2580             ' ZConf error="'.$self->{zconf}->{error}.'" '.
2581             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
2582 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2583 0           return undef;
2584             }
2585              
2586 0           return @sets;
2587             }
2588              
2589             =head2 modAccount
2590              
2591             Modifies a account.
2592              
2593             =head3 args hash
2594              
2595             Outside of account type, the rest are variables that will be changed.
2596              
2597             =head4 type
2598              
2599             This is the type of a account it is. It is always lower case as can be
2600             seen in the variables section.
2601              
2602             =head4 account
2603              
2604             This is the name of the account. It will be appended after the account
2605             type. Thus for the account 'pop3/some account name' it will be
2606             'some account name'.
2607              
2608             =cut
2609              
2610             sub modAccount{
2611 0     0 1   my $self=$_[0];
2612 0           my %args;
2613 0 0         if(defined($_[1])){
2614 0           %args= %{$_[1]};
  0            
2615             }
2616 0           my $method='modAccount';
2617              
2618             #blanks any previous errors
2619 0           $self->errorBlank;
2620 0 0         if ($self->error) {
2621 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2622 0           return undef;
2623             }
2624              
2625             #make sure the type is defined
2626 0 0         if (!defined($args{type})) {
2627 0           $self->{error}='2';
2628 0           $self->{errorString}='$args{type} is undefined';
2629 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2630 0           return undef;
2631             }
2632              
2633             #make sure it is a known type
2634 0 0         if (!defined($self->{legal}{$args{type}})) {
2635 0           $self->{error}='3';
2636 0           $self->{errorString}='$args{type}, "'.$args{type}.'", not a valid value';
2637 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2638 0           return undef;
2639             }
2640              
2641             #make sure it is a legit account name
2642 0 0         if (!$self->{zconf}->setNameLegit($args{account})){
2643 0           $self->{error}='3';
2644 0           $self->{errorString}='$args{account}, "'.$args{account}.'", not a legit account name';
2645 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2646 0           return undef;
2647             }
2648              
2649             #puts together the accountname
2650 0           my $account=$args{type}.'/'.$args{account};
2651              
2652             #makes sure the account exists
2653 0 0         if (!$self->accountExists($account)) {
2654 0           $self->{error}=6;
2655 0           $self->{errorString}='The account "'.$account.'" does not exist';
2656 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2657 0           return undef;
2658             }
2659              
2660             #adds them
2661 0           my $int=0;
2662 0           while (defined($self->{legal}{$args{type}}[$int])) {
2663 0           my $variable='accounts/'.$args{type}.'/'.$args{account}.'/'.$self->{legal}{$args{type}}[$int];
2664              
2665             #sets the value
2666             #not doing any error checking as there is no reason to believe it will fail
2667 0           $self->{zconf}->setVar('mail', $variable, $args{$self->{legal}{$args{type}}[$int]});
2668              
2669 0           $int++;
2670             }
2671              
2672             #saves it
2673 0           $self->{zconf}->writeSetFromLoadedConfig({config=>'mail'});
2674 0 0         if ($self->{zconf}->{error}) {
2675 0           $self->{error}=36;
2676 0           $self->{errorString}='ZConf failed to write the set out.';
2677 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2678 0           return undef;
2679             }
2680              
2681 0           return 1;
2682             }
2683              
2684             =head2 readSet
2685              
2686             This reads a specific set. If the set specified
2687             is undef, the default set is read.
2688              
2689             #read the default set
2690             $zcmail->readSet();
2691             if($zcmail->error){
2692             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2693             }
2694              
2695             #read the set 'someSet'
2696             $zcmail->readSet('someSet');
2697             if($zcmail->error){
2698             warn('Error:'.$zcmail->error.': '.$zcmail->errorString);
2699             }
2700              
2701             =cut
2702              
2703             sub readSet{
2704 0     0 1   my $self=$_[0];
2705 0           my $set=$_[1];
2706 0           my $method='readSet';
2707            
2708             #blanks any previous errors
2709 0           $self->errorBlank;
2710 0 0         if ($self->error) {
2711 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2712 0           return undef;
2713             }
2714              
2715 0           $self->{zconf}->read({config=>'mail', set=>$set});
2716 0 0         if ($self->{zconf}->{error}) {
2717 0           $self->{error}=2;
2718 0           $self->{errorString}='ZConf error reading the config "mail".'.
2719             ' ZConf error="'.$self->{zconf}->{error}.'" '.
2720             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
2721 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2722 0           return undef;
2723             }
2724              
2725 0           return 1;
2726             }
2727              
2728             =head2 send
2729              
2730             This sends a email. One arguement is accepted and that is a hash.
2731              
2732             =head3 args hash
2733              
2734             =head4 account
2735              
2736             This is the account it is sending for. If this is not specified,
2737             the default sendable account is used.
2738              
2739             =head4 to
2740              
2741             This is a array of to addresses.
2742              
2743             =head4 cc
2744              
2745             This is a array of cc addresses.
2746              
2747             =head4 bcc
2748              
2749             This is a array of bcc addresses.
2750              
2751             =head4 mail
2752              
2753             This is the raw mail message to send.
2754              
2755             =head4 save
2756              
2757             This will override if a sent message will be saved or not.
2758              
2759             =cut
2760              
2761             sub send{
2762 0     0 1   my $self=$_[0];
2763 0           my %args;
2764 0 0         if(defined($_[1])){
2765 0           %args= %{$_[1]};
  0            
2766             }
2767 0           my $method='send';
2768              
2769             #blanks any previous errors
2770 0           $self->errorBlank;
2771 0 0         if ($self->error) {
2772 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2773 0           return undef;
2774             }
2775              
2776 0 0         if (!defined($args{account})) {
2777 0           $args{account}=$self->defaultSendableGet;
2778             }
2779              
2780             #makes sure we have mail
2781 0 0         if (!defined($args{mail})) {
2782 0           $self->{error}=5;
2783 0           $self->{errorString}='The hash arg "mail" is missing and thus nothing to send';
2784 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2785 0           return undef;
2786             }
2787              
2788             #creates the SMTP connection
2789 0           my $smtp=$self->connectSMTP($args{account});
2790 0 0         if ($self->{error}) {
2791 0           warn('ZConf-Mail send:'.$self->{error}.': Failed to establish an SMTP connection');
2792 0           return undef;
2793             }
2794              
2795 0           $smtp->mail($self->{zconf}->{conf}{mail}{'accounts/'.$args{account}.'/from'});
2796              
2797             #sends the to addresses
2798 0           my $int=0;
2799 0           while (defined($args{to}[$int])) {
2800 0           $smtp->to($args{to}[$int]);
2801 0 0         if ($?) {
2802 0           $self->{error}=26;
2803 0           $self->{errorString}='Failed to send the To address "'.$args{to}[$int].'"';
2804 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2805             }
2806 0           $int++;
2807             }
2808              
2809             #sends the cc addresses
2810 0           $int=0;
2811 0           while (defined($args{cc}[$int])) {
2812 0           $smtp->to($args{cc}[$int]);
2813 0 0         if ($?) {
2814 0           $self->{error}=26;
2815 0           $self->{errorString}='Failed to send the CC address "'.$args{cc}[$int].'"';
2816 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2817             }
2818 0           $int++;
2819             }
2820              
2821             #sends the bcc addresses
2822 0           $int=0;
2823 0           while (defined($args{bcc}[$int])) {
2824 0           $smtp->to($args{bcc}[$int]);
2825 0 0         if ($?) {
2826 0           $self->{error}=26;
2827 0           $self->{errorString}='Failed to send the BCC address "'.$args{bcc}[$int].'"';
2828 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2829             }
2830 0           $int++;
2831             }
2832              
2833             #tries to start the data session
2834 0 0         if (!$smtp->data) {
2835 0           $self->{error}=27;
2836 0           $self->{errorString}='Failed to start the data session.';
2837 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2838             }
2839              
2840             #sends the data
2841 0 0         if (!$smtp->datasend($args{mail})) {
2842 0           $self->{error}=28;
2843 0           $self->{errorString}='Failed to send the data.';
2844 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2845             }
2846              
2847             #ends the data session
2848             #Not currently doing error checking as this appears to error occasionally
2849             #with out any detectable reason.
2850 0 0         if (!$smtp->dataend) {
2851             # warn('ZConf-Mail send:29: Failed to end the data.');
2852             # $self->{error}=29;
2853             # $self->{errorString}='Failed to end the data session.';
2854             }
2855              
2856             #quits
2857 0 0         if (!$smtp->quit) {
2858 0           $self->{error}=30;
2859 0           $self->{errorString}='Failed to end the SMTP session.';
2860 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2861             }
2862              
2863             #we know it has args if we get this far so we don't have to check it
2864 0           my %acctArgs=$self->getAccountArgs($args{account});
2865              
2866             #saves it if asked
2867 0 0         if ($args{save}) {
2868 0 0         if (!defined($acctArgs{saveTo})) {
2869 0           $self->{error}=37;
2870 0           $self->{errorString}='saveTo is undefined and thus the mail can\'t be saved.';
2871 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2872 0           return undef;
2873             }
2874              
2875 0 0         if ($acctArgs{saveTo}=~ /^$/) {
2876 0           $self->{error}=37;
2877 0           $self->{errorString}='saveTo is is set to "" and thus the mail can\'t be saved';
2878 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2879 0           return undef;
2880             }
2881            
2882 0           $self->deliver($acctArgs{saveTo}, $args{mail},{folder=>$acctArgs{folder}});
2883 0 0         if ($self->{error}) {
2884 0           warn('ZConf-BGSet send: deliver errored');
2885 0           return undef;
2886             }
2887              
2888 0           return 1;
2889             }
2890              
2891 0           $self->deliver($acctArgs{saveTo}, $args{mail},{folder=>$acctArgs{saveToFolder}});
2892 0 0         if ($self->{error}) {
2893 0           warn('ZConf-BGSet send: deliver errored');
2894 0           return undef;
2895             }
2896              
2897 0           return 1;
2898             }
2899              
2900             =head2 sendable
2901              
2902             Checks to see if a sendable.
2903              
2904             #checks to see if 'smtp/foo' is sendable
2905             if(!$zcmail->sendable('smtp/foo')){
2906             print 'not sendable'
2907             }
2908              
2909             =cut
2910              
2911             sub sendable{
2912 0     0 1   my $self=$_[0];
2913 0           my $account=$_[1];
2914 0           my $method='sendable';
2915              
2916             #blanks any previous errors
2917 0           $self->errorBlank;
2918 0 0         if ($self->error) {
2919 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2920 0           return undef;
2921             }
2922              
2923             #This implements a simple check to make sure no one passed
2924             #'pop3/' or something like that. It also makes sure that
2925             #nothing past the account name is refered to.
2926 0           my @split=split(/\//, $account);
2927 0 0 0       if (!defined($split[1]) || defined($split[3])) {
2928 0           $self->{error}=4;
2929 0           $self->{errorString}='"'.$account.'" is not a valid acocunt name';
2930 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2931 0           return undef;
2932             }
2933              
2934             #makes sure the account exists
2935 0 0         if (!$self->accountExists($account)) {
2936 0           $self->{error}=6;
2937 0           $self->{errorString}='The account "'.$account.'" does not exist';
2938 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2939 0           return undef;
2940             }
2941              
2942             #makes sure it is a smtp account
2943 0 0         if (!$account =~ /^smtp\//) {
2944 0           $self->{error}=24;
2945 0           $self->{errorString}='Account is not a sendable type.';
2946 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2947 0           return undef;
2948             }
2949              
2950 0           return 1;
2951             }
2952              
2953             =head2 sign
2954              
2955             This signs the body.
2956              
2957             There are three required arguements. The first is the
2958             account name it will be sending from. The second the
2959             body of the email. The third is the to address.
2960              
2961             =cut
2962              
2963             sub sign{
2964 0     0 1   my $self=$_[0];
2965 0           my $account=$_[1];
2966 0           my $body=$_[2];
2967 0           my $to=$_[3];
2968 0           my $method='sign';
2969              
2970             #blanks any previous errors
2971 0           $self->errorBlank;
2972 0 0         if ($self->error) {
2973 0           warn($self->{method}.' '.$method.': Failed to blank previous error');
2974 0           return undef;
2975             }
2976              
2977             #makes sure the account exists
2978 0 0         if (!$self->accountExists($account)) {
2979 0           $self->{error}=6;
2980 0           $self->{errorString}='"'.$account.'" does not exist';
2981 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2982 0           return undef;
2983             }
2984              
2985             #error if we don't have a body
2986 0 0         if (!defined($body)) {
2987 0           $self->{error}=5;
2988 0           $self->{errorString}='No body is defined';
2989 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2990 0           return undef;
2991             }
2992              
2993             #get the args for the account
2994 0           my %Aargs=$self->getAccountArgs($account);
2995 0 0         if ($self->{error}) {
2996 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
2997 0           return undef;
2998             }
2999              
3000 0 0         if ($Aargs{pgpType} eq 'mimesign') {
3001 0           $body="Content-Disposition: inline\n".
3002             "Content-Transfer-Encoding: quoted-printable\n".
3003             "Content-Type: text/plain\n\n".encode_qp($body);
3004             }
3005              
3006 0           my $hash='SHA512';
3007 0 0         if (defined($Aargs{PGPdigestAlgo})) {
3008 0           $hash=$Aargs{PGPdigestAlgo};
3009             }
3010              
3011             #make sure the sign type is specified
3012 0 0         if (!defined($Aargs{pgpType})) {
3013 0           $self->{error}=41;
3014 0           $self->{errorString}='"pgpType" account arg is not defined';
3015 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
3016 0           return undef;
3017             }
3018              
3019             #make sure a key is specified
3020 0 0         if (!defined($Aargs{PGPkey})) {
3021 0           $self->{error}=41;
3022 0           $self->{errorString}='"PGPkey" account arg is not defined';
3023 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
3024 0           return undef;
3025             }
3026              
3027             #make sure the sign type is supported
3028 0           my @types=('clearsign', 'mimesign', 'signencrypt');
3029 0           my $int=0;
3030 0           my $matched=0;
3031 0           while($types[$int]){
3032 0 0         if ($types[$int] eq $Aargs{pgpType}) {
3033 0           $matched=1;
3034             }
3035              
3036 0           $int++;
3037             }
3038 0 0         if (!$matched) {
3039 0           $self->{error}=43;
3040 0           $self->{errorString}='The type, "'.$Aargs{pgpType}.'", is not a valid type';
3041 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
3042 0           return undef;
3043             }
3044              
3045             #creates the body directory
3046 0           my $bodydir='/tmp/'.time().rand();
3047 0 0         if (!mkdir($bodydir)) {
3048 0           $self->{error}=39;
3049 0           $self->{errorString}='Faied to create the temporary directory,"'.
3050             $bodydir.'", for signing.';
3051 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
3052 0           return undef;
3053             }
3054 0           my $bodyfile=$bodydir.'/body';
3055              
3056             #if we are doing mimesigning, we need to
3057 0 0         if ($Aargs{pgpType} eq 'mimesign') {
3058 0           $body=~s/\n/\r\n/g;
3059             }
3060              
3061             #open it and write to it
3062 0 0         if (!open(BODYWRITE, '>'.$bodyfile)) {
3063 0           rmdir($bodydir);
3064 0           $self->{error}=40;
3065 0           $self->{errorString}='Failed to write body to "'.$bodyfile.
3066             '", for signing';
3067 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
3068 0           return undef;
3069             }
3070 0           print BODYWRITE $body;
3071              
3072             #this is the file that will be read into $sign
3073 0           my $read=undef;
3074              
3075             #this is what will be returned
3076 0           my $sign=undef;
3077              
3078             #handles clear signing
3079 0           my $execstring='gpg -u '.$Aargs{PGPkey}.' --digest-algo '.$hash.' ';
3080 0 0         if ($Aargs{pgpType} eq 'clearsign') {
3081 0           $execstring=$execstring.' --clearsign '.$bodyfile;
3082 0           system($execstring);
3083 0 0         if ($? ne '0') {
3084 0           $sign->{error}=44;
3085 0           $sign->{errorString}='Signing failed. Command="'.$execstring.'"';
3086 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
3087 0           return undef;
3088             }
3089 0           $read=$bodyfile.'.asc';
3090             }
3091              
3092             #handles mime signing
3093 0 0         if ($Aargs{pgpType} eq 'mimesign') {
3094 0           $execstring=$execstring.' -a --detach-sign '.$bodyfile;
3095 0           system($execstring);
3096 0 0         if ($? ne '0') {
3097 0           $sign->{error}=44;
3098 0           $sign->{errorString}='Signing failed. Command="'.$execstring.'"';
3099 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
3100 0           return undef;
3101             }
3102 0           $read=$bodyfile.'.asc';
3103             }
3104              
3105             #handles sign and encrypt
3106 0 0         if ($Aargs{pgpType} eq 'signencrypt') {
3107 0           $execstring=$execstring.' -se -r '..' '.$bodyfile;
3108 0           system($execstring);
3109 0 0         if ($? ne '0') {
3110 0           $sign->{error}=44;
3111 0           $sign->{errorString}='Signing failed. Command="'.$execstring.'"';
3112 0           warn($self->{module}.' '.$method.':'.$self->error.': '.$self->errorString);
3113 0           return undef;
3114             }
3115 0           $read=$bodyfile.'.gpg';
3116             }
3117              
3118 0           open(SIGNREAD, '<'.$read);
3119 0           $sign=join("", );
3120 0           close(SIGNREAD);
3121              
3122 0           unlink($bodyfile);
3123 0           unlink($read);
3124 0           rmdir($bodydir);
3125              
3126 0           return $sign;
3127             }
3128              
3129             =head1 ERROR RELATED METHODS
3130              
3131             =head2 error
3132              
3133             Returns the current error code and true if there is an error.
3134              
3135             If there is no error, undef is returned.
3136              
3137             if($zconf->error){
3138             warn('error: '.$zconf->error.":".$zconf->errorString);
3139             }
3140              
3141             =cut
3142              
3143             sub error{
3144 0     0 1   return $_[0]->{error};
3145             }
3146              
3147             =head2 errorBlank
3148              
3149             This blanks the error storage and is only meant for internal usage.
3150              
3151             It does the following.
3152              
3153             $self->{error}=undef;
3154             $self->{errorString}="";
3155              
3156             =cut
3157              
3158             #blanks the error flags
3159             sub errorBlank{
3160 0     0 1   my $self=$_[0];
3161              
3162 0 0         if ($self->{perror}){
3163 0           warn($self->{module}.' errorBlank; A permanent error is set');
3164 0           return undef;
3165             }
3166              
3167 0           $self->{error}=undef;
3168 0           $self->{errorString}="";
3169              
3170 0           return 1;
3171             }
3172              
3173             =head2 errorString
3174              
3175             Returns the error string if there is one. If there is not,
3176             it will return ''.
3177              
3178             if($zconf->error){
3179             warn('error: '.$zconf->error.":".$zconf->errorString);
3180             }
3181              
3182             =cut
3183              
3184             sub errorString{
3185 0     0 1   return $_[0]->{errorString};
3186             }
3187              
3188             =head1 VARIABLES
3189              
3190             In the various sections below, '*' is used to represent the name of a account.
3191             Account names can't match the following.
3192              
3193             undef
3194             /\//
3195             /^\./
3196             /^ /
3197             / $/
3198             /\.\./
3199              
3200             =head2 POP3
3201              
3202             =head3 accounts/pop3/*/user
3203              
3204             This is the username for a POP3 account.
3205              
3206             =head3 accounts/pop3/*/pass
3207              
3208             This is the password for a POP3 account.
3209              
3210             =head3 accounts/pop3/*/useSSL
3211              
3212             If set to a boolean value of true, SSL will be used.
3213              
3214             =head3 accounts/pop3/*/deliverTo
3215              
3216             This is the account to deliver to.
3217              
3218             =head3 accounts/imap/*/deliverToFolder
3219              
3220             This is the folder in the account to deliver to.
3221              
3222             =head3 accounts/pop3/*/fetchable
3223              
3224             If this account should be considered fetchable. If this flag
3225             is set, this will not be fetched my 'Mail::ZConf::Fetch'.
3226              
3227             =head3 accounts/pop3/*/auth
3228              
3229             This is the auth type to use with the POP3 server.
3230              
3231             =head3 accounts/pop3/*/server
3232              
3233             The POP3 server to use.
3234              
3235             =head3 accounts/pop3/*/port
3236              
3237             The port on the server to use.
3238              
3239             =head2 IMAP
3240              
3241             =head3 accounts/imap/*/
3242              
3243             Any thing under here under here is a IMAP account.
3244              
3245             =head3 accounts/imap/*/user
3246              
3247             This is the username for a IMAP account.
3248              
3249             =head3 accounts/imap/*/pass
3250              
3251             This is the password for a IMAP account.
3252              
3253             =head3 accounts/imap/*/useSSL
3254              
3255             If set to a boolean value of true, SSL will be used.
3256              
3257             =head3 accounts/imap/*/deliverTo
3258              
3259             This is the account to deliver to.
3260              
3261             =head3 accounts/imap/*/deliverToFolder
3262              
3263             This is the folder in the account to deliver to.
3264              
3265             =head3 accounts/imap/*/fetchable
3266              
3267             If this account should be considered fetchable. If this flag
3268             is set, this will not be fetched my 'ZConf::Mail::Fetch', not
3269             written yet.
3270              
3271             This should be set if you are planning on using it for storage.
3272              
3273             =head3 accounts/imap/*/inbox
3274              
3275             This is the inbox that the mail should be delivered to.
3276              
3277             =head3 accounts/imap/*/server
3278              
3279             The IMAP server to use.
3280              
3281             =head3 accounts/imap/*/port
3282              
3283             The port on the server to use.
3284              
3285             =head2 MBOX
3286              
3287             =head3 accounts/mbox/*/mbox
3288              
3289             This is the MBOX file to use.
3290              
3291             =head3 accounts/mbox/*/deliverTo
3292              
3293             This is the account to deliver to.
3294              
3295             =head3 accounts/mbox/*/fetchable
3296              
3297             If this account should be considered fetchable. If this flag
3298             is set, this will not be fetched my 'ZConf::Mail::Fetch', not
3299             written yet.
3300              
3301             =head2 Maildir
3302              
3303             =head3 accounts/maildir/*/maildir
3304              
3305             This is the MBOX file to use.
3306              
3307             =head3 accounts/maildir/*/deliverTo
3308              
3309             This is the account to deliver to.
3310              
3311             =head3 accounts/imap/*/deliverToFolder
3312              
3313             This is the folder in the account to deliver to.
3314              
3315             =head3 accounts/maildir/*/fetchable
3316              
3317             If this account should be considered fetchable. If this flag
3318             is set, this will not be fetched my 'ZConf::Mail::Fetch', not
3319             written yet.
3320              
3321             =head2 SMTP
3322              
3323             =head3 accounts/smtp/*/user
3324              
3325             This is the username for a SMTP account.
3326              
3327             =head3 accounts/smtp/*/pass
3328              
3329             This is the password for a SMTP account.
3330              
3331             =head3 accounts/smtp/*/auth
3332              
3333             This is the auth type to use with the SMTP server.
3334              
3335             =head3 accounts/smtp/*/server
3336              
3337             The SMTP server to use.
3338              
3339             =head3 accounts/smtp/*/port
3340              
3341             The port on the server to use.
3342              
3343             =head3 accounts/smtp/*/useSSL
3344              
3345             If set to a boolean value of true, SSL will be used.
3346              
3347             =head3 accounts/smtp/*/from
3348              
3349             The from address to use for a account.
3350              
3351             =head3 accounts/smtp/*/name
3352              
3353             The name that will be used with the account.
3354              
3355             =head3 accounts/smtp/*/saveTo
3356              
3357             This is the account to save it to. If it not defined
3358             or blank, it will not saved.
3359              
3360             =head3 accounts/smtp/*/saveToFolder
3361              
3362             This is the folder to save it to for the account.
3363              
3364             =head3 accounts/smtp/*/timeout
3365              
3366             The time out for connecting to the server.
3367              
3368             =head3 accounts/smtp/*/usePGP
3369              
3370             If PGP should be used or not for this account. This is a Perl boolean value.
3371              
3372             =head3 accounts/smtp/*/pgpType
3373              
3374             =head4 clearsign
3375              
3376             Clear sign the message.
3377              
3378             =head4 mimesign
3379              
3380             Attach the signature as a attachment.
3381              
3382             =head4 signencrypt
3383              
3384             Sign and encrypt the message. Not yet implemented.
3385              
3386             =head3 accounts/smtp/*/PGPkey
3387              
3388             The PGP key to use.
3389              
3390             =head3 accounts/smtp/*/PGPdigestAlgo
3391              
3392             The digest algorithym to use. It will default to 'SHA512' if not specified.
3393              
3394             To find what out what your version supports, run 'gpg --version'.
3395              
3396             =head2 EXEC
3397              
3398             =head3 deliver
3399              
3400             This is the command to execute for delivering a mail message. A single message
3401             will be delivered at a time by running the specified program and piping the message
3402             into it. Only a single message is delivered at once.
3403              
3404             A example would be setting this to '/usr/local/libexec/dovecot/deliver' to deliver a
3405             message one's dovecot account.
3406              
3407             =head2 FORMATTER
3408              
3409             =head3 formatter/marginLeft
3410              
3411             This is the left margin. The default is zero if this is not defined.
3412              
3413             =head3 formatter/marginRight
3414              
3415             This is the right margin. The default is 72 if this is not defined.
3416              
3417             =head3 formatter/squeeze
3418              
3419             Removes unneeded whitespace. This is on by default.
3420              
3421             =head3 formatter/ignore
3422              
3423             Don't reformat any paragraph that matches this line. The default is '^[ \t]'.
3424              
3425             =head3 formatter/justify
3426              
3427             How to justify the text. The default is left.
3428              
3429             =head3 formatter/tabspace
3430              
3431             This is the default spaces per tab. The default is '4'.
3432              
3433             =head2 MISC
3434              
3435             =head3 default/sendable
3436              
3437             This is the default sendable account. If this key does not exist or set to '',
3438             there is no default sendable account.
3439              
3440             =head3 default/fetchable
3441              
3442             This is the default fetchable account. If this key does not exist or set to '',
3443             there is no default fetchable account.
3444              
3445             =head2 INTERNAL VARIABLES
3446              
3447             =head3 $zcmail->{init}
3448              
3449             If this is false, '$zcmail->init' needs run.
3450              
3451             =head3 $zcmail->{legal}
3452              
3453             This hashes which contains the legal values for each type in a array. So for SMTP,
3454             '$zcmail->{legal}{smtp}' contains the array of legal values for SMTP.
3455              
3456             =head3 $zcmail->{required}
3457              
3458             This hashes which contains the required values for each type in a array. So for SMTP,
3459             '$zcmail->{required}{smtp}' contains the array of required values for SMTP.
3460              
3461             =head3 $zcmail->{fetchable}
3462              
3463             This contains a array of fetchable account types.
3464              
3465             =head3 $zcmail->{deliverable}
3466              
3467             This contains a array of deliverable account types.
3468              
3469             =head3 $zcmail->{sendable}
3470              
3471             This contains a array of sendable account types.
3472              
3473             =head1 ERROR CODES
3474              
3475             If any funtion errors, the error code is writen to '$zcmail->{error}', a error message
3476             is printed to stderr, and a short description is put in '$zcmail->{errorString}'.
3477              
3478             When no error is present '$zcmail->{error}' is false, specifically undef.
3479              
3480             =head2 1
3481              
3482             Could not create the config.
3483              
3484             =head2 2
3485              
3486             No account type specified.
3487              
3488             =head2 3
3489              
3490             Unknown account type specified.
3491              
3492             =head2 4
3493              
3494             Illegal account name.
3495              
3496             =head2 5
3497              
3498             A required variable is not defined.
3499              
3500             =head2 6
3501              
3502             Account does not exist.
3503              
3504             =head2 7
3505              
3506             Authenticating with the POP3 server failed.
3507              
3508             =head2 8
3509              
3510             Connecting to the POP3 server failed.
3511              
3512             =head2 9
3513              
3514             Failed to either connect to IMAP server or authenticate with it.
3515              
3516             =head2 10
3517              
3518             Failed to connect to SMTP server.
3519              
3520             =head2 11
3521              
3522             Failed to authenticate with the SMTP server.
3523              
3524             =head2 12
3525              
3526             Failed to send the from for the SMTP session.
3527              
3528             =head2 13
3529              
3530             Failed to authenticate or connect to the SMTP server.
3531              
3532             =head2 14
3533              
3534             Failed to access maildir.
3535              
3536             =head2 15
3537              
3538             Account is not fetchable.
3539              
3540             =head2 16
3541              
3542             Failed to connect to POP3.
3543              
3544             =head2 17
3545              
3546             POP3 fetch failed.
3547              
3548             =head2 18
3549              
3550             Failed to read a ZConf config.
3551              
3552             =head2 19
3553              
3554             Wrong account type.
3555              
3556             =head2 20
3557              
3558             IO::MultiPipe error. See the error string for detains on it.
3559              
3560             =head2 21
3561              
3562             Mbox message delete failed.
3563              
3564             =head2 22
3565              
3566             Mbox fetch failed.
3567              
3568             =head2 23
3569              
3570             IMAP folder select failed.
3571              
3572             =head2 24
3573              
3574             Account is not a sendable account type.
3575              
3576             =head2 25
3577              
3578             No To or CC defined.
3579              
3580             =head2 26
3581              
3582             Failed to send a To, CC, or BCC address.
3583              
3584             =head2 27
3585              
3586             Failed to start the data session.
3587              
3588             =head2 28
3589              
3590             Failed to send the data.
3591              
3592             =head2 29
3593              
3594             Failed to end the data session.
3595              
3596             =head2 30
3597              
3598             Failed to quit.
3599              
3600             =head2 31
3601              
3602             Failed to create a Email::Simple object.
3603              
3604             =head2 32
3605              
3606             The account has one or more missing variables.
3607              
3608             =head2 33
3609              
3610             No INBOX specified for the IMAP account.
3611              
3612             =head2 34
3613              
3614             Failed to selected IMAP folder.
3615              
3616             =head2 35
3617              
3618             Failed to append to the IMAP folder.
3619              
3620             =head2 36
3621              
3622             ZConf error.
3623              
3624             =head2 37
3625              
3626             'saveTo' is not enabled for this account. This means it is either
3627             undefined or set to ''.
3628              
3629             =head2 38
3630              
3631             File does not exist.
3632              
3633             =head2 39
3634              
3635             Failed to create temporary directory for signing.
3636              
3637             =head2 40
3638              
3639             Failed to create temprorary body file for signing.
3640              
3641             =head2 41
3642              
3643             No pgpType is not specified.
3644              
3645             =head2 42
3646              
3647             PGPGkey is not specified.
3648              
3649             =head2 43
3650              
3651             Sign type is not valid.
3652              
3653             =head2 44
3654              
3655             Signing failed.
3656              
3657             =head2 45
3658              
3659             The specified option is not a valid option.
3660              
3661             =head1 AUTHOR
3662              
3663             Zane C. Bowers, C<< >>
3664              
3665             =head1 BUGS
3666              
3667             Please report any bugs or feature requests to C, or through
3668             the web interface at L. I will be notified, and then you'll
3669             automatically be notified of progress on your bug as I make changes.
3670              
3671              
3672              
3673              
3674             =head1 SUPPORT
3675              
3676             You can find documentation for this module with the perldoc command.
3677              
3678             perldoc ZConf::Mail
3679              
3680              
3681             You can also look for information at:
3682              
3683             =over 4
3684              
3685             =item * RT: CPAN's request tracker
3686              
3687             L
3688              
3689             =item * AnnoCPAN: Annotated CPAN documentation
3690              
3691             L
3692              
3693             =item * CPAN Ratings
3694              
3695             L
3696              
3697             =item * Search CPAN
3698              
3699             L
3700              
3701             =back
3702              
3703              
3704             =head1 ACKNOWLEDGEMENTS
3705              
3706              
3707             =head1 COPYRIGHT & LICENSE
3708              
3709             Copyright 2008 Zane C. Bowers, all rights reserved.
3710              
3711             This program is free software; you can redistribute it and/or modify it
3712             under the same terms as Perl itself.
3713              
3714              
3715             =cut
3716              
3717             1; # End of ZConf::Mail