2 * Copyright (c) 2007-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@
33 #include <sys/socket.h>
34 #include <sys/sysctl.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #include <mach/mach.h>
38 #include <servers/bootstrap.h>
42 #include <asl_private.h>
45 #include <asl_store.h>
48 #define MOD_CASE_FOLD 'C'
50 #define MOD_SUBSTRING 'S'
51 #define MOD_PREFIX 'A'
52 #define MOD_SUFFIX 'Z'
53 #define MOD_NUMERIC 'N'
62 #define ASL_QUERY_OP_NOT 0x1000
64 #define QUERY_FLAG_SEARCH_REVERSE 0x00000001
66 #define FACILITY_CONSOLE "com.apple.console"
68 /* Shared with Libc */
69 #define NOTIFY_RC "com.apple.asl.remote"
73 #define SEARCH_MATCH 1
75 #define PROC_NOT_FOUND -1
76 #define PROC_NOT_UNIQUE -2
82 #define forever for(;;)
84 #define SEND_FORMAT_LEGACY 0
85 #define SEND_FORMAT_ASL 1
87 #define TIME_SEC 0x00000010
88 #define TIME_UTC 0x00000020
89 #define TIME_LCL 0x00000040
91 #define FORMAT_RAW 0x00000100
92 #define FORMAT_LEGACY 0x00000200
93 #define FORMAT_STD 0x00000400
94 #define FORMAT_XML 0x00000800
96 #define EXPORT 0x00000100
98 #define ASL_FILTER_MASK_PACEWNID 0xff
99 #define ASL_FILTER_MASK_PACEWNI 0x7f
100 #define ASL_FILTER_MASK_PACEWN 0x3f
101 #define ASL_FILTER_MASK_PACEW 0x1f
102 #define ASL_FILTER_MASK_PACE 0x0f
103 #define ASL_FILTER_MASK_PAC 0x07
105 #define FETCH_BATCH 1024
107 #define DB_SELECT_STORE 0
108 #define DB_SELECT_FILES 1
109 #define DB_SELECT_SYSLOGD 2
110 #define DB_SELECT_LEGACY 3
112 static asl_file_list_t
*db_files
= NULL
;
113 static asl_store_t
*store
= NULL
;
114 static asl_file_t
*legacy
= NULL
;
115 static asl_file_t
*export
= NULL
;
117 static uint32_t dbselect
= DB_SELECT_STORE
;
120 uint32_t notify_register_plain(const char *name
, int *out_token
);
122 extern char *asl_msg_to_string(aslmsg msg
, uint32_t *len
);
123 extern asl_msg_t
*asl_msg_from_string(const char *buf
);
124 extern char *asl_list_to_string(asl_search_result_t
*list
, uint32_t *outlen
);
125 extern asl_search_result_t
*asl_list_from_string(const char *buf
);
126 extern int asl_msg_cmp(asl_msg_t
*a
, asl_msg_t
*b
);
127 extern time_t asl_parse_time(const char *in
);
128 /* END PRIVATE API */
130 #define ASL_SERVICE_NAME "com.apple.system.logger"
131 static mach_port_t asl_server_port
= MACH_PORT_NULL
;
133 static const char *myname
= "syslog";
138 fprintf(stderr
, "usage:\n");
139 fprintf(stderr
, "%s -s [-r host] [-l level] message...\n", myname
);
140 fprintf(stderr
, " send a message\n");
141 fprintf(stderr
, "\n");
142 fprintf(stderr
, "%s -s [-r host] -k key val [key val]...\n", myname
);
143 fprintf(stderr
, " send a message with the given keys and values\n");
144 fprintf(stderr
, "\n");
145 fprintf(stderr
, "%s -c process [filter]\n", myname
);
146 fprintf(stderr
, " get (set if filter is specified) syslog filter for process (pid or name)\n");
147 fprintf(stderr
, " level may be any combination of the characters \"p a c e w n i d\"\n");
148 fprintf(stderr
, " p = Emergency (\"Panic\")\n");
149 fprintf(stderr
, " a = Alert\n");
150 fprintf(stderr
, " c = Critical\n");
151 fprintf(stderr
, " e = Error\n");
152 fprintf(stderr
, " w = Warning\n");
153 fprintf(stderr
, " n = Notice\n");
154 fprintf(stderr
, " i = Info\n");
155 fprintf(stderr
, " d = Debug\n");
156 fprintf(stderr
, " a minus sign preceeding a single letter means \"up to\" that level\n");
157 fprintf(stderr
, "\n");
158 fprintf(stderr
, "%s [-f file...] [-d path...] [-x file] [-w [N]] [-F format] [-u] [-k key [[op] val]]... [-o -k key [[op] val]] ...]...\n", myname
);
159 fprintf(stderr
, " -f read named file[s], rather than standard log message store.\n");
160 fprintf(stderr
, " -d read all file in named directory path, rather than standard log message store.\n");
161 fprintf(stderr
, " -x export to named ASL format file, rather than printing\n");
162 fprintf(stderr
, " -w watch data store (^C to quit)\n");
163 fprintf(stderr
, " prints the last N matching lines (default 10) before waiting\n");
164 fprintf(stderr
, " \"-w 0\" prints all matching lines before waiting\n");
165 fprintf(stderr
, " -F output format may be \"std\", \"raw\", \"bsd\", or \"xml\"\n");
166 fprintf(stderr
, " format may also be a string containing variables of the form\n");
167 fprintf(stderr
, " $Key or $(Key) - use the latter for non-whitespace delimited variables\n");
168 fprintf(stderr
, " -T timestamp format may be \"sec\" (seconds), \"utc\" (UTC), or \"local\" (local timezone)\n");
169 fprintf(stderr
, " -E text encoding may be \"vis\", \"safe\", or \"none\"\n");
170 fprintf(stderr
, " -u print timestamps using UTC (equivalent to \"-T utc\")\n");
171 fprintf(stderr
, " -k key/value match\n");
172 fprintf(stderr
, " if no operator or value is given, checks for the existance of the key\n");
173 fprintf(stderr
, " if no operator is given, default is \"%s\"\n", OP_EQ
);
174 fprintf(stderr
, " -C alias for \"-k Facility com.apple.console\"\n");
175 fprintf(stderr
, " -o begins a new query\n");
176 fprintf(stderr
, " queries are \'OR\'ed together\n");
177 fprintf(stderr
, "operators are zero or more modifiers followed by a comparison\n");
178 fprintf(stderr
, " %s equal\n", OP_EQ
);
179 fprintf(stderr
, " %s not equal\n", OP_NE
);
180 fprintf(stderr
, " %s greater than\n", OP_GT
);
181 fprintf(stderr
, " %s greater or equal\n", OP_GE
);
182 fprintf(stderr
, " %s less than\n", OP_LT
);
183 fprintf(stderr
, " %s less or equal\n", OP_LE
);
184 fprintf(stderr
, "optional modifiers for operators\n");
185 fprintf(stderr
, " %c case-fold\n", MOD_CASE_FOLD
);
186 fprintf(stderr
, " %c regular expression\n", MOD_REGEX
);
187 fprintf(stderr
, " %c substring\n", MOD_SUBSTRING
);
188 fprintf(stderr
, " %c prefix\n", MOD_PREFIX
);
189 fprintf(stderr
, " %c suffix\n", MOD_SUFFIX
);
190 fprintf(stderr
, " %c numeric comparison\n", MOD_NUMERIC
);
194 notify_status_string(int status
)
196 if (status
== NOTIFY_STATUS_OK
) return "OK";
197 if (status
== NOTIFY_STATUS_INVALID_NAME
) return "Process not registered";
198 if (status
== NOTIFY_STATUS_NOT_AUTHORIZED
) return "Not authorized";
199 return "Operation failed";
203 asl_level_string(int level
)
205 if (level
== ASL_LEVEL_EMERG
) return ASL_STRING_EMERG
;
206 if (level
== ASL_LEVEL_ALERT
) return ASL_STRING_ALERT
;
207 if (level
== ASL_LEVEL_CRIT
) return ASL_STRING_CRIT
;
208 if (level
== ASL_LEVEL_ERR
) return ASL_STRING_ERR
;
209 if (level
== ASL_LEVEL_WARNING
) return ASL_STRING_WARNING
;
210 if (level
== ASL_LEVEL_NOTICE
) return ASL_STRING_NOTICE
;
211 if (level
== ASL_LEVEL_INFO
) return ASL_STRING_INFO
;
212 if (level
== ASL_LEVEL_DEBUG
) return ASL_STRING_DEBUG
;
217 procinfo(char *pname
, int *pid
, int *uid
)
220 int i
, status
, nprocs
;
222 struct kinfo_proc
*procs
, *newprocs
;
229 mib
[2] = KERN_PROC_ALL
;
233 status
= sysctl(mib
, miblen
, NULL
, &size
, NULL
, 0);
237 newprocs
= reallocf(procs
, size
);
238 if (newprocs
== NULL
)
240 if (procs
!= NULL
) free(procs
);
241 return PROC_NOT_FOUND
;
245 status
= sysctl(mib
, miblen
, procs
, &size
, NULL
, 0);
246 } while ((status
== -1) && (errno
== ENOMEM
));
250 if (procs
!= NULL
) free(procs
);
251 return PROC_NOT_FOUND
;
254 if (size
% sizeof(struct kinfo_proc
) != 0)
256 if (procs
!= NULL
) free(procs
);
257 return PROC_NOT_FOUND
;
260 if (procs
== NULL
) return PROC_NOT_FOUND
;
262 nprocs
= size
/ sizeof(struct kinfo_proc
);
266 /* Search for a pid */
267 for (i
= 0; i
< nprocs
; i
++)
269 if (*pid
== procs
[i
].kp_proc
.p_pid
)
271 *uid
= procs
[i
].kp_eproc
.e_ucred
.cr_uid
;
276 return PROC_NOT_FOUND
;
279 *pid
= PROC_NOT_FOUND
;
281 for (i
= 0; i
< nprocs
; i
++)
283 if (!strcmp(procs
[i
].kp_proc
.p_comm
, pname
))
285 if (*pid
!= PROC_NOT_FOUND
)
288 return PROC_NOT_UNIQUE
;
291 *pid
= procs
[i
].kp_proc
.p_pid
;
292 *uid
= procs
[i
].kp_eproc
.e_ucred
.cr_uid
;
297 if (*pid
== PROC_NOT_FOUND
) return PROC_NOT_FOUND
;
303 rcontrol_get_string(const char *name
, int *val
)
308 status
= notify_register_plain(name
, &t
);
309 if (status
!= NOTIFY_STATUS_OK
) return status
;
312 status
= notify_get_state(t
, &x
);
321 rcontrol_set_string(const char *name
, int filter
)
326 status
= notify_register_plain(name
, &t
);
327 if (status
!= NOTIFY_STATUS_OK
) return status
;
330 status
= notify_set_state(t
, x
);
331 notify_post(NOTIFY_RC
);
337 asl_string_to_filter(char *s
)
341 if (s
== NULL
) return 0;
342 if (s
[0] == '\0') return 0;
344 if ((s
[0] >= '0') && (s
[0] <= '9')) return ASL_FILTER_MASK(atoi(s
));
348 if ((s
[1] == 'P') || (s
[1] == 'p')) i
= ASL_LEVEL_EMERG
;
349 else if ((s
[1] == 'A') || (s
[1] == 'a')) i
= ASL_LEVEL_ALERT
;
350 else if ((s
[1] == 'C') || (s
[1] == 'c')) i
= ASL_LEVEL_CRIT
;
351 else if ((s
[1] == 'E') || (s
[1] == 'e')) i
= ASL_LEVEL_ERR
;
352 else if ((s
[1] == 'X') || (s
[1] == 'x')) i
= ASL_LEVEL_ERR
;
353 else if ((s
[1] == 'W') || (s
[1] == 'w')) i
= ASL_LEVEL_WARNING
;
354 else if ((s
[1] == 'N') || (s
[1] == 'n')) i
= ASL_LEVEL_NOTICE
;
355 else if ((s
[1] == 'I') || (s
[1] == 'i')) i
= ASL_LEVEL_INFO
;
356 else if ((s
[1] == 'D') || (s
[1] == 'd')) i
= ASL_LEVEL_DEBUG
;
357 else i
= atoi(s
+ 1);
358 f
= ASL_FILTER_MASK_UPTO(i
);
363 for (i
= 0; s
[i
] != '\0'; i
++)
365 if ((s
[i
] == 'P') || (s
[i
] == 'p')) f
|= ASL_FILTER_MASK_EMERG
;
366 else if ((s
[i
] == 'A') || (s
[i
] == 'a')) f
|= ASL_FILTER_MASK_ALERT
;
367 else if ((s
[i
] == 'C') || (s
[i
] == 'c')) f
|= ASL_FILTER_MASK_CRIT
;
368 else if ((s
[i
] == 'E') || (s
[i
] == 'e')) f
|= ASL_FILTER_MASK_ERR
;
369 else if ((s
[i
] == 'X') || (s
[i
] == 'x')) f
|= ASL_FILTER_MASK_ERR
;
370 else if ((s
[i
] == 'W') || (s
[i
] == 'w')) f
|= ASL_FILTER_MASK_WARNING
;
371 else if ((s
[i
] == 'N') || (s
[i
] == 'n')) f
|= ASL_FILTER_MASK_NOTICE
;
372 else if ((s
[i
] == 'I') || (s
[i
] == 'i')) f
|= ASL_FILTER_MASK_INFO
;
373 else if ((s
[i
] == 'D') || (s
[i
] == 'd')) f
|= ASL_FILTER_MASK_DEBUG
;
380 asl_filter_string(int f
)
382 static char str
[1024];
385 memset(str
, 0, sizeof(str
));
388 if ((f
== ASL_FILTER_MASK_PACEWNID
) != 0)
390 strcat(str
, "Emergency - Debug");
394 if ((f
== ASL_FILTER_MASK_PACEWNI
) != 0)
396 strcat(str
, "Emergency - Info");
400 if ((f
== ASL_FILTER_MASK_PACEWN
) != 0)
402 strcat(str
, "Emergency - Notice");
406 if ((f
== ASL_FILTER_MASK_PACEW
) != 0)
408 strcat(str
, "Emergency - Warning");
412 if ((f
== ASL_FILTER_MASK_PACE
) != 0)
414 strcat(str
, "Emergency - Error");
418 if ((f
== ASL_FILTER_MASK_PAC
) != 0)
420 strcat(str
, "Emergency - Critical");
424 if ((f
& ASL_FILTER_MASK_EMERG
) != 0)
426 strcat(str
, "Emergency");
430 if ((f
& ASL_FILTER_MASK_ALERT
) != 0)
432 if (i
> 0) strcat(str
, ", ");
433 strcat(str
, "Alert");
437 if ((f
& ASL_FILTER_MASK_CRIT
) != 0)
439 if (i
> 0) strcat(str
, ", ");
440 strcat(str
, "Critical");
444 if ((f
& ASL_FILTER_MASK_ERR
) != 0)
446 if (i
> 0) strcat(str
, ", ");
447 strcat(str
, "Error");
451 if ((f
& ASL_FILTER_MASK_WARNING
) != 0)
453 if (i
> 0) strcat(str
, ", ");
454 strcat(str
, "Warning");
458 if ((f
& ASL_FILTER_MASK_NOTICE
) != 0)
460 if (i
> 0) strcat(str
, ", ");
461 strcat(str
, "Notice");
465 if ((f
& ASL_FILTER_MASK_INFO
) != 0)
467 if (i
> 0) strcat(str
, ", ");
472 if ((f
& ASL_FILTER_MASK_DEBUG
) != 0)
474 if (i
> 0) strcat(str
, ", ");
475 strcat(str
, "Debug");
479 if (i
== 0) sprintf(str
, "Off");
485 rcontrol_name(pid_t pid
, uid_t uid
)
487 static char str
[1024];
489 if (pid
== RC_SYSLOGD
) return NOTIFY_SYSTEM_ASL_FILTER
;
490 if (pid
== RC_MASTER
) return NOTIFY_SYSTEM_MASTER
;
492 memset(str
, 0, sizeof(str
));
493 if (uid
== 0) snprintf(str
, sizeof(str
) - 1, "%s.%d", NOTIFY_PREFIX_SYSTEM
, pid
);
494 else snprintf(str
, sizeof(str
) - 1, "user.uid.%d.syslog.%d", uid
, pid
);
499 rcontrol_get(pid_t pid
, uid_t uid
)
509 if (pid
== RC_SYSLOGD
) name
= "ASL Data Store";
511 status
= rcontrol_get_string(rcontrol_name(pid
, uid
), &filter
);
512 if (status
== NOTIFY_STATUS_OK
)
514 printf("%s filter mask: %s\n", name
, asl_filter_string(filter
));
518 printf("Unable to determine %s filter mask\n", name
);
522 status
= rcontrol_get_string(rcontrol_name(pid
, uid
), &filter
);
523 if (status
== NOTIFY_STATUS_OK
)
525 printf("Process %d syslog filter mask: %s\n", pid
, asl_filter_string(filter
));
529 printf("Unable to determine syslog filter mask for pid %d\n", pid
);
534 rcontrol_set(pid_t pid
, uid_t uid
, int filter
)
542 if (pid
== RC_SYSLOGD
) name
= "ASL Data Store";
543 status
= rcontrol_set_string(rcontrol_name(pid
, uid
), filter
);
545 if (status
== NOTIFY_STATUS_OK
)
547 printf("Set %s syslog filter mask: %s\n", name
, asl_filter_string(filter
));
551 printf("Unable to set %s syslog filter mask: %s\n", name
, notify_status_string(status
));
555 status
= rcontrol_set_string(rcontrol_name(pid
, uid
), filter
);
556 if (status
== NOTIFY_STATUS_OK
)
558 if (pid
== RC_SYSLOGD
) status
= notify_post(NOTIFY_SYSTEM_ASL_FILTER
);
559 printf("Set process %d syslog filter mask set: %s\n", pid
, asl_filter_string(filter
));
563 printf("Unable to set syslog filter mask for pid %d: %s\n", pid
, notify_status_string(status
));
568 rsend(aslmsg msg
, char *rhost
)
577 struct sockaddr_in dst
;
579 char myname
[MAXHOSTNAMELEN
+ 1];
581 if (msg
== NULL
) return 0;
583 h
= gethostbyname(rhost
);
584 if (h
== NULL
) return -1;
586 s
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
587 if (s
<= 0) return -1;
589 memset(&dst
, 0, sizeof(struct sockaddr_in
));
590 memcpy(&(dst
.sin_addr
.s_addr
), h
->h_addr_list
[0], 4);
591 dst
.sin_family
= AF_INET
;
593 dst
.sin_len
= sizeof(struct sockaddr_in
);
595 level
= ASL_LEVEL_DEBUG
;
597 val
= asl_get(msg
, ASL_KEY_LEVEL
);
598 if (val
!= NULL
) level
= atoi(val
);
600 memset(>ime
, 0, sizeof(struct tm
));
604 gmtime_r(&tick
, >ime
);
606 /* Canonical form: YYYY.MM.DD hh:mm:ss UTC */
607 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
);
611 asl_set(msg
, ASL_KEY_TIME
, timestr
);
615 if (gethostname(myname
, MAXHOSTNAMELEN
) == 0) asl_set(msg
, ASL_KEY_HOST
, myname
);
618 str
= asl_msg_to_string(msg
, &len
);
619 if (str
== NULL
) return -1;
621 asprintf(&out
, "%10u %s\n", len
+1, str
);
623 if (out
== NULL
) return -1;
625 sendto(s
, out
, len
+12, 0, (const struct sockaddr
*)&dst
, sizeof(struct sockaddr_in
));
633 rlegacy(char *msg
, int level
, char *rhost
)
640 struct sockaddr_in dst
;
642 char myname
[MAXHOSTNAMELEN
+ 1];
644 if (msg
== NULL
) return 0;
646 h
= gethostbyname(rhost
);
647 if (h
== NULL
) return -1;
649 s
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
650 if (s
<= 0) return -1;
652 memset(&dst
, 0, sizeof(struct sockaddr_in
));
653 memcpy(&(dst
.sin_addr
.s_addr
), h
->h_addr_list
[0], 4);
654 dst
.sin_family
= AF_INET
;
656 dst
.sin_len
= sizeof(struct sockaddr_in
);
659 ltime
= ctime(&tick
);
662 gethostname(myname
, MAXHOSTNAMELEN
);
664 asprintf(&out
, "<%d>%s %s syslog[%d]: %s", level
, ltime
+4, myname
, getpid(), msg
);
666 sendto(s
, out
, len
, 0, (const struct sockaddr
*)&dst
, sizeof(struct sockaddr_in
));
678 if (s
== NULL
) return 0;
681 if ((s
[0] == '-') || (s
[0] == '+')) i
= 1;
683 if (s
[i
] == '\0') return 0;
685 for (; s
[i
] != '\0'; i
++)
687 if (!isdigit(s
[i
])) return 0;
694 asl_string_to_level(const char *s
)
696 if (s
== NULL
) return -1;
698 if ((s
[0] >= '0') && (s
[0] <= '7') && (s
[1] == '\0')) return atoi(s
);
700 if (!strncasecmp(s
, "em", 2)) return ASL_LEVEL_EMERG
;
701 else if (!strncasecmp(s
, "p", 1)) return ASL_LEVEL_EMERG
;
702 else if (!strncasecmp(s
, "a", 1)) return ASL_LEVEL_ALERT
;
703 else if (!strncasecmp(s
, "c", 1)) return ASL_LEVEL_CRIT
;
704 else if (!strncasecmp(s
, "er", 2)) return ASL_LEVEL_ERR
;
705 else if (!strncasecmp(s
, "x", 1)) return ASL_LEVEL_ERR
;
706 else if (!strncasecmp(s
, "w", 1)) return ASL_LEVEL_WARNING
;
707 else if (!strncasecmp(s
, "n", 1)) return ASL_LEVEL_NOTICE
;
708 else if (!strncasecmp(s
, "i", 1)) return ASL_LEVEL_INFO
;
709 else if (!strncasecmp(s
, "d", 1)) return ASL_LEVEL_DEBUG
;
715 asl_string_to_char_level(const char *s
)
717 if (s
== NULL
) return NULL
;
719 if ((s
[0] >= '0') && (s
[0] <= '7') && (s
[1] == '\0')) return s
;
721 if (!strncasecmp(s
, "em", 2)) return "0";
722 else if (!strncasecmp(s
, "p", 1)) return "0";
723 else if (!strncasecmp(s
, "a", 1)) return "1";
724 else if (!strncasecmp(s
, "c", 1)) return "2";
725 else if (!strncasecmp(s
, "er", 2)) return "3";
726 else if (!strncasecmp(s
, "x", 1)) return "3";
727 else if (!strncasecmp(s
, "w", 1)) return "4";
728 else if (!strncasecmp(s
, "n", 1)) return "5";
729 else if (!strncasecmp(s
, "i", 1)) return "6";
730 else if (!strncasecmp(s
, "d", 1)) return "7";
736 syslog_remote_control(int argc
, char *argv
[])
738 int pid
, uid
, status
, mask
;
740 if ((argc
< 3) || (argc
> 4))
742 fprintf(stderr
, "usage:\n");
743 fprintf(stderr
, "%s -c process [mask]\n", myname
);
744 fprintf(stderr
, " get (set if mask is specified) syslog filter mask for process (pid or name)\n");
745 fprintf(stderr
, " process may be pid or process name\n");
746 fprintf(stderr
, " use \"-c 0\" to get master syslog filter mask\n");
747 fprintf(stderr
, " use \"-c 0 off\" to disable master syslog filter mask\n");
748 fprintf(stderr
, "\n");
755 status
= PROC_NOT_FOUND
;
757 if ((!strcmp(argv
[2], "syslogd")) || (!strcmp(argv
[2], "syslog")))
763 else if (_isanumber(argv
[2]) != 0)
766 status
= procinfo(NULL
, &pid
, &uid
);
770 status
= procinfo(argv
[2], &pid
, &uid
);
773 if (status
== PROC_NOT_FOUND
)
775 fprintf(stderr
, "%s: process not found\n", argv
[2]);
779 if (status
== PROC_NOT_UNIQUE
)
781 fprintf(stderr
, "%s: multiple processes found\n", argv
[2]);
782 fprintf(stderr
, "use pid to identify a process uniquely\n");
786 if (pid
== 0) pid
= RC_MASTER
;
790 if ((pid
== RC_MASTER
) && (!strcasecmp(argv
[3], "off"))) mask
= 0;
791 else if ((pid
== RC_SYSLOGD
) && (!strcasecmp(argv
[3], "off"))) mask
= 0;
794 mask
= asl_string_to_filter(argv
[3]);
797 printf("unknown syslog mask: %s\n", argv
[3]);
802 rcontrol_set(pid
, uid
, mask
);
806 rcontrol_get(pid
, uid
);
813 syslog_send(int argc
, char *argv
[])
815 int i
, start
, kv
, len
, rfmt
, rlevel
, filter
, status
;
818 char tmp
[64], *str
, *rhost
;
822 rfmt
= SEND_FORMAT_LEGACY
;
826 for (i
= 1; i
< argc
; i
++)
828 if (!strcmp(argv
[i
], "-s")) start
= i
+1;
829 else if (!strcmp(argv
[i
], "-k"))
832 rfmt
= SEND_FORMAT_ASL
;
834 else if (!strcmp(argv
[i
], "-r"))
839 else if (!strcmp(argv
[i
], "-l"))
841 rlevel
= asl_string_to_level(argv
[++i
]);
844 fprintf(stderr
, "Unknown level: %s\n", argv
[i
]);
851 asl
= asl_open(myname
, "syslog", 0);
852 asl_set_filter(asl
, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG
));
854 m
= asl_new(ASL_TYPE_MSG
);
855 asl_set(m
, ASL_KEY_SENDER
, myname
);
857 sprintf(tmp
, "%d", rlevel
);
858 asl_set(m
, ASL_KEY_LEVEL
, tmp
);
865 for (i
= start
; i
< argc
; i
++) len
+= (strlen(argv
[i
]) + 1);
866 str
= calloc(len
+ 1, 1);
867 if (str
== NULL
) return -1;
869 for (i
= start
; i
< argc
; i
++)
871 strcat(str
, argv
[i
]);
872 if ((i
+1) < argc
) strcat(str
, " ");
874 asl_set(m
, ASL_KEY_MSG
, str
);
878 for (i
= start
+ 1; i
< argc
; i
+= 2)
880 if (!strcmp(argv
[i
], "-k")) i
++;
881 asl_set(m
, argv
[i
], argv
[i
+ 1]);
882 if (!strcmp(argv
[i
], ASL_KEY_LEVEL
)) rlevel
= atoi(argv
[i
+ 1]);
889 status
= rcontrol_get_string(rcontrol_name(RC_SYSLOGD
, 0), &filter
);
892 fprintf(stderr
, "Warning: Can't get current syslogd ASL filter value\n");
894 else if ((ASL_FILTER_MASK(rlevel
) & filter
) == 0)
896 fprintf(stderr
, "Warning: The current syslogd ASL filter value (%s)\n", asl_filter_string(filter
));
897 fprintf(stderr
, " will exclude this message from the ASL database\n");
902 else if (rfmt
== SEND_FORMAT_ASL
)
906 else if ((rfmt
== SEND_FORMAT_LEGACY
) && (str
!= NULL
))
908 rlegacy(str
, rlevel
, rhost
);
913 if (str
!= NULL
) free(str
);
921 print_xml_header(FILE *f
)
923 if (f
== NULL
) return;
925 fprintf(f
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
926 fprintf(f
, "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
927 fprintf(f
, "<plist version=\"1.0\">\n");
928 fprintf(f
, "<array>\n");
932 print_xml_trailer(FILE *f
)
934 if (f
== NULL
) return;
936 fprintf(f
, "</array>\n");
937 fprintf(f
, "</plist>\n");
941 printmsg(FILE *f
, asl_msg_t
*msg
, char *fmt
, int pflags
)
945 uint32_t encode
, len
, status
;
953 status
= asl_file_save(export
, msg
, &xid
);
954 if (status
!= ASL_STATUS_OK
)
956 fprintf(stderr
, "export file write failed: %s\n", asl_core_error(status
));
957 asl_file_close(export
);
965 encode
= pflags
& 0x0000000f;
967 mf
= ASL_MSG_FMT_RAW
;
968 if (fmt
!= NULL
) mf
= (const char *)fmt
;
969 else if (pflags
& FORMAT_STD
) mf
= ASL_MSG_FMT_STD
;
970 else if (pflags
& FORMAT_LEGACY
) mf
= ASL_MSG_FMT_BSD
;
971 else if (pflags
& FORMAT_XML
) mf
= ASL_MSG_FMT_XML
;
973 tf
= ASL_TIME_FMT_SEC
;
974 if (pflags
& TIME_UTC
) tf
= ASL_TIME_FMT_UTC
;
975 if (pflags
& TIME_LCL
) tf
= ASL_TIME_FMT_LCL
;
978 str
= asl_format_message(msg
, mf
, tf
, encode
, &len
);
981 fprintf(f
, "%s", str
);
986 asl_search_result_t
*
987 store_query(asl_search_result_t
*q
, uint64_t start
, int count
, int dir
, uint64_t *last
)
990 asl_search_result_t
*res
;
994 status
= asl_store_open_read(NULL
, &store
);
995 if (status
!= 0) return NULL
;
999 status
= asl_store_match(store
, q
, &res
, last
, start
, count
, dir
);
1000 if (status
!= 0) return NULL
;
1005 asl_search_result_t
*
1006 file_query(asl_search_result_t
*q
, uint64_t start
, int count
, int dir
, uint64_t *last
)
1009 asl_search_result_t
*res
;
1012 status
= asl_file_list_match(db_files
, q
, &res
, last
, start
, count
, dir
);
1013 if (status
!= 0) return NULL
;
1018 asl_search_result_t
*
1019 legacy_query(asl_search_result_t
*q
, uint64_t start
, int count
, int dir
, uint64_t *last
)
1022 asl_search_result_t
*res
;
1025 status
= asl_file_match(legacy
, q
, &res
, last
, start
, count
, dir
);
1026 if (status
!= 0) return NULL
;
1031 asl_search_result_t
*
1032 syslogd_query(asl_search_result_t
*q
, uint64_t start
, int count
, int dir
, uint64_t *last
)
1036 uint32_t len
, reslen
, status
;
1038 kern_return_t kstatus
;
1039 security_token_t sec
;
1040 asl_search_result_t
*l
;
1042 if (asl_server_port
== MACH_PORT_NULL
)
1044 kstatus
= bootstrap_look_up(bootstrap_port
, ASL_SERVICE_NAME
, &asl_server_port
);
1045 if (kstatus
!= KERN_SUCCESS
)
1047 fprintf(stderr
, "query failed: can't contact syslogd\n");
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 if (dir
< 0) flags
= QUERY_FLAG_SEARCH_REVERSE
;
1073 kstatus
= _asl_server_query(asl_server_port
, (caddr_t
)vmstr
, len
, start
, count
, flags
, (caddr_t
*)&res
, &reslen
, last
, (int *)&status
, &sec
);
1075 if (res
== NULL
) return NULL
;
1076 l
= asl_list_from_string(res
);
1077 vm_deallocate(mach_task_self(), (vm_address_t
)res
, reslen
);
1082 search_once(FILE *f
, char *pfmt
, int pflags
, asl_search_result_t
*ql
, uint64_t qmin
, uint64_t *cmax
, uint32_t count
, uint32_t batch
, int dir
, uint32_t tail
)
1084 asl_search_result_t
*res
;
1087 if (pflags
& FORMAT_XML
) print_xml_header(f
);
1095 if (dbselect
== DB_SELECT_STORE
) res
= store_query(ql
, qmin
, batch
, dir
, cmax
);
1096 else if (dbselect
== DB_SELECT_FILES
) res
= file_query(ql
, qmin
, batch
, dir
, cmax
);
1097 else if (dbselect
== DB_SELECT_SYSLOGD
) res
= syslogd_query(ql
, qmin
, batch
, dir
, cmax
);
1098 else if (dbselect
== DB_SELECT_LEGACY
) res
= legacy_query(ql
, qmin
, batch
, dir
, cmax
);
1100 if ((dir
>= 0) && (*cmax
> qmin
)) qmin
= *cmax
;
1101 else if ((dir
< 0) && (*cmax
< qmin
)) qmin
= *cmax
;
1109 if ((batch
> 0) && (res
->count
< batch
)) more
= 0;
1110 total
+= res
->count
;
1111 if ((count
> 0) && (total
>= count
)) more
= 0;
1116 i
= res
->count
- tail
;
1121 if ((f
!= NULL
) || (export
!= NULL
))
1123 for (; i
< res
->count
; i
++) printmsg(f
, res
->msg
[i
], pfmt
, pflags
);
1126 aslresponse_free((aslresponse
)res
);
1130 if (pflags
& FORMAT_XML
) print_xml_trailer(f
);
1138 op
= ASL_QUERY_OP_NULL
;
1140 if (o
== NULL
) return op
;
1142 for (i
= 0; o
[i
] != '\0'; i
++)
1144 if (o
[i
] == MOD_CASE_FOLD
) op
|= ASL_QUERY_OP_CASEFOLD
;
1145 else if (o
[i
] == MOD_REGEX
) op
|= ASL_QUERY_OP_REGEX
;
1146 else if (o
[i
] == MOD_NUMERIC
) op
|= ASL_QUERY_OP_NUMERIC
;
1147 else if (o
[i
] == MOD_SUBSTRING
) op
|= ASL_QUERY_OP_SUBSTRING
;
1148 else if (o
[i
] == MOD_PREFIX
) op
|= ASL_QUERY_OP_PREFIX
;
1149 else if (o
[i
] == MOD_SUFFIX
) op
|= ASL_QUERY_OP_SUFFIX
;
1151 else if (!strncasecmp(o
+i
, OP_EQ
, sizeof(OP_EQ
)))
1153 op
|= ASL_QUERY_OP_EQUAL
;
1154 i
+= (sizeof(OP_EQ
) - 2);
1156 else if (!strncasecmp(o
+i
, OP_NE
, sizeof(OP_NE
)))
1158 op
|= ASL_QUERY_OP_NOT_EQUAL
;
1159 i
+= (sizeof(OP_NE
) - 2);
1161 else if (!strncasecmp(o
+i
, OP_GT
, sizeof(OP_GT
)))
1163 op
|= ASL_QUERY_OP_GREATER
;
1164 i
+= (sizeof(OP_GT
) - 2);
1166 else if (!strncasecmp(o
+i
, OP_GE
, sizeof(OP_GE
)))
1168 op
|= ASL_QUERY_OP_GREATER_EQUAL
;
1169 i
+= (sizeof(OP_GE
) - 2);
1171 else if (!strncasecmp(o
+i
, OP_LT
, sizeof(OP_LT
)))
1173 op
|= ASL_QUERY_OP_LESS
;
1174 i
+= (sizeof(OP_LT
) - 2);
1176 else if (!strncasecmp(o
+i
, OP_LE
, sizeof(OP_LE
)))
1178 op
|= ASL_QUERY_OP_LESS_EQUAL
;
1179 i
+= (sizeof(OP_LE
) - 2);
1183 fprintf(stderr
, "invalid option: %s\n", o
);
1189 if (op
& ASL_QUERY_OP_NUMERIC
)
1191 if (op
& ASL_QUERY_OP_CASEFOLD
)
1193 fprintf(stderr
, "warning: case fold modifier has no effect with numeric comparisons\n");
1194 op
&= ~ASL_QUERY_OP_CASEFOLD
;
1197 if (op
& ASL_QUERY_OP_REGEX
)
1199 fprintf(stderr
, "warning: regex modifier has no effect with numeric comparisons\n");
1200 op
&= ~ASL_QUERY_OP_REGEX
;
1203 if (op
& ASL_QUERY_OP_SUBSTRING
)
1205 fprintf(stderr
, "warning: substring modifier has no effect with numeric comparisons\n");
1206 op
&= ~ASL_QUERY_OP_SUBSTRING
;
1209 if (op
& ASL_QUERY_OP_PREFIX
)
1211 fprintf(stderr
, "warning: prefix modifier has no effect with numeric comparisons\n");
1212 op
&= ~ASL_QUERY_OP_PREFIX
;
1215 if (op
& ASL_QUERY_OP_SUFFIX
)
1217 fprintf(stderr
, "warning: suffix modifier has no effect with numeric comparisons\n");
1218 op
&= ~ASL_QUERY_OP_SUFFIX
;
1222 if (op
& ASL_QUERY_OP_REGEX
)
1224 if (op
& ASL_QUERY_OP_SUBSTRING
)
1226 fprintf(stderr
, "warning: substring modifier has no effect with regular expression comparisons\n");
1227 op
&= ~ASL_QUERY_OP_SUBSTRING
;
1230 if (op
& ASL_QUERY_OP_PREFIX
)
1232 fprintf(stderr
, "warning: prefix modifier has no effect with regular expression comparisons\n");
1233 op
&= ~ASL_QUERY_OP_PREFIX
;
1236 if (op
& ASL_QUERY_OP_SUFFIX
)
1238 fprintf(stderr
, "warning: suffix modifier has no effect with regular expression comparisons\n");
1239 op
&= ~ASL_QUERY_OP_SUFFIX
;
1247 add_op(asl_msg_t
*q
, char *key
, char *op
, char *val
, uint32_t flags
)
1252 if (key
== NULL
) return -1;
1253 if (q
== NULL
) return -1;
1256 if (strcmp(key
, ASL_KEY_TIME
) == 0)
1258 qval
= (const char *)val
;
1260 else if ((strcmp(key
, ASL_KEY_LEVEL
) == 0) && (_isanumber(val
) == 0))
1262 /* Convert level strings to numeric values */
1263 qval
= asl_string_to_char_level(val
);
1266 fprintf(stderr
, "invalid value for \"Level\"key: %s\n", val
);
1271 o
= ASL_QUERY_OP_NULL
;
1272 if (val
== NULL
) o
= ASL_QUERY_OP_TRUE
;
1277 if (o
== ASL_QUERY_OP_NULL
) return -1;
1280 fprintf(stderr
, "no value supplied for operator %s %s\n", key
, op
);
1284 if ((qval
== NULL
) && (o
& ASL_QUERY_OP_NUMERIC
) && (_isanumber(val
) == 0))
1286 fprintf(stderr
, "non-numeric value supplied for numeric operator %s %s %s\n", key
, op
, val
);
1292 if (qval
!= NULL
) asl_set_query(q
, key
, qval
, o
);
1293 else asl_set_query(q
, key
, val
, o
);
1299 add_db_file(const char *name
)
1304 if (dbselect
== DB_SELECT_LEGACY
)
1306 fprintf(stderr
, "syslog can only read one legacy format database\n");
1307 fprintf(stderr
, "can't combine legacy and non-legacy databases in a single search\n");
1311 /* shouldn't happen */
1312 if (name
== NULL
) return DB_SELECT_STORE
;
1315 status
= asl_file_open_read(name
, &s
);
1316 if (status
!= ASL_STATUS_OK
)
1318 fprintf(stderr
, "data store file %s open failed: %s \n", name
, asl_core_error(status
));
1324 fprintf(stderr
, "data store file %s open failed\n", name
);
1328 if (s
->flags
& ASL_FILE_FLAG_LEGACY_STORE
)
1330 if (db_files
!= NULL
)
1332 fprintf(stderr
, "syslog can only read a single legacy format database\n");
1333 fprintf(stderr
, "can't combine legacy and non-legacy databases in a single search\n");
1338 return DB_SELECT_LEGACY
;
1341 db_files
= asl_file_list_add(db_files
, s
);
1342 return DB_SELECT_FILES
;
1346 add_db_dir(const char *name
)
1349 struct dirent
*dent
;
1355 * Open all readable files
1360 fprintf(stderr
, "%s: %s\n", name
, strerror(errno
));
1364 while ((dent
= readdir(dp
)) != NULL
)
1366 if (dent
->d_name
[0] == '.') continue;
1369 asprintf(&path
, "%s/%s", name
, dent
->d_name
);
1372 * asl_file_open_read will fail if path is NULL,
1373 * if the file is not an ASL store file,
1374 * or if it isn't readable.
1377 status
= asl_file_open_read(path
, &s
);
1378 if (path
!= NULL
) free(path
);
1379 if ((status
!= ASL_STATUS_OK
) || (s
== NULL
)) continue;
1381 db_files
= asl_file_list_add(db_files
, s
);
1386 return DB_SELECT_FILES
;
1390 main(int argc
, char *argv
[])
1393 int i
, j
, n
, watch
, status
, pflags
, tflags
, iamroot
, user_tflag
;
1394 int notify_file
, notify_token
;
1395 asl_search_result_t
*qlist
;
1398 const char *exportname
;
1399 uint32_t flags
, tail_count
, batch
, encode
;
1400 uint64_t qmin
, cmax
;
1408 batch
= FETCH_BATCH
;
1409 pflags
= FORMAT_STD
;
1411 encode
= ASL_ENCODE_ASL
;
1415 i
= asl_store_location();
1416 if (i
== ASL_STORE_LOCATION_MEMORY
) dbselect
= DB_SELECT_SYSLOGD
;
1418 if (getuid() == 0) iamroot
= 1;
1420 for (i
= 1; i
< argc
; i
++)
1422 if ((!strcmp(argv
[i
], "-help")) || (!strcmp(argv
[i
], "--help")))
1428 if (!strcmp(argv
[i
], "-time"))
1431 printf("%llu\n", qmin
);
1435 if (!strcmp(argv
[i
], "-s"))
1437 syslog_send(argc
, argv
);
1441 if (!strcmp(argv
[i
], "-c"))
1443 syslog_remote_control(argc
, argv
);
1448 qlist
= (asl_search_result_t
*)calloc(1, sizeof(asl_search_result_t
));
1449 if (qlist
== NULL
) exit(1);
1451 for (i
= 1; i
< argc
; i
++)
1453 if (!strcmp(argv
[i
], "-f"))
1457 for (j
= i
+ 1; j
< argc
; j
++)
1459 if (!strcmp(argv
[j
], "-"))
1461 dbselect
= DB_SELECT_SYSLOGD
;
1464 else if (argv
[j
][0] == '-')
1470 dbselect
= add_db_file(argv
[j
]);
1475 if (!strcmp(argv
[i
], "-d"))
1479 for (j
= i
+ 1; j
< argc
; j
++)
1481 if (!strcmp(argv
[j
], "store"))
1483 dbselect
= add_db_dir(PATH_ASL_STORE
);
1485 else if (!strcmp(argv
[j
], "archive"))
1487 dbselect
= add_db_dir(PATH_ASL_ARCHIVE
);
1489 else if (argv
[j
][0] == '-')
1495 dbselect
= add_db_dir(argv
[j
]);
1500 else if (!strcmp(argv
[i
], "-w"))
1504 if (((i
+ 1) < argc
) && (argv
[i
+ 1][0] != '-'))
1507 tail_count
= atoi(argv
[i
]);
1510 else if (!strcmp(argv
[i
], "-u"))
1515 else if (!strcmp(argv
[i
], "-x"))
1517 if ((i
+ 1) >= argc
)
1519 aslresponse_free(qlist
);
1524 exportname
= argv
[++i
];
1526 else if (!strcmp(argv
[i
], "-E"))
1528 if ((i
+ 1) >= argc
)
1530 aslresponse_free(qlist
);
1537 if (!strcmp(argv
[i
], "vis")) encode
= ASL_ENCODE_ASL
;
1538 else if (!strcmp(argv
[i
], "safe")) encode
= ASL_ENCODE_SAFE
;
1539 else if (!strcmp(argv
[i
], "none")) encode
= ASL_ENCODE_NONE
;
1540 else if ((argv
[i
][0] >= '0') && (argv
[i
][0] <= '9') && (argv
[i
][1] == '\0')) encode
= atoi(argv
[i
]);
1542 else if (!strcmp(argv
[i
], "-F"))
1544 if ((i
+ 1) >= argc
)
1546 aslresponse_free(qlist
);
1553 if (!strcmp(argv
[i
], "raw"))
1555 pflags
= FORMAT_RAW
;
1556 if (user_tflag
== 0) tflags
= TIME_SEC
;
1558 else if (!strcmp(argv
[i
], "std"))
1560 pflags
= FORMAT_STD
;
1562 else if (!strcmp(argv
[i
], "bsd"))
1564 pflags
= FORMAT_LEGACY
;
1566 else if (!strcmp(argv
[i
], "xml"))
1568 pflags
= FORMAT_XML
;
1576 else if (!strcmp(argv
[i
], "-T"))
1578 if ((i
+ 1) >= argc
)
1580 aslresponse_free(qlist
);
1588 if (!strcmp(argv
[i
], "sec")) tflags
= TIME_SEC
;
1589 else if (!strcmp(argv
[i
], "utc")) tflags
= TIME_UTC
;
1590 else if (!strcmp(argv
[i
], "local")) tflags
= TIME_LCL
;
1591 else if (!strcmp(argv
[i
], "lcl")) tflags
= TIME_LCL
;
1592 else tflags
= TIME_LCL
;
1594 else if (!strcmp(argv
[i
], "-o"))
1598 if (qlist
->count
== 0)
1600 qlist
->msg
= (asl_msg_t
**)calloc(1, sizeof(asl_msg_t
*));
1604 qlist
->msg
= (asl_msg_t
**)reallocf(qlist
->msg
, (qlist
->count
+ 1) * sizeof(asl_msg_t
*));
1607 if (qlist
->msg
== NULL
) exit(1);
1609 cq
= asl_new(ASL_TYPE_QUERY
);
1610 qlist
->msg
[qlist
->count
] = cq
;
1613 else if (!strcmp(argv
[i
], "-n"))
1615 flags
= ASL_QUERY_OP_NOT
;
1617 else if (!strcmp(argv
[i
], "-C"))
1619 if (qlist
->count
== 0)
1621 qlist
->msg
= (asl_msg_t
**)calloc(1, sizeof(asl_msg_t
*));
1622 if (qlist
->msg
== NULL
) exit(1);
1624 cq
= asl_new(ASL_TYPE_QUERY
);
1625 qlist
->msg
[qlist
->count
] = cq
;
1629 status
= add_op(cq
, ASL_KEY_FACILITY
, OP_EQ
, FACILITY_CONSOLE
, flags
);
1634 aslresponse_free(qlist
);
1638 else if (!strcmp(argv
[i
], "-k"))
1641 for (n
= i
; n
< argc
; n
++)
1643 if (!strcmp(argv
[n
], "-o")) break;
1644 if (!strcmp(argv
[n
], "-n")) break;
1645 if (!strcmp(argv
[n
], "-k")) break;
1648 fprintf(stderr
, "invalid sequence: -k");
1649 for (j
= i
; j
<= n
; j
++) fprintf(stderr
, " %s", argv
[j
]);
1650 fprintf(stderr
, "\n");
1663 if (qlist
->count
== 0)
1665 qlist
->msg
= (asl_msg_t
**)calloc(1, sizeof(asl_msg_t
*));
1666 if (qlist
->msg
== NULL
) exit(1);
1668 cq
= asl_new(ASL_TYPE_QUERY
);
1669 qlist
->msg
[qlist
->count
] = cq
;
1674 if (n
== 1) status
= add_op(cq
, argv
[i
], NULL
, NULL
, flags
);
1675 else if (n
== 2) status
= add_op(cq
, argv
[i
], OP_EQ
, argv
[i
+1], flags
);
1676 else status
= add_op(cq
, argv
[i
], argv
[i
+1], argv
[i
+2], flags
);
1681 aslresponse_free(qlist
);
1692 if (exportname
!= NULL
)
1696 fprintf(stderr
, "Warning: -w flag has no effect with -x export flag\n");
1700 status
= asl_file_open_write(exportname
, 0644, -1, -1, &export
);
1701 if (status
!= ASL_STATUS_OK
)
1703 aslresponse_free(qlist
);
1704 fprintf(stderr
, "export file open failed: %s\n", asl_core_error(status
));
1709 * allow the string cache to be unlimited to maximize string dup compression
1710 * preserve message IDs
1712 export
->flags
= ASL_FILE_FLAG_UNLIMITED_CACHE
| ASL_FILE_FLAG_PRESERVE_MSG_ID
;
1725 if ((dbselect
== DB_SELECT_STORE
) || (dbselect
== DB_SELECT_SYSLOGD
))
1727 status
= notify_register_file_descriptor("com.apple.system.logger.message", ¬ify_file
, 0, ¬ify_token
);
1728 if (status
!= NOTIFY_STATUS_OK
) notify_token
= -1;
1732 if ((qlist
->count
== 0) && (watch
== 1))
1735 search_once(NULL
, NULL
, 0, NULL
, qmin
, &cmax
, 1, 1, -1, 0);
1736 qmin
= (cmax
+ 1) - tail_count
;
1740 /* output should be line buffered */
1741 if (outfile
!= NULL
) setlinebuf(outfile
);
1743 search_once(outfile
, pfmt
, pflags
, qlist
, qmin
, &cmax
, 0, batch
, 1, tail_count
);
1747 if (notify_token
== -1)
1752 if (cmax
> qmin
) qmin
= cmax
;
1753 search_once(outfile
, pfmt
, pflags
, qlist
, qmin
+ 1, &cmax
, 0, batch
, 1, 0);
1758 while (read(notify_file
, &i
, 4) == 4)
1760 if (cmax
> qmin
) qmin
= cmax
;
1761 search_once(outfile
, pfmt
, pflags
, qlist
, qmin
+ 1, &cmax
, 0, batch
, 1, 0);
1766 if (db_files
!= NULL
) asl_file_list_close(db_files
);
1767 if (store
!= NULL
) asl_store_close(store
);
1768 if (export
!= NULL
) asl_file_close(export
);
1770 aslresponse_free(qlist
);