2 * Copyright (c) 2004-2009 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 IndexNull ((uint32_t)-1)
55 #define forever for(;;)
57 #define ACT_STORE_FLAG_STAY_OPEN 0x00000001
58 #define ACT_STORE_FLAG_EXCLUDE_ASLDB 0x00000002
60 static asl_msg_t
*query
= NULL
;
61 static int reset
= RESET_NONE
;
62 static pthread_mutex_t reset_lock
= PTHREAD_MUTEX_INITIALIZER
;
64 typedef struct action_rule_s
70 struct action_rule_s
*next
;
89 static action_rule_t
*asl_action_rule
= NULL
;
90 static action_rule_t
*asl_datastore_rule
= NULL
;
91 static int filter_token
= -1;
93 int asl_action_close();
94 static int _parse_config_file(const char *);
95 extern void db_save_message(asl_msg_t
*m
);
100 char *a
, *p
, *e
, *out
;
103 if (s
== NULL
) return NULL
;
104 if (*s
== NULL
) return NULL
;
132 if (quote
== 0) quote
= 1;
136 if (((*p
== ' ') || (*p
== '\t')) && (quote
== 0))
149 if (len
== 0) return NULL
;
151 out
= malloc(len
+ 1);
152 if (out
== NULL
) return NULL
;
162 pthread_mutex_lock(&reset_lock
);
165 _parse_config_file(_PATH_ASL_CONF
);
168 pthread_mutex_unlock(&reset_lock
);
172 * Config File format:
173 * Set parameter rule - initializes a parameter.
175 * Query rule - if a message matches the query, then the action is invoked.
176 * The rule may be identified by either "?" or "Q".
177 * ? [k v] [k v] ... action args...
178 * Q [k v] [k v] ... action args...
179 * Universal match rule - the action is invoked for all messages
183 /* Skip over query */
185 _find_action(char *s
)
190 if (p
== NULL
) return NULL
;
191 if ((*p
!= 'Q') && (*p
!= '?') && (*p
!= '*')) return NULL
;
198 while ((*p
== ' ') || (*p
== '\t')) p
++;
200 if (*p
== '\0') return NULL
;
201 if (*p
!= '[') return p
;
203 /* skip to closing ] */
221 _parse_query_action(char *s
)
224 action_rule_t
*out
, *rule
;
226 act
= _find_action(s
);
227 if (act
== NULL
) return -1;
229 out
= (action_rule_t
*)calloc(1, sizeof(action_rule_t
));
230 if (out
== NULL
) return -1;
232 p
= strchr(act
, ' ');
233 if (p
!= NULL
) *p
= '\0';
235 if (!strcasecmp(act
, "ignore")) out
->action
= ACTION_IGNORE
;
236 else if (!strcasecmp(act
, "notify")) out
->action
= ACTION_NOTIFY
;
237 else if (!strcasecmp(act
, "broadcast")) out
->action
= ACTION_BROADCAST
;
238 else if (!strcasecmp(act
, "access")) out
->action
= ACTION_ACCESS
;
239 else if (!strcasecmp(act
, "store")) out
->action
= ACTION_STORE
;
240 else if (!strcasecmp(act
, "save")) out
->action
= ACTION_STORE
;
241 else if (!strcasecmp(act
, "store_directory")) out
->action
= ACTION_STORE_DIR
;
242 else if (!strcasecmp(act
, "store_dir")) out
->action
= ACTION_STORE_DIR
;
243 else if (!strcasecmp(act
, "forward")) out
->action
= ACTION_FORWARD
;
247 out
->options
= strdup(p
+1);
249 if (out
->options
== NULL
)
260 if (s
[0] == '*') out
->query
= asl_new(ASL_TYPE_QUERY
);
264 out
->query
= asl_msg_from_string(s
);
267 if (out
->query
== NULL
)
269 asldebug("out->query is NULL (ERROR)\n");
270 if (out
->options
!= NULL
) free(out
->options
);
275 if ((out
->action
== ACTION_STORE
) && (out
->options
== NULL
))
277 asldebug("action = ACTION_STORE options = NULL\n");
278 if (asl_datastore_rule
== NULL
) asl_datastore_rule
= out
;
281 for (rule
= asl_datastore_rule
; rule
->next
!= NULL
; rule
= rule
->next
);
287 asldebug("action = %d options = %s\n", out
->action
, out
->options
);
288 if (asl_action_rule
== NULL
) asl_action_rule
= out
;
291 for (rule
= asl_action_rule
; rule
->next
!= NULL
; rule
= rule
->next
);
300 * Used to sed config parameters.
301 * Line format "= name value"
304 _parse_set_param(char *s
)
307 uint32_t intval
, count
, v32a
, v32b
, v32c
;
309 if (s
== NULL
) return -1;
310 if (s
[0] == '\0') return 0;
312 /* skip '=' and whitespace */
314 while ((*s
== ' ') || (*s
== '\t')) s
++;
316 l
= explode(s
, " \t");
317 if (l
== NULL
) return -1;
319 for (count
= 0; l
[count
] != NULL
; count
++);
321 /* name is required */
328 /* value is required */
335 if (!strcasecmp(l
[0], "debug"))
337 /* = debug {0|1} [file] */
339 config_debug(intval
, l
[2]);
341 else if (!strcasecmp(l
[0], "cutoff"))
345 if (intval
> ASL_LEVEL_DEBUG
) intval
= ASL_LEVEL_DEBUG
;
346 global
.asl_log_filter
= ASL_FILTER_MASK_UPTO(intval
);
348 else if (!strcasecmp(l
[0], "mark_time"))
350 /* = mark_time seconds */
351 OSSpinLockLock(&global
.lock
);
352 global
.mark_time
= atoll(l
[1]);
353 OSSpinLockUnlock(&global
.lock
);
355 else if (!strcasecmp(l
[0], "dup_delay"))
357 /* = bsd_max_dup_time seconds */
358 OSSpinLockLock(&global
.lock
);
359 global
.bsd_max_dup_time
= atoll(l
[1]);
360 OSSpinLockUnlock(&global
.lock
);
362 else if (!strcasecmp(l
[0], "asl_store_ping_time"))
364 /* NB this is private / unpublished */
365 /* = asl_store_ping_time seconds */
366 OSSpinLockLock(&global
.lock
);
367 global
.asl_store_ping_time
= atoll(l
[1]);
368 OSSpinLockUnlock(&global
.lock
);
370 else if (!strcasecmp(l
[0], "utmp_ttl"))
372 /* = utmp_ttl seconds */
373 OSSpinLockLock(&global
.lock
);
374 global
.utmp_ttl
= (time_t)atoll(l
[1]);
375 OSSpinLockUnlock(&global
.lock
);
377 else if (!strcasecmp(l
[0], "fs_ttl"))
379 /* = fs_ttl seconds */
380 OSSpinLockLock(&global
.lock
);
381 global
.fs_ttl
= (time_t)atoll(l
[1]);
382 OSSpinLockUnlock(&global
.lock
);
384 else if (!strcasecmp(l
[0], "mps_limit"))
386 /* = mps_limit number */
387 OSSpinLockLock(&global
.lock
);
388 global
.mps_limit
= (uint32_t)atol(l
[1]);
389 OSSpinLockUnlock(&global
.lock
);
391 else if (!strcasecmp(l
[0], "max_file_size"))
393 /* = max_file_size bytes */
394 pthread_mutex_lock(global
.db_lock
);
396 if (global
.dbtype
& DB_TYPE_FILE
)
398 asl_store_close(global
.file_db
);
399 global
.file_db
= NULL
;
400 global
.db_file_max
= atoi(l
[1]);
403 pthread_mutex_unlock(global
.db_lock
);
405 else if ((!strcasecmp(l
[0], "db")) || (!strcasecmp(l
[0], "database")) || (!strcasecmp(l
[0], "datastore")))
407 /* NB this is private / unpublished */
408 /* = db type [max]... */
414 if ((l
[1][0] >= '0') && (l
[1][0] <= '9'))
417 if ((count
>= 3) && (strcmp(l
[2], "-"))) v32a
= atoi(l
[2]);
418 if ((count
>= 4) && (strcmp(l
[3], "-"))) v32b
= atoi(l
[3]);
419 if ((count
>= 5) && (strcmp(l
[4], "-"))) v32c
= atoi(l
[4]);
421 else if (!strcasecmp(l
[1], "file"))
423 intval
= DB_TYPE_FILE
;
424 if ((count
>= 3) && (strcmp(l
[2], "-"))) v32a
= atoi(l
[2]);
426 else if (!strncasecmp(l
[1], "mem", 3))
428 intval
= DB_TYPE_MEMORY
;
429 if ((count
>= 3) && (strcmp(l
[2], "-"))) v32b
= atoi(l
[2]);
431 else if (!strncasecmp(l
[1], "min", 3))
433 intval
= DB_TYPE_MINI
;
434 if ((count
>= 3) && (strcmp(l
[2], "-"))) v32c
= atoi(l
[2]);
442 if (v32a
== 0) v32a
= global
.db_file_max
;
443 if (v32b
== 0) v32b
= global
.db_memory_max
;
444 if (v32c
== 0) v32c
= global
.db_mini_max
;
446 config_data_store(intval
, v32a
, v32b
, v32c
);
459 if (s
== NULL
) return -1;
460 while ((*s
== ' ') || (*s
== '\t')) s
++;
462 /* First non-whitespace char is the rule type */
468 /* Blank Line or Comment */
475 /* Query-match action */
476 status
= _parse_query_action(s
);
482 status
= _parse_set_param(s
);
495 asprintf(&str
, "[%s syslogd] [%s %u] [%s %u] [%s Ignoring unrecognized entry in %s: %s] [%s 0] [%s 0] [Facility syslog]",
497 ASL_KEY_LEVEL
, ASL_LEVEL_ERR
,
498 ASL_KEY_PID
, getpid(),
499 ASL_KEY_MSG
, _PATH_ASL_CONF
, s
,
500 ASL_KEY_UID
, ASL_KEY_GID
);
503 if (str
!= NULL
) free(str
);
510 _act_notify(action_rule_t
*r
)
512 if (r
== NULL
) return;
513 if (r
->options
== NULL
) return;
515 notify_post(r
->options
);
519 _act_broadcast(action_rule_t
*r
, asl_msg_t
*msg
)
524 if (r
== NULL
) return;
525 if (msg
== NULL
) return;
528 if (val
== NULL
) val
= asl_get(msg
, ASL_KEY_MSG
);
529 if (val
== NULL
) return;
531 pw
= popen(_PATH_WALL
, "w");
534 asldebug("%s: error sending wall message: %s\n", MY_ID
, strerror(errno
));
538 fprintf(pw
, "%s", val
);
543 _act_access_control(action_rule_t
*r
, asl_msg_t
*msg
)
548 ruid
= atoi(r
->options
);
550 p
= strchr(r
->options
, ' ');
551 if (p
== NULL
) p
= strchr(r
->options
, '\t');
559 if (ruid
!= -1) asl_set((aslmsg
)msg
, ASL_KEY_READ_UID
, r
->options
);
562 if (rgid
!= -1) asl_set((aslmsg
)msg
, ASL_KEY_READ_GID
, p
);
569 _act_store_file_setup(struct store_data
*sd
)
573 if (sd
== NULL
) return ASL_STATUS_INVALID_STORE
;
574 if (sd
->store
== NULL
) return ASL_STATUS_INVALID_STORE
;
575 if (sd
->store
->store
== NULL
) return ASL_STATUS_INVALID_STORE
;
577 status
= asl_file_read_set_position(sd
->store
, ASL_FILE_POSITION_LAST
);
578 if (status
!= ASL_STATUS_OK
) return status
;
580 sd
->next_id
= sd
->store
->cursor_xid
+ 1;
581 if (fseek(sd
->store
->store
, 0, SEEK_END
) != 0) return ASL_STATUS_ACCESS_DENIED
;
583 return ASL_STATUS_OK
;
587 _act_store_dir_setup(struct store_data
*sd
, time_t tick
)
595 if (sd
== NULL
) return ASL_STATUS_INVALID_STORE
;
596 if (sd
->dir
== NULL
) return ASL_STATUS_INVALID_STORE
;
598 /* get / set message id from StoreData file */
601 if (sd
->storedata
== NULL
)
604 asprintf(&path
, "%s/%s", sd
->dir
, FILE_ASL_STORE_DATA
);
605 if (path
== NULL
) return ASL_STATUS_NO_MEMORY
;
607 memset(&sb
, 0, sizeof(struct stat
));
608 status
= stat(path
, &sb
);
611 /* StoreData exists: open and read last xid */
612 sd
->storedata
= fopen(path
, "r+");
613 if (sd
->storedata
== NULL
)
616 return ASL_STATUS_FAILED
;
619 if (fread(&xid
, sizeof(uint64_t), 1, sd
->storedata
) != 1)
622 fclose(sd
->storedata
);
623 sd
->storedata
= NULL
;
624 return ASL_STATUS_READ_FAILED
;
627 else if (errno
!= ENOENT
)
629 /* Unexpected stat error */
631 return ASL_STATUS_FAILED
;
635 /* StoreData does not exist: create it */
636 sd
->storedata
= fopen(path
, "w");
637 if (sd
->storedata
== NULL
)
640 return ASL_STATUS_FAILED
;
648 rewind(sd
->storedata
);
649 if (fread(&xid
, sizeof(uint64_t), 1, sd
->storedata
) != 1)
651 fclose(sd
->storedata
);
652 sd
->storedata
= NULL
;
653 return ASL_STATUS_READ_FAILED
;
657 xid
= asl_core_ntohq(xid
);
661 xid
= asl_core_htonq(xid
);
662 rewind(sd
->storedata
);
663 status
= fwrite(&xid
, sizeof(uint64_t), 1, sd
->storedata
);
666 fclose(sd
->storedata
);
667 sd
->storedata
= NULL
;
668 return ASL_STATUS_WRITE_FAILED
;
671 if ((sd
->flags
& ACT_STORE_FLAG_STAY_OPEN
) == 0)
673 fclose(sd
->storedata
);
674 sd
->storedata
= NULL
;
677 memset(&ctm
, 0, sizeof(struct tm
));
679 if (localtime_r((const time_t *)&tick
, &ctm
) == NULL
) return ASL_STATUS_FAILED
;
680 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
;
682 if (sd
->store
!= NULL
) asl_file_close(sd
->store
);
688 if (sd
->path
!= NULL
) free(sd
->path
);
691 asprintf(&(sd
->path
), "%s/%d.%02d.%02d.asl", sd
->dir
, ctm
.tm_year
+ 1900, ctm
.tm_mon
+ 1, ctm
.tm_mday
);
692 if (sd
->path
== NULL
) return ASL_STATUS_NO_MEMORY
;
694 sd
->p_year
= ctm
.tm_year
;
695 sd
->p_month
= ctm
.tm_mon
;
696 sd
->p_day
= ctm
.tm_mday
;
698 return ASL_STATUS_OK
;
702 _act_store(action_rule_t
*r
, asl_msg_t
*msg
)
704 struct store_data
*sd
;
710 char *str
, *opts
, *p
;
716 /* _act_store is not used for the main ASL data store */
717 if (r
->options
== NULL
) return;
721 /* set up store data */
722 sd
= (struct store_data
*)calloc(1, sizeof(struct store_data
));
723 if (sd
== NULL
) return;
728 if (r
->action
== ACTION_STORE
)
730 sd
->path
= _next_word(&opts
);
731 if (sd
->path
== NULL
)
734 r
->action
= ACTION_NONE
;
738 else if (r
->action
== ACTION_STORE_DIR
)
740 sd
->dir
= _next_word(&opts
);
744 r
->action
= ACTION_NONE
;
755 while (NULL
!= (p
= _next_word(&opts
)))
757 if (!strcmp(p
, "stayopen")) sd
->flags
|= ACT_STORE_FLAG_STAY_OPEN
;
758 else if (!strcmp(p
, "exclude_asldb")) sd
->flags
|= ACT_STORE_FLAG_EXCLUDE_ASLDB
;
759 else if (!strncmp(p
, "mode=0", 6))
763 if ((x
< '0') || (x
> '7'))
766 if (sd
->path
!= NULL
) free(sd
->path
);
767 if (sd
->dir
!= NULL
) free(sd
->dir
);
769 r
->action
= ACTION_NONE
;
774 sd
->mode
+= tmp_mode
<< 6;
777 if ((x
< '0') || (x
> '7'))
780 if (sd
->path
!= NULL
) free(sd
->path
);
781 if (sd
->dir
!= NULL
) free(sd
->dir
);
783 r
->action
= ACTION_NONE
;
788 sd
->mode
+= tmp_mode
<< 3;
791 if ((x
< '0') || (x
> '7'))
794 if (sd
->path
!= NULL
) free(sd
->path
);
795 if (sd
->dir
!= NULL
) free(sd
->dir
);
797 r
->action
= ACTION_NONE
;
802 sd
->mode
+= tmp_mode
;
804 else if (!strncmp(p
, "mode=", 5)) sd
->mode
= atoi(p
+4);
805 else if (!strncmp(p
, "uid=", 4)) sd
->uid
= atoi(p
+4);
806 else if (!strncmp(p
, "gid=", 4)) sd
->gid
= atoi(p
+4);
816 sd
= (struct store_data
*)r
->data
;
819 if (r
->action
== ACTION_STORE_DIR
)
821 val
= asl_get(msg
, ASL_KEY_TIME
);
822 if (val
== NULL
) return;
825 status
= _act_store_dir_setup(sd
, tick
);
826 if (status
!= ASL_STATUS_OK
)
828 asldebug("_act_store_dir_setup %s failed: %s\n", sd
->path
, asl_core_error(status
));
830 /* disable further activity */
831 asl_file_close(sd
->store
);
833 r
->action
= ACTION_NONE
;
838 if (sd
->store
== NULL
)
841 status
= asl_file_open_write(sd
->path
, sd
->mode
, sd
->uid
, sd
->gid
, &s
);
842 if ((status
!= ASL_STATUS_OK
) || (s
== NULL
))
844 asldebug("asl_file_open_write %s failed: %s\n", sd
->path
, asl_core_error(status
));
846 /* disable further activity */
847 asl_file_close(sd
->store
);
849 r
->action
= ACTION_NONE
;
856 if (r
->action
!= ACTION_STORE_DIR
)
858 status
= _act_store_file_setup(sd
);
859 if (status
!= ASL_STATUS_OK
)
861 asldebug("_act_store_file_setup %s failed: %s\n", sd
->path
, asl_core_error(status
));
863 /* disable further activity */
864 asl_file_close(sd
->store
);
866 r
->action
= ACTION_NONE
;
873 status
= asl_file_save(sd
->store
, msg
, &mid
);
874 if (status
!= ASL_STATUS_OK
)
876 asldebug("asl_file_save %s failed: %s\n", sd
->path
, asl_core_error(status
));
878 /* disable further activity on this file */
879 asl_file_close(sd
->store
);
881 r
->action
= ACTION_NONE
;
885 if ((sd
->flags
& ACT_STORE_FLAG_STAY_OPEN
) == 0)
887 asl_file_close(sd
->store
);
891 if (sd
->flags
& ACT_STORE_FLAG_EXCLUDE_ASLDB
)
893 opts
= (char *)asl_get(msg
, ASL_KEY_OPTION
);
896 asl_set(msg
, ASL_KEY_OPTION
, ASL_OPT_IGNORE
);
901 asprintf(&str
, "%s %s", ASL_OPT_IGNORE
, opts
);
904 asl_set(msg
, ASL_KEY_OPTION
, str
);
912 _act_forward(action_rule_t
*r
, asl_msg_t
*msg
)
914 /* To do: <rdar://problem/6130747> Add a "forward" action to asl.conf */
918 send_to_asl_store(asl_msg_t
*msg
)
920 const char *vlevel
, *val
;
922 uint32_t status
, level
, lmask
;
926 /* ASLOption "ignore" keeps a message out of the ASL datastore */
927 if (asl_check_option(msg
, ASL_OPT_IGNORE
) != 0) return;
929 if (filter_token
== -1)
931 /* set up com.apple.syslog.asl_filter */
932 status
= notify_register_check(NOTIFY_SYSTEM_ASL_FILTER
, &filter_token
);
933 if (status
!= NOTIFY_STATUS_OK
)
939 status
= notify_check(filter_token
, &x
);
940 if (status
== NOTIFY_STATUS_OK
)
942 v64
= global
.asl_log_filter
;
943 status
= notify_set_state(filter_token
, v64
);
945 if (status
!= NOTIFY_STATUS_OK
)
947 notify_cancel(filter_token
);
953 /* ASLOption "store" forces a message to be saved */
954 log_me
= asl_check_option(msg
, ASL_OPT_STORE
);
957 db_save_message(msg
);
962 if (filter_token
>= 0)
965 status
= notify_check(filter_token
, &x
);
966 if ((status
== NOTIFY_STATUS_OK
) && (x
== 1))
969 status
= notify_get_state(filter_token
, &v64
);
970 if ((status
== NOTIFY_STATUS_OK
) && (v64
!= 0)) global
.asl_log_filter
= v64
;
974 /* PID 0 (kernel) or PID 1 (launchd) messages are saved */
975 val
= asl_get(msg
, ASL_KEY_PID
);
976 if ((val
!= NULL
) && (atoi(val
) <= 1)) log_me
= 1;
979 vlevel
= asl_get(msg
, ASL_KEY_LEVEL
);
981 if (vlevel
!= NULL
) level
= atoi(vlevel
);
982 lmask
= ASL_FILTER_MASK(level
);
983 if ((lmask
& global
.asl_log_filter
) != 0) log_me
= 1;
986 if (log_me
== 0) return;
988 /* if there are no rules, save the message */
989 if (asl_datastore_rule
== NULL
)
991 db_save_message(msg
);
995 for (r
= asl_datastore_rule
; r
!= NULL
; r
= r
->next
)
997 if (asl_msg_cmp(r
->query
, msg
) == 1)
999 /* if any rule matches, save the message (once!) */
1000 db_save_message(msg
);
1007 asl_action_sendmsg(asl_msg_t
*msg
, const char *outid
)
1011 if (reset
== RESET_CONFIG
) _do_reset();
1013 if (msg
== NULL
) return -1;
1015 for (r
= asl_action_rule
; r
!= NULL
; r
= r
->next
)
1017 if (asl_msg_cmp(r
->query
, msg
) == 1)
1019 if (r
->action
== ACTION_NONE
) continue;
1020 else if (r
->action
== ACTION_IGNORE
) return 0;
1021 else if (r
->action
== ACTION_ACCESS
) _act_access_control(r
, msg
);
1022 else if (r
->action
== ACTION_NOTIFY
) _act_notify(r
);
1023 else if (r
->action
== ACTION_STORE
) _act_store(r
, msg
);
1024 else if (r
->action
== ACTION_STORE_DIR
) _act_store(r
, msg
);
1025 else if (r
->action
== ACTION_BROADCAST
) _act_broadcast(r
, msg
);
1026 else if (r
->action
== ACTION_FORWARD
) _act_forward(r
, msg
);
1030 send_to_asl_store(msg
);
1036 _parse_config_file(const char *name
)
1041 cf
= fopen(name
, "r");
1042 if (cf
== NULL
) return 1;
1044 while (NULL
!= (line
= get_line_from_file(cf
)))
1056 asl_action_init(void)
1058 asldebug("%s: init\n", MY_ID
);
1060 query
= asl_new(ASL_TYPE_QUERY
);
1061 aslevent_addmatch(query
, MY_ID
);
1062 aslevent_addoutput(asl_action_sendmsg
, MY_ID
);
1064 _parse_config_file(_PATH_ASL_CONF
);
1069 asl_action_reset(void)
1071 reset
= global
.reset
;
1076 asl_action_close(void)
1078 action_rule_t
*r
, *n
;
1079 struct store_data
*sd
;
1081 for (r
= asl_action_rule
; r
!= NULL
; r
= n
)
1085 if (((r
->action
== ACTION_STORE
) || (r
->action
== ACTION_STORE_DIR
) || (r
->action
== ACTION_NONE
)) && (r
->data
!= NULL
))
1087 sd
= (struct store_data
*)r
->data
;
1088 if (sd
->store
!= NULL
) asl_file_close(sd
->store
);
1089 if (sd
->storedata
!= NULL
) fclose(sd
->storedata
);
1090 if (sd
->path
!= NULL
) free(sd
->path
);
1091 if (sd
->dir
!= NULL
) free(sd
->dir
);
1096 if (r
->query
!= NULL
) asl_free(r
->query
);
1097 if (r
->options
!= NULL
) free(r
->options
);
1102 asl_action_rule
= NULL
;
1105 for (r
= asl_datastore_rule
; r
!= NULL
; r
= n
)
1109 if (r
->query
!= NULL
) asl_free(r
->query
);
1110 if (r
->options
!= NULL
) free(r
->options
);
1115 asl_datastore_rule
= NULL
;