// Lotus Notes Command Line Mail Client NOTES_MAIL by Gottfried Rudorfer
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright 2002 Gottfried Rudorfer. All Rights Reserved.
//
// MODULE: web.cpp
//
// PURPOSE: Implements CGI functions required by notes_mail
// for windows.
//
// COMMENTS:
//
// AUTHOR: Gottfried Rudorfer
// http://godefroy.sdf-eu.org/notes_mail/
//
#ifndef NOTES_MAIL_H
#include "Notes_Mail.h"
#endif
#ifndef WEB_H
#include "web.h"
#endif
void PrintLogo() {
int size = sizeof( Notes320_gif );
cout << "Content-type: image/gif\n\n";
_setmode( _fileno( stdout ), _O_BINARY );
fwrite( Notes320_gif, sizeof(char), size, stdout);
}
void PrintTree(Notes_Mail& aMail) {
HANDLE dirH = NULL;
WIN32_FIND_DATA fd;
DWORD findRet;
StringStringMap Dirs;
char strBuf[256];
string searchD = aMail.MailBox + "\\*";
dirH = FindFirstFile(
searchD.c_str(), // pointer to name of file to search for
&fd // pointer to returned information
);
if (dirH != INVALID_HANDLE_VALUE) {
if (strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..")) {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
Dirs[fd.cFileName] = "ok";
}
}
} else {
string err="Notes_Mail: Service: Error processing directory ";
err += aMail.MailBox.c_str();
err += " the error was: ";
GetLastErrorText(strBuf, 255);
err += strBuf;
cout << err;
}
while( FindNextFile(dirH, &fd) ) {
if (strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..")) {
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
Dirs[fd.cFileName] = "ok";
}
}
}
findRet = GetLastError();
if (ERROR_NO_MORE_FILES != findRet) {
string err="Notes_Mail: Service: Error processing directory ";
err += aMail.MailBox.c_str();
err += " the error was: ";
GetLastErrorText(strBuf, 255);
err += strBuf;
cout << err;
}
cout << "
" << endl;
for ( StringStringMap::iterator i = Dirs.begin(); i != Dirs.end(); ++i )
{
string Name = i->first;
if (stricmp(Name.c_str(), "Attachment"))
cout << " " << Name << " | " << endl;
}
cout << "
" << endl;
}
void PrintMailBox(Notes_Mail& aMail, string mailbox) {
HANDLE dirH = NULL;
WIN32_FIND_DATA fd;
DWORD findRet;
char strBuf[256];
unsigned int countB = 0;
VectorOfStrings Files;
string searchD = aMail.MailBox + "\\" + mailbox + "\\*";
dirH = FindFirstFile(
searchD.c_str(), // pointer to name of file to search for
&fd // pointer to returned information
);
if (dirH != INVALID_HANDLE_VALUE) {
if (strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..")) {
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
string Name = fd.cFileName;
int len = Name.length();
if ((len > PrefixLength) && (PrefixDelim == Name[-1+PrefixLength])) {
Files.push_back(fd.cFileName);
countB++;
}
}
}
} else {
string err="Notes_Mail: Service: Error processing directory ";
err += aMail.MailBox.c_str();
err += " the error was: ";
GetLastErrorText(strBuf, 255);
err += strBuf;
cout << err;
}
while( FindNextFile(dirH, &fd) ) {
if (strcmp(fd.cFileName, ".") && strcmp(fd.cFileName, "..")) {
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
string Name = fd.cFileName;
int len = Name.length();
if ((len > PrefixLength) && (PrefixDelim == Name[-1+PrefixLength])) {
Files.push_back(fd.cFileName);
countB++;
}
}
}
}
findRet = GetLastError();
if (ERROR_NO_MORE_FILES != findRet) {
string err="Notes_Mail: Service: Error processing directory ";
err += aMail.MailBox.c_str();
err += " the error was: ";
GetLastErrorText(strBuf, 255);
err += strBuf;
cout << err;
}
cout << "Mailbox \"" << mailbox << "\" with " << countB << " document(s)
" << endl;
cout << "
" << endl;
cout << "" << endl;
sort(Files.begin(), Files.end(), greater());
for(unsigned int i=0; i < Files.size(); ++i) {
string Name = Files[i];
cout << " " << Name << " | " << endl;
}
cout << "
\n
" << endl;
}
void PrintMailMsg(string mailbox, string mailmsg) {
Notes_Mail aMail;
string MyMailFileName = aMail.MailBox + "\\" + mailbox + "\\" + mailmsg;
int mailFD = -1, openErr = 0;
FILE *lockStream = NULL, *mailST = NULL;
struct tm *locTime;
struct _timeb timeStrIn;
char strBuf[128];
int noFile = 0, count=0, result = 0;
char inchar;
openErr=0;
if( (mailFD = _sopen( MyMailFileName.c_str(), _O_RDONLY, _SH_DENYNO )) == -1 ) {
openErr = 1;
} else {
if( (mailST = _fdopen( mailFD, "r" )) == NULL )
openErr = 2;
}
if (openErr) {
string err = "The file '";
err += MyMailFileName + "' was not opened. Error: " + strerror( errno );
cout << err;
return;
}
_ftime( &timeStrIn );
locTime = localtime(&timeStrIn.time);
BOOL timeP = 0, toP = 0, subjectP = 0, attachmentsP = 0, bodyP = 0, attributeP = 0;
string timeS="", toS="", subjectS="", attachmentS="", bodyS="", inStr="\n";
string errorText="";
string MailTo, MailSubject, MailBody;
StringStringMap Attachments, Attributes;
int len;
time_t mailtime = timeStrIn.time;
timeP = 1; // first field is time
while ((EOF != (inchar = getc(mailST))) && (errorText == "")) {
inStr+=inchar;
switch( inchar )
{
case '\n':
len = inStr.length();
if (len >= 3) { // search for '\n', '\001', '\n'
if ((inStr[len-1] == '\n') && (inStr[len-2] == ESC) && (inStr[len-3] == '\n')) {
int numF = -4 + inStr.length();
string field="";
if (numF > 0)
field = inStr.substr(1, numF);
inStr="\n";
if (timeP) { // process mail creation time
int temp = aMail.ToNumber(field.c_str());
if (-1 == temp) {
errorText += "first field must be time in digits";
} else {
mailtime = temp;
}
timeP = 0;
toP = 1;
} else if (toP) {
MailTo = field;
toP = 0;
subjectP = 1;
} else if (subjectP) {
MailSubject = field;
subjectP = 0;
attachmentsP = 1;
} else if (attachmentsP) {
string::size_type end, beg=field.find_first_not_of("\n");
while(beg != string::npos) {
end=field.find_first_of("\n",beg);
Attachments[field.substr(beg,end-beg)]="ok";
beg=field.find_first_not_of("\n",end);
}
attachmentsP = 0;
bodyP = 1;
} else if (bodyP) {
MailBody = field;
attributeP = 1;
bodyP = 0;
} else if (attributeP) {
string::size_type end, beg=field.find_first_not_of("\n");
while(beg != string::npos) {
end=field.find_first_of("\n",beg);
string this_attribute = field.substr(beg,end-beg);
beg=field.find_first_not_of("\n",end);
string Name, Value;
string::size_type eq_end, eq_beg=this_attribute.find_first_not_of("=");
eq_end=this_attribute.find_first_of("=",eq_beg);
if (eq_end != string::npos) {
Name =this_attribute.substr(eq_beg, eq_end-eq_beg);
Value=this_attribute.substr(eq_end+1, this_attribute.length()-eq_end-1);
} else {
errorText += "Attribute requires a = sign";
}
if ((Value.length() == 0) || (Value == "")) {
errorText += "Parse-Error: -attribute name=value , value must be defined";
} else {
Attributes[Name]=Value;
}
}
attributeP = 0;
} else {
errorText += "unknown extra field in file.";
}
}
}
break;
default:
break;
}
}
fclose(mailST);
_close(mailFD);
if ((stricmp(mailbox.c_str(), "Sent")) && (stricmp(mailbox.c_str(), "Received"))) {
if ((mailtime + 60 * 10) < timeStrIn.time) {
int diff = (timeStrIn.time - mailtime)/60;
sprintf(strBuf, "\n\nNotes_Mail.exe: Warning: This mail is %d min (%d hours, %d days) old!\n", diff, diff/60, diff/60/24);
MailBody += strBuf;
}
}
cout << "Mail Message \"" << mailmsg << "\"
" << endl;
cout << "
" << endl;
cout << "Address: " << MailTo << "
" << endl;
cout << "Subject: " << MailSubject << "
" << endl;
cout << "Attachments: ";
int countA = 0;
for ( StringStringMap::iterator at = Attachments.begin();
at != Attachments.end(); ++at )
{
string fullName = at->first;
string reducedName;
string PathSource="", NameSource="";
aMail.SplitPathName(fullName, PathSource, NameSource);
aMail.ReduceName(NameSource, reducedName);
cout << NameSource << "
" << endl;
countA++;
}
if (!countA)
cout << "(none)";
cout << "
" << endl;
cout << "Attributes: ";
int countAttr = 0;
for ( StringStringMap::iterator att = Attributes.begin();
att != Attributes.end(); ++att )
{
string Name = att->first;
string Value = att->second;
cout << Name << "=" << Value << "
" << endl;
countAttr++;
}
if (!countAttr)
cout << "(none)";
cout << "
" << endl;
cout << "Message-Body:
" << endl;
if (MailBody == "") {
cout << "(none)";
} else {
cout << "" << MailBody << "" << endl;
}
cout << "" << endl;
}
void PrintBody(int part) {
if (!part)
cout << "" << endl;
else
cout << "" << endl;
}
void NotesWeb(Notes_Mail& aMail) {
ReadParse mycgi;
string h_frame = "\n\nYour browser does not support frames.\n\n";
if (mycgi.in.find(h_logo) != mycgi.in.end()) {
PrintLogo();//
cout << "Logo" << endl;
} else if (mycgi.in.find(h_mailmsg) != mycgi.in.end()) { //
mycgi.PrintHeader();
PrintBody(0);
if ("" == aMail.MyGetenv("AUTH_USER")) {
cout << "This CGI requires security settings." << endl;
exit(0);
}
PrintMailMsg(mycgi.in["UseBox"], mycgi.in[h_mailmsg]);
} else if (mycgi.in.find(h_tree) != mycgi.in.end()) {
mycgi.PrintHeader();
PrintBody(0);
if ("" == aMail.MyGetenv("AUTH_USER")) {
cout << "This CGI requires security settings." << endl;
exit(0);
}
PrintTree(aMail);
} else if (mycgi.in.find(h_box) != mycgi.in.end()) { //
mycgi.PrintHeader();
PrintBody(0);
if ("" == aMail.MyGetenv("AUTH_USER")) {
cout << "This CGI requires security settings." << endl;
exit(0);
}
cout << "Please select the mail message from upper frame." << endl;
} else if (mycgi.in.find(h_mail) != mycgi.in.end()) { //
mycgi.PrintHeader();
PrintBody(0);
if ("" == aMail.MyGetenv("AUTH_USER")) {
cout << "This CGI requires security settings." << endl;
exit(0);
}
cout << "Please select the mailbox from left lower frame." << endl;
} else if (mycgi.in.find(h_mailbox) != mycgi.in.end()) { //
mycgi.PrintHeader();
PrintBody(0);
if ("" == aMail.MyGetenv("AUTH_USER")) {
cout << "This CGI requires security settings." << endl;
exit(0);
}
PrintMailBox(aMail, mycgi.in[h_mailbox]);
} else {
mycgi.PrintHeader();
cout << h_head << h_frame;
}
exit(0);
}