
/*
Eagles Bulletin Board System
Copyright (C) 1994, Ray Rocker, rrrocker@rock.b11.ingr.com
                                rock@seabass.st.usm.edu
                                72673.2105@compuserve.com

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 "client.h"
#include <ctype.h>
#include <malloc.h>

extern LOGININFO myinfo;
extern char *currentboard;
char *_menudesc_file;

/* New Menu Function */

int GetMenuIndex(t)
unsigned int t ;
{
    t = (t | 0x20) - 'a' ;
    return t % MAXMENUSZ ;
}

char InterpretMenuAction(action) 
char *action;
{
  if(action[0] != '$')
    return action[0] ;
  if(bbs_check_mail())
    return action[2] ;
  return action[1] ;
}

extern NMENU *bigMenuList ;

NMENU *menuEnt[MAXMENUDEPTH] ;
int currMenuEnt = -1 ;


/*ARGSUSED*/
int 
NDoMenu(menu_name)
char *menu_name ;
{
  int found, update = FULLUPDATE;
  int fieldsz = t_columns/3;
  char oldcmd = 'h', cmd ;
  int comm_loc ;
  NMENU *msp ;
  NMENUITEM *item = NULL ;
  
  for(msp = bigMenuList;msp;msp=msp->next)
    if(!strcmp(menu_name,msp->menu_id))
      break ;
  if(!msp || currMenuEnt == MAXMENUDEPTH)
    return 0 ;
  currMenuEnt++ ;
  menuEnt[currMenuEnt] = msp ;
  if (myinfo.lastlogin == 0 || BITISSET(myinfo.flags, FLG_SHARED)) cmd = 'H';
  else cmd = InterpretMenuAction(msp->menu_default) ;
  while (update != EXITMENU) {
      if (PagePending()) {
          if (Answer()) update = FULLUPDATE;
      }
      if (update == FULLUPDATE || update == PARTUPDATE) {
          update == FULLUPDATE ? clear() : move(0,0);
          if(!strcmp(msp->menu_title,"*")) {
              extern BBSINFO serverinfo ;
              prints("%s",serverinfo.boardname) ;
          } else
            prints("%s",msp->menu_title);
          clrtoeol();
          move(0, fieldsz*2);
          if (currentboard[0] == '\0')
            prints("No Board Currently Selected");
          else
            prints("Current Board: %s", currentboard);
          move(2,0);
          clrtoeol();
          move(1,0);
          prints("%s",msp->menu_prompt);
          comm_loc = strlen(msp->menu_prompt) ;
          clrtoeol();
      }
      if (bbs_check_mail()) {
          move(0, fieldsz);
          prints("(You have mail.)");
      }
      while(cmd != '\n') {
          item = msp->menucommands[GetMenuIndex(cmd)] ;
          if(item != NULL && HasPerm(item->enabled)) {
              move(1,comm_loc);
              standout();
              prints("%s", item->name) ;
              standend();
              clrtoeol();
          } else {
              bell();
              cmd = oldcmd;
          }
          oldcmd = cmd;
          cmd = MenuGetch();
          if (!isalpha(cmd) && cmd != '\n') {
              bell();
              cmd = oldcmd;
          }
      }
      item = msp->menucommands[GetMenuIndex(oldcmd)] ;
      if (item != NULL) {
          update = (item->action_func)(item->action_arg);
          BITCLR(update, FETCHNEW | NEWDIRECT);     
          if (update & MENUERROR) 
            cmd = InterpretMenuAction(item->error_action);
          else 
            cmd = InterpretMenuAction(item->default_action) ;
      }
  }
  currMenuEnt-- ;
  return FULLUPDATE;
}


do_help()
{
    NMENU *mp ;
    NMENUITEM *mip ;
    
    if(currMenuEnt < 0)
      return ;
    mp = menuEnt[currMenuEnt] ;
    move(3,0) ;
    clrtoeol() ;
    standout() ;
    prints("%s Menu Help Screen\n", mp->menu_id) ;
    standend() ;
    for(mip=mp->commlist;mip;mip=mip->next)
      if(HasPerm(mip->enabled))
        prints("%s\n",mip->help) ;
    clrtobot() ;
    return PARTUPDATE;
}

do_echo(s)
char *s ;
{
    clear() ;
    prints("%s",s) ;
    pressreturn() ;
    return FULLUPDATE ;
}

exec_func(s)
char *s ;
{
    int i ;
    char buf[4096] ;
    char *p, *q ;
    SHORT mode ;

    parse_default() ;
    strncpy(buf,s,sizeof(buf)) ;
    p=strchr(buf,':') ;
    if(p) {
        *p='\0' ;
        q=strchr(p+1,':') ;
        if(q) {
            *q='\0';
            mode = atoi(q+1);            
	}
        parse_environment(p+1) ;
    }
      
    if (mode > 1) bbs_set_mode(mode);
    clear() ;
    refresh() ;
    i = do_exec(buf,NULL) ;
    clear() ;
    if (mode > 1) bbs_set_mode(M_UNDEFINED);
    return FULLUPDATE ;
}
 
exec_func_w_pause(s)
char *s ;
{
    int i ;
    
    char buf[4096] ;
    char *p, *q ;
    SHORT mode ;

    parse_default() ;
    strncpy(buf,s,sizeof(buf)) ;
    p=strchr(buf,':') ;
    if(p) {
        *p='\0' ;
        q=strchr(p+1,':') ;
        if(q) {
            *q='\0';
            mode = atoi(q+1);            
	}
        parse_environment(p+1) ;
    }
      
    if (mode > 1) bbs_set_mode(mode) ;
    clear() ;
    refresh() ;
    i = do_exec(buf,NULL) ;
    pressreturn() ;
    clear() ;
    if (mode > 1) bbs_set_mode(M_UNDEFINED) ;
    return FULLUPDATE ;
}

int do_pipe_more() ;

int revised_pipe_more(s)
char *s ;
{
    char buf[4096] ;
    char *p ;
    
    parse_default() ;
    strncpy(buf,s,sizeof(buf)) ;
    p=strchr(buf,':') ;
    if(p) {
        *p='\0' ;
        parse_environment(p+1) ;
    }
      
    do_pipe_more(buf) ;
}

struct funcs {
    char *funcname ;
    int (*funcptr)() ;
} ;

int NotImpl(), EndMenu(), XyzMenu(), AdminMenu(), MailMenu(), TalkMenu();
int MainHelp(), XyzHelp(), AdminHelp(), MailHelp(), TalkHelp();
int ShowDate(), Welcome(), BoardInfo(), GnuInfo(), EditWelcome();
int MainReadHelp(), MailReadHelp();
int FileMenu(), FileHelp(), FileReadHelp();
int AllUsers(), OnlineUsers(), SetPasswd(), SetUsername(), SetAddress();
int ShortList(), Monitor();
int SetTermtype(), ShowOwnInfo(), AddAccount(), DeleteAccount();
int SetUserData(), SetUserPerms(), ToggleCloak(), ToggleExempt();
int Query(), QueryEdit();
int MailSend(), GroupSend(), ReadNewMail(), MailRead();
int MailDisplay(), MailDelete(), MailDelRange();
int MailReply(), GroupReply(), Forward();
int Visit(), BoardCounts(), Zap(), ReadNew(), SequentialRead();
int Boards(), SelectBoard(), AddBoard(), DeleteBoard(), ChangeBoard();
int SetBoardMgrs();
int Post(),  MainRead(), ReadMenuSelect();
int PostDisplay(), PostDelete(), PostMessage(), PostDelRange(), PostMark();
int PostEdit();
int FileBoards(), FileSelect(), FileDownload();
int FileUpload(), FileReceive(), FileReadMenuSelect();
int Chat(), Kick(), Talk(), SetPager(), SetOverrides();
int SignatureEdit();
#if !REMOTE_CLIENT
int SelectEditor(), SelectProtocol(), FileReadMenuProto(), FileView();
#endif

struct funcs funclist[] = {
    "exec", exec_func,
    "exec.pause", exec_func_w_pause,
    "exec.more", revised_pipe_more,
    "echo", do_echo,
    "NotImpl",NotImpl,
    "EndMenu",EndMenu,
    "Help",do_help,
    "Menu",NDoMenu,
    "ShowDate",ShowDate,
    "Welcome", Welcome,
    "BoardInfo",BoardInfo,
    "GnuInfo",GnuInfo,
    "EditWelcome",EditWelcome,
    "AllUsers",AllUsers,
    "OnlineUsers",OnlineUsers,
    "SetPasswd",SetPasswd,
    "SetUsername",SetUsername,
    "SetAddress",SetAddress,
    "ShortList",ShortList,
    "Monitor",Monitor,
    "SetTermtype",SetTermtype,
    "ShowOwnInfo",ShowOwnInfo,
    "AddAccount",AddAccount,
    "DeleteAccount",DeleteAccount,
    "SetUserData",SetUserData,
    "SetUserPerms",SetUserPerms,
    "ToggleCloak",ToggleCloak,
    "ToggleExempt",ToggleExempt,
    "Query",Query,
    "QueryEdit",QueryEdit,
    "MailSend",MailSend,
    "GroupSend",GroupSend,
    "ReadNewMail",ReadNewMail,
    "MailRead",MailRead,
    "Visit",Visit,
    "BoardCounts",BoardCounts,
    "Zap",Zap,
    "ReadNew",ReadNew,
    "Boards",Boards,
    "SelectBoard",SelectBoard,
    "AddBoard",AddBoard,
    "DeleteBoard",DeleteBoard,
    "ChangeBoard",ChangeBoard,
    "SetBoardMgrs",SetBoardMgrs,
    "Post",Post,
    "MainRead",MainRead,
    "FileBoards",FileBoards,
    "FileSelect",FileSelect,
    "FileDownload",FileDownload,
#if !REMOTE_CLIENT
    "SelectProtocol",SelectProtocol,
#endif
    "FileUpload",FileUpload,
    "Chat",Chat,
    "Kick",Kick,
    "Talk",Talk,
    "SetPager",SetPager,
    "SetOverrides",SetOverrides,
#if !REMOTE_CLIENT
    "SelectEditor",SelectEditor,
#endif
    "SignatureEdit",SignatureEdit,
    NULL,NULL
} ;

    
int (*findfunc(s))()
char *s ;
{
    int i ;
    
    for(i=0;funclist[i].funcname;i++)
      if(!strcmp(funclist[i].funcname,s))
        return funclist[i].funcptr ;
    return NULL ;
}

#if !REMOTE_CLIENT 

/* NOTE: This MUST agree with ACCESSFILE location in init.c */
#define ACCESSFILE "etc/access" 

char *funcstrings[MAX_CLNTCMDS];

form_function_list()
{
    FILE *fp;
    int i;
    char buf[1024], *equals;
    for (i=0; i<MAX_CLNTCMDS; i++) funcstrings[i] = NULL;
    i = 0;
    if ((fp = fopen(ACCESSFILE, "r")) != NULL) {
      while (i<MAX_CLNTCMDS && fgets(buf, sizeof buf, fp) != NULL) {
        if (*buf == '#' || isspace(*buf)) continue;
        if ((equals = strchr(buf, '=')) != NULL) {
          *equals = '\0';
          if ((funcstrings[i] = (char *)malloc(strlen(buf)+1)) != NULL)
	    strcpy(funcstrings[i], buf);
	}
	i++;
      }
      fclose(fp);
    }
}

free_function_list()
{
    int i;
    for (i=0; i<MAX_CLNTCMDS; i++)
      if (funcstrings[i] != NULL) free(funcstrings[i]);
}

convert_cmd_to_int(s) 
char *s;
{
    int i ;
    
    for (i=0; i<MAX_CLNTCMDS; i++) {
      if (funcstrings[i] == NULL) continue;
      if (!strcmp(funcstrings[i], s)) return i;
    }
    fprintf(stderr, "does not grok '%s'\n", s);
    sleep(2);
    return -1;
}

#else /* REMOTE_CLIENT */

convert_cmd_to_int(s) 
char *s;
{
    /* In the remote client, we're assuming numbers will be here */
    return 0;
}

#endif /* !REMOTE_CLIENT */

int line_num ;

ParseMenu()
{
    FILE *fp ;
    extern FILE *yyin ;
    
    if((fp = fopen(_menudesc_file,"r")) == NULL) {
        perror("open menu file") ;
        return -1 ;
    }
#if !REMOTE_CLIENT
    form_function_list();    
#endif
    yyin = fp ;
    line_num = 1 ;
    yyparse() ;
    fclose(fp) ;
#if !REMOTE_CLIENT
    free_function_list();
#endif
    return 0;
}

yywrap()
{
    return 1 ;
}

yyerror()
{
    char buf[512] ;
    sprintf(buf,"syntax error in '%s' %d.\n",_menudesc_file,line_num) ;
    do_echo(buf) ;
}
