/
roa/
roa/lib/boards/
roa/lib/config/
roa/lib/edits/
roa/lib/help/
roa/lib/misc/
roa/lib/plrobjs/
roa/lib/quests/
roa/lib/socials/
roa/lib/www/
roa/lib/www/LEDSign/
roa/lib/www/LEDSign/fonts/
roa/lib/www/LEDSign/scripts/
roa/src/s_inc/
roa/src/sclient/
roa/src/sclient/binary/
roa/src/sclient/text/
roa/src/util/
/************************************************************************
	Realms of Aurealis 		James Rhone aka Vall of RoA

finger.c			 	Realms of Aurealis mud finger code   
					12/29/96

		******** 100% Completely Original Code ********
		*** BE AWARE OF ALL RIGHTS AND RESERVATIONS ***
		******** 100% Completely Original Code ********
		        All rights reserved henceforth. 

    Please note that no guarantees are associated with any code from
Realms of Aurealis.  All code which has been released to the general
public has been done so with an 'as is' pretense.  RoA is based on both
Diku and CircleMUD and ALL licenses from both *MUST* be adhered to as well
as the RoA license.   *** Read, Learn, Understand, Improve ***
*************************************************************************/

// James Rhone (aka Vall)	The following is code which deals with RoA's 
//				version of the standard finger command
//				such as found on most unix systems.  It
//				has menus for entering finger info as well
//				as the basic finger interface for looking up
//				finger information on other players.
//
// As of this release, this does not scan the pfile for 'last login' and 
// 'created' fields though they are useful, I didn't wanna waste anymore
// company time writing them :)
// (actually, the 'created' field should be a one time lookup, but I still 
// havent imped it yet)
//

#include "sysdep.h"
#include "conf.h"

#include "structures.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "db.h"
#include "roaolc.h"
#include "acmd.h"
#include "global.h"

void fedit_top_menu(chdata *ch, char *input_str);
void fedit_confirm_quit(chdata *ch, char *input_str);
void fedit_confirm_save(chdata *ch, char *input_str);
void mfinger_confirm_delete(chdata *ch, char *input_str);

// basically killr all the strings in a finger struct -jtrhone
void wax_finger_tildas(struct finger_type *f)
{
  if (f->rl_name)
    killr(f->rl_name);
  if (f->age)
    killr(f->age);
  if (f->city)
    killr(f->city);
  if (f->state)
    killr(f->state);
  if (f->country)
    killr(f->country);
  if (f->phone)
    killr(f->phone);
  if (f->plan)
    killr(f->plan);
}

// this will write out the finger file information
// it MUST be called only when a character has their finger_editted
// struct allocated and filled out properly
// places file in lib/finger under <name>.fng   ex) Vall.fng
void write_finger_file(chdata *ch)
{
  char name[512];
  FILE *fp;
  struct finger_type *f;
  int i;

  if (IS_NPC(ch))
    return;

  sprintf(name, "finger/%s.fng", GET_NAME(ch));
  for (i = 0; name[i]; i++)
    name[i] = tolower(name[i]);

  if (!(f = ch->pc_specials->finger_editted))
  {
    sprintf(buf2, "SYSERR: Write_finger without allocated finger struct on %s.",name);
    mudlog(buf2, BRF, LEV_IMM, TRUE);
    return;
  }

  if (!(fp = fopen(name, "wt")))
  {
    sprintf(buf2, "SYSERR: Unable to open finger file for %s.",name);
    mudlog(buf2, BRF, LEV_IMM, TRUE);
    return;
  }

  // DONT FORGET TO WAX THE TILDAS!! -jtrhone
  wax_finger_tildas(f);

  if (f->rl_name)
    fprintf(fp, "%s~\n", f->rl_name);
  else
    fprintf(fp, "No Name Entered.~\n");

  if (f->age)
    fprintf(fp, "%s~\n", f->age);
  else
    fprintf(fp, "No Age Entered.~\n");

  if (f->city)
    fprintf(fp, "%s~\n", f->city);
  else
    fprintf(fp, "No City Entered.~\n");

  if (f->state)
    fprintf(fp, "%s~\n", f->state);
  else
    fprintf(fp, "No State Entered.~\n");

  if (f->country)
    fprintf(fp, "%s~\n", f->country);
  else
    fprintf(fp, "No Country Entered.~\n");

  if (f->phone)
    fprintf(fp, "%s~\n", f->phone);
  else
    fprintf(fp, "No Email Entered.~\n");

  if (f->plan)
    fprintf(fp, "%s~\n", f->plan);
  else
    fprintf(fp, "No Plan Entered.~\n");

  fclose(fp);
}

// free up the strings associated with a finger structure and the structure itself
void free_finger_struct(struct finger_type *f)
{
  FREENULL(f->rl_name);
  FREENULL(f->age);
  FREENULL(f->city);
  FREENULL(f->state);
  FREENULL(f->country);
  FREENULL(f->phone);
  FREENULL(f->plan);
  FREENULL(f);
}

// fill finger information struct with default data
void fill_finger_info(struct finger_type *f)
{
  if (!f->rl_name)
    f->rl_name = str_dup("No Name Entered.");

  if (!f->age)
    f->age     = str_dup("No Age Entered.");

  if (!f->city)
    f->city    = str_dup("No City Entered.");

  if (!f->state)
    f->state   = str_dup("No State Entered.");

  if (!f->country)
    f->country = str_dup("No Country Entered.");

  if (!f->phone)
    f->phone   = str_dup("No Email Entered.");

  if (!f->plan)
    f->plan    = str_dup("No Plan Entered.\n\r");
}

// f MUST BE ALLOCATED before we get to here, return TRUE if ok
BOOL get_finger_info(struct finger_type *f, char *arg)
{
  char name[512];
  FILE *fp;
  int i;

  sprintf(name, "finger/%s.fng", arg);
  for (i = 0; name[i]; i++)
    name[i] = tolower(name[i]);

  if (!(fp = fopen(name, "rt")))
    return FALSE;

  // now do the actual read of the finger info strings now
  f->rl_name   = fread_string(fp, buf);
  f->age       = fread_string(fp, buf);
  f->city      = fread_string(fp, buf);
  f->state     = fread_string(fp, buf);
  f->country   = fread_string(fp, buf);
  f->phone     = fread_string(fp, buf);
  f->plan      = fread_string(fp, buf);
  fclose(fp);
  return TRUE;
}

// still have to play with the way this looks, but this just sends mfinger
// information on 'arg'
// to ch in some pretty format with color codes installed   -jtrhone,roa
void send_finger_to_char(struct finger_type *f, chdata *ch, char *name)
{
  char buf[20000];

  send_to_char("\n\r",ch);
  sprintf(buf,             "%%6%%0MUD Finger Information%%0: %%6%s%%0\n\r",name);
  sprintf(buf+strlen(buf), "%%6%%0-=-=-=-=-=-=-=-=-=-=-=-%%0\n\r");

  sprintf(buf+strlen(buf), "%%6Real Name%%0: %%5%s%%0\n\r%%6Age      %%0: "
			   "%%5%s%%0\n\r%%6Email    %%0: %%5%s%%0\n\r",
	  f->rl_name, f->age, f->phone);

  sprintf(buf+strlen(buf), "%%6City%%0   : %%5%s%%0\n\r%%6State  %%0: %%5%s%%0\n\r"
			   "%%6Country%%0: %%5%s%%0\n\r",
	  f->city, f->state, f->country);

  sprintf(buf+strlen(buf), "%%6Plan%%0: \n\r%s\n\r", f->plan);

  page_string(ch->desc, buf, 1); 
}

ACMD(do_mfinger)
{
  char *argu = argument;
  struct finger_type *f;

  if (strlen(argument) > MAX_CLAN_LENGTH)
  {
    send_to_char("Excessive argument length.  Your actions have been logged.\n\r",ch);
    sprintf(buf, "PLRUPD: Possible mfinger crash attempt by %s.", GET_NAME(ch));
    mudlog(buf, BRF, LEV_IMM, TRUE);
    return;
  }

  skip_spaces(&argu);
  if (!*argu)
  {
    send_to_char("Usage: mfinger <player name>.\n\r",ch);
    return;
  }

  one_argument(argu, arg);
  CREATE(f, struct finger_type, 1);
  if (!get_finger_info(f, arg))
  {
    sprintf(buf, "Unable to find mfinger information on %s.\n\r",arg);
    S2C();
    free_finger_struct(f);
    return;
  }

  // ok it's filled, now send the data to the viewer
  send_finger_to_char(f, ch, arg);

  // ok now free up the finger struct
  free_finger_struct(f);
}

// here is the editor (RoAOLCv2.0) interface for editting mfinger
// information on a player
// the command 'mfingefedit' takes the character into a finger edit menu
// (based on RoAOLCv2.0 standards)
// James Rhone (aka jtrhone, aka Vall.... RoA)  12/29/96
ACMD(do_mfinger_edit)
{
  struct finger_type *f;

  if (IS_NPC(ch)) return;

  CREATE(f, struct finger_type, 1);
  if (!get_finger_info(f, GET_NAME(ch)))
  {
    fill_finger_info(f);
  }

  ch->pc_specials->finger_editted = f;

  SET_BIT(PLR_FLAGS(ch), PLR_BUILDING);
  MENU_HANDLER(ch) = fedit_top_menu;
  MENU_DEPTH(ch) = 0;   
  ch->pc_specials->field_changed = FALSE;
    
  (*MENU_HANDLER(ch))(ch, NULL);
}

// the first menu in the finger edit process
void fedit_top_menu(chdata *ch, char *input_str)
{
    char buf[MAX_STRING_LENGTH];
    int field;
    char *p;
    struct finger_type *f = ch->pc_specials->finger_editted;
    
    if (!input_str)
    {
	if (PLR_FLAGGED(ch, PLR_REFRESH))
	  clrscr(ch);
        sprintf(buf, "\n\r    %%B%%5%s FingerEdit Main Menu%%0\n\r", OLC_version);
	S2C();

	send_to_char("%B%5All fields are optional%0\n\r",ch);
	sprintf(buf, " 1.) %%1Real Name%%0: %s\n\r", f->rl_name); S2C();
	sprintf(buf, " 2.) %%1Age%%0      : %s\n\r", f->age); S2C();
	sprintf(buf, " 3.) %%1City%%0     : %s\n\r", f->city); S2C();
	sprintf(buf, " 4.) %%1State%%0    : %s\n\r", f->state); S2C();
	sprintf(buf, " 5.) %%1Country%%0  : %s\n\r", f->country); S2C();
	sprintf(buf, " 6.) %%1Email%%0    : %s\n\r", f->phone); S2C();
	sprintf(buf, " 7.) %%1Comments%%0 :\n\r%s\n\r", f->plan);S2C();

	send_to_char("\n\r", ch);
	MENU_PROMPT(ch) = "Enter field number to change or 0 to end: ";
	return;
    }

    strcpy(buf, input_str);
    p = strtok(buf, " 	\n\r");
    if (p)
	field = atoi(p);
    else
	field = 0;

    switch (field)
    {
      case 0:
	MENU_HANDLER(ch) = fedit_confirm_quit;
	(*MENU_HANDLER(ch))(ch, NULL);
	break;

      case 1:
	do_string_arg(ch, "Enter your name:\n\r", &f->rl_name, "");
	break;

      case 2:
	do_string_arg(ch, "Enter your age:\n\r", &f->age, "");
	break;
	
      case 3:
	do_string_arg(ch, "Enter your city:\n\r", &f->city, "");
	break;
	
      case 4:
	do_string_arg(ch, "Enter your state/province:\n\r", &f->state,"");
	break;
	
      case 5:
	do_string_arg(ch, "Enter your country:\n\r", &f->country, "");
	break;
	
      case 6:
	do_string_arg(ch, "Enter your email address:\n\r", &f->phone, "");
	break;
	
      case 7:
	do_long_string_arg(ch, "Enter your comments (.plan) (@):\n\r",&f->plan);
	break;

      default:
	send_to_char("That field cannot be changed.\n\r", ch);
	break;
    }

    ch->pc_specials->field_changed = TRUE;
}

void fedit_confirm_quit(chdata *ch, char *input_str)
{
    char buf[MAX_STRING_LENGTH];
    char *p;
    
    if (!input_str)
    {
	MENU_PROMPT(ch) = "Quit editting finger data (yes/NO)? ";
	return;
    }
    
    strcpy(buf, input_str);
    p = strtok(buf, " 	\n\r");
    if (p && strncasecmp("yes", p, strlen(p)) == 0)
    {
	MENU_HANDLER(ch) = fedit_confirm_save;
	(*MENU_HANDLER(ch))(ch, NULL);
    }
    else
    {
	MENU_HANDLER(ch) = fedit_top_menu;
	(*MENU_HANDLER(ch))(ch, NULL);
    }
}

void fedit_confirm_save(chdata *ch, char *input_str)
{
    char buf[MAX_STRING_LENGTH];
    char *p;
    
    if (!input_str)
    {
	MENU_PROMPT(ch) = "Save finger information (YES/no)? ";
	return;
    }
    
    strcpy(buf, input_str);
    p = strtok(buf, " 	\n\r");
    if (!p || strncasecmp("no", p, strlen(p)) != 0)
    {
      sprintf(buf, "PLRUPD: %s editted finger data", GET_NAME(ch));
      mudlog(buf, BRF, GET_LEVEL(ch), TRUE);
      write_finger_file(ch);
      send_to_char("Finger information saved.\n\r",ch);
    }
    else
      send_to_char("Finger information not saved.\n\r",ch);

    free_finger_struct(ch->pc_specials->finger_editted);
    ch->pc_specials->finger_editted = NULL;
    MENU_PROMPT(ch) = NULL;
    MENU_HANDLER(ch) = NULL;
    MENU_DEPTH(ch) = 0;
    REMOVE_BIT(PLR_FLAGS(ch), PLR_BUILDING);
}

/* function to confirm if someone wants to delete a finger file */
void mfinger_confirm_delete(chdata *ch, char *input_str)
{
    char buf[MAX_STRING_LENGTH];
    char *p;
    int i;
    
    if (!input_str)
    {
	MENU_PROMPT(ch) = "Delete your finger file (YES/no)? ";
	return;
    }
    
    strcpy(buf, input_str);
    p = strtok(buf, " 	\n\r");
    if (!p || strncasecmp("no", p, strlen(p)) != 0)
    {
      sprintf(buf, "finger/%s.fng", GET_NAME(ch));
      for (i = 0; buf[i]; i++)
        buf[i] = tolower(buf[i]);
      if (remove(buf) < 0)
        send_to_char("SYSERR: Finger file not deleted.\n\r",ch);
      else
        send_to_char("Finger file deleted.\n\r",ch);
    }
    else
      send_to_char("Finger file not deleted.\n\r",ch);

    /* set menu prompt, handler, and depth to nada, kicks them out of menu */
    MENU_PROMPT(ch) = NULL;
    MENU_HANDLER(ch) = NULL;
    MENU_DEPTH(ch) = 0;
}

// here is the way a player removes his/her finger information from the 
// lib/finger directory
// simply takes them into a confirmation menu (re: RoAOLCv2.0 Standards) -roa
ACMD(do_mfinger_delete)
{
  char name[512];
  FILE *fp;
  int i;

  /* only players should call this command */
  if (IS_NPC(ch)) return;

  sprintf(name, "finger/%s.fng", GET_NAME(ch));
  for (i = 0; name[i]; i++)
    name[i] = tolower(name[i]);

  if (!(fp = fopen(name, "rt")))
  {
    send_to_char("You have no finger information.\n\r",ch);
    return;
  }
  fclose(fp);

  MENU_HANDLER(ch) = mfinger_confirm_delete;
  MENU_DEPTH(ch) = 0;    
  (*MENU_HANDLER(ch))(ch, NULL);
}