Compare commits

...

25 Commits

Author SHA1 Message Date
Jef Roosens caee502382
refactor: move dynarray into own module 2023-02-23 09:54:50 +01:00
GreekStapler e5f0ac8dec fix: Plug memory leaks and fix strings that were not null terminated. 2023-02-02 19:29:34 +00:00
GreekStapler b9dbb8af5c fix: Initialised variable to keep CI from breaking (again). 2023-02-02 12:45:32 +00:00
GreekStapler da7e41e8ca refactor: Package extension now depends on what compression method was detected. 2023-02-02 11:42:00 +00:00
GreekStapler c0925fec14 fix: Initialise variables to keep CI from breaking. 2023-02-02 11:02:31 +00:00
Jef Roosens 655daff485
chore(package): ran fmt 2023-02-02 11:17:16 +01:00
Jef Roosens bfa1130478
refactor: separate directory for thirdparty code 2023-02-02 11:16:47 +01:00
GreekStapler 031e28ed33 refactor: Hashing function now streams data into hasher instead of doing it in one go. 2023-01-31 21:09:47 +00:00
GreekStapler 41fabe21a2 refactor: Package archive parser now returns meaningful error enums in case of failure. 2023-01-31 21:08:09 +00:00
GreekStapler e4d6ffc403 fix: Using snprintf while ignoring its return value could lead to valid inputs getting truncated. 2023-01-31 21:00:08 +00:00
GreekStapler 307e7ba6e9 fix: Initialise array pointers to 0 before performing check on them. 2023-01-31 20:41:05 +00:00
GreekStapler 4cacb1534f chore: Also renamed structs to follow naming conventions. 2023-01-29 12:45:48 +00:00
GreekStapler de1227b97b refactor: Added free function for package struct.
While going through with the renaming, I saw that I actually forgot to implement that part.
2023-01-29 11:55:22 +00:00
GreekStapler 4812cde905 chore: Package module now follows the naming and structure conventions of libvieter. 2023-01-29 11:48:59 +00:00
GreekStapler b87d6b1542 refactor: Subsituted old hash generation with a proper implementation. 2023-01-28 22:01:00 +00:00
GreekStapler 72fea90e13 fix: strcat can not be used on uninitialised strings in non-musl environments. 2023-01-28 10:28:41 +00:00
Jef Roosens b25da21fd1 chore: fix merge marker in makefile 2023-01-28 09:58:32 +01:00
GreekStapler 9452fea2ab fix: Somehow, test file changed line endings to CRLF. Changed it back to LF. 2023-01-27 22:24:54 +00:00
GreekStapler 10eb08b8e4 chore: Rebase to dev branch with binomial heap PR. 2023-01-27 22:23:23 +00:00
GreekStapler d1a8ba7737 refactor: Added SHA256 to package description file. 2023-01-27 22:17:57 +00:00
GreekStapler 2ce7a819a9 refactor: Decided to not return char** in function that creates the package description after all, now returns char*.
The method I was trying started to irk me when I thought of creating a test unit for it. Also fixed some other issues I found in the package_to_description function (SHA256SUM section still missing).
2023-01-27 22:17:57 +00:00
GreekStapler 2d6ac2ac19 fix: Took a very long time finding a very annyoing bug because realloc is the devil. 2023-01-27 22:17:57 +00:00
GreekStapler 6d731d788c refactor: Created function that will return the char ** (originally char *) that will be used to make the description file. Also removed free that was resulting in a crash. 2023-01-27 22:17:57 +00:00
GreekStapler a60c923547 refactor: Modified .PKGINFO parser not to rely on gotos and continues. Parser is now optimistic and assumes .PKGINFO file is valid.
After my changes to the macros, they still feel a bit hacky, but I'm content with them. I also changed the parser to assume the .PKGINFO files are always valid because they are automatically generated. The parser also assumes the same fields will always appear in the same fixed order. I made this change after checking how makepkg generated this file.
2023-01-27 22:17:57 +00:00
GreekStapler 276fa99e4b refactor: Add original .c package files by Jef. 2023-01-27 22:17:57 +00:00
17 changed files with 1157 additions and 4 deletions

View File

@ -6,15 +6,20 @@ LIB_FILENAME ?= libvieter.a
BUILD_DIR ?= build
SRC_DIR ?= src
TEST_DIR ?= test
INC_DIRS ?= include
3RDPARTY_DIR ?= thirdparty
INCLUDE_DIR ?= include
INC_DIRS ?= $(INCLUDE_DIR) $(3RDPARTY_DIR)/include
LIB := $(BUILD_DIR)/$(LIB_FILENAME)
SRCS != find '$(SRC_DIR)' -iname '*.c'
SRCS_H != find $(INC_DIRS) -iname '*.h'
SRCS_H != find $(INCLUDE_DIR) -iname '*.h'
SRCS_TEST != find '$(TEST_DIR)' -iname '*.c'
SRCS_3RDPARTY != find '$(3RDPARTY_DIR)/src' -iname '*.c'
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
$(info ${SRCS})
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o) $(SRCS_3RDPARTY:%=$(BUILD_DIR)/%.o)
OBJS_TEST := $(SRCS_TEST:%=$(BUILD_DIR)/%.o)
DEPS := $(SRCS:%=$(BUILD_DIR)/%.d) $(SRCS_TEST:%=$(BUILD_DIR)/%.d)
@ -22,6 +27,7 @@ BINS_TEST := $(OBJS_TEST:%.c.o=%)
TARGETS_TEST := $(BINS_TEST:%=test-%)
TARGETS_MEM_TEST := $(BINS_TEST:%=test-mem-%)
LIBFLAGS := -larchive
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
# -MMD: generate a .d file for every source file. This file can be imported by
@ -50,6 +56,9 @@ $(BUILD_DIR)/$(SRC_DIR)/%.c.o: $(SRC_DIR)/%.c
mkdir -p $(dir $@)
$(CC) $(VIETERCFLAGS) -c $< -o $@
$(BUILD_DIR)/$(3RDPARTY_DIR)/src/%.c.o: $(3RDPARTY_DIR)/src/%.c
mkdir -p $(dir $@)
$(CC) $(VIETERCFLAGS) -c $< -o $@
# =====TESTING=====
.PHONY: test
@ -73,7 +82,7 @@ build-test: $(BINS_TEST)
# might be changed later if this starts to become too slow.
$(BINS_TEST): %: %.c.o $(LIB)
$(CC) \
$^ -o $@
$^ $(LIBFLAGS) -o $@
# Along with the include directory, each test includes $(TEST_DIR) (which
# contains the acutest.h header file), and the src directory of the module it's

View File

@ -15,6 +15,10 @@ See the [source code](src) for the list of modules.
Everything is handled by the provided Makefile. To compile the static library,
simply run `make`.
### Required libraries
Libvieter requires libarchive.
### Project structure
Each module has its own subdirectory inside `src`, e.g. `src/cron`. This

View File

@ -0,0 +1,34 @@
#ifndef VIETER_DYNARRAY
#define VIETER_DYNARRAY
#include <stdlib.h>
#include <string.h>
typedef struct vieter_dynarray {
char **array;
size_t capacity;
size_t size;
} vieter_dynarray;
/*
* Allocate a dynamic array.
*/
vieter_dynarray *vieter_dynarray_init(size_t initial_capacity);
/*
* Initialise array (if it's not already initialised) and insert a string.
*/
void vieter_dynarray_add(vieter_dynarray *da, const char *s);
/*
* Deallocate dynamic array.
*/
void vieter_dynarray_free(vieter_dynarray *da);
/*
* Convert a vieter_dynarray into an array by freeing all its surrounding
* components and returning the underlying array pointer.
*/
char **vieter_dynarray_convert(vieter_dynarray *da);
#endif

View File

@ -0,0 +1,33 @@
#ifndef VIETER_PACKAGE
#define VIETER_PACKAGE
typedef struct vieter_package vieter_package;
typedef enum vieter_package_error {
vieter_package_ok = 0,
vieter_package_unarchive_error = 1,
vieter_package_stat_error = 2
} vieter_package_error;
/*
* Allocate an empty package
*/
vieter_package *vieter_package_init();
/*
* Parse package file into something usable by libvieter.
*/
vieter_package_error vieter_package_read_archive(vieter_package *pkg,
const char *pkg_path);
/*
* Deallocate a package.
*/
void vieter_package_free(vieter_package **ptp);
/*
* Create string that will become the package's desc file.
*/
char *vieter_package_to_description(vieter_package *pkg);
#endif

View File

@ -0,0 +1,58 @@
#include "vieter_dynarray.h"
vieter_dynarray *vieter_dynarray_init(size_t initial_capacity) {
vieter_dynarray *da = malloc(sizeof(vieter_dynarray));
da->size = 0;
da->capacity = initial_capacity;
return da;
}
void vieter_dynarray_add(vieter_dynarray *da, const char *s) {
// An empty vieter_dynarray does not have an allocated internal array
// yet
if (da->size == 0) {
da->array = malloc(sizeof(char *) * da->capacity);
// Initialise all char*'s to 0 so array[i] == NULL can be used to see if
// field is empty
memset(da->array, 0, sizeof(char *) * da->capacity);
}
// Double array size if it's full
else if (da->size == da->capacity) {
// if the realloc fails, access to memory in da->array is lost
da->array = realloc(da->array, sizeof(char *) * da->capacity * 2);
da->capacity *= 2;
// Same as the previous memset, but only for newly allocated pointers
memset(da->array + da->size, 0, sizeof(char *) * da->capacity / 2);
}
da->array[da->size] = strdup(s);
da->size++;
}
void vieter_dynarray_free(vieter_dynarray *da) {
if (da == NULL) {
return;
}
if (da->array != NULL) {
for (size_t i = 0; i < da->size; i++) {
free(da->array[i]);
}
free(da->array);
}
free(da);
}
char **vieter_dynarray_convert(vieter_dynarray *da) {
char **array = da->array;
da->array = NULL;
vieter_dynarray_free(da);
return array;
}

View File

@ -0,0 +1,5 @@
# package
This module handles both parsing the published Arch tarballs & the contents of
their `.PKGINFO` files, as well as generating the contents of the database
archives' `desc` & `files` files.

View File

@ -0,0 +1,263 @@
#include <archive.h>
#include <archive_entry.h>
#include <stdbool.h>
#include <stdlib.h>
#include "sha256.h"
#include "vieter_package_internal.h"
#define ADD_STRING(section, field) \
if (pkg_info->field != 0) { \
size_to_be_written = \
snprintf(aux, small_buff_size, section, pkg_info->field); \
if (size_to_be_written > small_buff_size) { \
aux = realloc(aux, size_to_be_written + 1); \
small_buff_size = size_to_be_written + 1; \
snprintf(aux, small_buff_size, section, pkg_info->field); \
} \
if (buff_size < strlen(description) + small_buff_size + 1) { \
description = realloc(description, buff_size * 2); \
buff_size *= 2; \
} \
strcat(description, aux); \
}
#define ADD_ARRAY(section, field) \
i = 0; \
if (pkg_info->field != NULL) { \
ADD_STRING(section, field->array[i]); \
i++; \
while (pkg_info->field->array[i] != NULL) { \
ADD_STRING("\n%s", field->array[i]); \
i++; \
} \
}
static char *ignored_names[5] = {".BUILDINFO", ".INSTALL", ".MTREE", ".PKGINFO",
".CHANGELOG"};
static size_t ignored_words_len = sizeof(ignored_names) / sizeof(char *);
vieter_package *vieter_package_init() {
return calloc(sizeof(vieter_package_info), 1);
}
vieter_package_error vieter_package_read_archive(vieter_package *pkg,
const char *pkg_path) {
struct archive *a = archive_read_new();
struct archive_entry *entry;
// These three are the most commonly used compression methods
archive_read_support_filter_zstd(a);
archive_read_support_filter_gzip(a);
archive_read_support_filter_xz(a);
// Contents should always be a tarball
archive_read_support_format_tar(a);
// TODO where does this 10240 come from?
int r = archive_read_open_filename(a, pkg_path, 10240);
// Exit early if we weren't able to successfully open the archive for reading
if (r != ARCHIVE_OK) {
return vieter_package_unarchive_error;
}
int compression_code = archive_filter_code(a, 0);
const char *path_name;
vieter_package_info *pkg_info = NULL;
vieter_dynarray *files = vieter_dynarray_init(16);
vieter_dynarray_add(files, "%FILES%");
while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
path_name = archive_entry_pathname(entry);
bool ignore = false;
for (size_t i = 0; i < ignored_words_len; i++) {
if (strcmp(path_name, ignored_names[i]) == 0) {
ignore = true;
break;
}
}
if (!ignore) {
vieter_dynarray_add(files, path_name);
}
if (strcmp(path_name, ".PKGINFO") == 0) {
// Read data of file into memory buffer
int size = archive_entry_size(entry);
char *buf = malloc(size + 1);
archive_read_data(a, buf, size);
buf[size] = '\0';
// Parse package vieter_package_info string into a struct
pkg_info = vieter_package_info_init();
vieter_package_info_parse(pkg_info, buf);
free(buf);
} else {
archive_read_data_skip(a);
}
}
// Get size of file
struct stat stats;
if (stat(pkg_path, &stats) != 0) {
// errno is set if stat() fails; the calling function should check
// the value of errno in case vieter_package_stat_error is returned
return vieter_package_stat_error;
}
pkg_info->csize = stats.st_size;
archive_read_free(a);
// Create final return value
pkg->path = strdup(pkg_path);
pkg->info = pkg_info;
pkg->files = files;
pkg->compression = compression_code;
return vieter_package_ok;
}
void vieter_package_sha256sum(vieter_package *pkg, char *res) {
FILE *f = fopen(pkg->path, "r");
// Try to read 100KiB at a time
unsigned char *in = malloc(102400);
// Actual number of bytes read
size_t read_size;
SHA256_CTX *ctx = malloc(sizeof(SHA256_CTX));
sha256_init(ctx);
while ((read_size = fread(in, 1, 102400, f)) != 0) {
sha256_update(ctx, in, read_size);
}
unsigned char hash[SHA256_BLOCK_SIZE];
sha256_final(ctx, hash);
fclose(f);
free(in);
free(ctx);
// We need to convert the bytes in the hash to get a string representation of
// its hex values i.e. turn 1001 1111 into the string "9f" Each byte of the
// hash is going to turn into two bytes in the final string so we are going to
// convert each half byte into a char
unsigned int half_byte = 0;
int j = 0;
// We advance 2 bytes in the string for every one byte of the hash
for (int i = 0; i < SHA256_BLOCK_SIZE; i++) {
// We transform the first half byte into the second character to keep
// each byte from becoming reversed in the final string
half_byte = hash[i] & 0b1111;
if (half_byte < 10) {
res[j + 1] = half_byte + 48;
} else {
res[j + 1] = half_byte + 87;
}
hash[i] = hash[i] >> 4;
half_byte = hash[i] & 0b1111;
if (half_byte < 10) {
res[j] = half_byte + 48;
} else {
res[j] = half_byte + 87;
}
j += 2;
}
res[j] = '\0';
}
char *vieter_package_to_description(vieter_package *pkg) {
vieter_package_info *pkg_info = pkg->info;
size_t buff_size = 1024;
int small_buff_size = 128;
int size_to_be_written;
char *aux = malloc(sizeof(char) * small_buff_size);
char *description = malloc(sizeof(char) * buff_size);
// Helper variable for ADD_ARRAY macro
int i;
// special case for FILENAME
char *ext = NULL;
switch (pkg->compression) {
case 0:
ext = ".tar";
break;
case 1:
ext = ".tar.gz";
break;
case 6:
ext = ".tar.xz";
break;
case 14:
ext = ".tar.zst";
break;
}
size_to_be_written =
snprintf(aux, small_buff_size, "%%FILENAME%%\n%s-%s-%s.pkg%s",
pkg_info->name, pkg_info->version, pkg_info->arch, ext);
// We neither want to let an arbritrarily long input to overflow the buffer
// nor to truncate perfectly valid inputs
if (size_to_be_written > small_buff_size) {
aux = realloc(aux, size_to_be_written + 1);
small_buff_size = size_to_be_written + 1;
snprintf(aux, small_buff_size, "%%FILENAME%%\n%s-%s-%s.pkg.tar.zst",
pkg_info->name, pkg_info->version, pkg_info->arch);
}
strcpy(description, aux);
ADD_STRING("\n\n%%NAME%%\n%s", name);
ADD_STRING("\n\n%%BASE%%\n%s", base);
ADD_STRING("\n\n%%VERSION%%\n%s", version);
ADD_STRING("\n\n%%DESC%%\n%s", description);
ADD_ARRAY("\n\n%%GROUPS%%\n%s", groups);
ADD_STRING("\n\n%%CSIZE%%\n%ld", csize);
ADD_STRING("\n\n%%ISIZE%%\n%ld", size);
char checksum[SHA256_BLOCK_SIZE * 2 + 1];
vieter_package_sha256sum(pkg, checksum);
snprintf(aux, small_buff_size, "\n\n%%SHA256SUM%%\n%s", checksum);
if (buff_size < strlen(description) + small_buff_size + 1) {
description = realloc(description, buff_size * 2);
buff_size *= 2;
}
strcat(description, aux);
ADD_STRING("\n\n%%URL%%\n%s", url);
ADD_ARRAY("\n\n%%LICENSE%%\n%s", licenses);
ADD_STRING("\n\n%%ARCH%%\n%s", arch);
ADD_STRING("\n\n%%BUILDDATE%%\n%ld", build_date);
ADD_STRING("\n\n%%PACKAGER%%\n%s", packager);
ADD_ARRAY("\n\n%%REPLACES%%\n%s", replaces);
ADD_ARRAY("\n\n%%CONFLICTS%%\n%s", conflicts);
ADD_ARRAY("\n\n%%PROVIDES%%\n%s", provides);
ADD_ARRAY("\n\n%%DEPENDS%%\n%s", depends);
ADD_ARRAY("\n\n%%OPTDEPENDS%%\n%s", optdepends);
ADD_ARRAY("\n\n%%MAKEDEPENDS%%\n%s", makedepends);
ADD_ARRAY("\n\n%%CHECKDEPENDS%%\n%s", checkdepends);
strcat(description, "\n\n");
free(aux);
return description;
}
void vieter_package_free(vieter_package **ptp) {
FREE_STRING((*ptp)->path);
vieter_package_info_free((*ptp)->info);
vieter_dynarray_free((*ptp)->files);
free(*ptp);
*ptp = NULL;
}

View File

@ -0,0 +1,86 @@
#include <stdbool.h>
#include "vieter_package_info.h"
#define PKG_INFO_STRING(key_ptr, field) \
if ((value_ptr = strstr(value_ptr, key_ptr)) != NULL) { \
value_ptr += strlen(key_ptr); \
tail_ptr = strchr(value_ptr, '\n'); \
tail_ptr[0] = '\0'; \
pkg_info->field = strdup(value_ptr); \
tail_ptr[0] = '\n'; \
} \
value_ptr = tail_ptr;
#define PKG_INFO_INT(key_ptr, field) \
value_ptr = strstr(value_ptr, key_ptr) + strlen(key_ptr); \
tail_ptr = strchr(value_ptr, '\n'); \
tail_ptr[0] = '\0'; \
pkg_info->field = atoi(value_ptr); \
tail_ptr[0] = '\n'; \
value_ptr = tail_ptr;
#define PKG_INFO_ARRAY(key_ptr, field) \
while ((value_ptr = strstr(value_ptr, key_ptr)) != NULL) { \
value_ptr = value_ptr + strlen(key_ptr); \
tail_ptr = strchr(value_ptr, '\n'); \
tail_ptr[0] = '\0'; \
if (pkg_info->field == NULL) { \
pkg_info->field = vieter_dynarray_init(4); \
} \
vieter_dynarray_add(pkg_info->field, value_ptr); \
tail_ptr[0] = '\n'; \
value_ptr = tail_ptr; \
} \
value_ptr = tail_ptr;
vieter_package_info *vieter_package_info_init() {
return calloc(1, sizeof(vieter_package_info));
}
void vieter_package_info_free(vieter_package_info *pkg_info) {
FREE_STRING(pkg_info->name);
FREE_STRING(pkg_info->base);
FREE_STRING(pkg_info->version);
FREE_STRING(pkg_info->description);
FREE_STRING(pkg_info->url);
FREE_STRING(pkg_info->arch);
FREE_STRING(pkg_info->packager);
FREE_STRING(pkg_info->pgpsig);
vieter_dynarray_free(pkg_info->groups);
vieter_dynarray_free(pkg_info->licenses);
vieter_dynarray_free(pkg_info->replaces);
vieter_dynarray_free(pkg_info->depends);
vieter_dynarray_free(pkg_info->conflicts);
vieter_dynarray_free(pkg_info->provides);
vieter_dynarray_free(pkg_info->optdepends);
vieter_dynarray_free(pkg_info->makedepends);
vieter_dynarray_free(pkg_info->checkdepends);
free(pkg_info);
}
void vieter_package_info_parse(vieter_package_info *pkg_info,
char *pkg_info_str) {
char *value_ptr = pkg_info_str, *tail_ptr = NULL;
PKG_INFO_STRING("\npkgname = ", name);
PKG_INFO_STRING("\npkgbase = ", base);
PKG_INFO_STRING("\npkgver = ", version);
PKG_INFO_STRING("\npkgdesc = ", description);
PKG_INFO_STRING("\nurl = ", url);
PKG_INFO_INT("\nbuilddate = ", build_date);
PKG_INFO_STRING("\npackager = ", packager);
PKG_INFO_INT("\nsize = ", size);
PKG_INFO_STRING("\narch = ", arch);
PKG_INFO_ARRAY("\nlicense = ", licenses);
PKG_INFO_ARRAY("\nreplaces = ", replaces);
PKG_INFO_ARRAY("\ngroup = ", groups);
PKG_INFO_ARRAY("\nconflict = ", conflicts);
PKG_INFO_ARRAY("\nprovides = ", provides);
PKG_INFO_ARRAY("\ndepend = ", depends);
PKG_INFO_ARRAY("\noptdepend = ", optdepends);
PKG_INFO_ARRAY("\nmakedepend = ", makedepends);
PKG_INFO_ARRAY("\ncheckdepend = ", checkdepends);
}

View File

@ -0,0 +1,52 @@
#ifndef VIETER_PACKAGE_INFO
#define VIETER_PACKAGE_INFO
#define FREE_STRING(sp) if (sp != NULL) free(sp)
#include <stdint.h>
#include "vieter_package.h"
#include "vieter_dynarray.h"
typedef struct vieter_package_info {
char *name;
char *base;
char *version;
char *description;
int64_t size;
int64_t csize;
char *url;
char *arch;
int64_t build_date;
char *packager;
char *pgpsig;
int64_t pgpsigsize;
vieter_dynarray *groups;
vieter_dynarray *licenses;
vieter_dynarray *replaces;
vieter_dynarray *depends;
vieter_dynarray *conflicts;
vieter_dynarray *provides;
vieter_dynarray *optdepends;
vieter_dynarray *makedepends;
vieter_dynarray *checkdepends;
} vieter_package_info;
/*
* Allocate and initialise a pkg_info pointer to hold .PKGINFO.
*/
vieter_package_info *vieter_package_info_init();
/*
* Parse .PKGINFO file into something usable by libvieter.
*/
void vieter_package_info_parse(vieter_package_info *pkg_info, char *pkg_info_str);
/*
* Deallocate a pkg_info pointer.
*/
void vieter_package_info_free(vieter_package_info *pkg_info);
#endif

View File

@ -0,0 +1,10 @@
#include "vieter_package.h"
#include "vieter_package_info.h"
#include "vieter_dynarray.h"
struct vieter_package {
char *path;
vieter_package_info *info;
vieter_dynarray *files;
int compression;
};

View File

@ -0,0 +1,22 @@
# Generated by makepkg 6.0.2
# using fakeroot version 1.30.1
pkgname = xcursor-dmz
pkgbase = xcursor-dmz
pkgver = 0.4.5-2
pkgdesc = Style neutral, scalable cursor theme
url = https://packages.debian.org/sid/dmz-cursor-theme
builddate = 1673751613
packager = Unknown Packager
size = 3469584
arch = any
license = MIT
replaces = test1
group = x11
conflict = test2
conflict = test3
provides = test4
depend = test5
depend = test6
optdepend = test7
makedepend = xorg-xcursorgen
checkdepend = test8

45
test/package/desc 100644
View File

@ -0,0 +1,45 @@
%FILENAME%
xcursor-dmz-0.4.5-2-any.pkg.tar.zst
%NAME%
xcursor-dmz
%BASE%
xcursor-dmz
%VERSION%
0.4.5-2
%DESC%
Style neutral, scalable cursor theme
%GROUPS%
x11
%CSIZE%
328282
%ISIZE%
3469584
%SHA256SUM%
4f4bce9e975334ed7775ff4ddf4d2e82e411d599802f6179a122f89149f53bfb
%URL%
https://packages.debian.org/sid/dmz-cursor-theme
%LICENSE%
MIT
%ARCH%
any
%BUILDDATE%
1673751613
%PACKAGER%
Unknown Packager
%MAKEDEPENDS%
xorg-xcursorgen

243
test/package/files 100644
View File

@ -0,0 +1,243 @@
%FILES%
usr/
usr/share/
usr/share/icons/
usr/share/icons/DMZ-Black/
usr/share/icons/DMZ-Black/cursor.theme
usr/share/icons/DMZ-Black/cursors/
usr/share/icons/DMZ-Black/cursors/00008160000006810000408080010102
usr/share/icons/DMZ-Black/cursors/028006030e0e7ebffc7f7070c0600140
usr/share/icons/DMZ-Black/cursors/03b6e0fcb3499374a867c041f52298f0
usr/share/icons/DMZ-Black/cursors/08e8e1c95fe2fc01f976f1e063a24ccd
usr/share/icons/DMZ-Black/cursors/1081e37283d90000800003c07f3ef6bf
usr/share/icons/DMZ-Black/cursors/14fef782d02440884392942c11205230
usr/share/icons/DMZ-Black/cursors/2870a09082c103050810ffdffffe0204
usr/share/icons/DMZ-Black/cursors/3085a0e285430894940527032f8b26df
usr/share/icons/DMZ-Black/cursors/3ecb610c1bf2410f44200f48c40d3599
usr/share/icons/DMZ-Black/cursors/4498f0e0c1937ffe01fd06f973665830
usr/share/icons/DMZ-Black/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408
usr/share/icons/DMZ-Black/cursors/6407b0e94181790501fd1e167b474872
usr/share/icons/DMZ-Black/cursors/640fb0e74195791501fd1ed57b41487f
usr/share/icons/DMZ-Black/cursors/9081237383d90e509aa00f00170e968f
usr/share/icons/DMZ-Black/cursors/9d800788f1b08800ae810202380a0822
usr/share/icons/DMZ-Black/cursors/X_cursor
usr/share/icons/DMZ-Black/cursors/alias
usr/share/icons/DMZ-Black/cursors/arrow
usr/share/icons/DMZ-Black/cursors/bd_double_arrow
usr/share/icons/DMZ-Black/cursors/bottom_left_corner
usr/share/icons/DMZ-Black/cursors/bottom_right_corner
usr/share/icons/DMZ-Black/cursors/bottom_side
usr/share/icons/DMZ-Black/cursors/bottom_tee
usr/share/icons/DMZ-Black/cursors/c7088f0f3e6c8088236ef8e1e3e70000
usr/share/icons/DMZ-Black/cursors/circle
usr/share/icons/DMZ-Black/cursors/col-resize
usr/share/icons/DMZ-Black/cursors/color-picker
usr/share/icons/DMZ-Black/cursors/copy
usr/share/icons/DMZ-Black/cursors/cross
usr/share/icons/DMZ-Black/cursors/cross_reverse
usr/share/icons/DMZ-Black/cursors/crossed_circle
usr/share/icons/DMZ-Black/cursors/crosshair
usr/share/icons/DMZ-Black/cursors/d9ce0ab605698f320427677b458ad60b
usr/share/icons/DMZ-Black/cursors/default
usr/share/icons/DMZ-Black/cursors/diamond_cross
usr/share/icons/DMZ-Black/cursors/dnd-ask
usr/share/icons/DMZ-Black/cursors/dnd-copy
usr/share/icons/DMZ-Black/cursors/dnd-link
usr/share/icons/DMZ-Black/cursors/dnd-move
usr/share/icons/DMZ-Black/cursors/dnd-none
usr/share/icons/DMZ-Black/cursors/dot_box_mask
usr/share/icons/DMZ-Black/cursors/dotbox
usr/share/icons/DMZ-Black/cursors/double_arrow
usr/share/icons/DMZ-Black/cursors/draft_large
usr/share/icons/DMZ-Black/cursors/draft_small
usr/share/icons/DMZ-Black/cursors/draped_box
usr/share/icons/DMZ-Black/cursors/e-resize
usr/share/icons/DMZ-Black/cursors/e29285e634086352946a0e7090d73106
usr/share/icons/DMZ-Black/cursors/ew-resize
usr/share/icons/DMZ-Black/cursors/fcf1c3c7cd4491d801f1e1c78f100000
usr/share/icons/DMZ-Black/cursors/fd_double_arrow
usr/share/icons/DMZ-Black/cursors/fleur
usr/share/icons/DMZ-Black/cursors/grab
usr/share/icons/DMZ-Black/cursors/grabbing
usr/share/icons/DMZ-Black/cursors/h_double_arrow
usr/share/icons/DMZ-Black/cursors/hand
usr/share/icons/DMZ-Black/cursors/hand1
usr/share/icons/DMZ-Black/cursors/hand2
usr/share/icons/DMZ-Black/cursors/help
usr/share/icons/DMZ-Black/cursors/icon
usr/share/icons/DMZ-Black/cursors/left_ptr
usr/share/icons/DMZ-Black/cursors/left_ptr_help
usr/share/icons/DMZ-Black/cursors/left_ptr_watch
usr/share/icons/DMZ-Black/cursors/left_side
usr/share/icons/DMZ-Black/cursors/left_tee
usr/share/icons/DMZ-Black/cursors/link
usr/share/icons/DMZ-Black/cursors/ll_angle
usr/share/icons/DMZ-Black/cursors/lr_angle
usr/share/icons/DMZ-Black/cursors/move
usr/share/icons/DMZ-Black/cursors/n-resize
usr/share/icons/DMZ-Black/cursors/ne-resize
usr/share/icons/DMZ-Black/cursors/nesw-resize
usr/share/icons/DMZ-Black/cursors/not-allowed
usr/share/icons/DMZ-Black/cursors/ns-resize
usr/share/icons/DMZ-Black/cursors/nw-resize
usr/share/icons/DMZ-Black/cursors/nwse-resize
usr/share/icons/DMZ-Black/cursors/openhand
usr/share/icons/DMZ-Black/cursors/pencil
usr/share/icons/DMZ-Black/cursors/pirate
usr/share/icons/DMZ-Black/cursors/plus
usr/share/icons/DMZ-Black/cursors/pointer
usr/share/icons/DMZ-Black/cursors/progress
usr/share/icons/DMZ-Black/cursors/question_arrow
usr/share/icons/DMZ-Black/cursors/right_ptr
usr/share/icons/DMZ-Black/cursors/right_side
usr/share/icons/DMZ-Black/cursors/right_tee
usr/share/icons/DMZ-Black/cursors/row-resize
usr/share/icons/DMZ-Black/cursors/s-resize
usr/share/icons/DMZ-Black/cursors/sb_down_arrow
usr/share/icons/DMZ-Black/cursors/sb_h_double_arrow
usr/share/icons/DMZ-Black/cursors/sb_left_arrow
usr/share/icons/DMZ-Black/cursors/sb_right_arrow
usr/share/icons/DMZ-Black/cursors/sb_up_arrow
usr/share/icons/DMZ-Black/cursors/sb_v_double_arrow
usr/share/icons/DMZ-Black/cursors/se-resize
usr/share/icons/DMZ-Black/cursors/size_bdiag
usr/share/icons/DMZ-Black/cursors/size_fdiag
usr/share/icons/DMZ-Black/cursors/size_hor
usr/share/icons/DMZ-Black/cursors/size_ver
usr/share/icons/DMZ-Black/cursors/sw-resize
usr/share/icons/DMZ-Black/cursors/target
usr/share/icons/DMZ-Black/cursors/tcross
usr/share/icons/DMZ-Black/cursors/text
usr/share/icons/DMZ-Black/cursors/top_left_arrow
usr/share/icons/DMZ-Black/cursors/top_left_corner
usr/share/icons/DMZ-Black/cursors/top_right_corner
usr/share/icons/DMZ-Black/cursors/top_side
usr/share/icons/DMZ-Black/cursors/top_tee
usr/share/icons/DMZ-Black/cursors/ul_angle
usr/share/icons/DMZ-Black/cursors/ur_angle
usr/share/icons/DMZ-Black/cursors/v_double_arrow
usr/share/icons/DMZ-Black/cursors/w-resize
usr/share/icons/DMZ-Black/cursors/wait
usr/share/icons/DMZ-Black/cursors/watch
usr/share/icons/DMZ-Black/cursors/xterm
usr/share/icons/DMZ-White/
usr/share/icons/DMZ-White/cursor.theme
usr/share/icons/DMZ-White/cursors/
usr/share/icons/DMZ-White/cursors/00008160000006810000408080010102
usr/share/icons/DMZ-White/cursors/028006030e0e7ebffc7f7070c0600140
usr/share/icons/DMZ-White/cursors/03b6e0fcb3499374a867c041f52298f0
usr/share/icons/DMZ-White/cursors/08e8e1c95fe2fc01f976f1e063a24ccd
usr/share/icons/DMZ-White/cursors/1081e37283d90000800003c07f3ef6bf
usr/share/icons/DMZ-White/cursors/14fef782d02440884392942c11205230
usr/share/icons/DMZ-White/cursors/2870a09082c103050810ffdffffe0204
usr/share/icons/DMZ-White/cursors/3085a0e285430894940527032f8b26df
usr/share/icons/DMZ-White/cursors/3ecb610c1bf2410f44200f48c40d3599
usr/share/icons/DMZ-White/cursors/4498f0e0c1937ffe01fd06f973665830
usr/share/icons/DMZ-White/cursors/5c6cd98b3f3ebcb1f9c7f1c204630408
usr/share/icons/DMZ-White/cursors/6407b0e94181790501fd1e167b474872
usr/share/icons/DMZ-White/cursors/640fb0e74195791501fd1ed57b41487f
usr/share/icons/DMZ-White/cursors/9081237383d90e509aa00f00170e968f
usr/share/icons/DMZ-White/cursors/9d800788f1b08800ae810202380a0822
usr/share/icons/DMZ-White/cursors/X_cursor
usr/share/icons/DMZ-White/cursors/alias
usr/share/icons/DMZ-White/cursors/arrow
usr/share/icons/DMZ-White/cursors/bd_double_arrow
usr/share/icons/DMZ-White/cursors/bottom_left_corner
usr/share/icons/DMZ-White/cursors/bottom_right_corner
usr/share/icons/DMZ-White/cursors/bottom_side
usr/share/icons/DMZ-White/cursors/bottom_tee
usr/share/icons/DMZ-White/cursors/c7088f0f3e6c8088236ef8e1e3e70000
usr/share/icons/DMZ-White/cursors/circle
usr/share/icons/DMZ-White/cursors/col-resize
usr/share/icons/DMZ-White/cursors/color-picker
usr/share/icons/DMZ-White/cursors/copy
usr/share/icons/DMZ-White/cursors/cross
usr/share/icons/DMZ-White/cursors/cross_reverse
usr/share/icons/DMZ-White/cursors/crossed_circle
usr/share/icons/DMZ-White/cursors/crosshair
usr/share/icons/DMZ-White/cursors/d9ce0ab605698f320427677b458ad60b
usr/share/icons/DMZ-White/cursors/default
usr/share/icons/DMZ-White/cursors/diamond_cross
usr/share/icons/DMZ-White/cursors/dnd-ask
usr/share/icons/DMZ-White/cursors/dnd-copy
usr/share/icons/DMZ-White/cursors/dnd-link
usr/share/icons/DMZ-White/cursors/dnd-move
usr/share/icons/DMZ-White/cursors/dnd-none
usr/share/icons/DMZ-White/cursors/dot_box_mask
usr/share/icons/DMZ-White/cursors/dotbox
usr/share/icons/DMZ-White/cursors/double_arrow
usr/share/icons/DMZ-White/cursors/draft_large
usr/share/icons/DMZ-White/cursors/draft_small
usr/share/icons/DMZ-White/cursors/draped_box
usr/share/icons/DMZ-White/cursors/e-resize
usr/share/icons/DMZ-White/cursors/e29285e634086352946a0e7090d73106
usr/share/icons/DMZ-White/cursors/ew-resize
usr/share/icons/DMZ-White/cursors/fcf1c3c7cd4491d801f1e1c78f100000
usr/share/icons/DMZ-White/cursors/fd_double_arrow
usr/share/icons/DMZ-White/cursors/fleur
usr/share/icons/DMZ-White/cursors/grab
usr/share/icons/DMZ-White/cursors/grabbing
usr/share/icons/DMZ-White/cursors/h_double_arrow
usr/share/icons/DMZ-White/cursors/hand
usr/share/icons/DMZ-White/cursors/hand1
usr/share/icons/DMZ-White/cursors/hand2
usr/share/icons/DMZ-White/cursors/help
usr/share/icons/DMZ-White/cursors/icon
usr/share/icons/DMZ-White/cursors/left_ptr
usr/share/icons/DMZ-White/cursors/left_ptr_help
usr/share/icons/DMZ-White/cursors/left_ptr_watch
usr/share/icons/DMZ-White/cursors/left_side
usr/share/icons/DMZ-White/cursors/left_tee
usr/share/icons/DMZ-White/cursors/link
usr/share/icons/DMZ-White/cursors/ll_angle
usr/share/icons/DMZ-White/cursors/lr_angle
usr/share/icons/DMZ-White/cursors/move
usr/share/icons/DMZ-White/cursors/n-resize
usr/share/icons/DMZ-White/cursors/ne-resize
usr/share/icons/DMZ-White/cursors/nesw-resize
usr/share/icons/DMZ-White/cursors/not-allowed
usr/share/icons/DMZ-White/cursors/ns-resize
usr/share/icons/DMZ-White/cursors/nw-resize
usr/share/icons/DMZ-White/cursors/nwse-resize
usr/share/icons/DMZ-White/cursors/openhand
usr/share/icons/DMZ-White/cursors/pencil
usr/share/icons/DMZ-White/cursors/pirate
usr/share/icons/DMZ-White/cursors/plus
usr/share/icons/DMZ-White/cursors/pointer
usr/share/icons/DMZ-White/cursors/progress
usr/share/icons/DMZ-White/cursors/question_arrow
usr/share/icons/DMZ-White/cursors/right_ptr
usr/share/icons/DMZ-White/cursors/right_side
usr/share/icons/DMZ-White/cursors/right_tee
usr/share/icons/DMZ-White/cursors/row-resize
usr/share/icons/DMZ-White/cursors/s-resize
usr/share/icons/DMZ-White/cursors/sb_down_arrow
usr/share/icons/DMZ-White/cursors/sb_h_double_arrow
usr/share/icons/DMZ-White/cursors/sb_left_arrow
usr/share/icons/DMZ-White/cursors/sb_right_arrow
usr/share/icons/DMZ-White/cursors/sb_up_arrow
usr/share/icons/DMZ-White/cursors/sb_v_double_arrow
usr/share/icons/DMZ-White/cursors/se-resize
usr/share/icons/DMZ-White/cursors/size_bdiag
usr/share/icons/DMZ-White/cursors/size_fdiag
usr/share/icons/DMZ-White/cursors/size_hor
usr/share/icons/DMZ-White/cursors/size_ver
usr/share/icons/DMZ-White/cursors/sw-resize
usr/share/icons/DMZ-White/cursors/target
usr/share/icons/DMZ-White/cursors/tcross
usr/share/icons/DMZ-White/cursors/text
usr/share/icons/DMZ-White/cursors/top_left_arrow
usr/share/icons/DMZ-White/cursors/top_left_corner
usr/share/icons/DMZ-White/cursors/top_right_corner
usr/share/icons/DMZ-White/cursors/top_side
usr/share/icons/DMZ-White/cursors/top_tee
usr/share/icons/DMZ-White/cursors/ul_angle
usr/share/icons/DMZ-White/cursors/ur_angle
usr/share/icons/DMZ-White/cursors/v_double_arrow
usr/share/icons/DMZ-White/cursors/w-resize
usr/share/icons/DMZ-White/cursors/wait
usr/share/icons/DMZ-White/cursors/watch
usr/share/icons/DMZ-White/cursors/xterm
usr/share/licenses/
usr/share/licenses/xcursor-dmz/
usr/share/licenses/xcursor-dmz/LICENSE

View File

@ -0,0 +1,97 @@
#include "acutest.h"
#include "vieter_package_internal.h"
void test_info_parse() {
FILE *f = fopen("./test/package/.PKGINFO", "r");
TEST_ASSERT_(f != NULL, "could not find test .PKGINFO file in ./test/package ");
fseek(f, 0L, SEEK_END);
size_t size = ftell(f);
fflush(stdout);
rewind(f);
char *pkg_info_str = malloc(size + 1);
fread(pkg_info_str, 1, size, f);
pkg_info_str[size] = '\0';
fclose(f);
vieter_package_info *pkg_info = vieter_package_info_init();
vieter_package_info_parse(pkg_info, pkg_info_str);
TEST_CHECK(!strcmp(pkg_info->name, "xcursor-dmz"));
TEST_CHECK(!strcmp(pkg_info->base, "xcursor-dmz"));
TEST_CHECK(!strcmp(pkg_info->version, "0.4.5-2"));
TEST_CHECK(!strcmp(pkg_info->description, "Style neutral, scalable cursor theme"));
TEST_CHECK(!strcmp(pkg_info->url, "https://packages.debian.org/sid/dmz-cursor-theme"));
TEST_CHECK(pkg_info->build_date == 1673751613);
TEST_CHECK(!strcmp(pkg_info->packager, "Unknown Packager"));
TEST_CHECK(pkg_info->size == 3469584);
TEST_CHECK(!strcmp(pkg_info->arch, "any"));
TEST_CHECK(!strcmp(pkg_info->licenses->array[0], "MIT"));
TEST_CHECK(!strcmp(pkg_info->replaces->array[0], "test1"));
TEST_CHECK(!strcmp(pkg_info->groups->array[0], "x11"));
TEST_CHECK(!strcmp(pkg_info->conflicts->array[0], "test2"));
TEST_CHECK(!strcmp(pkg_info->conflicts->array[1], "test3"));
TEST_CHECK(!strcmp(pkg_info->provides->array[0], "test4"));
TEST_CHECK(!strcmp(pkg_info->depends->array[0], "test5"));
TEST_CHECK(!strcmp(pkg_info->depends->array[1], "test6"));
TEST_CHECK(!strcmp(pkg_info->optdepends->array[0], "test7"));
TEST_CHECK(!strcmp(pkg_info->makedepends->array[0], "xorg-xcursorgen"));
TEST_CHECK(!strcmp(pkg_info->checkdepends->array[0], "test8"));
free(pkg_info_str);
vieter_package_info_free(pkg_info);
}
void test_pkg_read_archive_files() {
vieter_package *pkg = vieter_package_init();
vieter_package_error e = vieter_package_read_archive(pkg, "./test/package/xcursor-dmz-0.4.5-2-any.pkg.tar.zst");
TEST_ASSERT_(e == vieter_package_ok, "failure parsing pkg archive");
FILE *f = fopen("./test/package/files", "r");
TEST_ASSERT_(f != NULL, "could not find test files file in ./test/package");
char buff[128];
size_t i = 0;
while ((fgets(buff, 128, f)) != NULL || i < pkg->files->size) {
if (buff[strlen(buff) - 1] == '\n') {
buff[strlen(buff) - 1] = '\0';
}
TEST_CHECK_(!strcmp(pkg->files->array[i], buff), "%s != %s", pkg->files->array[i], buff);
i++;
}
TEST_CHECK(pkg->compression = 14);
vieter_package_free(&pkg);
}
void test_pkg_read_archive_desc() {
vieter_package *pkg = vieter_package_init();
vieter_package_error e = vieter_package_read_archive(pkg, "./test/package/xcursor-dmz-0.4.5-2-any.pkg.tar.zst");
TEST_ASSERT_(e == vieter_package_ok, "failure parsing pkg archive");
char *description = vieter_package_to_description(pkg);
FILE *f = fopen("./test/package/desc", "r");
TEST_ASSERT_(f != NULL, "could not find test desc file in ./test/package");
fseek(f, 0, SEEK_END);
size_t size = ftell(f);
rewind(f);
char *desc = malloc(size + 1);
fread(desc, 1, size, f);
desc[size] = '\0';
fclose(f);
TEST_CHECK(!strcmp(description, desc));
vieter_package_free(&pkg);
free(description);
free(desc);
}
TEST_LIST = {
{".PKGINFO parse", test_info_parse},
{"files array creation", test_pkg_read_archive_files},
{"desc file creation", test_pkg_read_archive_desc},
{NULL, NULL}
};

34
thirdparty/include/sha256.h vendored 100644
View File

@ -0,0 +1,34 @@
/*********************************************************************
* Filename: sha256.h
* Author: Brad Conte (brad AT bradconte.com)
* Copyright:
* Disclaimer: This code is presented "as is" without any guarantees.
* Details: Defines the API for the corresponding SHA1 implementation.
*********************************************************************/
#ifndef SHA256_H
#define SHA256_H
/*************************** HEADER FILES ***************************/
#include <stddef.h>
/****************************** MACROS ******************************/
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
/**************************** DATA TYPES ****************************/
typedef unsigned char BYTE; // 8-bit byte
typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines
typedef struct {
BYTE data[64];
WORD datalen;
unsigned long long bitlen;
WORD state[8];
} SHA256_CTX;
/*********************** FUNCTION DECLARATIONS **********************/
void sha256_init(SHA256_CTX *ctx);
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len);
void sha256_final(SHA256_CTX *ctx, BYTE hash[]);
#endif // SHA256_H

158
thirdparty/src/sha256.c vendored 100644
View File

@ -0,0 +1,158 @@
/*********************************************************************
* Filename: sha256.c
* Author: Brad Conte (brad AT bradconte.com)
* Copyright:
* Disclaimer: This code is presented "as is" without any guarantees.
* Details: Implementation of the SHA-256 hashing algorithm.
SHA-256 is one of the three algorithms in the SHA2
specification. The others, SHA-384 and SHA-512, are not
offered in this implementation.
Algorithm specification can be found here:
* http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf
This implementation uses little endian byte order.
*********************************************************************/
/*************************** HEADER FILES ***************************/
#include <stdlib.h>
#include <memory.h>
#include "sha256.h"
/****************************** MACROS ******************************/
#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
/**************************** VARIABLES *****************************/
static const WORD k[64] = {
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
};
/*********************** FUNCTION DEFINITIONS ***********************/
void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
{
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
for (i = 0, j = 0; i < 16; ++i, j += 4)
m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
for ( ; i < 64; ++i)
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
a = ctx->state[0];
b = ctx->state[1];
c = ctx->state[2];
d = ctx->state[3];
e = ctx->state[4];
f = ctx->state[5];
g = ctx->state[6];
h = ctx->state[7];
for (i = 0; i < 64; ++i) {
t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
t2 = EP0(a) + MAJ(a,b,c);
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
ctx->state[0] += a;
ctx->state[1] += b;
ctx->state[2] += c;
ctx->state[3] += d;
ctx->state[4] += e;
ctx->state[5] += f;
ctx->state[6] += g;
ctx->state[7] += h;
}
void sha256_init(SHA256_CTX *ctx)
{
ctx->datalen = 0;
ctx->bitlen = 0;
ctx->state[0] = 0x6a09e667;
ctx->state[1] = 0xbb67ae85;
ctx->state[2] = 0x3c6ef372;
ctx->state[3] = 0xa54ff53a;
ctx->state[4] = 0x510e527f;
ctx->state[5] = 0x9b05688c;
ctx->state[6] = 0x1f83d9ab;
ctx->state[7] = 0x5be0cd19;
}
void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
{
WORD i;
for (i = 0; i < len; ++i) {
ctx->data[ctx->datalen] = data[i];
ctx->datalen++;
if (ctx->datalen == 64) {
sha256_transform(ctx, ctx->data);
ctx->bitlen += 512;
ctx->datalen = 0;
}
}
}
void sha256_final(SHA256_CTX *ctx, BYTE hash[])
{
WORD i;
i = ctx->datalen;
// Pad whatever data is left in the buffer.
if (ctx->datalen < 56) {
ctx->data[i++] = 0x80;
while (i < 56)
ctx->data[i++] = 0x00;
}
else {
ctx->data[i++] = 0x80;
while (i < 64)
ctx->data[i++] = 0x00;
sha256_transform(ctx, ctx->data);
memset(ctx->data, 0, 56);
}
// Append to the padding the total message's length in bits and transform.
ctx->bitlen += ctx->datalen * 8;
ctx->data[63] = ctx->bitlen;
ctx->data[62] = ctx->bitlen >> 8;
ctx->data[61] = ctx->bitlen >> 16;
ctx->data[60] = ctx->bitlen >> 24;
ctx->data[59] = ctx->bitlen >> 32;
ctx->data[58] = ctx->bitlen >> 40;
ctx->data[57] = ctx->bitlen >> 48;
ctx->data[56] = ctx->bitlen >> 56;
sha256_transform(ctx, ctx->data);
// Since this implementation uses little endian byte ordering and SHA uses big endian,
// reverse all the bytes when copying the final state to the output hash.
for (i = 0; i < 4; ++i) {
hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
}
}