summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--inc/abrtlib.h7
-rw-r--r--lib/Plugins/FileTransfer.cpp9
-rw-r--r--lib/Utils/DebugDump.cpp14
-rw-r--r--lib/Utils/xfuncs.cpp19
-rw-r--r--src/Daemon/PluginManager.cpp3
5 files changed, 35 insertions, 17 deletions
diff --git a/inc/abrtlib.h b/inc/abrtlib.h
index c99f4b7e..02906f2f 100644
--- a/inc/abrtlib.h
+++ b/inc/abrtlib.h
@@ -122,6 +122,13 @@ void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
void xlisten(int s, int backlog);
ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, socklen_t tolen);
void xstat(const char *name, struct stat *stat_buf);
+/* Just testing dent->d_type == DT_REG is wrong: some filesystems
+ * do not report the type, they report DT_UNKNOWN for every dirent
+ * (and this is not a bug in filesystem, this is allowed by standards).
+ * This function handles this case. Note: it returns 0 on symlinks
+ * even if they point to regular files.
+ */
+int is_regular_file(struct dirent *dent, const char *dirname);
void xmove_fd(int from, int to);
char* xasprintf(const char *format, ...);
diff --git a/lib/Plugins/FileTransfer.cpp b/lib/Plugins/FileTransfer.cpp
index 08d915dc..9c2f3c55 100644
--- a/lib/Plugins/FileTransfer.cpp
+++ b/lib/Plugins/FileTransfer.cpp
@@ -137,13 +137,12 @@ static void traverse_directory(const char * directory, void * something,
dp = opendir(directory);
while ((dirp = readdir(dp)) != NULL)
{
- if (dirp->d_type == DT_REG)
+ if (is_regular_file(dirp, directory))
{
- complete_name[0] = '\0';
end = stpcpy(complete_name, directory);
if (end[-1] != '/')
{
- end = stpcpy(end, "/");
+ *end++ = '/';
}
end = stpcpy(end, dirp->d_name);
@@ -292,7 +291,8 @@ void CFileTransfer::Run(const std::string& pActiveDir, const std::string& pArgs)
dirlist.open(FILETRANSFER_DIRLIST, fstream::out | fstream::app );
dirlist << pActiveDir << endl;
dirlist.close();
- } else if(pArgs == "one")
+ }
+ else if (pArgs == "one")
{
/* just send one archive */
gethostname(hostname,HBLEN);
@@ -312,7 +312,6 @@ void CFileTransfer::Run(const std::string& pActiveDir, const std::string& pArgs)
}
else
{
-
gethostname(hostname,HBLEN);
dirlist.open(FILETRANSFER_DIRLIST, fstream::in);
diff --git a/lib/Utils/DebugDump.cpp b/lib/Utils/DebugDump.cpp
index 60564431..43eb3244 100644
--- a/lib/Utils/DebugDump.cpp
+++ b/lib/Utils/DebugDump.cpp
@@ -484,16 +484,10 @@ bool CDebugDump::GetNextFile(std::string& pFileName, std::string& pContent, bool
struct dirent *dent;
while ((dent = readdir(m_pGetNextFileDir)) != NULL)
{
- struct stat statbuf;
- std::string fullname = m_sDebugDumpDir + "/" + dent->d_name;
-
- /* some filesystems do not report the type! they report DT_UNKNOWN */
- if (dent->d_type == DT_REG
- || (dent->d_type == DT_UNKNOWN
- && lstat(fullname.c_str(), &statbuf) == 0
- && S_ISREG(statbuf.st_mode)
- )
- ) {
+ if (is_regular_file(dent, m_sDebugDumpDir.c_str()))
+ {
+ std::string fullname = m_sDebugDumpDir + "/" + dent->d_name;
+
pFileName = dent->d_name;
if (IsTextFile(fullname))
{
diff --git a/lib/Utils/xfuncs.cpp b/lib/Utils/xfuncs.cpp
index f447b8f4..d256c195 100644
--- a/lib/Utils/xfuncs.cpp
+++ b/lib/Utils/xfuncs.cpp
@@ -286,3 +286,22 @@ void xunlink(const char *pathname)
if (unlink(pathname))
perror_msg_and_die("can't remove file '%s'", pathname);
}
+
+/* Just testing dent->d_type == DT_REG is wrong: some filesystems
+ * do not report the type, they report DT_UNKNOWN for every dirent
+ * (and this is not a bug in filesystem, this is allowed by standards).
+ */
+int is_regular_file(struct dirent *dent, const char *dirname)
+{
+ if (dent->d_type == DT_REG)
+ return 1;
+ if (dent->d_type != DT_UNKNOWN)
+ return 0;
+
+ char *fullname = xasprintf("%s/%s", dirname, dent->d_name);
+ struct stat statbuf;
+ int r = lstat(fullname, &statbuf);
+ free(fullname);
+
+ return r == 0 && S_ISREG(statbuf.st_mode);
+}
diff --git a/src/Daemon/PluginManager.cpp b/src/Daemon/PluginManager.cpp
index 73d4dff0..4c1dae5c 100644
--- a/src/Daemon/PluginManager.cpp
+++ b/src/Daemon/PluginManager.cpp
@@ -133,8 +133,7 @@ void CPluginManager::LoadPlugins()
struct dirent *dent;
while ((dent = readdir(dir)) != NULL)
{
- // FIXME: need to handle DT_UNKNOWN too
- if (dent->d_type == DT_REG)
+ if (is_regular_file(dent, PLUGINS_LIB_DIR))
{
std::string name = dent->d_name;
std::string extension = name.substr(name.length() - sizeof(PLUGINS_LIB_EXTENSION) + 1);