Changeset 595

Show
Ignore:
Timestamp:
02/23/05 18:25:37 (4 years ago)
Author:
jajcus
Message:

- per-user presence control: working one-way subscriptions, directed presence and privacy-lists
- ignore list
- customizable status messages for available, unavailable and invisible modes

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/message.c

    r551 r595  
    5151void message_locale(struct stream_s *s,const char *from, const char *to, 
    5252                                const char *args, xmlnode msg); 
     53void message_ignore_unknown(struct stream_s *s,const char *from, const char *to, 
     54                                const char *args, xmlnode msg); 
     55void message_ignore(struct stream_s *s,const char *from, const char *to, 
     56                                const char *args, xmlnode msg); 
     57void message_unignore(struct stream_s *s,const char *from, const char *to, 
     58                                const char *args, xmlnode msg); 
     59void message_status(struct stream_s *s,const char *from, const char *to, 
     60                                const char *args, xmlnode msg); 
     61void message_offline_status(struct stream_s *s,const char *from, const char *to, 
     62                                const char *args, xmlnode msg); 
    5363 
    5464MsgCommand msg_commands[]={ 
    5565        {"get roster","gr",N_("Download user list from server"),message_get_roster,0}, 
    5666        {"friends only","fo",N_("\"Only for friends\" mode"),message_friends_only,0}, 
    57         {"invisible","iv",N_("\"Invisible\" mode"),message_invisible,0}, 
     67        {"invisible","iv",N_("\"Invisible\" mode. As an argument" 
     68                " you should pass 'on', 'off' or a status message to be shown" 
     69                " when invisible."),message_invisible,0}, 
    5870        {"locale","loc",N_("Set user locale (language)"),message_locale,0}, 
     71        {"ignore_unknown","iu",N_("Ignore messages from unknown users"),message_ignore_unknown,0}, 
     72        {"ignore","ig",N_("Add a user to, or view the ignore list"),message_ignore,0}, 
     73        {"unignore","ui",N_("Remove a user from, or view the ignore list"),message_unignore,0}, 
     74        {"status","st",N_("Status message to show to GG users. Use 'off' to use Jabber status."),message_status,0}, 
     75        {"offline_status","os",N_("Status message to show to GG users when not available. Use 'off' to use the one set with the command described above."),message_offline_status,0}, 
    5976        {NULL,NULL,NULL,0}, 
    6077}; 
     
    288305Session *session; 
    289306User *user; 
    290 int on; 
     307gboolean on; 
    291308 
    292309        session=session_get_by_jid(from,stream,0); 
     
    295312        else 
    296313                user=user_get_by_jid(from); 
    297         if (args && g_strcasecmp(args,"on")==0) on=1
    298         else if (args && g_strcasecmp(args,"off")==0) on=0
     314        if (args && g_strcasecmp(args,"on")==0) on=TRUE
     315        else if (args && g_strcasecmp(args,"off")==0) on=FALSE
    299316        else on=!user->friends_only; 
    300317 
     
    319336Session *session; 
    320337User *user; 
     338char *m; 
    321339int on; 
    322340 
     
    326344        else 
    327345                user=user_get_by_jid(from); 
    328         if (args && g_strcasecmp(args,"on")==0) on=1; 
    329         else if (args && g_strcasecmp(args,"off")==0) on=0; 
     346 
     347        if (args) { 
     348                if (g_strcasecmp(args,"on")==0) { 
     349                        on=TRUE; 
     350                        g_free(user->invisible_status); 
     351                        user->invisible_status=NULL; 
     352                } 
     353                else if (g_strcasecmp(args,"off")==0) { 
     354                        on=FALSE; 
     355                        g_free(user->invisible_status); 
     356                        user->invisible_status=NULL; 
     357                } 
     358                else { 
     359                        on=TRUE; 
     360                        g_free(user->invisible_status); 
     361                        user->invisible_status=g_strndup(args,70); 
     362                } 
     363        } 
    330364        else on=!user->invisible; 
    331365 
    332         if (user->invisible==on){ 
    333                 message_send(stream,to,from,1,_("No change."),0); 
    334                 return; 
    335         } 
    336366        user->invisible=on; 
    337367 
    338         if (on) 
    339                 message_send(stream,to,from,1,_("invisible: on"),0); 
    340         else 
    341                 message_send(stream,to,from,1,_("invisible: off"),0); 
     368        m=g_strdup_printf(_("invisible: %s status: %s%s%s"), 
     369                        (on?_("on"):_("off")), 
     370                        (user->invisible_status?"`":""), 
     371                        (user->invisible_status?user->invisible_status:_("not set")), 
     372                        (user->invisible_status?"'":"")); 
     373        message_send(stream,to,from,1,m,0); 
     374        g_free(m); 
    342375 
    343376        if (session!=NULL) session_send_status(session); 
    344377 
     378        user_save(user); 
     379} 
     380 
     381void message_status(struct stream_s *stream,const char *from, const char *to, 
     382                                const char *args, xmlnode msg){ 
     383Session *session; 
     384User *user; 
     385char *m; 
     386 
     387        session=session_get_by_jid(from,stream,0); 
     388        if (session!=NULL) 
     389                user=session->user; 
     390        else 
     391                user=user_get_by_jid(from); 
     392 
     393        g_free(user->status); 
     394        if (args) { 
     395                if (!g_strcasecmp(args,"off")) user->status=NULL; 
     396                else user->status=g_strndup(args,70); 
     397        } 
     398        else user->status=NULL; 
     399 
     400        m=g_strdup_printf(_("status: %s%s%s"), 
     401                        (user->status?"`":""), 
     402                        (user->status?user->status:_("not set")), 
     403                        (user->status?"'":"")); 
     404        message_send(stream,to,from,1,m,0); 
     405        g_free(m); 
     406 
     407        if (session!=NULL) session_send_status(session); 
     408        user_save(user); 
     409} 
     410 
     411void message_offline_status(struct stream_s *stream,const char *from, const char *to, 
     412                                const char *args, xmlnode msg){ 
     413Session *session; 
     414User *user; 
     415char *m; 
     416 
     417        session=session_get_by_jid(from,stream,0); 
     418        if (session!=NULL) 
     419                user=session->user; 
     420        else 
     421                user=user_get_by_jid(from); 
     422 
     423        g_free(user->offline_status); 
     424        if (args) { 
     425                if (!g_strcasecmp(args,"off")) user->offline_status=NULL; 
     426                else user->offline_status=g_strndup(args,70); 
     427        } 
     428        else user->offline_status=NULL; 
     429 
     430        m=g_strdup_printf(_("offline status: %s%s%s"), 
     431                        (user->offline_status?"`":""), 
     432                        (user->offline_status?user->offline_status:_("not set")), 
     433                        (user->offline_status?"'":"")); 
     434        message_send(stream,to,from,1,m,0); 
     435        g_free(m); 
     436 
     437        if (session!=NULL) session_send_status(session); 
    345438        user_save(user); 
    346439} 
     
    369462} 
    370463 
     464void message_ignore_unknown(struct stream_s *stream,const char *from, const char *to, 
     465                                const char *args, xmlnode msg){ 
     466Session *session; 
     467User *user; 
     468int on; 
     469 
     470        session=session_get_by_jid(from,stream,0); 
     471        if (session!=NULL) 
     472                user=session->user; 
     473        else 
     474                user=user_get_by_jid(from); 
     475        if (args && g_strcasecmp(args,"on")==0) on=TRUE; 
     476        else if (args && g_strcasecmp(args,"off")==0) on=FALSE; 
     477        else on=!user->ignore_unknown; 
     478 
     479        if (user->ignore_unknown==on){ 
     480                message_send(stream,to,from,1,_("No change."),0); 
     481                return; 
     482        } 
     483        user->ignore_unknown=on; 
     484 
     485        if (on) 
     486                message_send(stream,to,from,1,_("ignore unknown: on"),0); 
     487        else 
     488                message_send(stream,to,from,1,_("ignore unknown: off"),0); 
     489 
     490        if (session!=NULL) session_send_status(session); 
     491 
     492        user_save(user); 
     493} 
     494 
     495 
     496void message_ignore(struct stream_s *stream,const char *from, const char *to, 
     497                                const char *args, xmlnode msg){ 
     498Session *session; 
     499User *user; 
     500uin_t uin; 
     501Contact *c; 
     502gchar *m; 
     503 
     504        session=session_get_by_jid(from,stream,0); 
     505        if (session!=NULL) 
     506                user=session->user; 
     507        else 
     508                user=user_get_by_jid(from); 
     509 
     510        if (args && *args) uin=atoi(args); 
     511        else uin=0; 
     512 
     513        if (uin<=0) { 
     514                GList *it; 
     515                m=g_strdup(_("\nMessages from the following GG numbers will be ignored:")); 
     516                for(it=user->contacts;it;it=it->next){ 
     517                        c=(Contact *)it->data; 
     518                        if (!c->ignored) continue; 
     519                        m=g_strdup_printf(_("%s\n  %li"),m,(long)c->uin); 
     520                } 
     521                message_send(stream,to,from,1,m,0); 
     522                g_free(m); 
     523                return; 
     524        } 
     525 
     526        c=user_get_contact(user,uin,TRUE); 
     527        c->ignored=TRUE; 
     528        if (session) session_update_contact(session,c); 
     529                 
     530        m=g_strdup_printf(_("\nMessages from GG number %li will be ignored."),(long)uin); 
     531        message_send(stream,to,from,1,m,0); 
     532        g_free(m); 
     533 
     534        user_save(user); 
     535} 
     536 
     537void message_unignore(struct stream_s *stream,const char *from, const char *to, 
     538                                const char *args, xmlnode msg){ 
     539Session *session; 
     540User *user; 
     541uin_t uin; 
     542Contact *c; 
     543gchar *m; 
     544 
     545        session=session_get_by_jid(from,stream,0); 
     546        if (session!=NULL) 
     547                user=session->user; 
     548        else 
     549                user=user_get_by_jid(from); 
     550 
     551        if (args && *args) uin=atoi(args); 
     552        else uin=0; 
     553 
     554        if (uin<=0) { 
     555                message_ignore(stream,from,to,NULL,msg); 
     556                return; 
     557        } 
     558 
     559        c=user_get_contact(user,uin,FALSE); 
     560        if (c) { 
     561                c->ignored=FALSE; 
     562                user_check_contact(user,c); 
     563                if (session) session_update_contact(session,c); 
     564        } 
     565                 
     566        m=g_strdup_printf(_("\nMessages from GG number %li will NOT be ignored."),(long)uin); 
     567        message_send(stream,to,from,1,m,0); 
     568        g_free(m); 
     569         
     570        user_save(user); 
     571} 
    371572 
    372573int message_to_me(struct stream_s *stream,const char *from, 
    373574                const char *to,const char *body,xmlnode tag){ 
    374 int i
     575int i,ignored
    375576const char *ce; 
    376577char *args,*p; 
     
    378579Session *sess; 
    379580char *msg; 
     581GList *it; 
    380582 
    381583        sess=session_get_by_jid(from,stream,1); 
     
    417619        msg=g_strdup_printf(_("%s\n  friends only: %s"),msg,user->friends_only?_("on"):_("off")); 
    418620        msg=g_strdup_printf(_("%s\n  invisible: %s"),msg,user->invisible?_("on"):_("off")); 
     621        msg=g_strdup_printf(_("%s\n  ignore unknown: %s"),msg,user->ignore_unknown?_("on"):_("off")); 
    419622        msg=g_strdup_printf(_("%s\n  locale: %s"),msg,user->locale?user->locale:_("_default_")); 
     623        ignored=0; 
     624        for(it=user->contacts;it;it=it->next){ 
     625                Contact * c=(Contact *)it->data; 
     626                if (c->ignored) ignored++; 
     627        } 
     628        msg=g_strdup_printf(_("%s\n  number of ignored users: %i"),msg,ignored); 
    420629        msg=g_strdup_printf(_("%s\n\nRegistered as: %u"),msg,user->uin); 
    421630        if (sess->ggs) msg=g_strdup_printf("%s\n  %s",msg,session_get_info_string(sess)); 
  • trunk/src/presence.c

    r525 r595  
    6666 
    6767 
    68 int presence_send_probe(struct stream_s *stream,const char *to){ 
    69 xmlnode pres; 
    70 char *jid; 
    71  
    72         pres=xmlnode_new_tag("presence"); 
    73         jid=jid_my_registered(); 
    74         xmlnode_put_attrib(pres,"from",jid); 
    75         g_free(jid); 
    76         xmlnode_put_attrib(pres,"to",to); 
    77         xmlnode_put_attrib(pres,"type","probe"); 
    78         stream_write(stream,pres); 
    79         xmlnode_free(pres); 
    80         return 0; 
    81 
    82  
    83 int presence_send_subscribe(struct stream_s *stream,const char *from,const char *to){ 
     68int presence_send_probe(struct stream_s *stream,const char *from,const char *to){ 
    8469xmlnode pres; 
    8570 
     
    9479        } 
    9580        xmlnode_put_attrib(pres,"to",to); 
    96         xmlnode_put_attrib(pres,"type","subscribe"); 
     81        xmlnode_put_attrib(pres,"type","probe"); 
    9782        stream_write(stream,pres); 
    9883        xmlnode_free(pres); 
     
    10085} 
    10186 
    102 int presence_send_subscribed(struct stream_s *stream,const char *from,const char *to){ 
     87int presence_send_subscribe(struct stream_s *stream,const char *from,const char *to){ 
    10388xmlnode pres; 
    10489 
     
    11398        } 
    11499        xmlnode_put_attrib(pres,"to",to); 
    115         xmlnode_put_attrib(pres,"type","subscribed"); 
     100        xmlnode_put_attrib(pres,"type","subscribe"); 
    116101        stream_write(stream,pres); 
    117102        xmlnode_free(pres); 
     
    119104} 
    120105 
    121 int presence_send_unsubscribed(struct stream_s *stream,const char *from,const char *to){ 
     106int presence_send_subscribed(struct stream_s *stream,const char *from,const char *to){ 
    122107xmlnode pres; 
    123108 
     
    132117        } 
    133118        xmlnode_put_attrib(pres,"to",to); 
    134         xmlnode_put_attrib(pres,"type","unsubscribed"); 
     119        xmlnode_put_attrib(pres,"type","subscribed"); 
    135120        stream_write(stream,pres); 
    136121        xmlnode_free(pres); 
     
    138123} 
    139124 
    140 int presence_send_unsubscribe(struct stream_s *stream,const char *from,const char *to){ 
     125int presence_send_unsubscribed(struct stream_s *stream,const char *from,const char *to){ 
    141126xmlnode pres; 
    142127 
     
    151136        } 
    152137        xmlnode_put_attrib(pres,"to",to); 
    153         xmlnode_put_attrib(pres,"type","unsubscribe"); 
     138        xmlnode_put_attrib(pres,"type","unsubscribed"); 
    154139        stream_write(stream,pres); 
    155140        xmlnode_free(pres); 
     
    157142} 
    158143 
    159 int presence_send(struct stream_s *stream,const char *from, 
    160                 const char *to,int available,const char *show, 
    161                 const char *status,GTime timestamp){ 
     144int presence_send_unsubscribe(struct stream_s *stream,const char *from,const char *to){ 
    162145xmlnode pres; 
    163 xmlnode n; 
    164146 
    165147        pres=xmlnode_new_tag("presence"); 
     
    173155        } 
    174156        xmlnode_put_attrib(pres,"to",to); 
     157        xmlnode_put_attrib(pres,"type","unsubscribe"); 
     158        stream_write(stream,pres); 
     159        xmlnode_free(pres); 
     160        return 0; 
     161} 
     162 
     163int presence_send(struct stream_s *stream,const char *from, 
     164                const char *to,int available,const char *show, 
     165                const char *status,GTime timestamp){ 
     166xmlnode pres; 
     167xmlnode n; 
     168 
     169        pres=xmlnode_new_tag("presence"); 
     170        if (from!=NULL) 
     171                xmlnode_put_attrib(pres,"from",from); 
     172        else{ 
     173                char *jid; 
     174                jid=jid_my_registered(); 
     175                xmlnode_put_attrib(pres,"from",jid); 
     176                g_free(jid); 
     177        } 
     178        xmlnode_put_attrib(pres,"to",to); 
    175179 
    176180        /* if (available==-1) xmlnode_put_attrib(pres,"type","invisible"); 
     
    229233User *u; 
    230234Session *s; 
    231 int r; 
     235char *bare; 
     236uin_t uin; 
     237Contact *c; 
    232238 
    233239        u=user_get_by_jid(from); 
     
    248254        } 
    249255        s=session_get_by_jid(from,stream,0); 
    250         if (!s){ 
    251                 g_warning(N_("Couldn't find or open session for '%s'"),from); 
    252                 return -1; 
    253         } 
    254256        debug(L_("Subscribing %s to %s..."),from,to); 
    255         r=session_subscribe(s,jid_get_uin(to)); 
    256         if (!r){ 
    257                 debug(L_("Subscribed.")); 
    258                 presence_send_subscribed(stream,to,from); 
    259         } 
    260         else presence_send_error(stream,to,from,500,_("Subscription failed")); 
    261  
     257        uin=jid_get_uin(to); 
     258        c=user_get_contact(u,uin,TRUE); 
     259        if (!c) { 
     260                presence_send_error(stream,to,from,500,_("Subscription failed")); 
     261                return -1; 
     262        } 
     263        if (c->subscribe==SUB_UNDEFINED || c->subscribe==SUB_NONE) c->subscribe=SUB_TO; 
     264        else if (c->subscribe==SUB_FROM) c->subscribe=SUB_BOTH; 
     265        user_save(u); 
     266 
     267        if (s) session_update_contact(s,c);      
     268        debug(L_("Subscribed.")); 
     269        presence_send_subscribed(stream,to,from); 
     270        bare=jid_normalized(from,FALSE); 
     271        presence_send_subscribe(stream,to,bare); 
     272        g_free(bare); 
     273        return 0; 
     274
     275 
     276int presence_subscribed(struct stream_s *stream,const char *from,const char *to){ 
     277User *u; 
     278Session *s; 
     279Contact *c; 
     280uin_t uin; 
     281 
     282        u=user_get_by_jid(from); 
     283        if (!u){ 
     284                g_warning(N_("Presence subscription from unknown user (%s)"),from); 
     285                presence_send_unsubscribe(stream,to,from); 
     286                return -1; 
     287        } 
     288        if (jid_is_me(to)){ 
     289                debug(L_("Presence 'subscribed' sent to me")); 
     290                return 0; 
     291        } 
     292        if (!jid_has_uin(to) || !jid_is_my(to)){ 
     293                g_warning(N_("Bad 'to': %s"),to); 
     294                return -1; 
     295        } 
     296        s=session_get_by_jid(from,stream,0); 
     297        debug(L_("%s accepted %s's subscription..."),from,to); 
     298        uin=jid_get_uin(to); 
     299        c=user_get_contact(u,uin,TRUE); 
     300        if (!c) { 
     301                return -1; 
     302        } 
     303        if (c->subscribe==SUB_UNDEFINED) c->subscribe=SUB_BOTH; 
     304        else if (c->subscribe==SUB_NONE) c->subscribe=SUB_FROM; 
     305        else if (c->subscribe==SUB_TO) c->subscribe=SUB_BOTH; 
     306        user_save(u); 
     307 
     308        if (s) session_update_contact(s,c);      
    262309        return 0; 
    263310} 
    264311 
    265312int presence_unsubscribed(struct stream_s *stream,const char *from,const char *to){ 
    266  
    267         if (!jid_is_me(to)) return 0; 
    268  
    269         debug(L_("Presence unsubscribed sent to me.")); 
     313User *u; 
     314Session *s; 
     315Contact *c; 
     316uin_t uin; 
     317 
     318        u=user_get_by_jid(from); 
     319        if (!u){ 
     320                g_warning(N_("Presence 'unsubscribed' from unknown user (%s)"),from); 
     321                return -1; 
     322        } 
     323        if (jid_is_me(to)){ 
     324                debug(L_("Presence 'unsubscribed' sent to me")); 
     325                return 0; 
     326        } 
     327        if (!jid_has_uin(to) || !jid_is_my(to)){ 
     328                g_warning(N_("Bad 'to': %s"),to); 
     329                return -1; 
     330        } 
     331        s=session_get_by_jid(from,stream,0); 
     332        debug(L_("%s denied/canceled %s's subscription..."),from,to); 
     333        uin=jid_get_uin(to); 
     334        c=user_get_contact(u,uin,TRUE); 
     335        if (!c) { 
     336                return -1; 
     337        } 
     338        if (c->subscribe==SUB_FROM||c->subscribe==SUB_UNDEFINED) c->subscribe=SUB_NONE; 
     339        else if (c->subscribe==SUB_BOTH) c->subscribe=SUB_TO; 
     340        user_save(u); 
     341 
     342        if (s) session_update_contact(s,c);      
     343        return 0; 
     344
     345 
     346int presence_unsubscribe(struct stream_s *stream,const char *from,const char *to){ 
     347User *u; 
     348Session *s; 
     349Contact *c; 
     350uin_t uin; 
     351 
     352        if (jid_is_me(to)){ 
     353                debug(L_("Presence unsubscribe request sent to me")); 
     354                presence_send_unsubscribed(stream,to,from); 
     355                return 0; 
     356        } 
     357        u=user_get_by_jid(from); 
     358        if (!u){ 
     359                g_warning(N_("Presence subscription from unknown user (%s)"),from); 
     360                return -1; 
     361        } 
     362        if (!jid_has_uin(to) || !jid_is_my(to)){ 
     363                g_warning(N_("Bad 'to': %s"),to); 
     364                return -1; 
     365        } 
     366        s=session_get_by_jid(from,stream,0); 
     367        debug(L_("Unsubscribing %s from %s..."),from,to); 
     368         
     369        uin=jid_get_uin(to); 
     370        c=user_get_contact(u,uin,FALSE); 
     371        if (!c) { 
     372                presence_send_unsubscribed(stream,to,from); 
     373                return -1; 
     374        } 
     375        if (c->subscribe==SUB_TO) c->subscribe=SUB_NONE; 
     376        else if (c->subscribe==SUB_BOTH) c->subscribe=SUB_FROM; 
     377        user_save(u); 
     378 
     379        if (s) session_update_contact(s,c); 
     380         
     381         
     382        debug(L_("Unsubscribed.")); 
     383        presence_send_unsubscribed(stream,to,from); 
     384        if (!GG_S_NA(c->status) && c->status!=-1){ 
     385                char *ujid; 
     386                ujid=jid_build_full(uin); 
     387                presence_send(stream,ujid,u->jid,0,NULL,"Unsubscribed",0); 
     388                g_free(ujid); 
     389        } 
    270390        return 0; 
    271391} 
     
    274394Session *s; 
    275395User *u; 
     396Contact *c; 
    276397uin_t uin; 
    277398int status; 
     
    312433 
    313434        uin=jid_get_uin(to); 
     435 
     436        c=user_get_contact(u,uin,TRUE); 
     437        if (!c) { 
     438                return -1; 
     439        } 
     440        if (c->subscribe==SUB_FROM) c->subscribe=SUB_NONE; 
     441        else if (c->subscribe==SUB_BOTH) c->subscribe=SUB_TO; 
     442        user_save(u); 
     443 
     444        if (s) session_update_contact(s,c);      
     445 
    314446        status=0; 
    315447        stat=NULL; 
     
    333465        if (available) presence_send(stream,jid_build_full(uin),u->jid,available,show,stat,timestamp); 
    334466        else presence_send(stream,jid_build(uin),u->jid,available,show,stat,timestamp); 
    335         /* more XMPP-like, but it doesn't work well with legacy clients 
    336         else presence_send_error(stream,to,from,404,_("Not Found"));*/ 
    337         return 0; 
    338 
    339  
    340 int presence_unsubscribe(struct stream_s *stream,const char *from,const char *to){ 
    341 User *u; 
    342 Session *s; 
    343 int r; 
    344  
    345         if (jid_is_me(to)){ 
    346                 debug(L_("Presence unsubscribe request sent to me")); 
    347                 presence_send_unsubscribed(stream,to,from); 
    348                 return 0; 
    349         } 
    350         u=user_get_by_jid(from); 
    351         if (!u){ 
    352                 g_warning(N_("Presence subscription from unknown user (%s)"),from); 
    353                 return -1; 
    354         } 
    355         if (!jid_has_uin(to) || !jid_is_my(to)){ 
    356                 g_warning(N_("Bad 'to': %s"),to); 
    357                 return -1; 
    358         } 
    359         s=session_get_by_jid(from,stream,0); 
     467         
     468        return 0; 
     469
     470 
     471 
     472int presence_direct_available(struct stream_s *stream,const char *from,const char *to){ 
     473uin_t uin; 
     474Contact *c; 
     475Session *s; 
     476 
     477        uin=jid_get_uin(to); 
     478        if (uin<=0) return -1; 
     479 
     480        s=session_get_by_jid(from,NULL,0); 
    360481        if (!s){ 
    361                 g_warning(N_("Couldn't find or open session for '%s'"),from); 
    362                 return -1; 
    363         } 
    364         debug(L_("Unsubscribing %s from %s..."),from,to); 
    365         r=session_unsubscribe(s,jid_get_uin(to)); 
    366         if (!r){ 
    367                 debug(L_("Unsubscribed.")); 
    368                 presence_send_unsubscribed(stream,to,from); 
    369         } 
    370  
     482                g_warning(N_("Couldn't find session for '%s'"),from); 
     483                return -1; 
     484        } 
     485 
     486        c=user_get_contact(s->user,uin,TRUE); 
     487        if (!c) return -1; 
     488        c->got_online=TRUE; 
     489        session_update_contact(s,c); 
     490        return 0; 
     491
     492 
     493int presence_direct_unavailable(struct stream_s *stream,const char *from,const char *to){ 
     494uin_t uin; 
     495Contact *c; 
     496Session *s; 
     497 
     498        uin=jid_get_uin(to); 
     499        if (uin<=0) return -1; 
     500 
     501        s=session_get_by_jid(from,NULL,0); 
     502        if (!s){ 
     503                g_warning(N_("Couldn't find session for '%s'"),from); 
     504                return -1; 
     505        } 
     506 
     507        c=user_get_contact(s->user,uin,FALSE); 
     508        if (!c) return -1; 
     509        c->got_online=FALSE; 
     510        user_check_contact(s->user,c); 
     511        session_update_contact(s,c); 
    371512        return 0; 
    372513} 
     
    436577        if (!strcmp(type,"available")){ 
    437578                if (jid_has_uin(to)) 
    438                         return 0
     579                        return presence_direct_available(stream,from,to)
    439580                else 
    440581                        return presence(stream,from,to,1,show,status,priority); 
     
    442583        else if (!strcmp(type,"unavailable")){ 
    443584                if (jid_has_uin(to)) 
    444                         return 0
     585                        return presence_direct_unavailable(stream,from,to)
    445586                else 
    446587                        return presence(stream,from,to,0,show,status,priority); 
     
    448589        if (!strcmp(type,"invisible")){ 
    449590                if (jid_has_uin(to)) 
    450                         return 0
     591                        return presence_direct_unavailable(stream,from,to)
    451592                else 
    452593                        return presence(stream,from,to,-1,show,status,priority); 
     
    457598                return presence_unsubscribe(stream,from,to); 
    458599        else if (!strcmp(type,"subscribed")) 
    459                 return presence_subscribe(stream,from,to); 
     600                return presence_subscribed(stream,from,to); 
    460601        else if (!strcmp(type,"unsubscribed")) 
    461602                return presence_unsubscribed(stream,from,to); 
  • trunk/src/presence.h

    r306 r595  
    3838                const char *to,int available,const char *show, 
    3939                const char *status,GTime timestamp); 
    40 int presence_send_probe(struct stream_s *stream,const char *to); 
     40int presence_send_probe(struct stream_s *stream, const char *from, const char *to); 
    4141 
    4242int jabber_presence(struct stream_s *stream,xmlnode tag); 
  • trunk/src/register.c

    r587 r595  
    223223        g_free(newpasswdW); 
    224224        g_free(qaW); 
    225         if (gghttp!=NULL)
     225        if (gghttp!=NULL)
    226226                r=add_request(RT_PASSWD,from,to,id,form,gghttp,s); 
    227227                r->data=g_strdup(newpasswd); 
    228228        } 
    229          
    230229        return 0; 
    231230} 
  • trunk/src/sessions.c

    r570 r595  
    187187 
    188188        jid=(char *)data; 
    189         presence_send_probe(jabber_stream(),jid); 
     189        presence_send_probe(jabber_stream(),NULL,jid); 
    190190        g_free(jid); 
    191191        return FALSE; 
     
    260260char *ujid; 
    261261char *show; 
     262Contact *c; 
     263 
     264        c=user_get_contact(s->user,uin,FALSE); 
     265        if (c==NULL) { 
     266                debug(L_("%s got notification from unknown contact %i, ignoring.."),s->user->jid,uin); 
     267                return 0; 
     268        } 
     269        if (!c->got_probe && c->subscribe!=SUB_TO && c->subscribe!=SUB_BOTH) { 
     270                debug(L_("%s got notification from contact %i whose presence was not requested, ignoring.."),s->user->jid,uin); 
     271                return 0; 
     272        } 
    262273 
    263274        available=status_gg_to_jabber(status,&show,&desc); 
     
    272283        presence_send(s->s,ujid,s->user->jid,available,show,desc,0); 
    273284        g_free(ujid); 
    274         return 0; 
    275 } 
    276  
    277 int session_send_notify(Session *s){ 
    278 GList *it; 
    279 uin_t *userlist; 
    280 int userlist_len; 
    281 int i; 
    282  
    283         g_assert(s!=NULL); 
    284         userlist_len=g_list_length(s->user->contacts); 
    285         userlist=g_new(uin_t,userlist_len+1); 
    286  
    287         i=0; 
    288         for(it=g_list_first(s->user->contacts);it;it=it->next) 
    289                 userlist[i++]=((Contact *)it->data)->uin; 
    290  
    291         userlist[i]=0; 
    292  
    293         debug("gg_notify(%p,%p,%i)",s->ggs,userlist,userlist_len); 
    294         gg_notify(s->ggs,userlist,userlist_len); 
    295  
    296         g_free(userlist); 
    297285        return 0; 
    298286} 
     
    373361int chat; 
    374362GIOCondition cond; 
    375 Resource *r; 
    376363time_t timestamp; 
    377364 
     
    441428                        if (s->user->contacts) session_send_notify(s); 
    442429 
    443                         r=session_get_cur_resource(s); 
    444                         if (r) 
    445                                 presence_send(s->s,NULL,s->user->jid,r->available,r->show,r->status,0); 
    446                         else 
    447                                 presence_send(s->s,NULL,s->user->jid,1,NULL,"Online",0); 
     430 
    448431                        if (s->timeout_func) g_source_remove(s->timeout_func); 
    449432                        s->ping_timeout_func= 
     
    498481                                                        event->event.msg.msgclass, 
    499482                                                        (unsigned long)event->event.msg.time); 
     483                         
    500484                        if (event->event.msg.sender==0){ 
    501485                                if (!user_sys_msg_received(s->user,event->event.msg.msgclass)) break; 
     
    511495                        } 
    512496                        else{ 
     497                                Contact *c=user_get_contact(s->user, 
     498                                                event->event.msg.sender,0); 
     499                                if ((!c && s->user->ignore_unknown)  
     500                                                || (c && c->ignored)) { 
     501                                        debug(L_("Ignoring the message.")); 
     502                                        break; 
     503                                } 
    513504                                jid=jid_build_full(event->event.msg.sender); 
    514505                                if ((event->event.msg.msgclass&GG_CLASS_CHAT)!=0) chat=1; 
     
    623614 
    624615/* returns: -1 on error, 1 on status change, 0 on no change */ 
    625 int session_make_status(Session *s){ 
     616static int session_do_make_status(Session *s, Resource *r, gboolean send_presence){ 
    626617int status; 
    627 Resource *r; 
    628  
    629         r=session_get_cur_resource(s); 
    630         if (!r) return -1; 
     618char *status_descr; 
     619 
     620        if (!r) { 
     621                if (send_presence) presence_send(s->s,NULL,s->user->jid,1,NULL,s->gg_status_descr,0); 
     622                return -1; 
     623        } 
    631624        status=status_jabber_to_gg(r->available,r->show,r->status); 
    632         if (s->user->invisible || r->available==-1) status=GG_STATUS_INVISIBLE; 
     625        status_descr=r->status; 
     626        if (!r->available && s->user->offline_status) status_descr=s->user->offline_status; 
     627        else if (s->user->status) status_descr=s->user->status; 
     628        if (s->user->invisible || r->available==-1){ 
     629                status=GG_STATUS_INVISIBLE; 
     630                if (s->user->invisible_status) status_descr=s->user->invisible_status; 
     631        } 
    633632        else if (s->user->friends_only) status|=GG_STATUS_FRIENDS_MASK; 
    634633 
    635634        if (status==s->gg_status){ 
    636635                if (r->status!=NULL && s->gg_status_descr!=NULL 
    637                                 && !strcmp(r->status,s->gg_status_descr)) return 0; 
     636                                && !strcmp(status_descr,s->gg_status_descr)) return 0; 
    638637                if (r->status==NULL && s->gg_status_descr==NULL) return 0; 
    639638        } 
    640639        g_free(s->gg_status_descr); 
    641         s->gg_status_descr=g_strdup(r->status); 
     640        s->gg_status_descr=g_strdup(status_descr); 
    642641        s->gg_status=status; 
     642        if (send_presence) { 
     643                presence_send(s->s,NULL,s->user->jid,r->available,r->show,s->gg_status_descr,0); 
     644        } 
    643645        return 1; 
    644646} 
     647 
     648Resource *session_get_cur_resource(Session *s){ 
     649GList *it; 
     650Resource *r=NULL; 
     651int maxprio; 
     652 
     653        maxprio=-129; 
     654        for(it=g_list_last(s->resources);it;it=it->prev){ 
     655                Resource *r1=(Resource *)it->data; 
     656                if (r1->priority>maxprio){ 
     657                        r=r1; 
     658                        maxprio=r1->priority; 
     659                } 
     660        } 
     661        return r; 
     662} 
     663 
     664/* returns: -1 on error, 1 on status change, 0 on no change */ 
     665int session_make_status(Session *s, gboolean send_presence){ 
     666Resource *r; 
     667 
     668        r=session_get_cur_resource(s); 
     669        return session_do_make_status(s,r,send_presence); 
     670} 
     671 
    645672 
    646673static int session_try_login(Session *s){ 
     
    664691        login_params.protocol_version=GG_DEFAULT_PROTOCOL_VERSION; 
    665692 
    666         r=session_make_status(s); 
     693        r=session_make_status(s, FALSE); 
    667694        if (r!=-1){ 
    668695                debug(L_("Setting gg status to %i (%s)"),s->gg_status,s->gg_status_descr); 
     
    734761User *u; 
    735762char *njid; 
     763GList *it; 
    736764 
    737765        g_assert(sessions_jid!=NULL); 
     
    751779        u=user_get_by_jid(jid); 
    752780        if (!u) return NULL; 
     781 
     782        debug(L_("User loaded processing his subscriptions.")); 
     783        for(it=u->contacts;it;it=it->next){ 
     784                Contact *c; 
     785                char *c_jid; 
     786                c=(Contact *)it->data; 
     787                if (c->subscribe == SUB_UNDEFINED) { 
     788                        c_jid=jid_build(c->uin); 
     789                        presence_send_subscribe(stream,c_jid,u->jid); 
     790                        g_free(c_jid); 
     791                } 
     792                else if (c->subscribe == SUB_FROM || c->subscribe == SUB_BOTH){ 
     793                        c_jid=jid_build(c->uin); 
     794                        presence_send_probe(stream,c_jid,u->jid); 
     795                        g_free(c_jid); 
     796                } 
     797        } 
    753798        debug(L_("Creating new session")); 
    754799        return session_create(u,jid,NULL,NULL,stream,delay_login); 
    755800} 
    756801 
    757 Resource *session_get_cur_resource(Session *s){ 
    758 GList *it; 
    759 Resource *r=NULL; 
    760 int maxprio; 
    761  
    762         maxprio=-129; 
    763         for(it=g_list_last(s->resources);it;it=it->prev){ 
    764                 Resource *r1=(Resource *)it->data; 
    765                 if (r1->priority>maxprio){ 
    766                         r=r1; 
    767                         maxprio=r1->priority; 
    768                 } 
    769         } 
    770         return r; 
    771 } 
    772  
    773802int session_send_status(Session *s){ 
    774803int r; 
     
    776805        g_assert(s!=NULL); 
    777806        if (s->ggs==NULL) return -1; 
    778         r=session_make_status(s); 
     807        r=session_make_status(s, s->connected); 
    779808        if (r==-1) return -1; 
    780809        if (r==0) return 0; 
     
    804833                return; 
    805834        } 
    806         r=session_get_cur_resource(s); 
    807         if (r) presence_send(s->s,NULL,s->jid,r->available,r->show,r->status,0); 
     835        ses