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.AddBool("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 If non-null, also the information for files are updated that 82 have already been updated. 83 \return 84 - \c B_OK: Everything went fine. 85 - An error code otherwise. 86 */ 87 int 88 update_mime_info(const char *path, int recursive, int synchronous, int force) 89 { 90 // Force recursion when given a NULL path 91 if (!path) 92 recursive = true; 93 94 return do_mime_update(B_REG_MIME_UPDATE_MIME_INFO, path, recursive, 95 synchronous, force); 96 } 97 98 // create_app_meta_mime 99 /*! Creates a MIME database entry for one or more applications. 100 \a path should either point to an application file or should be \c NULL. 101 In the first case a MIME database entry for that application is created, 102 in the second case entries for all applications are created. 103 \param path The path to an application file, or \c NULL. 104 \param recursive Currently unused. 105 \param synchronous If non-null create_app_meta_mime() waits until the 106 operation is finished, otherwise it returns immediately and the 107 operation is done asynchronously. 108 \param force If non-null, entries are created even if they do already 109 exist. 110 \return 111 - \c B_OK: Everything went fine. 112 - An error code otherwise. 113 */ 114 status_t 115 create_app_meta_mime(const char *path, int recursive, int synchronous, 116 int force) 117 { 118 // If path is NULL, we are recursive, otherwise no. 119 recursive = !path; 120 121 return do_mime_update(B_REG_MIME_CREATE_APP_META_MIME, path, recursive, 122 synchronous, force); 123 } 124 125 // get_device_icon 126 /*! Retrieves an icon associated with a given device. 127 \param dev The path to the device. 128 \param icon A pointer to a buffer the icon data shall be written to. 129 \param size The size of the icon. Currently the sizes 16 (small, i.e 130 \c B_MINI_ICON) and 32 (large, i.e. \c B_LARGE_ICON) are 131 supported. 132 133 \todo The mounted directories for volumes can also have META:X:STD_ICON 134 attributes. Should those attributes override the icon returned 135 by ioctl(,B_GET_ICON,)? 136 137 \return 138 - \c B_OK: Everything went fine. 139 - An error code otherwise. 140 */ 141 status_t 142 get_device_icon(const char *dev, void *icon, int32 size) 143 { 144 status_t err = dev && icon 145 && (size == B_LARGE_ICON || size == B_MINI_ICON) 146 ? B_OK : B_BAD_VALUE; 147 148 int fd = -1; 149 150 if (!err) { 151 fd = open(dev, O_RDONLY); 152 err = fd != -1 ? B_OK : B_BAD_VALUE; 153 } 154 if (!err) { 155 device_icon iconData = { size, icon }; 156 err = ioctl(fd, B_GET_ICON, &iconData); 157 } 158 if (fd != -1) { 159 // If the file descriptor was open()ed, we need to close it 160 // regardless. Only if we haven't yet encountered any errors 161 // do we make note close()'s return value, however. 162 status_t error = close(fd); 163 if (!err) 164 err = error; 165 } 166 return err; 167 } 168 169 // get_device_icon 170 /*! Retrieves an icon associated with a given device. 171 \param dev The path to the device. 172 \param icon A pointer to a pre-allocated BBitmap of the correct dimension 173 to store the requested icon (16x16 for the mini and 32x32 for the 174 large icon). 175 \param which Specifies the size of the icon to be retrieved: 176 \c B_MINI_ICON for the mini and \c B_LARGE_ICON for the large icon. 177 178 \todo The mounted directories for volumes can also have META:X:STD_ICON 179 attributes. Should those attributes override the icon returned 180 by ioctl(,B_GET_ICON,)? 181 182 \return 183 - \c B_OK: Everything went fine. 184 - An error code otherwise. 185 */ 186 status_t 187 get_device_icon(const char *dev, BBitmap *icon, icon_size which) 188 { 189 // check parameters 190 status_t error = (dev && icon ? B_OK : B_BAD_VALUE); 191 BRect rect; 192 if (error == B_OK) { 193 if (which == B_MINI_ICON) 194 rect.Set(0, 0, 15, 15); 195 else if (which == B_LARGE_ICON) 196 rect.Set(0, 0, 31, 31); 197 else 198 error = B_BAD_VALUE; 199 } 200 // check whether icon size and bitmap dimensions do match 201 if (error == B_OK 202 && (icon->Bounds() != rect || icon->ColorSpace() != B_CMAP8)) { 203 error = B_BAD_VALUE; 204 } 205 // get the icon 206 if (error == B_OK) 207 error = get_device_icon(dev, icon->Bits(), which); 208 return error; 209 } 210 211