Browse code

enabled support for Dazuko

git-svn: trunk@355

Tomasz Kojm authored on 2004/03/01 02:29:09
Showing 11 changed files
... ...
@@ -1,3 +1,8 @@
1
+Sun Feb 29 18:28:22 CET 2004 (tk)
2
+---------------------------------
3
+  * clamd, configure: enabled support for on-access scanning under Linux and
4
+		      FreeBSD. Tested with Dazuko 2.0.0.
5
+
1 6
 Sat Feb 28 23:06:43 CET 2004 (tk)
2 7
 ---------------------------------
3 8
   * config parser: fixed segfault with empty argument for numerical option
... ...
@@ -81,7 +81,7 @@ dnl there is now a CREATE_PREFIX_TARGET_H in this file as a shorthand for
81 81
 dnl PREFIX_CONFIG_H from a target.h file, however w/o the target.h ever created
82 82
 dnl (the prefix is a bit different, since we add an extra -target- and -host-)
83 83
 dnl 
84
-dnl @version: $Id: aclocal.m4,v 1.24 2004/02/23 17:24:52 kojm Exp $
84
+dnl @version: $Id: aclocal.m4,v 1.25 2004/02/29 17:29:09 kojm Exp $
85 85
 dnl @author Guido Draheim <guidod@gmx.de>                 STATUS: used often
86 86
 
87 87
 AC_DEFUN([AC_CREATE_TARGET_H],
... ...
@@ -4041,7 +4041,7 @@ dnl      AC_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers)
4041 4041
 dnl      AC_COMPILE_CHECK_SIZEOF(off_t, $headers)
4042 4042
 dnl
4043 4043
 dnl @author Kaveh Ghazi <ghazi@caip.rutgers.edu>
4044
-dnl @version $Id: aclocal.m4,v 1.24 2004/02/23 17:24:52 kojm Exp $
4044
+dnl @version $Id: aclocal.m4,v 1.25 2004/02/29 17:29:09 kojm Exp $
4045 4045
 dnl
4046 4046
 AC_DEFUN([AC_COMPILE_CHECK_SIZEOF],
4047 4047
 [changequote(<<, >>)dnl
... ...
@@ -42,9 +42,12 @@ clamd_SOURCES = \
42 42
     others.h \
43 43
     clamuko.c \
44 44
     clamuko.h \
45
-    dazuko.h \
45
+    dazukoio_compat12.c \
46
+    dazukoio_compat12.h \
46 47
     dazukoio.c \
47 48
     dazukoio.h \
49
+    dazuko_xp.h \
50
+    dazukoio_xp.h \
48 51
     tests.c \
49 52
     tests.h
50 53
 
... ...
@@ -141,9 +141,12 @@ install_sh = @install_sh@
141 141
 @BUILD_CLAMD_TRUE@    others.h \
142 142
 @BUILD_CLAMD_TRUE@    clamuko.c \
143 143
 @BUILD_CLAMD_TRUE@    clamuko.h \
144
-@BUILD_CLAMD_TRUE@    dazuko.h \
144
+@BUILD_CLAMD_TRUE@    dazukoio_compat12.c \
145
+@BUILD_CLAMD_TRUE@    dazukoio_compat12.h \
145 146
 @BUILD_CLAMD_TRUE@    dazukoio.c \
146 147
 @BUILD_CLAMD_TRUE@    dazukoio.h \
148
+@BUILD_CLAMD_TRUE@    dazuko_xp.h \
149
+@BUILD_CLAMD_TRUE@    dazukoio_xp.h \
147 150
 @BUILD_CLAMD_TRUE@    tests.c \
148 151
 @BUILD_CLAMD_TRUE@    tests.h
149 152
 
... ...
@@ -166,8 +169,8 @@ PROGRAMS = $(sbin_PROGRAMS)
166 166
 @BUILD_CLAMD_TRUE@	localserver.$(OBJEXT) session.$(OBJEXT) \
167 167
 @BUILD_CLAMD_TRUE@	thrmgr.$(OBJEXT) server-th.$(OBJEXT) \
168 168
 @BUILD_CLAMD_TRUE@	scanner.$(OBJEXT) others.$(OBJEXT) \
169
-@BUILD_CLAMD_TRUE@	clamuko.$(OBJEXT) dazukoio.$(OBJEXT) \
170
-@BUILD_CLAMD_TRUE@	tests.$(OBJEXT)
169
+@BUILD_CLAMD_TRUE@	clamuko.$(OBJEXT) dazukoio_compat12.$(OBJEXT) \
170
+@BUILD_CLAMD_TRUE@	dazukoio.$(OBJEXT) tests.$(OBJEXT)
171 171
 clamd_OBJECTS = $(am_clamd_OBJECTS)
172 172
 @BUILD_CLAMD_TRUE@clamd_DEPENDENCIES = ../clamscan/getopt.o
173 173
 @BUILD_CLAMD_FALSE@clamd_DEPENDENCIES =
... ...
@@ -179,6 +182,7 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
179 179
 am__depfiles_maybe = depfiles
180 180
 @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/cfgfile.Po ./$(DEPDIR)/clamd.Po \
181 181
 @AMDEP_TRUE@	./$(DEPDIR)/clamuko.Po ./$(DEPDIR)/dazukoio.Po \
182
+@AMDEP_TRUE@	./$(DEPDIR)/dazukoio_compat12.Po \
182 183
 @AMDEP_TRUE@	./$(DEPDIR)/localserver.Po ./$(DEPDIR)/options.Po \
183 184
 @AMDEP_TRUE@	./$(DEPDIR)/others.Po ./$(DEPDIR)/scanner.Po \
184 185
 @AMDEP_TRUE@	./$(DEPDIR)/server-th.Po ./$(DEPDIR)/session.Po \
... ...
@@ -246,6 +250,7 @@ distclean-compile:
246 246
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clamd.Po@am__quote@
247 247
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clamuko.Po@am__quote@
248 248
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dazukoio.Po@am__quote@
249
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dazukoio_compat12.Po@am__quote@
249 250
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/localserver.Po@am__quote@
250 251
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@
251 252
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/others.Po@am__quote@
... ...
@@ -37,7 +37,7 @@
37 37
 #include "clamuko.h"
38 38
 #include "defaults.h"
39 39
 
40
-struct access_t acc;
40
+struct dazuko_access *acc;
41 41
 
42 42
 void clamuko_exit(int sig)
43 43
 {
... ...
@@ -45,13 +45,15 @@ void clamuko_exit(int sig)
45 45
     logg("*Clamuko: clamuko_exit(), signal %d\n", sig);
46 46
 
47 47
     if(clamuko_scanning) {
48
-	logg("*Clamuko: stopped while scanning %s\n", acc.filename);
49
-	acc.deny = 0;
48
+	logg("*Clamuko: stopped while scanning %s\n", acc->filename);
49
+	acc->deny = 0;
50 50
 	dazukoReturnAccess(&acc); /* is it needed ? */
51 51
     }
52 52
 
53
-    dazukoUnregister();
54
-    clamuko_running = 0;
53
+    if(dazukoUnregister())
54
+	logg("!Can't unregister with Dazuko\n");
55
+
56
+    /* clamuko_running = 0; */
55 57
     logg("Clamuko stopped.\n");
56 58
 }
57 59
 
... ...
@@ -68,7 +70,7 @@ void *clamukoth(void *arg)
68 68
 	struct stat sb;
69 69
 
70 70
 
71
-    clamuko_running = 1;
71
+    /* clamuko_running = 1; */
72 72
     clamuko_scanning = 0;
73 73
 
74 74
     /* ignore all signals except SIGUSR1 */
... ...
@@ -84,9 +86,9 @@ void *clamukoth(void *arg)
84 84
 #endif
85 85
 
86 86
     /* register */
87
-    if(dazukoRegister()) {
87
+    if(dazukoRegister("ClamAV", "r+")) {
88 88
 	logg("!Clamuko: Can't register with Dazuko\n");
89
-	clamuko_running = 0;
89
+	/* clamuko_running = 0; */
90 90
 	return NULL;
91 91
     } else
92 92
 	logg("Clamuko: Correctly registered with Dazuko.\n");
... ...
@@ -94,35 +96,34 @@ void *clamukoth(void *arg)
94 94
     /* access mask */
95 95
     if(cfgopt(tharg->copt, "ClamukoScanOnOpen")) {
96 96
 	logg("Clamuko: Scan-on-open mode activated.\n");
97
-	mask |= ON_OPEN;
97
+	mask |= DAZUKO_ON_OPEN;
98 98
     }
99 99
     if(cfgopt(tharg->copt, "ClamukoScanOnClose")) {
100 100
 	logg("Clamuko: Scan-on-close mode activated.\n");
101
-	mask |= ON_CLOSE;
101
+	mask |= DAZUKO_ON_CLOSE;
102 102
     }
103 103
     if(cfgopt(tharg->copt, "ClamukoScanOnExec")) {
104 104
 	logg("Clamuko: Scan-on-exec mode activated.\n");
105
-	mask |= ON_EXEC;
105
+	mask |= DAZUKO_ON_EXEC;
106 106
     }
107 107
 
108 108
     if(!mask) {
109 109
 	logg("!Access mask is not configured properly.\n");
110
-	clamuko_running = 0;
110
+	/* clamuko_running = 0; */
111 111
 	return NULL;
112 112
     }
113 113
 
114 114
     if(dazukoSetAccessMask(mask)) {
115 115
 	logg("!Clamuko: Can't set access mask in Dazuko.\n");
116
-	clamuko_running = 0;
116
+	/* clamuko_running = 0; */
117 117
 	return NULL;
118 118
     }
119 119
 
120
-
121 120
     if((pt = cfgopt(tharg->copt, "ClamukoIncludePath"))) {
122 121
 	while(pt) {
123 122
 	    if((dazukoAddIncludePath(pt->strarg))) {
124 123
 		logg("!Clamuko: Dazuko -> Can't include path %s\n", pt->strarg);
125
-		clamuko_running = 0;
124
+		/* clamuko_running = 0; */
126 125
 		return NULL;
127 126
 	    } else
128 127
 		logg("Clamuko: Included path %s\n", pt->strarg);
... ...
@@ -131,7 +132,7 @@ void *clamukoth(void *arg)
131 131
 	}
132 132
     } else {
133 133
 	logg("!Clamuko: please include at least one path.\n");
134
-	clamuko_running = 0;
134
+	/* clamuko_running = 0; */
135 135
 	return NULL;
136 136
     }
137 137
 
... ...
@@ -139,7 +140,7 @@ void *clamukoth(void *arg)
139 139
 	while(pt) {
140 140
 	    if((dazukoAddExcludePath(pt->strarg))) {
141 141
 		logg("!Clamuko: Dazuko -> Can't exclude path %s\n", pt->strarg);
142
-		clamuko_running = 0;
142
+		/* clamuko_running = 0; */
143 143
 		return NULL;
144 144
 	    } else
145 145
 		logg("Clamuko: Excluded path %s\n", pt->strarg);
... ...
@@ -179,25 +180,25 @@ void *clamukoth(void *arg)
179 179
 	    scan = 1;
180 180
 
181 181
 	    if(sizelimit) {
182
-		stat(acc.filename, &sb);
182
+		stat(acc->filename, &sb);
183 183
 		if(sb.st_size > sizelimit) {
184 184
 		    scan = 0;
185
-		    logg("*Clamuko: %s skipped (too big)\n", acc.filename);
185
+		    logg("*Clamuko: %s skipped (too big)\n", acc->filename);
186 186
 		}
187 187
 	    }
188 188
 
189
-	    if(scan && cl_scanfile(acc.filename, &virname, NULL, tharg->root, tharg->limits, options) == CL_VIRUS) {
190
-		logg("Clamuko: %s: %s FOUND\n", acc.filename, virname);
191
-		virusaction(acc.filename, virname, tharg->copt);
192
-		acc.deny = 1;
189
+	    if(scan && cl_scanfile(acc->filename, &virname, NULL, tharg->root, tharg->limits, options) == CL_VIRUS) {
190
+		logg("Clamuko: %s: %s FOUND\n", acc->filename, virname);
191
+		virusaction(acc->filename, virname, tharg->copt);
192
+		acc->deny = 1;
193 193
 	    } else
194
-		acc.deny = 0;
194
+		acc->deny = 0;
195 195
 
196 196
 	    if(dazukoReturnAccess(&acc)) {
197 197
 		logg("!Can't return access to Dazuko.\n");
198 198
 		logg("Clamuko stopped.\n");
199 199
 		dazukoUnregister();
200
-		clamuko_running = 0;
200
+		/* clamuko_running = 0; */
201 201
 		clamuko_scanning = 0;
202 202
 		return NULL;
203 203
 	    }
... ...
@@ -207,7 +208,7 @@ void *clamukoth(void *arg)
207 207
     }
208 208
 
209 209
     /* can't be ;) */
210
-    clamuko_running = 0;
210
+    /* clamuko_running = 0; */
211 211
     return NULL;
212 212
 }
213 213
 
... ...
@@ -21,7 +21,8 @@
21 21
 #ifndef __CLAMUKO_H
22 22
 #define __CLAMUKO_H
23 23
 
24
-short int clamuko_running, clamuko_scanning;
24
+/* short int clamuko_running, clamuko_scanning; */
25
+short int clamuko_scanning;
25 26
 void *clamukoth(void *arg);
26 27
 
27 28
 #endif
... ...
@@ -1,147 +1,898 @@
1
-/* Dazuko Interface. Interace with Dazuko for file access control.
2
-   Copyright (C) 2002 H+BEDV Datentechnik GmbH
3
-   Written by John Ogness <jogness@antivir.de>
4
-
5
-   This library is free software; you can redistribute it and/or
6
-   modify it under the terms of the GNU Lesser General Public
7
-   License as published by the Free Software Foundation; either
8
-   version 2.1 of the License, or (at your option) any later version.
9
-
10
-   This library is distributed in the hope that it will be useful,
11
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
-   Lesser General Public License for more details.
14
-
15
-   You should have received a copy of the GNU Lesser General Public
16
-   License along with this library; if not, write to the Free Software
17
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
-*/
19
-
20 1
 #if HAVE_CONFIG_H
21 2
 #include "clamav-config.h"
22 3
 #endif
23 4
 
24 5
 #ifdef CLAMUKO
6
+/* Dazuko Interface. Interace with Dazuko for file access control.
7
+   Written by John Ogness <jogness@antivir.de>
25 8
 
9
+   Copyright (c) 2002, 2003 H+BEDV Datentechnik GmbH
10
+   All rights reserved.
11
+
12
+   Redistribution and use in source and binary forms, with or without
13
+   modification, are permitted provided that the following conditions
14
+   are met:
15
+
16
+   1. Redistributions of source code must retain the above copyright notice,
17
+   this list of conditions and the following disclaimer.
18
+
19
+   2. Redistributions in binary form must reproduce the above copyright notice,
20
+   this list of conditions and the following disclaimer in the documentation
21
+   and/or other materials provided with the distribution.
22
+
23
+   3. Neither the name of Dazuko nor the names of its contributors may be used
24
+   to endorse or promote products derived from this software without specific
25
+   prior written permission.
26
+
27
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30
+   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37
+   POSSIBILITY OF SUCH DAMAGE.
38
+*/
39
+
40
+#include <stdio.h>
26 41
 #include <stdlib.h>
27 42
 #include <sys/types.h>
28
-#include <sys/stat.h>
29 43
 #include <fcntl.h>
30 44
 #include <string.h>
31 45
 #include <unistd.h>
32
-#include <sys/ioctl.h>
46
+#include "dazukoio_xp.h"
33 47
 #include "dazukoio.h"
34 48
 
35
-int	_DAZUKO_DEVICE;
36
-int	_DAZUKO_DEV_MAJOR;
49
+#if !defined(NO_COMPAT12)
50
+#include "dazukoio_compat12.h"
51
+#endif
52
+
53
+#define ITOA_SIZE	32
37 54
 
38
-int dazukoRegister(void)
55
+dazuko_id_t	*_GLOBAL_DAZUKO = NULL;
56
+
57
+#if !defined(NO_COMPAT12)
58
+char		_GLOBAL_DAZUKO_COMPAT12 = 0;
59
+#endif
60
+
61
+static inline char char_to_hex(char c)
39 62
 {
40
-	char	buffer[10];
63
+	/* ugly, but fast */
64
+
65
+	switch (c)
66
+	{
67
+		case '1': return 1;
68
+		case '2': return 2;
69
+		case '3': return 3;
70
+		case '4': return 4;
71
+		case '5': return 5;
72
+		case '6': return 6;
73
+		case '7': return 7;
74
+		case '8': return 8;
75
+		case '9': return 9;
76
+		case 'a': case 'A': return 10;
77
+		case 'b': case 'B': return 11;
78
+		case 'c': case 'C': return 12;
79
+		case 'd': case 'D': return 13;
80
+		case 'e': case 'E': return 14;
81
+		case 'f': case 'F': return 15;
82
+	}
83
+
84
+	return 0;
85
+}
86
+
87
+static void unescape_string(char *string)
88
+{
89
+	char	*p;
90
+
91
+	for (p=string ; *p ; p++)
92
+	{
93
+		/* check if we have \x */
94
+		if ((*p == '\\') && (*(p+1) == 'x'))
95
+		{
96
+			/* this is not cheap, but it should not occur often */
97
+
98
+			/* check if we have two more values following \x */
99
+			if (*(p+2) && *(p+3))
100
+			{
101
+				*p = char_to_hex(*(p+2));
102
+				*p <<= 4;
103
+				*p |= char_to_hex(*(p+3));
104
+
105
+				memmove(p + 1, p + 4, strlen(p+4) + 1);
106
+			}
107
+		}
108
+	}
109
+}
110
+
111
+static int get_value(const char *key, const char *string, char *buffer, size_t buffer_size)
112
+{
113
+	const char	*p1;
114
+	const char	*p2;
115
+	size_t		size;
116
+
117
+	if (buffer == NULL || buffer_size < 1)
118
+		return -1;
119
+
120
+	buffer[0] = 0;
41 121
 
42
-	_DAZUKO_DEVICE = open("/dev/dazuko", 0);
43
-	if (_DAZUKO_DEVICE < 0)
122
+	if (key == NULL || string == NULL)
44 123
 		return -1;
45 124
 
46
-	bzero(buffer, sizeof(buffer));
47
-	if (read(_DAZUKO_DEVICE, buffer, sizeof(buffer)-1) < 1)
125
+	p1 = strstr(string, key);
126
+	if (p1 == NULL)
127
+		return -1;
128
+
129
+	p1 += strlen(key);
130
+
131
+	for (p2=p1 ; *p2 && *p2!='\n' ; p2++)
132
+		continue;
133
+
134
+	size = p2 - p1;
135
+	if (size >= buffer_size)
136
+		size = buffer_size - 1;
137
+
138
+	memcpy(buffer, p1, size);
139
+
140
+	buffer[size] = 0;
141
+
142
+	return 0;
143
+}
144
+
145
+int dazukoRegister(const char *groupName, const char *mode)
146
+{
147
+	return dazukoRegister_TS(&_GLOBAL_DAZUKO, groupName, mode);
148
+}
149
+
150
+int dazukoRegister_TS(dazuko_id_t **dazuko_id, const char *groupName, const char *mode)
151
+{
152
+	struct dazuko_request	*request;
153
+	char			buffer[ITOA_SIZE];
154
+	char			regMode[3];
155
+	dazuko_id_t		*temp_id;
156
+	ssize_t			size;
157
+	int			write_mode = 0;
158
+#if !defined(NO_COMPAT12)
159
+	int			compat12_ret;
160
+#endif
161
+
162
+	if (dazuko_id == NULL)
163
+		return -1;
164
+
165
+	/* set default group name if one was not given */
166
+	if (groupName == NULL)
167
+		groupName = "_GENERIC";
168
+
169
+	/* set default mode if one was not given */
170
+	if (mode == NULL)
171
+		mode = "r";
172
+
173
+	if (strcasecmp(mode, "r") == 0)
174
+	{
175
+		strncpy(regMode, "R", sizeof(regMode));
176
+		write_mode = 0;
177
+	}
178
+	else if (strcasecmp(mode, "r+") == 0 || strcasecmp(mode, "rw") == 0)
179
+	{
180
+		strncpy(regMode, "RW", sizeof(regMode));
181
+		write_mode = 1;
182
+	}
183
+	else
48 184
 	{
49
-		close(_DAZUKO_DEVICE);
50 185
 		return -1;
51 186
 	}
52
-	_DAZUKO_DEV_MAJOR = atoi(buffer);
187
+	regMode[sizeof(regMode) - 1] = 0;
188
+
189
+#if !defined(NO_COMPAT12)
190
+	if (_GLOBAL_DAZUKO_COMPAT12)
191
+	{
192
+		compat12_ret = dazukoRegister_TS_compat12_wrapper(dazuko_id, groupName);
193
+
194
+		if (compat12_ret == 0)
195
+			(*dazuko_id)->write_mode = write_mode;
196
+
197
+		return compat12_ret;
198
+	}
199
+#endif
200
+
201
+	/* create temporary id */
202
+	temp_id = (dazuko_id_t *)malloc(sizeof(*temp_id));
203
+	if (temp_id == NULL)
204
+		return -1;
205
+
206
+	memset(temp_id, 0, sizeof(*temp_id));
207
+
208
+	/* open device */
209
+	temp_id->device = open("/dev/dazuko", O_RDWR);
210
+	if (temp_id->device < 0)
211
+	{
212
+		free(temp_id);
213
+		return -1;
214
+	}
215
+
216
+	/* read device major number */
217
+	memset(buffer, 0, sizeof(buffer));
218
+	if (read(temp_id->device, buffer, sizeof(buffer)-1) < 1)
219
+	{
220
+		close(temp_id->device);
221
+		free(temp_id);
222
+		return -1;
223
+	}
224
+
225
+	temp_id->dev_major = atoi(buffer);
226
+	if (temp_id->dev_major < 0)
227
+	{
228
+		close(temp_id->device);
229
+		free(temp_id);
230
+		return -1;
231
+	}
232
+
233
+	request = (struct dazuko_request *)malloc(sizeof(*request));
234
+	if (request == NULL)
235
+	{
236
+		close(temp_id->device);
237
+		free(temp_id);
238
+		return -1;
239
+	}
240
+
241
+	memset(request, 0, sizeof(*request));
242
+
243
+	request->type[0] = REGISTER;
244
+
245
+	size = 1 + 2 + 1 + strlen(regMode); /* \nRM=mode */
246
+	size = 1 + 2 + 1 + strlen(groupName); /* \nGN=groupName */
247
+	size += 1; /* \0 */
248
+
249
+	request->buffer = (char *)malloc(size);
250
+	if (request->buffer == NULL)
251
+	{
252
+		close(temp_id->device);
253
+		free(temp_id);
254
+		free(request);
255
+		return -1;
256
+	}
257
+	snprintf(request->buffer, size, "\nRM=%s\nGN=%s", regMode, groupName);
258
+	request->buffer[size - 1] = 0;
259
+
260
+	request->buffer_size = strlen(request->buffer) + 1;
261
+
262
+	size = 4096;
263
+	request->reply_buffer = (char *)malloc(size);
264
+	if (request->reply_buffer == NULL)
265
+	{
266
+		close(temp_id->device);
267
+		free(temp_id);
268
+		free(request->buffer);
269
+		free(request);
270
+		return -1;
271
+	}
272
+	memset(request->reply_buffer, 0, size);
273
+	request->reply_buffer_size = size;
274
+
275
+	snprintf(buffer, sizeof(buffer), "\nRA=%lu", (unsigned long)request);
276
+	buffer[sizeof(buffer)-1] = 0;
277
+	size = strlen(buffer) + 1;
278
+
279
+	if (write(temp_id->device, buffer, size) != size)
280
+	{
281
+		close(temp_id->device);
282
+		free(temp_id);
283
+		free(request->buffer);
284
+		free(request->reply_buffer);
285
+		free(request);
286
+
287
+#if !defined(NO_COMPAT12)
288
+		/* we try compat12 mode */
289
+		compat12_ret = dazukoRegister_TS_compat12_wrapper(dazuko_id, groupName);
290
+		if (compat12_ret == 0)
291
+		{
292
+			(*dazuko_id)->write_mode = write_mode;
293
+			_GLOBAL_DAZUKO_COMPAT12 = 1;
294
+		}
295
+
296
+		return compat12_ret;
297
+#else
298
+		return -1;
299
+#endif
300
+	}
301
+
302
+	if (get_value("\nID=", request->reply_buffer, buffer, sizeof(buffer)) != 0)
303
+	{
304
+		close(temp_id->device);
305
+		free(temp_id);
306
+		free(request->buffer);
307
+		free(request->reply_buffer);
308
+		free(request);
309
+
310
+#if !defined(NO_COMPAT12)
311
+		/* we try compat12 mode */
312
+		compat12_ret = dazukoRegister_TS_compat12_wrapper(dazuko_id, groupName);
313
+		if (compat12_ret == 0)
314
+		{
315
+			(*dazuko_id)->write_mode = write_mode;
316
+			_GLOBAL_DAZUKO_COMPAT12 = 1;
317
+		}
318
+
319
+		return compat12_ret;
320
+#else
321
+		return -1;
322
+#endif
323
+	}
324
+
325
+	temp_id->id = atoi(buffer);
326
+
327
+	if (temp_id->id < 0)
328
+	{
329
+		free(request->buffer);
330
+		free(request->reply_buffer);
331
+		free(request);
332
+
333
+		return -1;
334
+	}
335
+
336
+	temp_id->write_mode = write_mode;
337
+
338
+	free(request->buffer);
339
+	free(request->reply_buffer);
340
+	free(request);
341
+
342
+	*dazuko_id = temp_id;
53 343
 
54 344
 	return 0;
55 345
 }
56 346
 
57 347
 int dazukoSetAccessMask(unsigned long accessMask)
58 348
 {
59
-	struct option_t	opt;
349
+	return dazukoSetAccessMask_TS(_GLOBAL_DAZUKO, accessMask);
350
+}
351
+
352
+int dazukoSetAccessMask_TS(dazuko_id_t *dazuko_id, unsigned long accessMask)
353
+{
354
+	struct dazuko_request	*request;
355
+	ssize_t			size;
356
+	char			buffer[ITOA_SIZE];
357
+
358
+	if (dazuko_id == NULL)
359
+		return -1;
360
+
361
+#if !defined(NO_COMPAT12)
362
+	if (_GLOBAL_DAZUKO_COMPAT12)
363
+		return dazukoSetAccessMask_TS_compat12(dazuko_id, accessMask);
364
+#endif
365
+
366
+	if (dazuko_id->device < 0 || dazuko_id->dev_major < 0 || dazuko_id->id < 0)
367
+		return -1;
368
+
369
+	request = (struct dazuko_request *)malloc(sizeof(*request));
370
+	if (request == NULL)
371
+		return -1;
372
+
373
+	memset(request, 0, sizeof(*request));
374
+
375
+	request->type[0] = SET_ACCESS_MASK;
376
+
377
+	size = 1 + 2 + 1 + ITOA_SIZE; /* \nID=id */
378
+	size += 1 + 2 + 1 + ITOA_SIZE; /* \nAM=accessMask */
379
+	size += 1; /* \0 */
380
+
381
+	request->buffer = (char *)malloc(size);
382
+	if (request->buffer == NULL)
383
+	{
384
+		free(request);
385
+		return -1;
386
+	}
387
+	snprintf(request->buffer, size, "\nID=%d\nAM=%lu", dazuko_id->id, accessMask);
388
+	request->buffer[size - 1] = 0;
60 389
 
61
-	bzero(&opt, sizeof(opt));
390
+	request->buffer_size = strlen(request->buffer) + 1;
62 391
 
63
-	opt.command = SET_ACCESS_MASK;
64
-	opt.buffer[0] = (char)accessMask;
65
-	opt.buffer_length = 1;
392
+	snprintf(buffer, sizeof(buffer), "\nRA=%lu", (unsigned long)request);
393
+	buffer[sizeof(buffer)-1] = 0;
394
+	size = strlen(buffer) + 1;
66 395
 
67
-	if (ioctl(_DAZUKO_DEVICE, _IOW(_DAZUKO_DEV_MAJOR, IOCTL_SET_OPTION, void *), &opt) != 0)
396
+	if (write(dazuko_id->device, buffer, size) != size)
397
+	{
398
+		free(request->buffer);
399
+		free(request);
68 400
 		return -1;
401
+	}
402
+
403
+	free(request->buffer);
404
+	free(request);
69 405
 
70 406
 	return 0;
71 407
 }
72 408
 
73
-int dazuko_set_path(const char *path, int command)
409
+static int dazuko_set_path(dazuko_id_t *dazuko_id, const char *path, int type)
74 410
 {
75
-	struct option_t	opt;
411
+	struct dazuko_request	*request;
412
+	ssize_t			size;
413
+	char			buffer[ITOA_SIZE];
414
+
415
+	if (dazuko_id == NULL)
416
+		return -1;
417
+
418
+	if (dazuko_id->device < 0 || dazuko_id->dev_major < 0 || dazuko_id->id < 0)
419
+		return -1;
76 420
 
77 421
 	if (path == NULL)
78 422
 		return -1;
79 423
 
80
-	bzero(&opt, sizeof(opt));
424
+	request = (struct dazuko_request *)malloc(sizeof(*request));
425
+	if (request == NULL)
426
+		return -1;
427
+
428
+	memset(request, 0, sizeof(*request));
429
+
430
+	request->type[0] = type;
81 431
 
82
-	opt.command = command;
83
-	strncpy(opt.buffer, path, sizeof(opt.buffer) - 1);
84
-	opt.buffer_length = strlen(opt.buffer) + 1;
432
+	size = 1 + 2 + 1 + ITOA_SIZE; /* \nID=id */
433
+	size += 1 + 2 + 1 + strlen(path); /* \nPT=path */
434
+	size += 1; /* \0 */
85 435
 
86
-	if (ioctl(_DAZUKO_DEVICE, _IOW(_DAZUKO_DEV_MAJOR, IOCTL_SET_OPTION, void *), &opt) != 0)
436
+	request->buffer = (char *)malloc(size);
437
+	if (request->buffer == NULL)
438
+	{
439
+		free(request);
87 440
 		return -1;
441
+	}
442
+	snprintf(request->buffer, size, "\nID=%d\nPT=%s", dazuko_id->id, path);
443
+	request->buffer[size - 1] = 0;
444
+
445
+	request->buffer_size = strlen(request->buffer) + 1;
446
+
447
+	snprintf(buffer, sizeof(buffer), "\nRA=%lu", (unsigned long)request);
448
+	buffer[sizeof(buffer)-1] = 0;
449
+	size = strlen(buffer) + 1;
450
+
451
+	if (write(dazuko_id->device, buffer, size) != size)
452
+	{
453
+		free(request->buffer);
454
+		free(request);
455
+		return -1;
456
+	}
457
+
458
+	free(request->buffer);
459
+	free(request);
88 460
 
89 461
 	return 0;
90 462
 }
91 463
 
92 464
 int dazukoAddIncludePath(const char *path)
93 465
 {
94
-	return dazuko_set_path(path, ADD_INCLUDE_PATH);
466
+	return dazukoAddIncludePath_TS(_GLOBAL_DAZUKO, path);
467
+}
468
+
469
+int dazukoAddIncludePath_TS(dazuko_id_t *dazuko_id, const char *path)
470
+{
471
+#if !defined(NO_COMPAT12)
472
+	if (_GLOBAL_DAZUKO_COMPAT12)
473
+		return dazukoAddIncludePath_TS_compat12(dazuko_id, path);
474
+#endif
475
+
476
+	return dazuko_set_path(dazuko_id, path, ADD_INCLUDE_PATH);
95 477
 }
96 478
 
97 479
 int dazukoAddExcludePath(const char *path)
98 480
 {
99
-	return dazuko_set_path(path, ADD_EXCLUDE_PATH);
481
+	return dazukoAddExcludePath_TS(_GLOBAL_DAZUKO, path);
482
+}
483
+
484
+int dazukoAddExcludePath_TS(dazuko_id_t *dazuko_id, const char *path)
485
+{
486
+#if !defined(NO_COMPAT12)
487
+	if (_GLOBAL_DAZUKO_COMPAT12)
488
+		return dazukoAddExcludePath_TS_compat12(dazuko_id, path);
489
+#endif
490
+
491
+	return dazuko_set_path(dazuko_id, path, ADD_EXCLUDE_PATH);
100 492
 }
101 493
 
102 494
 int dazukoRemoveAllPaths(void)
103 495
 {
104
-	struct option_t	opt;
496
+	return dazukoRemoveAllPaths_TS(_GLOBAL_DAZUKO);
497
+}
105 498
 
106
-	bzero(&opt, sizeof(opt));
499
+int dazukoRemoveAllPaths_TS(dazuko_id_t *dazuko_id)
500
+{
501
+	struct dazuko_request	*request;
502
+	ssize_t			size;
503
+	char			buffer[ITOA_SIZE];
504
+
505
+	if (dazuko_id == NULL)
506
+		return -1;
507
+
508
+#if !defined(NO_COMPAT12)
509
+	if (_GLOBAL_DAZUKO_COMPAT12)
510
+		return dazukoRemoveAllPaths_TS_compat12(dazuko_id);
511
+#endif
512
+
513
+	if (dazuko_id->device < 0 || dazuko_id->dev_major < 0 || dazuko_id->id < 0)
514
+		return -1;
515
+
516
+	request = (struct dazuko_request *)malloc(sizeof(*request));
517
+	if (request == NULL)
518
+		return -1;
519
+
520
+	memset(request, 0, sizeof(*request));
521
+
522
+	request->type[0] = REMOVE_ALL_PATHS;
523
+
524
+	size = 1 + 2 + 1 + ITOA_SIZE; /* \nID=id */
525
+	size += 1; /* \0 */
526
+
527
+	request->buffer = (char *)malloc(size);
528
+	if (request->buffer == NULL)
529
+	{
530
+		free(request);
531
+		return -1;
532
+	}
533
+	snprintf(request->buffer, size, "\nID=%d", dazuko_id->id);
534
+	request->buffer[size - 1] = 0;
107 535
 
108
-	opt.command = REMOVE_ALL_PATHS;
109
-	opt.buffer_length = 0;
536
+	request->buffer_size = strlen(request->buffer) + 1;
110 537
 
111
-	if (ioctl(_DAZUKO_DEVICE, _IOW(_DAZUKO_DEV_MAJOR, IOCTL_SET_OPTION, void *), &opt) != 0)
538
+	snprintf(buffer, sizeof(buffer), "\nRA=%lu", (unsigned long)request);
539
+	buffer[sizeof(buffer)-1] = 0;
540
+	size = strlen(buffer) + 1;
541
+
542
+	if (write(dazuko_id->device, buffer, size) != size)
543
+	{
544
+		free(request->buffer);
545
+		free(request);
112 546
 		return -1;
547
+	}
548
+
549
+	free(request->buffer);
550
+	free(request);
113 551
 
114 552
 	return 0;
553
+}
115 554
 
555
+int dazukoGetAccess(struct dazuko_access **acc)
556
+{
557
+	return dazukoGetAccess_TS(_GLOBAL_DAZUKO, acc);
116 558
 }
117 559
 
118
-int dazukoGetAccess(struct access_t *acc)
560
+int dazukoGetAccess_TS(dazuko_id_t *dazuko_id, struct dazuko_access **acc)
119 561
 {
562
+	struct dazuko_request	*request;
563
+	struct dazuko_access	*temp_acc;
564
+	ssize_t			size;
565
+	size_t			filename_size;
566
+	char			buffer[ITOA_SIZE];
567
+#if !defined(NO_COMPAT12)
568
+	int			compat12_ret;
569
+#endif
570
+
571
+	if (dazuko_id == NULL)
572
+		return -1;
573
+
574
+#if !defined(NO_COMPAT12)
575
+	if (_GLOBAL_DAZUKO_COMPAT12)
576
+	{
577
+		compat12_ret = dazukoGetAccess_TS_compat12_wrapper(dazuko_id, acc);
578
+
579
+		if (compat12_ret == 0 && !(dazuko_id->write_mode))
580
+		{
581
+			/* we are in read_only mode so we return the access immediately */
582
+
583
+			dazukoReturnAccess_TS_compat12_wrapper(dazuko_id, acc, 1, 0);
584
+
585
+			/* this could be dangerous, we do not check if the return was successfull! */
586
+		}
587
+
588
+		return compat12_ret;
589
+	}
590
+#endif
591
+
592
+	if (dazuko_id->device < 0 || dazuko_id->dev_major < 0 || dazuko_id->id < 0)
593
+		return -1;
594
+
120 595
 	if (acc == NULL)
121 596
 		return -1;
122 597
 
123
-	bzero(acc, sizeof(struct access_t));
598
+	request = (struct dazuko_request *)malloc(sizeof(*request));
599
+	if (request == NULL)
600
+		return -1;
601
+
602
+	memset(request, 0, sizeof(*request));
603
+
604
+	request->type[0] = GET_AN_ACCESS;
605
+
606
+	size = 1 + 2 + 1 + ITOA_SIZE; /* \nID=id */
607
+	size += 1; /* \0 */
608
+
609
+	request->buffer = (char *)malloc(size);
610
+	if (request->buffer == NULL)
611
+	{
612
+		free(request);
613
+		return -1;
614
+	}
615
+	snprintf(request->buffer, size, "\nID=%d", dazuko_id->id);
616
+	request->buffer[size - 1] = 0;
617
+
618
+	request->buffer_size = strlen(request->buffer) + 1;
619
+
620
+	size = 1 + 2 + 1 + DAZUKO_FILENAME_MAX_LENGTH; /* \nFN=filename */
621
+	size += 1024; /* miscellaneous access attributes */
622
+	size += 1; /* \0 */
623
+	request->reply_buffer = (char *)malloc(size);
624
+	if (request->reply_buffer == NULL)
625
+	{
626
+		free(request->buffer);
627
+		free(request);
628
+		return -1;
629
+	}
630
+	memset(request->reply_buffer, 0, size);
631
+	request->reply_buffer_size = size;
632
+
633
+	temp_acc = (struct dazuko_access *)malloc(sizeof(*temp_acc));
634
+	if (temp_acc == NULL)
635
+	{
636
+		free(request->reply_buffer);
637
+		free(request->buffer);
638
+		free(request);
639
+		return -1;
640
+	}
641
+
642
+	memset(temp_acc, 0, sizeof(*temp_acc));
643
+
644
+	filename_size = DAZUKO_FILENAME_MAX_LENGTH + 1;
645
+	temp_acc->filename = (char *)malloc(filename_size);
646
+	if (temp_acc->filename == NULL)
647
+	{
648
+		free(temp_acc);
649
+		free(request->reply_buffer);
650
+		free(request->buffer);
651
+		free(request);
652
+		return -1;
653
+	}
654
+
655
+	snprintf(buffer, sizeof(buffer), "\nRA=%lu", (unsigned long)request);
656
+	buffer[sizeof(buffer)-1] = 0;
657
+	size = strlen(buffer) + 1;
124 658
 
125
-	if (ioctl(_DAZUKO_DEVICE, _IOR(_DAZUKO_DEV_MAJOR, IOCTL_GET_AN_ACCESS, struct access_t *), acc) != 0)
659
+	if (write(dazuko_id->device, buffer, size) != size)
660
+	{
661
+		free(temp_acc->filename);
662
+		free(temp_acc);
663
+		free(request->reply_buffer);
664
+		free(request->buffer);
665
+		free(request);
126 666
 		return -1;
667
+	}
668
+
669
+	if (request->reply_buffer_size_used > 0)
670
+	{
671
+		if (get_value("\nFN=", request->reply_buffer, temp_acc->filename, filename_size) == 0)
672
+		{
673
+			temp_acc->set_filename = 1;
674
+			unescape_string(temp_acc->filename);
675
+		}
676
+
677
+		if (get_value("\nEV=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
678
+		{
679
+			temp_acc->event = atoi(buffer);
680
+			temp_acc->set_event = 1;
681
+		}
682
+
683
+		if (get_value("\nFL=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
684
+		{
685
+			temp_acc->flags = atoi(buffer);
686
+			temp_acc->set_flags = 1;
687
+		}
688
+
689
+		if (get_value("\nMD=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
690
+		{
691
+			temp_acc->mode = atoi(buffer);
692
+			temp_acc->set_mode = 1;
693
+		}
694
+
695
+		if (get_value("\nUI=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
696
+		{
697
+			temp_acc->uid = atoi(buffer);
698
+			temp_acc->set_uid = 1;
699
+		}
700
+
701
+		if (get_value("\nPI=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
702
+		{
703
+			temp_acc->pid = atoi(buffer);
704
+			temp_acc->set_pid = 1;
705
+		}
706
+
707
+		if (get_value("\nFS=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
708
+		{
709
+			temp_acc->file_size = atol(buffer);
710
+			temp_acc->set_file_size = 1;
711
+		}
712
+
713
+		if (get_value("\nFU=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
714
+		{
715
+			temp_acc->file_uid = atoi(buffer);
716
+			temp_acc->set_file_uid = 1;
717
+		}
718
+
719
+		if (get_value("\nFG=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
720
+		{
721
+			temp_acc->file_gid = atoi(buffer);
722
+			temp_acc->set_file_gid = 1;
723
+		}
724
+
725
+		if (get_value("\nDT=", request->reply_buffer, buffer, sizeof(buffer)) == 0)
726
+		{
727
+			temp_acc->file_device = atoi(buffer);
728
+			temp_acc->set_file_device = 1;
729
+		}
730
+	}
731
+
732
+	free(request->reply_buffer);
733
+	free(request->buffer);
734
+	free(request);
735
+
736
+	*acc = temp_acc;
127 737
 
128 738
 	return 0;
129 739
 }
130 740
 
131
-int dazukoReturnAccess(struct access_t *acc)
741
+int dazukoReturnAccess(struct dazuko_access **acc)
742
+{
743
+	return dazukoReturnAccess_TS(_GLOBAL_DAZUKO, acc);
744
+}
745
+
746
+int dazukoReturnAccess_TS(dazuko_id_t *dazuko_id, struct dazuko_access **acc)
132 747
 {
748
+	struct dazuko_request	*request;
749
+	ssize_t			size;
750
+	char			buffer[ITOA_SIZE];
751
+
752
+	if (dazuko_id == NULL)
753
+		return -1;
754
+
755
+#if !defined(NO_COMPAT12)
756
+	if (_GLOBAL_DAZUKO_COMPAT12)
757
+		return dazukoReturnAccess_TS_compat12_wrapper(dazuko_id, acc, dazuko_id->write_mode, 1);
758
+#endif
759
+
760
+	if (dazuko_id->device < 0 || dazuko_id->dev_major < 0 || dazuko_id->id < 0)
761
+		return -1;
762
+
133 763
 	if (acc == NULL)
134 764
 		return -1;
135 765
 
136
-	if (ioctl(_DAZUKO_DEVICE, _IOW(_DAZUKO_DEV_MAJOR, IOCTL_RETURN_ACCESS, struct access_t *), acc) != 0)
766
+	if (*acc == NULL)
137 767
 		return -1;
138 768
 
769
+	if (dazuko_id->write_mode)
770
+	{
771
+		request = (struct dazuko_request *)malloc(sizeof(*request));
772
+		if (request == NULL)
773
+			return -1;
774
+
775
+		memset(request, 0, sizeof(*request));
776
+
777
+		request->type[0] = RETURN_AN_ACCESS;
778
+
779
+		size = 1 + 2 + 1 + ITOA_SIZE; /* \nID=id */
780
+		size += 1 + 2 + 1 + ITOA_SIZE; /* \nDN=deny */
781
+		size += 1; /* \0 */
782
+
783
+		request->buffer = (char *)malloc(size);
784
+		if (request->buffer == NULL)
785
+		{
786
+			free(request);
787
+			return -1;
788
+		}
789
+		snprintf(request->buffer, size, "\nID=%d\nDN=%d", dazuko_id->id, (*acc)->deny == 0 ? 0 : 1);
790
+		request->buffer[size - 1] = 0;
791
+
792
+		request->buffer_size = strlen(request->buffer) + 1;
793
+
794
+		snprintf(buffer, sizeof(buffer), "\nRA=%lu", (unsigned long)request);
795
+		buffer[sizeof(buffer)-1] = 0;
796
+		size = strlen(buffer) + 1;
797
+
798
+		if (write(dazuko_id->device, buffer, size) != size)
799
+		{
800
+			/* there could be big problems if this happens */
801
+
802
+			if ((*acc)->filename != NULL)
803
+				free((*acc)->filename);
804
+			free(*acc);
805
+			*acc = NULL;
806
+			free(request->buffer);
807
+			free(request);
808
+			return -1;
809
+		}
810
+
811
+		free(request->buffer);
812
+		free(request);
813
+	}
814
+
815
+	if ((*acc)->filename != NULL)
816
+		free((*acc)->filename);
817
+	free(*acc);
818
+	*acc = NULL;
819
+
139 820
 	return 0;
140 821
 }
141 822
 
142 823
 int dazukoUnregister(void)
143 824
 {
144
-	return close(_DAZUKO_DEVICE);
825
+	return dazukoUnregister_TS(&_GLOBAL_DAZUKO);
145 826
 }
146 827
 
828
+int dazukoUnregister_TS(dazuko_id_t **dazuko_id)
829
+{
830
+	struct dazuko_request	*request;
831
+	ssize_t			size;
832
+	char			buffer[ITOA_SIZE];
833
+
834
+	if (dazuko_id == NULL)
835
+		return -1;
836
+
837
+#if !defined(NO_COMPAT12)
838
+	if (_GLOBAL_DAZUKO_COMPAT12)
839
+		return dazukoUnregister_TS_compat12_wrapper(dazuko_id);
840
+#endif
841
+
842
+	if (*dazuko_id == NULL)
843
+		return -1;
844
+
845
+	if ((*dazuko_id)->device < 0)
846
+		return -1;
847
+
848
+	if ((*dazuko_id)->dev_major >= 0 && (*dazuko_id)->id >= 0)
849
+	{
850
+		request = (struct dazuko_request *)malloc(sizeof(*request));
851
+		if (request == NULL)
852
+			return -1;
853
+
854
+		memset(request, 0, sizeof(*request));
855
+
856
+		request->type[0] = UNREGISTER;
857
+
858
+		size = 1 + 2 + 1 + ITOA_SIZE; /* \nID=id */
859
+		size += 1; /* \0 */
860
+
861
+		request->buffer = (char *)malloc(size);
862
+		if (request->buffer == NULL)
863
+		{
864
+			free(request);
865
+			return -1;
866
+		}
867
+		snprintf(request->buffer, size, "\nID=%d", (*dazuko_id)->id);
868
+		request->buffer[size - 1] = 0;
869
+
870
+		request->buffer_size = strlen(request->buffer) + 1;
871
+
872
+		snprintf(buffer, sizeof(buffer), "\nRA=%lu", (unsigned long)request);
873
+		buffer[sizeof(buffer)-1] = 0;
874
+		size = strlen(buffer) + 1;
875
+
876
+		if (write((*dazuko_id)->device, buffer, size) != size)
877
+		{
878
+			/* there could be big problems if this happens */
879
+
880
+			close((*dazuko_id)->device);
881
+			free(*dazuko_id);
882
+			*dazuko_id = NULL;
883
+			free(request->buffer);
884
+			free(request);
885
+			return -1;
886
+		}
887
+
888
+		free(request->buffer);
889
+		free(request);
890
+	}
891
+
892
+	close((*dazuko_id)->device);
893
+	free(*dazuko_id);
894
+	*dazuko_id = NULL;
895
+
896
+	return 0;
897
+}
147 898
 #endif
... ...
@@ -1,44 +1,102 @@
1
+#if HAVE_CONFIG_H
2
+#include "clamav-config.h"
3
+#endif
4
+
5
+#ifdef CLAMUKO
1 6
 /* Dazuko Interface. Interace with Dazuko for file access control.
2
-   Copyright (C) 2002 H+BEDV Datentechnik GmbH
3 7
    Written by John Ogness <jogness@antivir.de>
4 8
 
5
-   This library is free software; you can redistribute it and/or
6
-   modify it under the terms of the GNU Lesser General Public
7
-   License as published by the Free Software Foundation; either
8
-   version 2.1 of the License, or (at your option) any later version.
9
+   Copyright (c) 2002, 2003 H+BEDV Datentechnik GmbH
10
+   All rights reserved.
9 11
 
10
-   This library is distributed in the hope that it will be useful,
11
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
-   Lesser General Public License for more details.
12
+   Redistribution and use in source and binary forms, with or without
13
+   modification, are permitted provided that the following conditions
14
+   are met:
14 15
 
15
-   You should have received a copy of the GNU Lesser General Public
16
-   License along with this library; if not, write to the Free Software
17
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
-*/
16
+   1. Redistributions of source code must retain the above copyright notice,
17
+   this list of conditions and the following disclaimer.
19 18
 
20
-#ifdef CLAMUKO
19
+   2. Redistributions in binary form must reproduce the above copyright notice,
20
+   this list of conditions and the following disclaimer in the documentation
21
+   and/or other materials provided with the distribution.
22
+
23
+   3. Neither the name of Dazuko nor the names of its contributors may be used
24
+   to endorse or promote products derived from this software without specific
25
+   prior written permission.
26
+
27
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28
+   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30
+   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31
+   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32
+   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33
+   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34
+   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35
+   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36
+   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37
+   POSSIBILITY OF SUCH DAMAGE.
38
+*/
21 39
 
22 40
 #ifndef DAZUKOIO_H
23 41
 #define DAZUKOIO_H
24 42
 
25
-#include "dazuko.h"
43
+/* event types */
44
+#define	DAZUKO_ON_OPEN			1
45
+#define	DAZUKO_ON_CLOSE			2
46
+#define	DAZUKO_ON_EXEC 			4
47
+#define	DAZUKO_ON_CLOSE_MODIFIED	8
48
+#define	DAZUKO_ON_UNLINK		16
49
+#define	DAZUKO_ON_RMDIR			32
26 50
 
27
-struct option_t
51
+struct dazuko_access
28 52
 {
29
-	int	command;
30
-	int	buffer_length;
31
-	char	buffer[DAZUKO_FILENAME_MAX_LENGTH];
53
+	int		deny;
54
+	int		event;
55
+	char		set_event;
56
+	int		flags;
57
+	char		set_flags;
58
+	int		mode;
59
+	char		set_mode;
60
+	int 		uid;
61
+	char		set_uid;
62
+	int		pid;
63
+	char		set_pid;
64
+	char		*filename;
65
+	char		set_filename;
66
+	unsigned long	file_size;
67
+	char		set_file_size;
68
+	int		file_uid;
69
+	char		set_file_uid;
70
+	int		file_gid;
71
+	char		set_file_gid;
72
+	int		file_mode;
73
+	char		set_file_mode;
74
+	int		file_device;
75
+	char		set_file_device;
32 76
 };
33 77
 
34
-int dazukoRegister(void);
78
+struct dazuko_id;
79
+typedef struct dazuko_id dazuko_id_t;
80
+
81
+/* single-threaded API */
82
+int dazukoRegister(const char *groupName, const char *mode);
35 83
 int dazukoSetAccessMask(unsigned long accessMask);
36 84
 int dazukoAddIncludePath(const char *path);
37 85
 int dazukoAddExcludePath(const char *path);
38 86
 int dazukoRemoveAllPaths(void);
39
-int dazukoGetAccess(struct access_t *acc);
40
-int dazukoReturnAccess(struct access_t *acc);
87
+int dazukoGetAccess(struct dazuko_access **acc);
88
+int dazukoReturnAccess(struct dazuko_access **acc);
41 89
 int dazukoUnregister(void);
42 90
 
91
+/* thread-safe API (as long as each thread has its own "dazuko_id_t") */
92
+int dazukoRegister_TS(dazuko_id_t **dazuko, const char *groupName, const char *mode);
93
+int dazukoSetAccessMask_TS(dazuko_id_t *dazuko, unsigned long accessMask);
94
+int dazukoAddIncludePath_TS(dazuko_id_t *dazuko, const char *path);
95
+int dazukoAddExcludePath_TS(dazuko_id_t *dazuko, const char *path);
96
+int dazukoRemoveAllPaths_TS(dazuko_id_t *dazuko);
97
+int dazukoGetAccess_TS(dazuko_id_t *dazuko, struct dazuko_access **acc);
98
+int dazukoReturnAccess_TS(dazuko_id_t *dazuko, struct dazuko_access **acc);
99
+int dazukoUnregister_TS(dazuko_id_t **dazuko);
100
+
43 101
 #endif
44 102
 #endif
... ...
@@ -17,6 +17,10 @@
17 17
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 18
  */
19 19
 
20
+#if HAVE_CONFIG_H
21
+#include "clamav-config.h"
22
+#endif
23
+
20 24
 #include <pthread.h>
21 25
 #include <errno.h>
22 26
 #include <signal.h>
... ...
@@ -319,19 +323,22 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
319 319
     pthread_attr_init(&thattr);
320 320
     pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED);
321 321
 
322
+    if(cfgopt(copt, "ClamukoScanOnLine"))
322 323
 #ifdef CLAMUKO
323
-    pthread_attr_init(&clamuko_attr);
324
-    pthread_attr_setdetachstate(&clamuko_attr, PTHREAD_CREATE_JOINABLE);
324
+    {
325
+	pthread_attr_init(&clamuko_attr);
326
+	pthread_attr_setdetachstate(&clamuko_attr, PTHREAD_CREATE_JOINABLE);
325 327
 
326
-    tharg = (struct thrarg *) mmalloc(sizeof(struct thrarg));
327
-    tharg->copt = copt;
328
-    tharg->root = root;
329
-    tharg->limits = &limits;
330
-    tharg->options = options;
328
+	tharg = (struct thrarg *) mmalloc(sizeof(struct thrarg));
329
+	tharg->copt = copt;
330
+	tharg->root = root;
331
+	tharg->limits = &limits;
332
+	tharg->options = options;
331 333
 
332
-    pthread_create(&clamuko_pid, &clamuko_attr, clamukoth, tharg);
334
+	pthread_create(&clamuko_pid, &clamuko_attr, clamukoth, tharg);
335
+    }
333 336
 #else
334
-    logg("!Clamuko is not available.\n");
337
+	logg("!Clamuko is not available.\n");
335 338
 #endif
336 339
 
337 340
     /* set up signal handling */
... ...
@@ -437,11 +444,13 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
437 437
 		exit(-1);
438 438
 	    }
439 439
 #ifdef CLAMUKO
440
-	    logg("Stopping and restarting Clamuko.\n");
441
-	    pthread_kill(clamuko_pid, SIGUSR1);
442
-	    pthread_join(clamuko_pid, NULL);
443
-	    tharg->root = root;
444
-	    pthread_create(&clamuko_pid, &clamuko_attr, clamukoth, tharg);
440
+	    if(cfgopt(copt, "ClamukoScanOnLine")) {
441
+		logg("Stopping and restarting Clamuko.\n");
442
+		pthread_kill(clamuko_pid, SIGUSR1);
443
+		pthread_join(clamuko_pid, NULL);
444
+		tharg->root = root;
445
+		pthread_create(&clamuko_pid, &clamuko_attr, clamukoth, tharg);
446
+	    }
445 447
 #endif
446 448
 	} else {
447 449
 	    pthread_mutex_unlock(&reload_mutex);
... ...
@@ -449,9 +458,11 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
449 449
     }
450 450
 
451 451
 #ifdef CLAMUKO
452
-    logg("Stopping Clamuko.\n");
453
-    pthread_kill(clamuko_pid, SIGUSR1);
454
-    pthread_join(clamuko_pid, NULL);
452
+    if(cfgopt(copt, "ClamukoScanOnLine")) {
453
+	logg("Stopping Clamuko.\n");
454
+	pthread_kill(clamuko_pid, SIGUSR1);
455
+	pthread_join(clamuko_pid, NULL);
456
+    }
455 457
 #endif
456 458
     logg("Exiting (clean)\n");
457 459
     return 0;
... ...
@@ -998,6 +998,7 @@ Optional Features:
998 998
   --enable-fast-install=PKGS  optimize for fast installation default=yes
999 999
   --disable-libtool-lock  avoid locking (might break parallel builds)
1000 1000
   --disable-bzip2	  Disable bzip2 support.
1001
+  --disable-clamuko	  Disable clamuko support (Linux and FreeBSD only)
1001 1002
   --enable-milter	  Build clamav-milter (if milter library found)
1002 1003
   --disable-dsig	  Disable digital signature support.
1003 1004
   --disable-pthreads      Disable POSIX threads support
... ...
@@ -4542,7 +4543,7 @@ test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
4542 4542
 case $host in
4543 4543
 *-*-irix6*)
4544 4544
   # Find out which ABI we are using.
4545
-  echo '#line 4545 "configure"' > conftest.$ac_ext
4545
+  echo '#line 4546 "configure"' > conftest.$ac_ext
4546 4546
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
4547 4547
   (eval $ac_compile) 2>&5
4548 4548
   ac_status=$?
... ...
@@ -5078,7 +5079,7 @@ chmod -w .
5078 5078
 save_CFLAGS="$CFLAGS"
5079 5079
 CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
5080 5080
 compiler_c_o=no
5081
-if { (eval echo configure:5081: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
5081
+if { (eval echo configure:5082: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
5082 5082
   # The compiler can only warn and ignore the option if not recognized
5083 5083
   # So say no if there are warnings
5084 5084
   if test -s out/conftest.err; then
... ...
@@ -6871,7 +6872,7 @@ else
6871 6871
     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
6872 6872
   lt_status=$lt_dlunknown
6873 6873
   cat > conftest.$ac_ext <<EOF
6874
-#line 6874 "configure"
6874
+#line 6875 "configure"
6875 6875
 #include "confdefs.h"
6876 6876
 
6877 6877
 #if HAVE_DLFCN_H
... ...
@@ -6969,7 +6970,7 @@ else
6969 6969
     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
6970 6970
   lt_status=$lt_dlunknown
6971 6971
   cat > conftest.$ac_ext <<EOF
6972
-#line 6972 "configure"
6972
+#line 6973 "configure"
6973 6973
 #include "confdefs.h"
6974 6974
 
6975 6975
 #if HAVE_DLFCN_H
... ...
@@ -8630,6 +8631,13 @@ fi
8630 8630
 
8631 8631
 fi
8632 8632
 
8633
+want_clamuko="yes"
8634
+# Check whether --enable-clamuko or --disable-clamuko was given.
8635
+if test "${enable_clamuko+set}" = set; then
8636
+  enableval="$enable_clamuko"
8637
+  want_clamuko="no"
8638
+fi;
8639
+
8633 8640
 
8634 8641
 
8635 8642
 
... ...
@@ -9705,6 +9713,13 @@ cat >>confdefs.h <<\_ACEOF
9705 9705
 #define _REENTRANT 1
9706 9706
 _ACEOF
9707 9707
 
9708
+	if test "$want_clamuko" = "yes"; then
9709
+
9710
+cat >>confdefs.h <<\_ACEOF
9711
+#define CLAMUKO 1
9712
+_ACEOF
9713
+
9714
+	fi
9708 9715
     fi
9709 9716
 
9710 9717
 cat >>confdefs.h <<\_ACEOF
... ...
@@ -74,6 +74,11 @@ then
74 74
     AC_CHECK_LIB(bz2, bzReadOpen, AC_DEFINE(NOBZ2PREFIX,1,bzip funtions do not have bz2 prefix),)
75 75
 fi
76 76
 
77
+want_clamuko="yes"
78
+AC_ARG_ENABLE(clamuko,
79
+[  --disable-clamuko	  Disable clamuko support (Linux and FreeBSD only)],
80
+want_clamuko="no",)
81
+
77 82
 AC_CHECK_FUNCS(setsid memcpy snprintf)
78 83
 AC_FUNC_SETPGRP
79 84
 
... ...
@@ -300,8 +305,11 @@ freebsd*)
300 300
 	TH_SAFE="-thread-safe"
301 301
 	AC_DEFINE(CL_THREAD_SAFE,1,[thread safe])
302 302
 	AC_DEFINE(_REENTRANT,1,[thread safe])
303
+	if test "$want_clamuko" = "yes"; then
304
+	    AC_DEFINE(CLAMUKO,1,[enable clamuko])
305
+	fi
303 306
     fi
304
-    AC_DEFINE(C_BSD,1,[os is solaris])
307
+    AC_DEFINE(C_BSD,1,[os is freebsd])
305 308
     ;;
306 309
 openbsd3.3*)
307 310
     if test "$have_pthreads" = "yes"; then