Created
October 31, 2014 03:18
-
-
Save fbriere/157693bb865eb0e43428 to your computer and use it in GitHub Desktop.
Simple uname(2) wrapper to work around a CrashPlan bug and enable real-time watching
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Simple uname(2) wrapper library that appends ".0" to any release version | |
* of the form X.Y -- for example, "3.16-2-amd64" becomes "3.16.0-2-amd64". | |
* | |
* This crude hack is meant to work around a CrashPlan bug[*]: real-time | |
* watching is only enabled after checking the kernel version for inotify | |
* support (which was added in 2.6.13), but the version is expected to be of | |
* the form X.Y.Z. If this is not the case, CrashPlan assumes that inotify | |
* is not supported, and real-time watching is disabled. | |
* | |
* [*] https://bugs.debian.org/745984 | |
* | |
* | |
* INSTRUCTIONS: | |
* | |
* 1. Compile (feel free to rename the .so): | |
* | |
* gcc -Wall -O2 -shared -fPIC -ldl crashplan_uname.c -o libcrashplan_uname.so | |
* | |
* 2. (Optional) Install the .so where it can be found by ld.so: | |
* | |
* mv libcrashplan_uname.so /usr/local/lib/ && ldconfig | |
* | |
* 3. Add the following line to CrashPlan's bin/run.conf: | |
* (You will need to provide a full pathname if you skipped step 2.) | |
* | |
* export LD_PRELOAD=libcrashplan_uname.so | |
* | |
* You can now (re-)start the CrashPlan engine. Enjoy! | |
*/ | |
#define _GNU_SOURCE /* RTLD_NEXT is a GNU feature */ | |
#include <dlfcn.h> /* dynamic linking */ | |
#include <sys/utsname.h> /* uname() itself */ | |
#include <ctype.h> /* isdigit() */ | |
#include <string.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
int uname (struct utsname *buf) { | |
/* real uname() function */ | |
static int (*real_uname) (struct utsname *buf); | |
int ret; | |
/* dlsym() error, if any */ | |
char *error; | |
/* We'll need to scan the release string, and maybe copy part of it */ | |
char *p, *tmp; | |
int n_dots = 0; | |
/* Find the real uname() if we haven't already written it down */ | |
if (!real_uname) { | |
real_uname = dlsym(RTLD_NEXT, "uname"); | |
if ((error = dlerror()) != NULL) { | |
fprintf(stderr, "%s\n", error); | |
exit(1); | |
} | |
} | |
ret = real_uname(buf); | |
/* No need to continue if there's not enough room for ".0" anyway */ | |
if (strlen(buf->release) + 2 >= sizeof(buf->release)) | |
return ret; | |
/* Counting the dots... (the field is guaranteed null-terminated) */ | |
for (p = buf->release; *p; p++) { | |
if (*p == '.') | |
n_dots++; | |
else if (! isdigit(*p)) | |
break; | |
} | |
if (n_dots < 2) { | |
/* (No need for strndup/strncpy -- we know everything fits) */ | |
tmp = strdup(p); | |
*p = '.'; p++; | |
*p = '0'; p++; | |
strcpy(p, tmp); | |
free(tmp); | |
} | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment