Changeset 429 for trunk/icedtea-web/plugin/icedteanp/IcedTeaNPPlugin.cc
- Timestamp:
- Sep 24, 2014, 9:34:21 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/icedtea-web/plugin/icedteanp/IcedTeaNPPlugin.cc
r419 r429 46 46 #include <sys/socket.h> 47 47 #include <fcntl.h> 48 #include <sstream> 48 49 #include "OS_OS2.h" 49 50 #endif … … 51 52 // System includes. 52 53 #include <dlfcn.h> 54 #include <unistd.h> 55 #include <fcntl.h> 56 #include <dirent.h> 53 57 #include <errno.h> 54 58 #include <libgen.h> … … 56 60 #include <stdlib.h> 57 61 #include <string.h> 62 #include <string> 58 63 #include <sys/stat.h> 59 64 #include <sys/types.h> 60 65 #include <unistd.h> 61 66 #include <new> 67 68 //IcedTea-plugin includes 69 #include "IcedTeaPluginUtils.h" 70 #include "IcedTeaParseProperties.h" 62 71 // Liveconnect extension 63 72 #include "IcedTeaScriptablePluginObject.h" … … 69 78 #define DT_SOCKET_DLL "dt_socket" 70 79 #endif 71 72 #if MOZILLA_VERSION_COLLAPSED < 109010073 // Documentbase retrieval includes.74 #include <nsIPluginInstance.h>75 #include <nsIPluginInstancePeer.h>76 #include <nsIPluginTagInfo2.h>77 78 // API's into Mozilla79 #include <nsCOMPtr.h>80 #include <nsICookieService.h>81 #include <nsIDNSRecord.h>82 #include <nsIDNSService.h>83 #include <nsINetUtil.h>84 #include <nsIProxyInfo.h>85 #include <nsIProtocolProxyService.h>86 #include <nsIScriptSecurityManager.h>87 #include <nsIIOService.h>88 #include <nsIURI.h>89 #include <nsNetCID.h>90 #include <nsStringAPI.h>91 #include <nsServiceManagerUtils.h>92 #endif93 94 // Error reporting macros.95 #define PLUGIN_ERROR(message) \96 g_printerr ("%s:%d: thread %p: Error: %s\n", __FILE__, __LINE__, \97 g_thread_self (), message)98 99 #define PLUGIN_ERROR_TWO(first, second) \100 g_printerr ("%s:%d: thread %p: Error: %s: %s\n", __FILE__, __LINE__, \101 g_thread_self (), first, second)102 103 #define PLUGIN_ERROR_THREE(first, second, third) \104 g_printerr ("%s:%d: thread %p: Error: %s: %s: %s\n", __FILE__, \105 __LINE__, g_thread_self (), first, second, third)106 80 107 81 // Plugin information passed to about:plugins. … … 167 141 " For more detail rerun \"firefox -g\" in a terminal window." 168 142 169 #if MOZILLA_VERSION_COLLAPSED < 1090100170 // Documentbase retrieval required definition.171 static NS_DEFINE_IID (kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID);172 #endif173 174 143 // Data directory for plugin. 175 static gchar* data_directory = NULL; 176 177 // Fully-qualified appletviewer executable. 178 static gchar* appletviewer_executable = NULL; 144 static std::string data_directory; 145 static DIR *data_directory_descriptor; 146 147 // Fully-qualified appletviewer default executable and rt.jar 148 static const char* appletviewer_default_executable = ICEDTEA_WEB_JRE "/bin/java"; 149 static const char* appletviewer_default_rtjar = ICEDTEA_WEB_JRE "/lib/rt.jar"; 179 150 180 151 // Applet viewer input channel (needs to be static because it is used in plugin_in_pipe_callback) … … 202 173 #endif 203 174 175 // Applet viewer debug pipe name. 176 gchar* debug_pipe_name = NULL; 177 204 178 // Applet viewer output watch source. 205 179 gint out_watch_source; … … 211 185 pthread_mutex_t pluginAsyncCallMutex; 212 186 187 /*to sync pipe to apletviewer console*/ 188 pthread_mutex_t debug_pipe_lock = PTHREAD_MUTEX_INITIALIZER; 189 213 190 // Applet viewer output channel. 214 191 GIOChannel* out_to_appletviewer; 192 193 // Applet viewer debug channel. 194 GIOChannel* debug_to_appletviewer = NULL; 215 195 216 196 // Tracks jvm status … … 235 215 JavaMessageSender* java_req_proc; 236 216 237 #if MOZILLA_VERSION_COLLAPSED < 1090100 238 // Documentbase retrieval type-punning union. 239 typedef union 240 { 241 void** void_field; 242 nsIPluginTagInfo2** info_field; 243 } info_union; 217 // Queue processing threads 218 static pthread_t plugin_request_processor_thread1; 219 static pthread_t plugin_request_processor_thread2; 220 static pthread_t plugin_request_processor_thread3; 221 222 #ifdef __OS2__ 223 struct QueueProcessorData 224 { 225 PluginRequestProcessor *processor; 226 bool stopRequested; 227 }; 228 229 static QueueProcessorData queue_processor_data1 = { NULL, false }; 230 static QueueProcessorData queue_processor_data2 = { NULL, false }; 231 static QueueProcessorData queue_processor_data3 = { NULL, false }; 244 232 #endif 245 233 246 234 // Static instance helper functions. 247 // Have the browser allocate a new ITNPPluginData structure.248 static void plugin_data_new (ITNPPluginData** data);249 235 // Retrieve the current document's documentbase. 250 static gchar* plugin_get_documentbase (NPP instance); 251 // Notify the user that the appletviewer is not installed correctly. 252 static void plugin_display_failure_dialog (); 236 static std::string plugin_get_documentbase (NPP instance); 253 237 // Callback used to monitor input pipe status. 254 238 static gboolean plugin_in_pipe_callback (GIOChannel* source, … … 259 243 GIOCondition condition, 260 244 gpointer plugin_data); 261 static NPError plugin_start_appletviewer (ITNPPluginData* data); 262 static gchar* plugin_create_applet_tag (int16_t argc, char* argn[], 263 char* argv[]); 245 std::string plugin_parameters_string (int argc, char* argn[], char* argv[]); 264 246 static void plugin_stop_appletviewer (); 265 // Uninitialize ITNPPluginData structure266 static void plugin_data_destroy (NPP instance);267 247 268 248 NPError get_cookie_info(const char* siteAddr, char** cookieString, uint32_t* len); 269 249 NPError get_proxy_info(const char* siteAddr, char** proxy, uint32_t* len); 270 250 void consume_message(gchar* message); 271 void start_jvm_if_needed();272 251 static void appletviewer_monitor(GPid pid, gint status, gpointer data); 273 252 void plugin_send_initialization_message(char* instance, gulong handle, 274 253 int width, int height, 275 254 char* url); 255 /* Returns JVM options set in itw-settings */ 256 std::vector<std::string*>* get_jvm_args(); 276 257 277 258 // Global instance counter. … … 288 269 static guint appletviewer_watch_id = -1; 289 270 271 bool debug_initiated = false; 290 272 int plugin_debug = getenv ("ICEDTEAPLUGIN_DEBUG") != NULL; 273 bool plugin_debug_headers = false; 274 bool plugin_debug_to_file = false ; 275 bool plugin_debug_to_streams = true ; 276 bool plugin_debug_to_system = false; 277 bool plugin_debug_to_console = true; 278 FILE * plugin_file_log; 279 std::string plugin_file_log_name; 280 291 281 int plugin_debug_suspend = (getenv("ICEDTEAPLUGIN_DEBUG") != NULL) && 292 282 (strcmp(getenv("ICEDTEAPLUGIN_DEBUG"), "suspend") == 0); 293 294 pthread_cond_t cond_message_available = PTHREAD_COND_INITIALIZER;295 283 296 284 … … 316 304 #endif 317 305 318 306 static std::string get_plugin_executable(){ 307 std::string custom_jre; 308 bool custom_jre_defined = find_custom_jre(custom_jre); 309 if (custom_jre_defined) { 310 if (IcedTeaPluginUtilities::file_exists(custom_jre+"/bin/java")){ 311 return custom_jre+"/bin/java"; 312 } else { 313 PLUGIN_ERROR("Your custom jre (/bin/java check) %s is not valid. Please fix %s in your %s. In attempt to run using default one. \n", custom_jre.c_str(), custom_jre_key.c_str(), default_file_ITW_deploy_props_name.c_str()); 314 } 315 } 316 return appletviewer_default_executable; 317 } 318 319 static std::string get_plugin_rt_jar(){ 320 std::string custom_jre; 321 bool custom_jre_defined = find_custom_jre(custom_jre); 322 if (custom_jre_defined) { 323 if (IcedTeaPluginUtilities::file_exists(custom_jre+"/lib/rt.jar")){ 324 return custom_jre+"/lib/rt.jar"; 325 } else { 326 PLUGIN_ERROR("Your custom jre (/lib/rt.jar check) %s is not valid. Please fix %s in your %s. In attempt to run using default one. \n", custom_jre.c_str(), custom_jre_key.c_str(), default_file_ITW_deploy_props_name.c_str()); 327 } 328 } 329 return appletviewer_default_rtjar; 330 } 331 332 static void cleanUpDir(){ 333 //free data_directory descriptor 334 if (data_directory_descriptor != NULL) { 335 closedir(data_directory_descriptor); 336 } 337 //clean up pipes directory 338 PLUGIN_DEBUG ("Removing runtime directory %s \n", data_directory.c_str()); 339 int removed = rmdir(data_directory.c_str()); 340 if (removed != 0) { 341 PLUGIN_ERROR ("Failed to remove runtime directory %s, because of %s \n", data_directory.c_str(), strerror(errno)); 342 } else { 343 PLUGIN_DEBUG ("Removed runtime directory %s \n", data_directory.c_str()); 344 } 345 data_directory_descriptor = NULL; 346 } 319 347 /* 320 348 * Find first member in GHashTable* depending on version of glib … … 344 372 // Creates a new icedtea np plugin instance. This function creates a 345 373 // ITNPPluginData* and stores it in instance->pdata. The following 346 // ITNPPluginData fiel s are initialized: instance_id, in_pipe_name,374 // ITNPPluginData fields are initialized: instance_id, in_pipe_name, 347 375 // in_from_appletviewer, in_watch_source, out_pipe_name, 348 376 // out_to_appletviewer, out_watch_source, appletviewer_mutex, owner, … … 366 394 if (!browser_functions.hasproperty(instance, window_ptr, identifier)) 367 395 { 368 printf("%s not found!\n", "document");396 PLUGIN_ERROR("%s not found!\n", "document"); 369 397 } 370 398 browser_functions.getproperty(instance, window_ptr, identifier, &member_ptr); … … 372 400 PLUGIN_DEBUG("Got variant %p\n", &member_ptr); 373 401 374 375 NPError np_error = NPERR_NO_ERROR;376 ITNPPluginData* data = NULL;377 378 gchar* documentbase = NULL;379 gchar* read_message = NULL;380 gchar* applet_tag = NULL;381 gchar* cookie_info = NULL;382 383 NPObject* npPluginObj = NULL;384 385 402 if (!instance) 386 { 387 PLUGIN_ERROR ("Browser-provided instance pointer is NULL."); 388 np_error = NPERR_INVALID_INSTANCE_ERROR; 389 goto cleanup_done; 390 } 403 { 404 PLUGIN_ERROR ("Browser-provided instance pointer is NULL.\n"); 405 return NPERR_INVALID_INSTANCE_ERROR; 406 } 391 407 392 408 // data 393 plugin_data_new (&data);409 ITNPPluginData* data = plugin_data_new (); 394 410 if (data == NULL) 395 { 396 PLUGIN_ERROR ("Failed to allocate plugin data."); 397 np_error = NPERR_OUT_OF_MEMORY_ERROR; 398 goto cleanup_done; 411 { 412 PLUGIN_ERROR ("Failed to allocate plugin data.\n"); 413 return NPERR_OUT_OF_MEMORY_ERROR; 399 414 } 400 415 401 416 // start the jvm if needed 402 start_jvm_if_needed(); 417 NPError startup_error = start_jvm_if_needed(); 418 if (startup_error != NPERR_NO_ERROR) { 419 PLUGIN_ERROR ("Failed to start JVM\n"); 420 return startup_error; 421 } 403 422 404 423 // Initialize data->instance_id. … … 422 441 g_mutex_lock (data->appletviewer_mutex); 423 442 443 std::string documentbase = plugin_get_documentbase (instance); 424 444 // Documentbase retrieval. 425 documentbase = plugin_get_documentbase (instance); 426 if (documentbase && argc != 0) 427 { 428 // Send applet tag message to appletviewer. 429 applet_tag = plugin_create_applet_tag (argc, argn, argv); 430 431 data->applet_tag = (gchar*) malloc(strlen(applet_tag)*sizeof(gchar) + strlen(documentbase)*sizeof(gchar) + 32); 432 g_sprintf(data->applet_tag, "tag %s %s", documentbase, applet_tag); 445 if (argc != 0) 446 { 447 // Send parameters to appletviewer. 448 std::string params_string = plugin_parameters_string(argc, argn, argv); 449 450 data->parameters_string = g_strdup_printf("tag %s %s", documentbase.c_str(), params_string.c_str()); 433 451 434 452 data->is_applet_instance = true; 435 } 436 437 if (argc == 0) 438 { 453 } 454 else 455 { 439 456 data->is_applet_instance = false; 440 457 } 441 458 442 459 g_mutex_unlock (data->appletviewer_mutex); … … 454 471 455 472 instance->pdata = data; 456 457 goto cleanup_done;458 459 cleanup_appletviewer_mutex:460 g_mutex_free (data->appletviewer_mutex);461 data->appletviewer_mutex = NULL;462 463 // cleanup_instance_string:464 g_free (data->instance_id);465 data->instance_id = NULL;466 467 // cleanup applet tag:468 g_free (data->applet_tag);469 data->applet_tag = NULL;470 471 // cleanup_data:472 // Eliminate back-pointer to plugin instance.473 data->owner = NULL;474 (*browser_functions.memfree) (data);475 data = NULL;476 477 // Initialization failed so return a NULL pointer for the browser478 // data.479 instance->pdata = NULL;480 481 cleanup_done:482 g_free (applet_tag);483 applet_tag = NULL;484 g_free (read_message);485 read_message = NULL;486 g_free (documentbase);487 documentbase = NULL;488 473 489 474 // store an identifier for this plugin … … 495 480 PLUGIN_DEBUG ("ITNP_New return\n"); 496 481 497 return np_error;482 return NPERR_NO_ERROR; 498 483 } 499 484 500 485 // Starts the JVM if it is not already running 501 voidstart_jvm_if_needed()486 NPError start_jvm_if_needed() 502 487 { 503 488 … … 514 499 { 515 500 PLUGIN_DEBUG("JVM is up. Returning.\n"); 516 return ;501 return NPERR_NO_ERROR; 517 502 } 518 503 … … 536 521 // in_pipe_name 537 522 in_pipe_name = g_strdup_printf ("%s/%d-icedteanp-appletviewer-to-plugin", 538 data_directory , getpid());523 data_directory.c_str(), getpid()); 539 524 if (!in_pipe_name) 540 525 { 541 PLUGIN_ERROR ("Failed to create input pipe name. ");526 PLUGIN_ERROR ("Failed to create input pipe name.\n"); 542 527 np_error = NPERR_OUT_OF_MEMORY_ERROR; 543 528 // If in_pipe_name is NULL then the g_free at … … 552 537 if (mkfifo (in_pipe_name, 0600) == -1 && errno != EEXIST) 553 538 { 554 PLUGIN_ERROR _TWO ("Failed to create input pipe", strerror (errno));539 PLUGIN_ERROR ("Failed to create input pipe\n", strerror (errno)); 555 540 np_error = NPERR_GENERIC_ERROR; 556 541 goto cleanup_in_pipe_name; … … 573 558 // out_pipe_name 574 559 out_pipe_name = g_strdup_printf ("%s/%d-icedteanp-plugin-to-appletviewer", 575 data_directory , getpid());560 data_directory.c_str(), getpid()); 576 561 577 562 if (!out_pipe_name) 578 563 { 579 PLUGIN_ERROR ("Failed to create output pipe name. ");564 PLUGIN_ERROR ("Failed to create output pipe name.\n"); 580 565 np_error = NPERR_OUT_OF_MEMORY_ERROR; 581 566 goto cleanup_out_pipe_name; … … 588 573 if (mkfifo (out_pipe_name, 0600) == -1 && errno != EEXIST) 589 574 { 590 PLUGIN_ERROR _TWO ("Failed to create output pipe", strerror (errno));575 PLUGIN_ERROR ("Failed to create output pipe\n", strerror (errno)); 591 576 np_error = NPERR_GENERIC_ERROR; 592 577 goto cleanup_out_pipe_name; … … 594 579 PLUGIN_DEBUG ("ITNP_New: created output fifo: %s\n", out_pipe_name); 595 580 #endif 581 582 // Create plugin-debug-to-appletviewer pipe which we refer to as the 583 // debug pipe. 584 initialize_debug();//should be already initialized, but... 585 if (plugin_debug_to_console){ 586 // debug_pipe_name 587 debug_pipe_name = g_strdup_printf ("%s/%d-icedteanp-plugin-debug-to-appletviewer", 588 data_directory.c_str(), getpid()); 589 590 if (!debug_pipe_name) 591 { 592 PLUGIN_ERROR ("Failed to create debug pipe name.\n"); 593 np_error = NPERR_OUT_OF_MEMORY_ERROR; 594 goto cleanup_debug_pipe_name; 595 } 596 597 // clean up any older pip 598 unlink (debug_pipe_name); 599 600 PLUGIN_DEBUG ("ITNP_New: creating debug fifo: %s\n", debug_pipe_name); 601 if (mkfifo (debug_pipe_name, 0600) == -1 && errno != EEXIST) 602 { 603 PLUGIN_ERROR ("Failed to create debug pipe\n", strerror (errno)); 604 np_error = NPERR_GENERIC_ERROR; 605 goto cleanup_debug_pipe_name; 606 } 607 PLUGIN_DEBUG ("ITNP_New: created debug fifo: %s\n", debug_pipe_name); 608 } 596 609 597 610 // Start a separate appletviewer process for each applet, even if … … 628 641 if (channel_error) 629 642 { 630 PLUGIN_ERROR _TWO ("Failed to create output channel",643 PLUGIN_ERROR ("Failed to create output channel, '%s'\n", 631 644 channel_error->message); 632 645 g_error_free (channel_error); … … 634 647 } 635 648 else 636 PLUGIN_ERROR ("Failed to create output channel ");649 PLUGIN_ERROR ("Failed to create output channel\n"); 637 650 638 651 np_error = NPERR_GENERIC_ERROR; … … 659 672 if (channel_error) 660 673 { 661 PLUGIN_ERROR _TWO ("Failed to create input channel",674 PLUGIN_ERROR ("Failed to create input channel, '%s'\n", 662 675 channel_error->message); 663 676 g_error_free (channel_error); … … 665 678 } 666 679 else 667 PLUGIN_ERROR ("Failed to create input channel ");680 PLUGIN_ERROR ("Failed to create input channel\n"); 668 681 669 682 np_error = NPERR_GENERIC_ERROR; … … 676 689 (GIOCondition) (G_IO_IN | G_IO_ERR | G_IO_HUP), 677 690 plugin_in_pipe_callback, (gpointer) in_from_appletviewer); 691 692 // Create plugin-to-appletviewer console debug channel. The default encoding for 693 // the file is UTF-8. 694 // debug_to_appletviewer 695 if (plugin_debug_to_console){ 696 debug_to_appletviewer = g_io_channel_new_file (debug_pipe_name, 697 "w", &channel_error); 698 if (!debug_to_appletviewer) 699 { 700 if (channel_error) 701 { 702 PLUGIN_ERROR ("Failed to debug output channel, '%s'\n", 703 channel_error->message); 704 g_error_free (channel_error); 705 channel_error = NULL; 706 } 707 else 708 PLUGIN_ERROR ("Failed to create debug channel\n"); 709 710 np_error = NPERR_GENERIC_ERROR; 711 goto cleanup_debug_to_appletviewer; 712 } 713 } 678 714 679 715 jvm_up = TRUE; 680 716 717 if (plugin_debug_to_console){ 718 //jvm is up, we can start console producer thread 719 pthread_t debug_to_console_consumer; 720 pthread_create(&debug_to_console_consumer,NULL,&flush_pre_init_messages,NULL); 721 } 681 722 goto done; 682 723 683 // Free allocated data 724 // Free allocated data in case of error 725 cleanup_debug_to_appletviewer: 726 if (plugin_debug_to_console){ 727 if (debug_to_appletviewer) 728 g_io_channel_unref (debug_to_appletviewer); 729 debug_to_appletviewer = NULL; 730 } 684 731 685 732 cleanup_in_watch_source: … … 702 749 g_io_channel_unref (out_to_appletviewer); 703 750 out_to_appletviewer = NULL; 751 752 if (plugin_debug_to_console){ 753 // cleanup_debug_pipe: 754 // Delete output pipe. 755 PLUGIN_DEBUG ("ITNP_New: deleting debug fifo: %s\n", debug_pipe_name); 756 unlink (debug_pipe_name); 757 PLUGIN_DEBUG ("ITNP_New: deleted debug fifo: %s\n", debug_pipe_name); 758 } 759 cleanup_debug_pipe_name: 760 if (plugin_debug_to_console){ 761 g_free (debug_pipe_name); 762 debug_pipe_name = NULL; 763 } 764 765 704 766 705 767 // cleanup_out_pipe: … … 735 797 #endif 736 798 799 cleanUpDir(); 737 800 done: 738 801 802 IcedTeaPluginUtilities::printDebugStatus(); 739 803 // Now other threads may re-enter.. unlock the mutex 740 804 g_mutex_unlock(vm_start_mutex); 805 return np_error; 741 806 742 807 } … … 765 830 break; 766 831 default: 767 PLUGIN_ERROR ("Unknown plugin value requested. ");832 PLUGIN_ERROR ("Unknown plugin value requested.\n"); 768 833 np_error = NPERR_GENERIC_ERROR; 769 834 break; … … 814 879 if (instance == NULL) 815 880 { 816 PLUGIN_ERROR ("Invalid instance. ");881 PLUGIN_ERROR ("Invalid instance.\n"); 817 882 818 883 return NPERR_INVALID_INSTANCE_ERROR; … … 927 992 plugin_send_initialization_message( 928 993 data->instance_id, (gulong) data->window_handle, 929 data->window_width, data->window_height, data-> applet_tag);994 data->window_width, data->window_height, data->parameters_string); 930 995 931 996 g_mutex_unlock (data->appletviewer_mutex); … … 1023 1088 return NPERR_GENERIC_ERROR; 1024 1089 } 1025 #if MOZILLA_VERSION_COLLAPSED < 10901001026 nsresult rv;1027 nsCOMPtr<nsIScriptSecurityManager> sec_man =1028 do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);1029 1030 if (!sec_man) {1031 return NPERR_GENERIC_ERROR;1032 }1033 1034 nsCOMPtr<nsIIOService> io_svc = do_GetService("@mozilla.org/network/io-service;1", &rv);1035 1036 if (NS_FAILED(rv) || !io_svc) {1037 return NPERR_GENERIC_ERROR;1038 }1039 1040 nsCOMPtr<nsIURI> uri;1041 io_svc->NewURI(nsCString(siteAddr), NULL, NULL, getter_AddRefs(uri));1042 1043 nsCOMPtr<nsICookieService> cookie_svc = do_GetService("@mozilla.org/cookieService;1", &rv);1044 1045 if (NS_FAILED(rv) || !cookie_svc) {1046 return NPERR_GENERIC_ERROR;1047 }1048 1049 rv = cookie_svc->GetCookieString(uri, NULL, cookieString);1050 1051 if (NS_FAILED(rv) || !*cookieString) {1052 return NPERR_GENERIC_ERROR;1053 }1054 1055 #else1056 1057 1090 // getvalueforurl needs an NPP instance. Quite frankly, there is no easy way 1058 1091 // to know which instance needs the information, as applets on Java side can … … 1073 1106 } 1074 1107 1075 #endif1076 1077 1108 return NPERR_NO_ERROR; 1078 1109 } … … 1095 1126 // HELPER FUNCTIONS 1096 1127 1097 static void 1098 plugin_data_new ( ITNPPluginData** data)1128 ITNPPluginData* 1129 plugin_data_new () 1099 1130 { 1100 1131 PLUGIN_DEBUG ("plugin_data_new\n"); 1101 1132 1102 *data = (ITNPPluginData*)1103 (*browser_functions.memalloc) (sizeof (struct ITNPPluginData)); 1104 1105 // appletviewer_alive is false until the applet viewer is spawned.1106 if (*data)1107 memset (*data, 0, sizeof (struct ITNPPluginData));1108 1133 ITNPPluginData* data = (ITNPPluginData*)browser_functions.memalloc(sizeof (struct ITNPPluginData)); 1134 1135 if (data) 1136 { 1137 // Call constructor on allocated data 1138 new (data) ITNPPluginData(); 1139 } 1109 1140 PLUGIN_DEBUG ("plugin_data_new return\n"); 1141 1142 return data; 1110 1143 } 1111 1144 … … 1115 1148 // documentbase. This function relies on browser-private data so it 1116 1149 // will only work when the plugin is loaded in a Mozilla-based 1117 // browser. We could not find a way to retrieve the documentbase 1118 // using the original Netscape plugin API so we use the XPCOM API 1119 // instead. 1120 #if MOZILLA_VERSION_COLLAPSED < 1090100 1121 static gchar* 1150 // browser. 1151 static std::string 1122 1152 plugin_get_documentbase (NPP instance) 1123 1153 { 1124 1154 PLUGIN_DEBUG ("plugin_get_documentbase\n"); 1125 1126 nsIPluginInstance* xpcom_instance = NULL;1127 nsIPluginInstancePeer* peer = NULL;1128 nsresult result = 0;1129 nsIPluginTagInfo2* pluginTagInfo2 = NULL;1130 info_union u = { NULL };1131 char const* documentbase = NULL;1132 gchar* documentbase_copy = NULL;1133 1134 xpcom_instance = (nsIPluginInstance*) (instance->ndata);1135 if (!xpcom_instance)1136 {1137 PLUGIN_ERROR ("xpcom_instance is NULL.");1138 goto cleanup_done;1139 }1140 1141 xpcom_instance->GetPeer (&peer);1142 if (!peer)1143 {1144 PLUGIN_ERROR ("peer is NULL.");1145 goto cleanup_done;1146 }1147 1148 u.info_field = &pluginTagInfo2;1149 1150 result = peer->QueryInterface (kIPluginTagInfo2IID,1151 u.void_field);1152 if (result || !pluginTagInfo2)1153 {1154 PLUGIN_ERROR ("pluginTagInfo2 retrieval failed.");1155 goto cleanup_peer;1156 }1157 1158 pluginTagInfo2->GetDocumentBase (&documentbase);1159 1160 if (!documentbase)1161 {1162 // NULL => dummy instantiation for LiveConnect1163 goto cleanup_plugintaginfo2;1164 }1165 1166 documentbase_copy = g_strdup (documentbase);1167 1168 // Release references.1169 cleanup_plugintaginfo2:1170 NS_RELEASE (pluginTagInfo2);1171 1172 cleanup_peer:1173 NS_RELEASE (peer);1174 1175 cleanup_done:1176 PLUGIN_DEBUG ("plugin_get_documentbase return\n");1177 1178 PLUGIN_DEBUG("plugin_get_documentbase returning: %s\n", documentbase_copy);1179 return documentbase_copy;1180 }1181 #else1182 static gchar*1183 plugin_get_documentbase (NPP instance)1184 {1185 PLUGIN_DEBUG ("plugin_get_documentbase\n");1186 1187 char const* documentbase = NULL;1188 gchar* documentbase_copy = NULL;1189 1155 1190 1156 // FIXME: This method is not ideal, but there are no known NPAPI call … … 1207 1173 1208 1174 std::string href_str = IcedTeaPluginUtilities::NPVariantAsString(href); 1209 documentbase_copy = g_strdup (href_str.c_str());1210 1175 1211 1176 // Release references. 1212 1177 browser_functions.releasevariantvalue(&href); 1213 1178 browser_functions.releasevariantvalue(&location); 1214 cleanup_done: 1179 1215 1180 PLUGIN_DEBUG ("plugin_get_documentbase return\n"); 1216 PLUGIN_DEBUG("plugin_get_documentbase returning: %s\n", documentbase_copy); 1217 1218 return documentbase_copy; 1219 } 1220 #endif 1221 1222 // This function displays an error message if the appletviewer has not 1223 // been installed correctly. 1224 static void 1225 plugin_display_failure_dialog () 1226 { 1227 #ifdef __OS2__ 1228 gchar *msg = NULL; 1229 1230 PLUGIN_DEBUG ("plugin_display_failure_dialog\n"); 1231 1232 msg = g_strdup_printf (FAILURE_MESSAGE, appletviewer_executable); 1233 WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, 1234 msg, "Error", 0, MB_ERROR | MB_OK | MB_MOVEABLE); 1235 g_free(msg); 1236 #else 1237 GtkWidget* dialog = NULL; 1238 1239 PLUGIN_DEBUG ("plugin_display_failure_dialog\n"); 1240 1241 dialog = gtk_message_dialog_new (NULL, 1242 GTK_DIALOG_DESTROY_WITH_PARENT, 1243 GTK_MESSAGE_ERROR, 1244 GTK_BUTTONS_CLOSE, 1245 FAILURE_MESSAGE, 1246 appletviewer_executable); 1247 gtk_widget_show_all (dialog); 1248 gtk_dialog_run (GTK_DIALOG (dialog)); 1249 gtk_widget_destroy (dialog); 1250 #endif 1251 1252 PLUGIN_DEBUG ("plugin_display_failure_dialog return\n"); 1253 } 1254 1255 1181 PLUGIN_DEBUG("plugin_get_documentbase returning: %s\n", href_str.c_str()); 1182 1183 return href_str; 1184 } 1256 1185 1257 1186 // plugin_in_pipe_callback is called when data is available on the … … 1279 1208 if (channel_error) 1280 1209 { 1281 PLUGIN_ERROR _TWO ("Failed to read line from input channel",1210 PLUGIN_ERROR ("Failed to read line from input channel, %s\n", 1282 1211 channel_error->message); 1283 1212 g_error_free (channel_error); … … 1285 1214 } 1286 1215 else 1287 PLUGIN_ERROR ("Failed to read line from input channel ");1216 PLUGIN_ERROR ("Failed to read line from input channel\n"); 1288 1217 #ifdef __OS2__ 1289 1218 // G_IO_ERR/HUP is not reported on file/pipe handles, simulate it … … 1318 1247 if (g_str_has_prefix(parts[1], "PluginProxyInfo")) 1319 1248 { 1320 gchar* proxy ;1249 gchar* proxy = NULL; 1321 1250 uint32_t len; 1322 1251 … … 1326 1255 1327 1256 gchar* proxy_info; 1328 1329 #if MOZILLA_VERSION_COLLAPSED < 10901001330 proxy = (char*) malloc(sizeof(char)*2048);1331 #endif1332 1257 1333 1258 proxy_info = g_strconcat ("plugin PluginProxyInfo reference ", parts[3], " ", NULL); … … 1345 1270 proxy_info = NULL; 1346 1271 1347 #if MOZILLA_VERSION_COLLAPSED < 1090100 1348 g_free(proxy); 1349 proxy = NULL; 1350 #endif 1272 g_free(proxy); 1273 proxy = NULL; 1351 1274 1352 1275 } else if (g_str_has_prefix(parts[1], "PluginCookieInfo")) … … 1356 1279 1357 1280 gchar* cookie_info = g_strconcat ("plugin PluginCookieInfo reference ", parts[3], " ", NULL); 1358 gchar* cookie_string ;1281 gchar* cookie_string = NULL; 1359 1282 uint32_t len; 1360 1283 if (get_cookie_info(decoded_url, &cookie_string, &len) == NPERR_NO_ERROR) … … 1370 1293 g_free(cookie_info); 1371 1294 cookie_info = NULL; 1295 g_free(cookie_string); 1296 cookie_string = NULL; 1372 1297 } else if (g_str_has_prefix(parts[1], "PluginSetCookie")) 1373 1298 { … … 1498 1423 return NPERR_GENERIC_ERROR; 1499 1424 } 1500 #if MOZILLA_VERSION_COLLAPSED < 10901001501 nsresult rv;1502 1503 // Initialize service variables1504 nsCOMPtr<nsIProtocolProxyService> proxy_svc = do_GetService("@mozilla.org/network/protocol-proxy-service;1", &rv);1505 1506 if (!proxy_svc) {1507 printf("Cannot initialize proxy service\n");1508 return NPERR_GENERIC_ERROR;1509 }1510 1511 nsCOMPtr<nsIIOService> io_svc = do_GetService("@mozilla.org/network/io-service;1", &rv);1512 1513 if (NS_FAILED(rv) || !io_svc) {1514 printf("Cannot initialize io service\n");1515 return NPERR_GENERIC_ERROR;1516 }1517 1518 // uri which needs to be accessed1519 nsCOMPtr<nsIURI> uri;1520 io_svc->NewURI(nsCString(siteAddr), NULL, NULL, getter_AddRefs(uri));1521 1522 // find the proxy address if any1523 nsCOMPtr<nsIProxyInfo> info;1524 proxy_svc->Resolve(uri, 0, getter_AddRefs(info));1525 1526 // if there is no proxy found, return immediately1527 if (!info) {1528 PLUGIN_DEBUG("%s does not need a proxy\n", siteAddr);1529 return NPERR_GENERIC_ERROR;1530 }1531 1532 // if proxy info is available, extract it1533 nsCString phost;1534 PRInt32 pport;1535 nsCString ptype;1536 1537 info->GetHost(phost);1538 info->GetPort(&pport);1539 info->GetType(ptype);1540 1541 // resolve the proxy address to an IP1542 nsCOMPtr<nsIDNSService> dns_svc = do_GetService("@mozilla.org/network/dns-service;1", &rv);1543 1544 if (!dns_svc) {1545 printf("Cannot initialize DNS service\n");1546 return NPERR_GENERIC_ERROR;1547 }1548 1549 nsCOMPtr<nsIDNSRecord> record;1550 dns_svc->Resolve(phost, 0U, getter_AddRefs(record));1551 1552 // TODO: Add support for multiple ips1553 nsDependentCString ipAddr;1554 record->GetNextAddrAsString(ipAddr);1555 1556 if (!strcmp(ptype.get(), "http"))1557 {1558 snprintf(*proxy, sizeof(char)*1024, "%s %s:%d", "PROXY", ipAddr.get(), pport);1559 } else1560 {1561 snprintf(*proxy, sizeof(char)*1024, "%s %s:%d", "SOCKS", ipAddr.get(), pport);1562 }1563 1564 *len = strlen(*proxy);1565 1566 PLUGIN_DEBUG("Proxy info for %s: %s\n", siteAddr, *proxy);1567 1568 #else1569 1570 1425 if (browser_functions.getvalueforurl) 1571 1426 { … … 1578 1433 return NPERR_GENERIC_ERROR; 1579 1434 } 1580 #endif1581 1435 1582 1436 return NPERR_NO_ERROR; … … 1678 1532 plugin_test_appletviewer () 1679 1533 { 1680 PLUGIN_DEBUG ("plugin_test_appletviewer: %s\n", appletviewer_executable); 1534 1535 PLUGIN_DEBUG ("plugin_test_appletviewer: %s\n", get_plugin_executable().c_str()); 1681 1536 NPError error = NPERR_NO_ERROR; 1682 1537 … … 1684 1539 gchar** environment; 1685 1540 1686 command_line[0] = g_strdup ( appletviewer_executable);1541 command_line[0] = g_strdup (get_plugin_executable().c_str()); 1687 1542 command_line[1] = g_strdup("-version"); 1688 1543 command_line[2] = NULL; … … 1696 1551 if (channel_error) 1697 1552 { 1698 PLUGIN_ERROR _TWO ("Failed to spawn applet viewer",1553 PLUGIN_ERROR ("Failed to spawn applet viewer %s\n", 1699 1554 channel_error->message); 1700 1555 g_error_free (channel_error); … … 1702 1557 } 1703 1558 else 1704 PLUGIN_ERROR ("Failed to spawn applet viewer ");1559 PLUGIN_ERROR ("Failed to spawn applet viewer\n"); 1705 1560 error = NPERR_GENERIC_ERROR; 1706 1561 } … … 1719 1574 } 1720 1575 1721 staticNPError1576 NPError 1722 1577 plugin_start_appletviewer (ITNPPluginData* data) 1723 1578 { … … 1725 1580 NPError error = NPERR_NO_ERROR; 1726 1581 1727 gchar** command_line; 1728 gchar** environment; 1729 1730 int cmd_num = 0; 1582 std::vector<std::string> command_line; 1583 gchar** environment = NULL; 1584 std::vector<std::string*>* jvm_args = get_jvm_args(); 1585 1586 // Construct command line parameters 1587 1588 command_line.push_back(get_plugin_executable()); 1589 1590 //Add JVM args to command_line 1591 for (int i = 0; i < jvm_args->size(); i++) 1592 { 1593 command_line.push_back(*jvm_args->at(i)); 1594 } 1595 1596 command_line.push_back(PLUGIN_BOOTCLASSPATH); 1597 // set the classpath to avoid using the default (cwd). 1598 command_line.push_back("-classpath"); 1599 command_line.push_back(get_plugin_rt_jar()); 1600 1601 // Enable coverage agent if we are running instrumented plugin 1602 #ifdef COVERAGE_AGENT 1603 command_line.push_back(COVERAGE_AGENT); 1604 #endif 1605 1731 1606 if (plugin_debug) 1732 1607 { 1733 command_line = (gchar**) malloc(sizeof(gchar*)*11); 1734 command_line[cmd_num++] = g_strdup(appletviewer_executable); 1735 command_line[cmd_num++] = g_strdup_printf(PLUGIN_BOOTCLASSPATH); 1736 // set the classpath to avoid using the default (cwd). 1737 command_line[cmd_num++] = g_strdup("-classpath"); 1738 command_line[cmd_num++] = g_strdup_printf("%s/lib/rt.jar", ICEDTEA_WEB_JRE); 1739 command_line[cmd_num++] = g_strdup("-Xdebug"); 1740 command_line[cmd_num++] = g_strdup("-Xnoagent"); 1741 if (plugin_debug_suspend) 1742 { 1743 command_line[cmd_num++] = g_strdup("-Xrunjdwp:transport="DT_SOCKET_DLL",address=8787,server=y,suspend=y"); 1744 } else 1745 { 1746 command_line[cmd_num++] = g_strdup("-Xrunjdwp:transport="DT_SOCKET_DLL",address=8787,server=y,suspend=n"); 1747 } 1748 command_line[cmd_num++] = g_strdup("sun.applet.PluginMain"); 1749 #ifdef __OS2__ 1750 command_line[cmd_num++] = g_strdup_printf("%d", out_pipe [1]); 1751 command_line[cmd_num++] = g_strdup_printf("%d", in_pipe [1]); 1608 command_line.push_back("-Xdebug"); 1609 command_line.push_back("-Xnoagent"); 1610 1611 //Debug flags 1612 std::string debug_flags = "-Xrunjdwp:transport="DT_SOCKET_DLL",address=8787,server=y,"; 1613 debug_flags += plugin_debug_suspend ? "suspend=y" : "suspend=n"; 1614 command_line.push_back(debug_flags); 1615 } 1616 1617 command_line.push_back("sun.applet.PluginMain"); 1618 #ifdef __OS2__ 1619 command_line.push_back((std::ostrstream() << out_pipe[1]).str()); 1620 command_line.push_back((std::ostrstream() << in_pipe[1]).str()); 1752 1621 #else 1753 command_line[cmd_num++] = g_strdup(out_pipe_name); 1754 command_line[cmd_num++] = g_strdup(in_pipe_name); 1755 #endif 1756 command_line[cmd_num] = NULL; 1757 } else 1758 { 1759 command_line = (gchar**) malloc(sizeof(gchar*)*8); 1760 command_line[cmd_num++] = g_strdup(appletviewer_executable); 1761 command_line[cmd_num++] = g_strdup_printf(PLUGIN_BOOTCLASSPATH); 1762 command_line[cmd_num++] = g_strdup("-classpath"); 1763 command_line[cmd_num++] = g_strdup_printf("%s/lib/rt.jar", ICEDTEA_WEB_JRE); 1764 command_line[cmd_num++] = g_strdup("sun.applet.PluginMain"); 1765 #ifdef __OS2__ 1766 command_line[cmd_num++] = g_strdup_printf("%d", out_pipe [1]); 1767 command_line[cmd_num++] = g_strdup_printf("%d", in_pipe [1]); 1622 command_line.push_back(out_pipe_name); 1623 command_line.push_back(in_pipe_name); 1624 #endif 1625 if (plugin_debug_to_console){ 1626 command_line.push_back(debug_pipe_name); 1627 } 1628 1629 // Finished command line parameters 1630 1631 environment = plugin_filter_environment(); 1632 std::vector<gchar*> vector_gchar = IcedTeaPluginUtilities::vectorStringToVectorGchar(&command_line); 1633 gchar **command_line_args = &vector_gchar[0]; 1634 1635 if (!g_spawn_async (NULL, command_line_args, environment, 1636 #ifdef __OS2__ 1637 (GSpawnFlags) (G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD), 1768 1638 #else 1769 command_line[cmd_num++] = g_strdup(out_pipe_name); 1770 command_line[cmd_num++] = g_strdup(in_pipe_name); 1771 #endif 1772 command_line[cmd_num] = NULL; 1773 } 1774 1775 environment = plugin_filter_environment(); 1776 1777 #ifdef __OS2__ 1778 int flags = G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD; 1779 #else 1780 int flags = G_SPAWN_DO_NOT_REAP_CHILD; 1781 #endif 1782 1783 if (!g_spawn_async (NULL, command_line, environment, 1784 (GSpawnFlags) flags, 1639 (GSpawnFlags) G_SPAWN_DO_NOT_REAP_CHILD, 1640 #endif 1785 1641 NULL, NULL, &appletviewer_pid, &channel_error)) 1786 1642 { 1787 1643 if (channel_error) 1788 1644 { 1789 PLUGIN_ERROR _TWO ("Failed to spawn applet viewer",1645 PLUGIN_ERROR ("Failed to spawn applet viewer %s\n", 1790 1646 channel_error->message); 1791 1647 g_error_free (channel_error); … … 1793 1649 } 1794 1650 else 1795 PLUGIN_ERROR ("Failed to spawn applet viewer ");1651 PLUGIN_ERROR ("Failed to spawn applet viewer\n"); 1796 1652 error = NPERR_GENERIC_ERROR; 1797 1653 } … … 1802 1658 signal (SIGPIPE, SIG_IGN); 1803 1659 1804 g_strfreev (environment); 1805 1806 for (int i = 0; i < cmd_num; i++) { 1807 g_free (command_line[i]); 1808 command_line[i] = NULL; 1809 } 1810 1811 g_free(command_line); 1812 command_line = NULL; 1660 //Free memory 1661 g_strfreev(environment); 1662 IcedTeaPluginUtilities::freeStringPtrVector(jvm_args); 1663 jvm_args = NULL; 1664 command_line_args = NULL; 1813 1665 1814 1666 if (appletviewer_pid) … … 1824 1676 1825 1677 /* 1826 * Replaces certain characters (\r, \n, etc) with HTML escape equivalents. 1827 * 1828 * Return string is allocated on the heap. Caller assumes responsibility 1829 * for freeing the memory via free() 1678 * Returns JVM options set in itw-settings 1830 1679 */ 1831 static char* 1832 encode_string(char* to_encode) 1833 { 1834 1835 // Do nothing for an empty string 1836 if (to_encode == '\0') 1837 return to_encode; 1838 1839 // worst case scenario -> all characters are newlines or 1840 // returns, each of which translates to 5 substitutions 1841 char* encoded = (char*) calloc(((strlen(to_encode)*5)+1), sizeof(char)); 1842 1843 strcpy(encoded, ""); 1844 1845 for (int i=0; i < strlen(to_encode); i++) 1846 { 1847 if (to_encode[i] == '\r') 1848 encoded = strcat(encoded, " "); 1849 else if (to_encode[i] == '\n') 1850 encoded = strcat(encoded, " "); 1851 else if (to_encode[i] == '>') 1852 encoded = strcat(encoded, ">"); 1853 else if (to_encode[i] == '<') 1854 encoded = strcat(encoded, "<"); 1855 else if (to_encode[i] == '&') 1856 encoded = strcat(encoded, "&"); 1857 else if (to_encode[i] == '"') 1858 encoded = strcat(encoded, """); 1680 std::vector<std::string*>* 1681 get_jvm_args() 1682 { 1683 std::string output; 1684 std::vector<std::string*>* tokenOutput = NULL; 1685 bool args_defined = read_deploy_property_value("deployment.plugin.jvm.arguments", output); 1686 if (!args_defined){ 1687 return new std::vector<std::string*>(); 1688 } 1689 tokenOutput = IcedTeaPluginUtilities::strSplit(output.c_str(), " \n"); 1690 return tokenOutput; 1691 } 1692 1693 1694 /* 1695 * Escape characters for passing to Java. 1696 * "\n" for new line, "\\" for "\", "\:" for ";" 1697 */ 1698 std::string 1699 escape_parameter_string(const char* to_encode) { 1700 std::string encoded; 1701 1702 if (to_encode == NULL) 1703 { 1704 return encoded; 1705 } 1706 1707 size_t length = strlen(to_encode); 1708 for (int i = 0; i < length; i++) 1709 { 1710 if (to_encode[i] == '\n') 1711 encoded += "\\n"; 1712 else if (to_encode[i] == '\\') 1713 encoded += "\\\\"; 1714 else if (to_encode[i] == ';') 1715 encoded += "\\:"; 1859 1716 else 1860 { 1861 char* orig_char = (char*) calloc(2, sizeof(char)); 1862 orig_char[0] = to_encode[i]; 1863 orig_char[1] = '\0'; 1864 1865 strcat(encoded, orig_char); 1866 1867 free(orig_char); 1868 orig_char = NULL; 1869 } 1717 encoded += to_encode[i]; 1870 1718 } 1871 1719 … … 1873 1721 } 1874 1722 1875 // Build up the applet tag string that we'll send to the applet 1876 // viewer. 1877 static gchar* 1878 plugin_create_applet_tag (int16_t argc, char* argn[], char* argv[]) 1879 { 1880 PLUGIN_DEBUG ("plugin_create_applet_tag\n"); 1881 1882 gchar* applet_tag = g_strdup ("<EMBED "); 1883 gchar* parameters = g_strdup (""); 1884 1885 for (int16_t i = 0; i < argc; i++) 1886 { 1887 gchar* argn_escaped = encode_string(argn[i]); 1888 gchar* argv_escaped = encode_string(argv[i]); 1889 1890 if (!g_ascii_strcasecmp (argn_escaped, "code")) 1891 { 1892 gchar* code = g_strdup_printf ("CODE=\"%s\" ", argv_escaped); 1893 applet_tag = g_strconcat (applet_tag, code, NULL); 1894 g_free (code); 1895 code = NULL; 1896 } 1897 else if (!g_ascii_strcasecmp (argn_escaped, "java_code")) 1898 { 1899 gchar* java_code = g_strdup_printf ("JAVA_CODE=\"%s\" ", argv_escaped); 1900 applet_tag = g_strconcat (applet_tag, java_code, NULL); 1901 g_free (java_code); 1902 java_code = NULL; 1903 } 1904 else if (!g_ascii_strcasecmp (argn_escaped, "codebase")) 1905 { 1906 gchar* codebase = g_strdup_printf ("CODEBASE=\"%s\" ", argv_escaped); 1907 applet_tag = g_strconcat (applet_tag, codebase, NULL); 1908 g_free (codebase); 1909 codebase = NULL; 1910 } 1911 else if (!g_ascii_strcasecmp (argn_escaped, "java_codebase")) 1912 { 1913 gchar* java_codebase = g_strdup_printf ("JAVA_CODEBASE=\"%s\" ", argv_escaped); 1914 applet_tag = g_strconcat (applet_tag, java_codebase, NULL); 1915 g_free (java_codebase); 1916 java_codebase = NULL; 1917 } 1918 else if (!g_ascii_strcasecmp (argn_escaped, "classid")) 1919 { 1920 gchar* classid = g_strdup_printf ("CLASSID=\"%s\" ", argv_escaped); 1921 applet_tag = g_strconcat (applet_tag, classid, NULL); 1922 g_free (classid); 1923 classid = NULL; 1924 } 1925 else if (!g_ascii_strcasecmp (argn_escaped, "archive")) 1926 { 1927 gchar* archive = g_strdup_printf ("ARCHIVE=\"%s\" ", argv_escaped); 1928 applet_tag = g_strconcat (applet_tag, archive, NULL); 1929 g_free (archive); 1930 archive = NULL; 1931 } 1932 else if (!g_ascii_strcasecmp (argn_escaped, "java_archive")) 1933 { 1934 gchar* java_archive = g_strdup_printf ("JAVA_ARCHIVE=\"%s\" ", argv_escaped); 1935 applet_tag = g_strconcat (applet_tag, java_archive, NULL); 1936 g_free (java_archive); 1937 java_archive = NULL; 1938 } 1939 else if (!g_ascii_strcasecmp (argn_escaped, "width")) 1940 { 1941 gchar* width = g_strdup_printf ("width=\"%s\" ", argv_escaped); 1942 applet_tag = g_strconcat (applet_tag, width, NULL); 1943 g_free (width); 1944 width = NULL; 1945 } 1946 else if (!g_ascii_strcasecmp (argn_escaped, "height")) 1947 { 1948 gchar* height = g_strdup_printf ("height=\"%s\" ", argv_escaped); 1949 applet_tag = g_strconcat (applet_tag, height, NULL); 1950 g_free (height); 1951 height = NULL; 1952 } 1953 else 1954 { 1955 1956 if (argv_escaped != '\0') 1957 { 1958 parameters = g_strconcat (parameters, "<PARAM NAME=\"", argn_escaped, 1959 "\" VALUE=\"", argv_escaped, "\">", NULL); 1960 } 1961 } 1962 1963 free(argn_escaped); 1964 free(argv_escaped); 1965 1966 argn_escaped = NULL; 1967 argv_escaped = NULL; 1968 } 1969 1970 applet_tag = g_strconcat (applet_tag, ">", parameters, "</EMBED>", NULL); 1971 1972 g_free (parameters); 1973 parameters = NULL; 1974 1975 PLUGIN_DEBUG ("plugin_create_applet_tag return\n"); 1976 1977 return applet_tag; 1723 /* 1724 * Build a string containing an encoded list of parameters to send to the applet viewer. 1725 * The parameters are separated as 'key1;value1;key2;value2;'. As well, they are 1726 * separated and escaped as: 1727 * "\n" for new line, "\\" for "\", "\:" for ";" 1728 */ 1729 std::string 1730 plugin_parameters_string (int argc, char* argn[], char* argv[]) 1731 { 1732 PLUGIN_DEBUG ("plugin_parameters_string\n"); 1733 1734 std::string parameters; 1735 1736 for (int i = 0; i < argc; i++) 1737 { 1738 if (argv[i] != NULL) 1739 { 1740 std::string name_escaped = escape_parameter_string(argn[i]); 1741 std::string value_escaped = escape_parameter_string(argv[i]); 1742 1743 //Encode parameters and send as 'key1;value1;key2;value2;' etc 1744 parameters += name_escaped; 1745 parameters += ';'; 1746 parameters += value_escaped; 1747 parameters += ';'; 1748 } 1749 } 1750 1751 PLUGIN_DEBUG ("plugin_parameters_string return\n"); 1752 1753 return parameters; 1978 1754 } 1979 1755 … … 2003 1779 if (channel_error) 2004 1780 { 2005 PLUGIN_ERROR _TWO ("Failed to write bytes to output channel",1781 PLUGIN_ERROR ("Failed to write bytes to output channel '%s' \n", 2006 1782 channel_error->message); 2007 1783 g_error_free (channel_error); … … 2009 1785 } 2010 1786 else 2011 PLUGIN_ERROR ("Failed to write bytes to output channel ");1787 PLUGIN_ERROR ("Failed to write bytes to output channel for %s", newline_message); 2012 1788 } 2013 1789 … … 2017 1793 if (channel_error) 2018 1794 { 2019 PLUGIN_ERROR _TWO ("Failed to flush bytes to output channel",1795 PLUGIN_ERROR ("Failed to flush bytes to output channel '%s'\n", 2020 1796 channel_error->message); 2021 1797 g_error_free (channel_error); … … 2023 1799 } 2024 1800 else 2025 PLUGIN_ERROR ("Failed to flush bytes to output channel ");1801 PLUGIN_ERROR ("Failed to flush bytes to output channel for %s", newline_message); 2026 1802 } 2027 1803 g_free (newline_message); 2028 1804 newline_message = NULL; 2029 1805 2030 PLUGIN_DEBUG (" PIPE: plugin wrote : %s\n", message);1806 PLUGIN_DEBUG (" PIPE: plugin wrote(?): %s\n", message); 2031 1807 } 2032 1808 2033 1809 PLUGIN_DEBUG ("plugin_send_message_to_appletviewer return\n"); 1810 } 1811 1812 // unlike like plugin_send_message_to_appletviewer 1813 // do not debug 1814 // do not error 1815 // do not have its own line end 1816 // is accesed by only one thread 1817 // have own pipe 1818 // jvm must be up 1819 void 1820 plugin_send_message_to_appletviewer_console (gchar const* newline_message) 1821 { 1822 gsize bytes_written = 0; 1823 if (g_io_channel_write_chars (debug_to_appletviewer, 1824 newline_message, -1, &bytes_written, 1825 &channel_error) != G_IO_STATUS_NORMAL) { 1826 if (channel_error) { 1827 //error must be freed 1828 g_error_free (channel_error); 1829 channel_error = NULL; 1830 } 1831 } 1832 } 1833 //flush only when its full 1834 void flush_plugin_send_message_to_appletviewer_console (){ 1835 if (g_io_channel_flush (debug_to_appletviewer, &channel_error) 1836 != G_IO_STATUS_NORMAL) { 1837 if (channel_error) { 1838 g_error_free (channel_error); 1839 channel_error = NULL; 1840 } 1841 } 2034 1842 } 2035 1843 … … 2084 1892 if (channel_error) 2085 1893 { 2086 PLUGIN_ERROR _TWO ("Failed to write shutdown message to"2087 " appletviewer ", channel_error->message);1894 PLUGIN_ERROR ("Failed to write shutdown message to " 1895 " appletviewer, %s \n", channel_error->message); 2088 1896 g_error_free (channel_error); 2089 1897 channel_error = NULL; 2090 1898 } 2091 1899 else 2092 PLUGIN_ERROR ("Failed to write shutdown message to ");1900 PLUGIN_ERROR ("Failed to write shutdown message to\n"); 2093 1901 } 2094 1902 … … 2098 1906 if (channel_error) 2099 1907 { 2100 PLUGIN_ERROR _TWO("Failed to write shutdown message to"2101 " appletviewer ", channel_error->message);1908 PLUGIN_ERROR ("Failed to write shutdown message to" 1909 " appletviewer %s \n", channel_error->message); 2102 1910 g_error_free (channel_error); 2103 1911 channel_error = NULL; 2104 1912 } 2105 1913 else 2106 PLUGIN_ERROR ("Failed to write shutdown message to ");1914 PLUGIN_ERROR ("Failed to write shutdown message to\n"); 2107 1915 } 2108 1916 … … 2113 1921 if (channel_error) 2114 1922 { 2115 PLUGIN_ERROR _TWO("Failed to shut down appletviewer"2116 " output channel ", channel_error->message);1923 PLUGIN_ERROR ("Failed to shut down appletviewer" 1924 " output channel %s \n", channel_error->message); 2117 1925 g_error_free (channel_error); 2118 1926 channel_error = NULL; 2119 1927 } 2120 1928 else 2121 PLUGIN_ERROR ("Failed to shut down appletviewer ");1929 PLUGIN_ERROR ("Failed to shut down appletviewer\n"); 2122 1930 } 2123 1931 } … … 2131 1939 if (channel_error) 2132 1940 { 2133 PLUGIN_ERROR _TWO("Failed to shut down appletviewer"2134 " input channel ", channel_error->message);1941 PLUGIN_ERROR ("Failed to shut down appletviewer" 1942 " input channel %s \n", channel_error->message); 2135 1943 g_error_free (channel_error); 2136 1944 channel_error = NULL; 2137 1945 } 2138 1946 else 2139 PLUGIN_ERROR ("Failed to shut down appletviewer ");1947 PLUGIN_ERROR ("Failed to shut down appletviewer\n"); 2140 1948 } 2141 1949 } … … 2156 1964 } 2157 1965 2158 staticvoid1966 void 2159 1967 plugin_data_destroy (NPP instance) 2160 1968 { … … 2173 1981 } 2174 1982 2175 tofree->window_handle = NULL; 2176 tofree->window_height = 0; 2177 tofree->window_width = 0; 2178 2179 // cleanup_appletviewer_mutex: 2180 g_mutex_free (tofree->appletviewer_mutex); 2181 tofree->appletviewer_mutex = NULL; 2182 2183 // cleanup_instance_string: 2184 g_free (tofree->instance_id); 2185 tofree->instance_id = NULL; 2186 2187 // cleanup applet tag 2188 g_free (tofree->applet_tag); 2189 tofree->applet_tag = NULL; 2190 2191 g_free(tofree->source); 2192 tofree->source = NULL; 2193 2194 // cleanup_data: 2195 // Eliminate back-pointer to plugin instance. 2196 tofree->owner = NULL; 1983 /* Explicitly call destructor */ 1984 tofree->~ITNPPluginData(); 1985 2197 1986 (*browser_functions.memfree) (tofree); 2198 tofree = NULL;2199 1987 2200 1988 PLUGIN_DEBUG ("plugin_data_destroy return\n"); … … 2204 1992 initialize_browser_functions(const NPNetscapeFuncs* browserTable) 2205 1993 { 2206 #if MOZILLA_VERSION_COLLAPSED < 10901002207 #define NPNETSCAPEFUNCS_LAST_FIELD_USED (browserTable->pluginthreadasynccall)2208 #else2209 1994 #define NPNETSCAPEFUNCS_LAST_FIELD_USED (browserTable->setvalueforurl) 2210 #endif2211 1995 2212 1996 //Determine the size in bytes, as a difference of the address past the last used field … … 2250 2034 pluginTable->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; 2251 2035 pluginTable->size = sizeof (NPPluginFuncs); 2252 2253 #if MOZILLA_VERSION_COLLAPSED < 10901002254 pluginTable->newp = NewNPP_NewProc (ITNP_New);2255 pluginTable->destroy = NewNPP_DestroyProc (ITNP_Destroy);2256 pluginTable->setwindow = NewNPP_SetWindowProc (ITNP_SetWindow);2257 pluginTable->newstream = NewNPP_NewStreamProc (ITNP_NewStream);2258 pluginTable->destroystream = NewNPP_DestroyStreamProc (ITNP_DestroyStream);2259 pluginTable->asfile = NewNPP_StreamAsFileProc (ITNP_StreamAsFile);2260 pluginTable->writeready = NewNPP_WriteReadyProc (ITNP_WriteReady);2261 pluginTable->write = NewNPP_WriteProc (ITNP_Write);2262 pluginTable->print = NewNPP_PrintProc (ITNP_Print);2263 pluginTable->urlnotify = NewNPP_URLNotifyProc (ITNP_URLNotify);2264 pluginTable->getvalue = NewNPP_GetValueProc (ITNP_GetValue);2265 #else2266 2036 pluginTable->newp = NPP_NewProcPtr (ITNP_New); 2267 2037 pluginTable->destroy = NPP_DestroyProcPtr (ITNP_Destroy); … … 2275 2045 pluginTable->urlnotify = NPP_URLNotifyProcPtr (ITNP_URLNotify); 2276 2046 pluginTable->getvalue = NPP_GetValueProcPtr (ITNP_GetValue); 2277 #endif2278 2047 2279 2048 return true; 2049 } 2050 2051 // Make sure the plugin data directory exists, creating it if necessary. 2052 NPError 2053 initialize_data_directory() 2054 { 2055 2056 data_directory = IcedTeaPluginUtilities::getRuntimePath() + "/icedteaplugin-"; 2057 if (getenv("USER") != NULL) { 2058 data_directory = data_directory + getenv("USER") + "-"; 2059 } 2060 data_directory += "XXXXXX"; 2061 // Now create a icedteaplugin subdir 2062 char fileNameX[data_directory.length()+1]; 2063 std::strcpy (fileNameX, data_directory.c_str()); 2064 char * fileName = mkdtemp(fileNameX); 2065 if (fileName == NULL) { 2066 PLUGIN_ERROR ("Failed to create data directory %s, %s\n", 2067 data_directory.c_str(), 2068 strerror (errno)); 2069 return NPERR_GENERIC_ERROR; 2070 } 2071 data_directory = std::string(fileName); 2072 2073 //open uniques icedteaplugin subdir for one single run 2074 data_directory_descriptor = opendir(data_directory.c_str()); 2075 if (data_directory_descriptor == NULL) { 2076 PLUGIN_ERROR ("Failed to open data directory %s %s\n", 2077 data_directory.c_str(), strerror (errno)); 2078 return NPERR_GENERIC_ERROR; 2079 } 2080 2081 return NPERR_NO_ERROR; 2280 2082 } 2281 2083 … … 2291 2093 // been called. There is no need to call this function more than once and 2292 2094 // this workaround avoids any duplicate calls. 2095 __attribute__ ((visibility ("default"))) 2293 2096 NPError 2294 2097 #if defined(_WIN32) || defined (__OS2__) … … 2310 2113 if ((browserTable == NULL) || (pluginTable == NULL)) 2311 2114 { 2312 PLUGIN_ERROR ("Browser or plugin function table is NULL. ");2115 PLUGIN_ERROR ("Browser or plugin function table is NULL.\n"); 2313 2116 2314 2117 return NPERR_INVALID_FUNCTABLE_ERROR; … … 2321 2124 if ((browserTable->version >> 8) > NP_VERSION_MAJOR) 2322 2125 { 2323 PLUGIN_ERROR ("Incompatible version. ");2126 PLUGIN_ERROR ("Incompatible version.\n"); 2324 2127 2325 2128 return NPERR_INCOMPATIBLE_VERSION_ERROR; … … 2334 2137 if ( !browser_functions_supported ) 2335 2138 { 2336 PLUGIN_ERROR ("Invalid browser function table. ");2139 PLUGIN_ERROR ("Invalid browser function table.\n"); 2337 2140 2338 2141 return NPERR_INVALID_FUNCTABLE_ERROR; … … 2348 2151 if ( !plugin_functions_supported ) 2349 2152 { 2350 PLUGIN_ERROR ("Invalid plugin function table. ");2153 PLUGIN_ERROR ("Invalid plugin function table.\n"); 2351 2154 2352 2155 return NPERR_INVALID_FUNCTABLE_ERROR; … … 2371 2174 NPError np_error = NPERR_NO_ERROR; 2372 2175 #ifndef __OS2__ 2373 // Make sure the plugin data directory exists, creating it if 2374 // necessary. 2375 data_directory = g_strconcat (P_tmpdir, NULL); 2376 if (!data_directory) 2377 { 2378 PLUGIN_ERROR ("Failed to create data directory name."); 2379 return NPERR_OUT_OF_MEMORY_ERROR; 2380 } 2381 2382 // If P_tmpdir does not exist, try /tmp directly 2383 2384 if (!g_file_test (data_directory, 2385 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 2386 { 2387 int file_error = 0; 2388 2389 data_directory = g_strconcat ("/tmp", NULL); 2390 if (!data_directory) 2391 { 2392 PLUGIN_ERROR ("Failed to create data directory name."); 2393 return NPERR_OUT_OF_MEMORY_ERROR; 2394 } 2395 2396 } 2397 2398 data_directory = g_strconcat (data_directory, "/icedteaplugin-", getenv("USER"), NULL); 2399 2400 if (!data_directory) 2401 { 2402 PLUGIN_ERROR ("Failed to create data directory name."); 2403 return NPERR_OUT_OF_MEMORY_ERROR; 2404 } 2405 2406 // Now create a icedteaplugin subdir 2407 if (!g_file_test (data_directory, 2408 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 2409 { 2410 int file_error = 0; 2411 2412 file_error = g_mkdir (data_directory, 0700); 2413 if (file_error != 0) 2414 { 2415 PLUGIN_ERROR_THREE ("Failed to create data directory", 2416 data_directory, 2417 strerror (errno)); 2418 np_error = NPERR_GENERIC_ERROR; 2419 goto cleanup_data_directory; 2420 } 2421 } 2422 2423 2424 // If data directory doesn't exit by this point, bail 2425 if (!g_file_test (data_directory, 2426 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 2427 { 2428 PLUGIN_ERROR_THREE ("Temp directory does not exist: ", 2429 data_directory, 2430 strerror (errno)); 2431 2432 np_error = NPERR_GENERIC_ERROR; 2433 goto cleanup_data_directory; 2434 2176 // create directory for pipes 2177 np_error = initialize_data_directory(); 2178 if (np_error != NPERR_NO_ERROR) 2179 { 2180 PLUGIN_ERROR("Unable to create data directory %s\n", data_directory.c_str()); 2181 return np_error; 2435 2182 } 2436 2183 #endif 2437 2184 2438 2185 // Set appletviewer_executable. 2439 gchar* filename = g_strdup(ICEDTEA_WEB_JRE); 2440 appletviewer_executable = g_strdup_printf ("%s/bin/java", 2441 filename); 2442 PLUGIN_DEBUG("Executing java at %s\n", appletviewer_executable); 2443 if (!appletviewer_executable) 2444 { 2445 PLUGIN_ERROR ("Failed to create appletviewer executable name."); 2446 np_error = NPERR_OUT_OF_MEMORY_ERROR; 2447 goto cleanup_filename; 2448 } 2449 2186 PLUGIN_DEBUG("Executing java at %s\n", get_plugin_executable().c_str()); 2450 2187 np_error = plugin_test_appletviewer (); 2451 2188 if (np_error != NPERR_NO_ERROR) 2452 2189 { 2453 plugin_display_failure_dialog (); 2454 goto cleanup_appletviewer_executable; 2455 } 2456 g_free (filename); 2190 PLUGIN_ERROR("Unable to find java executable %s\n", get_plugin_executable().c_str()); 2191 return np_error; 2192 } 2457 2193 2458 2194 // Initialize threads (needed for mutexes). … … 2464 2200 { 2465 2201 PLUGIN_DEBUG ("Failed to integrate with PM"); 2466 np_error = NPERR_GENERIC_ERROR; 2467 goto cleanup_appletviewer_executable; 2202 return NPERR_GENERIC_ERROR; 2468 2203 } 2469 2204 #endif … … 2471 2206 plugin_instance_mutex = g_mutex_new (); 2472 2207 2473 PLUGIN_DEBUG ("NP_Initialize: using %s\n", appletviewer_executable);2208 PLUGIN_DEBUG ("NP_Initialize: using %s\n", get_plugin_executable().c_str()); 2474 2209 2475 2210 plugin_req_proc = new PluginRequestProcessor(); … … 2508 2243 2509 2244 return NPERR_NO_ERROR; 2510 2511 cleanup_appletviewer_executable:2512 if (appletviewer_executable)2513 {2514 g_free (appletviewer_executable);2515 appletviewer_executable = NULL;2516 }2517 2518 cleanup_filename:2519 if (filename)2520 {2521 g_free (filename);2522 filename = NULL;2523 }2524 2525 cleanup_data_directory:2526 if (data_directory)2527 {2528 g_free (data_directory);2529 data_directory = NULL;2530 }2531 2532 2533 return np_error;2534 2245 } 2535 2246 … … 2566 2277 // Returns a string describing the MIME type that this plugin 2567 2278 // handles. 2279 __attribute__ ((visibility ("default"))) 2568 2280 #ifdef LEGACY_XULRUNNERAPI 2569 2281 char* … … 2573 2285 OSCALL NP_GetMIMEDescription () 2574 2286 { 2287 //this function is called severaltimes between lunches 2575 2288 PLUGIN_DEBUG ("NP_GetMIMEDescription\n"); 2576 2289 … … 2582 2295 // Returns a value relevant to the plugin as a whole. The browser 2583 2296 // calls this function to obtain information about the plugin. 2297 __attribute__ ((visibility ("default"))) 2584 2298 NPError 2585 2299 OSCALL NP_GetValue (void* future, NPPVariable variable, void* value) … … 2603 2317 2604 2318 default: 2605 PLUGIN_ERROR ("Unknown plugin value requested. ");2319 PLUGIN_ERROR ("Unknown plugin value requested.\n"); 2606 2320 result = NPERR_GENERIC_ERROR; 2607 2321 break; … … 2615 2329 // Shuts down the plugin. Called after the last plugin instance is 2616 2330 // destroyed. 2331 __attribute__ ((visibility ("default"))) 2617 2332 NPError 2618 2333 OSCALL NP_Shutdown (void) … … 2629 2344 g_mutex_free (plugin_instance_mutex); 2630 2345 plugin_instance_mutex = NULL; 2631 }2632 2633 if (data_directory)2634 {2635 g_free (data_directory);2636 data_directory = NULL;2637 }2638 2639 if (appletviewer_executable)2640 {2641 g_free (appletviewer_executable);2642 appletviewer_executable = NULL;2643 2346 } 2644 2347 … … 2699 2402 #endif 2700 2403 2404 if (plugin_debug_to_console){ 2405 //jvm_up is now false 2406 if (g_io_channel_shutdown (debug_to_appletviewer, 2407 TRUE, &channel_error) 2408 != G_IO_STATUS_NORMAL) 2409 { 2410 if (channel_error) 2411 { 2412 PLUGIN_ERROR ("Failed to shut down appletviewer" 2413 " debug channel\n", channel_error->message); 2414 g_error_free (channel_error); 2415 channel_error = NULL; 2416 } 2417 else 2418 PLUGIN_ERROR ("Failed to shut down debug to appletviewer\n"); 2419 } 2420 // cleanup_out_to_appletviewer: 2421 if (debug_to_appletviewer) 2422 g_io_channel_unref (debug_to_appletviewer); 2423 out_to_appletviewer = NULL; 2424 // cleanup_debug_pipe: 2425 // Delete debug pipe. 2426 PLUGIN_DEBUG ("NP_Shutdown: deleting debug fifo: %s\n", debug_pipe_name); 2427 unlink (debug_pipe_name); 2428 PLUGIN_DEBUG ("NP_Shutdown: deleted debug fifo: %s\n", debug_pipe_name); 2429 // cleanup_out_pipe_name: 2430 g_free (debug_pipe_name); 2431 debug_pipe_name = NULL; 2432 } 2433 2701 2434 // Destroy the call queue mutex 2702 2435 pthread_mutex_destroy(&pluginAsyncCallMutex); … … 2736 2469 //delete internal_bus; 2737 2470 2471 cleanUpDir(); 2472 2738 2473 PLUGIN_DEBUG ("NP_Shutdown return\n"); 2474 2475 if (plugin_debug_to_file){ 2476 fflush (plugin_file_log); 2477 //fclose (plugin_file_log); 2478 //keep writing untill possible! 2479 } 2739 2480 2740 2481 return NPERR_NO_ERROR; … … 2762 2503 if (!data->window_handle) 2763 2504 { 2764 plugin_send_initialization_message(data->instance_id, 0, 0, 0, data-> applet_tag);2505 plugin_send_initialization_message(data->instance_id, 0, 0, 0, data->parameters_string); 2765 2506 } 2766 2507 … … 2771 2512 if (java_result->error_occurred) 2772 2513 { 2773 printf("Error: Unable to fetch applet instance id from Java side.\n");2514 PLUGIN_ERROR("Error: Unable to fetch applet instance id from Java side.\n"); 2774 2515 return NULL; 2775 2516 } … … 2781 2522 if (java_result->error_occurred) 2782 2523 { 2783 printf("Error: Unable to fetch applet instance id from Java side.\n");2524 PLUGIN_ERROR("Error: Unable to fetch applet instance id from Java side.\n"); 2784 2525 return NULL; 2785 2526 } … … 2787 2528 applet_class_id.append(*(java_result->return_string)); 2788 2529 2789 obj = IcedTeaScriptableJava PackageObject::get_scriptable_java_object(instance, applet_class_id, instance_id, false);2530 obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(instance, applet_class_id, instance_id, false); 2790 2531 2791 2532 } else 2792 2533 { 2793 obj = IcedTeaScriptable PluginObject::get_scriptable_java_package_object(instance, "");2534 obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object(instance, ""); 2794 2535 } 2795 2536
Note:
See TracChangeset
for help on using the changeset viewer.