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