/* iterate over add-on-folders and collect information about each catalog-add-ons (types of catalogs) into fCatalogAddOnInfos. */ status_t LocaleRosterData::_InitializeCatalogAddOns() { BAutolock lock(fLock); if (!lock.IsLocked()) return B_ERROR; // add info about embedded default catalog: CatalogAddOnInfo* defaultCatalogAddOnInfo = new(std::nothrow) CatalogAddOnInfo("Default", "", DefaultCatalog::kDefaultCatalogAddOnPriority); if (!defaultCatalogAddOnInfo) return B_NO_MEMORY; defaultCatalogAddOnInfo->fInstantiateFunc = DefaultCatalog::Instantiate; defaultCatalogAddOnInfo->fCreateFunc = DefaultCatalog::Create; fCatalogAddOnInfos.AddItem((void*)defaultCatalogAddOnInfo); directory_which folders[] = { B_USER_ADDONS_DIRECTORY, B_COMMON_ADDONS_DIRECTORY, B_SYSTEM_ADDONS_DIRECTORY, }; BPath addOnPath; BDirectory addOnFolder; char buf[4096]; status_t err; for (uint32 f = 0; f < sizeof(folders) / sizeof(directory_which); ++f) { find_directory(folders[f], &addOnPath); BString addOnFolderName(addOnPath.Path()); addOnFolderName << "/locale/catalogs"; system_info info; if (get_system_info(&info) == B_OK && (info.abi & B_HAIKU_ABI_MAJOR) != (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR)) { switch (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR) { case B_HAIKU_ABI_GCC_2: addOnFolderName << "/gcc2"; break; case B_HAIKU_ABI_GCC_4: addOnFolderName << "/gcc4"; break; } } err = addOnFolder.SetTo(addOnFolderName.String()); if (err != B_OK) continue; // scan through all the folder's entries for catalog add-ons: int32 count; int8 priority; entry_ref eref; BNode node; BEntry entry; dirent* dent; while ((count = addOnFolder.GetNextDirents((dirent*)buf, 4096)) > 0) { dent = (dirent*)buf; while (count-- > 0) { if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && strcmp(dent->d_name, "gcc2") && strcmp(dent->d_name, "gcc4")) { // we have found (what should be) a catalog-add-on: eref.device = dent->d_pdev; eref.directory = dent->d_pino; eref.set_name(dent->d_name); entry.SetTo(&eref, true); // traverse through any links to get to the real thang! node.SetTo(&entry); priority = -1; if (node.ReadAttr(kPriorityAttr, B_INT8_TYPE, 0, &priority, sizeof(int8)) <= 0) { // add-on has no priority-attribute yet, so we load it // to fetch the priority from the corresponding // symbol... BString fullAddOnPath(addOnFolderName); fullAddOnPath << "/" << dent->d_name; image_id image = load_add_on(fullAddOnPath.String()); if (image >= B_OK) { uint8* prioPtr; if (get_image_symbol(image, "gCatalogAddOnPriority", B_SYMBOL_TYPE_DATA, (void**)&prioPtr) == B_OK) { priority = *prioPtr; node.WriteAttr(kPriorityAttr, B_INT8_TYPE, 0, &priority, sizeof(int8)); } unload_add_on(image); } } if (priority >= 0) { // add-ons with priority < 0 will be ignored CatalogAddOnInfo* addOnInfo = new(std::nothrow) CatalogAddOnInfo(dent->d_name, addOnFolderName, priority); if (addOnInfo) fCatalogAddOnInfos.AddItem((void*)addOnInfo); } } // Bump the dirent-pointer by length of the dirent just handled: dent = (dirent*)((char*)dent + dent->d_reclen); } } } fCatalogAddOnInfos.SortItems(CompareInfos); return B_OK; }
/* iterate over add-on-folders and collect information about each catalog-add-ons (types of catalogs) into fCatalogAddOnInfos. */ status_t LocaleRosterData::_InitializeCatalogAddOns() { BAutolock lock(fLock); if (!lock.IsLocked()) return B_ERROR; // add info about embedded default catalog: CatalogAddOnInfo* defaultCatalogAddOnInfo = new(std::nothrow) CatalogAddOnInfo("Default", "", DefaultCatalog::kDefaultCatalogAddOnPriority); if (!defaultCatalogAddOnInfo) return B_NO_MEMORY; defaultCatalogAddOnInfo->fInstantiateFunc = DefaultCatalog::Instantiate; defaultCatalogAddOnInfo->fCreateFunc = DefaultCatalog::Create; fCatalogAddOnInfos.AddItem((void*)defaultCatalogAddOnInfo); BStringList folders; BPathFinder::FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY, "locale/catalogs/", B_FIND_PATH_EXISTING_ONLY, folders); BPath addOnPath; BDirectory addOnFolder; char buf[4096]; status_t err; for (int32 f = 0; f < folders.CountStrings(); f++) { BString addOnFolderName = folders.StringAt(f); err = addOnFolder.SetTo(addOnFolderName.String()); if (err != B_OK) continue; // scan through all the folder's entries for catalog add-ons: int32 count; int8 priority; entry_ref eref; BNode node; BEntry entry; dirent* dent; while ((count = addOnFolder.GetNextDirents((dirent*)buf, sizeof(buf))) > 0) { dent = (dirent*)buf; while (count-- > 0) { if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0 && strcmp(dent->d_name, "x86") != 0 && strcmp(dent->d_name, "x86_gcc2") != 0) { // we have found (what should be) a catalog-add-on: eref.device = dent->d_pdev; eref.directory = dent->d_pino; eref.set_name(dent->d_name); entry.SetTo(&eref, true); // traverse through any links to get to the real thang! node.SetTo(&entry); priority = -1; if (node.ReadAttr(kPriorityAttr, B_INT8_TYPE, 0, &priority, sizeof(int8)) <= 0) { // add-on has no priority-attribute yet, so we load it // to fetch the priority from the corresponding // symbol... BString fullAddOnPath(addOnFolderName); fullAddOnPath << "/" << dent->d_name; image_id image = load_add_on(fullAddOnPath.String()); if (image >= B_OK) { uint8* prioPtr; if (get_image_symbol(image, "gCatalogAddOnPriority", B_SYMBOL_TYPE_DATA, (void**)&prioPtr) == B_OK) { priority = *prioPtr; node.WriteAttr(kPriorityAttr, B_INT8_TYPE, 0, &priority, sizeof(int8)); } unload_add_on(image); } } if (priority >= 0) { // add-ons with priority < 0 will be ignored CatalogAddOnInfo* addOnInfo = new(std::nothrow) CatalogAddOnInfo(dent->d_name, addOnFolderName, priority); if (addOnInfo) fCatalogAddOnInfos.AddItem((void*)addOnInfo); } } // Bump the dirent-pointer by length of the dirent just handled: dent = (dirent*)((char*)dent + dent->d_reclen); } } } fCatalogAddOnInfos.SortItems(CompareInfos); return B_OK; }
bool VirtualDirectoryPoseView::_EntryCreated(const BMessage* message) { NotOwningEntryRef entryRef; node_ref nodeRef; if (message->FindInt32("device", &nodeRef.device) != B_OK || message->FindInt64("node", &nodeRef.node) != B_OK || message->FindInt64("directory", &entryRef.directory) != B_OK || message->FindString("name", (const char**)&entryRef.name) != B_OK) { return true; } entryRef.device = nodeRef.device; // It might be one of our directories. BString path; if (message->FindString("path", &path) == B_OK && fDirectoryPaths.HasString(path)) { // Iterate through the directory and generate an entry-created message // for each entry. BDirectory directory; if (directory.SetTo(&nodeRef) != B_OK) return true; BPrivate::Storage::LongDirEntry entry; while (directory.GetNextDirents(&entry, sizeof(entry), 1) == 1) { if (strcmp(entry.d_name, ".") != 0 && strcmp(entry.d_name, "..") != 0) { _DispatchEntryCreatedOrRemovedMessage(B_ENTRY_CREATED, node_ref(entry.d_dev, entry.d_ino), NotOwningEntryRef(entry.d_pdev, entry.d_pino, entry.d_name), NULL, false); } } return true; } // See, if this entry actually becomes visible. If not, we can simply ignore // it. struct stat st; entry_ref visibleEntryRef; if (!_GetEntry(entryRef.name, visibleEntryRef, &st) || visibleEntryRef != entryRef) { return true; } // If it is a directory, translate it. VirtualDirectoryManager* manager = VirtualDirectoryManager::Instance(); AutoLocker<VirtualDirectoryManager> managerLocker(manager); bool entryTranslated = S_ISDIR(st.st_mode); if (entryTranslated) { if (manager == NULL) return true; if (manager->TranslateDirectoryEntry(*TargetModel()->NodeRef(), entryRef, nodeRef) != B_OK) { return true; } } // The entry might replace another entry. If it does, we'll fake a removed // message for the old one first. BPose* pose = fPoseList->FindPoseByFileName(entryRef.name); if (pose != NULL) { if (nodeRef == *pose->TargetModel()->NodeRef()) { // apparently not really a new entry -- can happen for // subdirectories return true; } // It may be a directory, so tell the manager. if (manager != NULL) manager->DirectoryRemoved(*pose->TargetModel()->NodeRef()); managerLocker.Unlock(); BMessage removedMessage(B_NODE_MONITOR); _DispatchEntryCreatedOrRemovedMessage(B_ENTRY_REMOVED, *pose->TargetModel()->NodeRef(), *pose->TargetModel()->EntryRef()); } else managerLocker.Unlock(); return entryTranslated ? (_DispatchEntryCreatedOrRemovedMessage(B_ENTRY_CREATED, nodeRef, entryRef), true) : _inherited::FSNotification(message); }
status_t BPackageRoster::GetActivePackages(BPackageInstallationLocation location, BPackageInfoSet& packageInfos) { // This method makes sense only on an installed Haiku, but not for the build // tools. #if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU) // check the given location directory_which packagesDirectory; switch (location) { case B_PACKAGE_INSTALLATION_LOCATION_SYSTEM: packagesDirectory = B_SYSTEM_PACKAGES_DIRECTORY; break; case B_PACKAGE_INSTALLATION_LOCATION_COMMON: packagesDirectory = B_COMMON_PACKAGES_DIRECTORY; break; case B_PACKAGE_INSTALLATION_LOCATION_HOME: packagesDirectory = B_USER_PACKAGES_DIRECTORY; break; default: return B_BAD_VALUE; } // find the package links directory BPath packageLinksPath; status_t error = find_directory(B_PACKAGE_LINKS_DIRECTORY, &packageLinksPath); if (error != B_OK) return error; // find and open the packages directory BPath packagesDirPath; error = find_directory(packagesDirectory, &packagesDirPath); if (error != B_OK) return error; BDirectory directory; error = directory.SetTo(packagesDirPath.Path()); if (error != B_OK) return error; // TODO: Implement that correctly be reading the activation files/directory! // iterate through the packages char buffer[sizeof(dirent) + B_FILE_NAME_LENGTH]; dirent* entry = (dirent*)&buffer; while (directory.GetNextDirents(entry, sizeof(buffer), 1) == 1) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; // get the full package file path BPath packagePath; error = packagePath.SetTo(packagesDirPath.Path(), entry->d_name); if (error != B_OK) continue; // read the package info from the file BPackageReader packageReader(NULL); error = packageReader.Init(packagePath.Path()); if (error != B_OK) continue; BPackageInfo info; BPackageInfoContentHandler handler(info); error = packageReader.ParseContent(&handler); if (error != B_OK || info.InitCheck() != B_OK) continue; // check whether the package is really active by verifying that a // package link exists for it BString packageLinkName(info.Name()); packageLinkName << '-' << info.Version().ToString(); BPath packageLinkPath; struct stat st; if (packageLinkPath.SetTo(packageLinksPath.Path(), packageLinkName) != B_OK || lstat(packageLinkPath.Path(), &st) != 0) { continue; } // add the info error = packageInfos.AddInfo(info); if (error != B_OK) return error; } return B_OK; #else return B_NOT_SUPPORTED; #endif }