/*
 * 4m v2.15 (main.c)
 * (C) Copyright 1990 by Carrick Sean Casey
 * (C) Copyright 1993 by Scott Chasin and Michaeljon Miller
 *
 * 3-24-93 See file COPYING for copyright information.
 *
 * Main module
 */

#include "4m.h"
#include "externs.h"
#include "../h/version.h"
#include "../h/term.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>

#ifdef SOLARIS
# include <sys/dirent.h>
#else
# include <sys/dir.h>
#endif

#include <netinet/in.h>
#include <netdb.h>
#include "../common/select.h"

extern fd_set fdset;


extern void setbuf ();
extern int getopt ();
extern int atoi ();
extern int puts ();
extern void configure ();
extern char *getenv (); 
extern int gethostname ();
extern void srand ();
extern time_t time ();
extern int write ();
extern int printf ();
extern void perror ();
extern int close ();
extern void sendpersonal ();
extern unsigned int sleep ();
extern void do_restrict ();
extern void trapsignals ();
extern char *getloginid ();
extern char *getgecos ();
extern void set_term ();
extern int termcap ();
extern void title ();
extern void status ();
extern void unset_term ();

extern int connecttoport();
extern int strcasecmp();
extern void setpolldelay();
extern void setpolltimeout();
extern int clientserve();

extern int logging ();
extern void closesessionlog ();

int main(argc, argv)
     int argc;
     char **argv;
{
    int c, restrict = 0;
    unsigned short port = 0;
    extern char *optarg;
    char *server = NULL, *nick = NULL, *term, *group = NULL;

    struct hostent *hp;
    struct in_addr localaddr;

    setbuf(stdin, NULL);
    setbuf(stdout, NULL);
    setbuf(stderr, NULL);

    while ((c = getopt(argc, argv, "f:g:n:h:p:l:wrd")) != EOF) {
        switch (c) {

            case 'd':
                dumb = TRUE;
                break;

            case 'f':
                strcpy(config_file, optarg);
                break;

            case 'g':
                group = optarg;
                break;

            case 'h':
                server = optarg;
                break;

            case 'p':
                port = (unsigned short) atoi(optarg);
                break;

            case 'n':
                nick = optarg;
                break;

            case 'l':
                myloginid = optarg;
                break;

            case 'w':
                whoflg++;
                gv.interactive = 0;
                break;

            case 'r':
                restrict = TRUE;
                break;

            default:
                puts("usage: 4m [-rwld] [-n nick] [-g group] [-f 4m.rc]\r");
                puts("-r          Restricted mode\r");
                puts("-w          Who is currently on 4mnet\r");
                puts("-d		 Run 4m in \"Dumb\" terminal mode\r");
                puts("-n nick     Enter with nickname set to nick\r");
                puts("-g group    Enter into specified group\r");
                puts("-f path     Use an alternate 4m.rc\r");
                exit(-1);
                break;
        }
    }

    configure();

    if (server != NULL)
        gv.default_host = server;

    if (port != 0)
        gv.default_port = (int) port;

    if (nick != NULL)
        gv.nick = nick;

    if (group != NULL)
        gv.group = group;


    if (!myloginid || !strlen(myloginid)) {
        if ((myloginid = getenv("LOGIN")) == NULL) {
            if ((myloginid = (char *)getloginid()) == NULL) {
                puts("Error - can't determine your login ID.");
                exit(-1);
            }
        }
    }

    if ((gecos = (char *)getgecos()) == NULL) 
        gecos = "Unknown";

 /* Get our nickname */
    if (!gv.nick || !strlen(gv.nick))
        if ((gv.nick = getenv("NICKNAME")) == NULL)
            gv.nick = myloginid;

    sprintf(mbox, "/usr/spool/mail/%s", myloginid);

    gethostname(localhost, 80);
    if ((hp = gethostbyname(localhost)) != 0) {
        memcpy((char *) &localaddr, hp->h_addr, sizeof(localaddr));
        local_ip = ntohl(localaddr.s_addr);
    }
 /* start up the server if we can and if we must */

    srand((unsigned) time(0));

    if (gv.interactive) {
        if (restrict && !gv.restricted)
            do_restrict();
        sprintf(mbuf, "\n\r\n\rWait .. ");
        write(1, mbuf, strlen(mbuf));
    }
    if (!gv.default_host) {
        printf("\n4m: You must specify a server with the -h <server> parameter.\n");
        exit(-1);
    }
    if (!gv.default_port)
        gv.default_port = 6677;

    if ((connecttoport(gv.default_host, (unsigned short) gv.default_port, 0)) < 0) {
        printf("\n4m: remote server not running.\n");
        exit(-1);
    }
    if (gv.interactive) {
        set_term();

        if ((term = getenv("TERM")) == NULL) {
            printf("\n4m: No TERM environment variable set;");
            printf(" Running in \"dumb\" mode.\n");
            dumb = TRUE;
        }
        if (!strcasecmp(term, "dumb") || !strcasecmp(term, "unknown"))
            dumb = TRUE;

        if (!dumb) {
            startup_t = time(NULL);
            termcap(term);
            page();
            title();
            status(0);
        }
    /* Set up inital poll delays */
        setpolldelay(POLL_DELAY);
        setpolltimeout(IDLE_POLLWAIT);

    /* trap signals */
        trapsignals();
    }
  /* Set up the history table */
  if ((history = (NAMLIST *) malloc((unsigned) sizeof(NAMLIST))) == NULL) {
        printf("4m: Cannot initialize history array.\n");
        exit (-1);
  }
  nlinit(history, gv.history);

  if ((cmd_history = (NAMLIST *) malloc((unsigned) sizeof(NAMLIST))) == NULL) {
        printf("4m: Cannot initialize history array.\n");
        exit (-1);
  }
  nlinit(cmd_history, gv.history);


 /* start the serve loop */
    if (clientserve() < 0) {
        perror("Client server failed");
        exit(-1);
    }
    exit(0);

    /* NOTREACHED */
}

SIGTYPE 
do_exit()
{
    int xindex;

    if (!dumb)
        gotoxy(0, lines - 2);

    if (gv.interactive)
        unset_term();

 /* close the session log */
    if (logging())
        closesessionlog();

 /* Clean out any pending file transfers */
    for (xindex = 0; xindex < MAX_XFERS; xindex++) {
        if (xfer_tab[xindex].status == ACTIVE) {
            if (xfer_tab[xindex].s != -1) {
                FD_CLR(xfer_tab[xindex].s, &fdset);
                close(xfer_tab[xindex].s);
            }
            close(xfer_tab[xindex].fd);
        }
        if (xfer_tab[xindex].status == WAIT) {
            sprintf(mbuf, "%s \002SEND DELETE %s", xfer_tab[xindex].who,
                    xfer_tab[xindex].filename);
            sendpersonal(mbuf);
            sleep(.5);
        }
    }

    exit(0);

    /* NOTREACHED */
}
