static int log_notify(struct blob_attr *msg) { struct blob_attr *tb[__LOG_MAX]; struct stat s; char buf[512]; uint32_t p; char *str; time_t t; char *c, *m; int ret = 0; if (sender.fd < 0) return 0; blobmsg_parse(log_policy, ARRAY_SIZE(log_policy), tb, blob_data(msg), blob_len(msg)); if (!tb[LOG_ID] || !tb[LOG_PRIO] || !tb[LOG_SOURCE] || !tb[LOG_TIME] || !tb[LOG_MSG]) return 1; if ((log_type == LOG_FILE) && log_size && (!stat(log_file, &s)) && (s.st_size > log_size)) { char *old = malloc(strlen(log_file) + 5); close(sender.fd); if (old) { sprintf(old, "%s.old", log_file); rename(log_file, old); free(old); } sender.fd = open(log_file, O_CREAT | O_WRONLY | O_APPEND, 0600); if (sender.fd < 0) { fprintf(stderr, "failed to open %s: %s\n", log_file, strerror(errno)); exit(-1); } } m = blobmsg_get_string(tb[LOG_MSG]); t = blobmsg_get_u64(tb[LOG_TIME]) / 1000; c = ctime(&t); p = blobmsg_get_u32(tb[LOG_PRIO]); c[strlen(c) - 1] = '\0'; str = blobmsg_format_json(msg, true); if (log_type == LOG_NET) { int err; snprintf(buf, sizeof(buf), "<%u>", p); strncat(buf, c + 4, 16); if (hostname) { strncat(buf, hostname, sizeof(buf) - strlen(buf) - 1); strncat(buf, " ", sizeof(buf) - strlen(buf) - 1); } if (log_prefix) { strncat(buf, log_prefix, sizeof(buf) - strlen(buf) - 1); strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1); } if (blobmsg_get_u32(tb[LOG_SOURCE]) == SOURCE_KLOG) strncat(buf, "kernel: ", sizeof(buf) - strlen(buf) - 1); strncat(buf, m, sizeof(buf) - strlen(buf) - 1); if (log_udp) err = write(sender.fd, buf, strlen(buf)); else { size_t buflen = strlen(buf); if (!log_trailer_null) buf[buflen] = '\n'; err = send(sender.fd, buf, buflen + 1, 0); } if (err < 0) { syslog(LOG_INFO, "failed to send log data to %s:%s via %s\n", log_ip, log_port, (log_udp) ? ("udp") : ("tcp")); uloop_fd_delete(&sender); close(sender.fd); sender.fd = -1; uloop_timeout_set(&retry, 1000); } } else { snprintf(buf, sizeof(buf), "%s %s.%s%s %s\n", c, getcodetext(LOG_FAC(p) << 3, facilitynames), getcodetext(LOG_PRI(p), prioritynames), (blobmsg_get_u32(tb[LOG_SOURCE])) ? ("") : (" kernel:"), m); ret = write(sender.fd, buf, strlen(buf)); } free(str); if (log_type == LOG_FILE) fsync(sender.fd); return ret; }
//--------------------------------------------------------------------------- bool TSyslogMessage::FromStringSyslogd(char * p, int size, sockaddr_in * from_addr) { if( from_addr ) SourceAddr = inet_ntoa(from_addr->sin_addr); else SourceAddr = ""; PRI = -1; // not exist if( *p == '<' ) { for(int i=1; i<5 && p[i]; i++) { if( p[i] == '>' ) { PRI = atoi(p+1); p += i + 1; break; } if( ! isdigit(p[i]) ) break; } } if( PRI >= 0 ) { // invalid facility number not allowed: message filtering mechanism will fail // replace invalid facility number by LOGALERT if( LOG_FAC(PRI) >= LOG_NFACILITIES ) PRI = LOG_PRI(PRI) | LOG_LOGALERT; Facility = getcodetext(LOG_FAC(PRI) << 3, facilitynames); Priority = getcodetext(LOG_PRI(PRI), prioritynames); } if( IsValidSyslogDate(p) ) { DateStr = String(p, 15); p += 16; // including space } else { // month names in english in compliance to syslog rfc TFormatSettings fs; GetLocaleFormatSettings(0x0409, fs); // usa DateStr = FormatDateTime("mmm dd hh:nn:ss", Now(), fs); } // try to find host name for(int i=0; i<255 && p[i]; i++) { if( p[i] == ' ' ) { // found HostName = String(p, i); p += i + 1; break; } else if( p[i] == ':' || p[i] == '[' || p[i] == ']' ) { // host name not exist - this is program name break; } } // try to find program name for(int i=0; i<(48+2) && p[i]; i++) { if( p[i] == ':' && p[i+1] == ' ' ) { // found Tag = String(p, i); p += i + 2; break; } } // and now - process message // Replace all tabs by spaces, // cut all carriage returns and line feeds, // replace all chars 0..32 by '.' Msg = ""; for(int i=0; p[i]; i++) { if( p[i] == '\t' || p[i] == '\n' ) Msg += ' '; else if( p[i] == '\r' ) ; else if( p[i] >= 0 && p[i] < 32 ) Msg += '.'; else Msg += p[i]; } if( MainCfg.bReceiveUTF8 ) Msg = Utf8ToAnsi(Msg); return true; }