/*
 *  FL-COW by Davide Libenzi ( File Links Copy On Write )
 *  Copyright (C) 2003  Davide Libenzi
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  Davide Libenzi <davidel@xmailserver.org>
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>


#ifdef HAVE_DLADDR

struct asym_name {
	struct asym_name *next;
	char *name;
};

static int asym_add(struct asym_name **lst, char const *name) {
	struct asym_name *asn;

	for (asn = *lst; asn != NULL; asn = asn->next)
		if (strcmp(asn->name, name) == 0)
			return 1;
	if ((asn = (struct asym_name *) malloc(sizeof(struct asym_name))) == NULL)
		return -1;
	asn->name = strdup(name);
	asn->next = *lst;
	*lst = asn;

	return 0;
}

int main(int ac, char **av) {
	int i;
	void *symaddr;
	struct asym_name *funlst = NULL;
	Dl_info syminf;

	for (i = 1; i < ac; i++) {
		if ((symaddr = dlsym(RTLD_NEXT, av[i])) != NULL &&
		    dladdr(symaddr, &syminf)) {
			if (asym_add(&funlst, syminf.dli_sname) == 0)
				fprintf(stdout, "FLCOW_MAPFUNC(%s);\n", syminf.dli_sname);
			if (strcmp(av[i], syminf.dli_sname))
				fprintf(stdout, "FLCOW_ALIAS(%s, %s);\n",
					av[i], syminf.dli_sname);
		} else {
			fprintf(stderr, "Unknown symbol: %s\n", av[i]);
			return 1;
		}
	}

	return 0;
}

#else

int main(int ac, char **av) {
	int i;

	for (i = 1; i < ac; i++)
		fprintf(stdout, "FLCOW_MAPFUNC(%s);\n", av[i]);

	return 0;
}

#endif

