mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-21 14:37:50 +00:00
vfs: GNU long file name support for tar
This commit is contained in:
parent
67869a697b
commit
89a9e88a7e
@ -72,24 +72,63 @@ class Vfs::Tar_file_system : public File_system
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char const *_data_begin() const { return (char const *)this + BLOCK_LEN; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GNU extension for long path names, which support unlimited sizes using
|
||||||
|
* separate records
|
||||||
|
*/
|
||||||
|
bool _long_name() const
|
||||||
|
{
|
||||||
|
return _type[0] == TYPE_LONG_LINK || _type[0] == TYPE_LONG_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Round up up next block
|
||||||
|
*/
|
||||||
|
file_size _block_align(file_size size) const {
|
||||||
|
return Genode::align_addr(size, BLOCK_SHIFT); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Next record header
|
||||||
|
*/
|
||||||
|
Record *_next() const {
|
||||||
|
return (Record *)(_data_begin() + _block_align(_read(_size))); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* length of on data block in tar */
|
/* length of one data block in tar */
|
||||||
enum { BLOCK_LEN = 512 };
|
enum {
|
||||||
|
BLOCK_SHIFT = 9, /* 512 bytes */
|
||||||
|
BLOCK_LEN = 1ul << BLOCK_SHIFT,
|
||||||
|
};
|
||||||
|
|
||||||
/* record type values */
|
/* record type values */
|
||||||
enum { TYPE_FILE = 0, TYPE_HARDLINK = 1,
|
enum {
|
||||||
TYPE_SYMLINK = 2, TYPE_DIR = 5 };
|
TYPE_FILE = 0, TYPE_HARDLINK = 1, TYPE_SYMLINK = 2, TYPE_DIR = 5,
|
||||||
|
/* GNU extensions */
|
||||||
|
TYPE_LONG_LINK = 75, TYPE_LONG_NAME = 76
|
||||||
|
};
|
||||||
|
|
||||||
file_size size() const { return _read(_size); }
|
file_size size() const { return _long_name() ? _next()->size() : _read(_size); }
|
||||||
unsigned uid() const { return _read(_uid); }
|
unsigned uid() const { return _long_name() ? _next()->uid() : _read(_uid); }
|
||||||
unsigned gid() const { return _read(_gid); }
|
unsigned gid() const { return _long_name() ? _next()->gid() : _read(_gid); }
|
||||||
unsigned mode() const { return _read(_mode); }
|
unsigned mode() const { return _long_name() ? _next()->mode() : _read(_mode); }
|
||||||
unsigned type() const { return _read(_type); }
|
unsigned type() const { return _long_name() ? _next()->type() : _read(_type); }
|
||||||
char const *name() const { return _name; }
|
void *data() const { return _long_name() ? _next()->data() : (void *)_data_begin(); }
|
||||||
char const *linked_name() const { return _linked_name; }
|
|
||||||
|
|
||||||
void *data() const { return (char *)this + BLOCK_LEN; }
|
char const *name() const { return _long_name() ? _data_begin() : _name; }
|
||||||
|
char const *linked_name() const { return _long_name() ? _data_begin() : _linked_name; }
|
||||||
|
|
||||||
|
file_size storage_size()
|
||||||
|
{
|
||||||
|
if (_long_name()) {
|
||||||
|
/* this size + next header + next size */
|
||||||
|
return _block_align(_read(_size)) + BLOCK_LEN + _block_align(_next()->size());
|
||||||
|
}
|
||||||
|
|
||||||
|
return _read(_size);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Node;
|
class Node;
|
||||||
@ -392,7 +431,7 @@ class Vfs::Tar_file_system : public File_system
|
|||||||
|
|
||||||
tar_record_action(record);
|
tar_record_action(record);
|
||||||
|
|
||||||
file_size size = record->size();
|
file_size size = record->storage_size();
|
||||||
|
|
||||||
/* some datablocks */ /* one metablock */
|
/* some datablocks */ /* one metablock */
|
||||||
block_id = block_id + (size / Record::BLOCK_LEN) + 1;
|
block_id = block_id + (size / Record::BLOCK_LEN) + 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user