/* Pure Load Balancer - (C)opyleft 2003 Jedi/Sector One <j@pureftpd.org> */

#include <config.h>
#include "plb.h"
#include "plb_globals.h"
#ifdef WITH_DMALLOC
# include <dmalloc.h>
#endif

void init_timeouts(void)
{
    timeout_header_client_read.tv_sec = (time_t) DEFAULT_CLIENT_TIMEOUT;
    timeout_header_client_write.tv_sec = (time_t) DEFAULT_CLIENT_TIMEOUT;
    timeout_header_server_read.tv_sec = (time_t) DEFAULT_SERVER_TIMEOUT;
    timeout_header_server_write.tv_sec = (time_t) DEFAULT_SERVER_TIMEOUT;
    
    timeout_forward_client_read.tv_sec = (time_t) DEFAULT_CLIENT_TIMEOUT;
    timeout_forward_client_write.tv_sec = (time_t) DEFAULT_CLIENT_TIMEOUT;
    timeout_forward_server_read.tv_sec = (time_t) DEFAULT_SERVER_TIMEOUT;
    timeout_forward_server_write.tv_sec = (time_t) DEFAULT_SERVER_TIMEOUT;
    
    timeout_cleanup.tv_sec = (time_t) DEFAULT_CLEANUP_TIMEOUT;    
}

int setsockopt_aggressive(const int fd)
{
    int ret = 0;
    
#ifdef SO_KEEPALIVE
    {
        int keep = 1;
        ret |= setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
                          (char *) &keep, sizeof keep);
    }
#endif
# ifdef SO_LINGER
    {
        struct linger li;
        li.l_onoff = li.l_linger = 0;
        ret |= setsockopt(fd, SOL_SOCKET, SO_LINGER,
                          (char *) &li, sizeof li);
    }
# endif
    
    return ret;
}

void socket_nonblock(const int fd)
{
    (void) fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);
}

int daemonize(void)
{
    pid_t child;
    
    if ((child = fork()) == (pid_t) -1) {
        plb_log(LL_ERROR, "Unable to fork : [%s]", strerror(errno));
        return -1;
    } else if (child != (pid_t) 0) {
        exit(0);
    } else {
        int i = 2;
        
        if (setsid() == (pid_t) -1) {
            plb_log(LL_ERROR, "Unable to create our own process group : [%s]",
                    strerror(errno)); /* continue, anyway */
        }
        do {
            if (isatty(i)) {
                while (close(i) != 0 && errno == EINTR);
            }
            i--;
        } while (i >= 0);
    }
    
    return 0;
}

int delete_pid_file(void)
{
    return 0;
}

int update_pid_file(const char * const pid_file)
{
    char buf[42];
    int fd;
    size_t towrite;
    ssize_t written;
    
    if (pid_file == NULL || *pid_file != '/') {
        return 0;
    }
    if (SNCHECK(snprintf(buf, sizeof buf, "%lu\n",
                         (unsigned long) getpid()), sizeof buf)) {
        return -1;
    }
    if (unlink(pid_file) != 0 && errno != ENOENT) {
        return -1;
    }
    if ((fd = open(pid_file, O_CREAT | O_WRONLY | O_TRUNC |
                   O_NOFOLLOW, (mode_t) 0644)) == -1) {
        plb_log(LL_ERROR, "Unable to create the [%s] pid file : [%s]",
                pid_file, strerror(errno));
        return -1;
    }
    towrite = strlen(buf);
    while ((written = write(fd, buf, towrite)) < (ssize_t) 0 &&
           errno == EINTR);
    if (written < (ssize_t) 0 || (size_t) written != towrite) {
        plb_log(LL_ERROR, "Error while writing the [%s] pid file : [%s]",
                pid_file, strerror(errno));        
        (void) ftruncate(fd, (off_t) 0);
        while (close(fd) != 0 && errno == EINTR);
        return -1;
    }
    while (close(fd) != 0 && errno == EINTR);    
    
    return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1