equal
deleted
inserted
replaced
3 // license that can be found in the LICENSE file. |
3 // license that can be found in the LICENSE file. |
4 |
4 |
5 package xmpp |
5 package xmpp |
6 |
6 |
7 import ( |
7 import ( |
|
8 "errors" |
8 "fmt" |
9 "fmt" |
9 "os" |
10 |
10 "xml" |
11 "encoding/xml" |
11 ) |
12 ) |
12 |
13 |
13 // This file contains support for roster management, RFC 3921, Section 7. |
14 // This file contains support for roster management, RFC 3921, Section 7. |
14 |
15 |
15 var rosterExt Extension = Extension{StanzaHandlers: map[string]func(*xml.Name) interface{}{NsRoster: newRosterQuery}, Start: startRosterFilter} |
16 var rosterExt Extension = Extension{StanzaHandlers: map[string]func(*xml.Name) interface{}{NsRoster: newRosterQuery}, Start: startRosterFilter} |
44 } |
45 } |
45 |
46 |
46 // Synchronously fetch this entity's roster from the server and cache |
47 // Synchronously fetch this entity's roster from the server and cache |
47 // that information. This is called once from a fairly deep call stack |
48 // that information. This is called once from a fairly deep call stack |
48 // as part of XMPP negotiation. |
49 // as part of XMPP negotiation. |
49 func fetchRoster(client *Client) os.Error { |
50 func fetchRoster(client *Client) error { |
50 rosterUpdate := rosterClients[client.Uid].rosterUpdate |
51 rosterUpdate := rosterClients[client.Uid].rosterUpdate |
51 |
52 |
52 iq := &Iq{From: client.Jid.String(), Id: <-Id, Type: "get", |
53 iq := &Iq{From: client.Jid.String(), Id: <-Id, Type: "get", |
53 Nested: []interface{}{RosterQuery{}}} |
54 Nested: []interface{}{RosterQuery{}}} |
54 ch := make(chan os.Error) |
55 ch := make(chan error) |
55 f := func(st Stanza) bool { |
56 f := func(st Stanza) bool { |
56 defer close(ch) |
57 defer close(ch) |
57 if iq.Type == "error" { |
58 if iq.Type == "error" { |
58 ch <- iq.Error |
59 ch <- iq.Error |
59 return false |
60 return false |
64 rq = q |
65 rq = q |
65 break |
66 break |
66 } |
67 } |
67 } |
68 } |
68 if rq == nil { |
69 if rq == nil { |
69 ch <- os.NewError(fmt.Sprintf( |
70 ch <- errors.New(fmt.Sprintf( |
70 "Roster query result not query: %v", st)) |
71 "Roster query result not query: %v", st)) |
71 return false |
72 return false |
72 } |
73 } |
73 for _, item := range rq.Item { |
74 for _, item := range rq.Item { |
74 rosterUpdate <- item |
75 rosterUpdate <- item |
129 snapshot := []RosterItem{} |
130 snapshot := []RosterItem{} |
130 for { |
131 for { |
131 select { |
132 select { |
132 case newIt := <-rosterUpdate: |
133 case newIt := <-rosterUpdate: |
133 if newIt.Subscription == "remove" { |
134 if newIt.Subscription == "remove" { |
134 roster[newIt.Jid] = RosterItem{}, false |
135 delete(roster, newIt.Jid) |
135 } else { |
136 } else { |
136 roster[newIt.Jid] = newIt |
137 roster[newIt.Jid] = newIt |
137 } |
138 } |
138 case rosterCh <- snapshot: |
139 case rosterCh <- snapshot: |
139 } |
140 } |