Added configuration option: E-mail address.
[squirrelmail.git] / functions / smtp.php
CommitLineData
b8ea4ed6 1<?
2 /** smtp.php
3 **
4 ** This contains all the functions needed to send messages through
36fa79c8 5 ** an smtp server or sendmail.
b8ea4ed6 6 **/
7
465db5d7 8
df15de21 9 // Returns true only if this message is multipart
10 function isMultipart () {
4ba45d11 11 global $attachments;
12
13 if (count($attachments)>0)
14 return true;
15 else
16 return false;
df15de21 17 }
18
19 // Attach the files that are due to be attached
4ba45d11 20 function attachFiles ($fp) {
c3c37167 21 global $attachments, $attachment_dir;
4ba45d11 22
23 while (list($localname, $remotename) = each($attachments)) {
05c8cad9 24 // This is to make sure noone is giving a filename in another
25 // directory
26 $localname = ereg_replace ("\\/", "", $localname);
27
c3c37167 28 $fileinfo = fopen ($attachment_dir.$localname.".info", "r");
4ba45d11 29 $filetype = fgets ($fileinfo, 8192);
30 fclose ($fileinfo);
31 $filetype = trim ($filetype);
32 if ($filetype=="")
33 $filetype = "application/octet-stream";
34
35 fputs ($fp, "--".mimeBoundary()."\n");
36 fputs ($fp, "Content-Type: $filetype\n");
37 fputs ($fp, "Content-Disposition: attachment; filename=\"$remotename\"\n");
38 fputs ($fp, "Content-Transfer-Encoding: base64\n\n");
39
c3c37167 40 $file = fopen ($attachment_dir.$localname, "r");
4ba45d11 41 while ($tmp = fread($file, 57))
42 fputs ($fp, chunk_split(base64_encode($tmp)));
43 fclose ($file);
44
c3c37167 45 unlink ($attachment_dir.$localname);
46 unlink ($attachment_dir.$localname.".info");
4ba45d11 47 }
df15de21 48 }
49
50 // Return a nice MIME-boundary
51 function mimeBoundary () {
52 global $mimeBoundaryString, $version, $REMOTE_ADDR, $SERVER_NAME,
53 $REMOTE_PORT;
54
55 if ($mimeBoundaryString == "") {
56 $temp = "SquirrelMail".$version.$REMOTE_ADDR.$SERVER_NAME.
57 $REMOTE_PORT;
4ba45d11 58 $mimeBoundaryString = "=-_+".substr(md5($temp),1,20);
465db5d7 59 }
df15de21 60
61 return $mimeBoundaryString;
465db5d7 62 }
63
24397423 64 /* Time offset for correct timezone */
65 function timezone () {
66 $diff_second = date("Z");
67 if ($diff_second > 0)
68 $sign = "+";
69 else
70 $sign = "-";
71
72 $diff_second = abs($diff_second);
73
74 $diff_hour = floor ($diff_second / 3600);
75 $diff_minute = floor (($diff_second-3600*$diff_hour) / 60);
76
77 $zonename = "(".strftime("%Z").")";
78 $result = sprintf ("%s%02d%02d %s", $sign, $diff_hour, $diff_minute, $zonename);
79 return ($result);
80 }
81
df15de21 82 /* Print all the needed RFC822 headers */
c99c5b31 83 function write822Header ($fp, $t, $c, $b, $subject) {
84 global $REMOTE_ADDR, $SERVER_NAME;
df15de21 85 global $data_dir, $username, $domain, $version, $useSendmail;
465db5d7 86
465db5d7 87 $to = parseAddrs($t);
88 $cc = parseAddrs($c);
89 $bcc = parseAddrs($b);
90 $from_addr = "$username@$domain";
91 $reply_to = getPref($data_dir, $username, "reply_to");
92 $from = getPref($data_dir, $username, "full_name");
93
94 $to_list = getLineOfAddrs($to);
95 $cc_list = getLineOfAddrs($cc);
96 $bcc_list = getLineOfAddrs($bcc);
97
98 if ($from == "")
99 $from = "<$from_addr>";
100 else
101 $from = $from . " <$from_addr>";
102
df15de21 103 /* This creates an RFC 822 date showing GMT */
24397423 104 $date = date("D, j M Y H:i:s ", mktime()) . timezone();
c99c5b31 105
df15de21 106 /* Make an RFC822 Received: line */
c99c5b31 107 fputs ($fp, "Received: from $REMOTE_ADDR by $SERVER_NAME with HTTP; ");
108 fputs ($fp, "$date\n");
109
df15de21 110 /* The rest of the header */
c99c5b31 111 fputs ($fp, "Date: $date\n");
112 fputs ($fp, "Subject: $subject\n"); // Subject
113 fputs ($fp, "From: $from\n"); // Subject
114 fputs ($fp, "To: $to_list\n"); // Who it's TO
465db5d7 115
116 if ($cc_list) {
117 fputs($fp, "Cc: $cc_list\n"); // Who the CCs are
118 }
df15de21 119
120 if ($reply_to != "")
121 fputs($fp, "Reply-To: $reply_to\n");
122
123 if ($useSendmail) {
124 if ($bcc_list) {
125 // BCCs is removed from header by sendmail
126 fputs($fp, "Bcc: $bcc_list\n");
127 }
465db5d7 128 }
df15de21 129
465db5d7 130 fputs($fp, "X-Mailer: SquirrelMail (version $version)\n"); // Identify SquirrelMail
df15de21 131
132 // Do the MIME-stuff
465db5d7 133 fputs($fp, "MIME-Version: 1.0\n");
df15de21 134
135 if (isMultipart()) {
136 fputs ($fp, "Content-Type: multipart/mixed; boundary=\"");
137 fputs ($fp, mimeBoundary());
138 fputs ($fp, "\"\n");
139 } else {
140 fputs($fp, "Content-Type: text/plain; charset=ISO-8859-1\n");
141 fputs($fp, "Content-Transfer-Encoding: 8bit\n");
142 }
143 }
144
145 // Send the body
146 function writeBody ($fp, $body) {
147 if (isMultipart()) {
148 fputs ($fp, "--".mimeBoundary()."\n");
149 fputs ($fp, "Content-Type: text/plain; charset=ISO-8859-1\n");
150 fputs ($fp, "Content-Transfer-Encoding: 8bit\n\n");
b75c48df 151 fputs ($fp, stripslashes($body) . "\n");
4ba45d11 152 attachFiles($fp);
df15de21 153 fputs ($fp, "\n--".mimeBoundary()."--\n");
154 } else {
b75c48df 155 fputs ($fp, stripslashes($body) . "\n");
df15de21 156 }
c99c5b31 157 }
465db5d7 158
c99c5b31 159 // Send mail using the sendmail command
160 function sendSendmail($t, $c, $b, $subject, $body) {
161 global $sendmail_path, $username, $domain;
162
163 // open pipe to sendmail
33244b71 164 $fp = popen (escapeshellcmd("$sendmail_path -odb -oi -t -f$username@$domain"), "w");
c99c5b31 165
166 write822Header ($fp, $t, $c, $b, $subject);
df15de21 167 writeBody($fp, $body);
465db5d7 168
169 pclose($fp);
170 }
171
b8ea4ed6 172 function smtpReadData($smtpConnection) {
173 $read = fgets($smtpConnection, 1024);
174 $counter = 0;
175 while ($read) {
176 echo $read . "<BR>";
177 $data[$counter] = $read;
178 $read = fgets($smtpConnection, 1024);
179 $counter++;
180 }
181 }
182
c99c5b31 183 function sendSMTP($t, $c, $b, $subject, $body) {
184 global $username, $domain, $version, $smtpServerAddress, $smtpPort;
7831268e 185
40ee9452 186 $to = parseAddrs($t);
187 $cc = parseAddrs($c);
188 $bcc = parseAddrs($b);
d3cdb279 189 $from_addr = "$username@$domain";
d3cdb279 190
c175e2e4 191 $smtpConnection = fsockopen($smtpServerAddress, $smtpPort, $errorNumber, $errorString);
b8ea4ed6 192 if (!$smtpConnection) {
193 echo "Error connecting to SMTP Server.<br>";
194 echo "$errorNumber : $errorString<br>";
195 exit;
196 }
d3cdb279 197 $tmp = nl2br(htmlspecialchars(fgets($smtpConnection, 1024)));
3021b626 198 errorCheck($tmp);
b8ea4ed6 199
40ee9452 200 $to_list = getLineOfAddrs($to);
201 $cc_list = getLineOfAddrs($cc);
202
203 /** Lets introduce ourselves */
204 fputs($smtpConnection, "HELO $domain\n");
d3cdb279 205 $tmp = nl2br(htmlspecialchars(fgets($smtpConnection, 1024)));
3021b626 206 errorCheck($tmp);
7831268e 207
40ee9452 208 /** Ok, who is sending the message? */
33daaa7d 209 fputs($smtpConnection, "MAIL FROM:<$from_addr>\n");
d3cdb279 210 $tmp = nl2br(htmlspecialchars(fgets($smtpConnection, 1024)));
3021b626 211 errorCheck($tmp);
b8ea4ed6 212
40ee9452 213 /** send who the recipients are */
214 for ($i = 0; $i < count($to); $i++) {
215 fputs($smtpConnection, "RCPT TO:<$to[$i]>\n");
d3cdb279 216 $tmp = nl2br(htmlspecialchars(fgets($smtpConnection, 1024)));
3021b626 217 errorCheck($tmp);
40ee9452 218 }
219 for ($i = 0; $i < count($cc); $i++) {
220 fputs($smtpConnection, "RCPT TO:<$cc[$i]>\n");
d3cdb279 221 $tmp = nl2br(htmlspecialchars(fgets($smtpConnection, 1024)));
3021b626 222 errorCheck($tmp);
40ee9452 223 }
224 for ($i = 0; $i < count($bcc); $i++) {
225 fputs($smtpConnection, "RCPT TO:<$bcc[$i]>\n");
d3cdb279 226 $tmp = nl2br(htmlspecialchars(fgets($smtpConnection, 1024)));
3021b626 227 errorCheck($tmp);
40ee9452 228 }
b8ea4ed6 229
40ee9452 230 /** Lets start sending the actual message */
b8ea4ed6 231 fputs($smtpConnection, "DATA\n");
d3cdb279 232 $tmp = nl2br(htmlspecialchars(fgets($smtpConnection, 1024)));
3021b626 233 errorCheck($tmp);
7831268e 234
c99c5b31 235 write822Header ($smtpConnection, $t, $c, $b, $subject);
40ee9452 236
df15de21 237 writeBody($smtpConnection, $body); // send the body of the message
7831268e 238
40ee9452 239 fputs($smtpConnection, ".\n"); // end the DATA part
d3cdb279 240 $tmp = nl2br(htmlspecialchars(fgets($smtpConnection, 1024)));
3021b626 241 $num = errorCheck($tmp);
242 if ($num != 250) {
243 echo "<HTML><BODY BGCOLOR=FFFFFF>ERROR<BR>Message not sent!<BR>Reason given: $tmp<BR></BODY></HTML>";
244 }
d3cdb279 245
40ee9452 246 fputs($smtpConnection, "QUIT\n"); // log off
78509c54 247
248 fclose($smtpConnection);
b8ea4ed6 249 }
3021b626 250
251
252 function errorCheck($line) {
253 // Status: 0 = fatal
254 // 5 = ok
255
256 $err_num = substr($line, 0, strpos($line, " "));
257 switch ($err_num) {
258 case 500: $message = "Syntax error; command not recognized";
259 $status = 0;
260 break;
261 case 501: $message = "Syntax error in parameters or arguments";
262 $status = 0;
263 break;
264 case 502: $message = "Command not implemented";
265 $status = 0;
266 break;
267 case 503: $message = "Bad sequence of commands";
268 $status = 0;
269 break;
270 case 504: $message = "Command parameter not implemented";
271 $status = 0;
272 break;
273
274
275 case 211: $message = "System status, or system help reply";
276 $status = 5;
277 break;
278 case 214: $message = "Help message";
279 $status = 5;
280 break;
281
282
283 case 220: $message = "Service ready";
284 $status = 5;
285 break;
286 case 221: $message = "Service closing transmission channel";
287 $status = 5;
288 break;
289 case 421: $message = "Service not available, closing chanel";
290 $status = 0;
291 break;
292
293
294 case 250: $message = "Requested mail action okay, completed";
295 $status = 5;
296 break;
297 case 251: $message = "User not local; will forward";
298 $status = 5;
299 break;
300 case 450: $message = "Requested mail action not taken: mailbox unavailable";
301 $status = 0;
302 break;
303 case 550: $message = "Requested action not taken: mailbox unavailable";
304 $status = 0;
305 break;
306 case 451: $message = "Requested action aborted: error in processing";
307 $status = 0;
308 break;
309 case 551: $message = "User not local; please try forwarding";
310 $status = 0;
311 break;
312 case 452: $message = "Requested action not taken: insufficient system storage";
313 $status = 0;
314 break;
315 case 552: $message = "Requested mail action aborted: exceeding storage allocation";
316 $status = 0;
317 break;
318 case 553: $message = "Requested action not taken: mailbox name not allowed";
319 $status = 0;
320 break;
321 case 354: $message = "Start mail input; end with .";
322 $status = 5;
323 break;
324 case 554: $message = "Transaction failed";
325 $status = 0;
326 break;
327 default: $message = "Unknown response: $line";
328 $status = 0;
329 $error_num = "001";
330 break;
331 }
332
333 if ($status == 0) {
334 echo "<HTML><BODY BGCOLOR=FFFFFF>";
335 echo "<TT>";
336 echo "<BR><B>ERROR</B><BR><BR>";
337 echo "&nbsp;&nbsp;&nbsp;<B>Error Number: </B>$err_num<BR>";
338 echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>Reason: </B>$message<BR>";
339 echo "<B>Server Response: </B>$line<BR>";
340 echo "<BR>MAIL NOT SENT";
341 echo "</TT></BODY></HTML>";
342 exit;
343 }
344 return $err_num;
345 }
df15de21 346
347 function sendMessage($t, $c, $b, $subject, $body) {
348 global $useSendmail;
349
350 if ($useSendmail==true) {
351 sendSendmail($t, $c, $b, $subject, $body);
352 } else {
353 sendSMTP($t, $c, $b, $subject, $body);
354 }
355
356 }
357
465db5d7 358?>