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>