PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/cde/programs/dtmail/dtmailpr/message.C

https://bitbucket.org/tifan/cde
C | 499 lines | 342 code | 84 blank | 73 comment | 93 complexity | 8eed314e2548928607fcea133b9d7e4b MD5 | raw file
Possible License(s): LGPL-2.1, IPL-1.0, 0BSD
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these librararies and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $TOG: message.C /main/9 1998/07/24 16:08:20 mgreess $
  24. *
  25. * (c) Copyright 1996 Digital Equipment Corporation.
  26. * (c) Copyright 1996 Hewlett-Packard Company.
  27. * (c) Copyright 1996 International Business Machines Corp.
  28. * (c) Copyright 1994,1996 Sun Microsystems, Inc.
  29. * (c) Copyright 1996 Novell, Inc.
  30. * (c) Copyright 1996 FUJITSU LIMITED.
  31. * (c) Copyright 1996 Hitachi.
  32. */
  33. /*
  34. *+SNOTICE
  35. *
  36. * RESTRICTED CONFIDENTIAL INFORMATION:
  37. *
  38. * The information in this document is subject to special
  39. * restrictions in a confidential disclosure agreement between
  40. * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
  41. * document outside HP, IBM, Sun, USL, SCO, or Univel without
  42. * Sun's specific written approval. This document and all copies
  43. * and derivative works thereof must be returned or destroyed at
  44. * Sun's request.
  45. *
  46. *+ENOTICE
  47. */
  48. #include "dmx.hh"
  49. // For CHARSET
  50. #include <DtHelp/LocaleXlate.h>
  51. #include <locale.h>
  52. #if !defined(USL) && !defined(__uxp__)
  53. #include <strings.h>
  54. #else
  55. #include <EUSCompat.h>
  56. #endif
  57. #include "utils/str_utils.h"
  58. DmxMsg::DmxMsg (void)
  59. {
  60. // initialize everything
  61. message = NULL;
  62. addlInfo = NULL;
  63. numBPs = 0;
  64. cachedValues = B_FALSE;
  65. isCurrent = B_FALSE;
  66. hasAttachments = B_FALSE;
  67. isNew = B_FALSE;
  68. return;
  69. }
  70. void
  71. DmxMsg::setHandle (DtMailMessageHandle &h)
  72. {
  73. msgHandle = h;
  74. return;
  75. }
  76. void
  77. DmxMsg::setHeader (DtMailHeaderLine &h)
  78. {
  79. msgHeader = h;
  80. return;
  81. }
  82. void
  83. DmxMsg::setMessage (DtMail::Message *m)
  84. {
  85. message = m;
  86. return;
  87. }
  88. void
  89. DmxMsg::setInfo (char *info)
  90. {
  91. addlInfo = strdup (info);
  92. return;
  93. }
  94. void
  95. DmxMsg::getFlags (void)
  96. {
  97. DtMailEnv env;
  98. DtMailBoolean flagState;
  99. memset (&env, '\0', sizeof (DtMailEnv));
  100. flagState = DTM_FALSE;
  101. flagState = message->flagIsSet (env, DtMailMessageMultipart);
  102. if (handleError (env, "msg: multipart?") == B_TRUE)
  103. exit (1);
  104. if (flagState == DTM_TRUE)
  105. {
  106. hasAttachments = B_TRUE;
  107. } else {
  108. hasAttachments = B_FALSE;
  109. }
  110. flagState = message->flagIsSet (env, DtMailMessageNew);
  111. if (handleError (env, "msg: new?") == B_TRUE)
  112. exit (1);
  113. if (flagState == DTM_TRUE)
  114. {
  115. isNew = B_TRUE;
  116. } else {
  117. isNew = B_FALSE;
  118. }
  119. return;
  120. }
  121. char *
  122. DmxMsg::printHeader (enum DmxHeaderType htype)
  123. {
  124. DtMailEnv env;
  125. char *status, *indicator;
  126. if (isCurrent == B_TRUE)
  127. {
  128. indicator = ">";
  129. } else {
  130. indicator = " ";
  131. }
  132. if (isNew == B_TRUE)
  133. {
  134. status = "N";
  135. } else {
  136. status = "O"; // how about "unread" ??
  137. }
  138. if (hasAttachments == B_TRUE)
  139. {
  140. indicator = "@";
  141. }
  142. // the addlInfo string is any extra info needed by the
  143. // viewer, such as a message number
  144. char *buffer = new char [1024];
  145. memset (buffer, 0, 1024);
  146. switch (htype)
  147. {
  148. case MSGLIST:
  149. sprintf (buffer, "%s%s%s %s",
  150. indicator, status, addlInfo,
  151. formatHeader (msgHeader, MSGLIST));
  152. break;
  153. case MSGHEADER:
  154. sprintf (buffer, "%s",
  155. formatHeader (msgHeader, MSGHEADER));
  156. break;
  157. default:
  158. printf ("error in DmxMsg::display\n");
  159. break;
  160. }
  161. return buffer;
  162. }
  163. void
  164. DmxMsg::display (void)
  165. {
  166. DtMailEnv env;
  167. boolean_t FirstIsText = B_FALSE;
  168. DtMail::BodyPart *firstPart = NULL, *nextpart = NULL;
  169. char *type;
  170. char *description = NULL;
  171. char *sunDataDescription = NULL;
  172. char *name = NULL;
  173. void * contents = NULL;
  174. unsigned long length = 0;
  175. int mode = 0;
  176. char *buf = NULL;
  177. // For CHARSET
  178. char *mime_cs = NULL, *from_cs = NULL, *to_cs = NULL;
  179. char *v3_cs = new char [64];
  180. if (cachedValues != B_TRUE)
  181. parse (); // read in body part info
  182. firstPart = bodyParts [0];
  183. firstPart->getContents(env,
  184. (const void **) &contents,
  185. &length,
  186. NULL, //type
  187. NULL, //name
  188. NULL, //mode
  189. NULL); //description
  190. if (handleError (env, "getContents") == B_TRUE)
  191. exit (1);
  192. // For CHARSET
  193. DtMailValueSeq value;
  194. boolean_t err = B_FALSE;
  195. // Get the bodypart's charset - Try MIME first then V3
  196. firstPart->getHeader(env, DtMailMessageContentType, DTM_TRUE, value);
  197. if (env.isNotSet()) {
  198. mime_cs = firstPart->csFromContentType(value);
  199. } else {
  200. env.clear();
  201. value.clear();
  202. firstPart->getHeader(env, DtMailMessageV3charset, DTM_TRUE, value);
  203. if (env.isNotSet()) {
  204. strcpy(v3_cs, *(value[0]));
  205. } else {
  206. err = B_TRUE;
  207. env.clear();
  208. value.clear();
  209. }
  210. }
  211. // If cannot obtain bodypart's charset header, then maybe this message
  212. // has only one bodypart, then in this case the charset header maybe
  213. // among the message's envelope (main message headers).
  214. // Get the envelope of the message (in order to access the headers)
  215. DtMail::Envelope *envelope = NULL;
  216. if (err == B_TRUE) {
  217. envelope = message->getEnvelope(env);
  218. err = B_FALSE;
  219. #ifdef DEBUG
  220. env.logError(DTM_FALSE, "DEBUG dtmailpr: Looking at main message header\n");
  221. #endif
  222. }
  223. if (envelope != NULL) {
  224. // Check for MIME charset header and then for V3 charset header
  225. envelope->getHeader(env, DtMailMessageContentType, DTM_TRUE, value);
  226. if (env.isNotSet()) {
  227. mime_cs = firstPart->csFromContentType(value);
  228. } else {
  229. err = B_TRUE;
  230. env.clear();
  231. }
  232. if (mime_cs == NULL || err == B_TRUE) {
  233. value.clear();
  234. envelope->getHeader(env, DtMailMessageV3charset, DTM_TRUE, value);
  235. if (env.isNotSet()) {
  236. strcpy(v3_cs, *(value[0]));
  237. } else {
  238. err = B_TRUE;
  239. env.clear();
  240. }
  241. }
  242. } else {
  243. #ifdef DEBUG
  244. env.logError(DTM_FALSE, "DEBUG dtmailpr: envelope is null\n");
  245. #endif
  246. env.clear();
  247. }
  248. // Default codeset in case mime_cs and v3_cs are both null.
  249. if ((mime_cs == NULL) && (strlen(v3_cs) == 0)) {
  250. char *ret = NULL;
  251. firstPart->DtXlateOpToStdLocale(DtLCX_OPER_SETLOCALE,
  252. setlocale(LC_CTYPE, NULL),
  253. NULL,
  254. NULL,
  255. &ret);
  256. strcpy(v3_cs, "DEFAULT");
  257. strcat(v3_cs, ".");
  258. strcat(v3_cs, ret);
  259. if (ret)
  260. free(ret);
  261. }
  262. // Get iconv from and to codeset and do conversion.
  263. int converted = 0;
  264. if (mime_cs) {
  265. from_cs = firstPart->csToConvName(mime_cs);
  266. #ifdef DEBUG
  267. env.logError(DTM_FALSE, "DEBUG dtmailpr: mime_cs = %s\n", mime_cs);
  268. #endif
  269. } else {
  270. from_cs = firstPart->csToConvName(v3_cs);
  271. #ifdef DEBUG
  272. env.logError(DTM_FALSE, "DEBUG dtmailpr: v3_cs = %s\n", v3_cs);
  273. #endif
  274. }
  275. to_cs = firstPart->locToConvName();
  276. #ifdef DEBUG
  277. if ( from_cs == NULL )
  278. env.logError(DTM_FALSE, "DEBUG dtmailpr: from_cs is NULL\n");
  279. else
  280. env.logError(DTM_FALSE, "DEBUG dtmailpr: from_cs = %s\n", from_cs);
  281. if ( to_cs == NULL )
  282. env.logError(DTM_FALSE, "DEBUG dtmailpr: to_cs is NULL\n");
  283. else
  284. env.logError(DTM_FALSE, "DEBUG dtmailpr: to_cs = %s\n", to_cs);
  285. #endif
  286. if ( from_cs && to_cs ) {
  287. if ( strcasecmp(from_cs, to_cs) != 0 ) {
  288. converted = firstPart->csConvert((char **)&contents, length, 0, from_cs, to_cs);
  289. #ifdef DEBUG
  290. env.logError(DTM_FALSE, "DEBUG dtmailpr: converted = %d\n", converted);
  291. #endif
  292. }
  293. }
  294. if ( mime_cs )
  295. free ( mime_cs );
  296. if ( from_cs )
  297. free( from_cs );
  298. if ( to_cs )
  299. free ( to_cs );
  300. // End of For CHARSET
  301. buf = new char [length + 1];
  302. memset (buf, 0, (size_t) length + 1);
  303. // have to "seek" length bytes into the
  304. // contents buffer
  305. memmove (buf, contents, (size_t) length);
  306. buf [length] = '\0'; // null-terminate
  307. // that puppy
  308. // For CHARSET
  309. if (converted && contents)
  310. free(contents);
  311. char *numbuf = new char [10241];
  312. memset (numbuf, 0, 1024);
  313. #ifdef NEVER
  314. // Don't want "Message 1:" appearing in print output
  315. sprintf (numbuf, "Messsage %s:\n%s\n",
  316. addlInfo, printHeader (MSGHEADER));
  317. #endif
  318. puts(printHeader(MSGHEADER));
  319. puts(buf);
  320. fflush(stdout);
  321. // No attachments? We're done.
  322. if (numBPs < 2)
  323. return;
  324. int i = 0;
  325. char *attbuf = NULL;
  326. printf ("\n");
  327. for (i = 1; i < numBPs ; i++)
  328. {
  329. nextpart = bodyParts [i];
  330. if (nextpart == NULL)
  331. fprintf (stderr, "Error getting part!\n");
  332. length = 0;
  333. type = "";
  334. sunDataDescription = "";
  335. description = "";
  336. name = "";
  337. mode = -1;
  338. nextpart->getContents(env, NULL, &length, &type,
  339. &name, &mode, &sunDataDescription);
  340. if (handleError (env, "getContents") == B_TRUE)
  341. exit (1);
  342. if (type == NULL)
  343. type = "(unknown)";
  344. if (sunDataDescription == NULL)
  345. {
  346. description = "";
  347. } else {
  348. // should add bracket or something
  349. attbuf = new char [strlen (sunDataDescription) +10];
  350. sprintf (attbuf, " (%s)", sunDataDescription);
  351. description = attbuf;
  352. }
  353. if (name == NULL)
  354. name = "(name)";
  355. printf ("[%d] \"%s\"%s, ", i, name, description);
  356. printf ("%s, %d bytes\n", type, length);
  357. if (attbuf != NULL)
  358. delete [] attbuf;
  359. }
  360. delete [] v3_cs;
  361. return;
  362. }
  363. void
  364. DmxMsg::parse (void)
  365. {
  366. // store the body parts for later reference
  367. DtMailEnv env;
  368. boolean_t FirstIsText = B_FALSE;
  369. DtMail::BodyPart *part = NULL, *nextpart = NULL;
  370. char *type = NULL, *attr = NULL;
  371. int bc = message->getBodyCount (env);
  372. if (handleError (env, "getBodyCount") == B_TRUE)
  373. exit (1);
  374. part = message->getFirstBodyPart (env);
  375. if (handleError (env, "getFirstBodyPart") == B_TRUE)
  376. exit (1);
  377. part->getContents (env, NULL, NULL, &type, NULL, NULL, NULL);
  378. if (handleError (env, "getContents") == B_TRUE)
  379. exit (1);
  380. bodyParts = new (DtMail::BodyPart *[bc]);
  381. cachedValues = B_TRUE;
  382. // cache values
  383. bodyParts [0] = part;
  384. numBPs++;
  385. if (type != NULL)
  386. {
  387. attr = DtDtsDataTypeToAttributeValue (type,
  388. DtDTS_DA_IS_TEXT,
  389. NULL);
  390. if (attr != NULL)
  391. {
  392. FirstIsText = B_TRUE;
  393. }
  394. //free (type); // it's allocating some data for us
  395. } else {
  396. FirstIsText = B_FALSE;
  397. }
  398. // No attachments? We're done.
  399. if (bc < 2)
  400. return;
  401. int i;
  402. for (i = 1; i < bc; i++)
  403. {
  404. nextpart = NULL;
  405. nextpart = message->getNextBodyPart (env,
  406. part);
  407. if (handleError (env, "getNextBodyPart") == B_TRUE)
  408. exit (1);
  409. if (nextpart == NULL)
  410. fprintf (stderr, "Error getting part!\n");
  411. bodyParts [i] = nextpart;
  412. numBPs++;
  413. part = nextpart;
  414. }
  415. }