Fix mkinitrd and initrdfs endian issues.

This commit is contained in:
Jonas 'Sortie' Termansen 2015-01-19 16:27:52 +01:00
parent 8743a0d4f9
commit 69159d275f
5 changed files with 160 additions and 9 deletions

View File

@ -17,8 +17,8 @@ all: $(BINARIES)
.PHONY: all install clean
%: %.cpp crc32.cpp rules.cpp
$(CXX) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) $< crc32.cpp rules.cpp -o $@
%: %.cpp crc32.cpp rules.cpp serialize.cpp
$(CXX) -std=gnu++11 $(CPPFLAGS) $(CXXFLAGS) $< crc32.cpp rules.cpp serialize.cpp -o $@
clean:
rm -f $(BINARIES)

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2015.
This file is part of Sortix.
@ -35,6 +35,7 @@
#include <sortix/initrd.h>
#include "crc32.h"
#include "serialize.h"
char* Substring(const char* str, size_t start, size_t length)
{
@ -46,7 +47,10 @@ char* Substring(const char* str, size_t start, size_t length)
bool ReadSuperBlock(int fd, initrd_superblock_t* dest)
{
return preadall(fd, dest, sizeof(*dest), 0) == sizeof(*dest);
if ( preadall(fd, dest, sizeof(*dest), 0) != sizeof(*dest) )
return false;
import_initrd_superblock(dest);
return true;
}
initrd_superblock_t* GetSuperBlock(int fd)
@ -61,7 +65,9 @@ initrd_superblock_t* GetSuperBlock(int fd)
bool ReadChecksum(int fd, initrd_superblock_t* sb, uint8_t* dest)
{
uint32_t offset = sb->fssize - sb->sumsize;
return preadall(fd, dest, sb->sumsize, offset) == sb->sumsize;
if ( preadall(fd, dest, sb->sumsize, offset) != sb->sumsize )
return false;
return true;
}
uint8_t* GetChecksum(int fd, initrd_superblock_t* sb)
@ -76,7 +82,10 @@ bool ReadInode(int fd, initrd_superblock_t* sb, uint32_t ino,
initrd_inode_t* dest)
{
uint32_t inodepos = sb->inodeoffset + sb->inodesize * ino;
return preadall(fd, dest, sizeof(*dest), inodepos) == sizeof(*dest);
if ( preadall(fd, dest, sizeof(*dest), inodepos) != sizeof(*dest) )
return false;
import_initrd_inode(dest);
return true;
}
initrd_inode_t* GetInode(int fd, initrd_superblock_t* sb, uint32_t ino)
@ -128,12 +137,15 @@ uint32_t Traverse(int fd, initrd_superblock_t* sb, initrd_inode_t* inode,
while ( offset < inode->size )
{
initrd_dirent_t* dirent = (initrd_dirent_t*) (direntries + offset);
import_initrd_dirent(dirent);
if ( dirent->namelen && !strcmp(dirent->name, name) )
{
result = dirent->inode;
export_initrd_dirent(dirent);
break;
}
offset += dirent->reclen;
export_initrd_dirent(dirent);
}
free(direntries);
if ( !result ) { errno = ENOENT; }
@ -142,9 +154,12 @@ uint32_t Traverse(int fd, initrd_superblock_t* sb, initrd_inode_t* inode,
bool CheckSumCRC32(const char* name, int fd, initrd_superblock_t* sb)
{
uint32_t* checksump = (uint32_t*) GetChecksum(fd, sb);
uint8_t* checksump = (uint8_t*) GetChecksum(fd, sb);
if ( !checksump ) { return false; }
uint32_t checksum = *checksump;
uint32_t checksum = (uint32_t) checksump[0] << 0 |
(uint32_t) checksump[1] << 8 |
(uint32_t) checksump[2] << 16 |
(uint32_t) checksump[3] << 24;
free(checksump);
uint32_t amount = sb->fssize - sb->sumsize;
uint32_t filesum;

View File

@ -1,6 +1,6 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014.
Copyright(C) Jonas 'Sortie' Termansen 2012, 2013, 2014, 2015.
This file is part of Sortix.
@ -26,6 +26,7 @@
#include <sys/types.h>
#include <dirent.h>
#include <endian.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
@ -46,6 +47,7 @@
#include "crc32.h"
#include "rules.h"
#include "serialize.h"
uint32_t HostModeToInitRD(mode_t mode)
{
@ -366,7 +368,9 @@ bool WriteNode(struct initrd_superblock* sb, int fd, const char* outputname,
dirent.reclen = sizeof(dirent) + dirent.namelen + 1;
dirent.reclen = (dirent.reclen+3)/4*4; // Align entries.
size_t entsize = sizeof(dirent);
export_initrd_dirent(&dirent);
ssize_t hdramt = pwriteall(fd, &dirent, entsize, dataoff);
import_initrd_dirent(&dirent);
ssize_t nameamt = pwriteall(fd, name, namelen+1, dataoff + entsize);
if ( hdramt < (ssize_t) entsize || nameamt < (ssize_t) (namelen+1) )
return error(0, errno, "write: %s", outputname), false;
@ -394,8 +398,10 @@ bool WriteNode(struct initrd_superblock* sb, int fd, const char* outputname,
uint32_t inodepos = sb->inodeoffset + node->ino * sb->inodesize;
uint32_t inodesize = sizeof(inode);
export_initrd_inode(&inode);
if ( pwriteall(fd, &inode, inodesize, inodepos) < inodesize )
return error(0, errno, "write: %s", outputname), false;
import_initrd_inode(&inode);
uint32_t increment = dataoff - origfssize;
sb->fssize += increment;
@ -449,18 +455,22 @@ bool Format(const char* outputname, int fd, uint32_t inodecount, Node* root)
sb.sumsize = crcsize;
sb.fssize += sb.sumsize;
export_initrd_superblock(&sb);
if ( pwriteall(fd, &sb, sizeof(sb), 0) < sizeof(sb) )
{
error(0, errno, "write: %s", outputname);
return false;
}
import_initrd_superblock(&sb);
uint32_t checksize = sb.fssize - sb.sumsize;
uint32_t crc;
if ( !CRC32File(&crc, outputname, fd, 0, checksize) )
return false;
crc = htole32(crc);
if ( pwriteall(fd, &crc, crcsize, checksize) < crcsize )
return false;
crc = le32toh(crc);
return true;
}

89
mkinitrd/serialize.cpp Normal file
View File

@ -0,0 +1,89 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2015.
This file is part of Sortix.
Sortix is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along
with Sortix. If not, see <http://www.gnu.org/licenses/>.
serialize.cpp
Import and export binary data structures
*******************************************************************************/
#include <endian.h>
#include <sortix/initrd.h>
#include "serialize.h"
void import_initrd_superblock(struct initrd_superblock* obj)
{
obj->fssize = le32toh(obj->fssize);
obj->revision = le32toh(obj->revision);
obj->inodesize = le32toh(obj->inodesize);
obj->inodecount = le32toh(obj->inodecount);
obj->inodeoffset = le32toh(obj->inodeoffset);
obj->root = le32toh(obj->root);
obj->sumalgorithm = le32toh(obj->sumalgorithm);
obj->sumsize = le32toh(obj->sumsize);
}
void export_initrd_superblock(struct initrd_superblock* obj)
{
obj->fssize = htole32(obj->fssize);
obj->revision = htole32(obj->revision);
obj->inodesize = htole32(obj->inodesize);
obj->inodecount = htole32(obj->inodecount);
obj->inodeoffset = htole32(obj->inodeoffset);
obj->root = htole32(obj->root);
obj->sumalgorithm = htole32(obj->sumalgorithm);
obj->sumsize = htole32(obj->sumsize);
}
void import_initrd_inode(struct initrd_inode* obj)
{
obj->mode = le32toh(obj->mode);
obj->uid = le32toh(obj->uid);
obj->nlink = le32toh(obj->nlink);
obj->ctime = le64toh(obj->ctime);
obj->mtime = le64toh(obj->mtime);
obj->dataoffset = le32toh(obj->dataoffset);
obj->size = le32toh(obj->size);
}
void export_initrd_inode(struct initrd_inode* obj)
{
obj->mode = htole32(obj->mode);
obj->uid = htole32(obj->uid);
obj->nlink = htole32(obj->nlink);
obj->ctime = htole64(obj->ctime);
obj->mtime = htole64(obj->mtime);
obj->dataoffset = htole32(obj->dataoffset);
obj->size = htole32(obj->size);
}
void import_initrd_dirent(struct initrd_dirent* obj)
{
obj->inode = le32toh(obj->inode);
obj->reclen = le16toh(obj->reclen);
obj->namelen = le16toh(obj->namelen);
}
void export_initrd_dirent(struct initrd_dirent* obj)
{
obj->inode = htole32(obj->inode);
obj->reclen = htole16(obj->reclen);
obj->namelen = htole16(obj->namelen);
}

37
mkinitrd/serialize.h Normal file
View File

@ -0,0 +1,37 @@
/*******************************************************************************
Copyright(C) Jonas 'Sortie' Termansen 2015.
This file is part of Sortix.
Sortix is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along
with Sortix. If not, see <http://www.gnu.org/licenses/>.
serialize.h
Import and export binary data structures
*******************************************************************************/
#ifndef SERIALIZE_H
#define SERIALIZE_H
#include <sortix/initrd.h>
void import_initrd_superblock(struct initrd_superblock* obj);
void export_initrd_superblock(struct initrd_superblock* obj);
void import_initrd_inode(struct initrd_inode* obj);
void export_initrd_inode(struct initrd_inode* obj);
void import_initrd_dirent(struct initrd_dirent* obj);
void export_initrd_dirent(struct initrd_dirent* obj);
#endif