gboolean session_timeout(gpointer data){ Session *s; GgServer *serv; g_assert(data!=NULL); s=(Session *)data; serv=(GgServer*)s->current_server->data; user_load_locale(s->user); s->timeout_func=0; g_warning(N_("Session timeout for %s"),s->jid); if(serv->port!=1){ g_warning(N_("Timeout for server %u - failure count: %d"), g_list_position(gg_servers, s->current_server), serv->error_count); } else { g_warning(N_("Timeout for hub %u"), g_list_position(gg_servers, s->current_server)); } return session_error(s); }
int jabber_message(struct stream_s *stream,xmlnode tag){ char *type; char *from; char *to; char *subject; char *body; int chat; xmlnode subject_n; xmlnode body_n; Session *s; User *u; body_n=xmlnode_get_tag(tag,"body"); if (body_n!=NULL) body=xmlnode_get_data(body_n); else body=NULL; subject_n=xmlnode_get_tag(tag,"subject"); if (subject_n!=NULL) subject=xmlnode_get_data(subject_n); else subject=NULL; from=xmlnode_get_attrib(tag,"from"); to=xmlnode_get_attrib(tag,"to"); type=xmlnode_get_attrib(tag,"type"); if (!acl_is_allowed(from,tag)){ if (type && !strcmp(type,"error")){ debug("Ignoring forbidden message error"); return -1; } if (!from) return -1; message_send_error(stream,to,from,NULL,405,_("Not allowed")); return -1; } if (from) u=user_get_by_jid(from); else u=NULL; user_load_locale(u); if (!type || !strcmp(type,"normal")) chat=0; else if (!strcmp(type,"chat")) chat=1; else if (!strcmp(type,"error")){ g_warning(N_("Error message received: %s"),xmlnode2str(tag)); return 0; } else{ g_warning(N_("Unsupported message type")); message_send_error(stream,to,from,body,500,_("Internal Server Error")); return -1; } if (!to || !jid_is_my(to)){ g_warning(N_("Bad 'to' in: %s"),xmlnode2str(tag)); message_send_error(stream,to,from,body,400,_("Bad Request")); return -1; } if (!jid_has_uin(to)){ return message_to_me(stream,from,to,body,tag); } if (!from){ g_warning(N_("Anonymous message? %s"),xmlnode2str(tag)); message_send_error(stream,to,from,body,400,_("Bad Request")); return -1; } s=session_get_by_jid(from,NULL,0); if (!s || !s->connected){ g_warning(N_("%s not logged in. While processing %s"),from,xmlnode2str(tag)); message_send_error(stream,to,from,body,407,_("Not logged in")); return -1; } if (subject) body=g_strdup_printf("Subject: %s\n%s",subject,body); session_send_message(s,jid_get_uin(to),chat,string_to_gg(body)); if (subject) g_free(body); return 0; }
int jabber_presence(struct stream_s *stream,xmlnode tag){ char *type; char *from; char *to; xmlnode prio_n; xmlnode show_n; xmlnode status_n; char *show,*status; int priority; char *tmp; User *u; type=xmlnode_get_attrib(tag,"type"); from=xmlnode_get_attrib(tag,"from"); to=xmlnode_get_attrib(tag,"to"); if (from) u=user_get_by_jid(from); else u=NULL; user_load_locale(u); if (!acl_is_allowed(from,tag)){ if (type && !strcmp(type,"error")){ debug("Ignoring forbidden presence error"); return -1; } if (!from) return -1; presence_send_error(stream,to,from,405,_("Not allowed")); return -1; } show_n=xmlnode_get_tag(tag,"show"); if (show_n) show=xmlnode_get_data(show_n); else show=NULL; status_n=xmlnode_get_tag(tag,"status"); if (status_n) status=xmlnode_get_data(status_n); else status=NULL; prio_n=xmlnode_get_tag(tag,"priority"); if (prio_n){ tmp=xmlnode_get_data(prio_n); if (tmp) priority=atoi(tmp); else priority=-1; } else priority=-1; if (!type) type="available"; if (!from || !to){ if (strcmp(type,"error")) presence_send_error(stream,to,from,406,_("Not Acceptable")); g_warning(N_("Bad <presence/>: %s"),xmlnode2str(tag)); return -1; } if (!jid_is_my(to)){ if (strcmp(type,"error")) presence_send_error(stream,to,from,406,_("Not Acceptable")); g_warning(N_("Wrong 'to' in %s"),xmlnode2str(tag)); return -1; } if (!strcmp(type,"available")){ if (jid_has_uin(to)) return presence_direct_available(stream,from,to); else return presence(stream,from,to,1,show,status,priority); } else if (!strcmp(type,"unavailable")){ if (jid_has_uin(to)) return presence_direct_unavailable(stream,from,to); else return presence(stream,from,to,0,show,status,priority); } if (!strcmp(type,"invisible")){ if (jid_has_uin(to)) return presence_direct_unavailable(stream,from,to); else return presence(stream,from,to,-1,show,status,priority); } else if (!strcmp(type,"subscribe")) return presence_subscribe(stream,from,to); else if (!strcmp(type,"unsubscribe")) return presence_unsubscribe(stream,from,to); else if (!strcmp(type,"subscribed")) return presence_subscribed(stream,from,to); else if (!strcmp(type,"unsubscribed")) return presence_unsubscribed(stream,from,to); else if (!strcmp(type,"probe")) return presence_probe(stream,from,to); else if (!strcmp(type,"error")){ g_warning(N_("Error presence received: %s"),xmlnode2str(tag)); return 0; } g_warning(N_("Unsupported type in %s"),xmlnode2str(tag)); presence_send_error(stream,to,from,501,_("Not Implemented")); return -1; }
int session_io_handler(Session *s){ struct gg_event *event; char *jid,*str; int chat; GIOCondition condition=s->g_pollfd.revents; time_t timestamp; gboolean state; user_load_locale(s->user); debug(L_("Checking error conditions...")); if (condition&(G_IO_ERR|G_IO_NVAL)){ if (condition&G_IO_ERR) g_warning(N_("Error on connection for %s, GGid: %i"),s->jid,s->ggs->uin); if (condition&G_IO_HUP){ g_warning(N_("Hangup on connection for %s, GGid: %i"),s->jid,s->ggs->uin); return session_error(s); } if (condition&G_IO_NVAL) g_warning(N_("Invalid channel on connection for %s"),s->jid); session_broken(s); return FALSE; } debug(L_("watching fd (gg_debug_level=%i)..."),gg_debug_level); event=gg_watch_fd(s->ggs); if (!event){ g_warning(N_("Connection broken. Session of %s, GGid: %i"),s->jid,s->ggs->uin); return session_error(s); } switch(event->type){ case GG_EVENT_DISCONNECT: g_warning(N_("Server closed connection of %s, GGid: %i"),s->jid,s->ggs->uin); session_error(s); gg_event_free(event); return FALSE; case GG_EVENT_CONN_FAILED: g_message(N_("Login failed (%d:%s) for %s, GGid: %i"), event->event.failure, (event->event.failure>GG_FAILURE_NUM_REASONS||event->event.failure<1)?"-UNKNOWN-":gg_failure_reason[event->event.failure-1], s->jid, s->ggs->uin); if (s->req_id) jabber_iq_send_error(s->s,s->jid,NULL,s->req_id,401,_("Unauthorized")); else { str=g_strdup(from_utf8(gg_failure_reason_txt[event->event.failure-1])); presence_send(s->s,NULL,s->user->jid,0,NULL,str,0); g_free(str); } state = FALSE; if (!s->req_id) switch(event->event.failure){ case GG_FAILURE_RESOLVING: case GG_FAILURE_CONNECTING: case GG_FAILURE_INVALID: case GG_FAILURE_READING: case GG_FAILURE_WRITING: case GG_FAILURE_TLS: state = session_try_next(s); default: break; } if (state) { s->connected=0; session_schedule_reconnect(s); } else session_remove(s); gg_event_free(event); return FALSE; case GG_EVENT_CONN_SUCCESS: g_message(L_("Login succeed for %s, GGid: %i"),s->jid,s->ggs->uin); if (s->req_id) jabber_iq_send_result(s->s,s->jid,NULL,s->req_id,NULL); if (s->req_id){ g_free(s->req_id); s->req_id=NULL; } if (s->query){ xmlnode_free(s->query); s->query=NULL; } if (!s->user->confirmed){ s->user->confirmed=1; user_save(s->user); } s->connected=1; session_send_status(s); session_send_notify(s); presence_send(s->s,NULL,s->user->jid,s->user->invisible?-1:1,NULL,s->gg_status_descr,0); if (s->timeout_func) g_source_remove(s->timeout_func); s->timeout_func=NULL; if (s->ping_timeout_func) g_source_remove(s->ping_timeout_func); s->ping_timeout_func=g_timeout_add(ping_interval*1000,session_ping,s); if (s->pubdir_change){ add_request(RT_CHANGE,s->jid,NULL,s->req_id, NULL,s->pubdir_change,s->s); gg_pubdir50_free(s->pubdir_change); s->pubdir_change=NULL; } if (s->get_roster){ gg_userlist_request(s->ggs, GG_USERLIST_GET, NULL); } break; case GG_EVENT_NOTIFY: session_event_notify(s,event); break; case GG_EVENT_NOTIFY_DESCR: session_event_notify_descr(s,event); break; case GG_EVENT_NOTIFY60: session_event_notify60(s,event); break; case GG_EVENT_STATUS: session_event_status(s, event->event.status.status, event->event.status.uin, event->event.status.descr, 0,0,0,0); break; case GG_EVENT_STATUS60: session_event_status(s, event->event.status60.status, event->event.status60.uin, event->event.status60.descr, 1, event->event.status60.remote_ip, event->event.status60.remote_port, event->event.status60.version); break; case GG_EVENT_MSG: if (event->event.msg.recipients_count>1){ debug(L_("Dropped conference message: sender: %i class: %i time: %lu"), event->event.msg.sender, event->event.msg.msgclass, (unsigned long)event->event.msg.time); break; } gg_messages_in++; debug(L_("Message: sender: %i class: %i time: %lu"), event->event.msg.sender, event->event.msg.msgclass, (unsigned long)event->event.msg.time); if (event->event.msg.sender==0){ if (!user_sys_msg_received(s->user,event->event.msg.msgclass)) break; if (ignore_system_messages == ISM_IGNORE_ALL) break; if (ignore_system_messages == ISM_IGNORE_HTML && strstr((const char *)event->event.msg.message, "<HTML>")) break; timestamp=event->event.msg.time; str=g_strdup_printf(_("GG System message #%i"), event->event.msg.msgclass); message_send_subject(s->s,jid, s->user->jid, str, string_from_gg((const char *)event->event.msg.message), timestamp); g_free(str); break; } else{ Contact *c=user_get_contact(s->user, event->event.msg.sender,0); if ((!c && s->user->ignore_unknown) || (c && c->ignored)) { debug(L_("Ignoring the message.")); break; } jid=jid_build_full(event->event.msg.sender); if ((event->event.msg.msgclass&GG_CLASS_CHAT)!=0) chat=1; else chat=0; } if ((event->event.msg.msgclass&GG_CLASS_QUEUED)!=0){ timestamp=event->event.msg.time; } else timestamp=0; if(event->event.msg.formats_length>0) message_send_rich(s->s,jid,s->user->jid,chat, (char *)event->event.msg.message,timestamp, event->event.msg.formats_length,(void *)event->event.msg.formats); else message_send(s->s,jid,s->user->jid,chat, string_from_gg((const char *)event->event.msg.message),timestamp); g_free(jid); break; case GG_EVENT_PONG: s->waiting_for_pong=FALSE; if (s->ping_timer){ g_timer_stop(s->ping_timer); debug(L_("Pong! ping time: %fs"), g_timer_elapsed(s->ping_timer,NULL)); } if (s->timeout_func) g_source_remove(s->timeout_func); s->timeout_func=NULL; break; case GG_EVENT_PUBDIR50_SEARCH_REPLY: request_response_search(event); break; case GG_EVENT_PUBDIR50_WRITE: request_response_write(event); break; case GG_EVENT_ACK: debug("GG_EVENT_ACK"); break; case GG_EVENT_NONE: debug("GG_EVENT_NONE"); break; case GG_EVENT_USERLIST: if(event->event.userlist.type==GG_USERLIST_GET_REPLY) get_roster_done(s,event); else g_warning(N_("Wrong gg userlist type: %i"),event->event.userlist.type); break; default: g_warning(N_("Unknown GG event: %i"),event->type); break; } session_setup_g_source(s); gg_event_free(event); debug(L_("io handler done...")); return FALSE; }