/*

	S I M P L E - C H A T

	chat.c

	Copyright 1997 (c) KK-NET (http://www.kk-net.net/)
				written by Kouji Kawabata

*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <strings.h>

#define	CHAT_FILE	"chat_log.html"
#define	MAX_BUFF_LEN	256
#define	MAX_LINE	30
#define	NAME_COLOR	"#808000"
#define	TIME_COLOR	"#005000"
#define	SAY_COLOR	"#000000"
#define	TIME_LEN_MAX	32

char *chat_name, *chat_say;
char chat_time[TIME_LEN_MAX];
char qbuff[MAX_BUFF_LEN];

void disp(int flag)
{
	FILE *fp;
	char buff[MAX_BUFF_LEN];

	if(NULL == (fp = fopen(CHAT_FILE, "r")))	{
		return;			/* Ouch! */
	}
	else	{
		if(flag == 2 && *chat_name != '\0')	{	/* after login */
			while(fgets(buff, MAX_BUFF_LEN, fp))
				if(flag && !strncmp(buff, "<!--name-->", 11))	{
					printf("<input type=hidden name=\"name\" value=\"%s\">\n<input type=hidden name=\"num\" value=\"%d\">", chat_name, getpid());
					flag = 0;
				}
				else
					fputs(buff, stdout);
		}
		else	{
			while(fgets(buff, MAX_BUFF_LEN, fp))
				if(flag && !strncmp(buff, "<!--name-->", 11))	{
					printf("%s<input type=hidden name=\"num\" value=\"%d\">", buff, getpid());
					flag = 0;
				}
				else	fputs(buff, stdout);
		}
	}
	fputs("<hr><font size=-2> [SIMPLE CHAT] 1997 (c) by <a href=\"http://www.kk-net.net/\">KK-NET</a>\n</body></html>", stdout);
}

int say(void)
{
	char c;
	int fd, i, j, bytes;
	struct  stat stat_struct;
	char lbuf[MAX_BUFF_LEN];
	char *mbuf, *p = qbuff;

	for(i = 0; !feof(stdin); i++)	{
		if('%' == (c = getchar()))	{
			c = getchar();
			if(c >= 'A')	c -= 0x37;
			else		c -= '0';
			c *= 16;
			qbuff[i] = c;
			c = getchar();
			if(c >= 'A')	c -= 0x37;
			else		c -= '0';
			qbuff[i] |= c;
		}
		else	{
			if(c == '+') c = ' ';
			qbuff[i] = c;
		}
	}
	qbuff[i - 3] = '\0';		/* qbuff[i - 1] = '\0'; for SUN/OS and solaris */
	chat_name = strstr(qbuff, "name=") + 5;
	chat_say = strstr(qbuff, "&chat=") + 6;
	*(strchr(qbuff, '&')) = '\0';

	if(*chat_say != '\0')	{	/* == '\0' may be reload only... */
		time_t current_time = time(NULL);
		struct tm time_struct;

		putenv("TZ=JST-9");
		time_struct = *(localtime(&current_time));

		strftime(chat_time, TIME_LEN_MAX, "[%m/%d %H:%M:%S]", &time_struct);

		sprintf(lbuf, "<font color=%s><b>%s</b></font><font size=-2 color=%s> %s </font><font color=%s>%s</font><br>\n"
		, NAME_COLOR, chat_name, TIME_COLOR, chat_time, SAY_COLOR, chat_say);
		if(0 > (fd = open(CHAT_FILE, O_RDONLY)))
			return;
		fstat(fd, &stat_struct);
		if(NULL == (mbuf = malloc((sizeof(char) * stat_struct.st_size) + 16)))
			return;
		read(fd, mbuf, stat_struct.st_size);
		close(fd);

		p = strstr(mbuf, "<!--begin-->\n");
		if(0 > (fd = open(CHAT_FILE, O_WRONLY | O_TRUNC)))
			return;
		write(fd, mbuf, p - mbuf + 13);
		write(fd, lbuf, strlen(lbuf));

		p += 13;
		bytes = stat_struct.st_size - (p - mbuf);
		for(j = i = 0; i < MAX_LINE-1 && j < bytes; j++)
			if('\n' == p[j])	i++;
		write(fd, p, j);
		close(fd);
	}
}

void main(void)
{
/*	setpriority(PRIO_PROCESS,0,5);		Do you need nice? */

	fputs("Content-type: text/html\n\n", stdout);
	if(getenv("CONTENT_LENGTH") == '\0')	{
		disp(1);
	}
	else	{
		say();
		disp(2);
	}
}
