2 * Copyright (c) 2007-2015 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 <TargetConditionals.h>
34 #include <sys/socket.h>
35 #include <sys/sysctl.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
38 #include <mach/mach.h>
39 #include <servers/bootstrap.h>
40 #include <bootstrap_priv.h>
45 #include <asl_msg_list.h>
46 #include <asl_private.h>
49 #include <asl_store.h>
51 #include <asl_client.h>
52 #include "asl_common.h"
54 #define MOD_CASE_FOLD 'C'
56 #define MOD_SUBSTRING 'S'
57 #define MOD_PREFIX 'A'
58 #define MOD_SUFFIX 'Z'
59 #define MOD_NUMERIC 'N'
68 #define ASL_QUERY_OP_NOT 0x1000
70 #define QUERY_FLAG_SEARCH_REVERSE 0x00000001
72 #define FACILITY_CONSOLE "com.apple.console"
76 #define SEARCH_MATCH 1
78 #define PROC_NOT_FOUND -1
79 #define PROC_NOT_UNIQUE -2
84 #define forever for(;;)
86 #define SEND_FORMAT_LEGACY 0
87 #define SEND_FORMAT_ASL 1
89 #define FORMAT_RAW 0x00000100
90 #define FORMAT_LEGACY 0x00000200
91 #define FORMAT_STD 0x00000400
92 #define FORMAT_XML 0x00000800
93 #define COMPRESS_DUPS 0x00010000
95 #define EXPORT 0x00000100
97 #define ASL_FILTER_MASK_PACEWNID 0xff
98 #define ASL_FILTER_MASK_PACEWNI 0x7f
99 #define ASL_FILTER_MASK_PACEWN 0x3f
100 #define ASL_FILTER_MASK_PACEW 0x1f
101 #define ASL_FILTER_MASK_PACE 0x0f
102 #define ASL_FILTER_MASK_PAC 0x07
104 #define FETCH_BATCH 1024
105 #define MAX_RANDOM 8192
107 #define DB_SELECT_ASL 0
108 #define DB_SELECT_STORE 1
109 #define DB_SELECT_FILES 2
110 #define DB_SELECT_SYSLOGD 3
111 #define DB_SELECT_LEGACY 4
113 /* STD and BSD format messages start with 'DAY MMM DD HH:MM:SS ' timestamp */
114 #define STD_BSD_DATE_LEN 20
116 /* Max message size for direct watch */
117 #define MAX_DIRECT_SIZE 16384
119 /* Buffer for direct watch data */
120 #define DIRECT_BUF_SIZE 1024
122 static asl_file_list_t
*db_files
= NULL
;
123 static asl_store_t
*store
= NULL
;
124 static asl_file_t
*legacy
= NULL
;
125 static asl_file_t
*export
= NULL
;
126 static const char *sort_key
= NULL
;
127 static const char *sort_key_2
= NULL
;
128 static int sort_numeric
= 0;
129 static char *last_printmsg_str
= NULL
;
130 static int last_printmsg_count
= 0;
131 static const char *tfmt
= NULL
;
133 #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
134 static uint32_t dbselect
= DB_SELECT_SYSLOGD
;
136 static uint32_t dbselect
= DB_SELECT_ASL
;
143 uint32_t total_messages
;
149 #define ASL_IOS_STATS_DIR "/var/log/asl/Logs/ASLStatistics"
150 static uint32_t stats_sender_count
;
151 static sender_stat_t
**stats_sender
;
152 static uint32_t stats_total_all_messages
;
155 uint32_t notify_register_plain(const char *name
, int *out_token
);
157 asl_msg_t
*_asl_server_control_query(void);
158 extern time_t asl_parse_time(const char *in
);
159 asl_msg_t
* asl_base_msg(asl_client_t
*asl
, uint32_t level
, const struct timeval
*tv
, const char *sstr
, const char *fstr
, const char *mstr
);
160 /* END PRIVATE API */
162 static mach_port_t asl_server_port
= MACH_PORT_NULL
;
164 static const char *myname
= "syslog";
167 asl_msg_list_t
*syslogd_query(asl_msg_list_t
*q
, uint64_t start
, int count
, int dir
, uint64_t *last
);
168 static void printmsg(FILE *f
, asl_msg_t
*msg
, char *fmt
, int pflags
);
170 #define HELP_UNAVAILABLE -1
171 #define HELP_CONTROL HELP_UNAVAILABLE /* undocumented */
174 #define HELP_REMOTE_CONTROL 2
175 #define HELP_CONFIG 3
176 #define HELP_MODULE 4
177 #define HELP_SEARCH 5
181 usage(uint32_t section
)
183 if (section
== HELP_UNAVAILABLE
)
185 fprintf(stderr
, "help is not available for this command\n");
189 fprintf(stderr
, "usage:\n");
191 if ((section
== HELP_ALL
) || (section
== HELP_SEND
))
193 fprintf(stderr
, "%s -s [-r host] [-l level] message...\n", myname
);
194 fprintf(stderr
, " send a message\n");
195 fprintf(stderr
, "\n");
197 fprintf(stderr
, "%s -s [-r host] -k key val [key val]...\n", myname
);
198 fprintf(stderr
, " send a message with the given keys and values\n");
199 fprintf(stderr
, "\n");
202 if ((section
== HELP_ALL
) || (section
== HELP_REMOTE_CONTROL
))
204 fprintf(stderr
, "%s -c process [mask] [-s [on|off]] [-t [on|off]]\n", myname
);
205 fprintf(stderr
, " get (set if mask or actions are specified) syslog filter mask and actions for process (pid or name)\n");
206 fprintf(stderr
, " mask may be any combination of the characters \"p a c e w n i d\"\n");
207 fprintf(stderr
, " p = Emergency (\"Panic\")\n");
208 fprintf(stderr
, " a = Alert\n");
209 fprintf(stderr
, " c = Critical\n");
210 fprintf(stderr
, " e = Error\n");
211 fprintf(stderr
, " w = Warning\n");
212 fprintf(stderr
, " n = Notice\n");
213 fprintf(stderr
, " i = Info\n");
214 fprintf(stderr
, " d = Debug\n");
215 fprintf(stderr
, " a minus sign preceding a single letter means \"up to\" that level\n");
216 fprintf(stderr
, " use \"0\" for process to get or set master syslog flags\n");
217 fprintf(stderr
, " use \"-c process off\" to deactivate current settings\n");
218 fprintf(stderr
, " -s controls sending ASL mesages (to syslogd)\n");
219 fprintf(stderr
, " -t controls sending Activity Tracing mesages\n");
220 fprintf(stderr
, "\n");
223 if ((section
== HELP_ALL
) || (section
== HELP_CONFIG
))
225 fprintf(stderr
, "%s -config [params...]\n", myname
);
226 fprintf(stderr
, " without params, fetch and print syslogd parameters and statistics\n");
227 fprintf(stderr
, " otherwise, set or reset syslogd configuration parameters\n");
228 fprintf(stderr
, "\n");
231 if ((section
== HELP_ALL
) || (section
== HELP_MODULE
))
233 fprintf(stderr
, "%s -module [name [action]]\n", myname
);
234 fprintf(stderr
, " with no name, prints configuration for all ASL output modules\n");
235 fprintf(stderr
, " with name and no action, prints configuration for named ASL output module\n");
236 fprintf(stderr
, " supported actions - module name required, use '*' (with single quotes) for all modules:\n");
237 fprintf(stderr
, " enable [01] enables (or disables with 0) named module\n");
238 fprintf(stderr
, " does not apply to com.apple.asl when '*' is used\n");
239 fprintf(stderr
, " checkpoint [file] checkpoints all files or specified file for named module\n");
240 fprintf(stderr
, "\n");
243 if ((section
== HELP_ALL
) || (section
== HELP_SEARCH
))
245 fprintf(stderr
, "%s [-f file...] [-d path...] [-x file] [-w [N]] [-F format] [-nocompress] [-u] [-sort key1 [key2]] [-nsort key1 [key2]] [-k key [[op] val]]... [-o -k key [[op] val]] ...]...\n", myname
);
246 fprintf(stderr
, " -f read named file[s], rather than standard log message store.\n");
247 fprintf(stderr
, " -d read all file in named directory path, rather than standard log message store.\n");
248 fprintf(stderr
, " -x export to named ASL format file, rather than printing\n");
249 fprintf(stderr
, " -w watch data store (^C to quit)\n");
250 fprintf(stderr
, " prints the last N matching lines (default 10) before waiting\n");
251 fprintf(stderr
, " \"-w all\" prints all matching lines before waiting\n");
252 fprintf(stderr
, " \"-w boot\" prints all matching lines since last system boot before waiting\n");
253 fprintf(stderr
, " -F output format may be \"std\", \"raw\", \"bsd\", or \"xml\"\n");
254 fprintf(stderr
, " format may also be a string containing variables of the form\n");
255 fprintf(stderr
, " $Key or $(Key) - use the latter for non-whitespace delimited variables\n");
256 fprintf(stderr
, " -T timestamp format may be \"sec\" (seconds), \"utc\" (UTC), or \"local\" (local timezone)\n");
257 fprintf(stderr
, " -E text encoding may be \"vis\", \"safe\", or \"none\"\n");
258 fprintf(stderr
, " -nodc no duplicate message compression\n");
259 fprintf(stderr
, " -u print timestamps using UTC (equivalent to \"-T utc\")\n");
260 fprintf(stderr
, " -sort sort messages using value for specified key1 (secondary sort by key2 if provided)\n");
261 fprintf(stderr
, " -nsort numeric sort messages using value for specified key1 (secondary sort by key2 if provided)\n");
262 fprintf(stderr
, " -k key/value match\n");
263 fprintf(stderr
, " if no operator or value is given, checks for the existence of the key\n");
264 fprintf(stderr
, " if no operator is given, default is \"%s\"\n", OP_EQ
);
265 fprintf(stderr
, " -B only process log messages since last system boot\n");
266 fprintf(stderr
, " -C alias for \"-k Facility com.apple.console\"\n");
267 fprintf(stderr
, " -o begins a new query\n");
268 fprintf(stderr
, " queries are \'OR\'ed together\n");
269 fprintf(stderr
, "operators are zero or more modifiers followed by a comparison\n");
270 fprintf(stderr
, " %s equal\n", OP_EQ
);
271 fprintf(stderr
, " %s not equal\n", OP_NE
);
272 fprintf(stderr
, " %s greater than\n", OP_GT
);
273 fprintf(stderr
, " %s greater or equal\n", OP_GE
);
274 fprintf(stderr
, " %s less than\n", OP_LT
);
275 fprintf(stderr
, " %s less or equal\n", OP_LE
);
276 fprintf(stderr
, "optional modifiers for operators\n");
277 fprintf(stderr
, " %c case-fold\n", MOD_CASE_FOLD
);
278 fprintf(stderr
, " %c regular expression\n", MOD_REGEX
);
279 fprintf(stderr
, " %c substring\n", MOD_SUBSTRING
);
280 fprintf(stderr
, " %c prefix\n", MOD_PREFIX
);
281 fprintf(stderr
, " %c suffix\n", MOD_SUFFIX
);
282 fprintf(stderr
, " %c numeric comparison\n", MOD_NUMERIC
);
283 fprintf(stderr
, "\n");
286 if ((section
== HELP_ALL
) || (section
== HELP_STATS
))
288 fprintf(stderr
, "%s -stats [-n n] [-d path] [-v]\n", myname
);
289 fprintf(stderr
, " compiles and prints syslogd usage statistics\n");
290 fprintf(stderr
, " -n n prints stats for just the top n (e.g. top 10) senders\n");
291 fprintf(stderr
, " -d path reads the ASL database at the given path for statistics\n");
292 fprintf(stderr
, " -v verbose ([message_count total_data data_average] for 10 minute intervals)\n");
293 fprintf(stderr
, "\n");
296 fprintf(stderr
, "NOTE: Most system logs have moved to a new logging system. See log(1) for more information.\n");
300 notify_status_string(int status
)
302 if (status
== NOTIFY_STATUS_OK
) return "OK";
303 if (status
== NOTIFY_STATUS_INVALID_NAME
) return "Process not registered";
304 if (status
== NOTIFY_STATUS_NOT_AUTHORIZED
) return "Not authorized";
305 return "Operation failed";
309 asl_level_string(int level
)
311 if (level
== ASL_LEVEL_EMERG
) return ASL_STRING_EMERG
;
312 if (level
== ASL_LEVEL_ALERT
) return ASL_STRING_ALERT
;
313 if (level
== ASL_LEVEL_CRIT
) return ASL_STRING_CRIT
;
314 if (level
== ASL_LEVEL_ERR
) return ASL_STRING_ERR
;
315 if (level
== ASL_LEVEL_WARNING
) return ASL_STRING_WARNING
;
316 if (level
== ASL_LEVEL_NOTICE
) return ASL_STRING_NOTICE
;
317 if (level
== ASL_LEVEL_INFO
) return ASL_STRING_INFO
;
318 if (level
== ASL_LEVEL_DEBUG
) return ASL_STRING_DEBUG
;
323 module_control(int argc
, char *argv
[])
325 const char *val
= NULL
;
330 for (i
= 2; i
< argc
; i
++)
332 if ((!strcmp(argv
[i
], "-help")) || (!strcmp(argv
[i
], "--help")))
339 asl_msg_t
*ctl
= _asl_server_control_query();
342 fprintf(stderr
, "can't get status information from syslogd\n");
354 asl_out_module_t
*m
= asl_out_module_init();
355 asl_out_module_t
*x
= m
;
359 if ((argc
== 0) || (!strcmp(argv
[0], x
->name
)))
361 asl_msg_lookup(ctl
, x
->name
, &val
, NULL
);
363 if (first
== 0) printf("\n");
366 if (x
->name
== NULL
) printf("ASL out module has no name\n");
367 else printf("ASL out module: %s %s[current status: %s]\n", x
->name
, (x
->flags
& MODULE_FLAG_LOCAL
) ? "local " : "", (val
== NULL
) ? "unknown" : val
);
369 asl_out_module_print(stdout
, x
);
375 asl_msg_release(ctl
);
376 asl_out_module_free(m
);
380 /* name enable [val] */
381 /* name disable [val] */
382 if ((!strcmp(argv
[1], "enable")) || (!strcmp(argv
[1], "disable")))
389 if (!strcmp(argv
[1], "enable"))
391 if (argc
< 3) want
= 1;
392 else if (!strcmp(argv
[2], "1")) want
= 1;
393 else if (!strcmp(argv
[2], "0")) want
= 0;
396 printf("invalid value %s for %s %s - expecting 0 or 1\n", argv
[2], argv
[0], argv
[1]);
402 if (argc
< 3) want
= 0;
403 else if (!strcmp(argv
[2], "1")) want
= 0;
404 else if (!strcmp(argv
[2], "0")) want
= 1;
407 printf("invalid value %s for %s %s - expecting 0 or 1\n", argv
[2], argv
[0], argv
[1]);
412 asl_msg_lookup(ctl
, argv
[0], &val
, NULL
);
415 if (!strcmp(val
, "enabled")) status
= 1;
419 asl_msg_release(ctl
);
423 printf("internal error: want = -1\n");
429 printf("module %s is already %s\n", argv
[0], val
);
433 cm
= asl_msg_new(ASL_TYPE_MSG
);
434 asprintf(&str
, "@ %s enable %d", argv
[0], want
);
436 if ((cm
== NULL
) || (str
== NULL
))
438 fprintf(stderr
, "can't allocate memory - exiting\n");
442 ac
= asl_client_open(NULL
, NULL
, 0);
443 asl_client_set_filter(ac
, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG
));
444 asl_msg_set_key_val(cm
, ASL_KEY_LEVEL
, "7");
445 asl_msg_set_key_val(cm
, ASL_KEY_OPTION
, "control");
446 asl_msg_set_key_val(cm
, ASL_KEY_MSG
, str
);
447 asl_client_send(ac
, cm
);
449 asl_client_release(ac
);
455 asl_msg_release(ctl
);
457 /* name checkpoint [file] */
458 if (!strcmp(argv
[1], "checkpoint"))
460 asl_msg_list_t
*q
= asl_msg_list_new();
461 asl_msg_t
*qm
= asl_msg_new(ASL_TYPE_QUERY
);
463 if ((q
== NULL
) || (qm
== NULL
))
465 fprintf(stderr
, "can't allocate memory - exiting\n");
469 asl_msg_list_append(q
, qm
);
472 asl_msg_set_key_val_op(qm
, ASL_KEY_OPTION
, "control", ASL_QUERY_OP_EQUAL
);
473 asprintf(&str
, "%s checkpoint%s%s", argv
[0], (argc
> 2) ? " " : "", (argc
> 2) ? argv
[2] : "");
474 asl_msg_set_key_val_op(qm
, "action", str
, ASL_QUERY_OP_EQUAL
);
476 asl_msg_list_t
*res
= syslogd_query((asl_msg_list_t
*)q
, 0, 0, 1, &last
);
478 asl_msg_list_release(res
);
482 printf("unknown module control: %s\n", argv
[1]);
487 procinfo(char *pname
, int *pid
, int *uid
)
490 int i
, status
, nprocs
;
492 struct kinfo_proc
*procs
, *newprocs
;
499 mib
[2] = KERN_PROC_ALL
;
503 status
= sysctl(mib
, miblen
, NULL
, &size
, NULL
, 0);
507 newprocs
= reallocf(procs
, size
);
508 if (newprocs
== NULL
)
510 if (procs
!= NULL
) free(procs
);
511 return PROC_NOT_FOUND
;
515 status
= sysctl(mib
, miblen
, procs
, &size
, NULL
, 0);
516 } while ((status
== -1) && (errno
== ENOMEM
));
520 if (procs
!= NULL
) free(procs
);
521 return PROC_NOT_FOUND
;
524 if (size
% sizeof(struct kinfo_proc
) != 0)
526 if (procs
!= NULL
) free(procs
);
527 return PROC_NOT_FOUND
;
530 if (procs
== NULL
) return PROC_NOT_FOUND
;
532 nprocs
= size
/ sizeof(struct kinfo_proc
);
536 /* Search for a pid */
537 for (i
= 0; i
< nprocs
; i
++)
539 if (*pid
== procs
[i
].kp_proc
.p_pid
)
541 *uid
= procs
[i
].kp_eproc
.e_ucred
.cr_uid
;
546 return PROC_NOT_FOUND
;
549 *pid
= PROC_NOT_FOUND
;
551 for (i
= 0; i
< nprocs
; i
++)
553 if (!strcmp(procs
[i
].kp_proc
.p_comm
, pname
))
555 if (*pid
!= PROC_NOT_FOUND
)
558 return PROC_NOT_UNIQUE
;
561 *pid
= procs
[i
].kp_proc
.p_pid
;
562 *uid
= procs
[i
].kp_eproc
.e_ucred
.cr_uid
;
567 if (*pid
== PROC_NOT_FOUND
) return PROC_NOT_FOUND
;
573 rcontrol_get_string(const char *name
, int *val
)
578 status
= notify_register_plain(name
, &t
);
579 if (status
!= NOTIFY_STATUS_OK
) return status
;
582 status
= notify_get_state(t
, &x
);
591 rcontrol_set_string(const char *name
, uint32_t bits
)
596 status
= notify_register_plain(name
, &t
);
597 if (status
!= NOTIFY_STATUS_OK
) return status
;
600 status
= notify_set_state(t
, x
);
601 notify_post(NOTIFY_RC
);
607 asl_string_to_filter(char *s
)
611 if (s
== NULL
) return 0;
612 if (s
[0] == '\0') return 0;
614 if ((s
[0] >= '0') && (s
[0] <= '9')) return ASL_FILTER_MASK(atoi(s
));
618 if ((s
[1] == 'P') || (s
[1] == 'p')) i
= ASL_LEVEL_EMERG
;
619 else if ((s
[1] == 'A') || (s
[1] == 'a')) i
= ASL_LEVEL_ALERT
;
620 else if ((s
[1] == 'C') || (s
[1] == 'c')) i
= ASL_LEVEL_CRIT
;
621 else if ((s
[1] == 'E') || (s
[1] == 'e')) i
= ASL_LEVEL_ERR
;
622 else if ((s
[1] == 'X') || (s
[1] == 'x')) i
= ASL_LEVEL_ERR
;
623 else if ((s
[1] == 'W') || (s
[1] == 'w')) i
= ASL_LEVEL_WARNING
;
624 else if ((s
[1] == 'N') || (s
[1] == 'n')) i
= ASL_LEVEL_NOTICE
;
625 else if ((s
[1] == 'I') || (s
[1] == 'i')) i
= ASL_LEVEL_INFO
;
626 else if ((s
[1] == 'D') || (s
[1] == 'd')) i
= ASL_LEVEL_DEBUG
;
627 else i
= atoi(s
+ 1);
628 f
= ASL_FILTER_MASK_UPTO(i
);
633 for (i
= 0; s
[i
] != '\0'; i
++)
635 if ((s
[i
] == 'P') || (s
[i
] == 'p')) f
|= ASL_FILTER_MASK_EMERG
;
636 else if ((s
[i
] == 'A') || (s
[i
] == 'a')) f
|= ASL_FILTER_MASK_ALERT
;
637 else if ((s
[i
] == 'C') || (s
[i
] == 'c')) f
|= ASL_FILTER_MASK_CRIT
;
638 else if ((s
[i
] == 'E') || (s
[i
] == 'e')) f
|= ASL_FILTER_MASK_ERR
;
639 else if ((s
[i
] == 'X') || (s
[i
] == 'x')) f
|= ASL_FILTER_MASK_ERR
;
640 else if ((s
[i
] == 'W') || (s
[i
] == 'w')) f
|= ASL_FILTER_MASK_WARNING
;
641 else if ((s
[i
] == 'N') || (s
[i
] == 'n')) f
|= ASL_FILTER_MASK_NOTICE
;
642 else if ((s
[i
] == 'I') || (s
[i
] == 'i')) f
|= ASL_FILTER_MASK_INFO
;
643 else if ((s
[i
] == 'D') || (s
[i
] == 'd')) f
|= ASL_FILTER_MASK_DEBUG
;
650 asl_filter_string(int f
)
652 static char str
[1024];
655 memset(str
, 0, sizeof(str
));
658 if ((f
== ASL_FILTER_MASK_PACEWNID
) != 0)
660 strcat(str
, "Emergency - Debug");
664 if ((f
== ASL_FILTER_MASK_PACEWNI
) != 0)
666 strcat(str
, "Emergency - Info");
670 if ((f
== ASL_FILTER_MASK_PACEWN
) != 0)
672 strcat(str
, "Emergency - Notice");
676 if ((f
== ASL_FILTER_MASK_PACEW
) != 0)
678 strcat(str
, "Emergency - Warning");
682 if ((f
== ASL_FILTER_MASK_PACE
) != 0)
684 strcat(str
, "Emergency - Error");
688 if ((f
== ASL_FILTER_MASK_PAC
) != 0)
690 strcat(str
, "Emergency - Critical");
694 if ((f
& ASL_FILTER_MASK_EMERG
) != 0)
696 strcat(str
, "Emergency");
700 if ((f
& ASL_FILTER_MASK_ALERT
) != 0)
702 if (i
> 0) strcat(str
, ", ");
703 strcat(str
, "Alert");
707 if ((f
& ASL_FILTER_MASK_CRIT
) != 0)
709 if (i
> 0) strcat(str
, ", ");
710 strcat(str
, "Critical");
714 if ((f
& ASL_FILTER_MASK_ERR
) != 0)
716 if (i
> 0) strcat(str
, ", ");
717 strcat(str
, "Error");
721 if ((f
& ASL_FILTER_MASK_WARNING
) != 0)
723 if (i
> 0) strcat(str
, ", ");
724 strcat(str
, "Warning");
728 if ((f
& ASL_FILTER_MASK_NOTICE
) != 0)
730 if (i
> 0) strcat(str
, ", ");
731 strcat(str
, "Notice");
735 if ((f
& ASL_FILTER_MASK_INFO
) != 0)
737 if (i
> 0) strcat(str
, ", ");
742 if ((f
& ASL_FILTER_MASK_DEBUG
) != 0)
744 if (i
> 0) strcat(str
, ", ");
745 strcat(str
, "Debug");
749 if (i
== 0) sprintf(str
, "Off");
755 rcontrol_name(pid_t pid
, uid_t uid
)
757 static char str
[1024];
759 if (pid
== RC_MASTER
) return NOTIFY_SYSTEM_MASTER
;
761 memset(str
, 0, sizeof(str
));
762 if (uid
== 0) snprintf(str
, sizeof(str
) - 1, "%s.%d", NOTIFY_PREFIX_SYSTEM
, pid
);
763 else snprintf(str
, sizeof(str
) - 1, "user.uid.%d.syslog.%d", uid
, pid
);
768 print_eval_bits(uint32_t eval
)
770 printf("0x%08x O%s ", eval
, (eval
& EVAL_ACTIVE
) ? "N " : "FF");
771 if (eval
& EVAL_SEND_ASL
) printf("ASL ");
772 if (eval
& EVAL_SEND_TRACE
) printf("TRACE ");
773 if (eval
& EVAL_TEXT_FILE
) printf("TEXT ");
774 if (eval
& EVAL_ASL_FILE
) printf("FILE ");
775 if (eval
& EVAL_TUNNEL
) printf("TUNNEL ");
776 printf("/ 0x%02x %s\n", eval
& EVAL_LEVEL_MASK
, asl_filter_string(eval
& EVAL_LEVEL_MASK
));
780 rcontrol_get(pid_t pid
, uid_t uid
)
788 status
= rcontrol_get_string(rcontrol_name(pid
, uid
), &filter
);
789 if (status
== NOTIFY_STATUS_OK
)
791 printf("Master settings: ");
792 print_eval_bits(filter
);
796 printf("Unable to determine master settings\n");
800 status
= rcontrol_get_string(rcontrol_name(pid
, uid
), &filter
);
801 if (status
== NOTIFY_STATUS_OK
)
803 printf("Process %d syslog settings: ", pid
);
804 print_eval_bits(filter
);
808 printf("Unable to determine syslog settings for pid %d\n", pid
);
813 rcontrol_set(pid_t pid
, uid_t uid
, uint32_t bits
)
818 rcname
= rcontrol_name(pid
, uid
);
822 status
= rcontrol_set_string(rcname
, bits
);
824 if (status
== NOTIFY_STATUS_OK
)
826 if (pid
== RC_MASTER
) status
= notify_post(NOTIFY_SYSTEM_MASTER
);
830 printf("Unable to set master syslog filter mask: %s\n", notify_status_string(status
));
834 status
= rcontrol_set_string(rcname
, bits
);
835 if (status
== NOTIFY_STATUS_OK
)
837 status
= notify_post(rcname
);
841 printf("Unable to set syslog filter mask for pid %d: %s\n", pid
, notify_status_string(status
));
846 rsend(asl_msg_t
*msg
, char *rhost
)
854 struct sockaddr_in dst
;
856 char host_name
[MAXHOSTNAMELEN
+ 1];
858 if (msg
== NULL
) return 0;
860 h
= gethostbyname(rhost
);
861 if (h
== NULL
) return -1;
863 s
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
864 if (s
<= 0) return -1;
866 memset(&dst
, 0, sizeof(struct sockaddr_in
));
867 memcpy(&(dst
.sin_addr
.s_addr
), h
->h_addr_list
[0], 4);
868 dst
.sin_family
= AF_INET
;
870 dst
.sin_len
= sizeof(struct sockaddr_in
);
872 level
= ASL_LEVEL_DEBUG
;
874 val
= asl_msg_get_val_for_key(msg
, ASL_KEY_LEVEL
);
875 if (val
!= NULL
) level
= atoi(val
);
880 asprintf(×tr
, "%llu", (unsigned long long)tick
);
883 asl_msg_set_key_val(msg
, ASL_KEY_TIME
, timestr
);
887 if (gethostname(host_name
, MAXHOSTNAMELEN
) == 0) asl_msg_set_key_val(msg
, ASL_KEY_HOST
, host_name
);
890 str
= asl_msg_to_string((asl_msg_t
*)msg
, &len
);
891 if (str
== NULL
) return -1;
893 asprintf(&out
, "%10u %s\n", len
+1, str
);
895 if (out
== NULL
) return -1;
897 sendto(s
, out
, len
+12, 0, (const struct sockaddr
*)&dst
, sizeof(struct sockaddr_in
));
905 rlegacy(char *msg
, int level
, char *rhost
)
912 struct sockaddr_in dst
;
914 char host_name
[MAXHOSTNAMELEN
+ 1];
916 if (msg
== NULL
) return 0;
918 h
= gethostbyname(rhost
);
919 if (h
== NULL
) return -1;
921 s
= socket(AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
922 if (s
<= 0) return -1;
924 memset(&dst
, 0, sizeof(struct sockaddr_in
));
925 memcpy(&(dst
.sin_addr
.s_addr
), h
->h_addr_list
[0], 4);
926 dst
.sin_family
= AF_INET
;
928 dst
.sin_len
= sizeof(struct sockaddr_in
);
931 ltime
= ctime(&tick
);
934 gethostname(host_name
, MAXHOSTNAMELEN
);
936 asprintf(&out
, "<%d>%s %s syslog[%d]: %s", level
, ltime
+4, host_name
, getpid(), msg
);
938 sendto(s
, out
, len
, 0, (const struct sockaddr
*)&dst
, sizeof(struct sockaddr_in
));
946 stats_print_sender_stats(sender_stat_t
*s
, uint32_t interval
, bool print_samples
)
949 uint32_t p10000
= (s
->total_messages
* 10000) / stats_total_all_messages
;
951 if (strcmp(s
->name
, "*")) printf("%s: %u (%u.%02u%%) %lu\n", s
->name
, s
->total_messages
, p10000
/ 100, p10000
% 100, s
->total_size
);
952 else printf("TOTAL: %u (100.00%%) %lu\n", s
->total_messages
, s
->total_size
);
957 printf("[message_count data_size data_average]\n");
959 for (i
= 0, k
= 0; i
< s
->count
; i
++)
963 if (s
->messages
[i
] > 0) avg
= s
->size
[i
] / s
->messages
[i
];
964 printf("[%u %lu %lu]", s
->messages
[i
], s
->size
[i
], avg
);
976 for (; i
< interval
; i
++)
979 if ((++k
== 6) || ((i
+ 1) == interval
))
995 stats_n_comp(const void *x
, const void *y
)
998 sender_stat_t
**p
= (sender_stat_t
**)x
;
999 sender_stat_t
**q
= (sender_stat_t
**)y
;
1000 pn
= (*p
)->total_messages
;
1001 qn
= (*q
)->total_messages
;
1006 stats_sender_set_stat_numbers(const char *name
, sender_stat_t
*s
, uint32_t interval
, uint32_t nmsgs
, size_t msize
)
1008 s
->messages
= (uint32_t *)reallocf(s
->messages
, interval
* sizeof(uint32_t));
1009 s
->size
= (size_t *)reallocf(s
->size
, interval
* sizeof(size_t));
1011 for (; s
->count
< interval
; s
->count
++)
1013 s
->messages
[s
->count
] = 0;
1014 s
->size
[s
->count
] = 0;
1017 s
->messages
[interval
- 1] = nmsgs
;
1018 s
->size
[interval
- 1] = msize
;
1020 s
->total_messages
+= nmsgs
;
1021 s
->total_size
+= msize
;
1023 if (strcmp(name
, "*")) stats_total_all_messages
+= nmsgs
;
1027 stats_sender_set_stats(uint32_t interval
, const char *name
, uint32_t nmsgs
, size_t msize
)
1030 for (i
= 0; i
< stats_sender_count
; i
++)
1032 if (strcmp(stats_sender
[i
]->name
, name
) == 0)
1034 stats_sender_set_stat_numbers(name
, stats_sender
[i
], interval
, nmsgs
, msize
);
1039 stats_sender
= (sender_stat_t
**)realloc(stats_sender
, (stats_sender_count
+ 1) * sizeof(sender_stat_t
*));
1040 stats_sender
[stats_sender_count
] = (sender_stat_t
*)calloc(1, sizeof(sender_stat_t
));
1041 stats_sender
[stats_sender_count
]->name
= strdup(name
);
1043 stats_sender_set_stat_numbers(name
, stats_sender
[stats_sender_count
], interval
, nmsgs
, msize
);
1044 stats_sender_count
++;
1048 stats_process_stat_msg(uint32_t interval
, asl_object_t msg
)
1054 for (i
= 0; i
< n
; i
++)
1056 const char *key
= NULL
;
1057 const char *val
= NULL
;
1060 if (asl_fetch_key_val_op(msg
, i
, &key
, &val
, NULL
) != 0) break;
1063 if (2 == sscanf(val
, "%u %lu", &s_n
, &s_size
))
1065 stats_sender_set_stats(interval
, key
+ 1, s_n
, s_size
);
1073 asl_stats(int argc
, char *argv
[])
1076 uint32_t i
, interval
, top
= UINT32_MAX
;
1077 bool print_samples
= false;
1078 asl_object_t store
= NULL
;
1080 for (i
= 2; i
< argc
; i
++)
1082 if ((!strcmp(argv
[i
], "-help")) || (!strcmp(argv
[i
], "--help")))
1087 else if (!strcmp(argv
[i
], "-n"))
1092 fprintf(stderr
, "error: expected an integer value following \"-n\"\n");
1097 top
= 1 + atoi(argv
[i
]);
1099 else if (!strcmp(argv
[i
], "-v"))
1101 print_samples
= true;
1103 else if (!strcmp(argv
[i
], "-d"))
1108 fprintf(stderr
, "error: expected a directory path following \"-d\"\n");
1112 store
= asl_open_path(argv
[i
], 0);
1115 fprintf(stderr
, "error: failed to open ASL directory %s\n", argv
[i
]);
1121 #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
1122 if (store
== NULL
) store
= asl_open_path(ASL_IOS_STATS_DIR
, 0);
1125 fprintf(stderr
, "error: failed to open ASL directory %s\n", ASL_IOS_STATS_DIR
);
1130 asl_object_t stats_query
= asl_new(ASL_TYPE_QUERY
);
1131 if (stats_query
== NULL
)
1133 fprintf(stderr
, "error: failed to create stats_query\n");
1137 asl_set_query(stats_query
, ASL_KEY_FACILITY
, "com.apple.asl.statistics", ASL_QUERY_OP_EQUAL
);
1139 asl_object_t stats
= asl_search(store
, stats_query
);
1140 asl_release(stats_query
);
1145 printf("no statistics records in the ASL database\n");
1149 for (interval
= 1, msg
= asl_next(stats
); msg
!= NULL
; interval
++, msg
= asl_next(stats
))
1151 stats_process_stat_msg(interval
, msg
);
1156 qsort(stats_sender
, stats_sender_count
, sizeof(sender_stat_t
*), stats_n_comp
);
1158 printf("sender: message_count (%% of total) data_size\n");
1160 for (i
= 0; (i
< stats_sender_count
) && (i
< top
); i
++)
1162 stats_print_sender_stats(stats_sender
[i
], interval
- 1, print_samples
);
1165 /* NB sender stats are not freed since we exit after this */
1174 if (s
== NULL
) return 0;
1177 if ((s
[0] == '-') || (s
[0] == '+')) i
= 1;
1179 if (s
[i
] == '\0') return 0;
1181 for (; s
[i
] != '\0'; i
++)
1183 if (!isdigit(s
[i
])) return 0;
1190 asl_string_to_level(const char *s
)
1192 if (s
== NULL
) return -1;
1194 if ((s
[0] >= '0') && (s
[0] <= '7') && (s
[1] == '\0')) return atoi(s
);
1196 if (!strncasecmp(s
, "em", 2)) return ASL_LEVEL_EMERG
;
1197 else if (!strncasecmp(s
, "p", 1)) return ASL_LEVEL_EMERG
;
1198 else if (!strncasecmp(s
, "a", 1)) return ASL_LEVEL_ALERT
;
1199 else if (!strncasecmp(s
, "c", 1)) return ASL_LEVEL_CRIT
;
1200 else if (!strncasecmp(s
, "er", 2)) return ASL_LEVEL_ERR
;
1201 else if (!strncasecmp(s
, "x", 1)) return ASL_LEVEL_ERR
;
1202 else if (!strncasecmp(s
, "w", 1)) return ASL_LEVEL_WARNING
;
1203 else if (!strncasecmp(s
, "n", 1)) return ASL_LEVEL_NOTICE
;
1204 else if (!strncasecmp(s
, "i", 1)) return ASL_LEVEL_INFO
;
1205 else if (!strncasecmp(s
, "d", 1)) return ASL_LEVEL_DEBUG
;
1211 asl_string_to_char_level(const char *s
)
1213 if (s
== NULL
) return NULL
;
1215 if ((s
[0] >= '0') && (s
[0] <= '7') && (s
[1] == '\0')) return s
;
1217 if (!strncasecmp(s
, "em", 2)) return "0";
1218 else if (!strncasecmp(s
, "p", 1)) return "0";
1219 else if (!strncasecmp(s
, "a", 1)) return "1";
1220 else if (!strncasecmp(s
, "c", 1)) return "2";
1221 else if (!strncasecmp(s
, "er", 2)) return "3";
1222 else if (!strncasecmp(s
, "x", 1)) return "3";
1223 else if (!strncasecmp(s
, "w", 1)) return "4";
1224 else if (!strncasecmp(s
, "n", 1)) return "5";
1225 else if (!strncasecmp(s
, "i", 1)) return "6";
1226 else if (!strncasecmp(s
, "d", 1)) return "7";
1232 syslog_remote_control(int argc
, char *argv
[])
1234 int i
, pid
, uid
, status
, mask
;
1239 usage(HELP_REMOTE_CONTROL
);
1243 for (i
= 2; i
< argc
; i
++)
1245 if ((!strcmp(argv
[i
], "-help")) || (!strcmp(argv
[i
], "--help")))
1247 usage(HELP_REMOTE_CONTROL
);
1255 status
= PROC_NOT_FOUND
;
1257 if ((!strcmp(argv
[2], "syslogd")) || (!strcmp(argv
[2], "syslog")))
1259 fprintf(stderr
, "%s: does not have a filter mask\n", argv
[2]);
1262 else if (_isanumber(argv
[2]) != 0)
1264 pid
= atoi(argv
[2]);
1265 status
= procinfo(NULL
, &pid
, &uid
);
1269 status
= procinfo(argv
[2], &pid
, &uid
);
1272 if (status
== PROC_NOT_FOUND
)
1274 fprintf(stderr
, "%s: process not found\n", argv
[2]);
1278 if (status
== PROC_NOT_UNIQUE
)
1280 fprintf(stderr
, "%s: multiple processes found\n", argv
[2]);
1281 fprintf(stderr
, "use pid to identify a process uniquely\n");
1285 if (pid
== 0) pid
= RC_MASTER
;
1289 rcontrol_get(pid
, uid
);
1293 bits
= EVAL_ACTIVE
| EVAL_SEND_ASL
| EVAL_SEND_TRACE
;
1295 for (i
= 3; i
< argc
; i
++)
1297 if ((!strcasecmp(argv
[i
], "off")) || (!strcmp(argv
[i
], "0")))
1301 else if (!strcmp(argv
[i
], "-s"))
1303 if (((i
+ 1) < argc
) && (argv
[i
+ 1][0] != '-'))
1306 if (!strcasecmp(argv
[i
], "off") || !strcmp(argv
[i
], "0")) bits
&= ~EVAL_SEND_ASL
;
1309 else if (!strcmp(argv
[i
], "-t"))
1311 if (((i
+ 1) < argc
) && (argv
[i
+ 1][0] != '-'))
1314 if (!strcasecmp(argv
[i
], "off") || !strcmp(argv
[i
], "0")) bits
&= ~EVAL_SEND_TRACE
;
1319 mask
= asl_string_to_filter(argv
[i
]);
1322 printf("can't understand mask: %s\n", argv
[i
]);
1325 bits
= (bits
& EVAL_ACTION_MASK
) | mask
;
1329 rcontrol_set(pid
, uid
, bits
);
1334 syslog_send(int argc
, char *argv
[])
1336 int status
, i
, start
, kv
, len
, rfmt
, rlevel
;
1337 asl_object_t asl
= NULL
;
1339 char tmp
[64], *str
, *rhost
;
1340 struct timeval tval
= {0, 0};
1341 char host_name
[MAXHOSTNAMELEN
+ 1];
1343 for (i
= 2; i
< argc
; i
++)
1345 if ((!strcmp(argv
[i
], "-help")) || (!strcmp(argv
[i
], "--help")))
1352 status
= gettimeofday(&tval
, NULL
);
1355 time_t tick
= time(NULL
);
1362 rfmt
= SEND_FORMAT_LEGACY
;
1366 for (i
= 1; i
< argc
; i
++)
1368 if (!strcmp(argv
[i
], "-s")) start
= i
+1;
1369 else if (!strcmp(argv
[i
], "-k"))
1372 rfmt
= SEND_FORMAT_ASL
;
1374 else if (!strcmp(argv
[i
], "-r"))
1379 else if (!strcmp(argv
[i
], "-l"))
1381 rlevel
= asl_string_to_level(argv
[++i
]);
1384 fprintf(stderr
, "Unknown level: %s\n", argv
[i
]);
1389 else if (!strcmp(argv
[i
], "-x"))
1394 fprintf(stderr
, "expected a path following -x\n");
1398 asl
= asl_open_path(argv
[i
], ASL_OPT_OPEN_WRITE
);
1401 fprintf(stderr
, "Could not open %s for write\n", argv
[i
]);
1408 if (asl
== NULL
) asl
= asl_open(myname
, "syslog", 0);
1409 asl_set_filter(asl
, ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG
));
1411 m
= asl_base_msg(NULL
, rlevel
, &tval
, myname
, "syslog", NULL
);
1414 fprintf(stderr
, "Could not create message\n");
1418 if (gethostname(host_name
, MAXHOSTNAMELEN
) == 0) asl_msg_set_key_val(m
, ASL_KEY_HOST
, host_name
);
1420 snprintf(tmp
, sizeof(tmp
), "%d", getuid());
1421 asl_msg_set_key_val(m
, ASL_KEY_UID
, tmp
);
1423 snprintf(tmp
, sizeof(tmp
), "%d", getgid());
1424 asl_msg_set_key_val(m
, ASL_KEY_GID
, tmp
);
1431 for (i
= start
; i
< argc
; i
++) len
+= (strlen(argv
[i
]) + 1);
1432 str
= calloc(len
+ 1, 1);
1433 if (str
== NULL
) return -1;
1435 for (i
= start
; i
< argc
; i
++)
1437 strcat(str
, argv
[i
]);
1438 if ((i
+1) < argc
) strcat(str
, " ");
1440 asl_msg_set_key_val(m
, ASL_KEY_MSG
, str
);
1444 for (i
= start
+ 1; i
< argc
; i
+= 2)
1446 if (!strcmp(argv
[i
], "-k")) i
++;
1447 asl_msg_set_key_val(m
, argv
[i
], argv
[i
+ 1]);
1448 if (!strcmp(argv
[i
], ASL_KEY_LEVEL
)) rlevel
= atoi(argv
[i
+ 1]);
1454 asl_send(asl
, (asl_object_t
)m
);
1456 else if (rfmt
== SEND_FORMAT_ASL
)
1460 else if ((rfmt
== SEND_FORMAT_LEGACY
) && (str
!= NULL
))
1462 rlegacy(str
, rlevel
, rhost
);
1467 if (str
!= NULL
) free(str
);
1475 syslog_config(int argc
, char *argv
[])
1483 const char *key
, *val
;
1485 for (i
= 2; i
< argc
; i
++)
1487 if ((!strcmp(argv
[i
], "-help")) || (!strcmp(argv
[i
], "--help")))
1496 asl_msg_t
*ctl
= _asl_server_control_query();
1499 fprintf(stderr
, "can't get status information from syslogd\n");
1503 for (x
= asl_msg_fetch(ctl
, 0, &key
, &val
, NULL
); x
!= IndexNull
; x
= asl_msg_fetch(ctl
, x
, &key
, &val
, NULL
))
1505 printf("%s %s\n", key
, val
);
1508 asl_msg_release(ctl
);
1515 fprintf(stderr
, "syslogd parameters may only be set by the superuser\n");
1519 str
= asl_string_new(0);
1520 asl_string_append(str
, "= ");
1522 for (i
= 2; i
< argc
; i
++)
1524 asl_string_append(str
, argv
[i
]);
1525 if ((i
+ 1) < argc
) asl_string_append(str
, " ");
1528 asl
= asl_client_open(myname
, "syslog", 0);
1530 m
= asl_msg_new(ASL_TYPE_MSG
);
1531 asl_msg_set_key_val(m
, ASL_KEY_LEVEL
, ASL_STRING_NOTICE
);
1532 asl_msg_set_key_val(m
, ASL_KEY_OPTION
, ASL_OPT_CONTROL
);
1533 asl_msg_set_key_val(m
, ASL_KEY_SENDER
, myname
);
1534 asl_msg_set_key_val(m
, ASL_KEY_MSG
, asl_string_bytes(str
));
1536 asl_client_send(asl
, m
);
1538 asl_string_release(str
);
1540 asl_client_release(asl
);
1546 syslog_control(int argc
, char *argv
[])
1554 for (i
= 2; i
< argc
; i
++)
1556 if ((!strcmp(argv
[i
], "-help")) || (!strcmp(argv
[i
], "--help")))
1558 usage(HELP_CONTROL
);
1566 fprintf(stderr
, "syslog control limited to use by superuser\n");
1570 str
= asl_string_new(0);
1571 asl_string_append(str
, "@ ");
1573 for (i
= 2; i
< argc
; i
++)
1575 asl_string_append(str
, argv
[i
]);
1576 if ((i
+ 1) < argc
) asl_string_append(str
, " ");
1579 asl
= asl_client_open(myname
, "syslog", 0);
1581 m
= asl_msg_new(ASL_TYPE_MSG
);
1582 asl_msg_set_key_val(m
, ASL_KEY_LEVEL
, ASL_STRING_NOTICE
);
1583 asl_msg_set_key_val(m
, ASL_KEY_OPTION
, ASL_OPT_CONTROL
);
1584 asl_msg_set_key_val(m
, ASL_KEY_SENDER
, myname
);
1585 asl_msg_set_key_val(m
, ASL_KEY_MSG
, asl_string_bytes(str
));
1587 asl_client_send(asl
, m
);
1589 asl_string_release(str
);
1591 asl_client_release(asl
);
1597 print_xml_header(FILE *f
)
1599 if (f
== NULL
) return;
1601 fprintf(f
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1602 fprintf(f
, "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
1603 fprintf(f
, "<plist version=\"1.0\">\n");
1604 fprintf(f
, "<array>\n");
1608 print_xml_trailer(FILE *f
)
1610 if (f
== NULL
) return;
1612 fprintf(f
, "</array>\n");
1613 fprintf(f
, "</plist>\n");
1617 printmsg(FILE *f
, asl_msg_t
*msg
, char *fmt
, int pflags
)
1621 uint32_t encode
, len
, status
;
1629 status
= asl_file_save(export
, msg
, &xid
);
1630 if (status
!= ASL_STATUS_OK
)
1632 fprintf(stderr
, "export file write failed: %s\n", asl_core_error(status
));
1633 asl_file_close(export
);
1641 encode
= pflags
& 0x0000000f;
1643 mf
= ASL_MSG_FMT_RAW
;
1644 if (fmt
!= NULL
) mf
= (const char *)fmt
;
1645 else if (pflags
& FORMAT_STD
) mf
= ASL_MSG_FMT_STD
;
1646 else if (pflags
& FORMAT_LEGACY
) mf
= ASL_MSG_FMT_BSD
;
1647 else if (pflags
& FORMAT_XML
) mf
= ASL_MSG_FMT_XML
;
1650 str
= asl_format_message((asl_msg_t
*)msg
, mf
, tfmt
, encode
, &len
);
1651 if (str
== NULL
) return;
1653 if (pflags
& COMPRESS_DUPS
)
1655 if (last_printmsg_str
!= NULL
)
1657 if (!strcmp(str
+ STD_BSD_DATE_LEN
, last_printmsg_str
+ STD_BSD_DATE_LEN
))
1659 last_printmsg_count
++;
1664 if (last_printmsg_count
> 0)
1666 fprintf(f
, "--- last message repeated %d time%s ---\n", last_printmsg_count
, (last_printmsg_count
== 1) ? "" : "s");
1669 free(last_printmsg_str
);
1670 last_printmsg_str
= str
;
1671 last_printmsg_count
= 0;
1673 fprintf(f
, "%s", str
);
1678 last_printmsg_str
= str
;
1679 last_printmsg_count
= 0;
1681 fprintf(f
, "%s", str
);
1686 fprintf(f
, "%s", str
);
1692 store_query(asl_msg_list_t
*q
, uint64_t start
, int count
, int dir
, uint64_t *last
)
1696 uint32_t status
= asl_store_open_read(NULL
, &store
);
1697 if (status
!= 0) return NULL
;
1700 return asl_store_match(store
, q
, last
, start
, count
, 0, dir
);
1704 file_query(asl_msg_list_t
*q
, uint64_t start
, int count
, int dir
, uint64_t *last
)
1706 return asl_file_list_match(db_files
, q
, last
, start
, count
, 0, dir
);;
1710 legacy_query(asl_msg_list_t
*q
, uint64_t start
, int count
, int dir
, uint64_t *last
)
1712 return asl_file_match(legacy
, q
, last
, start
, count
, 0, dir
);
1716 syslogd_query(asl_msg_list_t
*q
, uint64_t start
, int count
, int dir
, uint64_t *last
)
1720 uint32_t len
, reslen
, status
;
1722 kern_return_t kstatus
;
1725 if (asl_server_port
== MACH_PORT_NULL
)
1727 kstatus
= bootstrap_look_up2(bootstrap_port
, ASL_SERVICE_NAME
, &asl_server_port
, 0, BOOTSTRAP_PRIVILEGED_SERVER
);
1728 if (kstatus
!= KERN_SUCCESS
)
1730 fprintf(stderr
, "query failed: can't contact syslogd\n");
1731 asl_server_port
= MACH_PORT_NULL
;
1737 str
= asl_msg_list_to_string(q
, &len
);
1739 kstatus
= vm_allocate(mach_task_self(), (vm_address_t
*)&vmstr
, len
, VM_FLAGS_ANYWHERE
| VM_MAKE_TAG(VM_MEMORY_ASL
));
1740 if (kstatus
!= KERN_SUCCESS
)
1746 memmove(vmstr
, str
, len
);
1753 if (dir
< 0) flags
= QUERY_FLAG_SEARCH_REVERSE
;
1755 kstatus
= _asl_server_query_2(asl_server_port
, (caddr_t
)vmstr
, len
, start
, count
, flags
, (caddr_t
*)&res
, &reslen
, last
, (int *)&status
);
1757 if (res
== NULL
) return NULL
;
1758 l
= asl_msg_list_from_string(res
);
1759 vm_deallocate(mach_task_self(), (vm_address_t
)res
, reslen
);
1764 filter_and_print(asl_msg_t
*msg
, asl_msg_list_t
*ql
, FILE *f
, char *pfmt
, int pflags
)
1766 int i
, do_match
, did_match
;
1768 if (msg
== NULL
) return;
1771 if (ql
== NULL
) do_match
= 0;
1772 else if (ql
->count
== 0) do_match
= 0;
1780 for (i
= 0; (i
< ql
->count
) && (did_match
== 0); i
++)
1782 did_match
= asl_msg_cmp(ql
->msg
[i
], (asl_msg_t
*)msg
);
1786 if (did_match
!= 0) printmsg(f
, msg
, pfmt
, pflags
);
1789 #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
1791 syslogd_direct_watch(FILE *f
, char *pfmt
, int pflags
, asl_msg_list_t
*ql
)
1793 struct sockaddr_in address
;
1794 int i
, bytes
, sock
, stream
, status
;
1797 socklen_t addresslength
;
1798 char *str
, buf
[DIRECT_BUF_SIZE
];
1801 if (asl_server_port
== MACH_PORT_NULL
)
1803 status
= bootstrap_look_up(bootstrap_port
, ASL_SERVICE_NAME
, &asl_server_port
);
1804 if (status
!= KERN_SUCCESS
)
1806 fprintf(stderr
, "query failed: can't contact syslogd\n");
1811 addresslength
= sizeof(address
);
1812 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
1813 port
= (arc4random() % (IPPORT_HILASTAUTO
- IPPORT_HIFIRSTAUTO
)) + IPPORT_HIFIRSTAUTO
;
1815 memset(&address
, 0, addresslength
);
1816 address
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
1817 address
.sin_family
= AF_INET
;
1818 address
.sin_port
= htons(port
);
1820 status
= bind(sock
, (struct sockaddr
*)&address
, sizeof(address
));
1822 for (i
= 0; (i
< MAX_RANDOM
) && (status
< 0); i
++)
1824 port
= (arc4random() % (IPPORT_HILASTAUTO
- IPPORT_HIFIRSTAUTO
)) + IPPORT_HIFIRSTAUTO
;
1825 address
.sin_port
= htons(port
);
1827 status
= bind(sock
, (struct sockaddr
*)&address
, sizeof(address
));
1832 fprintf(stderr
, "query failed: can't find a port to connect to syslogd\n");
1838 if (listen(sock
, 1) == -1)
1845 _asl_server_register_direct_watch(asl_server_port
, i
);
1847 stream
= accept(sock
, (struct sockaddr
*)&address
, &addresslength
);
1858 bytes
= recvfrom(stream
, &n
, sizeof(n
), 0, NULL
, NULL
);
1861 fprintf(stderr
, "\nrecvfrom (message length) returned %d (errno %d) - exiting\n", bytes
, errno
);
1864 else inlen
= ntohl(n
);
1866 if (inlen
== 0) continue;
1869 if (inlen
<= DIRECT_BUF_SIZE
)
1875 str
= calloc(1, inlen
+ 1);
1878 fprintf(stderr
, "\ncan't allocate memory - exiting\n");
1889 bytes
= recvfrom(stream
, str
+ n
, inlen
- n
, 0, NULL
, NULL
);
1892 fprintf(stderr
, "\nrecvfrom (message body) returned %d (errno %d) at length %d of %d - exiting\n", bytes
, errno
, n
, inlen
);
1900 fprintf(stderr
, "\ntruncated message: expected %d bytes received %d bytes\n", inlen
, n
);
1906 msg
= asl_msg_from_string(str
);
1907 if (str
!= buf
) free(str
);
1908 filter_and_print(msg
, ql
, f
, pfmt
, pflags
);
1909 asl_msg_release(msg
);
1915 address
.sin_addr
.s_addr
= 0;
1920 sort_compare_key(asl_msg_t
*a
, asl_msg_t
*b
, const char *key
)
1922 const char *va
, *vb
;
1925 if (key
== NULL
) return 0;
1927 va
= asl_msg_get_val_for_key(a
, key
);
1928 vb
= asl_msg_get_val_for_key(b
, key
);
1930 if (va
== NULL
) return -1;
1931 if (vb
== NULL
) return 1;
1933 if (sort_numeric
== 1)
1937 if (na
< nb
) return -1;
1938 if (na
> nb
) return 1;
1942 return strcmp(va
, vb
);
1946 sort_compare(const void **ap
, const void **bp
)
1951 if (sort_key
== NULL
) return 0;
1953 a
= (asl_msg_t
*)*ap
;
1954 b
= (asl_msg_t
*)*bp
;
1956 cmp
= sort_compare_key(a
, b
, sort_key
);
1957 if ((cmp
== 0) && (sort_key_2
!= NULL
)) cmp
= sort_compare_key(a
, b
, sort_key_2
);
1963 search_once(FILE *f
, char *pfmt
, int pflags
, asl_msg_list_t
*ql
, uint64_t qmin
, uint64_t *cmax
, uint32_t count
, uint32_t batch
, int dir
, uint32_t tail
)
1965 asl_msg_list_t
*res
;
1968 if (pflags
& FORMAT_XML
) print_xml_header(f
);
1976 if (batch
== 0) more
= 0;
1978 if ((dbselect
== DB_SELECT_ASL
) || (dbselect
== DB_SELECT_STORE
)) res
= store_query(ql
, qmin
, batch
, dir
, cmax
);
1979 else if (dbselect
== DB_SELECT_FILES
) res
= file_query(ql
, qmin
, batch
, dir
, cmax
);
1980 else if (dbselect
== DB_SELECT_SYSLOGD
) res
= syslogd_query(ql
, qmin
, batch
, dir
, cmax
);
1981 else if (dbselect
== DB_SELECT_LEGACY
) res
= legacy_query(ql
, qmin
, batch
, dir
, cmax
);
1983 if ((dir
>= 0) && (*cmax
> qmin
)) qmin
= *cmax
+ 1;
1984 else if ((dir
< 0) && (*cmax
< qmin
)) qmin
= *cmax
- 1;
1992 if ((batch
> 0) && (res
->count
< batch
)) more
= 0;
1993 total
+= res
->count
;
1994 if ((count
> 0) && (total
>= count
)) more
= 0;
1999 i
= res
->count
- tail
;
2004 if (sort_key
!= NULL
)
2006 qsort(res
->msg
, res
->count
, sizeof(asl_msg_t
*), sort_compare
);
2009 if ((f
!= NULL
) || (export
!= NULL
))
2011 for (; i
< res
->count
; i
++) printmsg(f
, res
->msg
[i
], pfmt
, pflags
);
2014 asl_msg_list_release(res
);
2018 if ((pflags
& COMPRESS_DUPS
) && (last_printmsg_count
> 0))
2020 fprintf(f
, "--- last message repeated %d time%s ---\n", last_printmsg_count
, (last_printmsg_count
== 1) ? "" : "s");
2021 free(last_printmsg_str
);
2022 last_printmsg_str
= NULL
;
2023 last_printmsg_count
= 0;
2026 if (pflags
& FORMAT_XML
) print_xml_trailer(f
);
2034 op
= ASL_QUERY_OP_NULL
;
2036 if (o
== NULL
) return op
;
2038 for (i
= 0; o
[i
] != '\0'; i
++)
2040 if (o
[i
] == MOD_CASE_FOLD
) op
|= ASL_QUERY_OP_CASEFOLD
;
2041 else if (o
[i
] == MOD_REGEX
) op
|= ASL_QUERY_OP_REGEX
;
2042 else if (o
[i
] == MOD_NUMERIC
) op
|= ASL_QUERY_OP_NUMERIC
;
2043 else if (o
[i
] == MOD_SUBSTRING
) op
|= ASL_QUERY_OP_SUBSTRING
;
2044 else if (o
[i
] == MOD_PREFIX
) op
|= ASL_QUERY_OP_PREFIX
;
2045 else if (o
[i
] == MOD_SUFFIX
) op
|= ASL_QUERY_OP_SUFFIX
;
2047 else if (!strncasecmp(o
+i
, OP_EQ
, sizeof(OP_EQ
)))
2049 op
|= ASL_QUERY_OP_EQUAL
;
2050 i
+= (sizeof(OP_EQ
) - 2);
2052 else if (!strncasecmp(o
+i
, OP_NE
, sizeof(OP_NE
)))
2054 op
|= ASL_QUERY_OP_NOT_EQUAL
;
2055 i
+= (sizeof(OP_NE
) - 2);
2057 else if (!strncasecmp(o
+i
, OP_GT
, sizeof(OP_GT
)))
2059 op
|= ASL_QUERY_OP_GREATER
;
2060 i
+= (sizeof(OP_GT
) - 2);
2062 else if (!strncasecmp(o
+i
, OP_GE
, sizeof(OP_GE
)))
2064 op
|= ASL_QUERY_OP_GREATER_EQUAL
;
2065 i
+= (sizeof(OP_GE
) - 2);
2067 else if (!strncasecmp(o
+i
, OP_LT
, sizeof(OP_LT
)))
2069 op
|= ASL_QUERY_OP_LESS
;
2070 i
+= (sizeof(OP_LT
) - 2);
2072 else if (!strncasecmp(o
+i
, OP_LE
, sizeof(OP_LE
)))
2074 op
|= ASL_QUERY_OP_LESS_EQUAL
;
2075 i
+= (sizeof(OP_LE
) - 2);
2079 fprintf(stderr
, "invalid option: %s\n", o
);
2085 if (op
& ASL_QUERY_OP_NUMERIC
)
2087 if (op
& ASL_QUERY_OP_CASEFOLD
)
2089 fprintf(stderr
, "warning: case fold modifier has no effect with numeric comparisons\n");
2090 op
&= ~ASL_QUERY_OP_CASEFOLD
;
2093 if (op
& ASL_QUERY_OP_REGEX
)
2095 fprintf(stderr
, "warning: regex modifier has no effect with numeric comparisons\n");
2096 op
&= ~ASL_QUERY_OP_REGEX
;
2099 if (op
& ASL_QUERY_OP_SUBSTRING
)
2101 fprintf(stderr
, "warning: substring modifier has no effect with numeric comparisons\n");
2102 op
&= ~ASL_QUERY_OP_SUBSTRING
;
2105 if (op
& ASL_QUERY_OP_PREFIX
)
2107 fprintf(stderr
, "warning: prefix modifier has no effect with numeric comparisons\n");
2108 op
&= ~ASL_QUERY_OP_PREFIX
;
2111 if (op
& ASL_QUERY_OP_SUFFIX
)
2113 fprintf(stderr
, "warning: suffix modifier has no effect with numeric comparisons\n");
2114 op
&= ~ASL_QUERY_OP_SUFFIX
;
2118 if (op
& ASL_QUERY_OP_REGEX
)
2120 if (op
& ASL_QUERY_OP_SUBSTRING
)
2122 fprintf(stderr
, "warning: substring modifier has no effect with regular expression comparisons\n");
2123 op
&= ~ASL_QUERY_OP_SUBSTRING
;
2126 if (op
& ASL_QUERY_OP_PREFIX
)
2128 fprintf(stderr
, "warning: prefix modifier has no effect with regular expression comparisons\n");
2129 op
&= ~ASL_QUERY_OP_PREFIX
;
2132 if (op
& ASL_QUERY_OP_SUFFIX
)
2134 fprintf(stderr
, "warning: suffix modifier has no effect with regular expression comparisons\n");
2135 op
&= ~ASL_QUERY_OP_SUFFIX
;
2143 add_op(asl_msg_t
*q
, char *key
, char *op
, char *val
, uint32_t flags
)
2148 if (key
== NULL
) return -1;
2149 if (q
== NULL
) return -1;
2152 if (strcmp(key
, ASL_KEY_TIME
) == 0)
2154 qval
= (const char *)val
;
2156 else if ((strcmp(key
, ASL_KEY_LEVEL
) == 0) && (_isanumber(val
) == 0))
2158 /* Convert level strings to numeric values */
2159 qval
= asl_string_to_char_level(val
);
2162 fprintf(stderr
, "invalid value for \"Level\"key: %s\n", val
);
2167 o
= ASL_QUERY_OP_NULL
;
2168 if (val
== NULL
) o
= ASL_QUERY_OP_TRUE
;
2173 if (o
== ASL_QUERY_OP_NULL
) return -1;
2176 fprintf(stderr
, "no value supplied for operator %s %s\n", key
, op
);
2180 if ((qval
== NULL
) && (o
& ASL_QUERY_OP_NUMERIC
) && (_isanumber(val
) == 0))
2182 fprintf(stderr
, "non-numeric value supplied for numeric operator %s %s %s\n", key
, op
, val
);
2188 if (qval
!= NULL
) asl_msg_set_key_val_op(q
, key
, qval
, o
);
2189 else asl_msg_set_key_val_op(q
, key
, val
, o
);
2195 add_db_file(const char *name
)
2200 if (dbselect
== DB_SELECT_LEGACY
)
2202 fprintf(stderr
, "syslog can only read one legacy format database\n");
2203 fprintf(stderr
, "can't combine legacy and non-legacy databases in a single search\n");
2207 /* shouldn't happen */
2208 if (name
== NULL
) return DB_SELECT_ASL
;
2211 status
= asl_file_open_read(name
, &s
);
2212 if (status
!= ASL_STATUS_OK
)
2214 fprintf(stderr
, "data store file %s open failed: %s \n", name
, asl_core_error(status
));
2220 fprintf(stderr
, "data store file %s open failed\n", name
);
2224 if (s
->flags
& ASL_FILE_FLAG_LEGACY_STORE
)
2226 if (db_files
!= NULL
)
2228 fprintf(stderr
, "syslog can only read a single legacy format database\n");
2229 fprintf(stderr
, "can't combine legacy and non-legacy databases in a single search\n");
2234 return DB_SELECT_LEGACY
;
2237 db_files
= asl_file_list_add(db_files
, s
);
2238 return DB_SELECT_FILES
;
2242 add_db_dir(const char *name
)
2245 struct dirent
*dent
;
2251 * Try opening as a data store
2253 status
= asl_store_open_read(name
, &store
);
2256 if (name
== NULL
) return DB_SELECT_ASL
;
2257 if (!strcmp(name
, PATH_ASL_STORE
)) return DB_SELECT_ASL
;
2258 return DB_SELECT_STORE
;
2262 * Open all readable files
2267 fprintf(stderr
, "%s: %s\n", name
, strerror(errno
));
2271 while ((dent
= readdir(dp
)) != NULL
)
2273 if (dent
->d_name
[0] == '.') continue;
2276 asprintf(&path
, "%s/%s", name
, dent
->d_name
);
2279 * asl_file_open_read will fail if path is NULL,
2280 * if the file is not an ASL store file,
2281 * or if it isn't readable.
2284 status
= asl_file_open_read(path
, &s
);
2285 if (path
!= NULL
) free(path
);
2286 if ((status
!= ASL_STATUS_OK
) || (s
== NULL
)) continue;
2288 db_files
= asl_file_list_add(db_files
, s
);
2293 return DB_SELECT_FILES
;
2297 main(int argc
, char *argv
[])
2300 int i
, j
, n
, watch
, status
, pflags
, iamroot
, user_tflag
, export_preserve_id
, saw_dash_d
, since_boot
;
2301 int notify_file
, notify_token
;
2302 asl_msg_list_t
*qlist
;
2305 const char *exportname
;
2306 uint32_t flags
, tail_count
, batch
, encode
;
2307 uint64_t qmin
, cmax
;
2315 batch
= FETCH_BATCH
;
2316 pflags
= FORMAT_STD
| COMPRESS_DUPS
;
2317 encode
= ASL_ENCODE_SAFE
;
2320 export_preserve_id
= 0;
2324 i
= asl_store_location();
2325 if (i
== ASL_STORE_LOCATION_MEMORY
) dbselect
= DB_SELECT_SYSLOGD
;
2327 if (getuid() == 0) iamroot
= 1;
2329 if ((argc
> 1) && ((!strcmp(argv
[1], "-help")) || (!strcmp(argv
[1], "--help"))))
2335 for (i
= 1; i
< argc
; i
++)
2338 if ((!strcmp(argv
[i
], "-time")) || (!strcmp(argv
[i
], "--time")))
2341 printf("%llu\n", qmin
);
2345 if ((!strcmp(argv
[i
], "-stats")) || (!strcmp(argv
[i
], "--stats")))
2347 asl_stats(argc
, argv
);
2351 if ((!strcmp(argv
[i
], "-config")) || (!strcmp(argv
[i
], "--config")))
2353 syslog_config(argc
, argv
);
2357 if ((!strcmp(argv
[i
], "-control")) || (!strcmp(argv
[i
], "--control")))
2359 syslog_control(argc
, argv
);
2363 if ((!strcmp(argv
[i
], "-module")) || (!strcmp(argv
[i
], "--module")))
2365 module_control(argc
, argv
);
2369 if (!strcmp(argv
[i
], "-s"))
2371 syslog_send(argc
, argv
);
2375 if (!strcmp(argv
[i
], "-c"))
2377 syslog_remote_control(argc
, argv
);
2382 qlist
= asl_msg_list_new();
2383 if (qlist
== NULL
) exit(1);
2387 for (i
= 1; i
< argc
; i
++)
2389 if (!strcmp(argv
[i
], "-f"))
2393 for (j
= i
+ 1; j
< argc
; j
++)
2395 if (!strcmp(argv
[j
], "-"))
2397 dbselect
= DB_SELECT_SYSLOGD
;
2401 else if (argv
[j
][0] == '-')
2407 dbselect
= add_db_file(argv
[j
]);
2413 else if (!strcmp(argv
[i
], "-d"))
2417 if (saw_dash_d
< argc
)
2419 for (j
= saw_dash_d
; j
< argc
; j
++)
2421 if (!strcmp(argv
[j
], "store"))
2423 dbselect
= add_db_dir(PATH_ASL_STORE
);
2426 else if (!strcmp(argv
[j
], "archive"))
2428 dbselect
= add_db_dir(PATH_ASL_ARCHIVE
);
2431 else if (argv
[j
][0] == '-')
2437 dbselect
= add_db_dir(argv
[j
]);
2444 fprintf(stderr
, "missing directory name following -d flag\n");
2448 else if (!strcmp(argv
[i
], "-b"))
2450 batch
= atoi(argv
[++i
]);
2452 else if (!strcmp(argv
[i
], "-B"))
2456 else if (!strcmp(argv
[i
], "-w"))
2460 if (((i
+ 1) < argc
) && (argv
[i
+ 1][0] != '-'))
2463 if (!strcmp(argv
[i
], "all"))
2465 tail_count
= (uint32_t)-1;
2467 else if (!strcmp(argv
[i
], "boot"))
2473 tail_count
= atoi(argv
[i
]);
2477 else if (!strcmp(argv
[i
], "-sort"))
2479 if (((i
+ 1) < argc
) && (argv
[i
+ 1][0] != '-'))
2484 if (((i
+ 1) < argc
) && (argv
[i
+ 1][0] != '-'))
2487 sort_key_2
= argv
[i
];
2492 sort_key
= ASL_KEY_MSG_ID
;
2497 else if (!strcmp(argv
[i
], "-nsort"))
2499 if (((i
+ 1) < argc
) && (argv
[i
+ 1][0] != '-'))
2504 if (((i
+ 1) < argc
) && (argv
[i
+ 1][0] != '-'))
2507 sort_key_2
= argv
[i
];
2512 sort_key
= ASL_KEY_MSG_ID
;
2518 else if (!strcmp(argv
[i
], "-u"))
2523 else if ((!strcmp(argv
[i
], "-x")) || (!strcmp(argv
[i
], "-X")))
2525 if ((i
+ 1) >= argc
)
2527 asl_msg_list_release(qlist
);
2532 if (!strcmp(argv
[i
], "-x")) export_preserve_id
= 1;
2534 exportname
= argv
[++i
];
2536 else if (!strcmp(argv
[i
], "-E"))
2538 if ((i
+ 1) >= argc
)
2540 asl_msg_list_release(qlist
);
2547 if (!strcmp(argv
[i
], "vis")) encode
= ASL_ENCODE_ASL
;
2548 else if (!strcmp(argv
[i
], "safe")) encode
= ASL_ENCODE_SAFE
;
2549 else if (!strcmp(argv
[i
], "xml")) encode
= ASL_ENCODE_XML
;
2550 else if (!strcmp(argv
[i
], "none")) encode
= ASL_ENCODE_NONE
;
2551 else if ((argv
[i
][0] >= '0') && (argv
[i
][0] <= '9') && (argv
[i
][1] == '\0')) encode
= atoi(argv
[i
]);
2553 else if (!strcmp(argv
[i
], "-F"))
2555 if ((i
+ 1) >= argc
)
2557 asl_msg_list_release(qlist
);
2564 if (!strcmp(argv
[i
], "raw"))
2566 pflags
= FORMAT_RAW
;
2567 if (user_tflag
== 0) tfmt
= "sec";
2569 else if (!strcmp(argv
[i
], "std"))
2571 pflags
= FORMAT_STD
| COMPRESS_DUPS
;
2573 else if (!strcmp(argv
[i
], "bsd"))
2575 pflags
= FORMAT_LEGACY
| COMPRESS_DUPS
;
2577 else if (!strcmp(argv
[i
], "xml"))
2579 pflags
= FORMAT_XML
;
2580 encode
= ASL_ENCODE_XML
;
2588 else if (!strcmp(argv
[i
], "-T"))
2590 if ((i
+ 1) >= argc
)
2592 asl_msg_list_release(qlist
);
2601 else if (!strcmp(argv
[i
], "-nodc"))
2603 pflags
= pflags
& ~COMPRESS_DUPS
;
2605 else if (!strcmp(argv
[i
], "-o"))
2611 asl_msg_list_append(qlist
, cq
);
2612 asl_msg_release(cq
);
2616 else if (!strcmp(argv
[i
], "-n"))
2618 flags
= ASL_QUERY_OP_NOT
;
2620 else if (!strcmp(argv
[i
], "-C"))
2624 asl_msg_list_append(qlist
, cq
);
2625 asl_msg_release(cq
);
2630 cq
= asl_msg_new(ASL_TYPE_QUERY
);
2631 status
= add_op(cq
, ASL_KEY_FACILITY
, OP_EQ
, FACILITY_CONSOLE
, flags
);
2632 asl_msg_list_append(qlist
, cq
);
2633 asl_msg_release(cq
);
2638 asl_msg_list_release(qlist
);
2642 else if (!strcmp(argv
[i
], "-k"))
2645 for (n
= i
; n
< argc
; n
++)
2647 if (!strcmp(argv
[n
], "-o")) break;
2648 if (!strcmp(argv
[n
], "-n")) break;
2649 if (!strcmp(argv
[n
], "-k")) break;
2652 fprintf(stderr
, "invalid sequence: -k");
2653 for (j
= i
; j
<= n
; j
++) fprintf(stderr
, " %s", argv
[j
]);
2654 fprintf(stderr
, "\n");
2667 if (cq
== NULL
) cq
= asl_msg_new(ASL_TYPE_QUERY
);
2670 if (n
== 1) status
= add_op(cq
, argv
[i
], NULL
, NULL
, flags
);
2671 else if (n
== 2) status
= add_op(cq
, argv
[i
], OP_EQ
, argv
[i
+1], flags
);
2672 else status
= add_op(cq
, argv
[i
], argv
[i
+1], argv
[i
+2], flags
);
2677 asl_msg_list_release(qlist
);
2685 fprintf(stderr
, "syslog: unknown option \"%s\"\n", argv
[i
]);
2686 fprintf(stderr
, "run \"syslog -help\" for usage\n");
2693 asl_msg_list_append(qlist
, cq
);
2694 asl_msg_release(cq
);
2703 * Catch and report some cases where watch (-w) doesn't work
2707 if (sort_key
!= NULL
)
2709 fprintf(stderr
, "Warning: -w flag has no effect with -sort flag\n");
2713 if (dbselect
== DB_SELECT_FILES
)
2715 if (saw_dash_d
== 0)
2717 fprintf(stderr
, "Warning: -w flag not supported for a set of one or more files\n");
2721 fprintf(stderr
, "Warning: directory \"%s\" is not an ASL data store\n", argv
[saw_dash_d
]);
2722 fprintf(stderr
, " -w flag not supported for a set of one or more files\n");
2729 if (exportname
!= NULL
)
2733 fprintf(stderr
, "Warning: -w flag has no effect with -x export flag\n");
2737 status
= asl_file_open_write(exportname
, 0644, -1, -1, &export
);
2738 if (status
!= ASL_STATUS_OK
)
2740 asl_msg_list_release(qlist
);
2741 fprintf(stderr
, "export file open failed: %s\n", asl_core_error(status
));
2746 * allow the string cache to be unlimited to maximize string dup compression
2747 * preserve message IDs
2749 export
->flags
= ASL_FILE_FLAG_UNLIMITED_CACHE
;
2750 if (export_preserve_id
!= 0) export
->flags
|= ASL_FILE_FLAG_PRESERVE_MSG_ID
;
2761 fprintf(stderr
, "NOTE: Most system logs have moved to a new logging system. See log(1) for more information.\n");
2763 /* set starting point */
2764 if (since_boot
== 1)
2766 /* search back for last "BOOT_TIME (ut_type == 2) record */
2770 bt
= asl_msg_list_new();
2773 fprintf(stderr
, "\ncan't allocate memory - exiting\n");
2777 bq
= asl_msg_new(ASL_TYPE_QUERY
);
2780 fprintf(stderr
, "\ncan't allocate memory - exiting\n");
2784 asl_msg_list_append(bt
, bq
);
2785 asl_msg_release(bq
);
2787 asl_msg_set_key_val_op(bq
, "ut_type", "2", ASL_QUERY_OP_EQUAL
);
2789 search_once(NULL
, NULL
, 0, (asl_msg_list_t
*)bt
, -1, &qmin
, 1, 1, -1, 0);
2790 asl_msg_list_release(bt
);
2792 if (qmin
> 0) qmin
--;
2795 else if (watch
== 1)
2797 /* go back tail_count records from last record */
2799 search_once(NULL
, NULL
, 0, qlist
, qmin
, &cmax
, 1, 1, -1, 0);
2801 if (cmax
>= tail_count
) qmin
= cmax
- tail_count
;
2807 if ((watch
== 1) && (dbselect
== DB_SELECT_ASL
))
2809 status
= notify_register_file_descriptor("com.apple.system.logger.message", ¬ify_file
, 0, ¬ify_token
);
2810 if (status
!= NOTIFY_STATUS_OK
) notify_token
= -1;
2813 /* output should be line buffered */
2814 if (outfile
!= NULL
) setlinebuf(outfile
);
2816 search_once(outfile
, pfmt
, pflags
, qlist
, qmin
+ 1, &cmax
, 0, 0, 1, tail_count
);
2820 if (dbselect
== DB_SELECT_SYSLOGD
)
2822 #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
2823 syslogd_direct_watch(outfile
, pfmt
, pflags
, qlist
);
2825 fprintf(stderr
, "Warning: -w flag cannot be used when querying syslogd directly\n");
2829 else if (notify_token
== -1)
2834 if (cmax
> qmin
) qmin
= cmax
;
2835 search_once(outfile
, pfmt
, pflags
, qlist
, qmin
+ 1, &cmax
, 0, batch
, 1, 0);
2840 while (read(notify_file
, &i
, 4) == 4)
2842 if (cmax
> qmin
) qmin
= cmax
;
2843 search_once(outfile
, pfmt
, pflags
, qlist
, qmin
+ 1, &cmax
, 0, batch
, 1, 0);
2848 if (db_files
!= NULL
) asl_file_list_close(db_files
);
2849 if (store
!= NULL
) asl_store_release(store
);
2850 if (export
!= NULL
) asl_file_release(export
);
2852 asl_msg_list_release(qlist
);