/*
 * KON - Kanji ON Linux Console - Copyright (C) 1992, 1993 Takashi MANABE
 * (manabe@tut.ac.jp)
 * 
 * KON is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * KON is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 675
 * Mass Ave, Cambridge, MA 02139, USA.
 */
/*
 * Modified for Big5Con by Hung-Chi Chu <hcchu@r350.ee.ntu.edu.tw>
 */

#include	"big5con.h"

void 
StatReport()
{
    int             i;

    i = 0;
    while (fSRegs[i].registry) {
	message("%2X %-15s %c%c\r\n",
		i, fSRegs[i].registry,
		(i == lInfo.sb) ? '*' : ' ',
		(fSRegs[i].stat & FR_ATTACH) ? 'A' :
		((fSRegs[i].stat & FR_PROXY) ? 'P' : ' '));
	i++;
    }
    i = 0;
    while (fDRegs[i].registry) {
	message("%2X %-15s %c%c\r\n",
		i | CHR_DBC, fDRegs[i].registry,
		(i == lInfo.db) ?
		((lInfo.sc == CODE_EUC) ? 'E' :
		 ((lInfo.sc == CODE_SJIS) ? 'S' : ' ')) : ' ',
		(fDRegs[i].stat & FR_ATTACH) ? 'A' :
		((fDRegs[i].stat & FR_PROXY) ? 'P' : ' '));
	i++;
    }
}

int 
SocketInit(char *tty)
{
    int             len, sfd;
    struct sockaddr sinfo;

#if defined(linux)
    sprintf(sinfo.sa_data, "%s%s", SOCKET_BASENAME, tty);
#elif defined(__FreeBSD__)
    sprintf(sinfo.sa_data, "%s", SOCKET_BASENAME);
#endif
    unlink(sinfo.sa_data);
    if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
	PerrorExit(sinfo.sa_data);
    }
    sinfo.sa_family = AF_UNIX;
#if defined(linux)
    len = sizeof(sinfo.sa_family) + strlen(sinfo.sa_data);
#elif defined(__FreeBSD__)
    len = sizeof(sinfo.sa_family) + strlen(sinfo.sa_data) + 1;
#endif
    if (bind(sfd, &sinfo, len) < 0) {
	message("can't bind socket");
	PerrorExit(sinfo.sa_data);
    }
    listen(sfd, 1);
    return (sfd);
}

void 
SocketInterface(int sfd)
{
    int             fd, len;
    struct sockaddr clt;
    struct messageHeader mh;

    len = sizeof(struct sockaddr);
    if ((fd = accept(sfd, &clt, &len)) < 0)
	PerrorExit("accept");
    SocketRecCommand(fd, &mh);
    switch (mh.cmd) {
    case CHR_LOAD:
	FontAttach();
	break;
    case CHR_UNLOAD:
	FontDetach(FALSE);
	break;
    case CHR_TEXTMODE:
	TextMode();
	message("switched to text mode.\r\n");
	SocketSendCommand(fd, CHR_ACK);
	break;
    case CHR_GRAPHMODE:
	GraphMode();
	message("switched to graphics mode.\r\n");
	SocketSendCommand(fd, CHR_ACK);
	break;
    case CHR_RESTART:
	SocketSendCommand(fd, CHR_ACK);
	TermRestart(fd);
	break;
    case CHR_STAT:
	SocketSendCommand(fd, CHR_ACK);
	StatReport();
	break;
    default:
	message("unknown request.\r\n");
	SocketSendCommand(fd, CHR_NAK);
    }
    close(fd);
}
