dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / vscan / vscand / vs_stats.c
blobc053169727b592fbc80ab41df5485276e744a2db
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * Implementation of the vscan statistics interface
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <string.h>
36 #include <syslog.h>
37 #include <pthread.h>
38 #include <door.h>
39 #include <pwd.h>
40 #include <auth_attr.h>
41 #include <secdb.h>
42 #include <sys/stat.h>
43 #include <fcntl.h>
44 #include "vs_incl.h"
47 /* local data */
48 static vs_stats_t vscan_stats;
49 static int vs_stats_door_cookie;
50 static int vs_stats_door_fd = -1;
51 static pthread_mutex_t vs_stats_mutex = PTHREAD_MUTEX_INITIALIZER;
54 /* function prototype */
55 static int vs_stats_check_auth(void);
56 static void vs_stats_reset(void);
57 static void vs_stats_door_call(void *, char *, size_t, door_desc_t *, uint_t);
61 * vs_stats_init
63 * Invoked on daemon load and unload
65 int
66 vs_stats_init(void)
68 (void) pthread_mutex_lock(&vs_stats_mutex);
70 (void) memset(&vscan_stats, 0, sizeof (vs_stats_t));
72 /* door initialization */
73 if ((vs_stats_door_fd = door_create(vs_stats_door_call,
74 &vs_stats_door_cookie, (DOOR_UNREF | DOOR_REFUSE_DESC))) < 0) {
75 vs_stats_door_fd = -1;
76 } else {
77 (void) fdetach(VS_STATS_DOOR_NAME);
78 if (fattach(vs_stats_door_fd, VS_STATS_DOOR_NAME) < 0) {
79 (void) door_revoke(vs_stats_door_fd);
80 vs_stats_door_fd = -1;
84 (void) pthread_mutex_unlock(&vs_stats_mutex);
86 return ((vs_stats_door_fd == -1) ? -1 : 0);
91 * vs_stats_fini
93 * Invoked on daemon unload
95 void
96 vs_stats_fini(void)
98 (void) pthread_mutex_lock(&vs_stats_mutex);
100 /* door termination */
101 if (vs_stats_door_fd != -1)
102 (void) door_revoke(vs_stats_door_fd);
103 vs_stats_door_fd = -1;
105 (void) fdetach(VS_STATS_DOOR_NAME);
106 (void) unlink(VS_STATS_DOOR_NAME);
108 (void) pthread_mutex_unlock(&vs_stats_mutex);
113 * vs_stats_check_auth
115 * Returns: 0 caller authorized to reset stats
116 * -1 caller not authorized to reset stats
118 static int
119 vs_stats_check_auth()
121 ucred_t *uc = NULL;
122 uid_t uid;
123 struct passwd *pw;
125 if (door_ucred(&uc) != 0)
126 return (-1);
128 if (((uid = ucred_getsuid(uc)) == (uid_t)-1) ||
129 ((pw = getpwuid(uid)) == NULL) ||
130 (chkauthattr(VS_VALUE_AUTH, pw->pw_name) != 1)) {
131 ucred_free(uc);
132 return (-1);
135 ucred_free(uc);
136 return (0);
141 * vs_stats_door_call
143 /* ARGSUSED */
144 static void
145 vs_stats_door_call(void *cookie, char *ptr, size_t size, door_desc_t *dp,
146 uint_t n_desc)
148 /* LINTED E_BAD_PTR_CAST_ALIGN */
149 vs_stats_req_t *req = (vs_stats_req_t *)ptr;
150 vs_stats_rsp_t rsp;
152 if ((cookie != &vs_stats_door_cookie) ||
153 (ptr == NULL) ||
154 (size != sizeof (vs_stats_req_t)) ||
155 (req->vsr_magic != VS_STATS_DOOR_MAGIC)) {
156 return;
159 rsp.vsr_magic = VS_STATS_DOOR_MAGIC;
161 switch (req->vsr_id) {
162 case VS_STATS_GET:
163 (void) pthread_mutex_lock(&vs_stats_mutex);
164 rsp.vsr_stats = vscan_stats;
165 (void) pthread_mutex_unlock(&vs_stats_mutex);
166 (void) door_return((char *)&rsp, sizeof (vs_stats_rsp_t),
167 NULL, 0);
168 break;
170 case VS_STATS_RESET:
171 vs_stats_reset();
172 (void) door_return(NULL, 0, NULL, 0);
173 break;
175 default:
176 return;
182 * vs_stats_reset
184 * Reset totals and per-engine statistics to 0
186 static void
187 vs_stats_reset()
189 int i;
191 if (vs_stats_check_auth() != 0)
192 return;
194 (void) pthread_mutex_lock(&vs_stats_mutex);
196 vscan_stats.vss_scanned = 0;
197 vscan_stats.vss_infected = 0;
198 vscan_stats.vss_cleaned = 0;
199 vscan_stats.vss_failed = 0;
201 for (i = 0; i < VS_SE_MAX; i++)
202 vscan_stats.vss_eng[i].vss_errors = 0;
204 (void) pthread_mutex_unlock(&vs_stats_mutex);
209 * vs_stats_set
211 * Update scan request stats
213 void
214 vs_stats_set(int retval)
216 (void) pthread_mutex_lock(&vs_stats_mutex);
218 switch (retval) {
219 case VS_RESULT_CLEAN:
220 vscan_stats.vss_scanned++;
221 break;
222 case VS_RESULT_CLEANED:
223 vscan_stats.vss_scanned++;
224 vscan_stats.vss_infected++;
225 vscan_stats.vss_cleaned++;
226 break;
227 case VS_RESULT_FORBIDDEN:
228 vscan_stats.vss_scanned++;
229 vscan_stats.vss_infected++;
230 break;
231 case VS_RESULT_SE_ERROR:
232 case VS_RESULT_ERROR:
233 default:
234 vscan_stats.vss_failed++;
235 break;
238 (void) pthread_mutex_unlock(&vs_stats_mutex);
243 * vs_stats_eng_err
245 * Increment the error count stat for eng
247 void
248 vs_stats_eng_err(char *engid)
250 int i;
252 (void) pthread_mutex_lock(&vs_stats_mutex);
254 for (i = 0; i < VS_SE_MAX; i++) {
255 if (*(vscan_stats.vss_eng[i].vss_engid) == 0)
256 break;
258 if (strcmp(vscan_stats.vss_eng[i].vss_engid, engid) == 0) {
259 ++(vscan_stats.vss_eng[i].vss_errors);
260 break;
264 (void) pthread_mutex_unlock(&vs_stats_mutex);
269 * vs_stats_config
271 void
272 vs_stats_config(vs_props_all_t *config)
274 int i, j;
275 char *engid, *previd;
276 vs_stats_t prev;
278 (void) pthread_mutex_lock(&vs_stats_mutex);
280 (void) memcpy(&prev, &vscan_stats, sizeof (vs_stats_t));
281 (void) memset(&vscan_stats.vss_eng, 0, sizeof (vscan_stats.vss_eng));
283 for (i = 0; i < VS_SE_MAX; i++) {
284 engid = config->va_se[i].vep_engid;
285 if (*engid == 0)
286 break;
288 (void) strlcpy(vscan_stats.vss_eng[i].vss_engid, engid,
289 VS_SE_NAME_LEN);
291 /* find previous error count for engid */
292 for (j = 0; j < VS_SE_MAX; j++) {
293 previd = prev.vss_eng[j].vss_engid;
294 if (strcmp(previd, engid) == 0) {
295 vscan_stats.vss_eng[i].vss_errors =
296 prev.vss_eng[j].vss_errors;
297 break;
302 (void) pthread_mutex_unlock(&vs_stats_mutex);