Exemple #1
0
static void config_free_node(node *n)
{
	node	*m;
	attribute	*a, *b;
	if (n == NULL)
	{
		return;
	}
	n->parent = NULL;
	n->next = NULL;
	while (n != NULL)
	{
		m = n;
		if (n->children != NULL)
		{
			n = n->children;
			m->children = NULL;
		}
		else
		{
			if (n->next != NULL)
			{
				n = n->next;
			}
			else
			{
				n = n->parent;
			}
			if (m->name == NULL)
			{
				free(m->data);
			}
			else
			{
				irc_free(m->name);
			}
			a = m->attrs;
			while (a != NULL)
			{
				irc_free(a->name);
				irc_free(a->value);
				b = a->next;
				irc_free(a);
				a = b;
			}
			irc_free(m);
		}
	}
}
Exemple #2
0
/* immed=1 makes this function pretty much equal to irc_free(), except that
   this one will "log". In case the connection is already broken and we
   shouldn't try to write to it. */
void irc_abort(irc_t *irc, int immed, char *format, ...)
{
	char *reason = NULL;

	if (format != NULL) {
		va_list params;

		va_start(params, format);
		reason = g_strdup_vprintf(format, params);
		va_end(params);
	}

	if (reason) {
		irc_write(irc, "ERROR :Closing link: %s", reason);
	}

	ipc_to_master_str("OPERMSG :Client exiting: %s@%s [%s]\r\n",
	                  irc->user->nick ? irc->user->nick : "(NONE)",
	                  irc->user->host, reason ? : "");

	g_free(reason);

	irc_flush(irc);
	if (immed) {
		irc_free(irc);
	} else {
		b_event_remove(irc->ping_source_id);
		irc->ping_source_id = b_timeout_add(1, (b_event_handler) irc_free, irc);
	}
}
Exemple #3
0
node *config_get_node(node *root, char *name)
{
	node	*n;
	char	*x, *y, *z = NULL;

	if (name == NULL)
	{
		return root;
	}
	x = irc_strdup(name);
	n = root;
	for (y = strtok_r(x, "/", &z); y != NULL && n != NULL; y = strtok_r(NULL, "/", &z))
	{
		n = n->children;
		while (n != NULL)
		{
			if (n->name != NULL && !strcmp(y, n->name))
			{
				break;
			}
			n = n->next;
		}
	} while (y != NULL && n != NULL);
	irc_free(x);
	return n;
}
Exemple #4
0
storage_status_t storage_rename (const char *onick, const char *nnick, const char *password)
{
	storage_status_t status;
	GList *gl = global.storage;
	storage_t *primary_storage = gl->data;
	irc_t *irc;

	/* First, try to rename in the current write backend, assuming onick 
	 * is stored there */
	status = primary_storage->rename(onick, nnick, password);
	if (status != STORAGE_NO_SUCH_USER)
		return status;

	/* Try to load from a migration backend and save to the current backend. 
	 * Explicitly remove the account from the migration backend as otherwise 
	 * it'd still be usable under the old name */
	
	irc = g_new0(irc_t, 1);
	status = storage_load(onick, password, irc);
	if (status != STORAGE_OK) {
		irc_free(irc);
		return status;
	}

	g_free(irc->nick);
	irc->nick = g_strdup(nnick);

	status = storage_save(irc, FALSE);
	if (status != STORAGE_OK) {
		irc_free(irc);
		return status;
	}
	irc_free(irc);

	storage_remove(onick, password);

	return STORAGE_OK;
}
Exemple #5
0
void handle_client(int client_fd, char *ip, short port)
{
	irc_data_t irc_channels;
	char buf[MAX_CLIENT_SEND_BUFF_SZ];
	int retn = 0;
	irc_init(&irc_channels);
	if (0 != get_ip_from_hostname(ip, buf, sizeof(buf))) {
		perror("get ip from host error\n");
		goto err;
	}
	printf("connect to irc server: %s[%s] %d\n", ip, buf, port);
	irc_channels.socket_fd = create_client_socket(buf, port);
	if (0 > irc_channels.socket_fd) {
		goto err;
	}
	if (0 != pthread_create(&irc_channels.thread_recv, NULL
		, thread_recv_msg_from_server, &irc_channels)) {
		perror("create recv thread error!");
		goto err;
	}
	if (0 != pthread_create(&irc_channels.thread_send, NULL
		, thread_send_msg_to_server, &irc_channels)) {
		perror("create send thread error!");
		goto err;
	}

	for(;;) {
		retn = recv(client_fd, buf, sizeof(buf) - 1, 0);
		if (retn > 0) {
			buf[retn - 1] = '\0';
			fprintf(stdout, "[local-client]: recv: %s\n",buf);
			handle_msg_remove_illegal_ch(buf, retn);
			handle_msg_from_client(&irc_channels, buf, retn - 1);
		} else if (0 == retn) {
			fprintf(stdout, "client offline");
			break;
		} else {
			fprintf(stderr, "client error");
			break;
		}
	}

err:
	close(client_fd);
	irc_free(&irc_channels);
}
Exemple #6
0
void _socket_free(sock *sock)
{
	if (sock->laddr != NULL)
	{
		address_free(sock->laddr);
	}
	if (sock->raddr != NULL)
	{
		address_free(sock->raddr);
	}
#ifdef HAVE_SSL
	if (sock->sslstate != SSL_OFF)
	{
		SSL_free(sock->ssl);
	}
#endif
	irc_free(sock);
}
Exemple #7
0
static void ipc_child_cmd_takeover( irc_t *irc, char **cmd )
{
	if( strcmp( cmd[1], "NO" ) == 0 )
	{
		/* Master->New connection */
		/* No takeover, finish the login. */
	}
	else if( strcmp( cmd[1], "INIT" ) == 0 )
	{
		/* Master->New connection */
		if( !set_getbool( &irc->b->set, "allow_takeover" ) )
		{
			ipc_child_cmd_takeover_no( irc );
			return;
		}
		
		/* Offer to take over the old session, unless for some reason
		   we're already logging into IM connections. */
		if( irc->login_source_id != -1 )
			query_add( irc, NULL,
			           "You're already connected to this server. "
			           "Would you like to take over this session?",
			           ipc_child_cmd_takeover_yes,
		        	   ipc_child_cmd_takeover_no, NULL, irc );
		
		/* This one's going to connect to accounts, avoid that. */
		b_event_remove( irc->login_source_id );
		irc->login_source_id = -1;
	}
	else if( strcmp( cmd[1], "AUTH" ) == 0 )
	{
		/* Master->Old connection */
		if( irc->password && cmd[2] && cmd[3] &&
		    ipc_child_recv_fd != -1 &&
		    strcmp( irc->user->nick, cmd[2] ) == 0 &&
		    strcmp( irc->password, cmd[3] ) == 0 &&
		    set_getbool( &irc->b->set, "allow_takeover" ) )
		{
			irc_switch_fd( irc, ipc_child_recv_fd );
			irc_sync( irc );
			irc_rootmsg( irc, "You've successfully taken over your old session" );
			ipc_child_recv_fd = -1;
			
			ipc_to_master_str( "TAKEOVER DONE\r\n" );
		}
		else
		{
			ipc_to_master_str( "TAKEOVER FAIL\r\n" );
		}
	}
	else if( strcmp( cmd[1], "DONE" ) == 0 ) 
	{
		/* Master->New connection (now taken over by old process) */
		irc_free( irc );
	}
	else if( strcmp( cmd[1], "FAIL" ) == 0 ) 
	{
		/* Master->New connection */
		irc_rootmsg( irc, "Could not take over old session" );
	}
}
Exemple #8
0
int main(int argc, char **argv) {
   int ret, opt, conn, plugins_loaded = 0, banner_displayed = 0;
   unsigned long now, lastconn = time(NULL);
   FILE *urandom;

   runlevel = RL_OFFLINE;   

   while ((opt = getopt(argc, argv, "c:dj:u:vh")) != -1) {
      switch(opt) {
         case 'c':
            settings.config = optarg;
            break;
         case 'd':
            settings.daemonize = 1;
            break;
         case 'j':
            settings.chroot = optarg;
            break;
         case 'u':
            settings.chuser = optarg;
            break;
         case 'v':
            print_version();
            break;
         case 'h':
         default:
            print_usage(argv[0]);
            break;
      }
   }

   srand(time(NULL));
   
   urandom = fopen("/dev/urandom", "r");
   srrand(time(NULL) ^ getpid(), urandom);

   if (config_parse(settings.config)) {
      fprintf(stderr, "Unable to load configuration file '%s'.\n",
	settings.config);
      return -1;
   }

   if (checkconfig())
      return -1;

   if (settings.daemonize) {
      ret = fork();
      switch(ret) {
         case -1:
            fprintf(stderr, "Unable to fork to background\n");
            return -1;
        default:
            return 0;
      }
   }

   if (secure_it(settings.chroot, settings.chuser)) {
      fprintf(stderr, "Failed to chroot/setuid\n");
      return -1;
   }

#ifdef TLS
  if (gnutls_global_init() == GNUTLS_E_SUCCESS)
    atexit(gnutls_global_deinit);
  else
    fprintf(stderr, "Unable to initialize TLS library\n");
#endif

  if (dns_init() == -1)
      warn("Unable to initialize dns resolver\n");
  
   for(runlevel = RL_RUNNING; runlevel;) {
      if (irc_init() == -1) {
         warn("Unable to init irc data structure");
         return -1;
      }

      if(!plugins_loaded) {
         plugins_load();
         plugins_loaded = 1;
      }

      if(!banner_displayed) {
         banner_displayed = banner("Welcome to " PACKAGE_STRING
#ifdef SVN_REV
            "." SVN_REV
#endif
         );
      }

      while ((runlevel == RL_RUNNING) && (irc_conn() == -1)) {
         warn("Unable to establish irc connection\n");
         sleep(RECONNECT_DELAY);
      }

      lastconn = time(NULL);
      while(runlevel == RL_RUNNING)
         io_loop(100);
      
      irc_free();

      if((runlevel != RL_RUNNING) && plugins_loaded) { 
         plugins_unload();
         plugins_loaded = 0;
      }
      
      if(runlevel == RL_RELOAD) {
         printc("Reloading config file '%s'...\n", settings.config);
         if(config_parse(settings.config)) {
            warn("Error reloading config file.\n");
            runlevel = RL_OFFLINE;
         } else if(checkconfig()) {
            runlevel = RL_OFFLINE;
         }
         runlevel = RL_RUNNING;
      }

      conn = 0;
      now = time(NULL);
      if(runlevel != RL_OFFLINE) {
        runlevel = RL_RUNNING;
        if (now < lastconn + RECONNECT_DELAY)
          sleep(lastconn + RECONNECT_DELAY - now);
      }
   }

   if(urandom)
      fclose(urandom);
   return 0;
}