⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sessions.c

📁 AnyQ服务端源代码(2004/10/28)源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        /* Clean up and get out */        aim_conn_kill(ass, &authconn);        return NULL;    }  	else    {        aim_conn_addhandler(ass, authconn, AIM_CB_FAM_SPECIAL,                             AIM_CB_SPECIAL_FLAPVER, at_flapversion, 0);        aim_conn_addhandler(ass, authconn, AIM_CB_FAM_SPECIAL,                             AIM_CB_SPECIAL_CONNCOMPLETE, at_conncomplete, 0);        aim_conn_addhandler(ass, authconn, 0x0017, 0x0007,                             at_parse_login, 0);        aim_conn_addhandler(ass, authconn, 0x0017, 0x0003,                             at_parse_authresp, 0);            //m = mio_new(authconn->fd, &at_handle_mio, authconn, mio_handlers_new(at_session_handle_read, at_session_handle_write, NULL));        //m->rated = 0;        p = pool_new();        new = pmalloc(p, sizeof(_at_session));        new->m = NULL;        new->p = p;        new->ti = ti;    	new->mp_to = pth_msgport_create("aimsession_to");        new->cur=jid_new(new->p, jid_full(j));        new->from=jid_new(new->p, jid_full(from));        jid_set(new->from, "registered", JID_RESOURCE);        new->ass = ass;        new->exit_flag = 0;        new->loggedin = 0;        new->status = NULL;        new->away = 0;        new->icq = isdigit(user[0]);        new->buddies = xhash_new(137);        new->profile = NULL;        new->at_PPDB = NULL;        new->screenname = pstrdup(new->p, user);        new->password = pstrdup(new->p, pword);        new->icq_vcard_response = NULL;        new->ass->aux_data = (void *)new;        fpres = jutil_presnew(JPACKET__AVAILABLE, ti->i->id, "Online");        xmlnode_put_attrib(fpres, "from", jid_full(new->cur));        new->at_PPDB = ppdb_insert(new->at_PPDB, new->cur, fpres);        xmlnode_free(fpres);        /*        am = pmalloco(new->p, sizeof(_at_mio));        am->p = new->p;        am->s = new;        am->conn = authconn;        am->ass = ass;        */        /* mio_reset(m, &at_handle_mio, am); */        /* Ok everything is good, put this in the session hash */        jput = jid_new(new->p, jid_full(new->cur));        jid_set(jput, NULL, JID_RESOURCE);        xhash_put(ti->session__list, jid_full(jput), new);            log_debug(ZONE, "[AT] User Login: %s", jid_full(new->cur));        aim_request_login(ass, authconn, user);                attr = pth_attr_new();        new->tid = pth_spawn(attr, at_session_main, (void *)new);    	return new;    }    return NULL;}void *at_session_main(void *arg){    at_session s;    ati ti;	pth_event_t to;	jpq q;	xmlnode x;	aim_conn_t *waitingconn = NULL;    int status;    s = (at_session)arg;    ti = s->ti;	to = pth_event(PTH_EVENT_MSG, s->mp_to);	/* Do stuff */	log_debug(ZONE, "[AIM] In our main session");	while ((waitingconn = _aim_select(s->ass, to, &status)) >= 0)    {		if(s->exit_flag)			break;        switch(status)        {            case -1:                /* There was an error */                s->exit_flag = 1;                break;            case 0:                /* Nothing to do */                break;            case 1:			    log_debug(ZONE, "[AIM] Flushing outgoing queue");    			aim_tx_flushqueue(s->ass);                break;            case 2:    		    if (aim_get_command(s->ass, waitingconn) < 0)                {	    			/* XXX do something like send an error */		    		log_debug(ZONE,"[AIM] connection error (type 0x%04x:0x%04x)", waitingconn->type, waitingconn->subtype);                    aim_conn_kill(s->ass, &waitingconn);                    if (!aim_getconn_type(s->ass, AIM_CONN_TYPE_BOS))	                      log_debug(ZONE,"major connection error");			    	s->exit_flag = 1;    			}	        	else		    	{			    	aim_rxdispatch(s->ass);    			}                break;            case 3:		        while(1)        		{		        	q = (jpq)pth_msgport_get(s->mp_to);        			if(q == NULL)                    {		        		break;                    }                    at_aim_session_parser(s, q->p);                    if(s->exit_flag)                        break;        		}                 break;        }		if(s->exit_flag)			break;    }	/* Close up */	log_debug(ZONE,"[AIM] Closing up a main thread");	pth_event_free(to, PTH_FREE_ALL);	at_session_end(s);    pth_exit(NULL);	return NULL;}	void at_aim_session_parser(at_session s, jpacket jp){    ati ti;    int freed;    char *ns;    ti = s->ti;    log_debug(ZONE, "[AIM] Parsing Packet on sessions");            if(s->exit_flag > 0)    {        xmlnode_free(jp->x);        return;    }    switch(jp->type)    {        case JPACKET_IQ:            if(NSCHECK(xmlnode_get_tag(jp->x, "query"),NS_REGISTER))            {                /* Register the user */                freed = at_register(ti, jp);                break;            }            ns = xmlnode_get_attrib(jp->iq,"xmlns");            freed = at_run_iqcb(ti, ns, jp);            if(freed < 0)            {                /* XXX We could dup here and then return 0... */                jutil_error(jp->x, TERROR_NOTFOUND);                at_deliver(ti,jp->x);                freed = 1;            }            break;	    case JPACKET_MESSAGE:            /* Put the message on the line for the session to handle */            at_session_deliver(s, jp->x, jp->to);            freed = 1;            break;        case JPACKET_S10N:            /* Handle a S10N packet based on their subtype */            log_debug(ZONE, "[AT] We got a s10n packet");            freed = at_session_s10n(s, jp);            break;		case JPACKET_PRESENCE:            freed = at_session_pres(s, jp);            break;        default:            /* XXX do more!? */            /*jutil_error(jp->x, TERROR_NOTACCEPTABLE);            at_deliver(ti,jp->x);            */            xmlnode_free(jp->x);            freed = 1;            break;	}    if(freed==0)        xmlnode_free(jp->x);}void at_session_deliver(at_session s, xmlnode x, jid from){    /* XXX We need to check for the XHTML version of the msg */    char *body;    char *dest;    struct aim_sendimext_args args;    unsigned char *utf8_str;    unsigned char *unistr;    unsigned short unilen;    if(s->icq)        body = UTF8_to_str(xmlnode_pool(x),xmlnode_get_tag_data(x, "body"));    else        body = xmlnode_get_tag_data(x, "body");    if(body == NULL || from->user == NULL)        return;    // don't forget to free!    utf8_str = malloc(8192);    unistr = malloc(8192);    // only convert if AIM    if(!s->icq) {       msgconv_plain2aim(body, utf8_str, 8192);       body = utf8_str;    }    if(!s->icq || (strstr(body, "SEND-SMS") != body)) {        log_debug(ZONE, "[AIM] Sending a Message");        args.destsn = from->user;        args.flags = s->icq ? AIM_IMFLAGS_OFFLINE : 0;        // simple enough to be ascii ?        if(isAscii(body) || s->icq) {            args.msg = body;            args.msglen = strlen(body);        }        // unicode        else {            unilen = utf8_to_unicode(body, unistr, 8192);            args.flags |= AIM_IMFLAGS_UNICODE;            args.msg = unistr;            args.msglen = unilen * 2;  // length has to be in bytes, not wchars        }        aim_send_im_ext(s->ass, &args);        //aim_send_im(s->ass, from->user, s->icq ? AIM_IMFLAGS_OFFLINE : 0, body);        /* XXX set offline flag only if destination is really offline */    } else {        log_debug(ZONE, "[AIM] Sending a SMS");        aim_strsep(&body, ":");        dest = aim_strsep(&body, ":");        aim_icq_sendsms(s->ass,dest,body);    }    xmlnode_free(x);    free(utf8_str);    free(unistr);    return;}void _at_session_save_buddies(xht ht, const char *key, void *data, void *arg){    xmlnode item;    xmlnode roster;    char *user;    roster = (xmlnode)arg;    user = (char *)key;    item = xmlnode_insert_tag(roster, "item");    xmlnode_put_attrib(item, "name", user);    return;}void at_session_end(at_session s){    ati ti;    xmlnode x;    xmlnode xset;    int ret;    jid jend;    if(s == NULL)        log_warn(ZONE,"NULL Session told to end!");    else    {        ti = s->ti;        log_debug(ZONE, "[AT] Session (%s) told to end.", jid_full(s->cur));        printf("Ending session for %s\n", jid_full(s->cur));        jend = jid_new(s->p, jid_full(s->cur));        jid_set(jend, NULL, JID_RESOURCE);        xhash_zap(ti->session__list, jid_full(jend));        x = jutil_presnew(JPACKET__UNAVAILABLE, jid_full(s->cur), "Disconnected");        xmlnode_put_attrib(x, "from", jid_full(s->from));        at_deliver(ti,x);        xset = xmlnode_new_tag("buddies");        xhash_walk(s->buddies, &_at_session_save_buddies, xset);        log_debug(ZONE, "Saving buddies: %s", xmlnode2str(xset));        ret = at_xdb_set(ti, ti->i->id, s->cur, xset, AT_NS_ROSTER);        if(ret == 1)            xmlnode_free(xset);        pth_msgport_destroy(s->mp_to);        aim_logoff(s->ass);        aim_session_kill(s->ass);        log_debug(ZONE,"[AT] unlinking session");        at_session_unlink_buddies(s);        xhash_free(s->buddies);        log_warn(ZONE, "[AT] Closing down session for %s", jid_full(s->cur));        ppdb_free(s->at_PPDB);        free(s->ass);        pool_free(s->p);    }    return;}void _at_session_unlink_buddies(xht ht, const char *key, void *data, void *arg){    ati ti;    at_session s;    xmlnode p;    at_buddy buddy;    s = (at_session)arg;    buddy = (at_buddy)data;    ti = s->ti;    p = jutil_presnew(JPACKET__UNAVAILABLE, jid_full(s->cur), "Transport Disconnected");    xmlnode_put_attrib(p, "from", jid_full(buddy->full));    at_deliver(ti,p);    return;}void at_session_unlink_buddies(at_session s){    at_buddy cur, next;    xhash_walk(s->buddies, &_at_session_unlink_buddies, s);}int session_walk(void *user_data, const void *key, void *data){    log_debug(ZONE, "[AT] Walking key: %s data: %x", key, data);    return 0;}at_session at_session_find_by_jid(ati ti, jid j){    at_session s;    char *res;    if(j == NULL)        return NULL;    res = j->resource;    jid_set(j, NULL, JID_RESOURCE);    log_debug(ZONE, "[AT] Finding session for %s", jid_full(j));    s = (at_session)xhash_get(ti->session__list, jid_full(j));    j->resource = res;    /* XXX LEAK ALERT! This is a jid handling problem that we're working on */    j->full = NULL;    return s;}aim_conn_t *_aim_select(aim_session_t *sess,                                pth_event_t ev,                                int *status){    aim_conn_t *cur;    fd_set fds, wfds;    int maxfd = 0;    int i, haveconnecting = 0;    if (sess->connlist == NULL) {        *status = -1;        return NULL;    }    FD_ZERO(&fds);    FD_ZERO(&wfds);    maxfd = 0;    for (cur = sess->connlist; cur; cur = cur->next) {        if (cur->status & AIM_CONN_STATUS_INPROGRESS) {            FD_SET(cur->fd, &wfds);            haveconnecting++;        }        FD_SET(cur->fd, &fds);        if (cur->fd > maxfd)            maxfd = cur->fd;    }        /*     * If we have data waiting to be sent, return immediatly    */    if (!haveconnecting && (sess->queue_outgoing != NULL)) {        *status = 1;        return NULL;    }     if ((i = pth_select_ev(maxfd+1, &fds, &wfds, NULL, NULL, ev))>=1) {        for (cur = sess->connlist; cur; cur = cur->next) {            if (FD_ISSET(cur->fd, &fds) ||                 ((cur->status & AIM_CONN_STATUS_INPROGRESS) &&                 FD_ISSET(cur->fd, &wfds)))             {	            *status = 2;	            return cur;            }        }        *status = 0; /* shouldn't happen */    } else if ((i == -1) && (errno == EINTR))/* treat inerpts as a timeout */        *status = 0;    else        *status = i; /* can be 0 or -1 */    if(pth_event_occurred(ev))    {        /* Possible msgport event (should be, no timeout) */        *status = 3;        return (aim_conn_t *)1;    }    return NULL;  /* no waiting or error, return */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -