示例#1
0
static gint
hybrid_blist_cache_init(HybridConfig *config)
{
	gchar *cache_file_name;
	HybridBlistCache *cache;
	xmlnode *root;
	gint err;

	g_return_val_if_fail(config != NULL, HYBRID_ERROR);

	cache_file_name = g_strdup_printf("%s/blist.xml", config->config_path);

	hybrid_debug_info("config", "init the blist cache from %s",
			cache_file_name);

	cache = g_new0(HybridBlistCache, 1);
	cache->cache_file_name = cache_file_name;

	config->blist_cache = cache;

	if (!(root = xmlnode_root_from_file(cache_file_name))) {
		const gchar *root_string = "<blist></blist>";
		root = xmlnode_root(root_string, strlen(root_string));
		cache->root = root;

		goto blist_cache_init_null;
	}

	if (!root) {
		hybrid_debug_error("config", "FATAL, init blist cache");
		return HYBRID_ERROR;
	}

	cache->root = root;

	/* Load the cached buddy list */
	goto blist_cache_init_fin;

blist_cache_init_null:
	/* initialize the xml context since we don't have local cache */
	xmlnode_new_child(root, "accounts");

	xmlnode_save_file(root, cache->cache_file_name);

blist_cache_init_fin:
	/* initialize the icon path. */
	config->icon_path = g_strdup_printf("%s/icons", config->config_path);

	err = mkdir(config->icon_path, S_IRWXU|S_IRWXO|S_IRWXG);

	if (err && access(config->icon_path, R_OK|W_OK)) {
		hybrid_debug_error("config", "%s,cannot create, read or write",
				config->icon_path);
		g_free(config->icon_path);

		return HYBRID_ERROR;
	}

	return HYBRID_OK;
}
示例#2
0
static gboolean
stream_recv_cb(gint sk, XmppStream *stream)
{
    gchar buf[BUF_LENGTH];
    gint  n;

    if (!stream->ssl) {
        if ((n = recv(sk, buf, sizeof(buf) - 1, 0)) == -1) {
            
            hybrid_debug_error("xmpp", "init stream error.");
            return FALSE;
        }
    } else {

        if ((n = hybrid_ssl_read(stream->ssl, buf, sizeof(buf) - 1)) == -1) {
            
            hybrid_debug_error("xmpp", "stream read io error.");
            return TRUE;
        } else if (0 == n) {
            
            hybrid_debug_error("xmpp", "connection closed by server.");
            return FALSE;
        }
    }

    buf[n] = '\0';

    if (n > 0) {
        xmpp_process_pushed(stream, buf, n);
    } 

    return TRUE;
}
示例#3
0
HybridConnection*
hybrid_proxy_connect(const gchar *hostname, gint port, connect_callback func,
                     gpointer user_data)
{
    gint              sk;
    struct sockaddr   addr;
    HybridConnection *conn;

    g_return_val_if_fail(port != 0, NULL);
    g_return_val_if_fail(hostname != NULL, NULL);

    hybrid_debug_info("connect", "connecting to %s:%d", hostname, port);

    conn = g_new0(HybridConnection, 1);

    if ((sk = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

        hybrid_debug_error("connect", "create socket: %s", strerror(errno));
        hybrid_connection_destroy(conn);

        return NULL;
    }

    if (nonblock(sk) != HYBRID_OK) {

        hybrid_connection_destroy(conn);
        return NULL;
    }

    if (addr_init(hostname, port, &addr) != HYBRID_OK) {

        hybrid_connection_destroy(conn);
        return NULL;
    }

    if (connect(sk, &addr, sizeof(addr)) != 0) {

        if (errno != EINPROGRESS) {

            hybrid_debug_error("connect", "connect to \'%s:%d\':%s", hostname,
                               port, strerror(errno));
            hybrid_connection_destroy(conn);
            return NULL;
        }

        hybrid_debug_info("connect", "connect in progress");

        hybrid_event_add(sk, HYBRID_EVENT_WRITE, func, user_data);
    } else {
        /* connection establish imediately */
        func(sk, user_data);
    }

    conn->sk   = sk;
    conn->host = g_strdup(hostname);
    conn->port = port;

    return conn;
}
示例#4
0
/**
 * Callback function to handle the invite-connect event, when we
 * get this acknowledge message, we should start to invite the buddy
 * to the conversation.
 *
 * The message received is:
 *
 * SIP-C/4.0 200 OK
 * I: 5
 * Q: 2 R
 * XI: 3d2ef745db9741a8946a57c40b0eb4d5
 * X: 1200
 * K: text/plain
 * K: text/html-fragment
 * K: multiparty
 * K: nudge
 *
 * then we send out invite-buddy request:
 */
static gint
chat_reg_cb(fetion_account *account, const gchar *sipmsg,
			fetion_transaction *trans)
{
	fetion_sip *sip;
	sip_header *eheader;
	gchar *body;
	gchar *sip_text;
	fetion_transaction *new_trans;
	fetion_buddy *buddy;

	sip = account->sip;

	fetion_sip_set_type(sip, SIP_SERVICE);

	if (!(buddy = fetion_buddy_find_by_userid(account, trans->userid))) {

		hybrid_debug_error("fetion", "invite new buddy failed");

		return HYBRID_ERROR;
	}

	eheader = sip_event_header_create(SIP_EVENT_INVITEBUDDY);
	fetion_sip_add_header(sip, eheader);

	body = generate_invite_buddy_body(buddy->sipuri);

	new_trans = transaction_clone(trans);
	transaction_set_callid(new_trans, sip->callid);
	transaction_set_callback(new_trans, invite_buddy_cb);
	transaction_add(account, new_trans);

	sip_text = fetion_sip_to_string(sip, body);
	g_free(body);

	hybrid_debug_info("fetion", "invite new buddy,send:\n%s", sip_text);

	if (send(account->sk, sip_text, strlen(sip_text), 0) == -1) {

		hybrid_debug_error("fetion", "invite new buddy failed");

		return HYBRID_ERROR;
	}

	g_free(sip_text);

	return HYBRID_OK;
}
示例#5
0
void
fetion_update_portrait(fetion_account *ac, fetion_buddy *buddy)
{
	portrait_data *data;
	HybridBuddy *hybrid_buddy;
	const gchar *checksum;

	g_return_if_fail(ac != NULL);
	g_return_if_fail(buddy != NULL);

	data = g_new0(portrait_data, 1);
	data->buddy = buddy;
	data->ac = ac;
	data->portrait_type = PORTRAIT_TYPE_BUDDY;

	if (!(hybrid_buddy = hybrid_blist_find_buddy(ac->account, buddy->userid))) {
		hybrid_debug_error("fetion", "FATAL, update portrait,"
				" unable to find a buddy.");
		return;
	}

	checksum = hybrid_blist_get_buddy_checksum(hybrid_buddy);

	if (checksum != NULL && g_strcmp0(checksum, buddy->portrait_crc) == 0) {
		hybrid_debug_info("fetion", "portrait for %s(%s) up to date",
		buddy->nickname && *(buddy->nickname) != '\0' ? buddy->nickname : buddy->userid,
		buddy->portrait_crc);
		return;
	}

	hybrid_proxy_connect(ac->portrait_host_name, 80, portrait_conn_cb, data);
}
示例#6
0
gint
fetion_buddy_rename(fetion_account *ac, const gchar *userid,
		const gchar *newname)
{
	fetion_sip *sip;
	sip_header *eheader;
	gchar *res;
	gchar *body;

	g_return_val_if_fail(ac != NULL, HYBRID_ERROR);
	g_return_val_if_fail(userid != NULL, HYBRID_ERROR);
	g_return_val_if_fail(newname != NULL, HYBRID_ERROR);

	sip = ac->sip;

	fetion_sip_set_type(sip, SIP_SERVICE);
	eheader = sip_event_header_create(SIP_EVENT_SETCONTACTINFO);
	fetion_sip_add_header(sip , eheader);

	body = generate_rename_buddy_body(userid, newname);
	res = fetion_sip_to_string(sip, body);
	g_free(body);

	if (send(ac->sk, res, strlen(res), 0) == -1) {
		hybrid_debug_error("fetion", "rename buddy %s", userid);

		return HYBRID_ERROR;
	}

	g_free(res);

	return HYBRID_OK;
}
示例#7
0
gint
hybrid_get_http_length(const gchar *http_response)
{
    gchar       *pos, *stop;
    gchar       *temp;
    gint         length;
    const gchar *cur = "Content-Length: ";

    g_return_val_if_fail(http_response != NULL, 0);

    if (!(pos = g_strrstr(http_response, cur))) {
        hybrid_debug_error("http", "no Content-length in response header.");
        return 0;
    }

    pos += strlen(cur);

    for (stop = pos; *stop && *stop != '\r'; stop ++);

    temp = g_strndup(pos, stop - pos);
    length = atoi(temp);
    g_free(temp);

    return length;
}
示例#8
0
gint
hybrid_ssl_read(HybridSslConnection *ssl, gchar *buf, gint len)
{
    gint ret;

    hybrid_debug_info("ssl", "start ssl read.");

    ret = BIO_read(ssl->rbio, buf, len);

    switch (SSL_get_error(ssl->ssl, ret)) {
    case SSL_ERROR_NONE:
        hybrid_debug_info("ssl", "ssl read %d bytes, success!", ret);
        return ret;
    case SSL_ERROR_WANT_WRITE:
    case SSL_ERROR_WANT_READ:
        hybrid_debug_info("ssl", "ssl read WANT RW with ret %d.", ret);
        break;
    case SSL_ERROR_SYSCALL:
        hybrid_debug_info("ssl", "ssl read io error.");
        return -1;
    case SSL_ERROR_WANT_X509_LOOKUP:
        hybrid_debug_info("ssl", "ssl read X509.");
        return -1;
    case SSL_ERROR_ZERO_RETURN:
        hybrid_debug_info("ssl", "ssl connection permaturely closed.");
        return 0;
    case SSL_ERROR_SSL:
    default:
        hybrid_debug_error("ssl", "ssl read error:%s",
                           ERR_reason_error_string(ERR_get_error()));
        return -1;
    }

    return -1;
}
示例#9
0
/**
 * Create a new SSL struct with certificates loaded.
 */
static SSL*
ssl_new_with_certs(SSL_CTX *ctx)
{
    SSL *ssl;

    g_return_val_if_fail(ctx != NULL, NULL);

    if(SSL_CTX_use_certificate_file(ctx, CCERT_DIR"/client_cert",
                                    SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
    }

    if(SSL_CTX_use_PrivateKey_file(ctx, CCERT_DIR"/client_key",
                                   SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
    }

    if (!SSL_CTX_load_verify_locations(ctx, NULL, CERTS_DIR)) {
        ERR_print_errors_fp(stderr);
    }

    if (!(ssl = SSL_new(ctx))) {
        hybrid_debug_error("ssl", "create SSl:%s",
                           ERR_reason_error_string(ERR_get_error()));
        return NULL;
    }

    return ssl;

}
示例#10
0
文件: logs.c 项目: bigbo/hybrid
gint
hybrid_logs_init(void)
{
    const gchar *config_path;
    gchar *log_path;
    gint e;

    config_path = hybrid_config_get_path();

    log_path = g_strdup_printf("%s/logs/", config_path);

    e = mkdir(log_path, S_IRWXU|S_IRWXO|S_IRWXG);

    if (e && access(log_path, R_OK|W_OK)) {
        hybrid_debug_error("logs", "%s,cannot create, read or write",
                            log_path);
        g_free(log_path);

        return HYBRID_ERROR;
    }

    g_free(log_path);

    return HYBRID_OK;
}
示例#11
0
gint
xmpp_message_send(XmppStream *stream, const gchar *text, const gchar *to)
{
    xmlnode *root;
    xmlnode *node;
    gchar   *xml_string;

    g_return_val_if_fail(stream != NULL, HYBRID_ERROR);
    g_return_val_if_fail(text != NULL, HYBRID_ERROR);
    g_return_val_if_fail(to != NULL, HYBRID_ERROR);

    root = xmlnode_create("message");
    xmlnode_new_prop(root, "from", stream->jid);
    xmlnode_new_prop(root, "to", to);
    xmlnode_new_prop(root, "type", "chat");
    node = xmlnode_new_child(root, "body");
    xmlnode_set_content(node, text);

    xml_string = xmlnode_to_string(root);
    xmlnode_free(root);

    hybrid_debug_info("xmpp", "send message to %s:\n%s", to, xml_string);

    if (hybrid_ssl_write(stream->ssl, xml_string, strlen(xml_string)) == -1) {

        hybrid_debug_error("xmpp", "send message to %s failed\n", to);
        g_free(xml_string);

        return HYBRID_ERROR;
    }

    g_free(xml_string);

    return HYBRID_OK;
}
示例#12
0
/**
 * Callback function to handle the new-chat connecting event.
 * The message is:
 *
 * R fetion.com.cn SIP-C/4.0
 * F: 547264589
 * I: 5
 * Q: 2 R
 * A: TICKS auth="2051600954.830102111"
 * K: text/html-fragment
 * K: multiparty
 * K: nudge
 */
static gint
invite_connect_cb(gint sk, gpointer user_data)
{
	fetion_transaction *trans;
	fetion_account *account;
	fetion_sip *sip;
	invite_data *data;
	gchar *credential;
	gchar *sip_text;

	sip_header *aheader;
	sip_header *theader;
	sip_header *mheader;
	sip_header *nheader;

	data       = (invite_data*)user_data;
	trans      = data->trans;
	credential = data->credential;
	account    = trans->data;

	g_free(data);

	sip = account->sip;
	account->sk = sk;

	/* listen for this thread */
	account->source = hybrid_event_add(sk, HYBRID_EVENT_READ,
						hybrid_push_cb, account);

	fetion_sip_set_type(sip, SIP_REGISTER);
	aheader = sip_credential_header_create(credential);
	theader = sip_header_create("K", "text/html-fragment");
	mheader = sip_header_create("K", "multiparty");
	nheader = sip_header_create("K", "nudge");
	
	transaction_set_callid(trans, sip->callid);
	transaction_set_callback(trans, chat_reg_cb);
	transaction_add(account, trans);

	fetion_sip_add_header(sip, aheader);
	fetion_sip_add_header(sip, theader);
	fetion_sip_add_header(sip, mheader);
	fetion_sip_add_header(sip, nheader);

	sip_text = fetion_sip_to_string(sip, NULL);

	hybrid_debug_info("fetion", "register, send:\n%s", sip_text);
	
	if (send(sk, sip_text, strlen(sip_text), 0) == -1) {

		hybrid_debug_error("fetion", "register to the new chat channel failed");

		return HYBRID_ERROR;
	}

	g_free(sip_text);
	g_free(credential);

	return HYBRID_OK;
}
示例#13
0
文件: imap.c 项目: GCrean/hybrid
gint
hybrid_imap_auth(hybrid_imap *imap)
{
    gchar               *cmd;
    HybridSslConnection *ssl;

    ssl = imap->ssl;
    cmd = g_strdup_printf("A%d LOGIN %s %s\r\n",
                          imap->current_tag,
                          imap->username,
                          imap->password);

    hybrid_debug_info("imap", "send:\n%s", cmd);

    imap_trans_create(imap, imap_auth_cb, NULL);

    if (hybrid_ssl_write(ssl, cmd, strlen(cmd)) <= 0) {

        hybrid_debug_error("imap", "write to IMAP ssl connection error.");
        g_free(cmd);
        return HYBRID_ERROR;
    }

    g_free(cmd);

    return HYBRID_OK;
}
示例#14
0
文件: conv.c 项目: celiachen/hybrid
void
hybrid_conv_got_status(HybridAccount *account, const gchar *buddy_id, const gchar *text, gint type)
{
    HybridChatWindow *chat;
    HybridBuddy      *buddy;

    g_return_if_fail(account != NULL);
    g_return_if_fail(buddy_id != NULL);

    if (!(buddy = hybrid_blist_find_buddy(account, buddy_id))) {

        hybrid_debug_error("conv", "buddy doesn't exist.");
        return;
    }

    if (!(chat = hybrid_conv_find_chat(buddy_id))) {
        /*
         * Well, we haven't find an existing chat panel so far, check the type
         * to determine whether to create a new one.
         */
        if (type == MSG_NOTIFICATION_INPUT) {
            return;

        } else {
            chat = hybrid_chat_window_create(account, buddy->id, HYBRID_CHAT_PANEL_SYSTEM);
        }
    }

    if (type == MSG_NOTIFICATION_INPUT) {
        text_ops->notify(chat->textview, text, MSG_NOTIFICATION_INPUT);
    }

}
示例#15
0
static gboolean
ping_timeout_cb(XmppStream *stream)
{
    hybrid_debug_error("xmpp", "ping timeout");

    return FALSE;
}
示例#16
0
文件: conv.c 项目: celiachen/hybrid
void
hybrid_conv_clear_input(HybridAccount *account, const gchar *buddy_id)
{
    HybridBuddy      *buddy;
    HybridChatWindow *chat;

    g_return_if_fail(account != NULL);
    g_return_if_fail(buddy_id != NULL);

    if (!(buddy = hybrid_blist_find_buddy(account, buddy_id))) {

        hybrid_debug_error("conv", "buddy doesn't exist.");
        return;
    }

    if (!(chat = hybrid_conv_find_chat(buddy_id))) {
        return;
    }

    if (chat->input_source) {
        g_source_remove(chat->input_source);
    }

    text_ops->notify(chat->textview, "" , MSG_NOTIFICATION_INPUT);
}
示例#17
0
文件: imap.c 项目: GCrean/hybrid
gboolean
check_mail_cb(hybrid_imap *imap, const gchar *msg, gpointer user_data)
{
    const gchar *pos;
    const gchar *cur;
    gchar       *count_str;
    gint         count_int;

    hybrid_debug_info("imap", "recv:\n%s", msg);

    if (HYBRID_OK == check_resp_ok(msg)) {
        if ((pos = strstr(msg, "UNSEEN "))) {
            pos += 7;
            for (cur = pos; '\0' != *cur && ')' != *cur; cur ++);

            if ('\0' != *cur) {
                count_str = g_strndup(pos, cur - pos);
                count_int = atoi(count_str);
                g_free(count_str);

                process_unread_mails(imap, count_int);
            }
        }
    } else {
        hybrid_debug_error("imap", "check unread mail error.");
    }

    imap->mail_check_source = g_timeout_add_seconds(imap->mail_check_interval,
                                                    check_mail, imap);

    return FALSE;
}
示例#18
0
文件: pref.c 项目: CinsonChen/hybrid
gint
hybrid_pref_init(void)
{
    const gchar *body;
    gchar       *config_path;

    hybrid_pref = g_new0(HybridPref, 1);

    if (!(config_path = hybrid_config_get_path())) {

        hybrid_debug_error("pref", "get config path error.");

        return HYBRID_ERROR;
    }

    hybrid_pref->filename = g_strdup_printf("%s/pref.xml", config_path);

    g_free(config_path);

    if (!(hybrid_pref->root = 
                xmlnode_root_from_file(hybrid_pref->filename))) {

        body = "<pref></pref>";

        hybrid_pref->root = xmlnode_root(body, strlen(body));

        hybrid_pref_save();
    }

    return HYBRID_OK;
}
示例#19
0
文件: pref.c 项目: CinsonChen/hybrid
gchar*
hybrid_pref_get_string(const gchar *name)
{
    xmlnode *node;
    gchar   *type;
    gchar   *value;

    g_return_val_if_fail(hybrid_pref != NULL, FALSE);
    g_return_val_if_fail(hybrid_pref->root != NULL, FALSE);

    if (!(node = xmlnode_find(hybrid_pref->root, name))) {
        return NULL;
    }

    if (!xmlnode_has_prop(node, "type")) {

        hybrid_debug_info("pref", "invalid pref node.");
        
        return NULL;
    }

    type = xmlnode_prop(node, "type");

    if (g_strcmp0(type, "string") != 0) {

        hybrid_debug_error("pref",
                "string pref node with a type which is not string.");

        return NULL;
    }

    value = xmlnode_content(node);

    return value;
}
示例#20
0
文件: fetion.c 项目: celiachen/hybrid
/**
 * Process the user left message, we close the current channel,
 * and remove the session from the session list.
 */
static void
process_left_cb(fetion_account *ac, const gchar *sipmsg)
{
    extern GSList *channel_list;
    GSList        *pos;

    g_return_if_fail(ac != NULL);
    g_return_if_fail(sipmsg != NULL);

    hybrid_debug_info("fetion", "buddy left, recv:\n%s", sipmsg);

    for (pos = channel_list; pos; pos = pos->next) {
        if (pos->data == ac) {
            channel_list = g_slist_remove(channel_list, ac);

            goto channel_removed;
        }
    }

    hybrid_debug_error("fetion", "FATAL, can't find channel");

    return;

channel_removed:
    /* remove the read event source. */
    g_source_remove(ac->source);

    /* close the channel. */
    close(ac->sk);

    /* destroy the account. */
    fetion_account_destroy(ac);
}
示例#21
0
文件: core.c 项目: celiachen/hybrid
static void
create_account_menus(GtkUIManager *ui)
{
    GtkWidget *account_shell;
    GtkWidget *seperator;
    HybridAccount *account;
    GSList *pos;

    if (!(account_shell = gtk_ui_manager_get_widget(ui, "/MenuBar/Account"))) {
        hybrid_debug_error("core", "account menu init err");
        return;
    }

    account_shell = gtk_menu_item_get_submenu(GTK_MENU_ITEM(account_shell));

    if (account_list) {
        seperator = gtk_separator_menu_item_new();
        gtk_menu_shell_insert(GTK_MENU_SHELL(account_shell), seperator, 2);
    }

    for (pos = account_list; pos; pos = pos->next) {

        /* set the name of the account menu. */
        account = (HybridAccount*)pos->data;

        hybrid_account_create_menu(account);
    }
}
示例#22
0
/**
 * Callback function to handle the new_chat response message, if success
 * we would get the following message:
 *
 * SIP-C/4.0 200 OK
 * I: 4
 * Q: 2 S
 * A: CS address="221.176.31.128:8080;221.176.31.128:443",credential="439333922.916967705"
 *
 * Now we should start a new socket connect to 221.176.31.128:8080 with port 443 as
 * a back port if 8080 failed to connect.
 */
gint
new_chat_cb(fetion_account *account, const gchar *sipmsg,
				fetion_transaction *trans)
{
	gchar *auth;
	gchar *ip;
	gint port;
	gchar *credential;
	invite_data *data;
	fetion_transaction *new_trans;
	fetion_account *new_account;

	printf("%s\n", sipmsg);

	if (!(auth = sip_header_get_attr(sipmsg, "A"))) {

		hybrid_debug_error("fetion", "invalid invitation response.");

		return HYBRID_ERROR;
	}

	if (sip_header_get_auth(auth, &ip, &port, &credential) != HYBRID_OK) {

		hybrid_debug_error("fetion", "invalid invitation response.");

		return HYBRID_ERROR;
	}

	g_free(auth);

	new_trans = transaction_clone(trans);

	new_account = fetion_account_clone(account);
	fetion_account_set_who(new_account, trans->userid);

	transaction_set_data(new_trans, new_account);

	data = g_new0(invite_data, 1);
	data->trans = new_trans;
	data->credential = credential;

	hybrid_proxy_connect(ip, port, invite_connect_cb, data);

	g_free(ip);

	return HYBRID_OK;
}
示例#23
0
文件: config.c 项目: celiachen/hybrid
gchar*
hybrid_config_get_path(void)
{
    gchar        *home;
    static gchar *config_path = NULL;
    static gchar *hybrid_path = NULL;
    gint         e;

    if (hybrid_path)
        goto check_hybrid;
    if (config_path)
        goto check_conf;
    if (!(config_path = getenv("XDG_CONFIG_HOME"))) {
        if (!(home = getenv("HOME"))) {
            hybrid_debug_error("config", "No environment variable "
                               "named HOME\n");
            return NULL;
        }
        config_path = g_strdup_printf("%s/.config", home);
    } else {
        config_path = g_strdup_printf("%s", config_path);
    }

check_conf:
    e = mkdir(config_path, S_IRWXU|S_IRWXO|S_IRWXG);
    if (e && access(config_path, R_OK|W_OK)) {
        hybrid_debug_error("config", "cannot create, read from or write to %s",
                           config_path);
        g_free(config_path);
        config_path = NULL;
        return NULL;
    }

    hybrid_path = g_strdup_printf("%s/hybrid", config_path);

check_hybrid:
    e = mkdir(hybrid_path, S_IRWXU|S_IRWXO|S_IRWXG);
    if (e && access(hybrid_path, R_OK|W_OK)) {
        hybrid_debug_error("config", "cannot create, read from or write to %s",
                           hybrid_path);
        g_free(hybrid_path);
        hybrid_path = NULL;
        return NULL;
    }

    return hybrid_path;
}
示例#24
0
/**
 * Verify the peer's    certificate, if successfully verified,
 * save the peer's certificate
 */
static gint
ssl_verify_certs(SSL *ssl)
{
    FILE  *f;
    X509  *x;
    gchar *cert_path;
    gchar *cert_file;
    gchar  buf[256];
    gchar *pos;

    hybrid_debug_info("ssl", "verifying the peer's certificate");

    if ((x = SSL_get_peer_certificate(ssl)) != NULL) {
        if (SSL_get_verify_result(ssl)        == X509_V_OK) {

            X509_NAME_oneline(X509_get_subject_name(x), buf, 256);

            hybrid_debug_info("ssl", "client verification succeeded.");

            cert_path = hybrid_config_get_cert_path();

            if ((pos = strstr(buf, "CN="))) {
                cert_file = g_strdup_printf("%s/%s", cert_path, pos + 3);
            } else {
                cert_file = g_strdup_printf("%s/%s", cert_path, buf);
            }

            g_free(cert_path);

            f = fopen(cert_file, "w+");
            PEM_write_X509(f, x);
            fclose(f);
            g_free(cert_file);

        } else {
            hybrid_debug_error("ssl", "client verification failed.");
            return HYBRID_OK;
        }
    } else {
        hybrid_debug_error("ssl", "the peer certificate was not presented.\n");
    }

    return HYBRID_OK;
}
示例#25
0
文件: groupadd.c 项目: GCrean/hybrid
/**
 * Callback function of the save button click signal.
 */
static void
save_cb(GtkWidget *widget, HybridGroupAddWindow *window)
{
    GtkTreeModel  *model;
    GtkTreeIter    iter;
    HybridAccount *account;
    HybridModule  *proto;
    HybridIMOps   *ops;
    const gchar   *name;

    model = gtk_combo_box_get_model(GTK_COMBO_BOX(window->account_combo));

    if (!gtk_combo_box_get_active_iter(
                GTK_COMBO_BOX(window->account_combo), &iter)) {

        hybrid_debug_error("groupadd", "no account was choosed.");

        return;
    }

    gtk_tree_model_get(model, &iter,
                    GROUPADD_ACCOUNT_COLUMN, &account,
                    -1);

    name = gtk_entry_get_text(GTK_ENTRY(window->name_entry));

    if (!name || *name == '\0') {

        hybrid_debug_error("groupadd", "no group name was specified.");

        return;
    }

    proto = account->proto;
    ops      = proto->info->im_ops;

    /* call the protocol hook function. */
    if (ops->group_add) {
        ops->group_add(account, name);
    }

    /* destroy the groupadd window. */
    gtk_widget_destroy(window->window);
}
示例#26
0
gint 
resolve_host(const gchar *hostname, gchar *ip)
{
	g_return_val_if_fail(hostname != NULL, HYBRID_ERROR);

	struct addrinfo *result;
	struct sockaddr_in *addr;
	gchar *hash_value;

	hybrid_debug_info("dns", "resolve host \'%s\'", hostname);

	if (host_hash && (hash_value = g_hash_table_lookup(host_hash, hostname))) {
		strcpy(ip, (gchar*)hash_value);	
		hybrid_debug_info("dns", "ip of \'%s\' is \'%s\'", hostname, ip);
		return HYBRID_OK;
	}

	if (getaddrinfo(hostname, NULL, NULL, &result) != 0) {
		hybrid_debug_error("resolve_host", "resolve host \'%s\' failed",
				hostname);
		return HYBRID_ERROR;
	}

	addr = (struct sockaddr_in*)result->ai_addr;

	if (!inet_ntop(AF_INET, (void*)&addr->sin_addr, ip, 16)) {
		hybrid_debug_error("dns", "reslove host \'%s\' failed when"
				" transforming binary ip address to doted ip address",
				hostname);
		return HYBRID_ERROR;
	}

	if (!host_hash) {
		host_hash = g_hash_table_new(g_str_hash, g_str_equal);
	}

	hash_value = g_strdup(ip);

	g_hash_table_insert(host_hash, (gchar*)hostname, hash_value);

	hybrid_debug_info("dns", "ip of \'%s\' is \'%s\'", hostname, ip);

	return HYBRID_OK;
}
示例#27
0
gchar*
hybrid_config_get_path(void)
{
	gchar *home;
	gchar *config_path;
	gchar *hybrid_path;
	gint e;

	if (!(home = getenv("HOME"))) {
		hybrid_debug_error("config", "No environment variable named HOME\n");
		return NULL;
	}

	config_path = g_strdup_printf("%s/.config", home);

	e = mkdir(config_path, S_IRWXU|S_IRWXO|S_IRWXG);

	if (e && access(config_path, R_OK|W_OK)) {
		hybrid_debug_error("config", "%s,cannot create, read or write",
				config_path);
		g_free(config_path);

		return NULL;
	}

	hybrid_path = g_strdup_printf("%s/hybrid", config_path);

	e = mkdir(hybrid_path, S_IRWXU|S_IRWXO|S_IRWXG);

	if (e && access(hybrid_path, R_OK|W_OK)) {
		hybrid_debug_error("config", "%s,cannot create, read or write",
				hybrid_path);
		g_free(config_path);
		g_free(hybrid_path);

		return NULL;
	}

	g_free(config_path);

	return hybrid_path;
}
示例#28
0
gboolean
portrait_conn_cb(gint sk, gpointer user_data)
{
	portrait_data *data = (portrait_data*)user_data;
	portrait_trans *trans;
	gchar *http_string;
	gchar *encoded_sipuri;
	gchar *encoded_ssic;
	gchar *uri;

	trans = g_new0(portrait_trans, 1);
	trans->buddy = data->buddy;
	trans->ac = data->ac;
	trans->portrait_type = data->portrait_type;

	g_free(data);

	if (trans->portrait_type == PORTRAIT_TYPE_BUDDY) {
		encoded_sipuri = g_uri_escape_string(trans->buddy->sipuri, NULL, TRUE);

	} else {
		encoded_sipuri = g_uri_escape_string(trans->ac->sipuri, NULL, TRUE);
	}

	encoded_ssic = g_uri_escape_string(trans->ac->ssic, NULL, TRUE);

	uri = g_strdup_printf("/%s/getportrait.aspx", trans->ac->portrait_host_path);

	http_string = g_strdup_printf("GET %s?Uri=%s"
			  "&Size=120&c=%s HTTP/1.1\r\n"
			  "User-Agent: IIC2.0/PC "PROTO_VERSION"\r\n"
			  "Accept: image/pjpeg;image/jpeg;image/bmp;"
			  "image/x-windows-bmp;image/png;image/gif\r\n"
			  "Host: %s\r\nConnection: Close\r\n\r\n",
			  uri, encoded_sipuri, encoded_ssic,
			  trans->ac->portrait_host_name);

	g_free(encoded_sipuri);
	g_free(encoded_ssic);
	g_free(uri);

	if (send(sk, http_string, strlen(http_string), 0) == -1) {
		hybrid_debug_error("fetion", "download portrait for \'%s\':%s",
				trans->buddy->sid, strerror(errno));
		g_free(http_string);
		return FALSE;
	}

	g_free(http_string);

	hybrid_event_add(sk, HYBRID_EVENT_READ, portrait_recv_cb, trans);

	return FALSE;
}
示例#29
0
/**
 * Process the iq messages.
 */
static void
xmpp_stream_process_iq(XmppStream *stream, xmlnode *node)
{
    gchar         *id;
    gint           id_int;
    GSList        *pos;
    IqTransaction *trans;
    gchar         *value;

    g_return_if_fail(stream != NULL);
    g_return_if_fail(node != NULL);

    if (!xmlnode_has_prop(node, "type") ||
        !xmlnode_has_prop(node, "id")) {
        hybrid_debug_error("xmpp", "invalid iq message.");

        return;
    }

    value = xmlnode_prop(node, "type");

    /* response to a get or set request. */
    if (g_strcmp0(value, "result") == 0 ||
        g_strcmp0(value, "error") == 0) {

        id = xmlnode_prop(node, "id");
        id_int = atoi(id);
        g_free(id);

        for (pos = stream->pending_trans; pos; pos = pos->next) {
            trans = (IqTransaction*)pos->data;

            if (trans->iq_id == id_int) {

                if (trans->callback) {
                    trans->callback(stream, node, trans->user_data);
                }

                iq_transaction_remove(stream, trans);
            }
        }

    /*
     * An entity that receives an IQ request of type "get" or "set" MUST
       reply with an IQ response of type "result" or "error".
     */
    } else if (g_strcmp0(value, "get") == 0) { /* process later. */
    } else if (g_strcmp0(value, "set") == 0) {
        xmpp_stream_process_iq_set(stream, node);
    }

    g_free(value);
}
示例#30
0
gint
xmpp_message_send_typing(XmppStream *stream, const gchar *to, HybridInputState state)
{
    xmlnode *root;
    xmlnode *node;
    gchar   *xml_string;

    g_return_val_if_fail(stream != NULL, HYBRID_ERROR);
    g_return_val_if_fail(to != NULL, HYBRID_ERROR);

    root = xmlnode_create("message");
    xmlnode_new_prop(root, "from", stream->jid);
    xmlnode_new_prop(root, "to", to);
    xmlnode_new_prop(root, "type", "chat");

    switch (state) {
    case INPUT_STATE_TYPING:
      node = xmlnode_new_child(root, "composing");
      break;
    case INPUT_STATE_ACTIVE:
      node = xmlnode_new_child(root, "active");
      break;
    case INPUT_STATE_PAUSED:
      node = xmlnode_new_child(root, "paused");
      break;
    default:
      node = NULL;
      break;
    }

    if (node) {
        xmlnode_new_namespace(node, NULL, NS_CHANGESTATES);
    }

    xml_string = xmlnode_to_string(root);
    xmlnode_free(root);

    hybrid_debug_info("xmpp", "send message to %s:\n%s", to, xml_string);

    if (hybrid_ssl_write(stream->ssl, xml_string, strlen(xml_string)) == -1) {

        hybrid_debug_error("xmpp", "send message to %s failed\n", to);
        g_free(xml_string);

        return HYBRID_ERROR;
    }

    g_free(xml_string);

    return HYBRID_OK;
}