Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */ 2 : : 3 : : #include <errno.h> 4 : : #include <getopt.h> 5 : : #include <stdbool.h> 6 : : #include <stddef.h> 7 : : #include <string.h> 8 : : 9 : : #include "env-util.h" 10 : : #include "log.h" 11 : : #include "macro.h" 12 : : #include "process-util.h" 13 : : #include "string-util.h" 14 : : #include "verbs.h" 15 : : #include "virt.h" 16 : : 17 : : /* Wraps running_in_chroot() which is used in various places, but also adds an environment variable check so external 18 : : * processes can reliably force this on. 19 : : */ 20 : 0 : bool running_in_chroot_or_offline(void) { 21 : : int r; 22 : : 23 : : /* Added to support use cases like rpm-ostree, where from %post scripts we only want to execute "preset", but 24 : : * not "start"/"restart" for example. 25 : : * 26 : : * See docs/ENVIRONMENT.md for docs. 27 : : */ 28 : 0 : r = getenv_bool("SYSTEMD_OFFLINE"); 29 [ # # # # ]: 0 : if (r < 0 && r != -ENXIO) 30 [ # # ]: 0 : log_debug_errno(r, "Failed to parse $SYSTEMD_OFFLINE: %m"); 31 [ # # ]: 0 : else if (r >= 0) 32 : 0 : return r > 0; 33 : : 34 : : /* We've had this condition check for a long time which basically checks for legacy chroot case like Fedora's 35 : : * "mock", which is used for package builds. We don't want to try to start systemd services there, since 36 : : * without --new-chroot we don't even have systemd running, and even if we did, adding a concept of background 37 : : * daemons to builds would be an enormous change, requiring considering things like how the journal output is 38 : : * handled, etc. And there's really not a use case today for a build talking to a service. 39 : : * 40 : : * Note this call itself also looks for a different variable SYSTEMD_IGNORE_CHROOT=1. 41 : : */ 42 : 0 : r = running_in_chroot(); 43 [ # # ]: 0 : if (r < 0) 44 [ # # ]: 0 : log_debug_errno(r, "running_in_chroot(): %m"); 45 : : 46 : 0 : return r > 0; 47 : : } 48 : : 49 : 36 : int dispatch_verb(int argc, char *argv[], const Verb verbs[], void *userdata) { 50 : : const Verb *verb; 51 : : const char *name; 52 : : unsigned i; 53 : : int left; 54 : : 55 [ - + ]: 36 : assert(verbs); 56 [ - + ]: 36 : assert(verbs[0].dispatch); 57 [ - + ]: 36 : assert(argc >= 0); 58 [ - + ]: 36 : assert(argv); 59 [ - + ]: 36 : assert(argc >= optind); 60 : : 61 : 36 : left = argc - optind; 62 : 36 : argv += optind; 63 : 36 : optind = 0; 64 : 36 : name = argv[0]; 65 : : 66 : 164 : for (i = 0;; i++) { 67 : : bool found; 68 : : 69 : : /* At the end of the list? */ 70 [ + + ]: 164 : if (!verbs[i].dispatch) { 71 [ + + ]: 8 : if (name) 72 [ + - ]: 4 : log_error("Unknown operation %s.", name); 73 : : else 74 [ + - ]: 4 : log_error("Requires operation parameter."); 75 : 8 : return -EINVAL; 76 : : } 77 : : 78 [ + + ]: 156 : if (name) 79 : 140 : found = streq(name, verbs[i].verb); 80 : : else 81 : 16 : found = verbs[i].flags & VERB_DEFAULT; 82 : : 83 [ + + ]: 156 : if (found) { 84 : 28 : verb = &verbs[i]; 85 : 28 : break; 86 : : } 87 : : } 88 : : 89 [ - + ]: 28 : assert(verb); 90 : : 91 [ + + ]: 28 : if (!name) 92 : 4 : left = 1; 93 : : 94 [ + + ]: 28 : if (verb->min_args != VERB_ANY && 95 [ + + ]: 20 : (unsigned) left < verb->min_args) 96 [ + - ]: 4 : return log_error_errno(SYNTHETIC_ERRNO(EINVAL), 97 : : "Too few arguments."); 98 : : 99 [ + + ]: 24 : if (verb->max_args != VERB_ANY && 100 [ + + ]: 16 : (unsigned) left > verb->max_args) 101 [ + - ]: 4 : return log_error_errno(SYNTHETIC_ERRNO(EINVAL), 102 : : "Too many arguments."); 103 : : 104 [ - + # # ]: 20 : if ((verb->flags & VERB_ONLINE_ONLY) && running_in_chroot_or_offline()) { 105 [ # # ]: 0 : if (name) 106 [ # # ]: 0 : log_info("Running in chroot, ignoring request: %s", name); 107 : : else 108 [ # # ]: 0 : log_info("Running in chroot, ignoring request."); 109 : 0 : return 0; 110 : : } 111 : : 112 [ + + ]: 20 : if (name) 113 : 16 : return verb->dispatch(left, argv, userdata); 114 : : else { 115 : 4 : char* fake[2] = { 116 : 4 : (char*) verb->verb, 117 : : NULL 118 : : }; 119 : : 120 : 4 : return verb->dispatch(1, fake, userdata); 121 : : } 122 : : }