#include "innbbsconf.h"
#include "bbslib.h"

extern char *optarg;
extern int opterr, optind;
usage(name)
char   *name;
{
	fprintf(stderr, "Usage: %s [-p path] commands\n", name);
	fprintf(stderr, " where available commands:\n");
	fprintf(stderr, "  ctlinnbbsd reload   : reload datafiles for innbbsd\n");
	fprintf(stderr, "  ctlinnbbsd shutdown : shutdown innbbsd gracefully\n");
	fprintf(stderr, "  ctlinnbbsd mode     : examine mode of innbbsd\n");
	fprintf(stderr, "  ctlinnbbsd addhist <mid> path: add history\n");
	fprintf(stderr, "  ctlinnbbsd grephist <mid>: query history\n");
	fprintf(stderr, "  ctlinnbbsd verboselog on|off : verboselog on/off\n");
	fprintf(stderr, "  ctlinnbbsd hismaint : maintain history\n");
	fprintf(stderr, "  ctlinnbbsd listnodelist  : list nodelist.bbs\n");
	fprintf(stderr, "  ctlinnbbsd listnewsfeeds : list newsfeeds.bbs\n");
	fprintf(stderr, "  ctlinnbbsd pause    : pause innbbsd server\n");
	fprintf(stderr, "  ctlinnbbsd go       : resume innbbsd server\n");
#ifdef GETRUSAGE
	fprintf(stderr, "  ctlinnbbsd getrusage: get resource usage\n");
#endif
#ifdef MALLOCMAP
	fprintf(stderr, "  ctlinnbbsd mallocmap: get malloc map\n");
#endif
}


char   *DefaultPath = LOCALDAEMON;
char    INNBBSbuffer[4096];

FILE   *innbbsin, *innbbsout;
int     innbbsfd;
ctlinnbbsd(argc, argv)
int     argc;
char  **argv;
{
	fgets(INNBBSbuffer, sizeof INNBBSbuffer, innbbsin);
	printf("%s", INNBBSbuffer);
	if (strcasecmp(argv[0], "shutdown") == 0 ||
		strcasecmp(argv[0], "reload") == 0 ||
		strcasecmp(argv[0], "hismaint") == 0 ||
#ifdef GETRUSAGE
		strcasecmp(argv[0], "getrusage") == 0 ||
#endif
#ifdef MALLOCMAP
		strcasecmp(argv[0], "mallocmap") == 0 ||
#endif
		strcasecmp(argv[0], "mode") == 0 ||
		strcasecmp(argv[0], "listnodelist") == 0 ||
		strcasecmp(argv[0], "listnewsfeeds") == 0 ||
		strcasecmp(argv[0], "pause") == 0 ||
		strcasecmp(argv[0], "go") == 0
		) {
		fprintf(innbbsout, "%s\r\n", argv[0]);
		fflush(innbbsout);
		fgets(INNBBSbuffer, sizeof INNBBSbuffer, innbbsin);
		printf("%s", INNBBSbuffer);
		if (strcasecmp(argv[0], "mode") == 0
#ifdef GETRUSAGE
			||
			strcasecmp(argv[0], "getrusage") == 0
			||
			strcasecmp(argv[0], "mallocmap") == 0
#endif
			||
			strcasecmp(argv[0], "listnodelist") == 0
			||
			strcasecmp(argv[0], "listnewsfeeds") == 0
			) {
			while (fgets(INNBBSbuffer, sizeof INNBBSbuffer, innbbsin) != NULL) {
				if (strcmp(INNBBSbuffer, ".\r\n") == 0) {
					break;
				}
				printf("%s", INNBBSbuffer);
			}
		}
	} else if (strcasecmp(argv[0], "grephist") == 0 ||
		strcasecmp(argv[0], "verboselog") == 0) {
		if (argc < 2) {
			usage("ctlinnbbsd");
		} else {
			fprintf(innbbsout, "%s %s\r\n", argv[0], argv[1]);
			fflush(innbbsout);
			fgets(INNBBSbuffer, sizeof INNBBSbuffer, innbbsin);
			printf("%s\n", INNBBSbuffer);
		}
	} else if (strcasecmp(argv[0], "addhist") == 0) {
		if (argc < 3) {
			usage("ctlinnbbsd");
		} else {
			fprintf(innbbsout, "%s %s %s\r\n", argv[0], argv[1], argv[2]);
			fflush(innbbsout);
			fgets(INNBBSbuffer, sizeof INNBBSbuffer, innbbsin);
			printf("%s", INNBBSbuffer);
		}
	} else {
		fprintf(stderr, "invalid command %s\n", argv[0]);
	}
	if (strcasecmp(argv[0], "shutdown") != 0) {
		fprintf(innbbsout, "QUIT\r\n");
		fflush(innbbsout);
		fgets(INNBBSbuffer, sizeof INNBBSbuffer, innbbsin);
	}
}
initsocket()
{
	innbbsfd = unixclient(DefaultPath, "tcp");
	if (innbbsfd < 0) {
		fprintf(stderr, "Connect to %s error. You may not run innbbsd\n", DefaultPath);
		exit(2);
	}
	if ((innbbsin = fdopen(innbbsfd, "r")) == NULL ||
		(innbbsout = fdopen(innbbsfd, "w")) == NULL) {
		fprintf(stderr, "fdopen error\n");
		exit(3);
	}
}
closesocket()
{
	if (innbbsin != NULL)
		fclose(innbbsin);
	if (innbbsout != NULL)
		fclose(innbbsout);
	if (innbbsfd >= 0)
		close(innbbsfd);
}
main(argc, argv)
int     argc;
char  **argv;
{
	int     c, errflag = 0;
	while ((c = getopt(argc, argv, "p:h?")) != -1)
		switch (c) {
		case 'p':
			DefaultPath = optarg;
			break;
		case 'h':
		case '?':
		default:
			errflag++;
			break;
		}
	if (errflag > 0) {
		usage(argv[0]);
		return (1);
	}
	if (argc - optind < 1) {
		usage(argv[0]);
		exit(1);
	}
	initial_bbs(NULL);
	initsocket();
	ctlinnbbsd(argc - optind, argv + optind);
	closesocket();
}
