/*
** Alias v1.2
**
** A WWW User Redirector
**
** Copyright (C) 28.7.94 by Andreas Ley <ley@rz.uni-karlsruhe.de>
**
** 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.
**
** This program has been tested on a HP9000/715 with HP-UX A.09.07
** In this environment, neither lint -u nor gcc -Wall -fsyntax-only produce
** any messages. If you encounter any errors or need to make any changes to
** port it to another platform, please contact me.
**
** Usage:
**    - Create an aliases file with entries:
**		<username> <url>
**    - Any URL of the form http://slave.host/~username/ can now be replaced
**	by http://www.host/cgi-bin/alias/username/. If you're using CERN
**	httpd, you could create a httpd.conf entry reading:
**	Map	/~*	/cgi-bin/alias/*
**	and use http://www.host/~username/ as a generic URL
**
** Version 1.2 - 30.4.97
**	Add trailing slash only if needed
**
** Version 1.1 - 25.11.94
**	Added proxy interaction
**
** Version 1.0 - 28.7.94
**	Initial version
*/

static char copyright[] = "@(#)Copyright (C) 1994-1997 by Andreas Ley (ley@rz.uni-karlsruhe.de)";
static char sccsid[] = "@(#)alias v1.2 - A WWW User Redirector";

/* General definitions */

#define	MASTER	"webmaster@rz.uni-karlsruhe.de"
#define	INTERNAL_PROXY

/* File locations */

#define	ALIASES	"/usr/www/httpd/conf/alias.conf"

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <sys/types.h>
#include "alias_german.h"
/*
#include "alias_english.h"
*/

#define	FALSE	0		/* This is the naked Truth */
#define	TRUE	1		/* and this is the Light */

/* Global variables */

char	*image,master[]=MASTER;
int	debug=0;


/* Prints header of a HTML-Request */
void show_header(subtitle,description)
char	*subtitle,*description;
{
	if (debug)
		(void)fprintf(stderr,"show_header(\"%s\",\"%s\")\n",subtitle,description);
	(void)printf("Content-type: text/html\n\n");
	(void)printf("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n");
	(void)printf("<HTML>\n");
	(void)printf("<HEAD>\n");
	(void)printf("<TITLE>%s%s%s</TITLE>\n",TITLE,subtitle?" - ":"",subtitle?subtitle:"");
	(void)printf("<LINK REV=\"made\" HREF=\"mailto:%s\">\n",master);
	(void)printf("<META NAME=\"robots\" CONTENT=\"noindex,nofollow\">\n");
	(void)printf("</HEAD>\n");
	(void)printf("<BODY>\n");
	(void)printf("<H1>%s</H1>\n",subtitle?subtitle:TITLE);
	if (description) {
		(void)printf(description,master);
		(void)printf("<P>\n");
	}
}



/* Prints trailer of a HTML-Request */
void show_trailer()
{
	if (debug)
		(void)fprintf(stderr,"show_trailer()\n");
	(void)printf("</BODY>\n");
	(void)printf("</HTML>\n");
}



/* Shows an error page, based on wrong user input */
void show_error(error)
char	*error;
{
	if (debug)
		(void)fprintf(stderr,"show_error(\"%s\")\n",error);
	show_header(ERROR,error);
	show_trailer();
	exit(0);
}



/* Shows an error page, based on internal misfunction */
void show_fatal(error)
char	*error;
{
	if (debug)
		(void)fprintf(stderr,"show_fatal(\"%s\")\n",error);
	show_header(ERROR,error);
	(void)printf(ERROR_FATAL,master);
	(void)printf("<P>\n");
	show_trailer();
	exit(0);
}



/* Returns a Location: header */
void show_location(location)
char	*location;
{
	if (debug)
		(void)fprintf(stderr,"show_location(\"%s\")\n",location);
	(void)printf("Location: %s\n",location);
	(void)printf("URI: %s\n\n",location);
}



void usage()
{
	(void)fprintf(stderr,"Usage: %s [-h] [-v]\n",image);
	exit(1);
}


int main(argc,argv)
int	argc;
char	*argv[];
{
	int	c;
	char	buffer[10240],*ptr,*nptr;
	char	*username,*path_info,*url;
	FILE	*src;
	int	found;

	if ((image=strrchr(argv[0],'/')))
		image++;
	else
		image=argv[0];

	while ((c=getopt(argc,argv,"Dvh?")) != EOF)
		switch ((char)c) {
		case 'D':
			debug++;
			break;
		case 'v':
			(void)fprintf(stderr,"%s\n",sccsid+4);
			(void)fprintf(stderr,"%s\n",copyright+4);
			exit(0);
		case 'h':
			(void)fprintf(stderr,"%s\n",sccsid+4);
			(void)fprintf(stderr,"%s\n",copyright+4);
		case '?':
			usage(argv[0]);
		}

	if (!(username=getenv("PATH_INFO")))
		show_fatal(ERROR_MISSING_USERNAME);
	if (*username=='/')
		username++;
	if ((path_info=strchr(username,'/')))
		*path_info++='\0';
	else
		path_info="";
	if (debug)
		(void)fprintf(stderr,"username=\"%s\"\npath_info=\"%s\"\n",username,path_info);

	if ((src=fopen(ALIASES,"r"))) {
		found=FALSE;
		ptr=buffer;
		while(fgets(buffer,sizeof(buffer),src)) {
			if (*buffer!='#') {
				if ((ptr=strchr(buffer,'\n')))
					*ptr='\0';
				for (ptr=buffer;*ptr&&!strchr(" \t",*ptr);ptr++);
				if (*ptr)
					*ptr++='\0';
				while (strchr(" \t",*ptr))
					ptr++;
				if ((found=!strcmp(buffer,username)))
					break;
			}
		}
		fclose(src);
		if (!found) {
			if (debug)
				(void)fprintf(stderr,"user not found\n");
			(void)sprintf(buffer,ERROR_UNKNOWN_USER,username,master);
			show_error(buffer);
		}
		if (!*ptr) {
			if (debug)
				(void)fprintf(stderr,"no url\n");
			(void)sprintf(buffer,ERROR_NOURL,username);
			show_fatal(buffer);
		}
#ifdef INTERNAL_PROXY
		nptr=strstr(ptr,"://");
		if (nptr) {
			url=malloc(strlen(ptr)+strlen(path_info)+22);
			strcpy(url,"/httpd-internal-proxy/");
			strncpy(url+22,ptr,nptr-ptr);
			strcpy(url+22+(nptr-ptr),nptr+2);
		}
		else {
			url=malloc(strlen(ptr)+strlen(path_info)+2);
			strcpy(url,ptr);
		}
#else
		url=malloc(strlen(ptr)+strlen(path_info)+2);
		strcpy(url,ptr);
#endif
		if (debug)
			(void)fprintf(stderr,"url=\"%s\"\n",url);
		if (url[strlen(url)-1]!='/') {
			strcat(url,"/");
			if (debug)
				(void)fprintf(stderr,"url=\"%s\"\n",url);
		}
		strcat(url,path_info);
		if (debug)
			(void)fprintf(stderr,"url=\"%s\"\n",url);
	}
	else
		show_fatal(ERROR_READ);

	show_location(url);

	return(0);
}

