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