-/* $Log: secnet.c,v $
- * Revision 1.1 1996/03/13 22:27:41 sde1000
- * Initial revision
- *
- */
-
extern char version[];
#include "secnet.h"
#include "process.h"
/* XXX should be from autoconf */
-static char *configfile="/etc/secnet/secnet.conf";
+static const char *configfile="/etc/secnet/secnet.conf";
+static const char *sites_key="sites";
bool_t just_check_config=False;
static char *userid=NULL;
static uid_t uid=0;
bool_t background=True;
static char *pidfile=NULL;
bool_t require_root_privileges=False;
-string_t require_root_privileges_explanation=NULL;
+cstring_t require_root_privileges_explanation=NULL;
static pid_t secnet_pid;
void *state;
uint32_t max_nfds;
uint32_t nfds;
- string_t desc;
+ cstring_t desc;
struct poll_interest *next;
};
static struct poll_interest *reg=NULL;
{"debug", 1, 0, 'd'},
{"config", 1, 0, 'c'},
{"just-check-config", 0, 0, 'j'},
+ {"sites-key", 1, 0, 's'},
{0,0,0,0}
};
- c=getopt_long(argc, argv, "vwdnjc:ft:",
+ c=getopt_long(argc, argv, "vwdnjc:ft:s:",
long_options, &option_index);
if (c==-1)
break;
switch(c) {
case 2:
/* Help */
- fprintf(stderr,
- "Usage: secnet [OPTION]...\n\n"
- " -f, --silent, --quiet suppress error messages\n"
- " -w, --nowarnings suppress warnings\n"
- " -v, --verbose output extra diagnostics\n"
- " -c, --config=filename specify a configuration file\n"
- " -j, --just-check-config stop after reading configfile\n"
- " -n, --nodetach do not run in background\n"
- " -d, --debug=item,... set debug options\n"
- " --help display this help and exit\n"
- " --version output version information and exit\n"
+ printf("Usage: secnet [OPTION]...\n\n"
+ " -f, --silent, --quiet suppress error messages\n"
+ " -w, --nowarnings suppress warnings\n"
+ " -v, --verbose output extra diagnostics\n"
+ " -c, --config=filename specify a configuration file\n"
+ " -j, --just-check-config stop after reading "
+ "configuration file\n"
+ " -s, --sites-key=name configuration key that "
+ "specifies active sites\n"
+ " -n, --nodetach do not run in background\n"
+ " -d, --debug=item,... set debug options\n"
+ " --help display this help and exit\n"
+ " --version output version information "
+ "and exit\n"
);
exit(0);
break;
case 1:
/* Version */
- fprintf(stderr,"%s\n",version);
+ printf("%s\n",version);
exit(0);
break;
case 'v':
- message_level|=M_INFO|M_NOTICE|M_WARNING|M_ERROR|M_SECURITY|
+ message_level|=M_INFO|M_NOTICE|M_WARNING|M_ERR|M_SECURITY|
M_FATAL;
break;
just_check_config=True;
break;
+ case 's':
+ if (optarg)
+ sites_key=safe_strdup(optarg,"sites-key");
+ else
+ fatal("secnet: no sites key specified");
+ break;
+
case '?':
break;
default:
- Message(M_ERROR,"secnet: Unknown getopt code %c\n",c);
+ Message(M_ERR,"secnet: Unknown getopt code %c\n",c);
}
}
if (argc-optind != 0) {
- Message(M_ERROR,"secnet: You gave extra command line parameters, "
+ Message(M_ERR,"secnet: You gave extra command line parameters, "
"which were ignored.\n");
}
}
l=dict_lookup(config,"system");
if (!l || list_elem(l,0)->type!=t_dict) {
- fatal("configuration does not include a \"system\" dictionary\n");
+ fatal("configuration does not include a \"system\" dictionary");
}
system=list_elem(l,0)->data.dict;
loc=list_elem(l,0)->loc;
/* Arrange systemwide log facility */
l=dict_lookup(system,"log");
if (!l) {
- fatal("configuration does not include a system/log facility\n");
+ fatal("configuration does not include a system/log facility");
}
system_log=init_log(l);
} while(pw);
endpwent();
if (uid==0) {
- fatal("userid \"%s\" not found\n",userid);
+ fatal("userid \"%s\" not found",userid);
}
}
/* Check whether we need root privileges */
if (require_root_privileges && uid!=0) {
- fatal("the following configured feature (\"%s\") requires "
- "that secnet retain root privileges while running.\n",
+ fatal("the configured feature \"%s\" requires "
+ "that secnet retain root privileges while running.",
require_root_privileges_explanation);
}
/* Go along site list, starting sites */
- l=dict_lookup(config,"sites");
+ l=dict_lookup(config,sites_key);
if (!l) {
- Message(M_WARNING,"secnet: configuration did not define any "
- "remote sites\n");
+ Message(M_WARNING,"secnet: configuration key \"%s\" is missing; no "
+ "remote sites are defined\n",sites_key);
} else {
i=0;
while ((site=list_elem(l, i++))) {
}
void register_for_poll(void *st, beforepoll_fn *before,
- afterpoll_fn *after, uint32_t max_nfds, string_t desc)
+ afterpoll_fn *after, uint32_t max_nfds, cstring_t desc)
{
struct poll_interest *i;
int timeout;
struct pollfd *fds;
- fds=alloca(sizeof(*fds)*total_nfds);
- if (!fds) {
- fatal("run: couldn't alloca\n");
- }
+ fds=safe_malloc(sizeof(*fds)*total_nfds, "run");
Message(M_NOTICE,"%s [%d]: starting\n",version,secnet_pid);
if (gettimeofday(&tv_now, NULL)!=0) {
fatal_perror("main loop: gettimeofday");
}
- now=(tv_now.tv_sec*1000)+(tv_now.tv_usec/1000);
+ now=((uint64_t)tv_now.tv_sec*(uint64_t)1000)+
+ ((uint64_t)tv_now.tv_usec/(uint64_t)1000);
idx=0;
for (i=reg; i; i=i->next) {
i->after(i->state, fds+idx, i->nfds, &tv_now, &now);
if (rv!=0) {
/* XXX we need to handle this properly: increase the
nfds available */
- fatal("run: beforepoll_fn (%s) returns %d\n",i->desc,rv);
+ fatal("run: beforepoll_fn (%s) returns %d",i->desc,rv);
}
if (timeout<-1) {
- fatal("run: beforepoll_fn (%s) set timeout to %d\n",timeout);
+ fatal("run: beforepoll_fn (%s) set timeout to %d",timeout);
}
idx+=nfds;
remain-=nfds;
}
} while (rv<0);
} while (!finished);
+ free(fds);
}
static void droppriv(void)
{
FILE *pf=NULL;
pid_t p;
+ int errfds[2];
add_hook(PHASE_SHUTDOWN,system_phase_hook,NULL);
} else if (p==0) {
/* Child process - all done, just carry on */
if (pf) fclose(pf);
- /* Close stdin, stdout and stderr; we don't need them any more */
+ /* Close stdin and stdout; we don't need them any more.
+ stderr is redirected to the system/log facility */
+ if (pipe(errfds)!=0) {
+ fatal_perror("can't create pipe for stderr");
+ }
close(0);
close(1);
close(2);
+ dup2(errfds[1],0);
+ dup2(errfds[1],1);
+ dup2(errfds[1],2);
secnet_is_daemon=True;
+ setsid();
+ log_from_fd(errfds[0],"stderr",system_log);
} else {
/* Error */
fatal_perror("cannot fork");
droppriv();
start_signal_handling();
- request_signal_notification(SIGTERM,finish,"SIGTERM");
- if (!background) request_signal_notification(SIGINT,finish,"SIGINT");
+ request_signal_notification(SIGTERM,finish,safe_strdup("SIGTERM","run"));
+ if (!background) request_signal_notification(SIGINT,finish,
+ safe_strdup("SIGINT","run"));
request_signal_notification(SIGHUP,ignore_hup,NULL);
enter_phase(PHASE_RUN);
run();