/* status.c - functions dealing with the status file
 */

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


int status_fd = -1;
char status_file[1024];
int bbs__satellite = 0;
extern time_t start_time;


/* Write blank data to the current status file.
 */
void sat__blank(void)
{
	char buf[1024];

	if (status_fd < 0)
		return;

	snprintf(buf, sizeof(buf), "%s\n%s\n%s\n%s\n%ld\n%s\n%ld\n",
		 current_user, "", "", "Connecting", time(0), "",
		 start_time);

	my_flock(status_file, status_fd, LOCK_EX);
	lseek(status_fd, 0, SEEK_SET);
	write(status_fd, buf, strlen(buf));
	ftruncate(status_fd, strlen(buf));
	my_flock(status_file, status_fd, LOCK_UN);
}


/* Find a status file to store the current action in. The resulting fd is
 * stored in "status_fd", or -1 on error.
 */
void find_satellite(void)
{
	struct stat sb;
	struct stat sb_b;
	char *dir;
	time_t t;
	int i;

	dir = cf_str("status");		    /* read status dir from config */
	if (!dir)
		return;

	if (stat(dir, &sb))
		return;			    /* abort if can't stat directory */

	t = time(0);

	for (i = 1; i < 10000; i++) {
		sprintf(status_file, "%s/%d", dir, i);	/* generate file name */

		status_fd = open(status_file, O_RDWR);	/* try reading file */
		if (status_fd >= 0) {

			if (fstat(status_fd, &sb_b)) {	/* stat file */
				close(status_fd);
				status_fd = -1;
				continue;
			}

			if (!S_ISREG(sb_b.st_mode)) {	/* skip - not a file */
				close(status_fd);
				status_fd = -1;
				continue;
			}

			if (sb_b.st_mtime >= (t - 10800)) {	/* new file - skip */
				close(status_fd);
				status_fd = -1;
				continue;
			}

			bbs__satellite = i;
			sat__blank();	    /* write blank data to file */
			return;		    /* done */
		}

		status_fd = open(status_file, O_WRONLY | O_CREAT | O_EXCL,
				 S_IRUSR | S_IWUSR);

		if (status_fd < 0) {	    /* failed to create file */
			remove(status_file);	/* try removing */
			status_fd =
			    open(status_file, O_WRONLY | O_CREAT | O_EXCL,
				 S_IRUSR | S_IWUSR);
		}

		if (status_fd < 0)
			continue;	    /* still failed to create */

		fchmod(status_fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);

		bbs__satellite = i;
		sat__blank();		    /* write blank data to file */
		return;			    /* succeeded */
	}
}


/* Free the currently held status file, if any.
 */
void free_satellite(void)
{
	if (status_fd < 0)
		return;
	close(status_fd);
	remove(status_file);
	status_fd = -1;
}

/* EOF */
