#include "svc.h"
void
sfree(char **strp)
{
if (*strp)
free(*strp);
}
void
sreplace(char **strp, const char *orig)
{
if (*strp) {
free(*strp);
*strp = NULL;
}
if (orig)
*strp = strdup(orig);
}
void
sdup(char **strp)
{
if (*strp)
*strp = strdup(*strp);
}
void
afree(char ***aryp)
{
char **ary = *aryp;
int i;
if (ary) {
for (i = 0; ary[i]; ++i)
free(ary[i]);
free(ary);
}
*aryp = NULL;
}
void
adup(char ***aryp)
{
char **ary = *aryp;
char **nary;
int i;
if (ary) {
for (i = 0; ary[i]; ++i)
;
nary = calloc(i + 1, sizeof(char *));
bcopy(ary, nary, sizeof(char *) * (i + 1));
for (i = 0; nary[i]; ++i)
nary[i] = strdup(nary[i]);
*aryp = nary;
}
}
int
setup_pid_and_socket(command_t *cmd, int *lfdp, int *pfdp)
{
struct sockaddr_un sou;
size_t len;
char *pidfile;
asprintf(&pidfile, "%s/service.%s.pid", cmd->piddir, cmd->label);
*lfdp = -1;
*pfdp = open(pidfile, O_RDWR|O_CREAT|O_EXLOCK|O_NONBLOCK, 0640);
free(pidfile);
if (*pfdp < 0) {
if (errno == EWOULDBLOCK) {
fprintf(cmd->fp, "Cannot init, %s is already active\n",
cmd->label);
} else {
fprintf(cmd->fp,
"Cannot init, unable to create \"%s\": %s\n",
cmd->label,
strerror(errno));
}
return 1;
}
ftruncate(*pfdp, 0);
bzero(&sou, sizeof(sou));
if ((*lfdp = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0) {
sou.sun_family = AF_UNIX;
snprintf(sou.sun_path, sizeof(sou.sun_path),
"%s/service.%s.sk", cmd->piddir, cmd->label);
len = strlen(sou.sun_path);
len = offsetof(struct sockaddr_un, sun_path[len+1]);
remove(sou.sun_path);
if (bind(*lfdp, (void *)&sou, len) < 0) {
fprintf(cmd->fp, "Unable to bind \"%s\"\n",
sou.sun_path);
close(*lfdp);
*lfdp = -1;
} else if (listen(*lfdp, 32) < 0) {
fprintf(cmd->fp, "Unable to listen on \"%s\"\n",
sou.sun_path);
close(*lfdp);
*lfdp = -1;
}
} else {
fprintf(cmd->fp, "Unable to create unix-domain socket\n");
}
if (*lfdp >= 0) {
return 0;
} else {
close(*pfdp);
*pfdp = -1;
return 1;
}
}
void
remove_pid_and_socket(command_t *cmd, const char *label)
{
char *pidpath, *skpath;
asprintf(&pidpath, "%s/service.%s.pid", cmd->piddir, label);
remove(pidpath);
asprintf(&skpath, "%s/service.%s.sk", cmd->piddir, label);
remove(skpath);
free(pidpath);
free(skpath);
}