diff --git a/headers/build/os/storage/MimeType.h b/headers/build/os/storage/MimeType.h index 130e8609ef..be527681e3 100644 --- a/headers/build/os/storage/MimeType.h +++ b/headers/build/os/storage/MimeType.h @@ -109,6 +109,11 @@ public: /* Deprecated Use SetTo instead. */ status_t SetType(const char *mimeType); + static status_t GuessMimeType(const entry_ref *file, BMimeType *type); + static status_t GuessMimeType(const void *buffer, int32 length, + BMimeType *type); + static status_t GuessMimeType(const char *filename, BMimeType *type); + private: BMimeType(const char *mimeType, const char *mimePath); // if mimePath is NULL, defaults to "/boot/home/config/settings/beos_mime/" diff --git a/headers/build/private/storage/mime/CreateAppMetaMimeThread.h b/headers/build/private/storage/mime/CreateAppMetaMimeThread.h index 02be36ba8f..acab27d886 100644 --- a/headers/build/private/storage/mime/CreateAppMetaMimeThread.h +++ b/headers/build/private/storage/mime/CreateAppMetaMimeThread.h @@ -18,8 +18,9 @@ namespace Mime { class CreateAppMetaMimeThread : public MimeUpdateThread { public: - CreateAppMetaMimeThread(const char *name, int32 priority, BMessenger managerMessenger, - const entry_ref *root, bool recursive, bool force, BMessage *replyee); + CreateAppMetaMimeThread(const char *name, int32 priority, + BMessenger managerMessenger, const entry_ref *root, bool recursive, + int32 force, BMessage *replyee); status_t DoMimeUpdate(const entry_ref *entry, bool *entryIsDir); }; diff --git a/headers/build/private/storage/mime/MimeUpdateThread.h b/headers/build/private/storage/mime/MimeUpdateThread.h index 3adad5c3c3..df9c33a734 100644 --- a/headers/build/private/storage/mime/MimeUpdateThread.h +++ b/headers/build/private/storage/mime/MimeUpdateThread.h @@ -11,7 +11,7 @@ #define _MIME_UPDATE_THREAD_H #include -#include +//#include #include #include @@ -24,21 +24,24 @@ namespace BPrivate { namespace Storage { namespace Mime { -class MimeUpdateThread : public RegistrarThread { +class MimeUpdateThread /*: public RegistrarThread*/ { public: - MimeUpdateThread(const char *name, int32 priority, BMessenger managerMessenger, - const entry_ref *root, bool recursive, bool force, BMessage *replyee); + MimeUpdateThread(const char *name, int32 priority, + BMessenger managerMessenger, const entry_ref *root, bool recursive, + int32 force, BMessage *replyee); virtual ~MimeUpdateThread(); virtual status_t InitCheck(); - + + status_t DoUpdate() { return ThreadFunction(); } + protected: virtual status_t ThreadFunction(); virtual status_t DoMimeUpdate(const entry_ref *entry, bool *entryIsDir) = 0; const entry_ref fRoot; const bool fRecursive; - const bool fForce; + const int32 fForce; BMessage *fReplyee; bool DeviceSupportsAttributes(dev_t device); diff --git a/headers/build/private/storage/mime/UpdateMimeInfoThread.h b/headers/build/private/storage/mime/UpdateMimeInfoThread.h index 6bae0b2624..9dd8183a85 100644 --- a/headers/build/private/storage/mime/UpdateMimeInfoThread.h +++ b/headers/build/private/storage/mime/UpdateMimeInfoThread.h @@ -18,8 +18,9 @@ namespace Mime { class UpdateMimeInfoThread : public MimeUpdateThread { public: - UpdateMimeInfoThread(const char *name, int32 priority, BMessenger managerMessenger, - const entry_ref *root, bool recursive, bool force, BMessage *replyee); + UpdateMimeInfoThread(const char *name, int32 priority, + BMessenger managerMessenger, const entry_ref *root, bool recursive, + int32 force, BMessage *replyee); status_t DoMimeUpdate(const entry_ref *entry, bool *entryIsDir); }; diff --git a/src/build/libbe/storage/Jamfile b/src/build/libbe/storage/Jamfile index ea6eb9b012..6f4133aa7a 100644 --- a/src/build/libbe/storage/Jamfile +++ b/src/build/libbe/storage/Jamfile @@ -5,6 +5,8 @@ UseHeaders [ FDirName $(HAIKU_TOP) headers build private app ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) headers build private kernel ] : true ; UseHeaders [ FDirName $(HAIKU_TOP) headers build private storage ] : true ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) mime ] ; + USES_BE_API on storage_kit.o = true ; BuildPlatformMergeObject storage_kit.o : @@ -13,6 +15,7 @@ BuildPlatformMergeObject storage_kit.o : Entry.cpp EntryList.cpp File.cpp + Mime.cpp MimeType.cpp Node.cpp NodeInfo.cpp @@ -27,4 +30,8 @@ BuildPlatformMergeObject storage_kit.o : SymLink.cpp Volume.cpp storage_support.cpp + + database_support.cpp + MimeUpdateThread.cpp + UpdateMimeInfoThread.cpp ; diff --git a/src/build/libbe/storage/Mime.cpp b/src/build/libbe/storage/Mime.cpp index b3d2bc6f8f..a77d91d5dd 100644 --- a/src/build/libbe/storage/Mime.cpp +++ b/src/build/libbe/storage/Mime.cpp @@ -7,65 +7,19 @@ Mime type C functions implementation. */ -#include -#include -#include -#include #include +#include #include #include #include +#include #include -#include -#include -#include #include #include using namespace BPrivate; -enum { - NOT_IMPLEMENTED = B_ERROR, -}; - -// do_mime_update -//! Helper function that contacts the registrar for mime update calls -status_t do_mime_update(int32 what, const char *path, int recursive, - int synchronous, int force) -{ - BEntry root; - entry_ref ref; - - status_t err = root.SetTo(path ? path : "/"); - if (!err) - err = root.GetRef(&ref); - if (!err) { - BMessage msg(what); - BMessage reply; - status_t result; - - // Build and send the message, read the reply - if (!err) - err = msg.AddRef("entry", &ref); - if (!err) - err = msg.AddBool("recursive", recursive); - if (!err) - err = msg.AddBool("synchronous", synchronous); - if (!err) - err = msg.AddBool("force", force); - if (!err) - err = BRoster::Private().SendTo(&msg, &reply, true); - if (!err) - err = reply.what == B_REG_RESULT ? B_OK : B_BAD_VALUE; - if (!err) - err = reply.FindInt32("result", &result); - if (!err) - err = result; - } - return err; -} - // update_mime_info /*! \brief Updates the MIME information (i.e MIME type) for one or more files. If \a path points to a file, the MIME information for this file are @@ -87,12 +41,17 @@ status_t do_mime_update(int32 what, const char *path, int recursive, int update_mime_info(const char *path, int recursive, int synchronous, int force) { - // Force recursion when given a NULL path if (!path) - recursive = true; + return B_BAD_VALUE; - return do_mime_update(B_REG_MIME_UPDATE_MIME_INFO, path, recursive, - synchronous, force); + entry_ref ref; + status_t error = get_ref_for_path(path, &ref); + if (error != B_OK) + return error; + + BPrivate::Storage::Mime::UpdateMimeInfoThread updater("MIME update thread", + B_NORMAL_PRIORITY, BMessenger(), &ref, recursive, force, NULL); + return updater.DoUpdate(); } // create_app_meta_mime @@ -115,96 +74,7 @@ status_t create_app_meta_mime(const char *path, int recursive, int synchronous, int force) { - // If path is NULL, we are recursive, otherwise no. - recursive = !path; - - return do_mime_update(B_REG_MIME_CREATE_APP_META_MIME, path, recursive, - synchronous, force); -} - -// get_device_icon -/*! Retrieves an icon associated with a given device. - \param dev The path to the device. - \param icon A pointer to a buffer the icon data shall be written to. - \param size The size of the icon. Currently the sizes 16 (small, i.e - \c B_MINI_ICON) and 32 (large, i.e. \c B_LARGE_ICON) are - supported. - - \todo The mounted directories for volumes can also have META:X:STD_ICON - attributes. Should those attributes override the icon returned - by ioctl(,B_GET_ICON,)? - - \return - - \c B_OK: Everything went fine. - - An error code otherwise. -*/ -status_t -get_device_icon(const char *dev, void *icon, int32 size) -{ - status_t err = dev && icon - && (size == B_LARGE_ICON || size == B_MINI_ICON) - ? B_OK : B_BAD_VALUE; - - int fd = -1; - - if (!err) { - fd = open(dev, O_RDONLY); - err = fd != -1 ? B_OK : B_BAD_VALUE; - } - if (!err) { - device_icon iconData = { size, icon }; - err = ioctl(fd, B_GET_ICON, &iconData); - } - if (fd != -1) { - // If the file descriptor was open()ed, we need to close it - // regardless. Only if we haven't yet encountered any errors - // do we make note close()'s return value, however. - status_t error = close(fd); - if (!err) - err = error; - } - return err; -} - -// get_device_icon -/*! Retrieves an icon associated with a given device. - \param dev The path to the device. - \param icon A pointer to a pre-allocated BBitmap of the correct dimension - to store the requested icon (16x16 for the mini and 32x32 for the - large icon). - \param which Specifies the size of the icon to be retrieved: - \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. - - \todo The mounted directories for volumes can also have META:X:STD_ICON - attributes. Should those attributes override the icon returned - by ioctl(,B_GET_ICON,)? - - \return - - \c B_OK: Everything went fine. - - An error code otherwise. -*/ -status_t -get_device_icon(const char *dev, BBitmap *icon, icon_size which) -{ - // check parameters - status_t error = (dev && icon ? B_OK : B_BAD_VALUE); - BRect rect; - if (error == B_OK) { - if (which == B_MINI_ICON) - rect.Set(0, 0, 15, 15); - else if (which == B_LARGE_ICON) - rect.Set(0, 0, 31, 31); - else - error = B_BAD_VALUE; - } - // check whether icon size and bitmap dimensions do match - if (error == B_OK - && (icon->Bounds() != rect || icon->ColorSpace() != B_CMAP8)) { - error = B_BAD_VALUE; - } - // get the icon - if (error == B_OK) - error = get_device_icon(dev, icon->Bits(), which); - return error; + // We don't have a MIME DB... + return B_OK; } diff --git a/src/build/libbe/storage/MimeType.cpp b/src/build/libbe/storage/MimeType.cpp index e454511789..067358899b 100644 --- a/src/build/libbe/storage/MimeType.cpp +++ b/src/build/libbe/storage/MimeType.cpp @@ -351,6 +351,72 @@ BMimeType::SetType(const char *mimeType) return SetTo(mimeType); } +// GuessMimeType +status_t +BMimeType::GuessMimeType(const entry_ref *ref, BMimeType *type) +{ + if (!ref || !type) + return B_BAD_VALUE; + + // get BEntry + BEntry entry; + status_t error = entry.SetTo(ref); + if (error != B_OK) + return error; + + // does entry exist? + if (!entry.Exists()) + return B_ENTRY_NOT_FOUND; + + // check entry type + if (entry.IsDirectory()) + return type->SetType("application/x-vnd.be-directory"); + if (entry.IsSymLink()) + return type->SetType("application/x-vnd.be-symlink"); + if (!entry.IsFile()) + return B_ERROR; + + // we have a file, read the first 4 bytes + BFile file; + char buffer[4]; + if (file.SetTo(ref, B_READ_ONLY) == B_OK + && file.Read(buffer, 4) == 4) { + return GuessMimeType(buffer, 4, type); + } + + // we couldn't open or read the file + return type->SetType(B_FILE_MIME_TYPE); +} + +// GuessMimeType +status_t +BMimeType::GuessMimeType(const void *_buffer, int32 length, BMimeType *type) +{ + const uint8 *buffer = (const uint8*)_buffer; + if (!buffer || !type) + return B_BAD_VALUE; + + // we only know ELF files + if (length >= 4 && buffer[0] == 0x7f && buffer[1] == 'E' && buffer[2] == 'L' + && buffer[3] == 'F') { + return type->SetType(B_ELF_APP_MIME_TYPE); + } + + return type->SetType(B_FILE_MIME_TYPE); +} + +// GuessMimeType +status_t +BMimeType::GuessMimeType(const char *filename, BMimeType *type) +{ + if (!filename || !type) + return B_BAD_VALUE; + + entry_ref ref; + status_t error = get_ref_for_path(filename, &ref); + return (error == B_OK ? GuessMimeType(&ref, type) : error); +} + void BMimeType::_ReservedMimeType1() {} void BMimeType::_ReservedMimeType2() {} void BMimeType::_ReservedMimeType3() {} diff --git a/src/build/libbe/storage/mime/MimeUpdateThread.cpp b/src/build/libbe/storage/mime/MimeUpdateThread.cpp index 6c7a296c3a..3343c1cd1a 100644 --- a/src/build/libbe/storage/mime/MimeUpdateThread.cpp +++ b/src/build/libbe/storage/mime/MimeUpdateThread.cpp @@ -45,8 +45,8 @@ namespace Mime { MimeUpdateThread::MimeUpdateThread(const char *name, int32 priority, BMessenger managerMessenger, const entry_ref *root, bool recursive, int32 force, BMessage *replyee) - : RegistrarThread(name, priority, managerMessenger) - , fRoot(root ? *root : entry_ref()) + : /*RegistrarThread(name, priority, managerMessenger) + ,*/ fRoot(root ? *root : entry_ref()) , fRecursive(recursive) , fForce(force) , fReplyee(replyee) @@ -74,10 +74,7 @@ MimeUpdateThread::~MimeUpdateThread() status_t MimeUpdateThread::InitCheck() { - status_t err = RegistrarThread::InitCheck(); - if (!err) - err = fStatus; - return err; + return fStatus; } // ThreadFunction @@ -92,7 +89,7 @@ MimeUpdateThread::ThreadFunction() // Do the updates if (!err) err = UpdateEntry(&fRoot); - // Send a reply if we have a message to reply to +/* // Send a reply if we have a message to reply to if (fReplyee) { BMessage reply(B_REG_RESULT); status_t error = reply.AddInt32("result", err); @@ -112,7 +109,7 @@ MimeUpdateThread::ThreadFunction() } DBG(OUT("(id: %ld) exiting mime update thread with result 0x%lx\n", find_thread(NULL), err)); - return err; +*/ return err; } // DeviceSupportsAttributes @@ -132,34 +129,7 @@ MimeUpdateThread::ThreadFunction() bool MimeUpdateThread::DeviceSupportsAttributes(dev_t device) { - // See if an entry for this device already exists - std::list< std::pair >::iterator i; - for (i = fAttributeSupportList.begin(); - i != fAttributeSupportList.end(); - i++) - { - if (i->first == device) - return i->second; - } - - bool result = false; - - // If we get here, no such device is yet in our list, - // so we attempt to remedy the situation - BVolume volume; - status_t err = volume.SetTo(device); - if (!err) { - result = volume.KnowsAttr(); - // devices supporting attributes are likely to be queried - // again, devices not supporting attributes are not - std::pair p(device, result); - if (result) - fAttributeSupportList.push_front(p); - else - fAttributeSupportList.push_back(p); - } - - return result; + return true; } // UpdateEntry @@ -173,8 +143,8 @@ MimeUpdateThread::UpdateEntry(const entry_ref *ref) bool entryIsDir = false; // Look to see if we're being terminated - if (!err && fShouldExit) - err = B_CANCELED; +// if (!err && fShouldExit) +// err = B_CANCELED; // Before we update, make sure this entry lives on a device that supports // attributes. If not, we skip it and any of its children for diff --git a/src/build/libbe/storage/mime/database_support.cpp b/src/build/libbe/storage/mime/database_support.cpp index 84f2845fd0..cbfe084b89 100644 --- a/src/build/libbe/storage/mime/database_support.cpp +++ b/src/build/libbe/storage/mime/database_support.cpp @@ -39,6 +39,8 @@ namespace BPrivate { namespace Storage { namespace Mime { +#if 0 + static const char *get_user_settings_dir(BPath &path); static BPath sSettingsDirPath; @@ -52,6 +54,8 @@ const std::string kDatabaseDir = sSettingsDir + "/" + (is_running_on_haiku() ? sHaikuDBDirName : sBeOSDBDirName); const std::string kApplicationDatabaseDir = kDatabaseDir + "/application"; +#endif // 0 + #define ATTR_PREFIX "META:" #define MINI_ICON_ATTR_PREFIX ATTR_PREFIX "M:" #define LARGE_ICON_ATTR_PREFIX ATTR_PREFIX "L:" @@ -104,6 +108,8 @@ const char *kMetaMimeType = "application/x-vnd.Be-meta-mime"; // Error codes const status_t kMimeGuessFailureError = B_ERRORS_END+1; +#if 0 + // get_settings_dir /*! \brief Sets the supplied BPath to the user settings directory and returns it as C string. @@ -369,6 +375,7 @@ delete_attribute(const char *type, const char *attr) return err; } +#endif // 0 } // namespace Mime