2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /*******************************************************************************
27 ** $XConsortium: submit.c /main/5 1996/10/03 10:58:04 drk $
29 ** RESTRICTED CONFIDENTIAL INFORMATION:
31 ** The information in this document is subject to special
32 ** restrictions in a confidential disclosure agreement between
33 ** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
34 ** document outside HP, IBM, Sun, USL, SCO, or Univel without
35 ** Sun's specific written approval. This document and all copies
36 ** and derivative works thereof must be returned or destroyed at
39 ** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
41 *******************************************************************************/
44 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
45 * (c) Copyright 1993, 1994 International Business Machines Corp. *
46 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
47 * (c) Copyright 1993, 1994 Novell, Inc. *
58 #include <LocaleXlate.h>
60 #include "rerule.h" /* FALSE */
64 arpaPhrase(const char * name)
67 register const char *cp;
69 int gotlt, lastsp, didq;
71 const char * last_comma = name;
80 if (name == (char *) 0) {
84 /* We need to figure out what is the biggest possible address.
85 This will be the maximum distance between commas.
87 for (comma = name; *comma; comma++) {
90 distance = comma - last_comma;
91 biggest = biggest < distance ? distance : biggest;
95 distance = comma - last_comma;
96 biggest = biggest < distance ? distance : biggest;
97 biggest += 2; /* Just in case. */
100 addrs = (char **)malloc((n_addrs + 1) * sizeof(char *));
102 cp2 = (char *)malloc(biggest);
103 addrs[cur_addr++] = cp2;
108 for (cp = name; (c = *cp++) != 0;) {
112 Start of a comment, ignore it.
115 while ((c = *cp) != 0) {
119 if (*cp == 0) goto outcm;
129 if (nesting <= 0) break;
137 Start a quoted string.
138 Copy it in its entirety.
141 while ((c = *cp) != 0) {
145 if ((c = *cp) == 0) goto outqs;
151 if (gotlt == 0 || gotlt == '<') {
175 cp2 = (char *)malloc(biggest);
176 addrs[cur_addr++] = cp2;
190 cp2 = addrs[cur_addr - 1];
201 /* FALLTHROUGH . . . */
204 if (gotlt == 0 || gotlt == '<') {
215 addrs[cur_addr] = NULL;
220 formatMessage(char ** addrs, const char * subject, const char * body)
228 _DtXlateDb db = NULL;
229 char plat[_DtPLATFORM_MAX_LEN];
236 char *ret_locale = NULL;
237 char *ret_lang = NULL;
238 char *ret_codeset = NULL;
239 char default_charset[64];
241 unsigned long _len = 0;
244 /* Figure out how big we need the buffer to be. */
245 for (to = addrs; *to; to++) {
247 size += 2; /* Leave room for the , */
250 size += strlen(subject);
251 size += strlen(body);
253 /* We will need space for the header names, a blank line, and
254 other general formatting things. We could be exact, but
255 1024 is more than enough and give us some spare.
259 msg = (char *)malloc(size);
264 for (to = addrs; *to; to++) {
266 if (*(to + 1) != NULL) {
275 strcat(msg, "\nSubject: ");
277 /* Encode the body of the message */
279 /* 1) Open Lcx data bases */
281 if ((_DtLcxOpenAllDbs(&db) == 0) &&
282 (_DtXlateGetXlateEnv(db,plat,&execver,&compver) != 0))
285 strcat(msg, subject);
286 if (msg[strlen(msg) - 1] == '\n') {
287 msg[strlen(msg) - 1] = 0;
290 strcat(msg, "\nMime-Version: 1.0\n");
291 strcat(msg, "Content-Type: text/plain;charset=us-ascii\n\n");
297 body_len = strlen(body);
301 strcpy(mime_type,"text/plain");
302 rfc1522cpy(hdr_buf,subject);
303 strcat(hdr_buf,"Mime-Version: 1.0\n");
304 isAllASCII= CvtStr((char *)NULL,(void *)body,(unsigned long)body_len,(void**)&NewBuf, &_len, CURRENT_TO_INTERNET);
306 enc = getEncodingType(body,body_len,FALSE);
308 * Here is an ugly adjustment again. If mime_type is text/plain and if
309 * ret_codeset is ISO-2022-JP/KR/TW/CN, we have to always use
311 * This means if the user inputs UDC/VDC into the e-mail body,
312 * fold7 may convert it to the string with MSB-on character and
313 * dtmail passes it to sendmail as if I had all 7bit chars.
315 getCharSet(default_charset);
316 DtXlateOpToStdLocale(DtLCX_OPER_MIME, default_charset,
317 &ret_locale, &ret_lang, &ret_codeset);
318 if ( !strncasecmp( mime_type, "text/plain", 10 ) &&
319 ( !strncasecmp( ret_codeset, "ISO-2022-JP", 11 ) ||
320 !strncasecmp( ret_codeset, "ISO-2022-KR", 11 ) ||
321 !strncasecmp( ret_codeset, "ISO-2022-TW", 11 ) ||
322 !strncasecmp( ret_codeset, "ISO-2022-CN", 11 ) ) )
325 memset(digest,0,sizeof(digest));
326 md5PlainText(body,body_len,digest);
327 writeContentHeaders(hdr_buf,mime_type,enc,(char *)digest,isAllASCII);
328 strcat(hdr_buf,"\n");
329 strcat(hdr_buf,"Content-Length: ");
330 if (( NewBuf != NULL) && ( _len != 0))
332 sprintf(tmpbuf,"%ld",_len);
333 strcat(hdr_buf,tmpbuf);
334 strcat(hdr_buf,"\n");
336 strncat(msg,NewBuf,_len);
337 strcat(hdr_buf,"\n");
341 sprintf(tmpbuf,"%d",body_len);
342 strcat(hdr_buf,tmpbuf);
343 strcat(hdr_buf,"\n");
354 deliver(char ** addrs, char * msg)
363 for (n_addrs = 0; addrs[n_addrs]; n_addrs++) {
367 argv = (char **)malloc((n_addrs + 2) * sizeof(char *));
368 argv[0] = "/usr/lib/sendmail";
370 for (cp = 0; addrs[cp]; cp++) {
371 argv[cp + 1] = addrs[cp];
382 if (c_pid == 0) { /* The child. */
383 dup2(fd[0], STDIN_FILENO);
385 execvp("/usr/lib/sendmail", (char *const *)argv);
386 _exit(1); /* This had better never happen! */
388 else { /* The parent. */
389 write(fd[1], msg, strlen(msg));
393 waitpid(c_pid, &status, 0);
400 submit_mail(const char * to,
401 const char * subject,
410 Parse the address list so we can form a reasonable one
411 for the user to see in the message.
413 addrs = arpaPhrase(to);
415 msg = formatMessage(addrs, subject, body);
417 status = deliver(addrs, msg);
419 for (ad = addrs; *ad; ad++) {