mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
[MEDIUM] add support for logging via a UNIX socket
The code in haproxy-1.3.13.1 only supports syslogging to an internet address. The attached patch: - Adds support for syslogging to a UNIX domain socket (e.g., /dev/log). If the address field begins with '/' (absolute file path), then AF_UNIX is used to construct the socket. Otherwise, AF_INET is used. - Achieves clean single-source build on both Mac OS X and Linux (sockaddr_in.sin_len and sockaddr_un.sun_len field aren't always present). For handling sendto() failures in send_log(), it appears that the existing code is fine (no need to close/recreate socket) for both UDP and UNIX-domain syslog server. So I left things alone (did not close/recreate socket). Closing/recreating socket after each failure would also work, but would lead to increased amount of unnecessary socket creation/destruction if syslog is temporarily unavailable for some reason (especially for verbose loggers). Please consider this patch for inclusion into the upstream haproxy codebase.
This commit is contained in:
parent
ddbb82ff47
commit
81ae1953bf
@ -84,10 +84,20 @@ group <group name>
|
|||||||
log <address> <facility> [max level]
|
log <address> <facility> [max level]
|
||||||
Adds a global syslog server. Up to two global servers can be defined. They
|
Adds a global syslog server. Up to two global servers can be defined. They
|
||||||
will receive logs for startups and exits, as well as all logs from proxies
|
will receive logs for startups and exits, as well as all logs from proxies
|
||||||
configured with "log global". <address> is an IPv4 address optionally
|
configured with "log global".
|
||||||
followed by a colon and an UDP port. If no port is specified, 514 is used
|
|
||||||
by default (the standard syslog port). <facility> must be one of the 24
|
<address> can be one of:
|
||||||
standard syslog facilities :
|
|
||||||
|
- An IPv4 address optionally followed by a colon and an UDP port. If
|
||||||
|
no port is specified, 514 is used by default (the standard syslog
|
||||||
|
port).
|
||||||
|
|
||||||
|
- A filesystem path to a UNIX domain socket, keeping in mind
|
||||||
|
considerations for chroot (be sure the path is accessible inside
|
||||||
|
the chroot) and uid/gid (be sure the path is appropriately
|
||||||
|
writeable).
|
||||||
|
|
||||||
|
<facility> must be one of the 24 standard syslog facilities :
|
||||||
|
|
||||||
kern user mail daemon auth syslog lpr news
|
kern user mail daemon auth syslog lpr news
|
||||||
uucp cron auth2 ftp ntp audit alert cron2
|
uucp cron auth2 ftp ntp audit alert cron2
|
||||||
|
@ -124,6 +124,12 @@ extern int ishex(char s);
|
|||||||
*/
|
*/
|
||||||
extern const char *invalid_char(const char *name);
|
extern const char *invalid_char(const char *name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* converts <str> to a struct sockaddr_un* which is locally allocated.
|
||||||
|
* The format is "/path", where "/path" is a path to a UNIX domain socket.
|
||||||
|
*/
|
||||||
|
struct sockaddr_un *str2sun(char *str);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* converts <str> to a struct sockaddr_in* which is locally allocated.
|
* converts <str> to a struct sockaddr_in* which is locally allocated.
|
||||||
* The format is "addr:port", where "addr" can be a dotted IPv4 address,
|
* The format is "addr:port", where "addr" can be a dotted IPv4 address,
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
|
#include <types/log.h>
|
||||||
#include <types/protocols.h>
|
#include <types/protocols.h>
|
||||||
#include <types/task.h>
|
#include <types/task.h>
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ struct global {
|
|||||||
char *pidfile;
|
char *pidfile;
|
||||||
int logfac1, logfac2;
|
int logfac1, logfac2;
|
||||||
int loglev1, loglev2;
|
int loglev1, loglev2;
|
||||||
struct sockaddr_in logsrv1, logsrv2;
|
struct logsrv logsrv1, logsrv2;
|
||||||
struct {
|
struct {
|
||||||
int maxpollevents; /* max number of poll events at once */
|
int maxpollevents; /* max number of poll events at once */
|
||||||
} tune;
|
} tune;
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#ifndef _TYPES_LOG_H
|
#ifndef _TYPES_LOG_H
|
||||||
#define _TYPES_LOG_H
|
#define _TYPES_LOG_H
|
||||||
|
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
|
|
||||||
#define MAX_SYSLOG_LEN 1024
|
#define MAX_SYSLOG_LEN 1024
|
||||||
@ -44,6 +46,15 @@
|
|||||||
#define LW_REQHDR 1024 /* request header(s) */
|
#define LW_REQHDR 1024 /* request header(s) */
|
||||||
#define LW_RSPHDR 2048 /* response header(s) */
|
#define LW_RSPHDR 2048 /* response header(s) */
|
||||||
|
|
||||||
|
struct logsrv {
|
||||||
|
union {
|
||||||
|
struct sockaddr addr;
|
||||||
|
struct sockaddr_un un; /* AF_UNIX */
|
||||||
|
struct sockaddr_in in; /* AF_INET */
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
|
int logsrv_addrlen(const struct logsrv *logsrv);
|
||||||
|
|
||||||
#endif /* _TYPES_LOG_H */
|
#endif /* _TYPES_LOG_H */
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include <types/acl.h>
|
#include <types/acl.h>
|
||||||
#include <types/buffers.h>
|
#include <types/buffers.h>
|
||||||
#include <types/httperr.h>
|
#include <types/httperr.h>
|
||||||
|
#include <types/log.h>
|
||||||
#include <types/protocols.h>
|
#include <types/protocols.h>
|
||||||
#include <types/session.h>
|
#include <types/session.h>
|
||||||
#include <types/server.h>
|
#include <types/server.h>
|
||||||
@ -206,7 +207,7 @@ struct proxy {
|
|||||||
struct sockaddr_in tproxy_addr; /* non-local address we want to bind to for connect() */
|
struct sockaddr_in tproxy_addr; /* non-local address we want to bind to for connect() */
|
||||||
#endif
|
#endif
|
||||||
struct proxy *next;
|
struct proxy *next;
|
||||||
struct sockaddr_in logsrv1, logsrv2; /* 2 syslog servers */
|
struct logsrv logsrv1, logsrv2; /* 2 syslog servers */
|
||||||
signed char logfac1, logfac2; /* log facility for both servers. -1 = disabled */
|
signed char logfac1, logfac2; /* log facility for both servers. -1 = disabled */
|
||||||
int loglev1, loglev2; /* log level for each server, 7 by default */
|
int loglev1, loglev2; /* log level for each server, 7 by default */
|
||||||
int to_log; /* things to be logged (LW_*) */
|
int to_log; /* things to be logged (LW_*) */
|
||||||
|
@ -425,7 +425,7 @@ int cfg_parse_global(const char *file, int linenum, char **args)
|
|||||||
global.pidfile = strdup(args[1]);
|
global.pidfile = strdup(args[1]);
|
||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "log")) { /* syslog server address */
|
else if (!strcmp(args[0], "log")) { /* syslog server address */
|
||||||
struct sockaddr_in *sa;
|
struct logsrv logsrv;
|
||||||
int facility, level;
|
int facility, level;
|
||||||
|
|
||||||
if (*(args[1]) == 0 || *(args[2]) == 0) {
|
if (*(args[1]) == 0 || *(args[2]) == 0) {
|
||||||
@ -448,17 +448,23 @@ int cfg_parse_global(const char *file, int linenum, char **args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sa = str2sa(args[1]);
|
if (args[1][0] == '/') {
|
||||||
if (!sa->sin_port)
|
logsrv.u.addr.sa_family = AF_UNIX;
|
||||||
sa->sin_port = htons(SYSLOG_PORT);
|
logsrv.u.un = *str2sun(args[1]);
|
||||||
|
} else {
|
||||||
|
logsrv.u.addr.sa_family = AF_INET;
|
||||||
|
logsrv.u.in = *str2sa(args[1]);
|
||||||
|
if (!logsrv.u.in.sin_port)
|
||||||
|
logsrv.u.in.sin_port = htons(SYSLOG_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
if (global.logfac1 == -1) {
|
if (global.logfac1 == -1) {
|
||||||
global.logsrv1 = *sa;
|
global.logsrv1 = logsrv;
|
||||||
global.logfac1 = facility;
|
global.logfac1 = facility;
|
||||||
global.loglev1 = level;
|
global.loglev1 = level;
|
||||||
}
|
}
|
||||||
else if (global.logfac2 == -1) {
|
else if (global.logfac2 == -1) {
|
||||||
global.logsrv2 = *sa;
|
global.logsrv2 = logsrv;
|
||||||
global.logfac2 = facility;
|
global.logfac2 = facility;
|
||||||
global.loglev2 = level;
|
global.loglev2 = level;
|
||||||
}
|
}
|
||||||
@ -1639,7 +1645,7 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
|
|||||||
newsrv->prev_state = newsrv->state;
|
newsrv->prev_state = newsrv->state;
|
||||||
}
|
}
|
||||||
else if (!strcmp(args[0], "log")) { /* syslog server address */
|
else if (!strcmp(args[0], "log")) { /* syslog server address */
|
||||||
struct sockaddr_in *sa;
|
struct logsrv logsrv;
|
||||||
int facility;
|
int facility;
|
||||||
|
|
||||||
if (*(args[1]) && *(args[2]) == 0 && !strcmp(args[1], "global")) {
|
if (*(args[1]) && *(args[2]) == 0 && !strcmp(args[1], "global")) {
|
||||||
@ -1668,17 +1674,25 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sa = str2sa(args[1]);
|
if (args[1][0] == '/') {
|
||||||
if (!sa->sin_port)
|
logsrv.u.addr.sa_family = AF_UNIX;
|
||||||
sa->sin_port = htons(SYSLOG_PORT);
|
logsrv.u.un = *str2sun(args[1]);
|
||||||
|
} else {
|
||||||
|
logsrv.u.addr.sa_family = AF_INET;
|
||||||
|
logsrv.u.in = *str2sa(args[1]);
|
||||||
|
if (!logsrv.u.in.sin_port) {
|
||||||
|
logsrv.u.in.sin_port =
|
||||||
|
htons(SYSLOG_PORT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (curproxy->logfac1 == -1) {
|
if (curproxy->logfac1 == -1) {
|
||||||
curproxy->logsrv1 = *sa;
|
curproxy->logsrv1 = logsrv;
|
||||||
curproxy->logfac1 = facility;
|
curproxy->logfac1 = facility;
|
||||||
curproxy->loglev1 = level;
|
curproxy->loglev1 = level;
|
||||||
}
|
}
|
||||||
else if (curproxy->logfac2 == -1) {
|
else if (curproxy->logfac2 == -1) {
|
||||||
curproxy->logsrv2 = *sa;
|
curproxy->logsrv2 = logsrv;
|
||||||
curproxy->logfac2 = facility;
|
curproxy->logfac2 = facility;
|
||||||
curproxy->loglev2 = level;
|
curproxy->loglev2 = level;
|
||||||
}
|
}
|
||||||
|
110
src/log.c
110
src/log.c
@ -18,6 +18,7 @@
|
|||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
|
||||||
@ -30,6 +31,9 @@
|
|||||||
#include <types/log.h>
|
#include <types/log.h>
|
||||||
#include <types/session.h>
|
#include <types/session.h>
|
||||||
|
|
||||||
|
#ifndef MSG_NOSIGNAL
|
||||||
|
#define MSG_NOSIGNAL (0)
|
||||||
|
#endif /* !MSG_NOSIGNAL */
|
||||||
|
|
||||||
const char *log_facilities[NB_LOG_FACILITIES] = {
|
const char *log_facilities[NB_LOG_FACILITIES] = {
|
||||||
"kern", "user", "mail", "daemon",
|
"kern", "user", "mail", "daemon",
|
||||||
@ -140,6 +144,32 @@ int get_log_facility(const char *fac)
|
|||||||
return facility;
|
return facility;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the length of the address endpoint, suitable for use with sendto().
|
||||||
|
*/
|
||||||
|
int logsrv_addrlen(const struct logsrv *logsrv)
|
||||||
|
{
|
||||||
|
#ifdef __SOCKADDR_COMMON
|
||||||
|
switch (logsrv->u.addr.sa_family) {
|
||||||
|
case AF_UNIX:
|
||||||
|
return sizeof(logsrv->u.un);
|
||||||
|
case AF_INET:
|
||||||
|
return sizeof(logsrv->u.in);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else /* !__SOCKADDR_COMMON */
|
||||||
|
switch (logsrv->u.addr.sa_family) {
|
||||||
|
case AF_UNIX:
|
||||||
|
return logsrv->u.un.sun_len;
|
||||||
|
case AF_INET:
|
||||||
|
return logsrv->u.in.sin_len;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif /* !__SOCKADDR_COMMON */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function sends a syslog message to both log servers of a proxy,
|
* This function sends a syslog message to both log servers of a proxy,
|
||||||
@ -149,29 +179,20 @@ int get_log_facility(const char *fac)
|
|||||||
*/
|
*/
|
||||||
void send_log(struct proxy *p, int level, const char *message, ...)
|
void send_log(struct proxy *p, int level, const char *message, ...)
|
||||||
{
|
{
|
||||||
static int logfd = -1; /* syslog UDP socket */
|
static int logfdunix = -1; /* syslog to AF_UNIX socket */
|
||||||
|
static int logfdinet = -1; /* syslog to AF_INET socket */
|
||||||
static long tvsec = -1; /* to force the string to be initialized */
|
static long tvsec = -1; /* to force the string to be initialized */
|
||||||
va_list argp;
|
va_list argp;
|
||||||
static char logmsg[MAX_SYSLOG_LEN];
|
static char logmsg[MAX_SYSLOG_LEN];
|
||||||
static char *dataptr = NULL;
|
static char *dataptr = NULL;
|
||||||
int fac_level;
|
int fac_level;
|
||||||
int hdr_len, data_len;
|
int hdr_len, data_len;
|
||||||
struct sockaddr_in *sa[2];
|
struct logsrv *logsrvs[2];
|
||||||
int facilities[2], loglevel[2];
|
int facilities[2], loglevel[2];
|
||||||
|
int nblogger;
|
||||||
int nbloggers = 0;
|
int nbloggers = 0;
|
||||||
char *log_ptr;
|
char *log_ptr;
|
||||||
|
|
||||||
if (logfd < 0) {
|
|
||||||
if ((logfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
|
|
||||||
return;
|
|
||||||
/* we don't want to receive anything on this socket */
|
|
||||||
setsockopt(logfd, SOL_SOCKET, SO_RCVBUF, &zero, sizeof(zero));
|
|
||||||
/* need for AIX which does not know about MSG_DONTWAIT */
|
|
||||||
if (!MSG_DONTWAIT)
|
|
||||||
fcntl(logfd, F_SETFL, O_NONBLOCK);
|
|
||||||
shutdown(logfd, SHUT_RD); /* does nothing under Linux, maybe needed for others */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (level < 0 || progname == NULL || message == NULL)
|
if (level < 0 || progname == NULL || message == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -210,35 +231,70 @@ void send_log(struct proxy *p, int level, const char *message, ...)
|
|||||||
|
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
if (global.logfac1 >= 0) {
|
if (global.logfac1 >= 0) {
|
||||||
sa[nbloggers] = &global.logsrv1;
|
logsrvs[nbloggers] = &global.logsrv1;
|
||||||
facilities[nbloggers] = global.logfac1;
|
facilities[nbloggers] = global.logfac1;
|
||||||
loglevel[nbloggers] = global.loglev1;
|
loglevel[nbloggers] = global.loglev1;
|
||||||
nbloggers++;
|
nbloggers++;
|
||||||
}
|
}
|
||||||
if (global.logfac2 >= 0) {
|
if (global.logfac2 >= 0) {
|
||||||
sa[nbloggers] = &global.logsrv2;
|
logsrvs[nbloggers] = &global.logsrv2;
|
||||||
facilities[nbloggers] = global.logfac2;
|
facilities[nbloggers] = global.logfac2;
|
||||||
loglevel[nbloggers] = global.loglev2;
|
loglevel[nbloggers] = global.loglev2;
|
||||||
nbloggers++;
|
nbloggers++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (p->logfac1 >= 0) {
|
if (p->logfac1 >= 0) {
|
||||||
sa[nbloggers] = &p->logsrv1;
|
logsrvs[nbloggers] = &p->logsrv1;
|
||||||
facilities[nbloggers] = p->logfac1;
|
facilities[nbloggers] = p->logfac1;
|
||||||
loglevel[nbloggers] = p->loglev1;
|
loglevel[nbloggers] = p->loglev1;
|
||||||
nbloggers++;
|
nbloggers++;
|
||||||
}
|
}
|
||||||
if (p->logfac2 >= 0) {
|
if (p->logfac2 >= 0) {
|
||||||
sa[nbloggers] = &p->logsrv2;
|
logsrvs[nbloggers] = &p->logsrv2;
|
||||||
facilities[nbloggers] = p->logfac2;
|
facilities[nbloggers] = p->logfac2;
|
||||||
loglevel[nbloggers] = p->loglev2;
|
loglevel[nbloggers] = p->loglev2;
|
||||||
nbloggers++;
|
nbloggers++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (nbloggers-- > 0) {
|
/* Lazily set up syslog sockets for protocol families of configured
|
||||||
|
* syslog servers. */
|
||||||
|
for (nblogger = 0; nblogger < nbloggers; nblogger++) {
|
||||||
|
const struct logsrv *logsrv = logsrvs[nblogger];
|
||||||
|
int proto, *plogfd;
|
||||||
|
if (logsrv->u.addr.sa_family == AF_UNIX) {
|
||||||
|
proto = 0;
|
||||||
|
plogfd = &logfdunix;
|
||||||
|
} else {
|
||||||
|
/* sa_family == AF_INET */
|
||||||
|
proto = IPPROTO_UDP;
|
||||||
|
plogfd = &logfdinet;
|
||||||
|
}
|
||||||
|
if (*plogfd >= 0) {
|
||||||
|
/* socket already created. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((*plogfd = socket(logsrv->u.addr.sa_family, SOCK_DGRAM,
|
||||||
|
proto)) < 0) {
|
||||||
|
Alert("socket for logger #%d failed: %s (errno=%d)\n",
|
||||||
|
nblogger + 1, strerror(errno), errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* we don't want to receive anything on this socket */
|
||||||
|
setsockopt(*plogfd, SOL_SOCKET, SO_RCVBUF, &zero, sizeof(zero));
|
||||||
|
/* does nothing under Linux, maybe needed for others */
|
||||||
|
shutdown(*plogfd, SHUT_RD);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send log messages to syslog server. */
|
||||||
|
for (nblogger = 0; nblogger < nbloggers; nblogger++) {
|
||||||
|
const struct logsrv *logsrv = logsrvs[nblogger];
|
||||||
|
int *plogfd = logsrv->u.addr.sa_family == AF_UNIX ?
|
||||||
|
&logfdunix : &logfdinet;
|
||||||
|
int sent;
|
||||||
|
|
||||||
/* we can filter the level of the messages that are sent to each logger */
|
/* we can filter the level of the messages that are sent to each logger */
|
||||||
if (level > loglevel[nbloggers])
|
if (level > loglevel[nblogger])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* For each target, we may have a different facility.
|
/* For each target, we may have a different facility.
|
||||||
@ -248,7 +304,7 @@ void send_log(struct proxy *p, int level, const char *message, ...)
|
|||||||
* time, we only change the facility in the pre-computed header,
|
* time, we only change the facility in the pre-computed header,
|
||||||
* and we change the pointer to the header accordingly.
|
* and we change the pointer to the header accordingly.
|
||||||
*/
|
*/
|
||||||
fac_level = (facilities[nbloggers] << 3) + level;
|
fac_level = (facilities[nblogger] << 3) + level;
|
||||||
log_ptr = logmsg + 3; /* last digit of the log level */
|
log_ptr = logmsg + 3; /* last digit of the log level */
|
||||||
do {
|
do {
|
||||||
*log_ptr = '0' + fac_level % 10;
|
*log_ptr = '0' + fac_level % 10;
|
||||||
@ -258,14 +314,12 @@ void send_log(struct proxy *p, int level, const char *message, ...)
|
|||||||
*log_ptr = '<';
|
*log_ptr = '<';
|
||||||
|
|
||||||
/* the total syslog message now starts at logptr, for dataptr+data_len-logptr */
|
/* the total syslog message now starts at logptr, for dataptr+data_len-logptr */
|
||||||
|
sent = sendto(*plogfd, log_ptr, dataptr + data_len - log_ptr,
|
||||||
#ifndef MSG_NOSIGNAL
|
MSG_DONTWAIT | MSG_NOSIGNAL, &logsrv->u.addr, logsrv_addrlen(logsrv));
|
||||||
sendto(logfd, log_ptr, dataptr + data_len - log_ptr, MSG_DONTWAIT,
|
if (sent < 0) {
|
||||||
(struct sockaddr *)sa[nbloggers], sizeof(**sa));
|
Alert("sendto logger #%d failed: %s (errno=%d)\n",
|
||||||
#else
|
nblogger, strerror(errno), errno);
|
||||||
sendto(logfd, log_ptr, dataptr + data_len - log_ptr, MSG_DONTWAIT | MSG_NOSIGNAL,
|
}
|
||||||
(struct sockaddr *)sa[nbloggers], sizeof(**sa));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,37 @@ const char *limit_r(unsigned long n, char *buffer, int size, const char *alt)
|
|||||||
return (n) ? ultoa_r(n, buffer, size) : (alt ? alt : "");
|
return (n) ? ultoa_r(n, buffer, size) : (alt ? alt : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* converts <str> to a struct sockaddr_un* which is locally allocated.
|
||||||
|
* The format is "/path", where "/path" is a path to a UNIX domain socket.
|
||||||
|
*/
|
||||||
|
struct sockaddr_un *str2sun(char *str)
|
||||||
|
{
|
||||||
|
static struct sockaddr_un sun;
|
||||||
|
int strsz; /* length included null */
|
||||||
|
|
||||||
|
memset(&sun, 0, sizeof(sun));
|
||||||
|
str = strdup(str);
|
||||||
|
if (str == NULL)
|
||||||
|
goto out_nofree;
|
||||||
|
|
||||||
|
strsz = strlen(str) + 1;
|
||||||
|
if (strsz > sizeof(sun.sun_path)) {
|
||||||
|
Alert("Socket path '%s' too long (max %d)\n",
|
||||||
|
str, sizeof(sun.sun_path) - 1);
|
||||||
|
goto out_nofree;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef __SOCKADDR_COMMON
|
||||||
|
sun.sun_len = sizeof(sun);
|
||||||
|
#endif /* !__SOCKADDR_COMMON */
|
||||||
|
sun.sun_family = AF_UNIX;
|
||||||
|
memcpy(sun.sun_path, str, strsz);
|
||||||
|
|
||||||
|
free(str);
|
||||||
|
out_nofree:
|
||||||
|
return &sun;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns non-zero if character <s> is a hex digit (0-9, a-f, A-F), else zero.
|
* Returns non-zero if character <s> is a hex digit (0-9, a-f, A-F), else zero.
|
||||||
@ -153,6 +184,9 @@ struct sockaddr_in *str2sa(char *str)
|
|||||||
else
|
else
|
||||||
sa.sin_addr = *(struct in_addr *) *(he->h_addr_list);
|
sa.sin_addr = *(struct in_addr *) *(he->h_addr_list);
|
||||||
}
|
}
|
||||||
|
#ifndef __SOCKADDR_COMMON
|
||||||
|
sa.sin_len = sizeof(sa);
|
||||||
|
#endif /* !__SOCKADDR_COMMON */
|
||||||
sa.sin_port = htons(port);
|
sa.sin_port = htons(port);
|
||||||
sa.sin_family = AF_INET;
|
sa.sin_family = AF_INET;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user