tests: Retry tests use bashisms, so set #!
[nbdkit/ericb.git] / server / public.c
blob9a3aa315aadbbf3dee6f27880f9d26f6802f2f1d
1 /* nbdkit
2 * Copyright (C) 2013-2019 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
33 /* This file contains the public utility APIs to be exported by nbdkit
34 * for use by filters and plugins, declared in nbdkit-common.h.
37 #include <config.h>
39 #include <fcntl.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <stdbool.h>
43 #include <stdint.h>
44 #include <inttypes.h>
45 #include <string.h>
46 #include <unistd.h>
47 #include <limits.h>
48 #include <ctype.h>
49 #include <termios.h>
50 #include <errno.h>
51 #include <poll.h>
52 #include <signal.h>
53 #include <sys/socket.h>
55 #include "get-current-dir-name.h"
57 #include "internal.h"
59 char *
60 nbdkit_absolute_path (const char *path)
62 CLEANUP_FREE char *pwd = NULL;
63 char *ret;
65 if (path == NULL || *path == '\0') {
66 nbdkit_error ("cannot convert null or empty path to an absolute path");
67 return NULL;
70 if (*path == '/') {
71 ret = strdup (path);
72 if (!ret) {
73 nbdkit_error ("strdup: %m");
74 return NULL;
76 return ret;
79 pwd = get_current_dir_name ();
80 if (pwd == NULL) {
81 nbdkit_error ("get_current_dir_name: %m");
82 return NULL;
85 if (asprintf (&ret, "%s/%s", pwd, path) == -1) {
86 nbdkit_error ("asprintf: %m");
87 return NULL;
90 return ret;
93 char *
94 nbdkit_realpath (const char *path)
96 char *ret;
98 if (path == NULL || *path == '\0') {
99 nbdkit_error ("cannot resolve a null or empty path");
100 return NULL;
103 ret = realpath (path, NULL);
104 if (ret == NULL) {
105 nbdkit_error ("realpath: %s: %m", path);
106 return NULL;
109 return ret;
112 /* Common code for parsing integers. */
113 #define PARSE_COMMON_TAIL \
114 if (errno != 0) { \
115 nbdkit_error ("%s: could not parse number: \"%s\": %m", \
116 what, str); \
117 return -1; \
119 if (end == str) { \
120 nbdkit_error ("%s: empty string where we expected a number", \
121 what); \
122 return -1; \
124 if (*end) { \
125 nbdkit_error ("%s: could not parse number: \"%s\": trailing garbage", \
126 what, str); \
127 return -1; \
130 if (rp) \
131 *rp = r; \
132 return 0
134 /* Functions for parsing signed integers. */
136 nbdkit_parse_int (const char *what, const char *str, int *rp)
138 long r;
139 char *end;
141 errno = 0;
142 r = strtol (str, &end, 0);
143 #if INT_MAX != LONG_MAX
144 if (r < INT_MIN || r > INT_MAX)
145 errno = ERANGE;
146 #endif
147 PARSE_COMMON_TAIL;
151 nbdkit_parse_int8_t (const char *what, const char *str, int8_t *rp)
153 long r;
154 char *end;
156 errno = 0;
157 r = strtol (str, &end, 0);
158 if (r < INT8_MIN || r > INT8_MAX)
159 errno = ERANGE;
160 PARSE_COMMON_TAIL;
164 nbdkit_parse_int16_t (const char *what, const char *str, int16_t *rp)
166 long r;
167 char *end;
169 errno = 0;
170 r = strtol (str, &end, 0);
171 if (r < INT16_MIN || r > INT16_MAX)
172 errno = ERANGE;
173 PARSE_COMMON_TAIL;
177 nbdkit_parse_int32_t (const char *what, const char *str, int32_t *rp)
179 long r;
180 char *end;
182 errno = 0;
183 r = strtol (str, &end, 0);
184 #if INT32_MAX != LONG_MAX
185 if (r < INT32_MIN || r > INT32_MAX)
186 errno = ERANGE;
187 #endif
188 PARSE_COMMON_TAIL;
192 nbdkit_parse_int64_t (const char *what, const char *str, int64_t *rp)
194 long long r;
195 char *end;
197 errno = 0;
198 r = strtoll (str, &end, 0);
199 #if INT64_MAX != LONGLONG_MAX
200 if (r < INT64_MIN || r > INT64_MAX)
201 errno = ERANGE;
202 #endif
203 PARSE_COMMON_TAIL;
206 /* Functions for parsing unsigned integers. */
208 /* strtou* functions have surprising behaviour if the first character
209 * (after whitespace) is '-', so reject this early.
211 #define PARSE_ERROR_IF_NEGATIVE \
212 do { \
213 while (isspace (*str)) \
214 str++; \
215 if (*str == '-') { \
216 nbdkit_error ("%s: negative numbers are not allowed", what); \
217 return -1; \
219 } while (0)
222 nbdkit_parse_unsigned (const char *what, const char *str, unsigned *rp)
224 unsigned long r;
225 char *end;
227 PARSE_ERROR_IF_NEGATIVE;
228 errno = 0;
229 r = strtoul (str, &end, 0);
230 #if UINT_MAX != ULONG_MAX
231 if (r > UINT_MAX)
232 errno = ERANGE;
233 #endif
234 PARSE_COMMON_TAIL;
238 nbdkit_parse_uint8_t (const char *what, const char *str, uint8_t *rp)
240 unsigned long r;
241 char *end;
243 PARSE_ERROR_IF_NEGATIVE;
244 errno = 0;
245 r = strtoul (str, &end, 0);
246 if (r > UINT8_MAX)
247 errno = ERANGE;
248 PARSE_COMMON_TAIL;
252 nbdkit_parse_uint16_t (const char *what, const char *str, uint16_t *rp)
254 unsigned long r;
255 char *end;
257 PARSE_ERROR_IF_NEGATIVE;
258 errno = 0;
259 r = strtoul (str, &end, 0);
260 if (r > UINT16_MAX)
261 errno = ERANGE;
262 PARSE_COMMON_TAIL;
266 nbdkit_parse_uint32_t (const char *what, const char *str, uint32_t *rp)
268 unsigned long r;
269 char *end;
271 PARSE_ERROR_IF_NEGATIVE;
272 errno = 0;
273 r = strtoul (str, &end, 0);
274 #if UINT32_MAX != ULONG_MAX
275 if (r > UINT32_MAX)
276 errno = ERANGE;
277 #endif
278 PARSE_COMMON_TAIL;
282 nbdkit_parse_uint64_t (const char *what, const char *str, uint64_t *rp)
284 unsigned long long r;
285 char *end;
287 PARSE_ERROR_IF_NEGATIVE;
288 errno = 0;
289 r = strtoull (str, &end, 0);
290 #if UINT64_MAX != ULONGLONG_MAX
291 if (r > UINT64_MAX)
292 errno = ERANGE;
293 #endif
294 PARSE_COMMON_TAIL;
297 /* Parse a string as a size with possible scaling suffix, or return -1
298 * after reporting the error.
300 int64_t
301 nbdkit_parse_size (const char *str)
303 int64_t size;
304 char *end;
305 uint64_t scale = 1;
307 /* Disk sizes cannot usefully exceed off_t (which is signed) and
308 * cannot be negative. */
309 /* XXX Should we also parse things like '1.5M'? */
310 /* XXX Should we allow hex? If so, hex cannot use scaling suffixes,
311 * because some of them are valid hex digits */
312 errno = 0;
313 size = strtoimax (str, &end, 10);
314 if (str == end) {
315 nbdkit_error ("could not parse size string (%s)", str);
316 return -1;
318 if (size < 0) {
319 nbdkit_error ("size cannot be negative (%s)", str);
320 return -1;
322 if (errno) {
323 nbdkit_error ("size (%s) exceeds maximum value", str);
324 return -1;
327 switch (*end) {
328 /* No suffix */
329 case '\0':
330 end--; /* Safe, since we already filtered out empty string */
331 break;
333 /* Powers of 1024 */
334 case 'e': case 'E':
335 scale *= 1024;
336 /* fallthru */
337 case 'p': case 'P':
338 scale *= 1024;
339 /* fallthru */
340 case 't': case 'T':
341 scale *= 1024;
342 /* fallthru */
343 case 'g': case 'G':
344 scale *= 1024;
345 /* fallthru */
346 case 'm': case 'M':
347 scale *= 1024;
348 /* fallthru */
349 case 'k': case 'K':
350 scale *= 1024;
351 /* fallthru */
352 case 'b': case 'B':
353 break;
355 /* "sectors", ie. units of 512 bytes, even if that's not the real
356 * sector size */
357 case 's': case 'S':
358 scale = 512;
359 break;
361 default:
362 nbdkit_error ("could not parse size: unknown suffix '%s'", end);
363 return -1;
366 /* XXX Maybe we should support 'MiB' as a synonym for 'M'; and 'MB'
367 * for powers of 1000, for similarity to GNU tools. But for now,
368 * anything beyond 'M' is dropped. */
369 if (end[1]) {
370 nbdkit_error ("could not parse size: unknown suffix '%s'", end);
371 return -1;
374 if (INT64_MAX / scale < size) {
375 nbdkit_error ("overflow computing size (%s)", str);
376 return -1;
379 return size * scale;
382 /* Parse a string as a boolean, or return -1 after reporting the error.
385 nbdkit_parse_bool (const char *str)
387 if (!strcmp (str, "1") ||
388 !strcasecmp (str, "true") ||
389 !strcasecmp (str, "t") ||
390 !strcasecmp (str, "yes") ||
391 !strcasecmp (str, "y") ||
392 !strcasecmp (str, "on"))
393 return 1;
395 if (!strcmp (str, "0") ||
396 !strcasecmp (str, "false") ||
397 !strcasecmp (str, "f") ||
398 !strcasecmp (str, "no") ||
399 !strcasecmp (str, "n") ||
400 !strcasecmp (str, "off"))
401 return 0;
403 nbdkit_error ("could not decipher boolean (%s)", str);
404 return -1;
407 /* Read a password from configuration value. */
409 nbdkit_read_password (const char *value, char **password)
411 int tty, err;
412 struct termios orig, temp;
413 ssize_t r;
414 size_t n;
415 FILE *fp;
417 *password = NULL;
419 /* Read from stdin. */
420 if (strcmp (value, "-") == 0) {
421 printf ("password: ");
423 /* Set no echo. */
424 tty = isatty (0);
425 if (tty) {
426 tcgetattr (0, &orig);
427 temp = orig;
428 temp.c_lflag &= ~ECHO;
429 tcsetattr (0, TCSAFLUSH, &temp);
432 r = getline (password, &n, stdin);
433 err = errno;
435 /* Restore echo. */
436 if (tty)
437 tcsetattr (0, TCSAFLUSH, &orig);
439 /* Complete the printf above. */
440 printf ("\n");
442 if (r == -1) {
443 errno = err;
444 nbdkit_error ("could not read password from stdin: %m");
445 return -1;
447 if (*password && r > 0 && (*password)[r-1] == '\n')
448 (*password)[r-1] = '\0';
451 /* Read password from a file. */
452 else if (value[0] == '+') {
453 int fd;
455 fd = open (&value[1], O_CLOEXEC | O_RDONLY);
456 if (fd == -1) {
457 nbdkit_error ("open %s: %m", &value[1]);
458 return -1;
460 fp = fdopen (fd, "r");
461 if (fp == NULL) {
462 nbdkit_error ("fdopen %s: %m", &value[1]);
463 close (fd);
464 return -1;
466 r = getline (password, &n, fp);
467 err = errno;
468 fclose (fp);
469 if (r == -1) {
470 errno = err;
471 nbdkit_error ("could not read password from file %s: %m", &value[1]);
472 return -1;
474 if (*password && r > 0 && (*password)[r-1] == '\n')
475 (*password)[r-1] = '\0';
478 /* Parameter is the password. */
479 else {
480 *password = strdup (value);
481 if (*password == NULL) {
482 nbdkit_error ("strdup: %m");
483 return -1;
487 return 0;
491 nbdkit_nanosleep (unsigned sec, unsigned nsec)
493 struct timespec ts;
495 if (sec >= INT_MAX - nsec / 1000000000) {
496 nbdkit_error ("sleep request is too long");
497 errno = EINVAL;
498 return -1;
500 ts.tv_sec = sec + nsec / 1000000000;
501 ts.tv_nsec = nsec % 1000000000;
503 #if defined HAVE_PPOLL && defined POLLRDHUP
504 /* End the sleep early if any of these happen:
505 * - nbdkit has received a signal to shut down the server
506 * - the current connection is multi-threaded and another thread detects
507 * NBD_CMD_DISC or a problem with the connection
508 * - the input socket detects POLLRDHUP/POLLHUP/POLLERR
510 struct connection *conn = threadlocal_get_conn ();
511 struct pollfd fds[] = {
512 [0].fd = quit_fd,
513 [0].events = POLLIN,
514 [1].fd = conn ? conn->status_pipe[0] : -1,
515 [1].events = POLLIN,
516 [2].fd = conn ? conn->sockin : -1,
517 [2].events = POLLRDHUP,
519 sigset_t all;
521 /* Block all signals to this thread during the poll, so we don't
522 * have to worry about EINTR
524 if (sigfillset(&all))
525 abort ();
526 switch (ppoll (fds, sizeof fds / sizeof fds[0], &ts, &all)) {
527 case -1:
528 assert (errno != EINTR);
529 nbdkit_error ("poll: %m");
530 return -1;
531 case 0:
532 return 0;
535 /* We don't have to read the pipe-to-self; if poll returned an
536 * event, we know the connection should be shutting down.
538 assert (quit ||
539 (conn && conn->nworkers > 0 && connection_get_status (conn) < 1) ||
540 (conn && (fds[2].revents & (POLLRDHUP | POLLHUP | POLLERR))));
541 nbdkit_error ("aborting sleep to shut down");
542 errno = ESHUTDOWN;
543 return -1;
545 #else
546 /* The fallback path simply calls ordinary nanosleep, and will
547 * cause long delays on server shutdown.
549 * If however you want to port this to your platform, then
550 * porting ideas, in order of preference:
551 * - POSIX requires pselect; it's a bit clunkier to set up than poll,
552 * but the same ability to atomically mask all signals and operate
553 * on struct timespec makes it similar to the preferred ppoll interface
554 * - calculate an end time target, then use poll in a loop on EINTR with
555 * a recalculation of the timeout to still reach the end time (masking
556 * signals in that case is not safe, as it is a non-atomic race)
558 int r;
560 r = nanosleep (&ts, NULL);
561 if (r == -1 && errno != EINTR && errno != EAGAIN) {
562 nbdkit_error ("nanosleep: %m");
563 return -1;
565 return 0;
566 #endif
569 const char *
570 nbdkit_export_name (void)
572 struct connection *conn = threadlocal_get_conn ();
574 if (!conn) {
575 nbdkit_error ("no connection in this thread");
576 return NULL;
579 return conn->exportname;
583 nbdkit_peer_name (struct sockaddr *addr, socklen_t *addrlen)
585 struct connection *conn = threadlocal_get_conn ();
586 int s;
588 if (!conn) {
589 nbdkit_error ("no connection in this thread");
590 return -1;
593 s = conn->sockin;
594 if (s == -1) {
595 nbdkit_error ("socket not open");
596 return -1;
599 if (getpeername (s, addr, addrlen) == -1) {
600 nbdkit_error ("peername: %m");
601 return -1;
604 return 0;