aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog30
-rw-r--r--netx/net/sourceforge/jnlp/controlpanel/DebuggingPanel.java54
-rw-r--r--netx/net/sourceforge/jnlp/resources/Messages.properties4
-rw-r--r--netx/net/sourceforge/jnlp/util/logging/FileLog.java23
-rw-r--r--plugin/icedteanp/IcedTeaNPPlugin.cc92
-rw-r--r--plugin/icedteanp/IcedTeaNPPlugin.h3
-rw-r--r--plugin/icedteanp/IcedTeaParseProperties.cc45
-rw-r--r--plugin/icedteanp/IcedTeaParseProperties.h5
-rw-r--r--plugin/icedteanp/IcedTeaPluginUtils.cc67
-rw-r--r--plugin/icedteanp/IcedTeaPluginUtils.h84
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java2
-rw-r--r--tests/cpp-unit-tests/IcedTeaPluginUtilsTest.cc12
12 files changed, 353 insertions, 68 deletions
diff --git a/ChangeLog b/ChangeLog
index d29b310..269414f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2013-11-29 Jiri Vanek <[email protected]>
+
+ Enabled file logging in plugin, user enabled to choose logs dir.
+ * netx/net/sourceforge/jnlp/controlpanel/DebuggingPanel.java: added
+ text-field to show/edit logs' destination. Added reset to default button.
+ * netx/net/sourceforge/jnlp/resources/Messages.propertie: added proper
+ keys for new controls (CPFilesLogsDestDir) and (CPFilesLogsDestDirResert).
+ (DPEnableLogging) changed to "Enable debugging", as it is better.
+ * netx/net/sourceforge/jnlp/util/logging/FileLog.java: Filename of logs
+ changed to be human readable and to distinguish between c/java
+ * plugin/icedteanp/IcedTeaNPPlugin.cc: made aware of console (plugin_debug_to_console)
+ added stream to log into file (plugin_file_log) and holder of name (plugin_file_log_name)
+ Added various new lines to end of erorr/debug messages. Stream flushed,
+ not closed on plugin shutdown.
+ * plugin/icedteanp/IcedTeaNPPlugin.h: extern above three fields.
+ * plugin/icedteanp/IcedTeaParseProperties.cc: added functionality to provide
+ set or default log dir (get_log_dir), added (is_java_console_enabled)
+ to determine logging to console
+ * plugin/icedteanp/IcedTeaParseProperties.h: used glib.h, declared above functions
+ * plugin/icedteanp/IcedTeaPluginUtils.cc: added (initFileLog) function to open
+ correctly named, in proper palce and with correct permissions file for logging
+ (generateLogFileName) generate human readable file name, as java do.
+ (printDebugStatus) to debug status of logging
+ * plugin/icedteanp/IcedTeaPluginUtils.h: headers generated once, and reused
+ declared above functions.
+ * plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java:
+ commented out useless "woken" debug message
+ * tests/cpp-unit-tests/IcedTeaPluginUtilsTest.cc: made plugin_debug_to_console
+ aware.
+
2013-11-27 Andrew Azores <[email protected]>
Made JNLPClassLoaderDeadlock reproducer more reliable
diff --git a/netx/net/sourceforge/jnlp/controlpanel/DebuggingPanel.java b/netx/net/sourceforge/jnlp/controlpanel/DebuggingPanel.java
index bee0a53..68d34d9 100644
--- a/netx/net/sourceforge/jnlp/controlpanel/DebuggingPanel.java
+++ b/netx/net/sourceforge/jnlp/controlpanel/DebuggingPanel.java
@@ -23,13 +23,20 @@ import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.Box;
+import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import net.sourceforge.jnlp.config.Defaults;
import net.sourceforge.jnlp.config.DeploymentConfiguration;
import net.sourceforge.jnlp.runtime.Translator;
import net.sourceforge.jnlp.util.logging.LogConfig;
@@ -74,7 +81,41 @@ public class DebuggingPanel extends NamedBorderPanel implements ItemListener {
private void addComponents() {
GridBagConstraints c = new GridBagConstraints();
- JLabel debuggingDescription = new JLabel("<html>" + Translator.R("CPDebuggingDescription") + "<hr /><br /></html>");
+
+ final JLabel debuggingDescription = new JLabel("<html>" + Translator.R("CPDebuggingDescription") + "<hr /><br /></html>");
+ final JLabel logsDestinationTitle = new JLabel(Translator.R("CPFilesLogsDestDir")+": ");
+ final JTextField logsDestination = new JTextField(config.getProperty(DeploymentConfiguration.KEY_USER_LOG_DIR));
+ logsDestination.getDocument().addDocumentListener(new DocumentListener() {
+
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ save();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ save();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ save();
+
+ }
+
+ private void save() {
+ config.setProperty(DeploymentConfiguration.KEY_USER_LOG_DIR, logsDestination.getText());
+ }
+ });
+ final JButton logsDestinationReset = new JButton(Translator.R("CPFilesLogsDestDirResert"));
+ logsDestinationReset.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ logsDestination.setText(Defaults.getDefaults().get(DeploymentConfiguration.KEY_USER_LOG_DIR).getDefaultValue());
+ }
+ });
JCheckBox[] debuggingOptions = {
new JCheckBox(Translator.R("DPEnableLogging")),
@@ -130,9 +171,18 @@ public class DebuggingPanel extends NamedBorderPanel implements ItemListener {
debuggingOptions[i].addItemListener(this);
add(debuggingOptions[i], c);
-
+ if (i == 2) {
+ c.gridx++;
+ add(logsDestinationTitle, c);
+ c.gridx++;
+ add(logsDestination, c);
+ c.gridx++;
+ add(logsDestinationReset, c);
+ c.gridx-=3;
+ }
}
+
for (int j = 0; j < javaConsoleItems.length; j++) {
consoleComboBox.addItem(javaConsoleItems[j]);
if (config.getProperty(DeploymentConfiguration.KEY_CONSOLE_STARTUP_MODE).equals(javaConsoleItems[j].getValue())) {
diff --git a/netx/net/sourceforge/jnlp/resources/Messages.properties b/netx/net/sourceforge/jnlp/resources/Messages.properties
index 5cea7d2..2e5fb82 100644
--- a/netx/net/sourceforge/jnlp/resources/Messages.properties
+++ b/netx/net/sourceforge/jnlp/resources/Messages.properties
@@ -402,11 +402,13 @@ APSExceptionInstruction=Separate each entry with a semicolon.
# Control Panel - DebugginPanel
CPDebuggingPossibilites=Logging outputs
-DPEnableLogging=Enable logging
+DPEnableLogging=Enable debugging
DPEnableLoggingHint=When this switch is on, then also debug messages are logged. Same as -verbose or ICEDTEAPLUGIN_DEBUG=true
DPEnableHeaders=Enable headers
DPEnableHeadersHint=When this switch is on, each logged message have header with additional information like user, place in code and time
DPEnableFile=Enable logging to file
+CPFilesLogsDestDir=File logs directory
+CPFilesLogsDestDirResert=Reset to default
DPEnableFileHint=output messages will be saved to file in your {0} directory
DPEnableStds=Enable logging to standard outputs
DPEnableStdsHint=messages will be printed to standard outputs
diff --git a/netx/net/sourceforge/jnlp/util/logging/FileLog.java b/netx/net/sourceforge/jnlp/util/logging/FileLog.java
index 05b079a..3ac048b 100644
--- a/netx/net/sourceforge/jnlp/util/logging/FileLog.java
+++ b/netx/net/sourceforge/jnlp/util/logging/FileLog.java
@@ -38,6 +38,8 @@ package net.sourceforge.jnlp.util.logging;
import java.io.File;
import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
@@ -50,17 +52,20 @@ import net.sourceforge.jnlp.util.FileUtils;
*
*/
public final class FileLog implements SingleStreamLogger {
+ private static SimpleDateFormat fileLogNameFormatter = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss.S");
+ /**"Tue Nov 19 09:43:50 CET 2013"*/
+ private static SimpleDateFormat pluginSharedFormatter = new SimpleDateFormat("EEE MMM dd HH:mm:ss ZZZ yyyy");
private final Logger impl;
private final FileHandler fh;
private static final String defaultloggerName = "IcedTea-Web file-logger";
public FileLog() {
- this(defaultloggerName, LogConfig.getLogConfig().getIcedteaLogDir() + "itw-" + java.lang.System.currentTimeMillis() + ".log", false);
+ this(false);
}
public FileLog(boolean append) {
- this(defaultloggerName, LogConfig.getLogConfig().getIcedteaLogDir() + "itw-" + java.lang.System.currentTimeMillis() + ".log", append);
+ this(defaultloggerName, LogConfig.getLogConfig().getIcedteaLogDir() + "itw-javantx-" + getStamp() + ".log", append);
}
@@ -104,4 +109,18 @@ public final class FileLog implements SingleStreamLogger {
public void close(){
fh.close();
}
+
+ private static String getStamp() {
+ return fileLogNameFormatter.format(new Date());
+ }
+
+ public static SimpleDateFormat getFileLogNameFormatter() {
+ return fileLogNameFormatter;
+ }
+
+ public static SimpleDateFormat getPluginSharedFormatter() {
+ return pluginSharedFormatter;
+ }
+
+
}
diff --git a/plugin/icedteanp/IcedTeaNPPlugin.cc b/plugin/icedteanp/IcedTeaNPPlugin.cc
index c7318ef..30ab716 100644
--- a/plugin/icedteanp/IcedTeaNPPlugin.cc
+++ b/plugin/icedteanp/IcedTeaNPPlugin.cc
@@ -219,6 +219,10 @@ bool plugin_debug_headers = false;
bool plugin_debug_to_file = false ;
bool plugin_debug_to_streams = true ;
bool plugin_debug_to_system = false;
+bool plugin_debug_to_console = true;
+FILE * plugin_file_log;
+std::string plugin_file_log_name;
+
int plugin_debug_suspend = (getenv("ICEDTEAPLUGIN_DEBUG") != NULL) &&
(strcmp(getenv("ICEDTEAPLUGIN_DEBUG"), "suspend") == 0);
@@ -330,7 +334,7 @@ ITNP_New (NPMIMEType pluginType, NPP instance, uint16_t mode,
if (!instance)
{
- PLUGIN_ERROR ("Browser-provided instance pointer is NULL.");
+ PLUGIN_ERROR ("Browser-provided instance pointer is NULL.\n");
return NPERR_INVALID_INSTANCE_ERROR;
}
@@ -338,7 +342,7 @@ ITNP_New (NPMIMEType pluginType, NPP instance, uint16_t mode,
ITNPPluginData* data = plugin_data_new ();
if (data == NULL)
{
- PLUGIN_ERROR ("Failed to allocate plugin data.");
+ PLUGIN_ERROR ("Failed to allocate plugin data.\n");
return NPERR_OUT_OF_MEMORY_ERROR;
}
@@ -439,7 +443,7 @@ void start_jvm_if_needed()
data_directory.c_str(), getpid());
if (!in_pipe_name)
{
- PLUGIN_ERROR ("Failed to create input pipe name.");
+ PLUGIN_ERROR ("Failed to create input pipe name.\n");
np_error = NPERR_OUT_OF_MEMORY_ERROR;
// If in_pipe_name is NULL then the g_free at
// cleanup_in_pipe_name will simply return.
@@ -452,7 +456,7 @@ void start_jvm_if_needed()
PLUGIN_DEBUG ("ITNP_New: creating input fifo: %s\n", in_pipe_name);
if (mkfifo (in_pipe_name, 0600) == -1 && errno != EEXIST)
{
- PLUGIN_ERROR ("Failed to create input pipe", strerror (errno));
+ PLUGIN_ERROR ("Failed to create input pipe\n", strerror (errno));
np_error = NPERR_GENERIC_ERROR;
goto cleanup_in_pipe_name;
}
@@ -467,7 +471,7 @@ void start_jvm_if_needed()
if (!out_pipe_name)
{
- PLUGIN_ERROR ("Failed to create output pipe name.");
+ PLUGIN_ERROR ("Failed to create output pipe name.\n");
np_error = NPERR_OUT_OF_MEMORY_ERROR;
goto cleanup_out_pipe_name;
}
@@ -478,7 +482,7 @@ void start_jvm_if_needed()
PLUGIN_DEBUG ("ITNP_New: creating output fifo: %s\n", out_pipe_name);
if (mkfifo (out_pipe_name, 0600) == -1 && errno != EEXIST)
{
- PLUGIN_ERROR ("Failed to create output pipe", strerror (errno));
+ PLUGIN_ERROR ("Failed to create output pipe\n", strerror (errno));
np_error = NPERR_GENERIC_ERROR;
goto cleanup_out_pipe_name;
}
@@ -500,13 +504,13 @@ void start_jvm_if_needed()
{
if (channel_error)
{
- PLUGIN_ERROR ("Failed to create output channel",
+ PLUGIN_ERROR ("Failed to create output channel, '%s'\n",
channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to create output channel");
+ PLUGIN_ERROR ("Failed to create output channel\n");
np_error = NPERR_GENERIC_ERROR;
goto cleanup_out_to_appletviewer;
@@ -527,13 +531,13 @@ void start_jvm_if_needed()
{
if (channel_error)
{
- PLUGIN_ERROR ("Failed to create input channel",
+ PLUGIN_ERROR ("Failed to create input channel, '%s'\n",
channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to create input channel");
+ PLUGIN_ERROR ("Failed to create input channel\n");
np_error = NPERR_GENERIC_ERROR;
goto cleanup_in_from_appletviewer;
@@ -549,7 +553,7 @@ void start_jvm_if_needed()
goto done;
- // Free allocated data
+ // Free allocated data in case of error
cleanup_in_watch_source:
// Removing a source is harmless if it fails since it just means the
@@ -593,6 +597,7 @@ void start_jvm_if_needed()
done:
+ IcedTeaPluginUtilities::printDebugStatus();
// Now other threads may re-enter.. unlock the mutex
g_mutex_unlock(vm_start_mutex);
@@ -621,7 +626,7 @@ ITNP_GetValue (NPP instance, NPPVariable variable, void* value)
}
break;
default:
- PLUGIN_ERROR ("Unknown plugin value requested.");
+ PLUGIN_ERROR ("Unknown plugin value requested.\n");
np_error = NPERR_GENERIC_ERROR;
break;
}
@@ -670,7 +675,7 @@ ITNP_SetWindow (NPP instance, NPWindow* window)
if (instance == NULL)
{
- PLUGIN_ERROR ("Invalid instance.");
+ PLUGIN_ERROR ("Invalid instance.\n");
return NPERR_INVALID_INSTANCE_ERROR;
}
@@ -990,13 +995,13 @@ plugin_in_pipe_callback (GIOChannel* source,
{
if (channel_error)
{
- PLUGIN_ERROR ("Failed to read line from input channel",
+ PLUGIN_ERROR ("Failed to read line from input channel, %s\n",
channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to read line from input channel");
+ PLUGIN_ERROR ("Failed to read line from input channel\n");
} else
{
consume_message(message);
@@ -1329,13 +1334,13 @@ plugin_test_appletviewer ()
{
if (channel_error)
{
- PLUGIN_ERROR ("Failed to spawn applet viewer",
+ PLUGIN_ERROR ("Failed to spawn applet viewer %s\n",
channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to spawn applet viewer");
+ PLUGIN_ERROR ("Failed to spawn applet viewer\n");
error = NPERR_GENERIC_ERROR;
}
@@ -1409,13 +1414,13 @@ plugin_start_appletviewer (ITNPPluginData* data)
{
if (channel_error)
{
- PLUGIN_ERROR ("Failed to spawn applet viewer",
+ PLUGIN_ERROR ("Failed to spawn applet viewer %s\n",
channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to spawn applet viewer");
+ PLUGIN_ERROR ("Failed to spawn applet viewer\n");
error = NPERR_GENERIC_ERROR;
}
@@ -1540,13 +1545,13 @@ plugin_send_message_to_appletviewer (gchar const* message)
{
if (channel_error)
{
- PLUGIN_ERROR ("Failed to write bytes to output channel",
+ PLUGIN_ERROR ("Failed to write bytes to output channel '%s' \n",
channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to write bytes to output channel");
+ PLUGIN_ERROR ("Failed to write bytes to output channel for %s", newline_message);
}
if (g_io_channel_flush (out_to_appletviewer, &channel_error)
@@ -1554,18 +1559,18 @@ plugin_send_message_to_appletviewer (gchar const* message)
{
if (channel_error)
{
- PLUGIN_ERROR ("Failed to flush bytes to output channel",
+ PLUGIN_ERROR ("Failed to flush bytes to output channel '%s'\n",
channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to flush bytes to output channel");
+ PLUGIN_ERROR ("Failed to flush bytes to output channel for %s", newline_message);
}
g_free (newline_message);
newline_message = NULL;
- PLUGIN_DEBUG (" PIPE: plugin wrote: %s\n", message);
+ PLUGIN_DEBUG (" PIPE: plugin wrote(?): %s\n", message);
}
PLUGIN_DEBUG ("plugin_send_message_to_appletviewer return\n");
@@ -1621,13 +1626,13 @@ plugin_stop_appletviewer ()
{
if (channel_error)
{
- PLUGIN_ERROR ("Failed to write shutdown message to"
- " appletviewer", channel_error->message);
+ PLUGIN_ERROR ("Failed to write shutdown message to "
+ " appletviewer, %s \n", channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to write shutdown message to");
+ PLUGIN_ERROR ("Failed to write shutdown message to\n");
}
if (g_io_channel_flush (out_to_appletviewer, &channel_error)
@@ -1636,12 +1641,12 @@ plugin_stop_appletviewer ()
if (channel_error)
{
PLUGIN_ERROR ("Failed to write shutdown message to"
- " appletviewer", channel_error->message);
+ " appletviewer %s \n", channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to write shutdown message to");
+ PLUGIN_ERROR ("Failed to write shutdown message to\n");
}
if (g_io_channel_shutdown (out_to_appletviewer,
@@ -1651,12 +1656,12 @@ plugin_stop_appletviewer ()
if (channel_error)
{
PLUGIN_ERROR ("Failed to shut down appletviewer"
- " output channel", channel_error->message);
+ " output channel %s \n", channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to shut down appletviewer");
+ PLUGIN_ERROR ("Failed to shut down appletviewer\n");
}
}
@@ -1669,12 +1674,12 @@ plugin_stop_appletviewer ()
if (channel_error)
{
PLUGIN_ERROR ("Failed to shut down appletviewer"
- " input channel", channel_error->message);
+ " input channel %s \n", channel_error->message);
g_error_free (channel_error);
channel_error = NULL;
}
else
- PLUGIN_ERROR ("Failed to shut down appletviewer");
+ PLUGIN_ERROR ("Failed to shut down appletviewer\n");
}
}
}
@@ -1812,7 +1817,7 @@ initialize_data_directory()
file_error = g_mkdir (data_directory.c_str(), 0700);
if (file_error != 0)
{
- PLUGIN_ERROR ("Failed to create data directory",
+ PLUGIN_ERROR ("Failed to create data directory %s, %s\n",
data_directory.c_str(),
strerror (errno));
return NPERR_GENERIC_ERROR;
@@ -1824,7 +1829,7 @@ initialize_data_directory()
if (!g_file_test (data_directory.c_str(),
(GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
{
- PLUGIN_ERROR ("Temp directory does not exist: ",
+ PLUGIN_ERROR ("Temp directory does not exist %s, %s \n",
data_directory.c_str(),
strerror (errno));
return NPERR_GENERIC_ERROR;
@@ -1852,7 +1857,7 @@ NP_Initialize (NPNetscapeFuncs* browserTable, NPPluginFuncs* pluginTable)
if ((browserTable == NULL) || (pluginTable == NULL))
{
- PLUGIN_ERROR ("Browser or plugin function table is NULL.");
+ PLUGIN_ERROR ("Browser or plugin function table is NULL.\n");
return NPERR_INVALID_FUNCTABLE_ERROR;
}
@@ -1862,7 +1867,7 @@ NP_Initialize (NPNetscapeFuncs* browserTable, NPPluginFuncs* pluginTable)
// we've implemented.
if ((browserTable->version >> 8) > NP_VERSION_MAJOR)
{
- PLUGIN_ERROR ("Incompatible version.");
+ PLUGIN_ERROR ("Incompatible version.\n");
return NPERR_INCOMPATIBLE_VERSION_ERROR;
}
@@ -1875,7 +1880,7 @@ NP_Initialize (NPNetscapeFuncs* browserTable, NPPluginFuncs* pluginTable)
// Check if everything we rely on is supported
if ( !browser_functions_supported )
{
- PLUGIN_ERROR ("Invalid browser function table.");
+ PLUGIN_ERROR ("Invalid browser function table.\n");
return NPERR_INVALID_FUNCTABLE_ERROR;
}
@@ -1888,7 +1893,7 @@ NP_Initialize (NPNetscapeFuncs* browserTable, NPPluginFuncs* pluginTable)
// Check if everything we rely on is supported
if ( !plugin_functions_supported )
{
- PLUGIN_ERROR ("Invalid plugin function table.");
+ PLUGIN_ERROR ("Invalid plugin function table.\n");
return NPERR_INVALID_FUNCTABLE_ERROR;
}
@@ -1954,6 +1959,7 @@ __attribute__ ((visibility ("default")))
const char*
NP_GetMIMEDescription ()
{
+ //this function is called severaltimes between lunches
PLUGIN_DEBUG ("NP_GetMIMEDescription\n");
PLUGIN_DEBUG ("NP_GetMIMEDescription return\n");
@@ -1985,7 +1991,7 @@ NP_GetValue (void* future, NPPVariable variable, void* value)
break;
default:
- PLUGIN_ERROR ("Unknown plugin value requested.");
+ PLUGIN_ERROR ("Unknown plugin value requested.\n");
result = NPERR_GENERIC_ERROR;
break;
}
@@ -2081,6 +2087,12 @@ NP_Shutdown (void)
//delete internal_bus;
PLUGIN_DEBUG ("NP_Shutdown return\n");
+
+ if (plugin_debug_to_file){
+ fflush (plugin_file_log);
+ //fclose (plugin_file_log);
+ //keep writing untill possible!
+ }
return NPERR_NO_ERROR;
}
diff --git a/plugin/icedteanp/IcedTeaNPPlugin.h b/plugin/icedteanp/IcedTeaNPPlugin.h
index cc1f9f5..6e1465b 100644
--- a/plugin/icedteanp/IcedTeaNPPlugin.h
+++ b/plugin/icedteanp/IcedTeaNPPlugin.h
@@ -122,6 +122,9 @@ extern bool plugin_debug_headers;
extern bool plugin_debug_to_file;
extern bool plugin_debug_to_streams;
extern bool plugin_debug_to_system;
+extern bool plugin_debug_to_console;
+extern FILE * plugin_file_log;
+extern std::string plugin_file_log_name;
// Browser function table.
extern NPNetscapeFuncs browser_functions;
diff --git a/plugin/icedteanp/IcedTeaParseProperties.cc b/plugin/icedteanp/IcedTeaParseProperties.cc
index 4c19a96..2e370ff 100644
--- a/plugin/icedteanp/IcedTeaParseProperties.cc
+++ b/plugin/icedteanp/IcedTeaParseProperties.cc
@@ -76,6 +76,7 @@ bool read_deploy_property_value(string user_file, string system_file, bool use
bool find_custom_jre(string user_file, string main_file,string& dest);
//end of non-public IcedTeaParseProperties api
const std::string default_file_ITW_deploy_props_name = "deployment.properties";
+const std::string default_itw_log_dir_name = "log";
const std::string custom_jre_key = "deployment.jre.dir";
void remove_all_spaces(string& str)
@@ -110,7 +111,7 @@ string user_properties_file(){
string old_name = string(mypasswd->pw_dir)+"/.icedtea/"+default_file_ITW_deploy_props_name;
//exists? then itw was not yet migrated. Use it
if (IcedTeaPluginUtilities::file_exists(old_name)) {
- PLUGIN_ERROR("IcedTea-Web plugin is using out-dated configuration");
+ PLUGIN_ERROR("IcedTea-Web plugin is using out-dated configuration\n");
return old_name;
}
//we are probably on XDG specification now
@@ -122,6 +123,37 @@ string user_properties_file(){
return string(mypasswd->pw_dir)+"/.config/icedtea-web/"+default_file_ITW_deploy_props_name;
}
+string get_log_dir(){
+ string value;
+ if (!read_deploy_property_value("deployment.user.logdir", value)) {
+ int myuid = getuid();
+ struct passwd *mypasswd = getpwuid(myuid);
+ // try pre 1.5 file location
+ if (getenv ("XDG_CONFIG_HOME") != NULL){
+ string r1= string(getenv ("XDG_CONFIG_HOME"))+"/icedtea-web";
+ string r2 = r1+"/"+default_itw_log_dir_name;
+ if (!IcedTeaPluginUtilities::file_exists(r1)){
+ g_mkdir(r1.c_str(), 755);
+ }
+ if (!IcedTeaPluginUtilities::file_exists(r2)){
+ g_mkdir(r2.c_str(), 755);
+ }
+ return r2;
+ }
+ //if not then use default
+ string r1 = string(mypasswd->pw_dir)+"/.config/icedtea-web";
+ string r2 = r1+"/"+default_itw_log_dir_name;
+ if (!IcedTeaPluginUtilities::file_exists(r1)){
+ g_mkdir(r1.c_str(), 755);
+ }
+ if (!IcedTeaPluginUtilities::file_exists(r2)){
+ g_mkdir(r2.c_str(), 755);
+ }
+ return r2;
+ }
+ return value;
+}
+
string main_properties_file(){
return "/etc/.java/deployment/"+default_file_ITW_deploy_props_name;
@@ -149,6 +181,17 @@ bool find_system_config_file(string& dest){
return find_system_config_file(main_properties_file(), jdest, found, default_java_properties_file(), dest);
}
+bool is_java_console_enabled(){
+ string value;
+ if (!read_deploy_property_value("deployment.console.startup.mode", value)) {
+ return true;
+ }
+ if (value == "DISABLE") {
+ return false;
+ } else {
+ return true;
+ }
+}
bool read_bool_property(string key, bool defaultValue){
string value;
diff --git a/plugin/icedteanp/IcedTeaParseProperties.h b/plugin/icedteanp/IcedTeaParseProperties.h
index 4370e3c..88fd0d1 100644
--- a/plugin/icedteanp/IcedTeaParseProperties.h
+++ b/plugin/icedteanp/IcedTeaParseProperties.h
@@ -40,10 +40,11 @@ exception statement from your version. */
* Utility classes for parsing values from properties files
*/
#include <string>
-
+#include <glib.h>
//public api
std::string user_properties_file();
+std::string get_log_dir();
bool find_system_config_file(std::string& dest);
bool find_custom_jre(std::string& dest);
bool read_deploy_property_value(std::string property, std::string& dest);
@@ -52,7 +53,9 @@ bool is_debug_header_on();
bool is_logging_to_file();
bool is_logging_to_stds();
bool is_logging_to_system();
+bool is_java_console_enabled();
//half public api
extern const std::string default_file_ITW_deploy_props_name;
+extern const std::string default_itw_log_dir_name;
extern const std::string custom_jre_key;
//end of public api
diff --git a/plugin/icedteanp/IcedTeaPluginUtils.cc b/plugin/icedteanp/IcedTeaPluginUtils.cc
index b8881ac..dd2978f 100644
--- a/plugin/icedteanp/IcedTeaPluginUtils.cc
+++ b/plugin/icedteanp/IcedTeaPluginUtils.cc
@@ -399,7 +399,7 @@ IcedTeaPluginUtilities::getUTF16LEString(int length, int begin, std::vector<std:
wchar_t c;
- PLUGIN_DEBUG("Converted UTF-16LE string: ");
+ PLUGIN_DEBUG("Converted UTF-16LE string: \n");
result_unicode_str->clear();
for (int i = begin; i < begin+length; i+=2)
@@ -413,7 +413,7 @@ IcedTeaPluginUtilities::getUTF16LEString(int length, int begin, std::vector<std:
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9'))
{
- PLUGIN_DEBUG("%c", c);
+ PLUGIN_DEBUG("%c\n", c);
}
result_unicode_str->push_back(c);
@@ -1105,6 +1105,69 @@ bool IcedTeaPluginUtilities::file_exists(std::string filename)
return infile.good();
}
+void IcedTeaPluginUtilities::initFileLog(){
+ if (plugin_file_log != NULL ) {
+ //reusing
+ return;
+ }
+ plugin_file_log_name = get_log_dir() + "/" + IcedTeaPluginUtilities::generateLogFileName();
+ int plugin_file_log_fd = open(plugin_file_log_name.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600);
+ if (plugin_file_log_fd <=0 ) {
+ plugin_debug_to_file = false;
+ } else {
+ plugin_file_log = fdopen(plugin_file_log_fd, "w");
+ }
+ if (plugin_file_log == NULL ) {
+ plugin_debug_to_file = false;
+ }
+}
+
+
+
+std::string IcedTeaPluginUtilities::generateLogFileName(){
+ char times[96];
+ char result[100];
+ time_t t = time(NULL);
+ struct tm p;
+ localtime_r(&t, &p);
+ struct timeval current_time; \
+ gettimeofday (&current_time, NULL);\
+ strftime(times, 96, "%Y-%m-%d_%H:%M:%S", &p);
+ snprintf(result, 100, "%s.%i",times, current_time.tv_usec/1000);
+ return "itw-cplugin-"+std::string(result)+".log";
+}
+
+void IcedTeaPluginUtilities::printDebugStatus(){
+ if (plugin_debug){
+ PLUGIN_DEBUG("plugin_debug: true, initialised\n");
+ if (plugin_debug_headers){
+ PLUGIN_DEBUG("plugin_debug_headers: true\n");
+ } else {
+ PLUGIN_DEBUG("plugin_debug_headers: false\n");
+ }
+ if (plugin_debug_to_file){
+ PLUGIN_DEBUG("plugin_debug_to_file: true, using %s\n", plugin_file_log_name.c_str());
+ } else {
+ PLUGIN_DEBUG("plugin_debug_to_file: false\n");
+ }
+ if (plugin_debug_to_streams){
+ PLUGIN_DEBUG("plugin_debug_to_streams: true\n");
+ } else {
+ PLUGIN_DEBUG("plugin_debug_to_streams: false\n");
+ }
+ if (plugin_debug_to_system){
+ PLUGIN_DEBUG("plugin_debug_to_system: true\n");
+ } else {
+ PLUGIN_DEBUG("plugin_debug_to_system: false\n");
+ }
+ if (plugin_debug_to_console){
+ PLUGIN_DEBUG("plugin_debug_to_console: true\n");
+ } else {
+ PLUGIN_DEBUG("plugin_debug_to_console: false\n");
+ }
+ }
+ }
+
/******************************************
* Begin JavaMessageSender implementation *
diff --git a/plugin/icedteanp/IcedTeaPluginUtils.h b/plugin/icedteanp/IcedTeaPluginUtils.h
index 95aca25..c62faba 100644
--- a/plugin/icedteanp/IcedTeaPluginUtils.h
+++ b/plugin/icedteanp/IcedTeaPluginUtils.h
@@ -47,7 +47,9 @@ exception statement from your version. */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
+#include <sys/time.h>
+#include <fcntl.h>
#include <cstring>
#include <iostream>
#include <list>
@@ -68,41 +70,69 @@ exception statement from your version. */
do \
{ \
if (!debug_initiated) { \
- debug_initiated = true; \
+ debug_initiated = true; \
plugin_debug = getenv ("ICEDTEAPLUGIN_DEBUG") != NULL || is_debug_on(); \
plugin_debug_headers = is_debug_header_on(); \
plugin_debug_to_file = is_logging_to_file(); \
plugin_debug_to_streams = is_logging_to_stds(); \
plugin_debug_to_system = is_logging_to_system(); \
+ plugin_debug_to_console = is_java_console_enabled(); \
+ if (plugin_debug_to_file) { \
+ IcedTeaPluginUtilities::initFileLog(); \
+ } \
+ if (plugin_debug_to_console) { \
+ /*no op now*/ \
+ } \
+ IcedTeaPluginUtilities::printDebugStatus(); \
} \
} while (0)
-//f is after expansion used as FILE*
-#define CREATE_HEADER(f) \
+#define HEADER_SIZE 500
+#define BODY_SIZE 500
+#define MESSAGE_SIZE HEADER_SIZE + BODY_SIZE
+
+//header is destination char array
+#define CREATE_HEADER(ldebug_header) \
do \
{ \
- char s[200]; \
+ char times[100]; \
time_t t = time(NULL); \
struct tm p; \
localtime_r(&t, &p); \
- strftime(s, 200, "%a %b %d %H:%M:%S %Z %Y", &p); \
+ strftime(times, 100, "%a %b %d %H:%M:%S %Z %Y", &p);\
const char *userNameforDebug = (getenv("USERNAME") == NULL) ? "unknown user" : getenv("USERNAME"); \
- fprintf (f, "[%s][ITW-C-PLUGIN][MESSAGE_DEBUG][%s][%s:%d] ITNPP Thread# %ld, gthread %p: ", \
- userNameforDebug, s, __FILE__, __LINE__, pthread_self(), g_thread_self ()); \
+ /*this message is parsed in JavaConsole*/ \
+ snprintf(ldebug_header, HEADER_SIZE, "[%s][ITW-C-PLUGIN][MESSAGE_DEBUG][%s][%s:%d] ITNPP Thread# %ld, gthread %p: ", \
+ userNameforDebug, times, __FILE__, __LINE__, pthread_self(), g_thread_self ()); \
} while (0)
-
+
#define PLUGIN_DEBUG(...) \
do \
{ \
initialize_debug(); \
if (plugin_debug) { \
+ char ldebug_header[HEADER_SIZE]; \
+ char ldebug_body[BODY_SIZE]; \
+ char ldebug_message[MESSAGE_SIZE];\
+ if (plugin_debug_headers) { \
+ CREATE_HEADER(ldebug_header); \
+ } else { \
+ sprintf(ldebug_header,""); \
+ } \
+ snprintf(ldebug_body, BODY_SIZE, __VA_ARGS__); \
if (plugin_debug_to_streams) { \
- if (plugin_debug_headers) { \
- CREATE_HEADER(stdout); \
- } \
- fprintf (stdout, __VA_ARGS__); \
+ snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \
+ fprintf (stdout, "%s", ldebug_message);\
+ } \
+ if (plugin_debug_to_file) { \
+ snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \
+ fprintf (plugin_file_log, "%s", ldebug_message); \
+ fflush(plugin_file_log); \
+ } \
+ if (plugin_debug_to_console) { \
+ /*no op now*/ \
} \
} \
} while (0)
@@ -112,12 +142,27 @@ exception statement from your version. */
do \
{ \
initialize_debug(); \
+ char ldebug_header[HEADER_SIZE]; \
+ char ldebug_body[BODY_SIZE]; \
+ char ldebug_message[MESSAGE_SIZE]; \
+ if (plugin_debug_headers) { \
+ CREATE_HEADER(ldebug_header); \
+ } else { \
+ sprintf(ldebug_header,""); \
+ } \
+ snprintf(ldebug_body, BODY_SIZE, __VA_ARGS__); \
if (plugin_debug_to_streams) { \
- if (plugin_debug_headers) { \
- CREATE_HEADER(stderr); \
- } \
- fprintf (stderr, __VA_ARGS__); \
- } \
+ snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \
+ fprintf (stderr, "%s", ldebug_message); \
+ } \
+ if (plugin_debug_to_file) { \
+ snprintf(ldebug_message, MESSAGE_SIZE, "%s%s", ldebug_header, ldebug_body); \
+ fprintf (plugin_file_log, "%s", ldebug_message); \
+ fflush(plugin_file_log); \
+ } \
+ if (plugin_debug_to_console) { \
+ /*no op now*/ \
+ } \
} while (0)
@@ -338,7 +383,10 @@ class IcedTeaPluginUtilities
/*cutting whitespaces from end and start of string*/
static void trim(std::string& str);
static bool file_exists(std::string filename);
-
+ //file-loggers helpers
+ static std::string generateLogFileName();
+ static void initFileLog();
+ static void printDebugStatus();
};
/*
diff --git a/plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java b/plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java
index 907a2b2..79d925d 100644
--- a/plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java
+++ b/plugin/icedteanp/java/sun/applet/PluginMessageHandlerWorker.java
@@ -112,7 +112,7 @@ class PluginMessageHandlerWorker extends Thread {
waitForWork();
// Someone woke us up, see if there is work to do
- PluginDebug.debug("Consumer thread ", id, " woken...");
+ // PluginDebug.debug("Consumer thread ", id, " woken...");
}
}
}
diff --git a/tests/cpp-unit-tests/IcedTeaPluginUtilsTest.cc b/tests/cpp-unit-tests/IcedTeaPluginUtilsTest.cc
index abb0b19..1ac2145 100644
--- a/tests/cpp-unit-tests/IcedTeaPluginUtilsTest.cc
+++ b/tests/cpp-unit-tests/IcedTeaPluginUtilsTest.cc
@@ -184,38 +184,50 @@ void doDebugErrorRun() {
TEST(PLUGIN_DEBUG_ERROR_PROFILING_debug_on_headers_off) {
bool plugin_debug_backup = plugin_debug;
bool plugin_debug_headers_backup = plugin_debug_headers;
+ bool plugin_debug_console_backup = plugin_debug_to_console;
+ plugin_debug_to_console = false;
plugin_debug = true;
doDebugErrorRun();
plugin_debug = plugin_debug_backup;
plugin_debug_headers = plugin_debug_headers_backup;
+ plugin_debug_to_console = plugin_debug_console_backup;
}
TEST(PLUGIN_DEBUG_ERROR_PROFILING_debug_off_headers_off) {
bool plugin_debug_backup = plugin_debug;
bool plugin_debug_headers_backup = plugin_debug_headers;
+ bool plugin_debug_console_backup = plugin_debug_to_console;
+ plugin_debug_to_console = false;
plugin_debug = false;
doDebugErrorRun();
plugin_debug = plugin_debug_backup;
plugin_debug_headers = plugin_debug_headers_backup;
+ plugin_debug_to_console = plugin_debug_console_backup;
}
TEST(PLUGIN_DEBUG_ERROR_PROFILING_debug_on_headers_on) {
bool plugin_debug_backup = plugin_debug;
bool plugin_debug_headers_backup = plugin_debug_headers;
+ bool plugin_debug_console_backup = plugin_debug_to_console;
+ plugin_debug_to_console = false;
plugin_debug = true;
plugin_debug_headers = true;
doDebugErrorRun();
plugin_debug = plugin_debug_backup;
plugin_debug_headers = plugin_debug_headers_backup;
+ plugin_debug_to_console = plugin_debug_console_backup;
}
TEST(PLUGIN_DEBUG_ERROR_PROFILING_debug_off_headers_on) {
bool plugin_debug_backup = plugin_debug;
bool plugin_debug_headers_backup = plugin_debug_headers;
+ bool plugin_debug_console_backup = plugin_debug_to_console;
+ plugin_debug_to_console = false;
plugin_debug = false;
plugin_debug_headers = true;
doDebugErrorRun();
plugin_debug = plugin_debug_backup;
plugin_debug_headers = plugin_debug_headers_backup;
+ plugin_debug_to_console = plugin_debug_console_backup;
}