void sess_password(const char *password) { free(g_session.password); g_session.password = strdup(password); sess_connect(); }
/* * Main loop */ int sess_main(struct irc_session *sess) { /* Jump into mainloop */ while (!sess->kill) { time_t lastidle = time(NULL); time_t last_sign_of_life = time(NULL); if (sess_connect(sess) < 0) break; sess->session_start = time(NULL); sess_login(sess); /* Inner loop, receive and handle data */ while (!sess->kill) { /* * Since both idle and flood protection are based on second * precision, this is an optimal timeout */ struct timeval timeout = { .tv_sec = 1, .tv_usec = 0 }; int res = sess_handle_data(sess, &timeout); if (res < 0) { break; } else if (res > 0) { last_sign_of_life = time(NULL); } else { if ((time(NULL) - last_sign_of_life) >= TIMEOUT) { struct tm *tm = TIME_GETTIME(&last_sign_of_life); char buffer[TIMEBUF_MAX] = {0}; strftime(buffer, sizeof(buffer), STRFTIME_FORMAT, tm); log_info("Last sign of life was %d seconds " "ago (%s). Pinging server...", time(NULL) - last_sign_of_life, buffer); struct irc_message ping; irc_mkmessage(&ping, CMD_PING, NULL, 0, "%s", sess->hostname); if (sess_sendmsg_real(sess, &ping) <= 0) break; } } /* Try to send messages in outbuffer */ while (sess->buffer_out_start != sess->buffer_out_end) { struct irc_message *next = &(sess->buffer_out[sess->buffer_out_start]); unsigned len = irc_message_size(next); len = MAX(len, FLOODPROT_MIN); if (tokenbucket_consume(&sess->quota, len)) { sess_sendmsg_real(sess, next); sess->buffer_out_start = (sess->buffer_out_start + 1) % FLOODPROT_BUFFER; } else { break; } } /* Check if we have to emit an idle event */ if ((time(NULL) - lastidle) >= IDLE_INTERVAL) { if (sess->cb.on_idle) sess->cb.on_idle(sess->cb.arg, lastidle); lastidle = time(NULL); } /* And regenerate some tokens */ tokenbucket_generate(&sess->quota); } if (sess->cb.on_disconnect) sess->cb.on_disconnect(sess->cb.arg); /* Session is finished, free resources and start again unless killed */ hashtable_clear(sess->channels); hashtable_clear(sess->capabilities); sess_disconnect(sess); } return 0; } int sess_login(struct irc_session *sess) { struct irc_message nick; struct irc_message user; irc_mkmessage(&nick, CMD_NICK, (const char *[]){ sess->nick }, 1, NULL); irc_mkmessage(&user, CMD_USER, (const char *[]){ sess->user, "*", "*" }, 3, "%s", sess->real);