⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 options.c

📁 不用说了吧
💻 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 + -