#include <sys_defs.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <msg.h>
#include <listen.h>
#include <mymalloc.h>
#include <stringops.h>
#include <inet_addr_list.h>
#include <set_eugid.h>
#include <set_ugid.h>
#include <iostuff.h>
#include <myaddrinfo.h>
#include <sock_addr.h>
#include <mail_params.h>
#include "master.h"
void master_listen_init(MASTER_SERV *serv)
{
const char *myname = "master_listen_init";
char *end_point;
int n;
MAI_HOSTADDR_STR hostaddr;
struct sockaddr *sa;
switch (serv->type) {
case MASTER_SERV_TYPE_UNIX:
set_eugid(var_owner_uid, var_owner_gid);
serv->listen_fd[0] =
LOCAL_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
serv->max_proc : var_proc_limit, NON_BLOCKING);
close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
set_ugid(getuid(), getgid());
break;
case MASTER_SERV_TYPE_FIFO:
set_eugid(var_owner_uid, var_owner_gid);
serv->listen_fd[0] = fifo_listen(serv->name, 0622, NON_BLOCKING);
close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
set_ugid(getuid(), getgid());
break;
case MASTER_SERV_TYPE_INET:
for (n = 0; n < serv->listen_fd_count; n++) {
sa = SOCK_ADDR_PTR(MASTER_INET_ADDRLIST(serv)->addrs + n);
SOCKADDR_TO_HOSTADDR(sa, SOCK_ADDR_LEN(sa), &hostaddr,
(MAI_SERVPORT_STR *) 0, 0);
end_point = concatenate(hostaddr.buf,
":", MASTER_INET_PORT(serv), (char *) 0);
serv->listen_fd[n]
= inet_listen(end_point, serv->max_proc > var_proc_limit ?
serv->max_proc : var_proc_limit, NON_BLOCKING);
close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
myfree(end_point);
}
break;
#ifdef MASTER_SERV_TYPE_PASS
case MASTER_SERV_TYPE_PASS:
set_eugid(var_owner_uid, var_owner_gid);
serv->listen_fd[0] =
PASS_LISTEN(serv->name, serv->max_proc > var_proc_limit ?
serv->max_proc : var_proc_limit, NON_BLOCKING);
close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
set_ugid(getuid(), getgid());
break;
#endif
default:
msg_panic("%s: unknown service type: %d", myname, serv->type);
}
}
void master_listen_cleanup(MASTER_SERV *serv)
{
const char *myname = "master_listen_cleanup";
int n;
for (n = 0; n < serv->listen_fd_count; n++) {
if (close(serv->listen_fd[n]) < 0)
msg_warn("%s: close listener socket %d: %m",
myname, serv->listen_fd[n]);
serv->listen_fd[n] = -1;
}
}