Skip to content

Instantly share code, notes, and snippets.

@drscream
Last active August 29, 2015 14:17
Show Gist options
  • Save drscream/76e0552cf0d0e7ec292b to your computer and use it in GitHub Desktop.
Save drscream/76e0552cf0d0e7ec292b to your computer and use it in GitHub Desktop.
#! /bin/sh -e
if [ $# -ne 1 ]; then
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
fi
case "$1" in
-patch) patch -f --no-backup-if-mismatch -p1 < $0;;
-unpatch) patch -f --no-backup-if-mismatch -R -p1 < $0;;
*)
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1;;
esac
exit 0
@DPATCH@
Index: nullmailer-1.10/configure.in
===================================================================
--- nullmailer-1.10.orig/configure.in 2012-04-23 04:34:26.000000000 +0100
+++ nullmailer-1.10/configure.in 2012-05-12 17:59:14.000000000 +0100
@@ -48,6 +48,25 @@
dnl AC_CHECK_FUNCS(gettimeofday mkdir putenv rmdir socket)
AC_CHECK_FUNCS(setenv srandom)
+AC_MSG_CHECKING(for getaddrinfo)
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stddef.h>], [getaddrinfo(NULL, NULL, NULL, NULL)], has_getaddrinfo=yes, has_getaddrinfo=no)
+if test "$has_getaddrinfo" = yes; then
+ AC_MSG_RESULT(yes)
+else
+ AC_MSG_RESULT(no)
+fi
+
+if test x-$has_getaddrinfo = "x-no" ; then
+ AC_MSG_RESULT(disabled: getaddrinfo missing)
+else
+ AC_DEFINE(HAVE_GETADDRINFO,,[getaddrinfo code enabled])
+fi
+
+AC_SUBST(HAVE_GETADDRINFO)
+
AC_DEFINE(BUFSIZE, 4096, [Generic buffer size])
AM_CONDITIONAL(FDBUF_NO_MYSTRING, false)
Index: nullmailer-1.10/lib/tcpconnect.cc
===================================================================
--- nullmailer-1.10.orig/lib/tcpconnect.cc 2012-03-01 02:44:06.000000000 +0000
+++ nullmailer-1.10/lib/tcpconnect.cc 2012-05-12 17:59:14.000000000 +0100
@@ -28,7 +28,11 @@
#include <netinet/in.h>
#include "errcodes.h"
#include "connect.h"
+#ifdef HAVE_GETADDRINFO
+#include "lib/itoa.h"
+#endif
+#ifndef HAVE_GETADDRINFO
static int sethostbyname(const mystring& hostname, struct sockaddr_in& sa)
{
struct hostent *he = gethostbyname(hostname.c_str());
@@ -44,13 +48,48 @@
memcpy(&sa.sin_addr, he->h_addr, he->h_length);
return 0;
}
+#endif
int tcpconnect(const mystring& hostname, int port)
{
+#ifdef HAVE_GETADDRINFO
+ struct addrinfo req, *res, *orig_res;
+ const char *service = itoa(port, 6);
+
+ memset(&req, 0, sizeof(req));
+ req.ai_flags = AI_NUMERICSERV;
+ req.ai_socktype = SOCK_STREAM;
+ int e = getaddrinfo(hostname.c_str(), service, &req, &res);
+#else
struct sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
int e = sethostbyname(hostname, sa);
+#endif
if(e) return e;
+#ifdef HAVE_GETADDRINFO
+ int s = -1;
+ orig_res = res;
+
+ for (; res; res = res->ai_next ) {
+ s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+
+ if(s < 0)
+ continue;
+
+ if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
+ s = -1;
+ continue;
+ }
+
+ /* sucessful connection */
+ break;
+ }
+
+ freeaddrinfo(orig_res);
+
+ if(s < 0)
+ return -ERR_CONN_FAILED;
+#else
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
int s = socket(PF_INET, SOCK_STREAM, 0);
@@ -64,5 +103,6 @@
default: return -ERR_CONN_FAILED;
}
}
+#endif
return s;
}
Description: nullmailer didn't send QUIT after a successful transfer.
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=375380
Author: Nick Leverton <[email protected]>
Index: nullmailer-1.10/protocols/smtp.cc
===================================================================
--- nullmailer-1.10.orig/protocols/smtp.cc 2012-04-20 00:10:16.000000000 +0100
+++ nullmailer-1.10/protocols/smtp.cc 2012-05-12 18:03:58.000000000 +0100
@@ -53,6 +53,7 @@
void auth_plain(void);
void send_data(fdibuf& msg);
void send_envelope(fdibuf& msg);
+ void send_quit();
void send(fdibuf& msg);
};
@@ -202,10 +203,16 @@
protocol_succ(tmp.c_str());
}
+void smtp::send_quit()
+{
+ docmd("QUIT", 200);
+}
+
void smtp::send(fdibuf& msg)
{
send_envelope(msg);
send_data(msg);
+ send_quit();
}
void protocol_prep(fdibuf&)
#! /bin/sh -e
if [ $# -ne 1 ]; then
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1
fi
case "$1" in
-patch) patch -f --no-backup-if-mismatch -p1 < $0;;
-unpatch) patch -f --no-backup-if-mismatch -R -p1 < $0;;
*)
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
exit 1;;
esac
exit 0
@DPATCH@
Index: nullmailer-1.10/doc/nullmailer-send.8
===================================================================
--- nullmailer-1.10.orig/doc/nullmailer-send.8 2012-05-12 17:59:14.000000000 +0100
+++ nullmailer-1.10/doc/nullmailer-send.8 2012-05-12 17:59:39.000000000 +0100
@@ -3,6 +3,7 @@
nullmailer-send \- Send queued messages
.SH SYNOPSIS
.B nullmailer-send
+.RB [ \-\-daemon ]\ [ \-\-syslog ]
.SH DESCRIPTION
This program is responsible for coordinating the transmission of
messages that have been queued by
@@ -37,6 +38,15 @@
sleeps for a number of seconds specified by
.B pausetime
before retrying sending the contents of the queue.
+.SH OPTIONS
+.TP
+.BR \-d ,\ \-\-daemon
+Fork into the background, implies \-\-syslog.
+.TP
+.BR \-s ,\ \-\-syslog
+Use syslog for error and log messages.
+With \-\-daemon, syslog will be used exclusively, without \-\-daemon,
+syslog will be used additionally.
.SH CONTROL FILES
All the control files are reread each time the queue is run.
.TP
Index: nullmailer-1.10/protocols/protocol.cc
===================================================================
--- nullmailer-1.10.orig/protocols/protocol.cc 2012-04-20 00:10:16.000000000 +0100
+++ nullmailer-1.10/protocols/protocol.cc 2012-05-12 18:00:51.000000000 +0100
@@ -22,11 +22,15 @@
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
+#include <sys/syslog.h>
#include "connect.h"
#include "errcodes.h"
#include "protocol.h"
#include "cli++.h"
+static int use_syslog = 0;
+static int daemonize = 0;
+
const char* user = 0;
const char* pass = 0;
int port = 0;
@@ -44,6 +48,8 @@
"Set the user name for authentication", 0 },
{ 0, "pass", cli_option::string, 0, &pass,
"Set the password for authentication", 0 },
+ { 'd', "daemon", cli_option::flag, 1, &daemonize, "use syslog exclusively ", 0 },
+ { 's', "syslog", cli_option::flag, 1, &use_syslog, "use syslog additionally", 0 },
{ 0, "auth-login", cli_option::flag, AUTH_LOGIN, &auth_method,
"Use AUTH LOGIN instead of auto-detecting in SMTP", 0 },
#ifdef HAVE_TLS
@@ -65,13 +71,19 @@
void protocol_fail(int e, const char* msg)
{
- ferr << cli_program << ": Failed: " << msg << endl;
+ if (use_syslog)
+ syslog(LOG_ERR, "%s: Failed: %s", cli_program, msg);
+ if (!daemonize)
+ ferr << cli_program << ": Failed: " << msg << endl;
exit(e);
}
void protocol_succ(const char* msg)
{
- ferr << cli_program << ": Succeeded: " << msg << endl;
+ if (use_syslog)
+ syslog(LOG_INFO, "%s: Succeeded: %s", cli_program, msg);
+ if (!daemonize)
+ ferr << cli_program << ": Succeeded: " << msg << endl;
exit(0);
}
@@ -91,6 +103,10 @@
int cli_main(int, char* argv[])
{
+ if (daemonize)
+ use_syslog = 1;
+ if (use_syslog)
+ openlog("nullmailer", LOG_CONS | LOG_PID, LOG_MAIL);
const char* remote = argv[0];
if (port == 0)
port = use_ssl ? default_ssl_port : default_port;
Index: nullmailer-1.10/src/Makefile.in
===================================================================
--- nullmailer-1.10.orig/src/Makefile.in 2012-04-23 18:00:46.000000000 +0100
+++ nullmailer-1.10/src/Makefile.in 2012-05-12 18:01:48.000000000 +0100
@@ -61,7 +61,7 @@
nullmailer_queue_DEPENDENCIES = ../lib/libnullmailer.a
am_nullmailer_send_OBJECTS = send.$(OBJEXT)
nullmailer_send_OBJECTS = $(am_nullmailer_send_OBJECTS)
-nullmailer_send_DEPENDENCIES = ../lib/libnullmailer.a
+nullmailer_send_DEPENDENCIES = ../lib/cli++/libcli++.a ../lib/libnullmailer.a
am_nullmailer_smtpd_OBJECTS = smtpd.$(OBJEXT)
nullmailer_smtpd_OBJECTS = $(am_nullmailer_smtpd_OBJECTS)
nullmailer_smtpd_DEPENDENCIES = ../lib/libnullmailer.a
@@ -182,13 +182,13 @@
#noinst_PROGRAMS = address
INCLUDES = -I../lib -I../lib/cli++
mailq_SOURCES = mailq.cc
-mailq_LDADD = ../lib/libnullmailer.a
+mailq_LDADD = ../lib/cli++/libcli++.a ../lib/libnullmailer.a
nullmailer_inject_SOURCES = inject.cc
nullmailer_inject_LDADD = ../lib/cli++/libcli++.a ../lib/libnullmailer.a
nullmailer_queue_SOURCES = queue.cc
nullmailer_queue_LDADD = ../lib/libnullmailer.a
nullmailer_send_SOURCES = send.cc
-nullmailer_send_LDADD = ../lib/libnullmailer.a
+nullmailer_send_LDADD = ../lib/cli++/libcli++.a ../lib/libnullmailer.a
nullmailer_smtpd_SOURCES = smtpd.cc
nullmailer_smtpd_LDADD = ../lib/libnullmailer.a
sendmail_SOURCES = sendmail.cc
Index: nullmailer-1.10/src/send.cc
===================================================================
--- nullmailer-1.10.orig/src/send.cc 2012-03-01 02:44:06.000000000 +0000
+++ nullmailer-1.10/src/send.cc 2012-05-12 17:59:39.000000000 +0100
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#include <sys/syslog.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
@@ -40,14 +41,30 @@
#include "list.h"
#include "selfpipe.h"
#include "setenv.h"
+#include "cli++/cli++.h"
selfpipe selfpipe;
typedef list<mystring> slist;
-#define fail(MSG) do { fout << MSG << endl; return false; } while(0)
-#define fail2(MSG1,MSG2) do{ fout << MSG1 << MSG2 << endl; return false; }while(0)
-#define fail_sys(MSG) do{ fout << MSG << strerror(errno) << endl; return false; }while(0)
+static int use_syslog = 0;
+static int daemonize = 0;
+
+const char* cli_program = "nullmailer-send";
+const char* cli_help_prefix = "nullmailer daemon\n";
+const char* cli_help_suffix = "";
+const char* cli_args_usage = "";
+const int cli_args_min = 0;
+const int cli_args_max = 0;
+cli_option cli_options[] = {
+ { 'd', "daemon", cli_option::flag, 1, &daemonize, "daemonize , implies --syslog", 0 },
+ { 's', "syslog", cli_option::flag, 1, &use_syslog, "use syslog", 0 },
+ { 0, 0, cli_option::flag, 0, 0, 0, 0 }
+};
+
+#define fail(MSG) do { if (use_syslog) syslog(LOG_ERR, "%s", MSG); if (!daemonize) ferr << MSG << endl; return false; } while (0)
+#define fail2(MSG1,MSG2) do { if (use_syslog) syslog(LOG_ERR, "%s %s", MSG1, MSG2); if (!daemonize) fout << MSG1 << MSG2 << endl; return false; } while (0)
+#define fail_sys(MSG) do { if (use_syslog) syslog(LOG_ERR, "%s %s", MSG, strerror(errno)); if (!daemonize) ferr << MSG << strerror(errno) << endl; return false; } while (0)
struct remote
{
@@ -154,7 +171,10 @@
bool load_files()
{
reload_files = false;
- fout << "Rescanning queue." << endl;
+ if (use_syslog)
+ syslog(LOG_INFO, "Rescanning queue.");
+ if (!daemonize)
+ fout << "Rescanning queue." << endl;
DIR* dir = opendir(".");
if(!dir)
fail_sys("Cannot open queue directory: ");
@@ -172,12 +192,19 @@
void exec_protocol(int fd, remote& remote)
{
- if(close(0) == -1 || dup2(fd, 0) == -1 || close(fd) == -1)
+ if (!daemonize && close(STDIN_FILENO) < 0)
return;
+ if (fd != STDIN_FILENO)
+ if (dup2(fd, STDIN_FILENO) < 0 || close(fd) < 0)
+ return;
mystring program = PROTOCOL_DIR + remote.proto;
- const char* args[3+remote.options.count()];
+ const char* args[5+remote.options.count()];
unsigned i = 0;
args[i++] = program.c_str();
+ if (daemonize)
+ args[i++] = "-d";
+ if (use_syslog)
+ args[i++] = "-s";
for(slist::const_iter opt(remote.options); opt; opt++)
args[i++] = strdup((*opt).c_str());
args[i++] = remote.host.c_str();
@@ -214,7 +241,10 @@
if(status)
fail2("Sending failed: ", errorstr(status));
else {
- fout << "Sent file." << endl;
+ if (use_syslog)
+ syslog(LOG_INFO, "Sent file.");
+ if (!daemonize)
+ fout << "Sent file." << endl;
return true;
}
}
@@ -227,10 +257,20 @@
{
int fd = open(filename.c_str(), O_RDONLY);
if(fd == -1) {
- fout << "Can't open file '" << filename << "'" << endl;
+ if (use_syslog)
+ syslog(LOG_ERR, "Can't open file '%s'", filename.c_str());
+ if (!daemonize)
+ fout << "Can't open file '" << filename << "'" << endl;
return false;
}
- fout << "Starting delivery: protocol: " << remote.proto
+ if (use_syslog)
+ syslog(LOG_INFO, "Starting delivery: protocol: %s host: %s file: %s",
+ remote.proto.c_str(), remote.host.c_str(), filename.c_str());
+ if (!daemonize)
+ if (use_syslog)
+ syslog(LOG_INFO, "Starting delivery, %d message(s) in queue.", files.count());
+ if (!daemonize)
+ fout << "Starting delivery: protocol: " << remote.proto
<< " host: " << remote.host
<< " file: " << filename << endl;
pid_t pid = fork();
@@ -269,7 +309,10 @@
file++;
}
}
- fout << "Delivery complete, "
+ if (use_syslog)
+ syslog(LOG_INFO, "Delivery complete, %d message(s) remain.", files.count());
+ if (!daemonize)
+ fout << "Delivery complete, "
<< itoa(files.count()) << " message(s) remain." << endl;
return true;
}
@@ -314,7 +357,10 @@
int s = select(trigger+1, &readfds, 0, 0,
(files.count() == 0) ? 0 : &timeout);
if(s == 1) {
- fout << "Trigger pulled." << endl;
+ if (use_syslog)
+ syslog(LOG_INFO, "Trigger pulled.");
+ if (!daemonize)
+ fout << "Trigger pulled." << endl;
read_trigger();
reload_files = true;
}
@@ -327,8 +373,14 @@
return true;
}
-int main(int, char*[])
+int cli_main(int, char*[])
{
+ pid_t pid;
+
+ if (daemonize)
+ use_syslog = 1;
+ if (use_syslog)
+ openlog("nullmailer", LOG_CONS | LOG_PID, LOG_MAIL);
read_hostnames();
if(!selfpipe) {
@@ -337,13 +389,34 @@
}
selfpipe.catchsig(SIGCHLD);
- if(!open_trigger())
+ if(!open_trigger()) {
+ if (use_syslog)
+ syslog(LOG_CRIT, "Could not open trigger.");
+ if (!daemonize)
+ ferr << "Could not open trigger." << endl;
return 1;
+ }
if(chdir(QUEUE_MSG_DIR) == -1) {
fout << "Could not chdir to queue message directory." << endl;
+ if (use_syslog)
+ syslog(LOG_CRIT, "Could not chdir to queue message directory.");
+ if (!daemonize)
+ ferr << "Could not chdir to queue message directory." << endl;
return 1;
}
-
+
+ if (daemonize) {
+ if ((pid = fork()) < 0) {
+ syslog(LOG_CRIT, "Could not fork.");
+ return 1;
+ }
+ if (pid)
+ return 0;
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+ }
+
signal(SIGALRM, catch_alrm);
signal(SIGHUP, SIG_IGN);
load_config();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment