/
MailingList.cpp
696 lines (611 loc) · 21.5 KB
/
MailingList.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
/*MailingList.cpp
*
*MailingList objects represent the individual lists handled by a server
*
*
*Copyright 2013-2014 Andrew Wood awood@comms.org.uk
*All rights reserved
*/
#include "MailingList.h"
#include "IncomingMail.h"
#include "MailMistressApplication.h"
#include "AppWideBMessageDefs.h"
#include <storage/Directory.h>
#include <storage/File.h>
#include <storage/Path.h>
#include <storage/NodeMonitor.h>
#include <storage/Entry.h>
#include <app/Application.h>
#include <image.h>
#include <OS.h>
#include <stdlib.h>
#include <sstream>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cctype>
#include <mail/MailMessage.h>
extern BApplication* be_app;
class IncomingMail;
MailingList::MailingList(std::string icemail, std::string ogenvemail,std::string listname,std::string subjectpre,std::string dirpath,std::string authprogpath,std::string logfilepath,
bool forcetolist, std::string listowner, std::string listhelp, std::string listarchive, std::string listsubscribe, std::string listunsubscribe)
{
fApp=(MailMistressApplication*) be_app;
fListICAddress=icemail;
fListOGEnvelopeAddressFromAddress=ogenvemail;
fListName=listname;
fListInDirectoryPath=dirpath;
fAuthProgPath=authprogpath;
fLogFilePath=logfilepath;
fMaxContentBytes=100000000;
fLogSuccesses=true;
fPlainTextOnly='N';
fListSubjectPrefix=subjectpre; //already has [] surrounding it, this was done by MailMistressApplication
fForceReplyToList=forcetolist;
fListOwner=listowner; //will be null str if not set in conf file
fListHelp=listhelp; //will be null str if not set in conf file
fListArchive=listarchive; //will be null str if not set in conf file
fListSubscribe=listsubscribe; //will be null str if not set in conf file
fListUnSubscribe=listunsubscribe; //will be null str if not set in conf file
//set generic bounce msg in case there is a problem reading the custom msg file
fUnauthorisedBounceMsgContents=std::string("You are not authorised to post to the mailing list: ");
fUnauthorisedBounceMsgContents=fUnauthorisedBounceMsgContents+fListName+" ("+fListICAddress+")\n\n";
fUnauthorisedBounceMsgContents=fUnauthorisedBounceMsgContents+"This message was automatically generated by the "+fApp->GetAppName();
fUnauthorisedBounceMsgContents=fUnauthorisedBounceMsgContents+" for Haiku mailing list server at "+fListICAddress+"\nPlease contact the list owner for more details\n";
}
bool MailingList::InitLogFileSemaphores()
{
//return false if error
if (fLogFileSem = create_sem(1,"fLogFileSem") < B_NO_ERROR)
{
return false;
}
return true;
}
void MailingList::SetBounceMsg(std::string path)
{
//attempt to read the custom bounce message file
BFile bouncemsgbfile;
status_t bouncemsgfilestatus=bouncemsgbfile.SetTo(path.c_str(),B_READ_ONLY);
if (bouncemsgfilestatus==B_NO_ERROR)
{
off_t bytes; //size of file
if (bouncemsgbfile.GetSize(&bytes) == B_NO_ERROR)
{
char* buff = new char[bytes];
off_t bytesread=bouncemsgbfile.Read(buff,bytes);
if ( (bytesread > 0) && (bytesread < 50001) )
{
//file read ok
std::string oldbouncemsg=fUnauthorisedBounceMsgContents; //save generic bounce msg so it can be appended later
fUnauthorisedBounceMsgContents=""; //clear existing contents
for (int x=0; x < bytesread; x++)
{
fUnauthorisedBounceMsgContents=fUnauthorisedBounceMsgContents+buff[x];
}
fUnauthorisedBounceMsgContents=fUnauthorisedBounceMsgContents+"\n\n"+oldbouncemsg; //append generic msg
}
delete buff;
}
bouncemsgbfile.Unset(); //close file
}
}
void MailingList::SetArchivePath(std::string path)
{
fArchivePath=path;
}
void MailingList::SetMaxMsgBytes(unsigned long int bytes)
{
//will be adjusted down by the Go() method if app limit is lower
fMaxContentBytes=bytes;
}
void MailingList::Go()
{
if (fApp->GetMaxMsgBytes() < fMaxContentBytes)
{
fMaxContentBytes=fApp->GetMaxMsgBytes();
}
if (fApp->GetPlainTextOnly()=='Y')
{
if ( (fPlainTextOnly=='N') )
{
LogError("INFO: List is set to allow HTML text messages and attachments but server isn't. List setting is being overridden by server setting");
}
else if (fPlainTextOnly=='H')
{
LogError("INFO: List is set to allow HTML text messages but server isn't. List setting is being overridden by server setting");
}
fPlainTextOnly='Y';
}
else if (fApp->GetPlainTextOnly()=='H')
{
if ( (fPlainTextOnly=='N') )
{
LogError("INFO: List is set to allow HTML text messages but server isn't. List setting is being overridden by server setting");
fPlainTextOnly='H';
}
}
//setup Node Monitor to send messages to app if a new file appears
BDirectory indir(fListInDirectoryPath.c_str());
node_ref indir_node_ref;
status_t err;
if (indir.InitCheck() == B_OK)
{
indir.GetNodeRef(&indir_node_ref);
err=watch_node(&indir_node_ref,B_WATCH_DIRECTORY,be_app);
if (err!=B_OK)
{
//could not set watch on BDirectory
exit;
}
}
else
{
//could not init BDirectory
exit;
}
//now process any files which were already in the dir when we launched
BMessage msg(B_PULSE);
fApp->PostMessage(&msg,NULL);
}
void MailingList::SetPlainTextOnly(char pto)
{
fPlainTextOnly=pto;
}
bool MailingList::ProcessEmailFile(std::string emailfilepathstr)
{
/*
Check if sender of email is authorised to post to this list, if not return true and caller will delete file
else copy it to an outgoing email with relevent header changes, queue og mail for delivery
and return true so caller will delete file.
Any errors return false
*/
BFile* bfile = new BFile(emailfilepathstr.c_str(),B_READ_WRITE);
if (bfile->InitCheck() != B_NO_ERROR)
{
LogError("ERROR: Could not process an incoming email. BFile::InitCheck was false");
return false;
}
IncomingMail* ICMail= new IncomingMail(bfile,this);
if (ICMail->InitCheck()==false)
{
LogError("ERROR: Could not process an incoming email. File read failed. IncomingMail::InitCheck was false");
return false;
}
if (fLogSuccesses)
{
LogError("INFO: Processing an email file from "+ICMail->GetSendersAddr());
}
int32 authstatus=1;
/*
Return vals from external auth prog are
0=Authorised
1=Error
2=Not Authorsed - bounce msg
3=Not Authorised - silently discard
This func should return false if val is 1, thus ensuring the incoming file is not deleted and will be re-processed later
for all other values it should return true, indicating that the incoming file can be deleted
*/
int32 arg_c = 4; //no of args passed in arg_v
extern char **environ; //env variables
char **arg_v;
arg_v = (char **) malloc(sizeof(char*) * (arg_c+1)); //array must hold arg_c elements + a terminating null
std::stringstream epochsecs;
epochsecs << real_time_clock(); //secs now since unix epoch
int filenamecounterInt=0; //will be incremented until we get a unique filename string
bool nonuniquefilename=true;
BEntry tempFileBEntry;
std::string tempFilePath;
do
{
filenamecounterInt++;
std::stringstream filenamecounter;
filenamecounter << filenamecounterInt;
MailMistressApplication* app=(MailMistressApplication*) be_app;
tempFilePath=app->GetTempDirPath()+fListICAddress+"--"+ICMail->GetSendersAddr()+"--"+epochsecs.str()+filenamecounter.str();
//test if tempFilePath already exists
tempFileBEntry.SetTo(tempFilePath.c_str());
BFile tempFileBFile;
status_t tempFileResult=tempFileBFile.SetTo(&tempFileBEntry,B_READ_WRITE|B_FAIL_IF_EXISTS|B_CREATE_FILE); //fails if already exists
if (tempFileResult==B_FILE_EXISTS)
{
nonuniquefilename=true;
}
else if (tempFileResult==B_NO_ERROR)
{
nonuniquefilename=false;
tempFileBFile.Unset(); //close file
}
else
{
//error
bfile->Unset();
//delete ICMail obj
delete ICMail;
delete bfile;
return false;
}
}while(nonuniquefilename);
arg_v[0]=strdup(fAuthProgPath.c_str()); //path to exe
arg_v[1]=strdup((ICMail->GetSendersAddr()).c_str()); //senders email addr
arg_v[2]=strdup(tempFilePath.c_str()); //path to temp file
arg_v[3]=strdup(fListICAddress.c_str()); //list IC address
arg_v[4]=NULL;
thread_id authprog_team;
authprog_team=load_image(arg_c,(const char**)arg_v,(const char**)environ);
free(arg_v);
wait_for_thread(authprog_team,&authstatus);
//if authstatus==0 then temp file will now contain all recipient email addresses one per line
if (authstatus==0)
{
//send to recipients in temp file
if (DistributeEmail(ICMail,tempFilePath))
{
//delete temp file
tempFileBEntry.Remove();
//delete ICMail obj
delete ICMail;
//close orig email file
bfile->Unset();
delete bfile;
return true;
}
else
{
//delete temp file
tempFileBEntry.Remove();
//delete ICMail obj
delete ICMail;
//close orig email file
bfile->Unset();
delete bfile;
return false;
}
}
else if (authstatus==2)
{
LogError("INFO: Auth status 2 -- Bouncing to "+ICMail->GetSendersAddr());
BMailMessage* ogmail;
ogmail= new BMailMessage();
ogmail->AddHeaderField(B_MAIL_TO,(ICMail->GetSendersAddr()).c_str());
ogmail->AddHeaderField(B_MAIL_FROM,fListOGEnvelopeAddressFromAddress.c_str());
std::string bouncesubject=std::string("Undelivered mail: Your message to ");
bouncesubject=bouncesubject+fListName+" was rejected";
ogmail->AddHeaderField(B_MAIL_SUBJECT,bouncesubject.c_str());
ogmail->AddHeaderField("X-Mailer: ",(fApp->GetAppName()).c_str());
ogmail->AddContent(fUnauthorisedBounceMsgContents.c_str(),strlen(fUnauthorisedBounceMsgContents.c_str()));
ogmail->Send();
delete ogmail;
}
else if (authstatus==3)
{
LogError("INFO: Auth status 3 -- Silently discarding email from "+ICMail->GetSendersAddr());
}
//delete temp file
tempFileBEntry.Remove();
if ( (authstatus==2) || (authstatus==3) )
{
//ok so return true to delete incoming file
delete ICMail;
bfile->Unset();
delete bfile;
return true;
}
else
{
//error occured so return false and incoming file will be kept for reprocessing later
LogError("ERROR: Auth status 1 (or other error value). Either the autentication program failed to run or it encountered an error itself");
delete ICMail;
bfile->Unset();
delete bfile;
return false;
}
}
bool MailingList::DistributeEmail(IncomingMail* ICMail, std::string ogaddrfilepath)
{
//send ICMail to every address in ogaddrfilepath
std::vector<std::string> recipients;
BFile recipientlistbfile;
status_t filestatus=recipientlistbfile.SetTo(ogaddrfilepath.c_str(),B_READ_ONLY);
if (filestatus!=B_NO_ERROR)
{
LogError("ERROR: Could not read temp file from authentication program - the file could not be opened. Does it exist?");
return false;
}
off_t bytes; //size of file
if (recipientlistbfile.GetSize(&bytes) == B_NO_ERROR)
{
char* buff = new char[bytes];
off_t bytesread=recipientlistbfile.Read(buff,bytes);
if (bytesread > 0)
{
//file read ok
std::string addr="";
for (int x=0; x < bytesread; x++)
{
if (buff[x]!='\n')
{
addr=addr+buff[x];
}
else
{
recipients.push_back(addr);
addr="";
}
}
delete buff;
}
else
{
LogError("ERROR: Could not read temp file from authentication program - the file was empty");
delete buff;
return false;
}
}
else
{
LogError("ERROR: Could not read temp file from authentication program -- could not determine file size");
return false;
}
ICMail->AddSubjectPrefix(fListSubjectPrefix); //fListSubjectPrefix will be null str if not defined in conf file
ICMail->CleanHeaders(); //clean & setup headers ready for sending message out to recipients
ICMail->AdjustReplyTo(fForceReplyToList); //set reply to to either sender or list IC address
//if List-Xyz header values were set in conf file we need to set them in msg
if (fListOwner!="")
{
ICMail->SetListOwnerHeader(fListOwner);
}
if (fListHelp!="")
{
ICMail->SetListHelpHeader(fListHelp);
}
if (fListArchive!="")
{
ICMail->SetListArchiveHeader(fListArchive);
}
if (fListSubscribe!="")
{
ICMail->SetListSubscribeHeader(fListSubscribe);
}
if (fListUnSubscribe!="")
{
ICMail->SetListUnSubscribeHeader(fListUnSubscribe);
}
//call GetFromField to get email address in case we need to bounce msg
std::string ICsendersAddrField=ICMail->GetSendersAddr(); //returns null string if unable to find
//at present ICsendersAddrField now has address in form user@domain NOT <user@domain> is this in line with RFC spec?
if (ICMail->CheckIfPlainTextCriteriaPassed(fPlainTextOnly)==false)
{
//bounce
if (fPlainTextOnly=='Y')
{
//bounce to sender
LogError("INFO: Incoming email not text/plain and non plain text messages are not allowed. Bounced to "+ICsendersAddrField);
BMailMessage* ogmail;
ogmail= new BMailMessage();
ogmail->AddHeaderField(B_MAIL_TO,ICsendersAddrField.c_str());
ogmail->AddHeaderField(B_MAIL_FROM,fListOGEnvelopeAddressFromAddress.c_str());
std::string bouncesubject=std::string("Undelivered mail: Your message to ");
bouncesubject=bouncesubject+fListName+" was rejected";
ogmail->AddHeaderField(B_MAIL_SUBJECT,bouncesubject.c_str());
std::string xmailer=(fApp->GetAppName())+" mailing list server for Haiku";
ogmail->AddHeaderField("X-Mailer: ",xmailer.c_str());
ogmail->AddHeaderField("precedence: ","list");
std::string bouncecontent="Your message to "+fListName+" was rejected because this list only accepts plain text messages. Make sure your email program is not creating HTML or Rich Text emails and that there are no attached files.";
bouncecontent=bouncecontent+"\n\nThis is an automated reply sent from the "+fApp->GetAppName()+" for Haiku server at "+fListICAddress;
ogmail->AddContent(bouncecontent.c_str(),strlen(bouncecontent.c_str()));
ogmail->Send();
delete ogmail;
}
else
{
//fPlainTextOnly must be 'H'
//bounce to sender
LogError("INFO: Incoming email not HTML or plain text and non text messages are not allowed. Bounced to "+ICsendersAddrField);
BMailMessage* ogmail;
ogmail= new BMailMessage();
ogmail->AddHeaderField(B_MAIL_TO,ICsendersAddrField.c_str());
ogmail->AddHeaderField(B_MAIL_FROM,fListOGEnvelopeAddressFromAddress.c_str());
std::string bouncesubject=std::string("Undelivered mail: Your message to ");
bouncesubject=bouncesubject+fListName+" was rejected";
ogmail->AddHeaderField(B_MAIL_SUBJECT,bouncesubject.c_str());
std::string xmailer=(fApp->GetAppName())+" mailing list server for Haiku";
ogmail->AddHeaderField("X-Mailer: ",xmailer.c_str());
ogmail->AddHeaderField("precedence: ","list");
std::string bouncecontent="Your message to "+fListName+" was rejected because this list only accepts HTML or plain text messages. Make sure that there are no attached files.";
bouncecontent=bouncecontent+"\n\nThis is an automated reply sent from the "+fApp->GetAppName()+" for Haiku server at "+fListICAddress;
ogmail->AddContent(bouncecontent.c_str(),strlen(bouncecontent.c_str()));
ogmail->Send();
delete ogmail;
}
return true;
}
if (ICMail->GetICFileSize() > fMaxContentBytes)
{
//msg too big bounce to sender
LogError("INFO: Incoming email too big. Bounced to "+ICsendersAddrField);
BMailMessage* ogmail;
ogmail= new BMailMessage();
ogmail->AddHeaderField(B_MAIL_TO,ICsendersAddrField.c_str());
ogmail->AddHeaderField(B_MAIL_FROM,fListOGEnvelopeAddressFromAddress.c_str());
std::string bouncesubject=std::string("Undelivered mail: Your message to ");
bouncesubject=bouncesubject+fListName+" was rejected";
ogmail->AddHeaderField(B_MAIL_SUBJECT,bouncesubject.c_str());
std::string xmailer=(fApp->GetAppName())+" mailing list server for Haiku";
ogmail->AddHeaderField("X-Mailer: ",xmailer.c_str());
ogmail->AddHeaderField("precedence: ","list");
stringstream converter;
converter << fMaxContentBytes << " bytes, your message was " << ICMail->GetICFileSize() << " bytes";
std::string toobigcontent="Your message to "+fListName+" is too big and was rejected. Maximum allowable size for this list is "+converter.str();
toobigcontent=toobigcontent+"\n\nThis is an automated reply sent from the "+fApp->GetAppName()+" for Haiku server at "+fListICAddress;
ogmail->AddContent(toobigcontent.c_str(),strlen(toobigcontent.c_str()));
ogmail->Send();
delete ogmail;
return true;
}
//setup a temp file to store the modified og msg
std::stringstream epochsecs;
epochsecs << real_time_clock(); //secs now since unix epoch
int filenamecounterInt=0; //will be incremented until we get a unique filename string
bool nonuniquefilename=true;
BEntry tempFileBEntry;
std::string tempFilePath;
BFile* tempFileBFile = new BFile();
do
{
filenamecounterInt++;
std::stringstream filenamecounter;
filenamecounter << filenamecounterInt;
tempFilePath=fApp->GetTempDirPath()+fListICAddress+"--"+epochsecs.str()+filenamecounter.str();
//test if tempFilePath already exists
tempFileBEntry.SetTo(tempFilePath.c_str());
status_t tempFileResult=tempFileBFile->SetTo(&tempFileBEntry,B_READ_WRITE|B_FAIL_IF_EXISTS|B_CREATE_FILE); //fails if already exists
if (tempFileResult==B_FILE_EXISTS)
{
nonuniquefilename=true;
}
else if (tempFileResult==B_NO_ERROR)
{
nonuniquefilename=false;
}
else
{
//error
LogError("ERROR: Could not create temp file to store outgoing email");
return false;
}
}while(nonuniquefilename);
//Write modified msg into temp file
ICMail->WriteToFile(tempFileBFile);
//store senders addr so we can log it later
std::string sender="";
//Send out modified msg in temp file to all recipients
for (int x=0; x< recipients.size(); x++)
{
std::string recipient=recipients[x];
BEmailMessage* ogmail;
ogmail= new BEmailMessage(tempFileBFile);
ogmail->SetTo(recipient.c_str());
sender=std::string(ogmail->From());
//1st version of send indicates whether to change the From: field to the specified account (requires modified mailkit)
ogmail->SendViaAccountWithFromPreset(fListOGEnvelopeAddressFromAddress.c_str());
//ogmail->SendViaAccount(fListOGEnvelopeAddressFromAddress.c_str());
ogmail->Send(true);
delete ogmail;
}
tempFileBFile->Unset(); //close file
delete tempFileBFile; //delete obj
//archive msg if needed
bool archived=false;
if (fArchivePath!="")
{
BDirectory dir;
if ( dir.SetTo(fArchivePath.c_str()) !=B_OK )
{
LogError("ERROR: Could not archive message. Check archive folder exists and is writable");
}
else
{
if ( tempFileBEntry.MoveTo(&dir) !=B_NO_ERROR)
{
LogError("ERROR: Could not archive message. Check archive folder exists and is writable");
}
else
{
archived=true;
}
}
}
if (archived==false)
{
//if archived then the file was moved so we dont need to delete the original
tempFileBEntry.Remove();//remove file from filesystem
}
stringstream numRecipients;
numRecipients << recipients.size();
if ( (fLogSuccesses) && (recipients.size()>0) )
{
//if we recipients.size() was 0 sender var is null str as its set in the distribution loop
LogError("INFO: Successfully distributed an email to "+numRecipients.str()+" recipients from "+sender);
}
return true;
}
void MailingList::LogError(std::string msg)
{
if (fLogFilePath=="")
{
//log file not yet set (as during startup conf file pasrsing)
//use printf instead and dont warn about log file
printf(fApp->GetDateTime().c_str());
printf(" ");
printf(msg.c_str());
printf("\n");
return;
}
//check we can open file ok
//lock sem to prevent other threads accessing file
acquire_sem(fLogFileSem);
BFile logbfile;
status_t logfilestatus=logbfile.SetTo(fLogFilePath.c_str(),B_READ_WRITE|B_CREATE_FILE|B_OPEN_AT_END);
if (logfilestatus ==B_NO_ERROR)
{
std::string time=fApp->GetDateTime();
time=time+" ";
logbfile.Write(time.c_str(),strlen(time.c_str()));
logbfile.Write(msg.c_str(),strlen(msg.c_str()));
char nl='\n';
logbfile.Write(&nl,1);
logbfile.Unset(); //close file
}
else
{
//log file could not be opened use printf instead and do warn about log file
printf(fApp->GetDateTime().c_str());
printf(" ");
printf(msg.c_str());
printf(" ADDITIONALLY THIS MESSAGE SHOULD HAVE GONE TO THE LOG FILE BUT IT COULD NOT BE OPENED.");
printf(" Check %s has write permission to the specified file %s",(fApp->GetAppName()).c_str(),fLogFilePath.c_str());
printf("\n");
}
//unlock file sem
release_sem(fLogFileSem);
}
void MailingList::CheckInFolder()
{
//always called in the context of a MailWorker
//manually check through in dir to see if there are any emails
BDirectory indir(fListInDirectoryPath.c_str());
if (indir.InitCheck()!=B_OK)
{
LogError("ERROR: Could not do manual scan of in folder ("+fListInDirectoryPath+") as there was an error reading the folder (BDirectory InitCheck() failed)");
fApp->LogError("ERROR: List ("+fListName+") could not do manual scan of in folder ("+fListInDirectoryPath+") as there was an error reading the folder (BDirectory InitCheck() failed)");
}
entry_ref eref;
BEntry filebentry;
while(indir.GetNextEntry(&filebentry) == B_NO_ERROR)
{
BMessage msg(ORG_SIMPLE_MAILMISTRESS_PROCESSFILE);
BPath filebpath;
filebentry.GetPath(&filebpath);
std::string pathstr(filebpath.Path());
msg.AddString("FilePathStr",pathstr.c_str());
((MailMistressApplication*) be_app)->PostMessage(&msg);
}
}
std::string MailingList::GetName()
{
return fListName;
}
std::string MailingList::GetICAddress()
{
return fListICAddress;
}
std::string MailingList::GetSubjectPrefix()
{
return fListSubjectPrefix;
}
void MailingList::DeleteLogFileSem()
{
delete_sem(fLogFileSem);
}