--- a/innd/cc.c
+++ b/innd/cc.c
@@ -18,6 +18,7 @@
 #if	defined(DO_HAVE_UNIX_DOMAIN)
 #include <sys/un.h>
 #endif	/* defined(DO_HAVE_UNIX_DOMAIN) */
+#include <systemd/sd-daemon.h>
 
 
 /*
@@ -164,6 +165,64 @@ CCcurrmode()
     }
 }
 
+/*
+**  Notify systemd of the current operating modes.
+*/
+STATIC void
+CCsdnotify()
+{
+    char		*buff, *p;
+
+    /* bug: statically allocated buffer, but CCmode does this too */
+    p = buff = NEW(char, BUFSIZ);
+    p += strlen(strcpy(buff, "STATUS=Server "));
+
+    /* Server's mode. */
+    switch (Mode) {
+    default:
+	(void)sprintf(p, "Unknown %d", Mode);
+	p += strlen(p);
+	break;
+    case OMrunning:
+	p += strlen(strcpy(p, "running"));
+	break;
+    case OMpaused:
+	p += strlen(strcpy(p, "paused "));
+	p += strlen(strcpy(p, ModeReason));
+	break;
+    case OMthrottled:
+	p += strlen(strcpy(p, "throttled "));
+	p += strlen(strcpy(p, ModeReason));
+	break;
+    }
+
+    p += strlen(strcpy(p, ". "));
+    if (RejectReason) {
+	p += strlen(strcpy(p, "Rejecting "));
+	p += strlen(strcpy(p, RejectReason));
+    }
+    else
+	p += strlen(strcpy(p, "Allowing remote connections"));
+
+    /* Newsreaders. */
+    p += strlen(strcpy(p, ". "));
+    p += strlen(strcpy(p, "Readers "));
+    if (NNRPFollows)
+	p += strlen(strcpy(p, "follow "));
+    else
+	p += strlen(strcpy(p, "separate "));
+    if (NNRPReason == NULL)
+	p += strlen(strcpy(p, "enabled"));
+    else {
+	(void)sprintf(p, "disabled %s", NNRPReason);
+	p += strlen(p);
+    }
+    *p++ = '.';
+    *p++ = '\0';
+
+    sd_notify(0, buff);
+    DISPOSE(buff);
+}
 
 /*
 **  Add <> around Message-ID if needed.
@@ -279,6 +338,7 @@ CCallow(av)
 	return "1 Wrong reason";
     DISPOSE(RejectReason);
     RejectReason = NULL;
+    CCsdnotify();
     return NULL;
 }
 
@@ -697,6 +757,7 @@ CCgo(av)
 	ErrorCount = IO_ERROR_COUNT;
     HISsetup();
     syslog(L_NOTICE, "%s running", LogName);
+    CCsdnotify();
     if (ICDneedsetup)
 	ICDsetup(TRUE);
     SCHANwakeup((POINTER)&Mode);
@@ -1094,6 +1155,7 @@ CCparam(av)
     case 'n':
 	if (!CCparsebool('n', &NNRPFollows, *p))
 	    return BADVAL;
+	CCsdnotify();
 	break;
     case 'o':
 	MaxOutgoing = atoi(p);
@@ -1165,6 +1227,7 @@ CCblock(NewMode, reason)
     }
     syslog(L_NOTICE, "%s %s %s",
 	LogName, NewMode == OMpaused ? "paused" : "throttled", reason);
+    CCsdnotify();
     return NULL;
 }
 
@@ -1220,6 +1283,7 @@ CCreaders(av)
 	NNRPReason = COPY(p);
 	break;
     }
+    CCsdnotify();
     return NULL;
 }
 
@@ -1877,6 +1941,8 @@ CCsetup()
 #if     defined(SIGUSR1)
     (void)signal(SIGUSR1, CCresetup);
 #endif  /* defined(SIGUSR1) */
+
+    CCsdnotify();
 }
 
 
--- a/innd/innd.c
+++ b/innd/innd.c
@@ -17,6 +17,7 @@
 #include <arpa/nameser.h>
 #include <resolv.h>
 #endif	/* defined(DO_FAST_RESOLV) */
+#include <systemd/sd-daemon.h>
 
 
 #if	defined(DO_HAVE_SETBUFFER)
@@ -746,6 +747,22 @@ main(ac, av)
 
     openlog(path, logflags, LOG_INN_SERVER);
 
+    i = sd_listen_fds(1);
+    if (i < 0) {
+	syslog(L_FATAL, "%s sd_listen_fds(): %m", LogName);
+	exit(1);
+    } else if (i > 1) {
+	syslog(L_FATAL, "%s cant listen on multiple sockets", LogName);
+	exit(1);
+    } else if (i == 1) {
+	port = SD_LISTEN_FDS_START;
+	AmRoot = FALSE;
+	if (sd_is_socket(port, AF_INET, SOCK_STREAM, 1) < 0) {
+	    syslog(L_FATAL, "%s cant listen on non-AF_INET sockets", LogName);
+	    exit(1);
+	}
+    }
+
     if (ShouldSyntaxCheck) {
 	if ((p = (char *) CCcheckfile((char **)NULL)) == NULL)
 	    exit(0);
@@ -950,6 +967,7 @@ main(ac, av)
 	}
     }
     syslog(L_NOTICE, "%s starting", LogName);
+    sd_notify(0, "READY=1");
     CHANreadloop();
     CleanupAndExit(1, "CHANreadloop returned");
     /* NOTREACHED */
--- a/samples/rc.news
+++ b/samples/rc.news
@@ -64,22 +64,31 @@ fi
 rm -f ${NEWSCONTROL} ${NNTPCONNECT} ${SERVERPID}
 
 ##  Start the show.
+##  When using system, the daemon must be started last with exec
+if [ -z "$NOTIFY_SOCKET" -o -z "$LISTEN_PID" ] ; then
 echo -n 'Starting news server:'
 eval ${WHAT} ${RFLAG} ${FLAGS}
 echo -n ' innd'
+fi
 
 ${DOACTIVED} && {
+    if [ -z "$NOTIFY_SOCKET" -o -z "$LISTEN_PID" ] ; then
     echo -n ' actived'
+    fi
     ${NEWSBIN}/actived > $ERRLOG 2>&1
 }
 
 # Gee, looks like lisp, doesn't it?
 ${DOINNWATCH} && {
+    if [ -z "$NOTIFY_SOCKET" -o -z "$LISTEN_PID" ] ; then
     echo -n ' innwatch'
+    fi
     ( sleep 60 ; exec ${INNWATCH} > $ERRLOG 2>&1 ) &
 }
 
+if [ -z "$NOTIFY_SOCKET" -o -z "$LISTEN_PID" ] ; then
 echo '.'
+fi
 
 RMFILE=${MOST_LOGS}/expire.rm
 for F in ${RMFILE} ${RMFILE}.*; do
@@ -93,3 +102,8 @@ for F in ${RMFILE} ${RMFILE}.*; do
 	${NEWSBIN}/expirerm ${F}
     fi
 done &
+
+if [ "$NOTIFY_SOCKET" -a "$LISTEN_PID" ] ; then
+    eval exec ${INND} -f ${RFLAG} ${FLAGS}
+fi
+
--- a/innd/Makefile
+++ b/innd/Makefile
@@ -49,6 +49,9 @@ IDENT_LIB	= -lident
 
 CFLAGS+= -DTIMER
 
+DEFS+=$(shell pkg-config --cflags libsystemd)
+IDENT_LIB+=$(shell pkg-config --libs libsystemd)
+
 SOURCES	= \
 	art.c cc.c chan.c his.c icd.c innd.c lc.c nc.c newsfeeds.c ng.c \
 	proc.c rc.c site.c tcl.c perl.c timer.c
