diff options
-rw-r--r-- | inc/abrtlib.h | 7 | ||||
-rw-r--r-- | lib/Plugins/FileTransfer.cpp | 9 | ||||
-rw-r--r-- | lib/Utils/DebugDump.cpp | 14 | ||||
-rw-r--r-- | lib/Utils/xfuncs.cpp | 19 | ||||
-rw-r--r-- | src/Daemon/PluginManager.cpp | 3 |
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); |