/* * * transit.c * * Main routines * * Author: Landon Fuller * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "yp.h" #ifdef HAVE_RPC_SVC_SOC_H #include #endif #include #include #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 */ }