예제 #1
0
파일: daemon.c 프로젝트: InCNTRE/OFTT
/* If daemonization is configured, then starts daemonization, by forking and
 * returning in the child process.  The parent process hangs around until the
 * child lets it know either that it completed startup successfully (by calling
 * daemon_complete()) or that it failed to start up (by exiting with a nonzero
 * exit code). */
void
daemonize_start(void)
{
    daemonize_fd = -1;

    if (detach) {
        if (fork_and_wait_for_startup(&daemonize_fd) > 0) {
            /* Running in parent process. */
            exit(0);
        }
        /* Running in daemon or monitor process. */
    }

    if (monitor) {
        int saved_daemonize_fd = daemonize_fd;
        pid_t daemon_pid;

        daemon_pid = fork_and_wait_for_startup(&daemonize_fd);
        if (daemon_pid > 0) {
            /* Running in monitor process. */
            fork_notify_startup(saved_daemonize_fd);
            close_standard_fds();
            monitor_daemon(daemon_pid);
        }
        /* Running in daemon process. */
    }

    make_pidfile();

    /* Make sure that the unixctl commands for vlog get registered in a
     * daemon, even before the first log message. */
    vlog_init();
}
예제 #2
0
/* If daemonization is configured, then starts daemonization, by forking and
 * returning in the child process.  The parent process hangs around until the
 * child lets it know either that it completed startup successfully (by calling
 * daemon_complete()) or that it failed to start up (by exiting with a nonzero
 * exit code). */
void
daemonize_start(bool access_datapath)
{
    assert_single_threaded();
    daemonize_fd = -1;

    if (switch_user) {
        daemon_become_new_user__(access_datapath);
        switch_user = false;
    }

    if (detach) {
        pid_t pid;

        if (fork_and_wait_for_startup(&daemonize_fd, &pid)) {
            VLOG_FATAL("could not detach from foreground session");
        }
        if (pid > 0) {
            /* Running in parent process. */
            exit(0);
        }

        /* Running in daemon or monitor process. */
        setsid();
    }

    if (monitor) {
        int saved_daemonize_fd = daemonize_fd;
        pid_t daemon_pid;

        if (fork_and_wait_for_startup(&daemonize_fd, &daemon_pid)) {
            VLOG_FATAL("could not initiate process monitoring");
        }
        if (daemon_pid > 0) {
            /* Running in monitor process. */
            fork_notify_startup(saved_daemonize_fd);
            if (detach) {
                close_standard_fds();
            }
            monitor_daemon(daemon_pid);
        }
        /* Running in daemon process. */
    }

    forbid_forking("running in daemon process");

    if (pidfile) {
        make_pidfile();
    }

    /* Make sure that the unixctl commands for vlog get registered in a
     * daemon, even before the first log message. */
    vlog_init();
}
예제 #3
0
/* If configured with set_pidfile() or set_detach(), creates the pid file and
 * detaches from the foreground session.  */
void
daemonize(void)
{
    if (detach) {
        char c = 0;
        int fds[2];
        if (pipe(fds) < 0) {
            ofp_fatal(errno, "pipe failed");
        }

        switch (fork()) {
        default:
            /* Parent process: wait for child to create pidfile, then exit. */
            close(fds[1]);
            fatal_signal_fork();
            if (read(fds[0], &c, 1) != 1) {
                ofp_fatal(errno, "daemon child failed to signal startup");
            }
            exit(0);

        case 0:
            /* Child process. */
            close(fds[0]);
            make_pidfile();
            write(fds[1], &c, 1);
            close(fds[1]);
            setsid();
            chdir("/");
            break;

        case -1:
            /* Error. */
            ofp_fatal(errno, "could not fork");
            break;
        }
    } else {
        make_pidfile();
    }
}
예제 #4
0
/* main() for udpxrec module
 */
int udpxrec_main( int argc, char* const argv[] )
{
    int rc = 0, ch = 0, custom_log = 0, no_daemon = 0;
    static const char OPTMASK[] = "vb:e:M:p:B:n:m:l:c:R:u:T";
    time_t now = time(NULL);
    char now_buf[ 32 ] = {0}, sel_buf[ 32 ] = {0}, app_finfo[80] = {0};

    extern int optind, optopt;
    extern const char IPv4_ALL[];

    mk_app_info(g_udpxrec_app, g_app_info, sizeof(g_app_info) - 1);

    if( argc < 2 ) {
        usage( argv[0], stderr );
        return ERR_PARAM;
    }

    rc = init_recopt( &g_recopt );
    while( (0 == rc) && (-1 != (ch = getopt( argc, argv, OPTMASK ))) ) {
        switch(ch) {
            case 'T':   no_daemon = 1; break;
            case 'v':   set_verbose( &g_recopt.is_verbose ); break;
            case 'b':
                        if( (time_t)0 != g_recopt.end_time ) {
                            (void) fprintf( stderr, "Cannot specify start-recording "
                                    "time after end-recording time has been set\n" );
                        }

                        rc = a2time( optarg, &g_recopt.bg_time, time(NULL) );
                        if( 0 != rc ) {
                            (void) fprintf( stderr, "Invalid time: [%s]\n", optarg );
                            rc = ERR_PARAM;
                        }
                        else {
                            if( g_recopt.bg_time < now ) {
                                (void)strncpy( now_buf, Zasctime(localtime( &now )),
                                        sizeof(now_buf) );
                                (void)strncpy( sel_buf,
                                        Zasctime(localtime( &g_recopt.bg_time )),
                                        sizeof(sel_buf) );

                                (void) fprintf( stderr,
                                        "Selected %s time is in the past, "
                                        "now=[%s], selected=[%s]\n", "start",
                                        now_buf, sel_buf );
                                rc = ERR_PARAM;
                            }
                        }

                        break;
            case 'e':
                        if( (time_t)0 == g_recopt.bg_time ) {
                            g_recopt.bg_time = time(NULL);
                            (void)fprintf( stderr,
                                    "Start-recording time defaults to now [%s]\n",
                                    Zasctime( localtime( &g_recopt.bg_time ) ) );
                        }

                        rc = a2time( optarg, &g_recopt.end_time, g_recopt.bg_time );
                        if( 0 != rc ) {
                            (void) fprintf( stderr, "Invalid time: [%s]\n", optarg );
                            rc = ERR_PARAM;
                        }
                        else {
                            if( g_recopt.end_time < now ) {
                                (void)strncpy( now_buf, Zasctime(localtime( &now )),
                                        sizeof(now_buf) );
                                (void)strncpy( sel_buf,
                                        Zasctime(localtime( &g_recopt.end_time )),
                                        sizeof(sel_buf) );

                                (void) fprintf( stderr,
                                        "Selected %s time is in the past, "
                                        "now=[%s], selected=[%s]\n", "end",
                                        now_buf, sel_buf );
                                rc = ERR_PARAM;
                            }
                        }
                        break;

            case 'M':
                        rc = a2int64( optarg, &g_recopt.max_fsize );
                        if( 0 != rc ) {
                            (void) fprintf( stderr, "Invalid file size: [%s]\n",
                                    optarg );
                            rc = ERR_PARAM;
                        }
                        break;
            case 'p':
                        g_recopt.pidfile = strdup(optarg);
                        break;

            case 'B':
                        rc = a2size( optarg, &g_recopt.bufsize );
                        if( 0 != rc ) {
                            (void) fprintf( stderr, "Invalid buffer size: [%s]\n",
                                    optarg );
                            rc = ERR_PARAM;
                        }
                        else if( (g_recopt.bufsize < MIN_MCACHE_LEN) ||
                                 (g_recopt.bufsize > MAX_MCACHE_LEN)) {
                            (void) fprintf( stderr,
                                "Buffer size must be in [%ld-%ld] bytes range\n",
                                (long)MIN_MCACHE_LEN, (long)MAX_MCACHE_LEN );
                            rc = ERR_PARAM;
                        }

                        break;
            case 'n':
                      g_recopt.nice_incr = atoi( optarg );
                      if( 0 == g_recopt.nice_incr ) {
                        (void) fprintf( stderr,
                            "Invalid nice-value increment: [%s]\n", optarg );
                        rc = ERR_PARAM;
                      }
                      break;
            case 'm':
                      rc = get_ipv4_address( optarg, g_recopt.mcast_addr,
                              sizeof(g_recopt.mcast_addr) );
                      if( 0 != rc ) {
                        (void) fprintf( stderr, "Invalid multicast address: [%s]\n",
                                        optarg );
                          rc = ERR_PARAM;
                      }
                      break;
            case 'l':
                      g_flog = fopen( optarg, "a" );
                      if( NULL == g_flog ) {
                        rc = errno;
                        (void) fprintf( stderr, "Error opening logfile [%s]: %s\n",
                                optarg, strerror(rc) );
                        rc = ERR_PARAM; break;
                      }

                      Setlinebuf( g_flog );
                      custom_log = 1;
                      break;

            case 'c':
                      rc = get_addrport( optarg, g_recopt.rec_channel,
                                         sizeof( g_recopt.rec_channel ),
                                         &g_recopt.rec_port );
                      if( 0 != rc ) rc = ERR_PARAM;
                      break;

            case 'R':
                      g_recopt.rbuf_msgs = atoi( optarg );
                      if( (g_recopt.rbuf_msgs <= 0) && (-1 != g_recopt.rbuf_msgs) ) {
                        (void) fprintf( stderr,
                                "Invalid rcache size: [%s]\n", optarg );
                        rc = ERR_PARAM;
                      }
                      break;

            case 'u':
                      g_recopt.waitupd_sec = atoi(optarg);
                      if( g_recopt.waitupd_sec <= 0 ) {
                          (void) fprintf( stderr, "Invalid wait-update value [%s] "
                                  "(must be a number > 0)\n", optarg );
                          rc = ERR_PARAM;
                      }
                      break;

            case ':':
                      (void) fprintf( stderr, "Option [-%c] requires an argument\n",
                              optopt );
                      rc = ERR_PARAM; break;
            case '?':
                      (void) fprintf( stderr, "Unrecognized option: [-%c]\n", optopt );
                      rc = ERR_PARAM; break;
            default:
                      usage( argv[0], stderr );
                      rc = ERR_PARAM; break;

        } /* switch */
    } /* while getopt */

    if( 0 == rc ) {
        if( optind >= argc ) {
            (void) fputs( "Missing destination file parameter\n", stderr );
            rc = ERR_PARAM;
        }
        else {
            g_recopt.dstfile = strdup( argv[optind] );
        }

        if( !(g_recopt.max_fsize > 0 || g_recopt.end_time)  ) {
            (void) fputs( "Must specify either max file [-M] size "
                    "or end time [-e]\n", stderr );
            rc = ERR_PARAM;
        }

        if( !g_recopt.rec_channel[0] || !g_recopt.rec_port ) {
            (void) fputs( "Must specify multicast channel to record from\n",
                    stderr );
            rc = ERR_PARAM;
        }
    }

    if( rc ) {
        free_recopt( &g_recopt );
        return rc;
    }

    do {
        if( '\0' == g_recopt.mcast_addr[0] ) {
            (void) strncpy( g_recopt.mcast_addr, IPv4_ALL,
                    sizeof(g_recopt.mcast_addr) - 1 );
        }

        if( !custom_log ) {
            /* in debug mode output goes to stderr, otherwise to /dev/null */
            g_flog = ((uf_TRUE == g_recopt.is_verbose)
                    ? stderr
                    : fopen( "/dev/null", "a" ));
            if( NULL == g_flog ) {
                perror("fopen");
                rc = ERR_INTERNAL; break;
            }
        }

        if( 0 == geteuid() ) {
            if( !no_daemon ) {
                if( stderr == g_flog ) {
                    (void) fprintf( stderr,
                        "Logfile must be specified to run "
                        "in verbose mode in background\n" );
                    rc = ERR_PARAM; break;
                }

                if( NULL == g_recopt.pidfile ) {
                    (void) fprintf( stderr, "pidfile must be specified "
                            "to run as daemon\n" );
                    rc = ERR_PARAM; break;
                }

                if( 0 != (rc = daemonize(0, g_flog)) ) {
                    rc = ERR_INTERNAL; break;
                }
            }

        } /* 0 == geteuid() */

        if( NULL != g_recopt.pidfile ) {
            rc = make_pidfile( g_recopt.pidfile, getpid(), g_flog );
            if( 0 != rc ) break;
        }

        (void) set_nice( g_recopt.nice_incr, g_flog );

        if( 0 != (rc = setup_signals()) ) break;

        TRACE( fprint_recopt( g_flog, &g_recopt ) );

        TRACE( printcmdln( g_flog, g_app_info, argc, argv ) );

        if( g_recopt.bg_time ) {
            if( 0 != (rc = verify_channel()) || g_quit )
                break;

            rc = wait_till( g_recopt.bg_time, g_recopt.waitupd_sec );
            if( rc || g_quit ) break;
        }

        rc = record();

        if( NULL != g_recopt.pidfile ) {
            if( -1 == unlink(g_recopt.pidfile) ) {
                mperror( g_flog, errno, "unlink [%s]", g_recopt.pidfile );
            }
        }
    }
    while(0);

    if( g_flog ) {
        (void)tmfprintf( g_flog, "%s is exiting with rc=[%d]\n",
                app_finfo, rc );
    }

    if( g_flog && (stderr != g_flog) ) {
        (void) fclose(g_flog);
    }

    free_recopt( &g_recopt );

    return rc;
}
예제 #5
0
파일: mdmon.c 프로젝트: DanielRussell/mdadm
static int mdmon(char *devnm, int must_fork, int takeover)
{
	int mdfd;
	struct mdinfo *mdi, *di;
	struct supertype *container;
	sigset_t set;
	struct sigaction act;
	int pfd[2];
	int status;
	int ignore;
	pid_t victim = -1;
	int victim_sock = -1;

	dprintf("starting mdmon for %s\n", devnm);

	mdfd = open_dev(devnm);
	if (mdfd < 0) {
		pr_err("%s: %s\n", devnm, strerror(errno));
		return 1;
	}
	if (md_get_version(mdfd) < 0) {
		pr_err("%s: Not an md device\n", devnm);
		return 1;
	}

	/* Fork, and have the child tell us when they are ready */
	if (must_fork) {
		if (pipe(pfd) != 0) {
			pr_err("failed to create pipe\n");
			return 1;
		}
		switch(fork()) {
		case -1:
			pr_err("failed to fork: %s\n", strerror(errno));
			return 1;
		case 0: /* child */
			close(pfd[0]);
			break;
		default: /* parent */
			close(pfd[1]);
			if (read(pfd[0], &status, sizeof(status)) != sizeof(status)) {
				wait(&status);
				status = WEXITSTATUS(status);
			}
			close(pfd[0]);
			return status;
		}
	} else
		pfd[0] = pfd[1] = -1;

	container = xcalloc(1, sizeof(*container));
	strcpy(container->devnm, devnm);
	container->arrays = NULL;
	container->sock = -1;

	mdi = sysfs_read(mdfd, container->devnm, GET_VERSION|GET_LEVEL|GET_DEVS);

	if (!mdi) {
		pr_err("failed to load sysfs info for %s\n", container->devnm);
		exit(3);
	}
	if (mdi->array.level != UnSet) {
		pr_err("%s is not a container - cannot monitor\n", devnm);
		exit(3);
	}
	if (mdi->array.major_version != -1 ||
	    mdi->array.minor_version != -2) {
		pr_err("%s does not use external metadata - cannot monitor\n",
			devnm);
		exit(3);
	}

	container->ss = version_to_superswitch(mdi->text_version);
	if (container->ss == NULL) {
		pr_err("%s uses unsupported metadata: %s\n",
			devnm, mdi->text_version);
		exit(3);
	}

	container->devs = NULL;
	for (di = mdi->devs; di; di = di->next) {
		struct mdinfo *cd = xmalloc(sizeof(*cd));
		*cd = *di;
		cd->next = container->devs;
		container->devs = cd;
	}
	sysfs_free(mdi);

	/* SIGUSR is sent between parent and child.  So both block it
	 * and enable it only with pselect.
	 */
	sigemptyset(&set);
	sigaddset(&set, SIGUSR1);
	sigaddset(&set, SIGTERM);
	sigprocmask(SIG_BLOCK, &set, NULL);
	act.sa_handler = wake_me;
	act.sa_flags = 0;
	sigaction(SIGUSR1, &act, NULL);
	act.sa_handler = term;
	sigaction(SIGTERM, &act, NULL);
	act.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &act, NULL);

	victim = mdmon_pid(container->devnm);
	if (victim >= 0)
		victim_sock = connect_monitor(container->devnm);

	ignore = chdir("/");
	if (!takeover && victim > 0 && victim_sock >= 0) {
		if (fping_monitor(victim_sock) == 0) {
			pr_err("%s already managed\n", container->devnm);
			exit(3);
		}
		close(victim_sock);
		victim_sock = -1;
	}
	if (container->ss->load_container(container, mdfd, devnm)) {
		pr_err("Cannot load metadata for %s\n", devnm);
		exit(3);
	}
	close(mdfd);

	/* Ok, this is close enough.  We can say goodbye to our parent now.
	 */
	if (victim > 0)
		remove_pidfile(devnm);
	if (make_pidfile(devnm) < 0) {
		exit(3);
	}
	container->sock = make_control_sock(devnm);

	status = 0;
	if (pfd[1] >= 0) {
		if (write(pfd[1], &status, sizeof(status)) < 0)
			pr_err("failed to notify our parent: %d\n",
			       getppid());
		close(pfd[1]);
	}

	mlockall(MCL_CURRENT | MCL_FUTURE);

	if (clone_monitor(container) < 0) {
		pr_err("failed to start monitor process: %s\n",
			strerror(errno));
		exit(2);
	}

	if (victim > 0) {
		try_kill_monitor(victim, container->devnm, victim_sock);
		if (victim_sock >= 0)
			close(victim_sock);
	}

	setsid();
	close(0);
	open("/dev/null", O_RDWR);
	close(1);
	ignore = dup(0);
#ifndef DEBUG
	close(2);
	ignore = dup(0);
#endif

	/* This silliness is to stop the compiler complaining
	 * that we ignore 'ignore'
	 */
	if (ignore)
		ignore++;

	do_manager(container);

	exit(0);
}
예제 #6
0
파일: udpxy.c 프로젝트: avble/udpxy
int
udpxy_main( int argc, char* const argv[] )
{
    int rc = 0, ch = 0, port = -1,
        custom_log = 0, no_daemon = 0;

    char ipaddr[IPADDR_STR_SIZE] = "\0",
         mcast_addr[IPADDR_STR_SIZE] = "\0";

    char pidfile[ MAXPATHLEN ] = "\0";
    u_short MIN_MCAST_REFRESH = 0, MAX_MCAST_REFRESH = 0;

/* support for -r -w (file read/write) option is disabled by default;
 * those features are experimental and for dev debugging ONLY
 * */
#ifdef UDPXY_FILEIO
    static const char UDPXY_OPTMASK[] = "TvSa:l:p:m:c:B:n:R:r:w:H:M:";
#else
    static const char UDPXY_OPTMASK[] = "TvSa:l:p:m:c:B:n:R:H:M:";
#endif

    struct sigaction qact, iact, cact, oldact;

    init_app_info();
    (void) get_pidstr( PID_RESET, "S" );

    rc = init_uopt( &g_uopt );
    while( (0 == rc) && (-1 != (ch = getopt(argc, argv, UDPXY_OPTMASK))) ) {
        switch( ch ) {
            case 'v': set_verbose( &g_uopt.is_verbose );
                      break;
            case 'T': no_daemon = 1;
                      break;
            case 'S': g_uopt.cl_tpstat = uf_TRUE;
                      break;
            case 'a':
                      rc = get_ipv4_address( optarg, ipaddr, sizeof(ipaddr) );
                      if( 0 != rc ) {
                        (void) fprintf( stderr, "Invalid address: [%s]\n",
                                        optarg );
                          rc = ERR_PARAM;
                      }
                      break;

            case 'p':
                      port = atoi( optarg );
                      if( port <= 0 ) {
                        (void) fprintf( stderr, "Invalid port number: [%d]\n",
                                        port );
                        rc = ERR_PARAM;
                      }
                      break;

            case 'm':
                      rc = get_ipv4_address( optarg, mcast_addr,
                              sizeof(mcast_addr) );
                      if( 0 != rc ) {
                        (void) fprintf( stderr, "Invalid multicast address: "
                                "[%s]\n", optarg );
                          rc = ERR_PARAM;
                      }
                      break;

            case 'c':
                      g_uopt.max_clients = atoi( optarg );
                      if( (g_uopt.max_clients < MIN_CLIENT_COUNT) ||
                          (g_uopt.max_clients > MAX_CLIENT_COUNT) ) {
                        (void) fprintf( stderr,
                                "Client count should be between %d and %d\n",
                                MIN_CLIENT_COUNT, MAX_CLIENT_COUNT );
                        rc = ERR_PARAM;
                      }
                      break;

            case 'l':
                      g_flog = fopen( optarg, "a" );
                      if( NULL == g_flog ) {
                        rc = errno;
                        (void) fprintf( stderr, "Error opening logfile "
                                "[%s]: %s\n",
                                optarg, strerror(rc) );
                        rc = ERR_PARAM;
                        break;
                      }

                      Setlinebuf( g_flog );
                      custom_log = 1;
                      break;

            case 'B':
                      rc = a2size(optarg, &g_uopt.rbuf_len);
                      if( 0 != rc ) {
                            (void) fprintf( stderr, "Invalid buffer size: [%s]\n",
                                    optarg );
                            exit( ERR_PARAM );
                      }
                      else if( (g_uopt.rbuf_len < MIN_MCACHE_LEN) ||
                          (g_uopt.rbuf_len > MAX_MCACHE_LEN) ) {
                        fprintf(stderr, "Buffer size "
                                "must be within [%ld-%ld] bytes\n",
                                (long)MIN_MCACHE_LEN, (long)MAX_MCACHE_LEN );
                        rc = ERR_PARAM;
                      }
                      break;

            case 'n':
                      g_uopt.nice_incr = atoi( optarg );
                      if( 0 == g_uopt.nice_incr ) {
                        (void) fprintf( stderr,
                            "Invalid nice-value increment: [%s]\n", optarg );
                        rc = ERR_PARAM;
                        break;
                      }
                      break;

            case 'R':
                      g_uopt.rbuf_msgs = atoi( optarg );
                      if( (g_uopt.rbuf_msgs <= 0) && (-1 != g_uopt.rbuf_msgs) ) {
                        (void) fprintf( stderr,
                                "Invalid Rmsgs size: [%s]\n", optarg );
                        rc = ERR_PARAM;
                        break;
                      }
                      break;

            case 'H':
                      g_uopt.dhold_tmout = (time_t)atoi( optarg );
                      if( (0 == g_uopt.dhold_tmout) ||
                          ((g_uopt.dhold_tmout) < 0 && (-1 != g_uopt.dhold_tmout)) ) {
                        (void) fprintf( stderr, "Invalid value for max time "
                                "to hold buffered data: [%s]\n", optarg );
                        rc = ERR_PARAM;
                        break;
                      }
                      break;

    #ifdef UDPXY_FILEIO
            case 'r':
                      if( 0 != access(optarg, R_OK) ) {
                        perror("source file - access");
                        rc = ERR_PARAM;
                        break;
                      }

                      g_uopt.srcfile = strdup( optarg );
                      break;

            case 'w':
                      g_uopt.dstfile = strdup( optarg );
                      break;
    #endif /* UDPXY_FILEIO */
            case 'M':
                      g_uopt.mcast_refresh = (u_short)atoi( optarg );

                      MIN_MCAST_REFRESH = 30;
                      MAX_MCAST_REFRESH = 64000;
                      if( g_uopt.mcast_refresh &&
                         (g_uopt.mcast_refresh < MIN_MCAST_REFRESH ||
                          g_uopt.mcast_refresh > MAX_MCAST_REFRESH )) {
                            (void) fprintf( stderr, 
                                "Invalid multicast refresh period [%d] seconds, "
                                "min=[%d] sec, max=[%d] sec\n",
                                (int)g_uopt.mcast_refresh,
                                (int)MIN_MCAST_REFRESH, (int)MAX_MCAST_REFRESH );
                            rc = ERR_PARAM;
                            break;
                       }
                      break;

            case ':':
                      (void) fprintf( stderr,
                              "Option [-%c] requires an argument\n",
                                    optopt );
                      rc = ERR_PARAM;
                      break;
            case '?':
                      (void) fprintf( stderr,
                              "Unrecognized option: [-%c]\n", optopt );
                      rc = ERR_PARAM;
                      break;

            default:
                     usage( argv[0], stderr );
                     rc = ERR_PARAM;
                     break;
        }
    } /* while getopt */

    if (rc) {
        free_uopt( &g_uopt );
        return rc;
    }

    openlog( g_udpxy_app, LOG_CONS | LOG_PID, LOG_LOCAL0 );

    do {
        if( (argc < 2) || (port <= 0) || (rc != 0) ) {
            usage( argv[0], stderr );
            rc = ERR_PARAM; break;
        }

        if( '\0' == mcast_addr[0] ) {
            (void) strncpy( mcast_addr, IPv4_ALL, sizeof(mcast_addr) - 1 );
        }

        if( !custom_log ) {
            /* in debug mode output goes to stderr, otherwise to /dev/null */
            g_flog = ((uf_TRUE == g_uopt.is_verbose)
                    ? stderr
                    : fopen( "/dev/null", "a" ));
            if( NULL == g_flog ) {
                perror("fopen");
                rc = ERR_INTERNAL; break;
            }
        }

        if( 0 == geteuid() ) {
            if( !no_daemon ) {
                if( stderr == g_flog ) {
                    (void) fprintf( stderr,
                        "Logfile must be specified to run "
                        "in verbose mode in background\n" );
                    rc = ERR_PARAM; break;
                }

                if( 0 != (rc = daemonize(0, g_flog)) ) {
                    rc = ERR_INTERNAL; break;
                }
            }

            rc = set_pidfile( g_udpxy_app, port, pidfile, sizeof(pidfile) );
            if( 0 != rc ) {
                mperror( g_flog, errno, "set_pidfile" );
                rc = ERR_INTERNAL; break;
            }

            if( 0 != (rc = make_pidfile( pidfile, getpid(), g_flog )) )
                break;
        }

        qact.sa_handler = handle_quitsigs;
        sigemptyset(&qact.sa_mask);
        qact.sa_flags = 0;

        if( (sigaction(SIGTERM, &qact, &oldact) < 0) ||
            (sigaction(SIGQUIT, &qact, &oldact) < 0) ||
            (sigaction(SIGINT,  &qact, &oldact) < 0)) {
            perror("sigaction-quit");
            rc = ERR_INTERNAL; break;
        }

        iact.sa_handler = SIG_IGN;
        sigemptyset(&iact.sa_mask);
        iact.sa_flags = 0;

        if( (sigaction(SIGPIPE, &iact, &oldact) < 0) ) {
            perror("sigaction-ignore");
            rc = ERR_INTERNAL; break;
        }

        cact.sa_handler = handle_sigchld;
        sigemptyset(&cact.sa_mask);
        cact.sa_flags = 0;

        if( sigaction(SIGCHLD, &cact, &oldact) < 0 ) {
            perror("sigaction-sigchld");
            rc = ERR_INTERNAL; break;
        }

        syslog( LOG_NOTICE, "%s is starting\n", g_udpxy_finfo );
        TRACE( printcmdln( g_flog, g_udpxy_finfo, argc, argv ) );

        rc = srv_loop( ipaddr, port, mcast_addr );

        syslog( LOG_NOTICE, "%s is exiting with rc=[%d]\n",
                g_udpxy_finfo, rc);
        TRACE( tmfprintf( g_flog, "%s is exiting with rc=[%d]\n",
                    g_udpxy_app, rc ) );
        TRACE( printcmdln( g_flog, g_udpxy_finfo, argc, argv ) );
    } while(0);

    if( '\0' != pidfile[0] ) {
        if( -1 == unlink(pidfile) ) {
            mperror( g_flog, errno, "unlink [%s]", pidfile );
        }
    }

    if( g_flog && (stderr != g_flog) ) {
        (void) fclose(g_flog);
    }

    closelog();
    free_uopt( &g_uopt );

    return rc;
}
예제 #7
0
void daemonize_start(void)
{
    if (pidfile) {
        make_pidfile();
    }
}
예제 #8
0
int main(void)
  {
  pid_t pid, sid;     /* process ID and Session ID */

  /* Fork off the parent process */
  pid = fork();
  if (pid < 0)
    {
    exit(EXIT_FAILURE);
    }
    /* exit the parent process. */
    if (pid > 0)
      {
      exit(EXIT_SUCCESS);
      }

    /* Open any logs here */

    /* Create a new SID for the child process */
    sid = setsid();
    if (sid < 0)
      {
      /* Log the failure */
      exit(EXIT_FAILURE);
      }

    /* Change the current working directory */
    if ((chdir("/")) < 0)
      {
      /* Log the failure */
      exit(EXIT_FAILURE);
      }

    /* Close out the standard file descriptors */
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);
    /* reopen them pointing to /dev/null */
    fd0 = open ("/dev/null", (O_RDONLY | O_NOCTTY | O_NOFOLLOW));
    fd1 = open ("/dev/null", (O_WRONLY | O_NOCTTY | O_NOFOLLOW));
    fd2 = open ("/dev/null", (O_WRONLY | O_NOCTTY | O_NOFOLLOW));
    if (fd0 != 0 || fd1 != 1 || fd2 != 2 )
      {
      /* Log the failure */
      exit(EXIT_FAILURE);
      }

    /* change user id */
    if (setuid(UID) != 0)
      {
      /* Log the failure */
      exit(EXIT_FAILURE);
      }

    /* change group id */
    if (setgid(GID) != 0)
      {
      /* Log the failure */
      exit(EXIT_FAILURE);
      }

    /* make PID file */
    make_pidfile(PIDFILE);

    /* Change the file mode mask */
    umask(0);

    /* invoke signal handler */
    sa.sa_handler = handle_sighup;
    sa.sa_flags = 0;
    if (sigaction(SIGHUP,&sa,NULL))
      {
      /* Log the failure */
      exit(EXIT_FAILURE);
      }

    sa.sa_handler = handle_sigquit;
    sa.sa_flags = 0;
    if (sigaction(SIGQUIT,&sa,NULL))
      {
      /* Log the failure */
      exit(EXIT_FAILURE);
      }


    /* Daemon-specific initialization goes here */


   /* The Big Loop */
   while (1)
     {
     /* Do some task here ... */

          sleep(30); /* wait 30 seconds */
     }
  exit(EXIT_SUCCESS);
  }
예제 #9
0
int
main(int argc, char *argv[]) {
	int ret = EX_OK;
	primwatch_t primwatch;
	const char *log_type;
	const char *log_facility;
	const char *log_prefix;
	char log_path[MAXPATHLEN];
	const char *pid_file_path;
	const char *cntrl_addr;
	const char *cntrl_port;
	int64_t verbose_level;

	if (logger_create()) {
		fprintf(stderr, "failed in create logger");
		ret = EX_OSERR;
	}
	if (primwatch_initialize(&primwatch)) {
		fprintf(stderr, "failed in initaizliae");
		ret = EX_OSERR;
		goto last;
	}
	parse_args(&primwatch, argc, argv);
	if (logger_set_foreground(primwatch.foreground)) {
		fprintf(stderr, "failed in create logger");
		ret = EX_OSERR;
	}
	if (config_manager_load(primwatch.config_manager, primwatch.config_file)) {
		LOG(LOG_LV_ERR, "failed in load config file %s", primwatch.config_file);
		ret = EX_DATAERR;
		goto last;
	}
	if (config_manager_get_string(primwatch.config_manager, &log_type , "logType", NULL)) {
		LOG(LOG_LV_ERR, "failed in get log type from config");
		ret = EX_DATAERR;
		goto last;
	}
	if (config_manager_get_string(primwatch.config_manager, &log_facility , "logFacility", NULL)) {
		LOG(LOG_LV_ERR, "failed in get log facility from config");
		ret = EX_DATAERR;
		goto last;
	}
	if (config_manager_get_string(primwatch.config_manager, &log_prefix , "logPath", NULL)) {
		LOG(LOG_LV_ERR, "failed in get log path from config");
		ret = EX_DATAERR;
		goto last;
	}
	if (config_manager_get_string(primwatch.config_manager, &pid_file_path , "pidFilePath", NULL)) {
		LOG(LOG_LV_ERR, "failed in get pid file path from config");
		ret = EX_DATAERR;
		goto last;
	}
	if (config_manager_get_string(primwatch.config_manager, &cntrl_addr , "controllerAddress", NULL)) {
		LOG(LOG_LV_ERR, "failed in get controller address from config");
		ret = EX_DATAERR;
		goto last;
	}
	if (config_manager_get_string(primwatch.config_manager, &cntrl_port , "controllerPort", NULL)) {
		LOG(LOG_LV_ERR, "failed in get controller port from config");
		ret = EX_DATAERR;
		goto last;
	}
	if (config_manager_get_long(primwatch.config_manager, &verbose_level , "verboseLevel", NULL)) {
		LOG(LOG_LV_ERR, "failed in get verbose level from config");
		ret = EX_DATAERR;
		goto last;
	}
	snprintf(log_path, sizeof(log_path), "%s.daemon", log_prefix);
	if (logger_open((log_level_t)verbose_level, log_type, PROGIDENT, LOG_PID, log_facility, log_path)) {
		LOG(LOG_LV_ERR, "failed in open log");
		ret = EX_OSERR;
		goto last;
	}
        if (!primwatch.foreground) {
		if (daemon(1,1)) {
			LOG(LOG_LV_ERR, "failed in daemon");
			ret = EX_OSERR;
			goto last;
		}
		setsid();
	}
	if (primwatch_event_initialize(&primwatch)) {
		fprintf(stderr, "failed in initaizliae");
		ret = EX_OSERR;
		goto last;
	}
	if (make_pidfile(pid_file_path)) {
		LOG(LOG_LV_ERR, "failed in create file of process id");
		ret = EX_OSERR;
		goto last;
	}
	if (watcher_polling_start(primwatch.watcher)) {
		LOG(LOG_LV_ERR, "failed in initial polling");
		ret = EX_OSERR;
		goto last;
	}
	if (controller_start(primwatch.controller, cntrl_addr, cntrl_port)) {
		LOG(LOG_LV_ERR, "failed in start controller");
		ret = EX_OSERR;
		goto last;
	}
	signal_set(&primwatch.sig_int_event, SIGINT, primwatch_terminate, &primwatch);
	event_priority_set(&primwatch.sig_int_event, DEFAULT_EVENT_PRIORITY + 30);
	event_base_set(primwatch.event_base, &primwatch.sig_int_event);
	signal_add(&primwatch.sig_int_event, NULL);
	signal_set(&primwatch.sig_term_event, SIGTERM, primwatch_terminate, &primwatch);
	event_priority_set(&primwatch.sig_term_event, DEFAULT_EVENT_PRIORITY + 30);
	event_base_set(primwatch.event_base, &primwatch.sig_term_event);
	signal_add(&primwatch.sig_term_event, NULL);
	signal_set(&primwatch.sig_hup_event, SIGHUP, primwatch_reload, &primwatch);
	event_priority_set(&primwatch.sig_hup_event, DEFAULT_EVENT_PRIORITY + 30);
	event_base_set(primwatch.event_base, &primwatch.sig_hup_event);
	signal_add(&primwatch.sig_hup_event, NULL);
	signal_set(&primwatch.sig_chld_event, SIGCHLD, primwatch_sigchild, &primwatch);
	event_priority_set(&primwatch.sig_chld_event, DEFAULT_EVENT_PRIORITY + 30);
	event_base_set(primwatch.event_base, &primwatch.sig_chld_event);
	signal_add(&primwatch.sig_chld_event, NULL);
	if (event_base_dispatch(primwatch.event_base) == -1) {
		LOG(LOG_LV_ERR, "failed in event base dispatch");
		ret = EX_OSERR;
		goto last;
	}
last:
	unlink(pid_file_path);
	logger_close();
	logger_destroy();
	primwatch_finalize(&primwatch);

	return ret;
}
예제 #10
0
int
main(int argc, char *argv[])
{
    int i;
    int err;

    err = sel_alloc_selector(&ser2net_sel);
    if (err) {
	fprintf(stderr,
		"Could not initialize ser2net selector: '%s'\n",
		strerror(err));
	return -1;
    }

    for (i=1; i<argc; i++) {
	if ((argv[i][0] != '-') || (strlen(argv[i]) != 2)) {
	    fprintf(stderr, "Invalid argument: '%s'\n", argv[i]);
	    arg_error(argv[0]);
	}

	switch (argv[i][1]) {
	case 'n':
	    detach = 0;
	    break;

	case 'd':
	    detach = 0;
	    debug = 1;
	    break;

	case 'b':
	    cisco_ios_baud_rates = 1;
	    break;

	case 'C':
	    /* Get a config line. */
	    i++;
	    if (i == argc) {
		fprintf(stderr, "No config line specified with -C\n");
		arg_error(argv[0]);
	    }
	    handle_config_line(argv[i]);
	    config_file = NULL;
	    break;

	case 'c':
	    /* Get a config file. */
	    i++;
	    if (i == argc) {
		fprintf(stderr, "No config file specified with -c\n");
		arg_error(argv[0]);
	    }
	    config_file = argv[i];
	    break;

	case 'p':
	    /* Get the control port. */
	    i++;
	    if (i == argc) {
		fprintf(stderr, "No control port specified with -p\n");
		arg_error(argv[0]);
	    }
	    config_port = argv[i];
	    break;
	
	case 'P':
	    i++;
	    if (i == argc) {
		fprintf(stderr, "No pid file specified with -P\n");
		arg_error(argv[0]);
	    }
	    pid_file = argv[i];
	    break;

#ifdef USE_UUCP_LOCKING
	case 'u':
	    uucp_locking_enabled = 0;
	    break;
#endif

	case 'v':
	    printf("%s version %s\n", argv[0], VERSION);
	    exit(0);

	default:
	    fprintf(stderr, "Invalid option: '%s'\n", argv[i]);
	    arg_error(argv[0]);
	}
    }

    setup_sighup();
    if (config_port != NULL) {
	if (controller_init(config_port) == -1) {
	    fprintf(stderr, "Invalid control port specified with -p\n");
	    arg_error(argv[0]);
	}
    }

    if (debug && !detach)
	openlog("ser2net", LOG_PID | LOG_CONS | LOG_PERROR, LOG_DAEMON);

    if (config_file) {
	if (readconfig(config_file) == -1) {
	    return 1;
	}
    }

    if (detach) {
	int pid;

	/* Detach from the calling terminal. */
	openlog("ser2net", LOG_PID | LOG_CONS, LOG_DAEMON);
	syslog(LOG_NOTICE, "ser2net startup");
	if ((pid = fork()) > 0) {
	    exit(0);
	} else if (pid < 0) {
	    syslog(LOG_ERR, "Error forking first fork");
	    exit(1);
	} else {
	    /* setsid() is necessary if we really want to demonize */
	    setsid();
	    /* Second fork to really deamonize me. */
	    if ((pid = fork()) > 0) {
		exit(0);
	    } else if (pid < 0) {
		syslog(LOG_ERR, "Error forking second fork");
		exit(1);
	    }
	}

	/* Close all my standard I/O. */
	chdir("/");
	close(0);
	close(1);
	close(2);
    }

    /* write pid file */
    make_pidfile(pid_file);

    /* Ignore SIGPIPEs so they don't kill us. */
    signal(SIGPIPE, SIG_IGN);

    set_sighup_handler(reread_config);

    sel_select_loop(ser2net_sel);

    return 0;
}