1 //---------------------------------------------------------------------- 2 // This software is part of the OpenBeOS distribution and is covered 3 // by the OpenBeOS license. 4 //--------------------------------------------------------------------- 5 /*! 6 \file UpdateMimeInfoThread.h 7 UpdateMimeInfoThread implementation 8 */ 9 10 #include "UpdateMimeInfoThread.h" 11 12 #include <stdlib.h> 13 #include <string.h> 14 15 #include <AppFileInfo.h> 16 #include <Bitmap.h> 17 #include <fs_attr.h> 18 #include <Message.h> 19 #include <MimeType.h> 20 #include <mime/database_support.h> 21 #include <Node.h> 22 23 namespace BPrivate { 24 namespace Storage { 25 namespace Mime { 26 27 static const char *kAppFlagsAttribute = "BEOS:APP_FLAGS"; 28 29 // update_icon 30 static status_t 31 update_icon(BAppFileInfo &appFileInfoRead, BAppFileInfo &appFileInfoWrite, 32 const char *type, BBitmap &icon, icon_size iconSize) 33 { 34 status_t err = appFileInfoRead.GetIconForType(type, &icon, iconSize); 35 if (err == B_OK) 36 err = appFileInfoWrite.SetIconForType(type, &icon, iconSize); 37 else if (err == B_ENTRY_NOT_FOUND) 38 err = appFileInfoWrite.SetIconForType(type, NULL, iconSize); 39 return err; 40 } 41 42 // update_icon 43 static status_t 44 update_icon(BAppFileInfo &appFileInfoRead, BAppFileInfo &appFileInfoWrite, 45 const char *type) 46 { 47 uint8* data = NULL; 48 size_t size = 0; 49 50 status_t err = appFileInfoRead.GetIconForType(type, &data, &size); 51 if (err == B_OK) 52 err = appFileInfoWrite.SetIconForType(type, data, size); 53 else if (err == B_ENTRY_NOT_FOUND) 54 err = appFileInfoWrite.SetIconForType(type, NULL, size); 55 56 free(data); 57 58 return err; 59 } 60 61 // is_shared_object_mime_type 62 static bool 63 is_shared_object_mime_type(BMimeType &type) 64 { 65 return (type == B_APP_MIME_TYPE); 66 } 67 68 69 // constructor 70 //! Creates a new UpdateMimeInfoThread object 71 UpdateMimeInfoThread::UpdateMimeInfoThread(const char *name, int32 priority, 72 Database *database, BMessenger managerMessenger, const entry_ref *root, 73 bool recursive, int32 force, BMessage *replyee) 74 : MimeUpdateThread(name, priority, database, managerMessenger, root, 75 recursive, force, replyee) 76 { 77 } 78 79 // DoMimeUpdate 80 /*! \brief Performs an update_mime_info() update on the given entry 81 82 If the entry has no \c BEOS:TYPE attribute, or if \c fForce is true, the 83 entry is sniffed and its \c BEOS:TYPE attribute is set accordingly. 84 */ 85 status_t 86 UpdateMimeInfoThread::DoMimeUpdate(const entry_ref *entry, bool *entryIsDir) 87 { 88 status_t err = entry ? B_OK : B_BAD_VALUE; 89 bool updateType = false; 90 bool updateAppInfo = false; 91 BNode node; 92 93 if (!err) 94 err = node.SetTo(entry); 95 if (!err && entryIsDir) 96 *entryIsDir = node.IsDirectory(); 97 if (!err) { 98 // If not forced, only update if the entry has no file type attribute 99 attr_info info; 100 if (fForce == B_UPDATE_MIME_INFO_FORCE_UPDATE_ALL 101 || node.GetAttrInfo(kFileTypeAttr, &info) == B_ENTRY_NOT_FOUND) { 102 updateType = true; 103 } 104 updateAppInfo = (updateType 105 || fForce == B_UPDATE_MIME_INFO_FORCE_KEEP_TYPE); 106 } 107 108 // guess the MIME type 109 BMimeType type; 110 if (!err && (updateType || updateAppInfo)) { 111 err = BMimeType::GuessMimeType(entry, &type); 112 if (!err) 113 err = type.InitCheck(); 114 } 115 116 // update the MIME type 117 if (!err && updateType) { 118 const char *typeStr = type.Type(); 119 ssize_t len = strlen(typeStr)+1; 120 ssize_t bytes = node.WriteAttr(kFileTypeAttr, kFileTypeType, 0, typeStr, 121 len); 122 if (bytes < B_OK) 123 err = bytes; 124 else 125 err = (bytes != len ? (status_t)B_FILE_ERROR : (status_t)B_OK); 126 } 127 128 // update the app file info attributes, if this is a shared object 129 BFile file; 130 BAppFileInfo appFileInfoRead; 131 BAppFileInfo appFileInfoWrite; 132 if (!err && updateAppInfo && node.IsFile() 133 && is_shared_object_mime_type(type) 134 && file.SetTo(entry, B_READ_WRITE) == B_OK 135 && appFileInfoRead.SetTo(&file) == B_OK 136 && appFileInfoWrite.SetTo(&file) == B_OK) { 137 138 // we read from resources and write to attributes 139 appFileInfoRead.SetInfoLocation(B_USE_RESOURCES); 140 appFileInfoWrite.SetInfoLocation(B_USE_ATTRIBUTES); 141 142 // signature 143 char signature[B_MIME_TYPE_LENGTH]; 144 err = appFileInfoRead.GetSignature(signature); 145 if (err == B_OK) 146 err = appFileInfoWrite.SetSignature(signature); 147 else if (err == B_ENTRY_NOT_FOUND) 148 err = appFileInfoWrite.SetSignature(NULL); 149 if (err != B_OK) 150 return err; 151 152 // catalog entry 153 char catalogEntry[B_MIME_TYPE_LENGTH * 3]; 154 err = appFileInfoRead.GetCatalogEntry(catalogEntry); 155 if (err == B_OK) 156 err = appFileInfoWrite.SetCatalogEntry(catalogEntry); 157 else if (err == B_ENTRY_NOT_FOUND) 158 err = appFileInfoWrite.SetCatalogEntry(NULL); 159 if (err != B_OK) 160 return err; 161 162 // app flags 163 uint32 appFlags; 164 err = appFileInfoRead.GetAppFlags(&appFlags); 165 if (err == B_OK) { 166 err = appFileInfoWrite.SetAppFlags(appFlags); 167 } else if (err == B_ENTRY_NOT_FOUND) { 168 file.RemoveAttr(kAppFlagsAttribute); 169 err = B_OK; 170 } 171 if (err != B_OK) 172 return err; 173 174 // supported types 175 BMessage supportedTypes; 176 bool hasSupportedTypes = false; 177 err = appFileInfoRead.GetSupportedTypes(&supportedTypes); 178 if (err == B_OK) { 179 err = appFileInfoWrite.SetSupportedTypes(&supportedTypes); 180 hasSupportedTypes = true; 181 } else if (err == B_ENTRY_NOT_FOUND) 182 err = appFileInfoWrite.SetSupportedTypes(NULL); 183 if (err != B_OK) 184 return err; 185 186 // vector icon 187 err = update_icon(appFileInfoRead, appFileInfoWrite, NULL); 188 if (err != B_OK) 189 return err; 190 191 // small icon 192 BBitmap smallIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, 193 B_CMAP8); 194 if (smallIcon.InitCheck() != B_OK) 195 return smallIcon.InitCheck(); 196 err = update_icon(appFileInfoRead, appFileInfoWrite, NULL, smallIcon, 197 B_MINI_ICON); 198 if (err != B_OK) 199 return err; 200 201 // large icon 202 BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, 203 B_CMAP8); 204 if (largeIcon.InitCheck() != B_OK) 205 return largeIcon.InitCheck(); 206 err = update_icon(appFileInfoRead, appFileInfoWrite, NULL, largeIcon, 207 B_LARGE_ICON); 208 if (err != B_OK) 209 return err; 210 211 // version infos 212 const version_kind versionKinds[] 213 = {B_APP_VERSION_KIND, B_SYSTEM_VERSION_KIND}; 214 for (int i = 0; i < 2; i++) { 215 version_kind kind = versionKinds[i]; 216 version_info versionInfo; 217 err = appFileInfoRead.GetVersionInfo(&versionInfo, kind); 218 if (err == B_OK) 219 err = appFileInfoWrite.SetVersionInfo(&versionInfo, kind); 220 else if (err == B_ENTRY_NOT_FOUND) 221 err = appFileInfoWrite.SetVersionInfo(NULL, kind); 222 if (err != B_OK) 223 return err; 224 } 225 226 // icons for supported types 227 if (hasSupportedTypes) { 228 const char *supportedType; 229 for (int32 i = 0; 230 supportedTypes.FindString("types", i, &supportedType) == B_OK; 231 i++) { 232 // vector icon 233 err = update_icon(appFileInfoRead, appFileInfoWrite, 234 supportedType); 235 if (err != B_OK) 236 return err; 237 238 // small icon 239 err = update_icon(appFileInfoRead, appFileInfoWrite, 240 supportedType, smallIcon, B_MINI_ICON); 241 if (err != B_OK) 242 return err; 243 244 // large icon 245 err = update_icon(appFileInfoRead, appFileInfoWrite, 246 supportedType, largeIcon, B_LARGE_ICON); 247 if (err != B_OK) 248 return err; 249 } 250 } 251 } 252 253 return err; 254 } 255 256 } // namespace Mime 257 } // namespace Storage 258 } // namespace BPrivate 259 260