libnl  3.3.0-rc1
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  locale_t loc = newlocale(LC_MESSAGES_MASK, "", (locale_t)0);
85  if (loc == (locale_t)0) {
86  if (errno == ENOENT)
87  loc = newlocale(LC_MESSAGES_MASK,
88  "POSIX", (locale_t)0);
89  if (loc == (locale_t)0)
90  buf = "newlocale() failed";
91  }
92  if (loc != (locale_t)0)
93  buf = strerror_l(err, loc);
94  fprintf(stderr, "%s\n", buf);
95  if (loc != (locale_t)0)
96  freelocale(loc);
97  }
98 
99  exit(abs(err));
100 }
101 
102 int nl_cli_connect(struct nl_sock *sk, int protocol)
103 {
104  int err;
105 
106  if ((err = nl_connect(sk, protocol)) < 0)
107  nl_cli_fatal(err, "Unable to connect netlink socket: %s",
108  nl_geterror(err));
109 
110  return err;
111 }
112 
113 struct nl_sock *nl_cli_alloc_socket(void)
114 {
115  struct nl_sock *sock;
116 
117  if (!(sock = nl_socket_alloc()))
118  nl_cli_fatal(ENOBUFS, "Unable to allocate netlink socket");
119 
120  return sock;
121 }
122 
123 struct nl_addr *nl_cli_addr_parse(const char *str, int family)
124 {
125  struct nl_addr *addr;
126  int err;
127 
128  if ((err = nl_addr_parse(str, family, &addr)) < 0)
129  nl_cli_fatal(err, "Unable to parse address \"%s\": %s",
130  str, nl_geterror(err));
131 
132  return addr;
133 }
134 
135 int nl_cli_parse_dumptype(const char *str)
136 {
137  if (!strcasecmp(str, "brief"))
138  return NL_DUMP_LINE;
139  else if (!strcasecmp(str, "details") || !strcasecmp(str, "detailed"))
140  return NL_DUMP_DETAILS;
141  else if (!strcasecmp(str, "stats"))
142  return NL_DUMP_STATS;
143  else
144  nl_cli_fatal(EINVAL, "Invalid dump type \"%s\".\n", str);
145 
146  return 0;
147 }
148 
149 int nl_cli_confirm(struct nl_object *obj, struct nl_dump_params *params,
150  int default_yes)
151 {
152  nl_object_dump(obj, params);
153 
154  for (;;) {
155  char buf[32] = { 0 };
156  int answer;
157 
158  printf("Delete? (%c/%c) ",
159  default_yes ? 'Y' : 'y',
160  default_yes ? 'n' : 'N');
161 
162  if (!fgets(buf, sizeof(buf), stdin)) {
163  fprintf(stderr, "Error while reading\n.");
164  continue;
165  }
166 
167  switch ((answer = tolower(buf[0]))) {
168  case '\n':
169  answer = default_yes ? 'y' : 'n';
170  case 'y':
171  case 'n':
172  return answer == 'y';
173  }
174 
175  fprintf(stderr, "Invalid input, try again.\n");
176  }
177 
178  return 0;
179 
180 }
181 
182 struct nl_cache *nl_cli_alloc_cache(struct nl_sock *sock, const char *name,
183  int (*ac)(struct nl_sock *, struct nl_cache **))
184 {
185  struct nl_cache *cache;
186  int err;
187 
188  if ((err = ac(sock, &cache)) < 0)
189  nl_cli_fatal(err, "Unable to allocate %s cache: %s",
190  name, nl_geterror(err));
191 
192  nl_cache_mngt_provide(cache);
193 
194  return cache;
195 }
196 
197 struct nl_cache *nl_cli_alloc_cache_flags(struct nl_sock *sock,
198  const char *name, unsigned int flags,
199  int (*ac)(struct nl_sock *, struct nl_cache **,
200  unsigned int))
201 {
202  struct nl_cache *cache;
203  int err;
204 
205  if ((err = ac(sock, &cache, flags)) < 0)
206  nl_cli_fatal(err, "Unable to allocate %s cache: %s",
207  name, nl_geterror(err));
208 
209  nl_cache_mngt_provide(cache);
210 
211  return cache;
212 }
213 
214 void nl_cli_load_module(const char *prefix, const char *name)
215 {
216  char path[FILENAME_MAX+1];
217  void *handle;
218 
219  snprintf(path, sizeof(path), "%s/%s/%s.so",
220  PKGLIBDIR, prefix, name);
221 
222  if (!(handle = dlopen(path, RTLD_NOW)))
223  nl_cli_fatal(ENOENT, "Unable to load module \"%s\": %s\n",
224  path, dlerror());
225 }
226 
227 /** @} */
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