diff --git a/apps/ocspcheck/CMakeLists.txt b/apps/ocspcheck/CMakeLists.txt index 9cf7a8b..67ace03 100644 --- a/apps/ocspcheck/CMakeLists.txt +++ b/apps/ocspcheck/CMakeLists.txt @@ -4,6 +4,20 @@ set( ocspcheck.c ) +check_function_exists(getopt HAVE_GETOPT) +if(HAVE_GETOPT) + add_definitions(-DHAVE_GETOPT) +else() + set(GETOPT_SRC compat/getopt.c) +endif() + +check_function_exists(ftruncate HAVE_FTRUNCATE) +if(HAVE_FTRUNCATE) + add_definitions(-DHAVE_FTRUNCATE) +else() + set(FTRUNCATE_SRC compat/ftruncate.c) +endif() + check_function_exists(memmem HAVE_MEMMEM) if(HAVE_MEMMEM) add_definitions(-DHAVE_MEMMEM) @@ -17,7 +31,7 @@ else() add_definitions(-DDEFAULT_CA_FILE=\"${CMAKE_INSTALL_PREFIX}/etc/ssl/cert.pem\") endif() -add_executable(ocspcheck ${OCSPCHECK_SRC}) +add_executable(ocspcheck ${OCSPCHECK_SRC} ${GETOPT_SRC} ${FTRUNCATE_SRC}) target_include_directories(ocspcheck PRIVATE ../../include/compat diff --git a/apps/ocspcheck/ocspcheck.c b/apps/ocspcheck/ocspcheck.c index 516642b..3afb68b 100644 --- a/apps/ocspcheck/ocspcheck.c +++ b/apps/ocspcheck/ocspcheck.c @@ -561,6 +561,10 @@ main(int argc, char **argv) ssize_t written, w; short port; +#ifndef HAVE_GETOPT +#include "getopt.h" +#endif + while ((ch = getopt(argc, argv, "C:i:No:v")) != -1) { switch (ch) { case 'C': diff --git a/apps/ocspcheck/compat/ftruncate.c b/apps/ocspcheck/compat/ftruncate.c new file mode 100644 index 0000000..e825e50 --- /dev/null +++ b/apps/ocspcheck/compat/ftruncate.c @@ -0,0 +1,17 @@ +/* + * Public domain + * + * Kinichiro Inoguchi + */ + +#ifdef _WIN32 + +#include + +int +ftruncate(int fd, off_t length) +{ + return _chsize(fd, length); +} + +#endif diff --git a/apps/ocspcheck/compat/getopt.c b/apps/ocspcheck/compat/getopt.c new file mode 100644 index 0000000..ff05743 --- /dev/null +++ b/apps/ocspcheck/compat/getopt.c @@ -0,0 +1,131 @@ +/* + * Public domain + * + * EternalPhane + */ + +#include +#include + +#include "getopt.h" + +char *optarg = NULL; +int optind = 0, optopt = '?'; + +typedef int bool; +#define true 1 +#define false 0 + +static int nonopt_begin = 0, nonopt_end = 0; + +void clear_buf(); + +void permute(char *const argv[]) +{ + static char* buf = NULL; + if (!argv && buf) + return free(buf); + if (!buf) + atexit(clear_buf); + if (nonopt_begin == nonopt_end) + { + nonopt_begin = nonopt_end = optind; + return; + } + int nonopt_size = nonopt_end - nonopt_begin, + opt_size = optind - nonopt_end; + if (nonopt_size <= opt_size) + { + if (!realloc(buf, nonopt_size)) + free(buf), buf = malloc(nonopt_size); + memcpy(buf, nonopt_begin, nonopt_size); + memmove(nonopt_begin, nonopt_end, opt_size); + memcpy(nonopt_begin + opt_size, buf, nonopt_size); + } + else + { + if (!realloc(buf, opt_size)) + free(buf), buf = malloc(opt_size); + memcpy(buf, nonopt_end, opt_size); + memmove(nonopt_begin + opt_size, nonopt_begin, nonopt_size); + memcpy(nonopt_begin, buf, opt_size); + } + nonopt_begin += opt_size; + nonopt_end = optind; +} + +void clear_buf() +{ + permute(NULL); +} + +int getopt(int argc, char *const argv[], const char *optstring) +{ + static char *nextchar = NULL; + static bool posixly_correct = false, always_return_nonopt = false; + if (optind >= argc) + return -1; + if (!optind) + { + nonopt_begin = nonopt_end = 0; + posixly_correct = '+' == optstring[0] || getenv("POSIXLY_CORRECT"); + always_return_nonopt = '-' == optstring[0]; + if (posixly_correct || always_return_nonopt) + optstring++; + } + if (!nextchar || !*nextchar) + { + if (!posixly_correct && !always_return_nonopt) + { + int temp = optind++; + for (;;) + { + if (++temp >= argc || !strcmp("--", argv[temp])) + { + permute(argv); + if (temp < argc) + { + optind = temp + 1; + permute(argv); + } + optind = nonopt_begin; + return -1; + } + if ('-' == argv[temp][0] && argv[temp][1]) + break; + } + if (temp > optind) + { + permute(argv); + nonopt_end = optind = temp; + } + nextchar = argv[optind] + 1; + } + else + { + if (++optind >= argc || !strcmp("--", argv[optind])) + return -1; + if ('-' != argv[optind][0] || !argv[optind][1]) + return posixly_correct ? -1 : (optarg = argv[optind++], 1); + } + } + const char *temp = strchr(optstring, *nextchar++); + if (!temp) + return optopt = *(nextchar - 1), '?'; + if (':' == temp[1]) + { + bool err = false; + if (':' == temp[2]) + optarg = *nextchar ? nextchar : NULL; + else if (*nextchar) + optarg = nextchar; + else if ('-' != argv[++optind][0]) + optarg = argv[optind]; + else + return nextchar = argv[optind] + 1, + optopt = *temp, + ':' == optstring[0] ? ':' : '?'; + nextchar += strlen(nextchar); + } + return *temp; +} diff --git a/apps/ocspcheck/compat/getopt.h b/apps/ocspcheck/compat/getopt.h new file mode 100644 index 0000000..ada142e --- /dev/null +++ b/apps/ocspcheck/compat/getopt.h @@ -0,0 +1,15 @@ +/* + * Public domain + * + * EternalPhane + */ + +#ifndef GETOPT_H__ +#define GETOPT_H__ + +extern char *optarg; +extern int optind, opterr, optopt; + +int getopt(int argc, char *const argv[], const char *optstring); + +#endif \ No newline at end of file