/* MCM  -  MultiUser Communications Manager

   Copyright (C) 1991,2 Michael Sawyer

   This code may be reproduced without charge provided that this
   notice remains intact on all copies distributed.

   Any part of this code may be used in other programs provided that
   some citation of this work is given.
*/

/* Configuration section */

 /* Ultrix is BSD */
 /* If you are running BSD, make sure BSD gets defined somehow! */

#ifdef ultrix
#ifndef BSD
#define BSD
#endif
#endif

 /* If you are not using an ANSI compiler, need to define NOANSI */
 /* Assume worst case for defined() syntax */
#ifndef ANSI
#ifndef NOANSI
#define NOANSI
#endif
#endif

 /* Define this for machines (BSD) who need usleep() provided for them */
#ifdef BSD
#define NEED_USLEEP
#endif

 /* For usleep() machines, set the number of microseconds to sleep */
 /* while waiting for data */
#define DELAYTIME 25

 /* How nice do we want MCM to run? */
#define HOWNICE 5

 /* How many jobs will we allow on the server at any time? */
#define NUMJOBS 32

 /* If defines, this variable controls how often (in seconds) the MCM */
 /* server will time-stamp the session.  This time-stamp appears in */
 /* both the logfiles as well as to all users logged in. */
#define DELTAT 1800

 /* If you do not want the ability to use the termcap libraries to */
 /* provide full-screen support, comment this out. */
 /* curses support is completly remved from this version */
#define TERMCAP /* Termcap support */

 /* If your compiler has trouble with bitfields (none should), define this: */
/*#define BADBITS*/

 /* If you want name padding to be on by default, uncomment this. */
/*#define DFNAMEPAD */

 /* If you want job numbers by default, uncomment */
#define DFJOBNUMS

 /* If you want counts by default, uncomment */
/*#define DFCOUNTS */

/* END of user configuration... */



#define VERSION "mcm 1.1e [Beta] (C) 1991,2 Inlet Software/Michael Sawyer"

#include <signal.h>
#ifndef BSD
#include <sys/file.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <string.h>
#ifdef CURSES
#include <curses.h>
#else
#include <sys/ioctl.h>
#endif /* CURSES */
/* Just to make sure they exist... */
#ifndef TRUE
#define TRUE (1==1)
#define FALSE (1==0)
#endif

#ifdef NOANSI
#define _PARAMS(x) ()
#else
#define _PARAMS(x) x
#endif

#ifdef BADBITS
#define _BIT(x,y) x
#else
#define _BIT(x,y) x:y
#endif

extern int errno;

#define validjob(jobid) (!((jobid<0)||(jobid>NUMJOBS)))

/* And some prototypes */

void bailout _PARAMS((int, char*));
void sigprocessor _PARAMS((int));
int main _PARAMS((int, char**));
void check_connections _PARAMS(());
int communicate _PARAMS(());
void tell  _PARAMS((int, int, char*, char*));
void process _PARAMS((int, char*));
void loginuser _PARAMS((int));
void strcap _PARAMS((char*));
void starcommand _PARAMS((int, char*));
void slashcommand _PARAMS((int, char*));
void endsession _PARAMS((int));
void whothere _PARAMS((int, char*));
void gagpeople _PARAMS((int, char*));
void privconf _PARAMS((int, char*));
void rolldice _PARAMS((int, char*, int));
void sendmsg _PARAMS((int, char*));
void typefile _PARAMS((int, char*));
void wwrap _PARAMS((char*));
void txout _PARAMS((int, int, char*, char*, int));
void easytext _PARAMS((int, int, char*, char*, int));
void strcap _PARAMS((char*));
void struncap _PARAMS((char*));
void listenonly _PARAMS((int, char*));
void sendmsg _PARAMS((int, char*));
void doormessage _PARAMS((int, char*));
void dowins _PARAMS((int, char*));
void endsession _PARAMS((int));
void usertype _PARAMS((int, char*));
void userhelp _PARAMS((int, char*));
void modecommand _PARAMS((int,char*));
void setasst _PARAMS((char*));
void set_count _PARAMS((int, char*));
void set_jobid _PARAMS((int, char*));
void set_namepad _PARAMS((int,char*));

#ifdef NEED_USLEEP
int usleep _PARAMS((unsigned long));
#endif

#ifdef CURSES
void splinit _PARAMS((int, char*));
void splend _PARAMS((int));
void spltext _PARAMS((int,int,char*, char*, int));
void splredraw _PARAMS((int));
void splfollow _PARAMS((int));
void splnewinp _PARAMS((int));
void swwrap _PARAMS((char*));
#endif
#ifdef TERMCAP
void splinit _PARAMS((int,char*));
char *depad _PARAMS((char*));
void splend _PARAMS((int));
void spltxout _PARAMS((int,char*));
void spltext _PARAMS((int,int,char*,char*,int));
void splredraw _PARAMS((int));
void splchar _PARAMS((int,char));
void splbackup _PARAMS((int));
void splnewinp _PARAMS((int));
void set_lines _PARAMS((int,int));

/* The Termcap routines themselves */
int tgetent _PARAMS((char*,char*));
int tgetnum _PARAMS((char*));
char *tgetstr _PARAMS((char*,char**));
char *tgoto _PARAMS((char*,int,int));
#endif

/* Stuff from the personality modules */
void per_init ();
void per_sig2 ();
void per_timestep();
int per_tell _PARAMS((int, int, char*, char*));
int per_process _PARAMS((int, char*));
void per_login _PARAMS((int));
int per_starhelp _PARAMS((int));
int per_slashhelp _PARAMS((int));
int per_mode _PARAMS((int, char*));
int per_modehelp _PARAMS((int));
int per_preroll _PARAMS((int, char*));
int per_postroll _PARAMS((int, int, char*, int, int, int, int*));
void per_logout _PARAMS((int));

struct JOB
{
  int fd; /* a file descriptor for the socket */
  char buf[255]; /* Text buffer */
  char name[20]; /* Name of the user */
  char pass[20]; /* The password used */
  char from[48]; /* Name of host system */
  char extra[64]; /* Some extra info */
  unsigned char addrs[4]; /* Address of user's machine */
  unsigned int _BIT(width,8), /* Line width */
      _BIT(mode,2), /* 0=None, 1=name:, 2=pass:, 3=Normal */
      _BIT(firstrun,1), /* First run through process (CONNECT message) */
      _BIT(gagged,1), /* User is gagged */
      _BIT(privconf,1), /* User in private conf. */
      _BIT(maybeleader,1), /* User may becode leader */
      _BIT(showcount,1), /* Show the count of messages */
      _BIT(showjob,1), /* Show job IDs */
      _BIT(padname,1), /* Pad names */
      _BIT(userbt0,1), /* User Bit 0 (for pers. modules) */
      _BIT(userbt1,1), /* User bit 1 */
      _BIT(userbt2,1), /* User bit 2 */
      _BIT(userbt3,1), /* User bit 3 */
      _BIT(userby0,8), /* User byte 0 */
      _BIT(userby1,8), /* User byte 1 */
      _BIT(userby2,8), /* User byte 2 */
      _BIT(userby3,8), /* User byte 3 */
      _BIT(userby4,8), /* User byte 4 */
      _BIT(userby5,8), /* User byte 5 */
      userwd0, /* User word 0 */
      userwd1; /* User word 1 */
  char userstr[32]; /* User string */
  /* Stuff for CURSES */
#ifdef CURSES
  FILE *fp;
  SCREEN *basescr;
  WINDOW *rootwin, *inpwin, *outwin;
#endif
  /* Now stuff for termcap/info */
#ifdef TERMCAP
  char al[32], bc[32], cd[32], ce[32], cl[32], dc[32], dl[32], so[32], se[32];
  char sr[32], cm[32], cs[32], rs[32], xdo[32];
  int co, li;
  char termtype[32];
#endif
};

/* Global variables */

struct JOB job[NUMJOBS];

char msgtext[1024]; /* Message for the door */
int s; /* The socket */
struct servent *ps; /* Server entry */
struct sockaddr_in sin; /* Socket address */
int portid; /* ID of the port */
int msgcount; /* Counter of message numbers */
int listen_mode, /* -1 = floor opened, # = uid with floor */
    whogagged, /* List gagged users */
    defaultgag, /* New users are gagged as they enter */
    snoopmode, /* Snoop on private messages */
    confhear, /* Can conf users hear? */
    conftalk, /* Can they talk? */
    asstleader; /* Ass't room leader */
FILE *masterfp, *logfp;

/* EOF mcm.h */

