00001
00002
00003
00004
#ifdef HAVE_CONFIG_H
00005
#include <config.h>
00006
#endif
00007
00008
#include "kmidentity.h"
00009
#include "kfileio.h"
00010
#include "kmkernel.h"
00011
00012
#include <kdebug.h>
00013
#include <klocale.h>
00014
#include <kmessagebox.h>
00015
#include <kprocess.h>
00016
#include <kconfig.h>
00017
00018
#include <qfileinfo.h>
00019
00020
#include <sys/types.h>
00021
#include <stdlib.h>
00022
#include <stdio.h>
00023
#include <errno.h>
00024
#include <assert.h>
00025
00026 Signature::Signature()
00027 : mType( Disabled )
00028 {
00029
00030 }
00031
00032 Signature::Signature(
const QString & text )
00033 : mText( text ),
00034 mType( Inlined )
00035 {
00036
00037 }
00038
00039 Signature::Signature(
const QString & url,
bool isExecutable )
00040 : mUrl( url ),
00041 mType( isExecutable ? FromCommand : FromFile )
00042 {
00043 }
00044
00045 bool Signature::operator==(
const Signature & other )
const {
00046
if ( mType != other.
mType )
return false;
00047
switch ( mType ) {
00048
case Inlined:
return mText == other.
mText;
00049
case FromFile:
00050
case FromCommand:
return mUrl == other.
mUrl;
00051
default:
00052
case Disabled:
return true;
00053 }
00054 }
00055
00056 QString
Signature::rawText(
bool * ok )
const
00057
{
00058
switch ( mType ) {
00059
case Disabled:
00060
if ( ok ) *ok =
true;
00061
return QString::null;
00062
case Inlined:
00063
if ( ok ) *ok =
true;
00064
return mText;
00065
case FromFile:
00066
return textFromFile( ok );
00067
case FromCommand:
00068
return textFromCommand( ok );
00069 };
00070 kdFatal( 5006 ) <<
"Signature::type() returned unknown value!" << endl;
00071
return QString::null;
00072 }
00073
00074 QString Signature::textFromCommand(
bool * ok )
const
00075
{
00076 assert( mType == FromCommand );
00077
00078
00079
if ( mUrl.isEmpty() ) {
00080
if ( ok ) *ok =
true;
00081
return QString::null;
00082 }
00083
00084
00085 KProcess proc;
00086 proc.setUseShell(
true);
00087 proc << mUrl;
00088
00089
00090 QObject::connect( &proc, SIGNAL(receivedStdout(KProcess*,
char*,
int)),
00091 kmkernel, SLOT(slotCollectStdOut(KProcess*,
char*,
int)) );
00092
00093
00094
int rc = 0;
00095
if ( !proc.start( KProcess::Block, KProcess::Stdout ) )
00096 rc = -1;
00097
else
00098 rc = ( proc.normalExit() ) ? proc.exitStatus() : -1 ;
00099
00100
00101 QByteArray output = kmkernel->getCollectedStdOut( &proc );
00102
00103
00104
if ( rc != 0 ) {
00105
if ( ok ) *ok =
false;
00106 QString wmsg = i18n(
"<qt>Failed to execute signature script<br><b>%1</b>:<br>%2</qt>")
00107 .arg( mUrl ).arg( strerror(rc) );
00108 KMessageBox::error(0, wmsg);
00109
return QString::null;
00110 }
00111
00112
00113
if ( ok ) *ok =
true;
00114
00115
return QString::fromLocal8Bit( output.data(), output.size() );
00116 }
00117
00118 QString Signature::textFromFile(
bool * ok )
const
00119
{
00120 assert( mType == FromFile );
00121
00122
00123
if ( !KURL(mUrl).isLocalFile() && !(QFileInfo(mUrl).isRelative()
00124 && QFileInfo(mUrl).exists()) ) {
00125 kdDebug( 5006 ) <<
"Signature::textFromFile: non-local URLs are unsupported" << endl;
00126
if ( ok ) *ok =
false;
00127
return QString::null;
00128 }
00129
if ( ok ) *ok =
true;
00130
00131
return QString::fromLocal8Bit( kFileToString( mUrl,
false ) );
00132 }
00133
00134 QString
Signature::withSeparator(
bool * ok )
const
00135
{
00136
bool internalOK =
false;
00137 QString signature =
rawText( &internalOK );
00138
if ( !internalOK ) {
00139
if ( ok ) *ok =
false;
00140
return QString::null;
00141 }
00142
if ( ok ) *ok =
true;
00143
if ( signature.isEmpty() )
return signature;
00144
if ( signature.startsWith( QString::fromLatin1(
"-- \n") ) )
00145
00146
return QString::fromLatin1(
"\n") += signature;
00147
else if ( signature.find( QString::fromLatin1(
"\n-- \n") ) != -1 )
00148
00149
00150
return signature;
00151
else
00152
00153
return QString::fromLatin1(
"\n-- \n") + signature;
00154 }
00155
00156
00157 void Signature::setUrl(
const QString & url,
bool isExecutable )
00158 {
00159 mUrl = url;
00160 mType = isExecutable ? FromCommand : FromFile ;
00161 }
00162
00163
00164
static const char sigTypeKey[] =
"Signature Type";
00165
static const char sigTypeInlineValue[] =
"inline";
00166
static const char sigTypeFileValue[] =
"file";
00167
static const char sigTypeCommandValue[] =
"command";
00168
static const char sigTypeDisabledValue[] =
"disabled";
00169
static const char sigTextKey[] =
"Inline Signature";
00170
static const char sigFileKey[] =
"Signature File";
00171
static const char sigCommandKey[] =
"Signature Command";
00172
00173
void Signature::readConfig(
const KConfigBase * config )
00174 {
00175 QString sigType = config->readEntry( sigTypeKey );
00176
if ( sigType == sigTypeInlineValue ) {
00177 mType = Inlined;
00178 mText = config->readEntry( sigTextKey );
00179 }
else if ( sigType == sigTypeFileValue ) {
00180 mType = FromFile;
00181 mUrl = config->readPathEntry( sigFileKey );
00182 }
else if ( sigType == sigTypeCommandValue ) {
00183 mType = FromCommand;
00184 mUrl = config->readPathEntry( sigCommandKey );
00185 }
else {
00186 mType = Disabled;
00187 }
00188 }
00189
00190
void Signature::writeConfig( KConfigBase * config )
const
00191
{
00192
switch ( mType ) {
00193
case Inlined:
00194 config->writeEntry( sigTypeKey, sigTypeInlineValue );
00195 config->writeEntry( sigTextKey, mText );
00196
break;
00197
case FromFile:
00198 config->writeEntry( sigTypeKey, sigTypeFileValue );
00199 config->writePathEntry( sigFileKey, mUrl );
00200
break;
00201
case FromCommand:
00202 config->writeEntry( sigTypeKey, sigTypeCommandValue );
00203 config->writePathEntry( sigCommandKey, mUrl );
00204
break;
00205
case Disabled:
00206 config->writeEntry( sigTypeKey, sigTypeDisabledValue );
00207
default: ;
00208 }
00209 }
00210
00211 QDataStream & operator<<( QDataStream & stream,
const Signature & sig ) {
00212
return stream << static_cast<Q_UINT8>(sig.
mType)
00213 << sig.
mUrl
00214 << sig.
mText;
00215 }
00216
00217 QDataStream & operator>>( QDataStream & stream,
Signature & sig ) {
00218 Q_UINT8 s;
00219 stream >> s
00220 >> sig.
mUrl
00221 >> sig.
mText;
00222 sig.
mType = static_cast<Signature::Type>(s);
00223
return stream;
00224 }
00225
00226
KMIdentity KMIdentity::null;
00227
00228
bool KMIdentity::isNull()
const {
00229
return mIdentity.isNull() && mFullName.isNull() && mEmailAddr.isNull() &&
00230 mOrganization.isNull() && mReplyToAddr.isNull() && mBcc.isNull() &&
00231 mVCardFile.isNull() &&
00232 mPgpIdentity.isNull() && mFcc.isNull() && mDrafts.isNull() &&
00233 mTransport.isNull() && mDictionary.isNull() &&
00234 mSignature.
type() == Signature::Disabled;
00235 }
00236
00237 bool KMIdentity::operator==(
const KMIdentity & other )
const {
00238
return mUoid == other.
mUoid &&
00239 mIdentity == other.
mIdentity && mFullName == other.
mFullName &&
00240 mEmailAddr == other.
mEmailAddr && mOrganization == other.
mOrganization &&
00241 mReplyToAddr == other.
mReplyToAddr && mBcc == other.
mBcc &&
00242 mVCardFile == other.
mVCardFile &&
00243 mPgpIdentity == other.
mPgpIdentity && mFcc == other.
mFcc &&
00244 mDrafts == other.
mDrafts && mTransport == other.
mTransport &&
00245 mDictionary == other.
mDictionary && mSignature == other.
mSignature;
00246 }
00247
00248 KMIdentity::KMIdentity(
const QString &
id,
const QString & fullName,
00249
const QString & emailAddr,
const QString & organization,
00250
const QString & replyToAddr )
00251 : mUoid( 0 ), mIdentity( id ), mFullName( fullName ),
00252 mEmailAddr( emailAddr ), mOrganization( organization ),
00253 mReplyToAddr( replyToAddr ), mIsDefault( false )
00254 {
00255
00256 }
00257
00258 KMIdentity::~KMIdentity()
00259 {
00260 }
00261
00262
00263 void KMIdentity::readConfig(
const KConfigBase * config )
00264 {
00265 mUoid = config->readUnsignedNumEntry(
"uoid",0);
00266
00267 mIdentity = config->readEntry(
"Identity");
00268 mFullName = config->readEntry(
"Name");
00269 mEmailAddr = config->readEntry(
"Email Address");
00270 mVCardFile = config->readPathEntry(
"VCardFile");
00271 mOrganization = config->readEntry(
"Organization");
00272 mPgpIdentity = config->readEntry(
"Default PGP Key").local8Bit();
00273 mReplyToAddr = config->readEntry(
"Reply-To Address");
00274 mBcc = config->readEntry(
"Bcc");
00275 mFcc = config->readEntry(
"Fcc",
"sent-mail");
00276
if( mFcc.isEmpty() )
00277 mFcc =
"sent-mail";
00278 mDrafts = config->readEntry(
"Drafts",
"drafts");
00279
if( mDrafts.isEmpty() )
00280 mDrafts =
"drafts";
00281 mTransport = config->readEntry(
"Transport");
00282 mDictionary = config->readEntry(
"Dictionary" );
00283
00284 mSignature.
readConfig( config );
00285 kdDebug(5006) <<
"KMIdentity::readConfig(): UOID = " << mUoid
00286 <<
" for identity named \"" << mIdentity <<
"\"" << endl;
00287 }
00288
00289
00290 void KMIdentity::writeConfig( KConfigBase * config )
const
00291
{
00292 config->writeEntry(
"uoid", mUoid);
00293
00294 config->writeEntry(
"Identity", mIdentity);
00295 config->writeEntry(
"Name", mFullName);
00296 config->writeEntry(
"Organization", mOrganization);
00297 config->writeEntry(
"Default PGP Key", mPgpIdentity.data());
00298 config->writeEntry(
"Email Address", mEmailAddr);
00299 config->writeEntry(
"Reply-To Address", mReplyToAddr);
00300 config->writeEntry(
"Bcc", mBcc);
00301 config->writePathEntry(
"VCardFile", mVCardFile);
00302 config->writeEntry(
"Transport", mTransport);
00303 config->writeEntry(
"Fcc", mFcc);
00304 config->writeEntry(
"Drafts", mDrafts);
00305 config->writeEntry(
"Dictionary", mDictionary );
00306
00307 mSignature.
writeConfig( config );
00308 }
00309
00310 QDataStream & operator<<( QDataStream & stream,
const KMIdentity & i ) {
00311
return stream << static_cast<Q_UINT32>(i.
uoid())
00312 << i.
identityName()
00313 << i.
fullName()
00314 << i.
organization()
00315 << i.
pgpIdentity()
00316 << i.
emailAddr()
00317 << i.
replyToAddr()
00318 << i.
bcc()
00319 << i.
vCardFile()
00320 << i.
transport()
00321 << i.
fcc()
00322 << i.
drafts()
00323 << i.
mSignature
00324 << i.
dictionary();
00325 }
00326
00327 QDataStream & operator>>( QDataStream & stream,
KMIdentity & i ) {
00328
#if 1 // why doesn't it work like for Q_UINT8 above???
00329
Q_UINT32 uoid;
00330 stream >> uoid;
00331 i.
mUoid = uoid;
00332
return stream
00333
#else
00334
return stream >> (Q_UINT32)i.
mUoid
00335
#endif
00336
>> i.
mIdentity
00337 >> i.
mFullName
00338 >> i.
mOrganization
00339 >> i.
mPgpIdentity
00340 >> i.
mEmailAddr
00341 >> i.
mReplyToAddr
00342 >> i.
mBcc
00343 >> i.
mVCardFile
00344 >> i.
mTransport
00345 >> i.
mFcc
00346 >> i.
mDrafts
00347 >> i.
mSignature
00348 >> i.
mDictionary;
00349 }
00350
00351
00352 bool KMIdentity::mailingAllowed()
const
00353
{
00354
return !mEmailAddr.isEmpty();
00355 }
00356
00357
00358 void KMIdentity::setIsDefault(
bool flag ) {
00359 mIsDefault = flag;
00360 }
00361
00362
void KMIdentity::setIdentityName(
const QString & name ) {
00363 mIdentity = name;
00364 }
00365
00366
void KMIdentity::setFullName(
const QString &str)
00367 {
00368 mFullName = str;
00369 }
00370
00371
00372
00373
void KMIdentity::setOrganization(
const QString &str)
00374 {
00375 mOrganization = str;
00376 }
00377
00378
00379
00380
void KMIdentity::setPgpIdentity(
const QCString &str)
00381 {
00382 mPgpIdentity = str;
00383 }
00384
00385
00386
00387
void KMIdentity::setEmailAddr(
const QString &str)
00388 {
00389 mEmailAddr = str;
00390 }
00391
00392
00393
00394
void KMIdentity::setVCardFile(
const QString &str)
00395 {
00396 mVCardFile = str;
00397 }
00398
00399
00400
00401 QString
KMIdentity::fullEmailAddr(
void)
const
00402
{
00403
if (mFullName.isEmpty())
return mEmailAddr;
00404
00405
const QString specials(
"()<>@,.;:[]");
00406
00407 QString result;
00408
00409
00410
bool needsQuotes=
false;
00411
for (
unsigned int i=0; i < mFullName.length(); i++) {
00412
if ( specials.contains( mFullName[i] ) )
00413 needsQuotes =
true;
00414
else if ( mFullName[i] ==
'\\' || mFullName[i] ==
'"' ) {
00415 needsQuotes =
true;
00416 result +=
'\\';
00417 }
00418 result += mFullName[i];
00419 }
00420
00421
if (needsQuotes) {
00422 result.insert(0,
'"');
00423 result +=
'"';
00424 }
00425
00426 result +=
" <" + mEmailAddr +
'>';
00427
00428
return result;
00429 }
00430
00431
00432
void KMIdentity::setReplyToAddr(
const QString& str)
00433 {
00434 mReplyToAddr = str;
00435 }
00436
00437
00438
00439
void KMIdentity::setSignatureFile(
const QString &str)
00440 {
00441 mSignature.
setUrl( str,
signatureIsCommand() );
00442 }
00443
00444
00445
00446
void KMIdentity::setSignatureInlineText(
const QString &str )
00447 {
00448 mSignature.
setText( str );
00449 }
00450
00451
00452
00453
void KMIdentity::setTransport(
const QString &str)
00454 {
00455 mTransport = str;
00456 }
00457
00458
00459
void KMIdentity::setFcc(
const QString &str)
00460 {
00461 mFcc = str;
00462 }
00463
00464
00465
void KMIdentity::setDrafts(
const QString &str)
00466 {
00467 mDrafts = str;
00468 }
00469
00470
00471
00472
void KMIdentity::setDictionary(
const QString &str )
00473 {
00474 mDictionary = str;
00475 }
00476
00477
00478
00479 QString
KMIdentity::signatureText(
bool * ok )
const
00480
{
00481
bool internalOK =
false;
00482 QString
signatureText = mSignature.
withSeparator( &internalOK );
00483
if ( internalOK ) {
00484
if ( ok ) *ok=
true;
00485
return signatureText;
00486 }
00487
00488
00489
00490
00491
if ( ok ) *ok =
false;
00492
return QString::null;
00493
00494
#if 0 // ### FIXME: error handling
00495
if (mSignatureFile.endsWith(
"|"))
00496 {
00497 }
00498
else
00499 {
00500 }
00501
#endif
00502
00503
return QString::null;
00504 }