📄 cmdline.c
字号:
/* Command line processing *//* $Id: cmdline.c,v 1.107.2.7 2005/05/13 20:05:01 jonas Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <string.h>#include <sys/types.h>#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h> /* OS/2 needs this after sys/types.h */#endif#include <sys/stat.h> /* OS/2 needs this after sys/types.h */#ifdef HAVE_NETDB_H#include <netdb.h>#endif/* We need to have it here. Stupid BSD. */#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endif#ifdef HAVE_ARPA_INET_H#include <arpa/inet.h>#endif#include "elinks.h"#include "config/cmdline.h"#include "config/conf.h"#include "config/options.h"#include "config/opttypes.h"#include "intl/gettext/libintl.h"#include "lowlevel/dns.h"#include "protocol/uri.h"#include "sched/session.h"#include "util/error.h"#include "util/file.h"#include "util/lists.h"#include "util/memory.h"#include "util/string.h"/* Hack to handle URL extraction for -remote commands */static unsigned char *remote_url;static enum retvalparse_options_(int argc, unsigned char *argv[], struct option *opt, struct list_head *url_list){ while (argc) { argv++, argc--; if (argv[-1][0] == '-' && argv[-1][1]) { struct option *option; unsigned char *argname = &argv[-1][1]; unsigned char *oname = stracpy(argname); unsigned char *err; if (!oname) continue; /* Treat --foo same as -foo. */ if (argname[0] == '-') argname++; option = get_opt_rec(opt, argname); if (!option) option = get_opt_rec(opt, oname); if (!option) { unsigned char *pos; oname++; /* the '-' */ /* Substitute '-' by '_'. This helps * compatibility with that very wicked browser * called 'lynx'. */ for (pos = strchr(oname, '_'); pos; pos = strchr(pos, '_')) *pos = '-'; option = get_opt_rec(opt, oname); oname--; } mem_free(oname); if (!option) goto unknown_option; if (!option_types[option->type].cmdline) goto unknown_option; err = option_types[option->type].cmdline(option, &argv, &argc); if (err) { if (err[0]) { usrerror(gettext("Cannot parse option %s: %s"), argv[-1], err); return RET_ERROR; } /* XXX: Empty strings means all is well and have * a cup of shut the fsck up. */ return RET_COMMAND; } else if (remote_url) { if (url_list) add_to_string_list(url_list, remote_url, -1); mem_free(remote_url); remote_url = NULL; } } else if (url_list) { add_to_string_list(url_list, argv[-1], -1); } } return RET_OK;unknown_option: usrerror(gettext("Unknown option %s"), argv[-1]); return RET_ERROR;}enum retvalparse_options(int argc, unsigned char *argv[], struct list_head *url_list){ return parse_options_(argc, argv, cmdline_options, url_list);}/********************************************************************** Options handlers**********************************************************************/static unsigned char *eval_cmd(struct option *o, unsigned char ***argv, int *argc){ if (*argc < 1) return gettext("Parameter expected"); (*argv)++; (*argc)--; /* Consume next argument */ parse_config_file(config_options, "-eval", *(*argv - 1), NULL); fflush(stdout); return NULL;}static unsigned char *forcehtml_cmd(struct option *o, unsigned char ***argv, int *argc){ safe_strncpy(get_opt_str("mime.default_type"), "text/html", MAX_STR_LEN); return NULL;}static unsigned char *lookup_cmd(struct option *o, unsigned char ***argv, int *argc){ struct sockaddr_storage *addrs = NULL; int addrno, i; if (!*argc) return gettext("Parameter expected"); if (*argc > 1) return gettext("Too many parameters"); (*argv)++; (*argc)--; if (do_real_lookup(*(*argv - 1), &addrs, &addrno, 0)) {#ifdef HAVE_HERROR herror(gettext("error"));#else usrerror(gettext("Host not found"));#endif return ""; } for (i = 0; i < addrno; i++) {#ifdef CONFIG_IPV6 struct sockaddr_in6 addr = *((struct sockaddr_in6 *) &(addrs)[i]); unsigned char p[INET6_ADDRSTRLEN]; if (! inet_ntop(addr.sin6_family, (addr.sin6_family == AF_INET6 ? (void *) &addr.sin6_addr : (void *) &((struct sockaddr_in *) &addr)->sin_addr), p, INET6_ADDRSTRLEN)) ERROR(gettext("Resolver error")); else printf("%s\n", p);#else struct sockaddr_in addr = *((struct sockaddr_in *) &(addrs)[i]); unsigned char *p = (unsigned char *) &addr.sin_addr.s_addr; printf("%d.%d.%d.%d\n", (int) p[0], (int) p[1], (int) p[2], (int) p[3]);#endif } mem_free_if(addrs); fflush(stdout); return "";}#define skipback_whitespace(start, S) \ while ((start) < (S) && isspace((S)[-1])) (S)--;static unsigned char *remote_cmd(struct option *o, unsigned char ***argv, int *argc){ struct { unsigned char *name; enum { REMOTE_METHOD_OPENURL, REMOTE_METHOD_PING, REMOTE_METHOD_XFEDOCOMMAND, REMOTE_METHOD_ADDBOOKMARK, REMOTE_METHOD_NOT_SUPPORTED, } type; } remote_methods[] = { { "openURL", REMOTE_METHOD_OPENURL }, { "ping", REMOTE_METHOD_PING }, { "addBookmark", REMOTE_METHOD_ADDBOOKMARK }, { "xfeDoCommand", REMOTE_METHOD_XFEDOCOMMAND }, { NULL, REMOTE_METHOD_NOT_SUPPORTED }, }; unsigned char *command, *arg, *argend = NULL; int method, len = 0; if (*argc < 1) return gettext("Parameter expected"); command = *(*argv); while (isalpha(command[len])) len++; arg = strchr(&command[len], '('); if (arg) { arg++; skip_space(arg); argend = strchr(arg, ')'); } if (!argend) { /* Just open any passed URLs in new tabs */ remote_session_flags |= SES_REMOTE_NEW_TAB; return NULL; } skipback_whitespace(arg, argend); for (method = 0; remote_methods[method].name; method++) { unsigned char *name = remote_methods[method].name; if (!strlcasecmp(command, len, name, -1)) break; } switch (remote_methods[method].type) { case REMOTE_METHOD_OPENURL: if (arg == argend) { /* Prompt for a URL with a dialog box */ remote_session_flags |= SES_REMOTE_PROMPT_URL; break; } len = strcspn(arg, ",)"); if (arg[len] == ',') { unsigned char *where = arg + len + 1; if (strstr(where, "new-window")) { remote_session_flags |= SES_REMOTE_NEW_WINDOW; } else if (strstr(where, "new-tab")) { remote_session_flags |= SES_REMOTE_NEW_TAB; } else { /* Bail out when getting unknown parameter */ /* TODO: new-screen */ break; } } else { remote_session_flags |= SES_REMOTE_CURRENT_TAB; } while (len > 0 && isspace(arg[len - 1])) len--; if (len > 1) { /* Skip possible string delimiters. Atleast urlview * seems to add them. */ if ((arg[0] == '\'' && arg[len - 1] == '\'') || (arg[0] == '"' && arg[len - 1] == '"')) arg++, len -= 2; } if (len) remote_url = memacpy(arg, len); break; case REMOTE_METHOD_XFEDOCOMMAND: len = argend - arg; if (!strlcasecmp(arg, len, "openBrowser", 11)) { remote_session_flags = SES_REMOTE_NEW_WINDOW; } break; case REMOTE_METHOD_PING: remote_session_flags = SES_REMOTE_PING; break; case REMOTE_METHOD_ADDBOOKMARK: if (arg == argend) break; remote_url = memacpy(arg, argend - arg); remote_session_flags = SES_REMOTE_ADD_BOOKMARK; break; case REMOTE_METHOD_NOT_SUPPORTED: break; } /* If no flags was applied it can only mean we are dealing with * unknown method. */ if (!remote_session_flags) return gettext("Remote method not supported"); (*argv)++; (*argc)--; /* Consume next argument */ return NULL;}static unsigned char *version_cmd(struct option *o, unsigned char ***argv, int *argc){ printf("%s\n", full_static_version); fflush(stdout); return "";}/* Below we handle help usage printing. * * We're trying to achieve several goals here: * * - Genericly define a function to print option trees iteratively. * - Make output parsable for various doc tools (to make manpages). * - Do some non generic fancy stuff like printing semi-aliased * options (like: -?, -h and -help) on one line when printing * short help. */#define gettext_nonempty(x) (*(x) ? gettext(x) : (x))static voidprint_full_help(struct option *tree, unsigned char *path){ struct option *option; unsigned char saved[MAX_STR_LEN]; unsigned char *savedpos = saved; *savedpos = 0; foreach (option, *tree->value.tree) { enum option_type type = option->type; unsigned char *help; unsigned char *capt = option->capt; unsigned char *desc = (option->desc && *option->desc) ? (unsigned char *) gettext(option->desc) : (unsigned char *) "N/A"; /* Don't print deprecated aliases (if we don't walk command * line options which use aliases for legitimate options). */ if ((type == OPT_ALIAS && tree != cmdline_options) || (option->flags & OPT_HIDDEN)) continue; if (!capt && !strncasecmp(option->name, "_template_", 10)) capt = (unsigned char *) N_("Template option folder"); if (!capt) { int len = strlen(option->name); int max = MAX_STR_LEN - (savedpos - saved); safe_strncpy(savedpos, option->name, max); safe_strncpy(savedpos + len, ", -", max - len); savedpos += len + 3; continue; } help = gettext_nonempty(option_types[option->type].help_str); if (type != OPT_TREE) printf(" %s%s%s %s ", path, saved, option->name, help); /* Print the 'title' of each option type. */ switch (type) { case OPT_BOOL: case OPT_INT: case OPT_LONG: printf(gettext("(default: %ld)"), type == OPT_LONG ? option->value.big_number : (long) option->value.number); break; case OPT_STRING: printf(gettext("(default: \"%s\")"), option->value.string); break; case OPT_ALIAS: printf(gettext("(alias for %s)"), option->value.string); break; case OPT_CODEPAGE: printf(gettext("(default: %s)"), get_cp_name(option->value.number));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -