void message_status(struct stream_s *stream,const char *from, const char *to, const char *args, xmlnode msg){ Session *session; User *user; char *m; session=session_get_by_jid(from,stream,0); if (session!=NULL) user=session->user; else user=user_get_by_jid(from); g_free(user->status); if (args) { if (!g_strcasecmp(args,"off")) user->status=NULL; else user->status=g_strndup(string_to_gg(args),GG_STATUS_DESCR_MAXSIZE); } else user->status=NULL; m=g_strdup_printf(_("status: %s%s%s"), (user->status?"`":""), (user->status?string_from_gg(user->status):_("not set")), (user->status?"'":"")); message_send(stream,to,from,1,m,0); g_free(m); if (session!=NULL) session_send_status(session); user_save(user); }
int presence_send(struct stream_s *stream,const char *from, const char *to,int available,const char *show, const char *status,GTime timestamp){ xmlnode pres; xmlnode n; pres=xmlnode_new_tag("presence"); if (from!=NULL) xmlnode_put_attrib(pres,"from",from); else{ char *jid; jid=jid_my_registered(); xmlnode_put_attrib(pres,"from",jid); g_free(jid); } xmlnode_put_attrib(pres,"to",to); if (available==-1) xmlnode_put_attrib(pres,"type","invisible"); else if (!available) xmlnode_put_attrib(pres,"type","unavailable"); if (show){ n=xmlnode_insert_tag(pres,"show"); xmlnode_insert_cdata(n,show,-1); } if (status){ n=xmlnode_insert_tag(pres,"status"); xmlnode_insert_cdata(n,string_from_gg(status),-1); } if (timestamp){ struct tm *tm; time_t ttime = timestamp; char buf[101]; n=xmlnode_insert_tag(pres,"x"); xmlnode_put_attrib(n,"xmlns","jabber:x:delay"); tm=gmtime(&ttime); strftime(buf,100,"%Y%m%dT%H:%M:%S",tm); xmlnode_put_attrib(n,"stamp",buf); xmlnode_insert_cdata(n,"Presence update time",-1); } stream_write(stream,pres); xmlnode_free(pres); return 0; }
int message_to_me(struct stream_s *stream,const char *from, const char *to,const char *body,xmlnode tag){ int i,ignored; const char *ce; char *args,*p; User *user; Session *sess; char *msg, *t; GList *it; sess=session_get_by_jid(from,stream,1); if (sess) user=sess->user; else user=NULL; if (user==NULL){ message_send(stream,to,from,1,_("I don't know you. Register first."),0); return -1; } if (body!=NULL){ for(i=0;msg_commands[i].command;i++){ if (strncmp(body,msg_commands[i].command, strlen(msg_commands[i].command))==0) ce=body+strlen(msg_commands[i].command); else if (strncmp(body,msg_commands[i].abr, strlen(msg_commands[i].abr))==0) ce=body+strlen(msg_commands[i].abr); else continue; if (ce[0]!='\000' && !isspace(ce[0])) continue; p=g_strdup(ce); args=g_strstrip(p); msg_commands[i].handler(stream,from,to,args,tag); g_free(p); return 0; } } msg=g_strdup(_("\nAvailable commands and abbreviations:")); for(i=0;msg_commands[i].command;i++){ t=g_strdup_printf("%s\n %-14s %-4s - %s%s",msg, msg_commands[i].command, msg_commands[i].abr, _(msg_commands[i].description), msg_commands[i].experimental?_(" EXPERIMENTAL!"):""); g_free(msg); msg=t; } t=g_strdup_printf(_("%s\n\nCurrent settings:"),msg); g_free(msg); msg=t; t=g_strdup_printf(_("%s\n status: %s%s%s"),msg, (user->status?"`":""), (user->status?string_from_gg(user->status):_("not set")), (user->status?"'":"")); g_free(msg); msg=t; t=g_strdup_printf(_("%s\n friends only: %s"),msg,user->friends_only?_("on"):_("off")); g_free(msg); msg=t; t=g_strdup_printf(_("%s\n invisible: %s"),msg,user->invisible?_("on"):_("off")); g_free(msg); msg=t; t=g_strdup_printf(_("%s\n ignore unknown: %s"),msg,user->ignore_unknown?_("on"):_("off")); g_free(msg); msg=t; t=g_strdup_printf(_("%s\n locale: %s"),msg,user->locale?user->locale:_("_default_")); g_free(msg); msg=t; ignored=0; for(it=user->contacts;it;it=it->next){ Contact * c=(Contact *)it->data; if (c->ignored) ignored++; } t=g_strdup_printf(_("%s\n number of ignored users: %i"),msg,ignored); g_free(msg); msg=t; t=g_strdup_printf(_("%s\n\nRegistered as: %u"),msg,user->uin); g_free(msg); msg=t; if (sess->ggs){ char *t1=session_get_info_string(sess); t=g_strdup_printf("%s\n %s",msg,t1); g_free(t1); g_free(msg); msg=t; } message_send(stream,to,from,1,msg,0); g_free(msg); return 0; }
void get_roster_done(Session *s,struct gg_event *e){ char **results; char *body=NULL; char *jid; xmlnode roster; xmlnode msg; xmlnode n; int i; if(!e->event.userlist.reply){ message_send(s->s,NULL,s->user->jid,1,_("Roster empty."),0); return; } message_send(s->s,NULL,s->user->jid,0,_("Roster received."),0); msg=xmlnode_new_tag("message"); jid=jid_my_registered(); xmlnode_put_attrib(msg,"from",jid); g_free(jid); xmlnode_put_attrib(msg,"to",s->user->jid); n=xmlnode_insert_tag(msg,"body"); roster=xmlnode_insert_tag(msg,"x"); xmlnode_put_attrib(roster,"xmlns","jabber:x:roster"); body=g_strdup(""); results=g_strsplit(e->event.userlist.reply,"\r\n",0); for(i=0;results[i];i++){ char **cinfo; char *t,*jid; char *name=NULL; int j,uin; xmlnode item,tag; cinfo=g_strsplit(results[i],";",0); for(j=0;cinfo[j];j++); if (j<7){ g_strfreev(cinfo); continue; } uin=atoi(cinfo[6]); item=xmlnode_insert_tag(roster,"item"); t=g_strconcat(body,"\n",NULL); g_free(body); body=t; t=g_strdup_printf("%sUin: %u\n",body,uin); g_free(body); body=t; if (cinfo[2] && cinfo[2][0]){ t=g_strdup_printf("%sNick: %s\n",body,cinfo[2]); g_free(body); body=t; if (name==NULL) name=g_strdup(cinfo[2]); } if (cinfo[0] && cinfo[0][0]){ t=g_strdup_printf("%sFirst name: %s\n",body,cinfo[0]); g_free(body); body=t; if (name==NULL) name=g_strdup(cinfo[0]); } if (cinfo[1] && cinfo[1][0]){ t=g_strdup_printf("%sLast name: %s\n",body,cinfo[1]); g_free(body); body=t; if (name==NULL) name=g_strdup(cinfo[1]); } if (cinfo[3] && cinfo[3][0]){ t=g_strdup_printf("%sDisplay: %s\n",body,cinfo[3]); g_free(body); body=t; if (name) g_free(name); name=g_strdup(cinfo[3]); } if (cinfo[4] && cinfo[4][0]){ t=g_strdup_printf("%sPhone: %s\n",body,cinfo[4]); g_free(body); body=t; } if (cinfo[5] && cinfo[5][0]){ t=g_strdup_printf("%sGroup: %s\n",body,cinfo[5]); g_free(body); body=t; tag=xmlnode_insert_tag(item,"group"); xmlnode_insert_cdata(n,string_from_gg(cinfo[5]),-1); } if (cinfo[7] && cinfo[7][0]){ t=g_strdup_printf("%sE-mail: %s\n",body,cinfo[7]); g_free(body); body=t; } jid=jid_build(uin); xmlnode_put_attrib(item,"jid",jid); g_free(jid); if (name==NULL) name=g_strdup_printf("%u",uin); xmlnode_put_attrib(item,"name",string_from_gg(name)); g_free(name); g_strfreev(cinfo); } g_strfreev(results); xmlnode_insert_cdata(n,string_from_gg(body),-1); stream_write(s->s,msg); xmlnode_free(msg); }
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; }