1 /* 2 * Copyright 2002-2006, Haiku Inc. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Tyler Dauwalder 7 * Ingo Weinhold, bonefish@users.sf.net 8 */ 9 10 /*! 11 \file Mime.cpp 12 Mime type C functions implementation. 13 */ 14 15 #include <fs_attr.h> 16 #include <fs_info.h> 17 #include <Bitmap.h> 18 #include <Drivers.h> 19 #include <Entry.h> 20 #include <Mime.h> 21 #include <MimeType.h> 22 #include <mime/database_access.h> 23 #include <Node.h> 24 #include <RegistrarDefs.h> 25 #include <Roster.h> 26 #include <RosterPrivate.h> 27 28 #include <unistd.h> 29 #include <sys/ioctl.h> 30 31 using namespace BPrivate; 32 33 enum { 34 NOT_IMPLEMENTED = B_ERROR, 35 }; 36 37 // do_mime_update 38 //! Helper function that contacts the registrar for mime update calls 39 status_t 40 do_mime_update(int32 what, const char *path, int recursive, 41 int synchronous, int force) 42 { 43 BEntry root; 44 entry_ref ref; 45 46 status_t err = root.SetTo(path ? path : "/"); 47 if (!err) 48 err = root.GetRef(&ref); 49 if (!err) { 50 BMessage msg(what); 51 BMessage reply; 52 status_t result; 53 54 // Build and send the message, read the reply 55 if (!err) 56 err = msg.AddRef("entry", &ref); 57 if (!err) 58 err = msg.AddBool("recursive", recursive); 59 if (!err) 60 err = msg.AddBool("synchronous", synchronous); 61 if (!err) 62 err = msg.AddInt32("force", force); 63 if (!err) 64 err = BRoster::Private().SendTo(&msg, &reply, true); 65 if (!err) 66 err = reply.what == B_REG_RESULT ? B_OK : B_BAD_VALUE; 67 if (!err) 68 err = reply.FindInt32("result", &result); 69 if (!err) 70 err = result; 71 } 72 return err; 73 } 74 75 // update_mime_info 76 /*! \brief Updates the MIME information (i.e MIME type) for one or more files. 77 If \a path points to a file, the MIME information for this file are 78 updated only. If it points to a directory and \a recursive is non-null, 79 the information for all the files in the given directory tree are updated. 80 If path is \c NULL all files are considered; \a recursive is ignored in 81 this case. 82 \param path The path to a file or directory, or \c NULL. 83 \param recursive Non-null to trigger recursive behavior. 84 \param synchronous If non-null update_mime_info() waits until the 85 operation is finished, otherwise it returns immediately and the 86 update is done asynchronously. 87 \param force Specifies how to handle files that already have MIME 88 information: 89 - \c B_UPDATE_MIME_INFO_NO_FORCE: Files that already have a 90 \c BEOS:TYPE attribute won't be updated. 91 - \c B_UPDATE_MIME_INFO_FORCE_KEEP_TYPE: Files that already have a 92 \c BEOS:TYPE attribute will be updated too, but \c BEOS:TYPE 93 itself will remain untouched. 94 - \c B_UPDATE_MIME_INFO_FORCE_UPDATE_ALL: Similar to 95 \c B_UPDATE_MIME_INFO_FORCE_KEEP_TYPE, but the \c BEOS:TYPE 96 attribute will be updated too. 97 \return 98 - \c B_OK: Everything went fine. 99 - An error code otherwise. 100 */ 101 int 102 update_mime_info(const char *path, int recursive, int synchronous, int force) 103 { 104 // Force recursion when given a NULL path 105 if (!path) 106 recursive = true; 107 108 return do_mime_update(B_REG_MIME_UPDATE_MIME_INFO, path, recursive, 109 synchronous, force); 110 } 111 112 // create_app_meta_mime 113 /*! Creates a MIME database entry for one or more applications. 114 \a path should either point to an application file or should be \c NULL. 115 In the first case a MIME database entry for that application is created, 116 in the second case entries for all applications are created. 117 \param path The path to an application file, or \c NULL. 118 \param recursive Currently unused. 119 \param synchronous If non-null create_app_meta_mime() waits until the 120 operation is finished, otherwise it returns immediately and the 121 operation is done asynchronously. 122 \param force If non-null, entries are created even if they do already 123 exist. 124 \return 125 - \c B_OK: Everything went fine. 126 - An error code otherwise. 127 */ 128 status_t 129 create_app_meta_mime(const char *path, int recursive, int synchronous, 130 int force) 131 { 132 // If path is NULL, we are recursive, otherwise no. 133 recursive = !path; 134 135 return do_mime_update(B_REG_MIME_CREATE_APP_META_MIME, path, recursive, 136 synchronous, force); 137 } 138 139 // get_device_icon 140 /*! Retrieves an icon associated with a given device. 141 \param dev The path to the device. 142 \param icon A pointer to a buffer the icon data shall be written to. 143 \param size The size of the icon. Currently the sizes 16 (small, i.e 144 \c B_MINI_ICON) and 32 (large, i.e. \c B_LARGE_ICON) are 145 supported. 146 147 \todo The mounted directories for volumes can also have META:X:STD_ICON 148 attributes. Should those attributes override the icon returned 149 by ioctl(,B_GET_ICON,)? 150 151 \return 152 - \c B_OK: Everything went fine. 153 - An error code otherwise. 154 */ 155 status_t 156 get_device_icon(const char *dev, void *icon, int32 size) 157 { 158 status_t err = dev && icon && (size == B_LARGE_ICON || size == B_MINI_ICON) 159 ? B_OK : B_BAD_VALUE; 160 161 int fd = -1; 162 163 if (!err) { 164 fd = open(dev, O_RDONLY); 165 err = fd != -1 ? B_OK : B_BAD_VALUE; 166 } 167 if (!err) { 168 device_icon iconData = { size, icon }; 169 err = ioctl(fd, B_GET_ICON, &iconData); 170 } 171 if (fd != -1) { 172 // If the file descriptor was open()ed, we need to close it 173 // regardless. Only if we haven't yet encountered any errors 174 // do we make note close()'s return value, however. 175 status_t error = close(fd); 176 if (!err) 177 err = error; 178 } 179 return err; 180 } 181 182 // get_device_icon 183 /*! Retrieves an icon associated with a given device. 184 \param dev The path to the device. 185 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 186 to store the requested icon (16x16 for the mini and 32x32 for the 187 large icon). 188 \param which Specifies the size of the icon to be retrieved: 189 \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. 190 191 \todo The mounted directories for volumes can also have META:X:STD_ICON 192 attributes. Should those attributes override the icon returned 193 by ioctl(,B_GET_ICON,)? 194 195 \return 196 - \c B_OK: Everything went fine. 197 - An error code otherwise. 198 */ 199 status_t 200 get_device_icon(const char *dev, BBitmap *icon, icon_size which) 201 { 202 // check parameters 203 status_t error = (dev && icon ? B_OK : B_BAD_VALUE); 204 BRect rect; 205 if (error == B_OK) { 206 if (which == B_MINI_ICON) 207 rect.Set(0, 0, 15, 15); 208 else if (which == B_LARGE_ICON) 209 rect.Set(0, 0, 31, 31); 210 else 211 error = B_BAD_VALUE; 212 } 213 // check whether icon size and bitmap dimensions do match 214 if (error == B_OK 215 && (icon->Bounds() != rect || icon->ColorSpace() != B_CMAP8)) { 216 error = B_BAD_VALUE; 217 } 218 // TODO: support bitmap with other color spaces! 219 // get the icon 220 if (error == B_OK) 221 error = get_device_icon(dev, icon->Bits(), which); 222 return error; 223 } 224 225