/*
*
* transit.c
*
* Main routines
*
* Author: Landon Fuller <landonf@go2net.com>
*
* Copyright (c) 2000-2001 InfoSpace, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by InfoSpace, Inc.
* and its contributors.
* 4. Neither the name of InfoSpace, Inc nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "../autoconf.h"
#include <stdio.h>
#include <errno.h>
#include <syslog.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <memory.h>
#include <lber.h>
#include <ldap.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include "yp.h"
#ifdef HAVE_RPC_SVC_SOC_H
#include <rpc/svc_soc.h>
#endif
#include <rpc/pmap_clnt.h>
#include <rpcsvc/ypclnt.h>
#include "../lib/getopt.h"
#include "../include/config.h"
#include "../include/servconf.h"
#include "../include/transit.h"
#include "../include/modules.h"
#include "../include/log.h"
extern void ypprog_1 (struct svc_req *, register SVCXPRT *);
extern void ypprog_2 (struct svc_req *, register SVCXPRT *);
extern int children;
static void print_version (void)
{
printf ("%s (%s) Copyright (C) %s InfoSpace, Inc\n",
PROGNAME, VERSION, COPYDATE);
printf ("Written by %s\n", AUTHOR);
}
static void print_usage (FILE *stream)
{
fprintf (stream, "Usage: %s [-d domain] [--debug] [--version] [-f config file]\n",
PROGNAME);
}
static void print_help (void)
{
print_usage (stdout);
printf ("%s - NIS to LDAP gateway daemon\n",
PROGNAME);
printf (" -f config file Server config file\n");
printf (" -d domain NIS domain name\n");
printf (" --debug Do not fork\n");
printf (" --help Display this help list\n");
printf (" --version Display program version\n");
}
static void print_error (void)
{
print_usage (stderr);
fprintf (stderr, "Try `%s --help' or `%s --usage'\n",
PROGNAME, PROGNAME);
}
static void unregister (void)
{
#ifdef NISV1
(void) pmap_unset (YPPROG, YPOLDVERS);
#endif
(void) pmap_unset (YPPROG, YPVERS);
}
void fatal_cleanup (void)
{
unregister();
exit(1);
}
static void reaper(int signal)
{
int status;
if (signal == SIGCHLD)
{
while (wait4(-1, &status, WNOHANG, NULL) > 0)
children--;
} else {
fatal_cleanup();
}
return;
}
int main (int argc, char **argv)
{
int j;
register SVCXPRT *transp = NULL;
/* misc pref inits */
prefs.dflag = 0;
prefs.configfile = TRANSIT_CONFIG_FILE;
while(1)
{
int c;
int option_index = 0;
static struct option long_options[] =
{
{"debug", 0, NULL, '\255'},
{"usage", 0, NULL, '\254'},
{"help", 0, NULL, '\253'},
{"version", 0, NULL, '\252'},
{NULL, 0, NULL, '\0'}
};
c = getopt_long (argc, argv, "f:", long_options, &option_index);
if (c == (-1))
break;
switch (c)
{
case 'f':
prefs.configfile = optarg;
break;
case '\255':
prefs.dflag = 1;
break;
case '\254':
print_usage (stdout);
return 0;
case '\253':
print_help ();
return 0;
case '\252':
print_version ();
return 0;
default:
print_error ();
fatal_cleanup();
}
}
if (optind < argc)
{
print_usage (stderr);
fatal_cleanup();
}
/* init the config structure. */
init_server_config();
/* read in server configuration file, and set prefs.structure options */
read_server_config (prefs.configfile);
/* fill unset values with defaults, and fatal() on unset required values */
fill_server_config ();
modules_init(prefs.yp_modulelist);
/* this block of code forks the daemon, closes all fds
* and redirects stdin, stdout and stderr to /dev/null */
if (prefs.dflag != 1)
{
/* since we're forking, switch to syslog */
prefs.perr = 0;
if ((j = fork()) > 0)
exit (0);
if (j < 0)
{
log (LOG_ERR, "Fork failed: %s\n", strerror (errno));
exit (-1);
}
if (setsid() == -1)
{
log (LOG_ERR, "Setsid failed: %s\n", strerror (errno));
exit (-1);
}
if ((j = fork()) > 0)
exit (0);
if (j < 0)
{
log (LOG_ERR, "Fork failed: %s\n", strerror (errno));
exit (-1);
}
for (j = 0; j < getdtablesize(); ++j)
close (j);
errno = 0;
chdir("/");
umask(022);
j = open ("/dev/null", O_RDWR);
dup (j);
dup (j);
}
/* end of forking */
/* RPC code */
#ifdef NISV1
(void) pmap_unset (YPPROG, YPOLDVERS);
#endif
(void) pmap_unset(YPPROG, YPVERS);
transp = svcudp_create(RPC_ANYSOCK);
if (transp == NULL) {
fatal("cannot create udp service.\n");
}
#ifdef NISV1
if (!svc_register(transp, YPPROG, YPOLDVERS, ypprog_1, IPPROTO_UDP)) {
fatal("unable to register (YPPROG, YPOLDVERS, udp).\n");
}
#endif
if (!svc_register(transp, YPPROG, YPVERS, ypprog_2, IPPROTO_UDP)) {
fatal("unable to register (YPPROG, YPVERS, udp).\n");
}
transp = svctcp_create(RPC_ANYSOCK, 0, 0);
if (transp == NULL) {
fatal("cannot create tcp service.\n");
}
#ifdef NISV1
if (!svc_register(transp, YPPROG, YPOLDVERS, ypprog_1, IPPROTO_TCP)) {
fatal("unable to register (YPPROG, YPOLDVERS, tcp).\n");
}
#endif
if (!svc_register(transp, YPPROG, YPVERS, ypprog_2, IPPROTO_TCP)) {
fatal("unable to register (YPPROG, YPVERS, tcp).\n");
}
/*
* Make sure we survive a SIGPIPE
*/
(void) signal(SIGPIPE, SIG_IGN);
(void) signal(SIGTERM, (void *) fatal_cleanup);
(void) signal(SIGINT, (void *) fatal_cleanup);
(void) signal(SIGCHLD, reaper);
(void) signal(SIGHUP, SIG_IGN);
svc_run();
fprintf(stderr, "svc_run returned");
exit(1);
/* NOTREACHED */
}
syntax highlighted by Code2HTML, v. 0.9.1