예제 #1
0
// StatAttr
status_t
FileHandle::StatAttr(const char* name, attr_info* info)
{
    if (fFD < 0)
        return B_BAD_VALUE;

    return (fs_stat_attr(fFD, name, info) == 0 ? B_OK : errno);
}
예제 #2
0
파일: Node.cpp 프로젝트: mmanley/Antares
/*!	\brief Fills in the pre-allocated attr_info struct pointed to by \a info
	with useful information about the attribute specified by \a name.
	\param name the name of the attribute
	\param info the attr_info structure to be filled in
	\return
	- \c B_OK: Everything went fine.
	- \c B_BAD_VALUE: \c NULL \a name
	- \c B_FILE_ERROR: The object is not initialized.
	- \c B_ENTRY_NOT_FOUND: The node has no attribute \a name.
*/
status_t
BNode::GetAttrInfo(const char *name, struct attr_info *info) const
{
	if (fCStatus != B_OK)
		return B_FILE_ERROR;
	if (!name || !info)
		return B_BAD_VALUE;
	return (fs_stat_attr(fFd, name, info) < 0) ? errno : B_OK ;
}
bool has_rfork_attribute(const char *file)
{
	int fd = open(file, O_RDONLY);
	if (fd < 0)
		return false;

	struct attr_info info;
	bool result = (fs_stat_attr(fd, ATTR_NAME, &info) == 0);

	close(fd);
	return result;
}
SDL_RWops *sdl_rw_from_rfork(const char *file, bool writable)
{
	SDL_RWops *rwops = NULL;

	int fd = open(file, writable ? O_RDWR : O_RDONLY);
	if (fd < 0) {
		SDL_SetError("Couldn't open %s", file);
		return NULL;
	} else {
		struct attr_info info;
		fs_stat_attr(fd, ATTR_NAME, &info);

		rwops = SDL_AllocRW();
		if (rwops == NULL) {
			close(fd);
			return NULL;
		}

		rfork_data *d = (rfork_data *)malloc(sizeof(struct rfork_data));
		if (d == NULL) {
			free(rwops);
			close(fd);
			return NULL;
		}

		d->fd = fd;
		d->current = 0;
		d->size = info.size;

		rwops->seek = rfork_seek;
		rwops->read = rfork_read;
		rwops->write = rfork_write;
		rwops->close = rfork_close;
		rwops->hidden.unknown.data1 = d;

		return rwops;
	}
}
예제 #5
0
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);
			}
		}
	}
}
예제 #6
0
파일: catattr.cpp 프로젝트: mmanley/Antares
static status_t
catAttr(const char *attribute, const char *fileName, bool keepRaw = false)
{
    int fd = open(fileName, O_RDONLY);
    if (fd < 0)
        return errno;

    attr_info info;
    if (fs_stat_attr(fd, attribute, &info) < 0)
        return errno;

    // limit size of the attribute, only the first 64k will make it on screen
    off_t size = info.size;
    bool cut = false;
    if (size > 64 * 1024) {
        size = 64 * 1024;
        cut = true;
    }

    char* buffer = (char*)malloc(size);
    if (!buffer) {
        fprintf(stderr, "Could not allocate read buffer!\n");
        return B_NO_MEMORY;
    }

    ssize_t bytesRead = fs_read_attr(fd, attribute, info.type, 0, buffer, size);
    if (bytesRead < 0) {
        free(buffer);
        return errno;
    }

    if (bytesRead != size) {
        fprintf(stderr, "Could only read %ld bytes from attribute!\n",
                bytesRead);
        free(buffer);
        return B_ERROR;
    }

    if (keepRaw) {
        off_t pos = 0;
        ssize_t written = 0;
        while (pos < info.size) {
            // write what we have read so far
            written = write(STDOUT_FILENO, buffer, bytesRead);
            // check for write error
            if (written < bytesRead) {
                if (written >= 0) {
                    fprintf(stderr, "Could only write %ld bytes to stream!\n",
                            written);
                    written = B_ERROR;
                } else {
                    fprintf(stderr, "Failed to write to stream: %s\n",
                            strerror(written));
                }
                break;
            }
            // read next chunk of data at pos
            pos += bytesRead;
            bytesRead = fs_read_attr(fd, attribute, info.type, pos, buffer,
                                     size);
            // check for read error
            if (bytesRead < size && pos + bytesRead < info.size) {
                if (bytesRead >= 0) {
                    fprintf(stderr, "Could only read %ld bytes from "
                            "attribute!\n", bytesRead);
                } else {
                    fprintf(stderr, "Failed to read from attribute: %s\n",
                            strerror(bytesRead));
                }
                written = B_ERROR;
                break;
            }
        }
        free(buffer);
        if (written > 0)
            written = B_OK;
        return written;
    }

    switch (info.type) {
    case B_INT8_TYPE:
        printf("%s : int8 : %d\n", fileName, *((int8 *)buffer));
        break;
    case B_UINT8_TYPE:
        printf("%s : uint8 : %u\n", fileName, *((uint8 *)buffer));
        break;
    case B_INT16_TYPE:
        printf("%s : int16 : %d\n", fileName, *((int16 *)buffer));
        break;
    case B_UINT16_TYPE:
        printf("%s : uint16 : %u\n", fileName, *((uint16 *)buffer));
        break;
    case B_INT32_TYPE:
        printf("%s : int32 : %ld\n", fileName, *((int32 *)buffer));
        break;
    case B_UINT32_TYPE:
        printf("%s : uint32 : %lu\n", fileName, *((uint32 *)buffer));
        break;
    case B_INT64_TYPE:
        printf("%s : int64 : %Ld\n", fileName, *((int64 *)buffer));
        break;
    case B_UINT64_TYPE:
        printf("%s : uint64 : %Lu\n", fileName, *((uint64 *)buffer));
        break;
    case B_FLOAT_TYPE:
        printf("%s : float : %f\n", fileName, *((float *)buffer));
        break;
    case B_DOUBLE_TYPE:
        printf("%s : double : %f\n", fileName, *((double *)buffer));
        break;
    case B_BOOL_TYPE:
        printf("%s : bool : %d\n", fileName, *((unsigned char *)buffer));
        break;
    case B_STRING_TYPE:
        printf("%s : string : %s\n", fileName, buffer);
        break;

    case B_MIME_STRING_TYPE:
    case 'MSIG':
    case 'MSDC':
    case 'MPTH':
        printf("%s : %s : %s\n", fileName, type_to_string(info.type),
               buffer);
        break;

    case B_MESSAGE_TYPE:
    {
        BMessage message;
        if (!cut && message.Unflatten(buffer) == B_OK) {
            printf("%s : message :\n", fileName);
            message.PrintToStream();
            break;
        }
        // supposed to fall through
    }

    default:
        // The rest of the attributes types are displayed as raw data
        printf("%s : %s : \n", fileName, type_to_string(info.type));
        dumpRawData(buffer, size);
        break;
    }

    free(buffer);
    return B_OK;
}