示例#1
0
文件: upsconf.c 项目: AlexLov/nut
/* open the ups.conf, parse it, and call back do_upsconf_args() */
void read_upsconf(void)
{
	char	fn[SMALLBUF];
	PCONF_CTX_t	ctx;

	ups_section = NULL;
	snprintf(fn, sizeof(fn), "%s/ups.conf", confpath());

	pconf_init(&ctx, upsconf_err);

	if (!pconf_file_begin(&ctx, fn))
		fatalx(EXIT_FAILURE, "Can't open %s: %s", fn, ctx.errmsg);

	while (pconf_file_next(&ctx)) {
		if (pconf_parse_error(&ctx)) {
			upslogx(LOG_ERR, "Parse error: %s:%d: %s",
				fn, ctx.linenum, ctx.errmsg);
			continue;
		}

		conf_args(ctx.numargs, ctx.arglist);
	}

	pconf_finish(&ctx);

	free(ups_section);
}
示例#2
0
文件: upssched.c 项目: AlexLov/nut
static void conn_add(int sockfd)
{
	int	acc, ret;
	conn_t	*tmp, *last;
	struct	sockaddr_un	saddr;
#if defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED) 
	int			salen;
#else
	socklen_t	salen;
#endif

	salen = sizeof(saddr);
	acc = accept(sockfd, (struct sockaddr *) &saddr, &salen);

	if (acc < 0) {
		upslog_with_errno(LOG_ERR, "accept on unix fd failed");
		return;
	}

	/* enable nonblocking I/O */

	ret = fcntl(acc, F_GETFL, 0);

	if (ret < 0) {
		upslog_with_errno(LOG_ERR, "fcntl get on unix fd failed");
		close(acc);
		return;
	}

	ret = fcntl(acc, F_SETFL, ret | O_NDELAY);

	if (ret < 0) {
		upslog_with_errno(LOG_ERR, "fcntl set O_NDELAY on unix fd failed");
		close(acc);
		return;
	}

	tmp = last = connhead;

	while (tmp) {
		last = tmp;
		tmp = tmp->next;
	}

	tmp = xmalloc(sizeof(conn_t));
	tmp->fd = acc;
	tmp->next = NULL;

	if (last)
		last->next = tmp;
	else
		connhead = tmp;

	upsdebugx(3, "new connection on fd %d", acc);

	pconf_init(&tmp->ctx, NULL);
}
示例#3
0
文件: dstate.c 项目: JungleGenius/nut
static void sock_connect(int sock)
{
	int	fd, ret;
	conn_t	*conn;
	struct sockaddr_un sa;
#if defined(__hpux) && !defined(_XOPEN_SOURCE_EXTENDED) 
	int	salen;
#else
	socklen_t	salen;
#endif
	salen = sizeof(sa);
	fd = accept(sock, (struct sockaddr *) &sa, &salen);

	if (fd < 0) {
		upslog_with_errno(LOG_ERR, "accept on unix fd failed");
		return;
	}

	/* enable nonblocking I/O */
	if (!do_synchronous) {
		ret = fcntl(fd, F_GETFL, 0);

		if (ret < 0) {
			upslog_with_errno(LOG_ERR, "fcntl get on unix fd failed");
			close(fd);
			return;
		}

		ret = fcntl(fd, F_SETFL, ret | O_NDELAY);

		if (ret < 0) {
			upslog_with_errno(LOG_ERR, "fcntl set O_NDELAY on unix fd failed");
			close(fd);
			return;
		}	
	}

	conn = xcalloc(1, sizeof(*conn));
	conn->fd = fd;

	pconf_init(&conn->ctx, NULL);

	if (connhead) {
		conn->next = connhead;
		connhead->prev = conn;
	}

	connhead = conn;

	upsdebugx(3, "new connection on fd %d", fd);
}
示例#4
0
文件: conf.c 项目: baruch/nut
void load_upsdconf(int reloading)
{
    char	fn[SMALLBUF];
    PCONF_CTX_t	ctx;

    snprintf(fn, sizeof(fn), "%s/upsd.conf", confpath());

    check_perms(fn);

    pconf_init(&ctx, upsd_conf_err);

    if (!pconf_file_begin(&ctx, fn)) {
        pconf_finish(&ctx);

        if (!reloading)
            fatalx(EXIT_FAILURE, "%s", ctx.errmsg);

        upslogx(LOG_ERR, "Reload failed: %s", ctx.errmsg);
        return;
    }

    while (pconf_file_next(&ctx)) {
        if (pconf_parse_error(&ctx)) {
            upslogx(LOG_ERR, "Parse error: %s:%d: %s",
                    fn, ctx.linenum, ctx.errmsg);
            continue;
        }

        if (ctx.numargs < 1)
            continue;

        if (!parse_upsd_conf_args(ctx.numargs, ctx.arglist)) {
            unsigned int	i;
            char	errmsg[SMALLBUF];

            snprintf(errmsg, sizeof(errmsg),
                     "upsd.conf: invalid directive");

            for (i = 0; i < ctx.numargs; i++)
                snprintfcat(errmsg, sizeof(errmsg), " %s",
                            ctx.arglist[i]);

            upslogx(LOG_WARNING, "%s", errmsg);
        }

    }

    pconf_finish(&ctx);
}
示例#5
0
文件: upsmon.c 项目: ThomasKurz/nut
static void loadconfig(void)
{
    PCONF_CTX_t	ctx;

    pconf_init(&ctx, upsmon_err);

    if (!pconf_file_begin(&ctx, configfile)) {
        pconf_finish(&ctx);

        if (reload_flag == 1) {
            upslog_with_errno(LOG_ERR, "Reload failed: %s", ctx.errmsg);
            return;
        }

        fatalx(EXIT_FAILURE, "%s", ctx.errmsg);
    }

    while (pconf_file_next(&ctx)) {
        if (pconf_parse_error(&ctx)) {
            upslogx(LOG_ERR, "Parse error: %s:%d: %s",
                    configfile, ctx.linenum, ctx.errmsg);
            continue;
        }

        if (ctx.numargs < 1)
            continue;

        if (!parse_conf_arg(ctx.numargs, ctx.arglist)) {
            unsigned int	i;
            char	errmsg[SMALLBUF];

            snprintf(errmsg, sizeof(errmsg),
                     "%s line %d: invalid directive",
                     configfile, ctx.linenum);

            for (i = 0; i < ctx.numargs; i++)
                snprintfcat(errmsg, sizeof(errmsg), " %s",
                            ctx.arglist[i]);

            upslogx(LOG_WARNING, "%s", errmsg);
        }
    }

    pconf_finish(&ctx);
}
示例#6
0
文件: clone.c 项目: AlexLov/nut
static int sstate_connect(void)
{
	int	ret, fd;
	const char	*dumpcmd = "DUMPALL\n";
	struct sockaddr_un	sa;

	memset(&sa, '\0', sizeof(sa));
	sa.sun_family = AF_UNIX;
	snprintf(sa.sun_path, sizeof(sa.sun_path), "%s/%s", dflt_statepath(), device_path);

	fd = socket(AF_UNIX, SOCK_STREAM, 0);

	if (fd < 0) {
		upslog_with_errno(LOG_ERR, "Can't create socket for UPS [%s]", device_path);
		return -1;
	}

	ret = connect(fd, (struct sockaddr *) &sa, sizeof(sa));

	if (ret < 0) {
		time_t	now;

		close(fd);

		/* rate-limit complaints - don't spam the syslog */
		time(&now);

		if (difftime(now, last_connfail) < 60) {
			return -1;
		}

		last_connfail = now;

		upslog_with_errno(LOG_ERR, "Can't connect to UPS [%s]", device_path);
		return -1;
	}

	ret = fcntl(fd, F_GETFL, 0);

	if (ret < 0) {
		upslog_with_errno(LOG_ERR, "fcntl get on UPS [%s] failed", device_path);
		close(fd);
		return -1;
	}

	ret = fcntl(fd, F_SETFL, ret | O_NDELAY);

	if (ret < 0) {
		upslog_with_errno(LOG_ERR, "fcntl set O_NDELAY on UPS [%s] failed", device_path);
		close(fd);
		return -1;
	}

	/* get a dump started so we have a fresh set of data */
	ret = write(fd, dumpcmd, strlen(dumpcmd));

	if (ret != (int)strlen(dumpcmd)) {
		upslog_with_errno(LOG_ERR, "Initial write to UPS [%s] failed", device_path);
		close(fd);
		return -1;
	}

	pconf_init(&sock_ctx, NULL);

	time(&last_heard);

	dumpdone = 0;

	/* set ups.status to "WAIT" while waiting for the driver response to dumpcmd */
	dstate_setinfo("ups.status", "WAIT");

	upslogx(LOG_INFO, "Connected to UPS [%s]", device_path);
	return fd;
}
示例#7
0
文件: dummy-ups.c 项目: sbutler/nut
/* for dummy mode
 * parse the definition file and process its content
 */ 
static int parse_data_file(int upsfd)
{
	char	fn[SMALLBUF];
	char	*ptr, var_value[MAX_STRING_SIZE];
	int		value_args = 0, counter;
	time_t	now;

	time(&now);

	upsdebugx(1, "entering parse_data_file()");

	if (now < next_update)
	{
		upsdebugx(1, "leaving (paused)...");
		return 1;
	}

	/* initialise everything, to loop back at the beginning of the file */
	if (ctx == NULL)
	{
		ctx = (PCONF_CTX_t *)xmalloc(sizeof(PCONF_CTX_t));

		if (device_path[0] == '/')
			snprintf(fn, sizeof(fn), "%s", device_path);
		else
			snprintf(fn, sizeof(fn), "%s/%s", confpath(), device_path);

		pconf_init(ctx, upsconf_err);

		if (!pconf_file_begin(ctx, fn))
			fatalx(EXIT_FAILURE, "Can't open dummy-ups definition file %s: %s",
				fn, ctx->errmsg);
	}

	/* Reset the next call time, so that we can loop back on the file
	 * if there is no blocking action (ie TIMER) until the end of the file */
	next_update = -1;

	/* Now start or continue parsing... */
	while (pconf_file_next(ctx))
	{
		if (pconf_parse_error(ctx))
		{
			upsdebugx(2, "Parse error: %s:%d: %s",
				fn, ctx->linenum, ctx->errmsg);
			continue;
		}

		/* Check if we have something to process */
		if (ctx->numargs < 1)
			continue;

		/* Process actions (only "TIMER" ATM) */
		if (!strncmp(ctx->arglist[0], "TIMER", 5))
		{
			/* TIMER <seconds> will wait "seconds" before
			 * continuing the parsing */
			int delay = atoi (ctx->arglist[1]);
			time(&next_update);
			next_update += delay;
			upsdebugx(1, "suspending execution for %i seconds...", delay);
			break;
		}

		/* Remove ":" suffix, after the variable name */
		if ((ptr = strchr(ctx->arglist[0], ':')) != NULL)
			*ptr = '\0';

		upsdebugx(3, "parse_data_file: variable \"%s\" with %d args",
			ctx->arglist[0], (int)ctx->numargs);

		/* Skip the driver.* collection data */
		if (!strncmp(ctx->arglist[0], "driver.", 7))
		{
			upsdebugx(2, "parse_data_file: skipping %s", ctx->arglist[0]);
			continue;
		}

		/* From there, we get varname in arg[0], and values in other arg[1...x] */
		/* special handler for status */
		if (!strncmp( ctx->arglist[0], "ups.status", 10))
		{
			status_init();
			for (counter = 1, value_args = ctx->numargs ;
				counter < value_args ; counter++)
			{
				status_set(ctx->arglist[counter]);
			}
			status_commit();
		}
		else
		{
			for (counter = 1, value_args = ctx->numargs ;
				counter < value_args ; counter++)
			{
				if (counter == 1) /* don't append the first space separator */
					snprintf(var_value, sizeof(var_value), "%s", ctx->arglist[counter]);
				else
					snprintfcat(var_value, sizeof(var_value), " %s", ctx->arglist[counter]);
			}

			if (setvar(ctx->arglist[0], var_value) == STAT_SET_UNKNOWN)
			{
				upsdebugx(2, "parse_data_file: can't add \"%s\" with value \"%s\"\nError: %s",
					ctx->arglist[0], var_value, ctx->errmsg);
			}
			else
			{ 
				upsdebugx(3, "parse_data_file: added \"%s\" with value \"%s\"",
					ctx->arglist[0], var_value);
			}
		}
	}

	/* Cleanup parseconf if there is no pending action */
	if (next_update == -1)
	{
		pconf_finish(ctx);
		free(ctx);
		ctx=NULL;
	}
	return 1;
}
示例#8
0
int upscli_connect(UPSCONN *ups, const char *host, int port, int flags)
{
	struct	sockaddr_in	local, server;
	struct	hostent	*serv;
	unsigned long numericIPAddr=INADDR_NONE;

	/* clear out any lingering junk */
	ups->fd = INVALID_SOCKET;
	ups->host = NULL;
	ups->flags = 0;
	ups->upserror = 0;
	ups->syserrno = 0;
	ups->upsclient_magic = UPSCLIENT_MAGIC;

	ups->pc_ctx = malloc(sizeof(PCONF_CTX));

	if (!ups->pc_ctx) {
		ups->upserror = UPSCLI_ERR_NOMEM;
		return -1;		
	}

	pconf_init(ups->pc_ctx, NULL);

	ups->ssl_ctx = NULL;
	ups->ssl = NULL;

	if (!host) {
		ups->upserror = UPSCLI_ERR_NOSUCHHOST;
		return -1;
	}

	memset(&local, '\0', sizeof(struct sockaddr_in));
	local.sin_family = AF_INET;
	local.sin_port = htons(INADDR_ANY);

	memset(&server, '\0', sizeof(struct sockaddr_in));
	server.sin_family = AF_INET;
	server.sin_port = htons((u_short)port);

	//Windows is brain dead when it comes to gethostbyname and numeric ip addresses.  GRRrrrr
	numericIPAddr = inet_addr(host);
	if(numericIPAddr != INADDR_NONE)
	{
		/* the string is a numeric IP address, just set it on the
		   server addr struct */
		server.sin_addr.s_addr = numericIPAddr;
	}
	else if((serv = gethostbyname(host)) != (struct hostent *) NULL)
	{
		/* the string is a DNS name, we resolved and stored 
		   it to the serv structure so now set it on the 
		   server struct */
		memcpy (&server.sin_addr, serv->h_addr, serv->h_length);
	}
	else /* could not resolve name or IP */
	{
		ups->upserror = UPSCLI_ERR_NOSUCHHOST;
		ups->syserrno = errno = WSAGetLastError();
		return (-1);
	}

	if ((ups->fd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
		ups->upserror = UPSCLI_ERR_SOCKFAILURE;
		ups->syserrno = errno = WSAGetLastError();
		return -1;
	}

	if (bind(ups->fd, (struct sockaddr *) &local, 
		sizeof(struct sockaddr_in)) == -1) {
		ups->upserror = UPSCLI_ERR_BINDFAILURE;
		ups->syserrno = errno;
		close(ups->fd);
		ups->fd = INVALID_SOCKET;

		return -1;
	}

	if (connect(ups->fd, (struct sockaddr *) &server, 
		sizeof(struct sockaddr_in)) == -1) {
		ups->upserror = UPSCLI_ERR_CONNFAILURE;
		ups->syserrno = errno;
		close(ups->fd);
		ups->fd = INVALID_SOCKET;

		return -1;
	}

	/* don't use xstrdup for cleaner linking (fewer dependencies) */
	ups->host = strdup(host);

	if (!ups->host) {
		close(ups->fd);
		ups->fd = INVALID_SOCKET;

		ups->upserror = UPSCLI_ERR_NOMEM;
		return -1;
	}

	ups->port = port;

	if (flags & UPSCLI_CONN_TRYSSL) {
		upscli_sslinit(ups);

		/* see if something made us die inside sslinit */
		if (ups->upserror != 0)
			return -1;
	}

	if (flags & UPSCLI_CONN_REQSSL) {
		if (upscli_sslinit(ups) != 1) {
			ups->upserror = UPSCLI_ERR_SSLFAIL;
			upscli_closefd(ups);
			return -1;
		}
	}

	return 0;
}
示例#9
0
int upscli_tryconnect(UPSCONN_t *ups, const char *host, int port, int flags,struct timeval * timeout)
{
	int	sock_fd;
	struct addrinfo	hints, *res, *ai;
	char			sport[NI_MAXSERV];
	int			v;
	fd_set 			wfds;
	int			error;
	socklen_t		error_size;
	long			fd_flags;

	if (!ups) {
		return -1;
	}

	/* clear out any lingering junk */
	memset(ups, 0, sizeof(*ups));
	ups->upsclient_magic = UPSCLIENT_MAGIC;
	ups->fd = -1;

	if (!host) {
		ups->upserror = UPSCLI_ERR_NOSUCHHOST;
		return -1;
	}

	snprintf(sport, sizeof(sport), "%hu", (unsigned short int)port);

	memset(&hints, 0, sizeof(hints));

	if (flags & UPSCLI_CONN_INET6) {
		hints.ai_family = AF_INET6;
	} else if (flags & UPSCLI_CONN_INET) {
		hints.ai_family = AF_INET;
	} else {
		hints.ai_family = AF_UNSPEC;
	}

	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	while ((v = getaddrinfo(host, sport, &hints, &res)) != 0) {
		switch (v)
		{
		case EAI_AGAIN:
			continue;
		case EAI_NONAME:
			ups->upserror = UPSCLI_ERR_NOSUCHHOST;
			return -1;
		case EAI_MEMORY:
			ups->upserror = UPSCLI_ERR_NOMEM;
			return -1;
		case EAI_SYSTEM:
			ups->syserrno = errno;
			break;
		}

		ups->upserror = UPSCLI_ERR_UNKNOWN;
		return -1;
	}

	for (ai = res; ai != NULL; ai = ai->ai_next) {

		sock_fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);

		if (sock_fd < 0) {
			switch (errno)
			{
			case EAFNOSUPPORT:
			case EINVAL:
                                break;
			default:
				ups->upserror = UPSCLI_ERR_SOCKFAILURE;
				ups->syserrno = errno;
			}
			continue;
		}

		/* non blocking connect */
		if(timeout != NULL) {
			fd_flags = fcntl(sock_fd, F_GETFL);
			fd_flags |= O_NONBLOCK;
			fcntl(sock_fd, F_SETFL, fd_flags);
		}

		while ((v = connect(sock_fd, ai->ai_addr, ai->ai_addrlen)) < 0) {
			if(errno == EINPROGRESS) {
				FD_ZERO(&wfds);
				FD_SET(sock_fd, &wfds);
				select(sock_fd+1,NULL,&wfds,NULL,
						timeout);
				if (FD_ISSET(sock_fd, &wfds)) {
					error_size = sizeof(error);
					getsockopt(sock_fd,SOL_SOCKET,SO_ERROR,
							&error,&error_size);
					if( error == 0) {
						/* connect successful */
						v = 0;
						break;
					}
					errno = error;
				}
				else {
					/* Timeout */
					v = -1;
					break;
				}
			}

			switch (errno)
			{
			case EAFNOSUPPORT:
				break;
			case EINTR:
			case EAGAIN:
				continue;
			default:
				ups->upserror = UPSCLI_ERR_CONNFAILURE;
				ups->syserrno = errno;
			}
			break;
		}

		if (v < 0) {
			close(sock_fd);
			continue;
		}

		/* switch back to blocking operation */
		if(timeout != NULL) {
			fd_flags = fcntl(sock_fd, F_GETFL);
			fd_flags &= ~O_NONBLOCK;
			fcntl(sock_fd, F_SETFL, fd_flags);
		}

		ups->fd = sock_fd;
		ups->upserror = 0;
		ups->syserrno = 0;
		break;
	}

	freeaddrinfo(res);

	if (ups->fd < 0) {
		return -1;
	}

	pconf_init(&ups->pc_ctx, NULL);

	ups->host = strdup(host);

	if (!ups->host) {
		ups->upserror = UPSCLI_ERR_NOMEM;
		upscli_disconnect(ups);
		return -1;
	}

	ups->port = port;

	if (flags & UPSCLI_CONN_TRYSSL) {
		upscli_sslinit(ups);

		/* see if something made us die inside sslinit */
		if (ups->upserror != 0) {
			upscli_disconnect(ups);
			return -1;
		}
	}

	if ((flags & UPSCLI_CONN_REQSSL) && (upscli_sslinit(ups) != 1)) {
		ups->upserror = UPSCLI_ERR_SSLFAIL;
		upscli_disconnect(ups);
		return -1;
	}
		
	return 0;
}