1 /* 2 * Copyright 2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <SupportDefs.h> 8 9 #include <pwd.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <syslog.h> 14 #include <unistd.h> 15 16 17 #define DEFAULT_PRIORITY LOG_DEBUG 18 #define DEFAULT_FACILITY LOG_USER 19 20 21 extern const char *__progname; 22 static const char *sProgramName = __progname; 23 24 25 struct mapping { 26 const char* name; 27 int value; 28 }; 29 30 static mapping sPriorities[] = { 31 { "emerg", LOG_EMERG }, 32 { "panic", LOG_PANIC }, 33 { "alert", LOG_ALERT }, 34 { "critical", LOG_CRIT }, 35 { "crit", LOG_CRIT }, 36 { "error", LOG_ERR }, 37 { "err", LOG_ERR }, 38 { "warning", LOG_WARNING }, 39 { "warn", LOG_WARNING }, 40 { "notice", LOG_NOTICE }, 41 { "info", LOG_INFO }, 42 { "debug", LOG_DEBUG }, 43 { NULL, DEFAULT_PRIORITY }, 44 }; 45 46 static mapping sFacilities[] = { 47 { "kernel", LOG_KERN }, 48 { "kern", LOG_KERN }, 49 { "user", LOG_USER }, 50 { "mail", LOG_MAIL }, 51 { "daemon", LOG_DAEMON }, 52 { "auth", LOG_AUTH }, 53 { "security", LOG_AUTH }, 54 { "syslog", LOG_SYSLOG }, 55 { "lpr", LOG_LPR }, 56 { "news", LOG_NEWS }, 57 { "uucp", LOG_UUCP }, 58 { "cron", LOG_CRON }, 59 { "authpriv", LOG_AUTHPRIV }, 60 { NULL, DEFAULT_FACILITY }, 61 }; 62 63 64 static int 65 lookup_mapping(struct mapping* mappings, const char *string) 66 { 67 int32 i; 68 for (i = 0; mappings[i].name != NULL; i++) { 69 if (!strcasecmp(string, mappings[i].name)) 70 break; 71 } 72 73 return mappings[i].value; 74 } 75 76 77 static int 78 get_facility(const char *option) 79 { 80 char facility[256]; 81 strlcpy(facility, option, sizeof(facility)); 82 83 char *end = strchr(facility, '.'); 84 if (end == NULL) { 85 // there is no facility specified 86 return DEFAULT_FACILITY; 87 } 88 89 end[0] = '\0'; 90 91 return lookup_mapping(sFacilities, facility); 92 } 93 94 95 static int 96 get_priority(const char *option) 97 { 98 char *priority = strchr(option, '.'); 99 if (priority == NULL) { 100 // there is no facility specified 101 return DEFAULT_PRIORITY; 102 } 103 104 return lookup_mapping(sPriorities, ++priority); 105 } 106 107 108 static void 109 usage(void) 110 { 111 fprintf(stderr, "usage: %s [-i] [-t <tag>] [-p <[facility.]priority>] <message>\n\n" 112 "Sends a message to the system logging facility.\n" 113 "If <message> is omitted, the message is read from stdin.\n\n" 114 " -i\tAdds the team ID to the log.\n" 115 " -t\tSpecifies the tag under which this message is posted.\n" 116 " -p\tSets the facility and priority this is logged under.\n" 117 " \t<facility> can be one of:\n" 118 "\t\tkern, user, mail, daemon, auth, syslog, lpr, news,\n" 119 "\t\tuucp, cron, authpriv\n" 120 " \t<priority> can be one of:\n" 121 "\t\tdebug, info, notice, warning, warn, error, err,\n" 122 "\t\tcritical, crit,alert, panic, emerg.\n", sProgramName); 123 124 exit(-1); 125 } 126 127 128 int 129 main(int argc, char **argv) 130 { 131 struct passwd* passwd = getpwuid(geteuid()); 132 const char* tag = NULL; 133 int facility = DEFAULT_FACILITY; 134 int priority = DEFAULT_PRIORITY; 135 int options = 0; 136 137 // read arguments 138 139 int option; 140 while ((option = getopt(argc, argv, "it:p:")) != -1) { 141 switch (option) { 142 case 'i': // log team ID 143 options |= LOG_PID; 144 break; 145 146 case 't': // tag 147 tag = optarg; 148 break; 149 150 case 'p': // facility/priority 151 facility = get_facility(optarg); 152 priority = get_priority(optarg); 153 break; 154 155 default: 156 usage(); 157 break; 158 } 159 } 160 161 if (tag == NULL && passwd != NULL) 162 tag = passwd->pw_name; 163 164 argc -= optind; 165 argv = &argv[optind]; 166 167 openlog(tag, options, facility); 168 169 if (argc > 0) { 170 // take message from arguments 171 172 char* buffer = NULL; 173 int32 length = 0; 174 175 for (int32 i = 0; i < argc; i++) { 176 int32 newLength = length + strlen(argv[i]) + 1; 177 178 buffer = (char *)realloc(buffer, newLength); 179 if (buffer == NULL) { 180 fprintf(stderr, "%s: out of memory\n", sProgramName); 181 return -1; 182 } 183 184 strcpy(buffer + length, argv[i]); 185 length = newLength; 186 187 buffer[length - 1] = ' '; 188 } 189 190 buffer[length - 1] = '\0'; 191 syslog(priority, "%s", buffer); 192 free(buffer); 193 } else { 194 // read messages from stdin 195 196 char buffer[65536]; 197 while (fgets(buffer, sizeof(buffer), stdin) != NULL) { 198 syslog(priority, "%s", buffer); 199 } 200 } 201 202 closelog(); 203 return 0; 204 } 205 206