// 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 << "" << endl; } cout << "
" << Name << "
" << 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 << "" << endl; } cout << "
" << Name << "
\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 \n \n \n \n \n \n \n \n\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); }