libnl  3.2.14
utils.c
1 /*
2  * src/utils.c Utilities
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation version 2.1
7  * of the License.
8  *
9  * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
10  */
11 
12 /**
13  * @defgroup cli Command Line Interface API
14  *
15  * @{
16  *
17  * These modules provide an interface for text based applications. The
18  * functions provided are wrappers for their libnl equivalent with
19  * added error handling. The functions check for allocation failures,
20  * invalid input, and unknown types and will print error messages
21  * accordingly via nl_cli_fatal().
22  */
23 
24 #include <netlink/cli/utils.h>
25 
26 /**
27  * Parse a text based 32 bit unsigned integer argument
28  * @arg arg Integer in text form.
29  *
30  * Tries to convert the number provided in arg to a uint32_t. Will call
31  * nl_cli_fatal() if the conversion fails.
32  *
33  * @return 32bit unsigned integer.
34  */
35 uint32_t nl_cli_parse_u32(const char *arg)
36 {
37  unsigned long lval;
38  char *endptr;
39 
40  lval = strtoul(arg, &endptr, 0);
41  if (endptr == arg || lval == ULONG_MAX)
42  nl_cli_fatal(EINVAL, "Unable to parse \"%s\", not a number.",
43  arg);
44 
45  return (uint32_t) lval;
46 }
47 
48 void nl_cli_print_version(void)
49 {
50  printf("libnl tools version %s\n", LIBNL_VERSION);
51  printf(
52  "Copyright (C) 2003-2010 Thomas Graf <tgraf@redhat.com>\n"
53  "\n"
54  "This program comes with ABSOLUTELY NO WARRANTY. This is free \n"
55  "software, and you are welcome to redistribute it under certain\n"
56  "conditions. See the GNU General Public License for details.\n"
57  );
58 
59  exit(0);
60 }
61 
62 /**
63  * Print error message and quit application
64  * @arg err Error code.
65  * @arg fmt Error message.
66  *
67  * Prints the formatted error message to stderr and quits the application
68  * using the provided error code.
69  */
70 void nl_cli_fatal(int err, const char *fmt, ...)
71 {
72  va_list ap;
73 
74  fprintf(stderr, "Error: ");
75 
76  if (fmt) {
77  va_start(ap, fmt);
78  vfprintf(stderr, fmt, ap);
79  va_end(ap);
80  fprintf(stderr, "\n");
81  } else
82  fprintf(stderr, "%s\n", strerror(err));
83 
84  exit(abs(err));
85 }
86 
87 int nl_cli_connect(struct nl_sock *sk, int protocol)
88 {
89  int err;
90 
91  if ((err = nl_connect(sk, protocol)) < 0)
92  nl_cli_fatal(err, "Unable to connect netlink socket: %s",
93  nl_geterror(err));
94 
95  return err;
96 }
97 
98 struct nl_sock *nl_cli_alloc_socket(void)
99 {
100  struct nl_sock *sock;
101 
102  if (!(sock = nl_socket_alloc()))
103  nl_cli_fatal(ENOBUFS, "Unable to allocate netlink socket");
104 
105  return sock;
106 }
107 
108 struct nl_addr *nl_cli_addr_parse(const char *str, int family)
109 {
110  struct nl_addr *addr;
111  int err;
112 
113  if ((err = nl_addr_parse(str, family, &addr)) < 0)
114  nl_cli_fatal(err, "Unable to parse address \"%s\": %s",
115  str, nl_geterror(err));
116 
117  return addr;
118 }
119 
120 int nl_cli_parse_dumptype(const char *str)
121 {
122  if (!strcasecmp(str, "brief"))
123  return NL_DUMP_LINE;
124  else if (!strcasecmp(str, "details") || !strcasecmp(str, "detailed"))
125  return NL_DUMP_DETAILS;
126  else if (!strcasecmp(str, "stats"))
127  return NL_DUMP_STATS;
128  else
129  nl_cli_fatal(EINVAL, "Invalid dump type \"%s\".\n", str);
130 
131  return 0;
132 }
133 
134 int nl_cli_confirm(struct nl_object *obj, struct nl_dump_params *params,
135  int default_yes)
136 {
137  nl_object_dump(obj, params);
138 
139  for (;;) {
140  char buf[32] = { 0 };
141  int answer;
142 
143  printf("Delete? (%c/%c) ",
144  default_yes ? 'Y' : 'y',
145  default_yes ? 'n' : 'N');
146 
147  if (!fgets(buf, sizeof(buf), stdin)) {
148  fprintf(stderr, "Error while reading\n.");
149  continue;
150  }
151 
152  switch ((answer = tolower(buf[0]))) {
153  case '\n':
154  answer = default_yes ? 'y' : 'n';
155  case 'y':
156  case 'n':
157  return answer == 'y';
158  }
159 
160  fprintf(stderr, "Invalid input, try again.\n");
161  }
162 
163  return 0;
164 
165 }
166 
167 struct nl_cache *nl_cli_alloc_cache(struct nl_sock *sock, const char *name,
168  int (*ac)(struct nl_sock *, struct nl_cache **))
169 {
170  struct nl_cache *cache;
171  int err;
172 
173  if ((err = ac(sock, &cache)) < 0)
174  nl_cli_fatal(err, "Unable to allocate %s cache: %s",
175  name, nl_geterror(err));
176 
177  nl_cache_mngt_provide(cache);
178 
179  return cache;
180 }
181 
182 void nl_cli_load_module(const char *prefix, const char *name)
183 {
184  char path[FILENAME_MAX+1];
185  void *handle;
186 
187  snprintf(path, sizeof(path), "%s/%s/%s.so",
188  PKGLIBDIR, prefix, name);
189 
190  if (!(handle = dlopen(path, RTLD_NOW)))
191  nl_cli_fatal(ENOENT, "Unable to load module \"%s\": %s\n",
192  path, dlerror());
193 }
194 
195 /** @} */