Annotation of embedaddon/thttpd/cgi-src/redirect.c, revision 1.1
1.1 ! misho 1: /* redirect - simple redirection CGI program
! 2: **
! 3: ** Copyright © 1995 by Jef Poskanzer <jef@mail.acme.com>.
! 4: ** All rights reserved.
! 5: **
! 6: ** Redistribution and use in source and binary forms, with or without
! 7: ** modification, are permitted provided that the following conditions
! 8: ** are met:
! 9: ** 1. Redistributions of source code must retain the above copyright
! 10: ** notice, this list of conditions and the following disclaimer.
! 11: ** 2. Redistributions in binary form must reproduce the above copyright
! 12: ** notice, this list of conditions and the following disclaimer in the
! 13: ** documentation and/or other materials provided with the distribution.
! 14: **
! 15: ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
! 16: ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 17: ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 18: ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
! 19: ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 20: ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 21: ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 22: ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 23: ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 24: ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 25: ** SUCH DAMAGE.
! 26: */
! 27:
! 28: /* Three steps to set up a redirection:
! 29: ** 1. Make sure your web server is set up to allow CGI programs.
! 30: ** 2. Make a symbolic link from the file you want to redirect,
! 31: ** pointing at this program in the CGI bin directory.
! 32: ** 3. Add an entry to the file ".redirects" in the directory where your
! 33: ** http server runs CGI programs. For most servers, this is the
! 34: ** directory where the given CGI program lives. The format of the
! 35: ** file is a bunch of lines with a filename, whitespace, and the new
! 36: ** URL. For example:
! 37:
! 38: /test/oldfile.html http://www.acme.com/test/newfile.html
! 39:
! 40: ** The easiest way to figure out precisely what filename to put into
! 41: ** .redirects is to set up the symlink and then click on it. You'll get
! 42: ** back a "404 Not Found" page which includes the filename as received by
! 43: ** the redirect program, and that's what you want to use.
! 44: **
! 45: ** Note: this is designed for thttpd (http://www.acme.com/software/thttpd/)
! 46: ** and using it with other web servers may require some hacking. A possible
! 47: ** gotcha is with the symbolic link from the old file pointing at this
! 48: ** script - servers other than thttpd may not allow that link to be run
! 49: ** as a CGI program, because they don't check the link to see that it
! 50: ** points into the allowed CGI directory.
! 51: **
! 52: ** Note two: It would be really cool to have this program look for
! 53: ** the .redirects file in the same directory as the file being redirected,
! 54: ** instead of in the binaries directory. Unfortunately, this appears
! 55: ** to be impossible with the information CGI gives, plus the non-standardized
! 56: ** but widespread practice of running CGI programs in the directory where
! 57: ** the binary lives. Perhaps CGI 1.2 will address this.
! 58: */
! 59:
! 60: #include <sys/types.h>
! 61:
! 62: #include <stdio.h>
! 63: #include <stdlib.h>
! 64: #include <string.h>
! 65:
! 66: #include "config.h"
! 67:
! 68:
! 69: static char* argv0;
! 70:
! 71:
! 72: static void
! 73: internal_error( char* reason )
! 74: {
! 75: char* title = "500 Internal Error";
! 76:
! 77: (void) printf( "\
! 78: Status: %s\n\
! 79: Content-type: text/html\n\
! 80: \n\
! 81: <HTML><HEAD><TITLE>%s</TITLE></HEAD>\n\
! 82: <BODY><H2>%s</H2>\n\
! 83: Something unusual went wrong during a redirection request:\n\
! 84: <BLOCKQUOTE>\n\
! 85: %s\n\
! 86: </BLOCKQUOTE>\n\
! 87: </BODY></HTML>\n", title, title, title, reason );
! 88: }
! 89:
! 90:
! 91: static void
! 92: not_found( char* script_name )
! 93: {
! 94: char* title = "404 Not Found";
! 95:
! 96: (void) printf( "\
! 97: Status: %s\n\
! 98: Content-type: text/html\n\
! 99: \n\
! 100: <HTML><HEAD><TITLE>%s</TITLE></HEAD>\n\
! 101: <BODY><H2>%s</H2>\n\
! 102: The requested filename, %s, is set up to be redirected to another URL;\n\
! 103: however, the new URL has not yet been specified.\n\
! 104: </BODY></HTML>\n", title, title, title, script_name );
! 105: }
! 106:
! 107:
! 108: static void
! 109: moved( char* script_name, char* url )
! 110: {
! 111: char* title = "Moved";
! 112:
! 113: (void) printf( "\
! 114: Location: %s\n\
! 115: Content-type: text/html\n\
! 116: \n\
! 117: <HTML><HEAD><TITLE>%s</TITLE></HEAD>\n\
! 118: <BODY><H2>%s</H2>\n\
! 119: The requested filename, %s, has moved to a new URL:\n\
! 120: <A HREF=\"%s\">%s</A>.\n\
! 121: </BODY></HTML>\n", url, title, title, script_name, url, url );
! 122: }
! 123:
! 124:
! 125: int
! 126: main( int argc, char** argv )
! 127: {
! 128: char* script_name;
! 129: char* path_info;
! 130: char* cp;
! 131: FILE* fp;
! 132: char *star;
! 133: char buf[5000], file[5000], url[5000];
! 134:
! 135: argv0 = argv[0];
! 136:
! 137: /* Get the name that we were run as, which is the filename being
! 138: ** redirected.
! 139: */
! 140: script_name = getenv( "SCRIPT_NAME" );
! 141: if ( script_name == (char*) 0 )
! 142: {
! 143: internal_error( "Couldn't get SCRIPT_NAME environment variable." );
! 144: exit( 1 );
! 145: }
! 146:
! 147: /* Append the PATH_INFO, if any. This allows redirection of whole
! 148: ** directories.
! 149: */
! 150: path_info = getenv( "PATH_INFO" );
! 151: if ( path_info != (char*) 0 )
! 152: {
! 153: cp = (char*) malloc( strlen( script_name ) + strlen( path_info ) + 1 );
! 154: if ( cp == (char*) 0 )
! 155: {
! 156: internal_error( "Out of memory." );
! 157: exit( 1 );
! 158: }
! 159: (void) sprintf( cp, "%s%s", script_name, path_info );
! 160: script_name = cp;
! 161: }
! 162:
! 163: /* Open the redirects file. */
! 164: fp = fopen( ".redirects", "r" );
! 165: if ( fp == (FILE*) 0 )
! 166: {
! 167: internal_error( "Couldn't open .redirects file." );
! 168: exit( 1 );
! 169: }
! 170:
! 171: /* Search the file for a matching entry. */
! 172: while ( fgets( buf, sizeof(buf), fp ) != (char*) 0 )
! 173: {
! 174: /* Remove comments. */
! 175: cp = strchr( buf, '#' );
! 176: if ( cp != (char*) 0 )
! 177: *cp = '\0';
! 178: /* Skip leading whitespace. */
! 179: cp = buf;
! 180: cp += strspn( cp, " \t" );
! 181: /* Check for blank line. */
! 182: if ( *cp != '\0' )
! 183: {
! 184: /* Parse line. */
! 185: if ( sscanf( cp, "%[^ \t\n] %[^ \t\n]", file, url ) == 2 )
! 186: {
! 187: /* Check for wildcard match. */
! 188: star = strchr( file, '*' );
! 189: if ( star != (char*) 0 )
! 190: {
! 191: /* Check for leading match. */
! 192: if ( strncmp( file, script_name, star - file ) == 0 )
! 193: {
! 194: /* Got it; put together the full name. */
! 195: strcat( url, script_name + ( star - file ) );
! 196: /* XXX Whack the script_name, too? */
! 197: moved( script_name, url );
! 198: exit( 0 );
! 199: }
! 200: }
! 201: /* Check for exact match. */
! 202: if ( strcmp( file, script_name ) == 0 )
! 203: {
! 204: /* Got it. */
! 205: moved( script_name, url );
! 206: exit( 0 );
! 207: }
! 208: }
! 209: }
! 210: }
! 211:
! 212: /* No match found. */
! 213: not_found( script_name );
! 214: exit( 1 );
! 215: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>