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