/*
 * 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.
 */

/*
 * yahoo - finger for yabbs
 * 
 * usage: yahoo [<name>][@<address>]
 *        if there is a name it will get information on the user <name>
 *        from the yabbs server running at <address>.  If the <name> is 
 *        omitted it will just list who is on the yabbs server running
 *        at <address>.  If the @<address> is omitted it will use the
 *        default server.
 *
 *        multiple name@address requests are handled.
 *
 * thanks to pw1r@andrew.cmu.edu for the patches to make this behave
 * more like real finger.
 */

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "termcap.h"
#include "yabbslib/yabbslib.h"

extern char lower(char i);

extern int bbs_s;
int line, redraw;
int sputs_process;

int usercount, clientcount, channelcount;

void cli_page(char *name) {}
void cli_msgline(char *line, int type, void *null) {}
void cli_msghdrline(int x, char *to, char *from, char *d, char *subject, 
    void *null) {}
void cli_talkline(char *channel, char *name, char *msg, int type) {}
void cli_textline(char *line, void *null) {}
void cli_gfileline(char *line, void *null) {}
void cli_gfileindexline(char *name, char *path, char *type, void *null) {}
void cli_msgbasename(int baseid, char *basename, void *null) {}
void cli_useroptions(char *name, int slen, unsigned long opt, char *subs, 
    void *data) {}
void cli_founduser(char *name, void *null) {}
void cli_announce(int type, char *arg1, char *arg2) {}

#ifdef MSDOS
char *cli_yabbsrcname(void) {
    static char *yabbsrc = "yabbs.rc";
    return yabbsrc;
}

char *cli_hiddenyabbsrcname(void) {
    static char *yabbsrc = "yabbs.rc";
    return yabbsrc;
}
#else
char *cli_yabbsrcname(void) {
    static char *yabbsrc = "yabbsrc";
    return yabbsrc;
}

char *cli_hiddenyabbsrcname(void) {
    static char *yabbsrc = ".yabbsrc";
    return yabbsrc;
}
#endif

/* 
 * just like puts but it handles simple mime
 *
 * based loosly on the demonstration program in rfc1123.
 */
void puts_mime(char *st) {
    int c, i, l, x;
    char token[50];
    static int comment = 0; 

    l = strlen(st); i = 0;
    while (i < l) {
        c = st[i++];
        /* this is a MIME command.                                          */
        if (c == '<') {
            /* read out up to 50 characters of a token                      */
            for (x = 0; ((x < 49) && ((c = st[i++]) != '>') && (i < l)); x++) {
                token[x] = lower(c);
            }
            token[x] = 0;
            if (i > l) break;                       /* end of string        */
            /* if there was any more read till the '>'                      */
            if (c != '>') while (((c = st[i++]) != '>') && (i < l));
            if (i > l) break;                       /* end of string        */

            if (comment) {
                if (strcmp(token, "/comment") == 0) comment--;
            } else {
                if        (strcmp(token, "lt"        ) == 0) {
                    putchar('<');
                } else if (strcmp(token, "nl"        ) == 0) { 
                    putchar('\n');
                } else if (strcmp(token, "/paragraph") == 0) {
                    puts("\n\n");
                } else if (strcmp(token, "comment"   ) == 0) {
                    comment++; 
                } 
            } 
        } else if ((!comment) && (c != '\n')) {
            putchar(c);
        }
    }
    fflush(stdout);
}

void cli_fatalerror(char *msg) {
    printf("FATAL: %s\n", msg);
    exit(1);
}

void cli_error(char *msg) {
    printf("warning: %s\n", msg);
}

void cli_wholine(char *name, char *onfrom, char *onsince, int idle, void *n) {
    printf("%-12s   %-24.24s   %-24.24s   %i\n", 
        name, onfrom, onsince, idle / 60);
    if (onfrom[strlen(onfrom) - 1] != '*') clientcount++;
    usercount++;
}

void cli_planline(char *line, void *null)   {
    puts_mime(line);
    return;
}

void cli_channelline(char *channel, char *users, void *null) {
    if (strncmp(channel, "*priv", 5) == 0) strcpy(channel, "*private*");
    printf("%-12s   %s\n", channel, users);
    channelcount++;
}

void finger_at(void)
{
    usercount = clientcount = 0;
    printf("%-12s   %-24.24s   %-24.24s   %s\n", 
        "user", "host", "on since", "idle");
    printf("-------------------------------------------------------------------------\n");
    bbs_who(NULL);
    printf("%i users online, %i clients, %i local\n", usercount, clientcount,
        usercount - clientcount);
    printf("\n%-12s   %s\n", "channel", "users");
    printf("------------------------------------------------------------------\n");
    bbs_channels(NULL);
    printf("%i channels\n", channelcount);
    return;
}

/* split(name, host)
 *  splits name at the first @ to name and host, like for email and finger.
 *  returns 0, 1, 2, 3 depending if no name or host, name but no host,
 *  no name but host, name and host
 */
int split(char *s, char **name, char **host) {
    int r = 0;

    *host = NULL;
    *name = s;

    while (*s != '\0')  {
        if ((*s == '@') || (*s == '#')) {
            *(s++) = '\0';
            break;
        }
        s++;
    }
    
    *host = s;

    if((*name == NULL)||(strlen(*name) != 0))       r += 1;
    if((*host == NULL)||(strlen(*host) != 0))       r += 2;

    return r;
}
    
void main(int argc, char **argv) {
    int numnames = argc - 1;
    char **names = argv + 1;
    char *server;
    char *uname;

    if (numnames == 0) {
        bbs_connect(NULL);
        finger_at();
        bbs_logout();
        return;
    }

    while (numnames != 0) {
        switch (split(*names, &uname, &server)) {
            case 1: printf("[%s]\n", *names);
                    bbs_connect(NULL);  
                    bbs_getplanfile(*names, NULL);
                    break;
            
            case 2: printf("[@%s]\n", server);
                    bbs_connect(server);
                    finger_at();
                    break;

            case 3: printf("[%s@%s]\n", *names, server);
                    bbs_connect(server);
                    bbs_getplanfile(*names, NULL);
                    break;

            default:printf("Fatal error, should never reach this\n");
                    exit(-1);
                    break;
        }
        putchar('\n');
        bbs_logout();
        numnames--;
        names++;
    }
        
    return;
}
