On 08/10/2010 04:04 PM, Nikola Pajkovsky wrote:
Signed-off-by: Nikola Pajkovsky <npajkovs(a)redhat.com>
---
lib/plugins/Bugzilla.cpp | 24 ++++++++++++++++--------
lib/plugins/CCpp.cpp | 18 ++++++++++++------
lib/plugins/FileTransfer.cpp | 22 ++++++++++++----------
lib/plugins/Logger.cpp | 5 ++++-
lib/plugins/ReportUploader.cpp | 25 +++++++++++++++----------
lib/plugins/SOSreport.cpp | 21 ++++++++-------------
lib/plugins/SQLite3.cpp | 12 ++++++++----
lib/utils/DebugDump.cpp | 5 ++++-
lib/utils/abrt_xmlrpc.cpp | 8 +++++---
src/daemon/Daemon.cpp | 5 +++--
src/daemon/MiddleWare.cpp | 27 ++++++++++++++++++---------
src/daemon/PluginManager.cpp | 15 ++++++++++-----
12 files changed, 115 insertions(+), 72 deletions(-)
diff --git a/lib/plugins/Bugzilla.cpp b/lib/plugins/Bugzilla.cpp
index f3967cd..bd611af 100644
--- a/lib/plugins/Bugzilla.cpp
+++ b/lib/plugins/Bugzilla.cpp
@@ -558,9 +558,10 @@ void ctx::login(const char* login, const char* passwd)
if (!result)
{
- std::string errmsg = ssprintf(_("Cannot login. Check
Edit->Plugins->Bugzilla and /etc/abrt/plugins/Bugzilla.conf. Server said: %s"),
env.fault_string);
- error_msg("%s", errmsg.c_str()); // show error in daemon log
- throw CABRTException(EXCEP_PLUGIN, "%s", errmsg.c_str());
+ char *errmsg = xasprintf(_("Cannot login. Check
Edit->Plugins->Bugzilla and /etc/abrt/plugins/Bugzilla.conf. Server said: %s"),
env.fault_string);
+ CABRTException e(EXCEP_PLUGIN, "%s", errmsg);
+ free(errmsg);
+ throw e;
you've lost error_msg() here, so the error won't be logged in the daemon log
}
xmlrpc_DECREF(result);
}
@@ -796,13 +797,16 @@ std::string CReporterBugzilla::Report(const map_crash_data_t&
pCrashData,
update_client(_("Logging out..."));
bz_server.logout();
- std::string bug_status = ssprintf(
+
+ // not a wise solution, does it?
+ char *ret_bug_status = xasprintf(
"Status: NEW\n"
"%s/show_bug.cgi?id=%u",
BugzillaURL.c_str(),
(int)bug_id
);
- return bug_status;
+ std::string bug_statu = ret_bug_status;
TYPO: bug_statu
+ free(ret_bug_status);
- and missing return bug_status
}
else if (all_bugs_size > 1)
{
@@ -871,7 +875,7 @@ std::string CReporterBugzilla::Report(const map_crash_data_t&
pCrashData,
const char* arch = get_crash_data_item_content_or_NULL(pCrashData,
FILENAME_ARCHITECTURE);
const char* is_private = get_crash_data_item_content_or_NULL(pCrashData,
"is_private");
- description = ssprintf("Package: %s\n"
+ char *dsc = xasprintf("Package: %s\n"
"Architecture: %s\n"
"OS Release: %s\n"
"%s", package, arch, release,
description.c_str()
@@ -880,18 +884,20 @@ std::string CReporterBugzilla::Report(const map_crash_data_t&
pCrashData,
update_client(_("Adding new comment to bug %d"), (int)bug_id);
bool is_priv = is_private && (is_private[0] == '1');
- if (bz_server.add_comment(bug_id, description.c_str(), is_priv) == -1)
+ if (bz_server.add_comment(bug_id, dsc, is_priv) == -1)
{
+ free(dsc);
- you're asking for a double free here..
bug_info_destroy(&bz);
throw_if_xml_fault_occurred(&bz_server.env);
}
+ free(dsc);
- here is the second one...
}
}
update_client(_("Logging out..."));
bz_server.logout();
- std::string bug_status = ssprintf(
+ char *ret_bug_status = xasprintf(
"Status: %s%s%s\n"
"%s/show_bug.cgi?id=%u",
bz.bug_status,
@@ -900,6 +906,8 @@ std::string CReporterBugzilla::Report(const map_crash_data_t&
pCrashData,
BugzillaURL.c_str(),
(int)bug_id
);
+ std::string bug_status = ret_bug_status;
+ free(ret_bug_status);
what's the point of removing the ssprintf if you create the the
std::string anyway?
bug_info_destroy(&bz);
diff --git a/lib/plugins/CCpp.cpp b/lib/plugins/CCpp.cpp
index 629da66..4e73f1a 100644
--- a/lib/plugins/CCpp.cpp
+++ b/lib/plugins/CCpp.cpp
@@ -242,12 +242,14 @@ static void GetBacktrace(const char *pDebugDumpDir,
* BINARY_FILE if it is newer (to at least avoid gdb complaining).
*/
args[4] = (char*)"-ex";
- string file = ssprintf("file %s", executable.c_str());
- args[5] = (char*)file.c_str();
+
+ // need to be freed
+ args[5] = (char*)xasprintf("file %s", executable.c_str());
no need
for (char*), xasprintf returns char *
args[6] = (char*)"-ex";
- string corefile = ssprintf("core-file %s/"FILENAME_COREDUMP,
pDebugDumpDir);
- args[7] = (char*)corefile.c_str();
+
+ // need to be freed
+ args[7] = xasprintf("core-file %s/"FILENAME_COREDUMP, pDebugDumpDir);
args[8] = (char*)"-ex";
/*args[9] = ... see below */
@@ -271,12 +273,16 @@ static void GetBacktrace(const char *pDebugDumpDir,
const char *full = " full";
while (1)
{
- string cmd = ssprintf("%sbacktrace %u%s", thread_apply_all, bt_depth,
full);
- args[9] = (char*)cmd.c_str();
+ args[9] = xasprintf("%sbacktrace %u%s", thread_apply_all, bt_depth,
full);
pBacktrace = "";
ExecVP(args, xatoi_u(UID.c_str()), /*redirect_stderr:*/ 1, pBacktrace);
+ free(args[9]);
if (bt_depth <= 64 || pBacktrace.size() < 256*1024)
+ {
+ free(args[5]);
+ free(args[7]);
return;
+ }
bt_depth /= 2;
if (bt_depth <= 64 && thread_apply_all[0] != '\0')
{
diff --git a/lib/plugins/FileTransfer.cpp b/lib/plugins/FileTransfer.cpp
index cf7cf1f..a2ef810 100644
--- a/lib/plugins/FileTransfer.cpp
+++ b/lib/plugins/FileTransfer.cpp
@@ -252,17 +252,18 @@ void CFileTransfer::Run(const char *pActionDir, const char *pArgs,
int force)
if (strcmp(pArgs, "one") == 0)
{
/* Just send one archive */
- string archivename = ssprintf("%s/%s-%s%s", tmpdir_name, hostname,
DirBase(pActionDir).c_str(), m_sArchiveType.c_str());
+ char *archivename = xasprintf("%s/%s-%s%s", tmpdir_name, hostname,
DirBase(pActionDir).c_str(), m_sArchiveType.c_str());
try
{
- CreateArchive(archivename.c_str(), pActionDir);
- SendFile(m_sURL.c_str(), archivename.c_str());
+ CreateArchive(archivename, pActionDir);
+ SendFile(m_sURL.c_str(), archivename);
}
catch (CABRTException& e)
{
error_msg(_("Cannot create and send an archive: %s"), e.what());
}
- unlink(archivename.c_str());
+ unlink(archivename);
+ free(archivename);
}
else
{
@@ -279,20 +280,21 @@ void CFileTransfer::Run(const char *pActionDir, const char *pArgs,
int force)
while (fgets(dirname, sizeof(dirname), dirlist) != NULL)
{
strchrnul(dirname, '\n')[0] = '\0';
- string archivename = ssprintf("%s/%s-%s%s", tmpdir_name, hostname,
DirBase(dirname).c_str(), m_sArchiveType.c_str());
+ char *archivename = xasprintf("%s/%s-%s%s", tmpdir_name, hostname,
DirBase(dirname).c_str(), m_sArchiveType.c_str());
try
{
- VERB3 log("Creating archive '%s' of dir '%s'",
archivename.c_str(), dirname);
- CreateArchive(archivename.c_str(), dirname);
+ VERB3 log("Creating archive '%s' of dir '%s'",
archivename, dirname);
+ CreateArchive(archivename, dirname);
VERB3 log("Sending archive to '%s'", m_sURL.c_str());
- SendFile(m_sURL.c_str(), archivename.c_str());
+ SendFile(m_sURL.c_str(), archivename);
}
catch (CABRTException& e)
{
error_msg(_("Cannot create and send an archive: %s"),
e.what());
}
- VERB3 log("Deleting archive '%s'", archivename.c_str());
- unlink(archivename.c_str());
+ VERB3 log("Deleting archive '%s'", archivename);
+ unlink(archivename);
+ free(archivename);
}
fclose(dirlist);
diff --git a/lib/plugins/Logger.cpp b/lib/plugins/Logger.cpp
index ece450d..c1af6f5 100644
--- a/lib/plugins/Logger.cpp
+++ b/lib/plugins/Logger.cpp
@@ -77,7 +77,10 @@ std::string CLogger::Report(const map_crash_data_t& pCrashData,
close(fd);
const char *format = m_bAppendLogs ? _("The report was appended to %s") :
_("The report was stored to %s");
- return ssprintf(format, m_sLogPath.c_str());
+ char *ret = xasprintf(format, m_sLogPath.c_str());
+ std::string status = ret;
+ free(ret);
+ return status;
again, why turn char* to std::string ... I would return the allocated
char* and free it from the calling function...
}
PLUGIN_INFO(REPORTER,
diff --git a/lib/plugins/ReportUploader.cpp b/lib/plugins/ReportUploader.cpp
index eb01691..6e0c527 100644
--- a/lib/plugins/ReportUploader.cpp
+++ b/lib/plugins/ReportUploader.cpp
@@ -259,8 +259,9 @@ string CReportUploader::Report(const map_crash_data_t&
pCrashData,
// Create the compressed tarball
string outfile_basename = file_name + ".tar.gz";
string outfile_name = concat_path_file(tmpdir_name, outfile_basename.c_str());
- string cmd = ssprintf("tar -C %s --create --gzip --file=%s %s",
tmpdir_name, outfile_name.c_str(), file_name.c_str());
- RunCommand(cmd.c_str());
+ char *cmd = xasprintf("tar -C %s --create --gzip --file=%s %s",
tmpdir_name, outfile_name.c_str(), file_name.c_str());
+ RunCommand(cmd);
+ free(cmd);
// encrypt if requested
string key;
@@ -272,13 +273,15 @@ string CReportUploader::Report(const map_crash_data_t&
pCrashData,
outfile_basename += ".aes";
outfile_name += ".aes";
- cmd = ssprintf("openssl aes-128-cbc -in %s -out %s -pass stdin",
infile_name.c_str(), outfile_name.c_str());
- WriteCommand(cmd.c_str(), key.c_str());
+ cmd = xasprintf("openssl aes-128-cbc -in %s -out %s -pass stdin",
infile_name.c_str(), outfile_name.c_str());
+ WriteCommand(cmd, key.c_str());
+ free(cmd);
}
// generate md5sum
- cmd = ssprintf("cd %s; md5sum <%s", tmpdir_name,
outfile_basename.c_str());
- string md5sum = ReadCommand(cmd.c_str());
+ cmd = xasprintf("cd %s; md5sum <%s", tmpdir_name,
outfile_basename.c_str());
+ string md5sum = ReadCommand(cmd);
+ free(cmd);
// upload or cp to /tmp
if (do_upload)
@@ -288,8 +291,9 @@ string CReportUploader::Report(const map_crash_data_t&
pCrashData,
}
else
{
- cmd = ssprintf("cp %s /tmp/", outfile_name.c_str());
- RunCommand(cmd.c_str());
+ cmd = xasprintf("cp %s /tmp/", outfile_name.c_str());
+ RunCommand(cmd);
+ free(cmd);
}
// generate a reciept telling md5sum and encryption key
@@ -340,8 +344,9 @@ string CReportUploader::Report(const map_crash_data_t&
pCrashData,
//error_msg("%s", msg.c_str());
// delete the temporary directory
- cmd = ssprintf("rm -rf %s", tmpdir_name);
- RunCommand(cmd.c_str());
+ cmd = xasprintf("rm -rf %s", tmpdir_name);
+ RunCommand(cmd);
+ free(cmd);
return msg;
}
diff --git a/lib/plugins/SOSreport.cpp b/lib/plugins/SOSreport.cpp
index 6c8ab1f..35b19a1 100644
--- a/lib/plugins/SOSreport.cpp
+++ b/lib/plugins/SOSreport.cpp
@@ -81,27 +81,22 @@ void CActionSOSreport::Run(const char *pActionDir, const char *pArgs,
int force)
"mv sosreport*.tar.bz2 sosreport.tar.bz2 2>/dev/null;"
"mv sosreport*.tar.xz sosreport.tar.xz 2>/dev/null;"
;
- string command;
+ char *command = NULL;
vector_string_t args;
parse_args(pArgs, args, '"');
if (args.size() == 0 || args[0] == "")
- {
- command = ssprintf(command_default, pActionDir);
- }
+ command = xasprintf(command_default, pActionDir);
else
- {
- command = ssprintf(command_prefix, pActionDir, args[0].c_str());
- }
+ command = xasprintf(command_prefix, pActionDir, args[0].c_str());
- update_client(_("Running sosreport: %s"), command.c_str());
- string output = command;
- output += '\n';
- char *command_out = run_in_shell_and_save_output(/*flags:*/ 0, command.c_str(),
/*dir:*/ NULL, /*size_p:*/ NULL);
- output += command_out;
+ update_client(_("Running sosreport: %s"), command);
+ char *command_out = run_in_shell_and_save_output(/*flags:*/ 0, command, /*dir:*/
NULL, /*size_p:*/ NULL);
+ free(command);
update_client(_("Finished running sosreport"));
- VERB3 log("sosreport output:'%s'", output.c_str());
+ VERB3 log("sosreport output:'%s'", command_out);
+ free(command_out);
// Not needed: now we use "sosreport --tmp-dir DUMPDIR"
#if 0
diff --git a/lib/plugins/SQLite3.cpp b/lib/plugins/SQLite3.cpp
index 322f15a..2b17262 100644
--- a/lib/plugins/SQLite3.cpp
+++ b/lib/plugins/SQLite3.cpp
@@ -117,10 +117,12 @@ static void get_table(vector_database_rows_t& pTable,
int ret = sqlite3_get_table(db, sql, &table, &nrow, &ncol, &err);
if (ret != SQLITE_OK)
{
- string errstr = ssprintf("Error in SQL:'%s' error: %s", sql,
err);
+ char *errstr = xasprintf("Error in SQL:'%s' error: %s", sql,
err);
+ CABRTException e(EXCEP_PLUGIN, errstr);
+ free(errstr);
free(sql);
sqlite3_free(err);
- throw CABRTException(EXCEP_PLUGIN, errstr.c_str());
+ throw e;
}
VERB2 log("%d rows returned by SQL:%s", nrow, sql);
free(sql);
@@ -163,10 +165,12 @@ static int execute_sql(sqlite3 *db, const char *fmt, ...)
int ret = sqlite3_exec(db, sql, /*callback:*/ NULL, /*callback param:*/ NULL,
&err);
if (ret != SQLITE_OK)
{
- string errstr = ssprintf("Error in SQL:'%s' error: %s", sql,
err);
+ char *errstr = xasprintf("Error in SQL:'%s' error: %s", sql,
err);
+ CABRTException e(EXCEP_PLUGIN, errstr);
+ free(errstr);
free(sql);
sqlite3_free(err);
- throw CABRTException(EXCEP_PLUGIN, errstr.c_str());
+ throw e;
}
int affected = sqlite3_changes(db);
VERB2 log("%d rows affected by SQL:%s", affected, sql);
diff --git a/lib/utils/DebugDump.cpp b/lib/utils/DebugDump.cpp
index 30ceacc..cf9a8de 100644
--- a/lib/utils/DebugDump.cpp
+++ b/lib/utils/DebugDump.cpp
@@ -140,12 +140,15 @@ static bool GetAndSetLock(const char* pLockFile, const char* pPID)
}
if (isdigit_str(pid_buf))
{
- if (access(ssprintf("/proc/%s", pid_buf).c_str(), F_OK) == 0)
+ char *pid_path = xasprintf("/proc/%s", pid_buf);
+ if (access(pid_path, F_OK) == 0)
{
+ free(pid_path);
log("Lock file '%s' is locked by process %s",
pLockFile, pid_buf);
return false;
}
log("Lock file '%s' was locked by process %s, but it
crashed?", pLockFile, pid_buf);
+ free(pid_path);
}
/* The file may be deleted by now by other process. Ignore ENOENT */
if (unlink(pLockFile) != 0 && errno != ENOENT)
diff --git a/lib/utils/abrt_xmlrpc.cpp b/lib/utils/abrt_xmlrpc.cpp
index ac2654e..637b3e9 100644
--- a/lib/utils/abrt_xmlrpc.cpp
+++ b/lib/utils/abrt_xmlrpc.cpp
@@ -25,11 +25,13 @@
void throw_xml_fault(xmlrpc_env *env)
{
- std::string errmsg = ssprintf("XML-RPC Fault(%d): %s", env->fault_code,
env->fault_string);
+ char *errmsg = xasprintf("XML-RPC Fault(%d): %s", env->fault_code,
env->fault_string);
+ CABRTException e(EXCEP_PLUGIN, errmsg);
+ error_msg("%s", errmsg); // show error in daemon log
+ free(errmsg);
xmlrpc_env_clean(env); // this is needed ONLY if fault_occurred
xmlrpc_env_init(env); // just in case user catches ex and _continues_ to use env
- error_msg("%s", errmsg.c_str()); // show error in daemon log
- throw CABRTException(EXCEP_PLUGIN, errmsg.c_str());
+ throw e;
}
void throw_if_xml_fault_occurred(xmlrpc_env *env)
diff --git a/src/daemon/Daemon.cpp b/src/daemon/Daemon.cpp
index 735da5a..02fc0b6 100644
--- a/src/daemon/Daemon.cpp
+++ b/src/daemon/Daemon.cpp
@@ -558,13 +558,14 @@ static gboolean handle_inotify_cb(GIOChannel *gio, GIOCondition
condition, gpoin
) {
VERB1 log("Reporting the crash automatically");
map_crash_data_t crash_report;
- string crash_id = ssprintf("%s:%s", uid_str,
get_crash_data_item_content(crashinfo, CD_UUID).c_str());
+ char *crash_id = xasprintf("%s:%s", uid_str,
get_crash_data_item_content(crashinfo, CD_UUID).c_str());
mw_result_t crash_result = CreateCrashReport(
- crash_id.c_str(),
+ crash_id,
/*caller_uid:*/ 0,
/*force:*/ 0,
crash_report
);
+ free(crash_id);
if (crash_result == MW_OK)
{
map_analyzer_actions_and_reporters_t::const_iterator it =
g_settings_mapAnalyzerActionsAndReporters.find(analyzer);
diff --git a/src/daemon/MiddleWare.cpp b/src/daemon/MiddleWare.cpp
index c7ed4df..b14b39e 100644
--- a/src/daemon/MiddleWare.cpp
+++ b/src/daemon/MiddleWare.cpp
@@ -391,13 +391,14 @@ report_status_t Report(const map_crash_data_t& client_report,
{
throw CABRTException(EXCEP_ERROR, "Report(): UID or UUID is missing in
client's report data");
}
- string crash_id = ssprintf("%s:%s", UID, UUID);
+ char *crash_id = xasprintf("%s:%s", UID, UUID);
// Retrieve corresponding stored record
map_crash_data_t stored_report;
- mw_result_t r = FillCrashInfo(crash_id.c_str(), stored_report);
+ mw_result_t r = FillCrashInfo(crash_id, stored_report);
if (r != MW_OK)
{
+ free(crash_id);
return report_status_t();
}
@@ -406,8 +407,10 @@ report_status_t Report(const map_crash_data_t& client_report,
&& get_crash_data_item_content(stored_report, CD_INFORMALL) !=
"1"
&& strcmp(to_string(caller_uid).c_str(), UID) != 0
) {
- throw CABRTException(EXCEP_ERROR, "Report(): user with uid %ld can't
report crash %s",
- caller_uid, crash_id.c_str());
+ CABRTException e(EXCEP_ERROR, "Report(): user with uid %ld can't report
crash %s",
+ caller_uid, crash_id);
+ free(crash_id);
+ throw e;
}
const std::string& pDumpDir = get_crash_data_item_content(stored_report,
CD_DUMPDIR);
@@ -543,13 +546,14 @@ report_status_t Report(const map_crash_data_t& client_report,
const vector_string_t &v = ret_it->second;
if (v[REPORT_STATUS_IDX_FLAG] == "1")
{
- database->SetReportedPerReporter(crash_id.c_str(),
plugin_name.c_str(), v[REPORT_STATUS_IDX_MSG].c_str());
+ database->SetReportedPerReporter(crash_id, plugin_name.c_str(),
v[REPORT_STATUS_IDX_MSG].c_str());
}
ret_it++;
}
- database->SetReported(crash_id.c_str(), message.c_str());
+ database->SetReported(crash_id, message.c_str());
database->DisConnect();
}
+ free(crash_id);
return ret;
#undef client_report
@@ -1050,7 +1054,7 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir,
return res;
std::string UUID = GetLocalUUID(analyzer.c_str(), pDebugDumpDir);
- std::string crash_id = ssprintf("%s:%s", UID.c_str(), UUID.c_str());
+ char *crash_id = xasprintf("%s:%s", UID.c_str(), UUID.c_str());
/* Loads pCrashData (from the *first debugdump dir* if this one is a dup)
* Returns:
* MW_REPORTED: "the crash is flagged as reported in DB" (which also means
it's a dup)
@@ -1058,11 +1062,16 @@ mw_result_t SaveDebugDump(const char *pDebugDumpDir,
* MW_OK: "crash count is 1" (iow: this is a new crash, not a dup)
* else: an error code
*/
- return SaveDebugDumpToDatabase(crash_id.c_str(),
+
+ res = SaveDebugDumpToDatabase(crash_id,
analyzer_has_InformAllUsers(analyzer.c_str()),
time.c_str(),
pDebugDumpDir,
- pCrashData);
+ pCrashData
+ );
+ free(crash_id);
+
+ return res;
}
mw_result_t FillCrashInfo(const char *crash_id,
diff --git a/src/daemon/PluginManager.cpp b/src/daemon/PluginManager.cpp
index 4f64ed0..442cc64 100644
--- a/src/daemon/PluginManager.cpp
+++ b/src/daemon/PluginManager.cpp
@@ -159,8 +159,10 @@ CPlugin* CPluginManager::LoadPlugin(const char *pName, bool
enabled_only)
conf_name = "Kerneloops";
}
map_plugin_settings_t pluginSettings;
- string conf_fullname =
ssprintf(PLUGINS_CONF_DIR"/%s."PLUGINS_CONF_EXTENSION, conf_name);
- LoadPluginSettings(conf_fullname.c_str(), pluginSettings);
+ char *conf_fullname =
xasprintf(PLUGINS_CONF_DIR"/%s."PLUGINS_CONF_EXTENSION, conf_name);
+
+ LoadPluginSettings(conf_fullname, pluginSettings);
+ free(conf_fullname);
m_map_plugin_settings[pName] = pluginSettings;
/* If settings are empty, most likely .conf file does not exist.
* Don't mislead the user: */
@@ -185,13 +187,16 @@ CPlugin* CPluginManager::LoadPlugin(const char *pName, bool
enabled_only)
}
}
- string libPath =
ssprintf(PLUGINS_LIB_DIR"/"PLUGINS_LIB_PREFIX"%s."PLUGINS_LIB_EXTENSION,
pName);
- void *handle = dlopen(libPath.c_str(), RTLD_NOW);
+ char *lib_path =
xasprintf(PLUGINS_LIB_DIR"/"PLUGINS_LIB_PREFIX"%s."PLUGINS_LIB_EXTENSION,
pName);
+ void *handle = dlopen(lib_path, RTLD_NOW);
if (!handle)
{
- error_msg("Can't load '%s': %s", libPath.c_str(),
dlerror());
+ error_msg("Can't load '%s': %s", lib_path, dlerror());
+ free(lib_path);
return NULL; /* error */
}
+ free(lib_path);
+
CLoadedModule *module = new CLoadedModule(handle, pName);
if (module->GetMagicNumber() != PLUGINS_MAGIC_NUMBER
|| module->GetType() < 0
and the rest seems fine...
Jirka