Example #1
0
/*
 * Used for handling errors that occur before we daemonize.
 */
static void
early_error(const char *str)
{
	const char *cp;

	cp = mystrerror(errno);
	if (isatty(2)) {
		(void) fprintf(stderr, "%s: %s: %s\n", myname, str, cp);
	} else {
		reopen_log();
		logerr("%s: %s", str, cp);
	}
	exit(1);
}
Example #2
0
/*
 * Become a daemon.
 */
static void
daemonize(void)
{
	pid_t cpid;

	/*
	 * A little bit of magic here.  By the first fork+setsid, we
	 * disconnect from our current controlling terminal and become
	 * a session group leader.  By forking again without setsid,
	 * we make certain that we're not the session group leader and
	 * can never reacquire a controlling terminal.
	 */
	if ((cpid = fork()) == (pid_t)-1) {
		early_error("fork 1");
	}
	if (cpid != 0) {
		(void) wait(NULL);
		_exit(0);
	}
	if (setsid() == (pid_t)-1) {
		early_error("setsid");
	}
	if ((cpid = fork()) == (pid_t)-1) {
		early_error("fork 2");
	}
	if (cpid != 0) {
		/* Parent just exits */
		(void) printf("%d\n", (int)cpid);
		(void) fflush(stdout);
		_exit(0);
	}
	(void) chdir("/");
	(void) umask(0);
	(void) fdwalk(fdcloser, NULL);
	reopen_log();
}
Example #3
0
File: upslog.c Project: alezz/nut
int main(int argc, char **argv)
{
	int	interval = 30, i;
	const char	*prog = xbasename(argv[0]);
	time_t	now, nextpoll = 0;
	const char	*user = NULL;
	struct passwd	*new_uid = NULL;
	const char	*pidfilebase = prog;

	logformat = DEFAULT_LOGFORMAT;
	user = RUN_AS_USER;

	printf("Network UPS Tools %s %s\n", prog, UPS_VERSION);

	 while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:")) != -1) {
		switch(i) {
			case 'h':
				help(prog);
				break;

			case 's':
				monhost = optarg;
				break;

			case 'l':
				logfn = optarg;
				break;

			case 'i':
				interval = atoi(optarg);
				break;

			case 'f':
				logformat = optarg;
				break;

			case 'u':
				user = optarg;
				break;

			case 'V':
				exit(EXIT_SUCCESS);

			case 'p':
				pidfilebase = optarg;
				break;
		}
	}

	argc -= optind;
	argv += optind;

	/* not enough args for the old way? */
	if ((argc == 1) || (argc == 2))
		help(prog);

	/* see if it's being called in the old style - 3 or 4 args */

	/* <system> <logfn> <interval> [<format>] */

	if (argc >= 3) {
		monhost = argv[0];
		logfn = argv[1];
		interval = atoi(argv[2]);
	}

	if (argc >= 4) {
		/* read out the remaining argv entries to the format string */

		logformat = xmalloc(LARGEBUF);
		memset(logformat, '\0', LARGEBUF);

		for (i = 3; i < argc; i++)
			snprintfcat(logformat, LARGEBUF, "%s ", argv[i]);
	}

	if (!monhost)
		fatalx(EXIT_FAILURE, "No UPS defined for monitoring - use -s <system>");

	if (!logfn)
		fatalx(EXIT_FAILURE, "No filename defined for logging - use -l <file>");

	/* shouldn't happen */
	if (!logformat)
		fatalx(EXIT_FAILURE, "No format defined - but this should be impossible");

	printf("logging status of %s to %s (%is intervals)\n", 
		monhost, logfn, interval);

	if (upscli_splitname(monhost, &upsname, &hostname, &port) != 0) {
		fatalx(EXIT_FAILURE, "Error: invalid UPS definition.  Required format: upsname[@hostname[:port]]\n");
	}

	if (upscli_connect(&ups, hostname, port, UPSCLI_CONN_TRYSSL) < 0)
		fprintf(stderr, "Warning: initial connect failed: %s\n", 
			upscli_strerror(&ups));

	if (strcmp(logfn, "-") == 0)
		logfile = stdout;
	else
		logfile = fopen(logfn, "a");

	if (logfile == NULL)
		fatal_with_errno(EXIT_FAILURE, "could not open logfile %s", logfn);

	/* now drop root if we have it */
	new_uid = get_user_pwent(user);

	open_syslog(prog); 

	if (logfile != stdout)
		background();

	setup_signals();

	writepid(pidfilebase);

	become_user(new_uid);

	compile_format();

	while (exit_flag == 0) {
		time(&now);

		if (nextpoll > now) {
			/* there is still time left, so sleep it off */
			sleep(difftime(nextpoll, now));
			nextpoll += interval;
		} else {
			/* we spent more time in polling than the interval allows */
			nextpoll = now + interval;
		}

		if (reopen_flag) {
			upslogx(LOG_INFO, "Signal %d: reopening log file", 
				reopen_flag);
			reopen_log();
			reopen_flag = 0;
		}

		/* reconnect if necessary */
		if (upscli_fd(&ups) < 0) {
			upscli_connect(&ups, hostname, port, 0);
		}

		run_flist();

		/* don't keep connection open if we don't intend to use it shortly */
		if (interval > 30) {
			upscli_disconnect(&ups);
		}
	}

	upslogx(LOG_INFO, "Signal %d: exiting", exit_flag);

	if (logfile != stdout)
		fclose(logfile);

	upscli_disconnect(&ups);
	
	exit(EXIT_SUCCESS);
}