Parent: [9fb52e] (diff)

Child: [2a3075] (diff)

Download this file

idfile.cpp    138 lines (113 with data), 3.1 kB

  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
#ifndef lint
static char rcsid[] = "@(#$Id: idfile.cpp,v 1.3 2005-11-24 07:16:16 dockes Exp $ (C) 2005 J.F.Dockes";
#endif
#ifndef TEST_IDFILE
#include <unistd.h> // for access(2)
#include <ctype.h>
#include <fstream>
#include <sstream>
#include "idfile.h"
#include "debuglog.h"
#ifndef NO_NAMESPACES
using namespace std;
#endif /* NO_NAMESPACES */
std::list<string> idFileAllTypes()
{
std::list<string> lst;
lst.push_back("text/x-mail");
lst.push_back("message/rfc822");
return lst;
}
// Mail headers we compare to:
static const char *mailhs[] = {"From: ", "Received: ", "Message-Id: ", "To: ",
"Date: ", "Subject: ", "Status: "};
static const int mailhsl[] = {6, 10, 12, 4, 6, 9, 8};
static const int nmh = sizeof(mailhs) / sizeof(char *);
const int wantnhead = 3;
string idFile(const char *fn)
{
ifstream input;
input.open(fn, ios::in);
if (!input.is_open()) {
LOGERR(("idFile: could not open [%s]\n", fn));
return string("");
}
bool line1HasFrom = false;
int lookslikemail = 0;
// emacs VM sometimes inserts very long lines with continuations or
// not (for folder information). This forces us to look at many
// lines and long ones
for (int lnum = 1; lnum < 200; lnum++) {
#define LL 1024
char cline[LL+1];
cline[LL] = 0;
input.getline(cline, LL-1);
if (input.fail()) {
if (input.bad()) {
LOGERR(("idfile: error while reading [%s]\n", fn));
return string("");
}
// Must be eof ?
break;
}
LOGDEB2(("idfile: lnum %d : [%s]\n", lnum, cline));
// Check for a few things that can't be found in a mail file,
// (optimization to get a quick negative
// Lines must begin with whitespace or have a colon in the
// first 50 chars (hope no one comes up with a longer header
// name !
if (!isspace(cline[0])) {
char *cp = strchr(cline, ':');
if (cp == 0 || (cp - cline) > 70) {
LOGDEB2(("idfile: can't be mail header line: [%s]\n", cline));
break;
}
}
int ll = strlen(cline);
if (ll > 1000) {
LOGDEB2(("idFile: Line too long\n"));
return string("");
}
if (lnum == 1) {
if (!strncmp("From ", cline, 5)) {
line1HasFrom = true;
continue;
}
}
for (int i = 0; i < nmh; i++) {
if (!strncasecmp(mailhs[i], cline, mailhsl[i])) {
//fprintf(stderr, "Got [%s]\n", mailhs[i]);
lookslikemail++;
break;
}
}
if (lookslikemail >= wantnhead)
break;
}
if (line1HasFrom)
lookslikemail++;
if (lookslikemail >= wantnhead)
return line1HasFrom ? string("text/x-mail") : string("message/rfc822");
return string("");
}
#else
#include <string>
#include <iostream>
#include <unistd.h>
#include <fcntl.h>
using namespace std;
#include "debuglog.h"
#include "idfile.h"
int main(int argc, char **argv)
{
if (argc != 2) {
cerr << "Usage: idfile filename" << endl;
exit(1);
}
DebugLog::getdbl()->setloglevel(DEBDEB1);
DebugLog::setfilename("stderr");
string mime = idFile(argv[1]);
cout << argv[1] << " : " << mime << endl;
exit(0);
}
#endif