/* $Id: test-instalsentry.c,v 0.6.7.3 2001/12/14 00:06:05 gnao Exp $ */
/*
 * Copyright (C) 1998-99 Pancrazio `Ezio' de Mauro <p@demauro.net>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
/*
* Modifications by Gilbert Ashley <amigo@ibiblio.org>
* November 24 2007
*/

#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include <dlfcn.h>

#include "../localdefines.h"

#ifndef	LIBDIR 
	#define LIBDIR "/usr/local/lib"
#endif

#define ATFILE "at-testfile"
#define ATFILE2 ATFILE "2"

int *refcount;
int *timecount;
int passed, failed;
void* libc_handle=NULL;

void check_installsentry(void) {
	char *error;

	time(NULL);

	libc_handle=dlopen(LIBDIR"/installsentry.so",RTLD_LAZY);
	if(!libc_handle) {
		puts("Unable to open "LIBDIR"/installsentry.so");
		exit(255);
	}

	time(NULL);

	timecount=(int*)dlsym(libc_handle,"__installsentry_timecount");	
	if ((error = dlerror()) != NULL)  {
		fputs(error, stderr);
		exit(255);
	}

	if((*timecount)<2) {
		puts("This program must be run with installsentry");
		dlclose(libc_handle);
		exit(255);
	}

	refcount=(int*)dlsym(libc_handle,"__installsentry_refcount");	
	if ((error = dlerror()) != NULL)  {
		fputs(error, stderr);
		exit(255);
	}
}

#if(GLIBC_MINOR >= 4)

void test_openat(void) {
	int fd;
	int dfd;

	mkdir("/usr/local/test2", 0);
	
	dfd = open("/usr/local/test2", 0);
	fd = openat(dfd, ATFILE, O_CREAT, O_RDWR, 0700);
	/* close(dfd); */
	unlinkat(dfd, ATFILE, 0);
	close(dfd);
}

#endif

int do_test(const char *name, void (*function)(void), int increment) {
	int old_refcount;
	
	printf("Testing %s... ", name);
	old_refcount = *refcount;
	function();
	if(*refcount == old_refcount + increment) {
		printf("wanted refcount=%d returned refcount=%d",
			(old_refcount+increment),*refcount);
		puts("passed");
		passed++;
		return 0;
	} else {
		printf("wanted refcount=%d returned refcount=%d",
			(old_refcount+increment),*refcount);
	        puts("failed");
		failed++;
		return 1;
	}
}

int main(int argc, char **argv) {
	struct stat statbuf;

	check_installsentry();

	if(stat(ATFILE, &statbuf) != -1) {
		printf(ATFILE " already exists. Please remove it and run %s again\n", argv[0]);
		exit(254);
	}
	if(stat(ATFILE2, &statbuf) != -1) {
		printf(ATFILE2 " already exists. Please remove it and run %s again\n", argv[0]);
		exit(254);
	}
	puts("Testing installsentry " VERSION);
	puts("Using " ATFILE " and " ATFILE2 " as a test files\n");
	passed = failed = 0;
#if(GLIBC_MINOR >= 4)
	
	do_test("openat", test_openat, 4);
#endif
	
	putchar('\n');
	if(failed != 0) {
		printf("%d tests were not successful!\n", failed);
		printf("Please email this log to the maintainer with the output of\n");
		printf("\tnm %s\n", argv[0]);
	} else
		printf("All tests successful!\n");

	if(libc_handle!=NULL)
		dlclose(libc_handle);

	return failed;
}

