1 /* vim: set noet nosta sw=4 ts=4 ft=c : */ |
|
2 /* Squid docs: |
|
3 --------------------------------------------------------------------------- |
|
4 TAG: url_rewrite_program |
|
5 Specify the location of the executable for the URL rewriter. |
|
6 Since they can perform almost any function there isn't one included. |
|
7 |
|
8 For each requested URL rewriter will receive on line with the format |
|
9 |
|
10 URL <SP> client_ip "/" fqdn <SP> user <SP> method [<SP> kvpairs]<NL> |
|
11 |
|
12 In the future, the rewriter interface will be extended with |
|
13 key=value pairs ("kvpairs" shown above). Rewriter programs |
|
14 should be prepared to receive and possibly ignore additional |
|
15 whitespace-separated tokens on each input line. |
|
16 |
|
17 And the rewriter may return a rewritten URL. The other components of |
|
18 the request line does not need to be returned (ignored if they are). |
|
19 |
|
20 The rewriter can also indicate that a client-side redirect should |
|
21 be performed to the new URL. This is done by prefixing the returned |
|
22 URL with "301:" (moved permanently) or 302: (moved temporarily). |
|
23 |
|
24 By default, a URL rewriter is not used. |
|
25 --------------------------------------------------------------------------- */ |
|
26 |
|
27 /* |
|
28 * TODO |
|
29 * |
|
30 * flush stdout on writes |
|
31 * empty struct not necessary? |
|
32 * inet_pton( AF_INET, *char src, dest ) |
|
33 * an option to run the DB out of memory? |
|
34 * PRAGMA user_version = 1; |
|
35 * |
|
36 */ |
|
37 |
|
38 #include "volta.h" |
|
39 #include <time.h> |
|
40 unsigned short int debugmode; |
|
41 |
|
42 |
|
43 int |
|
44 main( int argc, char *argv[] ) { |
|
45 |
|
46 /* opt action flags */ |
|
47 struct { |
|
48 unsigned short int init; |
|
49 } actions = {0}; |
|
50 |
|
51 #ifdef DEBUG |
|
52 /* debugmode set at compile time, default to display everything */ |
|
53 debugmode = 99; |
|
54 #else |
|
55 debugmode = 0; |
|
56 #endif |
|
57 |
|
58 /* get_opt vars */ |
|
59 int opt = 0; |
|
60 opterr = 0; |
|
61 |
|
62 /* parse options */ |
|
63 while ( (opt = getopt( argc, argv, "a:d:hv" )) != -1 ) { |
|
64 switch ( opt ) { |
|
65 |
|
66 /* action */ |
|
67 case 'a': |
|
68 if ( strcmp( optarg, "init" ) == 0 ) actions.init++; |
|
69 break; |
|
70 |
|
71 /* debug */ |
|
72 case 'd': |
|
73 if ( optarg[0] == '-' ) { |
|
74 argc++; argv -= 1; |
|
75 debugmode = 1; |
|
76 } |
|
77 sscanf( optarg, "%hu", &debugmode ); |
|
78 break; |
|
79 |
|
80 /* help */ |
|
81 case 'h': |
|
82 usage( argv[0] ); |
|
83 return( 0 ); |
|
84 |
|
85 /* version */ |
|
86 case 'v': |
|
87 printf( "%s %s\n", PROG, VERSION ); |
|
88 return( 0 ); |
|
89 |
|
90 /* unknown option or option argument missing */ |
|
91 case '?': |
|
92 switch( optopt ) { |
|
93 case 'd': /* no debug argument, default to level 1 */ |
|
94 debugmode = 1; |
|
95 break; |
|
96 default: |
|
97 usage( argv[0] ); |
|
98 return( 1 ); |
|
99 } |
|
100 |
|
101 default: |
|
102 break; |
|
103 } |
|
104 } |
|
105 argc -= optind; |
|
106 argv += optind; |
|
107 |
|
108 /* perform actions */ |
|
109 if ( actions.init ) { |
|
110 debug( 1, LOC, "init! init! init!\n" ); |
|
111 return( 0 ); |
|
112 } |
|
113 |
|
114 /* start stdin parsing loop */ |
|
115 char line[ LINE_BUFSIZE ]; |
|
116 debug( 1, LOC, "Waiting for input...\n" ); |
|
117 while( fgets( line, LINE_BUFSIZE, stdin ) != NULL ) parse( line ); |
|
118 |
|
119 /* stdin closed */ |
|
120 debug( 1, LOC, "End of stream, shutting down.\n" ); |
|
121 return( 0 ); |
|
122 } |
|
123 |
|
124 |
|
125 /* |
|
126 * Basic usage |
|
127 */ |
|
128 void |
|
129 usage( char *prg ) |
|
130 { |
|
131 printf( "%s [-vh] [-d <level>] [-a <init>]\n", prg ); |
|
132 printf( " -v Display version\n" ); |
|
133 printf( " -d <level> Show debug information on stderr\n" ); |
|
134 printf( " -h Usage (you're lookin' at it)\n" ); |
|
135 printf( " -a Perform an action, being one of:\n" ); |
|
136 printf( " init: Initialize a new, empty database\n" ); |
|
137 printf( "\n" ); |
|
138 return; |
|
139 } |
|
140 |
|
141 |
|
142 /* |
|
143 * Debug function, only output to stderr if the debug level is |
|
144 * equal or greated to the output level. |
|
145 * |
|
146 * level: The minimum debug level that must be set for the |
|
147 * line to be logged. |
|
148 * file: The current code file that is emitting the log |
|
149 * line: The line number of the code file that is emitting the log |
|
150 * ... : any printf style strings and formats that constitute the log message |
|
151 */ |
|
152 void |
|
153 debug( int level, char *file, int line, const char *fmt, ... ) |
|
154 { |
|
155 if ( debugmode < level ) return; |
|
156 |
|
157 char timestamp[20]; |
|
158 time_t t = time( NULL ); |
|
159 struct tm *now = localtime( &t ); |
|
160 strftime( timestamp, 20, "%F %T", now ); |
|
161 |
|
162 va_list args; |
|
163 va_start( args, fmt ); |
|
164 fprintf( stderr, "%s [%s] #%d (%s:%04d): ", PROG, timestamp, getpid(), file, line ); |
|
165 vfprintf( stderr, fmt, args ); |
|
166 va_end( args ); |
|
167 |
|
168 return; |
|
169 } |
|
170 |
|