Line data Source code
1 : /* send-mail.c - Invoke sendmail or other delivery tool.
2 : * Copyright (C) 2016 g10 Code GmbH
3 : *
4 : * This file is part of GnuPG.
5 : *
6 : * GnuPG is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU General Public License as published by
8 : * the Free Software Foundation; either version 3 of the License, or
9 : * (at your option) any later version.
10 : *
11 : * GnuPG is distributed in the hope that it will be useful,
12 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : * GNU General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU General Public License
17 : * along with this program; if not, see <https://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include <config.h>
21 : #include <stdio.h>
22 : #include <stdlib.h>
23 : #include <string.h>
24 :
25 : #include "util.h"
26 : #include "exectool.h"
27 : #include "sysutils.h"
28 : #include "send-mail.h"
29 :
30 :
31 : static gpg_error_t
32 0 : run_sendmail (estream_t data)
33 : {
34 : gpg_error_t err;
35 0 : const char pgmname[] = "/usr/lib/sendmail";
36 : const char *argv[3];
37 :
38 0 : argv[0] = "-oi";
39 0 : argv[1] = "-t";
40 0 : argv[2] = NULL;
41 :
42 0 : err = gnupg_exec_tool_stream (pgmname, argv, data, NULL, NULL, NULL, NULL);
43 0 : if (err)
44 0 : log_error ("running '%s' failed: %s\n", pgmname, gpg_strerror (err));
45 0 : return err;
46 : }
47 :
48 :
49 : /* Send the data in FP as mail. */
50 : gpg_error_t
51 0 : send_mail (estream_t fp)
52 : {
53 0 : return run_sendmail (fp);
54 : }
55 :
56 :
57 : /* Convenience function to write a mail to a named file. */
58 : gpg_error_t
59 0 : send_mail_to_file (estream_t fp, const char *fname)
60 : {
61 : gpg_error_t err;
62 0 : estream_t outfp = NULL;
63 0 : char *buffer = NULL;
64 0 : size_t buffersize = 32 * 1024;
65 : size_t nbytes, nwritten;
66 :
67 0 : if (!fname)
68 0 : fname = "-";
69 :
70 0 : buffer = xtrymalloc (buffersize);
71 0 : if (!buffer)
72 0 : return gpg_error_from_syserror ();
73 :
74 0 : outfp = !strcmp (fname,"-")? es_stdout : es_fopen (fname, "wb");
75 0 : if (!outfp)
76 : {
77 0 : err = gpg_error_from_syserror ();
78 0 : log_error ("error creating '%s': %s\n", fname, gpg_strerror (err));
79 0 : goto leave;
80 : }
81 : for (;;)
82 : {
83 0 : if (es_read (fp, buffer, sizeof buffer, &nbytes))
84 : {
85 0 : err = gpg_error_from_syserror ();
86 0 : log_error ("error reading '%s': %s\n",
87 : es_fname_get (fp), gpg_strerror (err));
88 0 : goto leave;
89 : }
90 :
91 0 : if (!nbytes)
92 : {
93 0 : err = 0;
94 0 : break; /* Ready. */
95 : }
96 :
97 0 : if (es_write (outfp, buffer, nbytes, &nwritten))
98 : {
99 0 : err = gpg_error_from_syserror ();
100 0 : log_error ("error writing '%s': %s\n", fname, gpg_strerror (err));
101 0 : goto leave;
102 : }
103 0 : else if (nwritten != nbytes)
104 : {
105 0 : err = gpg_error (GPG_ERR_EIO);
106 0 : log_error ("error writing '%s': %s\n", fname, "short write");
107 0 : goto leave;
108 : }
109 0 : }
110 :
111 :
112 : leave:
113 0 : if (err)
114 : {
115 0 : if (outfp && outfp != es_stdout)
116 : {
117 0 : es_fclose (outfp);
118 0 : gnupg_remove (fname);
119 : }
120 : }
121 0 : else if (outfp && outfp != es_stdout && es_fclose (outfp))
122 : {
123 0 : err = gpg_error_from_syserror ();
124 0 : log_error ("error closing '%s': %s\n", fname, gpg_strerror (err));
125 : }
126 :
127 0 : xfree (buffer);
128 0 : return err;
129 : }
|