1*148c5f43SAlan Wright /*
2*148c5f43SAlan Wright * CDDL HEADER START
3*148c5f43SAlan Wright *
4*148c5f43SAlan Wright * The contents of this file are subject to the terms of the
5*148c5f43SAlan Wright * Common Development and Distribution License (the "License").
6*148c5f43SAlan Wright * You may not use this file except in compliance with the License.
7*148c5f43SAlan Wright *
8*148c5f43SAlan Wright * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*148c5f43SAlan Wright * or http://www.opensolaris.org/os/licensing.
10*148c5f43SAlan Wright * See the License for the specific language governing permissions
11*148c5f43SAlan Wright * and limitations under the License.
12*148c5f43SAlan Wright *
13*148c5f43SAlan Wright * When distributing Covered Code, include this CDDL HEADER in each
14*148c5f43SAlan Wright * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*148c5f43SAlan Wright * If applicable, add the following below this CDDL HEADER, with the
16*148c5f43SAlan Wright * fields enclosed by brackets "[]" replaced with your own identifying
17*148c5f43SAlan Wright * information: Portions Copyright [yyyy] [name of copyright owner]
18*148c5f43SAlan Wright *
19*148c5f43SAlan Wright * CDDL HEADER END
20*148c5f43SAlan Wright */
21*148c5f43SAlan Wright /*
22*148c5f43SAlan Wright * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23*148c5f43SAlan Wright */
24*148c5f43SAlan Wright
25*148c5f43SAlan Wright #include <stdio.h>
26*148c5f43SAlan Wright #include <stdlib.h>
27*148c5f43SAlan Wright #include <unistd.h>
28*148c5f43SAlan Wright #include <time.h>
29*148c5f43SAlan Wright #include <syslog.h>
30*148c5f43SAlan Wright #include <thread.h>
31*148c5f43SAlan Wright #include <string.h>
32*148c5f43SAlan Wright #include <strings.h>
33*148c5f43SAlan Wright #include <stdarg.h>
34*148c5f43SAlan Wright #include <dlfcn.h>
35*148c5f43SAlan Wright #include <sys/synch.h>
36*148c5f43SAlan Wright #include <sys/stat.h>
37*148c5f43SAlan Wright #include <sys/errno.h>
38*148c5f43SAlan Wright #include <ctype.h>
39*148c5f43SAlan Wright #include <smbsrv/ndl/eventlog.ndl>
40*148c5f43SAlan Wright #include <smbsrv/libmlsvc.h>
41*148c5f43SAlan Wright
42*148c5f43SAlan Wright typedef struct logr_eventlog {
43*148c5f43SAlan Wright const char *el_name;
44*148c5f43SAlan Wright const char *el_path;
45*148c5f43SAlan Wright } logr_eventlog_t;
46*148c5f43SAlan Wright
47*148c5f43SAlan Wright logr_eventlog_t logr_eventlog[] = {
48*148c5f43SAlan Wright { "System", "/var/adm/messages" },
49*148c5f43SAlan Wright { "smbd", "/var/smb/smbd_log.txt" },
50*148c5f43SAlan Wright { "smbrdr", "/var/smb/smbrdr_log.txt" }
51*148c5f43SAlan Wright };
52*148c5f43SAlan Wright
53*148c5f43SAlan Wright typedef enum {
54*148c5f43SAlan Wright LOGR_MONTH = 0,
55*148c5f43SAlan Wright LOGR_DAY,
56*148c5f43SAlan Wright LOGR_TIME,
57*148c5f43SAlan Wright LOGR_HOST,
58*148c5f43SAlan Wright LOGR_SOURCE,
59*148c5f43SAlan Wright LOGR_IDTAG,
60*148c5f43SAlan Wright LOGR_ID,
61*148c5f43SAlan Wright LOGR_PRI_FAC,
62*148c5f43SAlan Wright LOGR_NARG
63*148c5f43SAlan Wright } logr_syslog_tokens_t;
64*148c5f43SAlan Wright
65*148c5f43SAlan Wright /*
66*148c5f43SAlan Wright * Event code translation struct for use in processing config file
67*148c5f43SAlan Wright */
68*148c5f43SAlan Wright typedef struct logr_priority {
69*148c5f43SAlan Wright char *p_name;
70*148c5f43SAlan Wright int p_value;
71*148c5f43SAlan Wright } logr_priority_t;
72*148c5f43SAlan Wright
73*148c5f43SAlan Wright static logr_priority_t logr_pri_names[] = {
74*148c5f43SAlan Wright "panic", LOG_EMERG,
75*148c5f43SAlan Wright "emerg", LOG_EMERG,
76*148c5f43SAlan Wright "alert", LOG_ALERT,
77*148c5f43SAlan Wright "crit", LOG_CRIT,
78*148c5f43SAlan Wright "err", LOG_ERR,
79*148c5f43SAlan Wright "error", LOG_ERR,
80*148c5f43SAlan Wright "warn", LOG_WARNING,
81*148c5f43SAlan Wright "warning", LOG_WARNING,
82*148c5f43SAlan Wright "notice", LOG_NOTICE,
83*148c5f43SAlan Wright "info", LOG_INFO,
84*148c5f43SAlan Wright "debug", LOG_DEBUG
85*148c5f43SAlan Wright };
86*148c5f43SAlan Wright
87*148c5f43SAlan Wright typedef struct logr_syslog_node {
88*148c5f43SAlan Wright list_node_t ln_node;
89*148c5f43SAlan Wright char ln_logline[LOGR_MAXENTRYLEN];
90*148c5f43SAlan Wright } logr_syslog_node_t;
91*148c5f43SAlan Wright
92*148c5f43SAlan Wright static void *logr_interposer_hdl = NULL;
93*148c5f43SAlan Wright static struct {
94*148c5f43SAlan Wright boolean_t (*logr_op_supported)(char *);
95*148c5f43SAlan Wright int (*logr_op_snapshot)(logr_context_t *);
96*148c5f43SAlan Wright } logr_interposer_ops;
97*148c5f43SAlan Wright
98*148c5f43SAlan Wright /*
99*148c5f43SAlan Wright * Set the syslog timestamp.
100*148c5f43SAlan Wright *
101*148c5f43SAlan Wright * This is a private helper for logr_syslog_parse_entry(), which
102*148c5f43SAlan Wright * must ensure that the appropriate argv entries are non-null.
103*148c5f43SAlan Wright */
104*148c5f43SAlan Wright static void
logr_syslog_set_timestamp(char ** argv,logr_entry_t * le)105*148c5f43SAlan Wright logr_syslog_set_timestamp(char **argv, logr_entry_t *le)
106*148c5f43SAlan Wright {
107*148c5f43SAlan Wright char *month = argv[LOGR_MONTH];
108*148c5f43SAlan Wright char *day = argv[LOGR_DAY];
109*148c5f43SAlan Wright char *time = argv[LOGR_TIME];
110*148c5f43SAlan Wright struct timeval now;
111*148c5f43SAlan Wright struct tm tm, cur_tm;
112*148c5f43SAlan Wright char buf[32];
113*148c5f43SAlan Wright
114*148c5f43SAlan Wright bzero(&tm, sizeof (tm));
115*148c5f43SAlan Wright (void) snprintf(buf, 32, "%s %s %s", month, day, time);
116*148c5f43SAlan Wright if (strptime(buf, "%b" "%d" "%H:%M:%S", &tm) == NULL) {
117*148c5f43SAlan Wright le->le_timestamp.tv_sec = 0;
118*148c5f43SAlan Wright return;
119*148c5f43SAlan Wright }
120*148c5f43SAlan Wright
121*148c5f43SAlan Wright (void) gettimeofday(&now, NULL);
122*148c5f43SAlan Wright (void) localtime_r(&now.tv_sec, &cur_tm);
123*148c5f43SAlan Wright
124*148c5f43SAlan Wright tm.tm_isdst = cur_tm.tm_isdst;
125*148c5f43SAlan Wright tm.tm_year = cur_tm.tm_year;
126*148c5f43SAlan Wright if (tm.tm_mon > cur_tm.tm_mon)
127*148c5f43SAlan Wright tm.tm_year--;
128*148c5f43SAlan Wright
129*148c5f43SAlan Wright le->le_timestamp.tv_sec = mktime(&tm);
130*148c5f43SAlan Wright }
131*148c5f43SAlan Wright
132*148c5f43SAlan Wright /*
133*148c5f43SAlan Wright * Set the syslog priority.
134*148c5f43SAlan Wright *
135*148c5f43SAlan Wright * This is a private helper for logr_syslog_parse_entry(), which
136*148c5f43SAlan Wright * must ensure that the appropriate argv entries are non-null.
137*148c5f43SAlan Wright */
138*148c5f43SAlan Wright static void
logr_syslog_set_priority(char ** argv,logr_entry_t * le)139*148c5f43SAlan Wright logr_syslog_set_priority(char **argv, logr_entry_t *le)
140*148c5f43SAlan Wright {
141*148c5f43SAlan Wright logr_priority_t *entry;
142*148c5f43SAlan Wright char *token;
143*148c5f43SAlan Wright int sz = sizeof (logr_pri_names) / sizeof (logr_pri_names[0]);
144*148c5f43SAlan Wright int i;
145*148c5f43SAlan Wright
146*148c5f43SAlan Wright le->le_pri = LOG_INFO;
147*148c5f43SAlan Wright
148*148c5f43SAlan Wright if ((token = argv[LOGR_PRI_FAC]) == NULL)
149*148c5f43SAlan Wright return;
150*148c5f43SAlan Wright
151*148c5f43SAlan Wright for (i = 0; i < sz; i++) {
152*148c5f43SAlan Wright entry = &logr_pri_names[i];
153*148c5f43SAlan Wright
154*148c5f43SAlan Wright if (strstr(token, entry->p_name) != NULL) {
155*148c5f43SAlan Wright le->le_pri = entry->p_value;
156*148c5f43SAlan Wright break;
157*148c5f43SAlan Wright }
158*148c5f43SAlan Wright }
159*148c5f43SAlan Wright }
160*148c5f43SAlan Wright
161*148c5f43SAlan Wright /*
162*148c5f43SAlan Wright * Parse a syslog entry into a log_entry_t structure. A typical syslog
163*148c5f43SAlan Wright * entry has one of the following formats:
164*148c5f43SAlan Wright *
165*148c5f43SAlan Wright * <month> <day> <time> <host> <msg>
166*148c5f43SAlan Wright * <month> <day> <time> <host> <source>: [ID <ID> <facility.priority>] <msg>
167*148c5f43SAlan Wright *
168*148c5f43SAlan Wright * For Example:
169*148c5f43SAlan Wright * Oct 29 09:49:20 galaxy smbd[104039]: [ID 702911 daemon.info] init done
170*148c5f43SAlan Wright */
171*148c5f43SAlan Wright static int
logr_syslog_parse_entry(char * logline,logr_entry_t * le)172*148c5f43SAlan Wright logr_syslog_parse_entry(char *logline, logr_entry_t *le)
173*148c5f43SAlan Wright {
174*148c5f43SAlan Wright char buf[LOGR_MAXENTRYLEN];
175*148c5f43SAlan Wright char *argv[LOGR_NARG];
176*148c5f43SAlan Wright char *value;
177*148c5f43SAlan Wright char *bp;
178*148c5f43SAlan Wright int i;
179*148c5f43SAlan Wright
180*148c5f43SAlan Wright (void) memset(argv, 0, sizeof (char *) * LOGR_NARG);
181*148c5f43SAlan Wright (void) strlcpy(buf, logline, LOGR_MAXENTRYLEN);
182*148c5f43SAlan Wright
183*148c5f43SAlan Wright for (bp = buf, i = 0; i < LOGR_NARG; ++i) {
184*148c5f43SAlan Wright if (i == LOGR_SOURCE) {
185*148c5f43SAlan Wright /*
186*148c5f43SAlan Wright * If the [ID key is not present, everything
187*148c5f43SAlan Wright * that follows is the message text.
188*148c5f43SAlan Wright */
189*148c5f43SAlan Wright if (strstr(bp, "[ID") == NULL)
190*148c5f43SAlan Wright break;
191*148c5f43SAlan Wright }
192*148c5f43SAlan Wright
193*148c5f43SAlan Wright do {
194*148c5f43SAlan Wright if ((value = strsep(&bp, " \t")) == NULL)
195*148c5f43SAlan Wright break;
196*148c5f43SAlan Wright } while (*value == '\0');
197*148c5f43SAlan Wright
198*148c5f43SAlan Wright if ((argv[i] = value) == NULL)
199*148c5f43SAlan Wright return (-1);
200*148c5f43SAlan Wright }
201*148c5f43SAlan Wright
202*148c5f43SAlan Wright /*
203*148c5f43SAlan Wright * bp should be pointing at the remaining message text.
204*148c5f43SAlan Wright */
205*148c5f43SAlan Wright if ((value = strchr(bp, '\n')) != NULL)
206*148c5f43SAlan Wright *value = '\0';
207*148c5f43SAlan Wright
208*148c5f43SAlan Wright (void) strlcpy(le->le_msg, bp, LOGR_MAXENTRYLEN);
209*148c5f43SAlan Wright (void) strlcpy(le->le_hostname, argv[LOGR_HOST], MAXHOSTNAMELEN);
210*148c5f43SAlan Wright logr_syslog_set_timestamp(argv, le);
211*148c5f43SAlan Wright logr_syslog_set_priority(argv, le);
212*148c5f43SAlan Wright return (0);
213*148c5f43SAlan Wright }
214*148c5f43SAlan Wright
215*148c5f43SAlan Wright static void
logr_syslog_destroy_queue(list_t * queue)216*148c5f43SAlan Wright logr_syslog_destroy_queue(list_t *queue)
217*148c5f43SAlan Wright {
218*148c5f43SAlan Wright logr_syslog_node_t *head;
219*148c5f43SAlan Wright
220*148c5f43SAlan Wright while ((head = list_head(queue)) != NULL) {
221*148c5f43SAlan Wright list_remove(queue, head);
222*148c5f43SAlan Wright free(head);
223*148c5f43SAlan Wright }
224*148c5f43SAlan Wright list_destroy(queue);
225*148c5f43SAlan Wright }
226*148c5f43SAlan Wright
227*148c5f43SAlan Wright static int
logr_syslog_construct_queue(FILE * fp,list_t * queue)228*148c5f43SAlan Wright logr_syslog_construct_queue(FILE *fp, list_t *queue)
229*148c5f43SAlan Wright {
230*148c5f43SAlan Wright logr_syslog_node_t *node, *head;
231*148c5f43SAlan Wright int line_num = 0;
232*148c5f43SAlan Wright char logline[LOGR_MAXENTRYLEN];
233*148c5f43SAlan Wright
234*148c5f43SAlan Wright list_create(queue, sizeof (logr_syslog_node_t),
235*148c5f43SAlan Wright offsetof(logr_syslog_node_t, ln_node));
236*148c5f43SAlan Wright
237*148c5f43SAlan Wright bzero(logline, LOGR_MAXENTRYLEN);
238*148c5f43SAlan Wright while (fgets(logline, LOGR_MAXENTRYLEN, fp) != NULL) {
239*148c5f43SAlan Wright /* Read the last 1024 entries in the queue */
240*148c5f43SAlan Wright if (line_num > LOGR_NMSGMASK) {
241*148c5f43SAlan Wright head = list_head(queue);
242*148c5f43SAlan Wright list_remove(queue, head);
243*148c5f43SAlan Wright free(head);
244*148c5f43SAlan Wright }
245*148c5f43SAlan Wright
246*148c5f43SAlan Wright if ((node = malloc(sizeof (logr_syslog_node_t))) == NULL) {
247*148c5f43SAlan Wright logr_syslog_destroy_queue(queue);
248*148c5f43SAlan Wright return (-1);
249*148c5f43SAlan Wright }
250*148c5f43SAlan Wright bzero(node->ln_logline, LOGR_MAXENTRYLEN);
251*148c5f43SAlan Wright
252*148c5f43SAlan Wright (void) strlcpy(node->ln_logline, logline, LOGR_MAXENTRYLEN);
253*148c5f43SAlan Wright list_insert_tail(queue, node);
254*148c5f43SAlan Wright bzero(logline, LOGR_MAXENTRYLEN);
255*148c5f43SAlan Wright line_num++;
256*148c5f43SAlan Wright }
257*148c5f43SAlan Wright
258*148c5f43SAlan Wright return (0);
259*148c5f43SAlan Wright }
260*148c5f43SAlan Wright
261*148c5f43SAlan Wright /*
262*148c5f43SAlan Wright * logr_syslog_load
263*148c5f43SAlan Wright *
264*148c5f43SAlan Wright * Loads the given log file into log_info_t structure format.
265*148c5f43SAlan Wright *
266*148c5f43SAlan Wright * Returns pointer to the allocated log structure on success.
267*148c5f43SAlan Wright * Note that the caller is responsible for freeing the allocated
268*148c5f43SAlan Wright * memory for returned log_info_t structure.
269*148c5f43SAlan Wright */
270*148c5f43SAlan Wright static int
logr_syslog_load(FILE * fp,logr_info_t * log)271*148c5f43SAlan Wright logr_syslog_load(FILE *fp, logr_info_t *log)
272*148c5f43SAlan Wright {
273*148c5f43SAlan Wright logr_entry_t *entry;
274*148c5f43SAlan Wright int i = 0;
275*148c5f43SAlan Wright
276*148c5f43SAlan Wright list_t queue;
277*148c5f43SAlan Wright logr_syslog_node_t *node;
278*148c5f43SAlan Wright
279*148c5f43SAlan Wright if (logr_syslog_construct_queue(fp, &queue) < 0)
280*148c5f43SAlan Wright return (-1);
281*148c5f43SAlan Wright
282*148c5f43SAlan Wright node = list_head(&queue);
283*148c5f43SAlan Wright while (node) {
284*148c5f43SAlan Wright entry = &log->li_entry[i];
285*148c5f43SAlan Wright
286*148c5f43SAlan Wright if (logr_syslog_parse_entry(node->ln_logline, entry) != 0) {
287*148c5f43SAlan Wright node = list_next(&queue, node);
288*148c5f43SAlan Wright continue;
289*148c5f43SAlan Wright }
290*148c5f43SAlan Wright
291*148c5f43SAlan Wright if (++i > LOGR_NMSGMASK)
292*148c5f43SAlan Wright break;
293*148c5f43SAlan Wright
294*148c5f43SAlan Wright node = list_next(&queue, node);
295*148c5f43SAlan Wright }
296*148c5f43SAlan Wright
297*148c5f43SAlan Wright logr_syslog_destroy_queue(&queue);
298*148c5f43SAlan Wright log->li_idx = i;
299*148c5f43SAlan Wright
300*148c5f43SAlan Wright return (0);
301*148c5f43SAlan Wright }
302*148c5f43SAlan Wright
303*148c5f43SAlan Wright /*
304*148c5f43SAlan Wright * logr_syslog_snapshot
305*148c5f43SAlan Wright *
306*148c5f43SAlan Wright * Return a snapshot of the given log in the buffer
307*148c5f43SAlan Wright * provided by the caller. Returns the number of entries in
308*148c5f43SAlan Wright * the log.
309*148c5f43SAlan Wright */
310*148c5f43SAlan Wright static int
logr_syslog_snapshot(char * logname,logr_info_t * loginfo)311*148c5f43SAlan Wright logr_syslog_snapshot(char *logname, logr_info_t *loginfo)
312*148c5f43SAlan Wright {
313*148c5f43SAlan Wright FILE *fp;
314*148c5f43SAlan Wright char path[MAXPATHLEN];
315*148c5f43SAlan Wright int i;
316*148c5f43SAlan Wright
317*148c5f43SAlan Wright if ((loginfo == NULL) || (!logr_is_supported(logname)))
318*148c5f43SAlan Wright return (-1);
319*148c5f43SAlan Wright
320*148c5f43SAlan Wright path[0] = '\0';
321*148c5f43SAlan Wright for (i = 0; i < sizeof (logr_eventlog)/sizeof (logr_eventlog[0]); ++i) {
322*148c5f43SAlan Wright if (strcasecmp(logname, logr_eventlog[i].el_name) == 0)
323*148c5f43SAlan Wright (void) strlcpy(path, logr_eventlog[i].el_path,
324*148c5f43SAlan Wright MAXPATHLEN);
325*148c5f43SAlan Wright }
326*148c5f43SAlan Wright
327*148c5f43SAlan Wright if ((fp = fopen(path, "r")) == 0)
328*148c5f43SAlan Wright return (-1);
329*148c5f43SAlan Wright
330*148c5f43SAlan Wright if (logr_syslog_load(fp, loginfo) < 0) {
331*148c5f43SAlan Wright (void) fclose(fp);
332*148c5f43SAlan Wright return (-1);
333*148c5f43SAlan Wright }
334*148c5f43SAlan Wright (void) fclose(fp);
335*148c5f43SAlan Wright
336*148c5f43SAlan Wright if (loginfo->li_idx <= LOGR_NMSGMASK)
337*148c5f43SAlan Wright return (loginfo->li_idx);
338*148c5f43SAlan Wright
339*148c5f43SAlan Wright return (LOGR_NMSGMASK+1);
340*148c5f43SAlan Wright }
341*148c5f43SAlan Wright
342*148c5f43SAlan Wright /*
343*148c5f43SAlan Wright * logr_is_supported
344*148c5f43SAlan Wright *
345*148c5f43SAlan Wright * Determines if a given log is supported or not.
346*148c5f43SAlan Wright * Returns B_TRUE on success, B_FALSE on failure.
347*148c5f43SAlan Wright */
348*148c5f43SAlan Wright boolean_t
logr_is_supported(char * log_name)349*148c5f43SAlan Wright logr_is_supported(char *log_name)
350*148c5f43SAlan Wright {
351*148c5f43SAlan Wright int i;
352*148c5f43SAlan Wright
353*148c5f43SAlan Wright if (log_name == NULL)
354*148c5f43SAlan Wright return (B_FALSE);
355*148c5f43SAlan Wright
356*148c5f43SAlan Wright if (logr_interposer_ops.logr_op_supported != NULL)
357*148c5f43SAlan Wright return (logr_interposer_ops.logr_op_supported(log_name));
358*148c5f43SAlan Wright
359*148c5f43SAlan Wright for (i = 0; i < sizeof (logr_eventlog)/sizeof (logr_eventlog[0]); ++i) {
360*148c5f43SAlan Wright if (strcasecmp(log_name, logr_eventlog[i].el_name) == 0)
361*148c5f43SAlan Wright return (B_TRUE);
362*148c5f43SAlan Wright }
363*148c5f43SAlan Wright
364*148c5f43SAlan Wright return (B_FALSE);
365*148c5f43SAlan Wright }
366*148c5f43SAlan Wright
367*148c5f43SAlan Wright /*
368*148c5f43SAlan Wright * logr_get_snapshot
369*148c5f43SAlan Wright *
370*148c5f43SAlan Wright * Allocate memory and make a copy, as a snapshot, from system log.
371*148c5f43SAlan Wright * Returns 0 on success, -1 on failure.
372*148c5f43SAlan Wright */
373*148c5f43SAlan Wright int
logr_get_snapshot(logr_context_t * ctx)374*148c5f43SAlan Wright logr_get_snapshot(logr_context_t *ctx)
375*148c5f43SAlan Wright {
376*148c5f43SAlan Wright logr_read_data_t *data = NULL;
377*148c5f43SAlan Wright
378*148c5f43SAlan Wright if (logr_interposer_ops.logr_op_snapshot != NULL)
379*148c5f43SAlan Wright return (logr_interposer_ops.logr_op_snapshot(ctx));
380*148c5f43SAlan Wright
381*148c5f43SAlan Wright ctx->lc_cached_read_data = malloc(sizeof (logr_read_data_t));
382*148c5f43SAlan Wright if (ctx->lc_cached_read_data != NULL) {
383*148c5f43SAlan Wright data = ctx->lc_cached_read_data;
384*148c5f43SAlan Wright
385*148c5f43SAlan Wright data->rd_log = (logr_info_t *)malloc(sizeof (logr_info_t));
386*148c5f43SAlan Wright if (data->rd_log == NULL) {
387*148c5f43SAlan Wright free(data);
388*148c5f43SAlan Wright return (-1);
389*148c5f43SAlan Wright }
390*148c5f43SAlan Wright bzero(data->rd_log, sizeof (logr_info_t));
391*148c5f43SAlan Wright
392*148c5f43SAlan Wright data->rd_tot_recnum = logr_syslog_snapshot(ctx->lc_source_name,
393*148c5f43SAlan Wright data->rd_log);
394*148c5f43SAlan Wright if (data->rd_tot_recnum < 0) {
395*148c5f43SAlan Wright free(data->rd_log);
396*148c5f43SAlan Wright free(data);
397*148c5f43SAlan Wright return (-1);
398*148c5f43SAlan Wright }
399*148c5f43SAlan Wright
400*148c5f43SAlan Wright data->rd_first_read = 1;
401*148c5f43SAlan Wright
402*148c5f43SAlan Wright return (0);
403*148c5f43SAlan Wright }
404*148c5f43SAlan Wright
405*148c5f43SAlan Wright return (-1);
406*148c5f43SAlan Wright }
407*148c5f43SAlan Wright
408*148c5f43SAlan Wright /*
409*148c5f43SAlan Wright * logr_init
410*148c5f43SAlan Wright *
411*148c5f43SAlan Wright * Initializes the Eventlog service.
412*148c5f43SAlan Wright * Checks to see if a event log utility library
413*148c5f43SAlan Wright * is interposed. If yes then it'll initializes logr_interposer_ops
414*148c5f43SAlan Wright * structure with function pointers from this library.
415*148c5f43SAlan Wright */
416*148c5f43SAlan Wright void
logr_init(void)417*148c5f43SAlan Wright logr_init(void)
418*148c5f43SAlan Wright {
419*148c5f43SAlan Wright logr_interposer_hdl = smb_dlopen();
420*148c5f43SAlan Wright if (logr_interposer_hdl == NULL)
421*148c5f43SAlan Wright return;
422*148c5f43SAlan Wright
423*148c5f43SAlan Wright bzero((void *)&logr_interposer_ops, sizeof (logr_interposer_ops));
424*148c5f43SAlan Wright
425*148c5f43SAlan Wright logr_interposer_ops.logr_op_supported =
426*148c5f43SAlan Wright (boolean_t (*)())dlsym(logr_interposer_hdl, "logr_is_supported");
427*148c5f43SAlan Wright
428*148c5f43SAlan Wright logr_interposer_ops.logr_op_snapshot =
429*148c5f43SAlan Wright (int (*)())dlsym(logr_interposer_hdl, "logr_get_snapshot");
430*148c5f43SAlan Wright
431*148c5f43SAlan Wright if (logr_interposer_ops.logr_op_supported == NULL ||
432*148c5f43SAlan Wright logr_interposer_ops.logr_op_snapshot == NULL)
433*148c5f43SAlan Wright logr_fini();
434*148c5f43SAlan Wright }
435*148c5f43SAlan Wright
436*148c5f43SAlan Wright /*
437*148c5f43SAlan Wright * logr_fini
438*148c5f43SAlan Wright *
439*148c5f43SAlan Wright * Finalizes the Eventlog service.
440*148c5f43SAlan Wright * Closes handle to interposed library.
441*148c5f43SAlan Wright */
442*148c5f43SAlan Wright void
logr_fini(void)443*148c5f43SAlan Wright logr_fini(void)
444*148c5f43SAlan Wright {
445*148c5f43SAlan Wright smb_dlclose(logr_interposer_hdl);
446*148c5f43SAlan Wright logr_interposer_hdl = NULL;
447*148c5f43SAlan Wright bzero((void *)&logr_interposer_ops, sizeof (logr_interposer_ops));
448*148c5f43SAlan Wright }
449