Mercurial > pidgin.yaz
annotate src/protocols/silc/util.c @ 12498:a2de852981c1
[gaim-migrate @ 14810]
SF Patch #1380806 from charkins
"leave docklet loaded when notification area is not present"
"From the summary, this sounds weird, but I think its
better behavior. This really only effects some odd
corner cases. The existing behavior is that the docklet
plugin unloads itself after 10 seconds if the tray icon
isn't created. The behavior with this patch is that
there is a 3 second timeout (this is necessary to avoid
race condition when restoring the gtkblist's visibility
state on startup). After this timeout, the docklet
plugin stays loaded waiting for a notification to
appear, but is essentially non-functional.
In the typical scenario, this patch doesn't effect the
behavior. Here are some examples of where it does matter:
1) If gaim is closed with the buddy list hidden to the
docklet, then gaim is started again without a
notification area, the buddy list doesn't show up for
10 seconds (the time it takes for the docklet to
timeout). This patch would reduce this to 3 seconds.
2) If the user removes the notification area from their
panel, maybe to remove it from one panel and add it to
a different panel, but doesn't add a new one back
within 10 seconds, the current behavior would cause the
docklet plugin to be unloaded. With this patch, the
tray icon would automatically be added to the new
notification area when it becomes available.
3) The gnome-panel dies and is not restarted within 10
seconds. Similar to #2. (There was a bug filed for
this, but can't find it right now).
My main concern was that it could be confusing to the
user if they enable the docklet plugin, then 10 seconds
later it gets disabled without any notification. This
patch doesn't add any notification, but leaves the
plugin running so it will automatically use a
notification area when one becomes available.
I also removed an unused parameter from
docklet_remove() and changed the plugin description
slightly to reflect the change in queuing/notification.
Not sure how clear this is, so bug me on #gaim if you
have any questions. --charkins"
I made a few changes to this patch, but nothing terribly significant...
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Fri, 16 Dec 2005 09:16:14 +0000 |
parents | 029802981b81 |
children | cfc2f7fcb3dd |
rev | line source |
---|---|
8849 | 1 /* |
2 | |
3 silcgaim_util.c | |
4 | |
5 Author: Pekka Riikonen <priikone@silcnet.org> | |
6 | |
10825 | 7 Copyright (C) 2004 - 2005 Pekka Riikonen |
8849 | 8 |
9 This program is free software; you can redistribute it and/or modify | |
10 it under the terms of the GNU General Public License as published by | |
11 the Free Software Foundation; version 2 of the License. | |
12 | |
13 This program is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 */ | |
19 | |
20 #include "silcincludes.h" | |
21 #include "silcclient.h" | |
22 #include "silcgaim.h" | |
12217 | 23 #include "imgstore.h" |
8849 | 24 |
25 /**************************** Utility Routines *******************************/ | |
26 | |
27 static char str[256], str2[256]; | |
28 | |
29 const char *silcgaim_silcdir(void) | |
30 { | |
31 const char *hd = gaim_home_dir(); | |
32 memset(str, 0, sizeof(str)); | |
33 g_snprintf(str, sizeof(str) - 1, "%s" G_DIR_SEPARATOR_S ".silc", hd ? hd : "/tmp"); | |
34 return (const char *)str; | |
35 } | |
36 | |
37 const char *silcgaim_session_file(const char *account) | |
38 { | |
39 memset(str2, 0, sizeof(str2)); | |
40 g_snprintf(str2, sizeof(str2) - 1, "%s" G_DIR_SEPARATOR_S "%s_session", | |
41 silcgaim_silcdir(), account); | |
42 return (const char *)str2; | |
43 } | |
44 | |
45 gboolean silcgaim_ip_is_private(const char *ip) | |
46 { | |
47 if (silc_net_is_ip4(ip)) { | |
48 if (!strncmp(ip, "10.", 3)) { | |
49 return TRUE; | |
50 } else if (!strncmp(ip, "172.", 4) && strlen(ip) > 6) { | |
51 char tmp[3]; | |
8910 | 52 int s; |
8849 | 53 memset(tmp, 0, sizeof(tmp)); |
54 strncpy(tmp, ip + 4, 2); | |
8910 | 55 s = atoi(tmp); |
8849 | 56 if (s >= 16 && s <= 31) |
57 return TRUE; | |
58 } else if (!strncmp(ip, "192.168.", 8)) { | |
59 return TRUE; | |
60 } | |
61 } | |
62 | |
63 return FALSE; | |
64 } | |
65 | |
66 /* This checks stats for various SILC files and directories. First it | |
67 checks if ~/.silc directory exist and is owned by the correct user. If | |
68 it doesn't exist, it will create the directory. After that it checks if | |
69 user's Public and Private key files exists and creates them if needed. */ | |
70 | |
71 gboolean silcgaim_check_silc_dir(GaimConnection *gc) | |
72 { | |
73 char filename[256], file_public_key[256], file_private_key[256]; | |
74 char servfilename[256], clientfilename[256], friendsfilename[256]; | |
10825 | 75 char pkd[256], prd[256]; |
8849 | 76 struct stat st; |
77 struct passwd *pw; | |
78 | |
79 pw = getpwuid(getuid()); | |
80 if (!pw) { | |
9272 | 81 gaim_debug_error("silc", "silc: %s\n", strerror(errno)); |
8849 | 82 return FALSE; |
83 } | |
84 | |
9353 | 85 g_snprintf(filename, sizeof(filename) - 1, "%s", silcgaim_silcdir()); |
8849 | 86 g_snprintf(servfilename, sizeof(servfilename) - 1, "%s" G_DIR_SEPARATOR_S "serverkeys", |
87 silcgaim_silcdir()); | |
88 g_snprintf(clientfilename, sizeof(clientfilename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys", | |
89 silcgaim_silcdir()); | |
90 g_snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s" G_DIR_SEPARATOR_S "friends", | |
91 silcgaim_silcdir()); | |
92 | |
93 /* | |
94 * Check ~/.silc directory | |
95 */ | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
96 if ((g_stat(filename, &st)) == -1) { |
8849 | 97 /* If dir doesn't exist */ |
98 if (errno == ENOENT) { | |
99 if (pw->pw_uid == geteuid()) { | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
100 if ((g_mkdir(filename, 0755)) == -1) { |
9272 | 101 gaim_debug_error("silc", "Couldn't create '%s' directory\n", filename); |
8849 | 102 return FALSE; |
103 } | |
104 } else { | |
9272 | 105 gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", |
8849 | 106 filename); |
107 return FALSE; | |
108 } | |
109 } else { | |
9272 | 110 gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", filename, strerror(errno)); |
8849 | 111 return FALSE; |
112 } | |
113 } else { | |
9353 | 114 #ifndef _WIN32 |
8849 | 115 /* Check the owner of the dir */ |
116 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { | |
9272 | 117 gaim_debug_error("silc", "You don't seem to own '%s' directory\n", |
8849 | 118 filename); |
119 return FALSE; | |
120 } | |
9353 | 121 #endif |
8849 | 122 } |
123 | |
124 /* | |
125 * Check ~./silc/serverkeys directory | |
126 */ | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
127 if ((g_stat(servfilename, &st)) == -1) { |
8849 | 128 /* If dir doesn't exist */ |
129 if (errno == ENOENT) { | |
130 if (pw->pw_uid == geteuid()) { | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
131 if ((g_mkdir(servfilename, 0755)) == -1) { |
9272 | 132 gaim_debug_error("silc", "Couldn't create '%s' directory\n", servfilename); |
8849 | 133 return FALSE; |
134 } | |
135 } else { | |
9272 | 136 gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", |
8849 | 137 servfilename); |
138 return FALSE; | |
139 } | |
140 } else { | |
9272 | 141 gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", |
142 servfilename, strerror(errno)); | |
8849 | 143 return FALSE; |
144 } | |
145 } | |
146 | |
147 /* | |
148 * Check ~./silc/clientkeys directory | |
149 */ | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
150 if ((g_stat(clientfilename, &st)) == -1) { |
8849 | 151 /* If dir doesn't exist */ |
152 if (errno == ENOENT) { | |
153 if (pw->pw_uid == geteuid()) { | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
154 if ((g_mkdir(clientfilename, 0755)) == -1) { |
9272 | 155 gaim_debug_error("silc", "Couldn't create '%s' directory\n", clientfilename); |
8849 | 156 return FALSE; |
157 } | |
158 } else { | |
9272 | 159 gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", |
8849 | 160 clientfilename); |
161 return FALSE; | |
162 } | |
163 } else { | |
9272 | 164 gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", |
165 clientfilename, strerror(errno)); | |
8849 | 166 return FALSE; |
167 } | |
168 } | |
169 | |
170 /* | |
171 * Check ~./silc/friends directory | |
172 */ | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
173 if ((g_stat(friendsfilename, &st)) == -1) { |
8849 | 174 /* If dir doesn't exist */ |
175 if (errno == ENOENT) { | |
176 if (pw->pw_uid == geteuid()) { | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
177 if ((g_mkdir(friendsfilename, 0755)) == -1) { |
9272 | 178 gaim_debug_error("silc", "Couldn't create '%s' directory\n", friendsfilename); |
8849 | 179 return FALSE; |
180 } | |
181 } else { | |
9272 | 182 gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", |
8849 | 183 friendsfilename); |
184 return FALSE; | |
185 } | |
186 } else { | |
9272 | 187 gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", |
188 friendsfilename, strerror(errno)); | |
8849 | 189 return FALSE; |
190 } | |
191 } | |
192 | |
193 /* | |
194 * Check Public and Private keys | |
195 */ | |
10825 | 196 g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcgaim_silcdir()); |
197 g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcgaim_silcdir()); | |
8849 | 198 g_snprintf(file_public_key, sizeof(file_public_key) - 1, "%s", |
10825 | 199 gaim_account_get_string(gc->account, "public-key", pkd)); |
8849 | 200 g_snprintf(file_private_key, sizeof(file_public_key) - 1, "%s", |
10825 | 201 gaim_account_get_string(gc->account, "private-key", prd)); |
8849 | 202 |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
203 if ((g_stat(file_public_key, &st)) == -1) { |
8849 | 204 /* If file doesn't exist */ |
205 if (errno == ENOENT) { | |
206 gaim_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); | |
207 silc_create_key_pair(SILCGAIM_DEF_PKCS, | |
208 SILCGAIM_DEF_PKCS_LEN, | |
209 file_public_key, file_private_key, NULL, | |
10751 | 210 (gc->password == NULL) ? "" : gc->password, |
9272 | 211 NULL, NULL, NULL, FALSE); |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
212 g_stat(file_public_key, &st); |
8849 | 213 } else { |
9272 | 214 gaim_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n", |
215 file_public_key, strerror(errno)); | |
8849 | 216 return FALSE; |
217 } | |
218 } | |
219 | |
9353 | 220 #ifndef _WIN32 |
8849 | 221 /* Check the owner of the public key */ |
222 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { | |
9272 | 223 gaim_debug_error("silc", "You don't seem to own your public key!?\n"); |
8849 | 224 return FALSE; |
225 } | |
9353 | 226 #endif |
8849 | 227 |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
228 if ((g_stat(file_private_key, &st)) == -1) { |
8849 | 229 /* If file doesn't exist */ |
230 if (errno == ENOENT) { | |
231 gaim_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); | |
232 silc_create_key_pair(SILCGAIM_DEF_PKCS, | |
233 SILCGAIM_DEF_PKCS_LEN, | |
234 file_public_key, file_private_key, NULL, | |
10751 | 235 (gc->password == NULL) ? "" : gc->password, |
9272 | 236 NULL, NULL, NULL, FALSE); |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
237 g_stat(file_private_key, &st); |
8849 | 238 } else { |
9272 | 239 gaim_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n", |
240 file_private_key, strerror(errno)); | |
8849 | 241 return FALSE; |
242 } | |
243 } | |
244 | |
9353 | 245 #ifndef _WIN32 |
8849 | 246 /* Check the owner of the private key */ |
247 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { | |
9272 | 248 gaim_debug_error("silc", "You don't seem to own your private key!?\n"); |
8849 | 249 return FALSE; |
250 } | |
251 | |
252 /* Check the permissions for the private key */ | |
253 if ((st.st_mode & 0777) != 0600) { | |
9272 | 254 gaim_debug_warning("silc", "Wrong permissions in your private key file `%s'!\n" |
8849 | 255 "Trying to change them ... ", file_private_key); |
256 if ((chmod(file_private_key, 0600)) == -1) { | |
9272 | 257 gaim_debug_error("silc", |
8849 | 258 "Failed to change permissions for private key file!\n" |
259 "Permissions for your private key file must be 0600.\n"); | |
260 return FALSE; | |
261 } | |
9272 | 262 gaim_debug_warning("silc", "Done.\n\n"); |
8849 | 263 } |
9353 | 264 #endif |
8849 | 265 |
266 return TRUE; | |
267 } | |
268 | |
9353 | 269 #ifdef _WIN32 |
270 struct passwd *getpwuid(uid_t uid) { | |
271 struct passwd *pwd = calloc(1, sizeof(struct passwd)); | |
272 return pwd; | |
273 } | |
274 | |
275 uid_t getuid() { | |
276 return 0; | |
277 } | |
278 | |
279 uid_t geteuid() { | |
280 return 0; | |
281 } | |
282 #endif | |
283 | |
8849 | 284 void silcgaim_show_public_key(SilcGaim sg, |
285 const char *name, SilcPublicKey public_key, | |
286 GCallback callback, void *context) | |
287 { | |
288 SilcPublicKeyIdentifier ident; | |
289 SilcPKCS pkcs; | |
290 char *fingerprint, *babbleprint; | |
291 unsigned char *pk; | |
292 SilcUInt32 pk_len, key_len = 0; | |
293 GString *s; | |
294 char *buf; | |
295 | |
296 ident = silc_pkcs_decode_identifier(public_key->identifier); | |
297 if (!ident) | |
298 return; | |
299 | |
300 pk = silc_pkcs_public_key_encode(public_key, &pk_len); | |
301 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); | |
302 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); | |
303 | |
11488 | 304 if (silc_pkcs_alloc((unsigned char *)public_key->name, &pkcs)) { |
8849 | 305 key_len = silc_pkcs_public_key_set(pkcs, public_key); |
306 silc_pkcs_free(pkcs); | |
307 } | |
308 | |
309 s = g_string_new(""); | |
310 if (ident->realname) | |
10825 | 311 /* Hint for translators: Please check the tabulator width here and in |
312 the next strings (short strings: 2 tabs, longer strings 1 tab, | |
9274 | 313 sum: 3 tabs or 24 characters) */ |
314 g_string_append_printf(s, _("Real Name: \t%s\n"), ident->realname); | |
8849 | 315 if (ident->username) |
9274 | 316 g_string_append_printf(s, _("User Name: \t%s\n"), ident->username); |
8849 | 317 if (ident->email) |
9274 | 318 g_string_append_printf(s, _("EMail: \t\t%s\n"), ident->email); |
8849 | 319 if (ident->host) |
9274 | 320 g_string_append_printf(s, _("Host Name: \t%s\n"), ident->host); |
8849 | 321 if (ident->org) |
9274 | 322 g_string_append_printf(s, _("Organization: \t%s\n"), ident->org); |
8849 | 323 if (ident->country) |
9274 | 324 g_string_append_printf(s, _("Country: \t%s\n"), ident->country); |
9488 | 325 g_string_append_printf(s, _("Algorithm: \t%s\n"), public_key->name); |
9274 | 326 g_string_append_printf(s, _("Key Length: \t%d bits\n"), (int)key_len); |
327 g_string_append_printf(s, "\n"); | |
328 g_string_append_printf(s, _("Public Key Fingerprint:\n%s\n\n"), fingerprint); | |
329 g_string_append_printf(s, _("Public Key Babbleprint:\n%s"), babbleprint); | |
8849 | 330 |
331 buf = g_string_free(s, FALSE); | |
332 | |
11201 | 333 gaim_request_action(sg->gc, _("Public Key Information"), |
8849 | 334 _("Public Key Information"), |
335 buf, 0, context, 1, | |
336 _("Close"), callback); | |
337 | |
338 g_free(buf); | |
339 silc_free(fingerprint); | |
340 silc_free(babbleprint); | |
341 silc_free(pk); | |
342 silc_pkcs_free_identifier(ident); | |
343 } | |
344 | |
345 SilcAttributePayload | |
346 silcgaim_get_attr(SilcDList attrs, SilcAttribute attribute) | |
347 { | |
348 SilcAttributePayload attr = NULL; | |
349 | |
350 if (!attrs) | |
351 return NULL; | |
352 | |
353 silc_dlist_start(attrs); | |
354 while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) | |
355 if (attribute == silc_attribute_get_attribute(attr)) | |
356 break; | |
357 | |
358 return attr; | |
359 } | |
360 | |
361 void silcgaim_get_umode_string(SilcUInt32 mode, char *buf, | |
362 SilcUInt32 buf_size) | |
363 { | |
364 memset(buf, 0, buf_size); | |
365 if ((mode & SILC_UMODE_SERVER_OPERATOR) || | |
366 (mode & SILC_UMODE_ROUTER_OPERATOR)) { | |
367 strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ? | |
368 "[server operator] " : | |
369 (mode & SILC_UMODE_ROUTER_OPERATOR) ? | |
370 "[SILC operator] " : "[unknown mode] "); | |
371 } | |
372 if (mode & SILC_UMODE_GONE) | |
373 strcat(buf, "[away] "); | |
374 if (mode & SILC_UMODE_INDISPOSED) | |
375 strcat(buf, "[indisposed] "); | |
376 if (mode & SILC_UMODE_BUSY) | |
377 strcat(buf, "[busy] "); | |
378 if (mode & SILC_UMODE_PAGE) | |
379 strcat(buf, "[wake me up] "); | |
380 if (mode & SILC_UMODE_HYPER) | |
381 strcat(buf, "[hyperactive] "); | |
382 if (mode & SILC_UMODE_ROBOT) | |
383 strcat(buf, "[robot] "); | |
384 if (mode & SILC_UMODE_ANONYMOUS) | |
385 strcat(buf, "[anonymous] "); | |
386 if (mode & SILC_UMODE_BLOCK_PRIVMSG) | |
387 strcat(buf, "[blocks private messages] "); | |
388 if (mode & SILC_UMODE_DETACHED) | |
389 strcat(buf, "[detached] "); | |
390 if (mode & SILC_UMODE_REJECT_WATCHING) | |
391 strcat(buf, "[rejects watching] "); | |
392 if (mode & SILC_UMODE_BLOCK_INVITE) | |
393 strcat(buf, "[blocks invites] "); | |
394 } | |
395 | |
396 void silcgaim_get_chmode_string(SilcUInt32 mode, char *buf, | |
397 SilcUInt32 buf_size) | |
398 { | |
399 memset(buf, 0, buf_size); | |
400 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) | |
401 strcat(buf, "[permanent] "); | |
402 if (mode & SILC_CHANNEL_MODE_PRIVATE) | |
403 strcat(buf, "[private] "); | |
404 if (mode & SILC_CHANNEL_MODE_SECRET) | |
405 strcat(buf, "[secret] "); | |
406 if (mode & SILC_CHANNEL_MODE_SECRET) | |
407 strcat(buf, "[secret] "); | |
408 if (mode & SILC_CHANNEL_MODE_PRIVKEY) | |
409 strcat(buf, "[private key] "); | |
410 if (mode & SILC_CHANNEL_MODE_INVITE) | |
411 strcat(buf, "[invite only] "); | |
412 if (mode & SILC_CHANNEL_MODE_TOPIC) | |
413 strcat(buf, "[topic restricted] "); | |
414 if (mode & SILC_CHANNEL_MODE_ULIMIT) | |
415 strcat(buf, "[user count limit] "); | |
416 if (mode & SILC_CHANNEL_MODE_PASSPHRASE) | |
417 strcat(buf, "[passphrase auth] "); | |
418 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) | |
419 strcat(buf, "[public key auth] "); | |
420 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) | |
421 strcat(buf, "[users silenced] "); | |
422 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) | |
423 strcat(buf, "[operators silenced] "); | |
424 } | |
425 | |
426 void silcgaim_get_chumode_string(SilcUInt32 mode, char *buf, | |
427 SilcUInt32 buf_size) | |
428 { | |
429 memset(buf, 0, buf_size); | |
430 if (mode & SILC_CHANNEL_UMODE_CHANFO) | |
431 strcat(buf, "[founder] "); | |
432 if (mode & SILC_CHANNEL_UMODE_CHANOP) | |
433 strcat(buf, "[operator] "); | |
434 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) | |
435 strcat(buf, "[blocks messages] "); | |
436 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) | |
437 strcat(buf, "[blocks user messages] "); | |
438 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) | |
439 strcat(buf, "[blocks robot messages] "); | |
440 if (mode & SILC_CHANNEL_UMODE_QUIET) | |
441 strcat(buf, "[quieted] "); | |
442 } | |
9488 | 443 |
444 void | |
445 silcgaim_parse_attrs(SilcDList attrs, char **moodstr, char **statusstr, | |
446 char **contactstr, char **langstr, char **devicestr, | |
447 char **tzstr, char **geostr) | |
448 { | |
449 SilcAttributePayload attr; | |
450 SilcAttributeMood mood = 0; | |
451 SilcAttributeContact contact; | |
452 SilcAttributeObjDevice device; | |
453 SilcAttributeObjGeo geo; | |
454 | |
455 char tmp[1024]; | |
456 GString *s; | |
457 | |
458 *moodstr = NULL; | |
459 *statusstr = NULL; | |
460 *contactstr = NULL; | |
461 *langstr = NULL; | |
462 *devicestr = NULL; | |
463 *tzstr = NULL; | |
464 *geostr = NULL; | |
465 | |
466 if (!attrs) | |
467 return; | |
468 | |
469 s = g_string_new(""); | |
470 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_STATUS_MOOD); | |
471 if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) { | |
472 if (mood & SILC_ATTRIBUTE_MOOD_HAPPY) | |
473 g_string_append_printf(s, "[%s] ", _("Happy")); | |
474 if (mood & SILC_ATTRIBUTE_MOOD_SAD) | |
475 g_string_append_printf(s, "[%s] ", _("Sad")); | |
476 if (mood & SILC_ATTRIBUTE_MOOD_ANGRY) | |
477 g_string_append_printf(s, "[%s] ", _("Angry")); | |
478 if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS) | |
479 g_string_append_printf(s, "[%s] ", _("Jealous")); | |
480 if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED) | |
481 g_string_append_printf(s, "[%s] ", _("Ashamed")); | |
482 if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE) | |
483 g_string_append_printf(s, "[%s] ", _("Invincible")); | |
484 if (mood & SILC_ATTRIBUTE_MOOD_INLOVE) | |
485 g_string_append_printf(s, "[%s] ", _("In Love")); | |
486 if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY) | |
487 g_string_append_printf(s, "[%s] ", _("Sleepy")); | |
488 if (mood & SILC_ATTRIBUTE_MOOD_BORED) | |
489 g_string_append_printf(s, "[%s] ", _("Bored")); | |
490 if (mood & SILC_ATTRIBUTE_MOOD_EXCITED) | |
491 g_string_append_printf(s, "[%s] ", _("Excited")); | |
492 if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS) | |
493 g_string_append_printf(s, "[%s] ", _("Anxious")); | |
494 } | |
495 if (strlen(s->str)) { | |
496 *moodstr = s->str; | |
497 g_string_free(s, FALSE); | |
498 } else | |
499 g_string_free(s, TRUE); | |
500 | |
501 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_STATUS_FREETEXT); | |
502 memset(tmp, 0, sizeof(tmp)); | |
503 if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) | |
504 *statusstr = g_strdup(tmp); | |
505 | |
506 s = g_string_new(""); | |
507 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_CONTACT); | |
508 if (attr && silc_attribute_get_object(attr, &contact, sizeof(contact))) { | |
509 if (contact & SILC_ATTRIBUTE_CONTACT_CHAT) | |
510 g_string_append_printf(s, "[%s] ", _("Chat")); | |
511 if (contact & SILC_ATTRIBUTE_CONTACT_EMAIL) | |
512 g_string_append_printf(s, "[%s] ", _("Email")); | |
513 if (contact & SILC_ATTRIBUTE_CONTACT_CALL) | |
514 g_string_append_printf(s, "[%s] ", _("Phone")); | |
515 if (contact & SILC_ATTRIBUTE_CONTACT_PAGE) | |
516 g_string_append_printf(s, "[%s] ", _("Paging")); | |
517 if (contact & SILC_ATTRIBUTE_CONTACT_SMS) | |
518 g_string_append_printf(s, "[%s] ", _("SMS")); | |
519 if (contact & SILC_ATTRIBUTE_CONTACT_MMS) | |
520 g_string_append_printf(s, "[%s] ", _("MMS")); | |
521 if (contact & SILC_ATTRIBUTE_CONTACT_VIDEO) | |
522 g_string_append_printf(s, "[%s] ", _("Video Conferencing")); | |
523 } | |
524 if (strlen(s->str)) { | |
525 *contactstr = s->str; | |
526 g_string_free(s, FALSE); | |
527 } else | |
528 g_string_free(s, TRUE); | |
529 | |
530 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_LANGUAGE); | |
531 memset(tmp, 0, sizeof(tmp)); | |
532 if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) | |
533 *langstr = g_strdup(tmp); | |
534 | |
535 s = g_string_new(""); | |
536 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_DEVICE_INFO); | |
537 memset(&device, 0, sizeof(device)); | |
538 if (attr && silc_attribute_get_object(attr, &device, sizeof(device))) { | |
539 if (device.type == SILC_ATTRIBUTE_DEVICE_COMPUTER) | |
540 g_string_append_printf(s, "%s: ", _("Computer")); | |
541 if (device.type == SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE) | |
542 g_string_append_printf(s, "%s: ", _("Mobile Phone")); | |
543 if (device.type == SILC_ATTRIBUTE_DEVICE_PDA) | |
544 g_string_append_printf(s, "%s: ", _("PDA")); | |
545 if (device.type == SILC_ATTRIBUTE_DEVICE_TERMINAL) | |
546 g_string_append_printf(s, "%s: ", _("Terminal")); | |
547 g_string_append_printf(s, "%s %s %s %s", | |
548 device.manufacturer ? device.manufacturer : "", | |
549 device.version ? device.version : "", | |
550 device.model ? device.model : "", | |
551 device.language ? device.language : ""); | |
552 } | |
553 if (strlen(s->str)) { | |
554 *devicestr = s->str; | |
555 g_string_free(s, FALSE); | |
556 } else | |
557 g_string_free(s, TRUE); | |
558 | |
559 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_TIMEZONE); | |
560 memset(tmp, 0, sizeof(tmp)); | |
561 if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) | |
562 *tzstr = g_strdup(tmp); | |
563 | |
564 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_GEOLOCATION); | |
565 memset(&geo, 0, sizeof(geo)); | |
566 if (attr && silc_attribute_get_object(attr, &geo, sizeof(geo))) | |
567 *geostr = g_strdup_printf("%s %s %s (%s)", | |
568 geo.longitude ? geo.longitude : "", | |
569 geo.latitude ? geo.latitude : "", | |
570 geo.altitude ? geo.altitude : "", | |
571 geo.accuracy ? geo.accuracy : ""); | |
572 } | |
12217 | 573 |
574 #ifdef HAVE_SILCMIME_H | |
575 /* Returns MIME type of filetype */ | |
576 | |
577 char *silcgaim_file2mime(const char *filename) | |
578 { | |
579 const char *ct; | |
580 | |
581 ct = strrchr(filename, '.'); | |
582 if (!ct) | |
583 return NULL; | |
584 else if (!strcasecmp(".png", ct)) | |
585 return strdup("image/png"); | |
586 else if (!strcasecmp(".jpg", ct)) | |
587 return strdup("image/jpeg"); | |
588 else if (!strcasecmp(".jpeg", ct)) | |
589 return strdup("image/jpeg"); | |
590 else if (!strcasecmp(".gif", ct)) | |
591 return strdup("image/gif"); | |
592 else if (!strcasecmp(".tiff", ct)) | |
593 return strdup("image/tiff"); | |
594 | |
595 return NULL; | |
596 } | |
597 | |
598 /* Checks if message has images, and assembles MIME message if it has. | |
599 If only one image is present, creates simple MIME image message. If | |
600 there are multiple images and/or text with images multipart MIME | |
601 message is created. */ | |
602 | |
603 SilcDList silcgaim_image_message(const char *msg, SilcUInt32 *mflags) | |
604 { | |
605 SilcMime mime = NULL, p; | |
606 SilcDList list, parts = NULL; | |
607 const char *start, *end, *last; | |
608 GData *attribs; | |
609 char *type; | |
610 gboolean images = FALSE; | |
611 | |
612 last = msg; | |
613 while (last && *last && gaim_markup_find_tag("img", last, &start, | |
614 &end, &attribs)) { | |
615 GaimStoredImage *image = NULL; | |
616 const char *id; | |
617 | |
618 /* Check if there is text before image */ | |
619 if (start - last) { | |
620 char *text, *tmp; | |
621 p = silc_mime_alloc(); | |
622 | |
623 /* Add content type */ | |
624 silc_mime_add_field(p, "Content-Type", | |
625 "text/plain; charset=utf-8"); | |
626 | |
627 tmp = g_strndup(last, start - last); | |
628 text = gaim_unescape_html(tmp); | |
629 g_free(tmp); | |
630 /* Add text */ | |
631 silc_mime_add_data(p, text, strlen(text)); | |
632 g_free(text); | |
633 | |
634 if (!parts) | |
635 parts = silc_dlist_init(); | |
636 silc_dlist_add(parts, p); | |
637 } | |
638 | |
639 id = g_datalist_get_data(&attribs, "id"); | |
640 if (id && (image = gaim_imgstore_get(atoi(id)))) { | |
641 unsigned long imglen = gaim_imgstore_get_size(image); | |
642 gpointer img = gaim_imgstore_get_data(image); | |
643 | |
644 p = silc_mime_alloc(); | |
645 | |
646 /* Add content type */ | |
647 type = silcgaim_file2mime(gaim_imgstore_get_filename(image)); | |
648 if (!type) { | |
649 g_datalist_clear(&attribs); | |
650 last = end + 1; | |
651 continue; | |
652 } | |
653 silc_mime_add_field(p, "Content-Type", type); | |
654 silc_free(type); | |
655 | |
656 /* Add content transfer encoding */ | |
657 silc_mime_add_field(p, "Content-Transfer-Encoding", "binary"); | |
658 | |
659 /* Add image data */ | |
660 silc_mime_add_data(p, img, imglen); | |
661 | |
662 if (!parts) | |
663 parts = silc_dlist_init(); | |
664 silc_dlist_add(parts, p); | |
665 images = TRUE; | |
666 } | |
667 | |
668 g_datalist_clear(&attribs); | |
669 | |
670 /* Continue after tag */ | |
671 last = end + 1; | |
672 } | |
673 | |
674 /* Check for text after the image(s) */ | |
675 if (images && last && *last) { | |
676 char *tmp = gaim_unescape_html(last); | |
677 p = silc_mime_alloc(); | |
678 | |
679 /* Add content type */ | |
680 silc_mime_add_field(p, "Content-Type", | |
681 "text/plain; charset=utf-8"); | |
682 | |
683 /* Add text */ | |
684 silc_mime_add_data(p, tmp, strlen(tmp)); | |
685 g_free(tmp); | |
686 | |
687 if (!parts) | |
688 parts = silc_dlist_init(); | |
689 silc_dlist_add(parts, p); | |
690 } | |
691 | |
692 /* If there weren't any images, don't return anything. */ | |
693 if (!images) { | |
694 if (parts) | |
695 silc_dlist_uninit(parts); | |
696 return NULL; | |
697 } | |
698 | |
699 if (silc_dlist_count(parts) > 1) { | |
700 /* Multipart MIME message */ | |
701 char b[32]; | |
702 mime = silc_mime_alloc(); | |
703 silc_mime_add_field(mime, "MIME-Version", "1.0"); | |
704 g_snprintf(b, sizeof(b), "b%4X%4X", | |
705 (unsigned int)time(NULL), | |
706 silc_dlist_count(parts)); | |
707 silc_mime_set_multipart(mime, "mixed", b); | |
708 silc_dlist_start(parts); | |
709 while ((p = silc_dlist_get(parts)) != SILC_LIST_END) | |
710 silc_mime_add_multipart(mime, p); | |
711 } else { | |
712 /* Simple MIME message */ | |
713 silc_dlist_start(parts); | |
714 mime = silc_dlist_get(parts); | |
715 silc_mime_add_field(mime, "MIME-Version", "1.0"); | |
716 } | |
717 | |
718 *mflags &= ~SILC_MESSAGE_FLAG_UTF8; | |
719 *mflags |= SILC_MESSAGE_FLAG_DATA; | |
720 | |
721 /* Encode message. Fragment if it is too large */ | |
722 list = silc_mime_encode_partial(mime, 0xfc00); | |
723 | |
724 silc_dlist_uninit(parts); | |
725 | |
726 /* Added multiparts gets freed here */ | |
727 silc_mime_free(mime); | |
728 | |
729 return list; | |
730 } | |
731 | |
732 #endif /* HAVE_SILCMIME_H */ |