1: # include <syslog.h> 2: # include <sys/types.h> 3: # include <sys/stat.h> 4: # include <sgtty.h> 5: # ifdef LOG_IPC 6: # include <sys/socket.h> 7: #ifdef LOG_OLDIPC 8: # include <net/in.h> 9: #else LOG_OLDIPC 10: # include <netinet/in.h> 11: # include <netdb.h> 12: #endif LOG_OLDIPC 13: # endif LOG_IPC 14: 15: static char SccsId[] = "@(#)syslog.c 4.1 7/25/83"; 16: 17: 18: /* 19: ** SYSLOG -- print message on log file 20: ** 21: ** This routine looks a lot like printf, except that it 22: ** outputs to the log file instead of the standard output. 23: ** Also, it prints the module name in front of lines, 24: ** and has some other formatting types (or will sometime). 25: ** Also, it adds a newline on the end of messages. 26: ** 27: ** The output of this routine is intended to be read by 28: ** /etc/syslog, which will add timestamps. 29: ** 30: ** Parameters: 31: ** pri -- the message priority. 32: ** fmt -- the format string. 33: ** p0 -- the first of many parameters. 34: ** 35: ** Returns: 36: ** none 37: ** 38: ** Side Effects: 39: ** output to log. 40: */ 41: 42: # define MAXLINE 1000 /* maximum line length */ 43: # define BUFSLOP 20 /* space to allow for "extra stuff" */ 44: # define NULL 0 /* manifest */ 45: 46: int LogFile = -1; /* fd for log */ 47: int LogStat = 0; /* status bits, set by initlog */ 48: char *LogTag = NULL; /* string to tag the entry with */ 49: int LogMask = LOG_DEBUG; /* lowest priority to be logged */ 50: 51: # ifdef LOG_IPC 52: #ifndef LOG_OLDIPC 53: struct sockaddr_in SyslogAddr; 54: #else LOG_OLDIPC 55: struct sockaddr_in SyslogAddr = { AF_INET, LOG_PORT }; 56: struct sockproto SyslogProto = { PF_INET, IPPROTO_UDP }; 57: #endif LOG_OLDIPC 58: static char *SyslogHost = LOG_HOST; 59: # endif LOG_IPC 60: 61: syslog(pri, fmt, p0, p1, p2, p3, p4) 62: int pri; 63: char *fmt; 64: { 65: char buf[MAXLINE+BUFSLOP]; 66: register char *b; 67: char *f; 68: int prec; 69: int len; 70: register char c; 71: register char *p; 72: int i; 73: extern int errno; 74: extern int sys_nerr; 75: extern char *sys_errlist[]; 76: extern char *logcvt(); 77: char outline[MAXLINE + 1]; 78: 79: /* if we have no log, open it */ 80: if (LogFile < 0) 81: openlog(0, 0); 82: 83: /* see if we should just throw out this message */ 84: if (pri > LogMask) 85: return; 86: 87: f = fmt; 88: 89: while (*f != '\0') 90: { 91: /* beginning of line */ 92: b = buf; 93: 94: /* insert priority code */ 95: if (pri > 0 && (LogStat & LOG_COOLIT) == 0) 96: { 97: *b++ = '<'; 98: *b++ = pri + '0'; 99: *b++ = '>'; 100: } 101: 102: /* output current process ID */ 103: if ((LogStat & LOG_PID) != 0) 104: { 105: sprintf(b, "%d ", getpid()); 106: b += strlen(b); 107: } 108: 109: /* and module name */ 110: if (LogTag != 0) 111: { 112: for (p = LogTag; *p != '\0'; ) 113: *b++ = *p++; 114: *b++ = ':'; 115: *b++ = ' '; 116: } 117: while ((c = *f++) != '\0' && c != '\n') 118: { 119: /* output character directly if not interpolated */ 120: if (c != '%') 121: { 122: *b++ = c; 123: continue; 124: } 125: c = *f++; 126: switch (c) 127: { 128: case 'm': /* output error code */ 129: if (errno < 0 || errno > sys_nerr) 130: sprintf(b, "error %d", errno); 131: else 132: sprintf(b, "%s", sys_errlist[errno]); 133: break; 134: 135: default: 136: *b++ = '%'; 137: *b++ = c; 138: *b = '\0'; 139: break; 140: } 141: b += strlen(b); 142: if (b >= &buf[MAXLINE]) 143: break; 144: } 145: if (c == '\0') 146: f--; 147: 148: /* add trailing newline */ 149: *b++ = '\n'; 150: *b = '\0'; 151: 152: /* output string */ 153: sprintf(outline, buf, p0, p1, p2, p3, p4); 154: # ifdef LOG_IPC 155: if (LogStat & LOG_DGRAM) 156: { 157: register int r; 158: 159: #ifndef LOG_OLDIPC 160: r = sendto(LogFile, outline, strlen(outline), 0, 161: &SyslogAddr, sizeof SyslogAddr); 162: #else LOG_OLDIPC 163: r = send(LogFile, &SyslogAddr, outline, strlen(outline)); 164: #endif LOG_OLDIPC 165: # ifdef EBUG 166: if (r < 0) 167: perror("syslog: send"); 168: # endif EBUG 169: } 170: else 171: # endif LOG_IPC 172: write(LogFile, outline, strlen(outline)); 173: } 174: } 175: /* 176: ** OPENLOG -- open system log 177: ** 178: ** This happens automatically with reasonable defaults if you 179: ** do nothing. 180: ** 181: ** Parameters: 182: ** ident -- the name to be printed as a header for 183: ** all messages. 184: ** logstat -- a status word, interpreted as follows: 185: ** LOG_PID -- log the pid with each message. 186: ** 187: ** Returns: 188: ** 0 -- success. 189: ** -1 -- failure; logging on /dev/console instead. 190: ** 191: ** Side Effects: 192: ** Several global variables get set. 193: */ 194: 195: openlog(ident, logstat) 196: char *ident; 197: int logstat; 198: { 199: register int i; 200: register int fd; 201: struct stat st; 202: #ifndef LOG_OLDIPC 203: # ifdef LOG_IPC 204: struct servent *sp; 205: struct hostent *hp; 206: # endif LOG_IPC 207: #endif LOG_OLDIPC 208: 209: LogTag = ident; 210: LogStat = logstat; 211: 212: if (LogFile >= 0) 213: return; 214: 215: #ifdef notdef -------------------- 216: # ifdef LOG_IPC 217: #ifndef LOG_OLDIPC 218: sp = getservbyname("syslog", "udp"); 219: hp = gethostbyname(SyslogHost); 220: if (sp != NULL && hp != NULL) 221: { 222: bzero(&SyslogAddr, sizeof SyslogAddr); 223: SyslogAddr.sin_family = AF_INET; 224: LogFile = socket(AF_INET, SOCK_DGRAM, 0, 0); 225: if (LogFile >= 0 && bind(LogFile, &SyslogAddr, sizeof SyslogAddr, 0) < 0) 226: { 227: close(LogFile); 228: LogFile = -1; 229: } 230: # ifdef EBUG 231: if (LogFile < 0) 232: perror("syslog: socket"); 233: # endif EBUG 234: SyslogAddr.sin_port = sp->s_port; 235: bcopy(hp->h_addr, (char *) &SyslogAddr.sin_addr, hp->h_length); 236: LogStat |= LOG_DGRAM; 237: } 238: #else LOG_OLDIPC 239: SyslogAddr.sin_addr.s_addr = rhost(&SyslogHost); 240: LogFile = socket(SOCK_DGRAM, &SyslogProto, 0, 0); 241: # ifdef EBUG 242: if (LogFile < 0) 243: perror("syslog: socket"); 244: # endif EBUG 245: LogStat |= LOG_DGRAM; 246: #endif LOG_OLDIPC 247: # else LOG_IPC 248: LogFile = open("/dev/log", 1); 249: # endif LOG_IPC 250: 251: if (LogFile < 0) 252: { 253: nolog: 254: LogStat |= LOG_COOLIT; 255: LogStat &= ~LOG_DGRAM; 256: LogMask = LOG_CRIT; 257: # ifdef EBUG 258: LogFile = -1; 259: # else EBUG 260: LogFile = open("/dev/console", 1); 261: # endif EBUG 262: if (LogFile < 0) 263: { 264: perror("Cannot open /dev/console"); 265: LogFile = 2; 266: } 267: } 268: # ifndef LOG_IPC 269: if (fstat(LogFile, &st) < 0) 270: goto nolog; 271: switch (st.st_mode & S_IFMT) 272: { 273: case S_IFREG: 274: case S_IFDIR: 275: (void) close(LogFile); 276: goto nolog; 277: } 278: 279: # ifdef FIOCLEX 280: /* have it close automatically on exec */ 281: ioctl(LogFile, FIOCLEX, NULL); 282: # endif FIOCLEX 283: # endif LOG_IPC 284: #else notdef ---------------------- 285: LogStat |= LOG_COOLIT; 286: LogStat &= ~LOG_DGRAM; 287: LogMask = LOG_CRIT; 288: /* 289: LogFile = open("/dev/console", 1); 290: if (LogFile < 0) 291: { 292: perror("Cannot open /dev/console"); 293: LogFile = 2; 294: } 295: */ 296: LogFile = 2; 297: #endif notdef ---------------------- 298: } 299: /* 300: ** CLOSELOG -- close the system log 301: ** 302: ** Parameters: 303: ** none. 304: ** 305: ** Returns: 306: ** none. 307: ** 308: ** Side Effects: 309: ** The system log is closed. 310: */ 311: 312: closelog() 313: { 314: (void) close(LogFile); 315: LogFile = -1; 316: }