/*
 * this file is a part of yabbs - yet another bulletin board system.
 * Copyright (C) 1993, 1994 Alex Wetmore.  
 * email: alex@phred.org
 * address: 6 rech ave
 *          oreland pa 19075
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "bbsdefs.h"                        /* function prototypes      */

functable_t rcfuncs[] = {
    { "server", NULL, NULL, rc_server },
    { "volume", NULL, NULL, t_managelist },
    { "ignore", NULL, NULL, t_managelist },
    { "notify", NULL, NULL, t_managelist },
    { "alias", NULL, NULL, t_manageenv },
    { "set", NULL, NULL, t_manageenv },
    { "lock", NULL, NULL, t_managelist },
    { NULL, NULL, NULL, NULL }
};

int rc_server(char *st, int argc, char **argv) {
    return TRUE;
}

/*
 * read the .yabbsrc file and set user options from it
 */
void readrc(char *filename) {
    FILE *f;
    char fcmd[256];

    inrc = TRUE;
    f = fopen(filename, "r");
    if (f != NULL) {
        while (!feof(f)) {
            int rc;
            char errorstring[256];

            /* read a command from the rc file and parse it         */
            if (fgets(fcmd, 255, f) == NULL) continue;
            fcmd[255] = 0;
            fcmd[strlen(fcmd) - 1] = 0;

            /* ignore comments                                      */
            if (fcmd[0] == '#') continue;

            rc = parseandrun(rcfuncs, NULL, fcmd, errorstring);
            if (!rc) {
                char buf[256];

                sprintf(buf, "*** error \"%s\" in yabbsrc file %s ***\n", 
                    errorstring, filename);
                sputs(buf);
            }
        }
        fclose(f);
    }
    inrc = FALSE;
}

/*
 * the configuration menu.  Just call other procedures as needed.
 */

int doconfig(void) {
    char    cmd, temp[7];
    int     bye, done;

    bye = done = FALSE;
    while (!done) {
        bbs_clrscr(); drawuser();
        if (!(userinfo.options & O_XPERT)) sputs_mime(MNU_CONFIG);
        sputs("config: [plsxiqg?] ");
        cmd = waitfor("plsxiqg?");
        switch (lower(cmd)) {
            case '?' :  
                sputs("help\n\n"); 
                sputs_mime(MNU_CONFIG); 
                waitkey(); 
                break;
            case 'p' :  
                sputs("password\n\n"); 
                changepw(); 
                break;
            case 'l' : 
                sputs("lines\n\nIf you set lines to 0 \"more prompting\" will be disabled.\n");
                sputs("Also, setting this to 10 or less is not recommended.\n\n");
                sputs("How many lines does your screen have? ");
                sgets(temp, 5);
                userinfo.scrlen = atoi(temp);
                break;
            case 's' : 
                sputs("subscriptions\n\n"); 
                changesubs();
                break;
            case 'x' : 
                sputs("expert toggle\n\n"); 
                userinfo.options = userinfo.options ^ O_XPERT; 
                break;
            case 'i' :
                sputs("info file edit\n\n"); 
                changeplan(userinfo.name); 
                break;
            case 'g' : 
                sputs("goodbye\n\n"); 
                done = bye = TRUE; 
                break;
            case 'q' : 
                sputs("quit\n\n"); 
                done = TRUE; 
                bye = FALSE; 
                break;
            default  : 
                sputs("what?\n\n");
                break;
        }
    }
    saveopts();
    return bye;
}

/*
 * make a new user.  Ask them for their name, password, and then run
 * doconfig to let them do the rest.  They are automatically given access
 * to email and the first sub, and subscribed to both.
 */

int newuser(void) {
    char    name[9];
    int     okayname = FALSE;
        
    dumpsvr(F_NEWUSER);
    do {
        sputs("What would you like your name to be? (8 chars) ");
        sgets(name, 8);
        if (bbs_newuser(name, "newuser")) okayname = TRUE;
    } while (!okayname);
    strcpy(userinfo.name, name);
    changepw();
    return 0;
}

/*
 * allow a user to login.  If they enter new, create a new user, otherwise
 * check to make sure that their password and id match.  If they can't get
 * in after 5 trys dump them, otherwise return their user number.
 */

int login(void) {
    char    name[9], pass[9], buf[255];
    int     usr, attempts = 0, okaylogin;

    do {
        sputs("\nlogin: "); sgets(name, 8);
        if (strcmp(name, "new") == 0) {
            usr = newuser();
            strcpy(name, userinfo.name);
            okaylogin = TRUE;
        } else {
            sputs("password: "); sgetpw(pass);
            okaylogin = bbs_login(name, pass);
        }
    } while ((!okaylogin) && (++attempts < 10));
    strcpy(userinfo.name, name);
    if (attempts >= 10) {
        sputs("\nYou appear to being having trouble accessing your account,\n");
        sputs("please try again later.\n");
        return FALSE;
    }
    bbs_getoptions(NULL);
    bbs_clrscr();
    sprintf(buf, "welcome to yabbs, %s\n", name); sputs(buf);
    dumpsvr(F_NEWS);
    return TRUE;
}

/*
 * the main menu of the bbs.  Just call the appropriate procedure...
 */

void dobbs(void) {
    char    cmd, keystr[20], st[80];
    int     done;

    readbases();
    countnew();
    drawuser();
    done = FALSE;
    while (!done) {
        sputs("\n");
        if (!(userinfo.options & O_XPERT)) sputs_mime(MNU_MAIN);
        strcpy(keystr, "msciwtyfg!?"); 
        sprintf(st, "main: [%s] ", keystr);
        sputs(st);
        cmd = waitfor(keystr);
        sprintf(st, "%c) ", lower(cmd)); sputs(st);
        switch (lower(cmd)) {
            case '?' : sputs("help\n\n"); sputs_mime(MNU_MAIN); break;
            case 'm' : sputs("messages\n\n"); bbs_clrscr(); done = domessages(); 
                       break;
            case 's' : sputs("setup\n\n"); done = doconfig(); break;
            case 'c' : sputs("talk channels\n\n"); t_channels(NULL, 0, NULL); 
                       break;
            case 'i' : sputs("info on user\n\n"); readplan(userinfo.name); 
                       break;
            case 'w' : sputs("who\n\n"); who(); break;
            case 'g' : sputs("goodbye\n\n"); 
                       done = ynprompt("Are you sure? [Yn] ", TRUE); break;
            case 'y' : sputs("yalk\n\n"); dotalk(); break;
            case 't' : sputs("talk\n\n"); dotalk(); break;
            case 'u' : sputs(
                             "undocumented features, we gotta lot of them\n\n"
                       ); break;
            case 'f' : sputs("gfiles\n\n"); dogfil(""); break;
            case '!' : sputs("gnuinfo\n\n"); dumpsvr("COPYING-2.0"); break;
            default  : sputs("what?\n\n");
        }
    }
    sputs("\nlater . . .");
    sputs("\nPlease send any feedback that you may have about this software to:");
    sputs("\n  alex@phred.org\n");
}

void initenv(void) {
    char *st;

    inrc = TRUE;
    st = getenv("YPAGER");
    if (st != NULL) addtoenv("pager", st);
    else {
        st = getenv("PAGER");
        if (st != NULL) addtoenv("pager", st);
        else addtoenv("pager", DEFPAGER);
    }

    st = getenv("YEDITOR");
    if (st != NULL) addtoenv("editor", st);
    else {
        st = getenv("EDITOR");
        if (st != NULL) addtoenv("editor", st);
        else addtoenv("editor", DEFEDITOR);
    }
    inrc = FALSE;
}

/*
 * the main loop.  Wait for a connection, let the person login, if they do
 * succesfully then give them the main menu, otherwise drop their connection.
 */

void yabbsmain(int argc, char **argv) {
    char    timeb[35];
    time_t  tp;
    char    buf[1024], *home;
    char    *onfrom;

    /* init some variables                                              */
    ignores = NULL;
    nocaps = NULL;
    aliases = NULL;
    notify = NULL;
    env = NULL;
    locked = NULL;

    initenv();

    /* read the yabbsrc files                                           */
    home = getenv("HOME");
    sprintf(buf, "%s/%s", (home == NULL) ? "" : home, cli_hiddenyabbsrcname()); 
    readrc(buf);
    sprintf(buf, "%s/%s", LOCALETC, cli_yabbsrcname()); 
    readrc(buf);

    signal(SIGINT, sigquit);                /* normal quit signals      */
    signal(SIGQUIT, sigquit);
#ifdef JOBCONTROL
    signal(SIGTSTP, sigstop);               /* stop signal              */
    signal(SIGCONT, sigcont);               /* stop signal              */
#endif

    userinfo.scrlen = 0;                    /* don't pause on startup   */

    bbs_s = -1;
    terminit();

    sprintf(buf, "\n%s %s client - ver %s,\n%s%s", YABBSNAME, yabbssystype(),
        CLIENTVERSION, YABBSGNUHI, YABBSGNUCLI);
    sputs(buf);

    /* connect to a server                                              */
    sprintf(buf, "Connecting to %s . . . ", 
        (argc == 1) ? "default server" : argv[1]);
    sputs(buf);
    if (argc == 2) bbs_connect(argv[1]);
    else bbs_connect(NULL);
    sputs("connected!\n");

    /* if a home directory isn't set, set the one defined in CLIHOME    */
    if (home == NULL) {
        sprintf(buf, "HOME=%s", CLIHOME);
        putenv(buf);
    }

    getterm();

    dumpsvr(F_WELCOME);                     /* dump welcome file        */

    tp = time(NULL);                        /* get the time into a stng */
    strcpy(timeb, ( char *) ctime(&tp));
    timeb[strlen(timeb) - 1] = 0;
    sputs("the last few users: (the current time is "); 
    sputs(timeb); sputs(")\n");
    dumpsvr(F_LASTU);                       /* dump lastuser file       */

    if ((onfrom = getenv("HOSTFROM")) != NULL) bbs_onfrom(strlwr(onfrom));

    if (login()) dobbs();

    killconnection(K_SILENT);               /* logout                   */
}

/*
 * list all online users from the command line
 */

void yahoomain(int argc, char **argv) {
    who();
}
