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 libraries 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. *
59 #include <LocaleXlate.h>
61 #include "rerule.h" /* FALSE */
65 arpaPhrase(const char * name)
70 int gotlt, lastsp, didq;
72 const char * last_comma = name;
81 if (name == (char *) 0) {
85 /* We need to figure out what is the biggest possible address.
86 This will be the maximum distance between commas.
88 for (comma = name; *comma; comma++) {
91 distance = comma - last_comma;
92 biggest = biggest < distance ? distance : biggest;
96 distance = comma - last_comma;
97 biggest = biggest < distance ? distance : biggest;
98 biggest += 2; /* Just in case. */
101 addrs = (char **)malloc((n_addrs + 1) * sizeof(char *));
103 cp2 = (char *)malloc(biggest);
104 addrs[cur_addr++] = cp2;
109 for (cp = name; (c = *cp++) != 0;) {
113 Start of a comment, ignore it.
116 while ((c = *cp) != 0) {
120 if (*cp == 0) goto outcm;
130 if (nesting <= 0) break;
138 Start a quoted string.
139 Copy it in its entirety.
142 while ((c = *cp) != 0) {
146 if ((c = *cp) == 0) goto outqs;
152 if (gotlt == 0 || gotlt == '<') {
176 cp2 = (char *)malloc(biggest);
177 addrs[cur_addr++] = cp2;
191 cp2 = addrs[cur_addr - 1];
202 /* FALLTHROUGH . . . */
205 if (gotlt == 0 || gotlt == '<') {
216 addrs[cur_addr] = NULL;
221 formatMessage(char ** addrs, const char * subject, const char * body)
229 _DtXlateDb db = NULL;
230 char plat[_DtPLATFORM_MAX_LEN];
237 char *ret_locale = NULL;
238 char *ret_lang = NULL;
239 char *ret_codeset = NULL;
240 char default_charset[64];
242 unsigned long _len = 0;
245 /* Figure out how big we need the buffer to be. */
246 for (to = addrs; *to; to++) {
248 size += 2; /* Leave room for the , */
251 size += strlen(subject);
252 size += strlen(body);
254 /* We will need space for the header names, a blank line, and
255 other general formatting things. We could be exact, but
256 1024 is more than enough and give us some spare.
260 msg = (char *)malloc(size);
265 for (to = addrs; *to; to++) {
267 if (*(to + 1) != NULL) {
276 strcat(msg, "\nSubject: ");
278 /* Encode the body of the message */
280 /* 1) Open Lcx data bases */
282 if ((_DtLcxOpenAllDbs(&db) == 0) &&
283 (_DtXlateGetXlateEnv(db,plat,&execver,&compver) != 0))
286 strcat(msg, subject);
287 if (msg[strlen(msg) - 1] == '\n') {
288 msg[strlen(msg) - 1] = 0;
291 strcat(msg, "\nMime-Version: 1.0\n");
292 strcat(msg, "Content-Type: text/plain;charset=us-ascii\n\n");
298 body_len = strlen(body);
302 strcpy(mime_type,"text/plain");
303 rfc1522cpy(hdr_buf,subject);
304 strcat(hdr_buf,"Mime-Version: 1.0\n");
305 isAllASCII= CvtStr((char *)NULL,(void *)body,(unsigned long)body_len,(void**)&NewBuf, &_len, CURRENT_TO_INTERNET);
307 enc = getEncodingType(body,body_len,FALSE);
309 * Here is an ugly adjustment again. If mime_type is text/plain and if
310 * ret_codeset is ISO-2022-JP/KR/TW/CN, we have to always use
312 * This means if the user inputs UDC/VDC into the e-mail body,
313 * fold7 may convert it to the string with MSB-on character and
314 * dtmail passes it to sendmail as if I had all 7bit chars.
316 getCharSet(default_charset);
317 DtXlateOpToStdLocale(DtLCX_OPER_MIME, default_charset,
318 &ret_locale, &ret_lang, &ret_codeset);
319 if ( !strncasecmp( mime_type, "text/plain", 10 ) &&
320 ( !strncasecmp( ret_codeset, "ISO-2022-JP", 11 ) ||
321 !strncasecmp( ret_codeset, "ISO-2022-KR", 11 ) ||
322 !strncasecmp( ret_codeset, "ISO-2022-TW", 11 ) ||
323 !strncasecmp( ret_codeset, "ISO-2022-CN", 11 ) ) )
326 memset(digest,0,sizeof(digest));
327 md5PlainText(body,body_len,digest);
328 writeContentHeaders(hdr_buf,mime_type,enc,(char *)digest,isAllASCII);
329 strcat(hdr_buf,"\n");
330 strcat(hdr_buf,"Content-Length: ");
331 if (( NewBuf != NULL) && ( _len != 0))
333 sprintf(tmpbuf,"%ld",_len);
334 strcat(hdr_buf,tmpbuf);
335 strcat(hdr_buf,"\n");
337 strncat(msg,NewBuf,_len);
338 strcat(hdr_buf,"\n");
342 sprintf(tmpbuf,"%d",body_len);
343 strcat(hdr_buf,tmpbuf);
344 strcat(hdr_buf,"\n");
355 deliver(char ** addrs, char * msg)
364 for (n_addrs = 0; addrs[n_addrs]; n_addrs++) {
368 argv = (char **)malloc((n_addrs + 2) * sizeof(char *));
369 argv[0] = "/usr/lib/sendmail";
371 for (cp = 0; addrs[cp]; cp++) {
372 argv[cp + 1] = addrs[cp];
377 fprintf(stderr, "pipe() failed %d '%s'\n", errno, strerror(errno));
386 if (c_pid == 0) { /* The child. */
387 dup2(fd[0], STDIN_FILENO);
389 execvp("/usr/lib/sendmail", (char *const *)argv);
390 _exit(1); /* This had better never happen! */
392 else { /* The parent. */
393 if(-1 == write(fd[1], msg, strlen(msg))) {
394 fprintf(stderr, "write() failed %d '%s'\n", errno, strerror(errno));
400 waitpid(c_pid, &status, 0);
407 submit_mail(const char * to,
408 const char * subject,
417 Parse the address list so we can form a reasonable one
418 for the user to see in the message.
420 addrs = arpaPhrase(to);
422 msg = formatMessage(addrs, subject, body);
424 status = deliver(addrs, msg);
426 for (ad = addrs; *ad; ad++) {