Compare commits
	
		
			25 Commits 
		
	
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | 1f9bd26ae5 | |
|  | 19c5515c5e | |
|  | 96d07dfb54 | |
|  | ea852f9102 | |
|  | df83bf9fb3 | |
|  | e253e039c3 | |
|  | 46e7e093d9 | |
|  | b6d97df1bc | |
|  | 4c9b429eaa | |
|  | c7c4043108 | |
|  | 9211bc3351 | |
|  | bcae64e023 | |
|  | 03bae82569 | |
|  | 76e4adae92 | |
|  | 1ccd4101af | |
|  | bbdc2fbd6e | |
|  | d11a9d3638 | |
|  | d0914adbb5 | |
|  | fbbc15cf73 | |
|  | 660e711b17 | |
|  | 7561a74793 | |
|  | 01688fd546 | |
|  | edca243331 | |
|  | 4309ad8cc5 | |
|  | c2313fe0be | 
							
								
								
									
										15
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										15
									
								
								Makefile
								
								
								
								
							|  | @ -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) '$(SRC_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 | ||||
|  | @ -71,7 +80,7 @@ build-test: $(BINS_TEST) | |||
| 
 | ||||
| $(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
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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 | ||||
|  | @ -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 | ||||
|  | @ -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; | ||||
| } | ||||
|  | @ -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. | ||||
|  | @ -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; | ||||
| } | ||||
|  | @ -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); | ||||
| } | ||||
|  | @ -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 | ||||
|  | @ -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; | ||||
| }; | ||||
|  | @ -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 | ||||
|  | @ -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 | ||||
| 
 | ||||
|  | @ -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 | ||||
|  | @ -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} | ||||
| }; | ||||
										
											Binary file not shown.
										
									
								
							|  | @ -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
 | ||||
|  | @ -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; | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue