2 * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <sys/types.h>
26 #include <sys/socket.h>
41 #define _PATH_WALL "/usr/bin/wall"
42 #define _PATH_ASL_CONF "/etc/asl.conf"
43 #define MY_ID "asl_action"
46 #define ACTION_IGNORE 1
47 #define ACTION_NOTIFY 2
48 #define ACTION_BROADCAST 3
49 #define ACTION_ACCESS 4
50 #define ACTION_STORE 5
51 #define ACTION_STORE_DIR 6
52 #define ACTION_FORWARD 7
54 #define forever for(;;)
56 #define ACT_STORE_FLAG_STAY_OPEN 0x00000001
57 #define ACT_STORE_FLAG_CONTINUE 0x00000002
59 static asl_msg_t
*query
= NULL
;
60 static int reset
= RESET_NONE
;
61 static pthread_mutex_t reset_lock
= PTHREAD_MUTEX_INITIALIZER
;
63 typedef struct action_rule_s
69 struct action_rule_s
*next
;
88 static action_rule_t
*asl_action_rule
= NULL
;
89 static action_rule_t
*asl_datastore_rule
= NULL
;
90 static int filter_token
= -1;
92 int asl_action_close();
93 static int _parse_config_file(const char *);
94 extern void db_save_message(aslmsg m
);
99 char *a
, *p
, *e
, *out
;
102 if (s
== NULL
) return NULL
;
103 if (*s
== NULL
) return NULL
;
131 if (quote
== 0) quote
= 1;
135 if (((*p
== ' ') || (*p
== '\t')) && (quote
== 0))
148 if (len
== 0) return NULL
;
150 out
= malloc(len
+ 1);
151 if (out
== NULL
) return NULL
;
161 pthread_mutex_lock(&reset_lock
);
163 if (reset
== RESET_CONFIG
)
166 _parse_config_file(_PATH_ASL_CONF
);
171 pthread_mutex_unlock(&reset_lock
);
175 * Config File format:
176 * Set parameter rule - initializes a parameter.
178 * Query rule - if a message matches the query, then the action is invoked.
179 * The rule may be identified by either "?" or "Q".
180 * ? [k v] [k v] ... action args...
181 * Q [k v] [k v] ... action args...
182 * Universal match rule - the action is invoked for all messages
186 /* Skip over query */
188 _find_action(char *s
)
193 if (p
== NULL
) return NULL
;
194 if ((*p
!= 'Q') && (*p
!= '?') && (*p
!= '*')) return NULL
;
201 while ((*p
== ' ') || (*p
== '\t')) p
++;
203 if (*p
== '\0') return NULL
;
204 if (*p
!= '[') return p
;
206 /* skip to closing ] */
224 _parse_query_action(char *s
)
227 action_rule_t
*out
, *rule
;
229 act
= _find_action(s
);
230 if (act
== NULL
) return -1;
232 out
= (action_rule_t
*)calloc(1, sizeof(action_rule_t
));
233 if (out
== NULL
) return -1;
235 p
= strchr(act
, ' ');
236 if (p
!= NULL
) *p
= '\0';
238 if (!strcasecmp(act
, "ignore")) out
->action
= ACTION_IGNORE
;
239 else if (!strcasecmp(act
, "notify")) out
->action
= ACTION_NOTIFY
;
240 else if (!strcasecmp(act
, "broadcast")) out
->action
= ACTION_BROADCAST
;
241 else if (!strcasecmp(act
, "access")) out
->action
= ACTION_ACCESS
;
242 else if (!strcasecmp(act
, "store")) out
->action
= ACTION_STORE
;
243 else if (!strcasecmp(act
, "save")) out
->action
= ACTION_STORE
;
244 else if (!strcasecmp(act
, "store_directory")) out
->action
= ACTION_STORE_DIR
;
245 else if (!strcasecmp(act
, "store_dir")) out
->action
= ACTION_STORE_DIR
;
246 else if (!strcasecmp(act
, "forward")) out
->action
= ACTION_FORWARD
;
250 out
->options
= strdup(p
+1);
252 if (out
->options
== NULL
)
263 if (s
[0] == '*') out
->query
= asl_msg_new(ASL_TYPE_QUERY
);
267 out
->query
= asl_msg_from_string(s
);
270 if (out
->query
== NULL
)
272 asldebug("out->query is NULL (ERROR)\n");
278 if ((out
->action
== ACTION_STORE
) && (out
->options
== NULL
))
280 asldebug("action = ACTION_STORE options = NULL\n");
281 if (asl_datastore_rule
== NULL
) asl_datastore_rule
= out
;
284 for (rule
= asl_datastore_rule
; rule
->next
!= NULL
; rule
= rule
->next
);
290 asldebug("action = %d options = %s\n", out
->action
, out
->options
);
291 if (asl_action_rule
== NULL
) asl_action_rule
= out
;
294 for (rule
= asl_action_rule
; rule
->next
!= NULL
; rule
= rule
->next
);
303 * Used to sed config parameters.
304 * Line format "= name value"
307 _parse_set_param(char *s
)
310 uint32_t intval
, count
, v32a
, v32b
, v32c
;
312 if (s
== NULL
) return -1;
313 if (s
[0] == '\0') return 0;
315 /* skip '=' and whitespace */
317 while ((*s
== ' ') || (*s
== '\t')) s
++;
319 l
= explode(s
, " \t");
320 if (l
== NULL
) return -1;
322 for (count
= 0; l
[count
] != NULL
; count
++);
324 /* name is required */
331 /* value is required */
338 if (!strcasecmp(l
[0], "debug"))
340 /* = debug {0|1} [file] */
342 config_debug(intval
, l
[2]);
344 else if (!strcasecmp(l
[0], "cutoff"))
348 if (intval
> ASL_LEVEL_DEBUG
) intval
= ASL_LEVEL_DEBUG
;
349 global
.asl_log_filter
= ASL_FILTER_MASK_UPTO(intval
);
351 else if (!strcasecmp(l
[0], "mark_time"))
353 /* = mark_time seconds */
354 OSSpinLockLock(&global
.lock
);
355 global
.mark_time
= atoll(l
[1]);
356 OSSpinLockUnlock(&global
.lock
);
358 else if (!strcasecmp(l
[0], "dup_delay"))
360 /* = bsd_max_dup_time seconds */
361 OSSpinLockLock(&global
.lock
);
362 global
.bsd_max_dup_time
= atoll(l
[1]);
363 OSSpinLockUnlock(&global
.lock
);
365 else if (!strcasecmp(l
[0], "asl_store_ping_time"))
367 /* NB this is private / unpublished */
368 /* = asl_store_ping_time seconds */
369 OSSpinLockLock(&global
.lock
);
370 global
.asl_store_ping_time
= atoll(l
[1]);
371 OSSpinLockUnlock(&global
.lock
);
373 else if (!strcasecmp(l
[0], "utmp_ttl"))
375 /* = utmp_ttl seconds */
376 OSSpinLockLock(&global
.lock
);
377 global
.utmp_ttl
= (time_t)atoll(l
[1]);
378 OSSpinLockUnlock(&global
.lock
);
380 else if (!strcasecmp(l
[0], "fs_ttl"))
382 /* = fs_ttl seconds */
383 OSSpinLockLock(&global
.lock
);
384 global
.fs_ttl
= (time_t)atoll(l
[1]);
385 OSSpinLockUnlock(&global
.lock
);
387 else if (!strcasecmp(l
[0], "mps_limit"))
389 /* = mps_limit number */
390 OSSpinLockLock(&global
.lock
);
391 global
.mps_limit
= (uint32_t)atol(l
[1]);
392 OSSpinLockUnlock(&global
.lock
);
394 else if (!strcasecmp(l
[0], "max_file_size"))
396 /* = max_file_size bytes */
397 pthread_mutex_lock(global
.db_lock
);
399 if (global
.dbtype
& DB_TYPE_FILE
)
401 asl_store_close(global
.file_db
);
402 global
.file_db
= NULL
;
403 global
.db_file_max
= atoi(l
[1]);
406 pthread_mutex_unlock(global
.db_lock
);
408 else if ((!strcasecmp(l
[0], "db")) || (!strcasecmp(l
[0], "database")) || (!strcasecmp(l
[0], "datastore")))
410 /* NB this is private / unpublished */
411 /* = db type [max]... */
417 if ((l
[1][0] >= '0') && (l
[1][0] <= '9'))
420 if ((count
>= 3) && (strcmp(l
[2], "-"))) v32a
= atoi(l
[2]);
421 if ((count
>= 4) && (strcmp(l
[3], "-"))) v32b
= atoi(l
[3]);
422 if ((count
>= 5) && (strcmp(l
[4], "-"))) v32c
= atoi(l
[4]);
424 else if (!strcasecmp(l
[1], "file"))
426 intval
= DB_TYPE_FILE
;
427 if ((count
>= 3) && (strcmp(l
[2], "-"))) v32a
= atoi(l
[2]);
429 else if (!strncasecmp(l
[1], "mem", 3))
431 intval
= DB_TYPE_MEMORY
;
432 if ((count
>= 3) && (strcmp(l
[2], "-"))) v32b
= atoi(l
[2]);
434 else if (!strncasecmp(l
[1], "min", 3))
436 intval
= DB_TYPE_MINI
;
437 if ((count
>= 3) && (strcmp(l
[2], "-"))) v32c
= atoi(l
[2]);
445 if (v32a
== 0) v32a
= global
.db_file_max
;
446 if (v32b
== 0) v32b
= global
.db_memory_max
;
447 if (v32c
== 0) v32c
= global
.db_mini_max
;
449 config_data_store(intval
, v32a
, v32b
, v32c
);
462 if (s
== NULL
) return -1;
463 while ((*s
== ' ') || (*s
== '\t')) s
++;
465 /* First non-whitespace char is the rule type */
471 /* Blank Line or Comment */
478 /* Query-match action */
479 status
= _parse_query_action(s
);
485 status
= _parse_set_param(s
);
498 asprintf(&str
, "[%s syslogd] [%s %u] [%s %u] [%s Ignoring unrecognized entry in %s: %s] [%s 0] [%s 0] [Facility syslog]",
500 ASL_KEY_LEVEL
, ASL_LEVEL_ERR
,
501 ASL_KEY_PID
, getpid(),
502 ASL_KEY_MSG
, _PATH_ASL_CONF
, s
,
503 ASL_KEY_UID
, ASL_KEY_GID
);
513 _act_notify(action_rule_t
*r
)
515 if (r
== NULL
) return;
516 if (r
->options
== NULL
) return;
518 notify_post(r
->options
);
522 _act_broadcast(action_rule_t
*r
, aslmsg msg
)
524 #ifndef CONFIG_IPHONE
528 if (r
== NULL
) return;
529 if (msg
== NULL
) return;
532 if (val
== NULL
) val
= asl_get(msg
, ASL_KEY_MSG
);
533 if (val
== NULL
) return;
535 pw
= popen(_PATH_WALL
, "w");
538 asldebug("%s: error sending wall message: %s\n", MY_ID
, strerror(errno
));
542 fprintf(pw
, "%s", val
);
548 _act_access_control(action_rule_t
*r
, aslmsg msg
)
553 ruid
= atoi(r
->options
);
555 p
= strchr(r
->options
, ' ');
556 if (p
== NULL
) p
= strchr(r
->options
, '\t');
564 if (ruid
!= -1) asl_set(msg
, ASL_KEY_READ_UID
, r
->options
);
567 if (rgid
!= -1) asl_set(msg
, ASL_KEY_READ_GID
, p
);
574 _act_store_file_setup(struct store_data
*sd
)
578 if (sd
== NULL
) return ASL_STATUS_INVALID_STORE
;
579 if (sd
->store
== NULL
) return ASL_STATUS_INVALID_STORE
;
580 if (sd
->store
->store
== NULL
) return ASL_STATUS_INVALID_STORE
;
582 status
= asl_file_read_set_position(sd
->store
, ASL_FILE_POSITION_LAST
);
583 if (status
!= ASL_STATUS_OK
) return status
;
585 sd
->next_id
= sd
->store
->cursor_xid
+ 1;
586 if (fseek(sd
->store
->store
, 0, SEEK_END
) != 0) return ASL_STATUS_ACCESS_DENIED
;
588 return ASL_STATUS_OK
;
592 _act_store_dir_setup(struct store_data
*sd
, time_t tick
)
601 if (sd
== NULL
) return ASL_STATUS_INVALID_STORE
;
602 if (sd
->dir
== NULL
) return ASL_STATUS_INVALID_STORE
;
604 /* get / set message id from StoreData file */
607 if (sd
->storedata
== NULL
)
609 memset(&sb
, 0, sizeof(struct stat
));
610 status
= stat(sd
->dir
, &sb
);
613 /* must be a directory */
614 if (!S_ISDIR(sb
.st_mode
)) return ASL_STATUS_INVALID_STORE
;
616 else if (errno
== ENOENT
)
618 /* doesn't exist - create it */
620 status
= mkdir(sd
->dir
, sd
->mode
);
623 if (status
!= 0) return ASL_STATUS_WRITE_FAILED
;
625 if ((sd
->uid
!= 0) || (sd
->gid
!= 0))
627 if (chown(sd
->dir
, sd
->uid
, sd
->gid
) != 0) return ASL_STATUS_WRITE_FAILED
;
632 /* Unexpected stat error */
633 return ASL_STATUS_FAILED
;
637 asprintf(&path
, "%s/%s", sd
->dir
, FILE_ASL_STORE_DATA
);
638 if (path
== NULL
) return ASL_STATUS_NO_MEMORY
;
640 memset(&sb
, 0, sizeof(struct stat
));
641 status
= stat(path
, &sb
);
644 /* StoreData exists: open and read last xid */
645 sd
->storedata
= fopen(path
, "r+");
646 if (sd
->storedata
== NULL
)
649 return ASL_STATUS_FAILED
;
652 if (fread(&xid
, sizeof(uint64_t), 1, sd
->storedata
) != 1)
655 fclose(sd
->storedata
);
656 sd
->storedata
= NULL
;
657 return ASL_STATUS_READ_FAILED
;
660 else if (errno
== ENOENT
)
662 /* StoreData does not exist: create it */
663 sd
->storedata
= fopen(path
, "w");
664 if (sd
->storedata
== NULL
)
667 return ASL_STATUS_FAILED
;
670 if ((sd
->uid
!= 0) || (sd
->gid
!= 0))
672 if (chown(path
, sd
->uid
, sd
->gid
) != 0)
675 return ASL_STATUS_WRITE_FAILED
;
681 /* Unexpected stat error */
683 return ASL_STATUS_FAILED
;
690 rewind(sd
->storedata
);
691 if (fread(&xid
, sizeof(uint64_t), 1, sd
->storedata
) != 1)
693 fclose(sd
->storedata
);
694 sd
->storedata
= NULL
;
695 return ASL_STATUS_READ_FAILED
;
699 xid
= asl_core_ntohq(xid
);
703 xid
= asl_core_htonq(xid
);
704 rewind(sd
->storedata
);
705 status
= fwrite(&xid
, sizeof(uint64_t), 1, sd
->storedata
);
708 fclose(sd
->storedata
);
709 sd
->storedata
= NULL
;
710 return ASL_STATUS_WRITE_FAILED
;
713 if ((sd
->flags
& ACT_STORE_FLAG_STAY_OPEN
) == 0)
715 fclose(sd
->storedata
);
716 sd
->storedata
= NULL
;
719 memset(&ctm
, 0, sizeof(struct tm
));
721 if (localtime_r((const time_t *)&tick
, &ctm
) == NULL
) return ASL_STATUS_FAILED
;
722 if ((sd
->p_year
== ctm
.tm_year
) && (sd
->p_month
== ctm
.tm_mon
) && (sd
->p_day
== ctm
.tm_mday
) && (sd
->path
!= NULL
)) return ASL_STATUS_OK
;
724 if (sd
->store
!= NULL
) asl_file_close(sd
->store
);
733 asprintf(&(sd
->path
), "%s/%d.%02d.%02d.asl", sd
->dir
, ctm
.tm_year
+ 1900, ctm
.tm_mon
+ 1, ctm
.tm_mday
);
734 if (sd
->path
== NULL
) return ASL_STATUS_NO_MEMORY
;
736 sd
->p_year
= ctm
.tm_year
;
737 sd
->p_month
= ctm
.tm_mon
;
738 sd
->p_day
= ctm
.tm_mday
;
740 return ASL_STATUS_OK
;
744 _act_store(action_rule_t
*r
, aslmsg msg
)
746 struct store_data
*sd
;
751 mode_t tmp_mode
, mask
;
752 char *str
, *opts
, *p
;
758 /* _act_store is not used for the main ASL data store */
759 if (r
->options
== NULL
) return;
763 /* set up store data */
764 sd
= (struct store_data
*)calloc(1, sizeof(struct store_data
));
765 if (sd
== NULL
) return;
770 if (r
->action
== ACTION_STORE
)
772 sd
->path
= _next_word(&opts
);
773 if ((sd
->path
== NULL
) || (sd
->path
[0] != '/'))
776 asprintf(&str
, "[%s syslogd] [%s %u] [%s %u] [Facility syslog] [%s Invalid path for \"store\" action: %s]",
778 ASL_KEY_LEVEL
, ASL_LEVEL_ERR
,
779 ASL_KEY_PID
, getpid(),
780 ASL_KEY_MSG
, (sd
->path
== NULL
) ? "no path specified" : sd
->path
);
785 r
->action
= ACTION_NONE
;
789 else if (r
->action
== ACTION_STORE_DIR
)
791 sd
->dir
= _next_word(&opts
);
792 if ((sd
->dir
== NULL
) || (sd
->dir
[0] != '/'))
795 asprintf(&str
, "[%s syslogd] [%s %u] [%s %u] [Facility syslog] [%s Invalid path for \"store_directory\" action: %s]",
797 ASL_KEY_LEVEL
, ASL_LEVEL_ERR
,
798 ASL_KEY_PID
, getpid(),
799 ASL_KEY_MSG
, (sd
->dir
== NULL
) ? "no path specified" : sd
->dir
);
804 r
->action
= ACTION_NONE
;
815 while (NULL
!= (p
= _next_word(&opts
)))
817 if (!strcmp(p
, "stayopen"))
819 sd
->flags
|= ACT_STORE_FLAG_STAY_OPEN
;
821 else if (!strcmp(p
, "continue"))
823 sd
->flags
|= ACT_STORE_FLAG_CONTINUE
;
825 else if (!strncmp(p
, "mode=0", 6))
829 if ((x
< '0') || (x
> '7'))
835 r
->action
= ACTION_NONE
;
840 sd
->mode
+= tmp_mode
<< 6;
843 if ((x
< '0') || (x
> '7'))
849 r
->action
= ACTION_NONE
;
854 sd
->mode
+= tmp_mode
<< 3;
857 if ((x
< '0') || (x
> '7'))
863 r
->action
= ACTION_NONE
;
868 sd
->mode
+= tmp_mode
;
870 else if (!strncmp(p
, "mode=", 5)) sd
->mode
= atoi(p
+4);
871 else if (!strncmp(p
, "uid=", 4)) sd
->uid
= atoi(p
+4);
872 else if (!strncmp(p
, "gid=", 4)) sd
->gid
= atoi(p
+4);
882 sd
= (struct store_data
*)r
->data
;
885 if (r
->action
== ACTION_STORE_DIR
)
887 val
= asl_get(msg
, ASL_KEY_TIME
);
888 if (val
== NULL
) return;
891 status
= _act_store_dir_setup(sd
, tick
);
892 if (status
!= ASL_STATUS_OK
)
894 asldebug("_act_store_dir_setup %s failed: %s\n", sd
->path
, asl_core_error(status
));
896 /* disable further activity */
897 asl_file_close(sd
->store
);
899 r
->action
= ACTION_NONE
;
904 if (sd
->store
== NULL
)
909 status
= asl_file_open_write(sd
->path
, (sd
->mode
& 0666), sd
->uid
, sd
->gid
, &s
);
912 if ((status
!= ASL_STATUS_OK
) || (s
== NULL
))
914 asldebug("asl_file_open_write %s failed: %s\n", sd
->path
, asl_core_error(status
));
916 /* disable further activity */
917 asl_file_close(sd
->store
);
919 r
->action
= ACTION_NONE
;
926 if (r
->action
!= ACTION_STORE_DIR
)
928 status
= _act_store_file_setup(sd
);
929 if (status
!= ASL_STATUS_OK
)
931 asldebug("_act_store_file_setup %s failed: %s\n", sd
->path
, asl_core_error(status
));
933 /* disable further activity */
934 asl_file_close(sd
->store
);
936 r
->action
= ACTION_NONE
;
943 status
= asl_file_save(sd
->store
, msg
, &mid
);
944 if (status
!= ASL_STATUS_OK
)
946 asldebug("asl_file_save %s failed: %s\n", sd
->path
, asl_core_error(status
));
948 /* disable further activity on this file */
949 asl_file_close(sd
->store
);
951 r
->action
= ACTION_NONE
;
955 if ((sd
->flags
& ACT_STORE_FLAG_STAY_OPEN
) == 0)
957 asl_file_close(sd
->store
);
961 if ((sd
->flags
& ACT_STORE_FLAG_CONTINUE
) == 0)
963 opts
= (char *)asl_get(msg
, ASL_KEY_OPTION
);
966 asl_set(msg
, ASL_KEY_OPTION
, ASL_OPT_IGNORE
);
971 asprintf(&str
, "%s %s", ASL_OPT_IGNORE
, opts
);
974 asl_set(msg
, ASL_KEY_OPTION
, str
);
982 _act_forward(action_rule_t
*r
, aslmsg msg
)
984 /* To do: <rdar://problem/6130747> Add a "forward" action to asl.conf */
988 send_to_asl_store(aslmsg msg
)
990 const char *vlevel
, *val
;
992 uint32_t status
, level
, lmask
;
996 if (filter_token
== -1)
998 /* set up com.apple.syslog.asl_filter */
999 status
= notify_register_check(NOTIFY_SYSTEM_ASL_FILTER
, &filter_token
);
1000 if (status
!= NOTIFY_STATUS_OK
)
1006 status
= notify_check(filter_token
, &x
);
1007 if (status
== NOTIFY_STATUS_OK
)
1009 v64
= global
.asl_log_filter
;
1010 status
= notify_set_state(filter_token
, v64
);
1012 if (status
!= NOTIFY_STATUS_OK
)
1014 notify_cancel(filter_token
);
1020 /* ASLOption "store" forces a message to be saved */
1021 log_me
= asl_check_option(msg
, ASL_OPT_STORE
);
1024 db_save_message(msg
);
1029 if (filter_token
>= 0)
1032 status
= notify_check(filter_token
, &x
);
1033 if ((status
== NOTIFY_STATUS_OK
) && (x
== 1))
1036 status
= notify_get_state(filter_token
, &v64
);
1037 if ((status
== NOTIFY_STATUS_OK
) && (v64
!= 0)) global
.asl_log_filter
= v64
;
1041 /* PID 0 (kernel) or PID 1 (launchd) messages are saved */
1042 val
= asl_get(msg
, ASL_KEY_PID
);
1043 if ((val
!= NULL
) && (atoi(val
) <= 1)) log_me
= 1;
1046 vlevel
= asl_get(msg
, ASL_KEY_LEVEL
);
1048 if (vlevel
!= NULL
) level
= atoi(vlevel
);
1049 lmask
= ASL_FILTER_MASK(level
);
1050 if ((lmask
& global
.asl_log_filter
) != 0) log_me
= 1;
1053 if (log_me
== 0) return;
1055 /* if there are no rules, save the message */
1056 if (asl_datastore_rule
== NULL
)
1058 db_save_message(msg
);
1062 for (r
= asl_datastore_rule
; r
!= NULL
; r
= r
->next
)
1064 if (asl_msg_cmp(r
->query
, (asl_msg_t
*)msg
) == 1)
1066 /* if any rule matches, save the message (once!) */
1067 db_save_message(msg
);
1074 asl_action_sendmsg(aslmsg msg
, const char *outid
)
1078 if (reset
!= RESET_NONE
) _do_reset();
1080 if (msg
== NULL
) return -1;
1082 for (r
= asl_action_rule
; r
!= NULL
; r
= r
->next
)
1084 if (asl_msg_cmp(r
->query
, (asl_msg_t
*)msg
) == 1)
1086 if ((r
->action
== ACTION_STORE
) || (r
->action
== ACTION_STORE_DIR
))
1089 if (asl_check_option(msg
, ASL_OPT_IGNORE
) != 0) return -1;
1092 if (r
->action
== ACTION_NONE
) continue;
1093 else if (r
->action
== ACTION_IGNORE
) return -1;
1094 else if (r
->action
== ACTION_ACCESS
) _act_access_control(r
, msg
);
1095 else if (r
->action
== ACTION_NOTIFY
) _act_notify(r
);
1096 else if (r
->action
== ACTION_BROADCAST
) _act_broadcast(r
, msg
);
1097 else if (r
->action
== ACTION_FORWARD
) _act_forward(r
, msg
);
1101 if (asl_check_option(msg
, ASL_OPT_IGNORE
) != 0) return -1;
1103 send_to_asl_store(msg
);
1109 _parse_config_file(const char *name
)
1114 cf
= fopen(name
, "r");
1115 if (cf
== NULL
) return 1;
1117 while (NULL
!= (line
= get_line_from_file(cf
)))
1129 asl_action_init(void)
1131 asldebug("%s: init\n", MY_ID
);
1133 query
= asl_msg_new(ASL_TYPE_QUERY
);
1134 aslevent_addmatch(query
, MY_ID
);
1135 aslevent_addoutput(asl_action_sendmsg
, MY_ID
);
1137 _parse_config_file(_PATH_ASL_CONF
);
1142 asl_action_reset(void)
1144 reset
= global
.reset
;
1149 asl_action_close(void)
1151 action_rule_t
*r
, *n
;
1152 struct store_data
*sd
;
1154 for (r
= asl_action_rule
; r
!= NULL
; r
= n
)
1158 if (((r
->action
== ACTION_STORE
) || (r
->action
== ACTION_STORE_DIR
) || (r
->action
== ACTION_NONE
)) && (r
->data
!= NULL
))
1160 sd
= (struct store_data
*)r
->data
;
1161 if (sd
->store
!= NULL
) asl_file_close(sd
->store
);
1162 if (sd
->storedata
!= NULL
) fclose(sd
->storedata
);
1169 if (r
->query
!= NULL
) asl_msg_release(r
->query
);
1175 asl_action_rule
= NULL
;
1178 for (r
= asl_datastore_rule
; r
!= NULL
; r
= n
)
1182 if (r
->query
!= NULL
) asl_msg_release(r
->query
);
1188 asl_datastore_rule
= NULL
;