/***************************************************************************
 *						INVESTMENT INTELLIGENCE SYSTEMS CORPORATION
 *
 *									PROPRIETARY DATA
 *
 *		THIS DOCUMENT CONTAINS TRADE SECRET DATA WHICH IS THE PROPERTY OF
 *		INVESTMENT INTELLIGENCE. THIS DOCUMENT IS SUBMITTED TO RECIPIENT IN
 *		CONFIDENCE. INFORMATION CONTAINED HEREIN MAY NOT BE USED, COPIED OR
 *		DISCLOSED IN WHOLE OR IN PART EXCEPT AS PERMITTED BY WRITTEN AGREEMENT
 *		SIGNED BY AN OFFICER OF INVESTMENT INTELLIGENCE SYSTEMS CORPORATION
 *
 *		THIS MATERIAL IS ALSO COPYRIGHTED AS AN UNPUBLISHED WORK UNDER
 *		SECTIONS 104 AND 408 OF TITLE 17 OF THE UNITED STATES CODE.
 *		UNAUTHORIZED USE, COPYING OR OTHER REPRODUCTION IS PROHIBITED BY LAW.
 *
 *		Title:	WZClient.c
 *		Sccsid:	@(#)WZClient.c	3.3.1.5	09/29/98	10:53:47
 *		Author:	Phil Shotton
 *		Created:	Wed 26 Mar 18:12:45 1997
 *
 ***************************************************************************/

/*
 * Program to send commands to a Wingz using the WZListen boundin
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#include "wzlisten.h"

static char * pname;
static int debuglvl = 0;

void usage(void)
{
    fprintf(stderr,"Usage:\n\t%s [ -d ] [ -h host ] [ -p port ] [ -s password ] command | -f commfile\n\n",pname);
    exit(1);
}

void main(int argc, char ** argv)
{
    extern char *optarg;			 /* defined by getopt() */
    extern int optind;				 /* defined by getopt() */
    extern int opterr;				 /* defined by getopt() */
    int c;					 /* return from getopt() */
    char * host, *port, *ifile, *secure;
    int sock;
    char buff[TT_MAXCMD_LEN];

    host = "localhost";
    port = TT_COMMPORT;
    ifile = NULL;
    buff[0] = '\0';
    secure = "";
    
    pname = argv[0];

    while ((c = getopt(argc, argv, "dh:p:f:s:")) != -1)
    {
	switch (c)
	{

	case 'h': host = optarg; break;
	case 'p': port = optarg; break;
	case 'f': ifile = optarg; break;
	case 'd': debuglvl = 1; break;
	case 's': secure = optarg; break;
	default: usage();
	    break;
	}
    }

    if(NULL == ifile)
    {
	if(optind >= argc)
	    usage();
    }

    if(!(sock = setupcomm(host,port)))
	exit(errno);

    sprintf(buff, "%s:%d:%d:%s\n", WZ_MAGIC, geteuid(),
	    getegid(), secure);

    write(sock,buff,strlen(buff));
    buff[0] = 0;
    
    if(NULL != ifile)
    {
	FILE * fp;
	if(NULL == (fp = fopen(ifile,"r")))
	{
	    perror("Can't access file:");
	    close(sock);
	    exit(errno);
	}
	while(fgets(buff,TT_MAXCMD_LEN,fp))
	{
            int t = strlen(buff)-1;
            if (buff[t] == '\n')
                buff[t] = ';';
            
	    if(debuglvl)
	    {
		fprintf(stderr,"Sending %s to remote\n",buff);
	    }
	    write(sock,buff,strlen(buff));
	}
        write(sock,"\n",1);
	fclose(fp);
    }
    else
    {
	int i;
	for(i = optind; i < argc; i++)
	{
	    if(i != optind)
		strcat(buff," ");
	    strcat(buff,argv[i]);
	}
	strcat(buff,"\n");
	if(debuglvl)
	{
	    fprintf(stderr,"Sending %s to remote\n",buff);
	}
	write(sock,buff,1+strlen(buff));
    }
    close(sock);
}

int setupcomm(char * host, char * port)
{
    int fd;
    struct servent * svc;
    struct hostent * hst;
    struct sockaddr_in addr_in;
    int on,nport;

    if(debuglvl)
    {
	fprintf(stderr,"Connecting to host %s on port %s\n",
		 host,port);
    }
    if( isallnum(port))
	nport=atoi(port);
    else
    {
	if (NULL == (svc = getservbyname(port,"tcp")))
	{
	    fprintf(stderr,"Can't find service %s\n",port);
	    return 0;
	}
	else
	    nport = ntohs(svc->s_port);
    }
    
    if(NULL == (hst = gethostbyname(host)))
    {
	fprintf(stderr,"Can't find host %s\n",host);
	return 0;
    }

    if (0 > (fd = socket(AF_INET,SOCK_STREAM,0)))
    {
	perror("Can't create socket");
	return NULL;
    }
    
    on = 1;

    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
		   (char*)&on, sizeof(on)))
    {
	perror("Can't setup socket");
	return 0;
    }
    
    memset((char*)&addr_in,0,sizeof(addr_in));
    addr_in.sin_port = htons(nport);
    addr_in.sin_family = AF_INET;
    addr_in.sin_addr.s_addr = ((struct in_addr *)(hst->h_addr))->s_addr;

    if(connect(fd,(struct sockaddr *)&addr_in,sizeof(addr_in)))
    {
	perror("Can't connect");
	return 0;
    }

    if(0 > fcntl(fd, F_SETFL, O_NDELAY))
	perror("Can't setup socket");

    if(debuglvl)
    {
	fprintf(stderr,"Connection successful\n");
    }
    return fd;
}

int isallnum(char * name)
{
    for(;*name;name++)
	if ((!isdigit(*name)) && ('.'  != *name))
	    return 0;
    return 1;
}
