/*********************************************
**********************************************
This is a file of general utility functions useful
for programming in general and icq in specific

This software is provided AS IS to be used in
whatever way you see fit and is placed in the
public domain.

Author : Matthew Smith April 23, 1998
Contributors :  airog (crabbkw@rose-hulman.edu) May 13, 1998


Changes :
**********************************************
**********************************************/
#include "micq.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef _WIN32
   #include <io.h>
   #define S_IRUSR		_S_IREAD
   #define S_IWUSR		_S_IWRITE
#endif
#ifdef UNIX
   #ifdef AMIGA
     #define S_IRUSR		 S_IREAD
     #define S_IWUSR		 S_IWRITE
   #else
     #include <unistd.h>
     #include <termios.h>
   #endif
#endif

static char rcfile[256];


/***************************************************************
Turns keybord echo off for the password
****************************************************************/
S_DWORD Echo_Off( void )
{
#if defined(UNIX) && !defined(AMIGA)
	struct termios attr; /* used for getting and setting terminal
				attributes */

	/* Now turn off echo */
	if (tcgetattr(STDIN_FILENO, &attr) != 0) return(-1);
		/* Start by getting current attributes.  This call copies
		all of the terminal paramters into attr */

	attr.c_lflag &= ~(ECHO);
		/* Turn off echo flag.  NOTE: We are careful not to modify any
		bits except ECHO */
	if (tcsetattr(STDIN_FILENO,TCSAFLUSH,&attr) != 0) return(-2);
		/* Wait for all of the data to be printed. */
		/* Set all of the terminal parameters from the (slightly)
		   modified struct termios */
		/* Discard any characters that have been typed but not yet read */
#endif
	return 0;
}


/***************************************************************
Turns keybord echo back on after the password
****************************************************************/
S_DWORD Echo_On( void )
{
#if defined(UNIX) && !defined(AMIGA)
	struct termios attr; /* used for getting and setting terminal
				attributes */

	if (tcgetattr(STDIN_FILENO, &attr) != 0) return(-1);

	attr.c_lflag |= ECHO;
	if(tcsetattr(STDIN_FILENO,TCSANOW,&attr) != 0) return(-1);
#endif
	return 0;
}

/**************************************************************
Same as fprintf but for FD_T's
***************************************************************/
void M_fdprint( FD_T fd, char *str, ... )
{
   va_list args;
   int k;
   char buf[2048]; /* this should big enough */
        
   assert( buf != NULL );
   assert( 2048 >= strlen( str ) );
   
   va_start( args, str );
   vsprintf( buf, str, args );
   k = write( fd, buf, strlen( buf ) );
   assert( k == strlen( buf ) );
   va_end( args );
}

/***********************************************************
Reads a line of input from the file descriptor fd into buf
an entire line is read but no more than len bytes are 
actually stored
************************************************************/
int M_fdnreadln( FD_T fd, char *buf, size_t len )
{
   int i,j;
   char tmp;

   assert( buf != NULL );
   assert( len > 0 );
   tmp = 0;
   for ( i=-1; ( tmp != '\n' )  ; )
   {
      if  ( ( i < len ) || ( i == -1 ) )
      {
         i++;
         j = read( fd, &buf[i], 1 );
         tmp = buf[i];
      }
      else
      {
         j = read( fd, &tmp, 1 );
      }
      assert( j != -1 );
      if ( j == 0 )
      {
         buf[i] =  0;
         return -1;
      }
   }
   if ( i < 1 )
   {
      buf[i] = 0;
   }
   else
   {
      if ( buf[i-1] == '\r' )
      {
         buf[i-1] = 0;
      }
      else
      {
         buf[i] = 0;
      }
   } 
   return 0;
}

/********************************************
returns a string describing the status or
a NULL if no such string exists
*********************************************/
char *Convert_Status_2_Str( int status )
{
   if ( STATUS_OFFLINE == status ) /* this because -1 & 0xFFFF is not -1 */
   {
      return "Offline";
   }
   
   switch ( status & 0xffff )
   {
   case STATUS_ONLINE:
      return "Online";
      break;
   case STATUS_DND:
      return "Do not disturb";
      break;
   case STATUS_AWAY:
      return "Away";
      break;
   case STATUS_OCCUPIED:
      return "Occupied";
      break;
   case STATUS_NA:
      return "Not available";
      break;
   case STATUS_INVISIBLE:
      return "Invisible";
      break;
   case STATUS_FREE_CHAT:
      return "Free for chat";
      break;
   default :
      return NULL;
      break;
   }
}

/********************************************
prints out the status of new_status as a string
if possible otherwise as a hex number
*********************************************/
void Print_Status( DWORD new_status  )
{
   if ( Convert_Status_2_Str( new_status ) != NULL )
   {
      printf( "%s", Convert_Status_2_Str( new_status ) );
      if ( Verbose )
         printf( " %02X",( WORD ) ( new_status >> 16 ) );
   }
   else
   {
      printf( "%08lX", new_status );
   }
}

/**********************************************
Prints the name of a user or there UIN if name
is not know.
***********************************************/
int Print_UIN_Name( DWORD uin )
{
   int i;
   
   for ( i=0; i < Num_Contacts; i++ )
   {
      if ( Contacts[i].uin == uin )
         break;
   }

   if ( i == Num_Contacts )
   {
      printf( CLIENTCOL "%lu" NOCOL, uin );
      return -1 ;
   }
   else
   {
      printf( CONTACTCOL "%s" NOCOL ,Contacts[i].nick );
      return i;
   }
}

/*********************************************
Converts a nick name into a uin from the contact
list.
**********************************************/
DWORD nick2uin( char *nick )
{
   int i;
   BOOL non_numeric=FALSE;
   
   for ( i=0; i< Num_Contacts; i++ )
   {
      if ( ! strncasecmp( nick, Contacts[i].nick, 19  ) )
      {
         if ( (S_DWORD) Contacts[i].uin > 0 )
            return Contacts[i].uin;
         else
            return -Contacts[i].uin; /* alias */
      }
   }
   for ( i=0; i < strlen( nick ); i++ )
   {
      if ( ! isdigit( (int) nick[i] ) )
      {
         non_numeric=TRUE;
         break;
      }
   }
   if ( non_numeric )
      return -1; /* not found and not a number */
   else
      return atoi( nick );
}


static void Initalize_RC_File( void )
{
   FD_T rcf;
   time_t t;
   char nickstr[100];
 
   rcf = open( rcfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
   if ( rcf == -1 )
   {
      perror( "Error creating config file " );
      exit( 1);
   }
   M_fdprint( rcf, "# This file was generated by Micq of %s %s\n",__TIME__,__DATE__);
   t = time( NULL );
   M_fdprint( rcf, "# This file was generated on %s", ctime( &t ) );   
   printf( "Enter UIN or nickname : #" );
   fflush( stdout );
   scanf( "%s", nickstr );
   UIN = nick2uin( nickstr );
   M_fdprint( rcf, "UIN %d\n", UIN );
   printf( "Enter password : " );
   fflush( stdout );
   Echo_Off();
   scanf( "%s", passwd );
   Echo_On();
   M_fdprint( rcf, "Password %s\n", passwd );
   set_status = STATUS_ONLINE;
   M_fdprint( rcf, "Status %d\n", STATUS_ONLINE );
   M_fdprint( rcf, "Server %s\n", "icq1.mirabilis.com" );
   strcpy( server, "icq1.mirabilis.com" );
   remote_port = 4000;
   M_fdprint( rcf, "Port %d\n", 4000 );
   M_fdprint( rcf, "#No_Log\n" );
   M_fdprint( rcf, "\n#Russian\n#if you want KOI8-R to CP1251 Russain translation uncomment the above line.\n" );

   M_fdprint( rcf, "\n# Below are the commands which can be changed to most anything you want :)\n" );
   M_fdprint( rcf, "message_cmd msg\n");
   M_fdprint( rcf, "info_cmd info\n");
   M_fdprint( rcf, "quit_cmd q\n");
   M_fdprint( rcf, "reply_cmd r\n");
   M_fdprint( rcf, "again_cmd a\n");
   M_fdprint( rcf, "list_cmd w\n");
   M_fdprint( rcf, "away_cmd away\n");
   M_fdprint( rcf, "na_cmd na\n");
   M_fdprint( rcf, "dnd_cmd dnd\n");
   M_fdprint( rcf, "online_cmd online\n");
   
   M_fdprint( rcf, "occ_cmd occ\n");
   M_fdprint( rcf, "ffc_cmd ffc\n");
   M_fdprint( rcf, "inv_cmd inv\n");
   M_fdprint( rcf, "search_cmd search\n");
   M_fdprint( rcf, "status_cmd status\n");
   M_fdprint( rcf, "auth_cmd auth\n");
   M_fdprint( rcf, "auto_cmd auto\n");
   M_fdprint( rcf, "add_cmd add\n");
   M_fdprint( rcf, "change_cmd change\n");

			   
   M_fdprint( rcf, "\n# Ok now the contact list\n" );
   M_fdprint( rcf, "Contacts\n" );
   M_fdprint( rcf, "11300897 Linux Master\n" );
   M_fdprint( rcf, "11290140 Morgoth\n" );
   M_fdprint( rcf, "alias1\n" );
   M_fdprint( rcf, "# ^-- Alias to morgtoh\n" );
   Num_Contacts = 3;
   Contacts[0].uin = 11300897;
   strcpy( Contacts[0].nick, "Linux Master" );
   Contacts[0].status = STATUS_OFFLINE;
   Contacts[0].last_time = -1L;
   Contacts[0].current_ip = 0x7f000001;
   Contacts[ 0 ].port = 0;
   Contacts[ 0 ].sok = (SOK_T ) -1L;
   Contacts[1].uin = 11290140;
   strcpy( Contacts[1].nick, "Morgoth" );
   Contacts[1].status = STATUS_OFFLINE;
   Contacts[1].last_time = -1L;
   Contacts[1].current_ip = 0x7f000001;
   Contacts[ 1 ].port = 0;
   Contacts[ 1 ].sok = (SOK_T ) -1L;
   Contacts[2].uin = -11290140;
   strcpy( Contacts[2].nick, "alias1" );
   Contacts[2].status = STATUS_OFFLINE;
   Contacts[2].last_time = -1L;
   Contacts[2].current_ip = 0x7f000001;
   Contacts[ 2 ].port = 0;
   Contacts[ 2 ].sok = (SOK_T ) -1L;
   close( rcf );
   
	strcpy(message_cmd, "msg");
	strcpy(info_cmd, "info");
	strcpy(add_cmd, "add");
	strcpy(quit_cmd, "q");
	strcpy(reply_cmd, "r");       
	strcpy(again_cmd, "a");
	strcpy(list_cmd, "w");
	strcpy(away_cmd, "away");
	strcpy(na_cmd, "na");
	strcpy(dnd_cmd, "dnd");   
	strcpy(online_cmd, "online");
	strcpy(occ_cmd, "occ");
	strcpy(ffc_cmd, "ffc");
	strcpy(inv_cmd, "inv");
	strcpy(status_cmd, "status");
	strcpy(auth_cmd, "auth");
	strcpy(auto_cmd, "auto");
	strcpy(search_cmd, "search");
}

static void Read_RC_File( FD_T rcf )
{
   char buf[100];
   char *tmp;
   DWORD tmp_uin;
   
   message_cmd[0]='\0'; /* for error checking later */
   quit_cmd[0]='\0'; /* for error checking later */
   info_cmd[0]='\0'; /* for error checking later */
   reply_cmd[0]='\0'; /* for error checking later */
   again_cmd[0]='\0'; /* for error checking later */
   add_cmd[0]='\0'; /* for error checking later */

   list_cmd[0]='\0'; /* for error checking later */
   away_cmd[0]='\0'; /* for error checking later */
   na_cmd[0]='\0'; /* for error checking later */
   dnd_cmd[0]='\0'; /* for error checking later */
   online_cmd[0]='\0'; /* for error checking later */
   occ_cmd[0]='\0'; /* for error checking later */
   ffc_cmd[0]='\0'; /* for error checking later */
   inv_cmd[0]='\0'; /* for error checking later */
   status_cmd[0]='\0'; /* for error checking later */
   auth_cmd[0]='\0'; /* for error checking later */
   auto_cmd[0]='\0'; /* for error checking later */
   change_cmd[0]='\0'; /* for error checking later */
   search_cmd[0]='\0'; /* for error checking later */

   
   Contact_List = FALSE;
   for ( ; !Contact_List; )
   {
      M_fdnreadln( rcf, buf, sizeof( buf ) );
      if ( ( buf[0] != '#' ) && ( buf[0] != 0 ) )
      {
         tmp = strtok( buf, " " );
         if ( ! strcasecmp( tmp, "Server" ) )
         {
            strcpy( server, strtok( NULL, " \n\t" ) );
         }
         else if ( ! strcasecmp( tmp, "Password" ) )
         {
            strcpy( passwd, strtok( NULL, "\n\t" ) );
         }
         else if ( ! strcasecmp( tmp, "Russian" ) )
         {
            Russian = TRUE;
         }
         else if ( ! strcasecmp( tmp, "No_Log" ) )
         {
            Logging = FALSE;
         }
         else if ( ! strcasecmp( tmp, "UIN" ) )
         {
             UIN = atoi( strtok( NULL, " \n\t" ) );
         }
         else if ( ! strcasecmp( tmp, "port" ) )
         {
             remote_port = atoi( strtok( NULL, " \n\t" ) );
         }
         else if ( ! strcasecmp( tmp, "Status" ) )
         {
             set_status = atoi( strtok( NULL, " \n\t" ) );
         }
	      else if ( ! strcasecmp( tmp, "message_cmd") )
	      {
		      strncpy(message_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "info_cmd") )
	      {
		      strncpy(info_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "quit_cmd") )
	      {
		      strncpy(quit_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "reply_cmd") )
	      {
		      strncpy(reply_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "again_cmd") )
	      {
		      strncpy(again_cmd,strtok(NULL," \n\t"), 16 );
	      }

	      else if ( ! strcasecmp( tmp, "list_cmd") )
	      {
		      strncpy(list_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "away_cmd") )
	      {
		      strncpy(away_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "na_cmd") )
	      {
		      strncpy(na_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "dnd_cmd") )
	      {
		      strncpy(dnd_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "online_cmd") )
	      {
		      strncpy(online_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "occ_cmd") )
	      {
		      strncpy(occ_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "ffc_cmd") )
	      {
		      strncpy(ffc_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "inv_cmd") )
	      {
		      strncpy(inv_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "status_cmd") )
	      {
		      strncpy(status_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "auth_cmd") )
	      {
		      strncpy(auth_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "auto_cmd") )
	      {
		      strncpy(auto_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "change_cmd") )
	      {
		      strncpy(change_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "add_cmd") )
	      {
		      strncpy(add_cmd,strtok(NULL," \n\t"), 16 );
	      }
	      else if ( ! strcasecmp( tmp, "search_cmd") )
	      {
		      strncpy(search_cmd,strtok(NULL," \n\t"), 16 );
	      }
         else if ( ! strcasecmp( tmp, "Contacts" ) )
         {
            Contact_List = TRUE;
         }
      }
   }
   for ( ; ! M_fdnreadln( rcf, buf, sizeof( buf ) ); )
   {
      if ( Num_Contacts == 100 )
         break;
      if ( ( buf[0] != '#' ) && ( buf[0] != 0 ) )
      {
         if ( isdigit( (int) buf[0] ) )
         {
            Contacts[ Num_Contacts ].uin = atoi( strtok( buf, " " ) );
            Contacts[ Num_Contacts ].status = STATUS_OFFLINE;
            Contacts[ Num_Contacts ].last_time = -1L;
            Contacts[ Num_Contacts ].current_ip = -1L;
            tmp = strtok( NULL, "" );
            if ( tmp != NULL )
               memcpy( Contacts[ Num_Contacts ].nick, tmp, sizeof( Contacts->nick )  );
            else
               Contacts[ Num_Contacts ].nick[0] = 0;
            if ( Contacts[ Num_Contacts ].nick[19] != 0 )
               Contacts[ Num_Contacts ].nick[19] = 0;
            if ( Verbose )
               printf( "%ld = %s\n", Contacts[ Num_Contacts ].uin, Contacts[ Num_Contacts ].nick );
            Num_Contacts++;
         }
         else
         {
            tmp_uin = Contacts[ Num_Contacts - 1 ].uin;
            tmp = strtok( buf, ", \t" ); /* aliases may not have spaces */
            for ( ; tmp!=NULL; Num_Contacts++ )
            {
               Contacts[ Num_Contacts ].uin = -tmp_uin;
               Contacts[ Num_Contacts ].status = STATUS_OFFLINE;
               Contacts[ Num_Contacts ].last_time = -1L;
               Contacts[ Num_Contacts ].current_ip = -1L;
               Contacts[ Num_Contacts ].port = 0;
               Contacts[ Num_Contacts ].sok = (SOK_T ) -1L;
               memcpy( Contacts[ Num_Contacts ].nick, tmp, sizeof( Contacts->nick )  );
               tmp = strtok( NULL, ", \t" );
            }
         }
      }
   }
   if(message_cmd[0]=='\0')
	   strcpy(message_cmd, "msg");
   if(info_cmd[0]=='\0')
	   strcpy(info_cmd, "info");
   if(quit_cmd[0]=='\0')
	   strcpy(quit_cmd, "q");
   if(reply_cmd[0]=='\0')
	   strcpy(reply_cmd, "r");       
   if(again_cmd[0]=='\0')
	   strcpy(again_cmd, "a");

   if(list_cmd[0]=='\0')
	   strcpy(list_cmd, "w");
   if(away_cmd[0]=='\0')
	   strcpy(away_cmd, "away");
   if(na_cmd[0]=='\0')
	   strcpy(na_cmd, "na");
   if(dnd_cmd[0]=='\0')
	   strcpy(dnd_cmd, "dnd");   
   if(online_cmd[0]=='\0')
	   strcpy(online_cmd, "online");
   if(occ_cmd[0]=='\0')
	   strcpy(occ_cmd, "occ");
   if(ffc_cmd[0]=='\0')
	   strcpy(ffc_cmd, "ffc");
   if(inv_cmd[0]=='\0')
	   strcpy(inv_cmd, "inv");
   if(status_cmd[0]=='\0')
	   strcpy(status_cmd, "status");
   if(add_cmd[0]=='\0')
	   strcpy(add_cmd, "add");
   if(auth_cmd[0]=='\0')
	   strcpy(auth_cmd, "auth");
   if(auto_cmd[0]=='\0')
	   strcpy(auto_cmd, "auto");
   if(search_cmd[0]=='\0')
	   strcpy(search_cmd, "search");


   if(change_cmd[0]=='\0')
	   strcpy(change_cmd, "change");
   if ( Verbose )
   {
      printf( "UIN = %ld\n", UIN );
      printf( "port = %ld\n", remote_port );
      printf( "passwd = %s\n", passwd );
      printf( "server = %s\n", server );
      printf( "status = %ld\n", set_status );
      printf( "# of contacts = %d\n", Num_Contacts );
      printf( "UIN of contact[0] = %ld\n", Contacts[0].uin );
      printf( "Message_cmd = %s\n", message_cmd );
   }
}

/*******************************************************
Gets config info from the rc file in the users home 
directory.
********************************************************/
void Get_Unix_Config_Info( void )
{
   char *path;
   FD_T rcf;

#ifdef _WIN32
   path = ".\\";
#endif

#if defined(UNIX) && !defined(AMIGA)
   path = getenv( "HOME" );
   strcat( path, "/" );
#else
 #ifdef AMIGA
   path = "PROGDIR:";
 #endif
#endif

   strcpy( rcfile, path );
   strcat( rcfile, ".micqrc" );
   rcf = open( rcfile, O_RDONLY );
   if ( rcf == -1 )
   {
      if ( errno == ENOENT ) /* file not found */
      {
         Initalize_RC_File();
      }
      else
      {
         perror( "Error reading config file exiting " );
         exit( 1 );
      }
   }
   else
   {
      Read_RC_File( rcf );
   }
}

void Print_IP( DWORD uin )
{
   int i;
   DWORD t;
   
   for ( i=0; i< Num_Contacts; i++ )
   {
      if ( Contacts[i].uin == uin )
      {
         if ( Contacts[i].current_ip != -1L )
         {
            t = Contacts[i].current_ip;
            if ( Int_End )
               printf( "%u.%u.%u.%u",(BYTE) (t>>24),(BYTE) (t>>16),(BYTE) (t>>8),(BYTE) (t) );
            else
               printf( "%u.%u.%u.%u",(BYTE) (t),(BYTE) (t>>8),(BYTE) (t>>16),(BYTE) (t>>24) );
         }
         else
         {
            printf( "unknown" );
         }
         return;
      }
   }
   printf( "unknown" );
}

/************************************************
Gets the TCP port of the specified UIN
************************************************/
DWORD Get_Port( DWORD uin )
{
   int i;
   
   for ( i=0; i< Num_Contacts; i++ )
   {
      if ( Contacts[i].uin == uin )
      {
         return Contacts[i].port;
      }
   }
   return -1L;
}

/********************************************
Converts an intel endian character sequence to
a DWORD
*********************************************/
DWORD Chars_2_DW( unsigned char *buf )
{
   DWORD i;
   
   i= buf[3];
   i <<= 8;
   i+= buf[2];
   i <<= 8;
   i+= buf[1];
   i <<= 8;
   i+= buf[0];
   
   return i;
}

/********************************************
Converts an intel endian character sequence to
a WORD
*********************************************/
WORD Chars_2_Word( unsigned char *buf )
{
   WORD i;
   
   i= buf[1];
   i <<= 8;
   i += buf[0];
   
   return i;
}

/********************************************
Converts a DWORD to
an intel endian character sequence 
*********************************************/
void DW_2_Chars( unsigned char *buf, DWORD num )
{
   buf[3] = ( unsigned char ) ((num)>>24)& 0x000000FF;
   buf[2] = ( unsigned char ) ((num)>>16)& 0x000000FF;
   buf[1] = ( unsigned char ) ((num)>>8)& 0x000000FF;
   buf[0] = ( unsigned char ) (num) & 0x000000FF;
}

/********************************************
Converts a WORD to
an intel endian character sequence 
*********************************************/
void Word_2_Chars( unsigned char *buf, WORD num )
{
   buf[1] = ( unsigned char ) (((unsigned)num)>>8) & 0x00FF;
   buf[0] = ( unsigned char ) ((unsigned)num) & 0x00FF;
}

void Prompt( void )
{
   printf( SERVCOL "Micq> " NOCOL );
   fflush( stdout );
}

void Time_Stamp( void )
{
   struct tm *thetime;
   time_t p;
   
   p=time(NULL);
   thetime=localtime(&p);

   printf( "%.02d:%.02d:%.02d",thetime->tm_hour,thetime->tm_min,thetime->tm_sec );
}

void Add_User( SOK_T sok, DWORD uin, char *name )
{
   FD_T rcf;

   rcf = open( rcfile, O_RDWR | O_APPEND );
   M_fdprint( rcf, "%d %s\n", uin, name );
   close( rcf );
   Contacts[ Num_Contacts ].uin = uin;
   Contacts[ Num_Contacts ].status = STATUS_OFFLINE;
   Contacts[ Num_Contacts ].last_time = -1L;
   Contacts[ Num_Contacts ].current_ip = -1L;
   Contacts[ Num_Contacts ].port = 0;
   Contacts[ Num_Contacts ].sok = (SOK_T ) -1L;
   memcpy( Contacts[ Num_Contacts ].nick, name, sizeof( Contacts->nick )  );
   Num_Contacts++;
   snd_contact_list( sok );
}

/*************************************************************************
 *
 *      Function: log_event
 *
 *      Purpose: Log the event provided to the log with a time stamp.
 *      Andrew Frolov dron@ilm.net
 *************************************************************************/

int log_event( char *desc, char *msg, DWORD uin )
{
   FILE    *msgfd;
   char    buffer[256];
   time_t  timeval;
   char *path;

   if ( ! Logging )
      return 0;
      
#ifdef _WIN32
   path = ".\\";
#endif

#if defined(UNIX) && !defined(AMIGA)
   path = getenv( "HOME" );
   strcat( path, "/" );
#else
   #ifdef AMIGA
    path = "PROGDIR:";
   #endif
#endif

   strcpy( buffer, path );
   strcat( buffer, "micq_log" );


   if( ( msgfd = fopen(buffer, "a") ) == (FILE *) NULL ) 
   {
           fprintf(stderr, "Couldn't open %s for logging\n",
                            buffer);
           return(-1);
   }
   timeval = time(0);
   fprintf(msgfd, "\n%-24.24s %s %ld\n%s\n", ctime(&timeval),desc, uin, msg);
   fclose(msgfd);

#if defined(UNIX) && !defined(AMIGA)
   chmod( buffer, 0600 );
#endif
   return(0);
}
