Exemplo n.º 1
0
User *user_get_by_jid(const char *jid){
User *u;
char *njid;

	njid=jid_normalized(jid,0);
	if (njid==NULL) return NULL;
	u=(User *)g_hash_table_lookup(users_jid,(gpointer)njid);
	g_free(njid);
	if (u==NULL) u=user_load(jid);
	return u;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
User *user_create(const char *jid,uin_t uin,const char * password){
User *u;
char *p,*njid;

	g_message(L_("Creating user '%s'"),jid);

	njid=jid_normalized(jid,0);
	if (njid==NULL){
		g_warning(L_("Bad JID: '%s'"),jid);
		return NULL;
	}

	u=(User *)g_hash_table_lookup(users_jid,(gpointer)njid);
	if (u){
		g_warning(L_("User '%s' already exists"),jid);
		g_free(njid);
		return NULL;
	}

	if (uin<1){
		g_warning(L_("Bad UIN"));
		g_free(njid);
		return NULL;
	}
	if (!password){
		g_warning(L_("Password not given"));
		g_free(njid);
		return NULL;
	}
	if (!jid){
		g_warning(L_("JID not given"));
		g_free(njid);
		return NULL;
	}

	u=g_new0(User,1);
	u->uin=uin;
	u->jid=g_strdup(jid);
	p=strchr(u->jid,'/');
	if (p) *p=0;
	u->password=g_strdup(password);
	u->confirmed=0;
	u->invisible=0;
	u->friends_only=1;
	g_hash_table_insert(users_jid,(gpointer)njid,(gpointer)u);
	u->refcount=0;
	u->deleted=FALSE;
	return u;
}
Exemplo n.º 4
0
int session_remove(Session *s){
gpointer key,value;
char *njid;

	if (s==NULL) return 1;
	g_assert(sessions_jid!=NULL);
	njid=jid_normalized(s->jid,0);
	g_assert(njid!=NULL);
	if (g_hash_table_lookup_extended(sessions_jid,(gpointer)njid,&key,&value)){
		g_hash_table_remove(sessions_jid,(gpointer)njid);
		g_free(key);
	}
	g_free(njid);
	session_destroy(s);

	return 0;
}
Exemplo n.º 5
0
int user_free(User *u){
gpointer key,value;
char *njid;
	
	g_assert(u->refcount==0);
	g_assert(users_jid!=NULL);

	njid=jid_normalized(u->jid,0);
	g_assert(njid!=NULL);
	if (g_hash_table_lookup_extended(users_jid,(gpointer)njid,&key,&value)){
		g_assert(u==value);
		g_hash_table_remove(users_jid,(gpointer)njid);
		g_free(key);
	}
	else debug(L_("user_remove: user '%s' not found in hash table"),njid);
	g_free(njid);
	return user_destroy(u);
}
Exemplo n.º 6
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);
}
Exemplo n.º 7
0
Session * session_create(User *user,const char *jid,const char *req_id,
		const xmlnode query,struct stream_s *stream,int delay_login){
Session *s;
char *njid;

	g_message(L_("Creating session for '%s'"),jid);
	njid=jid_normalized(jid,0);
	if (njid==NULL){
		g_message(L_("Bad JID: '%s'"),jid);
		return NULL;
	}

	g_assert(user!=NULL);

	if (user->deleted){
		g_message(L_("User deleted: '%s'"),user->jid);
		return NULL;
	}
	
	s=g_new0(Session,1);
	s->user=user;
	user_ref(user);
	s->gg_status=-1;
	s->jid=g_strdup(jid);
	if (req_id) s->req_id=g_strdup(req_id);
	s->query=xmlnode_dup(query);
	s->current_server=g_list_first(gg_servers);
	s->g_pollfd.fd=-1;

	if (!delay_login && session_try_login(s)){
		session_destroy(s);
		return NULL;
	}

	s->s=stream;

	g_assert(sessions_jid!=NULL);
	g_hash_table_insert(sessions_jid,(gpointer)njid,(gpointer)s);
	return s;
}
Exemplo n.º 8
0
void session_print(Session *s,int indent){
char *space,*space1;
GList *it;
Resource *r,*cr;
char *njid;

	space=g_strnfill(indent*2,' ');
	space1=g_strnfill((indent+1)*2,' ');
	njid=jid_normalized(s->jid,0);
	g_message(L_("%sSession: %p"),space,s);
	g_message("%sJID: %s",space,s->jid);
	g_message(L_("%sUser:"******"%sResources:"),space);
	cr=session_get_cur_resource(s);
	for(it=g_list_first(s->resources);it;it=g_list_next(it)){
		r=(Resource *)it->data;
		g_message(L_("%sResource: %p%s"),space1,r,(r==cr)?N_(" (current)"):"");
		if (njid && r->name) g_message("%sJID: %s/%s",space1,njid,r->name);
		else g_message("%sJID: %s",space1,s->jid);
		g_message(L_("%sPriority: %i"),space1,r->priority);
		g_message(L_("%sAvailable: %i"),space1,r->available);
		if (r->show)
			g_message(L_("%sShow: %s"),space1,r->show);
		if (r->status)
			g_message(L_("%sStatus: %s"),space1,r->status);
	}
	g_message(L_("%sGG session: %p"),space,s->ggs);
	g_message(L_("%sGSource: %p"),space,s->g_source);
	g_message(L_("%sStream: %p"),space,s->s);
	g_message(L_("%sConnected: %i"),space,s->connected);
	g_message(L_("%sRequest id: %s"),space,s->req_id?s->req_id:"(null)");
	g_message(L_("%sRequest query: %s"),space,s->query?xmlnode2str(s->query):"(null)");
	g_message(L_("%sWaiting for ping: %i"),space,(int)s->waiting_for_pong);
	g_free(njid);
	g_free(space1);
	g_free(space);
}
Exemplo n.º 9
0
int user_delete(User *u){
int r;
char *njid;

	g_assert(u!=NULL);

	njid=jid_normalized(u->jid,0);
	g_assert(njid!=NULL);

	r=unlink(njid);
	if (r && errno!=ENOENT){
		g_warning(L_("Couldn't unlink '%s': %s"),njid,g_strerror(errno));
		r=-1;
	}
	else r=0;

	g_free(njid);

	u->deleted=TRUE;

	users_gc();

	return r;
}
Exemplo n.º 10
0
User *user_load(const char *jid){
char *fn,*njid;
xmlnode xml,tag,t;
char *uin,*ujid,*name,*password,*email,*locale;
char *status;
int last_sys_msg=0,invisible=0,friends_only=0,ignore_unknown=0;
unsigned int file_format_version=0;
SubscriptionType subscribe;
User *u;
GList *contacts;
char *p;
char *data;

	uin=ujid=name=password=email=NULL;
	debug(L_("Loading user '%s'"),jid);
	fn=jid_normalized(jid,0);
	if (fn==NULL){
		g_warning(L_("Bad JID: %s"),jid);
		return NULL;
	}
	errno=0;
	xml=xmlnode_file(fn);
	if (xml==NULL){
		debug(L_("Couldn't read or parse '%s': %s"),fn,errno?g_strerror(errno):N_("XML parse error"));
		g_free(fn);
		return NULL;
	}
	g_free(fn);
	tag=xmlnode_get_tag(xml,"version");
	if (tag!=NULL) {
		p=xmlnode_get_attrib(tag,"file_format");
		if (p!=NULL) file_format_version=(unsigned int)strtol(p,NULL,16);
	}
	tag=xmlnode_get_tag(xml,"jid");
	if (tag!=NULL) {
		ujid=xmlnode_get_data(tag);
		subscribe=get_subscribe(tag, file_format_version);
	}
	if (ujid==NULL){
		g_warning(L_("Couldn't find JID in %s's file"),jid);
		return NULL;
	}
	tag=xmlnode_get_tag(xml,"uin");
	if (tag!=NULL) uin=xmlnode_get_data(tag);
	if (uin==NULL){
		g_warning(L_("Couldn't find UIN in %s's file"),jid);
		return NULL;
	}
	tag=xmlnode_get_tag(xml,"password");
	if (tag!=NULL) password=xmlnode_get_data(tag);
	if (password==NULL){
		g_warning(L_("Couldn't find password in %s's file"),jid);
		return NULL;
	}
	tag=xmlnode_get_tag(xml,"email");
	if (tag!=NULL) email=xmlnode_get_data(tag);
	tag=xmlnode_get_tag(xml,"name");
	if (tag!=NULL) name=xmlnode_get_data(tag);
	tag=xmlnode_get_tag(xml,"last_sys_msg");
	if (tag!=NULL){
		data=xmlnode_get_data(tag);
		if (data!=NULL)
			last_sys_msg=atoi(data);
	}
	tag=xmlnode_get_tag(xml,"friendsonly");
	if (tag!=NULL) friends_only=1;
	tag=xmlnode_get_tag(xml,"invisible");
	if (tag!=NULL) invisible=1;
	tag=xmlnode_get_tag(xml,"ignore_unknown");
	if (tag!=NULL) ignore_unknown=1;
	tag=xmlnode_get_tag(xml,"locale");
	if (tag!=NULL) locale=xmlnode_get_data(tag);
	else locale=NULL;
	tag=xmlnode_get_tag(xml,"status");
	if (tag!=NULL) {
		status=xmlnode_get_data(tag);
		if (status==NULL) status="";
	}
	else status=NULL;
	tag=xmlnode_get_tag(xml,"userlist");
	contacts=NULL;
	if (tag!=NULL){
		Contact *c;

		for(t=xmlnode_get_firstchild(tag);t;t=xmlnode_get_nextsibling(t)){
			char *node_name;
			node_name=xmlnode_get_name(t);
			if (!node_name) continue;
			if (!strcmp(node_name,"uin")){
				char *d;
				int uin;

				d=xmlnode_get_data(t);
				if (d==NULL) continue;
				uin=atoi(d);
				if (uin<=0) continue;

				c=g_new0(Contact,1);
				c->status=-1;
				c->uin=uin;
				contacts=g_list_append(contacts,c);
				continue;
			}
			if (!strcmp(node_name,"contact")){
				char *d;
				int uin;

				d=xmlnode_get_attrib(t,"uin");
				if (d==NULL) continue;
				
				uin=atoi(d);
				if (uin<=0) continue;

				c=g_new0(Contact,1);
				c->status=-1;
				c->uin=uin;
				
				d=xmlnode_get_attrib(t,"ignored");
				if (d!=NULL && d[0]!='\000') c->ignored=1;
				else c->ignored=0;
				d=xmlnode_get_attrib(t,"blocked");
				if (d!=NULL && d[0]!='\000') c->blocked=1;
				else c->blocked=0;
				c->subscribe=get_subscribe(t, file_format_version);
				contacts=g_list_append(contacts,c);
			}
		}
	}
	u=g_new0(User,1);
	u->uin=atoi(uin);
	u->jid=g_strdup(jid);
	p=strchr(u->jid,'/');
	if (p) *p=0;
	u->password=g_strdup(password);
	u->last_sys_msg=last_sys_msg;
	u->friends_only=friends_only;
	u->invisible=invisible;
	u->ignore_unknown=ignore_unknown;
	u->locale=g_strdup(locale);
	u->status=g_strdup(from_utf8(status));
	u->contacts=contacts;
	xmlnode_free(xml);
	g_assert(users_jid!=NULL);
	njid=jid_normalized(u->jid,0);
	g_assert(njid!=NULL);
	g_hash_table_insert(users_jid,(gpointer)njid,(gpointer)u);
	u->confirmed=1;
	u->subscribe=subscribe;
	return u;
}
Exemplo n.º 11
0
int user_save(User *u){
FILE *f;
char *fn;
char *str;
char *njid;
int r;
xmlnode xml,tag,ctag,userlist;

	g_assert(u!=NULL);
	str=strchr(u->jid,'/');
	g_assert(str==NULL);

	if (!u->confirmed){
		g_message(L_("Not saving user '%s' - account not confirmed."),u->jid);
		return -1;
	}

	g_debug(L_("Saving user '%s'"),u->jid);
	njid=jid_normalized(u->jid,0);
	g_assert(njid!=NULL);
	fn=g_strdup_printf("%s.new",njid);
	f=fopen(fn,"w");
	if (!f){
		g_warning(L_("Couldn't open '%s': %s"),fn,g_strerror(errno));
		g_free(fn);
		g_free(njid);
		return -1;
	}
	xml=xmlnode_new_tag("user");
	tag=xmlnode_insert_tag(xml,"version");
	str=g_strdup_printf("%08x",USER_FILE_FORMAT_VERSION);
	xmlnode_put_attrib(tag,"file_format",str);
	g_free(str);
	tag=xmlnode_insert_tag(xml,"jid");
	xmlnode_insert_cdata(tag,u->jid,-1);
	set_subscribe(tag, u->subscribe);
	tag=xmlnode_insert_tag(xml,"uin");
	str=g_strdup_printf("%lu",(unsigned long)u->uin);
	xmlnode_insert_cdata(tag,str,-1);
	g_free(str);
	tag=xmlnode_insert_tag(xml,"password");
	xmlnode_insert_cdata(tag,u->password,-1);

	if (u->last_sys_msg>0){
		tag=xmlnode_insert_tag(xml,"last_sys_msg");
		str=g_strdup_printf("%i",u->last_sys_msg);
		xmlnode_insert_cdata(tag,str,-1);
		g_free(str);
	}

	if (u->invisible) tag=xmlnode_insert_tag(xml,"invisible");
	if (u->friends_only) tag=xmlnode_insert_tag(xml,"friendsonly");
	if (u->ignore_unknown) tag=xmlnode_insert_tag(xml,"ignore_unknown");
	if (u->locale){
		tag=xmlnode_insert_tag(xml,"locale");
		xmlnode_insert_cdata(tag,u->locale,-1);
	}
	if (u->status){
		tag=xmlnode_insert_tag(xml,"status");
		xmlnode_insert_cdata(tag,to_utf8(u->status),-1);
	}

	if (u->contacts){
		GList *it;
		Contact *c;

		userlist=xmlnode_insert_tag(xml,"userlist");
		for(it=g_list_first(u->contacts);it;it=it->next){
			c=(Contact *)it->data;
			ctag=xmlnode_insert_tag(userlist,"contact");
			str=g_strdup_printf("%lu",(unsigned long)c->uin);
			xmlnode_put_attrib(ctag,"uin",str);
			if (c->ignored) xmlnode_put_attrib(ctag,"ignored","ignored");
			if (c->blocked) xmlnode_put_attrib(ctag,"blocked","blocked");
			set_subscribe(ctag, c->subscribe);
			g_free(str);
		}
	}

	str=xmlnode2str(xml);
	r=fputs(str,f);
	if (r<0){
		g_warning(L_("Couldn't save '%s': %s"),u->jid,g_strerror(errno));
		fclose(f);
		unlink(fn);
		xmlnode_free(xml);
		g_free(fn);
		g_free(njid);
		return -1;
	}
	fclose(f);
	r=unlink(njid);
	if (r && errno!=ENOENT){
		g_warning(L_("Couldn't unlink '%s': %s"),njid,g_strerror(errno));
		xmlnode_free(xml);
		g_free(fn);
		g_free(njid);
		return -1;
	}

	r=rename(fn,njid);
	if (r){
		g_warning(L_("Couldn't rename '%s' to '%s': %s"),fn,u->jid,g_strerror(errno));
		xmlnode_free(xml);
		g_free(fn);
		g_free(njid);
		return -1;
	}

	xmlnode_free(xml);
	g_free(fn);
	g_free(njid);
	return 0;
}