00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
#include "kmime_mdn.h"
00033
00034
#include "kmime_version.h"
00035
#include "kmime_util.h"
00036
00037
#include <klocale.h>
00038
#include <kdebug.h>
00039
00040
#include <qcstring.h>
00041
00042
#include <unistd.h>
00043
00044
namespace KMime {
00045
00046
namespace MDN {
00047
00048
static const struct {
00049 DispositionType dispositionType;
00050
const char * string;
00051
const char * description;
00052 } dispositionTypes[] = {
00053 { Displayed,
"displayed",
00054 I18N_NOOP(
"The message sent on ${date} to ${to} with subject "
00055
"\"${subject}\" has been displayed. This is no guarantee that "
00056
"the message has been read or understood.") },
00057 { Deleted,
"deleted",
00058 I18N_NOOP(
"The message sent on ${date} to ${to} with subject "
00059
"\"${subject}\" has been deleted unseen. This is no guarantee "
00060
"that the message will not be \"undeleted\" and nonetheless "
00061
"read later on.") },
00062 { Dispatched,
"dispatched",
00063 I18N_NOOP(
"The message sent on ${date} to ${to} with subject "
00064
"\"${subject}\" has been dispatched. This is no guarantee "
00065
"that the message will not be read later on.") },
00066 { Processed,
"processed",
00067 I18N_NOOP(
"The message sent on ${date} to ${to} with subject "
00068
"\"${subject}\" has been processed by some automatic means.") },
00069 { Denied,
"denied",
00070 I18N_NOOP(
"The message sent on ${date} to ${to} with subject "
00071
"\"${subject}\" has been acted upon. The sender does not wish "
00072
"to disclose more details to you than that.") },
00073 { Failed,
"failed",
00074 I18N_NOOP(
"Generation of a Message Disposition Notification for the "
00075
"message sent on ${date} to ${to} with subject \"${subject}\" "
00076
"failed. Reason is given in the Failure: header field below.") }
00077 };
00078
00079
static const int numDispositionTypes
00080 =
sizeof dispositionTypes /
sizeof *dispositionTypes;
00081
00082
00083
static const char * stringFor( DispositionType d ) {
00084
for (
int i = 0 ; i < numDispositionTypes ; ++i )
00085
if ( dispositionTypes[i].dispositionType == d )
00086
return dispositionTypes[i].string;
00087
return 0;
00088 }
00089
00090
00091
00092
00093
00094
static const struct {
00095 DispositionModifier dispositionModifier;
00096
const char * string;
00097 } dispositionModifiers[] = {
00098 { Error,
"error" },
00099 { Warning,
"warning" },
00100 { Superseded,
"superseded" },
00101 { Expired,
"expired" },
00102 { MailboxTerminated,
"mailbox-terminated" }
00103 };
00104
00105
static const int numDispositionModifiers
00106 =
sizeof dispositionModifiers /
sizeof * dispositionModifiers;
00107
00108
00109
static const char * stringFor( DispositionModifier m ) {
00110
for (
int i = 0 ; i < numDispositionModifiers ; ++i )
00111
if ( dispositionModifiers[i].dispositionModifier == m )
00112
return dispositionModifiers[i].string;
00113
return 0;
00114 }
00115
00116
00117
00118
00119
00120
static const struct {
00121 ActionMode actionMode;
00122
const char * string;
00123 } actionModes[] = {
00124 { ManualAction,
"manual-action" },
00125 { AutomaticAction,
"automatic-action" }
00126 };
00127
00128
static const int numActionModes =
sizeof actionModes /
sizeof *actionModes;
00129
00130
static const char * stringFor( ActionMode a ) {
00131
for (
int i = 0 ; i < numActionModes ; ++i )
00132
if ( actionModes[i].actionMode == a )
00133
return actionModes[i].string;
00134
return 0;
00135 }
00136
00137
00138
00139
00140
00141
00142
static const struct {
00143 SendingMode sendingMode;
00144
const char * string;
00145 } sendingModes[] = {
00146 { SentManually,
"MDN-sent-manually" },
00147 { SentAutomatically,
"MDN-sent-automatically" }
00148 };
00149
00150
static const int numSendingModes =
sizeof sendingModes /
sizeof *sendingModes;
00151
00152
static const char * stringFor( SendingMode s ) {
00153
for (
int i = 0 ; i < numSendingModes ; ++i )
00154
if ( sendingModes[i].sendingMode == s )
00155
return sendingModes[i].string;
00156
return 0;
00157 }
00158
00159
static QCString dispositionField( DispositionType d, ActionMode a, SendingMode s,
00160
const QValueList<DispositionModifier> & m ) {
00161
00162
00163
QCString result =
"Disposition: ";
00164 result += stringFor( a );
00165 result +=
"/";
00166 result += stringFor( s );
00167 result +=
"; ";
00168 result += stringFor( d );
00169
00170
00171
bool first =
true;
00172
for (
QValueList<DispositionModifier>::const_iterator mt = m.begin() ;
00173 mt != m.end() ; ++mt ) {
00174
if ( first ) {
00175 result +=
"/";
00176 first =
false;
00177 }
else {
00178 result +=
",";
00179 }
00180 result += stringFor( *mt );
00181 }
00182
return result +
"\n";
00183 }
00184
00185
static QCString finalRecipient(
const QString & recipient ) {
00186
if ( recipient.isEmpty() )
00187
return QCString();
00188
else
00189
return "Final-Recipient: rfc822; "
00190 + encodeRFC2047String( recipient,
"utf-8" ) +
"\n";
00191 }
00192
00193
static QCString orginalRecipient(
const QCString & recipient ) {
00194
if ( recipient.isEmpty() )
00195
return QCString();
00196
else
00197
return "Original-Recipient: " + recipient +
"\n";
00198 }
00199
00200
static QCString originalMessageID(
const QCString & msgid ) {
00201
if ( msgid.isEmpty() )
00202
return QCString();
00203
else
00204
return "Original-Message-ID: " + msgid +
"\n";
00205 }
00206
00207
static QCString reportingUAField() {
00208
char hostName[256];
00209
if ( gethostname( hostName, 255 ) )
00210 hostName[0] =
'\0';
00211
else
00212 hostName[255] =
'\0';
00213
return QCString(
"Reporting-UA: ") + hostName
00214 +
"; KMime " KMIME_VERSION_STRING
"\n";
00215 }
00216
00217
QCString dispositionNotificationBodyContent(
const QString & r,
00218
const QCString & o,
00219
const QCString & omid,
00220 DispositionType d,
00221 ActionMode a,
00222 SendingMode s,
00223
const QValueList<DispositionModifier> & m,
00224
const QString & special )
00225 {
00226
00227
QString spec;
00228
if ( special.endsWith(
"\n") )
00229 spec = special.left( special.length() - 1 );
00230
else
00231 spec = special;
00232
00233
00234
QCString result = reportingUAField();
00235 result += orginalRecipient( o );
00236 result += finalRecipient( r );
00237 result += originalMessageID( omid );
00238 result += dispositionField( d, a, s, m );
00239
00240
00241
if ( d == Failed )
00242 result +=
"Failure: " + encodeRFC2047String( spec,
"utf-8" ) +
"\n";
00243
else if ( m.contains( Error ) )
00244 result +=
"Error: " + encodeRFC2047String( spec,
"utf-8" ) +
"\n";
00245
else if ( m.contains( Warning ) )
00246 result +=
"Warning: " + encodeRFC2047String( spec,
"utf-8" ) +
"\n";
00247
00248
return result;
00249 }
00250
00251
QString descriptionFor( DispositionType d,
00252
const QValueList<DispositionModifier> & ) {
00253
for (
int i = 0 ; i < numDispositionTypes ; ++i )
00254
if ( dispositionTypes[i].dispositionType == d )
00255
return i18n( dispositionTypes[i].description );
00256 kdWarning() <<
"KMime::MDN::descriptionFor(): No such disposition type: "
00257 << (
int)d << endl;
00258
return QString::null;
00259 }
00260
00261 }
00262 }