Remove update_mime_info() support from libbe_build

It was there only for <build>mimeset, which is now always invoked with a
custom MIME DB and thus won't use the function anymore. We could
actually easily implement it using MimeInfoUpdater, if the MIME DB
directory the build system generates was compiled in.
This commit is contained in:
Ingo Weinhold 2013-05-09 03:41:39 +02:00
parent 518840e305
commit bbd98073f9
4 changed files with 7 additions and 660 deletions

View File

@ -2,8 +2,6 @@ SubDir HAIKU_TOP src build libbe storage ;
UsePrivateBuildHeaders app kernel shared storage ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) mime ] ;
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits storage ] ;
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits storage mime ] ;
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits storage sniffer ] ;
@ -50,9 +48,6 @@ BuildPlatformMergeObjectPIC <libbe_build>storage_kit.o :
Supertype.cpp
SupportingApps.cpp
MimeUpdateThread.cpp
UpdateMimeInfoThread.cpp
# sniffer
CharStream.cpp
Err.cpp

View File

@ -1,77 +1,25 @@
/*
* Copyright 2002-2008, Haiku Inc.
* Copyright 2013, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tyler Dauwalder
* Ingo Weinhold, bonefish@users.sf.net
* Ingo Weinhold <ingo_weinhold@gmx.de>
*/
/*!
\file Mime.cpp
Mime type C functions implementation.
*/
#include <Mime.h>
#include <mime/UpdateMimeInfoThread.h>
using namespace BPrivate;
// 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
updated only. If it points to a directory and \a recursive is non-null,
the information for all the files in the given directory tree are updated.
If path is \c NULL all files are considered; \a recursive is ignored in
this case.
\param path The path to a file or directory, or \c NULL.
\param recursive Non-null to trigger recursive behavior.
\param synchronous If non-null update_mime_info() waits until the
operation is finished, otherwise it returns immediately and the
update is done asynchronously.
\param force If non-null, also the information for files are updated that
have already been updated.
\return
- \c B_OK: Everything went fine.
- An error code otherwise.
*/
int
update_mime_info(const char *path, int recursive, int synchronous, int force)
update_mime_info(const char* path, int recursive, int synchronous, int force)
{
if (!path)
return B_BAD_VALUE;
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();
return B_NOT_SUPPORTED;
}
// create_app_meta_mime
/*! Creates a MIME database entry for one or more applications.
\a path should either point to an application file or should be \c NULL.
In the first case a MIME database entry for that application is created,
in the second case entries for all applications are created.
\param path The path to an application file, or \c NULL.
\param recursive Currently unused.
\param synchronous If non-null create_app_meta_mime() waits until the
operation is finished, otherwise it returns immediately and the
operation is done asynchronously.
\param force If non-null, entries are created even if they do already
exist.
\return
- \c B_OK: Everything went fine.
- An error code otherwise.
*/
status_t
create_app_meta_mime(const char *path, int recursive, int synchronous,
create_app_meta_mime(const char* path, int recursive, int synchronous,
int force)
{
// We don't have a MIME DB...
return B_OK;
return B_NOT_SUPPORTED;
}

View File

@ -1,207 +0,0 @@
/*
* Copyright 2002-2006, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tyler Dauwalder
* Ingo Weinhold, bonefish@users.sf.net
*/
/*!
\file MimeUpdateThread.cpp
MimeUpdateThread implementation
*/
#include <stdio.h>
#include <Directory.h>
#include <Message.h>
#include <Path.h>
#include <RegistrarDefs.h>
#include <Volume.h>
#include <storage_support.h>
#include "mime/MimeUpdateThread.h"
//#define DBG(x) x
#define DBG(x)
#define OUT printf
namespace BPrivate {
namespace Storage {
#if (defined(__BEOS__) || defined(__HAIKU__))
// device_is_root_device
bool
device_is_root_device(dev_t device)
{
return device == 1;
}
#endif
namespace Mime {
/*! \class MimeUpdateThread
\brief RegistrarThread class implementing the common functionality of
update_mime_info() and create_app_meta_mime()
*/
// constructor
/*! \brief Creates a new MimeUpdateThread object.
If \a replyee is non-NULL and construction succeeds, the MimeThreadObject
assumes resposibility for its deletion.
Also, if \c non-NULL, \a replyee is expected to be a \c B_REG_MIME_UPDATE_MIME_INFO
or a \c B_REG_MIME_CREATE_APP_META_MIME message with a \c true \c "synchronous"
field detached from the registrar's mime manager looper (though this is not verified).
The message will be replied to at the end of the thread's execution.
*/
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())
, fRecursive(recursive)
, fForce(force)
, fReplyee(replyee)
, fStatus(root ? B_OK : B_BAD_VALUE)
{
}
// destructor
/*! \brief Destroys the MimeUpdateThread object.
If the object was properly initialized (i.e. InitCheck() returns \c B_OK) and
the replyee message passed to the constructor was \c non-NULL, the replyee
message is deleted.
*/
MimeUpdateThread::~MimeUpdateThread()
{
// delete our acquired BMessage
if (InitCheck() == B_OK)
delete fReplyee;
}
// InitCheck()
/*! \brief Returns the initialization status of the object
*/
status_t
MimeUpdateThread::InitCheck()
{
return fStatus;
}
// ThreadFunction
/*! \brief Implements the common functionality of update_mime_info() and
create_app_meta_mime(), namely iterating through the filesystem and
updating entries.
*/
status_t
MimeUpdateThread::ThreadFunction()
{
status_t err = InitCheck();
// Do the updates
if (!err)
err = UpdateEntry(&fRoot);
/* // 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);
err = error;
if (!err)
err = fReplyee->SendReply(&reply);
}
// Flag ourselves as finished
fIsFinished = true;
// Notify the thread manager to make a cleanup run
if (!err) {
BMessage msg(B_REG_MIME_UPDATE_THREAD_FINISHED);
status_t error = fManagerMessenger.SendMessage(&msg, (BHandler*)NULL, 500000);
if (error)
OUT("WARNING: ThreadManager::ThreadEntryFunction(): Termination notification "
"failed with error 0x%lx\n", error);
}
DBG(OUT("(id: %ld) exiting mime update thread with result 0x%lx\n",
find_thread(NULL), err));
*/ return err;
}
// DeviceSupportsAttributes
/*! \brief Returns true if the given device supports attributes, false
if not (or if an error occurs while determining).
Device numbers and their corresponding support info are cached in
a std::list to save unnecessarily \c statvfs()ing devices that have
already been statvfs()ed (which might otherwise happen quite often
for a device that did in fact support attributes).
\return
- \c true: The device supports attributes
- \c false: The device does not support attributes, or there was an
error while determining
*/
bool
MimeUpdateThread::DeviceSupportsAttributes(dev_t device)
{
return true;
}
// UpdateEntry
/*! \brief Updates the given entry and then recursively updates all the entry's child
entries if the entry is a directory and \c fRecursive is true.
*/
status_t
MimeUpdateThread::UpdateEntry(const entry_ref *ref)
{
status_t err = ref ? B_OK : B_BAD_VALUE;
bool entryIsDir = false;
// Look to see if we're being terminated
// 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
// updates (we don't signal an error, however).
//BPath path(ref);
//printf("Updating '%s' (%s)... \n", path.Path(),
// (DeviceSupportsAttributes(ref->device) ? "yes" : "no"));
if (!err
&& (device_is_root_device(ref->device)
|| DeviceSupportsAttributes(ref->device))) {
// Update this entry
if (!err)
err = DoMimeUpdate(ref, &entryIsDir);
// If we're recursing and this is a directory, update
// each of the directory's children as well
if (!err && fRecursive && entryIsDir) {
BDirectory dir;
err = dir.SetTo(ref);
if (!err) {
entry_ref childRef;
while (!err) {
err = dir.GetNextRef(&childRef);
if (err) {
// If we've come to the end of the directory listing,
// it's not an error.
if (err == B_ENTRY_NOT_FOUND)
err = B_OK;
break;
} else {
err = UpdateEntry(&childRef);
}
}
}
}
}
return err;
}
} // namespace Mime
} // namespace Storage
} // namespace BPrivate

View File

@ -1,389 +0,0 @@
/*
* Copyright 2002-2006, Haiku Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tyler Dauwalder
* Ingo Weinhold, bonefish@users.sf.net
*/
/*!
\file UpdateMimeInfoThread.h
UpdateMimeInfoThread implementation
*/
#include "mime/UpdateMimeInfoThread.h"
#include <AppFileInfo.h>
#include <Bitmap.h>
#include <fs_attr.h>
#include <Message.h>
#include <Messenger.h>
#include <mime/database_support.h>
#include <Node.h>
#include <Resources.h>
#include <String.h>
#if !defined(__BEOS__) || defined(__HAIKU__)
# include <MimeType.h>
#else
# define B_VECTOR_ICON_TYPE 'VICN'
#endif
#ifndef B_UPDATE_MIME_INFO_FORCE_UPDATE_ALL
# define B_UPDATE_MIME_INFO_FORCE_UPDATE_ALL 2
#endif
#ifndef B_UPDATE_MIME_INFO_FORCE_KEEP_TYPE
# define B_UPDATE_MIME_INFO_FORCE_KEEP_TYPE 1
#endif
#ifndef B_BITMAP_NO_SERVER_LINK
# define B_BITMAP_NO_SERVER_LINK 0
#endif
namespace BPrivate {
namespace Storage {
namespace Mime {
static const char *kAppFlagsAttribute = "BEOS:APP_FLAGS";
static status_t
update_icon(BAppFileInfo &appFileInfoRead, BAppFileInfo &appFileInfoWrite,
const char *type, BBitmap &icon, icon_size iconSize)
{
status_t err = appFileInfoRead.GetIconForType(type, &icon, iconSize);
if (err == B_OK)
err = appFileInfoWrite.SetIconForType(type, &icon, iconSize);
else if (err == B_ENTRY_NOT_FOUND || err == B_NAME_NOT_FOUND) {
err = appFileInfoWrite.SetIconForType(type, NULL, iconSize);
#if defined(__BEOS__) && !defined(__HAIKU__)
// gives an error if the attribute didn't exist yet...
err = B_OK;
#endif
}
return err;
}
/*!
This updates the vector icon of the file from its resources.
Instead of putting this functionality into BAppFileInfo (as done in Haiku),
we're doing it here, so that the mimeset executable that runs under BeOS
can make use of it as well.
*/
static status_t
update_vector_icon(BFile& file, const char *type)
{
// try to read icon from resources
BResources resources(&file);
BString name("BEOS:");
// check type param
if (type) {
if (BMimeType::IsValid(type))
name += type;
else
return B_BAD_VALUE;
} else
name += "ICON";
size_t size;
const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE, name.String(), &size);
if (data == NULL) {
// remove attribute; the resources don't have an icon
file.RemoveAttr(name.String());
return B_OK;
}
// update icon
ssize_t written = file.WriteAttr(name.String(), B_VECTOR_ICON_TYPE, 0, data, size);
if (written < B_OK)
return written;
if ((size_t)written < size) {
file.RemoveAttr(name.String());
return B_ERROR;
}
return B_OK;
}
#if defined(__BEOS__) || !defined(__HAIKU__)
// BMimeType::GuessMimeType() doesn't seem to work under BeOS
status_t
guess_mime_type(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);
}
status_t
guess_mime_type(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 guess_mime_type(buffer, 4, type);
}
// we couldn't open or read the file
return type->SetType(B_FILE_MIME_TYPE);
}
#endif
static bool
is_shared_object_mime_type(BMimeType &type)
{
return (type == B_APP_MIME_TYPE);
}
// #pragma mark -
//! Creates a new UpdateMimeInfoThread object
UpdateMimeInfoThread::UpdateMimeInfoThread(const char *name, int32 priority,
BMessenger managerMessenger, const entry_ref *root, bool recursive,
int32 force, BMessage *replyee)
: MimeUpdateThread(name, priority, managerMessenger, root, recursive, force,
replyee)
{
}
// DoMimeUpdate
/*! \brief Performs an update_mime_info() update on the given entry
If the entry has no \c BEOS:TYPE attribute, or if \c fForce is true, the
entry is sniffed and its \c BEOS:TYPE attribute is set accordingly.
*/
status_t
UpdateMimeInfoThread::DoMimeUpdate(const entry_ref *entry, bool *entryIsDir)
{
if (entry == NULL)
return B_BAD_VALUE;
bool updateType = false;
bool updateAppInfo = false;
BNode node;
status_t err = node.SetTo(entry);
if (!err && entryIsDir)
*entryIsDir = node.IsDirectory();
if (!err) {
// If not forced, only update if the entry has no file type attribute
attr_info info;
if (fForce == B_UPDATE_MIME_INFO_FORCE_UPDATE_ALL
|| node.GetAttrInfo(kFileTypeAttr, &info) == B_ENTRY_NOT_FOUND)
updateType = true;
updateAppInfo = updateType
|| fForce == B_UPDATE_MIME_INFO_FORCE_KEEP_TYPE;
}
// guess the MIME type
BMimeType type;
if (!err && (updateType || updateAppInfo)) {
err = BMimeType::GuessMimeType(entry, &type);
#if defined(__BEOS__) && !defined(__HAIKU__)
// GuessMimeType() doesn't seem to work correctly under BeOS
if (err)
err = guess_mime_type(entry, &type);
#endif
if (!err)
err = type.InitCheck();
}
// update the MIME type
if (!err && updateType) {
const char *typeStr = type.Type();
ssize_t len = strlen(typeStr) + 1;
ssize_t bytes = node.WriteAttr(kFileTypeAttr, kFileTypeType, 0,
typeStr, len);
if (bytes < B_OK)
err = bytes;
else
err = (bytes != len ? (status_t)B_FILE_ERROR : (status_t)B_OK);
}
// update the app file info attributes, if this is a shared object
BFile file;
BAppFileInfo appFileInfoRead;
BAppFileInfo appFileInfoWrite;
if (!err && updateAppInfo && node.IsFile()
&& is_shared_object_mime_type(type)
&& file.SetTo(entry, B_READ_WRITE) == B_OK
&& appFileInfoRead.SetTo(&file) == B_OK
&& appFileInfoWrite.SetTo(&file) == B_OK) {
// we read from resources and write to attributes
appFileInfoRead.SetInfoLocation(B_USE_RESOURCES);
appFileInfoWrite.SetInfoLocation(B_USE_ATTRIBUTES);
// signature
char signature[B_MIME_TYPE_LENGTH];
err = appFileInfoRead.GetSignature(signature);
if (err == B_OK)
err = appFileInfoWrite.SetSignature(signature);
else if (err == B_ENTRY_NOT_FOUND || err == B_NAME_NOT_FOUND || err == B_BAD_VALUE) {
// BeOS returns B_BAD_VALUE on shared libraries
err = appFileInfoWrite.SetSignature(NULL);
#if defined(__BEOS__) && !defined(__HAIKU__)
err = B_OK;
#endif
}
if (err != B_OK)
return err;
// catalog entry
char catalogEntry[B_MIME_TYPE_LENGTH * 3];
err = appFileInfoRead.GetCatalogEntry(catalogEntry);
if (err == B_OK)
err = appFileInfoWrite.SetCatalogEntry(catalogEntry);
else if (err == B_ENTRY_NOT_FOUND)
err = appFileInfoWrite.SetCatalogEntry(NULL);
if (err != B_OK)
return err;
// app flags
uint32 appFlags;
err = appFileInfoRead.GetAppFlags(&appFlags);
if (err == B_OK) {
err = appFileInfoWrite.SetAppFlags(appFlags);
} else if (err == B_ENTRY_NOT_FOUND || err == B_NAME_NOT_FOUND || err == B_BAD_VALUE) {
file.RemoveAttr(kAppFlagsAttribute);
err = B_OK;
}
if (err != B_OK)
return err;
// supported types
BMessage supportedTypes;
bool hasSupportedTypes = false;
err = appFileInfoRead.GetSupportedTypes(&supportedTypes);
if (err == B_OK) {
err = appFileInfoWrite.SetSupportedTypes(&supportedTypes);
hasSupportedTypes = true;
} else if (err == B_ENTRY_NOT_FOUND || err == B_NAME_NOT_FOUND || err == B_BAD_VALUE) {
#if defined(__BEOS__) && !defined(__HAIKU__)
file.RemoveAttr(kSupportedTypesAttr);
err = B_OK;
#else
err = appFileInfoWrite.SetSupportedTypes(NULL);
#endif
}
if (err != B_OK)
return err;
// vector icon
err = update_vector_icon(file, NULL);
if (err != B_OK)
return err;
// small icon
BBitmap smallIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK,
B_CMAP8);
if (smallIcon.InitCheck() != B_OK)
return smallIcon.InitCheck();
err = update_icon(appFileInfoRead, appFileInfoWrite, NULL, smallIcon,
B_MINI_ICON);
if (err != B_OK)
return err;
// large icon
BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK,
B_CMAP8);
if (largeIcon.InitCheck() != B_OK)
return largeIcon.InitCheck();
err = update_icon(appFileInfoRead, appFileInfoWrite, NULL, largeIcon,
B_LARGE_ICON);
if (err != B_OK)
return err;
// version infos
const version_kind versionKinds[]
= {B_APP_VERSION_KIND, B_SYSTEM_VERSION_KIND};
for (int i = 0; i < 2; i++) {
version_kind kind = versionKinds[i];
version_info versionInfo;
err = appFileInfoRead.GetVersionInfo(&versionInfo, kind);
if (err == B_OK)
err = appFileInfoWrite.SetVersionInfo(&versionInfo, kind);
else if (err == B_ENTRY_NOT_FOUND || err == B_NAME_NOT_FOUND || err == B_BAD_VALUE) {
#if !defined(HAIKU_HOST_PLATFORM_DANO) && !defined(HAIKU_HOST_PLATFORM_BEOS) && !defined(HAIKU_HOST_PLATFORM_BONE)
// BeOS crashes when calling SetVersionInfo() with a NULL pointer
err = appFileInfoWrite.SetVersionInfo(NULL, kind);
#else
err = B_OK;
#endif
}
if (err != B_OK)
return err;
}
// icons for supported types
if (hasSupportedTypes) {
const char *supportedType;
for (int32 i = 0;
supportedTypes.FindString("types", i, &supportedType) == B_OK;
i++) {
// vector icon
err = update_vector_icon(file, supportedType);
if (err != B_OK)
return err;
// small icon
err = update_icon(appFileInfoRead, appFileInfoWrite,
supportedType, smallIcon, B_MINI_ICON);
if (err != B_OK)
return err;
// large icon
err = update_icon(appFileInfoRead, appFileInfoWrite,
supportedType, largeIcon, B_LARGE_ICON);
if (err != B_OK)
return err;
}
}
}
return err;
}
} // namespace Mime
} // namespace Storage
} // namespace BPrivate