| 30 | static status_t |
| 31 | CopyData(BFile& srcFile, BFile& dstFile) |
| 32 | { |
| 33 | char buffer[4096]; |
| 34 | |
| 35 | while (true) { |
| 36 | ssize_t bytesRead = srcFile.Read(buffer, sizeof(buffer)); |
| 37 | if (bytesRead > 0) { |
| 38 | ssize_t bytesWritten = dstFile.Write(buffer, bytesRead); |
| 39 | if (bytesWritten < 0) |
| 40 | return bytesWritten; |
| 41 | } else if (bytesRead < 0) |
| 42 | return bytesRead; |
| 43 | else |
| 44 | break; |
| 45 | } |
| 46 | |
| 47 | return B_OK; |
| 48 | } |
| 49 | |
| 50 | |
| 51 | static status_t |
| 52 | CopyAttributes(BNode& srcNode, BNode& dstNode) |
| 53 | { |
| 54 | srcNode.RewindAttrs(); |
| 55 | char name[B_ATTR_NAME_LENGTH]; |
| 56 | while (srcNode.GetNextAttrName(name) == B_OK) { |
| 57 | attr_info info; |
| 58 | if (srcNode.GetAttrInfo(name, &info) == B_OK) { |
| 59 | char buffer[info.size]; |
| 60 | |
| 61 | ssize_t bytesRead = srcNode.ReadAttr(name, info.type, 0, buffer, info.size); |
| 62 | if (bytesRead > 0) { |
| 63 | ssize_t bytesWritten = dstNode.WriteAttr(name, info.type, 0, |
| 64 | buffer, info.size); |
| 65 | if (bytesWritten < 0) |
| 66 | return bytesWritten; |
| 67 | } else |
| 68 | return bytesRead; |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | return B_OK; |
| 73 | } |
| 74 | |
| 75 | |
| 76 | static status_t |
| 77 | CopyScreenSaver(BFile& srcFile, BFile& dstFile) |
| 78 | { |
| 79 | status_t status = CopyData(srcFile, dstFile); |
| 80 | if (status < B_OK) |
| 81 | return status; |
| 82 | |
| 83 | return CopyAttributes(srcFile, dstFile); |
| 84 | } |
| 85 | |
| 86 | |
| 103 | |
| 104 | // monitor the user's addons directory |
| 105 | BPath userAddonsScrDirPath; |
| 106 | status_t status = find_directory(B_USER_ADDONS_DIRECTORY, |
| 107 | &userAddonsScrDirPath); |
| 108 | if (status == B_OK) |
| 109 | status = userAddonsScrDirPath.Append("Screen Savers"); |
| 110 | |
| 111 | if (status < B_OK) { |
| 112 | BString errorMessage; |
| 113 | errorMessage << "At " << __PRETTY_FUNCTION__ << "\n"; |
| 114 | errorMessage << "find_directory() failed. \nReason: "; |
| 115 | errorMessage << strerror(status); |
| 116 | (new BAlert("AlertError", errorMessage.String(), "OK", NULL, NULL, |
| 117 | B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go(); |
| 118 | return; |
| 119 | } |
| 120 | |
| 121 | BEntry userAddonsScrDirEntry(userAddonsScrDirPath.Path()); |
| 122 | node_ref nodeRef; |
| 123 | userAddonsScrDirEntry.GetNodeRef(&nodeRef); |
| 124 | status = watch_node(&nodeRef, B_WATCH_DIRECTORY, this); |
| 125 | if (status != B_OK) |
| 126 | fprintf(stderr, "Could not start watching: %s\n", strerror(status)); |
61 | | // TODO: find_directory() anyone?? |
62 | | char temp[2*B_PATH_NAME_LENGTH]; |
63 | | sprintf(temp,"cp %s '/boot/home/config/add-ons/Screen Savers/'\n", path.Path()); |
64 | | system(temp); |
65 | | fScreenSaverWindow->PostMessage(kMsgUpdateList); |
| 160 | if (srcEntry.InitCheck() != B_OK) |
| 161 | return; |
| 162 | |
| 163 | BPath srcPath; |
| 164 | srcEntry.GetPath(&srcPath); |
| 165 | |
| 166 | if (srcEntry.IsDirectory()) { |
| 167 | BString errorMessage; |
| 168 | errorMessage << srcPath.Leaf() << " is a directory!\n"; |
| 169 | errorMessage << "You can not install a directory!"; |
| 170 | (new BAlert("AlertError", errorMessage.String(), "OK", NULL, NULL, |
| 171 | B_WIDTH_AS_USUAL, B_INFO_ALERT))->Go(); |
| 172 | return; |
| 173 | } |
| 174 | |
| 175 | BFile srcFile(srcPath.Path(), O_RDONLY); |
| 176 | if (srcFile.InitCheck() != B_OK) |
| 177 | return; |
| 178 | |
| 179 | // Check if the file in question is really a screensaver |
| 180 | |
| 181 | // First check for black-listed files: |
| 182 | // binary files that may crash the ScreenSaver pref. |
| 183 | // without being really screensavers, and the |
| 184 | // user may try to throw in the ScreenSaver pref. window |
| 185 | |
| 186 | BString blackListed1("libroot.so"); |
| 187 | BString blackListed2("runtime_loader"); |
| 188 | |
| 189 | BString candidateScr(srcPath.Leaf()); |
| 190 | |
| 191 | if (candidateScr == blackListed1 |
| 192 | || candidateScr == blackListed2) { |
| 193 | BString errorMessage; |
| 194 | errorMessage << "File " << srcPath.Leaf() << "\n"; |
| 195 | errorMessage << "is not a screensaver file!"; |
| 196 | (new BAlert("AlertError", errorMessage.String(), "OK", NULL, NULL, |
| 197 | B_WIDTH_AS_USUAL, B_INFO_ALERT))->Go(); |
| 198 | continue; |
| 199 | } |
| 200 | |
| 201 | |
| 202 | // Check all the other files |
| 203 | |
| 204 | image_id candidateScreenSaverId = load_add_on(srcPath.Path()); |
| 205 | if (candidateScreenSaverId < B_OK) { |
| 206 | BString errorMessage; |
| 207 | errorMessage << "File " << srcPath.Leaf() << "\n"; |
| 208 | errorMessage << "is not a screensaver file!"; |
| 209 | (new BAlert("AlertError", errorMessage.String(), "OK", NULL, NULL, |
| 210 | B_WIDTH_AS_USUAL, B_INFO_ALERT))->Go(); |
| 211 | |
| 212 | unload_add_on(candidateScreenSaverId); |
| 213 | continue; |
| 214 | } |
| 215 | |
| 216 | BScreenSaver* (*instantiate)(BMessage* msg, image_id image); |
| 217 | status_t getImageSymbolStatus = get_image_symbol(candidateScreenSaverId, |
| 218 | "instantiate_screen_saver", B_SYMBOL_TYPE_TEXT, (void**)&instantiate); |
| 219 | unload_add_on(candidateScreenSaverId); |
| 220 | |
| 221 | if (getImageSymbolStatus < B_OK) { |
| 222 | BString errorMessage; |
| 223 | errorMessage << "File " << srcPath.Leaf() << "\n"; |
| 224 | errorMessage << "is not a screensaver file!"; |
| 225 | (new BAlert("AlertError", errorMessage.String(), "OK", NULL, NULL, |
| 226 | B_WIDTH_AS_USUAL, B_INFO_ALERT))->Go(); |
| 227 | continue; |
| 228 | } |
| 229 | |
| 230 | BPath userNewScreenSaver; |
| 231 | status_t status = find_directory(B_USER_ADDONS_DIRECTORY, |
| 232 | &userNewScreenSaver); |
| 233 | if (status < B_OK) { |
| 234 | BString errorMessage; |
| 235 | errorMessage << "At " << __PRETTY_FUNCTION__ << "\n"; |
| 236 | errorMessage << "find_directory() failed. \nReason: "; |
| 237 | errorMessage << strerror(status); |
| 238 | (new BAlert("AlertError", errorMessage.String(), "OK", NULL, NULL, |
| 239 | B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go(); |
| 240 | return; |
| 241 | } |
| 242 | |
| 243 | userNewScreenSaver.Append("Screen Savers"); |
| 244 | userNewScreenSaver.Append(srcPath.Leaf()); |
| 245 | |
| 246 | BFile destFile(userNewScreenSaver.Path(), O_RDWR | O_CREAT); |
| 247 | if (destFile.InitCheck() != B_OK) |
| 248 | return; |
| 249 | |
| 250 | status = CopyScreenSaver(srcFile, destFile); |
| 251 | if (status < B_OK) { |
| 252 | BString errorMessage; |
| 253 | errorMessage << "At " << __PRETTY_FUNCTION__ << "\n"; |
| 254 | errorMessage << "Copying the screensaver file failed. \nReason: "; |
| 255 | errorMessage << strerror(status); |
| 256 | (new BAlert("AlertError", errorMessage.String(), "OK", NULL, NULL, |
| 257 | B_WIDTH_AS_USUAL, B_STOP_ALERT))->Go(); |
| 258 | return; |
| 259 | } |
| 260 | |
| 261 | fScreenSaverWindow->PostMessage(kMsgUpdateList); |
| 262 | } |