/* file.c - handle temporary message composition files
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include "lock.h"
#include "u2u.h"
#include "bbs.h"

#ifndef O_SYNC				    /* FreeBSD kludge */
#ifdef O_FSYNC
#define O_SYNC O_FSYNC
#endif
#endif				/* O_SYNC */

char **u2u__file_list = 0;
char **u2u__recipient_list = 0;
int u2u__list_size = 0;

extern time_t u2u__last_checked;

int log_truncate(int, int, long, long, int);


/* Return a filename for writing a message to "recipients" in. The file is
 * created if it does not already exist. The filename will persist in memory
 * until u2u_remove_file() is called for the same recipients.
 */
char *u2u_create_file(char *recipients)
{
	char buf[64];
	int fd, i;

	if ((u2u__recipient_list) && (u2u__file_list)) {
		for (i = 0; i < u2u__list_size; i++) {
			if ((u2u__recipient_list[i]) &&
			    (!strcmp(u2u__recipient_list[i], recipients)))
				return (u2u__file_list[i]);
		}
	}

	snprintf(buf, sizeof(buf), "/tmp/mbbs-%s-XXXXXX", current_user);
	fd = mkstemp(buf);
	if (fd < 0)
		return ("");

	fchmod(fd, S_IRUSR | S_IWUSR);
	close(fd);

	if ((u2u__recipient_list) && (u2u__file_list)) {
		for (i = 0; i < u2u__list_size; i++) {
			if (u2u__recipient_list[i] == 0) {
				u2u__recipient_list[i] =
				    strdup(recipients);
				u2u__file_list[i] = strdup(buf);
				return (u2u__file_list[i]);
			}
		}
	}


	u2u__list_size++;
	u2u__recipient_list = realloc(u2u__recipient_list,
				      sizeof(char *) * u2u__list_size);
	u2u__file_list = realloc(u2u__file_list,
				 sizeof(char *) * u2u__list_size);

	u2u__recipient_list[u2u__list_size - 1] = strdup(recipients);
	u2u__file_list[u2u__list_size - 1] = strdup(buf);

	return (u2u__file_list[u2u__list_size - 1]);
}


/* Remove the temporary file for sending to "recipients".
 */
void u2u_remove_file(char *recipients)
{
	int i;

	if (!recipients)
		return;
	if (!u2u__recipient_list)
		return;
	if (!u2u__file_list)
		return;

	for (i = 0; i < u2u__list_size; i++) {
		if ((u2u__recipient_list[i]) &&
		    (!strcmp(u2u__recipient_list[i], recipients))) {

			remove(u2u__file_list[i]);

			free(u2u__recipient_list[i]);
			free(u2u__file_list[i]);

			u2u__recipient_list[i] = 0;
			u2u__file_list[i] = 0;
			return;
		}
	}
}


/* Delete any temporary message files and truncate the user's messages file
 * if it's too big.
 */
void u2u_fini(void)
{
	char buf[1024];
	int i, fd;

	if (!u2u__recipient_list)
		return;
	if (!u2u__file_list)
		return;

	for (i = 0; i < u2u__list_size; i++) {
		if (u2u__file_list[i]) {
			remove(u2u__file_list[i]);
			free(u2u__recipient_list[i]);
			free(u2u__file_list[i]);
			u2u__recipient_list[i] = 0;
			u2u__file_list[i] = 0;
		}
	}

	sprintf(buf, "%s/%s", cf_str("u2u"), current_user);
	fd = open(buf, O_CREAT | O_SYNC | O_RDWR);
	my_flock(buf, fd, LOCK_EX);

	log_truncate(fd, -1, cf_int("u2uomax") * 1024,
		     cf_int("u2uomin") * 1024, 1);
	fsync(fd);
	my_flock(buf, fd, LOCK_UN);
	close(fd);

	u2u__last_checked = time(0) + 1;
}

/* EOF */
