void message_invisible(struct stream_s *stream,const char *from, const char *to, const char *args, xmlnode msg){ Session *session; User *user; Resource *r; gboolean on; session=session_get_by_jid(from,stream,0); if (session!=NULL) user=session->user; else user=user_get_by_jid(from); if (args && g_strcasecmp(args,"on")==0) on=TRUE; else if (args && g_strcasecmp(args,"off")==0) on=FALSE; else on=!user->invisible; if (user->invisible==on){ message_send(stream,to,from,1,_("No change."),0); return; } user->invisible=on; if (on) message_send(stream,to,from,1,_("invisible: on"),0); else message_send(stream,to,from,1,_("invisible: off"),0); if (session!=NULL) session_send_status(session); r=session_get_cur_resource(session); if ( r ) presence_send(stream,NULL,user->jid,user->invisible?-1:r->available,r->show,session->gg_status_descr,0); user_save(user); }
void message_unignore(struct stream_s *stream,const char *from, const char *to, const char *args, xmlnode msg){ Session *session; User *user; uin_t uin; Contact *c; gchar *m; session=session_get_by_jid(from,stream,0); if (session!=NULL) user=session->user; else user=user_get_by_jid(from); if (args && *args) uin=atoi(args); else uin=0; if (uin<=0) { message_ignore(stream,from,to,NULL,msg); return; } c=user_get_contact(user,uin,FALSE); if (c) { c->ignored=FALSE; user_check_contact(user,c); if (session) session_update_contact(session,c); } m=g_strdup_printf(_("\nMessages from GG number %li will NOT be ignored."),(long)uin); message_send(stream,to,from,1,m,0); g_free(m); user_save(user); }
void message_ignore_unknown(struct stream_s *stream,const char *from, const char *to, const char *args, xmlnode msg){ Session *session; User *user; gboolean on; session=session_get_by_jid(from,stream,0); if (session!=NULL) user=session->user; else user=user_get_by_jid(from); if (args && g_strcasecmp(args,"on")==0) on=TRUE; else if (args && g_strcasecmp(args,"off")==0) on=FALSE; else on=!user->ignore_unknown; if (user->ignore_unknown==on){ message_send(stream,to,from,1,_("No change."),0); return; } user->ignore_unknown=on; if (on) message_send(stream,to,from,1,_("ignore unknown: on"),0); else message_send(stream,to,from,1,_("ignore unknown: off"),0); if (session!=NULL) session_send_status(session); user_save(user); }
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_subscribe(struct stream_s *stream,const char *from,const char *to){ User *u; Session *s; char *bare; uin_t uin; Contact *c; u=user_get_by_jid(from); if (jid_is_me(to)){ debug(L_("Presence subscribe request sent to me")); if (!u) { presence_send_unsubscribed(stream,to,from); return 0; } presence_send_subscribed(stream,to,from); if (u->subscribe==SUB_UNDEFINED || u->subscribe==SUB_NONE) u->subscribe=SUB_TO; else if (u->subscribe==SUB_FROM) u->subscribe=SUB_BOTH; if (u->subscribe!=SUB_FROM && u->subscribe!=SUB_BOTH){ presence_send_subscribe(stream,to,from); } user_save(u); return 0; } if (!u){ g_warning(N_("Presence subscription from unknown user (%s)"),from); presence_send_unsubscribed(stream,to,from); return -1; } if (!jid_has_uin(to) || !jid_is_my(to)){ g_warning(N_("Bad 'to': %s"),to); return -1; } s=session_get_by_jid(from,stream,0); debug(L_("Subscribing %s to %s..."),from,to); uin=jid_get_uin(to); c=user_get_contact(u,uin,TRUE); if (!c) { presence_send_error(stream,to,from,500,_("Subscription failed")); return -1; } if (c->subscribe==SUB_UNDEFINED || c->subscribe==SUB_NONE) c->subscribe=SUB_TO; else if (c->subscribe==SUB_FROM) c->subscribe=SUB_BOTH; user_save(u); if (s) session_update_contact(s,c); debug(L_("Subscribed.")); presence_send_subscribed(stream,to,from); bare=jid_normalized(from,FALSE); if (c->subscribe!=SUB_FROM && c->subscribe!=SUB_BOTH) { presence_send_subscribe(stream,to,bare); } g_free(bare); return 0; }
int presence_unsubscribe(struct stream_s *stream,const char *from,const char *to){ User *u; Session *s; Contact *c; uin_t uin; u=user_get_by_jid(from); if (!u){ g_warning(N_("Presence subscription from unknown user (%s)"),from); presence_send_unsubscribed(stream,to,from); return -1; } if (jid_is_me(to)){ debug(L_("Presence unsubscribe request sent to me")); if (u->subscribe==SUB_TO || u->subscribe==SUB_UNDEFINED) u->subscribe=SUB_NONE; else if (u->subscribe==SUB_BOTH) u->subscribe=SUB_FROM; user_save(u); return 0; } if (!jid_has_uin(to) || !jid_is_my(to)){ g_warning(N_("Bad 'to': %s"),to); return -1; } s=session_get_by_jid(from,stream,0); debug(L_("Unsubscribing %s from %s..."),from,to); uin=jid_get_uin(to); c=user_get_contact(u,uin,FALSE); if (!c) { presence_send_unsubscribed(stream,to,from); return -1; } if (c->subscribe==SUB_TO) c->subscribe=SUB_NONE; else if (c->subscribe==SUB_BOTH) c->subscribe=SUB_FROM; user_save(u); if (s) session_update_contact(s,c); debug(L_("Unsubscribed.")); presence_send_unsubscribed(stream,to,from); if (!GG_S_NA(c->status) && c->status!=-1){ char *ujid; ujid=jid_build_full(uin); presence_send(stream,ujid,u->jid,0,NULL,"Unsubscribed",0); g_free(ujid); } return 0; }
int presence(struct stream_s *stream,const char *from,const char *to, int available,const char *show,const char *status,int priority){ Session *s; const char *resource; User *u; s=session_get_by_jid(from,available?stream:NULL,1); if (!s){ debug(L_("presence: No such session: %s"),from); presence_send_error(stream,NULL,from,407,_("Not logged in")); u=user_get_by_jid(from); if (u==NULL) presence_send_unsubscribed(stream,to,from); return -1; } resource=jid_get_resource(from); session_set_status(s,resource,available,show,string_to_gg(status),priority); return 0; }
Session *session_get_by_jid(const char *jid,Stream *stream,int delay_login){ Session *s; User *u; char *njid; GList *it; g_assert(sessions_jid!=NULL); debug(L_("Looking up session for '%s'"),jid); njid=jid_normalized(jid,0); if (njid==NULL){ g_message(L_("Bad JID: '%s'"),jid); return NULL; } debug(L_("Using '%s' as key"),njid); s=(Session *)g_hash_table_lookup(sessions_jid,(gpointer)njid); g_free(njid); if (s) return s; debug(L_("Session not found")); if (!stream) return NULL; u=user_get_by_jid(jid); if (!u) return NULL; debug(L_("User loaded, processing his subscriptions.")); for(it=g_list_first(u->contacts);it;it=g_list_next(it)){ Contact *c; char *c_jid; c=(Contact *)it->data; if (c->subscribe == SUB_UNDEFINED) { c_jid=jid_build(c->uin); presence_send_subscribe(stream,c_jid,u->jid); g_free(c_jid); } else if (c->subscribe == SUB_FROM || c->subscribe == SUB_BOTH){ c_jid=jid_build(c->uin); presence_send_probe(stream,c_jid,u->jid); g_free(c_jid); } } debug(L_("Creating new session")); return session_create(u,jid,NULL,NULL,stream,delay_login); }
void message_ignore(struct stream_s *stream,const char *from, const char *to, const char *args, xmlnode msg){ Session *session; User *user; uin_t uin; Contact *c; gchar *m; session=session_get_by_jid(from,stream,0); if (session!=NULL) user=session->user; else user=user_get_by_jid(from); if (args && *args) uin=atoi(args); else uin=0; if (uin<=0) { GList *it; m=g_strdup(_("\nMessages from the following GG numbers will be ignored:")); for(it=user->contacts;it;it=it->next){ c=(Contact *)it->data; if (!c->ignored) continue; m=g_strdup_printf(_("%s\n %li"),m,(long)c->uin); } message_send(stream,to,from,1,m,0); g_free(m); return; } c=user_get_contact(user,uin,TRUE); c->ignored=TRUE; if (session) session_update_contact(session,c); m=g_strdup_printf(_("\nMessages from GG number %li will be ignored."),(long)uin); message_send(stream,to,from,1,m,0); g_free(m); user_save(user); }
void message_locale(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); if (args && args[0]){ if (user->locale) g_free(user->locale); user->locale=g_strdup(args); } m=g_strdup_printf(_("Locale set to: %s"),user->locale?user->locale:_("_default_")); message_send(stream,to,from,1,m,0); g_free(m); user_save(user); }
int presence_subscribed(struct stream_s *stream,const char *from,const char *to){ User *u; Session *s; Contact *c; uin_t uin; u=user_get_by_jid(from); if (!u){ g_warning(N_("Presence subscription from unknown user (%s)"),from); presence_send_unsubscribe(stream,to,from); return -1; } if (jid_is_me(to)){ if (u->subscribe==SUB_NONE) u->subscribe=SUB_FROM; else if (u->subscribe==SUB_UNDEFINED || u->subscribe==SUB_TO) u->subscribe=SUB_BOTH; user_save(u); debug(L_("Presence 'subscribed' sent to me")); return 0; } if (!jid_has_uin(to) || !jid_is_my(to)){ g_warning(N_("Bad 'to': %s"),to); return -1; } s=session_get_by_jid(from,stream,0); debug(L_("%s accepted %s's subscription..."),from,to); uin=jid_get_uin(to); c=user_get_contact(u,uin,TRUE); if (!c) { return -1; } if (c->subscribe==SUB_UNDEFINED) c->subscribe=SUB_BOTH; else if (c->subscribe==SUB_NONE) c->subscribe=SUB_FROM; else if (c->subscribe==SUB_TO) c->subscribe=SUB_BOTH; user_save(u); if (s) session_update_contact(s,c); return 0; }
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 presence_probe(struct stream_s *stream,const char *from,const char *to){ Session *s; User *u; Contact *c; uin_t uin; int status; int available; char *show,*stat,*jid; GList *it; GTime timestamp; s=session_get_by_jid(from,NULL,0); if (jid_is_me(to)){ if (s){ if (!s->connected){ presence_send(stream,to,from,0,NULL,"Disconnected",0); } else{ Resource *r=session_get_cur_resource(s); if (r) presence_send(stream,NULL,s->user->jid,s->user->invisible?-1:r->available, r->show,r->status,0); } return 0; } else if (user_get_by_jid(from)) { presence_send(stream, to, from, 0, NULL, "Not logged in", 0); } else { presence_send_unsubscribed(stream, NULL, from); } return 0; } if (!jid_is_my(to)){ presence_send_unsubscribed(stream,to,from); return -1; } if (s) u=s->user; else u=user_get_by_jid(from); if (!u){ presence_send_unsubscribed(stream,to,from); return -1; } uin=jid_get_uin(to); /* create the contact: if we got 'prope' the user has it on his * contact list, do not change that */ c = user_get_contact(u, uin, TRUE); if (!c) { return -1; } c->got_probe=TRUE; if (s) session_update_contact(s,c); status=0; stat=NULL; timestamp=0; for(it=u->contacts;it;it=it->next){ Contact *c=(Contact *)it->data; if (c && c->uin==uin){ status=c->status; timestamp=c->last_update; stat=c->status_desc; } } if (!status){ // user not found on userlist? presence_send_unsubscribed(stream,to,from); return -1; } if (status==-1) return 0; /* Not known yet */ available=status_gg_to_jabber(status,&show,&stat); if (available) jid=jid_build_full(uin); else jid=jid_build(uin); presence_send(stream,jid,u->jid,available,show,stat,timestamp); g_free(jid); return 0; }