#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <sys/utsname.h>

typedef int (*uname_t)(struct utsname * buf);

static __thread uname_t orig_uname = NULL;

int uname(struct utsname *buf)
{
    int err;
    if (!orig_uname) {
        orig_uname = dlsym(RTLD_NEXT, "uname");
        if (!orig_uname) {
            fprintf(stderr, "Error loading original uname(): %s\n", dlerror());
            exit(-1);
        }
    }

    err = orig_uname(buf);
    if (err)
        return err;

    /* Fairly unsafe... */
    char * abi_s = strstr(buf->release, "-");
    if (!abi_s)
        return err;
    abi_s++;
    int abi = atoi(abi_s);
    if (abi <= 0) {
        fprintf(stderr, "WARNING: Unexpected kernel ABI number: %d (the uname wrapper only supports > 0)\n", abi);
        return err;
    }
    char * abi_s_end = strstr(abi_s, "-");
    if (!abi_s_end)
        return err;
    for (char* r_it = abi_s_end-1; r_it >= abi_s; r_it--) {
        if (*r_it != '0') {
            (*r_it)--;
            break;
        }
    }
    return 0;
}
