FUSE compat: add MIME type faking
* Add special handling for reading the BEOS:TYPE attribute to supply on-the-fly fake MIME types for FUSE module filesystems, the same way it's done in our FAT and NTFS FS modules * Reuse the mime_ext_table which we already have and put it into a shared location so we don't get further extra copies of it
This commit is contained in:
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
|
||||||
|
This file may be used under the terms of the Be Sample Code License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MIME_TYPES_H
|
||||||
|
#define MIME_TYPES_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern const char* kAttrMimeTypeName;
|
||||||
|
|
||||||
|
extern status_t set_mime(const char** mime, const char* filename);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
Copyright 1999-2001, Be Incorporated. All Rights Reserved.
|
||||||
|
This file may be used under the terms of the Be Sample Code License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <file_systems/mime_ext_table.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct ext_mime {
|
||||||
|
char *extension;
|
||||||
|
char *mime;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct ext_mime mimes[] = {
|
||||||
|
{ "gz", "application/x-gzip" },
|
||||||
|
{ "hqx", "application/x-binhex40" },
|
||||||
|
{ "lha", "application/x-lharc" },
|
||||||
|
{ "pcl", "application/x-pcl" },
|
||||||
|
{ "pdf", "application/pdf" },
|
||||||
|
{ "ps", "application/postscript" },
|
||||||
|
{ "sit", "application/x-stuff-it" },
|
||||||
|
{ "tar", "application/x-tar" },
|
||||||
|
{ "tgz", "application/x-gzip" },
|
||||||
|
{ "uue", "application/x-uuencode" },
|
||||||
|
{ "z", "application/x-compress" },
|
||||||
|
{ "zip", "application/zip" },
|
||||||
|
{ "zoo", "application/x-zoo" },
|
||||||
|
{ "rar", "application/x-rar" },
|
||||||
|
{ "pkg", "application/x-scode-UPkg" },
|
||||||
|
{ "7z", "application/x-7z-compressed" },
|
||||||
|
{ "bz2", "application/x-bzip2" },
|
||||||
|
{ "xz", "application/x-xz" },
|
||||||
|
|
||||||
|
{ "jar", "application/x-jar" },
|
||||||
|
|
||||||
|
{ "aif", "audio/x-aiff" },
|
||||||
|
{ "aiff", "audio/x-aiff" },
|
||||||
|
{ "au", "audio/basic" },
|
||||||
|
{ "mid", "audio/x-midi" },
|
||||||
|
{ "midi", "audio/x-midi" },
|
||||||
|
{ "mod", "audio/mod" },
|
||||||
|
{ "ra", "audio/x-real-audio" },
|
||||||
|
{ "wav", "audio/x-wav" },
|
||||||
|
{ "mp3", "audio/x-mpeg" },
|
||||||
|
{ "ogg", "audio/x-vorbis" },
|
||||||
|
{ "flac", "audio/x-flac" },
|
||||||
|
{ "wma", "audio/x-ms-wma" },
|
||||||
|
|
||||||
|
{ "avi", "video/x-msvideo" },
|
||||||
|
{ "mov", "video/quicktime" },
|
||||||
|
{ "qt", "video/quicktime" },
|
||||||
|
{ "mpg", "video/mpeg" },
|
||||||
|
{ "mpeg", "video/mpeg" },
|
||||||
|
{ "flv", "video/x-flv" },
|
||||||
|
{ "mp4", "video/mp4" },
|
||||||
|
{ "mkv", "video/x-matroska" },
|
||||||
|
{ "asf", "application/x-asf" },
|
||||||
|
{ "rm", "video/vnd.rn-realvideo" },
|
||||||
|
{ "wmv", "video/x-ms-wmv" },
|
||||||
|
|
||||||
|
{ "bmp", "image/x-bmp" },
|
||||||
|
{ "fax", "image/g3fax" },
|
||||||
|
{ "gif", "image/gif" },
|
||||||
|
{ "iff", "image/x-iff" },
|
||||||
|
{ "jpg", "image/jpeg" },
|
||||||
|
{ "jpeg", "image/jpeg" },
|
||||||
|
{ "pbm", "image/x-portable-bitmap" },
|
||||||
|
{ "pcx", "image/x-pcx" },
|
||||||
|
{ "pgm", "image/x-portable-graymap" },
|
||||||
|
{ "png", "image/png" },
|
||||||
|
{ "ppm", "image/x-portable-pixmap" },
|
||||||
|
{ "rgb", "image/x-rgb" },
|
||||||
|
{ "tga", "image/x-targa" },
|
||||||
|
{ "tif", "image/tiff" },
|
||||||
|
{ "tiff", "image/tiff" },
|
||||||
|
{ "xbm", "image/x-xbitmap" },
|
||||||
|
{ "djvu", "image/x-djvu" },
|
||||||
|
{ "svg", "image/svg+xml" },
|
||||||
|
{ "ico", "image/vnd.microsoft.icon" },
|
||||||
|
|
||||||
|
{ "doc", "application/msword" },
|
||||||
|
{ "xls", "application/vnd.ms-excel" },
|
||||||
|
{ "xls", "application/vnd.ms-excel" },
|
||||||
|
{ "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
|
||||||
|
{ "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
|
||||||
|
{ "ppt", "application/vnd.ms-powerpoint" },
|
||||||
|
{ "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
|
||||||
|
{ "chm", "application/x-chm" },
|
||||||
|
|
||||||
|
{ "txt", "text/plain" },
|
||||||
|
{ "xml", "text/plain" },
|
||||||
|
{ "htm", "text/html" },
|
||||||
|
{ "html", "text/html" },
|
||||||
|
{ "rtf", "text/rtf" },
|
||||||
|
{ "c", "text/x-source-code" },
|
||||||
|
{ "cc", "text/x-source-code" },
|
||||||
|
{ "c++", "text/x-source-code" },
|
||||||
|
{ "h", "text/x-source-code" },
|
||||||
|
{ "hh", "text/x-source-code" },
|
||||||
|
{ "hpp", "text/x-source-code" },
|
||||||
|
{ "cxx", "text/x-source-code" },
|
||||||
|
{ "cpp", "text/x-source-code" },
|
||||||
|
{ "S", "text/x-source-code" },
|
||||||
|
{ "java", "text/x-source-code" },
|
||||||
|
{ "ini", "text/plain" },
|
||||||
|
{ "inf", "text/plain" },
|
||||||
|
|
||||||
|
{ "ttf", "application/x-truetype" },
|
||||||
|
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const char* kAttrMimeTypeName = "BEOS:TYPE";
|
||||||
|
|
||||||
|
static const char* kFailBackMime = "application/octet-stream";
|
||||||
|
static const char* kDirectoryMime = "application/x-vnd.Be-directory";
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
set_mime(const char** mime, const char* filename)
|
||||||
|
{
|
||||||
|
struct ext_mime *p;
|
||||||
|
int32 namelen;
|
||||||
|
int32 ext_len;
|
||||||
|
*mime = NULL;
|
||||||
|
|
||||||
|
if (filename == NULL) {
|
||||||
|
*mime = kDirectoryMime;
|
||||||
|
return B_NO_ERROR;
|
||||||
|
}
|
||||||
|
namelen = strlen(filename);
|
||||||
|
|
||||||
|
for (p = mimes; p->extension; p++) {
|
||||||
|
ext_len = strlen(p->extension);
|
||||||
|
|
||||||
|
if (namelen <= ext_len)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (filename[namelen-ext_len-1] != '.')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!strcasecmp(filename + namelen - ext_len, p->extension))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(p->mime == NULL)
|
||||||
|
*mime = kFailBackMime;
|
||||||
|
else
|
||||||
|
*mime = p->mime;
|
||||||
|
|
||||||
|
return B_NO_ERROR;
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "FUSEVolume.h"
|
#include "FUSEVolume.h"
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <file_systems/mime_ext_table.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@@ -282,18 +283,22 @@ private:
|
|||||||
|
|
||||||
struct FUSEVolume::AttrCookie : RWLockable {
|
struct FUSEVolume::AttrCookie : RWLockable {
|
||||||
public:
|
public:
|
||||||
AttrCookie()
|
AttrCookie(const char* name)
|
||||||
:
|
:
|
||||||
fValue(NULL),
|
fValue(NULL),
|
||||||
fSize(0)
|
fSize(0),
|
||||||
|
fType(0)
|
||||||
{
|
{
|
||||||
|
_SetType(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
AttrCookie(const char* value)
|
AttrCookie(const char* name, const char* value)
|
||||||
:
|
:
|
||||||
fValue(strdup(value)),
|
fValue(strdup(value)),
|
||||||
fSize(strlen(value) + 1)
|
fSize(strlen(value) + 1),
|
||||||
|
fType(0)
|
||||||
{
|
{
|
||||||
|
_SetType(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
~AttrCookie()
|
~AttrCookie()
|
||||||
@@ -306,6 +311,11 @@ public:
|
|||||||
return fValue != NULL;
|
return fValue != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 Type() const
|
||||||
|
{
|
||||||
|
return fType;
|
||||||
|
}
|
||||||
|
|
||||||
status_t Allocate(size_t size)
|
status_t Allocate(size_t size)
|
||||||
{
|
{
|
||||||
fValue = (char*)malloc(size);
|
fValue = (char*)malloc(size);
|
||||||
@@ -341,9 +351,19 @@ public:
|
|||||||
return fSize;
|
return fSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _SetType(const char* name)
|
||||||
|
{
|
||||||
|
if (strcmp(name, kAttrMimeTypeName) == 0)
|
||||||
|
fType = B_MIME_STRING_TYPE;
|
||||||
|
else
|
||||||
|
fType = B_RAW_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char* fValue;
|
char* fValue;
|
||||||
size_t fSize;
|
size_t fSize;
|
||||||
|
uint32 fType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -2165,10 +2185,22 @@ FUSEVolume::OpenAttr(void* _node, const char* name, int openMode,
|
|||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
|
|
||||||
int attrSize = fuse_fs_getxattr(fFS, path, name, NULL, 0);
|
int attrSize = fuse_fs_getxattr(fFS, path, name, NULL, 0);
|
||||||
if (attrSize < 0)
|
if (attrSize < 0) {
|
||||||
return attrSize;
|
if (strcmp(name, kAttrMimeTypeName) == 0) {
|
||||||
|
// Return a fake MIME type attribute based on the file extension
|
||||||
|
const char* mimeType = NULL;
|
||||||
|
error = set_mime(&mimeType, S_ISDIR(node->type) ? NULL : &path[0]);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
*_cookie = new(std::nothrow)AttrCookie(name, mimeType);
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
AttrCookie* cookie = new(std::nothrow)AttrCookie();
|
// Reading attribute failed
|
||||||
|
return attrSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttrCookie* cookie = new(std::nothrow)AttrCookie(name);
|
||||||
error = cookie->Allocate(attrSize);
|
error = cookie->Allocate(attrSize);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
@@ -2227,7 +2259,7 @@ FUSEVolume::ReadAttrStat(void* _node, void* _cookie, struct stat* st)
|
|||||||
RETURN_ERROR(B_BAD_VALUE);
|
RETURN_ERROR(B_BAD_VALUE);
|
||||||
|
|
||||||
st->st_size = cookie->Size();
|
st->st_size = cookie->Size();
|
||||||
st->st_type = B_RAW_TYPE;
|
st->st_type = cookie->Type();
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,10 @@ SharedLibrary libuserlandfs_fuse.so
|
|||||||
fuse_opt.c
|
fuse_opt.c
|
||||||
FUSEFileSystem.cpp
|
FUSEFileSystem.cpp
|
||||||
FUSEVolume.cpp
|
FUSEVolume.cpp
|
||||||
|
mime_ext_table.c
|
||||||
:
|
:
|
||||||
<nogrist>userlandfs_server shared be [ TargetLibsupc++ ]
|
<nogrist>userlandfs_server shared be [ TargetLibsupc++ ]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
SEARCH on [ FGristFiles mime_ext_table.c ]
|
||||||
|
+= [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems shared ] ;
|
||||||
|
|||||||
Reference in New Issue
Block a user