diff options
| author | Karel Klic <kklic@redhat.com> | 2009-12-18 19:12:50 +0100 |
|---|---|---|
| committer | Karel Klic <kklic@redhat.com> | 2009-12-18 19:12:50 +0100 |
| commit | e7661d7e411172ddad8838040ded025ad6bfbb14 (patch) | |
| tree | f2451b553b4fcf959bd2bfc29172f9fb855e5fdd /lib | |
| parent | ce1904e24b576a7356488852a240d777717b2598 (diff) | |
| parent | 46b2fb8df8d4e025f5bbdd9f53be1f658a9e82c6 (diff) | |
| download | abrt-e7661d7e411172ddad8838040ded025ad6bfbb14.tar.gz abrt-e7661d7e411172ddad8838040ded025ad6bfbb14.tar.xz abrt-e7661d7e411172ddad8838040ded025ad6bfbb14.zip | |
Merge branch 'master' of git://git.fedorahosted.org/git/abrt
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Plugins/CCpp.cpp | 46 | ||||
| -rw-r--r-- | lib/Plugins/Catcut.cpp | 13 | ||||
| -rw-r--r-- | lib/Plugins/FileTransfer.cpp | 12 | ||||
| -rw-r--r-- | lib/Plugins/Firefox.cpp | 8 | ||||
| -rw-r--r-- | lib/Plugins/Kerneloops.conf | 20 | ||||
| -rw-r--r-- | lib/Plugins/KerneloopsReporter.cpp | 4 | ||||
| -rw-r--r-- | lib/Plugins/Mailx.cpp | 2 | ||||
| -rw-r--r-- | lib/Plugins/SQLite3.cpp | 21 | ||||
| -rw-r--r-- | lib/Plugins/TicketUploader.cpp | 12 | ||||
| -rw-r--r-- | lib/Utils/CrashTypesSocket.cpp | 2 | ||||
| -rw-r--r-- | lib/Utils/DebugDump.cpp | 16 | ||||
| -rw-r--r-- | lib/Utils/DebugDump.h | 4 | ||||
| -rw-r--r-- | lib/Utils/Makefile.am | 2 | ||||
| -rw-r--r-- | lib/Utils/abrt_xmlrpc.cpp | 10 | ||||
| -rw-r--r-- | lib/Utils/abrt_xmlrpc.h | 5 | ||||
| -rw-r--r-- | lib/Utils/daemon.cpp | 139 | ||||
| -rw-r--r-- | lib/Utils/xatonum.cpp | 50 |
17 files changed, 300 insertions, 66 deletions
diff --git a/lib/Plugins/CCpp.cpp b/lib/Plugins/CCpp.cpp index 37a2c8b..99c1c77 100644 --- a/lib/Plugins/CCpp.cpp +++ b/lib/Plugins/CCpp.cpp @@ -37,7 +37,7 @@ using namespace std; #define CORE_PATTERN_IFACE "/proc/sys/kernel/core_pattern" -#define CORE_PATTERN "|"CCPP_HOOK_PATH" "DEBUG_DUMPS_DIR" %p %s %u" +#define CORE_PATTERN "|"CCPP_HOOK_PATH" "DEBUG_DUMPS_DIR" %p %s %u %c" #define FILENAME_COREDUMP "coredump" #define FILENAME_BACKTRACE "backtrace" @@ -96,7 +96,7 @@ static string concat_str_vector(char **strings) } /* Returns status. See `man 2 wait` for status information. */ -static int ExecVP(char **pArgs, uid_t uid, string& pOutput) +static int ExecVP(char **pArgs, uid_t uid, int redirect_stderr, string& pOutput) { int pipeout[2]; pid_t child; @@ -114,8 +114,6 @@ static int ExecVP(char **pArgs, uid_t uid, string& pOutput) xmove_fd(pipeout[1], STDOUT_FILENO); /* Make sure stdin is safely open to nothing */ xmove_fd(xopen("/dev/null", O_RDONLY), STDIN_FILENO); - /* Not a good idea, we won't see any error messages */ - /* close(STDERR_FILENO); */ struct passwd* pw = getpwuid(uid); gid_t gid = pw ? pw->pw_gid : uid; @@ -136,6 +134,11 @@ static int ExecVP(char **pArgs, uid_t uid, string& pOutput) unsetenv("LC_NUMERIC"); unsetenv("LC_TIME"); + if (redirect_stderr) + { + /* We want parent to see errors in the same stream */ + xdup2(STDOUT_FILENO, STDERR_FILENO); + } execvp(pArgs[0], pArgs); /* VERB1 since sometimes we expect errors here */ VERB1 perror_msg("Can't execute '%s'", pArgs[0]); @@ -309,7 +312,7 @@ static void GetBacktrace(const char *pDebugDumpDir, args[11] = (char*)"info sharedlib"; args[12] = NULL; - ExecVP(args, atoi(UID.c_str()), pBacktrace); + ExecVP(args, xatoi_u(UID.c_str()), /*redirect_stderr:*/ 1, pBacktrace); } static void GetIndependentBuildIdPC(const char *unstrip_n_output, @@ -355,7 +358,7 @@ static string run_unstrip_n(const char *pDebugDumpDir) args[3] = NULL; string output; - ExecVP(args, atoi(UID.c_str()), output); + ExecVP(args, xatoi_u(UID.c_str()), /*redirect_stderr:*/ 0, output); free(args[1]); @@ -386,18 +389,18 @@ static void InstallDebugInfos(const char *pDebugDumpDir, close(pipeout[0]); xmove_fd(pipeout[1], STDOUT_FILENO); xmove_fd(xopen("/dev/null", O_RDONLY), STDIN_FILENO); - /* Not a good idea, we won't see any error messages */ - /*close(STDERR_FILENO);*/ - - setsid(); char *coredump = xasprintf("%s/"FILENAME_COREDUMP, pDebugDumpDir); /* SELinux guys are not happy with /tmp, using /var/run/abrt */ char *tempdir = xasprintf(LOCALSTATEDIR"/run/abrt/tmp-%u-%lu", (int)getpid(), (long)time(NULL)); /* log() goes to stderr/syslog, it's ok to use it here */ VERB1 log("Executing: %s %s %s %s", "abrt-debuginfo-install", coredump, tempdir, debuginfo_dirs); + /* We want parent to see errors in the same stream */ + xdup2(STDOUT_FILENO, STDERR_FILENO); execlp("abrt-debuginfo-install", "abrt-debuginfo-install", coredump, tempdir, debuginfo_dirs, NULL); - exit(1); + perror_msg("Can't execute '%s'", "abrt-debuginfo-install"); + /* Serious error (1 means "some debuginfos not found") */ + exit(2); } close(pipeout[1]); @@ -436,9 +439,20 @@ static void InstallDebugInfos(const char *pDebugDumpDir, update_client("%s", buff); } } - fclose(pipeout_fp); - wait(NULL); + + int status = 0; + while (waitpid(child, &status, 0) < 0 && errno == EINTR) + continue; + if (WIFEXITED(status)) + { + if (WEXITSTATUS(status) > 1) + error_msg("%s exited with %u", "abrt-debuginfo-install", (int)WEXITSTATUS(status)); + } + else + { + error_msg("%s killed by signal %u", "abrt-debuginfo-install", (int)WTERMSIG(status)); + } } static double get_dir_size(const char *dirname, @@ -564,7 +578,7 @@ string CAnalyzerCCpp::GetGlobalUUID(const char *pDebugDumpDir) close(pipeout[0]); /* read side of the pipe */ /* abrt-backtrace is executed under the user's uid and gid. */ - uid_t uid = atoi(uid_str.c_str()); + uid_t uid = xatoi_u(uid_str.c_str()); struct passwd* pw = getpwuid(uid); gid_t gid = pw ? pw->pw_gid : uid; setgroups(1, &gid); @@ -659,7 +673,7 @@ void CAnalyzerCCpp::CreateReport(const char *pDebugDumpDir, int force) dd.Close(); /* do not keep dir locked longer than needed */ string build_ids; - if (m_bInstallDebugInfo && DebuginfoCheckPolkit(atoi(UID.c_str()))) + if (m_bInstallDebugInfo && DebuginfoCheckPolkit(xatoi_u(UID.c_str()))) { if (m_nDebugInfoCacheMB > 0) { @@ -750,7 +764,7 @@ void CAnalyzerCCpp::SetSettings(const map_plugin_settings_t& pSettings) it = pSettings.find("DebugInfoCacheMB"); if (it != end) { - m_nDebugInfoCacheMB = atoi(it->second.c_str()); + m_nDebugInfoCacheMB = xatou(it->second.c_str()); } it = pSettings.find("InstallDebugInfo"); if (it == end) //compat, remove after 0.0.11 diff --git a/lib/Plugins/Catcut.cpp b/lib/Plugins/Catcut.cpp index ebddfdd..a56015d 100644 --- a/lib/Plugins/Catcut.cpp +++ b/lib/Plugins/Catcut.cpp @@ -1,6 +1,3 @@ -#include <xmlrpc-c/base.h> -#include <xmlrpc-c/client.h> -#include <curl/curl.h> #include "abrtlib.h" #include "abrt_xmlrpc.h" #include "Catcut.h" @@ -18,11 +15,7 @@ using namespace std; static int put_stream(const char *pURL, FILE* f, size_t content_length) { - CURL* curl = curl_easy_init(); - if (!curl) - { - throw CABRTException(EXCEP_PLUGIN, "put_stream: can't initialize curl library"); - } + CURL* curl = xcurl_easy_init(); /* enable uploading */ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); /* specify target */ @@ -510,12 +503,12 @@ void CReporterCatcut::SetSettings(const map_plugin_settings_t& pSettings) it = pSettings.find("RetryCount"); if (it != end) { - m_nRetryCount = atoi(it->second.c_str()); + m_nRetryCount = xatoi_u(it->second.c_str()); } it = pSettings.find("RetryDelay"); if (it != end) { - m_nRetryDelay = atoi(it->second.c_str()); + m_nRetryDelay = xatoi_u(it->second.c_str()); } } diff --git a/lib/Plugins/FileTransfer.cpp b/lib/Plugins/FileTransfer.cpp index c98645c..60e1e66 100644 --- a/lib/Plugins/FileTransfer.cpp +++ b/lib/Plugins/FileTransfer.cpp @@ -35,8 +35,8 @@ #include <libtar.h> #include <bzlib.h> #include <zlib.h> -#include <curl/curl.h> #include "abrtlib.h" +#include "abrt_xmlrpc.h" /* for xcurl_easy_init */ #include "FileTransfer.h" #include "DebugDump.h" #include "ABRTException.h" @@ -85,11 +85,7 @@ void CFileTransfer::SendFile(const char *pURL, const char *pFilename) fclose(f); throw CABRTException(EXCEP_PLUGIN, "Can't stat archive file '%s'", pFilename); } - curl = curl_easy_init(); - if (!curl) - { - throw CABRTException(EXCEP_PLUGIN, "Curl library init error"); - } + curl = xcurl_easy_init(); /* enable uploading */ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); /* specify target */ @@ -388,13 +384,13 @@ void CFileTransfer::SetSettings(const map_plugin_settings_t& pSettings) it = pSettings.find("RetryCount"); if (it != end) { - m_nRetryCount = atoi(it->second.c_str()); + m_nRetryCount = xatoi_u(it->second.c_str()); } it = pSettings.find("RetryDelay"); if (it != end) { - m_nRetryDelay = atoi(it->second.c_str()); + m_nRetryDelay = xatoi_u(it->second.c_str()); } it = pSettings.find("ArchiveType"); diff --git a/lib/Plugins/Firefox.cpp b/lib/Plugins/Firefox.cpp index bcc5948..2bb7f9c 100644 --- a/lib/Plugins/Firefox.cpp +++ b/lib/Plugins/Firefox.cpp @@ -281,7 +281,7 @@ static void GetBacktrace(const char *pDebugDumpDir, std::string& pBacktrace) args[9] = (char*)"thread apply all backtrace full"; args[10] = NULL; - ExecVP(args, atoi(UID.c_str()), pBacktrace); + ExecVP(args, xatoi_u(UID.c_str()), pBacktrace); free(args[5]); free(args[7]); @@ -454,7 +454,7 @@ static std::string run_unstrip_n(const char *pDebugDumpDir) args[3] = NULL; std::string output; - ExecVP(args, atoi(UID.c_str()), output); + ExecVP(args, xatoi_u(UID.c_str()), output); free(args[1]); @@ -886,7 +886,7 @@ void CAnalyzerFirefox::CreateReport(const char *pDebugDumpDir, int force) dd.Close(); /* do not keep dir locked longer than needed */ std::string build_ids; - if (m_bInstallDebugInfo && DebuginfoCheckPolkit(atoi(UID.c_str()))) { + if (m_bInstallDebugInfo && DebuginfoCheckPolkit(xatoi_u(UID.c_str()))) { if (m_nDebugInfoCacheMB > 0) trim_debuginfo_cache(m_nDebugInfoCacheMB); InstallDebugInfos(pDebugDumpDir, build_ids); @@ -974,7 +974,7 @@ void CAnalyzerFirefox::SetSettings(const map_plugin_settings_t& pSettings) it = pSettings.find("DebugInfoCacheMB"); if (it != end) { - m_nDebugInfoCacheMB = atoi(it->second.c_str()); + m_nDebugInfoCacheMB = xatou(it->second.c_str()); } it = pSettings.find("InstallDebugInfo"); if (it == end) //compat, remove after 0.0.11 diff --git a/lib/Plugins/Kerneloops.conf b/lib/Plugins/Kerneloops.conf index a014153..5623596 100644 --- a/lib/Plugins/Kerneloops.conf +++ b/lib/Plugins/Kerneloops.conf @@ -1,15 +1,17 @@ -# compatibility with kerneloops.org tool +# Do we want kernel oopses to be visible to any user? +# Set to "yes" for compatibility with kerneloops.org tool. InformAllUsers = yes +# Automatically perform reporting. +# With default abrt.conf, it invokes KerneloopsReporter +# and thus reports oops to kerneloops.org. +# ("root" because all oopses are filed by abrt with user "root") AutoReportUIDs = root -# KerneloopsReporter configuration. Reports kernel crashes collected by the addon. -################################################################################ +# Kerneloops Scanner configuration +################################## +SysLogFile = /var/log/messages -# kerneloops.org +# KerneloopsReporter configuration +################################## SubmitURL = http://submit.kerneloops.org/submitoops.php - -# Kerneloops Scanner configuration. -################################################################################ - -SysLogFile = /var/log/messages diff --git a/lib/Plugins/KerneloopsReporter.cpp b/lib/Plugins/KerneloopsReporter.cpp index 26430be..5cb525b 100644 --- a/lib/Plugins/KerneloopsReporter.cpp +++ b/lib/Plugins/KerneloopsReporter.cpp @@ -25,9 +25,9 @@ */ #include "abrtlib.h" +#include "abrt_xmlrpc.h" /* for xcurl_easy_init */ #include "KerneloopsReporter.h" #include "CommLayerInner.h" -#include <curl/curl.h> #include "ABRTException.h" #define FILENAME_KERNELOOPS "kerneloops" @@ -64,7 +64,7 @@ static int http_post_to_kerneloops_site(const char *url, const char *oopsdata) struct curl_httppost *post = NULL; struct curl_httppost *last = NULL; - handle = curl_easy_init(); + handle = xcurl_easy_init(); curl_easy_setopt(handle, CURLOPT_URL, url); curl_formadd(&post, &last, diff --git a/lib/Plugins/Mailx.cpp b/lib/Plugins/Mailx.cpp index b06edeb..6904c16 100644 --- a/lib/Plugins/Mailx.cpp +++ b/lib/Plugins/Mailx.cpp @@ -163,7 +163,7 @@ std::string CMailx::Report(const map_crash_report_t& pCrashReport, update_client(_("Sending an email...")); const char *uid_str = pCrashReport.find(CD_MWUID)->second[CD_CONTENT].c_str(); - exec_and_feed_input(atoi(uid_str), emailBody.c_str(), args); + exec_and_feed_input(xatoi_u(uid_str), emailBody.c_str(), args); while (*args) { diff --git a/lib/Plugins/SQLite3.cpp b/lib/Plugins/SQLite3.cpp index d95c273..1979f24 100644 --- a/lib/Plugins/SQLite3.cpp +++ b/lib/Plugins/SQLite3.cpp @@ -198,9 +198,9 @@ static bool check_table(sqlite3 *db) if (pos != string::npos) { string tableVersion = tableName.substr(pos + 2); - if (atoi(tableVersion.c_str()) < ABRT_TABLE_VERSION) + if (xatoi_u(tableVersion.c_str()) < ABRT_TABLE_VERSION) { - update_from_old_ver(db, atoi(tableVersion.c_str())); + update_from_old_ver(db, xatoi_u(tableVersion.c_str())); } return true; } @@ -238,7 +238,18 @@ CSQLite3::CSQLite3() : CSQLite3::~CSQLite3() { - DisConnect(); + /* Paranoia. In C++, destructor will abort() if it was called while unwinding + * the stack and it throws an exception. + */ + try + { + DisConnect(); + m_sDBPath.clear(); + } + catch (...) + { + error_msg_and_die("Internal error"); + } } void CSQLite3::DisConnect() @@ -262,7 +273,7 @@ void CSQLite3::Connect() { if (ret != SQLITE_CANTOPEN) { - throw CABRTException(EXCEP_PLUGIN, "Can't open database: %s", sqlite3_errmsg(m_pDB)); + throw CABRTException(EXCEP_PLUGIN, "Can't open database '%s': %s", m_sDBPath.c_str(), sqlite3_errmsg(m_pDB)); } ret = sqlite3_open_v2(m_sDBPath.c_str(), @@ -272,7 +283,7 @@ void CSQLite3::Connect() ); if (ret != SQLITE_OK) { - throw CABRTException(EXCEP_PLUGIN, "Can't create database: %s", sqlite3_errmsg(m_pDB)); + throw CABRTException(EXCEP_PLUGIN, "Can't create database '%s': %s", m_sDBPath.c_str(), sqlite3_errmsg(m_pDB)); } } diff --git a/lib/Plugins/TicketUploader.cpp b/lib/Plugins/TicketUploader.cpp index 06b6cde..a4fe0e8 100644 --- a/lib/Plugins/TicketUploader.cpp +++ b/lib/Plugins/TicketUploader.cpp @@ -20,8 +20,8 @@ #include <string> #include <fstream> #include <sstream> -#include <curl/curl.h> #include "abrtlib.h" +#include "abrt_xmlrpc.h" /* for xcurl_easy_init */ #include "TicketUploader.h" #include "DebugDump.h" #include "ABRTException.h" @@ -124,11 +124,7 @@ void CTicketUploader::SendFile(const char *pURL, const char *pFilename) { throw CABRTException(EXCEP_PLUGIN, "Can't stat archive file '%s'", pFilename); } - CURL* curl = curl_easy_init(); - if (!curl) - { - throw CABRTException(EXCEP_PLUGIN, "Curl library init error"); - } + CURL* curl = xcurl_easy_init(); /* enable uploading */ curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); /* specify target */ @@ -394,12 +390,12 @@ void CTicketUploader::SetSettings(const map_plugin_settings_t& pSettings) it = pSettings.find("RetryCount"); if (it != end) { - m_nRetryCount = atoi(it->second.c_str()); + m_nRetryCount = xatoi_u(it->second.c_str()); } it = pSettings.find("RetryDelay"); if (it != end) { - m_nRetryDelay = atoi(it->second.c_str()); + m_nRetryDelay = xatoi_u(it->second.c_str()); } } diff --git a/lib/Utils/CrashTypesSocket.cpp b/lib/Utils/CrashTypesSocket.cpp index f16e2a9..3525c6a 100644 --- a/lib/Utils/CrashTypesSocket.cpp +++ b/lib/Utils/CrashTypesSocket.cpp @@ -114,7 +114,7 @@ static int get_number_from_string(const std::string& pMessage, int& len) } } len = ii + 1; - return atoi(sNumber.c_str()); + return xatoi(sNumber.c_str()); } //TODO: remove constant 4 and place it in a message diff --git a/lib/Utils/DebugDump.cpp b/lib/Utils/DebugDump.cpp index 765b514..b4c3ee4 100644 --- a/lib/Utils/DebugDump.cpp +++ b/lib/Utils/DebugDump.cpp @@ -68,6 +68,22 @@ CDebugDump::CDebugDump() : m_bLocked(false) {} +CDebugDump::~CDebugDump() +{ + /* Paranoia. In C++, destructor will abort() if it was called while unwinding + * the stack and it throws an exception. + */ + try + { + Close(); + m_sDebugDumpDir.clear(); + } + catch (...) + { + error_msg_and_die("Internal error"); + } +} + void CDebugDump::Open(const char *pDir) { if (m_bOpened) diff --git a/lib/Utils/DebugDump.h b/lib/Utils/DebugDump.h index 7dfe61e..c59552e 100644 --- a/lib/Utils/DebugDump.h +++ b/lib/Utils/DebugDump.h @@ -41,6 +41,8 @@ #define FILENAME_COMMENT "comment" #define FILENAME_REPRODUCE "reproduce" #define FILENAME_RATING "rating" +#define FILENAME_CMDLINE "cmdline" + class CDebugDump { @@ -57,7 +59,7 @@ class CDebugDump public: CDebugDump(); - ~CDebugDump() { Close(); } + ~CDebugDump(); void Open(const char *pDir); void Create(const char *pDir, int64_t uid); diff --git a/lib/Utils/Makefile.am b/lib/Utils/Makefile.am index 9618751..d5e9d98 100644 --- a/lib/Utils/Makefile.am +++ b/lib/Utils/Makefile.am @@ -13,7 +13,9 @@ libABRTUtils_la_SOURCES = \ read_write.cpp \ logging.cpp \ copyfd.cpp \ + daemon.cpp \ skip_whitespace.cpp \ + xatonum.cpp \ popen_and_save_output.cpp \ stringops.cpp \ dirsize.cpp \ diff --git a/lib/Utils/abrt_xmlrpc.cpp b/lib/Utils/abrt_xmlrpc.cpp index 7205316..ae1d098 100644 --- a/lib/Utils/abrt_xmlrpc.cpp +++ b/lib/Utils/abrt_xmlrpc.cpp @@ -5,6 +5,16 @@ #include "abrt_xmlrpc.h" #include "ABRTException.h" +CURL* xcurl_easy_init() +{ + CURL* curl = curl_easy_init(); + if (!curl) + { + error_msg_and_die("Can't create curl handle"); + } + return curl; +} + void throw_if_xml_fault_occurred(xmlrpc_env *env) { if (env->fault_occurred) diff --git a/lib/Utils/abrt_xmlrpc.h b/lib/Utils/abrt_xmlrpc.h index e67ab19..352e80c 100644 --- a/lib/Utils/abrt_xmlrpc.h +++ b/lib/Utils/abrt_xmlrpc.h @@ -1,6 +1,7 @@ #ifndef ABRT_XMLRPC_H_ #define ABRT_XMLRPC_H_ 1 +#include <curl/curl.h> #include <xmlrpc-c/base.h> #include <xmlrpc-c/client.h> @@ -15,13 +16,15 @@ struct abrt_xmlrpc_conn { xmlrpc_server_info* m_pServer_info; abrt_xmlrpc_conn(const char* url, bool no_ssl_verify) { new_xmlrpc_client(url, no_ssl_verify); } + /* this never throws exceptions - calls C functions only */ ~abrt_xmlrpc_conn() { destroy_xmlrpc_client(); } void new_xmlrpc_client(const char* url, bool no_ssl_verify); void destroy_xmlrpc_client(); }; -/* Utility function */ +/* Utility functions */ void throw_if_xml_fault_occurred(xmlrpc_env *env); +CURL* xcurl_easy_init(); #endif diff --git a/lib/Utils/daemon.cpp b/lib/Utils/daemon.cpp new file mode 100644 index 0000000..7aa891c --- /dev/null +++ b/lib/Utils/daemon.cpp @@ -0,0 +1,139 @@ +/* + Copyright (C) 2009 RedHat inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#include "abrtlib.h" +#define FILENAME_CMDLINE "cmdline" +#define VAR_RUN_PID_FILE VAR_RUN"/abrt.pid" + +static char *append_escaped(char *start, const char *s) +{ + char hex_char_buf[] = "\\x00"; + + *start++ = ' '; + char *dst = start; + const unsigned char *p = (unsigned char *)s; + + while (1) + { + const unsigned char *old_p = p; + while (*p > ' ' && *p <= 0x7e && *p != '\"' && *p != '\'' && *p != '\\') + p++; + if (dst == start) + { + if (p != (unsigned char *)s && *p == '\0') + { + /* entire word does not need escaping and quoting */ + strcpy(dst, s); + dst += strlen(s); + return dst; + } + *dst++ = '\''; + } + + strncpy(dst, s, (p - old_p)); + dst += (p - old_p); + + if (*p == '\0') + { + *dst++ = '\''; + *dst = '\0'; + return dst; + } + const char *a; + switch (*p) + { + case '\r': a = "\\r"; break; + case '\n': a = "\\n"; break; + case '\t': a = "\\t"; break; + case '\'': a = "\\\'"; break; + case '\"': a = "\\\""; break; + case '\\': a = "\\\\"; break; + case ' ': a = " "; break; + default: + hex_char_buf[2] = "0123456789abcdef"[*p >> 4]; + hex_char_buf[3] = "0123456789abcdef"[*p & 0xf]; + a = hex_char_buf; + } + strcpy(dst, a); + dst += strlen(a); + p++; + } +} + +// taken from kernel +#define COMMAND_LINE_SIZE 2048 +char* get_cmdline(pid_t pid) +{ + char path[sizeof("/proc/%u/cmdline") + sizeof(int)*3]; + char cmdline[COMMAND_LINE_SIZE]; + char escaped_cmdline[COMMAND_LINE_SIZE*4 + 4]; + + escaped_cmdline[1] = '\0'; + sprintf(path, "/proc/%u/cmdline", (int)pid); + int fd = open(path, O_RDONLY); + if (fd >= 0) + { + int len = read(fd, cmdline, sizeof(cmdline) - 1); + close(fd); + + if (len > 0) + { + cmdline[len] = '\0'; + char *src = cmdline; + char *dst = escaped_cmdline; + while ((src - cmdline) < len) + { + dst = append_escaped(dst, src); + src += strlen(src) + 1; + } + } + } + + return xstrdup(escaped_cmdline + 1); /* +1 skips extraneous leading space */ +} + +int daemon_is_ok() +{ + int fd = open(VAR_RUN_PID_FILE, O_RDONLY); + if (fd < 0) + { + return 0; + } + + char pid[sizeof(pid_t)*3 + 2]; + int len = read(fd, pid, sizeof(pid)-1); + close(fd); + if (len <= 0) + return 0; + + pid[len] = '\0'; + *strchrnul(pid, '\n') = '\0'; + /* paranoia: we don't want to check /proc//stat or /proc///stat */ + if (pid[0] == '\0' || pid[0] == '/') + return 0; + + /* TODO: maybe readlink and check that it is "xxx/abrt"? */ + char path[sizeof("/proc/%s/stat") + sizeof(pid)]; + sprintf(path, "/proc/%s/stat", pid); + struct stat sb; + if (stat(path, &sb) == -1) + { + return 0; + } + + return 1; +} diff --git a/lib/Utils/xatonum.cpp b/lib/Utils/xatonum.cpp new file mode 100644 index 0000000..b096ca8 --- /dev/null +++ b/lib/Utils/xatonum.cpp @@ -0,0 +1,50 @@ +/* + * Utility routines. + * + * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> + * + * Licensed under GPLv2, see file LICENSE in this tarball for details. + */ +#include "abrtlib.h" + +unsigned xatou(const char *numstr) +{ + unsigned r; + int old_errno; + char *e; + + if (*numstr < '0' || *numstr > '9') + goto inval; + + old_errno = errno; + errno = 0; + r = strtoul(numstr, &e, 10); + if (errno || numstr == e || *e != '\0') + goto inval; /* error / no digits / illegal trailing chars */ + errno = old_errno; /* Ok. So restore errno. */ + return r; + + inval: + error_msg_and_die("invalid number '%s'", numstr); +} + +int xatoi_u(const char *numstr) +{ + unsigned r = xatou(numstr); + if (r > (unsigned)INT_MAX) + error_msg_and_die("invalid number '%s'", numstr); + return r; +} + +int xatoi(const char *numstr) +{ + unsigned r; + + if (*numstr != '-') + return xatoi_u(numstr); + + r = xatou(numstr + 1); + if (r > (unsigned)INT_MAX + 1) + error_msg_and_die("invalid number '%s'", numstr); + return - (int)r; +} |
