1 /***************************************************************************\
2 ** **
3 ** htdump **
4 ** **
5 ** Program to make http requests and redirect, save or pipe the output. **
6 ** Ideal for automation and debugging. **
7 ** **
8 ** **
9 ** By Ren Hoek (ren@arak.cs.hro.nl) Under Artistic License, 2000 **
10 ** **
11 \***************************************************************************/
12
13
14
15 /***************************************************************************/
16 /** Includes **/
17
18 #include "global.h"
19
20 #include <unistd.h>
21 #include <getopt.h>
22
23
24
25
26
27 /***************************************************************************\
28 ** **
29 ** InitConfig() **
30 ** **
31 ** Initializes the config struct. **
32 ** **
33 \***************************************************************************/
34
InitConfig(int Argc,char ** Argv)35 void InitConfig(int Argc, char **Argv)
36 {
37 bzero(&CONFIG, sizeof(struct ALL_CONFIG_DATA)); /* Clear struct */
38
39 CONFIG.argc=Argc; /* Save argument count in CONFIG */
40 CONFIG.argv=Argv; /* Save argument pointer in CONFIG */
41
42 ArgCopy(&CONFIG.url_service, "80"); /* e.g. '8080' */
43 ArgCopy(&CONFIG.hdr_command, "GET");
44 CONFIG.hdr_version = 2; /* Standard on HTTP/1.1 */
45
46
47 CopyArguments(); /* Parse commandline */
48
49
50 }
51
52
53
54
55
56 /***************************************************************************\
57 ** **
58 ** ArgCopy() **
59 ** **
60 ** Copies and allocates some memory. **
61 ** **
62 \***************************************************************************/
63
ArgCopy(UCHAR ** Arg,UCHAR * NewValue)64 void ArgCopy(UCHAR **Arg, UCHAR *NewValue)
65 {
66 if(*Arg) free(*Arg);
67
68 *Arg=malloc(strlen(NewValue)+1);
69
70 if(*Arg==NULL)
71 {
72 perror("ArgCopy");
73 exit(1);
74 }
75
76 strcpy(*Arg, NewValue);
77 }
78
79
80
81 /***************************************************************************\
82 ** **
83 ** ArgAdd() **
84 ** **
85 ** Copies and allocates some memory. **
86 ** **
87 \***************************************************************************/
88
ArgAdd(UCHAR ** Arg,UCHAR * NewValue)89 void ArgAdd(UCHAR **Arg, UCHAR *NewValue)
90 {
91 UINT t;
92 UCHAR *p;
93
94 if(*Arg==NULL)
95 {
96 t=0; /* No previous values to add too */
97 ArgCopy(Arg, NewValue);
98 }
99 else
100 {
101 t=strlen(*Arg); /* Get size of old value */
102 t=t+strlen(NewValue)+1; /* Add size of new value plus 1 byte for '\0' */
103 p=malloc(t); /* Allocate memory for new value */
104 if(p==NULL)
105 {
106 perror("ArgAdd");
107 exit(1);
108 }
109 strcpy(p, *Arg); /* Copy old value */
110 strcat(p, NewValue); /* Add new value */
111 free(*Arg); /* Free old memory */
112 *Arg=p; /* Set pointer to new memory */
113 }
114 }
115
116
117
118 /***************************************************************************\
119 ** **
120 ** CopyArguments() **
121 ** **
122 ** Parses the commandline into the CONFIG struct. **
123 ** **
124 \***************************************************************************/
125
CopyArguments(void)126 void CopyArguments(void)
127 {
128 UINT t;
129 UCHAR buffer[512];
130
131
132 #define NO_ARG 0
133 #define ONE_ARG 1
134 #define OPT_ARG 2
135
136 static struct option long_options[] =
137 { {"command", ONE_ARG, NULL, 1},
138 {"post", ONE_ARG, NULL, 2},
139 {"debug", OPT_ARG, NULL, 3},
140 {"file", OPT_ARG, NULL, 4},
141 {"escape", OPT_ARG, NULL, 5},
142 {"accept", ONE_ARG, NULL, 6},
143 {"cookie", ONE_ARG, NULL, 7},
144 {"host", ONE_ARG, NULL, 8},
145 {"referer", ONE_ARG, NULL, 9},
146 {"from", ONE_ARG, NULL, 10},
147 {"range", ONE_ARG, NULL, 11},
148 {"agent", ONE_ARG, NULL, 12},
149 {"version", ONE_ARG, NULL, 13},
150 {"jar", ONE_ARG, NULL, 14},
151 {"extra", ONE_ARG, NULL, 15},
152 {"resume", NO_ARG, NULL, 16},
153 {"help", NO_ARG, NULL, 17},
154 {NULL, 0, NULL, 0}
155 };
156
157
158 CONFIG.new_argc = CONFIG.argc; /* Don't touch the original arguments */
159 CONFIG.new_argv = CONFIG.argv;
160
161
162 while ((t = getopt_long(CONFIG.new_argc
163 ,CONFIG.new_argv
164 ,"h"
165 ,long_options
166 ,NULL
167 )) != EOF)
168 {
169 switch(t)
170 {
171 case 1: /* Command to send, default GET */
172 ArgCopy(&CONFIG.hdr_command, optarg);
173 break;
174
175 case 2: /* POST message */
176 ArgCopy(&CONFIG.post_content, optarg);
177 ArgCopy(&CONFIG.hdr_command, "POST");
178 break;
179
180 case 3: /* Turn on debugging */
181 if(optarg)
182 CONFIG.debug=atoi(optarg);
183 else
184 CONFIG.debug++;
185 break;
186
187 case 4: /* Write data retrieved to file */
188 if(optarg)
189 ArgCopy(&CONFIG.output_file, optarg); /* Filename specified */
190 else
191 ArgCopy(&CONFIG.output_file, ""); /* Extract filename from url */
192 break;
193
194 case 5: /* Escape characters in url */
195 if(optarg)
196 CONFIG.escape=atoi(optarg);
197 else
198 CONFIG.escape=1;
199 break;
200
201 case 6: /* Accept: */
202 ArgCopy(&CONFIG.hdr_accept, optarg);
203 break;
204
205
206 /* Have to break the pattern here a bit, and add the complete cookie info
207 here instead of in BuildArguments. This because you can add more then
208 one cookie, making this the best place to process it.
209 */
210
211
212 case 7: /* Cookie: */
213 sprintf(buffer, "Cookie: %s\n", optarg);
214 ArgAdd(&CONFIG.hdr_cookie, buffer);
215 break;
216
217 case 8: /* Host: */
218 ArgCopy(&CONFIG.hdr_host, optarg);
219 break;
220
221 case 9: /* Referer: */
222 ArgCopy(&CONFIG.hdr_referer, optarg);
223 break;
224
225 case 10: /* From: */
226 ArgCopy(&CONFIG.hdr_from, optarg);
227 break;
228
229 case 11: /* Range: bytes=xxx */
230 ArgCopy(&CONFIG.hdr_range, optarg);
231 break;
232
233 case 12: /* User-Agent: */
234 ArgCopy(&CONFIG.hdr_agent, optarg);
235 break;
236
237 case 13: /* HTTP version */
238 switch(optarg[0])
239 {
240 case 'r':
241 case 'R': CONFIG.hdr_version=0;
242 break;
243 case '0': CONFIG.hdr_version=1;
244 break;
245 case '1': CONFIG.hdr_version=2;
246 break;
247 }
248 break;
249
250 case 14: /* Cookie jar */
251 ArgCopy(&CONFIG.cookie_jar, optarg);
252 break;
253
254 case 15: /* Extra */
255 sprintf(buffer, "%s\n", optarg);
256 ArgAdd(&CONFIG.hdr_extra, buffer);
257 break;
258
259 case 16: /* Resume */
260 CONFIG.output_resume=1;
261 break;
262
263 case 17: /* Help */
264 default:
265 case '?': Usage(); /* Usage, does not return */
266
267 } /* end of switch() */
268
269 } /* end of while() */
270
271 CONFIG.new_argc = CONFIG.new_argc - optind; /* Remove processed options */
272 CONFIG.new_argv = CONFIG.new_argv + optind;
273
274 } /* End of CopyArguments() */
275