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>