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 <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>] " 112 "<message>\n\n" 113 "Sends a message to the system logging facility.\n" 114 "If <message> is omitted, the message is read from stdin.\n\n" 115 " -i\tAdds the team ID to the log.\n" 116 " -t\tSpecifies the tag under which this message is posted.\n" 117 " -p\tSets the facility and priority this is logged under.\n" 118 " \t<facility> can be one of:\n" 119 "\t\tkern, user, mail, daemon, auth, syslog, lpr, news,\n" 120 "\t\tuucp, cron, authpriv\n" 121 " \t<priority> can be one of:\n" 122 "\t\tdebug, info, notice, warning, warn, error, err,\n" 123 "\t\tcritical, crit,alert, panic, emerg.\n", sProgramName); 124 125 exit(-1); 126 } 127 128 129 int 130 main(int argc, char **argv) 131 { 132 struct passwd* passwd = getpwuid(geteuid()); 133 const char* tag = NULL; 134 int facility = DEFAULT_FACILITY; 135 int priority = DEFAULT_PRIORITY; 136 int options = 0; 137 138 // read arguments 139 140 int option; 141 while ((option = getopt(argc, argv, "it:p:")) != -1) { 142 switch (option) { 143 case 'i': // log team ID 144 options |= LOG_PID; 145 break; 146 147 case 't': // tag 148 tag = optarg; 149 break; 150 151 case 'p': // facility/priority 152 facility = get_facility(optarg); 153 priority = get_priority(optarg); 154 break; 155 156 default: 157 usage(); 158 break; 159 } 160 } 161 162 if (tag == NULL && passwd != NULL) 163 tag = passwd->pw_name; 164 165 argc -= optind; 166 argv = &argv[optind]; 167 168 openlog(tag, options, facility); 169 170 if (argc > 0) { 171 // take message from arguments 172 173 char* buffer = NULL; 174 int32 length = 0; 175 176 for (int32 i = 0; i < argc; i++) { 177 int32 newLength = length + strlen(argv[i]) + 1; 178 179 buffer = (char *)realloc(buffer, newLength + 1); 180 if (buffer == NULL) { 181 fprintf(stderr, "%s: out of memory\n", sProgramName); 182 return -1; 183 } 184 185 strcpy(buffer + length, argv[i]); 186 length = newLength; 187 188 buffer[length - 1] = ' '; 189 } 190 191 if (length > 1 && buffer[length - 2] != '\n') { 192 buffer[length - 1] = '\n'; 193 buffer[length] = '\0'; 194 } else 195 buffer[length - 1] = '\0'; 196 197 syslog(priority, "%s", buffer); 198 free(buffer); 199 } else { 200 // read messages from stdin 201 202 char buffer[65536]; 203 while (fgets(buffer, sizeof(buffer), stdin) != NULL) { 204 syslog(priority, "%s", buffer); 205 } 206 } 207 208 closelog(); 209 return 0; 210 } 211 212