#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <Application.h>
#include <StorageKit.h>
#include <SupportKit.h>
extern const char* __progname;
static const char* kProgramName = __progname;
time_t gDateStampTime;
static void
DisplayErrorMessage(const char* messageString = NULL, status_t errorNumber = 0,
const char* titleString = NULL)
{
char errorBuffer[2048];
if (titleString == NULL)
titleString = "Error Message:";
if (messageString == NULL) {
if (errorNumber == B_OK)
messageString = "No error, no message, why bother?";
else
messageString = "Error";
}
if (errorNumber != 0) {
snprintf(errorBuffer, sizeof(errorBuffer), "%s: %s (%" B_PRIx32 ")"
"has occured.", messageString, strerror(errorNumber), errorNumber);
messageString = errorBuffer;
}
fputs(titleString, stderr);
fputc('\n', stderr);
fputs(messageString, stderr);
fputc('\n', stderr);
}
bool
IsStartOfMailMessage(char* lineString)
{
if (memcmp("From ", lineString, 5) != 0)
return false;
char* string = lineString + 4;
while (*string == ' ')
string++;
while (*string != ' ' && *string != 0)
string++;
while (*string == ' ')
string++;
if (memcmp(string, "Mon", 3) != 0 && memcmp(string, "Tue", 3) != 0
&& memcmp(string, "Wed", 3) != 0 && memcmp(string, "Thu", 3) != 0
&& memcmp(string, "Fri", 3) != 0 && memcmp(string, "Sat", 3) != 0
&& memcmp(string, "Sun", 3) != 0) {
fprintf(stderr, "False alarm, not a valid day of the week in \"%s\""
".\n", lineString);
return false;
}
string += 3;
while (*string == ' ')
string++;
if (memcmp(string, "Jan", 3) != 0 && memcmp(string, "Feb", 3) != 0
&& memcmp(string, "Mar", 3) != 0 && memcmp(string, "Apr", 3) != 0
&& memcmp(string, "May", 3) != 0 && memcmp(string, "Jun", 3) != 0
&& memcmp(string, "Jul", 3) != 0 && memcmp(string, "Aug", 3) != 0
&& memcmp(string, "Sep", 3) != 0 && memcmp(string, "Oct", 3) != 0
&& memcmp(string, "Nov", 3) != 0 && memcmp(string, "Dec", 3) != 0) {
fprintf(stderr, "False alarm, not a valid month name in \"%s\".\n",
lineString);
return false;
}
string += 3;
while (*string == ' ')
string++;
if (*string < '0' || *string > '9') {
fprintf(stderr, "False alarm, not a valid day of the "
"month number in \"%s\".\n", lineString);
return false;
}
while (*string >= '0' && *string <= '9')
string++;
while (*string == ' ')
string++;
if (string[0] < '0' || string[0] > '9'
|| string[1] < '0' || string[1] > '9'
|| string[2] != ':'
|| string[3] < '0' || string[3] > '9'
|| string[4] < '0' || string[4] > '9'
|| string[5] != ':'
|| string[6] < '0' || string[6] > '9'
|| string[7] < '0' || string[7] > '9') {
fprintf(stderr, "False alarm, not a valid time value in \"%s\".\n",
lineString);
return false;
}
string += 8;
while (*string == ' ')
string++;
if (string[0] >= 'A' && string[0] <= 'Z'
&& string[1] >= 'A' && string[1] <= 'Z'
&& string[2] >= 'A' && string[2] <= 'Z') {
string += 3;
while (*string == ' ')
string++;
}
if (string[0] < '0' || string[0] > '9'
|| string[1] < '0' || string[1] > '9'
|| string[2] < '0' || string[2] > '9'
|| string[3] < '0' || string[3] > '9') {
fprintf(stderr, "False alarm, not a valid 4 digit year in \"%s\".\n",
lineString);
return false;
}
string += 4;
while (*string == ' ')
string++;
if ((string[0] == '+' || string[0] == '-')
&& string[1] >= '0' && string[1] <= '9'
&& string[2] >= '0' && string[2] <= '9'
&& string[3] >= '0' && string[3] <= '9'
&& string[4] >= '0' && string[4] <= '9') {
string += 5;
while (*string == ' ')
string++;
}
if (*string != 0) {
fprintf(stderr, "False alarm, extra stuff after the "
"year/time zone in \"%s\".\n", lineString);
return false;
}
return true;
}
status_t
ProcessMessageFile(char* fileName)
{
fprintf(stdout, "Now processing: \"%s\"\n", fileName);
FILE* inputFile = fopen(fileName, "rb");
if (inputFile == NULL) {
DisplayErrorMessage("Unable to open file", errno);
return errno;
}
BString messageText;
int lineNumber = 0;
while (!feof(inputFile)) {
char line[102400];
if (fgets(line, sizeof(line), inputFile) == NULL) {
if (ferror(inputFile)) {
char errorString[2048];
snprintf(errorString, sizeof(errorString),
"Error while reading from \"%s\"", fileName);
DisplayErrorMessage(errorString, errno);
fclose(inputFile);
return errno;
}
break;
}
char* string = line + strlen(line) - 1;
while (string >= line && *string < 32)
string--;
*(++string) = 0;
if (lineNumber == 0 && line[0] == 0) {
continue;
}
lineNumber++;
if (lineNumber == 1 && !IsStartOfMailMessage(line)) {
time_t timestamp = gDateStampTime++;
messageText.Append("From baron@be.com ");
messageText.Append(ctime(×tamp));
}
messageText.Append(line);
messageText.Append("\n");
}
int i = messageText.Length();
while (i > 0 && (messageText[i - 1] == '\n' || messageText[i - 1] == '\r'))
i--;
messageText.Truncate(i);
messageText.Append("\n\n");
status_t status = B_OK;
if (puts(messageText.String()) < 0) {
DisplayErrorMessage ("Error while writing the message", errno);
status = errno;
}
fclose(inputFile);
return status;
}
int
main(int argc, char** argv)
{
BApplication app("application/x-vnd.Haiku-mail2mbox");
if (argc <= 1 || argc >= 3) {
printf("%s is a utility for converting Mail e-mail\n", argv[0]);
printf("files to Unix Pine style e-mail files. It could well\n");
printf("work with other Unix style mailbox files. Each message in\n");
printf("the input directory is converted and sent to the standard\n");
printf("output. Usage:\n\n");
printf("%s InputDirectory >OutputFile\n\n", kProgramName);
printf("Public domain, by Alexander G. M. Smith.\n");
return -10;
}
gDateStampTime = time (NULL);
char inputPathName[B_PATH_NAME_LENGTH];
strlcpy(inputPathName, argv[1], sizeof(inputPathName) - 2);
char tempString[2048];
DIR* dir = opendir(inputPathName);
if (dir == NULL) {
sprintf(tempString, "Problems opening directory named \"%s\".",
inputPathName);
DisplayErrorMessage(tempString, errno);
return 1;
}
if (inputPathName[strlen(inputPathName) - 1] != '/')
strcat(inputPathName, "/");
int messagesDoneCount = 0;
status_t status = B_OK;
while (dirent_t* entry = readdir(dir)) {
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, ".."))
break;
strlcpy(tempString, inputPathName, sizeof(tempString));
strlcat(tempString, entry->d_name, sizeof(tempString));
status = ProcessMessageFile(tempString);
if (status != B_OK)
break;
messagesDoneCount++;
}
closedir(dir);
if (status != B_OK) {
DisplayErrorMessage("Stopping early because an error occured", status);
return status;
}
fprintf(stderr, "Did %d messages successfully.\n", messagesDoneCount);
return 0;
}