equal
deleted
inserted
replaced
11 |
11 |
12 import ( |
12 import ( |
13 "bytes" |
13 "bytes" |
14 "fmt" |
14 "fmt" |
15 "io" |
15 "io" |
16 "log" |
|
17 "net" |
16 "net" |
18 "os" |
17 "os" |
19 "sync" |
18 "sync" |
|
19 "syslog" |
20 "xml" |
20 "xml" |
21 ) |
21 ) |
22 |
22 |
23 const ( |
23 const ( |
24 // Version of RFC 3920 that we implement. |
24 // Version of RFC 3920 that we implement. |
34 NsRoster = "jabber:iq:roster" |
34 NsRoster = "jabber:iq:roster" |
35 |
35 |
36 // DNS SRV names |
36 // DNS SRV names |
37 serverSrv = "xmpp-server" |
37 serverSrv = "xmpp-server" |
38 clientSrv = "xmpp-client" |
38 clientSrv = "xmpp-client" |
39 |
39 ) |
40 // BUG(cjyar) Make this a parameter to NewClient, not a |
40 |
41 // constant. We should have both a log level and a |
41 var ( |
42 // syslog.Writer, so the app can control how much time we |
42 // If non-nil when NewClient() is called, log messages will be |
43 // spend generating log messages, as well as where they go. |
43 // sent to this writer. |
44 debug = false |
44 Log *syslog.Writer |
|
45 // Threshold for which messages are logged. |
|
46 Loglevel syslog.Priority = syslog.LOG_NOTICE |
45 ) |
47 ) |
46 |
48 |
47 // This channel may be used as a convenient way to generate a unique |
49 // This channel may be used as a convenient way to generate a unique |
48 // id for an iq, message, or presence stanza. |
50 // id for an iq, message, or presence stanza. |
49 var Id <-chan string |
51 var Id <-chan string |
237 } |
239 } |
238 |
240 |
239 func tee(r io.Reader, w io.Writer, prefix string) { |
241 func tee(r io.Reader, w io.Writer, prefix string) { |
240 defer tryClose(r, w) |
242 defer tryClose(r, w) |
241 |
243 |
242 buf := bytes.NewBuffer(nil) |
244 buf := bytes.NewBuffer([]uint8(prefix)) |
243 for { |
245 for { |
244 var c [1]byte |
246 var c [1]byte |
245 n, _ := r.Read(c[:]) |
247 n, _ := r.Read(c[:]) |
246 if n == 0 { |
248 if n == 0 { |
247 break |
249 break |
250 if n == 0 { |
252 if n == 0 { |
251 break |
253 break |
252 } |
254 } |
253 buf.Write(c[:n]) |
255 buf.Write(c[:n]) |
254 if c[0] == '\n' || c[0] == '>' { |
256 if c[0] == '\n' || c[0] == '>' { |
255 fmt.Printf("%s%s\n", prefix, buf.String()) |
257 Log.Debug(buf.String()) |
256 buf.Reset() |
258 buf.Reset() |
257 } |
259 } |
258 } |
260 } |
259 leftover := buf.String() |
261 leftover := buf.String() |
260 if leftover != "" { |
262 if leftover != "" { |
261 fmt.Printf("%s%s\n", prefix, leftover) |
263 Log.Debug(buf.String()) |
262 } |
264 } |
263 } |
265 } |
264 |
266 |
265 func tryClose(xs ...interface{}) { |
267 func tryClose(xs ...interface{}) { |
266 f1 := func(ch chan<- interface{}) { |
268 f1 := func(ch chan<- interface{}) { |
305 []interface{}{ Generic{XMLName: xml.Name{Space: |
307 []interface{}{ Generic{XMLName: xml.Name{Space: |
306 NsSession, Local: "session"}}}} |
308 NsSession, Local: "session"}}}} |
307 ch := make(chan os.Error) |
309 ch := make(chan os.Error) |
308 f := func(st Stanza) bool { |
310 f := func(st Stanza) bool { |
309 if st.GetType() == "error" { |
311 if st.GetType() == "error" { |
310 log.Printf("Can't start session: %v", st) |
312 if Log != nil { |
|
313 Log.Err(fmt.Sprintf("Can't start session: %v", |
|
314 st)) |
|
315 } |
311 ch <- st.GetError() |
316 ch <- st.GetError() |
312 return false |
317 return false |
313 } |
318 } |
314 ch <- nil |
319 ch <- nil |
315 return false |
320 return false |