2 wmget - A background download manager as a Window Maker dock app
3 Copyright (c) 2001-2003 Aaron Trickey <aaron@amtrickey.net>
5 Permission is hereby granted, free of charge, to any person
6 obtaining a copy of this software and associated documentation files
7 (the "Software"), to deal in the Software without restriction,
8 including without limitation the rights to use, copy, modify, merge,
9 publish, distribute, sublicense, and/or sell copies of the Software,
10 and to permit persons to whom the Software is furnished to do so,
11 subject to the following conditions:
13 The above copyright notice and this permission notice shall be
14 included in all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 ********************************************************************
25 config.c - Implementation of command-line and RC-file configuration
27 The code in this file parses RC files and command lines and provides
28 defaults for what you don't specify. Used to configure both
37 #include <sys/types.h>
48 #define O(s,l,a,t) optchar_##l = s,
56 /***********************************************************************
57 * clear_request(): Initialize an empty Request object.
59 void clear_request (Request
*req
)
65 req
->continue_from
= -1;
79 static void set_silent ()
81 set_output_level (OL_SILENT
);
85 static void set_verbose ()
87 set_output_level (OL_DEBUG
);
91 static void set_output (Request
*r
, ServerConfig
*c
, const char *value
)
93 if (r
) r
->save_to
= value
;
97 /* For server configuration, we must set the default to an
100 if (value
[0] == '/') {
101 if (strlen (value
) + 1 > sizeof c
->job_defaults
.save_to
) {
103 "Download directory name too long! Defaulting to home directory");
104 strcpy (c
->job_defaults
.save_to
, home_directory ());
106 strcpy (c
->job_defaults
.save_to
, value
);
109 if (strlen (value
) + strlen (home_directory ()) + 2
110 > sizeof c
->job_defaults
.save_to
) {
112 "Download directory name too long! Defaulting to home directory");
113 strcpy (c
->job_defaults
.save_to
, home_directory ());
115 strcpy (c
->job_defaults
.save_to
, home_directory ());
116 strcat (c
->job_defaults
.save_to
, "/");
117 strcat (c
->job_defaults
.save_to
, value
);
121 /* And we need to make sure it's really a directory.
123 if ( stat (c
->job_defaults
.save_to
, &st
)
124 || !S_ISDIR (st
.st_mode
)) {
126 "``output'' option is not a valid directory! Defaulting to home");
127 strcpy (c
->job_defaults
.save_to
, home_directory ());
133 static void set_display (Request
*r
, ServerConfig
*c
, const char *value
)
135 if (r
) r
->display
= value
;
136 if (c
) info ("Cannot set ``display'' option on dockapp");
140 static void set_overwrite (Request
*r
, ServerConfig
*c
)
142 if (r
) r
->overwrite
= 1;
143 if (c
) c
->job_defaults
.overwrite
= 1;
147 static void set_continue (Request
*r
, ServerConfig
*c
)
149 if (r
) r
->continue_from
= 1;
150 if (c
) c
->job_defaults
.continue_from
= 1;
154 static void set_proxy (Request
*r
, ServerConfig
*c
, const char *value
)
156 if (r
) r
->proxy
= value
;
157 if (c
) STRCPY_TO_ARRAY (c
->job_defaults
.proxy
, value
);
161 static void set_follow (Request
*r
, ServerConfig
*c
, const char *value
)
163 if (r
) r
->follow
= atoi (value
);
164 if (c
) c
->job_defaults
.follow
= atoi (value
);
168 static void set_user_agent (Request
*r
, ServerConfig
*c
, const char *v
)
170 if (r
) r
->user_agent
= v
;
171 if (c
) STRCPY_TO_ARRAY (c
->job_defaults
.user_agent
, v
);
175 static void set_ascii (Request
*r
, ServerConfig
*c
)
177 if (r
) r
->use_ascii
= 1;
178 if (c
) c
->job_defaults
.use_ascii
= 1;
182 static void set_referer (Request
*r
, ServerConfig
*c
, const char *v
)
184 if (r
) r
->referer
= v
;
185 if (c
) STRCPY_TO_ARRAY (c
->job_defaults
.referer
, v
);
189 static void set_headers (Request
*r
, ServerConfig
*c
)
191 if (r
) r
->include
= 1;
192 if (c
) c
->job_defaults
.include
= 1;
196 static void set_interface (Request
*r
, ServerConfig
*c
, const char *v
)
198 if (r
) r
->interface
= v
;
199 if (c
) STRCPY_TO_ARRAY (c
->job_defaults
.interface
, v
);
203 static void set_proxy_auth (Request
*r
, ServerConfig
*c
, const char *v
)
205 if (r
) r
->proxy_auth
= v
;
206 if (c
) STRCPY_TO_ARRAY (c
->job_defaults
.proxy_auth
, v
);
210 static void set_auth (Request
*r
, ServerConfig
*c
, const char *v
)
213 if (c
) STRCPY_TO_ARRAY (c
->job_defaults
.auth
, v
);
217 /***********************************************************************
218 * load_cmdline(): Parse options from the command line.
220 static int load_cmdline (int argc
, char **argv
,
221 Request
*req
, ServerConfig
*cfg
)
224 static const char shortopts
[] = {
227 #define O(s,l,a,t) s a,
228 #include "config.def"
235 static const struct option longopts
[] = {
236 #define no no_argument
237 #define yes required_argument
238 #define O(s,l,a,t) { #l, a, 0, s },
239 #include "config.def"
246 while ((o
= getopt_long (argc
, argv
, shortopts
, longopts
, 0))
256 set_##l (req, cfg a); \
258 #include "config.def"
267 if (strlen (argv
[optind
]) > MAXURL
) {
268 error ("URL too long!");
270 req
->source_url
= argv
[optind
];
276 if (strcasecmp (argv
[optind
], "dock") == 0) {
277 /* That's part of the syntax... ignore. */
284 error ("Extra argument: '%s'", argv
[optind
]);
291 static void read_rcfile (FILE *rcfp
, ServerConfig
*cfg
)
293 char line
[MAXRCLINELEN
];
295 while (fgets (line
, sizeof line
, rcfp
)) {
299 char *tictactoe
= strchr (line
, '#');
305 name
= line
; /* locate name: */
306 while (*name
&& isspace (*name
)) /* skip leading ws */
308 if (!*name
) { /* no name? skip line */
311 value
= name
; /* locate value: */
312 while (*value
&& !isspace (*value
)) /* skip name */
314 if (*value
) { /* not eol: look for val */
315 *value
++ = '\0'; /* terminate name */
316 while (*value
&& isspace (*value
)) /* skip dividing ws */
318 value_end
= value
+ strlen (value
); /* right-trim */
320 while (value_end
> value
&& isspace (*value_end
)) {
326 # define ARG_yes(NAM) \
328 error ("Keyword '" #NAM "' in config file is missing " \
329 "its required argument"); \
331 debug ("set " #NAM " (%s)", value); \
332 set_##NAM (0, cfg, value); \
335 # define ARG_no(NAM) \
337 error ("Keyword '" #NAM "' in config file has an "\
338 "extra argument: '%s'", value); \
340 debug ("set " #NAM " <no value>"); \
341 set_##NAM (0, cfg); \
344 # define O(s,l,a,t) \
345 if (strcasecmp (name, #l) == 0) { \
349 # include "config.def"
355 error ("Unknown keyword in config file: %s", name
);
360 static void load_rcfile (ServerConfig
*cfg
)
362 char rcfile
[MAXPATHLEN
+ 1];
363 static const char *rcfile_base
= "/.wmgetrc";
366 strcpy (rcfile
, home_directory ());
367 if (strlen (rcfile
) + strlen (rcfile_base
) >= sizeof rcfile
) {
368 error ("Your home directory name is too long!");
372 strcat (rcfile
, rcfile_base
);
374 if ((rcfp
= fopen (rcfile
, "rt"))) {
375 read_rcfile (rcfp
, cfg
);
378 /* rcfiles are fully optional... */
379 debug_sys ("Could not open rcfile '%s'", rcfile
);
384 void config_server (int argc
, char **argv
, ServerConfig
*cfg
)
386 /* Default job options: These take effect unless overridden by
387 * server configuration or per-job configuration.
389 cfg
->job_defaults
.display
[0] = 0;
390 STRCPY_TO_ARRAY (cfg
->job_defaults
.save_to
, home_directory ());
391 cfg
->job_defaults
.overwrite
= 0;
392 cfg
->job_defaults
.continue_from
= 0;
393 cfg
->job_defaults
.proxy
[0] = 0;
394 cfg
->job_defaults
.follow
= 5;
395 STRCPY_TO_ARRAY (cfg
->job_defaults
.user_agent
, DEFAULT_USER_AGENT
);
397 cfg
->job_defaults
.use_ascii
= 0;
398 cfg
->job_defaults
.referer
[0] = 0;
399 cfg
->job_defaults
.include
= 0;
400 cfg
->job_defaults
.interface
[0] = 0;
401 cfg
->job_defaults
.proxy_auth
[0] = 0;
402 cfg
->job_defaults
.auth
[0] = 0;
405 load_cmdline (argc
, argv
, 0, cfg
);
409 void config_request (int argc
, char **argv
, Request
*req
)
413 load_cmdline (argc
, argv
, req
, 0);