+static void removepreload(void) {
+ const char *myself, *found;
+ char *newval, *preload;
+ int lpreload, lmyself, before, after;
+
+ preload= getenv(PRELOAD_VAR);
+ myself= getenv(AUTHBINDLIB_VAR);
+ if (!myself || !preload) return;
+
+ lpreload= strlen(preload);
+ lmyself= strlen(myself);
+
+ if (lmyself < 1 || lpreload<lmyself) return;
+ if (lpreload==lmyself) {
+ if (!strcmp(preload,myself)) unsetenv(PRELOAD_VAR);
+ return;
+ }
+ if (!memcmp(preload,myself,lmyself) && preload[lmyself]==':') {
+ before= 0; after= lpreload-(lmyself+1);
+ } else if (!memcmp(preload+lpreload-lmyself,myself,lmyself) &&
+ preload[lpreload-(lmyself+1)]==':') {
+ before= lpreload-(lmyself+1); after= 0;
+ } else {
+ if (lpreload<lmyself+2) return;
+ found= preload+1;
+ for (;;) {
+ found= strstr(found,myself); if (!found) return;
+ if (found > preload+lpreload-(lmyself+1)) return;
+ if (found[-1]==':' && found[lmyself]==':') break;
+ found++;
+ }
+ before= found-preload;
+ after= lpreload-(before+lmyself+1);
+ }
+ newval= malloc(before+after+1);
+ if (newval) {
+ memcpy(newval,preload,before);
+ strcpy(newval+before,preload+lpreload-after);
+ if (setenv(PRELOAD_VAR,newval,1)) return;
+ free(newval);
+ }
+ strcpy(preload+before,preload+lpreload-after);
+ return;
+}
+
+int _init(void);
+int _init(void) {
+ char *levels;
+ int levelno;
+
+ /* If AUTHBIND_LEVELS is
+ * unset => always strip from preload
+ * set and starts with `y' => never strip from preload, keep AUTHBIND_LEVELS
+ * set to integer > 1 => do not strip now, subtract one from AUTHBIND_LEVELS
+ * set to integer 1 => do not strip now, unset AUTHBIND_LEVELS
+ * set to empty string or 0 => strip now, unset AUTHBIND_LEVELS
+ */
+ levels= getenv(AUTHBIND_LEVELS_VAR);
+ if (levels) {
+ if (levels[0]=='y') return 0;
+ levelno= atoi(levels);
+ if (levelno > 0) {
+ levelno--;
+ if (levelno > 0) sprintf(levels,"%d",levelno);
+ else unsetenv(AUTHBIND_LEVELS_VAR);
+ return 0;
+ }
+ unsetenv(AUTHBIND_LEVELS_VAR);
+ }
+ removepreload();
+ return 0;
+}
+
+static const int evilsignals[]= { SIGFPE, SIGILL, SIGSEGV, SIGBUS, 0 };
+