Mercurial > pidgin
annotate src/protocols/silc/util.c @ 14122:dabbcb9b013d
[gaim-migrate @ 16759]
This initializes threads for glib and dbus, because under some
circumstances multithreaded libraries are causing dbus badness
(namely, gnome-vfs). This fix doesn't really belong in Gaim, but in
the interest of expedience (we don't want to wait for upstream
libraries to get their initializations all worked around to make
things safe) the fix goes here. Note that all Gaim frontends will
have to initialize glib threads if other threaded libraries which
interact with glib or dbus or what-have-you come into play.
committer: Tailor Script <tailor@pidgin.im>
| author | Ethan Blanton <elb@pidgin.im> |
|---|---|
| date | Mon, 14 Aug 2006 21:46:17 +0000 |
| parents | 545dbc931e8c |
| children | 0154168c414a |
| 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; | |
| 13659 | 78 int fd; |
| 8849 | 79 |
| 80 pw = getpwuid(getuid()); | |
| 81 if (!pw) { | |
| 9272 | 82 gaim_debug_error("silc", "silc: %s\n", strerror(errno)); |
| 8849 | 83 return FALSE; |
| 84 } | |
| 85 | |
| 9353 | 86 g_snprintf(filename, sizeof(filename) - 1, "%s", silcgaim_silcdir()); |
| 8849 | 87 g_snprintf(servfilename, sizeof(servfilename) - 1, "%s" G_DIR_SEPARATOR_S "serverkeys", |
| 88 silcgaim_silcdir()); | |
| 89 g_snprintf(clientfilename, sizeof(clientfilename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys", | |
| 90 silcgaim_silcdir()); | |
| 91 g_snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s" G_DIR_SEPARATOR_S "friends", | |
| 92 silcgaim_silcdir()); | |
| 93 | |
| 94 /* | |
| 95 * Check ~/.silc directory | |
| 96 */ | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
97 if ((g_stat(filename, &st)) == -1) { |
| 8849 | 98 /* If dir doesn't exist */ |
| 99 if (errno == ENOENT) { | |
| 100 if (pw->pw_uid == geteuid()) { | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
101 if ((g_mkdir(filename, 0755)) == -1) { |
| 9272 | 102 gaim_debug_error("silc", "Couldn't create '%s' directory\n", filename); |
| 8849 | 103 return FALSE; |
| 104 } | |
| 105 } else { | |
| 9272 | 106 gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", |
| 8849 | 107 filename); |
| 108 return FALSE; | |
| 109 } | |
| 110 } else { | |
| 9272 | 111 gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", filename, strerror(errno)); |
| 8849 | 112 return FALSE; |
| 113 } | |
| 114 } else { | |
| 9353 | 115 #ifndef _WIN32 |
| 8849 | 116 /* Check the owner of the dir */ |
| 117 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { | |
| 9272 | 118 gaim_debug_error("silc", "You don't seem to own '%s' directory\n", |
| 8849 | 119 filename); |
| 120 return FALSE; | |
| 121 } | |
| 9353 | 122 #endif |
| 8849 | 123 } |
| 124 | |
| 125 /* | |
| 126 * Check ~./silc/serverkeys directory | |
| 127 */ | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
128 if ((g_stat(servfilename, &st)) == -1) { |
| 8849 | 129 /* If dir doesn't exist */ |
| 130 if (errno == ENOENT) { | |
| 131 if (pw->pw_uid == geteuid()) { | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
132 if ((g_mkdir(servfilename, 0755)) == -1) { |
| 9272 | 133 gaim_debug_error("silc", "Couldn't create '%s' directory\n", servfilename); |
| 8849 | 134 return FALSE; |
| 135 } | |
| 136 } else { | |
| 9272 | 137 gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", |
| 8849 | 138 servfilename); |
| 139 return FALSE; | |
| 140 } | |
| 141 } else { | |
| 9272 | 142 gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", |
| 143 servfilename, strerror(errno)); | |
| 8849 | 144 return FALSE; |
| 145 } | |
| 146 } | |
| 147 | |
| 148 /* | |
| 149 * Check ~./silc/clientkeys directory | |
| 150 */ | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
151 if ((g_stat(clientfilename, &st)) == -1) { |
| 8849 | 152 /* If dir doesn't exist */ |
| 153 if (errno == ENOENT) { | |
| 154 if (pw->pw_uid == geteuid()) { | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
155 if ((g_mkdir(clientfilename, 0755)) == -1) { |
| 9272 | 156 gaim_debug_error("silc", "Couldn't create '%s' directory\n", clientfilename); |
| 8849 | 157 return FALSE; |
| 158 } | |
| 159 } else { | |
| 9272 | 160 gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", |
| 8849 | 161 clientfilename); |
| 162 return FALSE; | |
| 163 } | |
| 164 } else { | |
| 9272 | 165 gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", |
| 166 clientfilename, strerror(errno)); | |
| 8849 | 167 return FALSE; |
| 168 } | |
| 169 } | |
| 170 | |
| 171 /* | |
| 172 * Check ~./silc/friends directory | |
| 173 */ | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
174 if ((g_stat(friendsfilename, &st)) == -1) { |
| 8849 | 175 /* If dir doesn't exist */ |
| 176 if (errno == ENOENT) { | |
| 177 if (pw->pw_uid == geteuid()) { | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
178 if ((g_mkdir(friendsfilename, 0755)) == -1) { |
| 9272 | 179 gaim_debug_error("silc", "Couldn't create '%s' directory\n", friendsfilename); |
| 8849 | 180 return FALSE; |
| 181 } | |
| 182 } else { | |
| 9272 | 183 gaim_debug_error("silc", "Couldn't create '%s' directory due to a wrong uid!\n", |
| 8849 | 184 friendsfilename); |
| 185 return FALSE; | |
| 186 } | |
| 187 } else { | |
| 9272 | 188 gaim_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", |
| 189 friendsfilename, strerror(errno)); | |
| 8849 | 190 return FALSE; |
| 191 } | |
| 192 } | |
| 193 | |
| 194 /* | |
| 195 * Check Public and Private keys | |
| 196 */ | |
| 10825 | 197 g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcgaim_silcdir()); |
| 198 g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcgaim_silcdir()); | |
| 8849 | 199 g_snprintf(file_public_key, sizeof(file_public_key) - 1, "%s", |
| 10825 | 200 gaim_account_get_string(gc->account, "public-key", pkd)); |
| 8849 | 201 g_snprintf(file_private_key, sizeof(file_public_key) - 1, "%s", |
| 10825 | 202 gaim_account_get_string(gc->account, "private-key", prd)); |
| 8849 | 203 |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
204 if ((g_stat(file_public_key, &st)) == -1) { |
| 8849 | 205 /* If file doesn't exist */ |
| 206 if (errno == ENOENT) { | |
| 207 gaim_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); | |
|
14086
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
208 if (!silc_create_key_pair(SILCGAIM_DEF_PKCS, |
| 8849 | 209 SILCGAIM_DEF_PKCS_LEN, |
| 210 file_public_key, file_private_key, NULL, | |
| 10751 | 211 (gc->password == NULL) ? "" : gc->password, |
|
14086
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
212 NULL, NULL, NULL, FALSE)) { |
|
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
213 gaim_debug_error("silc", "Couldn't create key pair\n"); |
|
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
214 return FALSE; |
|
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
215 } |
|
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
216 |
|
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
217 if ((g_stat(file_public_key, &st)) == -1) { |
|
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
218 gaim_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n", |
|
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
219 file_public_key, strerror(errno)); |
|
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
220 return FALSE; |
|
545dbc931e8c
[gaim-migrate @ 16709]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
13659
diff
changeset
|
221 } |
| 8849 | 222 } else { |
| 9272 | 223 gaim_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n", |
| 224 file_public_key, strerror(errno)); | |
| 8849 | 225 return FALSE; |
| 226 } | |
| 227 } | |
| 228 | |
| 9353 | 229 #ifndef _WIN32 |
| 8849 | 230 /* Check the owner of the public key */ |
| 231 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { | |
| 9272 | 232 gaim_debug_error("silc", "You don't seem to own your public key!?\n"); |
| 8849 | 233 return FALSE; |
| 234 } | |
| 9353 | 235 #endif |
| 8849 | 236 |
| 13659 | 237 fd = open(file_private_key, O_RDONLY); |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
238 if ((g_stat(file_private_key, &st)) == -1) { |
| 8849 | 239 /* If file doesn't exist */ |
| 240 if (errno == ENOENT) { | |
| 241 gaim_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5); | |
| 242 silc_create_key_pair(SILCGAIM_DEF_PKCS, | |
| 243 SILCGAIM_DEF_PKCS_LEN, | |
| 244 file_public_key, file_private_key, NULL, | |
| 10751 | 245 (gc->password == NULL) ? "" : gc->password, |
| 9272 | 246 NULL, NULL, NULL, FALSE); |
| 13659 | 247 if (fd != -1) |
| 248 close(fd); | |
| 249 fd = open(file_private_key, O_RDONLY); | |
|
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
9488
diff
changeset
|
250 g_stat(file_private_key, &st); |
| 8849 | 251 } else { |
| 9272 | 252 gaim_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n", |
| 253 file_private_key, strerror(errno)); | |
| 13659 | 254 if (fd != -1) |
| 255 close(fd); | |
| 8849 | 256 return FALSE; |
| 257 } | |
| 258 } | |
| 259 | |
| 9353 | 260 #ifndef _WIN32 |
| 8849 | 261 /* Check the owner of the private key */ |
| 262 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { | |
| 9272 | 263 gaim_debug_error("silc", "You don't seem to own your private key!?\n"); |
| 13659 | 264 if (fd != -1) |
| 265 close(fd); | |
| 8849 | 266 return FALSE; |
| 267 } | |
| 268 | |
| 269 /* Check the permissions for the private key */ | |
| 270 if ((st.st_mode & 0777) != 0600) { | |
| 9272 | 271 gaim_debug_warning("silc", "Wrong permissions in your private key file `%s'!\n" |
| 13659 | 272 "Trying to change them ...\n", file_private_key); |
| 273 if ((fd != -1) && (fchmod(fd, S_IRUSR | S_IWUSR)) == -1) { | |
| 9272 | 274 gaim_debug_error("silc", |
| 8849 | 275 "Failed to change permissions for private key file!\n" |
| 276 "Permissions for your private key file must be 0600.\n"); | |
| 13659 | 277 if (fd != -1) |
| 278 close(fd); | |
| 8849 | 279 return FALSE; |
| 280 } | |
| 9272 | 281 gaim_debug_warning("silc", "Done.\n\n"); |
| 8849 | 282 } |
| 9353 | 283 #endif |
| 8849 | 284 |
| 13659 | 285 if (fd != -1) |
| 286 close(fd); | |
| 287 | |
| 8849 | 288 return TRUE; |
| 289 } | |
| 290 | |
| 9353 | 291 #ifdef _WIN32 |
| 292 struct passwd *getpwuid(uid_t uid) { | |
| 293 struct passwd *pwd = calloc(1, sizeof(struct passwd)); | |
| 294 return pwd; | |
| 295 } | |
| 296 | |
| 297 uid_t getuid() { | |
| 298 return 0; | |
| 299 } | |
| 300 | |
| 301 uid_t geteuid() { | |
| 302 return 0; | |
| 303 } | |
| 304 #endif | |
| 305 | |
| 8849 | 306 void silcgaim_show_public_key(SilcGaim sg, |
| 307 const char *name, SilcPublicKey public_key, | |
| 308 GCallback callback, void *context) | |
| 309 { | |
| 310 SilcPublicKeyIdentifier ident; | |
| 311 SilcPKCS pkcs; | |
| 312 char *fingerprint, *babbleprint; | |
| 313 unsigned char *pk; | |
| 314 SilcUInt32 pk_len, key_len = 0; | |
| 315 GString *s; | |
| 316 char *buf; | |
| 317 | |
| 318 ident = silc_pkcs_decode_identifier(public_key->identifier); | |
| 319 if (!ident) | |
| 320 return; | |
| 321 | |
| 322 pk = silc_pkcs_public_key_encode(public_key, &pk_len); | |
| 323 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); | |
| 324 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); | |
| 325 | |
| 11488 | 326 if (silc_pkcs_alloc((unsigned char *)public_key->name, &pkcs)) { |
| 8849 | 327 key_len = silc_pkcs_public_key_set(pkcs, public_key); |
| 328 silc_pkcs_free(pkcs); | |
| 329 } | |
| 330 | |
| 331 s = g_string_new(""); | |
| 332 if (ident->realname) | |
| 10825 | 333 /* Hint for translators: Please check the tabulator width here and in |
| 334 the next strings (short strings: 2 tabs, longer strings 1 tab, | |
| 9274 | 335 sum: 3 tabs or 24 characters) */ |
| 336 g_string_append_printf(s, _("Real Name: \t%s\n"), ident->realname); | |
| 8849 | 337 if (ident->username) |
| 9274 | 338 g_string_append_printf(s, _("User Name: \t%s\n"), ident->username); |
| 8849 | 339 if (ident->email) |
|
13545
cfc2f7fcb3dd
[gaim-migrate @ 15922]
Richard Laager <rlaager@wiktel.com>
parents:
12217
diff
changeset
|
340 g_string_append_printf(s, _("E-Mail: \t\t%s\n"), ident->email); |
| 8849 | 341 if (ident->host) |
| 9274 | 342 g_string_append_printf(s, _("Host Name: \t%s\n"), ident->host); |
| 8849 | 343 if (ident->org) |
| 9274 | 344 g_string_append_printf(s, _("Organization: \t%s\n"), ident->org); |
| 8849 | 345 if (ident->country) |
| 9274 | 346 g_string_append_printf(s, _("Country: \t%s\n"), ident->country); |
| 9488 | 347 g_string_append_printf(s, _("Algorithm: \t%s\n"), public_key->name); |
| 9274 | 348 g_string_append_printf(s, _("Key Length: \t%d bits\n"), (int)key_len); |
| 349 g_string_append_printf(s, "\n"); | |
| 350 g_string_append_printf(s, _("Public Key Fingerprint:\n%s\n\n"), fingerprint); | |
| 351 g_string_append_printf(s, _("Public Key Babbleprint:\n%s"), babbleprint); | |
| 8849 | 352 |
| 353 buf = g_string_free(s, FALSE); | |
| 354 | |
| 11201 | 355 gaim_request_action(sg->gc, _("Public Key Information"), |
| 8849 | 356 _("Public Key Information"), |
| 357 buf, 0, context, 1, | |
| 358 _("Close"), callback); | |
| 359 | |
| 360 g_free(buf); | |
| 361 silc_free(fingerprint); | |
| 362 silc_free(babbleprint); | |
| 363 silc_free(pk); | |
| 364 silc_pkcs_free_identifier(ident); | |
| 365 } | |
| 366 | |
| 367 SilcAttributePayload | |
| 368 silcgaim_get_attr(SilcDList attrs, SilcAttribute attribute) | |
| 369 { | |
| 370 SilcAttributePayload attr = NULL; | |
| 371 | |
| 372 if (!attrs) | |
| 373 return NULL; | |
| 374 | |
| 375 silc_dlist_start(attrs); | |
| 376 while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) | |
| 377 if (attribute == silc_attribute_get_attribute(attr)) | |
| 378 break; | |
| 379 | |
| 380 return attr; | |
| 381 } | |
| 382 | |
| 383 void silcgaim_get_umode_string(SilcUInt32 mode, char *buf, | |
| 384 SilcUInt32 buf_size) | |
| 385 { | |
| 386 memset(buf, 0, buf_size); | |
| 387 if ((mode & SILC_UMODE_SERVER_OPERATOR) || | |
| 388 (mode & SILC_UMODE_ROUTER_OPERATOR)) { | |
| 389 strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ? | |
| 390 "[server operator] " : | |
| 391 (mode & SILC_UMODE_ROUTER_OPERATOR) ? | |
| 392 "[SILC operator] " : "[unknown mode] "); | |
| 393 } | |
| 394 if (mode & SILC_UMODE_GONE) | |
| 395 strcat(buf, "[away] "); | |
| 396 if (mode & SILC_UMODE_INDISPOSED) | |
| 397 strcat(buf, "[indisposed] "); | |
| 398 if (mode & SILC_UMODE_BUSY) | |
| 399 strcat(buf, "[busy] "); | |
| 400 if (mode & SILC_UMODE_PAGE) | |
| 401 strcat(buf, "[wake me up] "); | |
| 402 if (mode & SILC_UMODE_HYPER) | |
| 403 strcat(buf, "[hyperactive] "); | |
| 404 if (mode & SILC_UMODE_ROBOT) | |
| 405 strcat(buf, "[robot] "); | |
| 406 if (mode & SILC_UMODE_ANONYMOUS) | |
| 407 strcat(buf, "[anonymous] "); | |
| 408 if (mode & SILC_UMODE_BLOCK_PRIVMSG) | |
| 409 strcat(buf, "[blocks private messages] "); | |
| 410 if (mode & SILC_UMODE_DETACHED) | |
| 411 strcat(buf, "[detached] "); | |
| 412 if (mode & SILC_UMODE_REJECT_WATCHING) | |
| 413 strcat(buf, "[rejects watching] "); | |
| 414 if (mode & SILC_UMODE_BLOCK_INVITE) | |
| 415 strcat(buf, "[blocks invites] "); | |
| 416 } | |
| 417 | |
| 418 void silcgaim_get_chmode_string(SilcUInt32 mode, char *buf, | |
| 419 SilcUInt32 buf_size) | |
| 420 { | |
| 421 memset(buf, 0, buf_size); | |
| 422 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) | |
| 423 strcat(buf, "[permanent] "); | |
| 424 if (mode & SILC_CHANNEL_MODE_PRIVATE) | |
| 425 strcat(buf, "[private] "); | |
| 426 if (mode & SILC_CHANNEL_MODE_SECRET) | |
| 427 strcat(buf, "[secret] "); | |
| 428 if (mode & SILC_CHANNEL_MODE_SECRET) | |
| 429 strcat(buf, "[secret] "); | |
| 430 if (mode & SILC_CHANNEL_MODE_PRIVKEY) | |
| 431 strcat(buf, "[private key] "); | |
| 432 if (mode & SILC_CHANNEL_MODE_INVITE) | |
| 433 strcat(buf, "[invite only] "); | |
| 434 if (mode & SILC_CHANNEL_MODE_TOPIC) | |
| 435 strcat(buf, "[topic restricted] "); | |
| 436 if (mode & SILC_CHANNEL_MODE_ULIMIT) | |
| 437 strcat(buf, "[user count limit] "); | |
| 438 if (mode & SILC_CHANNEL_MODE_PASSPHRASE) | |
| 439 strcat(buf, "[passphrase auth] "); | |
| 440 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) | |
| 441 strcat(buf, "[public key auth] "); | |
| 442 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) | |
| 443 strcat(buf, "[users silenced] "); | |
| 444 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) | |
| 445 strcat(buf, "[operators silenced] "); | |
| 446 } | |
| 447 | |
| 448 void silcgaim_get_chumode_string(SilcUInt32 mode, char *buf, | |
| 449 SilcUInt32 buf_size) | |
| 450 { | |
| 451 memset(buf, 0, buf_size); | |
| 452 if (mode & SILC_CHANNEL_UMODE_CHANFO) | |
| 453 strcat(buf, "[founder] "); | |
| 454 if (mode & SILC_CHANNEL_UMODE_CHANOP) | |
| 455 strcat(buf, "[operator] "); | |
| 456 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) | |
| 457 strcat(buf, "[blocks messages] "); | |
| 458 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS) | |
| 459 strcat(buf, "[blocks user messages] "); | |
| 460 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS) | |
| 461 strcat(buf, "[blocks robot messages] "); | |
| 462 if (mode & SILC_CHANNEL_UMODE_QUIET) | |
| 463 strcat(buf, "[quieted] "); | |
| 464 } | |
| 9488 | 465 |
| 466 void | |
| 467 silcgaim_parse_attrs(SilcDList attrs, char **moodstr, char **statusstr, | |
| 468 char **contactstr, char **langstr, char **devicestr, | |
| 469 char **tzstr, char **geostr) | |
| 470 { | |
| 471 SilcAttributePayload attr; | |
| 472 SilcAttributeMood mood = 0; | |
| 473 SilcAttributeContact contact; | |
| 474 SilcAttributeObjDevice device; | |
| 475 SilcAttributeObjGeo geo; | |
| 476 | |
| 477 char tmp[1024]; | |
| 478 GString *s; | |
| 479 | |
| 480 *moodstr = NULL; | |
| 481 *statusstr = NULL; | |
| 482 *contactstr = NULL; | |
| 483 *langstr = NULL; | |
| 484 *devicestr = NULL; | |
| 485 *tzstr = NULL; | |
| 486 *geostr = NULL; | |
| 487 | |
| 488 if (!attrs) | |
| 489 return; | |
| 490 | |
| 491 s = g_string_new(""); | |
| 492 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_STATUS_MOOD); | |
| 493 if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) { | |
| 494 if (mood & SILC_ATTRIBUTE_MOOD_HAPPY) | |
| 495 g_string_append_printf(s, "[%s] ", _("Happy")); | |
| 496 if (mood & SILC_ATTRIBUTE_MOOD_SAD) | |
| 497 g_string_append_printf(s, "[%s] ", _("Sad")); | |
| 498 if (mood & SILC_ATTRIBUTE_MOOD_ANGRY) | |
| 499 g_string_append_printf(s, "[%s] ", _("Angry")); | |
| 500 if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS) | |
| 501 g_string_append_printf(s, "[%s] ", _("Jealous")); | |
| 502 if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED) | |
| 503 g_string_append_printf(s, "[%s] ", _("Ashamed")); | |
| 504 if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE) | |
| 505 g_string_append_printf(s, "[%s] ", _("Invincible")); | |
| 506 if (mood & SILC_ATTRIBUTE_MOOD_INLOVE) | |
| 507 g_string_append_printf(s, "[%s] ", _("In Love")); | |
| 508 if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY) | |
| 509 g_string_append_printf(s, "[%s] ", _("Sleepy")); | |
| 510 if (mood & SILC_ATTRIBUTE_MOOD_BORED) | |
| 511 g_string_append_printf(s, "[%s] ", _("Bored")); | |
| 512 if (mood & SILC_ATTRIBUTE_MOOD_EXCITED) | |
| 513 g_string_append_printf(s, "[%s] ", _("Excited")); | |
| 514 if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS) | |
| 515 g_string_append_printf(s, "[%s] ", _("Anxious")); | |
| 516 } | |
| 517 if (strlen(s->str)) { | |
| 518 *moodstr = s->str; | |
| 519 g_string_free(s, FALSE); | |
| 520 } else | |
| 521 g_string_free(s, TRUE); | |
| 522 | |
| 523 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_STATUS_FREETEXT); | |
| 524 memset(tmp, 0, sizeof(tmp)); | |
| 525 if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) | |
| 526 *statusstr = g_strdup(tmp); | |
| 527 | |
| 528 s = g_string_new(""); | |
| 529 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_CONTACT); | |
| 530 if (attr && silc_attribute_get_object(attr, &contact, sizeof(contact))) { | |
| 531 if (contact & SILC_ATTRIBUTE_CONTACT_CHAT) | |
| 532 g_string_append_printf(s, "[%s] ", _("Chat")); | |
| 533 if (contact & SILC_ATTRIBUTE_CONTACT_EMAIL) | |
|
13545
cfc2f7fcb3dd
[gaim-migrate @ 15922]
Richard Laager <rlaager@wiktel.com>
parents:
12217
diff
changeset
|
534 g_string_append_printf(s, "[%s] ", _("E-Mail")); |
| 9488 | 535 if (contact & SILC_ATTRIBUTE_CONTACT_CALL) |
| 536 g_string_append_printf(s, "[%s] ", _("Phone")); | |
| 537 if (contact & SILC_ATTRIBUTE_CONTACT_PAGE) | |
| 538 g_string_append_printf(s, "[%s] ", _("Paging")); | |
| 539 if (contact & SILC_ATTRIBUTE_CONTACT_SMS) | |
| 540 g_string_append_printf(s, "[%s] ", _("SMS")); | |
| 541 if (contact & SILC_ATTRIBUTE_CONTACT_MMS) | |
| 542 g_string_append_printf(s, "[%s] ", _("MMS")); | |
| 543 if (contact & SILC_ATTRIBUTE_CONTACT_VIDEO) | |
| 544 g_string_append_printf(s, "[%s] ", _("Video Conferencing")); | |
| 545 } | |
| 546 if (strlen(s->str)) { | |
| 547 *contactstr = s->str; | |
| 548 g_string_free(s, FALSE); | |
| 549 } else | |
| 550 g_string_free(s, TRUE); | |
| 551 | |
| 552 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_PREFERRED_LANGUAGE); | |
| 553 memset(tmp, 0, sizeof(tmp)); | |
| 554 if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) | |
| 555 *langstr = g_strdup(tmp); | |
| 556 | |
| 557 s = g_string_new(""); | |
| 558 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_DEVICE_INFO); | |
| 559 memset(&device, 0, sizeof(device)); | |
| 560 if (attr && silc_attribute_get_object(attr, &device, sizeof(device))) { | |
| 561 if (device.type == SILC_ATTRIBUTE_DEVICE_COMPUTER) | |
| 562 g_string_append_printf(s, "%s: ", _("Computer")); | |
| 563 if (device.type == SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE) | |
| 564 g_string_append_printf(s, "%s: ", _("Mobile Phone")); | |
| 565 if (device.type == SILC_ATTRIBUTE_DEVICE_PDA) | |
| 566 g_string_append_printf(s, "%s: ", _("PDA")); | |
| 567 if (device.type == SILC_ATTRIBUTE_DEVICE_TERMINAL) | |
| 568 g_string_append_printf(s, "%s: ", _("Terminal")); | |
| 569 g_string_append_printf(s, "%s %s %s %s", | |
| 570 device.manufacturer ? device.manufacturer : "", | |
| 571 device.version ? device.version : "", | |
| 572 device.model ? device.model : "", | |
| 573 device.language ? device.language : ""); | |
| 574 } | |
| 575 if (strlen(s->str)) { | |
| 576 *devicestr = s->str; | |
| 577 g_string_free(s, FALSE); | |
| 578 } else | |
| 579 g_string_free(s, TRUE); | |
| 580 | |
| 581 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_TIMEZONE); | |
| 582 memset(tmp, 0, sizeof(tmp)); | |
| 583 if (attr && silc_attribute_get_object(attr, tmp, sizeof(tmp))) | |
| 584 *tzstr = g_strdup(tmp); | |
| 585 | |
| 586 attr = silcgaim_get_attr(attrs, SILC_ATTRIBUTE_GEOLOCATION); | |
| 587 memset(&geo, 0, sizeof(geo)); | |
| 588 if (attr && silc_attribute_get_object(attr, &geo, sizeof(geo))) | |
| 589 *geostr = g_strdup_printf("%s %s %s (%s)", | |
| 590 geo.longitude ? geo.longitude : "", | |
| 591 geo.latitude ? geo.latitude : "", | |
| 592 geo.altitude ? geo.altitude : "", | |
| 593 geo.accuracy ? geo.accuracy : ""); | |
| 594 } | |
| 12217 | 595 |
| 596 #ifdef HAVE_SILCMIME_H | |
| 597 /* Returns MIME type of filetype */ | |
| 598 | |
| 599 char *silcgaim_file2mime(const char *filename) | |
| 600 { | |
| 601 const char *ct; | |
| 602 | |
| 603 ct = strrchr(filename, '.'); | |
| 604 if (!ct) | |
| 605 return NULL; | |
| 606 else if (!strcasecmp(".png", ct)) | |
| 607 return strdup("image/png"); | |
| 608 else if (!strcasecmp(".jpg", ct)) | |
| 609 return strdup("image/jpeg"); | |
| 610 else if (!strcasecmp(".jpeg", ct)) | |
| 611 return strdup("image/jpeg"); | |
| 612 else if (!strcasecmp(".gif", ct)) | |
| 613 return strdup("image/gif"); | |
| 614 else if (!strcasecmp(".tiff", ct)) | |
| 615 return strdup("image/tiff"); | |
| 616 | |
| 617 return NULL; | |
| 618 } | |
| 619 | |
| 620 /* Checks if message has images, and assembles MIME message if it has. | |
| 621 If only one image is present, creates simple MIME image message. If | |
| 622 there are multiple images and/or text with images multipart MIME | |
| 623 message is created. */ | |
| 624 | |
| 625 SilcDList silcgaim_image_message(const char *msg, SilcUInt32 *mflags) | |
| 626 { | |
| 627 SilcMime mime = NULL, p; | |
| 628 SilcDList list, parts = NULL; | |
| 629 const char *start, *end, *last; | |
| 630 GData *attribs; | |
| 631 char *type; | |
| 632 gboolean images = FALSE; | |
| 633 | |
| 634 last = msg; | |
| 635 while (last && *last && gaim_markup_find_tag("img", last, &start, | |
| 636 &end, &attribs)) { | |
| 637 GaimStoredImage *image = NULL; | |
| 638 const char *id; | |
| 639 | |
| 640 /* Check if there is text before image */ | |
| 641 if (start - last) { | |
| 642 char *text, *tmp; | |
| 643 p = silc_mime_alloc(); | |
| 644 | |
| 645 /* Add content type */ | |
| 646 silc_mime_add_field(p, "Content-Type", | |
| 647 "text/plain; charset=utf-8"); | |
| 648 | |
| 649 tmp = g_strndup(last, start - last); | |
| 650 text = gaim_unescape_html(tmp); | |
| 651 g_free(tmp); | |
| 652 /* Add text */ | |
| 653 silc_mime_add_data(p, text, strlen(text)); | |
| 654 g_free(text); | |
| 655 | |
| 656 if (!parts) | |
| 657 parts = silc_dlist_init(); | |
| 658 silc_dlist_add(parts, p); | |
| 659 } | |
| 660 | |
| 661 id = g_datalist_get_data(&attribs, "id"); | |
| 662 if (id && (image = gaim_imgstore_get(atoi(id)))) { | |
| 663 unsigned long imglen = gaim_imgstore_get_size(image); | |
| 664 gpointer img = gaim_imgstore_get_data(image); | |
| 665 | |
| 666 p = silc_mime_alloc(); | |
| 667 | |
| 668 /* Add content type */ | |
| 669 type = silcgaim_file2mime(gaim_imgstore_get_filename(image)); | |
| 670 if (!type) { | |
| 671 g_datalist_clear(&attribs); | |
| 672 last = end + 1; | |
| 673 continue; | |
| 674 } | |
| 675 silc_mime_add_field(p, "Content-Type", type); | |
| 676 silc_free(type); | |
| 677 | |
| 678 /* Add content transfer encoding */ | |
| 679 silc_mime_add_field(p, "Content-Transfer-Encoding", "binary"); | |
| 680 | |
| 681 /* Add image data */ | |
| 682 silc_mime_add_data(p, img, imglen); | |
| 683 | |
| 684 if (!parts) | |
| 685 parts = silc_dlist_init(); | |
| 686 silc_dlist_add(parts, p); | |
| 687 images = TRUE; | |
| 688 } | |
| 689 | |
| 690 g_datalist_clear(&attribs); | |
| 691 | |
| 692 /* Continue after tag */ | |
| 693 last = end + 1; | |
| 694 } | |
| 695 | |
| 696 /* Check for text after the image(s) */ | |
| 697 if (images && last && *last) { | |
| 698 char *tmp = gaim_unescape_html(last); | |
| 699 p = silc_mime_alloc(); | |
| 700 | |
| 701 /* Add content type */ | |
| 702 silc_mime_add_field(p, "Content-Type", | |
| 703 "text/plain; charset=utf-8"); | |
| 704 | |
| 705 /* Add text */ | |
| 706 silc_mime_add_data(p, tmp, strlen(tmp)); | |
| 707 g_free(tmp); | |
| 708 | |
| 709 if (!parts) | |
| 710 parts = silc_dlist_init(); | |
| 711 silc_dlist_add(parts, p); | |
| 712 } | |
| 713 | |
| 714 /* If there weren't any images, don't return anything. */ | |
| 715 if (!images) { | |
| 716 if (parts) | |
| 717 silc_dlist_uninit(parts); | |
| 718 return NULL; | |
| 719 } | |
| 720 | |
| 721 if (silc_dlist_count(parts) > 1) { | |
| 722 /* Multipart MIME message */ | |
| 723 char b[32]; | |
| 724 mime = silc_mime_alloc(); | |
| 725 silc_mime_add_field(mime, "MIME-Version", "1.0"); | |
| 726 g_snprintf(b, sizeof(b), "b%4X%4X", | |
| 727 (unsigned int)time(NULL), | |
| 728 silc_dlist_count(parts)); | |
| 729 silc_mime_set_multipart(mime, "mixed", b); | |
| 730 silc_dlist_start(parts); | |
| 731 while ((p = silc_dlist_get(parts)) != SILC_LIST_END) | |
| 732 silc_mime_add_multipart(mime, p); | |
| 733 } else { | |
| 734 /* Simple MIME message */ | |
| 735 silc_dlist_start(parts); | |
| 736 mime = silc_dlist_get(parts); | |
| 737 silc_mime_add_field(mime, "MIME-Version", "1.0"); | |
| 738 } | |
| 739 | |
| 740 *mflags &= ~SILC_MESSAGE_FLAG_UTF8; | |
| 741 *mflags |= SILC_MESSAGE_FLAG_DATA; | |
| 742 | |
| 743 /* Encode message. Fragment if it is too large */ | |
| 744 list = silc_mime_encode_partial(mime, 0xfc00); | |
| 745 | |
| 746 silc_dlist_uninit(parts); | |
| 747 | |
| 748 /* Added multiparts gets freed here */ | |
| 749 silc_mime_free(mime); | |
| 750 | |
| 751 return list; | |
| 752 } | |
| 753 | |
| 754 #endif /* HAVE_SILCMIME_H */ |
