/** Get mime-type of file given by file descriptor. * This function gives a brief mime-type for the given file. * @param fd file descriptor of open file, make sure the file descriptor is rewinded. * Warning, the file descriptor is closed by the underlying libmagic. Use dup() to * duplicate it and pass this as file descriptor if you need the file afterwards. * @return descriptive string */ std::string mimetype_file(int fd) { std::string rv; #ifdef HAVE_LIBMAGIC # ifdef MAGIC_MIME_TYPE magic_t m = magic_open( MAGIC_ERROR | MAGIC_MIME_TYPE ); # else magic_t m = magic_open( MAGIC_ERROR | MAGIC_MIME ); # endif magic_load( m, NULL ); const char * res = magic_descriptor( m, fd ); if ( res == NULL ) { fawkes::Exception e("Failed to determine mime type of descriptor: %s", magic_error(m)); magic_close(m); throw e; } rv = res; # ifndef MAGIC_MIME_TYPE rv = rv.substr(0, rv.find(",")); # endif magic_close(m); #else throw fawkes::Exception("Failed to determine file type " "(libmagic not available at compile time)"); #endif return rv; }
/** Get filetype of file given by file descriptor. * Returns a long decriptive string of the filetype, similar to the file * console utility. * @param fd file descriptor of open file, make sure the file descriptor is rewinded * Warning, the file descriptor is closed by the underlying libmagic. Use dup() to * duplicate it and pass this as file descriptor if you need the file afterwards. * @return descriptive string */ std::string filetype_file(int fd) { std::string rv; #ifdef HAVE_LIBMAGIC magic_t m = magic_open( MAGIC_ERROR ); magic_load( m, NULL ); const char * res = magic_descriptor( m, fd ); if ( res == NULL ) { fawkes::Exception e("Failed to determine file type of descriptor: %s", magic_error(m)); magic_close(m); throw e; } rv = res; magic_close( m ); #else throw fawkes::Exception("Failed to determine file type " "(libmagic not available at compile time)"); #endif return rv; }
R_API const char *r_magic_descriptor(RMagic* m, int fd) { return magic_descriptor (m, fd); }
const char *Spider::DetectMimeType(const std::string &path) { int smb_fd = smbc_open(path.c_str(), O_RDONLY, 0); if (UNLIKELY(smb_fd < 0)) { if (LIKELY(errno == EISDIR)) return "inode/directory"; DetectError(); MSS_ERROR(("smbc_open " + path).c_str(), error_); return "unknown"; } // Extract name of the file // Don't detele '/' symbol it need to form path. std::string name(path, path.rfind("/")); // Create a storage for file header in TMPDIR and open it int fd = open((TMPDIR + name).c_str(), O_CREAT | O_RDWR | O_EXCL, 00744 /* rwxr--r-- */); if (UNLIKELY(fd == -1)) { if (LIKELY(errno = ENOTDIR)) { // TODO(yulyugin): Check if TMPDIR doesn't exists create it. } DetectError(); MSS_ERROR("open", error_); if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } return "unknown"; } void *buf = malloc(HEADERSIZE); // Buffer to store header. // Copy file header to TMPDIR if (UNLIKELY(smbc_read(smb_fd, buf, HEADERSIZE) < 0)) { DetectError(); MSS_ERROR("smbc_read", error_); if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } if (UNLIKELY(close(fd))) { DetectError(); MSS_ERROR("close", error_); } free(buf); return "unknown"; } if (UNLIKELY(write(fd, buf, HEADERSIZE) < 0)) { DetectError(); MSS_ERROR("write", error_); if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } if (UNLIKELY(close(fd))) { DetectError(); MSS_ERROR("close", error_); } free(buf); return "unknown"; } // Move to the begining of the file if (UNLIKELY(lseek(fd, 0, SEEK_SET) != 0)) { DetectError(); MSS_ERROR("lseek", error_); if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } if (UNLIKELY(close(fd))) { DetectError(); MSS_ERROR("close", error_); } free(buf); return "unknown"; } const char *mime_type = magic_descriptor(cookie_, fd); if (UNLIKELY(mime_type == NULL)) { error_ = magic_errno(cookie_); MSS_ERROR("magic_descriptor", error_); if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } if (UNLIKELY(close(fd))) { DetectError(); MSS_ERROR("close", error_); } free(buf); return "unknown"; } if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } free(buf); // Remove temporary file. if (UNLIKELY(unlink((TMPDIR + name).c_str()))) { DetectError(); MSS_ERROR("unlink", error_); } return mime_type; }