pidgin/gtknotify.c

branch
soc.2013.gobjectification.plugins
changeset 37016
48f85579cc4c
parent 36964
30cbb41e0803
parent 35297
2d76d38118a8
child 37066
1ebce1f4993b
equal deleted inserted replaced
37015:28ee14bbe0ab 37016:48f85579cc4c
1244 else if (ui_handle != NULL) 1244 else if (ui_handle != NULL)
1245 gtk_widget_destroy(GTK_WIDGET(ui_handle)); 1245 gtk_widget_destroy(GTK_WIDGET(ui_handle));
1246 } 1246 }
1247 1247
1248 #ifndef _WIN32 1248 #ifndef _WIN32
1249 static gint 1249 static gboolean
1250 uri_command(const char *command, gboolean sync) 1250 uri_command(GSList *arg_list, gboolean sync)
1251 { 1251 {
1252 gchar *tmp; 1252 gchar *tmp;
1253 GError *error = NULL; 1253 GError *error = NULL;
1254 gint ret = 0; 1254 GSList *it;
1255 1255 gchar **argv;
1256 purple_debug_misc("gtknotify", "Executing %s\n", command); 1256 gint argc, i;
1257 1257 gchar *program;
1258 if (!purple_program_is_valid(command)) 1258
1259 { 1259 g_return_val_if_fail(arg_list != NULL, FALSE);
1260 tmp = g_strdup_printf(_("The browser command \"%s\" is invalid."), 1260
1261 command ? command : "(none)"); 1261 program = arg_list->data;
1262 purple_debug_misc("gtknotify", "Executing %s (%s)\n", program,
1263 sync ? "sync" : "async");
1264
1265 if (!purple_program_is_valid(program)) {
1266 purple_debug_error("gtknotify", "Command \"%s\" is invalid\n",
1267 program);
1268 tmp = g_strdup_printf(
1269 _("The browser command \"%s\" is invalid."),
1270 program ? program : "(null)");
1262 purple_notify_error(NULL, NULL, _("Unable to open URL"), tmp, NULL); 1271 purple_notify_error(NULL, NULL, _("Unable to open URL"), tmp, NULL);
1263 g_free(tmp); 1272 g_free(tmp);
1264 1273
1265 } 1274 return FALSE;
1266 else if (sync) 1275 }
1276
1277 argc = g_slist_length(arg_list);
1278 argv = g_new(gchar*, argc + 1);
1279 i = 0;
1280 for (it = arg_list; it; it = g_slist_next(it)) {
1281 if (purple_debug_is_verbose()) {
1282 purple_debug_misc("gtknotify", "argv[%d] = \"%s\"\n",
1283 i, (gchar*)it->data);
1284 }
1285 argv[i++] = it->data;
1286 }
1287 argv[i] = NULL;
1288
1289 if (sync) {
1290 gint exit_status = 0;
1291
1292 if (g_spawn_sync(NULL, argv, NULL, G_SPAWN_SEARCH_PATH |
1293 G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
1294 NULL, NULL, NULL, NULL, &exit_status, &error) &&
1295 exit_status == 0)
1296 {
1297 g_free(argv);
1298 return TRUE;
1299 }
1300
1301 purple_debug_error("gtknotify",
1302 "Error launching \"%s\": %s (status: %d)\n", program,
1303 error ? error->message : "(null)", exit_status);
1304 tmp = g_strdup_printf(_("Error launching \"%s\": %s"), program,
1305 error ? error->message : "(null)");
1306 g_error_free(error);
1307 purple_notify_error(NULL, NULL, _("Unable to open URL"), tmp, NULL);
1308 g_free(tmp);
1309
1310 g_free(argv);
1311 return FALSE;
1312 }
1313
1314 if (g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH |
1315 G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL,
1316 NULL, NULL, &error))
1267 { 1317 {
1268 gint status; 1318 g_free(argv);
1269 1319 return TRUE;
1270 if (!g_spawn_command_line_sync(command, NULL, NULL, &status, &error)) 1320 }
1271 { 1321
1272 tmp = g_strdup_printf(_("Error launching \"%s\": %s"), 1322 purple_debug_warning("gtknotify", "Error launching \"%s\": %s\n",
1273 command, error->message); 1323 program, error ? error->message : "(null)");
1274 purple_notify_error(NULL, NULL, _("Unable to open URL"), tmp, NULL); 1324 g_error_free(error);
1275 g_free(tmp); 1325
1276 g_error_free(error); 1326 g_free(argv);
1277 } 1327 return FALSE;
1278 else
1279 ret = status;
1280 }
1281 else
1282 {
1283 if (!g_spawn_command_line_async(command, &error))
1284 {
1285 tmp = g_strdup_printf(_("Error launching \"%s\": %s"),
1286 command, error->message);
1287 purple_notify_error(NULL, NULL, _("Unable to open URL"), tmp, NULL);
1288 g_free(tmp);
1289 g_error_free(error);
1290 }
1291 }
1292
1293 return ret;
1294 } 1328 }
1295 #endif /* _WIN32 */ 1329 #endif /* _WIN32 */
1296 1330
1297 static void * 1331 static void *
1298 pidgin_notify_uri(const char *uri) 1332 pidgin_notify_uri(const char *uri)
1299 { 1333 {
1300 #ifndef _WIN32 1334 #ifndef _WIN32
1301 char *escaped = g_shell_quote(uri);
1302 char *command = NULL;
1303 char *remote_command = NULL;
1304 const char *web_browser; 1335 const char *web_browser;
1305 int place; 1336 int place;
1306 1337 gchar *uri_escaped, *uri_custom = NULL;
1307 web_browser = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser"); 1338 GSList *argv = NULL, *argv_remote = NULL;
1339 gchar **usercmd_argv = NULL;
1340
1341 /* Replace some special characters like $ with their percent-encoded
1342 value. This shouldn't be necessary because we shell-escape the entire
1343 arg before exec'ing the browser, however, we had a report that a URL
1344 containing $(xterm) was causing xterm to start on his system. This is
1345 obviously a bug on his system, but it's pretty easy for us to protect
1346 against it. */
1347 uri_escaped = g_uri_escape_string(uri, ":;/%#,+?=&@", FALSE);
1348
1349 web_browser = purple_prefs_get_string(PIDGIN_PREFS_ROOT
1350 "/browsers/browser");
1308 place = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/browsers/place"); 1351 place = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/browsers/place");
1309 1352
1310 /* if they are running gnome, use the gnome web browser */ 1353 /* if they are running gnome, use the gnome web browser */
1311 if (purple_running_gnome() == TRUE) 1354 if (purple_running_gnome() == TRUE) {
1312 {
1313 char *tmp = g_find_program_in_path("xdg-open"); 1355 char *tmp = g_find_program_in_path("xdg-open");
1314 if (tmp == NULL) 1356 if (tmp == NULL)
1315 command = g_strdup_printf("gnome-open %s", escaped); 1357 argv = g_slist_append(argv, "gnome-open");
1316 else 1358 else
1317 command = g_strdup_printf("xdg-open %s", escaped); 1359 argv = g_slist_append(argv, "xdg-open");
1318 g_free(tmp); 1360 g_free(tmp);
1319 } 1361 argv = g_slist_append(argv, uri_escaped);
1320 else if (purple_running_osx() == TRUE) 1362 } else if (purple_running_osx() == TRUE) {
1321 { 1363 argv = g_slist_append(argv, "open");
1322 command = g_strdup_printf("open %s", escaped); 1364 argv = g_slist_append(argv, uri_escaped);
1323 } 1365 } else if (!strcmp(web_browser, "epiphany") ||
1324 else if (!strcmp(web_browser, "epiphany") ||
1325 !strcmp(web_browser, "galeon")) 1366 !strcmp(web_browser, "galeon"))
1326 { 1367 {
1368 argv = g_slist_append(argv, (gpointer)web_browser);
1369
1327 if (place == PIDGIN_BROWSER_NEW_WINDOW) 1370 if (place == PIDGIN_BROWSER_NEW_WINDOW)
1328 command = g_strdup_printf("%s -w %s", web_browser, escaped); 1371 argv = g_slist_append(argv, "-w");
1329 else if (place == PIDGIN_BROWSER_NEW_TAB) 1372 else if (place == PIDGIN_BROWSER_NEW_TAB)
1330 command = g_strdup_printf("%s -n %s", web_browser, escaped); 1373 argv = g_slist_append(argv, "-n");
1331 else 1374
1332 command = g_strdup_printf("%s %s", web_browser, escaped); 1375 argv = g_slist_append(argv, uri_escaped);
1333 } 1376 } else if (!strcmp(web_browser, "xdg-open")) {
1334 else if (!strcmp(web_browser, "xdg-open")) 1377 argv = g_slist_append(argv, "xdg-open");
1335 { 1378 argv = g_slist_append(argv, uri_escaped);
1336 command = g_strdup_printf("xdg-open %s", escaped); 1379 } else if (!strcmp(web_browser, "gnome-open")) {
1337 } 1380 argv = g_slist_append(argv, "gnome-open");
1338 else if (!strcmp(web_browser, "gnome-open")) 1381 argv = g_slist_append(argv, uri_escaped);
1339 { 1382 } else if (!strcmp(web_browser, "kfmclient")) {
1340 command = g_strdup_printf("gnome-open %s", escaped); 1383 argv = g_slist_append(argv, "kfmclient");
1341 } 1384 argv = g_slist_append(argv, "openURL");
1342 else if (!strcmp(web_browser, "kfmclient")) 1385 argv = g_slist_append(argv, uri_escaped);
1343 {
1344 command = g_strdup_printf("kfmclient openURL %s", escaped);
1345 /* 1386 /*
1346 * Does Konqueror have options to open in new tab 1387 * Does Konqueror have options to open in new tab
1347 * and/or current window? 1388 * and/or current window?
1348 */ 1389 */
1349 } 1390 } else if (!strcmp(web_browser, "mozilla") ||
1350 else if (!strcmp(web_browser, "mozilla") || 1391 !strcmp(web_browser, "mozilla-firebird") ||
1351 !strcmp(web_browser, "mozilla-firebird") || 1392 !strcmp(web_browser, "firefox") ||
1352 !strcmp(web_browser, "firefox") || 1393 !strcmp(web_browser, "seamonkey"))
1353 !strcmp(web_browser, "seamonkey"))
1354 { 1394 {
1355 char *args = ""; 1395 argv = g_slist_append(argv, (gpointer)web_browser);
1356 1396 argv = g_slist_append(argv, uri_escaped);
1357 command = g_strdup_printf("%s %s", web_browser, escaped); 1397
1358 1398 g_assert(uri_custom == NULL);
1359 /* 1399 if (place == PIDGIN_BROWSER_NEW_WINDOW) {
1360 * Firefox 0.9 and higher require a "-a firefox" option when 1400 uri_custom = g_strdup_printf("openURL(%s,new-window)",
1361 * using -remote commands. This breaks older versions of 1401 uri_escaped);
1362 * mozilla. So we include this other handly little string 1402 } else if (place == PIDGIN_BROWSER_NEW_TAB) {
1363 * when calling firefox. If the API for remote calls changes 1403 uri_custom = g_strdup_printf("openURL(%s,new-tab)",
1364 * any more in firefox then firefox should probably be split 1404 uri_escaped);
1365 * apart from mozilla-firebird and mozilla... but this is good 1405 }
1366 * for now. 1406
1407 if (uri_custom != NULL) {
1408 argv_remote = g_slist_append(argv_remote,
1409 (gpointer)web_browser);
1410
1411 /* Firefox 0.9 and higher require a "-a firefox" option
1412 * when using -remote commands. This breaks older
1413 * versions of mozilla. So we include this other handly
1414 * little string when calling firefox. If the API for
1415 * remote calls changes any more in firefox then firefox
1416 * should probably be split apart from mozilla-firebird
1417 * and mozilla... but this is good for now.
1418 */
1419 if (!strcmp(web_browser, "firefox")) {
1420 argv_remote = g_slist_append(argv_remote, "-a");
1421 argv_remote = g_slist_append(argv_remote,
1422 "firefox");
1423 }
1424
1425 argv_remote = g_slist_append(argv_remote, "-remote");
1426 argv_remote = g_slist_append(argv_remote, uri_custom);
1427 }
1428 } else if (!strcmp(web_browser, "opera")) {
1429 argv = g_slist_append(argv, "opera");
1430
1431 if (place == PIDGIN_BROWSER_NEW_WINDOW)
1432 argv = g_slist_append(argv, "-newwindow");
1433 else if (place == PIDGIN_BROWSER_NEW_TAB)
1434 argv = g_slist_append(argv, "-newpage");
1435 /* `opera -remote "openURL(%s)"` command causes Pidgin to hang,
1436 * if there is no Opera instance running.
1367 */ 1437 */
1368 if (!strcmp(web_browser, "firefox")) 1438
1369 args = "-a firefox"; 1439 argv = g_slist_append(argv, uri_escaped);
1370 1440 } else if (!strcmp(web_browser, "google-chrome")) {
1371 if (place == PIDGIN_BROWSER_NEW_WINDOW) 1441 /* Google Chrome doesn't have command-line arguments that
1372 remote_command = g_strdup_printf("%s %s -remote " 1442 * control the opening of links from external calls. This is
1373 "openURL(%s,new-window)", 1443 * controlled solely from a preference within Google Chrome.
1374 web_browser, args, escaped); 1444 */
1375 else if (place == PIDGIN_BROWSER_NEW_TAB) 1445 argv = g_slist_append(argv, "google-chrome");
1376 remote_command = g_strdup_printf("%s %s -remote " 1446 argv = g_slist_append(argv, uri_escaped);
1377 "openURL(%s,new-tab)", 1447 } else if (!strcmp(web_browser, "chrome")) {
1378 web_browser, args, escaped); 1448 /* Chromium doesn't have command-line arguments that control
1379 } 1449 * the opening of links from external calls. This is controlled
1380 else if (!strcmp(web_browser, "opera")) 1450 * solely from a preference within Chromium.
1381 { 1451 */
1382 if (place == PIDGIN_BROWSER_NEW_WINDOW) 1452 argv = g_slist_append(argv, "chrome");
1383 command = g_strdup_printf("opera -newwindow %s", escaped); 1453 argv = g_slist_append(argv, uri_escaped);
1384 else if (place == PIDGIN_BROWSER_NEW_TAB) 1454 } else if (!strcmp(web_browser, "chromium-browser")) {
1385 command = g_strdup_printf("opera -newpage %s", escaped);
1386 else
1387 command = g_strdup_printf("opera %s", escaped);
1388
1389 }
1390 else if (!strcmp(web_browser, "google-chrome"))
1391 {
1392 /* Google Chrome doesn't have command-line arguments that control the
1393 * opening of links from external calls. This is controlled solely from
1394 * a preference within Google Chrome. */
1395 command = g_strdup_printf("google-chrome %s", escaped);
1396 }
1397 else if (!strcmp(web_browser, "chrome"))
1398 {
1399 /* Chromium doesn't have command-line arguments that control the 1455 /* Chromium doesn't have command-line arguments that control the
1400 * opening of links from external calls. This is controlled solely from 1456 * opening of links from external calls. This is controlled
1401 * a preference within Chromium. */ 1457 * solely from a preference within Chromium.
1402 command = g_strdup_printf("chrome %s", escaped); 1458 */
1403 } 1459 argv = g_slist_append(argv, "chromium-browser");
1404 else if (!strcmp(web_browser, "chromium-browser")) 1460 argv = g_slist_append(argv, uri_escaped);
1405 { 1461 } else if (!strcmp(web_browser, "custom")) {
1406 /* Chromium doesn't have command-line arguments that control the 1462 GError *error = NULL;
1407 * opening of links from external calls. This is controlled solely from 1463 const char *usercmd_command;
1408 * a preference within Chromium. */ 1464 gint usercmd_argc, i;
1409 command = g_strdup_printf("chromium-browser %s", escaped); 1465 gboolean uri_added = FALSE;
1410 } 1466
1411 else if (!strcmp(web_browser, "custom")) 1467 usercmd_command = purple_prefs_get_string(PIDGIN_PREFS_ROOT
1412 { 1468 "/browsers/manual_command");
1413 const char *web_command; 1469
1414 1470 if (usercmd_command == NULL || *usercmd_command == '\0') {
1415 web_command = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/manual_command");
1416
1417 if (web_command == NULL || *web_command == '\0')
1418 {
1419 purple_notify_error(NULL, NULL, _("Unable to open URL"), 1471 purple_notify_error(NULL, NULL, _("Unable to open URL"),
1420 _("The 'Manual' browser command has been " 1472 _("The 'Manual' browser command has been "
1421 "chosen, but no command has been set."), NULL); 1473 "chosen, but no command has been set."), NULL);
1474 g_free(uri_escaped);
1422 return NULL; 1475 return NULL;
1423 } 1476 }
1424 1477
1425 if (strstr(web_command, "%s")) 1478 if (!g_shell_parse_argv(usercmd_command, &usercmd_argc,
1426 command = purple_strreplace(web_command, "%s", escaped); 1479 &usercmd_argv, &error))
1427 else
1428 { 1480 {
1429 /* 1481 purple_notify_error(NULL, NULL, _("Unable to open URL: "
1430 * There is no "%s" in the browser command. Assume the user 1482 "the 'Manual' browser command seems invalid."),
1431 * wanted the URL tacked on to the end of the command. 1483 error ? error->message : NULL, NULL);
1432 */ 1484 g_error_free(error);
1433 command = g_strdup_printf("%s %s", web_command, escaped); 1485 g_free(uri_escaped);
1434 } 1486 return NULL;
1435 } 1487 }
1436 1488
1437 g_free(escaped); 1489 for (i = 0; i < usercmd_argc; i++) {
1438 1490 gchar *cmd_part = usercmd_argv[i];
1439 if (remote_command != NULL) 1491
1440 { 1492 if (uri_added || strstr(cmd_part, "%s") == NULL) {
1493 argv = g_slist_append(argv, cmd_part);
1494 continue;
1495 }
1496
1497 uri_custom = purple_strreplace(cmd_part, "%s",
1498 uri_escaped);
1499 argv = g_slist_append(argv, uri_custom);
1500 uri_added = TRUE;
1501 }
1502
1503 /* There is no "%s" in the browser command. Assume the user
1504 * wanted the URL tacked on to the end of the command.
1505 */
1506 if (!uri_added)
1507 argv = g_slist_append(argv, uri_escaped);
1508 }
1509
1510 if (argv_remote != NULL) {
1441 /* try the remote command first */ 1511 /* try the remote command first */
1442 if (uri_command(remote_command, TRUE) != 0) 1512 if (!uri_command(argv_remote, TRUE))
1443 uri_command(command, FALSE); 1513 uri_command(argv, FALSE);
1444 1514 } else
1445 g_free(remote_command); 1515 uri_command(argv, FALSE);
1446 1516
1447 } 1517 g_strfreev(usercmd_argv);
1448 else 1518 g_free(uri_escaped);
1449 uri_command(command, FALSE); 1519 g_free(uri_custom);
1450 1520 g_slist_free(argv);
1451 g_free(command); 1521 g_slist_free(argv_remote);
1452 1522
1453 #else /* !_WIN32 */ 1523 #else /* !_WIN32 */
1454 winpidgin_notify_uri(uri); 1524 winpidgin_notify_uri(uri);
1455 #endif /* !_WIN32 */ 1525 #endif /* !_WIN32 */
1456 1526

mercurial