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:
Ingo Weinhold
2006-01-28 22:00:16 +00:00
parent 58b53fd940
commit 15285cb04d
9 changed files with 121 additions and 191 deletions
+5
View File
@@ -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);
};
+7
View File
@@ -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
;
+13 -143
View File
@@ -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;
}
+66
View File
@@ -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