cleanup ecdsa
This commit is contained in:
		
							parent
							
								
									59482e53da
								
							
						
					
					
						commit
						993f043463
					
				| @ -1,20 +0,0 @@ | ||||
| include $(TOPDIR)/rules.mk | ||||
| 
 | ||||
| PKG_NAME:=gluon-lib-ecdsa | ||||
| PKG_VERSION=1 | ||||
| 
 | ||||
| include ../gluon.mk | ||||
| 
 | ||||
| define Package/gluon-lib-ecdsa | ||||
|   TITLE:=Lua bindings for ecdsautil | ||||
|   DEPENDS:=+liblua +libecdsautil | ||||
| endef | ||||
| 
 | ||||
| define Package/gluon-lib-ecdsa/install | ||||
| 	$(Gluon/Build/Install) | ||||
| 
 | ||||
| 	$(INSTALL_DIR) $(1)/usr/lib/lua/gluon | ||||
| 	$(INSTALL_BIN) $(PKG_BUILD_DIR)/ecdsa.so $(1)/usr/lib/lua/gluon/ | ||||
| endef | ||||
| 
 | ||||
| $(eval $(call BuildPackageGluon,gluon-lib-ecdsa)) | ||||
| @ -1,22 +0,0 @@ | ||||
| CFLAGS  += -Wall -fPIC | ||||
| LDFLAGS += -llua -lm | ||||
| OBJ = hexutil.o ecdsa_util.o util.c ecdsa.o | ||||
| LIB = ecdsa.so | ||||
| 
 | ||||
| CFLAGS += $(shell pkg-config --cflags ecdsautil) | ||||
| LDFLAGS += $(shell pkg-config --libs ecdsautil) | ||||
| 
 | ||||
| %.o: %.c | ||||
| 	$(CC) $(CPPFLAGS) $(CFLAGS) $(LUA_CFLAGS) $(CFLAGS) $(FPIC) -c -o $@ $< | ||||
| 
 | ||||
| all: compile | ||||
| 
 | ||||
| compile: $(OBJ) | ||||
| 	$(CC) $(LDFLAGS) -fPIC -shared -o $(LIB) $(OBJ) $(LDFLAGS) | ||||
| 
 | ||||
| install: compile | ||||
| 	mkdir -p $(DESTDIR)/usr/lib/lua/gluon | ||||
| 	cp $(LIB) $(DESTDIR)/usr/lib/lua/gluon/$(LIB) | ||||
| 
 | ||||
| clean: | ||||
| 	rm -f *.o *.so | ||||
| @ -1,73 +0,0 @@ | ||||
| /*
 | ||||
| Copyright 2021 Maciej Krüger <maciej@xeredo.it> | ||||
| 
 | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
| 
 | ||||
| 	http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| 
 | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| #define _GNU_SOURCE | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <string.h> | ||||
| #include <limits.h> | ||||
| 
 | ||||
| #include <lua.h> | ||||
| #include <lualib.h> | ||||
| #include <lauxlib.h> | ||||
| 
 | ||||
| #include "ecdsa_util.h" | ||||
| 
 | ||||
| #define ECDSA "gluon.ecdsa" | ||||
| 
 | ||||
| // TODO: fix all the memory leaks
 | ||||
| 
 | ||||
| static bool verify(lua_State *L, const char *data, const char *sig, const char *key) { | ||||
| 	struct verify_params params = { | ||||
| 		.good_signatures = 1 | ||||
| 	}; | ||||
| 
 | ||||
| 	if (!hash_data(¶ms, data)) { | ||||
| 		return luaL_error(L, "failed hashing data"); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!load_signatures(¶ms, 1, &sig, false)) { | ||||
| 		return luaL_error(L, "failed loading signature"); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!load_pubkeys(¶ms, 1, &key, false)) { | ||||
| 		return luaL_error(L, "failed loading key"); | ||||
| 	} | ||||
| 
 | ||||
| 	return do_verify(¶ms); | ||||
| } | ||||
| 
 | ||||
| static int lua_verify(lua_State *L) { | ||||
| 	lua_pushboolean(L, verify(L, luaL_checkstring(L, 1), luaL_checkstring(L, 2), luaL_checkstring(L, 3))); | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static const luaL_reg ecdsa_methods[] = { | ||||
| 	{ "verify",			lua_verify          }, | ||||
| 
 | ||||
| 	{ } | ||||
| }; | ||||
| 
 | ||||
| int luaopen_gluon_ecdsa(lua_State *L) | ||||
| { | ||||
| 	luaL_register(L, ECDSA, ecdsa_methods); | ||||
| 
 | ||||
| 	return 1; | ||||
| } | ||||
| @ -1,92 +0,0 @@ | ||||
| #include "ecdsa_util.h" | ||||
| #include "hexutil.h" | ||||
| #include "util.h" | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <string.h> | ||||
| #include <limits.h> | ||||
| 
 | ||||
| bool do_verify(struct verify_params* params) { | ||||
| 	ecdsa_verify_context_t ctxs[params->n_signatures]; | ||||
| 	for (size_t i = 0; i < params->n_signatures; i++) | ||||
| 		ecdsa_verify_prepare_legacy(&ctxs[i], ¶ms->hash, ¶ms->signatures[i]); | ||||
| 
 | ||||
| 	long unsigned int good_signatures = ecdsa_verify_list_legacy(ctxs, params->n_signatures, params->pubkeys, params->n_pubkeys); | ||||
| 
 | ||||
| 	if (good_signatures < params->good_signatures) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| int hash_data(struct verify_params* params, const char* data) { | ||||
|   ecdsa_sha256_context_t hash_ctx; | ||||
|   ecdsa_sha256_init(&hash_ctx); | ||||
|   ecdsa_sha256_update(&hash_ctx, data, strlen(data)); | ||||
| 
 | ||||
|   ecdsa_sha256_final(&hash_ctx, params->hash.p); | ||||
| 
 | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| int load_pubkeys(struct verify_params* params, const size_t n_pubkeys, const char **pubkeys_str, const bool ignore_pubkeys) { | ||||
|   params->pubkeys = safe_malloc(n_pubkeys * sizeof(ecc_25519_work_t)); | ||||
| 
 | ||||
| 	size_t ignored_keys = 0; | ||||
| 
 | ||||
| 	for (size_t i = 0; i < n_pubkeys; i++) { | ||||
| 		ecc_int256_t pubkey_packed; | ||||
| 		if (!pubkeys_str[i]) | ||||
| 			goto pubkey_fail; | ||||
| 		if (!parsehex(pubkey_packed.p, pubkeys_str[i], 32)) | ||||
| 			goto pubkey_fail; | ||||
| 		if (!ecc_25519_load_packed_legacy(¶ms->pubkeys[i-ignored_keys], &pubkey_packed)) | ||||
| 			goto pubkey_fail; | ||||
| 		if (!ecdsa_is_valid_pubkey(¶ms->pubkeys[i-ignored_keys])) | ||||
| 			goto pubkey_fail; | ||||
| 		continue; | ||||
| 
 | ||||
| pubkey_fail: | ||||
| 		if (ignore_pubkeys) { | ||||
| 			fprintf(stderr, "warning: ignoring invalid public key %s\n", pubkeys_str[i]); | ||||
| 			ignored_keys++; | ||||
| 		} else { | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	params->n_pubkeys = n_pubkeys - ignored_keys; | ||||
| 
 | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| int load_signatures(struct verify_params* params, const size_t n_signatures, const char **signatures_str, const bool ignore_signatures) { | ||||
| 	params->signatures = safe_malloc(n_signatures * sizeof(ecdsa_signature_t)); | ||||
| 
 | ||||
|   size_t ignored_signatures = 0; | ||||
| 
 | ||||
| 	for (size_t i = 0; i < n_signatures; i++) { | ||||
| 		if (!signatures_str[i]) | ||||
| 			goto signature_fail; | ||||
| 		if (!parsehex(¶ms->signatures[i-ignored_signatures], signatures_str[i], 64)) | ||||
| 			goto signature_fail; | ||||
| 		continue; | ||||
| 
 | ||||
| signature_fail: | ||||
| 		if (ignore_signatures) { | ||||
| 			fprintf(stderr, "warning: ignoring invalid signature %s\n", signatures_str[i]); | ||||
| 			ignored_signatures++; | ||||
| 		} else { | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	params->n_signatures = n_signatures - ignored_signatures; | ||||
| 
 | ||||
| 	return 1; | ||||
| } | ||||
| @ -1,19 +0,0 @@ | ||||
| #include <ecdsautil/ecdsa.h> | ||||
| #include <ecdsautil/sha256.h> | ||||
| 
 | ||||
| struct verify_params { | ||||
|   ecc_int256_t hash; | ||||
| 
 | ||||
| 	size_t n_signatures; | ||||
| 	ecdsa_signature_t *signatures; | ||||
| 
 | ||||
| 	size_t n_pubkeys; | ||||
| 	ecc_25519_work_t *pubkeys; | ||||
| 
 | ||||
| 	unsigned long good_signatures; | ||||
| }; | ||||
| 
 | ||||
| bool do_verify(struct verify_params* params); | ||||
| int hash_data(struct verify_params* params, const char* data); | ||||
| int load_pubkeys(struct verify_params* params, const size_t n_pubkeys, const char **pubkeys_str, const bool ignore_pubkeys); | ||||
| int load_signatures(struct verify_params* params, const size_t n_signatures, const char **signatures_str, const bool ignore_signatures); | ||||
| @ -1,58 +0,0 @@ | ||||
| /*
 | ||||
|   Copyright (c) 2012, Nils Schneider <nils@nilsschneider.net> | ||||
|   All rights reserved. | ||||
| 
 | ||||
|   Redistribution and use in source and binary forms, with or without | ||||
|   modification, are permitted provided that the following conditions are met: | ||||
| 
 | ||||
|     1. Redistributions of source code must retain the above copyright notice, | ||||
|        this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright notice, | ||||
|        this list of conditions and the following disclaimer in the documentation | ||||
|        and/or other materials provided with the distribution. | ||||
| 
 | ||||
|   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
|   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
|   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
|   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
|   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
|   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| */ | ||||
| 
 | ||||
| #include "hexutil.h" | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| int parsehex(void *buffer, const char *string, size_t len) { | ||||
|   // number of digits must be even
 | ||||
|   if ((strlen(string) & 1) == 1) | ||||
|     return 0; | ||||
| 
 | ||||
|   // number of digits must be 2 * len
 | ||||
|   if (strlen(string) != 2 * len) | ||||
|     return 0; | ||||
| 
 | ||||
|   while (len--) { | ||||
|     int ret; | ||||
|     ret = sscanf(string, "%02hhx", (char*)(buffer++)); | ||||
|     string += 2; | ||||
| 
 | ||||
|     if (ret != 1) | ||||
|       break; | ||||
|   } | ||||
| 
 | ||||
|   if (len != -1) | ||||
|     return 0; | ||||
| 
 | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| void hexdump(FILE *stream, unsigned char *buffer, size_t len) { | ||||
|   while (len--) | ||||
|     fprintf(stream, "%02hhx", *(buffer++)); | ||||
| } | ||||
| @ -1,38 +0,0 @@ | ||||
| /*
 | ||||
|   Copyright (c) 2012, Nils Schneider <nils@nilsschneider.net> | ||||
|   All rights reserved. | ||||
| 
 | ||||
|   Redistribution and use in source and binary forms, with or without | ||||
|   modification, are permitted provided that the following conditions are met: | ||||
| 
 | ||||
|     1. Redistributions of source code must retain the above copyright notice, | ||||
|        this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright notice, | ||||
|        this list of conditions and the following disclaimer in the documentation | ||||
|        and/or other materials provided with the distribution. | ||||
| 
 | ||||
|   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
|   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
|   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
|   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
|   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
|   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| */ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| 
 | ||||
| /* Converts a string of hexadecimal digits and stores it in a given buffer.
 | ||||
|  * In order for this function to return successfully the decoded string | ||||
|  * must fit exactly into the buffer. | ||||
|  */ | ||||
| int parsehex(void *buffer, const char *string, size_t len); | ||||
| 
 | ||||
| /* Converts a byte array to a hexadecimal string.
 | ||||
|  */ | ||||
| void hexdump(FILE *stream, unsigned char *buffer, size_t len); | ||||
| @ -1,122 +0,0 @@ | ||||
| /*
 | ||||
|   Copyright (c) 2017, Jan-Philipp Litza <janphilipp@litza.de> | ||||
|   All rights reserved. | ||||
| 
 | ||||
|   Redistribution and use in source and binary forms, with or without | ||||
|   modification, are permitted provided that the following conditions are met: | ||||
| 
 | ||||
|     1. Redistributions of source code must retain the above copyright notice, | ||||
|        this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright notice, | ||||
|        this list of conditions and the following disclaimer in the documentation | ||||
|        and/or other materials provided with the distribution. | ||||
| 
 | ||||
|   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
|   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
|   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
|   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
|   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
|   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| */ | ||||
| 
 | ||||
| 
 | ||||
| #include "util.h" | ||||
| 
 | ||||
| #include <fcntl.h> | ||||
| #include <glob.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <time.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include <sys/wait.h> | ||||
| 
 | ||||
| 
 | ||||
| void run_dir(const char *dir) { | ||||
| 	char pat[strlen(dir) + 3]; | ||||
| 	sprintf(pat, "%s/*", dir); | ||||
| 	glob_t globbuf; | ||||
| 	if (glob(pat, 0, NULL, &globbuf)) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (size_t i = 0; i < globbuf.gl_pathc; i++) { | ||||
| 		char *path = globbuf.gl_pathv[i]; | ||||
| 		if (access(path, X_OK) < 0) | ||||
| 			continue; | ||||
| 
 | ||||
| 		pid_t pid = fork(); | ||||
| 		if (pid < 0) { | ||||
| 			fputs("autoupdater: warning: failed to fork: %m", stderr); | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		if (pid == 0) { | ||||
| 			execl(path, path, (char *)NULL); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 
 | ||||
| 		int wstatus; | ||||
| 		if (waitpid(pid, &wstatus, 0) != pid) { | ||||
| 			fprintf(stderr, "autoupdater: warning: failed waiting for child %d corresponding to %s: ", pid, path); | ||||
| 			perror(NULL); | ||||
| 		} else if (!WIFEXITED(wstatus)) { | ||||
| 			fprintf(stderr, "autoupdater: warning: execution of %s exited abnormally\n", path); | ||||
| 		} else if (WEXITSTATUS(wstatus)) { | ||||
| 			fprintf(stderr, "autoupdater: warning: execution of %s exited with status code %d\n", path, WEXITSTATUS(wstatus)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	globfree(&globbuf); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void randomize(void) { | ||||
| 	struct timespec tv; | ||||
| 	if (clock_gettime(CLOCK_MONOTONIC, &tv)) { | ||||
| 		perror("autoupdater: error: clock_gettime"); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 
 | ||||
| 	srandom(tv.tv_nsec); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| float get_uptime(void) { | ||||
| 	FILE *f = fopen("/proc/uptime", "r"); | ||||
| 	if (f) { | ||||
| 		float uptime; | ||||
| 		int match = fscanf(f, "%f", &uptime); | ||||
| 		fclose(f); | ||||
| 
 | ||||
| 		if (match == 1) | ||||
| 			return uptime; | ||||
| 	} | ||||
| 
 | ||||
| 	fputs("autoupdater: error: unable to determine uptime\n", stderr); | ||||
| 	exit(1); | ||||
| } | ||||
| 
 | ||||
| void * safe_malloc(size_t size) { | ||||
| 	void *ret = malloc(size); | ||||
| 	if (!ret) { | ||||
| 		fprintf(stderr, "autoupdater: error: failed to allocate memory\n"); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void * safe_realloc(void *ptr, size_t size) { | ||||
| 	void *ret = realloc(ptr, size); | ||||
| 	if (!ret) { | ||||
| 		fprintf(stderr, "autoupdater: error: failed to allocate memory\n"); | ||||
| 		abort(); | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| @ -1,35 +0,0 @@ | ||||
| /*
 | ||||
|   Copyright (c) 2017, Jan-Philipp Litza <janphilipp@litza.de> | ||||
|   All rights reserved. | ||||
| 
 | ||||
|   Redistribution and use in source and binary forms, with or without | ||||
|   modification, are permitted provided that the following conditions are met: | ||||
| 
 | ||||
|     1. Redistributions of source code must retain the above copyright notice, | ||||
|        this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright notice, | ||||
|        this list of conditions and the following disclaimer in the documentation | ||||
|        and/or other materials provided with the distribution. | ||||
| 
 | ||||
|   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
|   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
|   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
|   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
|   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
|   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
|   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
|   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
| */ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <stddef.h> | ||||
| 
 | ||||
| 
 | ||||
| void run_dir(const char *dir); | ||||
| void randomize(void); | ||||
| float get_uptime(void); | ||||
| 
 | ||||
| void * safe_malloc(size_t size); | ||||
| void * safe_realloc(void *ptr, size_t size); | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user