libnl  3.3.0
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 #include <locale.h>
26 
27 /**
28  * Parse a text based 32 bit unsigned integer argument
29  * @arg arg Integer in text form.
30  *
31  * Tries to convert the number provided in arg to a uint32_t. Will call
32  * nl_cli_fatal() if the conversion fails.
33  *
34  * @return 32bit unsigned integer.
35  */
36 uint32_t nl_cli_parse_u32(const char *arg)
37 {
38  unsigned long lval;
39  char *endptr;
40 
41  lval = strtoul(arg, &endptr, 0);
42  if (endptr == arg || lval == ULONG_MAX)
43  nl_cli_fatal(EINVAL, "Unable to parse \"%s\", not a number.",
44  arg);
45 
46  return (uint32_t) lval;
47 }
48 
49 void nl_cli_print_version(void)
50 {
51  printf("libnl tools version %s\n", LIBNL_VERSION);
52  printf(
53  "Copyright (C) 2003-2010 Thomas Graf <tgraf@redhat.com>\n"
54  "\n"
55  "This program comes with ABSOLUTELY NO WARRANTY. This is free \n"
56  "software, and you are welcome to redistribute it under certain\n"
57  "conditions. See the GNU General Public License for details.\n"
58  );
59 
60  exit(0);
61 }
62 
63 /**
64  * Print error message and quit application
65  * @arg err Error code.
66  * @arg fmt Error message.
67  *
68  * Prints the formatted error message to stderr and quits the application
69  * using the provided error code.
70  */
71 void nl_cli_fatal(int err, const char *fmt, ...)
72 {
73  va_list ap;
74 
75  fprintf(stderr, "Error: ");
76 
77  if (fmt) {
78  va_start(ap, fmt);
79  vfprintf(stderr, fmt, ap);
80  va_end(ap);
81  fprintf(stderr, "\n");
82  } else {
83  char *buf;
84 #ifdef HAVE_STRERROR_L
85  locale_t loc = newlocale(LC_MESSAGES_MASK, "", (locale_t)0);
86  if (loc == (locale_t)0) {
87  if (errno == ENOENT)
88  loc = newlocale(LC_MESSAGES_MASK,
89  "POSIX", (locale_t)0);
90  if (loc == (locale_t)0)
91  buf = "newlocale() failed";
92  }
93  if (loc != (locale_t)0)
94  buf = strerror_l(err, loc);
95 #else
96  buf = strerror(err);
97 #endif
98  fprintf(stderr, "%s\n", buf);
99 #ifdef HAVE_STRERROR_L
100  if (loc != (locale_t)0)
101  freelocale(loc);
102 #endif
103  }
104 
105  exit(abs(err));
106 }
107 
108 int nl_cli_connect(struct nl_sock *sk, int protocol)
109 {
110  int err;
111 
112  if ((err = nl_connect(sk, protocol)) < 0)
113  nl_cli_fatal(err, "Unable to connect netlink socket: %s",
114  nl_geterror(err));
115 
116  return err;
117 }
118 
119 struct nl_sock *nl_cli_alloc_socket(void)
120 {
121  struct nl_sock *sock;
122 
123  if (!(sock = nl_socket_alloc()))
124  nl_cli_fatal(ENOBUFS, "Unable to allocate netlink socket");
125 
126  return sock;
127 }
128 
129 struct nl_addr *nl_cli_addr_parse(const char *str, int family)
130 {
131  struct nl_addr *addr;
132  int err;
133 
134  if ((err = nl_addr_parse(str, family, &addr)) < 0)
135  nl_cli_fatal(err, "Unable to parse address \"%s\": %s",
136  str, nl_geterror(err));
137 
138  return addr;
139 }
140 
141 int nl_cli_parse_dumptype(const char *str)
142 {
143  if (!strcasecmp(str, "brief"))
144  return NL_DUMP_LINE;
145  else if (!strcasecmp(str, "details") || !strcasecmp(str, "detailed"))
146  return NL_DUMP_DETAILS;
147  else if (!strcasecmp(str, "stats"))
148  return NL_DUMP_STATS;
149  else
150  nl_cli_fatal(EINVAL, "Invalid dump type \"%s\".\n", str);
151 
152  return 0;
153 }
154 
155 int nl_cli_confirm(struct nl_object *obj, struct nl_dump_params *params,
156  int default_yes)
157 {
158  nl_object_dump(obj, params);
159 
160  for (;;) {
161  char buf[32] = { 0 };
162  int answer;
163 
164  printf("Delete? (%c/%c) ",
165  default_yes ? 'Y' : 'y',
166  default_yes ? 'n' : 'N');
167 
168  if (!fgets(buf, sizeof(buf), stdin)) {
169  fprintf(stderr, "Error while reading\n.");
170  continue;
171  }
172 
173  switch ((answer = tolower(buf[0]))) {
174  case '\n':
175  answer = default_yes ? 'y' : 'n';
176  case 'y':
177  case 'n':
178  return answer == 'y';
179  }
180 
181  fprintf(stderr, "Invalid input, try again.\n");
182  }
183 
184  return 0;
185 
186 }
187 
188 struct nl_cache *nl_cli_alloc_cache(struct nl_sock *sock, const char *name,
189  int (*ac)(struct nl_sock *, struct nl_cache **))
190 {
191  struct nl_cache *cache;
192  int err;
193 
194  if ((err = ac(sock, &cache)) < 0)
195  nl_cli_fatal(err, "Unable to allocate %s cache: %s",
196  name, nl_geterror(err));
197 
198  nl_cache_mngt_provide(cache);
199 
200  return cache;
201 }
202 
203 struct nl_cache *nl_cli_alloc_cache_flags(struct nl_sock *sock,
204  const char *name, unsigned int flags,
205  int (*ac)(struct nl_sock *, struct nl_cache **,
206  unsigned int))
207 {
208  struct nl_cache *cache;
209  int err;
210 
211  if ((err = ac(sock, &cache, flags)) < 0)
212  nl_cli_fatal(err, "Unable to allocate %s cache: %s",
213  name, nl_geterror(err));
214 
215  nl_cache_mngt_provide(cache);
216 
217  return cache;
218 }
219 
220 void nl_cli_load_module(const char *prefix, const char *name)
221 {
222  char path[FILENAME_MAX+1];
223  void *handle;
224 
225  snprintf(path, sizeof(path), "%s/%s/%s.so",
226  PKGLIBDIR, prefix, name);
227 
228  if (!(handle = dlopen(path, RTLD_NOW)))
229  nl_cli_fatal(ENOENT, "Unable to load module \"%s\": %s\n",
230  path, dlerror());
231 }
232 
233 /** @} */
Dump object briefly on one line.
Definition: types.h:22
void nl_cache_mngt_provide(struct nl_cache *cache)
Provide a cache for global use.
Definition: cache_mngt.c:332
int nl_addr_parse(const char *addrstr, int hint, struct nl_addr **result)
Allocate abstract address based on character string.
Definition: addr.c:291
Dump all attributes but no statistics.
Definition: types.h:23
struct nl_sock * nl_socket_alloc(void)
Allocate new netlink socket.
Definition: socket.c:205
int nl_connect(struct nl_sock *sk, int protocol)
Create file descriptor and bind socket.
Definition: nl.c:103
void nl_object_dump(struct nl_object *obj, struct nl_dump_params *params)
Dump this object according to the specified parameters.
Definition: object.c:288
uint32_t nl_cli_parse_u32(const char *arg)
Parse a text based 32 bit unsigned integer argument.
Definition: utils.c:36
void nl_cli_fatal(int err, const char *fmt,...)
Print error message and quit application.
Definition: utils.c:71
Dumping parameters.
Definition: types.h:33
Dump all attributes including statistics.
Definition: types.h:24