PlatformCommon.c revision 47e4cebad7397422144bb03a21f3f7682c062c4a
147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/* -*- Mode: C; tab-width: 4 -*- 247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. 447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Licensed under the Apache License, Version 2.0 (the "License"); 647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * you may not use this file except in compliance with the License. 747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * You may obtain a copy of the License at 847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * http://www.apache.org/licenses/LICENSE-2.0 1047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * 1147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Unless required by applicable law or agreed to in writing, software 1247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * distributed under the License is distributed on an "AS IS" BASIS, 1347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * See the License for the specific language governing permissions and 1547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * limitations under the License. 1647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */ 1747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 1847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <stdio.h> // Needed for fopen() etc. 1947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <unistd.h> // Needed for close() 2047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <string.h> // Needed for strlen() etc. 2147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <errno.h> // Needed for errno etc. 2247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <sys/socket.h> // Needed for socket() etc. 2347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <netinet/in.h> // Needed for sockaddr_in 2447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include <syslog.h> 2547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 2647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "mDNSEmbeddedAPI.h" // Defines the interface provided to the client layer above 2747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "DNSCommon.h" 2847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "PlatformCommon.h" 2947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 3047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#ifdef NOT_HAVE_SOCKLEN_T 3147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt typedef unsigned int socklen_t; 3247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif 3347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 3447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// Bind a UDP socket to find the source address to a destination 3547e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport void mDNSPlatformSourceAddrForDest(mDNSAddr *const src, const mDNSAddr *const dst) 3647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 3747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt union { struct sockaddr s; struct sockaddr_in a4; struct sockaddr_in6 a6; } addr; 3847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt socklen_t len = sizeof(addr); 3947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt socklen_t inner_len = 0; 4047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int sock = socket(AF_INET, SOCK_DGRAM, 0); 4147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt src->type = mDNSAddrType_None; 4247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (sock == -1) return; 4347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (dst->type == mDNSAddrType_IPv4) 4447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 4547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt inner_len = sizeof(addr.a4); 4647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt #ifndef NOT_HAVE_SA_LEN 4747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr.a4.sin_len = inner_len; 4847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt #endif 4947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr.a4.sin_family = AF_INET; 5047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr.a4.sin_port = 1; // Not important, any port will do 5147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr.a4.sin_addr.s_addr = dst->ip.v4.NotAnInteger; 5247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 5347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else if (dst->type == mDNSAddrType_IPv6) 5447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 5547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt inner_len = sizeof(addr.a6); 5647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt #ifndef NOT_HAVE_SA_LEN 5747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr.a6.sin6_len = inner_len; 5847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt #endif 5947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr.a6.sin6_family = AF_INET6; 6047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr.a6.sin6_flowinfo = 0; 6147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr.a6.sin6_port = 1; // Not important, any port will do 6247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr.a6.sin6_addr = *(struct in6_addr*)&dst->ip.v6; 6347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt addr.a6.sin6_scope_id = 0; 6447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 6547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else return; 6647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 6747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if ((connect(sock, &addr.s, inner_len)) < 0) 6847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { LogMsg("mDNSPlatformSourceAddrForDest: connect %#a failed errno %d (%s)", dst, errno, strerror(errno)); goto exit; } 6947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 7047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if ((getsockname(sock, &addr.s, &len)) < 0) 7147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { LogMsg("mDNSPlatformSourceAddrForDest: getsockname failed errno %d (%s)", errno, strerror(errno)); goto exit; } 7247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 7347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt src->type = dst->type; 7447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (dst->type == mDNSAddrType_IPv4) src->ip.v4.NotAnInteger = addr.a4.sin_addr.s_addr; 7547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else src->ip.v6 = *(mDNSv6Addr*)&addr.a6.sin6_addr; 7647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltexit: 7747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt close(sock); 7847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 7947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 8047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt// dst must be at least MAX_ESCAPED_DOMAIN_NAME bytes, and option must be less than 32 bytes in length 8147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSlocal mDNSBool GetConfigOption(char *dst, const char *option, FILE *f) 8247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 8347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char buf[32+1+MAX_ESCAPED_DOMAIN_NAME]; // Option name, one space, option value 8447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt unsigned int len = strlen(option); 8547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (len + 1 + MAX_ESCAPED_DOMAIN_NAME > sizeof(buf)-1) { LogMsg("GetConfigOption: option %s too long", option); return mDNSfalse; } 8647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fseek(f, 0, SEEK_SET); // set position to beginning of stream 8747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt while (fgets(buf, sizeof(buf), f)) // Read at most sizeof(buf)-1 bytes from file, and append '\0' C-string terminator 8847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 8947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!strncmp(buf, option, len)) 9047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 9147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt strncpy(dst, buf + len + 1, MAX_ESCAPED_DOMAIN_NAME-1); 9247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (dst[MAX_ESCAPED_DOMAIN_NAME-1]) dst[MAX_ESCAPED_DOMAIN_NAME-1] = '\0'; 9347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt len = strlen(dst); 9447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (len && dst[len-1] == '\n') dst[len-1] = '\0'; // chop newline 9547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return mDNStrue; 9647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 9747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 9847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt debugf("Option %s not set", option); 9947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return mDNSfalse; 10047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 10147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 10247e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport void ReadDDNSSettingsFromConfFile(mDNS *const m, const char *const filename, domainname *const hostname, domainname *const domain, mDNSBool *DomainDiscoveryDisabled) 10347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 10447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt char buf[MAX_ESCAPED_DOMAIN_NAME] = ""; 10547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mStatus err; 10647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt FILE *f = fopen(filename, "r"); 10747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 10847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (hostname) hostname->c[0] = 0; 10947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (domain) domain->c[0] = 0; 11047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (DomainDiscoveryDisabled) *DomainDiscoveryDisabled = mDNSfalse; 11147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 11247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (f) 11347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 11447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (DomainDiscoveryDisabled && GetConfigOption(buf, "DomainDiscoveryDisabled", f) && !strcasecmp(buf, "true")) *DomainDiscoveryDisabled = mDNStrue; 11547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (hostname && GetConfigOption(buf, "hostname", f) && !MakeDomainNameFromDNSNameString(hostname, buf)) goto badf; 11647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (domain && GetConfigOption(buf, "zone", f) && !MakeDomainNameFromDNSNameString(domain, buf)) goto badf; 11747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt buf[0] = 0; 11847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt GetConfigOption(buf, "secret-64", f); // failure means no authentication 11947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fclose(f); 12047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt f = NULL; 12147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 12247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 12347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 12447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (errno != ENOENT) LogMsg("ERROR: Config file exists, but cannot be opened."); 12547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return; 12647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 12747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 12847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (domain && domain->c[0] && buf[0]) 12947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 13047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt DomainAuthInfo *info = (DomainAuthInfo*)mDNSPlatformMemAllocate(sizeof(*info)); 13147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt // for now we assume keyname = service reg domain and we use same key for service and hostname registration 13247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt err = mDNS_SetSecretForDomain(m, info, domain, domain, buf, NULL, 0, NULL); 13347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (err) LogMsg("ERROR: mDNS_SetSecretForDomain returned %d for domain %##s", err, domain->c); 13447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 13547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 13647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt return; 13747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 13847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt badf: 13947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt LogMsg("ERROR: malformatted config file"); 14047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (f) fclose(f); 14147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 14247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 14347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if MDNS_DEBUGMSGS 14447e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport void mDNSPlatformWriteDebugMsg(const char *msg) 14547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 14647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr,"%s\n", msg); 14747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fflush(stderr); 14847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 14947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif 15047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 15147e4cebad7397422144bb03a21f3f7682c062c4aRobert GreenwaltmDNSexport void mDNSPlatformWriteLogMsg(const char *ident, const char *buffer, mDNSLogLevel_t loglevel) 15247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 15347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if APPLE_OSX_mDNSResponder && LogTimeStamps 15447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt extern mDNS mDNSStorage; 15547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt extern mDNSu32 mDNSPlatformClockDivisor; 15647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt mDNSs32 t = mDNSStorage.timenow ? mDNSStorage.timenow : mDNSPlatformClockDivisor ? mDNS_TimeNow_NoLock(&mDNSStorage) : 0; 15747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int ms = ((t < 0) ? -t : t) % 1000; 15847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif 15947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 16047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (mDNS_DebugMode) // In debug mode we write to stderr 16147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 16247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if APPLE_OSX_mDNSResponder && LogTimeStamps 16347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (ident && ident[0] && mDNSPlatformClockDivisor) 16447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr,"%8d.%03d: %s\n", (int)(t/1000), ms, buffer); 16547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 16647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif 16747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr,"%s\n", buffer); 16847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fflush(stderr); 16947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 17047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else // else, in production mode, we write to syslog 17147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 17247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt static int log_inited = 0; 17347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 17447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt int syslog_level = LOG_ERR; 17547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt switch (loglevel) 17647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt { 17747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case MDNS_LOG_MSG: syslog_level = LOG_ERR; break; 17847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case MDNS_LOG_OPERATION: syslog_level = LOG_WARNING; break; 17947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case MDNS_LOG_SPS: syslog_level = LOG_NOTICE; break; 18047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case MDNS_LOG_INFO: syslog_level = LOG_INFO; break; 18147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt case MDNS_LOG_DEBUG: syslog_level = LOG_DEBUG; break; 18247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt default: 18347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fprintf(stderr, "Unknown loglevel %d, assuming LOG_ERR\n", loglevel); 18447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt fflush(stderr); 18547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 18647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 18747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (!log_inited) { openlog(ident, LOG_CONS, LOG_DAEMON); log_inited++; } 18847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt 18947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if APPLE_OSX_mDNSResponder && LogTimeStamps 19047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt if (ident && ident[0] && mDNSPlatformClockDivisor) 19147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog(syslog_level, "%8d.%03d: %s", (int)(t/1000), ms, buffer); 19247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt else 19347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif 19447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt syslog(syslog_level, "%s", buffer); 19547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 19647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt } 197