/[weechat]/weechat/src/irc/irc-server.c
ViewVC logotype

Diff of /weechat/src/irc/irc-server.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.46 by flashcode, Sun Feb 20 00:08:23 2005 UTC revision 1.47 by flashcode, Sun Feb 20 13:37:49 2005 UTC
# Line 27  Line 27 
27  #include <stdlib.h>  #include <stdlib.h>
28  #include <unistd.h>  #include <unistd.h>
29  #include <errno.h>  #include <errno.h>
30    #include <signal.h>
31  #include <stdio.h>  #include <stdio.h>
32  #include <stdarg.h>  #include <stdarg.h>
33  #include <string.h>  #include <string.h>
34  #include <pwd.h>  #include <pwd.h>
 #include <sys/types.h>  
35  #include <sys/socket.h>  #include <sys/socket.h>
36    #include <sys/types.h>
37    #include <sys/wait.h>
38  #include <netinet/in.h>  #include <netinet/in.h>
39  #include <arpa/inet.h>  #include <arpa/inet.h>
40  #include <netdb.h>  #include <netdb.h>
# Line 57  int check_away = 0; Line 59  int check_away = 0;
59  void  void
60  server_init (t_irc_server *server)  server_init (t_irc_server *server)
61  {  {
62        /* user choices */
63      server->name = NULL;      server->name = NULL;
64      server->autoconnect = 0;      server->autoconnect = 0;
65      server->autoreconnect = 1;      server->autoreconnect = 1;
# Line 73  server_init (t_irc_server *server) Line 76  server_init (t_irc_server *server)
76      server->command = NULL;      server->command = NULL;
77      server->command_delay = 1;      server->command_delay = 1;
78      server->autojoin = NULL;      server->autojoin = NULL;
79        server->autorejoin = 0;
80        
81        /* internal vars */
82        server->child_pid = 0;
83        server->child_read = -1;
84        server->child_write = -1;
85        server->sock4 = -1;
86        server->is_connected = 0;
87      server->unterminated_message = NULL;      server->unterminated_message = NULL;
88      server->nick = NULL;      server->nick = NULL;
     server->is_connected = 0;  
89      server->reconnect_start = 0;      server->reconnect_start = 0;
90      server->reconnect_join = 0;      server->reconnect_join = 0;
     server->sock4 = -1;  
     server->server_read = -1;  
     server->server_write = -1;  
91      server->is_away = 0;      server->is_away = 0;
92      server->away_time = 0;      server->away_time = 0;
93      server->lag = 0;      server->lag = 0;
# Line 643  server_recv (t_irc_server *server) Line 650  server_recv (t_irc_server *server)
650  }  }
651    
652  /*  /*
653   * server_connect: connect to an IRC server   * server_kill_child: kill child process and close pipe
654     */
655    
656    void
657    server_kill_child (t_irc_server *server)
658    {
659        /* kill process */
660        if (server->child_pid > 0)
661        {
662            kill (server->child_pid, SIGKILL);
663            waitpid (server->child_pid, NULL, 0);
664            server->child_pid = 0;
665        }
666        
667        /* close pipe used with child */
668        if (server->child_read != -1)
669        {
670            close (server->child_read);
671            server->child_read = -1;
672        }
673        if (server->child_write != -1)
674        {
675            close (server->child_write);
676            server->child_write = -1;
677        }
678    }
679    
680    /*
681     * server_close_connection: close server connection (kill child, close socket/pipes)
682     */
683    
684    void
685    server_close_connection (t_irc_server *server)
686    {
687        server_kill_child (server);
688        
689        /* close network socket */
690        if (server->sock4 != -1)
691        {
692            close (server->sock4);
693            server->sock4 = -1;
694        }
695        
696        /* free any pending message */
697        if (server->unterminated_message)
698        {
699            free (server->unterminated_message);
700            server->unterminated_message = NULL;
701        }
702        
703        /* server is now disconnected */
704        server->is_connected = 0;
705    }
706    
707    /*
708     * server_reconnect_schedule: schedule reconnect for a server
709     */
710    
711    void
712    server_reconnect_schedule (t_irc_server *server)
713    {
714        if (server->autoreconnect)
715        {
716            server->reconnect_start = time (NULL);
717            irc_display_prefix (server->buffer, PREFIX_INFO);
718            gui_printf (server->buffer, _("%s: Reconnecting to server in %d seconds\n"),
719                        PACKAGE_NAME, server->autoreconnect_delay);
720        }
721        else
722            server->reconnect_start = 0;
723    }
724    
725    /*
726     * server_child_read: read connection progress from child process
727     */
728    
729    void
730    server_child_read (t_irc_server *server)
731    {
732        char buffer[1];
733        int num_read;
734        
735        num_read = read (server->child_read, buffer, sizeof (buffer));
736        if (num_read != -1)
737        {
738            switch (buffer[0])
739            {
740                /* connection OK */
741                case '0':
742                    server_kill_child (server);
743                    irc_login (server);
744                    break;
745                /* adress not found */
746                case '1':
747                    irc_display_prefix (server->buffer, PREFIX_ERROR);
748                    gui_printf (server->buffer,
749                                _("%s address \"%s\" not found\n"),
750                                WEECHAT_ERROR, server->address);
751                    server_close_connection (server);
752                    server_reconnect_schedule (server);
753                    break;
754                /* IP address not found */
755                case '2':
756                    irc_display_prefix (server->buffer, PREFIX_ERROR);
757                    gui_printf (server->buffer,
758                                _("%s IP address not found\n"), WEECHAT_ERROR);
759                    server_close_connection (server);
760                    server_reconnect_schedule (server);
761                    break;
762                /* connection refused */
763                case '3':
764                    irc_display_prefix (server->buffer, PREFIX_ERROR);
765                    gui_printf (server->buffer,
766                                _("%s connection refused\n"), WEECHAT_ERROR);
767                    server_close_connection (server);
768                    server_reconnect_schedule (server);
769                    break;
770            }
771        }
772    }
773    
774    /*
775     * server_child: child process trying to connect to server
776   */   */
777    
778  int  int
779  server_connect (t_irc_server *server)  server_child (t_irc_server *server)
780  {  {
     int set;  
781      struct hostent *ip4_hostent;      struct hostent *ip4_hostent;
782      struct sockaddr_in addr;      struct sockaddr_in addr;
783      char *ip_address;      char *ip_address;
784      int error;      int error;
785      int server_pipe[2];      
786        /* bind to hostname */
787        ip4_hostent = gethostbyname (server->address);
788        if (!ip4_hostent)
789        {
790            write (server->child_write, "1", 1);
791            return 0;
792        }
793        memset (&addr, 0, sizeof (addr));
794        memcpy (&addr.sin_addr, ip4_hostent->h_addr, ip4_hostent->h_length);
795        addr.sin_port = htons (server->port);
796        addr.sin_family = AF_INET;
797        
798        /* find IP address */
799        ip_address = inet_ntoa (addr.sin_addr);
800        if (!ip_address)
801        {
802            write (server->child_write, "2", 1);
803            return 0;
804        }
805        
806        /* connect to server */
807        error = connect (server->sock4, (struct sockaddr *) &addr, sizeof (addr));
808        if (error != 0)
809        {
810            write (server->child_write, "3", 1);
811            return 0;
812        }
813        
814        /* connection OK */
815        write (server->child_write, "0", 1);
816        
817        return 0;
818    }
819    
820    /*
821     * server_connect: connect to an IRC server
822     */
823    
824    int
825    server_connect (t_irc_server *server)
826    {
827        int child_pipe[2], set;
828        pid_t pid;
829    
830      irc_display_prefix (server->buffer, PREFIX_INFO);      irc_display_prefix (server->buffer, PREFIX_INFO);
831      gui_printf (server->buffer,      gui_printf (server->buffer,
# Line 662  server_connect (t_irc_server *server) Line 833  server_connect (t_irc_server *server)
833                  PACKAGE_NAME, server->address, server->port);                  PACKAGE_NAME, server->address, server->port);
834      wee_log_printf (_("connecting to server %s:%d...\n"),      wee_log_printf (_("connecting to server %s:%d...\n"),
835                      server->address, server->port);                      server->address, server->port);
836      server->is_connected = 0;      
837        /* close any opened connection and kill child process if running */
838      /* create pipe */      server_close_connection (server);
839      if (pipe (server_pipe) < 0)      
840        /* create pipe for child process */
841        if (pipe (child_pipe) < 0)
842      {      {
843          irc_display_prefix (server->buffer, PREFIX_ERROR);          irc_display_prefix (server->buffer, PREFIX_ERROR);
844          gui_printf (server->buffer,          gui_printf (server->buffer,
845                      _("%s cannot create pipe\n"), WEECHAT_ERROR);                      _("%s cannot create pipe\n"), WEECHAT_ERROR);
         server_free (server);  
846          return 0;          return 0;
847      }      }
848      server->server_read = server_pipe[0];      server->child_read = child_pipe[0];
849      server->server_write = server_pipe[1];      server->child_write = child_pipe[1];
850        
851      /* create socket and set options */      /* create socket and set options */
852      server->sock4 = socket (AF_INET, SOCK_STREAM, 0);      server->sock4 = socket (AF_INET, SOCK_STREAM, 0);
853      set = 1;      if (server->sock4 == -1)
     if (setsockopt  
         (server->sock4, SOL_SOCKET, SO_REUSEADDR, (char *) &set,  
          sizeof (set)) == -1)  
854      {      {
855          irc_display_prefix (server->buffer, PREFIX_ERROR);          irc_display_prefix (server->buffer, PREFIX_ERROR);
856          gui_printf (server->buffer,          gui_printf (server->buffer,
857                      _("%s cannot set socket option \"SO_REUSEADDR\"\n"),                      _("%s cannot create socket\n"), WEECHAT_ERROR);
858                      WEECHAT_ERROR);          server_close_connection (server);
859            return 0;
860      }      }
861        
862        /* set SO_REUSEADDR option for socket */
863      set = 1;      set = 1;
864      if (setsockopt      if (setsockopt (server->sock4, SOL_SOCKET, SO_REUSEADDR,
865          (server->sock4, SOL_SOCKET, SO_KEEPALIVE, (char *) &set,          (void *) &set, sizeof (set)) == -1)
          sizeof (set)) == -1)  
866      {      {
867          irc_display_prefix (server->buffer, PREFIX_ERROR);          irc_display_prefix (server->buffer, PREFIX_ERROR);
868          gui_printf (server->buffer,          gui_printf (server->buffer,
869                      _("%s cannot set socket option \"SO_KEEPALIVE\"\n"),                      _("%s cannot set socket option \"SO_REUSEADDR\"\n"),
870                      WEECHAT_ERROR);                      WEECHAT_WARNING);
     }  
   
     /* bind to hostname */  
     ip4_hostent = gethostbyname (server->address);  
     if (!ip4_hostent)  
     {  
         irc_display_prefix (server->buffer, PREFIX_ERROR);  
         gui_printf (server->buffer,  
                     _("%s address \"%s\" not found\n"),  
                     WEECHAT_ERROR, server->address);  
         close (server->server_read);  
         close (server->server_write);  
         close (server->sock4);  
         server->sock4 = -1;  
         return 0;  
871      }      }
872      memset (&addr, 0, sizeof (addr));      
873      memcpy (&addr.sin_addr, ip4_hostent->h_addr, ip4_hostent->h_length);      /* set SO_KEEPALIVE option for socket */
874      addr.sin_port = htons (server->port);      set = 1;
875      addr.sin_family = AF_INET;      if (setsockopt (server->sock4, SOL_SOCKET, SO_KEEPALIVE,
876      /*error = bind(server->sock4, (struct sockaddr *)(&addr), sizeof(addr));          (void *) &set, sizeof (set)) == -1)
     if (error != 0)  
     {  
         irc_display_prefix (server->buffer, PREFIX_ERROR);  
         gui_printf (server->buffer,  
                     _("%s can't bind to hostname\n"), WEECHAT_ERROR);  
         return 0;  
     }*/  
     ip_address = inet_ntoa (addr.sin_addr);  
     if (!ip_address)  
877      {      {
878          irc_display_prefix (server->buffer, PREFIX_ERROR);          irc_display_prefix (server->buffer, PREFIX_ERROR);
879          gui_printf (server->buffer,          gui_printf (server->buffer,
880                      _("%s IP address not found\n"), WEECHAT_ERROR);                      _("%s cannot set socket option \"SO_KEEPALIVE\"\n"),
881          close (server->server_read);                      WEECHAT_WARNING);
         close (server->server_write);  
         close (server->sock4);  
         server->sock4 = -1;  
         return 0;  
882      }      }
883        
884      /* connection to server */      switch (pid = fork ())
     irc_display_prefix (server->buffer, PREFIX_INFO);  
     gui_printf (server->buffer,  
                 _("%s: server IP is: %s\n"), PACKAGE_NAME, ip_address);  
   
     error = connect (server->sock4, (struct sockaddr *) &addr, sizeof (addr));  
     if (error != 0)  
885      {      {
886          irc_display_prefix (server->buffer, PREFIX_ERROR);          /* fork failed */
887          gui_printf (server->buffer,          case -1:
888                      _("%s cannot connect to irc server\n"), WEECHAT_ERROR);              server_close_connection (server);
889          close (server->server_read);              return 0;
890          close (server->server_write);          /* child process */
891          close (server->sock4);          case 0:
892          server->sock4 = -1;              setuid (getuid ());
893          return 0;              server_child (server);
894                _exit (EXIT_SUCCESS);
895      }      }
896            
897        /* parent process go on here */
898        server->child_pid = pid;
899        
900      return 1;      return 1;
901  }  }
902    
# Line 772  server_reconnect (t_irc_server *server) Line 913  server_reconnect (t_irc_server *server)
913      server->reconnect_start = 0;      server->reconnect_start = 0;
914            
915      if (server_connect (server))      if (server_connect (server))
     {  
916          server->reconnect_join = 1;          server->reconnect_join = 1;
         irc_login (server);  
     }  
917      else      else
918      {          server_reconnect_schedule (server);
         server->reconnect_start = time (NULL);  
         irc_display_prefix (server->buffer, PREFIX_INFO);  
         gui_printf (server->buffer, _("%s: Reconnecting to server in %d seconds\n"),  
                     PACKAGE_NAME, server->autoreconnect_delay);  
     }  
919  }  }
920    
921  /*  /*
# Line 801  server_auto_connect (int command_line) Line 934  server_auto_connect (int command_line)
934              || ((!command_line) && (ptr_server->autoconnect)) )              || ((!command_line) && (ptr_server->autoconnect)) )
935          {          {
936              (void) gui_buffer_new (gui_current_window, ptr_server, NULL, 0, 1);              (void) gui_buffer_new (gui_current_window, ptr_server, NULL, 0, 1);
937              if (server_connect (ptr_server))              gui_redraw_buffer (gui_current_window->buffer);
938                  irc_login (ptr_server);              server_connect (ptr_server);
939          }          }
940      }      }
941  }  }
# Line 828  server_disconnect (t_irc_server *server, Line 961  server_disconnect (t_irc_server *server,
961          }          }
962      }      }
963            
964      /* close communication with server */      irc_display_prefix (server->buffer, PREFIX_INFO);
965      if (server->server_read >= 0)      gui_printf (server->buffer, _("Disconnected from server!\n"));
         close (server->server_read);  
     server->server_read = -1;  
       
     if (server->server_write >= 0)  
         close (server->server_write);  
     server->server_write = -1;  
       
     if (server->sock4 >= 0)  
         close (server->sock4);  
     server->sock4 = -1;  
966            
967      if (server->unterminated_message)      server_close_connection (server);
         free (server->unterminated_message);  
     server->unterminated_message = NULL;  
968            
     server->is_connected = 0;  
969      server->is_away = 0;      server->is_away = 0;
970      server->away_time = 0;      server->away_time = 0;
971      server->lag = 0;      server->lag = 0;
# Line 854  server_disconnect (t_irc_server *server, Line 974  server_disconnect (t_irc_server *server,
974      server->lag_next_check = time (NULL) + cfg_irc_lag_check;      server->lag_next_check = time (NULL) + cfg_irc_lag_check;
975            
976      if ((reconnect) && (server->autoreconnect))      if ((reconnect) && (server->autoreconnect))
977      {          server_reconnect_schedule (server);
         server->reconnect_start = time (NULL);  
         irc_display_prefix (server->buffer, PREFIX_INFO);  
         gui_printf (server->buffer, _("%s: Reconnecting to server in %d seconds\n"),  
                     PACKAGE_NAME, server->autoreconnect_delay);  
     }  
978      else      else
979          server->reconnect_start = 0;          server->reconnect_start = 0;
980            

Legend:
Removed from v.1.46  
changed lines
  Added in v.1.47

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26