File: Enable-setting-content-headers-in-email.patch

package info (click to toggle)
cron 3.0pl1-197
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 3,816 kB
  • sloc: ansic: 54,879; xml: 1,600; perl: 733; sh: 463; makefile: 446; python: 43
file content (184 lines) | stat: -rw-r--r-- 5,874 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
From: Christian Kastner <ckk@kvr.at>
Date: Sun, 10 Jan 2016 20:32:28 +0100
Subject: Enable setting content headers in email

Set the ContentType: header based on the system locale or cron's environment,
if available.

Implementation taken from Fedora Core's version of cron.

Bug-Debian: https://bugs.debian.org/338051
Bug-Debian: https://bugs.debian.org/309150
Bug-Debian: https://bugs.debian.org/600310
Forwarded: no
Last-Update: 2016-01-10
---
 cron.c       | 16 ++++++++++++++++
 cron.h       |  3 +++
 crontab.5    | 14 ++++++++++++++
 do_command.c | 39 ++++++++++++++++++++++++++++++++++++++-
 externs.h    |  5 +++++
 5 files changed, 76 insertions(+), 1 deletion(-)

diff --git a/cron.c b/cron.c
index b073ecc..db0e073 100644
--- a/cron.c
+++ b/cron.c
@@ -30,6 +30,7 @@ static char rcsid[] = "$Id: cron.c,v 2.11 1994/01/15 20:43:43 vixie Exp $";
 #include <sys/types.h>
 #include <fcntl.h>
 #include <libgen.h>
+#include <strings.h>
 
 static	void	usage __P((void)),
 		run_reboot_jobs __P((cron_db *)),
@@ -66,6 +67,7 @@ main(argc, argv)
 	char	*argv[];
 {
 	cron_db	database;
+	char	*cs;
 
 	ProgramName = basename(argv[0]);
 
@@ -95,6 +97,20 @@ main(argc, argv)
 	setenv("PATH", _PATH_DEFPATH, 1);
 #endif
 
+	/* Get the default locale character set for the mail
+	* "Content-Type: ...; charset=" header
+	*/
+	setlocale(LC_ALL,""); /* set locale to system defaults or to
+				that specified by any  LC_* env vars */
+	setlocale(LC_COLLATE, "C"); /* Except for collation, since load_database() uses a-z */
+	/* Except that "US-ASCII" is preferred to "ANSI_x3.4-1968" in MIME,
+	* even though "ANSI_x3.4-1968" is the official charset name. */
+	if ((cs = nl_langinfo(CODESET)) != 0L &&
+			strcasecmp(cs, "ANSI_x3.4-1968") != 0)
+		strncpy(cron_default_mail_charset, cs, MAX_ENVSTR);
+	else
+		strcpy( cron_default_mail_charset, "US-ASCII");
+
 	/* if there are no debug flags turned on, fork as a daemon should.
 	 */
 # if DEBUGGING
diff --git a/cron.h b/cron.h
index 7cce1c5..2a12bd2 100644
--- a/cron.h
+++ b/cron.h
@@ -294,6 +294,8 @@ static long GMToff;
 
 int	lsbsysinit_mode;
 
+char	cron_default_mail_charset[MAX_ENVSTR] = "";
+
 # if DEBUGGING
 int	DebugFlags;
 char	*DebugFlagNames[] = {	/* sync with #defines */
@@ -312,6 +314,7 @@ extern	time_t	StartTime;
 extern  time_min timeRunning;
 extern  time_min virtualTime;
 extern  time_min clockTime;
+extern	char	cron_default_mail_charset[MAX_ENVSTR];
 # if DEBUGGING
 extern	int	DebugFlags;
 extern	char	*DebugFlagNames[];
diff --git a/crontab.5 b/crontab.5
index 0f72f28..c0863b3 100644
--- a/crontab.5
+++ b/crontab.5
@@ -121,6 +121,20 @@ override the settings described above nor any settings in the
 .I crontab
 file itself.  Note in particular that if you want a PATH other than
 "/usr/bin:/bin", you will need to set it in the crontab file.
+.PP
+By default, cron will send mail using the mail "Content-Type:" header of
+"text/plain" with the "charset=" parameter set to the charmap / codeset of the
+locale in which
+.IR crond (8)
+is started up \(en i.e.\& either the default system locale,
+if no LC_* environment variables are set, or the locale specified by
+the LC_* environment variables
+( see
+.IR locale (7) ).
+You can use different character encodings for mailed cron job output by
+setting the CONTENT_TYPE and CONTENT_TRANSFER_ENCODING variables in crontabs,
+to the correct values of the mail headers of those names.
+.PP
 The format of a cron command is very much the V7 standard, with a number of
 upward-compatible extensions.  Each line has five time and date fields,
 followed by a command, followed by a newline character ('\en').
diff --git a/do_command.c b/do_command.c
index 82c2cc6..f646722 100644
--- a/do_command.c
+++ b/do_command.c
@@ -470,8 +470,12 @@ child_process(e, u)
 
 			if (mailto) {
 				register char	**env;
+				char		**jobenv = build_env(e->envp);
 				auto char	mailcmd[MAX_COMMAND];
 				auto char	hostname[MAXHOSTNAMELEN];
+				char	*content_type = env_get("CONTENT_TYPE",jobenv),
+					*content_transfer_encoding = env_get("CONTENT_TRANSFER_ENCODING",jobenv);
+
 
 				(void) gethostname(hostname, MAXHOSTNAMELEN);
 				(void) snprintf(mailcmd, sizeof(mailcmd),
@@ -490,7 +494,40 @@ child_process(e, u)
 					arpadate(&StartTime));
 # endif /* MAIL_DATE */
 				fprintf(mail, "MIME-Version: 1.0\n");
-				fprintf(mail, "Content-Transfer-Encoding: 8bit\n");
+
+				if (content_type == 0L) {
+					fprintf(mail, "Content-Type: text/plain; charset=%s\n",
+						cron_default_mail_charset);
+				} else {
+					/* user specified Content-Type header.
+					 * disallow new-lines for security reasons
+					 * (else users could specify arbitrary mail headers!)
+					 */
+					char *nl=content_type;
+					size_t ctlen = strlen(content_type);
+
+					while ((*nl != '\0') &&
+							((nl=strchr(nl,'\n')) != 0L) &&
+							(nl < (content_type+ctlen))) {
+						*nl = ' ';
+					}
+				       fprintf(mail,"Content-Type: %s\n", content_type);
+				}
+
+				if (content_transfer_encoding != 0L) {
+					char *nl=content_transfer_encoding;
+					size_t ctlen = strlen(content_transfer_encoding);
+					while ((*nl != '\0') &&
+							((nl=strchr(nl,'\n')) != 0L) &&
+							(nl < (content_transfer_encoding+ctlen))) {
+						*nl = ' ';
+					}
+
+					fprintf(mail,"Content-Transfer-Encoding: %s\n",
+							content_transfer_encoding);
+				} else {
+					fprintf(mail,"Content-Transfer-Encoding: 8bit\n");
+				}
 
 				for (env = e->envp;  *env;  env++)
 					fprintf(mail, "X-Cron-Env: <%s>\n",
diff --git a/externs.h b/externs.h
index 5d10430..dab6da5 100644
--- a/externs.h
+++ b/externs.h
@@ -26,6 +26,11 @@
 # define WAIT_IS_INT 1
 extern char *tzname[2];
 # define TZONE(tm) tzname[(tm).tm_isdst]
+/* include locale stuff for mailer "Content-Type":
+ */
+#include <locale.h>
+#include <nl_types.h>
+#include <langinfo.h>
 #endif
 
 #if defined(UNIXPC)