Пример #1
0
static unsigned routes_max(void) {
        static thread_local unsigned cached = 0;

        _cleanup_free_ char *s4 = NULL, *s6 = NULL;
        unsigned val4 = ROUTES_DEFAULT_MAX_PER_FAMILY, val6 = ROUTES_DEFAULT_MAX_PER_FAMILY;

        if (cached > 0)
                return cached;

        if (sysctl_read("net/ipv4/route/max_size", &s4) >= 0) {
                truncate_nl(s4);
                if (safe_atou(s4, &val4) >= 0 &&
                    val4 == 2147483647U)
                        /* This is the default "no limit" value in the kernel */
                        val4 = ROUTES_DEFAULT_MAX_PER_FAMILY;
        }

        if (sysctl_read("net/ipv6/route/max_size", &s6) >= 0) {
                truncate_nl(s6);
                (void) safe_atou(s6, &val6);
        }

        cached = MAX(ROUTES_DEFAULT_MAX_PER_FAMILY, val4) +
                 MAX(ROUTES_DEFAULT_MAX_PER_FAMILY, val6);
        return cached;
}
Пример #2
0
int config_parse_unsigned(
                const char *filename,
                unsigned line,
                const char *section,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {

        unsigned *u = data;
        int r;

        assert(filename);
        assert(lvalue);
        assert(rvalue);
        assert(data);

        r = safe_atou(rvalue, u);
        if (r < 0) {
                log_error("[%s:%u] Failed to parse numeric value: %s", filename, line, rvalue);
                return r;
        }

        return 0;
}
Пример #3
0
static int client_run(int ifindex, const char *seed_str, const struct ether_addr *ha, sd_event *e) {
        sd_ipv4ll *ll;

        assert_se(sd_ipv4ll_new(&ll) >= 0);
        assert_se(sd_ipv4ll_attach_event(ll, e, 0) >= 0);

        assert_se(sd_ipv4ll_set_index(ll, ifindex) >= 0);
        assert_se(sd_ipv4ll_set_mac(ll, ha) >= 0);
        assert_se(sd_ipv4ll_set_callback(ll, ll_handler, NULL) >= 0);

        if (seed_str) {
                unsigned seed;

                assert_se(safe_atou(seed_str, &seed) >= 0);

                assert_se(sd_ipv4ll_set_address_seed(ll, seed) >= 0);
        }

        log_info("starting IPv4LL client");

        assert_se(sd_ipv4ll_start(ll) >= 0);

        assert_se(sd_event_loop(e) >= 0);

        assert_se(!sd_ipv4ll_unref(ll));

        return EXIT_SUCCESS;
}
int socket_address_parse(SocketAddress *a, const char *s) {
        char *e, *n;
        unsigned u;
        int r;

        assert(a);
        assert(s);

        zero(*a);
        a->type = SOCK_STREAM;

        if (*s == '[') {
                /* IPv6 in [x:.....:z]:p notation */

                if (!socket_ipv6_is_supported()) {
                        log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
                        return -EAFNOSUPPORT;
                }

                e = strchr(s+1, ']');
                if (!e)
                        return -EINVAL;

                n = strndupa(s+1, e-s-1);

                errno = 0;
                if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
                        return errno > 0 ? -errno : -EINVAL;

                e++;
                if (*e != ':')
                        return -EINVAL;

                e++;
                r = safe_atou(e, &u);
                if (r < 0)
                        return r;

                if (u <= 0 || u > 0xFFFF)
                        return -EINVAL;

                a->sockaddr.in6.sin6_family = AF_INET6;
                a->sockaddr.in6.sin6_port = htons((uint16_t) u);
                a->size = sizeof(struct sockaddr_in6);

        } else if (*s == '/') {
                /* AF_UNIX socket */

                size_t l;

                l = strlen(s);
                if (l >= sizeof(a->sockaddr.un.sun_path))
                        return -EINVAL;

                a->sockaddr.un.sun_family = AF_UNIX;
                memcpy(a->sockaddr.un.sun_path, s, l);
                a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;

        } else if (*s == '@') {
Пример #5
0
static int prompt_loop(const char *text, char **l, bool (*is_valid)(const char *name), char **ret) {
        int r;

        assert(text);
        assert(is_valid);
        assert(ret);

        for (;;) {
                _cleanup_free_ char *p = NULL;
                unsigned u;

                r = ask_string(&p, "%s %s (empty to skip): ", draw_special_char(DRAW_TRIANGULAR_BULLET), text);
                if (r < 0) {
                        log_error("Failed to query user: %s", strerror(-r));
                        return r;
                }

                if (isempty(p)) {
                        log_warning("No data entered, skipping.");
                        return 0;
                }

                r = safe_atou(p, &u);
                if (r >= 0) {
                        char *c;

                        if (u <= 0 || u > strv_length(l)) {
                                log_error("Specified entry number out of range.");
                                continue;
                        }

                        log_info("Selected '%s'.", l[u-1]);

                        c = strdup(l[u-1]);
                        if (!c)
                                return log_oom();

                        free(*ret);
                        *ret = c;
                        return 0;
                }

                if (!is_valid(p)) {
                        log_error("Entered data invalid.");
                        continue;
                }

                free(*ret);
                *ret = p;
                p = 0;
                return 0;
        }
}
Пример #6
0
static void test_ioprio_class_from_to_string_one(const char *val, int expected) {
        assert_se(ioprio_class_from_string(val) == expected);
        if (expected >= 0) {
                _cleanup_free_ char *s = NULL;
                unsigned ret;

                assert_se(ioprio_class_to_string_alloc(expected, &s) == 0);
                /* We sometimes get a class number and sometimes a number back */
                assert_se(streq(s, val) ||
                          safe_atou(val, &ret) == 0);
        }
}
Пример #7
0
int parse_cpu_set_and_warn(
                const char *rvalue,
                cpu_set_t **cpu_set,
                const char *unit,
                const char *filename,
                unsigned line,
                const char *lvalue) {

        const char *whole_rvalue = rvalue;
        _cleanup_cpu_free_ cpu_set_t *c = NULL;
        unsigned ncpus = 0;

        assert(lvalue);
        assert(rvalue);

        for (;;) {
                _cleanup_free_ char *word = NULL;
                unsigned cpu;
                int r;

                r = extract_first_word(&rvalue, &word, WHITESPACE, EXTRACT_QUOTES);
                if (r < 0) {
                        log_syntax(unit, LOG_ERR, filename, line, r, "Invalid value for %s: %s", lvalue, whole_rvalue);
                        return r;
                }
                if (r == 0)
                        break;

                if (!c) {
                        c = cpu_set_malloc(&ncpus);
                        if (!c)
                                return log_oom();
                }

                r = safe_atou(word, &cpu);
                if (r < 0 || cpu >= ncpus) {
                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU affinity '%s'", rvalue);
                        return -EINVAL;
                }

                CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
        }

        /* On success, sets *cpu_set and returns ncpus for the system. */
        if (c) {
                *cpu_set = c;
                c = NULL;
        }

        return (int) ncpus;
}
Пример #8
0
                                /* Ignore failure. E.g. 10.M is valid */
                                frac = l2;
                                for (; e < e2; e++)
                                        frac /= 10;
                        }
                }

                e += strspn(e, WHITESPACE);

                for (i = start_pos; i < n_entries; i++)
                        if (startswith(e, table[i].suffix))
                                break;

                if (i >= n_entries)
                        return -EINVAL;

                if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
                        return -ERANGE;

                tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
                if (tmp > ULLONG_MAX - r)
                        return -ERANGE;

                r += tmp;
                if ((unsigned long long) (uint64_t) r != r)
                        return -ERANGE;

                p = e + strlen(table[i].suffix);

                start_pos = i + 1;

        } while (*p);

        *size = r;

        return 0;
}

#if 0 /* NM_IGNORED */
int parse_range(const char *t, unsigned *lower, unsigned *upper) {
        _cleanup_free_ char *word = NULL;
        unsigned l, u;
        int r;

        assert(lower);
        assert(upper);

        /* Extract the lower bound. */
        r = extract_first_word(&t, &word, "-", EXTRACT_DONT_COALESCE_SEPARATORS);
        if (r < 0)
                return r;
        if (r == 0)
                return -EINVAL;

        r = safe_atou(word, &l);
        if (r < 0)
                return r;

        /* Check for the upper bound and extract it if needed */
        if (!t)
                /* Single number with no dashes. */
                u = l;
        else if (!*t)
                /* Trailing dash is an error. */
                return -EINVAL;
        else {
                r = safe_atou(t, &u);
                if (r < 0)
                        return r;
        }

        *lower = l;
        *upper = u;
        return 0;
}
Пример #9
0
_public_ int sd_session_get_vt(const char *session, unsigned *vtnr) {
        _cleanup_free_ char *vtnr_string = NULL;
        unsigned u;
        int r;

        r = session_get_string(session, "VTNR", &vtnr_string);
        if (r < 0)
                return r;

        r = safe_atou(vtnr_string, &u);
        if (r < 0)
                return r;

        *vtnr = u;
        return 0;
}
Пример #10
0
int parse_percent_unbounded(const char *p) {
        const char *pc, *n;
        unsigned v;
        int r;

        pc = endswith(p, "%");
        if (!pc)
                return -EINVAL;

        n = strndupa(p, pc - p);
        r = safe_atou(n, &v);
        if (r < 0)
                return r;

        return (int) v;
}
Пример #11
0
static int device_set_devuid(sd_device *device, const char *uid) {
        unsigned u;
        int r;

        assert(device);
        assert(uid);

        r = safe_atou(uid, &u);
        if (r < 0)
                return r;

        r = device_add_property_internal(device, "DEVUID", uid);
        if (r < 0)
                return r;

        device->devuid = u;

        return 0;
}
Пример #12
0
static int device_set_devgid(sd_device *device, const char *gid) {
        unsigned g;
        int r;

        assert(device);
        assert(gid);

        r = safe_atou(gid, &g);
        if (r < 0)
                return r;

        r = device_add_property_internal(device, "DEVGID", gid);
        if (r < 0)
                return r;

        device->devgid = g;

        return 0;
}
Пример #13
0
int signal_from_string(const char *s) {
        int signo;
        int offset = 0;
        unsigned u;

        signo = __signal_from_string(s);
        if (signo > 0)
                return signo;

        if (startswith(s, "RTMIN+")) {
                s += 6;
                offset = SIGRTMIN;
        }
        if (safe_atou(s, &u) >= 0) {
                signo = (int) u + offset;
                if (signo > 0 && signo < _NSIG)
                        return signo;
        }
        return -EINVAL;
}
Пример #14
0
int dns_type_from_string(const char *s) {
        const struct dns_type_name *sc;

        assert(s);

        sc = lookup_dns_type(s, strlen(s));
        if (sc)
                return sc->id;

        s = startswith_no_case(s, "TYPE");
        if (s) {
                unsigned x;

                if (safe_atou(s, &x) >= 0 &&
                    x <= UINT16_MAX)
                        return (int) x;
        }

        return _DNS_TYPE_INVALID;
}
Пример #15
0
/* verify the capability parser */
static void test_cap_list(void) {
        int i;

        assert_se(!capability_to_name(-1));
        assert_se(!capability_to_name(capability_list_length()));

        for (i = 0; i < capability_list_length(); i++) {
                const char *n;

                assert_se(n = capability_to_name(i));
                assert_se(capability_from_name(n) == i);
                printf("%s = %i\n", n, i);
        }

        assert_se(capability_from_name("asdfbsd") == -EINVAL);
        assert_se(capability_from_name("CAP_AUDIT_READ") == CAP_AUDIT_READ);
        assert_se(capability_from_name("cap_audit_read") == CAP_AUDIT_READ);
        assert_se(capability_from_name("cAp_aUdIt_rEAd") == CAP_AUDIT_READ);
        assert_se(capability_from_name("0") == 0);
        assert_se(capability_from_name("15") == 15);
        assert_se(capability_from_name("-1") == -EINVAL);

        for (i = 0; i < capability_list_length(); i++) {
                _cleanup_cap_free_charp_ char *a = NULL;
                const char *b;
                unsigned u;

                assert_se(a = cap_to_name(i));

                /* quit the loop as soon as libcap starts returning
                 * numeric ids, formatted as strings */
                if (safe_atou(a, &u) >= 0)
                        break;

                assert_se(b = capability_to_name(i));

                printf("%s vs. %s\n", a, b);

                assert_se(strcasecmp(a, b) == 0);
        }
}
Пример #16
0
static int add_match(Set *set, const char *match) {
        int r = -ENOMEM;
        unsigned pid;
        const char* prefix;
        char *pattern = NULL;
        _cleanup_free_ char *p = NULL;

        if (strchr(match, '='))
                prefix = "";
        else if (strchr(match, '/')) {
                p = path_make_absolute_cwd(match);
                if (!p)
                        goto fail;

                match = p;
                prefix = "COREDUMP_EXE=";
        }
        else if (safe_atou(match, &pid) == 0)
                prefix = "COREDUMP_PID=";
        else
                prefix = "COREDUMP_COMM=";

        pattern = strjoin(prefix, match, NULL);
        if (!pattern)
                goto fail;

        log_debug("Adding pattern: %s", pattern);
        r = set_put(set, pattern);
        if (r < 0) {
                log_error("Failed to add pattern '%s': %s",
                          pattern, strerror(-r));
                free(pattern);
                goto fail;
        }

        return 0;
fail:
        log_error("Failed to add match: %s", strerror(-r));
        return r;
}
Пример #17
0
static void verify_contents(sd_journal *j, unsigned skip) {
        unsigned i;

        assert(j);

        i = 0;
        SD_JOURNAL_FOREACH(j) {
                const void *d;
                char *k, *c;
                size_t l;
                unsigned u;

                assert_se(sd_journal_get_cursor(j, &k) >= 0);
                printf("cursor: %s\n", k);
                free(k);

                assert_se(sd_journal_get_data(j, "MAGIC", &d, &l) >= 0);
                printf("\t%.*s\n", (int) l, (const char*) d);

                assert_se(sd_journal_get_data(j, "NUMBER", &d, &l) >= 0);
                assert_se(k = strndup(d, l));
                printf("\t%s\n", k);

                if (skip > 0) {
                        assert_se(safe_atou(k + 7, &u) >= 0);
                        assert_se(i == u);
                        i += skip;
                }

                free(k);

                assert_se(sd_journal_get_cursor(j, &c) >= 0);
                assert_se(sd_journal_test_cursor(j, c) > 0);
                free(c);
        }

        if (skip > 0)
                assert_se(i == N_ENTRIES);
}
Пример #18
0
static int parse_argv(int argc, char *argv[]) {

        enum {
                ARG_VERSION = 0x100,
                ARG_DEPTH,
                ARG_CPU_TYPE,
                ARG_ORDER,
                ARG_RECURSIVE,
        };

        static const struct option options[] = {
                { "help",         no_argument,       NULL, 'h'           },
                { "version",      no_argument,       NULL, ARG_VERSION   },
                { "delay",        required_argument, NULL, 'd'           },
                { "iterations",   required_argument, NULL, 'n'           },
                { "batch",        no_argument,       NULL, 'b'           },
                { "raw",          no_argument,       NULL, 'r'           },
                { "depth",        required_argument, NULL, ARG_DEPTH     },
                { "cpu",          optional_argument, NULL, ARG_CPU_TYPE  },
                { "order",        required_argument, NULL, ARG_ORDER     },
                { "recursive",    required_argument, NULL, ARG_RECURSIVE },
                { "machine",      required_argument, NULL, 'M'           },
                {}
        };

        bool recursive_unset = false;
        int c, r;

        assert(argc >= 1);
        assert(argv);

        while ((c = getopt_long(argc, argv, "hptcmin:brd:kPM:", options, NULL)) >= 0)

                switch (c) {

                case 'h':
                        help();
                        return 0;

                case ARG_VERSION:
                        return version();

                case ARG_CPU_TYPE:
                        if (optarg) {
                                if (streq(optarg, "time"))
                                        arg_cpu_type = CPU_TIME;
                                else if (streq(optarg, "percentage"))
                                        arg_cpu_type = CPU_PERCENT;
                                else {
                                        log_error("Unknown argument to --cpu=: %s", optarg);
                                        return -EINVAL;
                                }
                        } else
                                arg_cpu_type = CPU_TIME;

                        break;

                case ARG_DEPTH:
                        r = safe_atou(optarg, &arg_depth);
                        if (r < 0) {
                                log_error("Failed to parse depth parameter.");
                                return -EINVAL;
                        }

                        break;

                case 'd':
                        r = parse_sec(optarg, &arg_delay);
                        if (r < 0 || arg_delay <= 0) {
                                log_error("Failed to parse delay parameter.");
                                return -EINVAL;
                        }

                        break;

                case 'n':
                        r = safe_atou(optarg, &arg_iterations);
                        if (r < 0) {
                                log_error("Failed to parse iterations parameter.");
                                return -EINVAL;
                        }

                        break;

                case 'b':
                        arg_batch = true;
                        break;

                case 'r':
                        arg_raw = true;
                        break;

                case 'p':
                        arg_order = ORDER_PATH;
                        break;

                case 't':
                        arg_order = ORDER_TASKS;
                        break;

                case 'c':
                        arg_order = ORDER_CPU;
                        break;

                case 'm':
                        arg_order = ORDER_MEMORY;
                        break;

                case 'i':
                        arg_order = ORDER_IO;
                        break;

                case ARG_ORDER:
                        if (streq(optarg, "path"))
                                arg_order = ORDER_PATH;
                        else if (streq(optarg, "tasks"))
                                arg_order = ORDER_TASKS;
                        else if (streq(optarg, "cpu"))
                                arg_order = ORDER_CPU;
                        else if (streq(optarg, "memory"))
                                arg_order = ORDER_MEMORY;
                        else if (streq(optarg, "io"))
                                arg_order = ORDER_IO;
                        else {
                                log_error("Invalid argument to --order=: %s", optarg);
                                return -EINVAL;
                        }
                        break;

                case 'k':
                        arg_count = COUNT_ALL_PROCESSES;
                        break;

                case 'P':
                        arg_count = COUNT_USERSPACE_PROCESSES;
                        break;

                case ARG_RECURSIVE:
                        r = parse_boolean(optarg);
                        if (r < 0) {
                                log_error("Failed to parse --recursive= argument: %s", optarg);
                                return r;
                        }

                        arg_recursive = r;
                        recursive_unset = r == 0;
                        break;

                case 'M':
                        arg_machine = optarg;
                        break;

                case '?':
                        return -EINVAL;

                default:
                        assert_not_reached("Unhandled option");
                }

        if (optind == argc-1) {
                if (arg_machine) {
                        log_error("Specifying a control group path together with the -M option is not allowed");
                        return -EINVAL;
                }
                arg_root = argv[optind];
        } else if (optind < argc) {
                log_error("Too many arguments.");
                return -EINVAL;
        }

        if (recursive_unset && arg_count == COUNT_PIDS) {
                log_error("Non-recursive counting is only supported when counting processes, not tasks. Use -P or -k.");
                return -EINVAL;
        }

        return 1;
}
Пример #19
0
static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
        Automount *a = AUTOMOUNT(u);
        int r;

        assert(a);
        assert(fds);

        if (streq(key, "state")) {
                AutomountState state;

                state = automount_state_from_string(value);
                if (state < 0)
                        log_debug_unit(u->id, "Failed to parse state value %s", value);
                else
                        a->deserialized_state = state;
        } else if (streq(key, "result")) {
                AutomountResult f;

                f = automount_result_from_string(value);
                if (f < 0)
                        log_debug_unit(u->id, "Failed to parse result value %s", value);
                else if (f != AUTOMOUNT_SUCCESS)
                        a->result = f;

        } else if (streq(key, "dev-id")) {
                unsigned d;

                if (safe_atou(value, &d) < 0)
                        log_debug_unit(u->id, "Failed to parse dev-id value %s", value);
                else
                        a->dev_id = (unsigned) d;
        } else if (streq(key, "token")) {
                unsigned token;

                if (safe_atou(value, &token) < 0)
                        log_debug_unit(u->id, "Failed to parse token value %s", value);
                else {
                        if (!a->tokens)
                                if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
                                        return -ENOMEM;

                        r = set_put(a->tokens, UINT_TO_PTR(token));
                        if (r < 0)
                                return r;
                }
        } else if (streq(key, "pipe-fd")) {
                int fd;

                if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
                        log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value);
                else {
                        if (a->pipe_fd >= 0)
                                close_nointr_nofail(a->pipe_fd);

                        a->pipe_fd = fdset_remove(fds, fd);
                }
        } else
                log_debug_unit(u->id, "Unknown serialization key '%s'", key);

        return 0;
}
Пример #20
0
static int parse_argv(int argc, char *argv[]) {

        enum {
                ARG_VERSION = 0x100,
                ARG_FILES_MAX,
                ARG_FILE_SIZE_MAX,
                ARG_TIMEOUT
        };

        static const struct option options[] = {
                { "help",          no_argument,       NULL, 'h'                },
                { "version",       no_argument,       NULL, ARG_VERSION        },
                { "files-max",     required_argument, NULL, ARG_FILES_MAX      },
                { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX  },
                { "timeout",       required_argument, NULL, ARG_TIMEOUT        },
                {}
        };

        int c;

        assert(argc >= 0);
        assert(argv);

        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {

                switch (c) {

                case 'h':
                        return help();

                case ARG_VERSION:
                        puts(PACKAGE_STRING);
                        puts(SYSTEMD_FEATURES);
                        return 0;

                case ARG_FILES_MAX:
                        if (safe_atou(optarg, &arg_files_max) < 0 || arg_files_max <= 0) {
                                log_error("Failed to parse maximum number of files %s.", optarg);
                                return -EINVAL;
                        }
                        break;

                case ARG_FILE_SIZE_MAX: {
                        unsigned long long ull;

                        if (safe_atollu(optarg, &ull) < 0 || ull <= 0) {
                                log_error("Failed to parse maximum file size %s.", optarg);
                                return -EINVAL;
                        }

                        arg_file_size_max = (off_t) ull;
                        break;
                }

                case ARG_TIMEOUT:
                        if (parse_sec(optarg, &arg_timeout) < 0 || arg_timeout <= 0) {
                                log_error("Failed to parse timeout %s.", optarg);
                                return -EINVAL;
                        }

                        break;

                case '?':
                        return -EINVAL;

                default:
                        assert_not_reached("Unhandled option");
                }
        }

        if (optind != argc-1 &&
            optind != argc-2) {
                help();
                return -EINVAL;
        }

        return 1;
}
Пример #21
0
static int parse_argv(int argc, char *argv[]) {

        enum {
                ARG_VERSION = 0x100,
                ARG_IGNORE_ENV
        };

        static const struct option options[] = {
                { "connections-max", required_argument, NULL, 'c'           },
                { "help",            no_argument,       NULL, 'h'           },
                { "version",         no_argument,       NULL, ARG_VERSION   },
                {}
        };

        int c, r;

        assert(argc >= 0);
        assert(argv);

        while ((c = getopt_long(argc, argv, "c:h", options, NULL)) >= 0)

                switch (c) {

                case 'h':
                        return help();

                case ARG_VERSION:
                        return version();

                case 'c':
                        r = safe_atou(optarg, &arg_connections_max);
                        if (r < 0) {
                                log_error("Failed to parse --connections-max= argument: %s", optarg);
                                return r;
                        }

                        if (arg_connections_max < 1) {
                                log_error("Connection limit is too low.");
                                return -EINVAL;
                        }

                        break;

                case '?':
                        return -EINVAL;

                default:
                        assert_not_reached("Unhandled option");
                }

        if (optind >= argc) {
                log_error("Not enough parameters.");
                return -EINVAL;
        }

        if (argc != optind+1) {
                log_error("Too many parameters.");
                return -EINVAL;
        }

        arg_remote_host = argv[optind];
        return 1;
}
Пример #22
0
int config_parse_address(const char *unit,
                         const char *filename,
                         unsigned line,
                         const char *section,
                         unsigned section_line,
                         const char *lvalue,
                         int ltype,
                         const char *rvalue,
                         void *data,
                         void *userdata) {
    Network *network = userdata;
    _cleanup_address_free_ Address *n = NULL;
    _cleanup_free_ char *address = NULL;
    const char *e;
    int r;

    assert(filename);
    assert(section);
    assert(lvalue);
    assert(rvalue);
    assert(data);

    if (streq(section, "Network")) {
        /* we are not in an Address section, so treat
         * this as the special '0' section */
        section_line = 0;
    }

    r = address_new_static(network, section_line, &n);
    if (r < 0)
        return r;

    /* Address=address/prefixlen */

    /* prefixlen */
    e = strchr(rvalue, '/');
    if (e) {
        unsigned i;
        r = safe_atou(e + 1, &i);
        if (r < 0) {
            log_syntax(unit, LOG_ERR, filename, line, EINVAL,
                       "Interface prefix length is invalid, "
                       "ignoring assignment: %s", e + 1);
            return 0;
        }

        n->prefixlen = (unsigned char) i;

        address = strndup(rvalue, e - rvalue);
        if (!address)
            return log_oom();
    } else {
        address = strdup(rvalue);
        if (!address)
            return log_oom();
    }

    r = net_parse_inaddr(address, &n->family, &n->in_addr);
    if (r < 0) {
        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
                   "Address is invalid, ignoring assignment: %s", address);
        return 0;
    }

    if (n->family == AF_INET && !n->broadcast.s_addr)
        n->broadcast.s_addr = n->in_addr.in.s_addr |
                              htonl(0xfffffffflu >> n->prefixlen);

    n = NULL;

    return 0;
}
Пример #23
0
static int parse_argv(int argc, char *argv[]) {

        enum {
                ARG_VERSION = 0x100,
                ARG_DEPTH,
                ARG_CPU_TYPE
        };

        static const struct option options[] = {
                { "help",       no_argument,       NULL, 'h'         },
                { "version",    no_argument,       NULL, ARG_VERSION },
                { "delay",      required_argument, NULL, 'd'         },
                { "iterations", required_argument, NULL, 'n'         },
                { "batch",      no_argument,       NULL, 'b'         },
                { "depth",      required_argument, NULL, ARG_DEPTH   },
                { "cpu",        optional_argument, NULL, ARG_CPU_TYPE},
                {}
        };

        int c;
        int r;

        assert(argc >= 1);
        assert(argv);

        while ((c = getopt_long(argc, argv, "hptcmin:bd:", options, NULL)) >= 0)

                switch (c) {

                case 'h':
                        help();
                        return 0;

                case ARG_VERSION:
                        puts(PACKAGE_STRING);
                        puts(SYSTEMD_FEATURES);
                        return 0;

                case ARG_CPU_TYPE:
                        if (optarg) {
                                if (strcmp(optarg, "time") == 0)
                                        arg_cpu_type = CPU_TIME;
                                else if (strcmp(optarg, "percentage") == 0)
                                        arg_cpu_type = CPU_PERCENT;
                                else
                                        return -EINVAL;
                        }
                        break;

                case ARG_DEPTH:
                        r = safe_atou(optarg, &arg_depth);
                        if (r < 0) {
                                log_error("Failed to parse depth parameter.");
                                return -EINVAL;
                        }

                        break;

                case 'd':
                        r = parse_sec(optarg, &arg_delay);
                        if (r < 0 || arg_delay <= 0) {
                                log_error("Failed to parse delay parameter.");
                                return -EINVAL;
                        }

                        break;

                case 'n':
                        r = safe_atou(optarg, &arg_iterations);
                        if (r < 0) {
                                log_error("Failed to parse iterations parameter.");
                                return -EINVAL;
                        }

                        break;

                case 'b':
                        arg_batch = true;
                        break;

                case 'p':
                        arg_order = ORDER_PATH;
                        break;

                case 't':
                        arg_order = ORDER_TASKS;
                        break;

                case 'c':
                        arg_order = ORDER_CPU;
                        break;

                case 'm':
                        arg_order = ORDER_MEMORY;
                        break;

                case 'i':
                        arg_order = ORDER_IO;
                        break;

                case '?':
                        return -EINVAL;

                default:
                        assert_not_reached("Unhandled option");
                }

        if (optind < argc) {
                log_error("Too many arguments.");
                return -EINVAL;
        }

        return 1;
}
Пример #24
0
int config_parse_destination(const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {
        Network *network = userdata;
        _cleanup_route_free_ Route *n = NULL;
        _cleanup_free_ char *address = NULL;
        const char *e;
        int r;

        assert(filename);
        assert(section);
        assert(lvalue);
        assert(rvalue);
        assert(data);

        r = route_new_static(network, section_line, &n);
        if (r < 0)
                return r;

        /* Destination=address/prefixlen */

        /* address */
        e = strchr(rvalue, '/');
        if (e) {
                address = strndup(rvalue, e - rvalue);
                if (!address)
                        return log_oom();
        } else {
                address = strdup(rvalue);
                if (!address)
                        return log_oom();
        }

        r = net_parse_inaddr(address, &n->family, &n->dst_addr);
        if (r < 0) {
                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
                           "Destination is invalid, ignoring assignment: %s", address);
                return 0;
        }

        /* prefixlen */
        if (e) {
                unsigned i;

                r = safe_atou(e + 1, &i);
                if (r < 0) {
                        log_syntax(unit, LOG_ERR, filename, line, EINVAL,
                                   "Route destination prefix length is invalid, "
                                   "ignoring assignment: %s", e + 1);
                        return 0;
                }

                n->dst_prefixlen = (unsigned char) i;
        } else {
                switch (n->family) {
                        case AF_INET:
                                n->dst_prefixlen = 32;
                                break;
                        case AF_INET6:
                                n->dst_prefixlen = 128;
                                break;
                }
        }

        n = NULL;

        return 0;
}
Пример #25
0
static const char* fallback_chassis(void) {
        char *type;
        unsigned t;
        int v, r;

        v = detect_virtualization();
        if (VIRTUALIZATION_IS_VM(v))
                return "vm";
        if (VIRTUALIZATION_IS_CONTAINER(v))
                return "container";

        r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type);
        if (r < 0)
                goto try_acpi;

        r = safe_atou(type, &t);
        free(type);
        if (r < 0)
                goto try_acpi;

        /* We only list the really obvious cases here. The DMI data is unreliable enough, so let's not do any
           additional guesswork on top of that.

           See the SMBIOS Specification 3.0 section 7.4.1 for details about the values listed here:

           https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf
         */

        switch (t) {

        case 0x3: /* Desktop */
        case 0x4: /* Low Profile Desktop */
        case 0x6: /* Mini Tower */
        case 0x7: /* Tower */
                return "desktop";

        case 0x8: /* Portable */
        case 0x9: /* Laptop */
        case 0xA: /* Notebook */
        case 0xE: /* Sub Notebook */
                return "laptop";

        case 0xB: /* Hand Held */
                return "handset";

        case 0x11: /* Main Server Chassis */
        case 0x1C: /* Blade */
        case 0x1D: /* Blade Enclosure */
                return "server";

        case 0x1E: /* Tablet */
                return "tablet";

        case 0x1F: /* Convertible */
        case 0x20: /* Detachable */
                return "convertible";
        }

try_acpi:
        r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type);
        if (r < 0)
                return NULL;

        r = safe_atou(type, &t);
        free(type);
        if (r < 0)
                return NULL;

        /* We only list the really obvious cases here as the ACPI data is not really super reliable.
         *
         * See the ACPI 5.0 Spec Section 5.2.9.1 for details:
         *
         * http://www.acpi.info/DOWNLOADS/ACPIspec50.pdf
         */

        switch(t) {

        case 1: /* Desktop */
        case 3: /* Workstation */
        case 6: /* Appliance PC */
                return "desktop";

        case 2: /* Mobile */
                return "laptop";

        case 4: /* Enterprise Server */
        case 5: /* SOHO Server */
        case 7: /* Performance Server */
                return "server";

        case 8: /* Tablet */
                return "tablet";
        }

        return NULL;
}
Пример #26
0
static const char* fallback_chassis(void) {
    int r;
    char *type;
    unsigned t;
    int v;

    v = detect_virtualization();

    if (VIRTUALIZATION_IS_VM(v))
        return "vm";
    if (VIRTUALIZATION_IS_CONTAINER(v))
        return "container";

    r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type);
    if (r < 0)
        goto try_dmi;

    r = safe_atou(type, &t);
    free(type);
    if (r < 0)
        goto try_dmi;

    /* We only list the really obvious cases here as the ACPI data
     * is not really super reliable.
     *
     * See the ACPI 5.0 Spec Section 5.2.9.1 for details:
     *
     * http://www.acpi.info/DOWNLOADS/ACPIspec50.pdf
     */

    switch(t) {

    case 1:
    case 3:
    case 6:
        return "desktop";

    case 2:
        return "laptop";

    case 4:
    case 5:
    case 7:
        return "server";

    case 8:
        return "tablet";
    }

try_dmi:
    r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type);
    if (r < 0)
        return NULL;

    r = safe_atou(type, &t);
    free(type);
    if (r < 0)
        return NULL;

    /* We only list the really obvious cases here. The DMI data is
       unreliable enough, so let's not do any additional guesswork
       on top of that.

       See the SMBIOS Specification 3.0 section 7.4.1 for
       details about the values listed here:

       https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf
     */

    switch (t) {

    case 0x3:
    case 0x4:
    case 0x6:
    case 0x7:
        return "desktop";

    case 0x8:
    case 0x9:
    case 0xA:
    case 0xE:
        return "laptop";

    case 0xB:
        return "handset";

    case 0x11:
    case 0x1C:
    case 0x1D:
        return "server";

    case 0x1E:
        return "tablet";
    }

    return NULL;
}
Пример #27
0
int udev_parse_config_full(
                unsigned *ret_children_max,
                usec_t *ret_exec_delay_usec,
                usec_t *ret_event_timeout_usec,
                ResolveNameTiming *ret_resolve_name_timing) {

        _cleanup_free_ char *log_val = NULL, *children_max = NULL, *exec_delay = NULL, *event_timeout = NULL, *resolve_names = NULL;
        int r;

        r = parse_env_file(NULL, "/etc/udev/udev.conf",
                           "udev_log", &log_val,
                           "children_max", &children_max,
                           "exec_delay", &exec_delay,
                           "event_timeout", &event_timeout,
                           "resolve_names", &resolve_names);
        if (r == -ENOENT)
                return 0;
        if (r < 0)
                return r;

        if (log_val) {
                const char *log;
                size_t n;

                /* unquote */
                n = strlen(log_val);
                if (n >= 2 &&
                    ((log_val[0] == '"' && log_val[n-1] == '"') ||
                     (log_val[0] == '\'' && log_val[n-1] == '\''))) {
                        log_val[n - 1] = '\0';
                        log = log_val + 1;
                } else
                        log = log_val;

                /* we set the udev log level here explicitly, this is supposed
                 * to regulate the code in libudev/ and udev/. */
                r = log_set_max_level_from_string_realm(LOG_REALM_UDEV, log);
                if (r < 0)
                        log_debug_errno(r, "/etc/udev/udev.conf: failed to set udev log level '%s', ignoring: %m", log);
        }

        if (ret_children_max && children_max) {
                r = safe_atou(children_max, ret_children_max);
                if (r < 0)
                        log_notice_errno(r, "/etc/udev/udev.conf: failed to set parse children_max=%s, ignoring: %m", children_max);
        }

        if (ret_exec_delay_usec && exec_delay) {
                r = parse_sec(exec_delay, ret_exec_delay_usec);
                if (r < 0)
                        log_notice_errno(r, "/etc/udev/udev.conf: failed to set parse exec_delay=%s, ignoring: %m", exec_delay);
        }

        if (ret_event_timeout_usec && event_timeout) {
                r = parse_sec(event_timeout, ret_event_timeout_usec);
                if (r < 0)
                        log_notice_errno(r, "/etc/udev/udev.conf: failed to set parse event_timeout=%s, ignoring: %m", event_timeout);
        }

        if (ret_resolve_name_timing && resolve_names) {
                ResolveNameTiming t;

                t = resolve_name_timing_from_string(resolve_names);
                if (t < 0)
                        log_notice("/etc/udev/udev.conf: failed to set parse resolve_names=%s, ignoring.", resolve_names);
                else
                        *ret_resolve_name_timing = t;
        }

        return 0;
}
Пример #28
0
int vt_disallocate(const char *name) {
        int fd, r;
        unsigned u;

        /* Deallocate the VT if possible. If not possible
         * (i.e. because it is the active one), at least clear it
         * entirely (including the scrollback buffer) */

        if (!startswith(name, "/dev/"))
                return -EINVAL;

        if (!tty_is_vc(name)) {
                /* So this is not a VT. I guess we cannot deallocate
                 * it then. But let's at least clear the screen */

                fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
                if (fd < 0)
                        return fd;

                loop_write(fd,
                           "\033[r"    /* clear scrolling region */
                           "\033[H"    /* move home */
                           "\033[2J",  /* clear screen */
                           10, false);
                safe_close(fd);

                return 0;
        }

        if (!startswith(name, "/dev/tty"))
                return -EINVAL;

        r = safe_atou(name+8, &u);
        if (r < 0)
                return r;

        if (u <= 0)
                return -EINVAL;

        /* Try to deallocate */
        fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
        if (fd < 0)
                return fd;

        r = ioctl(fd, VT_DISALLOCATE, u);
        safe_close(fd);

        if (r >= 0)
                return 0;

        if (errno != EBUSY)
                return -errno;

        /* Couldn't deallocate, so let's clear it fully with
         * scrollback */
        fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
        if (fd < 0)
                return fd;

        loop_write(fd,
                   "\033[r"   /* clear scrolling region */
                   "\033[H"   /* move home */
                   "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
                   10, false);
        safe_close(fd);

        return 0;
}
Пример #29
0
static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
        Automount *a = AUTOMOUNT(u);
        int r;

        assert(a);
        assert(fds);

        if (streq(key, "state")) {
                AutomountState state;

                state = automount_state_from_string(value);
                if (state < 0)
                        log_unit_debug(u, "Failed to parse state value: %s", value);
                else
                        a->deserialized_state = state;
        } else if (streq(key, "result")) {
                AutomountResult f;

                f = automount_result_from_string(value);
                if (f < 0)
                        log_unit_debug(u, "Failed to parse result value: %s", value);
                else if (f != AUTOMOUNT_SUCCESS)
                        a->result = f;

        } else if (streq(key, "dev-id")) {
                unsigned d;

                if (safe_atou(value, &d) < 0)
                        log_unit_debug(u, "Failed to parse dev-id value: %s", value);
                else
                        a->dev_id = (unsigned) d;
        } else if (streq(key, "token")) {
                unsigned token;

                if (safe_atou(value, &token) < 0)
                        log_unit_debug(u, "Failed to parse token value: %s", value);
                else {
                        r = set_ensure_allocated(&a->tokens, NULL);
                        if (r < 0) {
                                log_oom();
                                return 0;
                        }

                        r = set_put(a->tokens, UINT_TO_PTR(token));
                        if (r < 0)
                                log_unit_error_errno(u, r, "Failed to add token to set: %m");
                }
        } else if (streq(key, "expire-token")) {
                unsigned token;

                if (safe_atou(value, &token) < 0)
                        log_unit_debug(u, "Failed to parse token value: %s", value);
                else {
                        r = set_ensure_allocated(&a->expire_tokens, NULL);
                        if (r < 0) {
                                log_oom();
                                return 0;
                        }

                        r = set_put(a->expire_tokens, UINT_TO_PTR(token));
                        if (r < 0)
                                log_unit_error_errno(u, r, "Failed to add expire token to set: %m");
                }
        } else if (streq(key, "pipe-fd")) {
                int fd;

                if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
                        log_unit_debug(u, "Failed to parse pipe-fd value: %s", value);
                else {
                        safe_close(a->pipe_fd);
                        a->pipe_fd = fdset_remove(fds, fd);
                }
        } else
                log_unit_debug(u, "Unknown serialization key: %s", key);

        return 0;
}