/*
** File: hey_arg.c
** Desc: Parse the arguments to hey, including constructing the list
**       of usernames etc. Also handles the environment variables
**       supported
** Auth: Cian Synnott <pooka@redbrick.dcu.ie>
** Date: Mon Nov  9 19:35:21 GMT 1998
**
** $Id: hey_arg.c,v 1.3 2002/01/05 01:58:56 c-hey Exp $
*/

#include "hey_arg.h"
#include "aux.h"

/* If strdup() is not present, change references to strdup() to 
** mystrdup() */
#ifndef HAVE_STRDUP
#define strdup mystrdup
#endif

/* 
** Those things which one can set via environment variables.
** I'll leave strings to be malloc()'d later, when we find out what 
** length they are.
*/
int   hey_wrap;				/* word-wrapping limit */
int   hey_nousers=0;			/* number of users getting heyed */
char *hey_title;			/* 'title' message for the hey */
char *hey_borders;			/* string containing the border chars */
char *hey_success;			/* string to output on success */
char *hey_eof;				/* replacement EOF */
char *hey_prompt;                       /* string to use as hey prompt */
int   hey_maxnames;			/* maximum number of names in prompt */
/*
** Suppress the potentialy annoying mesg status warning
*/
int mesg_warning_suppress = 0;


/* List to hold all the users in */
g_list *hey_userlist = NULL;

/* Create a new user, and parse the argument string into their name & tty */
hey_user *hey_userNew(char *argstring) {
	hey_user *u;
	int i;

	if (!(u = (hey_user *) malloc(sizeof(hey_user)))) 
		perror_exit("Error while allocating a user");

	for (i = 0; i < NAMELEN && *(argstring + i) && *(argstring + i) != '.'; i++) 
		u->name[i] = *(argstring + i);
	u->name[i] = 0;

	if (*(argstring + i) == '.') {
		i++;
		strncpy(u->tty, argstring + i, TTYLEN);
	} else 
		u->tty[0] = 0;


	hey_nousers++;
	u->exists = 0;
	u->login = 0;
	u->mesg = 0;

	return u;
}

/* Free the space taken by a user */
void  hey_userFree(hey_user *u) {
	free(u);
}

/* Key a user on their name */
int   hey_userKey(void *key, void *data) {
	char *name = (char *) key;
	hey_user *u = (hey_user *) data;

	if (!strncmp(name, u->name, NAMELEN)) {
		return 1;
	} else
		return 0;
}

/*
** Usage & credit statements. :o) 
*/
void hey_usage(void) {
	printf ("Usage: hey [-wthmcbsepn] user[.tty] [...]\n"
			"    -w <wrap>        Specifies what column to wrap words at.\n"
			"    -t <title>       Specifies the title string for the message.\n"
			"    -b <borderstr>   Specifies the message's border.\n"
			"    -s <successmsg>  Specifies message to print on success.\n"
			"    -e <eofstring>   Specifies an alternative EOF string.\n");
	/* gcc 3.0 warning demands we split this string :) */
	printf (
			"    -p <prompt>      Specifies the prompt string.\n"
			"    -n <maxnames>    Specifies the maximum number of names prompted.\n"
			"    -m               Ignore potentially annoying mesg n warnings.\n"
			"    -c               Shows the credits.\n"
			"    -h               Shows this listing.\n"
			"Refer to the manpage for further information on the options.\n");
}

void hey_credits(void) {
	printf ("c-hey v%s (c) 2001 Cian Synnott <pooka@redbrick.dcu.ie>\n"
"A C implementation of the 'hey' command found here and there in Perl.\n"
"See the copyright notice in the distribution for more info on hey's history.\n"
"The distribution is available at http://c-hey.redbrick.dcu.ie/\n", HEY_VERSION);
}

/* Parse all the input options */
void hey_parse_options(int argc, char *argv[]) {
	hey_user *u;
	int option;

	/* Cycle through options */
	opterr = 0;
	while ((option = getopt(argc, argv, "w:t:hmcvb:e:s:p:n:")) != EOF) {
		switch (option) {
			
			/* Word wrapping */
			case 'w' :
				hey_wrap = atoi(optarg); 
				if (hey_wrap < 10 || hey_wrap > 70) {
					hey_wrap = DEFAULT_HEY_WRAP;
				}
				break;

			/* Title string */
			case 't':
				if (!(hey_title = strdup(optarg))) 
					perror_exit("Error while allocating title");
				if (strlen(hey_title) > 70) {
					free(hey_title);
					hey_title = DEFAULT_HEY_TITLE;
				}
				break;
			
			/* Help me!!! */
			case 'h':
			case '?':
				hey_usage();
				exit(0);
				break;
				
			/* Show credits */	
			case 'v':	   /* version alias */
			case 'c':
				hey_credits();
				exit(0);
				break;
         
         		/* suppress the mesg status warning */
         		case 'm':
            			mesg_warning_suppress = 1;
           			break;
            

			/* Set the border string */
			case 'b':
				if (!(hey_borders = strdup(optarg))) 
					perror_exit("Error while allocating borders");
				if (strlen(hey_borders) > 9 || strlen(hey_borders) < 5) {
					hey_borders = DEFAULT_HEY_BORDERS;
				}
				break;

			/* set the eof string */
			case 'e':
				if (!(hey_eof = strdup(optarg)))
					perror_exit("Error while allocating eofstring");
				break;

			/* Set the success message */
			case 's': 
				if (!(hey_success = strdup(optarg))) 
					perror_exit("Error while allocating success message");
				break;
		
			/* the prompt */	
			case 'p':
				if (!(hey_prompt = strdup(optarg)))
					perror_exit("Error while allocating prompt");
				break;

			case 'n':
				hey_maxnames = atoi(optarg);
				break;

		} /* End switch */
	
	} /* End while */

	/* If there're no more arguments, no users have been specified */
	if (optind == argc) {
		hey_usage();
		exit(1);
	}
		
	/* Allocate space for the userlist */
	hey_userlist = g_listAlloc(hey_userKey);
	
	/* Now we cycle through the remaining arguments and pop them into the
	** userlist */
	for (; optind < argc; optind++) {
		u = hey_userNew(argv[optind]);
		g_listAppend(hey_userlist, u, hey_userFree);
	}

	/* Rockin'. We're finished here */
	return;
}

/* Checks for hey environment variables, and failing that sets them to their
** default values. No need to return a value as failure here will be of the
** memory variety, and we can therefore barf & exit */
void hey_get_env(void) {
	char *envar;

	/* Wrap first ... */
	if (!(envar = getenv("HEY_WRAP"))) {
		hey_wrap = DEFAULT_HEY_WRAP;
	} else {
		hey_wrap = atoi(envar);
		if (hey_wrap < 10 || hey_wrap > 70) {
			hey_wrap = DEFAULT_HEY_WRAP;
		}
	}
	
	/* Now title */
	if (!(envar = getenv("HEY_TITLE"))) {
		hey_title = DEFAULT_HEY_TITLE;
	} else {
		if (!(hey_title = strdup(envar))) 
			printerr_exit("Woah, memory error while allocating the title.\n");
			
		if (strlen(hey_title) > 70) {
			free(hey_title);
			hey_title = DEFAULT_HEY_TITLE;		
		}
	}

	/* Now borders */
	if (!(envar = getenv("HEY_BORDERS"))) {
		hey_borders = DEFAULT_HEY_BORDERS;
	} else {
		if (!(hey_borders = strdup(envar))) 
			printerr_exit("Woah, memory error while allocating the borders.\n");
		
		if (strlen (hey_borders) > 9 || strlen (hey_borders) < 5) {
			hey_borders = DEFAULT_HEY_BORDERS;
		}
	}

	/* Now prompt */
	if (!(envar = getenv("HEY_PROMPT"))) {
		hey_prompt = DEFAULT_HEY_PROMPT;
	} else {
		if (!(hey_prompt = strdup(envar)))
			printerr_exit("Woah, memory error while allocating prompt");
	}

	/* Now maxnames */
	if (!(envar = getenv("HEY_MAXNAMES"))) {
		hey_maxnames = DEFAULT_HEY_MAXNAMES;
	} else {
		hey_maxnames = atoi(getenv("HEY_MAXNAMES"));
	}

	/* replacement EOF */
	if (!(envar = getenv("HEY_EOF"))) {
		hey_eof = NULL;
	} else {
		if (!(hey_eof = strdup(envar))) {
			printerr_exit("Woah, memory error while allocating the replacement EOF.\n");
		}
	}

	/* Finally, success */
	if (!(envar = getenv("HEY_SUCCESS"))) {
		hey_success = DEFAULT_HEY_SUCCESS;
	} else {
		if (!(hey_success = strdup(envar))) 
			printerr_exit("Woah, memory error while allocating the borders.\n");
	}

	return;
}


