#include <time.h>
#include <stdio.h>
#include <linux/audit.h>
#include <linux/unistd.h>
#include <errno.h>

_syscall3(int, _auditor,
	  void *, data,
	  int, length,
	  int *, result_p)

main()
{
	for (;;) {
		struct __aud_header_s thead;
		char data[1000];
		int retval, length;

		retval = _auditor(data, 1000, &length);
		if (retval != 0) {
			fprintf(stderr, "auditor returned: %d=%s\n",
				errno, strerror(errno));
		} else {
			int i;

			fprintf(stderr,"returned length is %d\n", length);
			if (length <= 0) {
				continue;
			}
			for (i=0; i<length; i+=thead.length) {
				memcpy(&thead, data+i, sizeof(thead));
				fprintf(stderr, "0x%x + %d, %d, aid=%d,"
					" proc=%d, event=%x\n",
					thead.flags, thead.generation,
					thead.length, thead.audit_id,
					thead.proc_id, thead.event_class);
				fprintf(stderr, "%.24s + %9d nsec\n",
					ctime((time_t *)&thead.time_sec),
					thead.time_nsec);

				switch (*((int *)(i+sizeof(thead)+data))) {
				case AUD_AET_AUD_SWITCH:
				{
					int v1,v2;
					unsigned u1,u2;

					memcpy(&v1, 1*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v1));
					memcpy(&v2, 2*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v2));
					memcpy(&u1, 3*sizeof(u1)
					       +i+sizeof(thead)+data,
					       sizeof(u1));
					memcpy(&u2, 4*sizeof(u2)
					       +i+sizeof(thead)+data,
					       sizeof(u2));
					fprintf(stderr,
						"-> aud_switch(%d,pid=%d)"
						" %x -> %x\n",
						v1,v2,u1,u2);
					break;
				}
				case AUD_AET_PIPE:
				{
					int v1,v2;

					memcpy(&v1, 1*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v1));
					memcpy(&v2, 2*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v2));
					fprintf(stderr,
						"-> pipe() => fds=[%d,%d]\n"
						,v1,v2);
					break;
				}
				case AUD_AET_CHDIR:
				{
					fprintf(stderr, "-> chdir(%s)\n",
						1*sizeof(int)
						+i+sizeof(thead)+data);
					break;
				}
				case AUD_AET_RMDIR:
				{
					fprintf(stderr, "-> rmdir(%s)\n",
						1*sizeof(int)
						+i+sizeof(thead)+data);
					break;
				}
				case AUD_AET_RENAME:
				{
					const char *name = 1*sizeof(int)
						+i+sizeof(thead)+data;
					fprintf(stderr, "-> rename(%s,",name);
					name += 1+strlen(name);
					fprintf(stderr,"%s)\n",name);
					break;
				}
				case AUD_AET_LINK:
				{
					const char *name = 1*sizeof(int)
						+i+sizeof(thead)+data;
					fprintf(stderr, "-> link(%s,",name);
					name += 1+strlen(name);
					fprintf(stderr,"%s)\n",name);
					break;
				}
				case AUD_AET_MKDIR:
				{
					int v1;

					memcpy(&v1, 1*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v1));
					fprintf(stderr, "-> mkdir(%s,0%o)\n",
						2*sizeof(int)
						+i+sizeof(thead)+data,
						v1);
					break;
				}
				case AUD_AET_OPEN:
				{
					int v1,v2;
					short unsigned u1;

					memcpy(&v1, 1*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v1));
					memcpy(&v2, 2*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v2));
					memcpy(&u1, 3*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(u1));
					fprintf(stderr, "-> open(%s,%x,0%o) => fd=%d\n",
						3*sizeof(int)+sizeof(u1)
						+i+sizeof(thead)+data,
						v1,v2,u1);
					break;
				}
				case AUD_AET_EXIT:
				{
					int v1;

					memcpy(&v1, 1*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v1));
					fprintf(stderr, "-> _exit(%d)\n", v1);
					break;
				}
				case AUD_AET_SETGID:
				{
					int v1;

					memcpy(&v1, 1*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v1));

					fprintf(stderr, "-> setgid(%d)\n",v1);
					break;
				}
				case AUD_AET_SETUID:
				{
					int v1;

					memcpy(&v1, 1*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v1));

					fprintf(stderr, "-> setuid(%d)\n",v1);
					break;
				}
				case AUD_AET_FORK:
				{
					int v1;
			
					memcpy(&v1, 1*sizeof(int)
					       +i+sizeof(thead)+data,
					       sizeof(v1));
					fprintf(stderr, "-> fork()"
						" => [child=%d]\n",v1);
					break;
				}
				default:
				{
					int j;

					for (j=sizeof(thead);
					     j<thead.length; ++j) {
						fprintf(stderr,
							"[%x] ",data[i+j]);
					}
					fprintf(stderr, "\n");
					fprintf(stderr, "-> ?? event "
						"of type %d\n",
						*((int *)(sizeof(thead)
							  +data)));
				}
				}
			}
		}
	}
	exit (0);
}