Exemplo n.º 1
0
void sess_password(const char *password)
{
  free(g_session.password);
  g_session.password = strdup(password);

  sess_connect();
}
Exemplo n.º 2
0
/*
 * 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);