コード例 #1
0
uint32_t
asl_store_open_aux(asl_store_t *s, aslmsg msg, int *out_fd, char **url)
{
	struct tm ctm;
	time_t msg_time, bb;
	char *path, *dir, *tstring;
	const char *val;
	uid_t ruid, u;
	gid_t rgid, g;
	mode_t m;
	uint32_t status;
	uint64_t fid;
	int fd;

	if (s == NULL) return ASL_STATUS_INVALID_STORE;
	if (msg == NULL) return ASL_STATUS_INVALID_ARG;
	if (out_fd == NULL) return ASL_STATUS_INVALID_ARG;
	if (url == NULL) return ASL_STATUS_INVALID_ARG;

	msg_time = time(NULL);

	val = asl_get(msg, ASL_KEY_READ_UID);
	ruid = -1;
	if (val != NULL) ruid = atoi(val);

	val = asl_get(msg, ASL_KEY_READ_GID);
	rgid = -1;
	if (val != NULL) rgid = atoi(val);

	bb = 0;
	val = asl_get(msg, ASL_KEY_EXPIRE_TIME);
	if (val != NULL)
	{
		bb = 1;
		msg_time = asl_parse_time(val);
	}

	if (localtime_r((const time_t *)&msg_time, &ctm) == NULL) return ASL_STATUS_FAILED;

	dir = NULL;
	if (bb == 1)
	{
		/*
		 * This supports 12 monthly "Best Before" buckets.
		 * We advance the actual expiry time to day zero of the following month.
		 * mktime() is clever enough to know that you actually mean the last day
		 * of the previous month.  What we get back from localtime is the last
		 * day of the month in which the message expires, which we use in the name.
		 */
		ctm.tm_sec = 0;
		ctm.tm_min = 0;
		ctm.tm_hour = 0;
		ctm.tm_mday = 0;
		ctm.tm_mon += 1;

		bb = mktime(&ctm);

		if (localtime_r((const time_t *)&bb, &ctm) == NULL) return ASL_STATUS_FAILED;
		asprintf(&dir, "BB.AUX.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
	}
	else
	{
		asprintf(&dir, "AUX.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
	}

	if (dir == NULL) return ASL_STATUS_NO_MEMORY;

	status = asl_store_mkdir(s, dir, 0755);
	if (status != ASL_STATUS_OK)
	{
		free(dir);
		return status;
	}

	fid = s->next_id;
	s->next_id++;
	tstring = NULL;

	asprintf(&tstring, "%s/%llu", dir, fid);
	free(dir);
	if (tstring == NULL) return ASL_STATUS_NO_MEMORY;

	u = 0;
	g = 0;
	m = 0644;
	path = asl_store_make_ug_path(s->base_dir, tstring, NULL, ruid, rgid, &u, &g, &m);
	free(tstring);
	if (path == NULL) return ASL_STATUS_NO_MEMORY;

	fd = asl_file_create(path, u, g, m);
	if (fd < 0)
	{
		free(path);
		*out_fd = -1;
		return ASL_STATUS_WRITE_FAILED;
	}

	/* URL is file://<path> */
	*url = NULL;
	asprintf(url, "file://%s", path);
	free(path);

	*out_fd = fd;

	return status;
}
コード例 #2
0
/* save a message to an appropriately named BB file */
static uint32_t 
save_bb_msg(aslmsg msg)
{
	const char *val;
	uid_t u, ruid;
	gid_t g, rgid;
	struct tm ctm;
	time_t msg_time, bb;
	char *path, *tstring;
	asl_file_t *out;
	uint64_t mid;
	mode_t m;
	uint32_t status;

	if (msg == NULL) return ASL_STATUS_OK;

	val = asl_get(msg, ASL_KEY_EXPIRE_TIME);
	if (val == NULL)  return ASL_STATUS_INVALID_ARG;
	msg_time = asl_parse_time(val);

	val = asl_get(msg, ASL_KEY_READ_UID);
	ruid = -1;
	if (val != NULL) ruid = atoi(val);

	val = asl_get(msg, ASL_KEY_READ_GID);
	rgid = -1;
	if (val != NULL) rgid = atoi(val);

	if (localtime_r((const time_t *)&msg_time, &ctm) == NULL) return ASL_STATUS_FAILED;

	/*
	 * This supports 12 monthy "Best Before" buckets.
	 * We advance the actual expiry time to day zero of the following month.
	 * mktime() is clever enough to know that you actually mean the last day
	 * of the previous month.  What we get back from localtime is the last
	 * day of the month in which the message expires, which we use in the name.
	 */
	ctm.tm_sec = 0;
	ctm.tm_min = 0;
	ctm.tm_hour = 0;
	ctm.tm_mday = 0;
	ctm.tm_mon += 1;

	bb = mktime(&ctm);

	u = 0;
	g = 0;
	if (ruid != -1) u = ruid;
	if (rgid != -1) g = rgid;

	out = NULL;

	if (cache_file != NULL)
	{
		if ((cache_uid == u) && (cache_gid == g) && (cache_bb == bb))
		{
			out = cache_file;
		}
		else
		{
			asl_file_close(cache_file);
			cache_file = NULL;
			cache_uid = -1;
			cache_gid = -1;
			cache_bb = 0;
		}
	}

	if (out == NULL)
	{
		if (localtime_r((const time_t *)&bb, &ctm) == NULL) return ASL_STATUS_FAILED;

		tstring = NULL;
		asprintf(&tstring, "%s/BB.%d.%02d.%02d", store_path, ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
		if (tstring == NULL) return ASL_STATUS_NO_MEMORY;

		path = NULL;
		m = 0644;

		if (ruid == -1)
		{
			if (rgid == -1)
			{
				asprintf(&path, "%s.asl", tstring);
			}
			else
			{
				m = 0640;
				asprintf(&path, "%s.G%d.asl", tstring, g);
			}
		}
		else
		{
			if (rgid == -1)
			{
				m = 0600;
				asprintf(&path, "%s.U%d.asl", tstring, u);
			}
			else
			{
				m = 0640;
				asprintf(&path, "%s.U%d.G%u.asl", tstring, u, g);
			}
		}

		if (path == NULL) return ASL_STATUS_NO_MEMORY;

		status = asl_file_open_write(path, m, u, g, &out);
		free(path);
		if (status != ASL_STATUS_OK) return status;
		if (out == NULL) return ASL_STATUS_FAILED;

		out->flags = ASL_FILE_FLAG_PRESERVE_MSG_ID;

		cache_file = out;
		cache_uid = u;
		cache_gid = g;
		cache_bb = bb;
	}

	status = asl_file_save(out, msg, &mid);

	return status;
}
コード例 #3
0
uint32_t
asl_store_save(asl_store_t *s, aslmsg msg)
{
	struct tm ctm;
	time_t msg_time, now, bb;
	char *path, *tmp_path, *tstring, *scratch;
	const char *val;
	uid_t ruid;
	gid_t rgid;
	asl_file_t *f;
	uint32_t status, check_cache, trigger_aslmanager, len;
	uint64_t xid, ftime;
	size_t fsize;

	if (s == NULL) return ASL_STATUS_INVALID_STORE;
	if (msg == NULL) return ASL_STATUS_INVALID_ARG;

	now = time(NULL);

	check_cache = 0;
	if ((s->last_write + FILE_CACHE_TTL) <= now) check_cache = 1;

	trigger_aslmanager = 0;

	msg_time = 0;
	val = asl_get(msg, ASL_KEY_TIME);
	if (val == NULL) msg_time = now;
	else msg_time = asl_parse_time(val);

	if (msg_time >= s->start_tomorrow)
	{
		if (now >= s->start_tomorrow)
		{
			/* new day begins */
			check_cache = 0;
			asl_store_file_closeall(s);

			/*
			 * _asl_start_today should never fail, but if it does,
			 * just push forward one day.  That will probably be correct, and if
			 * it isn't, the next message that gets saved will push it ahead again
			 * until we get to the right date.
			 */
			s->start_today = _asl_start_today();
			if (s->start_today == 0) s->start_today = s->start_tomorrow;

			s->start_tomorrow = s->start_today + SECONDS_PER_DAY;
		}
	}

	val = asl_get(msg, ASL_KEY_READ_UID);
	ruid = -1;
	if (val != NULL) ruid = atoi(val);

	val = asl_get(msg, ASL_KEY_READ_GID);
	rgid = -1;
	if (val != NULL) rgid = atoi(val);

	bb = 0;
	val = asl_get(msg, ASL_KEY_EXPIRE_TIME);
	if (val != NULL)
	{
		bb = 1;
		msg_time = asl_parse_time(val);
	}

	if (fseeko(s->storedata, 0, SEEK_SET) != 0) return ASL_STATUS_WRITE_FAILED;

	xid = asl_core_htonq(s->next_id);
	if (fwrite(&xid, sizeof(uint64_t), 1, s->storedata) != 1) return ASL_STATUS_WRITE_FAILED;

	/* flush data */
	fflush(s->storedata);

	xid = s->next_id;
	s->next_id++;

	s->last_write = now;

	if (localtime_r((const time_t *)&msg_time, &ctm) == NULL) return ASL_STATUS_FAILED;

	tstring = NULL;
	if (bb == 1)
	{
		/*
		 * This supports 12 monthly "Best Before" buckets.
		 * We advance the actual expiry time to day zero of the following month.
		 * mktime() is clever enough to know that you actually mean the last day
		 * of the previous month.  What we get back from localtime is the last
		 * day of the month in which the message expires, which we use in the name.
		 */
		ctm.tm_sec = 0;
		ctm.tm_min = 0;
		ctm.tm_hour = 0;
		ctm.tm_mday = 0;
		ctm.tm_mon += 1;

		bb = mktime(&ctm);

		if (localtime_r((const time_t *)&bb, &ctm) == NULL) return ASL_STATUS_FAILED;
		asprintf(&tstring, "BB.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
	}
	else
	{
		asprintf(&tstring, "%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
	}

	if (tstring == NULL) return ASL_STATUS_NO_MEMORY;

	status = asl_store_file_open_write(s, tstring, ruid, rgid, bb, &f, now, check_cache);
	free(tstring);
	tstring = NULL;

	if (status != ASL_STATUS_OK) return status;

	status = asl_file_save(f, msg, &xid);
	if (status != ASL_STATUS_OK) return status;

	fsize = asl_file_size(f);
	ftime = asl_file_ctime(f);

	/* if file is larger than max_file_size, rename it and trigger aslmanager */
	if ((s->max_file_size != 0) && (fsize > s->max_file_size))
	{
		trigger_aslmanager = 1;
		status = ASL_STATUS_OK;

		path = asl_store_file_path(s, f);

		asl_store_file_close(s, f);

		if (path != NULL)
		{
			tmp_path = NULL;

			len = strlen(path);
			if ((len >= 4) && (!strcmp(path + len - 4, ".asl")))
			{
				/* rename xxxxxxx.asl to xxxxxxx.timestamp.asl */
				scratch = strdup(path);
				if (scratch != NULL)
				{
					scratch[len - 4] = '\0';
					asprintf(&tmp_path, "%s.%llu.asl", scratch, ftime);
					free(scratch);

				}
			}
			else
			{
				/* append timestamp */
				asprintf(&tmp_path, "%s.%llu", path, ftime);
			}

			if (tmp_path == NULL)
			{
				status = ASL_STATUS_NO_MEMORY;
			}
			else
			{
				if (rename(path, tmp_path) != 0) status = ASL_STATUS_FAILED;
				free(tmp_path);
			}

			free(path);
		}
	}

	if (trigger_aslmanager != 0) asl_trigger_aslmanager();

	return status;
}