|
|
1.1 root 1: #include <stdarg.h>
2: #ifdef __unix__
3: #include <syslog.h>
4: #endif
5:
6: #include "xp_syslog.h"
7: #include "sockwrap.h"
8: #include "gen_defs.h"
9:
10: static SOCKET syslog_sock=INVALID_SOCKET;
11: static char log_host[1025]=
12: static int log_opts=LOG_CONS;
13: #ifdef __unix__
14: "";
15: #else
16: "localhost";
17: #endif
18:
19: static char syslog_tag[33]="undefined";
20: static int default_facility=LOG_USER;
21:
22: static u_long resolve_ip(char *addr)
23: {
24: HOSTENT* host;
25: char* p;
26:
27: if(*addr==0)
28: return((u_long)INADDR_NONE);
29:
30: for(p=addr;*p;p++)
31: if(*p!='.' && !isdigit(*p))
32: break;
33: if(!(*p))
34: return(inet_addr(addr));
35: if((host=gethostbyname(addr))==NULL)
36: return((u_long)INADDR_NONE);
37: return(*((ulong*)host->h_addr_list[0]));
38: }
39:
40: void xp_set_loghost(const char *hostname)
41: {
42: SAFECOPY(log_host, hostname);
43: }
44:
45: void xp_openlog(const char *ident, int logopt, int facility)
46: {
47: int sock;
48: SOCKADDR_IN syslog_addr;
49: socklen_t syslog_len;
50:
51: #ifdef __unix__
52: if(!log_host[0]) {
53: openlog(ident,logopt,facility);
54: return;
55: }
56: #endif
57:
58: memset(&syslog_addr, 0, sizeof(syslog_addr));
59: syslog_addr.sin_addr.s_addr=INADDR_ANY;
60: syslog_addr.sin_family=AF_INET;
61: syslog_addr.sin_port=htons(SYSLOG_PORT);
62:
63: syslog_sock=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
64: if(syslog_sock==INVALID_SOCKET)
65: return;
66: if(bind(syslog_sock, (struct sockaddr *)&syslog_addr, sizeof(syslog_addr))) {
67: syslog_addr.sin_port=0;
68: if(bind(syslog_sock, (struct sockaddr *)&syslog_addr, sizeof(syslog_addr)))
69: return;
70: }
71: syslog_addr.sin_addr.s_addr=resolve_ip(log_host);
72: syslog_addr.sin_port=htons(SYSLOG_PORT);
73: if(connect(syslog_sock, (struct sockaddr *)&syslog_addr, sizeof(syslog_addr))) {
74: closesocket(syslog_sock);
75: syslog_sock=INVALID_SOCKET;
76: return;
77: }
78:
79: log_opts=logopt;
80:
81: SAFECOPY(syslog_tag, ident);
82: }
83:
84: void xp_vsyslog(int priority, const char *message, va_list va)
85: {
86: int orig_errno=ERROR_VALUE;
87: time_t now;
88: char timestr[32];
89: char msg_to_send[1025];
90: char format[1025];
91: char *msg_end;
92: char *p;
93: int i;
94:
95: #ifdef __unix__
96: if(!log_host[0]) {
97: vsyslog(priority, message, va);
98: return;
99: }
100: #endif
101:
102: /* Ensure we can even send this thing */
103: if(syslog_sock==INVALID_SOCKET && !(log_opts & LOG_CONS) && !(log_opts & LOG_PERROR))
104: return;
105:
106: /* Check for valid priority */
107: if(priority & ~(LOG_PRIMASK|LOG_FACMASK)) {
108: i=priority;
109: /* Fix to something legal */
110: priority &= (LOG_PRIMASK|LOG_FACMASK);
111: /* Ooooo... re-entrant! */
112: syslog(priority,"Unknown priority %x",i);
113: }
114:
115: /* Set default facility if needed */
116: if(!(priority & LOG_FACMASK))
117: priority |= default_facility;
118:
119: time(&now);
120: ctime_r(&now, timestr);
121: /* Remove trailing \n */
122: timestr[24]=0;
123:
124: snprintf(format, sizeof(format), "<%d>%.15s %.32s: %s", priority, timestr+4 /* Remove day of week */, syslog_tag, message);
125: format[sizeof(format)-1]=0;
126: vsnprintf(msg_to_send, sizeof(msg_to_send), format, va);
127: msg_to_send[sizeof(msg_to_send)-1]=0;
128:
129: /* Clean out invalid chars (as per RFC3164) */
130: msg_end=msg_to_send+sizeof(msg_to_send)-1;
131: for(p=msg_to_send; *p; p++) {
132: if(*p<32) {
133: i=strlen(p);
134: memmove(p, p+1, i);
135: *p='^';
136: p++;
137: *p|=0x40;
138: if(p+i > msg_end)
139: *msg_end=0;
140: else
141: *(p+i)=0;
142: }
143: else if(*p>126)
144: *p=' ';
145: }
146: if(syslog_sock!=INVALID_SOCKET)
147: sendsocket(syslog_sock, msg_to_send, strlen(msg_to_send));
148: else if(log_opts & LOG_CONS)
149: puts(msg_to_send);
150: if(log_opts & LOG_PERROR) {
151: fputs(stderr,msg_to_send);
152: fputs(stderr,"\n");
153: }
154: }
155:
156: void xp_syslog(int priority, const char *message, ...)
157: {
158: va_list va;
159:
160: va_start(va, message);
161: vsyslog(priority, message, va);
162: va_end(va);
163: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.