Annotation of embedaddon/thttpd/cgi-src/redirect.c, revision 1.1.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>