static status_t GetDefaultGateway(BString& gateway) { // TODO: This method is here because BNetworkInterface // doesn't yet have any route getting methods int socket = ::socket(AF_INET, SOCK_DGRAM, 0); if (socket < 0) return errno; FileDescriptorCloser fdCloser(socket); // Obtain gateway ifconf config; config.ifc_len = sizeof(config.ifc_value); if (ioctl(socket, SIOCGRTSIZE, &config, sizeof(struct ifconf)) < 0) return errno; uint32 size = (uint32)config.ifc_value; if (size == 0) return B_ERROR; void* buffer = malloc(size); if (buffer == NULL) return B_NO_MEMORY; MemoryDeleter bufferDeleter(buffer); config.ifc_len = size; config.ifc_buf = buffer; if (ioctl(socket, SIOCGRTTABLE, &config, sizeof(struct ifconf)) < 0) return errno; ifreq* interface = (ifreq*)buffer; ifreq* end = (ifreq*)((uint8*)buffer + size); while (interface < end) { route_entry& route = interface->ifr_route; if ((route.flags & RTF_GATEWAY) != 0) { sockaddr_in* inetAddress = (sockaddr_in*)route.gateway; gateway = inet_ntoa(inetAddress->sin_addr); } int32 addressSize = 0; if (route.destination != NULL) addressSize += route.destination->sa_len; if (route.mask != NULL) addressSize += route.mask->sa_len; if (route.gateway != NULL) addressSize += route.gateway->sa_len; interface = (ifreq *)((addr_t)interface + IF_NAMESIZE + sizeof(route_entry) + addressSize); } return B_OK; }
/*static*/ PackageSettingsItem* PackageSettingsItem::Load(::Directory* systemDirectory, const char* name) { // open the driver settings file const char* settingsFilePath = kSystemSettingsDirectory "/packages" + strlen(kSystemDirectory) + 1; int fd = open_from(systemDirectory, settingsFilePath, B_READ_ONLY, 0); if (fd < 0) return NULL; FileDescriptorCloser fdCloser(fd); // load the driver settings void* settingsHandle = load_driver_settings_file(fd); if (settingsHandle == NULL) return NULL; CObjectDeleter<void, status_t> settingsDeleter(settingsHandle, &unload_driver_settings); const driver_settings* settings = get_driver_settings(settingsHandle); for (int i = 0; i < settings->parameter_count; i++) { const driver_parameter& parameter = settings->parameters[i]; if (strcmp(parameter.name, "Package") != 0 || parameter.value_count < 1 || strcmp(parameter.values[0], name) != 0) { continue; } PackageSettingsItem* settingsItem = new(std::nothrow) PackageSettingsItem; if (settingsItem == NULL || settingsItem->Init(parameter) != B_OK) { delete settingsItem; return NULL; } return settingsItem; } return NULL; }
void PackageWriter::_AddEntry(int dirFD, Entry* entry, const char* fileName) { printf("PackageWriter::_AddEntry(%d, %p, \"%s\")\n", dirFD, entry, fileName); bool isImplicitEntry = entry != NULL && entry->IsImplicit(); // open the node int fd = openat(dirFD, fileName, O_RDONLY | (isImplicitEntry ? 0 : O_NOTRAVERSE)); if (fd < 0) { fprintf(stderr, "Error: Failed to open entry \"%s\": %s\n", fileName, strerror(errno)); throw status_t(errno); } FDCloser fdCloser(fd); // stat the node struct stat st; if (fstat(fd, &st) < 0) { fprintf(stderr, "Error: Failed to fstat() file \"%s\": %s\n", fileName, strerror(errno)); throw status_t(errno); } // implicit entries must be directories if (isImplicitEntry && !S_ISDIR(st.st_mode)) { fprintf(stderr, "Error: Non-leaf path component \"%s\" is not a " "directory\n", fileName); throw status_t(B_BAD_VALUE); } // check/translate the node type uint8 fileType; uint32 defaultPermissions; if (S_ISREG(st.st_mode)) { fileType = B_HPKG_FILE_TYPE_FILE; defaultPermissions = B_HPKG_DEFAULT_FILE_PERMISSIONS; } else if (S_ISLNK(st.st_mode)) { fileType = B_HPKG_FILE_TYPE_SYMLINK; defaultPermissions = B_HPKG_DEFAULT_SYMLINK_PERMISSIONS; } else if (S_ISDIR(st.st_mode)) { fileType = B_HPKG_FILE_TYPE_DIRECTORY; defaultPermissions = B_HPKG_DEFAULT_DIRECTORY_PERMISSIONS; } else { // unsupported node type fprintf(stderr, "Error: Unsupported node type, entry: \"%s\"\n", fileName); throw status_t(B_UNSUPPORTED); } // add attribute entry Attribute* entryAttribute = _AddStringAttribute( B_HPKG_ATTRIBUTE_NAME_DIRECTORY_ENTRY, fileName); Stacker<Attribute> entryAttributeStacker(fTopAttribute, entryAttribute); // add stat data if (fileType != B_HPKG_DEFAULT_FILE_TYPE) _AddAttribute(B_HPKG_ATTRIBUTE_NAME_FILE_TYPE, fileType); if (defaultPermissions != uint32(st.st_mode & ALLPERMS)) { _AddAttribute(B_HPKG_ATTRIBUTE_NAME_FILE_PERMISSIONS, uint32(st.st_mode & ALLPERMS)); } _AddAttribute(B_HPKG_ATTRIBUTE_NAME_FILE_ATIME, uint32(st.st_atime)); _AddAttribute(B_HPKG_ATTRIBUTE_NAME_FILE_MTIME, uint32(st.st_mtime)); _AddAttribute(B_HPKG_ATTRIBUTE_NAME_FILE_CRTIME, uint32(st.st_crtime)); // TODO: File user/group! // add file data/symlink path if (S_ISREG(st.st_mode)) { // regular file -- add data if (st.st_size > 0) { FDDataReader dataReader(fd); status_t error = _AddData(dataReader, st.st_size); if (error != B_OK) throw status_t(error); } } else if (S_ISLNK(st.st_mode)) { // symlink -- add link address char path[B_PATH_NAME_LENGTH + 1]; ssize_t bytesRead = readlinkat(dirFD, fileName, path, B_PATH_NAME_LENGTH); if (bytesRead < 0) { fprintf(stderr, "Error: Failed to read symlink \"%s\": %s\n", fileName, strerror(errno)); throw status_t(errno); } path[bytesRead] = '\0'; _AddStringAttribute(B_HPKG_ATTRIBUTE_NAME_SYMLINK_PATH, path); } // add attributes if (DIR* attrDir = fs_fopen_attr_dir(fd)) { CObjectDeleter<DIR, int> attrDirCloser(attrDir, fs_close_attr_dir); while (dirent* entry = readdir(attrDir)) { attr_info attrInfo; if (fs_stat_attr(fd, entry->d_name, &attrInfo) < 0) { fprintf(stderr, "Error: Failed to stat attribute \"%s\" of " "file \"%s\": %s\n", entry->d_name, fileName, strerror(errno)); throw status_t(errno); } // create attribute entry Attribute* attributeAttribute = _AddStringAttribute( B_HPKG_ATTRIBUTE_NAME_FILE_ATTRIBUTE, entry->d_name); Stacker<Attribute> attributeAttributeStacker(fTopAttribute, attributeAttribute); // add type _AddAttribute(B_HPKG_ATTRIBUTE_NAME_FILE_ATTRIBUTE_TYPE, (uint32)attrInfo.type); // add data AttributeDataReader dataReader(fd, entry->d_name, attrInfo.type); status_t error = _AddData(dataReader, attrInfo.size); if (error != B_OK) throw status_t(error); } } if (S_ISDIR(st.st_mode)) { // directory -- recursively add children if (isImplicitEntry) { // this is an implicit entry -- just add it's children for (EntryList::ConstIterator it = entry->ChildIterator(); Entry* child = it.Next();) { _AddEntry(fd, child, child->Name()); } } else { // we need to clone the directory FD for fdopendir() int clonedFD = dup(fd); if (clonedFD < 0) { fprintf(stderr, "Error: Failed to dup() directory FD: %s\n", strerror(errno)); throw status_t(errno); } DIR* dir = fdopendir(clonedFD); if (dir == NULL) { fprintf(stderr, "Error: Failed to open directory \"%s\": %s\n", fileName, strerror(errno)); close(clonedFD); throw status_t(errno); } CObjectDeleter<DIR, int> dirCloser(dir, closedir); while (dirent* entry = readdir(dir)) { // skip "." and ".." if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { continue; } _AddEntry(fd, NULL, entry->d_name); } } } }