Good deal of hackery to get update_mime_info() to work on the host
platform to the extend we need it. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16129 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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/"
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#define _MIME_UPDATE_THREAD_H
|
||||
|
||||
#include <Entry.h>
|
||||
#include <RegistrarThread.h>
|
||||
//#include <RegistrarThread.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <list>
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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 <libbe_build>storage_kit.o = true ;
|
||||
|
||||
BuildPlatformMergeObject <libbe_build>storage_kit.o :
|
||||
@@ -13,6 +15,7 @@ BuildPlatformMergeObject <libbe_build>storage_kit.o :
|
||||
Entry.cpp
|
||||
EntryList.cpp
|
||||
File.cpp
|
||||
Mime.cpp
|
||||
MimeType.cpp
|
||||
Node.cpp
|
||||
NodeInfo.cpp
|
||||
@@ -27,4 +30,8 @@ BuildPlatformMergeObject <libbe_build>storage_kit.o :
|
||||
SymLink.cpp
|
||||
Volume.cpp
|
||||
storage_support.cpp
|
||||
|
||||
database_support.cpp
|
||||
MimeUpdateThread.cpp
|
||||
UpdateMimeInfoThread.cpp
|
||||
;
|
||||
|
||||
@@ -7,65 +7,19 @@
|
||||
Mime type C functions implementation.
|
||||
*/
|
||||
|
||||
#include <fs_attr.h>
|
||||
#include <fs_info.h>
|
||||
#include <Bitmap.h>
|
||||
#include <Drivers.h>
|
||||
#include <Entry.h>
|
||||
#include <Messenger.h>
|
||||
#include <Mime.h>
|
||||
#include <MimeType.h>
|
||||
#include <mime/database_access.h>
|
||||
#include <mime/UpdateMimeInfoThread.h>
|
||||
#include <Node.h>
|
||||
#include <RegistrarDefs.h>
|
||||
#include <Roster.h>
|
||||
#include <RosterPrivate.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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<dev_t,bool> >::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<dev_t,bool> 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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user