Mercurial > pidgin.yaz
annotate src/protocols/jabber/jutil.c @ 8193:e0a70b763872
[gaim-migrate @ 8915]
ok, this should all work now
committer: Tailor Script <tailor@pidgin.im>
author | Nathan Walp <nwalp@pidgin.im> |
---|---|
date | Sat, 31 Jan 2004 22:30:29 +0000 |
parents | 9a6df4d567e0 |
children | c13a4913a071 |
rev | line source |
---|---|
7014 | 1 /* |
2 * gaim - Jabber Protocol Plugin | |
3127 | 3 * |
7014 | 4 * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com> |
3127 | 5 * |
7014 | 6 * This program is free software; you can redistribute it and/or modify |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
3127 | 10 * |
7014 | 11 * This program is distributed in the hope that it will be useful, |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
3127 | 19 * |
7014 | 20 */ |
21 #include "internal.h" | |
22 #include "server.h" | |
8043 | 23 #include "util.h" |
7014 | 24 |
7322 | 25 #include "chat.h" |
7014 | 26 #include "presence.h" |
27 #include "jutil.h" | |
3127 | 28 |
7014 | 29 time_t str_to_time(const char *timestamp) |
30 { | |
31 struct tm t; | |
32 time_t retval = 0; | |
33 char buf[32]; | |
34 char *c; | |
35 int tzoff = 0; | |
2086 | 36 |
7014 | 37 time(&retval); |
38 localtime_r(&retval, &t); | |
39 | |
40 snprintf(buf, sizeof(buf), "%s", timestamp); | |
41 c = buf; | |
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3127
diff
changeset
|
42 |
7014 | 43 /* 4 digit year */ |
44 if(!sscanf(c, "%04d", &t.tm_year)) return 0; | |
45 c+=4; | |
46 if(*c == '-') | |
47 c++; | |
2086 | 48 |
7014 | 49 t.tm_year -= 1900; |
50 | |
51 /* 2 digit month */ | |
52 if(!sscanf(c, "%02d", &t.tm_mon)) return 0; | |
53 c+=2; | |
54 if(*c == '-') | |
55 c++; | |
56 | |
57 t.tm_mon -= 1; | |
2086 | 58 |
7014 | 59 /* 2 digit day */ |
60 if(!sscanf(c, "%02d", &t.tm_mday)) return 0; | |
61 c+=2; | |
62 if(*c == 'T') { /* we have more than a date, keep going */ | |
63 c++; /* skip the "T" */ | |
2086 | 64 |
7014 | 65 /* 2 digit hour */ |
66 if(sscanf(c, "%02d:%02d:%02d", &t.tm_hour, &t.tm_min, &t.tm_sec)) { | |
67 int tzhrs, tzmins; | |
68 c+=8; | |
69 if(*c == '.') /* dealing with precision we don't care about */ | |
70 c += 4; | |
2086 | 71 |
7014 | 72 if((*c == '+' || *c == '-') && |
73 sscanf(c+1, "%02d:%02d", &tzhrs, &tzmins)) { | |
74 tzoff = tzhrs*60*60 + tzmins*60; | |
75 if(*c == '+') | |
76 tzoff *= -1; | |
77 } | |
2086 | 78 |
7014 | 79 #ifdef HAVE_TM_GMTOFF |
80 tzoff += t.tm_gmtoff; | |
81 #else | |
82 # ifdef HAVE_TIMEZONE | |
83 tzset(); /* making sure */ | |
84 tzoff -= timezone; | |
85 # endif | |
86 #endif | |
87 } | |
2086 | 88 } |
7014 | 89 retval = mktime(&t); |
2086 | 90 |
7014 | 91 retval += tzoff; |
2086 | 92 |
7014 | 93 return retval; |
2086 | 94 } |
95 | |
7014 | 96 const char *jabber_get_state_string(int s) { |
97 switch(s) { | |
98 case JABBER_STATE_AWAY: | |
99 return _("Away"); | |
100 break; | |
101 case JABBER_STATE_CHAT: | |
102 return _("Chatty"); | |
103 break; | |
104 case JABBER_STATE_XA: | |
105 return _("Extended Away"); | |
106 break; | |
107 case JABBER_STATE_DND: | |
108 return _("Do Not Disturb"); | |
109 break; | |
110 default: | |
111 return _("Available"); | |
112 break; | |
113 } | |
2086 | 114 } |
115 | |
7310 | 116 gboolean jabber_nodeprep_validate(const char *str) |
117 { | |
118 const char *c; | |
119 | |
120 if(!str) | |
121 return TRUE; | |
122 | |
123 if(strlen(str) > 1023) | |
124 return FALSE; | |
125 | |
126 c = str; | |
127 while(c && *c) { | |
128 gunichar ch = g_utf8_get_char(c); | |
129 if(ch == '\"' || ch == '&' || ch == '\'' || ch == '/' || ch == ':' || | |
130 ch == '<' || ch == '>' || ch == '@' || !g_unichar_isgraph(ch)) { | |
131 return FALSE; | |
132 } | |
133 c = g_utf8_next_char(c); | |
134 } | |
135 | |
136 return TRUE; | |
137 } | |
138 | |
139 gboolean jabber_nameprep_validate(const char *str) | |
140 { | |
141 const char *c; | |
142 | |
143 if(!str) | |
144 return TRUE; | |
145 | |
146 if(strlen(str) > 1023) | |
147 return FALSE; | |
148 | |
149 c = str; | |
150 while(c && *c) { | |
151 gunichar ch = g_utf8_get_char(c); | |
152 if(!g_unichar_isgraph(ch)) | |
153 return FALSE; | |
154 | |
155 c = g_utf8_next_char(c); | |
156 } | |
157 | |
158 | |
159 return TRUE; | |
160 } | |
161 | |
162 gboolean jabber_resourceprep_validate(const char *str) | |
163 { | |
164 const char *c; | |
165 | |
166 if(!str) | |
167 return TRUE; | |
168 | |
169 if(strlen(str) > 1023) | |
170 return FALSE; | |
171 | |
172 c = str; | |
173 while(c && *c) { | |
174 gunichar ch = g_utf8_get_char(c); | |
7419 | 175 if(!g_unichar_isgraph(ch) && ch != ' ') |
7310 | 176 return FALSE; |
177 | |
178 c = g_utf8_next_char(c); | |
179 } | |
180 | |
181 return TRUE; | |
182 } | |
183 | |
184 | |
7014 | 185 JabberID* |
186 jabber_id_new(const char *str) | |
2086 | 187 { |
7014 | 188 char *at; |
189 char *slash; | |
190 JabberID *jid; | |
2086 | 191 |
7306 | 192 if(!str || !g_utf8_validate(str, -1, NULL)) |
7014 | 193 return NULL; |
2086 | 194 |
7014 | 195 jid = g_new0(JabberID, 1); |
196 | |
7306 | 197 at = g_utf8_strchr(str, -1, '@'); |
198 slash = g_utf8_strchr(str, -1, '/'); | |
2086 | 199 |
7014 | 200 if(at) { |
7306 | 201 jid->node = g_utf8_normalize(str, at-str, G_NORMALIZE_NFKC); |
7014 | 202 if(slash) { |
7306 | 203 jid->domain = g_utf8_normalize(at+1, slash-(at+1), G_NORMALIZE_NFKC); |
204 jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC); | |
7014 | 205 } else { |
7306 | 206 jid->domain = g_utf8_normalize(at+1, -1, G_NORMALIZE_NFKC); |
7014 | 207 } |
208 } else { | |
209 if(slash) { | |
7306 | 210 jid->domain = g_utf8_normalize(str, slash-str, G_NORMALIZE_NFKC); |
211 jid->resource = g_utf8_normalize(slash+1, -1, G_NORMALIZE_NFKC); | |
7014 | 212 } else { |
7306 | 213 jid->domain = g_utf8_normalize(str, -1, G_NORMALIZE_NFKC); |
214 } | |
215 } | |
216 | |
217 | |
7310 | 218 if(!jabber_nodeprep_validate(jid->node) || |
219 !jabber_nameprep_validate(jid->domain) || | |
220 !jabber_resourceprep_validate(jid->resource)) { | |
7306 | 221 jabber_id_free(jid); |
222 return NULL; | |
223 } | |
224 | |
7014 | 225 return jid; |
2086 | 226 } |
227 | |
7014 | 228 void |
229 jabber_id_free(JabberID *jid) | |
2086 | 230 { |
7014 | 231 if(jid) { |
232 if(jid->node) | |
233 g_free(jid->node); | |
234 if(jid->domain) | |
235 g_free(jid->domain); | |
236 if(jid->resource) | |
237 g_free(jid->resource); | |
238 g_free(jid); | |
239 } | |
2086 | 240 } |
241 | |
7014 | 242 |
7306 | 243 char *jabber_get_resource(const char *in) |
7014 | 244 { |
7306 | 245 JabberID *jid = jabber_id_new(in); |
246 char *out; | |
7014 | 247 |
7306 | 248 if(!jid) |
7014 | 249 return NULL; |
7306 | 250 |
251 out = g_strdup(jid->resource); | |
252 jabber_id_free(jid); | |
253 | |
254 return out; | |
7014 | 255 } |
256 | |
7306 | 257 char *jabber_get_bare_jid(const char *in) |
7014 | 258 { |
7306 | 259 JabberID *jid = jabber_id_new(in); |
260 char *out; | |
7014 | 261 |
7306 | 262 if(!jid) |
263 return NULL; | |
264 | |
7322 | 265 out = g_strdup_printf("%s%s%s", jid->node ? jid->node : "", |
266 jid->node ? "@" : "", jid->domain); | |
7306 | 267 jabber_id_free(jid); |
268 | |
269 return out; | |
7014 | 270 } |
7261 | 271 |
7322 | 272 const char *jabber_normalize(const GaimAccount *account, const char *in) |
7261 | 273 { |
7322 | 274 GaimConnection *gc = account ? account->gc : NULL; |
275 JabberStream *js = gc ? gc->proto_data : NULL; | |
276 static char buf[3072]; /* maximum legal length of a jabber jid */ | |
277 JabberID *jid; | |
7445 | 278 char *node, *domain; |
7261 | 279 |
7322 | 280 jid = jabber_id_new(in); |
7310 | 281 |
7322 | 282 if(!jid) |
7310 | 283 return NULL; |
284 | |
7445 | 285 node = jid->node ? g_utf8_strdown(jid->node, -1) : NULL; |
286 domain = g_utf8_strdown(jid->domain, -1); | |
287 | |
288 | |
289 if(js && node && jid->resource && | |
290 jabber_chat_find(js, node, domain)) | |
291 g_snprintf(buf, sizeof(buf), "%s@%s/%s", node, domain, | |
7322 | 292 jid->resource); |
293 else | |
7445 | 294 g_snprintf(buf, sizeof(buf), "%s%s%s", node ? node : "", |
295 node ? "@" : "", domain); | |
7322 | 296 |
7429 | 297 jabber_id_free(jid); |
7445 | 298 g_free(node); |
299 g_free(domain); | |
7429 | 300 |
7261 | 301 return buf; |
302 } | |
7306 | 303 |
8043 | 304 GaimConversation * |
305 jabber_find_unnormalized_conv(const char *name, GaimAccount *account) | |
306 { | |
307 GaimConversation *c = NULL; | |
308 GList *cnv; | |
309 | |
310 g_return_val_if_fail(name != NULL, NULL); | |
311 | |
312 for(cnv = gaim_get_conversations(); cnv; cnv = cnv->next) { | |
313 c = (GaimConversation*)cnv->data; | |
314 if(gaim_conversation_get_type(c) == GAIM_CONV_IM && | |
315 !gaim_utf8_strcasecmp(name, gaim_conversation_get_name(c)) && | |
316 account == gaim_conversation_get_account(c)) | |
317 return c; | |
318 } | |
319 | |
320 return NULL; | |
321 } |