2 * Copyright (c) 2004 Apple Computer, 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@
32 #include <sys/socket.h>
33 #include <sys/sysctl.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
36 #include <mach/mach.h>
37 #include <servers/bootstrap.h>
41 #include <asl_private.h>
43 #include <asl_store.h>
45 #define MOD_CASE_FOLD 'C'
47 #define MOD_SUBSTRING 'S'
48 #define MOD_PREFIX 'A'
49 #define MOD_SUFFIX 'Z'
50 #define MOD_NUMERIC 'N'
59 #define ASL_QUERY_OP_NOT 0x1000
61 #define FACILITY_CONSOLE "com.apple.console"
65 #define SEARCH_MATCH 1
67 #define PROC_NOT_FOUND -1
68 #define PROC_NOT_UNIQUE -2
74 #define forever for(;;)
76 #define SEND_FORMAT_LEGACY 0
77 #define SEND_FORMAT_ASL 1
79 #define TIME_SEC 0x00000001
80 #define TIME_UTC 0x00000002
81 #define TIME_LCL 0x00000004
83 #define FORMAT_RAW 0x00000010
84 #define FORMAT_LEGACY 0x00000020
85 #define FORMAT_STD 0x00000040
86 #define FORMAT_XML 0x00000080
88 #define EXPORT 0x00000100
90 #define ASL_FILTER_MASK_PACEWNID 0xff
91 #define ASL_FILTER_MASK_PACEWNI 0x7f
92 #define ASL_FILTER_MASK_PACEWN 0x3f
93 #define ASL_FILTER_MASK_PACEW 0x1f
94 #define ASL_FILTER_MASK_PACE 0x0f
95 #define ASL_FILTER_MASK_PAC 0x07
97 #define FETCH_BATCH 256
99 #define _PATH_ASL_STORE "/var/log/asl.db"
100 static asl_store_t
**dbstore
= NULL
;
101 static uint32_t store_count
= 0;
102 static uint32_t store_raw
= 1;
104 static asl_store_t
*export
= NULL
;
107 uint32_t notify_register_plain(const char *name
, int *out_token
);
109 extern char *asl_msg_to_string(aslmsg msg
, uint32_t *len
);
110 extern asl_msg_t
*asl_msg_from_string(const char *buf
);
111 extern char *asl_list_to_string(asl_search_result_t
*list
, uint32_t *outlen
);
112 extern asl_search_result_t
*asl_list_from_string(const char *buf
);
113 extern int asl_msg_cmp(asl_msg_t
*a
, asl_msg_t
*b
);
114 extern time_t asl_parse_time(const char *in
);
115 /* END PRIVATE API */
117 static const char *myname
= "syslog";
119 #define ASL_SERVICE_NAME "com.apple.system.logger"
120 static mach_port_t asl_server_port
= MACH_PORT_NULL
;
125 fprintf(stderr
, "usage:\n");
126 fprintf(stderr
, "%s -s [-r host] [-l level] message...\n", myname
);
127 fprintf(stderr
, " send a message\n");
128 fprintf(stderr
, "\n");
129 fprintf(stderr
, "%s -s [-r host] -k key val [key val]...\n", myname
);
130 fprintf(stderr
, " send a message with the given keys and values\n");
131 fprintf(stderr
, "\n");
132 fprintf(stderr
, "%s -c process [filter]\n", myname
);
133 fprintf(stderr
, " get (set if filter is specified) syslog filter for process (pid or name)\n");
134 fprintf(stderr
, " level may be any combination of the characters \"p a c e w n i d\"\n");
135 fprintf(stderr
, " p = Emergency (\"Panic\")\n");
136 fprintf(stderr
, " a = Alert\n");
137 fprintf(stderr
, " c = Critical\n");
138 fprintf(stderr
, " e = Error\n");
139 fprintf(stderr
, " w = Warning\n");
140 fprintf(stderr
, " n = Notice\n");
141 fprintf(stderr
, " i = Info\n");
142 fprintf(stderr
, " d = Debug\n");
143 fprintf(stderr
, " a minus sign preceeding a single letter means \"up to\" that level\n");
144 fprintf(stderr
, "\n");
145 fprintf(stderr
, "%s -p [-db [file]...] [-k key [[op] val]]... [-o -k key [[op] val]] ...]...\n", myname
);
146 fprintf(stderr
, " -db prune /var/log/asl.db or named file, rather than sending a prune command to syslogd.\n");
147 fprintf(stderr
, " -p prune datastore according to input expression (see below)\n");
148 fprintf(stderr
, "\n");
149 fprintf(stderr
, "%s [-db [file]...] [-x file] [-w [N]] [-F format] [-u] [-k key [[op] val]]... [-o -k key [[op] val]] ...]...\n", myname
);
150 fprintf(stderr
, " -db read /var/log/asl.db or named file, rather than querying syslogd.\n");
151 fprintf(stderr
, " use \"-\" to explicitly include a connection to syslogd.\n");
152 fprintf(stderr
, " -x export to named database, rather than printing\n");
153 fprintf(stderr
, " -w watch database (^C to quit)\n");
154 fprintf(stderr
, " prints the last N matching lines (default 10) before waiting\n");
155 fprintf(stderr
, " \"-w 0\" prints all matching lines before waiting\n");
156 fprintf(stderr
, " -F output format may be \"std\", \"raw\", \"bsd\", or \"xml\"\n");
157 fprintf(stderr
, " format may also be a string containing variables of the form\n");
158 fprintf(stderr
, " $Key or $(Key) - use the latter for non-whitespace delimited variables\n");
159 fprintf(stderr
, " -T timestamp format may be \"sec\" (seconds), \"utc\" (UTC), or \"local\" (local timezone)\n");
160 fprintf(stderr
, " -u print timestamps using UTC (equivalent to \"-T utc\")\n");
161 fprintf(stderr
, " -k key/value match\n");
162 fprintf(stderr
, " if no operator or value is given, checks for the existance of the key\n");
163 fprintf(stderr
, " if no operator is given, default is \"%s\"\n", OP_EQ
);
164 fprintf(stderr
, " -C alias for \"-k Facility com.apple.console\"\n");
165 fprintf(stderr
, " -o begins a new query\n");
166 fprintf(stderr
, " queries are \'OR\'ed together\n");
167 fprintf(stderr
, "operators are zero or more modifiers followed by a comparison\n");
168 fprintf(stderr
, " %s equal\n", OP_EQ
);
169 fprintf(stderr
, " %s not equal\n", OP_NE
);
170 fprintf(stderr
, " %s greater than\n", OP_GT
);
171 fprintf(stderr
, " %s greater or equal\n", OP_GE
);
172 fprintf(stderr
, " %s less than\n", OP_LT
);
173 fprintf(stderr
, " %s less or equal\n", OP_LE
);
174 fprintf(stderr
, "optional modifiers for operators\n");
175 fprintf(stderr
, " %c case-fold\n", MOD_CASE_FOLD
);
176 fprintf(stderr
, " %c regular expression\n", MOD_REGEX
);
177 fprintf(stderr
, " %c substring\n", MOD_SUBSTRING
);
178 fprintf(stderr
, " %c prefix\n", MOD_PREFIX
);
179 fprintf(stderr
, " %c suffix\n", MOD_SUFFIX
);
180 fprintf(stderr
, " %c numeric comparison\n", MOD_NUMERIC
);
184 notify_status_string(int status
)
186 if (status
== NOTIFY_STATUS_OK
) return "OK";
187 if (status
== NOTIFY_STATUS_INVALID_NAME
) return "Process not registered";
188 if (status
== NOTIFY_STATUS_NOT_AUTHORIZED
) return "Not authorized";
189 return "Operation failed";
193 asl_level_string(int level
)
195 if (level
== ASL_LEVEL_EMERG
) return ASL_STRING_EMERG
;
196 if (level
== ASL_LEVEL_ALERT
) return ASL_STRING_ALERT
;
197 if (level
== ASL_LEVEL_CRIT
) return ASL_STRING_CRIT
;
198 if (level
== ASL_LEVEL_ERR
) return ASL_STRING_ERR
;
199 if (level
== ASL_LEVEL_WARNING
) return ASL_STRING_WARNING
;
200 if (level
== ASL_LEVEL_NOTICE
) return ASL_STRING_NOTICE
;
201 if (level
== ASL_LEVEL_INFO
) return ASL_STRING_INFO
;
202 if (level
== ASL_LEVEL_DEBUG
) return ASL_STRING_DEBUG
;
207 procinfo(char *pname
, int *pid
, int *uid
)
210 int i
, status
, nprocs
;
212 struct kinfo_proc
*procs
, *newprocs
;
219 mib
[2] = KERN_PROC_ALL
;
223 status
= sysctl(mib
, miblen
, NULL
, &size
, NULL
, 0);
227 newprocs
= reallocf(procs
, size
);
228 if (newprocs
== NULL
)
230 if (procs
!= NULL
) free(procs
);
231 return PROC_NOT_FOUND
;
235 status
= sysctl(mib
, miblen
, procs
, &size
, NULL
, 0);
236 } while ((status
== -1) && (errno
== ENOMEM
));
240 if (procs
!= NULL
) free(procs
);
241 return PROC_NOT_FOUND
;
244 if (size
% sizeof(struct kinfo_proc
) != 0)
246 if (procs
!= NULL
) free(procs
);
247 return PROC_NOT_FOUND
;
250 if (procs
== NULL
) return PROC_NOT_FOUND
;
252 nprocs
= size
/ sizeof(struct kinfo_proc
);
256 /* Search for a pid */
257 for (i
= 0; i
< nprocs
; i
++)
259 if (*pid
== procs
[i
].kp_proc
.p_pid
)
261 *uid
= procs
[i
].kp_eproc
.e_ucred
.cr_uid
;
266 return PROC_NOT_FOUND
;
269 *pid
= PROC_NOT_FOUND
;
271 for (i
= 0; i
< nprocs
; i
++)
273 if (!strcmp(procs
[i
].kp_proc
.p_comm
, pname
))
275 if (*pid
!= PROC_NOT_FOUND
)
278 return PROC_NOT_UNIQUE
;
281 *pid
= procs
[i
].kp_proc
.p_pid
;
282 *uid
= procs
[i
].kp_eproc
.e_ucred
.cr_uid
;
287 if (*pid
== PROC_NOT_FOUND
) return PROC_NOT_FOUND
;
293 rcontrol_get_string(const char *prefix
, int pid
, int *val
)
299 status
= NOTIFY_STATUS_OK
;
301 if (pid
== RC_SYSLOGD
)
303 status
= notify_register_plain(NOTIFY_SYSTEM_ASL_FILTER
, &t
);
305 else if (pid
== RC_MASTER
)
307 status
= notify_register_plain(NOTIFY_SYSTEM_MASTER
, &t
);
312 asprintf(&name
, "%s.%d", prefix
, pid
);
313 if (name
== NULL
) return NOTIFY_STATUS_FAILED
;
315 status
= notify_register_plain(name
, &t
);
319 if (status
!= NOTIFY_STATUS_OK
) return status
;
322 status
= notify_get_state(t
, &x
);
331 rcontrol_set_string(const char *prefix
, int pid
, int filter
)
337 status
= NOTIFY_STATUS_OK
;
339 if (pid
== RC_SYSLOGD
)
341 status
= notify_register_plain(NOTIFY_SYSTEM_ASL_FILTER
, &t
);
343 else if (pid
== RC_MASTER
)
345 status
= notify_register_plain(NOTIFY_SYSTEM_MASTER
, &t
);
350 asprintf(&name
, "%s.%d", prefix
, pid
);
351 if (name
== NULL
) return NOTIFY_STATUS_FAILED
;
353 status
= notify_register_plain(name
, &t
);
357 if (status
!= NOTIFY_STATUS_OK
) return status
;
360 status
= notify_set_state(t
, x
);
361 if ((pid
== RC_SYSLOGD
) && (status
== NOTIFY_STATUS_OK
)) status
= notify_post(NOTIFY_SYSTEM_ASL_FILTER
);
367 asl_string_to_filter(char *s
)
371 if (s
== NULL
) return 0;
372 if (s
[0] == '\0') return 0;
374 if ((s
[0] >= '0') && (s
[0] <= '9')) return ASL_FILTER_MASK(atoi(s
));
378 if ((s
[1] == 'P') || (s
[1] == 'p')) i
= ASL_LEVEL_EMERG
;
379 else if ((s
[1] == 'A') || (s
[1] == 'a')) i
= ASL_LEVEL_ALERT
;
380 else if ((s
[1] == 'C') || (s
[1] == 'c')) i
= ASL_LEVEL_CRIT
;
381 else if ((s
[1] == 'E') || (s
[1] == 'e')) i
= ASL_LEVEL_ERR
;
382 else if ((s
[1] == 'X') || (s
[1] == 'x')) i
= ASL_LEVEL_ERR
;
383 else if ((s
[1] == 'W') || (s
[1] == 'w')) i
= ASL_LEVEL_WARNING
;
384 else if ((s
[1] == 'N') || (s
[1] == 'n')) i
= ASL_LEVEL_NOTICE
;
385 else if ((s
[1] == 'I') || (s
[1] == 'i')) i
= ASL_LEVEL_INFO
;
386 else if ((s
[1] == 'D') || (s
[1] == 'd')) i
= ASL_LEVEL_DEBUG
;
387 else i
= atoi(s
+ 1);
388 f
= ASL_FILTER_MASK_UPTO(i
);
393 for (i
= 0; s
[i
] != '\0'; i
++)
395 if ((s
[i
] == 'P') || (s
[i
] == 'p')) f
|= ASL_FILTER_MASK_EMERG
;
396 else if ((s
[i
] == 'A') || (s
[i
] == 'a')) f
|= ASL_FILTER_MASK_ALERT
;
397 else if ((s
[i
] == 'C') || (s
[i
] == 'c')) f
|= ASL_FILTER_MASK_CRIT
;
398 else if ((s
[i
] == 'E') || (s
[i
] == 'e')) f
|= ASL_FILTER_MASK_ERR
;
399 else if ((s
[i
] == 'X') || (s
[i
] == 'x')) f
|= ASL_FILTER_MASK_ERR
;
400 else if ((s
[i
] == 'W') || (s
[i
] == 'w')) f
|= ASL_FILTER_MASK_WARNING
;
401 else if ((s
[i
] == 'N') || (s
[i
] == 'n')) f
|= ASL_FILTER_MASK_NOTICE
;
402 else if ((s
[i
] == 'I') || (s
[i
] == 'i')) f
|= ASL_FILTER_MASK_INFO
;
403 else if ((s
[i
] == 'D') || (s
[i
] == 'd')) f
|= ASL_FILTER_MASK_DEBUG
;
410 asl_filter_string(int f
)
412 static char str
[1024];
415 memset(str
, 0, sizeof(str
));
418 if ((f
== ASL_FILTER_MASK_PACEWNID
) != 0)
420 strcat(str
, "Emergency - Debug");
424 if ((f
== ASL_FILTER_MASK_PACEWNI
) != 0)
426 strcat(str
, "Emergency - Info");
430 if ((f
== ASL_FILTER_MASK_PACEWN
) != 0)
432 strcat(str
, "Emergency - Notice");
436 if ((f
== ASL_FILTER_MASK_PACEW
) != 0)
438 strcat(str
, "Emergency - Warning");
442 if ((f
== ASL_FILTER_MASK_PACE
) != 0)
444 strcat(str
, "Emergency - Error");
448 if ((f
== ASL_FILTER_MASK_PAC
) != 0)
450 strcat(str
, "Emergency - Critical");
454 if ((f
& ASL_FILTER_MASK_EMERG
) != 0)
456 strcat(str
, "Emergency");
460 if ((f
& ASL_FILTER_MASK_ALERT
) != 0)
462 if (i
> 0) strcat(str
, ", ");
463 strcat(str
, "Alert");
467 if ((f
& ASL_FILTER_MASK_CRIT
) != 0)
469 if (i
> 0) strcat(str
, ", ");
470 strcat(str
, "Critical");
474 if ((f
& ASL_FILTER_MASK_ERR
) != 0)
476 if (i
> 0) strcat(str
, ", ");
477 strcat(str
, "Error");
481 if ((f
& ASL_FILTER_MASK_WARNING
) != 0)
483 if (i
> 0) strcat(str
, ", ");
484 strcat(str
, "Warning");
488 if ((f
& ASL_FILTER_MASK_NOTICE
) != 0)
490 if (i
> 0) strcat(str
, ", ");
491 strcat(str
, "Notice");
495 if ((f
& ASL_FILTER_MASK_INFO
) != 0)
497 if (i
> 0) strcat(str
, ", ");
502 if ((f
& ASL_FILTER_MASK_DEBUG
) != 0)
504 if (i
> 0) strcat(str
, ", ");
505 strcat(str
, "Debug");
509 if (i
== 0) sprintf(str
, "Off");
515 rcontrol_get(const char *prefix
, int pid
)
525 if (pid
== RC_SYSLOGD
) name
= "ASL Data Store";
527 status
= rcontrol_get_string(NULL
, pid
, &filter
);
528 if (status
== NOTIFY_STATUS_OK
)
530 printf("%s filter mask: %s\n", name
, asl_filter_string(filter
));
534 printf("Unable to determine %s filter mask\n", name
);
538 status
= rcontrol_get_string(prefix
, pid
, &filter
);
539 if (status
== NOTIFY_STATUS_OK
)
541 printf("Process %d syslog filter mask: %s\n", pid
, asl_filter_string(filter
));
545 printf("Unable to determine syslog filter mask for pid %d\n", pid
);
550 rcontrol_set(const char *prefix
, int pid
, int filter
)
558 if (pid
== RC_SYSLOGD
) name
= "ASL Data Store";
559 status
= rcontrol_set_string(NULL
, pid
, filter
);
561 if (status
== NOTIFY_STATUS_OK
)
563 printf("Set %s syslog filter mask: %s\n", name
, asl_filter_string(filter
));
567 printf("Unable to set %s syslog filter mask: %s\n", name
, notify_status_string(status
));
571 status
= rcontrol_set_string(prefix
, pid
, filter
);
572 if (status
== NOTIFY_STATUS_OK
)
574 printf("Set process %d syslog filter mask set: %s\n", pid
, asl_filter_string(filter
));
578 printf("Unable to set syslog filter mask for pid %d: %s\n", pid
, notify_status_string(status
));
583 rsend(aslmsg msg
, char *rhost
)
592 struct sockaddr_in dst
;
594 char myname
[MAXHOSTNAMELEN
+ 1];
596 if (msg
== NULL
) return 0;
598 h
= gethostbyname(rhost
);
599 if (h
== NULL
) return -1;
601 s
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
602 if (s
<= 0) return -1;
604 memset(&dst
, 0, sizeof(struct sockaddr_in
));
605 memcpy(&(dst
.sin_addr
.s_addr
), h
->h_addr_list
[0], 4);
606 dst
.sin_family
= AF_INET
;
608 dst
.sin_len
= sizeof(struct sockaddr_in
);
610 level
= ASL_LEVEL_DEBUG
;
612 val
= asl_get(msg
, ASL_KEY_LEVEL
);
613 if (val
!= NULL
) level
= atoi(val
);
615 memset(>ime
, 0, sizeof(struct tm
));
619 gmtime_r(&tick
, >ime
);
621 /* Canonical form: YYYY.MM.DD hh:mm:ss UTC */
622 asprintf(×tr
, "%d.%02d.%02d %02d:%02d:%02d UTC", gtime
.tm_year
+ 1900, gtime
.tm_mon
+ 1, gtime
.tm_mday
, gtime
.tm_hour
, gtime
.tm_min
, gtime
.tm_sec
);
626 asl_set(msg
, ASL_KEY_TIME
, timestr
);
630 if (gethostname(myname
, MAXHOSTNAMELEN
) == 0) asl_set(msg
, ASL_KEY_HOST
, myname
);
633 str
= asl_msg_to_string(msg
, &len
);
634 if (str
== NULL
) return -1;
636 asprintf(&out
, "%10u %s\n", len
+1, str
);
638 if (out
== NULL
) return -1;
640 sendto(s
, out
, len
+12, 0, (const struct sockaddr
*)&dst
, sizeof(struct sockaddr_in
));
648 rlegacy(char *msg
, int level
, char *rhost
)
655 struct sockaddr_in dst
;
657 char myname
[MAXHOSTNAMELEN
+ 1];
659 if (msg
== NULL
) return 0;
661 h
= gethostbyname(rhost
);
662 if (h
== NULL
) return -1;
664 s
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
665 if (s
<= 0) return -1;
667 memset(&dst
, 0, sizeof(struct sockaddr_in
));
668 memcpy(&(dst
.sin_addr
.s_addr
), h
->h_addr_list
[0], 4);
669 dst
.sin_family
= AF_INET
;
671 dst
.sin_len
= sizeof(struct sockaddr_in
);
674 ltime
= ctime(&tick
);
677 gethostname(myname
, MAXHOSTNAMELEN
);
679 asprintf(&out
, "<%d>%s %s syslog[%d]: %s", level
, ltime
+4, myname
, getpid(), msg
);
681 sendto(s
, out
, len
, 0, (const struct sockaddr
*)&dst
, sizeof(struct sockaddr_in
));
693 if (s
== NULL
) return 0;
696 if ((s
[0] == '-') || (s
[0] == '+')) i
= 1;
698 if (s
[i
] == '\0') return 0;
700 for (; s
[i
] != '\0'; i
++)
702 if (!isdigit(s
[i
])) return 0;
709 asl_string_to_level(const char *s
)
711 if (s
== NULL
) return -1;
713 if ((s
[0] >= '0') && (s
[0] <= '7') && (s
[1] == '\0')) return atoi(s
);
715 if (!strncasecmp(s
, "em", 2)) return ASL_LEVEL_EMERG
;
716 else if (!strncasecmp(s
, "p", 1)) return ASL_LEVEL_EMERG
;
717 else if (!strncasecmp(s
, "a", 1)) return ASL_LEVEL_ALERT
;
718 else if (!strncasecmp(s
, "c", 1)) return ASL_LEVEL_CRIT
;
719 else if (!strncasecmp(s
, "er", 2)) return ASL_LEVEL_ERR
;
720 else if (!strncasecmp(s
, "x", 1)) return ASL_LEVEL_ERR
;
721 else if (!strncasecmp(s
, "w", 1)) return ASL_LEVEL_WARNING
;
722 else if (!strncasecmp(s
, "n", 1)) return ASL_LEVEL_NOTICE
;
723 else if (!strncasecmp(s
, "i", 1)) return ASL_LEVEL_INFO
;
724 else if (!strncasecmp(s
, "d", 1)) return ASL_LEVEL_DEBUG
;
730 syslog_remote_control(int argc
, char *argv
[])
732 int pid
, uid
, status
, mask
;
735 if ((argc
< 3) || (argc
> 4))
737 fprintf(stderr
, "usage:\n");
738 fprintf(stderr
, "%s -c process [mask]\n", myname
);
739 fprintf(stderr
, " get (set if mask is specified) syslog filter mask for process (pid or name)\n");
740 fprintf(stderr
, " process may be pid or process name\n");
741 fprintf(stderr
, " use \"-c 0\" to get master syslog filter mask\n");
742 fprintf(stderr
, " use \"-c 0 off\" to disable master syslog filter mask\n");
743 fprintf(stderr
, "\n");
750 status
= PROC_NOT_FOUND
;
752 if ((!strcmp(argv
[2], "syslogd")) || (!strcmp(argv
[2], "syslog")))
758 else if (_isanumber(argv
[2]) != 0)
761 status
= procinfo(NULL
, &pid
, &uid
);
765 status
= procinfo(argv
[2], &pid
, &uid
);
768 if (status
== PROC_NOT_FOUND
)
770 fprintf(stderr
, "%s: process not found\n", argv
[2]);
774 if (status
== PROC_NOT_UNIQUE
)
776 fprintf(stderr
, "%s: multiple processes found\n", argv
[2]);
777 fprintf(stderr
, "use pid to identify a process uniquely\n");
781 if (pid
== 0) pid
= RC_MASTER
;
783 prefix
= NOTIFY_PREFIX_USER
;
784 if (uid
== 0) prefix
= NOTIFY_PREFIX_SYSTEM
;
788 if ((pid
== RC_MASTER
) && (!strcasecmp(argv
[3], "off"))) mask
= 0;
789 else if ((pid
== RC_SYSLOGD
) && (!strcasecmp(argv
[3], "off"))) mask
= 0;
792 mask
= asl_string_to_filter(argv
[3]);
795 printf("unknown syslog mask: %s\n", argv
[3]);
800 rcontrol_set(prefix
, pid
, mask
);
804 rcontrol_get(prefix
, pid
);
811 syslog_send(int argc
, char *argv
[])
813 int i
, start
, kv
, len
, rfmt
, rlevel
;
816 char tmp
[64], *str
, *rhost
;
820 rfmt
= SEND_FORMAT_LEGACY
;
824 for (i
= 1; i
< argc
; i
++)
826 if (!strcmp(argv
[i
], "-s")) start
= i
+1;
827 else if (!strcmp(argv
[i
], "-k"))
830 rfmt
= SEND_FORMAT_ASL
;
832 else if (!strcmp(argv
[i
], "-r"))
837 else if (!strcmp(argv
[i
], "-l"))
839 rlevel
= asl_string_to_level(argv
[++i
]);
842 fprintf(stderr
, "Unknown level: %s\n", argv
[i
]);
849 asl
= asl_open(myname
, "syslog", 0);
850 asl_set_filter(asl
, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG
));
852 m
= asl_new(ASL_TYPE_MSG
);
853 asl_set(m
, ASL_KEY_SENDER
, myname
);
855 sprintf(tmp
, "%d", rlevel
);
856 asl_set(m
, ASL_KEY_LEVEL
, tmp
);
863 for (i
= start
; i
< argc
; i
++) len
+= (strlen(argv
[i
]) + 1);
864 str
= calloc(len
+ 1, 1);
865 if (str
== NULL
) return -1;
867 for (i
= start
; i
< argc
; i
++)
869 strcat(str
, argv
[i
]);
870 if ((i
+1) < argc
) strcat(str
, " ");
872 asl_set(m
, ASL_KEY_MSG
, str
);
876 for (i
= start
+ 1; i
< argc
; i
+= 2) asl_set(m
, argv
[i
], argv
[i
+ 1]);
883 else if (rfmt
== SEND_FORMAT_ASL
)
887 else if ((rfmt
== SEND_FORMAT_LEGACY
) && (str
!= NULL
))
889 rlegacy(str
, rlevel
, rhost
);
894 if (str
!= NULL
) free(str
);
902 print_xml_header(FILE *f
)
904 if (f
== NULL
) return;
906 fprintf(f
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
907 fprintf(f
, "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
908 fprintf(f
, "<plist version=\"1.0\">\n");
909 fprintf(f
, "<array>\n");
913 print_xml_trailer(FILE *f
)
915 if (f
== NULL
) return;
917 fprintf(f
, "</array>\n");
918 fprintf(f
, "</plist>\n");
922 print_xml_str(FILE *f
, const char *str
)
926 if (f
== NULL
) return;
927 if (str
== NULL
) return;
929 for (i
= 0; str
[i
] != '\0'; i
++)
931 if (str
[i
] == '&') fprintf(f
, "&");
932 else if (str
[i
] == '<') fprintf(f
, "<");
933 else if (str
[i
] == '>') fprintf(f
, ">");
934 else if (str
[i
] == '"') fprintf(f
, """);
935 else if (str
[i
] == '\'') fprintf(f
, "'");
936 else fprintf(f
, "%c", str
[i
]);
941 printsafe(FILE *f
, const char *str
)
946 if (f
== NULL
) return;
947 if (str
== NULL
) return;
949 for (i
= 0; str
[i
] != '\0'; i
++)
953 if (isascii(c
) && iscntrl(c
))
955 if (c
== '\n') printf("\\n");
956 else if (c
== '\t') printf("\t");
957 else printf("^%c", c
^ 0100);
959 else printf("%c", c
);
964 printmsg(FILE *f
, asl_msg_t
*msg
, char *fmt
, int pflags
)
968 uint32_t len
, status
;
975 status
= asl_store_save(export
, msg
, -1, -1, &msgid
);
976 if (status
!= ASL_STATUS_OK
)
978 fprintf(stderr
, "export database write failed: %s\n", asl_store_error(status
));
979 asl_store_close(export
);
987 mf
= ASL_MSG_FMT_RAW
;
988 if (fmt
!= NULL
) mf
= (const char *)fmt
;
989 else if (pflags
& FORMAT_STD
) mf
= ASL_MSG_FMT_STD
;
990 else if (pflags
& FORMAT_LEGACY
) mf
= ASL_MSG_FMT_BSD
;
991 else if (pflags
& FORMAT_XML
) mf
= ASL_MSG_FMT_XML
;
993 tf
= ASL_TIME_FMT_SEC
;
994 if (pflags
& TIME_UTC
) tf
= ASL_TIME_FMT_UTC
;
995 if (pflags
& TIME_LCL
) tf
= ASL_TIME_FMT_LCL
;
998 str
= asl_format_message(msg
, mf
, tf
, &len
);
1001 fprintf(f
, "%s", str
);
1007 send_prune(asl_search_result_t
*pl
)
1011 uint32_t len
, status
;
1012 kern_return_t kstatus
;
1013 security_token_t sec
;
1015 if (asl_server_port
== MACH_PORT_NULL
) return 1;
1018 str
= asl_list_to_string(pl
, &len
);
1020 kstatus
= vm_allocate(mach_task_self(), (vm_address_t
*)&vmstr
, len
, TRUE
);
1021 if (kstatus
!= KERN_SUCCESS
)
1027 memmove(vmstr
, str
, len
);
1034 kstatus
= _asl_server_prune(asl_server_port
, (caddr_t
)vmstr
, len
, (int *)&status
, &sec
);
1035 if (kstatus
!= KERN_SUCCESS
) status
= 1;
1040 asl_search_result_t
*
1041 send_query(asl_search_result_t
*q
, uint64_t start
, int count
, int dir
, uint64_t *last
)
1045 uint32_t len
, reslen
, status
;
1046 kern_return_t kstatus
;
1047 security_token_t sec
;
1048 asl_search_result_t
*l
;
1050 if (asl_server_port
== MACH_PORT_NULL
) return NULL
;
1053 str
= asl_list_to_string(q
, &len
);
1055 kstatus
= vm_allocate(mach_task_self(), (vm_address_t
*)&vmstr
, len
, TRUE
);
1056 if (kstatus
!= KERN_SUCCESS
)
1062 memmove(vmstr
, str
, len
);
1071 kstatus
= _asl_server_query(asl_server_port
, (caddr_t
)vmstr
, len
, start
, count
, dir
, (caddr_t
*)&res
, &reslen
, last
, (int *)&status
, &sec
);
1073 if (res
== NULL
) return NULL
;
1074 l
= asl_list_from_string(res
);
1075 vm_deallocate(mach_task_self(), (vm_address_t
)res
, reslen
);
1079 asl_search_result_t
*
1080 db_query(asl_store_t
*s
, asl_search_result_t
*q
, uint64_t qmin
, uint64_t *cmax
)
1083 asl_search_result_t
*res
;
1086 status
= asl_store_match(s
, q
, &res
, cmax
, qmin
, 0, 1, 0, 0);
1087 if (status
!= 0) return NULL
;
1093 search_once(FILE *f
, char *pfmt
, int pflags
, asl_search_result_t
*ql
, uint64_t qmin
, uint64_t *cmax
, uint32_t count
, uint32_t tail
)
1095 asl_search_result_t
*res
;
1098 if (pflags
& FORMAT_XML
) print_xml_header(f
);
1101 while (i
< store_count
)
1104 if ((dbstore
[i
] == NULL
) && (store_raw
== 0))
1108 res
= send_query(ql
, qmin
, 0, 0, cmax
);
1113 res
= send_query(ql
, qmin
, count
, 0, cmax
);
1114 if (*cmax
> qmin
) qmin
= *cmax
;
1115 if (res
== NULL
) i
++;
1116 else if (res
->count
< count
) i
++;
1121 res
= db_query(dbstore
[i
], ql
, qmin
, cmax
);
1130 j
= res
->count
- tail
;
1135 for (; j
< res
->count
; j
++) printmsg(f
, res
->msg
[j
], pfmt
, pflags
);
1137 aslresponse_free((aslresponse
)res
);
1141 if (pflags
& FORMAT_XML
) print_xml_trailer(f
);
1149 op
= ASL_QUERY_OP_NULL
;
1151 if (o
== NULL
) return op
;
1153 for (i
= 0; o
[i
] != '\0'; i
++)
1155 if (o
[i
] == MOD_CASE_FOLD
) op
|= ASL_QUERY_OP_CASEFOLD
;
1156 else if (o
[i
] == MOD_REGEX
) op
|= ASL_QUERY_OP_REGEX
;
1157 else if (o
[i
] == MOD_NUMERIC
) op
|= ASL_QUERY_OP_NUMERIC
;
1158 else if (o
[i
] == MOD_SUBSTRING
) op
|= ASL_QUERY_OP_SUBSTRING
;
1159 else if (o
[i
] == MOD_PREFIX
) op
|= ASL_QUERY_OP_PREFIX
;
1160 else if (o
[i
] == MOD_SUFFIX
) op
|= ASL_QUERY_OP_SUFFIX
;
1162 else if (!strncasecmp(o
+i
, OP_EQ
, sizeof(OP_EQ
)))
1164 op
|= ASL_QUERY_OP_EQUAL
;
1165 i
+= (sizeof(OP_EQ
) - 2);
1167 else if (!strncasecmp(o
+i
, OP_NE
, sizeof(OP_NE
)))
1169 op
|= ASL_QUERY_OP_NOT_EQUAL
;
1170 i
+= (sizeof(OP_NE
) - 2);
1172 else if (!strncasecmp(o
+i
, OP_GT
, sizeof(OP_GT
)))
1174 op
|= ASL_QUERY_OP_GREATER
;
1175 i
+= (sizeof(OP_GT
) - 2);
1177 else if (!strncasecmp(o
+i
, OP_GE
, sizeof(OP_GE
)))
1179 op
|= ASL_QUERY_OP_GREATER_EQUAL
;
1180 i
+= (sizeof(OP_GE
) - 2);
1182 else if (!strncasecmp(o
+i
, OP_LT
, sizeof(OP_LT
)))
1184 op
|= ASL_QUERY_OP_LESS
;
1185 i
+= (sizeof(OP_LT
) - 2);
1187 else if (!strncasecmp(o
+i
, OP_LE
, sizeof(OP_LE
)))
1189 op
|= ASL_QUERY_OP_LESS_EQUAL
;
1190 i
+= (sizeof(OP_LE
) - 2);
1194 fprintf(stderr
, "invalid option: %s\n", o
);
1200 if (op
& ASL_QUERY_OP_NUMERIC
)
1202 if (op
& ASL_QUERY_OP_CASEFOLD
)
1204 fprintf(stderr
, "warning: case fold modifier has no effect with numeric comparisons\n");
1205 op
&= ~ASL_QUERY_OP_CASEFOLD
;
1208 if (op
& ASL_QUERY_OP_REGEX
)
1210 fprintf(stderr
, "warning: regex modifier has no effect with numeric comparisons\n");
1211 op
&= ~ASL_QUERY_OP_REGEX
;
1214 if (op
& ASL_QUERY_OP_SUBSTRING
)
1216 fprintf(stderr
, "warning: substring modifier has no effect with numeric comparisons\n");
1217 op
&= ~ASL_QUERY_OP_SUBSTRING
;
1220 if (op
& ASL_QUERY_OP_PREFIX
)
1222 fprintf(stderr
, "warning: prefix modifier has no effect with numeric comparisons\n");
1223 op
&= ~ASL_QUERY_OP_PREFIX
;
1226 if (op
& ASL_QUERY_OP_SUFFIX
)
1228 fprintf(stderr
, "warning: suffix modifier has no effect with numeric comparisons\n");
1229 op
&= ~ASL_QUERY_OP_SUFFIX
;
1233 if (op
& ASL_QUERY_OP_REGEX
)
1235 if (op
& ASL_QUERY_OP_SUBSTRING
)
1237 fprintf(stderr
, "warning: substring modifier has no effect with regular expression comparisons\n");
1238 op
&= ~ASL_QUERY_OP_SUBSTRING
;
1241 if (op
& ASL_QUERY_OP_PREFIX
)
1243 fprintf(stderr
, "warning: prefix modifier has no effect with regular expression comparisons\n");
1244 op
&= ~ASL_QUERY_OP_PREFIX
;
1247 if (op
& ASL_QUERY_OP_SUFFIX
)
1249 fprintf(stderr
, "warning: suffix modifier has no effect with regular expression comparisons\n");
1250 op
&= ~ASL_QUERY_OP_SUFFIX
;
1258 add_op(asl_msg_t
*q
, char *key
, char *op
, char *val
, uint32_t flags
)
1262 if (key
== NULL
) return -1;
1263 if (q
== NULL
) return -1;
1265 o
= ASL_QUERY_OP_NULL
;
1269 if (o
== ASL_QUERY_OP_NULL
) return -1;
1272 fprintf(stderr
, "no value supplied for operator %s %s\n", key
, op
);
1276 if ((o
& ASL_QUERY_OP_NUMERIC
) && (strcmp(key
, ASL_KEY_TIME
) != 0) && (_isanumber(val
) == 0))
1278 fprintf(stderr
, "non-numeric value supplied for numeric operator %s %s %s\n", key
, op
, val
);
1285 asl_set_query(q
, key
, val
, o
);
1291 add_store(const char *name
, uint32_t flags
)
1300 status
= asl_store_open(name
, flags
, &s
);
1301 if (status
!= ASL_STATUS_OK
)
1303 fprintf(stderr
, "database %s open failed: %s \n", name
, asl_store_error(status
));
1309 fprintf(stderr
, "database %s open failed\n", name
);
1318 if (store_count
== 0) dbstore
= (asl_store_t
**)calloc(1, sizeof(asl_store_t
*));
1319 else dbstore
= (asl_store_t
**)reallocf(dbstore
, (store_count
+ 1) * sizeof(asl_store_t
*));
1321 if (dbstore
== NULL
)
1323 fprintf(stderr
, "Can't allocate memory!\n");
1327 dbstore
[store_count
] = s
;
1332 main(int argc
, char *argv
[])
1335 int i
, j
, n
, watch
, prune
, status
, pflags
, tflags
, sflags
, iamroot
, user_tflag
;
1336 int notify_file
, notify_token
;
1337 asl_search_result_t
*qlist
, *lx
, *res
;
1339 char *logname
, *pfmt
;
1340 const char *dbname
, *exportname
;
1341 uint32_t flags
, tail_count
, batch
;
1342 uint64_t qmin
, cmax
;
1343 kern_return_t kstatus
;
1353 batch
= FETCH_BATCH
;
1354 sflags
= ASL_STORE_FLAG_READ_ONLY
;
1355 pflags
= FORMAT_STD
;
1358 dbname
= _PATH_ASL_STORE
;
1361 if (getuid() == 0) iamroot
= 1;
1363 for (i
= 1; i
< argc
; i
++)
1365 if ((!strcmp(argv
[i
], "-help")) || (!strcmp(argv
[i
], "--help")))
1371 if (!strcmp(argv
[i
], "-s"))
1373 syslog_send(argc
, argv
);
1377 if (!strcmp(argv
[i
], "-c"))
1379 syslog_remote_control(argc
, argv
);
1383 if (!strcmp(argv
[i
], "-p"))
1390 qlist
= (asl_search_result_t
*)calloc(1, sizeof(asl_search_result_t
));
1391 if (qlist
== NULL
) exit(1);
1393 for (i
= 1; i
< argc
; i
++)
1395 if (!strcmp(argv
[i
], "-db"))
1399 for (j
= i
+ 1; j
< argc
; j
++)
1401 if (!strcmp(argv
[j
], "-"))
1403 /* -db - means add syslogd search (dbstore is NULL) */
1404 add_store(NULL
, sflags
);
1406 else if (argv
[j
][0] == '-')
1410 /* No databases: add /var/log/asl.db */
1411 add_store(_PATH_ASL_STORE
, sflags
);
1419 add_store(argv
[j
], sflags
);
1425 /* No databases: add /var/log/asl.db */
1426 add_store(_PATH_ASL_STORE
, sflags
);
1429 else if (!strcmp(argv
[i
], "-w"))
1433 if (((i
+ 1) < argc
) && (argv
[i
+ 1][0] != '-'))
1436 tail_count
= atoi(argv
[i
]);
1439 else if (!strcmp(argv
[i
], "-u"))
1444 else if (!strcmp(argv
[i
], "-x"))
1446 if ((i
+ 1) >= argc
)
1448 aslresponse_free(qlist
);
1453 exportname
= argv
[++i
];
1455 else if (!strcmp(argv
[i
], "-f"))
1457 if ((i
+ 1) >= argc
)
1459 aslresponse_free(qlist
);
1464 logname
= argv
[++i
];
1466 else if (!strcmp(argv
[i
], "-F"))
1468 if ((i
+ 1) >= argc
)
1470 aslresponse_free(qlist
);
1477 if (!strcmp(argv
[i
], "raw"))
1479 pflags
= FORMAT_RAW
;
1480 if (user_tflag
== 0) tflags
= TIME_SEC
;
1482 else if (!strcmp(argv
[i
], "std"))
1484 pflags
= FORMAT_STD
;
1486 else if (!strcmp(argv
[i
], "bsd"))
1488 pflags
= FORMAT_LEGACY
;
1490 else if (!strcmp(argv
[i
], "xml"))
1492 pflags
= FORMAT_XML
;
1500 else if (!strcmp(argv
[i
], "-T"))
1502 if ((i
+ 1) >= argc
)
1504 aslresponse_free(qlist
);
1512 if (!strcmp(argv
[i
], "sec")) tflags
= TIME_SEC
;
1513 else if (!strcmp(argv
[i
], "utc")) tflags
= TIME_UTC
;
1514 else if (!strcmp(argv
[i
], "local")) tflags
= TIME_LCL
;
1515 else if (!strcmp(argv
[i
], "lcl")) tflags
= TIME_LCL
;
1516 else tflags
= TIME_LCL
;
1518 else if (!strcmp(argv
[i
], "-o"))
1522 if (qlist
->count
== 0)
1524 qlist
->msg
= (asl_msg_t
**)calloc(1, sizeof(asl_msg_t
*));
1528 qlist
->msg
= (asl_msg_t
**)reallocf(qlist
->msg
, (qlist
->count
+ 1) * sizeof(asl_msg_t
*));
1531 if (qlist
->msg
== NULL
) exit(1);
1533 cq
= asl_new(ASL_TYPE_QUERY
);
1534 qlist
->msg
[qlist
->count
] = cq
;
1537 else if (!strcmp(argv
[i
], "-n"))
1539 flags
= ASL_QUERY_OP_NOT
;
1541 else if (!strcmp(argv
[i
], "-C"))
1543 if (qlist
->count
== 0)
1545 qlist
->msg
= (asl_msg_t
**)calloc(1, sizeof(asl_msg_t
*));
1546 if (qlist
->msg
== NULL
) exit(1);
1548 cq
= asl_new(ASL_TYPE_QUERY
);
1549 qlist
->msg
[qlist
->count
] = cq
;
1553 status
= add_op(cq
, ASL_KEY_FACILITY
, OP_EQ
, FACILITY_CONSOLE
, flags
);
1558 aslresponse_free(qlist
);
1562 else if (!strcmp(argv
[i
], "-k"))
1565 for (n
= i
; n
< argc
; n
++)
1567 if (!strcmp(argv
[n
], "-o")) break;
1568 if (!strcmp(argv
[n
], "-n")) break;
1569 if (!strcmp(argv
[n
], "-k")) break;
1572 fprintf(stderr
, "invalid sequence: -k");
1573 for (j
= i
; j
<= n
; j
++) fprintf(stderr
, " %s", argv
[j
]);
1574 fprintf(stderr
, "\n");
1587 if (qlist
->count
== 0)
1589 qlist
->msg
= (asl_msg_t
**)calloc(1, sizeof(asl_msg_t
*));
1590 if (qlist
->msg
== NULL
) exit(1);
1592 cq
= asl_new(ASL_TYPE_QUERY
);
1593 qlist
->msg
[qlist
->count
] = cq
;
1598 if (n
== 1) status
= add_op(cq
, argv
[i
], NULL
, NULL
, flags
);
1599 else if (n
== 2) status
= add_op(cq
, argv
[i
], OP_EQ
, argv
[i
+1], flags
);
1600 else status
= add_op(cq
, argv
[i
], argv
[i
+1], argv
[i
+2], flags
);
1605 aslresponse_free(qlist
);
1613 if (store_count
== 0) add_store(NULL
, sflags
);
1615 kstatus
= bootstrap_look_up(bootstrap_port
, ASL_SERVICE_NAME
, &asl_server_port
);
1616 if (kstatus
!= KERN_SUCCESS
)
1620 fprintf(stderr
, "prune operation failed: can't contact syslogd server\n");
1626 fprintf(stderr
, "operation failed: can't contact syslogd server\n");
1630 /* force raw access (for single-user mode when syslogd is not running) */
1633 fprintf(stderr
, "*** can't contact syslogd server - using read-only database access ***\n");
1634 add_store(_PATH_ASL_STORE
, ASL_STORE_FLAG_READ_ONLY
);
1643 fprintf(stderr
, "Warning: -w flag has no effect when pruning\n");
1647 if (qlist
->count
== 0)
1649 fprintf(stderr
, "no queries for pruning\n");
1651 aslresponse_free(qlist
);
1652 for (j
= 0; j
< store_count
; j
++) asl_store_close(dbstore
[j
]);
1653 if (dbstore
!= NULL
) free(dbstore
);
1658 for (i
= 0; i
< store_count
; i
++)
1660 status
= ASL_STATUS_OK
;
1662 if ((dbstore
[i
] == NULL
) && (store_raw
== 0))
1666 fprintf(stderr
, "you must be root to prune the log database\n");
1668 aslresponse_free(qlist
);
1669 for (j
= 0; j
< store_count
; j
++) asl_store_close(dbstore
[j
]);
1670 if (dbstore
!= NULL
) free(dbstore
);
1675 status
= send_prune(qlist
);
1679 status
= asl_store_prune(dbstore
[i
], qlist
);
1682 if (status
!= ASL_STATUS_OK
)
1684 fprintf(stderr
, "database prune failed: %s\n", asl_store_error(status
));
1686 aslresponse_free(qlist
);
1687 for (j
= 0; j
< store_count
; j
++) asl_store_close(dbstore
[j
]);
1688 if (dbstore
!= NULL
) free(dbstore
);
1694 aslresponse_free(qlist
);
1701 if (exportname
!= NULL
)
1705 fprintf(stderr
, "Warning: -w flag has no effect with -x export flag\n");
1709 status
= asl_store_open(exportname
, 0, &export
);
1710 if (status
!= ASL_STATUS_OK
)
1712 aslresponse_free(qlist
);
1713 fprintf(stderr
, "export database open failed: %s\n", asl_store_error(status
));
1730 fprintf(stderr
, "Warning: -w flag can only be used to watch syslogd's active database\n");
1733 else if (store_count
> 1)
1735 fprintf(stderr
, "Warning: -w flag has no effect with multiple databases\n");
1740 status
= notify_register_file_descriptor("com.apple.system.logger.message", ¬ify_file
, 0, ¬ify_token
);
1741 if (status
!= NOTIFY_STATUS_OK
) notify_token
= -1;
1745 if ((qlist
->count
== 0) && (watch
== 1) && (store_raw
== 0))
1747 lx
= (asl_search_result_t
*)calloc(1, sizeof(asl_search_result_t
));
1748 if (lx
== NULL
) exit(1);
1751 lx
->msg
= (asl_msg_t
**)calloc(1, sizeof(asl_msg_t
*));
1752 if (lx
->msg
== NULL
)
1754 aslresponse_free(lx
);
1758 lx
->msg
[0] = asl_new(ASL_TYPE_QUERY
);
1759 if (lx
->msg
[0] == NULL
)
1761 aslresponse_free(lx
);
1765 asl_set_query(lx
->msg
[0], "Level", "0", ASL_QUERY_OP_NUMERIC
| ASL_QUERY_OP_GREATER_EQUAL
);
1767 res
= send_query(lx
, qmin
, 1, 1, &cmax
);
1768 aslresponse_free(lx
);
1769 aslresponse_free(res
);
1770 qmin
= cmax
- tail_count
;
1774 if (qlist
->count
== 0)
1776 qlist
->msg
= (asl_msg_t
**)calloc(1, sizeof(asl_msg_t
*));
1777 if (qlist
->msg
== NULL
) exit(1);
1779 cq
= asl_new(ASL_TYPE_QUERY
);
1780 qlist
->msg
[qlist
->count
] = cq
;
1784 search_once(outfile
, pfmt
, pflags
, qlist
, qmin
, &cmax
, batch
, tail_count
);
1788 if (notify_token
== -1)
1793 if (cmax
> qmin
) qmin
= cmax
;
1794 search_once(outfile
, pfmt
, pflags
, qlist
, qmin
, &cmax
, 0, 0);
1799 while (read(notify_file
, &i
, 4) == 4)
1801 if (cmax
> qmin
) qmin
= cmax
;
1802 search_once(outfile
, pfmt
, pflags
, qlist
, qmin
, &cmax
, 0, 0);
1807 for (i
= 0; i
< store_count
; i
++) asl_store_close(dbstore
[i
]);
1808 if (dbstore
!= NULL
) free(dbstore
);
1809 if (export
!= NULL
) asl_store_close(export
);
1811 aslresponse_free(qlist
);