/******************************************************************************
 * This file is part of a software distribution, which is furnished under the *
 * terms of a license.  Use of this software  by any means is subject to this *
 * license  and  signifies  the  acceptance of  the  licensing  terms  stated *
 * therein. Please see  the file LICENSE in the  top-level directory  of this *
 * software  distribution  for detailed copyright  disclaimers  and licensing *
 * terms.                                                                     *
 ******************************************************************************
 * Copryight (c) by Andreas S. Wetzel - All rights reserved.                  *
 ******************************************************************************/

/* $Id: vd_subr.c,v 1.2 2001/03/19 14:54:06 mickey Exp $ */

#include <vchat.h>
#include <proto_vchatd.h>

#include <netdb.h>
#include <signal.h>
#include <netinet/in.h>

#ifdef HAVE_SYSLOG_H
#  include <syslog.h>
#endif

/******* Globals ********/

char	*bannerfile = NULL;

signed long inichan = 0;

extern	char *prog_name;

extern	char *optarg;
extern	int optind;
extern	int opterr;
extern	int optopt;
extern	int errno;

extern VP	vp;
extern VD	vd;
extern VTCAP	vtcap;
extern VCONN	sconn;

/*
 * int get_param(int argc, char *argv[]);
 *
 * Process commandline arguments given to vchat.
 * Returns 0 if successfull, -1 in case of failure.
 */

int get_param(int argc, char *argv[])
{
	int opt;
	struct hostent *ht;

	char optstr[] = ":b:B:c:p:s:lL:S";

	vp.logswitch = vd.logswitch = 0;
	sprintf(vp.logfile, "vchatd-log");
	vp.logfl = (FILE *)NULL;

	while((opt = getopt(argc, argv, optstr)) != -1)
	{
		switch(opt)
		{
			case 'b':	if(access(optarg, R_OK) == -1)
					{
						fprintf(stderr, "%s: failed to open bannerfile '%s'.\r\n",
							prog_name, optarg);

						return(-1);
					}
					else
					{
						bannerfile = optarg;
					}
					break;
			case 'c':	inichan = strtol(optarg, NULL, 0);
					break;
			case 'l':	vd.logswitch = 0x1;
					break;
			case 'L':	sprintf(vp.logfile, "%s", optarg);
					break;
			case 'p':	vp.sv_port = atoi(optarg);
					break;
			case 's':	if((ht = gethostbyname(optarg)) == NULL)
					{
#if HAVE_HERROR
						herror(optarg);
#else
						fprintf(stderr, "No address associated with name '%s'\n", optarg);
#endif
						return(-1);
					}
					else
					{
						BCOPY(ht->h_addr, &vp.sv_ip, ht->h_length);
					}
					break;
			case 'S':	vd.logswitch = 0x2;
					break;
			case ':':	usage("Option -%c requires an argument.", optopt);
					return(-1);
			case '?':	usage("Unrecognized option: -%c", optopt);
					return(-1);

		}
	}

	/*
	 * Prepare logging if desired
	 */

	switch(vd.logswitch)
	{
		case 0:		break;

		case 1:		if((vp.logfl = fopen(vp.logfile, "a")) == NULL)
				{
					fprintf(stderr, "%s: unable to open logfile '%s' for output - logging disabled.\n",
						prog_name, vp.logfile);
					sleep(1);
					vd.logswitch = 0;
				}
				break;

		case 2:
#if HAVE_SYSLOG_H
		openlog(prog_name, LOG_NDELAY, LOG_LOCAL2);
#endif
				break;

	}

	return(0);
}

/*
 * void vquit(char *fmt, ...);
 *
 * Exit from the program with the specified message.
 */

void vquit(char *fmt, ...)
{
	va_list ap;

#if HAVE_SIGACTION
	struct sigaction sa;
#else
	struct sigvec sv;
#endif

	va_start(ap, fmt);

	/*
	 * Shutdown signal handlers
	 */

	v_io_end();
	v_timer_end();

	/*
	 * Reset SIGINT and SIGTSTP to their default handlers
	 */

#if HAVE_SIGACTION
	sa.sa_handler = SIG_DFL;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;

	sigaction(SIGINT, &sa, NULL);
	sigaction(SIGTSTP, &sa, NULL);
#else
	sv.sv_handler = SIG_DFL;
	sigemptyset(&sv.sv_mask);
	sv.sv_flags = 0;

	sigvec(SIGINT, &sv, NULL);
	sigvec(SIGTSTP, &sv, NULL);
#endif

	/*
	 * Free buffers used by the command history
	 */

	history_exit();

	/*
	 * Sleep a while...
	 */

	vsleep(0, 250000);

	/*
	 * Close connection to VChat server
	 */

	close(sconn.fd);

	if(fmt != NULL)
	{
		/*
		 * Reset terminal key mode
		 */

		keymode(0);

		/*
		 * Output the reset sequence to the terminal
		 */

		if(vtcap.term_reset)
			tputs(vtcap.term_reset, 1, (void *)outc);

		printf("%c[0;0r", 27);

		/*
		 * Move to the bottom of the screen and output program
		 * termination string
		 */

		mv(1, vtcap.rows);

		vprintf(fmt, ap);
		printf("\r\n\r\n");
	}

	/*
	 * Close logging
	 */

	log(VLOG_INFO, "Exiting");

	switch(vd.logswitch)
	{
		case 0:		break;
		case 1:		fclose(vp.logfl);
				break;
		case 2:
#if HAVE_SYSLOG_H
		closelog();
#endif
				break;
	}

	/*
	 * Exit from the program with zero return status
	 */

	va_end(ap);

	exit(0);
}

/*
 * SIZE	*getsize(void);
 *
 * Determines the current terminal size in characters.
 */

SIZE *getsize(void)
{
	static SIZE size;

	char	*xptr;
	char	*yptr;

	if((xptr = (char *)getenv("COLUMNS")) && (yptr = (char *)getenv("LINES")))
	{
		size.x = atoi(xptr);
		size.y = atoi(yptr);
	}
	else
	{
		size.x = 0;
		size.y = 0;
	}

	return(&size);
}

/*
 * void ring_my_bell(char *dat, size_t size);
 *
 * Outputs the name of the user specified by the parameter <dat> and <size>
 * followed by the word "DING!" in the users conference window and rings
 * the terminal bell. This function is called from rcv_sv_msg() whenever
 * a MSG_WAKEUP message is received from the remote conference server.
 */

void ring_my_bell(char *dat, size_t size)
{
	u_char name[VPNICKSIZE+1];

	BZERO(name, VPNICKSIZE+1);
	BCOPY(dat, name, (size > VPNICKSIZE) ? VPNICKSIZE : size);

	putchar(BEL);

	cprintf(chat, "(%s%s%s) %s%sDING!%s", S_FG_CYN, name, S_OFF,
		S_BOLD, S_BLINK, S_OFF);
}


syntax highlighted by Code2HTML, v. 0.9.1