#ifndef __PLB_H__
#define __PLB_H__ 1
#ifndef __GNUC__
# ifdef __attribute__
# undef __attribute__
# endif
# define __attribute__(a)
#endif
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
# include <stdarg.h>
#else
# if HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_STRING_H
# if !STDC_HEADERS && HAVE_MEMORY_H
# include <memory.h>
# endif
# include <string.h>
#else
# if HAVE_STRINGS_H
# include <strings.h>
# endif
#endif
#include <limits.h>
#include <errno.h>
#include <ctype.h>
#include <signal.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include <syslog.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#elif defined(HAVE_SYS_FCNTL_H)
# include <sys/fcntl.h>
#endif
#ifdef HAVE_IOCTL_H
# include <ioctl.h>
#elif defined(HAVE_SYS_IOCTL_H)
# include <sys/ioctl.h>
#endif
#include <sys/socket.h>
#ifdef HAVE_NETINET_IN_SYSTM_H
# include <netinet/in_systm.h>
#endif
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <pwd.h>
#include <grp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <event.h>
#ifndef HAVE_GETOPT_LONG
# include "bsd-getopt_long.h"
#else
# include <getopt.h>
#endif
#ifdef HAVE_ALLOCA
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# endif
# define ALLOCA(X) alloca(X)
# define ALLOCA_FREE(X) do { } while (0)
#else
# define ALLOCA(X) malloc(X)
# define ALLOCA_FREE(X) free(X)
#endif
#include "mysnprintf.h"
#ifndef errno
extern int errno;
#endif
#ifdef TCP_CORK
# define CORK_ON(SK) do { int optval = 1; setsockopt(SK, SOL_TCP, TCP_CORK, \
&optval, sizeof optval); } while(0)
# define CORK_OFF(SK) do { int optval = 0; setsockopt(SK, SOL_TCP, TCP_CORK, \
&optval, sizeof optval); } while(0)
#else
# define CORK_ON(SK) do { } while(0)
# define CORK_OFF(SK) do { } while(0)
#endif
#ifndef O_NOFOLLOW
# define O_NOFOLLOW 0
#endif
#ifndef O_DIRECTORY
# define O_DIRECTORY 0
#endif
#ifndef SOL_IP
# define SOL_IP IPPROTO_IP
#endif
#ifndef SOL_TCP
# define SOL_TCP IPPROTO_TCP
#endif
#ifndef INADDR_NONE
# define INADDR_NONE 0
#endif
#if !defined(O_NDELAY) && defined(O_NONBLOCK)
# define O_NDELAY O_NONBLOCK
#endif
#ifndef FNDELAY
# define FNDELAY O_NDELAY
#endif
#ifndef HAVE_STRTOULL
# ifdef HAVE_STRTOQ
# define strtoull(X, Y, Z) strtoq(X, Y, Z)
# else
# define strtoull(X, Y, Z) strtoul(X, Y, Z)
# endif
#endif
#ifndef ULONG_LONG_MAX
# define ULONG_LONG_MAX (1ULL << 63)
#endif
#ifdef STAT_MACROS_BROKEN
# undef S_ISBLK
# undef S_ISCHR
# undef S_ISDIR
# undef S_ISFIFO
# undef S_ISLNK
# undef S_ISMPB
# undef S_ISMPC
# undef S_ISNWK
# undef S_ISREG
# undef S_ISSOCK
#endif /* STAT_MACROS_BROKEN. */
#ifndef S_IFMT
# define S_IFMT 0170000
#endif
#if !defined(S_ISBLK) && defined(S_IFBLK)
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#endif
#if !defined(S_ISCHR) && defined(S_IFCHR)
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
#if !defined(S_ISDIR) && defined(S_IFDIR)
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#if !defined(S_ISREG) && defined(S_IFREG)
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#if !defined(S_ISFIFO) && defined(S_IFIFO)
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
#endif
#if !defined(S_ISLNK) && defined(S_IFLNK)
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
#if !defined(S_ISSOCK) && defined(S_IFSOCK)
# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
#endif
#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
#endif
#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
#endif
#ifndef S_IEXEC
# define S_IEXEC S_IXUSR
#endif
#ifndef S_IXUSR
# define S_IXUSR S_IEXEC
#endif
#ifndef S_IXGRP
# define S_IXGRP (S_IEXEC >> 3)
#endif
#ifndef S_IXOTH
# define S_IXOTH (S_IEXEC >> 6)
#endif
#ifndef S_IXUGO
# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
#endif
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
# define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
# define STDERR_FILENO 2
#endif
#ifndef HAVE_SETEUID
# ifdef HAVE_SETREUID
# define seteuid(X) setreuid(-1, (X))
# elif defined(HAVE_SETRESUID)
# define seteuid(X) setresuid(-1, (X), -1)
# else
# define seteuid(X) (-1)
# endif
#endif
#ifndef HAVE_SETEGID
# ifdef HAVE_SETREGID
# define setegid(X) setregid(-1, (X))
# elif defined(HAVE_SETRESGID)
# define setegid(X) setresgid(-1, (X), -1)
# else
# define setegid(X) (-1)
# endif
#endif
#ifdef ACCEPT_UNICODE_CONTROL_CHARS
# define ISCTRLCODE(X) ((X) == 0x7f || ((unsigned char) (X)) < 32U)
#else
# define ISCTRLCODE(X) ((X) == 0x7f || !(((unsigned char) (X)) & 0x60))
#endif
#define DEFAULT_BACKLOG 100
#define HEADER_MAX 8192
#define POSTBUF_CHUNKS 8192
#define REPLYBUF_CHUNKS 32768
#define DEFAULT_SERVER_TIMEOUT 30
#define DEFAULT_CLIENT_TIMEOUT 30
#define DEFAULT_CLEANUP_TIMEOUT 30
#define DEFAULT_MAX_CLIENTS 1000
#define DEFAULT_SERVER_RETRY 15U
#define HTTP_HEADER_END "\r\n\r\n"
#define SMTP_HEADER_END "\r\n"
#define DEFAULT_LOG_LEVEL LL_WARNING
#define SERVER_FULL_MSG "Server too busy, sorry\r\n" /* change this for smtp */
typedef enum State_ {
STATE_OFFLINE, STATE_HEADER, STATE_SEND_HEADER, STATE_HEADER_SENT,
STATE_IGNORE
} State;
typedef enum LogLevel_ {
LL_DEBUG, LL_NOTIFY, LL_WARNING, LL_ERROR, LL_FATAL
} LogLevel;
typedef enum Protocol_ {
PROTOCOL_HTTP, PROTOCOL_SMTP
} Protocol;
typedef struct Server_ {
char *name;
struct Server_ *next;
struct sockaddr_storage ai_addr;
socklen_t ai_addrlen;
int ai_family;
unsigned int status;
int cleanup_fd;
struct event cleanup_ev;
} Server;
typedef struct Client_ {
char *header;
char *postbuf;
char *replybuf;
struct event client_read_ev;
struct event client_write_ev;
struct event server_read_ev;
struct event server_write_ev;
size_t header_len;
size_t postbuf_len;
size_t replybuf_len;
size_t header_written;
size_t postbuf_written;
size_t replybuf_written;
int client_fd;
int server_fd;
State state;
Server *server;
} Client;
void init_timeouts(void);
int setsockopt_aggressive(const int fd);
void socket_nonblock(const int fd);
int daemonize(void);
int update_pid_file(const char * const pid_file);
int delete_pid_file(void);
void server_send_header(int evfd, short event, void *client_);
void client_read_header(Client * const client);
void server_forward_request(int evfd, short event, void *client_);
void client_forward_request(Client * const client);
void server_forward_reply(int evfd, short event, void *client_);
void client_forward_reply(int evfd, short event, void *client_);
int connect_server(Client * const client);
void server_mark_failure(Client * const client);
void client_read(const int evfd, short event, void * const client_);
void client_disconnect(Client * const client);
int handle_timeout(const short event, Client * const client);
void new_client(const int listenfd, short event, void *ev_);
void periodic_cleanup(int dummy, const short event, void *ev);
int plb_open_log(const char * const log_file);
void plb_close_log(void);
void plb_log(const LogLevel level, const char * const fmt, ...)
__attribute__ ((format(printf, 2, 3)));
int plb_drop_caps(const char * const user, const char * const group,
const char * const emptydir);
#endif
syntax highlighted by Code2HTML, v. 0.9.1