~ubuntu-branches/ubuntu/wily/clamav/wily

« back to all changes in this revision

Viewing changes to debian/patches/0008-Add-upstream-systemd-support-for-clamav-daemon-and-c.patch

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman, Sebastian Andrzej Siewior, Andreas Cadhalpun, Scott Kitterman, Javier Fernández-Sanguino
  • Date: 2015-01-28 00:25:13 UTC
  • mfrom: (0.48.14 sid)
  • Revision ID: package-import@ubuntu.com-20150128002513-lil2oi74cooy4lzr
Tags: 0.98.6+dfsg-1
[ Sebastian Andrzej Siewior ]
* update "fix-ssize_t-size_t-off_t-printf-modifier", include of misc.h was
  missing but was pulled in via the systemd patch.
* Don't leak return codes from libmspack to clamav API. (Closes: #774686).

[ Andreas Cadhalpun ]
* Add patch to avoid emitting incremental progress messages when not
  outputting to a terminal. (Closes: #767350)
* Update lintian-overrides for unused-file-paragraph-in-dep5-copyright.
* clamav-base.postinst: always chown /var/log/clamav and /var/lib/clamav
  to clamav:clamav, not only on fresh installations. (Closes: #775400)
* Adapt the clamav-daemon and clamav-freshclam logrotate scripts,
  so that they correctly work under systemd.
* Move the PidFile variable from the clamd/freshclam configuration files
  to the init scripts. This makes the init scripts more robust against
  misconfiguration and avoids error messages with systemd. (Closes: #767353)
* debian/copyright: drop files from Files-Excluded only present in github
  tarballs
* Drop Workaround-a-bug-in-libc-on-Hurd.patch, because hurd got fixed.
  (see #752237)
* debian/rules: Remove useless --with-system-tommath --without-included-ltdl
  configure options.

[ Scott Kitterman ]
* Stop stripping llvm when repacking the tarball as the system llvm on some
  releases is too old to use
* New upstream bugfix release
  - Library shared object revisions.
  - Includes a patch from Sebastian Andrzej Siewior making ClamAV pid files
    compatible with systemd.
  - Fix a heap out of bounds condition with crafted Yoda's crypter files.
    This issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted mew packer files. This
    issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted upx packer files. This
    issue was discovered by Kevin Szkudlapski of Quarkslab.
  - Fix a heap out of bounds condition with crafted upack packer files. This
    issue was discovered by Sebastian Andrzej Siewior. CVE-2014-9328.
  - Compensate a crash due to incorrect compiler optimization when handling
    crafted petite packer files. This issue was discovered by Sebastian
    Andrzej Siewior.
* Update lintian override for embedded zlib to match new so version

[ Javier Fernández-Sanguino ]
* Updated Spanish Debconf template translation (Closes: #773563)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
From d2564db5d3f50adc67474ffb22b0ee7027a82828 Mon Sep 17 00:00:00 2001
2
 
From: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
3
 
Date: Mon, 11 Aug 2014 23:22:05 +0200
4
 
Subject: Add upstream systemd support for clamav-daemon and clamav-freshclam.
5
 
 
6
 
---
7
 
 Makefile.am                           |   2 +-
8
 
 clamd/Makefile.am                     |   4 ++
9
 
 clamd/clamav-daemon.service.in        |  17 ++++++
10
 
 clamd/clamav-daemon.socket            |  12 ++++
11
 
 clamd/clamd.c                         | 102 +++++++++++++++++++++++++++-------
12
 
 clamd/localserver.c                   |  34 ++++++++++++
13
 
 clamd/server-th.c                     |  55 +++++++++++-------
14
 
 clamd/tcpserver.c                     |  50 +++++++++++++++++
15
 
 configure.ac                          |   3 +
16
 
 freshclam/Makefile.am                 |   4 ++
17
 
 freshclam/clamav-freshclam.service.in |  12 ++++
18
 
 freshclam/freshclam.c                 |  39 +++++++++++--
19
 
 m4/reorganization/libs/systemd.m4     |  18 ++++++
20
 
 shared/misc.h                         |   8 +++
21
 
 shared/optparser.c                    |   2 +-
22
 
 15 files changed, 318 insertions(+), 44 deletions(-)
23
 
 create mode 100644 clamd/clamav-daemon.service.in
24
 
 create mode 100644 clamd/clamav-daemon.socket
25
 
 create mode 100644 freshclam/clamav-freshclam.service.in
26
 
 create mode 100644 m4/reorganization/libs/systemd.m4
27
 
 
28
 
diff --git a/Makefile.am b/Makefile.am
29
 
index 2eecd94b668b..017d6327ff58 100644
30
 
--- a/Makefile.am
31
 
+++ b/Makefile.am
32
 
@@ -33,7 +33,7 @@ pkgconfig_DATA = libclamav.pc
33
 
 # don't complain that configuration files and databases are not removed, this is intended
34
 
 distuninstallcheck_listfiles = find . -type f ! -name clamd.conf ! -name freshclam.conf ! -name daily.cvd ! -name main.cvd -print
35
 
 DISTCLEANFILES = target.h
36
 
-DISTCHECK_CONFIGURE_FLAGS=--enable-milter --disable-clamav --enable-all-jit-targets --enable-llvm=yes
37
 
+DISTCHECK_CONFIGURE_FLAGS=--enable-milter --disable-clamav --enable-all-jit-targets --enable-llvm=yes --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
38
 
 lcov:
39
 
        ($(MAKE); cd unit_tests; $(MAKE) lcov)
40
 
 quick-check:
41
 
diff --git a/clamd/Makefile.am b/clamd/Makefile.am
42
 
index 61bbd69d1133..edc133138e58 100644
43
 
--- a/clamd/Makefile.am
44
 
+++ b/clamd/Makefile.am
45
 
@@ -50,6 +50,10 @@ clamd_SOURCES = \
46
 
 
47
 
 AM_CFLAGS=@WERR_CFLAGS@
48
 
 
49
 
+if INSTALL_SYSTEMD_UNITS
50
 
+systemdsystemunit_DATA = clamav-daemon.socket clamav-daemon.service
51
 
+endif
52
 
+
53
 
 endif
54
 
 
55
 
 LIBS = $(top_builddir)/libclamav/libclamav.la @CLAMD_LIBS@ @THREAD_LIBS@
56
 
diff --git a/clamd/clamav-daemon.service.in b/clamd/clamav-daemon.service.in
57
 
new file mode 100644
58
 
index 000000000000..0a5d456a2b36
59
 
--- /dev/null
60
 
+++ b/clamd/clamav-daemon.service.in
61
 
@@ -0,0 +1,17 @@
62
 
+[Unit]
63
 
+Description=Clam AntiVirus userspace daemon
64
 
+Documentation=man:clamd(8) man:clamd.conf(5) http://www.clamav.net/lang/en/doc/
65
 
+Requires=clamav-daemon.socket
66
 
+# Check for database existence
67
 
+ConditionPathExistsGlob=@DBDIR@/main.{c[vl]d,inc}
68
 
+ConditionPathExistsGlob=@DBDIR@/daily.{c[vl]d,inc}
69
 
+
70
 
+[Service]
71
 
+ExecStart=@prefix@/sbin/clamd --foreground=true
72
 
+# Reload the database
73
 
+ExecReload=/bin/kill -USR2 $MAINPID
74
 
+StandardOutput=syslog
75
 
+
76
 
+[Install]
77
 
+WantedBy=multi-user.target
78
 
+Also=clamav-daemon.socket
79
 
diff --git a/clamd/clamav-daemon.socket b/clamd/clamav-daemon.socket
80
 
new file mode 100644
81
 
index 000000000000..43a34cd36aad
82
 
--- /dev/null
83
 
+++ b/clamd/clamav-daemon.socket
84
 
@@ -0,0 +1,12 @@
85
 
+[Unit]
86
 
+Description=Socket for Clam AntiVirus userspace daemon
87
 
+Documentation=man:clamd(8) man:clamd.conf(5) http://www.clamav.net/lang/en/doc/
88
 
+
89
 
+[Socket]
90
 
+ListenStream=/run/clamav/clamd.ctl
91
 
+#ListenStream=127.0.0.1:1024
92
 
+ExecStartPost=/bin/chown -R clamav:clamav /run/clamav/
93
 
+ExecStopPost=/bin/rm /run/clamav/clamd.ctl
94
 
+
95
 
+[Install]
96
 
+WantedBy=sockets.target
97
 
diff --git a/clamd/clamd.c b/clamd/clamd.c
98
 
index 96204291f433..ec15eacc8c25 100644
99
 
--- a/clamd/clamd.c
100
 
+++ b/clamd/clamd.c
101
 
@@ -72,7 +72,7 @@
102
 
 #include "scanner.h"
103
 
 
104
 
 short debug_mode = 0, logok = 0;
105
 
-short foreground = 0;
106
 
+short foreground = -1;
107
 
 char hostid[37];
108
 
 
109
 
 char *get_hostid(void *cbdata);
110
 
@@ -160,6 +160,31 @@ int main(int argc, char **argv)
111
 
         debug_mode = 1;
112
 
     }
113
 
 
114
 
+    /* check foreground option from command line to override config file */
115
 
+    int j;
116
 
+    for(j = 0; j < argc; j += 1)
117
 
+    {
118
 
+        if ((memcmp(argv[j], "--foreground", 12) == 0) || (memcmp(argv[j], "-F", 2) == 0))
119
 
+        {
120
 
+            /* found */
121
 
+            break;
122
 
+        }
123
 
+    }
124
 
+
125
 
+    if (j < argc)
126
 
+    {
127
 
+        if(optget(opts, "Foreground")->enabled)
128
 
+        {
129
 
+            foreground = 1;
130
 
+        }
131
 
+        else
132
 
+        {
133
 
+            foreground = 0;
134
 
+        }
135
 
+    }
136
 
+
137
 
+    int num_fd = sd_listen_fds(0);
138
 
+
139
 
     /* parse the config file */
140
 
     cfgfile = optget(opts, "config-file")->strarg;
141
 
     pt = strdup(cfgfile);
142
 
@@ -295,7 +320,9 @@ int main(int argc, char **argv)
143
 
         if(optget(opts, "LocalSocket")->enabled)
144
 
             localsock = 1;
145
 
 
146
 
-        if(!tcpsock && !localsock) {
147
 
+        logg("#Received %d file descriptor(s) from systemd.\n", num_fd);
148
 
+
149
 
+        if(!tcpsock && !localsock && num_fd == 0) {
150
 
             logg("!Please define server type (local and/or TCP).\n");
151
 
             ret = 1;
152
 
             break;
153
 
@@ -577,7 +604,9 @@ int main(int argc, char **argv)
154
 
             break;
155
 
         }
156
 
 
157
 
-        if(tcpsock) {
158
 
+        if(tcpsock || num_fd > 0) {
159
 
+            int *t;
160
 
+
161
 
             opt = optget(opts, "TCPAddr");
162
 
             if (opt->enabled) {
163
 
                 int breakout = 0;
164
 
@@ -604,7 +633,7 @@ int main(int argc, char **argv)
165
 
             }
166
 
         }
167
 
 #ifndef _WIN32
168
 
-        if(localsock) {
169
 
+        if(localsock && num_fd == 0) {
170
 
             int *t;
171
 
             mode_t sock_mode, umsk = umask(0777); /* socket is created with 000 to avoid races */
172
 
 
173
 
@@ -666,8 +695,43 @@ int main(int argc, char **argv)
174
 
             nlsockets++;
175
 
         }
176
 
 
177
 
+        /* check for local sockets passed by systemd */
178
 
+        if (num_fd > 0)
179
 
+        {
180
 
+            int *t;
181
 
+            t = realloc(lsockets, sizeof(int) * (nlsockets + 1));
182
 
+            if (!(t)) {
183
 
+                ret = 1;
184
 
+                break;
185
 
+            }
186
 
+            lsockets = t;
187
 
+
188
 
+            lsockets[nlsockets] = localserver(opts);
189
 
+            if (lsockets[nlsockets] == -1)
190
 
+            {
191
 
+                ret = 1;
192
 
+                break;
193
 
+            }
194
 
+            else if (lsockets[nlsockets] > 0)
195
 
+            {
196
 
+                nlsockets++;
197
 
+            }
198
 
+        }
199
 
+
200
 
         /* fork into background */
201
 
-        if(!optget(opts, "Foreground")->enabled) {
202
 
+        if (foreground == -1)
203
 
+        {
204
 
+            if (optget(opts, "Foreground")->enabled)
205
 
+            {
206
 
+                foreground = 1;
207
 
+            }
208
 
+            else
209
 
+            {
210
 
+                foreground = 0;
211
 
+            }
212
 
+        }
213
 
+        if(foreground == 0)
214
 
+        {
215
 
 #ifdef C_BSD       
216
 
             /* workaround for OpenBSD bug, see https://wwws.clamav.net/bugzilla/show_bug.cgi?id=885 */
217
 
             for(ret=0;(unsigned int)ret<nlsockets;ret++) {
218
 
@@ -701,8 +765,6 @@ int main(int argc, char **argv)
219
 
                 if(chdir("/") == -1)
220
 
                     logg("^Can't change current working directory to root\n");
221
 
 
222
 
-        } else {
223
 
-            foreground = 1;
224
 
         }
225
 
 #endif
226
 
 
227
 
@@ -716,22 +778,24 @@ int main(int argc, char **argv)
228
 
 
229
 
     } while (0);
230
 
 
231
 
-    logg("*Closing the main socket%s.\n", (nlsockets > 1) ? "s" : "");
232
 
-
233
 
-    for (i = 0; i < nlsockets; i++) {
234
 
-        closesocket(lsockets[i]);
235
 
-    }
236
 
+    if (num_fd == 0)
237
 
+    {
238
 
+        logg("*Closing the main socket%s.\n", (nlsockets > 1) ? "s" : "");
239
 
 
240
 
+        for (i = 0; i < nlsockets; i++) {
241
 
+            closesocket(lsockets[i]);
242
 
+        }
243
 
 #ifndef _WIN32
244
 
-    if(nlsockets && localsock) {
245
 
-        opt = optget(opts, "LocalSocket");
246
 
+        if(nlsockets && localsock) {
247
 
+            opt = optget(opts, "LocalSocket");
248
 
 
249
 
-        if(unlink(opt->strarg) == -1)
250
 
-            logg("!Can't unlink the socket file %s\n", opt->strarg);
251
 
-        else
252
 
-            logg("Socket file removed.\n");
253
 
-    }
254
 
+            if(unlink(opt->strarg) == -1)
255
 
+                logg("!Can't unlink the socket file %s\n", opt->strarg);
256
 
+            else
257
 
+                logg("Socket file removed.\n");
258
 
+        }
259
 
 #endif
260
 
+    }
261
 
 
262
 
     free(lsockets);
263
 
 
264
 
diff --git a/clamd/localserver.c b/clamd/localserver.c
265
 
index db07415212ad..d963efd244f5 100644
266
 
--- a/clamd/localserver.c
267
 
+++ b/clamd/localserver.c
268
 
@@ -39,6 +39,7 @@
269
 
 
270
 
 #include "shared/optparser.h"
271
 
 #include "shared/output.h"
272
 
+#include "shared/misc.h"
273
 
 
274
 
 #include "others.h"
275
 
 #include "server.h"
276
 
@@ -60,6 +61,39 @@ int localserver(const struct optstruct *opts)
277
 
        STATBUF foo;
278
 
        char *estr;
279
 
 
280
 
+    int num_fd = sd_listen_fds(0);
281
 
+    if (num_fd > 2)
282
 
+    {
283
 
+        logg("!LOCAL: Received more than two file descriptors from systemd.\n");
284
 
+        return -1;
285
 
+    }
286
 
+    else if (num_fd > 0)
287
 
+    {
288
 
+        /* use socket passed by systemd */
289
 
+        int i;
290
 
+        for(i = 0; i < num_fd; i += 1)
291
 
+        {
292
 
+            sockfd = SD_LISTEN_FDS_START + i;
293
 
+            if (sd_is_socket(sockfd, AF_UNIX, SOCK_STREAM, 1) == 1)
294
 
+            {
295
 
+                /* correct socket */
296
 
+                break;
297
 
+            }
298
 
+            else
299
 
+            {
300
 
+                /* wrong socket */
301
 
+                sockfd = -2;
302
 
+            }
303
 
+        }
304
 
+        if (sockfd == -2)
305
 
+        {
306
 
+            logg("#LOCAL: No local AF_UNIX SOCK_STREAM socket received from systemd.\n");
307
 
+            return -2;
308
 
+        }
309
 
+        logg("#LOCAL: Received AF_UNIX SOCK_STREAM socket from systemd.\n");
310
 
+        return sockfd;
311
 
+    }
312
 
+    /* create socket */
313
 
     memset((char *) &server, 0, sizeof(server));
314
 
     server.sun_family = AF_UNIX;
315
 
     strncpy(server.sun_path, optget(opts, "LocalSocket")->strarg, sizeof(server.sun_path));
316
 
diff --git a/clamd/server-th.c b/clamd/server-th.c
317
 
index d97cd6fb34e1..5c12811b662b 100644
318
 
--- a/clamd/server-th.c
319
 
+++ b/clamd/server-th.c
320
 
@@ -48,6 +48,7 @@
321
 
 
322
 
 #include "shared/output.h"
323
 
 #include "shared/optparser.h"
324
 
+#include "shared/misc.h"
325
 
 
326
 
 #include "fan.h"
327
 
 #include "server.h"
328
 
@@ -445,13 +446,19 @@ static void *acceptloop_th(void *arg)
329
 
     }
330
 
     pthread_mutex_unlock(fds->buf_mutex);
331
 
 
332
 
-    for (i=0;i < fds->nfds; i++) {
333
 
-       if (fds->buf[i].fd == -1)
334
 
-           continue;
335
 
-       logg("$Shutdown: closed fd %d\n", fds->buf[i].fd);
336
 
-       shutdown(fds->buf[i].fd, 2);
337
 
-       closesocket(fds->buf[i].fd);
338
 
+    if (sd_listen_fds(0) == 0)
339
 
+    {
340
 
+        /* only close the sockets, when not using systemd socket activation */
341
 
+        for (i=0;i < fds->nfds; i++)
342
 
+        {
343
 
+            if (fds->buf[i].fd == -1)
344
 
+                continue;
345
 
+            logg("$Shutdown: closed fd %d\n", fds->buf[i].fd);
346
 
+            shutdown(fds->buf[i].fd, 2);
347
 
+            closesocket(fds->buf[i].fd);
348
 
+        }
349
 
     }
350
 
+
351
 
     fds_free(fds);
352
 
     pthread_mutex_destroy(fds->buf_mutex);
353
 
     pthread_mutex_lock(&exit_mutex);
354
 
@@ -1344,16 +1351,22 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
355
 
        if (progexit) {
356
 
            pthread_mutex_unlock(&exit_mutex);
357
 
            pthread_mutex_lock(fds->buf_mutex);
358
 
-           for (i=0;i < fds->nfds; i++) {
359
 
-               if (fds->buf[i].fd == -1)
360
 
-                   continue;
361
 
-               thrmgr_group_terminate(fds->buf[i].group);
362
 
-               if (thrmgr_group_finished(fds->buf[i].group, EXIT_ERROR)) {
363
 
-                   logg("$Shutdown closed fd %d\n", fds->buf[i].fd);
364
 
-                   shutdown(fds->buf[i].fd, 2);
365
 
-                   closesocket(fds->buf[i].fd);
366
 
-                   fds->buf[i].fd = -1;
367
 
-               }
368
 
+        if (sd_listen_fds(0) == 0)
369
 
+        {
370
 
+            /* only close the sockets, when not using systemd socket activation */
371
 
+            for (i=0;i < fds->nfds; i++)
372
 
+            {
373
 
+                if (fds->buf[i].fd == -1)
374
 
+                    continue;
375
 
+                thrmgr_group_terminate(fds->buf[i].group);
376
 
+                if (thrmgr_group_finished(fds->buf[i].group, EXIT_ERROR))
377
 
+                {
378
 
+                    logg("$Shutdown closed fd %d\n", fds->buf[i].fd);
379
 
+                    shutdown(fds->buf[i].fd, 2);
380
 
+                    closesocket(fds->buf[i].fd);
381
 
+                    fds->buf[i].fd = -1;
382
 
+                }
383
 
+            }
384
 
            }
385
 
            pthread_mutex_unlock(fds->buf_mutex);
386
 
            break;
387
 
@@ -1462,9 +1475,13 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
388
 
 #endif
389
 
     if(dbstat.entries)
390
 
        cl_statfree(&dbstat);
391
 
-    logg("*Shutting down the main socket%s.\n", (nsockets > 1) ? "s" : "");
392
 
-    for (i = 0; i < nsockets; i++)
393
 
-       shutdown(socketds[i], 2);
394
 
+    if (sd_listen_fds(0) == 0)
395
 
+    {
396
 
+        /* only close the sockets, when not using systemd socket activation */
397
 
+        logg("*Shutting down the main socket%s.\n", (nsockets > 1) ? "s" : "");
398
 
+        for (i = 0; i < nsockets; i++)
399
 
+            shutdown(socketds[i], 2);
400
 
+    }
401
 
 
402
 
     if((opt = optget(opts, "PidFile"))->enabled) {
403
 
        if(unlink(opt->strarg) == -1)
404
 
diff --git a/clamd/tcpserver.c b/clamd/tcpserver.c
405
 
index c3027a85c1f4..81387b3c8512 100644
406
 
--- a/clamd/tcpserver.c
407
 
+++ b/clamd/tcpserver.c
408
 
@@ -60,6 +60,56 @@ int tcpserver(int **lsockets, unsigned int *nlsockets, char *ipaddr, const struc
409
 
 
410
 
     sockets = *lsockets;
411
 
 
412
 
+    int num_fd = sd_listen_fds(0);
413
 
+    if (num_fd > 2)
414
 
+    {
415
 
+        logg("!TCP: Received more than two file descriptors from systemd.\n");
416
 
+        return -1;
417
 
+    }
418
 
+    else if (num_fd > 0)
419
 
+    {
420
 
+        /* use socket passed by systemd */
421
 
+        int i;
422
 
+        for(i = 0; i < num_fd; i += 1)
423
 
+        {
424
 
+            sockfd = SD_LISTEN_FDS_START + i;
425
 
+            if (sd_is_socket(sockfd, AF_INET, SOCK_STREAM, 1) == 1)
426
 
+            {
427
 
+                /* correct socket */
428
 
+                logg("#TCP: Received AF_INET SOCK_STREAM socket from systemd.\n");
429
 
+                break;
430
 
+            }
431
 
+            else if (sd_is_socket(sockfd, AF_INET6, SOCK_STREAM, 1) == 1)
432
 
+            {
433
 
+                /* correct socket */
434
 
+                logg("#TCP: Received AF_INET6 SOCK_STREAM socket from systemd.\n");
435
 
+                break;
436
 
+            }
437
 
+            else
438
 
+            {
439
 
+                /* wrong socket */
440
 
+                sockfd = -2;
441
 
+            }
442
 
+        }
443
 
+        if (sockfd == -2)
444
 
+        {
445
 
+            logg("#TCP: No tcp AF_INET/AF_INET6 SOCK_STREAM socket received from systemd.\n");
446
 
+            return -2;
447
 
+        }
448
 
+
449
 
+        t = realloc(sockets, sizeof(int) * (*nlsockets + 1));
450
 
+        if (!(t)) {
451
 
+            return -1;
452
 
+        }
453
 
+        sockets = t;
454
 
+
455
 
+        sockets[*nlsockets] = sockfd;
456
 
+        (*nlsockets)++;
457
 
+        *lsockets = sockets;
458
 
+        return 0;
459
 
+    }
460
 
+
461
 
+    /* create socket */
462
 
     snprintf(port, sizeof(port), "%lld", optget(opts, "TCPSocket")->numarg);
463
 
 
464
 
     memset(&hints, 0x00, sizeof(struct addrinfo));
465
 
diff --git a/configure.ac b/configure.ac
466
 
index 41043753fc92..02caad29410a 100644
467
 
--- a/configure.ac
468
 
+++ b/configure.ac
469
 
@@ -86,6 +86,7 @@ AM_MAINTAINER_MODE
470
 
 m4_include([m4/reorganization/libs/libz.m4])
471
 
 m4_include([m4/reorganization/libs/bzip.m4])
472
 
 m4_include([m4/reorganization/libs/unrar.m4])
473
 
+m4_include([m4/reorganization/libs/systemd.m4])
474
 
 m4_include([m4/reorganization/code_checks/ipv6.m4])
475
 
 m4_include([m4/reorganization/code_checks/dns.m4])
476
 
 m4_include([m4/reorganization/code_checks/fanotify.m4])
477
 
@@ -137,9 +138,11 @@ clamscan/Makefile
478
 
 database/Makefile
479
 
 docs/Makefile
480
 
 clamd/Makefile
481
 
+clamd/clamav-daemon.service
482
 
 clamdscan/Makefile
483
 
 clamsubmit/Makefile
484
 
 clamav-milter/Makefile
485
 
+freshclam/clamav-freshclam.service
486
 
 freshclam/Makefile
487
 
 sigtool/Makefile
488
 
 clamconf/Makefile
489
 
diff --git a/freshclam/Makefile.am b/freshclam/Makefile.am
490
 
index 58fc17471c35..051bf3380e98 100644
491
 
--- a/freshclam/Makefile.am
492
 
+++ b/freshclam/Makefile.am
493
 
@@ -49,6 +49,10 @@ freshclam_SOURCES = \
494
 
     mirman.c \
495
 
     mirman.h
496
 
 
497
 
+if INSTALL_SYSTEMD_UNITS
498
 
+systemdsystemunit_DATA = clamav-freshclam.service
499
 
+endif
500
 
+
501
 
 AM_CFLAGS=@WERR_CFLAGS@
502
 
 DEFS = @DEFS@ -DCL_NOTHREADS
503
 
 AM_CPPFLAGS = @SSL_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @FRESHCLAM_CPPFLAGS@  @JSON_CPPFLAGS@
504
 
diff --git a/freshclam/clamav-freshclam.service.in b/freshclam/clamav-freshclam.service.in
505
 
new file mode 100644
506
 
index 000000000000..f717cd642106
507
 
--- /dev/null
508
 
+++ b/freshclam/clamav-freshclam.service.in
509
 
@@ -0,0 +1,12 @@
510
 
+[Unit]
511
 
+Description=ClamAV virus database updater
512
 
+Documentation=man:freshclam(1) man:freshclam.conf(5) http://www.clamav.net/lang/en/doc/
513
 
+# If user wants it run from cron, don't start the daemon.
514
 
+ConditionPathExists=!/etc/cron.d/clamav-freshclam
515
 
+
516
 
+[Service]
517
 
+ExecStart=@prefix@/bin/freshclam -d --foreground=true
518
 
+StandardOutput=syslog
519
 
+
520
 
+[Install]
521
 
+WantedBy=multi-user.target
522
 
diff --git a/freshclam/freshclam.c b/freshclam/freshclam.c
523
 
index 166586bf6447..f170613877c4 100644
524
 
--- a/freshclam/freshclam.c
525
 
+++ b/freshclam/freshclam.c
526
 
@@ -64,7 +64,7 @@
527
 
 static short terminate = 0;
528
 
 extern int active_children;
529
 
 
530
 
-static short foreground = 1;
531
 
+static short foreground = -1;
532
 
 char updtmpdir[512], dbdir[512];
533
 
 int sigchld_wait = 1;
534
 
 const char *pidfile = NULL;
535
 
@@ -117,7 +117,7 @@ sighandler (int sig)
536
 
         if (pidfile)
537
 
             unlink (pidfile);
538
 
         logg ("Update process terminated\n");
539
 
-        exit (2);
540
 
+        exit (0);
541
 
     }
542
 
 
543
 
     return;
544
 
@@ -322,6 +322,26 @@ main (int argc, char **argv)
545
 
         return 0;
546
 
     }
547
 
 
548
 
+    /* check foreground option from command line to override config file */
549
 
+    int j;
550
 
+    for(j = 0; j < argc; j += 1)
551
 
+    {
552
 
+        if ((memcmp(argv[j], "--foreground", 12) == 0) || (memcmp(argv[j], "-F", 2) == 0))
553
 
+        {
554
 
+            /* found */
555
 
+            break;
556
 
+        }
557
 
+    }
558
 
+
559
 
+       if (j < argc) {
560
 
+               if(optget(opts, "Foreground")->enabled) {
561
 
+                       foreground = 1;
562
 
+               }
563
 
+               else {
564
 
+                       foreground = 0;
565
 
+               }
566
 
+       }
567
 
+
568
 
     /* parse the config file */
569
 
     cfgfile = optget (opts, "config-file")->strarg;
570
 
     pt = strdup (cfgfile);
571
 
@@ -638,7 +658,19 @@ main (int argc, char **argv)
572
 
         bigsleep = 24 * 3600 / checks;
573
 
 
574
 
 #ifndef _WIN32
575
 
-        if (!optget (opts, "Foreground")->enabled)
576
 
+        /* fork into background */
577
 
+        if (foreground == -1)
578
 
+        {
579
 
+            if (optget(opts, "Foreground")->enabled)
580
 
+            {
581
 
+                foreground = 1;
582
 
+            }
583
 
+            else
584
 
+            {
585
 
+                foreground = 0;
586
 
+            }
587
 
+        }
588
 
+        if(foreground == 0)
589
 
         {
590
 
             if (daemonize () == -1)
591
 
             {
592
 
@@ -646,7 +678,6 @@ main (int argc, char **argv)
593
 
                 optfree (opts);
594
 
                 return FCE_FAILEDUPDATE;
595
 
             }
596
 
-            foreground = 0;
597
 
             mprintf_disabled = 1;
598
 
         }
599
 
 #endif
600
 
diff --git a/m4/reorganization/libs/systemd.m4 b/m4/reorganization/libs/systemd.m4
601
 
new file mode 100644
602
 
index 000000000000..cac5d4272fda
603
 
--- /dev/null
604
 
+++ b/m4/reorganization/libs/systemd.m4
605
 
@@ -0,0 +1,18 @@
606
 
+dnl Check for systemd-daemon
607
 
+PKG_CHECK_MODULES(SYSTEMD, [libsystemd-daemon], [AC_DEFINE([HAVE_SYSTEMD],,[systemd-daemon is supported])], [AC_MSG_RESULT([systemd-daemon is not supported])])
608
 
+CLAMD_LIBS="$CLAMD_LIBS $SYSTEMD_LIBS"
609
 
+CFLAGS="$CFLAGS $SYSTEMD_CFLAGS"
610
 
+
611
 
+dnl Check for systemd system unit installation directory (see man 7 daemon)
612
 
+AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),, [with_systemdsystemunitdir=auto])
613
 
+AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
614
 
+     def_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
615
 
+     AS_IF([test "x$def_systemdsystemunitdir" = "x"],
616
 
+         [AS_IF([test "x$with_systemdsystemunitdir" = "xyes"], [AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
617
 
+          with_systemdsystemunitdir=no],
618
 
+         [with_systemdsystemunitdir=$def_systemdsystemunitdir])])
619
 
+AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
620
 
+      [AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
621
 
+AM_CONDITIONAL(INSTALL_SYSTEMD_UNITS, [test "x$with_systemdsystemunitdir" != "xno"])
622
 
+AC_MSG_RESULT([checking for systemd system unit installation directory... $with_systemdsystemunitdir])
623
 
+
624
 
diff --git a/shared/misc.h b/shared/misc.h
625
 
index 7f3a9f962d0d..3e093936caa1 100644
626
 
--- a/shared/misc.h
627
 
+++ b/shared/misc.h
628
 
@@ -37,6 +37,14 @@
629
 
 # endif
630
 
 #endif
631
 
 
632
 
+#ifdef HAVE_SYSTEMD
633
 
+# include <systemd/sd-daemon.h>
634
 
+#else
635
 
+# define sd_listen_fds(u) 0
636
 
+# define SD_LISTEN_FDS_START 3
637
 
+# define sd_is_socket(f, a, s, l) 1
638
 
+#endif
639
 
+
640
 
 #include <limits.h>
641
 
 
642
 
 #ifndef PATH_MAX
643
 
diff --git a/shared/optparser.c b/shared/optparser.c
644
 
index 63c88550d5b8..b61ec832a32f 100644
645
 
--- a/shared/optparser.c
646
 
+++ b/shared/optparser.c
647
 
@@ -272,7 +272,7 @@ const struct clam_option __clam_options[] = {
648
 
 
649
 
     { "AllowAllMatchScan", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD, "Permit use of the ALLMATCHSCAN command.", "yes" },
650
 
 
651
 
-    { "Foreground", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_MILTER, "Don't fork into background.", "no" },
652
 
+    { "Foreground", "foreground", 'F', CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_MILTER, "Don't fork into background.", "no" },
653
 
 
654
 
     { "Debug", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_FRESHCLAM, "Enable debug messages in libclamav.", "no" },
655