#include <sys/types.h>
#include <sys/device.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <regex.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <libprop/proplib.h>
#include <sys/udev.h>
#include "udevd.h"
int
send_xml(int s, char *xml)
{
ssize_t r,n;
size_t sz;
sz = strlen(xml) + 1;
r = send(s, &sz, sizeof(sz), 0);
if (r <= 0)
return r;
r = 0;
while (r < (ssize_t)sz) {
n = send(s, xml+r, sz-r, 0);
if (n <= 0)
return n;
r += n;
}
return r;
}
int
read_xml(int s, char **buf)
{
char *xml;
size_t sz;
int n, r;
*buf = NULL;
n = recv(s, &sz, sizeof(sz), MSG_WAITALL);
if ((n <= 0) || (sz > 12*1024*1024))
return n;
xml = malloc(sz+2);
r = 0;
while (r < (ssize_t)sz) {
n = recv(s, xml+r, sz-r, MSG_WAITALL);
if (n <= 0) {
free(xml);
return n;
}
r += n;
}
*buf = xml;
return r;
}
int
unblock_descriptor(int s)
{
int flags, ret;
flags = fcntl(s, F_GETFL, 0);
ret = fcntl(s, F_SETFL, flags | O_NONBLOCK);
return ret;
}
int
block_descriptor(int s)
{
int flags, ret;
flags = fcntl(s, F_GETFL, 0);
ret = fcntl(s, F_SETFL, flags & ~O_NONBLOCK);
return ret;
}
int
init_local_server(const char *sockfile, int socktype, int nonblock)
{
mode_t msk;
int s;
struct sockaddr_un un_addr;
if ((s = socket(AF_UNIX, socktype, 0)) < 0)
return -1;
memset(&un_addr, 0, sizeof(un_addr));
un_addr.sun_family = AF_UNIX;
strncpy(un_addr.sun_path, sockfile, SOCKFILE_NAMELEN);
un_addr.sun_path[SOCKFILE_NAMELEN - 1] = '\0';
unlink(un_addr.sun_path);
if (nonblock && unblock_descriptor(s) < 0) {
close(s);
return -1;
}
msk = umask(S_IXUSR|S_IXGRP|S_IXOTH);
if (bind(s, (struct sockaddr *)&un_addr, sizeof(un_addr)) < 0) {
close(s);
return -1;
}
umask(msk);
if (socktype == SOCK_STREAM && listen(s, LOCAL_BACKLOG) < 0) {
close(s);
return -1;
}
return s;
}