/*
	Schrodinger's Box Haven  code version -0.1 alpha
        Copyright (C) 1994, Gordon Chan

	You can do whatever ya want with this code as long as you leave this
        copyright & disclaimer intact.  You can hack it up all you want, etc...
        No guarantees.

	Send comments, flames, bug reports, etc ... to
		au233@freenet.carleton.ca  <---- (preferred address for now)
		gjc@achilles.net
		gchan@ccs.carleton.ca
*/


/* Here's the copyrights & disclaimers from the Opium Den and unixCB codes */

/* Opium Den */
/*
  val's haven code v -0.85

        Copyright (C) 1994 Joel Ward

        Warranty:
                Don't blame me for anything.

        You can do whatever the fuck you want with this code as long as you
don't remove this copyright/disclaimer notice.
*/

/* unixCB */
/*
  
  cbd.c
  
  "cbd.c" is the main code for the CB simulator.
  
  Copyright (c) 1992, Gary Grossman.  All rights reserved.
  Send comments and questions to: garyg@soda.berkeley.edu
  
  */

#include <stdio.h>
#include <string.h>

#include "linked_lists.h"
#include "main.h"
#include "misc_commands.h"
#include "user_input.h"
#include "security.h"


/* routines used for quitting */

void get_out (user, text)
	struct user *user;
	char *text;
{
	char temp[120];

	toggle_user (user, Fcomm_line);

	sprintf (temp, ">> %s on line %d has just left.\r\n", user->name, 
	  user->desc);
	if (!strcmp(text, "yes") || !strcmp(text, "y") )
		delete_user (user, ">> Later Dude!\r\n", 0, temp);
	else 
		write_user (user->desc, ">> Still here dude!\r\n");
}


/* print version */

void version (user, text)
  struct user *user;
  char *text;
{
  write_user(user->desc, 
   ">> This is version -0.1 alpha of Schrodinger's Box Haven code.\r\n"); 
}


/* print out help files for users */

void show_help (user, text)
  struct user *user;
  char *text;
{
  write_file_to(user, HELP, ">> No help files available.\r\n");
  if (user->sec_level >= COSYSOP)
    write_file_to(user, POWER, ">> No cosysop help files available.\r\n");
  if (user->sec_level >= SYSOP)
    write_file_to(user, OP_POWER, ">> No sysop help files available.\r\n");
  if (user->sec_level == GOD)
    write_file_to(user, ADMIN, ">> No god help files available.\r\n");
}

 
/* gag and reverse-gag routines */

void toggle_gag (user, victim)
	struct user *user;
	char *victim;
{
	struct user *u;
	char temp[120];

	if (!*victim) {
		write_user (user->desc, ">> You did not gag anyone.\r\n");
		toggle_user (user, Fcomm_line);
		return;
	}
		
	victim[NAMEMAX-1] = '\0';
	if ( (u = (struct user *) find_user (victim)) == (struct user *) 0) { 	
		sprintf (temp, ">> %s is not logged on.\r\n", victim);
		write_user (user->desc, temp);
		toggle_user (user, Fcomm_line);
		user->linecharmax = INPUTMAX;
		return;
	} else if (u == user) {
		write_user (user->desc, ">> Gagging yourself with a spoon?\r\n");
		toggle_user (user, Fcomm_line);
		user->linecharmax = INPUTMAX;
		return;
	} else {
		if (!user->gags) {
			if ( (user->gags = (unsigned char *) malloc (bitarrsize(MAXCONNECT)*sizeof(user->gags))) == (unsigned char *) 0) {
				write_user (user->desc, ">> Gags could not be allocated.  No gags.\r\n");	
				user->linecharmax = INPUTMAX;
				return;
			} else 
				bzero (user->gags, bitarrsize(MAXCONNECT));
		}
	
		togbit (user->gags, u->desc-1);
		if (testbit(user->gags, u->desc-1) ) {
			sprintf (temp, ">> %s on line %d has been gagged.  Ha ha ha!\r\n", u->name, u->desc);
			write_user (user->desc, temp);
			sprintf (temp, ">> %s on line %d has gagged you.\r\n",
			  user->name, user->desc);
			process_output (u, temp);
		} else {
			sprintf (temp, ">> %s on line %d has been un-gagged.\r\n", u->name, u->desc);
			write_user (user->desc, temp);
			sprintf (temp, ">> %s on line %d has un-gagged you.\r\n",
			  user->name, user->desc);
			process_output (u, temp);
		}	
		if (!num_of_annoy(user->gags) ) {
			free (user->gags);
			user->gags = (unsigned char *) 0;
			write_err ("  user->gags NUKED\r\n");
		}
		user->linecharmax = INPUTMAX;
		toggle_user (user, Fcomm_line);
	}
}


void toggle_reverse_gag (user, victim)
	struct user *user;
	char *victim;
{
	struct user *u;
	char temp[120];

	if (!*victim) {
		write_user (user->desc, ">> You did not reverse-gag anyone.\r\n");
		toggle_user (user, Fcomm_line);
		return;
	}
		
	victim[NAMEMAX-1] = '\0';
	if ( (u = (struct user *) find_user (victim)) == (struct user *) 0) { 	
		sprintf (temp, ">> %s is not logged on.\r\n", victim);
		write_user (user->desc, temp);
		toggle_user (user, Fcomm_line);
		user->linecharmax = INPUTMAX;
		return;
	} else if (u == user) {
		write_user (user->desc, ">> What!?!?  You are reverse-gagging yourself?  BARF.\r\n");
		toggle_user (user, Fcomm_line);
		user->linecharmax = INPUTMAX;
		return;
	} else {
		if (!user->reverse_gags) {
			if ( (user->reverse_gags = (unsigned char *) malloc (bitarrsize(MAXCONNECT)*sizeof(user->reverse_gags))) == (unsigned char *) 0) {
				write_user (user->desc, ">> Reverse-gags could not be allocated.  No reverse-gags.\r\n");	
				user->linecharmax = INPUTMAX;
				return;
			} else 
				bzero (user->reverse_gags, bitarrsize(MAXCONNECT));
		}
	
		togbit (user->reverse_gags, u->desc-1);
		if (testbit(user->reverse_gags, u->desc-1) ) {
			sprintf (temp, ">> %s on line %d has been reverse-gagged.  Ha ha ha!\r\n",
			  u->name, u->desc);
			write_user (user->desc, temp);
			sprintf (temp, ">> %s on line %d has reverse-gagged you.\r\n",
			  user->name, user->desc);
			process_output (u, temp);
		} else {
			sprintf (temp, ">> %s on line %d has been un-reverse-gagged.\r\n", 
			  u->name, u->desc);
			write_user (user->desc, temp);
			sprintf (temp, ">> %s on line %d has un-reverse-gagged you.\r\n",
			  user->name, user->desc);
			process_output (u, temp);
		}
		if (!num_of_annoy(user->reverse_gags) ) {
			free (user->reverse_gags);
			user->reverse_gags = (unsigned char *) 0;
			write_err ("  user->reverse_gags NUKED\r\n");
		}
		toggle_user (user, Fcomm_line);
		user->linecharmax = INPUTMAX;
	}
}


int num_of_annoy (gripe)
	unsigned char *gripe;
{
	struct user *u;
	int count = 0;

	for (u = firstuser; u; u = u->next)
		if (testbit(gripe, u->desc-1) )
			count++;
	return count;
}


#ifdef LOGIN_SCREEN
/* routines used for login */

void set_login (user)
	struct user *user;
{
	toggle_user (user, Fcomm_line);
	toggle_user (user, Fmultiple_comm);

	write_file_to (user, LOGINSCREEN, "\r\nNo login screen.  How boring.  ;) ;)\r\n\n");

	write_user (user->desc, "Squishy login: ");
	clear_queue (user->input);

	user->present_comm = login;
}	

	
void login (user, text)
	struct user *user;
	char *text;
{
	FILE *fptr;

        text[ACCOUNTMAX-1] = '\0'; 
	sprintf (user->account, "./accounts/%s", text);	
	fptr = fopen(user->account, "rb");	

	if (!fptr) {
		delete_user (user, "\n>> No account by that name.\r\n", 1, (char *) 0);
		return;
	}

	fclose (fptr);

	write_user (user->desc, "Password: ");
	clear_queue (user->input);
	
	user->present_comm = password;
}

		
void password (user, text)
	struct user *user;
	char *text;
{
	FILE *fptr;
	char passwd[MAXPASSWD];

	fptr = fopen(user->account, "rb");	
	if (fptr) {
		fgets (user->name, NAMEMAX, fptr);
		strip_cr (user->name);	

		fgets (passwd, MAXPASSWD, fptr);
		strip_cr (passwd);

		fclose (fptr);
	}

	if (strncmp (passwd, text, MAXPASSWD) ) {
		delete_user (user, "\n>> Wrong password.\r\n", 1, (char *) 0);
		return;
	}


	toggle_user (user, Fmultiple_comm); 
	toggle_user (user, Fcomm_line);
	toggle_user (user, Flogged_in);

	greeting (user);
}
#endif
