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