log_control.c
1 /* 2 * Copyright (c) 2003-2007,2009-2010,2013-2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 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 11 * file. 12 * 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. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 * 23 * log_control.c 24 */ 25 26 #include <string.h> 27 #include <getopt.h> 28 #include <stdlib.h> 29 30 #include <Security/SecItem.h> 31 #include <CoreFoundation/CoreFoundation.h> 32 33 #include "SecurityTool/sharedTool/tool_errors.h" 34 35 #include <Security/SecLogging.h> 36 37 #include <utilities/debugging.h> 38 39 #include <utilities/SecCFWrappers.h> 40 41 #include "SecurityCommands.h" 42 43 44 static void 45 set_log_settings(const char * settings) 46 { 47 CFErrorRef error = NULL; 48 49 CFStringRef scope = CFStringCreateWithCString(kCFAllocatorDefault, settings, kCFStringEncodingUTF8); 50 51 if (!SecSetLoggingInfoForXPCScope((CFPropertyListRef) scope, &error)) { 52 fprintf(stderr, "Failed: "); 53 CFShow(error); 54 } 55 56 CFReleaseSafe(scope); 57 CFReleaseSafe(error); 58 } 59 60 static void 61 set_circle_settings(const char * settings) 62 { 63 CFErrorRef error = NULL; 64 65 CFStringRef scope = CFStringCreateWithCString(kCFAllocatorDefault, settings, kCFStringEncodingUTF8); 66 67 if (!SecSetLoggingInfoForCircleScope((CFPropertyListRef) scope, &error)) { 68 fprintf(stderr, "Failed: "); 69 CFShow(error); 70 } 71 72 CFReleaseSafe(scope); 73 CFReleaseSafe(error); 74 } 75 76 static const char * getScopeIDName(int id) 77 { 78 switch (id) { 79 case kScopeIDXPC: return "XPC"; 80 case kScopeIDDefaults: return "Defaults"; 81 case kScopeIDEnvironment: return "Environment Variables"; 82 case kScopeIDConfig: return "Config"; 83 case kScopeIDCircle: return "Circle"; 84 default: return "Unknown"; 85 } 86 }; 87 88 static const char * getPriorityName(CFNumberRef id_number) 89 { 90 int priority = -1; 91 92 CFNumberGetValue(id_number, kCFNumberIntType, &priority); 93 94 switch (priority) { 95 case ASL_LEVEL_EMERG: return ASL_STRING_EMERG; 96 case ASL_LEVEL_ALERT: return ASL_STRING_ALERT; 97 case ASL_LEVEL_CRIT: return ASL_STRING_CRIT; 98 case ASL_LEVEL_ERR: return ASL_STRING_ERR; 99 case ASL_LEVEL_WARNING: return ASL_STRING_WARNING; 100 case ASL_LEVEL_NOTICE: return ASL_STRING_NOTICE; 101 case ASL_LEVEL_INFO: return ASL_STRING_INFO; 102 case ASL_LEVEL_DEBUG: return ASL_STRING_DEBUG; 103 default: return "Unknown"; 104 105 } 106 }; 107 108 static void print_comma_separated(FILE* file, CFArrayRef array) 109 { 110 fprintf(file, "["); 111 __block const char *separator = ""; 112 CFArrayForEach(array, ^(const void *value) { 113 cffprint(file, CFSTR("%s%@"), separator, value); 114 separator = ", "; 115 }); 116 fprintf(file, "]"); 117 118 } 119 120 static void 121 list_log_settings() 122 { 123 CFErrorRef error = NULL; 124 125 CFArrayRef result = SecGetCurrentServerLoggingInfo(&error); 126 if (result) { 127 __block int index = 0; 128 CFArrayForEach(result, ^(const void *value) { 129 printf("%s: ", getScopeIDName(index)); 130 131 if (isArray(value)) { 132 print_comma_separated(stdout, (CFArrayRef) value); 133 printf("\n"); 134 } else if (isDictionary(value)) { 135 printf("\n"); 136 CFDictionaryForEach((CFDictionaryRef) value, ^(const void *level, const void *array) { 137 printf(" %s: ", getPriorityName(level)); 138 if (isArray(array)) { 139 print_comma_separated(stdout, (CFArrayRef) array); 140 } else { 141 cffprint(stdout, CFSTR("%@"), array); 142 } 143 printf("\n"); 144 }); 145 } else { 146 cffprint(stdout, CFSTR("%@\n"), value); 147 } 148 149 ++index; 150 }); 151 } else { 152 fprintf(stderr, "Failed: "); 153 CFShow(error); 154 } 155 156 CFReleaseSafe(error); 157 } 158 159 int log_control(int argc, char * const *argv) 160 { 161 int ch, result = 2; /* @@@ Return 2 triggers usage message. */ 162 163 bool list = false; 164 /* 165 "-l - list" 166 */ 167 while ((ch = getopt(argc, argv, "ls:c:")) != -1) 168 { 169 switch (ch) 170 { 171 case 'l': 172 list = true; 173 break; 174 case 's': 175 set_log_settings(optarg); 176 break; 177 case 'c': 178 set_circle_settings(optarg); 179 break; 180 case '?': 181 default: 182 goto fail; 183 } 184 } 185 186 argc -= optind; 187 argv += optind; 188 189 if (argc > 1) 190 goto fail; 191 192 if (argc == 1) { 193 set_log_settings(argv[0]); 194 195 argc -= 1; 196 argv += 1; 197 } 198 199 (void) argv; 200 201 if (argc != 0) 202 goto fail; 203 204 if (list) 205 list_log_settings(); 206 207 result = 0; 208 209 fail: 210 return result; 211 }