/*
 * 4m v2.15 (msgs.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.
 *
 * Message protocol parsing
 */

#include "4m.h"
#include "externs.h"
#include "../h/version.h"
#include <ctype.h>

#ifdef HAS_STRINGS
# include <strings.h>
#endif

#ifdef HAS_STRING
# include <string.h>
#endif

#include "../h/term.h"


extern char *getword ();
extern void mbreakprint ();
extern char *skipword ();
extern void parse ();
extern void putl ();
extern void split ();
extern void do_exit ();
extern int atoi ();
extern void sendlogin ();
extern time_t time ();
extern void sendcmd ();
extern int nlcount ();
extern char *nlget ();
extern int parse_packet ();
extern char *get_tail ();
extern char *idle_time ();
extern char *local_ampm ();
extern char *signon_time ();
extern long int atol ();
extern char *datestr ();
extern char *idlephrase ();
extern char *strchr ();


extern void status ();


extern int ishushed ();

void c_openmsg(pkt)
     char *pkt;
{
    char from [15];

    strcpy (from, getword(pkt));

    if (ishushed(from))
        return;

    mbreakprint(0, from, skipword(pkt));

    return;
}

/* Admin messages */

void c_adminmsg(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s", words[0], args);
    putl(mbuf, PL_ALL);

    return;
}

/* personal message */

void m_personal(pkt)
     char *pkt;
{
    char from[16], *text;

    parse(pkt);
    strcpy(from, words[0]);
    text = args;

    if (ishushed(from))
        return;

    if (!numwords) {
       strcpy(msg_from, from);
       strcpy(msg_str, text);
       build (gv.p_msgformat, mbuf);
       putl (mbuf, PL_ALL);
       return;
    }

    mbreakprint(1, from, text);

    return;
}

/* beep message */

void beep(pkt)
     char *pkt;
{
    split(pkt);

    if (ishushed(fields[0]))
        return;

    if (gv.beeps)
        sprintf(mbuf, "%c[Beep!] %s sent you a beep.", '\007', fields[0]);
    else
        sprintf(mbuf, "[Beep!] %s sent you a beep.", fields[0]);

    putl(mbuf, PL_SCR);

 /* logs and review buffers don't get audible beeps */
    sprintf(mbuf, "[Beep!] %s sent you a beep.", fields[0]);
    putl(mbuf, (PL_BUF | PL_LOG));

    return;
}

/* "please drop the connection" message */

void exitmsg()
{
    do_exit();

    /* NOTREACHED */
}


/* protocol version message */

void protomsg(pkt)
     char *pkt;
{
    char  str[9];
    int proto_level;

    split(pkt);

    proto_level = atoi(fields[0]);

    if (!whoflg) {
        sprintf(mbuf, "Connected to %s (%s/p%d).",
                fields[1], fields[2], proto_level);
        putl(mbuf, PL_SCR);
    }

    memset(str, 0, sizeof(str));
    strncpy(str, myloginid, 8);

/*  if (strlen(myloginid) > 8)
     str[8] = 0; */

    if (whoflg)
    /* we want a who */
        sendlogin(str, gv.nick, gv.group, "who");
    else
    /* we want to log in */
        sendlogin(str, gv.nick, gv.group, "login");

    return;
}


/* server is telling us we are logged in */

void loginokmsg(pkt)
     char *pkt;
{
    int i, cnt;

    connected = TRUE;
    startup_t = time(NULL);

    if (!echoback)
        sendcmd("echoback", "off");

    cnt = nlcount(notify);
    for (i = 0; i < cnt; i++)
        sendcmd("notify", nlget(notify));

    cnt = nlcount(execute);
    for (i = 0; i < cnt; i++)
        parse_packet(nlget(execute));

    strcpy(nick, gv.nick);
    status(1);

    return;
}

/* system status update message */

void statusmsg(pkt)
     char *pkt;
{
    if (!strcmp(fields[0], "RSVP"))
        if (ishushed(getword(fields[1])))
            return;

    sprintf(mbuf, "[%s] %s", getword(pkt), get_tail(pkt));
    putl(mbuf, PL_ALL);

    return;
}

void output(pkt)
     char *pkt;
{
    putl(pkt, PL_SCR | PL_LOG);

    return;
}

void cmdoutmsg(pkt)
     char *pkt;
{

    parse(pkt);


    if (!dumb)
        hidecursor();

    if (strcmp(words[0], "wg") == 0) {

        if (*fields[2] == '\0') {
            sprintf(mbuf, ">%s", words[1]);
            putl(mbuf, PL_SCR | PL_LOG);
        } else {
            sprintf(mbuf2, ">%s", words[1]);
            sprintf(mbuf, "%-9s  %s", mbuf2, words[2]);
            putl(mbuf, PL_SCR | PL_LOG);
        }

    } else if (strcmp(words[0], "c") == 0) {
        sprintf(mbuf, "%c%s", gv.cmdchar, words[1]);
        putl(mbuf, PL_SCR | PL_LOG);
    } else
    /* just some generic command output */
        putl(args, PL_SCR | PL_LOG);

    if (!dumb)
        showcursor();

    return;
}

void page_output(pkt)
     char *pkt;
{
    int oldsize;

    oldsize = gv.pagesize;
    gv.pagesize = lines;
    putl(pkt, PL_SCR | PL_LOG);
    gv.pagesize = oldsize;

    return;
}


void errormsg(pkt)
     char *pkt;
{
    char buf[255];

    sprintf(buf, "[Error] %s", pkt);
    putl(buf, PL_ALL);

    return;
}


/* important system message */

void importantmsg(pkt)
     char *pkt;
{
    sprintf(mbuf, "\007[%s] %s", getword(pkt), get_tail(pkt));
    putl(mbuf, PL_ALL);

    return;
}

void groupheader(pkt)
     char *pkt;
{
    parse(pkt);

    putl(" ", PL_ALL);
    sprintf(mbuf, "Group: %-8s     %s", words[0], get_tail(args));
    putl(mbuf, PL_ALL);
    putl("   Nickname     S   Idle   Sign-On  Account", PL_SCR | PL_LOG);

    return;
}

void whoheader(pkt)
     char *pkt;
{
    putl("   Nickname     S   Idle   Sign-On  Account", PL_SCR | PL_LOG);

    return;
}

void wholisting(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "  %c%-12s %-3s%-7s %s  %s@%s  %s",
            *words[1] == 'm' ? '*' : ' ',
            words[2],
            words[3],
            idle_time(atoi(words[4])),
            signon_time ((time_t) atol(words[6]), 0),
            words[7], words[8], words[9]);

    putl(mbuf, PL_SCR | PL_LOG);

    return;
}

void m_chnick(pkt)
     char *pkt;
{
    strcpy(nick, pkt);
    status(1);

    return;
}

void m_chgroup(pkt)
     char *pkt;
{

    parse(pkt);

    strcpy(group, words[1]);
    strcpy(mode, words[2]);

    parse(args);
    parse(args);

    topic = args;

    status(1);

    sprintf(mbuf, "[Join] You are now in group: %s", group);
    putl(mbuf, PL_ALL);

    if (strlen(topic) > 1) {
        sprintf(mbuf, "[Topic] %s", topic);
        putl(mbuf, PL_ALL);
    }

    return;
}

void m_sendingto (pkt)
     char *pkt;
{
    parse (pkt);
    strcpy (group, words[0]);
    status (1);
}  

void m_signon(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s (%s@%s) has just arrived.", words[0], words[1],
            words[2], words[3]);

    putl(mbuf, PL_ALL);

    return;
}

void m_join(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s (%s@%s) has just arrived.", words[0], words[1],
            words[2], words[3]);
    putl(mbuf, PL_ALL);

    return;
}

void m_signoff(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s just signed off.", words[0], words[1]);
    putl(mbuf, PL_ALL);

    return;
}

void m_part(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s just left the group.", words[0], words[1]);
    putl(mbuf, PL_ALL);

    return;
}

void m_action(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[Action] %s", args);
    putl(mbuf, PL_ALL);

    return;
}

void m_away(pkt)
     char *pkt;
{
    putl("[Away] You are now marked as away.", PL_ALL);
    away = TRUE;

    return;
}

void m_awaymsg(pkt)
     char *pkt;
{
    strcpy(awaymsg, pkt);
    status(1);

    return;
}

void m_here(pkt)
     char *pkt;
{
    putl("[Away] You are now marked as here.", PL_ALL);
    away = FALSE;
    memset(awaymsg, 0, strlen(awaymsg));
    status(1);

    return;
}

void m_name(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s is now known as %s", words[0], words[1], words[2]);
    putl(mbuf, PL_ALL);

    return;
}

void m_invite(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[Invite] You have been invited to group %s by %s",
            words[1], words[2]);
    putl(mbuf, PL_ALL);

    return;
}

void m_kick(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s kicked %s from the group.", words[0],
            words[1], words[2]);
    putl(mbuf, PL_ALL);

    return;
}

void m_kicked(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[Kick] %s", args);
    putl(mbuf, PL_ALL);

    return;
}

void m_topic(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[Topic] %s", args);
    putl(mbuf, PL_ALL);

    return;
}

void m_chtopic(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s changed the topic to: %s", words[0], words[1], 
            get_tail(args));
    putl(mbuf, PL_ALL);

    return;
}

void m_members(pkt)
     char *pkt;
{
    sprintf(mbuf, "[Members] %s", pkt);
    putl(mbuf, PL_ALL);

    return;
}

void m_whois(pkt)
     char *pkt;
{
    int mins;
    char action[24];

    parse(pkt);
    parse(args);

    mins = atoi(words[5]) / 60;

    if (mins > 5 && mins < 20)
        strcpy(action, "lurking");
    else if (mins > 20)
        strcpy(action, "sleeping");
    else
        strcpy(action, "currently");

    sprintf(mbuf, "[Whois] %s is %s@%s.", words[0], words[1], words[2]);
    putl(mbuf, PL_ALL);

    sprintf(mbuf, "[Whois] On via server %s since %s %s.", words[3],
        local_ampm((time_t) atol(words[4]), 0), datestr(atol(words[4])));
    putl(mbuf, PL_ALL);

    if (atoi(words[5]) > 1) {
        sprintf(mbuf, "[Whois] Has been idle for %s.", idlephrase(words[5]));
        putl(mbuf, PL_ALL);
    }
    sprintf(mbuf, "[Whois] Currently running client version %s.", words[11]);
    putl(mbuf, PL_ALL);

    if (atoi(words[9]) > 1 && atoi(words[10]) > 1) {
        sprintf(mbuf, "[Whois] Has sent %d messages (%d bytes total).",
                atoi(words[9]), atoi(words[10]));
        putl(mbuf, PL_ALL);
    }
    sprintf(mbuf, "[Whois] Is %s in group %s", action, words[6]);
    if (words[7][0] == 'M')
        strcat(mbuf, " as a moderator.");
    else
        strcat(mbuf, ".");
    putl(mbuf, PL_ALL);

    if (words[8][0] == '@')
        putl("[Whois] Is a 4m operator.", PL_ALL);

    return;
}

void m_motd(pkt)
     char *pkt;
{
    putl(pkt, PL_ALL);

    return;
}

void m_echobackp(pkt)
     char *pkt;
{
    parse(pkt);
    mbreakprint(2, words[0], args);

    return;
}

void m_userisaway(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[Away] %s is marked as away.", words[0]);
    putl(mbuf, PL_ALL);

    sprintf(mbuf, "[Away] Reason: %s", args);
    putl(mbuf, PL_ALL);

    return;
}

void m_groupmode(pkt)
     char *pkt;
{
    char modebuf[50];

    parse(pkt);

    if (strchr(words[1], 'r'))
        strcpy(modebuf, "Restricted ");

    if (strchr(words[1], 'm'))
        strcat(modebuf, "Moderated ");

    if (strchr(words[1], 'q'))
        strcat(modebuf, "Quiet ");

    if (strchr(words[1], 'a'))
        strcat(modebuf, "Announcements ");

    if (strchr(words[1], 'l'))
        strcat(modebuf, "Anonymous ");

    if (strchr(words[1], 't'))
        strcat(modebuf, "Topic-allowed ");

    if (strchr(words[1], 'i'))
        strcat(modebuf, "Invisible ");

    sprintf(mbuf, "[Modes]  %s", modebuf);
    putl(mbuf, PL_ALL);

    return;
}

void m_groupmods(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[Moderators] %s", args);
    putl(mbuf, PL_ALL);

    return;
}

void m_groupinvites(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[Invites] %s", args);
    putl(mbuf, PL_ALL);

    return;
}

void m_groupmisc(pkt)
     char *pkt;
{
    parse(pkt);

    putl("", PL_ALL);
    sprintf(mbuf, "[Status] Group %s was created at %s on %s.", words[0],
            local_ampm(atol(words[1]), 0), datestr(atol(words[1])));
    putl(mbuf, PL_ALL);

    sprintf(mbuf, "[Status] Has had %s visitors and %s topic changes.",
            words[5], words[2]);
    putl(mbuf, PL_ALL);

    sprintf(mbuf, "[Status] There has been %s mode changes and %s user kicks.",
            words[4], words[3]);
    putl(mbuf, PL_ALL);

    return;
}

void m_chmode(pkt)
     char *pkt;
{
    parse(pkt);

    strcpy (mode, words[2]);
    status (1);

    sprintf(mbuf, "[%s] %s changed mode to ", words[0], words[1]); 
    parse (args);
    parse (args);
    strcat (mbuf, args);

    putl (mbuf, PL_ALL);

    return;
}

void m_claim(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s has claimed moderatorship of the group.",
            words[0], words[1]);
    putl(mbuf, PL_ALL);

    return;
}

void m_demoted(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s has demoted %s.", words[0], words[1], words[2]);
    putl(mbuf, PL_ALL);

    return;
}

void m_promoted(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[%s] %s has promoted %s.", words[0], words[1], words[2]);
    putl(mbuf, PL_ALL);

    return;
}

void m_refuse(pkt)
     char *pkt;
{
    sprintf(mbuf, "[Refuse] %s", pkt);
    putl(mbuf, PL_ALL);

    return;
}

void m_servheader(pkt)
     char *pkt;
{
    parse(pkt);

    putl ("Server Name              Port    Users    Info", PL_ALL);
}

void m_servers(pkt)
     char *pkt;
{
    int s_port, s_users;
    long s_timeon;
    char s_name[MAX_NODELEN];

    parse (pkt);

    strcpy (s_name, words[0]);
    s_port = atoi (words[1]);
    s_timeon = atol (words[2]);
    s_users = atoi (words[3]);

    parse (args);
    parse (args);
    parse (args);

    sprintf (mbuf, "%-25s%d     %-2d      %s", s_name, s_port, s_users, args);
    putl (mbuf, PL_ALL);
}

void m_notify(pkt)
     char *pkt;
{
    parse(pkt);

    sprintf(mbuf, "[Notify] %s: %s (%s@%s)", words[0], words[1], words[2],
            words[3]);
    putl(mbuf, PL_ALL);

    return;
}


