util.c
上传用户:ai20ln
上传日期:2007-01-05
资源大小:79k
文件大小:48k
源码类别:

ICQ/即时通讯

开发平台:

Unix_Linux

  1. /*********************************************
  2. **********************************************
  3. This is a file of general utility functions useful
  4. for programming in general and icq in specific
  5. This software is provided AS IS to be used in
  6. whatever way you see fit and is placed in the
  7. public domain.
  8. Author : Matthew Smith April 23, 1998
  9. Contributors :  airog (crabbkw@rose-hulman.edu) May 13, 1998
  10. Changes :
  11.   6-18-98 Added support for saving auto reply messages. Fryslan
  12.  
  13. **********************************************
  14. **********************************************/
  15. #include "micq.h"
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <stdarg.h>
  19. #include <assert.h>
  20. #include <string.h>
  21. #include <ctype.h>
  22. #include <errno.h>
  23. #include <time.h>
  24. #include <sys/types.h>
  25. #include <sys/time.h>
  26. #include <sys/stat.h>
  27. #include <netinet/in.h>
  28. #include <arpa/inet.h>
  29. #include <fcntl.h>
  30. #ifdef _WIN32
  31.    #include <io.h>
  32.    #define S_IRUSR _S_IREAD
  33.    #define S_IWUSR _S_IWRITE
  34. #endif
  35. #ifdef UNIX
  36.    #include <unistd.h>
  37.    #include <termios.h>
  38. #endif
  39. #ifdef UNIX
  40. char *strdup( const char * );
  41. int strcasecmp( const char *, const char * );
  42. int strncasecmp( const char *, const char *, size_t );
  43. #endif
  44. #define   ADD_COMMAND(a, b)     else if ( ! strcasecmp( tmp, a) )   
  45.       {                                                          
  46.       strncpy( b,strtok(NULL," nt"), 16 );                  
  47.       }                                                          
  48. #define   ADD_MESS(a, b)     else if ( ! strcasecmp( tmp, a) )   
  49.       {                                                          
  50.       strncpy( b,strtok(NULL,"n"), 450 );                  
  51.       }                                                          
  52. #define ADD_COLOR(a)      else if ( ! strncmp( str2, a , strlen( a ) ) ) 
  53.       {                                                                 
  54.          if ( Color )                                                   
  55.             printf( a );                                                
  56.          str2 += strlen( a );                                           
  57.       }
  58. static char rcfile[256];
  59. typedef struct 
  60. {
  61.    const char *name;
  62.    WORD code;
  63. } COUNTRY_CODE;
  64. static COUNTRY_CODE Country_Codes[] = { {"USA",1 },
  65.                                  {"Afghanistan", 93 },
  66.  {"Albania", 355 },
  67.                                  {"Algeria", 213 },
  68.                                  {"American Samoa", 684 },
  69.  {"Andorra", 376 },
  70.  {"Angola", 244 },
  71.  {"Anguilla", 101 },
  72.  {"Antigua", 102 },
  73.                                  {"Argentina", 54 },
  74.  {"Armenia", 374 },
  75.                                  {"Aruba", 297 },
  76.  {"Ascention Island", 274 },
  77.                                  {"Australia", 61 },
  78.                                  {"Australian Antartic Territory", 6721 },
  79.                                  {"Austria", 43 },
  80.                                  {"Azerbaijan", 934 },
  81.                                  {"Bahamas", 103 },
  82.                                  {"Bahrain", 973 },
  83.                                  {"Bangladesh", 880 },
  84.                                  {"Barbados", 104 },
  85.                                  {"Belarus", 375 },
  86.                                  {"Belgium", 32 },
  87.                                  {"Belize", 501 },
  88.                                  {"Benin", 229 },
  89.                                  {"Bermuda", 105 },
  90.                                  {"Bhutan", 975 },
  91.                                  {"Bolivia", 591 },
  92.                                  {"Bosnia & Herzegovina", 387 },
  93.                                  {"Botswana", 267 },
  94.                                  {"Brazil",55 },
  95.  {"British Virgin Islands", 106 },
  96.  {"Brunei", 673 },
  97.  {"Bulgaria", 359 },
  98.  {"Burkina Faso", 226 },
  99.  {"Burundi", 257 },
  100.  {"Cambodia", 855 },
  101.                                  {"Cameroon", 237 },
  102.                                  {"Canada",107 },
  103.  {"Cape Verde Islands", 238 },
  104.  {"Cayman Islands", 108},
  105.  {"Central African Republic", 236},
  106.  {"Chad", 235},
  107.  {"Christmas Island", 672},
  108.  {"Cocos-Keeling Islands", 6101},
  109.  {"Comoros", 2691},
  110.  {"Congo", 242},
  111.  {"Cook Islands", 682},
  112.                                  {"Chile", 56 },
  113.                                  {"China", 86 },
  114.                                  {"Columbia", 57 },
  115.                                  {"Costa Rice", 506 },
  116.                                  {"Croatia", 385 }, /* Observerd */
  117.  { "Cuba", 53 },
  118.                                  {"Cyprus", 357 },
  119.                                  {"Czech Republic", 42 },
  120.                                  {"Denmark",45 },
  121.  {"Diego Garcia", 246},
  122.  {"Djibouti", 253},
  123.  {"Dominica", 109},
  124.  {"Dominican Republic", 110},
  125.                                  {"Ecuador", 593 },
  126.                                  {"Egypt", 20 },
  127.                                  {"El Salvador", 503 },
  128.  {"Equitorial Guinea", 240},
  129.  {"Eritrea", 291},
  130.  {"Estonia", 372},
  131.                                  {"Ethiopia", 251 },
  132.  {"F.Y.R.O.M. (Former Yugoslavia)", 389},
  133.  {"Faeroe Islands", 298},
  134.  {"Falkland Islands", 500},
  135.  {"Federated States of Micronesia", 691 },
  136.                                  {"Fiji", 679 },
  137.                                  {"Finland", 358 },
  138.                                  {"France", 33 },
  139.                                  {"French Antilles", 596 },  /* Leave it */
  140.                                  {"French Antilles", 5901 }, /* Either on or the other is right :) */
  141.                                  {"French Guiana", 594 },
  142.                                  {"French Polynesia", 689 },
  143.                                  {"Gabon", 241 },
  144.                                  {"Gambia", 220 },
  145.                                  {"Georgia", 995 },
  146.                                  {"Germany", 49 },
  147.                                  {"Ghana", 233 },
  148.                                  {"Gibraltar", 350 },
  149.                                  {"Greece", 30 },
  150.                                  {"Greenland", 299 },
  151.                                  {"Grenada", 111 },
  152.                                  {"Guadeloupe", 590 },
  153.                                  {"Guam", 671 },
  154.                                  {"Guantanomo Bay", 5399 },
  155.                                  {"Guatemala", 502 },
  156.                                  {"Guinea", 224 },
  157.                                  {"Guinea-Bissau", 245 },
  158.                                  {"Guyana", 592 },
  159.                                  {"Haiti", 509 },
  160.                                  {"Honduras", 504 },
  161.                                  {"Hong Kong", 852 },
  162.                                  {"Hungary", 36 },
  163.                                  {"Iceland", 354 },
  164.                                  {"India", 91 },
  165.                                  {"Indonesia", 62 },
  166.                                  {"INMARSAT", 870 },
  167.                                  {"INMARSAT Atlantic-East", 870 },
  168.                                  {"Iran", 98 },
  169.                                  {"Iraq", 964 },
  170.                                  {"Ireland", 353 },
  171.                                  {"Israel", 972 },
  172.                                  {"Italy", 39 },
  173.                                  {"Ivory Coast", 225 },
  174.                                  {"Japan", 81 },
  175.                                  {"Jordan", 962 },
  176.                                  {"Kenya", 254 },
  177.                                  {"South Korea", 82 },
  178.                                  {"Kuwait", 965 },
  179.                                  {"Liberia", 231 },
  180.                                  {"Libya", 218 },
  181.                                  {"Liechtenstein", 4101 },
  182.                                  {"Luxembourg", 352 },
  183.                                  {"Malawi", 265 },
  184.                                  {"Malaysia", 60 },
  185.                                  {"Mali", 223 },
  186.                                  {"Malta", 356 },
  187.                                  {"Mexico", 52 },
  188.                                  {"Monaco", 33 },
  189.                                  {"Morocco", 212 },
  190.                                  {"Namibia", 264 },
  191.                                  {"Nepal", 977 },
  192.                                  {"Netherlands", 31 },
  193.                                  {"Netherlands Antilles", 599 },
  194.                                  {"New Caledonia", 687 },
  195.                                  {"New Zealand", 64 },
  196.                                  {"Nicaragua", 505 },
  197.                                  {"Nigeria", 234 },
  198.                                  {"Norway",47 }, 
  199.                                  {"Oman", 968 },
  200.                                  {"Pakistan", 92 },
  201.                                  {"Panama", 507 },
  202.                                  {"Papua New Guinea", 675 },
  203.                                  {"Paraguay", 595 },
  204.                                  {"Peru", 51 },
  205.                                  {"Philippines", 63 },
  206.                                  {"Poland", 48 },
  207.                                  {"Portugal", 351 },
  208.                                  {"Qatar", 974 },
  209.                                  {"Romania", 40 },
  210.                                  {"Russia",7 },
  211.                                  {"Saipan", 670 },
  212.                                  {"San Marino", 39 },
  213.                                  {"Saudia Arabia", 966 },
  214.                                  {"Saipan", 670 },
  215.                                  {"Senegal", 221},
  216.                                  {"Singapore", 65 },
  217.                                  {"Slovakia", 42 },
  218.                                  {"South Africa", 27 },
  219.                                  {"Spain", 34 },
  220.                                  {"Sri Lanka", 94 },
  221.                                  {"Suriname", 597 },
  222.                                  {"Sweden",46 },
  223.                                  {"Switzerland", 41 },
  224.                                  {"Taiwan", 886 },
  225.                                  {"Tanzania", 255 },
  226.                                  {"Thailand", 66 },
  227.                                  {"Tunisia", 216 },
  228.                                  {"Turkey", 90 },
  229.                                  {"United Arab Emirates", 971 },
  230.                                  {"Uruguay", 598 },
  231.                                  {"UK",0x2c },
  232.  {"Ukraine", 380 },
  233.                                  {"Vatican City", 39 },
  234.                                  {"Venezuela", 58 },
  235.                                  {"Vietnam", 84 },
  236.                                  {"Yemen", 967 },
  237.                                  {"Yugoslavia", 38 },
  238.                                  {"Zaire", 243 },
  239.                                  {"Zimbabwe", 263 },
  240. #ifdef FUNNY_MSGS
  241.                                  {"Illegal alien",0 },
  242.                                  {"Illegal alien",0xffff } };
  243. #else
  244.                                  {"Not entered",0 },
  245.                                  {"Not entered",0xffff } };
  246. #endif
  247. const char *Get_Country_Name( int code )
  248. {
  249.    int i;
  250.    
  251.    for ( i = 0; Country_Codes[i].code != 0xffff; i++)
  252.    {
  253.       if ( Country_Codes[i].code == code )
  254.       {
  255.          return Country_Codes[i].name;
  256.       }
  257.    }
  258.    if ( Country_Codes[i].code == code )
  259.    {
  260.       return Country_Codes[i].name;
  261.    }
  262.    return NULL;
  263. }
  264. /***************************************************************
  265. Turns keybord echo off for the password
  266. ****************************************************************/
  267. S_DWORD Echo_Off( void )
  268. {
  269. #ifdef UNIX
  270. struct termios attr; /* used for getting and setting terminal
  271. attributes */
  272. /* Now turn off echo */
  273. if (tcgetattr(STDIN_FILENO, &attr) != 0) return(-1);
  274. /* Start by getting current attributes.  This call copies
  275. all of the terminal paramters into attr */
  276. attr.c_lflag &= ~(ECHO);
  277. /* Turn off echo flag.  NOTE: We are careful not to modify any
  278. bits except ECHO */
  279. if (tcsetattr(STDIN_FILENO,TCSAFLUSH,&attr) != 0) return(-2);
  280. /* Wait for all of the data to be printed. */
  281. /* Set all of the terminal parameters from the (slightly)
  282.    modified struct termios */
  283. /* Discard any characters that have been typed but not yet read */
  284. #endif
  285. return 0;
  286. }
  287. /***************************************************************
  288. Turns keybord echo back on after the password
  289. ****************************************************************/
  290. S_DWORD Echo_On( void )
  291. {
  292. #ifdef UNIX
  293. struct termios attr; /* used for getting and setting terminal
  294. attributes */
  295. if (tcgetattr(STDIN_FILENO, &attr) != 0) return(-1);
  296. attr.c_lflag |= ECHO;
  297. if(tcsetattr(STDIN_FILENO,TCSANOW,&attr) != 0) return(-1);
  298. #endif
  299. return 0;
  300. }
  301. /**************************************************************
  302. Same as fM_print but for FD_T's
  303. ***************************************************************/
  304. void M_fdprint( FD_T fd, char *str, ... )
  305. {
  306.    va_list args;
  307.    int k;
  308.    char buf[2048]; /* this should big enough */
  309.         
  310.    assert( buf != NULL );
  311.    assert( 2048 >= strlen( str ) );
  312.    
  313.    va_start( args, str );
  314.    vsprintf( buf, str, args );
  315.    k = write( fd, buf, strlen( buf ) );
  316.    if ( k != strlen( buf ) )
  317.    {
  318.       perror(str);
  319.       exit ( 10);
  320.    }
  321.    va_end( args );
  322. }
  323. /************************************************************
  324. Prints the preformated sting to stdout.
  325. Plays sounds if appropriate.
  326. ************************************************************/
  327. static void M_prints( char *str )
  328. {
  329.    int i;
  330.    
  331.    for ( i=0; str[i] != 0; i++ )
  332.    {
  333.       if ( str[i] != 'a' )
  334.          printf( "%c", str[i] );
  335.       else if ( SOUND_ON == Sound )
  336.          printf( "a" );
  337.       else if ( SOUND_CMD == Sound )
  338.   system ( Sound_Str );
  339.    }
  340. }
  341. /**************************************************************
  342. M_print with colors.
  343. ***************************************************************/
  344. void M_print( char *str, ... )
  345. {
  346.    va_list args;
  347.    char buf[2048];
  348.    char *str1, *str2;
  349.    
  350.    va_start( args, str );
  351. #ifndef CURSES_UI
  352.    vsprintf( buf, str, args );
  353.    str2 = buf;
  354.    while ( (void *) NULL != ( str1 = strchr( str2, 'x1b' ) ) )
  355.    {
  356.       str1[0] = 0;
  357.       M_prints( str2 );
  358.       str1[0] = 0x1B;
  359.       str2 = str1;
  360.       if ( FALSE ) {;}
  361.       ADD_COLOR( NOCOL )
  362.       ADD_COLOR( SERVCOL )
  363.       ADD_COLOR( MESSCOL )
  364.       ADD_COLOR( CONTACTCOL )
  365.       ADD_COLOR( CLIENTCOL )
  366.       else
  367.       {
  368.           str2++;
  369.       }
  370.    }
  371.    M_prints( str2 );
  372. #else
  373.    #error No curses support included yet.
  374.    #error You must add it yourself.
  375. #endif
  376.    va_end( args );
  377. }
  378. /***********************************************************
  379. Reads a line of input from the file descriptor fd into buf
  380. an entire line is read but no more than len bytes are 
  381. actually stored
  382. ************************************************************/
  383. int M_fdnreadln( FD_T fd, char *buf, size_t len )
  384. {
  385.    int i,j;
  386.    char tmp;
  387.    assert( buf != NULL );
  388.    assert( len > 0 );
  389.    tmp = 0;
  390.    len--;
  391.    for ( i=-1; ( tmp != 'n' )  ; )
  392.    {
  393.       if  ( ( i < len ) || ( i == -1 ) )
  394.       {
  395.          i++;
  396.          j = read( fd, &buf[i], 1 );
  397.          tmp = buf[i];
  398.       }
  399.       else
  400.       {
  401.          j = read( fd, &tmp, 1 );
  402.       }
  403.       assert( j != -1 );
  404.       if ( j == 0 )
  405.       {
  406.          buf[i] =  0;
  407.          return -1;
  408.       }
  409.    }
  410.    if ( i < 1 )
  411.    {
  412.       buf[i] = 0;
  413.    }
  414.    else
  415.    {
  416.       if ( buf[i-1] == 'r' )
  417.       {
  418.          buf[i-1] = 0;
  419.       }
  420.       else
  421.       {
  422.          buf[i] = 0;
  423.       }
  424.    } 
  425.    return 0;
  426. }
  427. /********************************************
  428. returns a string describing the status or
  429. a NULL if no such string exists
  430. *********************************************/
  431. char *Convert_Status_2_Str( int status )
  432. {
  433.    if ( STATUS_OFFLINE == status ) /* this because -1 & 0xFFFF is not -1 */
  434.    {
  435.       return "Offline";
  436.    }
  437.    
  438.    switch ( status & 0x1ff )
  439.    {
  440.    case STATUS_ONLINE:
  441.       return "Online";
  442.       break;
  443.    case STATUS_DND:
  444.       return "Do not disturb";
  445.       break;
  446.    case STATUS_AWAY:
  447.       return "Away";
  448.       break;
  449.    case STATUS_OCCUPIED:
  450.       return "Occupied";
  451.       break;
  452.    case STATUS_NA:
  453.    case STATUS_NA_99:
  454.       return "Not available";
  455.       break;
  456.    case STATUS_INVISIBLE:
  457.       return "Invisible";
  458.       break;
  459.    case STATUS_OCCUPIED_MAC:
  460.       return "Occupied (macintosh)";
  461.       break;
  462.    case STATUS_FREE_CHAT:
  463.       return "Free for chat";
  464.       break;
  465.    default :
  466.       return NULL;
  467.       break;
  468.    }
  469. }
  470. /********************************************
  471. Prints a informative string to the screen.
  472. describing the command
  473. *********************************************/
  474. void Print_CMD( WORD cmd )
  475. {
  476.    switch ( cmd )
  477.    {
  478.    case CMD_KEEP_ALIVE:
  479.       M_print( "Keep Alive" );
  480.       break;
  481.    case CMD_KEEP_ALIVE2:
  482.       M_print( "Secondary Keep Alive" );
  483.       break;
  484.    case CMD_CONT_LIST:
  485.       M_print( "Contact List" );
  486.       break;
  487.    case CMD_INVIS_LIST:
  488.       M_print( "Invisible List" );
  489.       break;
  490.    case CMD_VIS_LIST:
  491.       M_print( "Visible List" );
  492.       break;
  493.    case CMD_RAND_SEARCH:
  494.       M_print( "Random Search" );
  495.       break;
  496.    case CMD_RAND_SET:
  497.       M_print( "Set Random" );
  498.       break;
  499.    case CMD_ACK_MESSAGES:
  500.       M_print( "Delete Server Messages" );
  501.       break;
  502.    case CMD_LOGIN_1:
  503.       M_print( "Finish Login" );
  504.       break;
  505.    case CMD_LOGIN:
  506.       M_print( "Login" );
  507.       break;
  508.    case CMD_SENDM:
  509.       M_print( "Send Message" );
  510.       break;
  511.    case CMD_INFO_REQ:
  512.       M_print( "Info Request" );
  513.       break;
  514.    case CMD_EXT_INFO_REQ:
  515.       M_print( "Extended Info Request" );
  516.       break;
  517.    default :
  518.       M_print( "%04X", cmd );
  519.       break;
  520.    }
  521. }
  522. /********************************************
  523. prints out the status of new_status as a string
  524. if possible otherwise as a hex number
  525. *********************************************/
  526. void Print_Status( DWORD new_status  )
  527. {
  528.    if ( Convert_Status_2_Str( new_status ) != NULL )
  529.    {
  530.       M_print( "%s", Convert_Status_2_Str( new_status ) );
  531.       if ( Verbose )
  532.          M_print( " %06X",( WORD ) ( new_status >> 8 ) );
  533.    }
  534.    else
  535.    {
  536.       M_print( "%08lX", new_status );
  537.    }
  538. }
  539. /**********************************************
  540.  * Returns the nick of a UIN if we know it else
  541.  * it will return Unknow UIN
  542.  **********************************************/
  543. char *UIN2nick( DWORD uin)
  544. {
  545.    int i;
  546.    for ( i=0; i < Num_Contacts; i++ )
  547.    {
  548.      if ( Contacts[i].uin == uin )
  549.         break;
  550.    }
  551.    if ( i == Num_Contacts )
  552.    {
  553.       return "Unknow UIN";
  554.   }
  555.    else
  556.   {
  557.       return Contacts[i].nick;
  558.   }
  559. }
  560. /**********************************************
  561. Prints the name of a user or there UIN if name
  562. is not know.
  563. ***********************************************/
  564. int Print_UIN_Name( DWORD uin )
  565. {
  566.    int i;
  567.    
  568.    for ( i=0; i < Num_Contacts; i++ )
  569.    {
  570.       if ( Contacts[i].uin == uin )
  571.          break;
  572.    }
  573.    if ( i == Num_Contacts )
  574.    {
  575.       M_print( CLIENTCOL "%lu" NOCOL, uin );
  576.       return -1 ;
  577.    }
  578.    else
  579.    {
  580.       M_print( "%s%s%s", CONTACTCOL, Contacts[i].nick, NOCOL );
  581.       return i;
  582.    }
  583. }
  584. /*********************************************
  585. Converts a nick name into a uin from the contact
  586. list.
  587. **********************************************/
  588. DWORD nick2uin( char *nick )
  589. {
  590.    int i;
  591.    BOOL non_numeric=FALSE;
  592.    
  593.    for ( i=0; i< Num_Contacts; i++ )
  594.    {
  595.       if ( ! strncasecmp( nick, Contacts[i].nick, 19  ) )
  596.       {
  597.          if ( (S_DWORD) Contacts[i].uin > 0 )
  598.             return Contacts[i].uin;
  599.          else
  600.             return -Contacts[i].uin; /* alias */
  601.       }
  602.    }
  603.    for ( i=0; i < strlen( nick ); i++ )
  604.    {
  605.       if ( ! isdigit( (int) nick[i] ) )
  606.       {
  607.          non_numeric=TRUE;
  608.          break;
  609.       }
  610.    }
  611.    if ( non_numeric )
  612.       return -1; /* not found and not a number */
  613.    else
  614.       return atoi( nick );
  615. }
  616. /**************************************************
  617. Automates the process of creating a new user.
  618. ***************************************************/
  619. void Init_New_User( void )
  620. {
  621.    SOK_T sok; 
  622.    srv_net_icq_pak pak;
  623.    int s;
  624.    struct timeval tv;
  625.    fd_set readfds;
  626. #ifdef _WIN32
  627.    WSADATA wsaData;
  628. #endif
  629.       
  630. #ifdef _WIN32
  631.    i = WSAStartup( 0x0101, &wsaData );
  632.    if ( i != 0 ) {
  633. #ifdef FUNNY_MSGS
  634. perror("Windows Sockets broken blame Bill -");
  635. #else
  636. perror("Sorry, can't initialize Windows Sockets...");
  637. #endif
  638.     exit(1);
  639.    }
  640. #endif
  641.    M_print( "nCreating Connection...n");
  642.    sok = Connect_Remote( server, remote_port, STDERR );
  643.    if ( ( sok == -1 ) || ( sok == 0 ) ) 
  644.    {
  645.     M_print( "Couldn't establish connectionn" );
  646.     exit( 1 );
  647.    }
  648.    M_print( "Sending Request...n" );
  649.    reg_new_user( sok, passwd );
  650.    for ( ; ; )
  651.    {
  652. #ifdef UNIX
  653.   tv.tv_sec = 3;
  654.       tv.tv_usec = 500000;
  655. #else
  656.   tv.tv_sec = 0;
  657.       tv.tv_usec = 100000;
  658. #endif
  659.       FD_ZERO(&readfds);
  660.       FD_SET(sok, &readfds);
  661.       /* don't care about writefds and exceptfds: */
  662.       select(sok+1, &readfds, NULL, NULL, &tv);
  663.       M_print( "Waiting for response....n" );
  664.       if (FD_ISSET(sok, &readfds))
  665.       {
  666.          s = SOCKREAD( sok, &pak.head.ver, sizeof( pak ) - 2  );
  667.          if ( Chars_2_Word( pak.head.cmd ) == SRV_NEW_UIN )
  668.          {
  669.             UIN = Chars_2_DW( pak.head.UIN );
  670.             M_print( "nYour new UIN is %s%ld%s!n",SERVCOL, UIN, NOCOL );
  671.             return;
  672.          }
  673.          else
  674.          {
  675. /*            Hex_Dump( &pak.head.ver, s );*/
  676.          }
  677.       }
  678.       reg_new_user( sok, passwd );
  679.    }
  680. }
  681. static void Initalize_RC_File( void )
  682. {
  683.    FD_T rcf;
  684. /*   time_t t; */
  685.    char passwd2[ sizeof(passwd) ];
  686.    strcpy( server, "icq1.mirabilis.com" );
  687.    remote_port = 4000;
  688. #if 0   
  689.    M_fdprint( rcf, "# This file was generated by Micq of %s %sn",__TIME__,__DATE__);
  690.    t = time( NULL );
  691.    M_fdprint( rcf, "# This file was generated on %s", ctime( &t ) );   
  692. #endif
  693.    M_print( "Enter UIN or 0 for new UIN: #" );
  694.    fflush( stdout );
  695.    scanf( "%ld", &UIN );
  696. password_entry:
  697.    M_print( "Enter password : " );
  698.    fflush( stdout );
  699.    Echo_Off();
  700.    memset( passwd, 0, sizeof( passwd ) );
  701.    M_fdnreadln(STDIN, passwd, sizeof(passwd));
  702.    Echo_On();
  703.    if ( UIN == 0 )
  704.    {
  705.       if ( 0 == passwd[0] )
  706.       {
  707.          M_print( "nMust enter password!n" );
  708.          goto password_entry;
  709.       }
  710.       M_print( "nReenter password to verify: " );
  711.       fflush( stdout );
  712.       Echo_Off();
  713.       memset( passwd2, 0, sizeof( passwd2 ) );
  714.       M_fdnreadln(STDIN, passwd2, sizeof(passwd));
  715.       Echo_On();
  716.       if ( strcmp( passwd, passwd2 ) )
  717.       {
  718.          M_print( "nPasswords did not match reentern" );
  719.          goto password_entry;
  720.       }
  721.       Init_New_User();
  722.    }
  723. #if 0
  724.    M_fdprint( rcf, "UIN %dn", UIN );
  725.    M_fdprint( rcf, "Password %sn", passwd );
  726. #endif
  727.    set_status = STATUS_ONLINE;
  728. #if 0
  729.    M_fdprint( rcf, "Status %dn", STATUS_ONLINE );
  730.    M_fdprint( rcf, "Server %sn", server );
  731.    M_fdprint( rcf, "Port %dn", remote_port );
  732.    M_fdprint( rcf, "#No_Logn" );
  733.    M_fdprint( rcf, "n#Russiann#if you want KOI8-R to CP1251 Russain translation uncomment the above line.n" );
  734.    M_fdprint( rcf, "n# Below are the commands which can be changed to most anything you want :)n" );
  735.    M_fdprint( rcf, "message_cmd msgn");
  736.    M_fdprint( rcf, "info_cmd infon");
  737.    M_fdprint( rcf, "quit_cmd qn");
  738.    M_fdprint( rcf, "reply_cmd rn");
  739.    M_fdprint( rcf, "again_cmd an");
  740.    M_fdprint( rcf, "list_cmd wn");
  741.    M_fdprint( rcf, "away_cmd awayn");
  742.    M_fdprint( rcf, "auto_rep_str_away I told you I wasn't here!n");
  743.    M_fdprint( rcf, "na_cmd nan");
  744.    M_fdprint( rcf, "auto_rep_str_na Working, working always working...n");
  745.    M_fdprint( rcf, "dnd_cmd dndn");
  746. M_fdprint( rcf, "auto_rep_str_dnd Don't page me, my head is hurting!n");
  747.    M_fdprint( rcf, "online_cmd onlinen");
  748.    
  749.    M_fdprint( rcf, "occ_cmd occn");
  750. M_fdprint( rcf, "auto_rep_str_occ I am working on opening this beer so I am busy.n");
  751.    M_fdprint( rcf, "ffc_cmd ffcn");
  752.    M_fdprint( rcf, "inv_cmd invn");
  753. M_fdprint( rcf, "auto_rep_str_inv So you can see me, so you can't!n");
  754.    M_fdprint( rcf, "search_cmd searchn");
  755.    M_fdprint( rcf, "status_cmd statusn");
  756.    M_fdprint( rcf, "auth_cmd authn");
  757.    M_fdprint( rcf, "auto_cmd auton");
  758.    M_fdprint( rcf, "add_cmd addn");
  759.    M_fdprint( rcf, "change_cmd changen");
  760. M_fdprint( rcf, "save_cmd saven");
  761. M_fdprint( rcf, "alter_cmd altern");
  762. M_fdprint( rcf, "msga_cmd msgan");
  763. M_fdprint( rcf, "url_cmd urln");
  764. M_fdprint( rcf, "update_cmd updaten");
  765.  
  766.    
  767.    M_fdprint( rcf, "n# Ok now the contact listn" );
  768.    M_fdprint( rcf, "n# Put a star in front of any UIN # to add them to your visible list.n" );
  769.    M_fdprint( rcf, "Contactsn" );
  770.    M_fdprint( rcf, "11300897 Linux Mastern" );
  771.    M_fdprint( rcf, "11290140 Micq Authorn" );
  772.    M_fdprint( rcf, "alias1n" );
  773.    M_fdprint( rcf, "# ^-- Alias to Micq Authorn" );
  774. #endif
  775.    Num_Contacts = 2;
  776.    Contacts[ 0 ].vis_list = FALSE;
  777.    Contacts[ 1 ].vis_list = FALSE;
  778.    Contacts[0].uin = 11290140;
  779.    strcpy( Contacts[0].nick, "Micq Author" );
  780.    Contacts[0].status = STATUS_OFFLINE;
  781.    Contacts[0].last_time = -1L;
  782.    Contacts[0].current_ip[0] = 0xff;
  783.    Contacts[0].current_ip[1] = 0xff;
  784.    Contacts[0].current_ip[2] = 0xff;
  785.    Contacts[0].current_ip[3] = 0xff;
  786.    Contacts[ 0 ].port = 0;
  787.    Contacts[ 0 ].sok = (SOK_T ) -1L;
  788.    Contacts[1].uin = -11290140;
  789.    strcpy( Contacts[1].nick, "alias1" );
  790.    Contacts[1].status = STATUS_OFFLINE;
  791.    Contacts[1].current_ip[0] = 0xff;
  792.    Contacts[1].current_ip[1] = 0xff;
  793.    Contacts[1].current_ip[2] = 0xff;
  794.    Contacts[1].current_ip[3] = 0xff;
  795.    Contacts[1].current_ip[0] = 0xff;
  796.    Contacts[1].current_ip[1] = 0xff;
  797.    Contacts[1].current_ip[2] = 0xff;
  798.    Contacts[1].current_ip[3] = 0xff;
  799.    Contacts[ 1 ].port = 0;
  800.    Contacts[ 1 ].sok = (SOK_T ) -1L;
  801. #if 0
  802.    close( rcf );
  803. #endif
  804.    
  805. strcpy(message_cmd, "msg");
  806. strcpy(info_cmd, "info");
  807. strcpy(add_cmd, "add");
  808. strcpy(quit_cmd, "q");
  809. strcpy(reply_cmd, "r");       
  810. strcpy(again_cmd, "a");
  811. strcpy(list_cmd, "w");
  812. strcpy(away_cmd, "away");
  813. strcpy(na_cmd, "na");
  814. strcpy(dnd_cmd, "dnd");   
  815. strcpy(online_cmd, "online");
  816. strcpy(occ_cmd, "occ");
  817. strcpy(ffc_cmd, "ffc");
  818. strcpy(inv_cmd, "inv");
  819. strcpy(status_cmd, "status");
  820. strcpy(auth_cmd, "auth");
  821. strcpy(change_cmd, "change");
  822. strcpy(auto_cmd, "auto");
  823. strcpy(search_cmd, "search");
  824. strcpy(save_cmd, "save");
  825. strcpy(alter_cmd, "alter");
  826. strcpy(msga_cmd, "msga");
  827. strcpy(url_cmd, "url");
  828. strcpy(update_cmd, "update");
  829.    
  830.    Current_Status = STATUS_ONLINE;
  831.    
  832.    rcf = open( rcfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  833.    if ( rcf == -1 )
  834.    {
  835.       perror( "Error creating config file " );
  836.       exit( 1);
  837.    }
  838.    close( rcf );
  839.    if ( Save_RC() == -1 )
  840.    {
  841.       perror( "Error creating config file " );
  842.       exit( 1);
  843.    }
  844. }
  845. static void Read_RC_File( FD_T rcf )
  846. {
  847.    char buf[450];
  848.    char *tmp;
  849.    int i;
  850. DWORD tmp_uin;
  851.    
  852.    message_cmd[0]='';/* for error checking later */
  853.    quit_cmd[0]='';   /* for error checking later */
  854.    info_cmd[0]='';   /* for error checking later */
  855.    reply_cmd[0]='';  /* for error checking later */
  856.    again_cmd[0]='';  /* for error checking later */
  857.    add_cmd[0]='';    /* for error checking later */
  858.    list_cmd[0]='';   /* for error checking later */
  859.    away_cmd[0]='';   /* for error checking later */
  860.    na_cmd[0]='';     /* for error checking later */
  861.    dnd_cmd[0]='';    /* for error checking later */
  862.    online_cmd[0]=''; /* for error checking later */
  863.    occ_cmd[0]='';    /* for error checking later */
  864.    ffc_cmd[0]='';    /* for error checking later */
  865.    inv_cmd[0]='';    /* for error checking later */
  866.    status_cmd[0]=''; /* for error checking later */
  867.    auth_cmd[0]='';   /* for error checking later */
  868.    auto_cmd[0]='';   /* for error checking later */
  869.    change_cmd[0]=''; /* for error checking later */
  870.    search_cmd[0]=''; /* for error checking later */
  871.    save_cmd[0]='';   /* for error checking later */
  872.    alter_cmd[0]='';  /* for error checking later */
  873.    msga_cmd[0]='';   /* for error checking later */
  874.    url_cmd[0]='';   /* for error checking later */
  875.    update_cmd[0]='';   /* for error checking later */
  876.    Sound_Str[0]='';   /* for error checking later */
  877.    passwd[0] = 0;
  878.    UIN = 0;
  879.    Contact_List = FALSE;
  880.    for ( i=1; !Contact_List || buf == 0; i++ )
  881.    {
  882. /*      M_print( "Starting Line " SERVCOL " %d" NOCOL "n", i );*/
  883.       M_fdnreadln( rcf, buf, sizeof( buf ) );
  884.       if ( ( buf[0] != '#' ) && ( buf[0] != 0 ) )
  885.       {
  886.          tmp = strtok( buf, " " );
  887.          if ( ! strcasecmp( tmp, "Server" ) )
  888.             { strcpy( server, strtok( NULL, " nt" ) ); }
  889.          else if ( ! strcasecmp( tmp, "Password" ) )
  890.             { strcpy( passwd, strtok( NULL, "nt" ) ); }
  891.          else if ( ! strcasecmp( tmp, "Russian" ) )
  892.             {  Russian = TRUE; }
  893.          else if ( ! strcasecmp( tmp, "No_Log" ) )
  894.             { Logging = FALSE;   }
  895.          else if ( ! strcasecmp( tmp, "UIN" ) )
  896.             {  UIN = atoi( strtok( NULL, " nt" ) );         }
  897.          else if ( ! strcasecmp( tmp, "port" ) )
  898.             {  remote_port = atoi( strtok( NULL, " nt" ) ); }
  899.          else if ( ! strcasecmp( tmp, "Status" ) )
  900.             {  set_status = atoi( strtok( NULL, " nt" ) ); }
  901.          else if ( ! strcasecmp( tmp, "Auto" ) )
  902.             { auto_resp = TRUE; }
  903.          ADD_COMMAND( "message_cmd", message_cmd )
  904.          ADD_COMMAND( "info_cmd", info_cmd )
  905.          ADD_COMMAND( "quit_cmd", quit_cmd )
  906.          ADD_COMMAND( "reply_cmd", reply_cmd )
  907.          ADD_COMMAND( "again_cmd", again_cmd )
  908.          ADD_COMMAND( "list_cmd", list_cmd )
  909.          ADD_COMMAND( "away_cmd", away_cmd )
  910.          ADD_MESS( "auto_rep_str_away", auto_rep_str_away )
  911.          ADD_MESS( "auto_rep_str_na", auto_rep_str_na )
  912.          ADD_COMMAND( "na_cmd", na_cmd )
  913.          ADD_COMMAND( "dnd_cmd", dnd_cmd )
  914.          ADD_MESS( "auto_rep_str_dnd", auto_rep_str_dnd )
  915.          ADD_MESS( "auto_rep_str_occ", auto_rep_str_occ )
  916.          ADD_MESS( "auto_rep_str_inv", auto_rep_str_inv )
  917.    else if ( ! strcasecmp( tmp, "Sound" ) ) {  
  918.      strcpy( Sound_Str, strtok( NULL, "nt" ) ); 
  919.      Sound = SOUND_CMD;
  920.    }
  921.          ADD_COMMAND( "online_cmd", online_cmd )
  922.          ADD_COMMAND( "occ_cmd", occ_cmd )
  923.          ADD_COMMAND( "ffc_cmd", ffc_cmd )
  924.          ADD_COMMAND( "inv_cmd", inv_cmd )
  925.          ADD_COMMAND( "status_cmd", status_cmd )
  926.          ADD_COMMAND( "auth_cmd", auth_cmd )
  927.          ADD_COMMAND( "auto_cmd", auto_cmd )
  928.          ADD_COMMAND( "change_cmd", change_cmd )
  929.          ADD_COMMAND( "add_cmd", add_cmd )
  930.          ADD_COMMAND( "search_cmd", search_cmd )
  931.          ADD_COMMAND( "save_cmd", save_cmd )
  932.          ADD_COMMAND( "alter_cmd", alter_cmd )
  933.          ADD_COMMAND( "msga_cmd", msga_cmd )
  934.          ADD_COMMAND( "update_cmd", update_cmd )
  935.          ADD_COMMAND( "url_cmd", url_cmd )
  936.          else if ( ! strcasecmp( tmp, "Contacts" ) )
  937.          {
  938.             Contact_List = TRUE;
  939.          }
  940.          else
  941.          {
  942.             M_print( SERVCOL "Unrecognized command in rc file : %s, ignored." NOCOL "n", tmp );
  943.          }
  944.     }
  945. }
  946.    for ( ; ! M_fdnreadln( rcf, buf, sizeof( buf ) ); )
  947.    {
  948.       if ( Num_Contacts == 100 )
  949.          break;
  950.       if ( ( buf[0] != '#' ) && ( buf[0] != 0 ) )
  951.       {
  952.          if ( isdigit( (int) buf[0] ) )
  953.          {
  954.             Contacts[ Num_Contacts ].uin = atoi( strtok( buf, " " ) );
  955.             Contacts[ Num_Contacts ].status = STATUS_OFFLINE;
  956.             Contacts[ Num_Contacts ].last_time = -1L;
  957.             Contacts[ Num_Contacts ].current_ip[0] = 0xff;
  958.             Contacts[ Num_Contacts ].current_ip[1] = 0xff;
  959.             Contacts[ Num_Contacts ].current_ip[2] = 0xff;
  960.             Contacts[ Num_Contacts ].current_ip[3] = 0xff;
  961.             tmp = strtok( NULL, "" );
  962.             if ( tmp != NULL )
  963.                memcpy( Contacts[ Num_Contacts ].nick, tmp, sizeof( Contacts->nick )  );
  964.             else
  965.                Contacts[ Num_Contacts ].nick[0] = 0;
  966.             if ( Contacts[ Num_Contacts ].nick[19] != 0 )
  967.                Contacts[ Num_Contacts ].nick[19] = 0;
  968.             if ( Verbose )
  969.                M_print( "%ld = %sn", Contacts[ Num_Contacts ].uin, Contacts[ Num_Contacts ].nick );
  970.             Contacts[ Num_Contacts ].vis_list = FALSE;
  971.             Num_Contacts++;
  972.          }
  973.          else if ( buf[0] == '*' )
  974.          {
  975.             Contacts[ Num_Contacts ].uin = atoi( strtok( &buf[1], " " ) );
  976.             Contacts[ Num_Contacts ].status = STATUS_OFFLINE;
  977.             Contacts[ Num_Contacts ].last_time = -1L;
  978.             Contacts[ Num_Contacts ].current_ip[0] = 0xff;
  979.             Contacts[ Num_Contacts ].current_ip[1] = 0xff;
  980.             Contacts[ Num_Contacts ].current_ip[2] = 0xff;
  981.             Contacts[ Num_Contacts ].current_ip[3] = 0xff;
  982.             tmp = strtok( NULL, "" );
  983.             if ( tmp != NULL )
  984.                memcpy( Contacts[ Num_Contacts ].nick, tmp, sizeof( Contacts->nick )  );
  985.             else
  986.                Contacts[ Num_Contacts ].nick[0] = 0;
  987.             if ( Contacts[ Num_Contacts ].nick[19] != 0 )
  988.                Contacts[ Num_Contacts ].nick[19] = 0;
  989.             if ( Verbose )
  990.                M_print( "%ld = %sn", Contacts[ Num_Contacts ].uin, Contacts[ Num_Contacts ].nick );
  991.             Contacts[ Num_Contacts ].invis_list = FALSE;
  992.             Contacts[ Num_Contacts ].vis_list = TRUE;
  993.             Num_Contacts++;
  994.          }
  995.          else if ( buf[0] == '~' )
  996.          {
  997.             Contacts[ Num_Contacts ].uin = atoi( strtok( &buf[1], " " ) );
  998.             Contacts[ Num_Contacts ].status = STATUS_OFFLINE;
  999.             Contacts[ Num_Contacts ].last_time = -1L;
  1000.             Contacts[ Num_Contacts ].current_ip[0] = 0xff;
  1001.             Contacts[ Num_Contacts ].current_ip[1] = 0xff;
  1002.             Contacts[ Num_Contacts ].current_ip[2] = 0xff;
  1003.             Contacts[ Num_Contacts ].current_ip[3] = 0xff;
  1004.             tmp = strtok( NULL, "" );
  1005.             if ( tmp != NULL )
  1006.                memcpy( Contacts[ Num_Contacts ].nick, tmp, sizeof( Contacts->nick )  );
  1007.             else
  1008.                Contacts[ Num_Contacts ].nick[0] = 0;
  1009.             if ( Contacts[ Num_Contacts ].nick[19] != 0 )
  1010.                Contacts[ Num_Contacts ].nick[19] = 0;
  1011.             if ( Verbose )
  1012.                M_print( "%ld = %sn", Contacts[ Num_Contacts ].uin, Contacts[ Num_Contacts ].nick );
  1013.             Contacts[ Num_Contacts ].invis_list = TRUE;
  1014.             Contacts[ Num_Contacts ].vis_list = FALSE;
  1015.             Num_Contacts++;
  1016.          }
  1017.          else
  1018.          {
  1019.             tmp_uin = Contacts[ Num_Contacts - 1 ].uin;
  1020.             tmp = strtok( buf, ", t" ); /* aliases may not have spaces */
  1021.             for ( ; tmp!=NULL; Num_Contacts++ )
  1022.             {
  1023.                Contacts[ Num_Contacts ].uin = -tmp_uin;
  1024.                Contacts[ Num_Contacts ].status = STATUS_OFFLINE;
  1025.                Contacts[ Num_Contacts ].last_time = -1L;
  1026.                Contacts[ Num_Contacts ].current_ip[0] = 0xff;
  1027.                Contacts[ Num_Contacts ].current_ip[1] = 0xff;
  1028.                Contacts[ Num_Contacts ].current_ip[2] = 0xff;
  1029.                Contacts[ Num_Contacts ].current_ip[3] = 0xff;
  1030.                Contacts[ Num_Contacts ].port = 0;
  1031.                Contacts[ Num_Contacts ].sok = (SOK_T ) -1L;
  1032.                Contacts[ Num_Contacts ].invis_list = FALSE;
  1033.                Contacts[ Num_Contacts ].vis_list = FALSE;
  1034.                memcpy( Contacts[ Num_Contacts ].nick, tmp, sizeof( Contacts->nick )  );
  1035.                tmp = strtok( NULL, ", t" );
  1036.             }
  1037.          }
  1038.       }
  1039.    }
  1040.    if(message_cmd[0]=='')
  1041.    strcpy(message_cmd, "msg");
  1042.    if(update_cmd[0]=='')
  1043.    strcpy(update_cmd, "update");
  1044.    if(info_cmd[0]=='')
  1045.    strcpy(info_cmd, "info");
  1046.    if(quit_cmd[0]=='')
  1047.    strcpy(quit_cmd, "q");
  1048.    if(reply_cmd[0]=='')
  1049.    strcpy(reply_cmd, "r");       
  1050.    if(again_cmd[0]=='')
  1051.    strcpy(again_cmd, "a");
  1052.    if(list_cmd[0]=='')
  1053.    strcpy(list_cmd, "w");
  1054.    if(away_cmd[0]=='')
  1055.    strcpy(away_cmd, "away");
  1056.    if(na_cmd[0]=='')
  1057.    strcpy(na_cmd, "na");
  1058.    if(dnd_cmd[0]=='')
  1059.    strcpy(dnd_cmd, "dnd");   
  1060.    if(online_cmd[0]=='')
  1061.    strcpy(online_cmd, "online");
  1062.    if(occ_cmd[0]=='')
  1063.    strcpy(occ_cmd, "occ");
  1064.    if(ffc_cmd[0]=='')
  1065.    strcpy(ffc_cmd, "ffc");
  1066.    if(inv_cmd[0]=='')
  1067.    strcpy(inv_cmd, "inv");
  1068.    if(status_cmd[0]=='')
  1069.    strcpy(status_cmd, "status");
  1070.    if(add_cmd[0]=='')
  1071.    strcpy(add_cmd, "add");
  1072.    if(auth_cmd[0]=='')
  1073.    strcpy(auth_cmd, "auth");
  1074.    if(auto_cmd[0]=='')
  1075.    strcpy(auto_cmd, "auto");
  1076.    if(search_cmd[0]=='')
  1077.    strcpy(search_cmd, "search");
  1078.    if(save_cmd[0]=='')
  1079.    strcpy(save_cmd, "save");
  1080.    if(alter_cmd[0]=='')
  1081.    strcpy(alter_cmd, "alter");
  1082.    if(msga_cmd[0]=='')
  1083.    strcpy(msga_cmd, "msga");
  1084.    if(url_cmd[0]=='')
  1085.    strcpy(url_cmd, "url");
  1086.    if(change_cmd[0]=='')
  1087.    strcpy(change_cmd, "change");
  1088.    if ( Verbose )
  1089.    {
  1090.       M_print( "UIN = %ldn", UIN );
  1091.       M_print( "port = %ldn", remote_port );
  1092.       M_print( "passwd = %sn", passwd );
  1093.       M_print( "server = %sn", server );
  1094.       M_print( "status = %ldn", set_status );
  1095.       M_print( "# of contacts = %dn", Num_Contacts );
  1096.       M_print( "UIN of contact[0] = %ldn", Contacts[0].uin );
  1097.       M_print( "Message_cmd = %sn", message_cmd );
  1098.    }
  1099.    if (UIN == 0 ) 
  1100.    {
  1101.       fprintf( stderr, "Bad .micqrc file.  No UIN found aborting.an" );
  1102.       exit( 1);
  1103.    }
  1104. }
  1105. /*******************************************************
  1106. Gets config info from the rc file in the users home 
  1107. directory.
  1108. ********************************************************/
  1109. void Get_Unix_Config_Info( void )
  1110. {
  1111.    char *path;
  1112.    FD_T rcf;
  1113. #ifdef _WIN32
  1114.    path = ".\";
  1115. #endif
  1116. #ifdef UNIX
  1117.    path = getenv( "HOME" );
  1118.    strcat( path, "/" );
  1119. #endif
  1120. #ifdef __amigaos__
  1121.    path = "PROGDIR:";
  1122. #endif
  1123.    strcpy( rcfile, path );
  1124.    strcat( rcfile, ".micqrc" );
  1125.    rcf = open( rcfile, O_RDONLY );
  1126.    if ( rcf == -1 )
  1127.    {
  1128.       if ( errno == ENOENT ) /* file not found */
  1129.       {
  1130.          Initalize_RC_File();
  1131.       }
  1132.       else
  1133.       {
  1134.          perror( "Error reading config file exiting " );
  1135.          exit( 1 );
  1136.       }
  1137.    }
  1138.    else
  1139.    {
  1140.       Read_RC_File( rcf );
  1141.    }
  1142. }
  1143. void Print_IP( DWORD uin )
  1144. {
  1145.    int i;
  1146. #if 0
  1147.    struct in_addr sin;
  1148. #endif
  1149.    
  1150.    for ( i=0; i< Num_Contacts; i++ )
  1151.    {
  1152.       if ( Contacts[i].uin == uin )
  1153.       {
  1154.          if ( * (DWORD *)Contacts[i].current_ip != -1L )
  1155.          {
  1156.            M_print( "%d.%d.%d.%d", Contacts[i].current_ip[0],
  1157.                                    Contacts[i].current_ip[1],
  1158.                                    Contacts[i].current_ip[2],
  1159.                                    Contacts[i].current_ip[3] );
  1160. #if 0
  1161.             sin.s_addr = Contacts[i].current_ip;
  1162.             M_print( "%s", inet_ntoa( sin ) );
  1163. #endif
  1164.          }
  1165.          else
  1166.          {
  1167.             M_print( "unknown" );
  1168.          }
  1169.          return;
  1170.       }
  1171.    }
  1172.    M_print( "unknown" );
  1173. }
  1174. /************************************************
  1175. Gets the TCP port of the specified UIN
  1176. ************************************************/
  1177. DWORD Get_Port( DWORD uin )
  1178. {
  1179.    int i;
  1180.    
  1181.    for ( i=0; i< Num_Contacts; i++ )
  1182.    {
  1183.       if ( Contacts[i].uin == uin )
  1184.       {
  1185.          return Contacts[i].port;
  1186.       }
  1187.    }
  1188.    return -1L;
  1189. }
  1190. /********************************************
  1191. Converts an intel endian character sequence to
  1192. a DWORD
  1193. *********************************************/
  1194. DWORD Chars_2_DW( unsigned char *buf )
  1195. {
  1196.    DWORD i;
  1197.    
  1198.    i= buf[3];
  1199.    i <<= 8;
  1200.    i+= buf[2];
  1201.    i <<= 8;
  1202.    i+= buf[1];
  1203.    i <<= 8;
  1204.    i+= buf[0];
  1205.    
  1206.    return i;
  1207. }
  1208. /********************************************
  1209. Converts an intel endian character sequence to
  1210. a WORD
  1211. *********************************************/
  1212. WORD Chars_2_Word( unsigned char *buf )
  1213. {
  1214.    WORD i;
  1215.    
  1216.    i= buf[1];
  1217.    i <<= 8;
  1218.    i += buf[0];
  1219.    
  1220.    return i;
  1221. }
  1222. /********************************************
  1223. Converts a DWORD to
  1224. an intel endian character sequence 
  1225. *********************************************/
  1226. void DW_2_Chars( unsigned char *buf, DWORD num )
  1227. {
  1228.    buf[3] = ( unsigned char ) ((num)>>24)& 0x000000FF;
  1229.    buf[2] = ( unsigned char ) ((num)>>16)& 0x000000FF;
  1230.    buf[1] = ( unsigned char ) ((num)>>8)& 0x000000FF;
  1231.    buf[0] = ( unsigned char ) (num) & 0x000000FF;
  1232. }
  1233. /********************************************
  1234. Converts a WORD to
  1235. an intel endian character sequence 
  1236. *********************************************/
  1237. void Word_2_Chars( unsigned char *buf, WORD num )
  1238. {
  1239.    buf[1] = ( unsigned char ) (((unsigned)num)>>8) & 0x00FF;
  1240.    buf[0] = ( unsigned char ) ((unsigned)num) & 0x00FF;
  1241. }
  1242. void Prompt( void )
  1243. {
  1244.    M_print( SERVCOL "Micq> " NOCOL );
  1245.    fflush( stdout );
  1246. }
  1247. void Time_Stamp( void )
  1248. {
  1249.    struct tm *thetime;
  1250.    time_t p;
  1251.    
  1252.    p=time(NULL);
  1253.    thetime=localtime(&p);
  1254.    M_print( "%.02d:%.02d:%.02d",thetime->tm_hour,thetime->tm_min,thetime->tm_sec );
  1255. }
  1256. void Add_User( SOK_T sok, DWORD uin, char *name )
  1257. {
  1258.    FD_T rcf;
  1259.    rcf = open( rcfile, O_RDWR | O_APPEND );
  1260.    M_fdprint( rcf, "%d %sn", uin, name );
  1261.    close( rcf );
  1262.    Contacts[ Num_Contacts ].uin = uin;
  1263.    Contacts[ Num_Contacts ].status = STATUS_OFFLINE;
  1264.    Contacts[ Num_Contacts ].last_time = -1L;
  1265.    Contacts[ Num_Contacts ].current_ip[0] = 0xff;
  1266.    Contacts[ Num_Contacts ].current_ip[1] = 0xff;
  1267.    Contacts[ Num_Contacts ].current_ip[2] = 0xff;
  1268.    Contacts[ Num_Contacts ].current_ip[3] = 0xff;
  1269.    Contacts[ Num_Contacts ].port = 0;
  1270.    Contacts[ Num_Contacts ].sok = (SOK_T ) -1L;
  1271.    Contacts[ Num_Contacts ].vis_list = FALSE;
  1272.    Contacts[ Num_Contacts ].invis_list = FALSE;
  1273.    memcpy( Contacts[ Num_Contacts ].nick, name, sizeof( Contacts->nick )  );
  1274.    Num_Contacts++;
  1275.    snd_contact_list( sok );
  1276. }
  1277. /************************************************
  1278.  *   This function should save your auto reply messages in the rc file.
  1279.  *   NOTE: the code isn't realy neat yet, I hope to change that soon.
  1280.  *   Added on 6-20-98 by Fryslan
  1281.  ***********************************************/
  1282. int Save_RC()
  1283. {
  1284.    FD_T rcf;
  1285.    time_t t;
  1286.    int i, j;
  1287.  
  1288.    rcf = open( rcfile, O_RDWR );
  1289.    if ( rcf == -1 ) return -1;
  1290.    M_fdprint( rcf, "# This file was generated by Micq of %s %sn",__TIME__,__DATE__);
  1291.    t = time( NULL );
  1292.    M_fdprint( rcf, "# This file was generated on %s", ctime( &t ) );   
  1293.    M_fdprint( rcf, "UIN %dn", UIN );
  1294.    M_fdprint( rcf, "Password %sn", passwd );
  1295.    M_fdprint( rcf, "Status %dn", Current_Status );
  1296.    M_fdprint( rcf, "Server %sn", "icq1.mirabilis.com" );
  1297.    M_fdprint( rcf, "Port %dn", 4000 );
  1298.    if ( Logging )
  1299.       M_fdprint( rcf, "#No_Logn" );
  1300.    else
  1301.       M_fdprint( rcf, "No_Logn" );
  1302.    if ( Russian )
  1303.       M_fdprint( rcf, "nRussiann#if you want KOI8-R to CP1251 Russain translation uncomment the above line.n" );
  1304.    else
  1305.       M_fdprint( rcf, "n#Russiann#if you want KOI8-R to CP1251 Russain translation uncomment the above line.n" );
  1306.    if ( auto_resp )
  1307.       M_fdprint( rcf, "n#Automatic responses on.nAuton" );
  1308.    else
  1309.       M_fdprint( rcf, "n#Automatic responses off.n#Auton" );
  1310.    M_fdprint( rcf, "n# Below are the commands which can be changed to most anything you want :)n" );
  1311.    M_fdprint( rcf, "message_cmd %sn",message_cmd);
  1312.    M_fdprint( rcf, "info_cmd %sn",info_cmd);
  1313.    M_fdprint( rcf, "quit_cmd %sn",quit_cmd);
  1314.    M_fdprint( rcf, "reply_cmd %sn",reply_cmd);
  1315.    M_fdprint( rcf, "again_cmd %sn",again_cmd);
  1316.    M_fdprint( rcf, "list_cmd %sn",list_cmd);
  1317.    M_fdprint( rcf, "away_cmd %sn",away_cmd);
  1318.    M_fdprint( rcf, "na_cmd %sn",na_cmd);
  1319.    M_fdprint( rcf, "dnd_cmd %sn",dnd_cmd);
  1320.    M_fdprint( rcf, "online_cmd %sn",online_cmd);
  1321.    
  1322.    M_fdprint( rcf, "occ_cmd %sn",occ_cmd);
  1323.    M_fdprint( rcf, "ffc_cmd %sn",ffc_cmd);
  1324.    M_fdprint( rcf, "inv_cmd %sn",inv_cmd);
  1325.    M_fdprint( rcf, "search_cmd %sn",search_cmd);
  1326.    M_fdprint( rcf, "status_cmd %sn",status_cmd);
  1327.    M_fdprint( rcf, "auth_cmd %sn",auth_cmd);
  1328.    M_fdprint( rcf, "auto_cmd %sn",auto_cmd);
  1329.    M_fdprint( rcf, "add_cmd %sn",add_cmd);
  1330.    M_fdprint( rcf, "change_cmd %sn",change_cmd);
  1331.    M_fdprint( rcf, "save_cmd %sn",save_cmd);
  1332.    M_fdprint( rcf, "alter_cmd %sn",alter_cmd);
  1333.    M_fdprint( rcf, "msga_cmd %sn",msga_cmd);
  1334.    M_fdprint( rcf, "url_cmd %sn",url_cmd);
  1335.    M_fdprint( rcf, "update_cmd %sn",update_cmd);
  1336.    M_fdprint( rcf, "n#Now auto response messagesn" );  
  1337.    M_fdprint( rcf, "auto_rep_str_away %sn",auto_rep_str_away);
  1338.    M_fdprint( rcf, "auto_rep_str_na %sn",auto_rep_str_na);
  1339.    M_fdprint( rcf, "auto_rep_str_dnd %sn",auto_rep_str_dnd);
  1340.    M_fdprint( rcf, "auto_rep_str_occ %sn",auto_rep_str_occ);
  1341.    M_fdprint( rcf, "auto_rep_str_inv %sn",auto_rep_str_inv);
  1342.    M_fdprint( rcf, "n# Ok now the contact listn" );
  1343.    M_fdprint( rcf, "#  Use * in front of the nickname of anyone you want to see you while you're invisble.n" );
  1344.    M_fdprint( rcf, "#  Use ~ in front of the nickname of anyone you want to always see you as offline.n" );
  1345.    M_fdprint( rcf, "#  People in the second group won't show up in your list.n" );
  1346.    M_fdprint( rcf, "Contactsn" );
  1347. /* adding contacts to the rc file. */
  1348. /* we start counting at zero in the index. */
  1349.    for (i=0;i<Num_Contacts;i++)
  1350.    {
  1351.       if ( ! ( Contacts[i].uin & 0x80000000L ) )
  1352.       {
  1353.          if ( Contacts[i].vis_list )
  1354.          {
  1355.             M_fdprint( rcf, "*" );
  1356.          }
  1357.          if ( Contacts[i].invis_list )
  1358.          {
  1359.             M_fdprint( rcf, "~" );
  1360.          }
  1361.  M_fdprint( rcf, "%d %sn",Contacts[i].uin,Contacts[i].nick);
  1362. /*  M_fdprint( rcf, "#Begining of aliases for %sn", Contacts[i].nick ); */
  1363.  for ( j=0; j< Num_Contacts; j++ )
  1364.  {
  1365.     if ( Contacts[j].uin == -Contacts[i].uin )
  1366.     {
  1367.        M_fdprint( rcf, "%s ", Contacts[j].nick );
  1368.     }
  1369.  }
  1370.  M_fdprint( rcf, "n" );
  1371. /*  M_fdprint( rcf, "n#End of aliases for %sn", Contacts[i].nick ); */
  1372.       }
  1373.    }
  1374. M_fdprint( rcf, "n" );
  1375.    return close( rcf );
  1376. }
  1377. /*************************************************************************
  1378.  *      Function: log_event
  1379.  *      Purpose: Log the event provided to the log with a time stamp.
  1380.  *      Andrew Frolov dron@ilm.net
  1381.  *      6-20-98 Added names to the logs. Fryslan
  1382.  *************************************************************************/
  1383. int log_event( char *desc, char *msg, DWORD uin )
  1384. {
  1385.    FILE    *msgfd;
  1386.    char    buffer[256];
  1387.    time_t  timeval;
  1388.    char *path;
  1389.    char *home;
  1390.    if ( ! Logging )
  1391.       return 0;
  1392.       
  1393. #ifdef _WIN32
  1394.    path = ".\";
  1395. #endif
  1396. #ifdef UNIX
  1397.    home = getenv( "HOME" );
  1398.    path = malloc( strlen( home ) + 2 );
  1399.    strcpy( path, home );
  1400.    if ( path[ strlen( path ) - 1 ] != '/' )
  1401.       strcat( path, "/" );
  1402. #endif
  1403. #ifdef __amigaos__
  1404.    path = "PROGDIR:";
  1405. #endif
  1406.    strcpy( buffer, path );
  1407.    strcat( buffer, "micq_log" );
  1408.    if( ( msgfd = fopen(buffer, "a") ) == (FILE *) NULL ) 
  1409.    {
  1410.            fprintf(stderr, "Couldn't open %s for loggingn",
  1411.                             buffer);
  1412.            return(-1);
  1413.    }
  1414.    timeval = time(0);
  1415. if ( ! strcasecmp(UIN2nick(uin),"Unknow UIN"))
  1416.    fprintf(msgfd, "n%-24.24s %s %ldn%sn", ctime(&timeval), desc, uin, msg);
  1417. else
  1418.    fprintf(msgfd, "n%-24.24s %s %sn%sn", ctime(&timeval), desc, UIN2nick(uin), msg);
  1419.  
  1420.    fclose(msgfd);
  1421. #ifdef UNIX
  1422.    chmod( buffer, 0600 );
  1423.    free( path );
  1424. #endif
  1425.    return(0);
  1426. }
  1427. /*************************************************
  1428.  clears the screen 
  1429. **************************************************/
  1430. void clrscr(void)
  1431. {
  1432. #ifdef UNIX
  1433. system( "clear" );
  1434. #else
  1435. #ifdef _WIN32
  1436. system( "cls" );
  1437. #else
  1438. int x;
  1439. char newline = 'n';
  1440.   for(x = 0; x<=25; x++)
  1441. M_print("%c",newline);
  1442. #endif
  1443. #endif
  1444. }
  1445. /************************************************************
  1446. Displays a hex dump of buf on the screen.
  1447. *************************************************************/
  1448. void Hex_Dump( void *buffer, size_t len )
  1449. {
  1450.       int i;
  1451.       int j;
  1452.       char *buf;
  1453.       
  1454.       buf = buffer;
  1455.       assert( len > 0 );
  1456.       assert( len < 1000 );
  1457.       if ( len < 0 )
  1458.        return;
  1459.       for ( i=0 ; i < len; i++ )
  1460.       {
  1461.          M_print( "%02x ", ( unsigned char ) buf[i] );
  1462.          if ( ( i & 15 ) == 15 )
  1463.          {
  1464.             M_print( "  " );
  1465.             for ( j = 15; j >= 0; j-- )
  1466.             {
  1467.                if ( buf[i-j] > 31 )
  1468.                   M_print( "%c", buf[i-j] );
  1469.                else
  1470.                   M_print( "." );
  1471.                if ( ( (i-j) & 3 ) == 3 )
  1472.                   M_print( " " );
  1473.             }
  1474.             M_print( "n" );
  1475.          }
  1476.          else if ( ( i & 7 ) == 7 )
  1477.             M_print( "- " );
  1478.          else if ( ( i & 3 ) == 3 )
  1479.             M_print( "  " );
  1480.       }
  1481.       M_print( "  " );
  1482.       for ( j = i % 16; j > 0; j-- )
  1483.       {
  1484.          if ( buf[i-j] > 31 )
  1485.             M_print( "%c", buf[i-j] );
  1486.          else
  1487.             M_print( "." );
  1488.          if ( ( (i-j) & 3 ) == 3 )
  1489.             M_print( " " );
  1490.       }
  1491.       M_print( "n" );
  1492. }