/* This file is part of Pies.
Copyright (C) 2008, 2009 Sergey Poznyakoff
Pies is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
Pies is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Pies. If not, see . */
#ifdef HAVE_CONFIG_H
# include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "progname.h"
#include "inttostr.h"
#include "c-ctype.h"
#include "xalloc.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
#include "obstack.h"
#include "xvasprintf.h"
#include "acl.h"
#include "libpies.h"
#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
#define TESTTIME 2*60
#define SLEEPTIME 5*60
#define MAXSPAWN 10
#define DEFAULT_PASS_FD_TIMEOUT 5
#define RETR_OUT 0
#define RETR_ERR 1
enum redir_type
{
redir_null,
redir_syslog,
redir_file
};
struct redirector
{
enum redir_type type;
union
{
int prio;
char *file;
} v;
};
typedef struct limits_rec *limits_record_t;
enum return_action
{
action_restart,
action_disable,
};
#define STATUS_SIG_BIT 0x80000000
#define STATUS_CODE(c) ((c) & ~STATUS_SIG_BIT)
struct action
{
struct action *next;
size_t nstat;
unsigned *status;
enum return_action act; /* Action to take when the component terminates */
char *addr; /* Addresses to notify about it. */
char *message; /* Notification mail. */
char *command; /* Execute this command */
};
/* user privs */
struct pies_privs
{
char *user;
int allgroups;
gl_list_t groups;
};
enum pies_comp_mode
{
/* Execute the component, no sockets are opened. This is the default
Pies mode. */
pies_comp_exec,
/* Open a socket and start a component with stdin/stdout bound to that
socket. Corresponds to MeTA1 notion of `start_action = accept'.
*/
pies_comp_accept,
/* Inetd mode: like above, but start the component only when an
incoming connection is requested. Corresponds to
`start_action = nostartaccept' in MeTA1.
*/
pies_comp_inetd,
/* Open a socket, start a component, and pass the socket fd to the
component via the UNIX domain socket. Corresponds to
`start_action = pass' in MeTA1. */
pies_comp_pass_fd
};
struct component
{
enum pies_comp_mode mode;
char *tag; /* Entry tag (for diagnostics purposes) */
char *program; /* Program name */
char **argv; /* Program command line */
char **env; /* Program environment */
char *dir; /* Working directory */
gl_list_t prereq; /* Prerequisites */
gl_list_t depend; /* Dependency targets */
/* FIXME: disabled and precious can be encoded as bits in mode */
int disabled; /* The componenet is disabled */
int precious; /* The component is precious (cannot be disabled) */
char *rmfile; /* Try to remove this file before starting */
struct pies_privs privs; /* UID/GIDS+groups to run under */
mode_t umask; /* Umask to install before starting */
limits_record_t limits; /* System limits */
struct pies_url *socket_url; /* Socket to listen on
(if mode != pies_comp_exec) */
char *pass_fd_socket; /* Socket to pass fd on
(if mode == pies_comp_pass_fd) */
unsigned pass_fd_timeout; /* Maximum time to wait for pass_fd socket to
become available. */
pies_acl_t acl;
/* Redirectors: */
int facility; /* Syslog facility. */
struct redirector redir[2]; /* Repeaters for stdout and stderr */
/* Actions to execute on various exit codes: */
struct action *act_head, *act_tail;
struct action act_temp; /* Auxiliary object used during configuration */
};
extern int log_to_stderr;
extern char *log_tag;
extern int log_facility;
extern unsigned long shutdown_timeout;
extern struct component default_component;
extern pies_acl_t pies_acl;
extern limits_record_t pies_limits;
extern char *mailer_program;
extern char *mailer_command_line;
extern int mailer_argc;
extern char **mailer_argv;
void register_prog (struct component *comp);
size_t progman_running_count (void);
void progman_start (void);
void progman_wake_sleeping (void);
void progman_stop (void);
void progman_cleanup (int expect_term);
void progman_stop_component (const char *name);
void progman_dump_stats (const char *filename);
void progman_dump_prereq (void);
void progman_dump_depmap (void);
int progman_accept (int socket);
int progman_build_depmap (void);
void progman_create_sockets (void);
struct component *progman_lookup_component (const char *tag);
void log_setup (int want_stderr);
void signal_setup (RETSIGTYPE (*sf)(int));
typedef struct pies_depmap *pies_depmap_t;
typedef struct pies_depmap_pos *pies_depmap_pos_t;
enum pies_depmap_direction
{
depmap_row = 0,
depmap_col = !depmap_row
};
pies_depmap_t depmap_alloc (unsigned count);
pies_depmap_t depmap_copy (pies_depmap_t dpm);
void depmap_set (pies_depmap_t dmap, unsigned row, unsigned col);
int depmap_isset (pies_depmap_t dmap, unsigned row, unsigned col);
void depmap_tc (pies_depmap_t dmap);
unsigned depmap_first (pies_depmap_t dmap, enum pies_depmap_direction dir,
unsigned coord, pies_depmap_pos_t *ppos);
unsigned depmap_next (pies_depmap_t dmap, pies_depmap_pos_t pos);
int assert_grecs_value_type (grecs_locus_t *locus,
const grecs_value_t *value, int type);
struct component *component_create (const char *name);
void component_finish (struct component *comp, grecs_locus_t *locus);
struct grecs_keyword *find_component_keyword (const char *ident);
/* url.c */
struct pies_url
{
char *string;
char *proto;
char *host;
int port;
char *path;
char *user;
char *passwd;
int argc;
char **argv;
};
int pies_url_create (struct pies_url **purl, const char *str);
void pies_url_destroy (struct pies_url **purl);
const char * pies_url_get_arg (struct pies_url *url, const char *argname);
void pies_pause (void);
int register_listener (int fd);
int pass_fd (const char *socket, int fd, unsigned time_out);
int create_socket (struct pies_url *url, const char *user, mode_t umask);
int parse_limits (limits_record_t *plrec, char *str, char **endp);
int set_limits (const char *name, limits_record_t lrec);
void meta1_parser_set_debug (void);
int meta1lex (void);
int meta1error (char *s);
int meta1parse (void);
void logmsg (int prio, const char *fmt, ...);
void logmsg_printf (int prio, const char *fmt, ...);
void logmsg_vprintf (int prio, const char *fmt, va_list ap);
extern unsigned debug_level;
extern int source_info_option;
void debug_msg (const char *fmt, ...);
#define debug(lev, args) \
do \
if (debug_level >= lev) \
{ \
if (source_info_option) \
logmsg_printf (LOG_DEBUG, "%s:%lu:%s: ", \
__FILE__, __LINE__, __FUNCTION__); \
debug_msg args; \
} \
while (0)
/* meta.c */
struct metadef
{
char *kw;
char *value;
const char *(*expand) (struct metadef *, void *);
char *storage;
void *data;
};
char *meta_expand_string (const char *string, struct metadef *def, void *data);
void meta_free (struct metadef *def);
/* addrfmt.c */
void sockaddr_to_str (const struct sockaddr *sa, int salen,
char *bufptr, size_t buflen,
size_t *plen);
char *sockaddr_to_astr (const struct sockaddr *sa, int salen);
/* userprivs.c */
int switch_to_privs (uid_t uid, gid_t gid, gl_list_t retain_groups);
void pies_priv_setup (struct pies_privs *);
void pies_epriv_setup (struct pies_privs *);