mimeheader.cc
00001 /*************************************************************************** 00002 mimeheader.cc - description 00003 ------------------- 00004 begin : Fri Oct 20 2000 00005 copyright : (C) 2000 by Sven Carstens 00006 email : s.carstens@gmx.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This program is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU General Public License as published by * 00013 * the Free Software Foundation; either version 2 of the License, or * 00014 * (at your option) any later version. * 00015 * * 00016 ***************************************************************************/ 00017 00018 #include "mimeheader.h" 00019 #include "mimehdrline.h" 00020 #include "mailheader.h" 00021 #include "rfcdecoder.h" 00022 00023 #include <tqregexp.h> 00024 00025 // #include <iostream.h> 00026 #include <tdeglobal.h> 00027 #include <kinstance.h> 00028 #include <kiconloader.h> 00029 #include <kmimetype.h> 00030 #include <kmimemagic.h> 00031 #include <kmdcodec.h> 00032 #include <kdebug.h> 00033 00034 mimeHeader::mimeHeader (): 00035 typeList (17, false), dispositionList (17, false) 00036 { 00037 // Case insensitive hashes are killing us. Also are they too small? 00038 originalHdrLines.setAutoDelete (true); 00039 additionalHdrLines.setAutoDelete (false); // is also in original lines 00040 nestedParts.setAutoDelete (true); 00041 typeList.setAutoDelete (true); 00042 dispositionList.setAutoDelete (true); 00043 nestedMessage = NULL; 00044 contentLength = 0; 00045 contentType = "application/octet-stream"; 00046 } 00047 00048 mimeHeader::~mimeHeader () 00049 { 00050 } 00051 00052 /* 00053 TQPtrList<mimeHeader> mimeHeader::getAllParts() 00054 { 00055 TQPtrList<mimeHeader> retVal; 00056 00057 // caller is responsible for clearing 00058 retVal.setAutoDelete( false ); 00059 nestedParts.setAutoDelete( false ); 00060 00061 // shallow copy 00062 retVal = nestedParts; 00063 00064 // can't have duplicate pointers 00065 nestedParts.clear(); 00066 00067 // restore initial state 00068 nestedParts.setAutoDelete( true ); 00069 00070 return retVal; 00071 } */ 00072 00073 void 00074 mimeHeader::addHdrLine (mimeHdrLine * aHdrLine) 00075 { 00076 mimeHdrLine *addLine = new mimeHdrLine (aHdrLine); 00077 if (addLine) 00078 { 00079 originalHdrLines.append (addLine); 00080 if (tqstrnicmp (addLine->getLabel (), "Content-", 8)) 00081 { 00082 additionalHdrLines.append (addLine); 00083 } 00084 else 00085 { 00086 int skip; 00087 const char *aCStr = addLine->getValue ().data (); 00088 TQDict < TQString > *aList = 0; 00089 00090 skip = mimeHdrLine::parseSeparator (';', aCStr); 00091 if (skip > 0) 00092 { 00093 int cut = 0; 00094 if (skip >= 2) 00095 { 00096 if (aCStr[skip - 1] == '\r') 00097 cut++; 00098 if (aCStr[skip - 1] == '\n') 00099 cut++; 00100 if (aCStr[skip - 2] == '\r') 00101 cut++; 00102 if (aCStr[skip - 1] == ';') 00103 cut++; 00104 } 00105 TQCString mimeValue = TQCString (aCStr, skip - cut + 1); // cutting of one because of 0x00 00106 00107 00108 if (!tqstricmp (addLine->getLabel (), "Content-Disposition")) 00109 { 00110 aList = &dispositionList; 00111 _contentDisposition = mimeValue; 00112 } 00113 else if (!tqstricmp (addLine->getLabel (), "Content-Type")) 00114 { 00115 aList = &typeList; 00116 contentType = mimeValue; 00117 } 00118 else 00119 if (!tqstricmp (addLine->getLabel (), "Content-Transfer-Encoding")) 00120 { 00121 contentEncoding = mimeValue; 00122 } 00123 else if (!tqstricmp (addLine->getLabel (), "Content-ID")) 00124 { 00125 contentID = mimeValue; 00126 } 00127 else if (!tqstricmp (addLine->getLabel (), "Content-Description")) 00128 { 00129 _contentDescription = mimeValue; 00130 } 00131 else if (!tqstricmp (addLine->getLabel (), "Content-MD5")) 00132 { 00133 contentMD5 = mimeValue; 00134 } 00135 else if (!tqstricmp (addLine->getLabel (), "Content-Length")) 00136 { 00137 contentLength = mimeValue.toULong (); 00138 } 00139 else 00140 { 00141 additionalHdrLines.append (addLine); 00142 } 00143 // cout << addLine->getLabel().data() << ": '" << mimeValue.data() << "'" << endl; 00144 00145 aCStr += skip; 00146 while ((skip = mimeHdrLine::parseSeparator (';', aCStr))) 00147 { 00148 if (skip > 0) 00149 { 00150 addParameter (TQCString (aCStr, skip).simplifyWhiteSpace(), aList); 00151 // cout << "-- '" << aParm.data() << "'" << endl; 00152 mimeValue = TQCString (addLine->getValue ().data (), skip); 00153 aCStr += skip; 00154 } 00155 else 00156 break; 00157 } 00158 } 00159 } 00160 } 00161 } 00162 00163 void 00164 mimeHeader::addParameter (const TQCString& aParameter, TQDict < TQString > *aList) 00165 { 00166 if ( !aList ) 00167 return; 00168 00169 TQString *aValue; 00170 TQCString aLabel; 00171 int pos = aParameter.find ('='); 00172 // cout << aParameter.left(pos).data(); 00173 aValue = new TQString (); 00174 aValue->setLatin1 (aParameter.right (aParameter.length () - pos - 1)); 00175 aLabel = aParameter.left (pos); 00176 if ((*aValue)[0] == '"') 00177 *aValue = aValue->mid (1, aValue->length () - 2); 00178 00179 aList->insert (aLabel, aValue); 00180 // cout << "=" << aValue->data() << endl; 00181 } 00182 00183 TQString 00184 mimeHeader::getDispositionParm (const TQCString& aStr) 00185 { 00186 return getParameter (aStr, &dispositionList); 00187 } 00188 00189 TQString 00190 mimeHeader::getTypeParm (const TQCString& aStr) 00191 { 00192 return getParameter (aStr, &typeList); 00193 } 00194 00195 void 00196 mimeHeader::setDispositionParm (const TQCString& aLabel, const TQString& aValue) 00197 { 00198 setParameter (aLabel, aValue, &dispositionList); 00199 return; 00200 } 00201 00202 void 00203 mimeHeader::setTypeParm (const TQCString& aLabel, const TQString& aValue) 00204 { 00205 setParameter (aLabel, aValue, &typeList); 00206 } 00207 00208 TQDictIterator < TQString > mimeHeader::getDispositionIterator () 00209 { 00210 return TQDictIterator < TQString > (dispositionList); 00211 } 00212 00213 TQDictIterator < TQString > mimeHeader::getTypeIterator () 00214 { 00215 return TQDictIterator < TQString > (typeList); 00216 } 00217 00218 TQPtrListIterator < mimeHdrLine > mimeHeader::getOriginalIterator () 00219 { 00220 return TQPtrListIterator < mimeHdrLine > (originalHdrLines); 00221 } 00222 00223 TQPtrListIterator < mimeHdrLine > mimeHeader::getAdditionalIterator () 00224 { 00225 return TQPtrListIterator < mimeHdrLine > (additionalHdrLines); 00226 } 00227 00228 void 00229 mimeHeader::outputHeader (mimeIO & useIO) 00230 { 00231 if (!getDisposition ().isEmpty ()) 00232 { 00233 useIO.outputMimeLine (TQCString ("Content-Disposition: ") 00234 + getDisposition () 00235 + outputParameter (&dispositionList)); 00236 } 00237 00238 if (!getType ().isEmpty ()) 00239 { 00240 useIO.outputMimeLine (TQCString ("Content-Type: ") 00241 + getType () + outputParameter (&typeList)); 00242 } 00243 if (!getDescription ().isEmpty ()) 00244 useIO.outputMimeLine (TQCString ("Content-Description: ") + 00245 getDescription ()); 00246 if (!getID ().isEmpty ()) 00247 useIO.outputMimeLine (TQCString ("Content-ID: ") + getID ()); 00248 if (!getMD5 ().isEmpty ()) 00249 useIO.outputMimeLine (TQCString ("Content-MD5: ") + getMD5 ()); 00250 if (!getEncoding ().isEmpty ()) 00251 useIO.outputMimeLine (TQCString ("Content-Transfer-Encoding: ") + 00252 getEncoding ()); 00253 00254 TQPtrListIterator < mimeHdrLine > ait = getAdditionalIterator (); 00255 while (ait.current ()) 00256 { 00257 useIO.outputMimeLine (ait.current ()->getLabel () + ": " + 00258 ait.current ()->getValue ()); 00259 ++ait; 00260 } 00261 useIO.outputMimeLine (TQCString ("")); 00262 } 00263 00264 TQString 00265 mimeHeader::getParameter (const TQCString& aStr, TQDict < TQString > *aDict) 00266 { 00267 TQString retVal, *found; 00268 if (aDict) 00269 { 00270 //see if it is a normal parameter 00271 found = aDict->find (aStr); 00272 if (!found) 00273 { 00274 //might be a continuated or encoded parameter 00275 found = aDict->find (aStr + "*"); 00276 if (!found) 00277 { 00278 //continuated parameter 00279 TQString decoded, encoded; 00280 int part = 0; 00281 00282 do 00283 { 00284 TQCString search; 00285 search.setNum (part); 00286 search = aStr + "*" + search; 00287 found = aDict->find (search); 00288 if (!found) 00289 { 00290 found = aDict->find (search + "*"); 00291 if (found) 00292 encoded += rfcDecoder::encodeRFC2231String (*found); 00293 } 00294 else 00295 { 00296 encoded += *found; 00297 } 00298 part++; 00299 } 00300 while (found); 00301 if (encoded.find ('\'') >= 0) 00302 { 00303 retVal = rfcDecoder::decodeRFC2231String (encoded.local8Bit ()); 00304 } 00305 else 00306 { 00307 retVal = 00308 rfcDecoder::decodeRFC2231String (TQCString ("''") + 00309 encoded.local8Bit ()); 00310 } 00311 } 00312 else 00313 { 00314 //simple encoded parameter 00315 retVal = rfcDecoder::decodeRFC2231String (found->local8Bit ()); 00316 } 00317 } 00318 else 00319 { 00320 retVal = *found; 00321 } 00322 } 00323 return retVal; 00324 } 00325 00326 void 00327 mimeHeader::setParameter (const TQCString& aLabel, const TQString& aValue, 00328 TQDict < TQString > *aDict) 00329 { 00330 bool encoded = true; 00331 uint vlen, llen; 00332 TQString val = aValue; 00333 00334 if (aDict) 00335 { 00336 00337 //see if it needs to get encoded 00338 if (encoded && aLabel.find ('*') == -1) 00339 { 00340 val = rfcDecoder::encodeRFC2231String (aValue); 00341 } 00342 //kdDebug(7116) << "mimeHeader::setParameter() - val = '" << val << "'" << endl; 00343 //see if it needs to be truncated 00344 vlen = val.length(); 00345 llen = aLabel.length(); 00346 if (vlen + llen + 4 > 80 && llen < 80 - 8 - 2 ) 00347 { 00348 const int limit = 80 - 8 - 2 - (int)llen; 00349 // the -2 is there to allow extending the length of a part of val 00350 // by 1 or 2 in order to prevent an encoded character from being 00351 // split in half 00352 int i = 0; 00353 TQString shortValue; 00354 TQCString shortLabel; 00355 00356 while (!val.isEmpty ()) 00357 { 00358 int partLen; // the length of the next part of the value 00359 if ( limit >= int(vlen) ) { 00360 // the rest of the value fits completely into one continued header 00361 partLen = vlen; 00362 } 00363 else { 00364 partLen = limit; 00365 // make sure that we don't split an encoded char in half 00366 if ( val[partLen-1] == '%' ) { 00367 partLen += 2; 00368 } 00369 else if ( partLen > 1 && val[partLen-2] == '%' ) { 00370 partLen += 1; 00371 } 00372 // make sure partLen does not exceed vlen (could happen in case of 00373 // an incomplete encoded char) 00374 if ( partLen > int(vlen) ) { 00375 partLen = vlen; 00376 } 00377 } 00378 shortValue = val.left( partLen ); 00379 shortLabel.setNum (i); 00380 shortLabel = aLabel + "*" + shortLabel; 00381 val = val.right( vlen - partLen ); 00382 vlen = vlen - partLen; 00383 if (encoded) 00384 { 00385 if (i == 0) 00386 { 00387 shortValue = "''" + shortValue; 00388 } 00389 shortLabel += "*"; 00390 } 00391 //kdDebug(7116) << "mimeHeader::setParameter() - shortLabel = '" << shortLabel << "'" << endl; 00392 //kdDebug(7116) << "mimeHeader::setParameter() - shortValue = '" << shortValue << "'" << endl; 00393 //kdDebug(7116) << "mimeHeader::setParameter() - val = '" << val << "'" << endl; 00394 aDict->insert (shortLabel, new TQString (shortValue)); 00395 i++; 00396 } 00397 } 00398 else 00399 { 00400 aDict->insert (aLabel, new TQString (val)); 00401 } 00402 } 00403 } 00404 00405 TQCString 00406 mimeHeader::outputParameter (TQDict < TQString > *aDict) 00407 { 00408 TQCString retVal; 00409 if (aDict) 00410 { 00411 TQDictIterator < TQString > it (*aDict); 00412 while (it.current ()) 00413 { 00414 retVal += (";\n\t" + it.currentKey () + "=").latin1 (); 00415 if (it.current ()->find (' ') > 0 || it.current ()->find (';') > 0) 00416 { 00417 retVal += '"' + it.current ()->utf8 () + '"'; 00418 } 00419 else 00420 { 00421 retVal += it.current ()->utf8 (); 00422 } 00423 // << it.current()->utf8() << "'"; 00424 ++it; 00425 } 00426 retVal += "\n"; 00427 } 00428 return retVal; 00429 } 00430 00431 void 00432 mimeHeader::outputPart (mimeIO & useIO) 00433 { 00434 TQPtrListIterator < mimeHeader > nestedParts = getNestedIterator (); 00435 TQCString boundary; 00436 if (!getTypeParm ("boundary").isEmpty ()) 00437 boundary = getTypeParm ("boundary").latin1 (); 00438 00439 outputHeader (useIO); 00440 if (!getPreBody ().isEmpty ()) 00441 useIO.outputMimeLine (getPreBody ()); 00442 if (getNestedMessage ()) 00443 getNestedMessage ()->outputPart (useIO); 00444 while (nestedParts.current ()) 00445 { 00446 if (!boundary.isEmpty ()) 00447 useIO.outputMimeLine ("--" + boundary); 00448 nestedParts.current ()->outputPart (useIO); 00449 ++nestedParts; 00450 } 00451 if (!boundary.isEmpty ()) 00452 useIO.outputMimeLine ("--" + boundary + "--"); 00453 if (!getPostBody ().isEmpty ()) 00454 useIO.outputMimeLine (getPostBody ()); 00455 } 00456 00457 int 00458 mimeHeader::parsePart (mimeIO & useIO, const TQString& boundary) 00459 { 00460 int retVal = 0; 00461 bool mbox = false; 00462 TQCString preNested, postNested; 00463 mbox = parseHeader (useIO); 00464 00465 kdDebug(7116) << "mimeHeader::parsePart - parsing part '" << getType () << "'" << endl; 00466 if (!tqstrnicmp (getType (), "Multipart", 9)) 00467 { 00468 retVal = parseBody (useIO, preNested, getTypeParm ("boundary")); //this is a message in mime format stuff 00469 setPreBody (preNested); 00470 int localRetVal; 00471 do 00472 { 00473 mimeHeader *aHeader = new mimeHeader; 00474 00475 // set default type for multipart/digest 00476 if (!tqstrnicmp (getType (), "Multipart/Digest", 16)) 00477 aHeader->setType ("Message/RFC822"); 00478 00479 localRetVal = aHeader->parsePart (useIO, getTypeParm ("boundary")); 00480 addNestedPart (aHeader); 00481 } 00482 while (localRetVal); //get nested stuff 00483 } 00484 if (!tqstrnicmp (getType (), "Message/RFC822", 14)) 00485 { 00486 mailHeader *msgHeader = new mailHeader; 00487 retVal = msgHeader->parsePart (useIO, boundary); 00488 setNestedMessage (msgHeader); 00489 } 00490 else 00491 { 00492 retVal = parseBody (useIO, postNested, boundary, mbox); //just a simple part remaining 00493 setPostBody (postNested); 00494 } 00495 return retVal; 00496 } 00497 00498 int 00499 mimeHeader::parseBody (mimeIO & useIO, TQCString & messageBody, 00500 const TQString& boundary, bool mbox) 00501 { 00502 TQCString inputStr; 00503 TQCString buffer; 00504 TQString partBoundary; 00505 TQString partEnd; 00506 int retVal = 0; //default is last part 00507 00508 if (!boundary.isEmpty ()) 00509 { 00510 partBoundary = TQString ("--") + boundary; 00511 partEnd = TQString ("--") + boundary + "--"; 00512 } 00513 00514 while (useIO.inputLine (inputStr)) 00515 { 00516 //check for the end of all parts 00517 if (!partEnd.isEmpty () 00518 && !tqstrnicmp (inputStr, partEnd.latin1 (), partEnd.length () - 1)) 00519 { 00520 retVal = 0; //end of these parts 00521 break; 00522 } 00523 else if (!partBoundary.isEmpty () 00524 && !tqstrnicmp (inputStr, partBoundary.latin1 (), 00525 partBoundary.length () - 1)) 00526 { 00527 retVal = 1; //continue with next part 00528 break; 00529 } 00530 else if (mbox && inputStr.find ("From ") == 0) 00531 { 00532 retVal = 0; // end of mbox 00533 break; 00534 } 00535 buffer += inputStr; 00536 if (buffer.length () > 16384) 00537 { 00538 messageBody += buffer; 00539 buffer = ""; 00540 } 00541 } 00542 00543 messageBody += buffer; 00544 return retVal; 00545 } 00546 00547 bool 00548 mimeHeader::parseHeader (mimeIO & useIO) 00549 { 00550 bool mbox = false; 00551 bool first = true; 00552 mimeHdrLine my_line; 00553 TQCString inputStr; 00554 00555 kdDebug(7116) << "mimeHeader::parseHeader - starting parsing" << endl; 00556 while (useIO.inputLine (inputStr)) 00557 { 00558 int appended; 00559 if (inputStr.find ("From ") != 0 || !first) 00560 { 00561 first = false; 00562 appended = my_line.appendStr (inputStr); 00563 if (!appended) 00564 { 00565 addHdrLine (&my_line); 00566 appended = my_line.setStr (inputStr); 00567 } 00568 if (appended <= 0) 00569 break; 00570 } 00571 else 00572 { 00573 mbox = true; 00574 first = false; 00575 } 00576 inputStr = (const char *) NULL; 00577 } 00578 00579 kdDebug(7116) << "mimeHeader::parseHeader - finished parsing" << endl; 00580 return mbox; 00581 } 00582 00583 mimeHeader * 00584 mimeHeader::bodyPart (const TQString & _str) 00585 { 00586 // see if it is nested a little deeper 00587 int pt = _str.find('.'); 00588 if (pt != -1) 00589 { 00590 TQString tempStr = _str; 00591 mimeHeader *tempPart; 00592 00593 tempStr = _str.right (_str.length () - pt - 1); 00594 if (nestedMessage) 00595 { 00596 kdDebug(7116) << "mimeHeader::bodyPart - recursing message" << endl; 00597 tempPart = nestedMessage->nestedParts.at (_str.left(pt).toULong() - 1); 00598 } 00599 else 00600 { 00601 kdDebug(7116) << "mimeHeader::bodyPart - recursing mixed" << endl; 00602 tempPart = nestedParts.at (_str.left(pt).toULong() - 1); 00603 } 00604 if (tempPart) 00605 tempPart = tempPart->bodyPart (tempStr); 00606 return tempPart; 00607 } 00608 00609 kdDebug(7116) << "mimeHeader::bodyPart - returning part " << _str << endl; 00610 // or pick just the plain part 00611 if (nestedMessage) 00612 { 00613 kdDebug(7116) << "mimeHeader::bodyPart - message" << endl; 00614 return nestedMessage->nestedParts.at (_str.toULong () - 1); 00615 } 00616 kdDebug(7116) << "mimeHeader::bodyPart - mixed" << endl; 00617 return nestedParts.at (_str.toULong () - 1); 00618 } 00619 00620 void mimeHeader::serialize(TQDataStream& stream) 00621 { 00622 int nestedcount = nestedParts.count(); 00623 if (nestedParts.isEmpty() && nestedMessage) 00624 nestedcount = 1; 00625 stream << nestedcount << contentType << TQString (getTypeParm ("name")) << _contentDescription 00626 << _contentDisposition << contentEncoding << contentLength << partSpecifier; 00627 // serialize nested message 00628 if (nestedMessage) 00629 nestedMessage->serialize(stream); 00630 00631 // serialize nested parts 00632 if (!nestedParts.isEmpty()) 00633 { 00634 TQPtrListIterator < mimeHeader > it(nestedParts); 00635 mimeHeader* part; 00636 while ( (part = it.current()) != 0 ) 00637 { 00638 ++it; 00639 part->serialize(stream); 00640 } 00641 } 00642 } 00643 00644 #ifdef KMAIL_COMPATIBLE 00645 // compatibility subroutines 00646 TQString 00647 mimeHeader::bodyDecoded () 00648 { 00649 kdDebug(7116) << "mimeHeader::bodyDecoded" << endl; 00650 TQByteArray temp; 00651 00652 temp = bodyDecodedBinary (); 00653 return TQString::fromLatin1 (temp.data (), temp.count ()); 00654 } 00655 00656 TQByteArray 00657 mimeHeader::bodyDecodedBinary () 00658 { 00659 TQByteArray retVal; 00660 00661 if (contentEncoding.find ("quoted-printable", 0, false) == 0) 00662 retVal = KCodecs::quotedPrintableDecode(postMultipartBody); 00663 else if (contentEncoding.find ("base64", 0, false) == 0) 00664 KCodecs::base64Decode(postMultipartBody, retVal); 00665 else retVal = postMultipartBody; 00666 00667 kdDebug(7116) << "mimeHeader::bodyDecodedBinary - size is " << retVal.size () << endl; 00668 return retVal; 00669 } 00670 00671 void 00672 mimeHeader::setBodyEncodedBinary (const TQByteArray & _arr) 00673 { 00674 setBodyEncoded (_arr); 00675 } 00676 00677 void 00678 mimeHeader::setBodyEncoded (const TQByteArray & _arr) 00679 { 00680 TQByteArray setVal; 00681 00682 kdDebug(7116) << "mimeHeader::setBodyEncoded - in size " << _arr.size () << endl; 00683 if (contentEncoding.find ("quoted-printable", 0, false) == 0) 00684 setVal = KCodecs::quotedPrintableEncode(_arr); 00685 else if (contentEncoding.find ("base64", 0, false) == 0) 00686 KCodecs::base64Encode(_arr, setVal); 00687 else 00688 setVal.duplicate (_arr); 00689 kdDebug(7116) << "mimeHeader::setBodyEncoded - out size " << setVal.size () << endl; 00690 00691 postMultipartBody.duplicate (setVal); 00692 kdDebug(7116) << "mimeHeader::setBodyEncoded - out size " << postMultipartBody.size () << endl; 00693 } 00694 00695 TQString 00696 mimeHeader::iconName () 00697 { 00698 TQString fileName; 00699 00700 // FIXME: bug? Why throw away this data? 00701 fileName = 00702 KMimeType::mimeType (contentType.lower ())->icon (TQString(), false); 00703 fileName = 00704 TDEGlobal::instance ()->iconLoader ()->iconPath (fileName, TDEIcon::Desktop); 00705 // if (fileName.isEmpty()) 00706 // fileName = TDEGlobal::instance()->iconLoader()->iconPath( "unknown", TDEIcon::Desktop ); 00707 return fileName; 00708 } 00709 00710 void 00711 mimeHeader::setNestedMessage (mailHeader * inPart, bool destroy) 00712 { 00713 // if(nestedMessage && destroy) delete nestedMessage; 00714 nestedMessage = inPart; 00715 } 00716 00717 TQString 00718 mimeHeader::headerAsString () 00719 { 00720 mimeIOTQString myIO; 00721 00722 outputHeader (myIO); 00723 return myIO.getString (); 00724 } 00725 00726 TQString 00727 mimeHeader::magicSetType (bool aAutoDecode) 00728 { 00729 TQString mimetype; 00730 TQByteArray body; 00731 KMimeMagicResult *result; 00732 00733 KMimeMagic::self ()->setFollowLinks (TRUE); // is it necessary ? 00734 00735 if (aAutoDecode) 00736 body = bodyDecodedBinary (); 00737 else 00738 body = postMultipartBody; 00739 00740 result = KMimeMagic::self ()->findBufferType (body); 00741 mimetype = result->mimeType (); 00742 contentType = mimetype; 00743 return mimetype; 00744 } 00745 #endif