Exemplo n.º 1
0
/**
 * nsm_get_state - retrieve on-disk NSM state number
 *
 * Returns an odd NSM state number read from disk, or an initial
 * state number.  Zero is returned if some error occurs.
 */
int
nsm_get_state(_Bool update)
{
	int fd, state = 0;
	ssize_t result;
	char *path = NULL;

	path = nsm_make_pathname(NSM_STATE_FILE);
	if (path == NULL) {
		xlog(L_ERROR, "Failed to allocate path for " NSM_STATE_FILE);
		goto out;
	}

	fd = open(path, O_RDONLY);
	if (fd == -1) {
		if (errno != ENOENT) {
			xlog(L_ERROR, "Failed to open %s: %m", path);
			goto out;
		}

		xlog(L_NOTICE, "Initializing NSM state");
		state = 1;
		update = true;
		goto update;
	}

	result = read(fd, &state, sizeof(state));
	if (exact_error_check(result, sizeof(state))) {
		xlog_warn("Failed to read %s: %m", path);

		xlog(L_NOTICE, "Initializing NSM state");
		state = 1;
		update = true;
		goto update;
	}

	if ((state & 1) == 0)
		state++;

update:
	if(fd >= 0)
		(void)close(fd);

	if (update) {
		state += 2;
		if (!nsm_atomic_write(path, &state, sizeof(state)))
			state = 0;
	}

out:
	free(path);
	return state;
}
Exemplo n.º 2
0
static _Bool
nsm_append_monitored_host(const char *path, const char *line)
{
	_Bool result = false;
	char *buf = NULL;
	struct stat stb;
	size_t buflen;
	ssize_t len;
	int fd;

	if (stat(path, &stb) == -1) {
		xlog(L_ERROR, "Failed to insert: "
			"could not stat original file %s: %m", path);
		goto out;
	}
	buflen = (size_t)stb.st_size + strlen(line);

	buf = malloc(buflen + 1);
	if (buf == NULL) {
		xlog(L_ERROR, "Failed to insert: no memory");
		goto out;
	}
	memset(buf, 0, buflen + 1);

	fd = open(path, O_RDONLY);
	if (fd == -1) {
		xlog(L_ERROR, "Failed to insert: "
			"could not open original file %s: %m", path);
		goto out;
	}

	len = read(fd, buf, (size_t)stb.st_size);
	if (exact_error_check(len, (size_t)stb.st_size)) {
		xlog(L_ERROR, "Failed to insert: "
			"could not read original file %s: %m", path);
		(void)close(fd);
		goto out;
	}
	(void)close(fd);

	strcat(buf, line);

	if (nsm_atomic_write(path, buf, buflen))
		result = true;

out:
	free(buf);
	return result;
}
Exemplo n.º 3
0
static void
nsm_delete_host(const char *directory, const char *hostname,
		const char *mon_name, const char *my_name)
{
	char line[LINELEN + 1 + SM_MAXSTRLEN + 2];
	char *outbuf = NULL;
	struct stat stb;
	char *path, *next;
	size_t remaining;
	FILE *f;

	path = nsm_make_record_pathname(directory, hostname);
	if (path == NULL) {
		xlog(L_ERROR, "Bad filename, not deleting");
		return;
	}

	if (stat(path, &stb) == -1) {
		xlog(L_ERROR, "Failed to delete: "
			"could not stat original file %s: %m", path);
		goto out;
	}
	remaining = (size_t)stb.st_size + 1;

	outbuf = malloc(remaining);
	if (outbuf == NULL) {
		xlog(L_ERROR, "Failed to delete: no memory");
		goto out;
	}

	f = fopen(path, "r");
	if (f == NULL) {
		xlog(L_ERROR, "Failed to delete: "
			"could not open original file %s: %m", path);
		goto out;
	}

	/*
	 * Walk the records in the file, and copy the non-matching
	 * ones to our output buffer.
	 */
	next = outbuf;
	while (fgets(line, (int)sizeof(line), f) != NULL) {
		struct sockaddr_in sin;
		struct mon m;
		size_t len;

		if (!nsm_parse_line(line, &sin, &m)) {
			xlog(L_ERROR, "Failed to delete: "
				"could not parse original file %s", path);
			(void)fclose(f);
			goto out;
		}

		if (strcmp(mon_name, m.mon_id.mon_name) == 0 &&
			 strcmp(my_name, m.mon_id.my_id.my_name) == 0)
			continue;

		/* nsm_parse_line destroys the contents of line[], so
		 * reconstruct the copy in our output buffer. */
		len = nsm_create_monitor_record(next, remaining,
					(struct sockaddr *)(char *)&sin, &m);
		if (len == 0) {
			xlog(L_ERROR, "Failed to delete: "
				"could not construct output record");
			(void)fclose(f);
			goto out;
		}
		next += len;
		remaining -= len;
	}

	(void)fclose(f);

	/*
	 * If nothing was copied when we're done, then unlink the file.
	 * Otherwise, atomically update the contents of the file.
	 */
	if (next != outbuf) {
		if (!nsm_atomic_write(path, outbuf, strlen(outbuf)))
			xlog(L_ERROR, "Failed to delete: "
				"could not write new file %s: %m", path);
	} else {
		if (unlink(path) == -1)
			xlog(L_ERROR, "Failed to delete: "
				"could not unlink file %s: %m", path);
	}

out:
	free(outbuf);
	free(path);
}