package: Add checksum command

This commit is contained in:
Ingo Weinhold 2014-07-14 00:46:20 +02:00
parent 03b36acbe6
commit fa50ee854d
5 changed files with 178 additions and 0 deletions

View File

@ -4,6 +4,7 @@ UsePrivateHeaders kernel shared storage support ;
BinCommand package :
command_add.cpp
command_checksum.cpp
command_create.cpp
command_dump.cpp
command_extract.cpp

View File

@ -0,0 +1,162 @@
/*
* Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <new>
#include <File.h>
#include <String.h>
#include <package/hpkg/HPKGDefs.h>
#include <package/hpkg/PackageWriter.h>
#include <DataPositionIOWrapper.h>
#include <FdIO.h>
#include <SHA256.h>
#include "package.h"
#include "PackageWriterListener.h"
using BPackageKit::BHPKG::BPackageWriter;
using BPackageKit::BHPKG::BPackageWriterListener;
using BPackageKit::BHPKG::BPackageWriterParameters;
struct ChecksumIO : BDataIO {
ChecksumIO()
{
fChecksummer.Init();
}
virtual ssize_t Write(const void* buffer, size_t size)
{
if (size > 0)
fChecksummer.Update(buffer, size);
return (ssize_t)size;
}
BString Digest()
{
const uint8* digest = fChecksummer.Digest();
BString hex;
size_t length = fChecksummer.DigestLength();
char* buffer = hex.LockBuffer(length * 2);
if (buffer == NULL)
{
throw std::bad_alloc();
}
for (size_t i = 0; i < length; i++)
snprintf(buffer + 2 * i, 3, "%02x", digest[i]);
hex.UnlockBuffer();
return hex;
}
private:
SHA256 fChecksummer;
};
static BPositionIO*
create_stdio(bool isInput)
{
BFdIO* dataIO = new BFdIO(isInput ? 0 : 1, false);
return new BDataPositionIOWrapper(dataIO);
}
int
command_checksum(int argc, const char* const* argv)
{
bool quiet = false;
bool verbose = false;
while (true) {
static struct option sLongOptions[] = {
{ "help", no_argument, 0, 'h' },
{ "quiet", no_argument, 0, 'q' },
{ "verbose", no_argument, 0, 'v' },
{ 0, 0, 0, 0 }
};
opterr = 0; // don't print errors
int c = getopt_long(argc, (char**)argv, "+hqv",
sLongOptions, NULL);
if (c == -1)
break;
switch (c) {
case 'h':
print_usage_and_exit(false);
break;
case 'q':
quiet = true;
break;
case 'v':
verbose = true;
break;
default:
print_usage_and_exit(true);
break;
}
}
// The optional remaining argument is the package file.
if (argc - optind > 1)
print_usage_and_exit(true);
const char* packageFileName = optind < argc ? argv[optind++] : NULL;
// open the input package
status_t error = B_OK;
BPositionIO* inputFile;
if (packageFileName == NULL || strcmp(packageFileName, "-") == 0) {
inputFile = create_stdio(true);
} else {
BFile* inputFileFile = new BFile;
error = inputFileFile->SetTo(packageFileName, O_RDONLY);
if (error != B_OK) {
fprintf(stderr, "Error: Failed to open input file \"%s\": %s\n",
packageFileName, strerror(error));
return 1;
}
inputFile = inputFileFile;
}
// write the output package to a BDataIO that computes the checksum
BPackageWriterParameters writerParameters;
writerParameters.SetCompressionLevel(0);
writerParameters.SetCompression(
BPackageKit::BHPKG::B_HPKG_COMPRESSION_NONE);
PackageWriterListener listener(verbose, quiet);
BPackageWriter packageWriter(&listener);
ChecksumIO outputFile;
error = packageWriter.Init(new BDataPositionIOWrapper(&outputFile), true,
&writerParameters);
if (error != B_OK)
return 1;
error = packageWriter.Recompress(inputFile);
if (error != B_OK)
return 1;
printf("%s\n", outputFile.Digest().String());
return 0;
}

View File

@ -41,6 +41,16 @@ static const char* kUsage =
" -q - Be quiet (don't show any output except for errors).\n"
" -v - Be verbose (show more info about created package).\n"
"\n"
" checksum [ <options> ] [ <package> ]\n"
" Computes the checksum of package file <package>. If <package> is "
"omitted\n"
" or \"-\", the file is read from stdin. This is only supported, if the "
"package\n"
" is uncompressed.\n"
"\n"
" -q - Be quiet (don't show any output except for errors).\n"
" -v - Be verbose (show more info about created package).\n"
"\n"
" create [ <options> ] <package>\n"
" Creates package file <package> from contents of current directory.\n"
"\n"
@ -134,6 +144,9 @@ main(int argc, const char* const* argv)
if (strcmp(command, "add") == 0)
return command_add(argc - 1, argv + 1);
if (strcmp(command, "checksum") == 0)
return command_checksum(argc - 1, argv + 1);
if (strcmp(command, "create") == 0)
return command_create(argc - 1, argv + 1);

View File

@ -9,6 +9,7 @@
void print_usage_and_exit(bool error);
int command_add(int argc, const char* const* argv);
int command_checksum(int argc, const char* const* argv);
int command_create(int argc, const char* const* argv);
int command_dump(int argc, const char* const* argv);
int command_extract(int argc, const char* const* argv);

View File

@ -8,6 +8,7 @@ USES_BE_API on <build>package = true ;
BuildPlatformMain <build>package :
command_add.cpp
command_checksum.cpp
command_create.cpp
command_dump.cpp
command_extract.cpp