?? options.c
字號:
/* options.c -- process the command line options Copyright (C) 2001, 2002 Free Software Foundation, Inc. Written by Marcus Brinkmann. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <getopt.h>#include <stdio.h>#include <errno.h>#if STDC_HEADERS# include <stdlib.h>#else# ifndef HAVE_STRCHR# define strchr index# define strrchr rindex# endif#endif#if HAVE_STRING_H# include <string.h>#else# include <strings.h>#endif#include <sys/socket.h>#include <net/if.h>#include "ifconfig.h"/* Be verbose about actions. */int verbose;/* Array of all interfaces on the command line. */struct ifconfig *ifs;/* Size of IFS. */int nifs;static struct ifconfig ifconfig_initializer ={ NULL, /* name */ 0, /* valid */};struct format formats[] ={ /* This is the default output format if no system_default_format is specified. */ { "default", "${format}{gnu}", }, /* This is the standard GNU output. */ { "gnu", "${first?}{}{${\\n}}${format}{gnu-one-entry}" }, { "gnu-one-entry", "${format}{check-existance}" \ "${name} (${index}):${\\n}" \ "${addr?}{ inet address ${tab}{16}${addr}${\\n}}" \ "${netmask?}{ netmask ${tab}{16}${netmask}${\\n}}" \ "${brdaddr?}{ broadcast ${tab}{16}${brdaddr}${\\n}}" \ "${dstaddr?}{ peer address ${tab}{16}${dstaddr}${\\n}}" \ "${flags?}{ flags ${tab}{16}${flags}${\\n}}" \ "${mtu?}{ mtu ${tab}{16}${mtu}${\\n}}" \ "${metric?}{ metric ${tab}{16}${metric}${\\n}}" \ "${exists?}{hwtype?}{${hwtype?}{ link encap ${tab}{16}${hwtype}${\\n}}}" \ "${exists?}{hwaddr?}{${hwaddr?}{ hardware addr ${tab}{16}${hwaddr}${\\n}}}" \ "${exists?}{txqlen?}{${txqlen?}{ tx queue len ${tab}{16}${txqlen}${\\n}}}" }, /* Resembles the output of ifconfig 1.39 (1999-03-19) in net-tools 1.52. */ { "net-tools", "${format}{check-existance}" \ "${name}${exists?}{hwtype?}{${hwtype?}{${tab}{10}Link encap:${hwtype}}" \ "${hwaddr?}{ HWaddr ${hwaddr}}}${\\n}" \ "${addr?}{${tab}{10}inet addr:${addr}" \ "${brdaddr?}{ Bcast:${brdaddr}}" \ "${netmask?}{ Mask:${netmask}}" \ "${newline}}" \ "${tab}{10}${flags}" \ "${mtu?}{ MTU:${mtu}}" \ "${metric?}{ Metric:${metric}}" \ "${newline}" \ "${exists?}{txqlen?}{${txqlen?}{${tab}{10}txqueuelen:${txqlen}}${\\n}}" \ "${newline}" }, /* Resembles the output of ifconfig shipped with unix systems like Solaris 2.7 or HPUX 10.20. */ { "unix", "${format}{check-existance}" \ "${name}: flags=${flags}{number}<${flags}{string}{,}>" \ "${mtu?}{ mtu ${mtu}}${\\n}" \ "${addr?}{${\\t}inet ${addr}" \ " netmask ${netmask}{0}{%02x}${netmask}{1}{%02x}" \ "${netmask}{2}{%02x}${netmask}{3}{%02x}" \ "${brdaddr?}{ broadcast ${brdaddr}}${\\n}}" \ "${exists?}{hwtype?}{${hwtype?}{${\\t}${hwtype}" \ "}${exists?}{hwaddr?}{${hwaddr?}{ ${hwaddr}}}${\\n}}" }, /* Resembles the output of ifconfig shipped with OSF 4.0g. */ { "osf", "${format}{check-existance}" \ "${name}: flags=${flags}{number}{%x}<${flags}{string}{,}>${\\n}" \ "${addr?}{${\\t}inet ${addr}" \ " netmask ${netmask}{0}{%02x}${netmask}{1}{%02x}" \ "${netmask}{2}{%02x}${netmask}{3}{%02x}" \ "${brdaddr?}{ broadcast ${brdaddr}}" \ "${mtu?}{ ipmtu ${mtu}}${\\n}}" }, /* If interface does not exist, print error message and exit. */ { "check-existance", "${index?}{}" \ "{${error}{${progname}: error: interface `${name}' does not exist${\\n}}" \ "${exit}{1}}" }, { 0, 0 }};/* Default format. */const char *default_format;/* The "+" is necessary to avoid parsing of system specific pseudo options like `-promisc'. */static const char *short_options = "+i:a:m:d:p:b:M:vV" ;static struct option long_options[] = {#ifdef SYSTEM_LONG_OPTIONSSYSTEM_LONG_OPTIONS#endif {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {"help", no_argument, 0, '&'}, {"interface", required_argument, 0, 'i'}, {"address", required_argument, 0, 'a'}, {"netmask", required_argument, 0, 'm'}, {"dstaddr", required_argument, 0, 'd'}, {"peer", required_argument, 0, 'p'}, {"brdaddr", required_argument, 0, 'b'}, {"broadcast", required_argument, 0, 'B'}, {"mtu", required_argument, 0, 'M'}, {"metric", required_argument, 0, '3'}, {"format", optional_argument, 0, '4'}, {0, 0, 0, 0}};voidusage (int err){ if (err != EXIT_SUCCESS) { fprintf (stderr, "Usage: %s [OPTION]...%s\n", program_name, system_help ? " [SYSTEM OPTION]..." : ""); fprintf (stderr, "Try `%s --help' for more information.\n", program_name); } else { fprintf (stdout, "Usage: %s [OPTION]...%s\n", program_name, system_help ? " [SYSTEM OPTION]..." : ""); puts ("Configure network interfaces.\n\n\Options are:\n\ -i, --interface NAME Configure network interface NAME\n\ -a, --address ADDR Set interface address to ADDR\n\ -m, --netmask MASK Set netmask to MASK\n\ -d, --dstaddr DSTADDR,\n\ -p, --peer DSTADDR Set destination (peer) address to DSTADDR\n\ -b, --broadcast BRDADDR,\n\ --brdaddr BRDADDR Set broadcast address to BRDADDR\n\ -M, --mtu N Set mtu of interface to N\n\ --metric N Set metric of interface to N\n\ --format=FORMAT Select output format (or set back to default)"); if (system_help_options) puts (system_help_options); puts("\ -v, --verbose Output information when configuring interface.\n\ --help Display this help and exit\n\ -V, --version Output version information and exit"); if (system_help) { puts ("\nSystem options are:"); puts (system_help); puts ("\The system options provide an alternative, backward compatible command line\n\interface. It is discouraged and should not be used."); } fprintf (stdout, "\nSubmit bug reports to %s.\n", PACKAGE_BUGREPORT); } exit (err);}struct ifconfig *parse_opt_new_ifs (char *name){ struct ifconfig *ifp; ifs = realloc (ifs, ++nifs * sizeof (struct ifconfig)); if (!ifs) { fprintf (stderr, "%s: can't get memory for interface " "configuration: %s\n", program_name, strerror (errno)); exit (EXIT_FAILURE); } ifp = &ifs[nifs - 1]; *ifp = ifconfig_initializer; ifp->name = name; return ifp;}#define PARSE_OPT_SET_ADDR(field, fname, fvalid) \void \parse_opt_set_##field (struct ifconfig *ifp, char *addr) \{ \ if (!ifp) \ { \ fprintf (stderr, "%s: no interface specified for " #fname \ " `%s'\n", program_name, addr); \ usage (EXIT_FAILURE); \ } \ if (ifp->valid & IF_VALID_##fvalid) \ { \ fprintf (stderr, "%s: only one " #fname \ " allowed for interface `%s'\n", \ program_name, ifp->name); \ usage (EXIT_FAILURE); \ } \ ifp->field = addr; \ ifp->valid |= IF_VALID_##fvalid; \}PARSE_OPT_SET_ADDR(address, address, ADDR)PARSE_OPT_SET_ADDR(netmask, netmask, NETMASK)PARSE_OPT_SET_ADDR(dstaddr, destination/peer address, DSTADDR)PARSE_OPT_SET_ADDR(brdaddr, broadcast address, BRDADDR)#define PARSE_OPT_SET_INT(field, fname, fvalid) \void \parse_opt_set_##field (struct ifconfig *ifp, char *arg) \{ \ char *end; \ if (!ifp) \ { \ fprintf (stderr, "%s: no interface specified for " #fname \ " `%s'\n", program_name, arg); \ usage (EXIT_FAILURE); \ } \ if (ifp->valid & IF_VALID_##fvalid) \ { \ fprintf (stderr, "%s: only one " #fname \ " allowed for interface `%s'\n", \ program_name, ifp->name); \ usage (EXIT_FAILURE); \ } \ ifp->field = strtol (arg, &end, 0); \ if (*arg == '\0' || *end != '\0') \ { \ fprintf (stderr, "%s: mtu value `%s' for interface `%s' " \ "is not a number.\n", \ program_name, optarg, ifp->name); \ exit (EXIT_FAILURE); \ } \ ifp->valid |= IF_VALID_##fvalid; \}PARSE_OPT_SET_INT(mtu, mtu value, MTU)PARSE_OPT_SET_INT(metric, metric value, METRIC)voidparse_opt_set_af (struct ifconfig *ifp, char *af){ if (!ifp) { fprintf (stderr, "%s: no interface specified for address" " family `%s'\n", program_name, af); usage (EXIT_FAILURE); } if (! strcasecmp (af, "inet")) ifp->af = AF_INET; else { fprintf (stderr, "%s: unknown address family `%s' for interface `%s'" " is not a number.\n", program_name, optarg, ifp->name); exit (EXIT_FAILURE); } ifp->valid |= IF_VALID_AF;}voidparse_opt_set_default_format (const char *new_format){ struct format *frm = formats; const char *format = new_format; if (! format) format = system_default_format ? system_default_format : "default"; while (frm->name) { if (! strcmp (format ? format : "default", frm->name)) break; frm++; } /* If we didn't find the format, set the user specified one. */ if (frm->name) default_format = frm->templ; else if (format) default_format = format; else default_format = "default";}/* Must be reentrant! */voidparse_opt_finalize (struct ifconfig *ifp){ if (ifp && ! ifp->valid) { ifp->valid = IF_VALID_FORMAT; ifp->format = default_format; }}char *program_name;voidparse_opt (int argc, char *argv[]){ int option; struct ifconfig *ifp = ifs; program_name = argv[0]; parse_opt_set_default_format (NULL); while ((option = getopt_long (argc, argv, short_options, long_options, 0)) != EOF) { /* XXX: Allow new ifs be created by system_parse_opt. Provide helper function for that (esp necessary for system specific parsing of remaining args. */ if (system_parse_opt (&ifp, option, optarg)) continue; switch(option) { case 'i': /* Interface name. */ parse_opt_finalize (ifp); ifp = parse_opt_new_ifs (optarg); break; case 'a': /* Interface address. */ parse_opt_set_address (ifp, optarg); break; case 'm': /* Interface netmask. */ parse_opt_set_netmask (ifp, optarg); break; case 'd': /* Interface dstaddr. */ case 'p': parse_opt_set_dstaddr (ifp, optarg); break; case 'b': /* Interface broadcast address. */ case 'B': parse_opt_set_brdaddr (ifp, optarg); break; case 'M': /* Interface MTU. */ parse_opt_set_mtu (ifp, optarg); break; case '3': /* Interface metric. */ parse_opt_set_metric (ifp, optarg); break; case '4': /* Output format. */ parse_opt_set_default_format (optarg); break; case 'v': /* Verbose. */ verbose = 1; break; case '&': /* Help. */ usage (EXIT_SUCCESS); /* Not reached. */ case 'V': /* Version. */ printf ("ifconfig (%s) %s\n", PACKAGE_NAME, PACKAGE_VERSION); exit (EXIT_SUCCESS); case '?': default: usage (EXIT_FAILURE); /* Not reached. */ } } parse_opt_finalize (ifp); if (optind < argc) { if (! system_parse_opt_rest (&ifp, argc - optind, &argv[optind])) usage (EXIT_FAILURE); parse_opt_finalize (ifp); } if (!ifs) { /* No interfaces specified. Get a list of all interfaces. */ struct if_nameindex *ifnx, *ifnxp; ifnx = ifnxp = if_nameindex(); while (ifnxp->if_index != 0 || ifnxp->if_name != NULL) { struct ifconfig *ifp; ifs = realloc (ifs, ++nifs * sizeof (struct ifconfig)); if (!ifs) { fprintf (stderr, "%s: can't get memory for interface " "configuration: %s\n", program_name, strerror (errno)); exit (EXIT_FAILURE); } ifp = &ifs[nifs - 1]; *ifp = ifconfig_initializer; ifp->name = ifnxp->if_name; ifp->valid = IF_VALID_FORMAT; ifp->format = default_format; ifnxp++; } /* XXX: We never do if_freenameindex (ifnx), because we are keeping the names for later instead using strdup (if->if_name) here. */ }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -