📄 init.c
字号:
/* Reading/parsing the initialization file. Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001, 2003 Free Software Foundation, Inc.This file is part of GNU Wget.GNU Wget is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.GNU Wget is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with Wget; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.In addition, as a special exception, the Free Software Foundationgives permission to link the code of its release of Wget with theOpenSSL project's "OpenSSL" library (or with modified versions of itthat use the same license as the "OpenSSL" library), and distributethe linked executables. You must obey the GNU General Public Licensein all respects for all of the code used other than "OpenSSL". If youmodify this file, you may extend this exception to your version of thefile, but you are not obligated to do so. If you do not wish to doso, delete this exception statement from your version. */#include <config.h>#include <stdio.h>#include <sys/types.h>#include <stdlib.h>#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef HAVE_STRING_H# include <string.h>#else# include <strings.h>#endif#include <errno.h>#ifdef WINDOWS# include <winsock.h>#else# include <sys/socket.h># include <netinet/in.h>#ifndef __BEOS__# include <arpa/inet.h>#endif#endif#ifdef HAVE_PWD_H# include <pwd.h>#endif#include <assert.h>#include "wget.h"#include "utils.h"#include "init.h"#include "host.h"#include "netrc.h"#include "cookies.h" /* for cookie_jar_delete */#include "progress.h"#ifndef errnoextern int errno;#endifextern struct cookie_jar *wget_cookie_jar;/* We want tilde expansion enabled only when reading `.wgetrc' lines; otherwise, it will be performed by the shell. This variable will be set by the wgetrc-reading function. */static int enable_tilde_expansion;#define CMD_DECLARE(func) static int func \ PARAMS ((const char *, const char *, void *))CMD_DECLARE (cmd_boolean);CMD_DECLARE (cmd_bytes);CMD_DECLARE (cmd_bytes_large);CMD_DECLARE (cmd_directory_vector);CMD_DECLARE (cmd_lockable_boolean);CMD_DECLARE (cmd_number);CMD_DECLARE (cmd_number_inf);CMD_DECLARE (cmd_string);CMD_DECLARE (cmd_file);CMD_DECLARE (cmd_directory);CMD_DECLARE (cmd_time);CMD_DECLARE (cmd_vector);CMD_DECLARE (cmd_spec_dirstruct);CMD_DECLARE (cmd_spec_header);CMD_DECLARE (cmd_spec_htmlify);CMD_DECLARE (cmd_spec_mirror);CMD_DECLARE (cmd_spec_progress);CMD_DECLARE (cmd_spec_recursive);CMD_DECLARE (cmd_spec_restrict_file_names);CMD_DECLARE (cmd_spec_timeout);CMD_DECLARE (cmd_spec_useragent);/* List of recognized commands, each consisting of name, closure and function. When adding a new command, simply add it to the list, but be sure to keep the list sorted alphabetically, as findcmd() depends on it. Also, be sure to add any entries that allocate memory (e.g. cmd_string and cmd_vector guys) to the cleanup() function below. */static struct { char *name; void *closure; int (*action) PARAMS ((const char *, const char *, void *));} commands[] = { { "accept", &opt.accepts, cmd_vector }, { "addhostdir", &opt.add_hostdir, cmd_boolean }, { "alwaysrest", &opt.always_rest, cmd_boolean }, /* deprecated */ { "background", &opt.background, cmd_boolean }, { "backupconverted", &opt.backup_converted, cmd_boolean }, { "backups", &opt.backups, cmd_number }, { "base", &opt.base_href, cmd_string }, { "bindaddress", &opt.bind_address, cmd_string }, { "cache", &opt.allow_cache, cmd_boolean }, { "connecttimeout", &opt.connect_timeout, cmd_time }, { "continue", &opt.always_rest, cmd_boolean }, { "convertlinks", &opt.convert_links, cmd_boolean }, { "cookies", &opt.cookies, cmd_boolean }, { "cutdirs", &opt.cut_dirs, cmd_number },#ifdef ENABLE_DEBUG { "debug", &opt.debug, cmd_boolean },#endif { "deleteafter", &opt.delete_after, cmd_boolean }, { "dirprefix", &opt.dir_prefix, cmd_directory }, { "dirstruct", NULL, cmd_spec_dirstruct }, { "dnscache", &opt.dns_cache, cmd_boolean }, { "dnstimeout", &opt.dns_timeout, cmd_time }, { "domains", &opt.domains, cmd_vector }, { "dotbytes", &opt.dot_bytes, cmd_bytes }, { "dotsinline", &opt.dots_in_line, cmd_number }, { "dotspacing", &opt.dot_spacing, cmd_number }, { "dotstyle", &opt.dot_style, cmd_string },#ifdef HAVE_SSL { "egdfile", &opt.sslegdsock, cmd_file },#endif { "excludedirectories", &opt.excludes, cmd_directory_vector }, { "excludedomains", &opt.exclude_domains, cmd_vector }, { "followftp", &opt.follow_ftp, cmd_boolean }, { "followtags", &opt.follow_tags, cmd_vector }, { "forcehtml", &opt.force_html, cmd_boolean }, { "ftpproxy", &opt.ftp_proxy, cmd_string }, { "glob", &opt.ftp_glob, cmd_boolean }, { "header", NULL, cmd_spec_header }, { "htmlextension", &opt.html_extension, cmd_boolean }, { "htmlify", NULL, cmd_spec_htmlify }, { "httpkeepalive", &opt.http_keep_alive, cmd_boolean }, { "httppasswd", &opt.http_passwd, cmd_string }, { "httpproxy", &opt.http_proxy, cmd_string }, { "httpsproxy", &opt.https_proxy, cmd_string }, { "httpuser", &opt.http_user, cmd_string }, { "ignorelength", &opt.ignore_length, cmd_boolean }, { "ignoretags", &opt.ignore_tags, cmd_vector }, { "includedirectories", &opt.includes, cmd_directory_vector }, { "input", &opt.input_filename, cmd_file }, { "killlonger", &opt.kill_longer, cmd_boolean }, { "limitrate", &opt.limit_rate, cmd_bytes }, { "loadcookies", &opt.cookies_input, cmd_file }, { "logfile", &opt.lfilename, cmd_file }, { "login", &opt.ftp_acc, cmd_string }, { "mirror", NULL, cmd_spec_mirror }, { "netrc", &opt.netrc, cmd_boolean }, { "noclobber", &opt.noclobber, cmd_boolean }, { "noparent", &opt.no_parent, cmd_boolean }, { "noproxy", &opt.no_proxy, cmd_vector }, { "numtries", &opt.ntry, cmd_number_inf },/* deprecated*/ { "outputdocument", &opt.output_document, cmd_file }, { "pagerequisites", &opt.page_requisites, cmd_boolean }, { "passiveftp", &opt.ftp_pasv, cmd_lockable_boolean }, { "passwd", &opt.ftp_pass, cmd_string }, { "postdata", &opt.post_data, cmd_string }, { "postfile", &opt.post_file_name, cmd_file }, { "progress", &opt.progress_type, cmd_spec_progress }, { "proxypasswd", &opt.proxy_passwd, cmd_string }, { "proxyuser", &opt.proxy_user, cmd_string }, { "quiet", &opt.quiet, cmd_boolean }, { "quota", &opt.quota, cmd_bytes_large }, { "randomwait", &opt.random_wait, cmd_boolean }, { "readtimeout", &opt.read_timeout, cmd_time }, { "reclevel", &opt.reclevel, cmd_number_inf }, { "recursive", NULL, cmd_spec_recursive }, { "referer", &opt.referer, cmd_string }, { "reject", &opt.rejects, cmd_vector }, { "relativeonly", &opt.relative_only, cmd_boolean }, { "removelisting", &opt.remove_listing, cmd_boolean }, { "restrictfilenames", NULL, cmd_spec_restrict_file_names }, { "retrsymlinks", &opt.retr_symlinks, cmd_boolean }, { "retryconnrefused", &opt.retry_connrefused, cmd_boolean }, { "robots", &opt.use_robots, cmd_boolean }, { "savecookies", &opt.cookies_output, cmd_file }, { "saveheaders", &opt.save_headers, cmd_boolean }, { "serverresponse", &opt.server_response, cmd_boolean }, { "spanhosts", &opt.spanhost, cmd_boolean }, { "spider", &opt.spider, cmd_boolean },#ifdef HAVE_SSL { "sslcadir", &opt.sslcadir, cmd_directory }, { "sslcafile", &opt.sslcafile, cmd_file }, { "sslcertfile", &opt.sslcertfile, cmd_file }, { "sslcertkey", &opt.sslcertkey, cmd_file }, { "sslcerttype", &opt.sslcerttype, cmd_number }, { "sslcheckcert", &opt.sslcheckcert, cmd_number }, { "sslprotocol", &opt.sslprotocol, cmd_number },#endif /* HAVE_SSL */ { "strictcomments", &opt.strict_comments, cmd_boolean }, { "timeout", NULL, cmd_spec_timeout }, { "timestamping", &opt.timestamping, cmd_boolean }, { "tries", &opt.ntry, cmd_number_inf }, { "useproxy", &opt.use_proxy, cmd_boolean }, { "useragent", NULL, cmd_spec_useragent }, { "verbose", &opt.verbose, cmd_boolean }, { "wait", &opt.wait, cmd_time }, { "waitretry", &opt.waitretry, cmd_time }};/* Look up COM in the commands[] array and return its index. If COM is not found, -1 is returned. This function uses binary search. */static intfindcmd (const char *com){ int lo = 0, hi = countof (commands) - 1; while (lo <= hi) { int mid = (lo + hi) >> 1; int cmp = strcasecmp (com, commands[mid].name); if (cmp < 0) hi = mid - 1; else if (cmp > 0) lo = mid + 1; else return mid; } return -1;}/* Reset the variables to default values. */static voiddefaults (void){ char *tmp; /* Most of the default values are 0. Just reset everything, and fill in the non-zero values. Note that initializing pointers to NULL this way is technically illegal, but porting Wget to a machine where NULL is not all-zero bit pattern will be the least of the implementors' worries. */ memset (&opt, 0, sizeof (opt)); opt.cookies = 1; opt.verbose = -1; opt.ntry = 20; opt.reclevel = 5; opt.add_hostdir = 1; opt.ftp_acc = xstrdup ("anonymous"); opt.ftp_pass = xstrdup ("-wget@"); opt.netrc = 1; opt.ftp_glob = 1; opt.htmlify = 1; opt.http_keep_alive = 1; opt.use_proxy = 1; tmp = getenv ("no_proxy"); if (tmp) opt.no_proxy = sepstring (tmp); opt.allow_cache = 1; opt.read_timeout = 900; opt.use_robots = 1; opt.remove_listing = 1; opt.dot_bytes = 1024; opt.dot_spacing = 10; opt.dots_in_line = 50; opt.dns_cache = 1; /* The default for file name restriction defaults to the OS type. */#if !defined(WINDOWS) && !defined(__CYGWIN__) opt.restrict_files_os = restrict_unix;#else opt.restrict_files_os = restrict_windows;#endif opt.restrict_files_ctrl = 1;}/* Return the user's home directory (strdup-ed), or NULL if none is found. */char *home_dir (void){ char *home = getenv ("HOME"); if (!home) {#ifndef WINDOWS /* If HOME is not defined, try getting it from the password file. */ struct passwd *pwd = getpwuid (getuid ()); if (!pwd || !pwd->pw_dir) return NULL; home = pwd->pw_dir;#else /* WINDOWS */ home = "C:\\"; /* #### Maybe I should grab home_dir from registry, but the best that I could get from there is user's Start menu. It sucks! */#endif /* WINDOWS */ } return home ? xstrdup (home) : NULL;}/* Return the path to the user's .wgetrc. This is either the value of `WGETRC' environment variable, or `$HOME/.wgetrc'. If the `WGETRC' variable exists but the file does not exist, the function will exit(). */static char *wgetrc_file_name (void){ char *env, *home; char *file = NULL; /* Try the environment. */ env = getenv ("WGETRC"); if (env && *env) { if (!file_exists_p (env)) { fprintf (stderr, _("%s: WGETRC points to %s, which doesn't exist.\n"), exec_name, env); exit (1); } return xstrdup (env); }#ifndef WINDOWS /* If that failed, try $HOME/.wgetrc. */ home = home_dir (); if (home) { file = (char *)xmalloc (strlen (home) + 1 + strlen (".wgetrc") + 1); sprintf (file, "%s/.wgetrc", home); } FREE_MAYBE (home);#else /* WINDOWS */ /* Under Windows, "home" is (for the purposes of this function) the directory where `wget.exe' resides, and `wget.ini' will be used as file name. SYSTEM_WGETRC should not be defined under WINDOWS. It is not as trivial as I assumed, because on 95 argv[0] is full path, but on NT you get what you typed in command line. --dbudor */ home = ws_mypath (); if (home) { file = (char *)xmalloc (strlen (home) + strlen ("wget.ini") + 1); sprintf (file, "%swget.ini", home); }#endif /* WINDOWS */ if (!file) return NULL; if (!file_exists_p (file)) { xfree (file); return NULL; } return file;}static int parse_line PARAMS ((const char *, char **, char **, int *));static int setval_internal PARAMS ((int, const char *, const char *));/* Initialize variables from a wgetrc file. */static voidrun_wgetrc (const char *file){ FILE *fp; char *line; int ln; fp = fopen (file, "rb"); if (!fp) { fprintf (stderr, _("%s: Cannot read %s (%s).\n"), exec_name, file, strerror (errno)); return; } enable_tilde_expansion = 1; ln = 1; while ((line = read_whole_line (fp))) { char *com, *val; int comind, status; /* Parse the line. */ status = parse_line (line, &com, &val, &comind); xfree (line); /* If everything is OK, set the value. */ if (status == 1) { if (!setval_internal (comind, com, val)) fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name, file, ln); xfree (com); xfree (val); } else if (status == 0) fprintf (stderr, _("%s: Error in %s at line %d.\n"), exec_name, file, ln); ++ln; } enable_tilde_expansion = 0; fclose (fp);}/* Initialize the defaults and run the system wgetrc and user's own wgetrc. */voidinitialize (void){ char *file; /* Load the hard-coded defaults. */ defaults (); /* If SYSTEM_WGETRC is defined, use it. */#ifdef SYSTEM_WGETRC if (file_exists_p (SYSTEM_WGETRC)) run_wgetrc (SYSTEM_WGETRC);#endif /* Override it with your own, if one exists. */ file = wgetrc_file_name (); if (!file) return; /* #### We should canonicalize `file' and SYSTEM_WGETRC with something like realpath() before comparing them with `strcmp' */#ifdef SYSTEM_WGETRC if (!strcmp (file, SYSTEM_WGETRC)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -