Esempio n. 1
0
static int
gnuv3_is_vtable_name (const char *name)
{
  return startswith (name, "_ZTV");
}
Esempio n. 2
0
bool PhiAnalysis::isRequired(const std::string &name, CFGBlock* block) {
    assert(!startswith(name, "!"));
    return required_phis[block].count(name) != 0;
}
Esempio n. 3
0
int parse_time(const char *t, usec_t *usec, usec_t default_unit) {
        const char *p, *s;
        usec_t r = 0;
        bool something = false;

        assert(t);
        assert(usec);
        assert(default_unit > 0);

        p = t;

        p += strspn(p, WHITESPACE);
        s = startswith(p, "infinity");
        if (s) {
                s += strspn(s, WHITESPACE);
                if (*s != 0)
                        return -EINVAL;

                *usec = USEC_INFINITY;
                return 0;
        }

        for (;;) {
                long long l, z = 0;
                char *e;
                unsigned n = 0;
                usec_t multiplier = default_unit, k;

                p += strspn(p, WHITESPACE);

                if (*p == 0) {
                        if (!something)
                                return -EINVAL;

                        break;
                }

                errno = 0;
                l = strtoll(p, &e, 10);
                if (errno > 0)
                        return -errno;
                if (l < 0)
                        return -ERANGE;

                if (*e == '.') {
                        char *b = e + 1;

                        errno = 0;
                        z = strtoll(b, &e, 10);
                        if (errno > 0)
                                return -errno;

                        if (z < 0)
                                return -ERANGE;

                        if (e == b)
                                return -EINVAL;

                        n = e - b;

                } else if (e == p)
                        return -EINVAL;

                e += strspn(e, WHITESPACE);
                p = extract_multiplier(e, &multiplier);

                something = true;

                k = (usec_t) z * multiplier;

                for (; n > 0; n--)
                        k /= 10;

                r += (usec_t) l * multiplier + k;
        }

        *usec = r;

        return 0;
}
Esempio n. 4
0
static gdb::unique_xmalloc_ptr<char>
explicit_location_lex_one (const char **inp,
			   const struct language_defn *language,
			   explicit_completion_info *completion_info)
{
  const char *start = *inp;

  if (*start == '\0')
    return NULL;

  /* If quoted, skip to the ending quote.  */
  if (strchr (get_gdb_linespec_parser_quote_characters (), *start))
    {
      if (completion_info != NULL)
	completion_info->quoted_arg_start = start;

      const char *end = find_end_quote (start + 1, *start);

      if (end == NULL)
	{
	  if (completion_info == NULL)
	    error (_("Unmatched quote, %s."), start);

	  end = start + strlen (start);
	  *inp = end;
	  return gdb::unique_xmalloc_ptr<char> (savestring (start + 1,
							    *inp - start - 1));
	}

      if (completion_info != NULL)
	completion_info->quoted_arg_end = end;
      *inp = end + 1;
      return gdb::unique_xmalloc_ptr<char> (savestring (start + 1,
							*inp - start - 2));
    }

  /* If the input starts with '-' or '+', the string ends with the next
     whitespace or comma.  */
  if (*start == '-' || *start == '+')
    {
      while (*inp[0] != '\0' && *inp[0] != ',' && !isspace (*inp[0]))
	++(*inp);
    }
  else
    {
      /* Handle numbers first, stopping at the next whitespace or ','.  */
      while (isdigit (*inp[0]))
	++(*inp);
      if (*inp[0] == '\0' || isspace (*inp[0]) || *inp[0] == ',')
	return gdb::unique_xmalloc_ptr<char> (savestring (start,
							  *inp - start));

      /* Otherwise stop at the next occurrence of whitespace, '\0',
	 keyword, or ','.  */
      *inp = start;
      while ((*inp)[0]
	     && (*inp)[0] != ','
	     && !(isspace ((*inp)[0])
		  || linespec_lexer_lex_keyword (&(*inp)[1])))
	{
	  /* Special case: C++ operator,.  */
	  if (language->la_language == language_cplus
	      && startswith (*inp, CP_OPERATOR_STR))
	    (*inp) += CP_OPERATOR_LEN;
	  ++(*inp);
	}
    }

  if (*inp - start > 0)
    return gdb::unique_xmalloc_ptr<char> (savestring (start, *inp - start));

  return NULL;
}
Esempio n. 5
0
int parse_size(const char *t, uint64_t base, uint64_t *size) {

    /* Soo, sometimes we want to parse IEC binary suffixes, and
     * sometimes SI decimal suffixes. This function can parse
     * both. Which one is the right way depends on the
     * context. Wikipedia suggests that SI is customary for
     * hardware metrics and network speeds, while IEC is
     * customary for most data sizes used by software and volatile
     * (RAM) memory. Hence be careful which one you pick!
     *
     * In either case we use just K, M, G as suffix, and not Ki,
     * Mi, Gi or so (as IEC would suggest). That's because that's
     * frickin' ugly. But this means you really need to make sure
     * to document which base you are parsing when you use this
     * call. */

    struct table {
        const char *suffix;
        unsigned long long factor;
    };

    static const struct table iec[] = {
        { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
        { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
        { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
        { "G", 1024ULL*1024ULL*1024ULL },
        { "M", 1024ULL*1024ULL },
        { "K", 1024ULL },
        { "B", 1ULL },
        { "",  1ULL },
    };

    static const struct table si[] = {
        { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
        { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
        { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
        { "G", 1000ULL*1000ULL*1000ULL },
        { "M", 1000ULL*1000ULL },
        { "K", 1000ULL },
        { "B", 1ULL },
        { "",  1ULL },
    };

    const struct table *table;
    const char *p;
    unsigned long long r = 0;
    unsigned n_entries, start_pos = 0;

    assert(t);
    assert(base == 1000 || base == 1024);
    assert(size);

    if (base == 1000) {
        table = si;
        n_entries = ELEMENTSOF(si);
    } else {
        table = iec;
        n_entries = ELEMENTSOF(iec);
    }

    p = t;
    do {
        unsigned long long l, tmp;
        double frac = 0;
        char *e;
        unsigned i;

        p += strspn(p, WHITESPACE);
        if (*p == '-')
            return -ERANGE;

        errno = 0;
        l = strtoull(p, &e, 10);
        if (errno > 0)
            return -errno;
        if (e == p)
            return -EINVAL;

        if (*e == '.') {
            e++;

            /* strtoull() itself would accept space/+/- */
            if (*e >= '0' && *e <= '9') {
                unsigned long long l2;
                char *e2;

                l2 = strtoull(e, &e2, 10);
                if (errno > 0)
                    return -errno;

                /* 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;
}
Esempio n. 6
0
/*
 * get_file_options:
 *
 * If vendor == NULL, find a line in the config file with only "OPTIONS=";
 * if vendor and model are set find the first OPTIONS line in the config
 * file that matches. Set argc and argv to match the OPTIONS string.
 *
 * vendor and model can end in '\n'.
 */
static int get_file_options(struct udev *udev,
                            const char *vendor, const char *model,
                            int *argc, char ***newargv)
{
        char *buffer;
        _cleanup_fclose_ FILE *f;
        char *buf;
        char *str1;
        char *vendor_in, *model_in, *options_in; /* read in from file */
        int lineno;
        int c;
        int retval = 0;

        f = fopen(config_file, "re");
        if (f == NULL) {
                if (errno == ENOENT)
                        return 1;
                else {
                        log_error_errno(errno, "can't open %s: %m", config_file);
                        return -1;
                }
        }

        /*
         * Allocate a buffer rather than put it on the stack so we can
         * keep it around to parse any options (any allocated newargv
         * points into this buffer for its strings).
         */
        buffer = malloc(MAX_BUFFER_LEN);
        if (!buffer)
                return log_oom();

        *newargv = NULL;
        lineno = 0;
        for (;;) {
                vendor_in = model_in = options_in = NULL;

                buf = fgets(buffer, MAX_BUFFER_LEN, f);
                if (buf == NULL)
                        break;
                lineno++;
                if (buf[strlen(buffer) - 1] != '\n') {
                        log_error("Config file line %d too long", lineno);
                        break;
                }

                while (isspace(*buf))
                        buf++;

                /* blank or all whitespace line */
                if (*buf == '\0')
                        continue;

                /* comment line */
                if (*buf == '#')
                        continue;

                str1 = strsep(&buf, "=");
                if (str1 && strcaseeq(str1, "VENDOR")) {
                        str1 = get_value(&buf);
                        if (!str1) {
                                retval = log_oom();
                                break;
                        }
                        vendor_in = str1;

                        str1 = strsep(&buf, "=");
                        if (str1 && strcaseeq(str1, "MODEL")) {
                                str1 = get_value(&buf);
                                if (!str1) {
                                        retval = log_oom();
                                        break;
                                }
                                model_in = str1;
                                str1 = strsep(&buf, "=");
                        }
                }

                if (str1 && strcaseeq(str1, "OPTIONS")) {
                        str1 = get_value(&buf);
                        if (!str1) {
                                retval = log_oom();
                                break;
                        }
                        options_in = str1;
                }

                /*
                 * Only allow: [vendor=foo[,model=bar]]options=stuff
                 */
                if (!options_in || (!vendor_in && model_in)) {
                        log_error("Error parsing config file line %d '%s'", lineno, buffer);
                        retval = -1;
                        break;
                }
                if (vendor == NULL) {
                        if (vendor_in == NULL)
                                break;
                } else if (vendor_in &&
                           startswith(vendor, vendor_in) &&
                           (!model_in || startswith(model, model_in))) {
                                /*
                                 * Matched vendor and optionally model.
                                 *
                                 * Note: a short vendor_in or model_in can
                                 * give a partial match (that is FOO
                                 * matches FOOBAR).
                                 */
                                break;
                }
        }

        if (retval == 0) {
                if (vendor_in != NULL || model_in != NULL ||
                    options_in != NULL) {
                        /*
                         * Something matched. Allocate newargv, and store
                         * values found in options_in.
                         */
                        strcpy(buffer, options_in);
                        c = argc_count(buffer) + 2;
                        *newargv = calloc(c, sizeof(**newargv));
                        if (!*newargv)
                                retval = log_oom();
                        else {
                                *argc = c;
                                c = 0;
                                /*
                                 * argv[0] at 0 is skipped by getopt, but
                                 * store the buffer address there for
                                 * later freeing
                                 */
                                (*newargv)[c] = buffer;
                                for (c = 1; c < *argc; c++)
                                        (*newargv)[c] = strsep(&buffer, " \t");
                        }
                } else {
                        /* No matches  */
                        retval = 1;
                }
        }
        if (retval != 0)
                free(buffer);
        return retval;
}
Esempio n. 7
0
enum nss_status _nss_myhostname_gethostbyname4_r(
                const char *name,
                struct gaih_addrtuple **pat,
                char *buffer, size_t buflen,
                int *errnop, int *h_errnop,
                int32_t *ttlp) {

        struct gaih_addrtuple *r_tuple, *r_tuple_prev = NULL;
        _cleanup_free_ struct local_address *addresses = NULL;
        _cleanup_free_ char *hn = NULL;
        const char *canonical = NULL;
        int n_addresses = 0;
        uint32_t local_address_ipv4;
        struct local_address *a;
        size_t l, idx, ms;
        char *r_name;
        unsigned n;

        PROTECT_ERRNO;
        BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);

        assert(name);
        assert(pat);
        assert(buffer);
        assert(errnop);
        assert(h_errnop);

        if (is_localhost(name)) {
                /* We respond to 'localhost', so that /etc/hosts
                 * is optional */

                canonical = "localhost";
                local_address_ipv4 = htobe32(INADDR_LOOPBACK);

        } else if (is_gateway_hostname(name)) {

                n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
                if (n_addresses <= 0) {
                        *h_errnop = HOST_NOT_FOUND;
                        return NSS_STATUS_NOTFOUND;
                }

                canonical = "_gateway";

        } else {
                hn = gethostname_malloc();
                if (!hn) {
                        *errnop = ENOMEM;
                        *h_errnop = NO_RECOVERY;
                        return NSS_STATUS_TRYAGAIN;
                }

                /* We respond to our local host name, our hostname suffixed with a single dot. */
                if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
                        *h_errnop = HOST_NOT_FOUND;
                        return NSS_STATUS_NOTFOUND;
                }

                n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
                if (n_addresses < 0)
                        n_addresses = 0;

                canonical = hn;
                local_address_ipv4 = LOCALADDRESS_IPV4;
        }

        l = strlen(canonical);
        ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2);
        if (buflen < ms) {
                *errnop = ERANGE;
                *h_errnop = NETDB_INTERNAL;
                return NSS_STATUS_TRYAGAIN;
        }

        /* First, fill in hostname */
        r_name = buffer;
        memcpy(r_name, canonical, l+1);
        idx = ALIGN(l+1);

        assert(n_addresses >= 0);
        if (n_addresses == 0) {
                /* Second, fill in IPv6 tuple */
                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                r_tuple->next = r_tuple_prev;
                r_tuple->name = r_name;
                r_tuple->family = AF_INET6;
                memcpy(r_tuple->addr, LOCALADDRESS_IPV6, 16);
                r_tuple->scopeid = 0;

                idx += ALIGN(sizeof(struct gaih_addrtuple));
                r_tuple_prev = r_tuple;

                /* Third, fill in IPv4 tuple */
                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                r_tuple->next = r_tuple_prev;
                r_tuple->name = r_name;
                r_tuple->family = AF_INET;
                *(uint32_t*) r_tuple->addr = local_address_ipv4;
                r_tuple->scopeid = 0;

                idx += ALIGN(sizeof(struct gaih_addrtuple));
                r_tuple_prev = r_tuple;
        }

        /* Fourth, fill actual addresses in, but in backwards order */
        for (a = addresses + n_addresses - 1, n = 0; (int) n < n_addresses; n++, a--) {
                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                r_tuple->next = r_tuple_prev;
                r_tuple->name = r_name;
                r_tuple->family = a->family;
                r_tuple->scopeid = a->family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&a->address.in6) ? a->ifindex : 0;
                memcpy(r_tuple->addr, &a->address, 16);

                idx += ALIGN(sizeof(struct gaih_addrtuple));
                r_tuple_prev = r_tuple;
        }

        /* Verify the size matches */
        assert(idx == ms);

        /* Nscd expects us to store the first record in **pat. */
        if (*pat)
                **pat = *r_tuple_prev;
        else
                *pat = r_tuple_prev;

        if (ttlp)
                *ttlp = 0;

        /* Explicitly reset both *h_errnop and h_errno to work around
         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
        *h_errnop = NETDB_SUCCESS;
        h_errno = 0;

        return NSS_STATUS_SUCCESS;
}
Esempio n. 8
0
/** Built-in preprocessing callback
 *
 * Built-in preprocessing callback to break or not to break URLs according to
 * some rules by Chicago Manual of Style 15th ed.
 * If data is NULL, prohibit break.
 * Otherwise, allow break by rule above.
 */
gcstring_t *linebreak_prep_URIBREAK(linebreak_t * lbobj, void *data,
				    unistr_t * str, unistr_t * text)
{
    gcstring_t *gcstr;
    size_t i;
    unichar_t *ptr;

    /* Pass I */

    if (text != NULL) {
	/*
	 * Search URL in str.
	 * Following code loosely refers RFC3986 but some practical
	 * assumptions are put:
	 *
	 * o Broken pct-encoded sequences (e.g. single "%") are allowed.
	 * o scheme names must end with alphanumeric, must be longer than
	 *   or equal to two octets, and must not contain more than one
	 *   non-alphanumeric ("+", "-" or ".").
	 * o URLs containing neither non-empty path, query part nor fragment
	 *   (e.g. "about:") are omitted: they are treated as ordinal words.
	 */
	for (ptr = NULL, i = 0; i < str->len; ptr = NULL, i++) {
	    int has_double_slash, has_authority, has_empty_path,
		has_no_query, has_no_fragment;
	    size_t alphadigit, nonalphadigit;

	    /* skip non-alpha. */
	    if (!is_alpha(str, i))
		continue;

	    ptr = str->str + i;

	    /* "url:" - case insensitive */
	    if (startswith(str, i, "url:", 4, 0))
		i += 4;

	    /* scheme */
	    if (is_alpha(str, i))
		i++;
	    else
		continue;

	    nonalphadigit = 0;
	    alphadigit = 1;
	    while (1) {
		if (is_alpha(str, i) || is_digit(str, i))
		    alphadigit++;
		else if (is(str, i, '+') || is(str, i, '-') || is(str, i, '.'))
		    nonalphadigit++;
		else
		    break;
		i++;
	    }
	    if (alphadigit < 2 || 1 < nonalphadigit ||
	        ! (is_digit(str, i - 1) || is_alpha(str, i - 1)))
		continue;

	    /* ":" */
	    if (is(str, i, ':'))
		i++;
	    else
		continue;

	    /* hier-part */
	    has_double_slash = 0;
	    has_authority = 0;
	    has_empty_path = 0;
	    has_no_query = 0;
	    has_no_fragment = 0;
	    if (startswith(str, i, "//", 2, 0)) {
		/* "//" */
		has_double_slash = 1;
		i += 2;

		/* authority - FIXME:syntax relaxed */
		if (is(str, i, '[') || is(str, i, ':') || is(str, i, '@') ||
		    is_unreserved(str, i) || is_pct_encoded(str, i) ||
		    is_sub_delim(str, i)) {
		    has_authority = 1;
		    i++;
		    while (is(str, i, '[') || is(str, i, ']') ||
			   is(str, i, ':') || is(str, i, '@') ||
			   is_unreserved(str, i) || is_pct_encoded(str, i) ||
			   is_sub_delim(str, i))
			i++;
		}
	    }

	    /* path */
	    if (has_double_slash) {
		if (has_authority)
		    goto path_abempty;
		else
		    goto path_absolute;
	    } /* else goto path_rootless; */

	    /* path_rootless: */
	    if (is_pchar(str, i)) { /* FIXME:path-noscheme not concerned */
		i++;
		while (is_pchar(str, i))
		    i++;
		goto path_abempty;
	    } else {
		has_empty_path = 1;
		goto path_empty;
	    }

	  path_absolute:
	    if (startswith(str, i, "//", 2, 0))
		continue;
	    else if (is(str, i, '/')) {
		i++;
		if (is_pchar(str, i)) {
		    i++;
		    while (is_pchar(str, i))
			i++;
		}
		goto path_abempty;
	    } else
		continue;

	  path_abempty:
	    if (is(str, i, '/')) {
		i++;
		while (is(str, i, '/') || is_pchar(str, i))
		    i++;
	    } /* else goto path_empty; */

	  path_empty:
	    ;

	    /* query */
	    if (is(str, i, '?')) {
		i++;
		while (is(str, i, '/') || is(str, i, '?') || is_pchar(str, i))
		    i++;
	    } else
		has_no_query = 1;

	    /* fragment */
	    if (is(str, i, '#')) {
		i++;
		while (is(str, i, '/') || is(str, i, '?') || is_pchar(str, i))
		    i++;
	    } else
		has_no_fragment = 1;

	    if (has_empty_path && has_no_query && has_no_fragment)
		continue;

	    break;
	}

	if (ptr != NULL)
	    str->len = i - (ptr - str->str);
	str->str = ptr;
	return NULL;
    }

    /* Pass II */

    if ((gcstr = gcstring_newcopy(str, lbobj)) == NULL) {
	lbobj->errnum = errno ? errno : ENOMEM;
	return NULL;
    }

    /* non-break URI. */
    if (data == NULL) {
	for (i = 1; i < gcstr->gclen; i++)
	    gcstr->gcstr[i].flag = LINEBREAK_FLAG_PROHIBIT_BEFORE;
	return gcstr;
    }

    /* break URI. */
    if (startswith((unistr_t *) gcstr, 0, "url:", 4, 0)) {
	gcstr->gcstr[4].flag = LINEBREAK_FLAG_ALLOW_BEFORE;
	i = 5;
    } else
	i = 1;
    for (; i < gcstr->gclen; i++) {
	unichar_t u, v;
	u = gcstr->str[gcstr->gcstr[i - 1].idx];
	v = gcstr->str[gcstr->gcstr[i].idx];

	/*
	 * Some rules based on CMoS 15th ed.
	 * 17.11 1.1: [/] ÷ [^/]
	 * 17.11 2:   [-] ×
	 * 6.17 2:   [.] ×
	 * 17.11 1.2: ÷ [-~.,_?#%]
	 * 17.11 1.3: ÷ [=&]
	 * 17.11 1.3: [=&] ÷
	 * Default:  ALL × ALL
	 */
	if (u == '/' && v != '/')
	    gcstr->gcstr[i].flag = LINEBREAK_FLAG_ALLOW_BEFORE;
	else if (u == '-' || u == '.')
	    gcstr->gcstr[i].flag = LINEBREAK_FLAG_PROHIBIT_BEFORE;
	else if (v == '-' || v == '~' || v == '.' || v == ',' ||
		 v == '_' || v == '?' || v == '#' || v == '%' ||
		 u == '=' || v == '=' || u == '&' || v == '&')
	    gcstr->gcstr[i].flag = LINEBREAK_FLAG_ALLOW_BEFORE;
	else
	    gcstr->gcstr[i].flag = LINEBREAK_FLAG_PROHIBIT_BEFORE;
    }

    /* Won't break punctuations at end of matches. */
    for (i = gcstr->gclen - 1; 1 <= i; i--) {
	unichar_t u = gcstr->str[gcstr->gcstr[i].idx];
	if (gcstr->gcstr[i].flag == LINEBREAK_FLAG_ALLOW_BEFORE &&
	    (u == '"' || u == '.' || u == ':' || u == ';' || u == ',' ||
	     u == '>'))
	    gcstr->gcstr[i].flag = LINEBREAK_FLAG_PROHIBIT_BEFORE;
	else
	    break;
    }
    return gcstr;
}
Esempio n. 9
0
void proto_tick() {
	int nbytes;
	char data[BUFSIZE/2];

	while (bot->running) {
		memset(&data, 0, BUFSIZE/2);

tick:
		tick_functions();

		recv:
		if ((nbytes = recv(bot->socket, data, (BUFSIZE/2)-1, 0)) == -1) {
			if (errno == EINTR) {
				// what a pain in the ass,
				// we got interrupted >.>
				goto recv;
			}

			if (errno == EAGAIN) {
				usleep(16666);
				goto tick;
			}


			perror("recv failed");
			exit(4);
		}

		strcat(bot->buffer, data);

		if (nbytes == 0) {
			bot->running = 0;
		}

		char *i = irc_getline(bot);
		if (i == NULL) {
			return;
		}

		for (; i != NULL; i = irc_nextline(bot)) {

			printf("%s\n", i);

			if (startswith(i, "PING")) {
				char *t = last(i);
				sockprintf(bot->socket, "PONG %s", t);
				free(t);
				free(i);
				continue;
			}

			struct message *msg = parse(i);

			if (EQ(msg->meth, "422") || EQ(msg->meth, "376")) {
				sockprintf(bot->socket, "JOIN #bots");
			}

			Link *handlers = hashmap_get(msg->meth, bot->handlers);
			for (Link *i = handlers; i != NULL; i = i->next) {
				((handler_t)i->ptr)(bot, msg);
			}
			freemsg(msg);
			free(i);
		}
	}
}
static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], bool test) {
        struct udev_list_entry *entry;
        unsigned release[1024];
        unsigned release_count = 0;
        _cleanup_close_ int fd = -1;
        const char *node;
        int has_abs = -1;

        node = udev_device_get_devnode(dev);
        if (!node) {
                log_error("No device node for \"%s\"", udev_device_get_syspath(dev));
                return EXIT_FAILURE;
        }

        udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev)) {
                const char *key;
                char *endptr;

                key = udev_list_entry_get_name(entry);
                if (startswith(key, "KEYBOARD_KEY_")) {
                        const char *keycode;
                        unsigned scancode;

                        /* KEYBOARD_KEY_<hex scan code>=<key identifier string> */
                        scancode = strtoul(key + 13, &endptr, 16);
                        if (endptr[0] != '\0') {
                                log_warning("Unable to parse scan code from \"%s\"", key);
                                continue;
                        }

                        keycode = udev_list_entry_get_value(entry);

                        /* a leading '!' needs a force-release entry */
                        if (keycode[0] == '!') {
                                keycode++;

                                release[release_count] = scancode;
                                if (release_count <  ELEMENTSOF(release)-1)
                                        release_count++;

                                if (keycode[0] == '\0')
                                        continue;
                        }

                        if (fd == -1) {
                                fd = open_device(node);
                                if (fd < 0)
                                        return EXIT_FAILURE;
                        }

                        map_keycode(fd, node, scancode, keycode);
                } else if (startswith(key, "EVDEV_ABS_")) {
                        unsigned evcode;

                        /* EVDEV_ABS_<EV_ABS code>=<min>:<max>:<res>:<fuzz>:<flat> */
                        evcode = strtoul(key + 10, &endptr, 16);
                        if (endptr[0] != '\0') {
                                log_warning("Unable to parse EV_ABS code from \"%s\"", key);
                                continue;
                        }

                        if (fd == -1) {
                                fd = open_device(node);
                                if (fd < 0)
                                        return EXIT_FAILURE;
                        }

                        if (has_abs == -1) {
                                unsigned long bits;
                                int rc;

                                rc = ioctl(fd, EVIOCGBIT(0, sizeof(bits)), &bits);
                                if (rc < 0) {
                                        log_error_errno(errno, "Unable to EVIOCGBIT device \"%s\"", node);
                                        return EXIT_FAILURE;
                                }

                                has_abs = !!(bits & (1 << EV_ABS));
                                if (!has_abs)
                                        log_warning("EVDEV_ABS override set but no EV_ABS present on device \"%s\"", node);
                        }

                        if (!has_abs)
                                continue;

                        override_abs(fd, node, evcode, udev_list_entry_get_value(entry));
                } else if (streq(key, "POINTINGSTICK_SENSITIVITY"))
                        set_trackpoint_sensitivity(dev, udev_list_entry_get_value(entry));
        }

        /* install list of force-release codes */
        if (release_count > 0)
                install_force_release(dev, release, release_count);

        return EXIT_SUCCESS;
}
Esempio n. 11
0
void
c_type_print_base (struct type *type, struct ui_file *stream,
		   int show, int level, const struct type_print_options *flags)
{
  int i;
  int len, real_len;
  enum
    {
      s_none, s_public, s_private, s_protected
    }
  section_type;
  int need_access_label = 0;
  int j, len2;

  QUIT;

  if (type == NULL)
    {
      fputs_filtered (_("<type unknown>"), stream);
      return;
    }

  /* When SHOW is zero or less, and there is a valid type name, then
     always just print the type name directly from the type.  */
  /* If we have "typedef struct foo {. . .} bar;" do we want to print
     it as "struct foo" or as "bar"?  Pick the latter, because C++
     folk tend to expect things like "class5 *foo" rather than "struct
     class5 *foo".  */

  if (show <= 0
      && TYPE_NAME (type) != NULL)
    {
      c_type_print_modifier (type, stream, 0, 1);
      print_name_maybe_canonical (TYPE_NAME (type), flags, stream);
      return;
    }

  type = check_typedef (type);

  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_TYPEDEF:
      /* If we get here, the typedef doesn't have a name, and we
	 couldn't resolve TYPE_TARGET_TYPE.  Not much we can do.  */
      gdb_assert (TYPE_NAME (type) == NULL);
      gdb_assert (TYPE_TARGET_TYPE (type) == NULL);
      fprintf_filtered (stream, _("<unnamed typedef>"));
      break;

    case TYPE_CODE_ARRAY:
    case TYPE_CODE_PTR:
    case TYPE_CODE_MEMBERPTR:
    case TYPE_CODE_REF:
    case TYPE_CODE_FUNC:
    case TYPE_CODE_METHOD:
    case TYPE_CODE_METHODPTR:
      c_type_print_base (TYPE_TARGET_TYPE (type),
			 stream, show, level, flags);
      break;

    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
      {
	struct type_print_options local_flags = *flags;
	struct type_print_options semi_local_flags = *flags;
	struct cleanup *local_cleanups = make_cleanup (null_cleanup, NULL);

	local_flags.local_typedefs = NULL;
	semi_local_flags.local_typedefs = NULL;

	if (!flags->raw)
	  {
	    if (flags->local_typedefs)
	      local_flags.local_typedefs
		= copy_typedef_hash (flags->local_typedefs);
	    else
	      local_flags.local_typedefs = create_typedef_hash ();

	    make_cleanup_free_typedef_hash (local_flags.local_typedefs);
	  }

	c_type_print_modifier (type, stream, 0, 1);
	if (TYPE_CODE (type) == TYPE_CODE_UNION)
	  fprintf_filtered (stream, "union ");
	else if (TYPE_DECLARED_CLASS (type))
	  fprintf_filtered (stream, "class ");
	else
	  fprintf_filtered (stream, "struct ");

	/* Print the tag if it exists.  The HP aCC compiler emits a
	   spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed
	   enum}" tag for unnamed struct/union/enum's, which we don't
	   want to print.  */
	if (TYPE_TAG_NAME (type) != NULL
	    && !startswith (TYPE_TAG_NAME (type), "{unnamed"))
	  {
	    /* When printing the tag name, we are still effectively
	       printing in the outer context, hence the use of FLAGS
	       here.  */
	    print_name_maybe_canonical (TYPE_TAG_NAME (type), flags, stream);
	    if (show > 0)
	      fputs_filtered (" ", stream);
	  }

	if (show < 0)
	  {
	    /* If we just printed a tag name, no need to print anything
	       else.  */
	    if (TYPE_TAG_NAME (type) == NULL)
	      fprintf_filtered (stream, "{...}");
	  }
	else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
	  {
	    struct type *basetype;
	    int vptr_fieldno;

	    c_type_print_template_args (&local_flags, type, stream);

	    /* Add in template parameters when printing derivation info.  */
	    add_template_parameters (local_flags.local_typedefs, type);
	    cp_type_print_derivation_info (stream, type, &local_flags);

	    /* This holds just the global typedefs and the template
	       parameters.  */
	    semi_local_flags.local_typedefs
	      = copy_typedef_hash (local_flags.local_typedefs);
	    if (semi_local_flags.local_typedefs)
	      make_cleanup_free_typedef_hash (semi_local_flags.local_typedefs);

	    /* Now add in the local typedefs.  */
	    recursively_update_typedef_hash (local_flags.local_typedefs, type);

	    fprintf_filtered (stream, "{\n");
	    if (TYPE_NFIELDS (type) == 0 && TYPE_NFN_FIELDS (type) == 0
		&& TYPE_TYPEDEF_FIELD_COUNT (type) == 0)
	      {
		if (TYPE_STUB (type))
		  fprintfi_filtered (level + 4, stream,
				     _("<incomplete type>\n"));
		else
		  fprintfi_filtered (level + 4, stream,
				     _("<no data fields>\n"));
	      }

	    /* Start off with no specific section type, so we can print
	       one for the first field we find, and use that section type
	       thereafter until we find another type.  */

	    section_type = s_none;

	    /* For a class, if all members are private, there's no need
	       for a "private:" label; similarly, for a struct or union
	       masquerading as a class, if all members are public, there's
	       no need for a "public:" label.  */

	    if (TYPE_DECLARED_CLASS (type))
	      {
		QUIT;
		len = TYPE_NFIELDS (type);
		for (i = TYPE_N_BASECLASSES (type); i < len; i++)
		  if (!TYPE_FIELD_PRIVATE (type, i))
		    {
		      need_access_label = 1;
		      break;
		    }
		QUIT;
		if (!need_access_label)
		  {
		    len2 = TYPE_NFN_FIELDS (type);
		    for (j = 0; j < len2; j++)
		      {
			len = TYPE_FN_FIELDLIST_LENGTH (type, j);
			for (i = 0; i < len; i++)
			  if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type,
									  j), i))
			    {
			      need_access_label = 1;
			      break;
			    }
			if (need_access_label)
			  break;
		      }
		  }
	      }
	    else
	      {
		QUIT;
		len = TYPE_NFIELDS (type);
		for (i = TYPE_N_BASECLASSES (type); i < len; i++)
		  if (TYPE_FIELD_PRIVATE (type, i)
		      || TYPE_FIELD_PROTECTED (type, i))
		    {
		      need_access_label = 1;
		      break;
		    }
		QUIT;
		if (!need_access_label)
		  {
		    len2 = TYPE_NFN_FIELDS (type);
		    for (j = 0; j < len2; j++)
		      {
			QUIT;
			len = TYPE_FN_FIELDLIST_LENGTH (type, j);
			for (i = 0; i < len; i++)
			  if (TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type,
									   j), i)
			      || TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type,
									    j),
							i))
			    {
			      need_access_label = 1;
			      break;
			    }
			if (need_access_label)
			  break;
		      }
		  }
	      }

	    /* If there is a base class for this type,
	       do not print the field that it occupies.  */

	    len = TYPE_NFIELDS (type);
	    vptr_fieldno = get_vptr_fieldno (type, &basetype);
	    for (i = TYPE_N_BASECLASSES (type); i < len; i++)
	      {
		QUIT;

		/* If we have a virtual table pointer, omit it.  Even if
		   virtual table pointers are not specifically marked in
		   the debug info, they should be artificial.  */
		if ((i == vptr_fieldno && type == basetype)
		    || TYPE_FIELD_ARTIFICIAL (type, i))
		  continue;

		if (need_access_label)
		  {
		    if (TYPE_FIELD_PROTECTED (type, i))
		      {
			if (section_type != s_protected)
			  {
			    section_type = s_protected;
			    fprintfi_filtered (level + 2, stream,
					       "protected:\n");
			  }
		      }
		    else if (TYPE_FIELD_PRIVATE (type, i))
		      {
			if (section_type != s_private)
			  {
			    section_type = s_private;
			    fprintfi_filtered (level + 2, stream,
					       "private:\n");
			  }
		      }
		    else
		      {
			if (section_type != s_public)
			  {
			    section_type = s_public;
			    fprintfi_filtered (level + 2, stream,
					       "public:\n");
			  }
		      }
		  }

		print_spaces_filtered (level + 4, stream);
		if (field_is_static (&TYPE_FIELD (type, i)))
		  fprintf_filtered (stream, "static ");
		c_print_type (TYPE_FIELD_TYPE (type, i),
			      TYPE_FIELD_NAME (type, i),
			      stream, show - 1, level + 4,
			      &local_flags);
		if (!field_is_static (&TYPE_FIELD (type, i))
		    && TYPE_FIELD_PACKED (type, i))
		  {
		    /* It is a bitfield.  This code does not attempt
		       to look at the bitpos and reconstruct filler,
		       unnamed fields.  This would lead to misleading
		       results if the compiler does not put out fields
		       for such things (I don't know what it does).  */
		    fprintf_filtered (stream, " : %d",
				      TYPE_FIELD_BITSIZE (type, i));
		  }
		fprintf_filtered (stream, ";\n");
	      }

	  /* If there are both fields and methods, put a blank line
	     between them.  Make sure to count only method that we
	     will display; artificial methods will be hidden.  */
	  len = TYPE_NFN_FIELDS (type);
	  if (!flags->print_methods)
	    len = 0;
	  real_len = 0;
	  for (i = 0; i < len; i++)
	    {
	      struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
	      int len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
	      int j;

	      for (j = 0; j < len2; j++)
		if (!TYPE_FN_FIELD_ARTIFICIAL (f, j))
		  real_len++;
	    }
	  if (real_len > 0 && section_type != s_none)
	    fprintf_filtered (stream, "\n");

	  /* C++: print out the methods.  */
	  for (i = 0; i < len; i++)
	    {
	      struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
	      int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
	      const char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
	      const char *name = type_name_no_tag (type);
	      int is_constructor = name && strcmp (method_name,
						   name) == 0;

	      for (j = 0; j < len2; j++)
		{
		  const char *mangled_name;
		  char *demangled_name;
		  struct cleanup *inner_cleanup;
		  const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
		  int is_full_physname_constructor =
		    TYPE_FN_FIELD_CONSTRUCTOR (f, j)
		    || is_constructor_name (physname)
		    || is_destructor_name (physname)
		    || method_name[0] == '~';

		  /* Do not print out artificial methods.  */
		  if (TYPE_FN_FIELD_ARTIFICIAL (f, j))
		    continue;

		  inner_cleanup = make_cleanup (null_cleanup, NULL);

		  QUIT;
		  if (TYPE_FN_FIELD_PROTECTED (f, j))
		    {
		      if (section_type != s_protected)
			{
			  section_type = s_protected;
			  fprintfi_filtered (level + 2, stream,
					     "protected:\n");
			}
		    }
		  else if (TYPE_FN_FIELD_PRIVATE (f, j))
		    {
		      if (section_type != s_private)
			{
			  section_type = s_private;
			  fprintfi_filtered (level + 2, stream,
					     "private:\n");
			}
		    }
		  else
		    {
		      if (section_type != s_public)
			{
			  section_type = s_public;
			  fprintfi_filtered (level + 2, stream,
					     "public:\n");
			}
		    }

		  print_spaces_filtered (level + 4, stream);
		  if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
		    fprintf_filtered (stream, "virtual ");
		  else if (TYPE_FN_FIELD_STATIC_P (f, j))
		    fprintf_filtered (stream, "static ");
		  if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0)
		    {
		      /* Keep GDB from crashing here.  */
		      fprintf_filtered (stream,
					_("<undefined type> %s;\n"),
					TYPE_FN_FIELD_PHYSNAME (f, j));
		      break;
		    }
		  else if (!is_constructor	/* Constructors don't
						   have declared
						   types.  */
			   && !is_full_physname_constructor  /* " " */
			   && !is_type_conversion_operator (type, i, j))
		    {
		      c_print_type (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)),
				    "", stream, -1, 0,
				    &local_flags);
		      fputs_filtered (" ", stream);
		    }
		  if (TYPE_FN_FIELD_STUB (f, j))
		    {
		      char *tem;

		      /* Build something we can demangle.  */
		      tem = gdb_mangle_name (type, i, j);
		      make_cleanup (xfree, tem);
		      mangled_name = tem;
		    }
		  else
		    mangled_name = TYPE_FN_FIELD_PHYSNAME (f, j);

		  demangled_name =
		    gdb_demangle (mangled_name,
				  DMGL_ANSI | DMGL_PARAMS);
		  if (demangled_name == NULL)
		    {
		      /* In some cases (for instance with the HP
			 demangling), if a function has more than 10
			 arguments, the demangling will fail.
			 Let's try to reconstruct the function
			 signature from the symbol information.  */
		      if (!TYPE_FN_FIELD_STUB (f, j))
			{
			  int staticp = TYPE_FN_FIELD_STATIC_P (f, j);
			  struct type *mtype = TYPE_FN_FIELD_TYPE (f, j);

			  cp_type_print_method_args (mtype,
						     "",
						     method_name,
						     staticp,
						     stream, &local_flags);
			}
		      else
			fprintf_filtered (stream,
					  _("<badly mangled name '%s'>"),
					  mangled_name);
		    }
		  else
		    {
		      char *p;
		      char *demangled_no_class
			= remove_qualifiers (demangled_name);

		      /* Get rid of the `static' appended by the
			 demangler.  */
		      p = strstr (demangled_no_class, " static");
		      if (p != NULL)
			{
			  int length = p - demangled_no_class;
			  char *demangled_no_static;

			  demangled_no_static
			    = (char *) xmalloc (length + 1);
			  strncpy (demangled_no_static,
				   demangled_no_class, length);
			  *(demangled_no_static + length) = '\0';
			  fputs_filtered (demangled_no_static, stream);
			  xfree (demangled_no_static);
			}
		      else
			fputs_filtered (demangled_no_class, stream);
		      xfree (demangled_name);
		    }

		  do_cleanups (inner_cleanup);

		  fprintf_filtered (stream, ";\n");
		}
	    }

	  /* Print typedefs defined in this class.  */

	  if (TYPE_TYPEDEF_FIELD_COUNT (type) != 0 && flags->print_typedefs)
	    {
	      if (TYPE_NFIELDS (type) != 0 || TYPE_NFN_FIELDS (type) != 0)
		fprintf_filtered (stream, "\n");

	      for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++)
		{
		  struct type *target = TYPE_TYPEDEF_FIELD_TYPE (type, i);

		  /* Dereference the typedef declaration itself.  */
		  gdb_assert (TYPE_CODE (target) == TYPE_CODE_TYPEDEF);
		  target = TYPE_TARGET_TYPE (target);

		  print_spaces_filtered (level + 4, stream);
		  fprintf_filtered (stream, "typedef ");

		  /* We want to print typedefs with substitutions
		     from the template parameters or globally-known
		     typedefs but not local typedefs.  */
		  c_print_type (target,
				TYPE_TYPEDEF_FIELD_NAME (type, i),
				stream, show - 1, level + 4,
				&semi_local_flags);
		  fprintf_filtered (stream, ";\n");
		}
	    }

	    fprintfi_filtered (level, stream, "}");
	  }

	do_cleanups (local_cleanups);
      }
      break;

    case TYPE_CODE_ENUM:
      c_type_print_modifier (type, stream, 0, 1);
      fprintf_filtered (stream, "enum ");
      if (TYPE_DECLARED_CLASS (type))
	fprintf_filtered (stream, "class ");
      /* Print the tag name if it exists.
         The aCC compiler emits a spurious 
         "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}"
         tag for unnamed struct/union/enum's, which we don't
         want to print.  */
      if (TYPE_TAG_NAME (type) != NULL
	  && !startswith (TYPE_TAG_NAME (type), "{unnamed"))
	{
	  print_name_maybe_canonical (TYPE_TAG_NAME (type), flags, stream);
	  if (show > 0)
	    fputs_filtered (" ", stream);
	}

      wrap_here ("    ");
      if (show < 0)
	{
	  /* If we just printed a tag name, no need to print anything
	     else.  */
	  if (TYPE_TAG_NAME (type) == NULL)
	    fprintf_filtered (stream, "{...}");
	}
      else if (show > 0 || TYPE_TAG_NAME (type) == NULL)
	{
	  LONGEST lastval = 0;

	  /* We can't handle this case perfectly, as DWARF does not
	     tell us whether or not the underlying type was specified
	     in the source (and other debug formats don't provide this
	     at all).  We choose to print the underlying type, if it
	     has a name, when in C++ on the theory that it's better to
	     print too much than too little; but conversely not to
	     print something egregiously outside the current
	     language's syntax.  */
	  if (current_language->la_language == language_cplus
	      && TYPE_TARGET_TYPE (type) != NULL)
	    {
	      struct type *underlying = check_typedef (TYPE_TARGET_TYPE (type));

	      if (TYPE_NAME (underlying) != NULL)
		fprintf_filtered (stream, ": %s ", TYPE_NAME (underlying));
	    }

	  fprintf_filtered (stream, "{");
	  len = TYPE_NFIELDS (type);
	  for (i = 0; i < len; i++)
	    {
	      QUIT;
	      if (i)
		fprintf_filtered (stream, ", ");
	      wrap_here ("    ");
	      fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
	      if (lastval != TYPE_FIELD_ENUMVAL (type, i))
		{
		  fprintf_filtered (stream, " = %s",
				    plongest (TYPE_FIELD_ENUMVAL (type, i)));
		  lastval = TYPE_FIELD_ENUMVAL (type, i);
		}
	      lastval++;
	    }
	  fprintf_filtered (stream, "}");
	}
      break;

    case TYPE_CODE_FLAGS:
      {
	struct type_print_options local_flags = *flags;

	local_flags.local_typedefs = NULL;

	c_type_print_modifier (type, stream, 0, 1);
	fprintf_filtered (stream, "flag ");
	print_name_maybe_canonical (TYPE_NAME (type), flags, stream);
	if (show > 0)
	  {
	    fputs_filtered (" ", stream);
	    fprintf_filtered (stream, "{\n");
	    if (TYPE_NFIELDS (type) == 0)
	      {
		if (TYPE_STUB (type))
		  fprintfi_filtered (level + 4, stream,
				     _("<incomplete type>\n"));
		else
		  fprintfi_filtered (level + 4, stream,
				     _("<no data fields>\n"));
	      }
	    len = TYPE_NFIELDS (type);
	    for (i = 0; i < len; i++)
	      {
		QUIT;
		print_spaces_filtered (level + 4, stream);
		/* We pass "show" here and not "show - 1" to get enum types
		   printed.  There's no other way to see them.  */
		c_print_type (TYPE_FIELD_TYPE (type, i),
			      TYPE_FIELD_NAME (type, i),
			      stream, show, level + 4,
			      &local_flags);
		fprintf_filtered (stream, " @%d",
				  TYPE_FIELD_BITPOS (type, i));
		if (TYPE_FIELD_BITSIZE (type, i) > 1)
		  {
		    fprintf_filtered (stream, "-%d",
				      TYPE_FIELD_BITPOS (type, i)
				      + TYPE_FIELD_BITSIZE (type, i) - 1);
		  }
		fprintf_filtered (stream, ";\n");
	      }
	    fprintfi_filtered (level, stream, "}");
	  }
      }
      break;

    case TYPE_CODE_VOID:
      fprintf_filtered (stream, "void");
      break;

    case TYPE_CODE_UNDEF:
      fprintf_filtered (stream, _("struct <unknown>"));
      break;

    case TYPE_CODE_ERROR:
      fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type));
      break;

    case TYPE_CODE_RANGE:
      /* This should not occur.  */
      fprintf_filtered (stream, _("<range type>"));
      break;

    case TYPE_CODE_NAMESPACE:
      fputs_filtered ("namespace ", stream);
      fputs_filtered (TYPE_TAG_NAME (type), stream);
      break;

    default:
      /* Handle types not explicitly handled by the other cases, such
         as fundamental types.  For these, just print whatever the
         type name is, as recorded in the type itself.  If there is no
         type name, then complain.  */
      if (TYPE_NAME (type) != NULL)
	{
	  c_type_print_modifier (type, stream, 0, 1);
	  print_name_maybe_canonical (TYPE_NAME (type), flags, stream);
	}
      else
	{
	  /* At least for dump_symtab, it is important that this not
	     be an error ().  */
	  fprintf_filtered (stream, _("<invalid type code %d>"),
			    TYPE_CODE (type));
	}
      break;
    }
}
Esempio n. 12
0
static void
tfile_open (const char *arg, int from_tty)
{
  char *temp;
  struct cleanup *old_chain;
  int flags;
  int scratch_chan;
  char header[TRACE_HEADER_SIZE];
  char linebuf[1000]; /* Should be max remote packet size or so.  */
  gdb_byte byte;
  int bytes, i;
  struct trace_status *ts;
  struct uploaded_tp *uploaded_tps = NULL;
  struct uploaded_tsv *uploaded_tsvs = NULL;
  char *filename;

  target_preopen (from_tty);
  if (!arg)
    error (_("No trace file specified."));

  filename = tilde_expand (arg);
  if (!IS_ABSOLUTE_PATH(filename))
    {
      temp = concat (current_directory, "/", filename, (char *) NULL);
      xfree (filename);
      filename = temp;
    }

  old_chain = make_cleanup (xfree, filename);

  flags = O_BINARY | O_LARGEFILE;
  flags |= O_RDONLY;
  scratch_chan = gdb_open_cloexec (filename, flags, 0);
  if (scratch_chan < 0)
    perror_with_name (filename);

  /* Looks semi-reasonable.  Toss the old trace file and work on the new.  */

  discard_cleanups (old_chain);	/* Don't free filename any more.  */
  unpush_target (&tfile_ops);

  trace_filename = xstrdup (filename);
  trace_fd = scratch_chan;

  /* Make sure this is clear.  */
  buffer_free (&trace_tdesc);

  bytes = 0;
  /* Read the file header and test for validity.  */
  tfile_read ((gdb_byte *) &header, TRACE_HEADER_SIZE);

  bytes += TRACE_HEADER_SIZE;
  if (!(header[0] == 0x7f
	&& (startswith (header + 1, "TRACE0\n"))))
    error (_("File is not a valid trace file."));

  push_target (&tfile_ops);

  trace_regblock_size = 0;
  ts = current_trace_status ();
  /* We know we're working with a file.  Record its name.  */
  ts->filename = trace_filename;
  /* Set defaults in case there is no status line.  */
  ts->running_known = 0;
  ts->stop_reason = trace_stop_reason_unknown;
  ts->traceframe_count = -1;
  ts->buffer_free = 0;
  ts->disconnected_tracing = 0;
  ts->circular_buffer = 0;

  TRY
    {
      /* Read through a section of newline-terminated lines that
	 define things like tracepoints.  */
      i = 0;
      while (1)
	{
	  tfile_read (&byte, 1);

	  ++bytes;
	  if (byte == '\n')
	    {
	      /* Empty line marks end of the definition section.  */
	      if (i == 0)
		break;
	      linebuf[i] = '\0';
	      i = 0;
	      tfile_interp_line (linebuf, &uploaded_tps, &uploaded_tsvs);
	    }
	  else
	    linebuf[i++] = byte;
	  if (i >= 1000)
	    error (_("Excessively long lines in trace file"));
	}

      /* By now, tdesc lines have been read from tfile - let's parse them.  */
      target_find_description ();

      /* Record the starting offset of the binary trace data.  */
      trace_frames_offset = bytes;

      /* If we don't have a blocksize, we can't interpret the
	 traceframes.  */
      if (trace_regblock_size == 0)
	error (_("No register block size recorded in trace file"));
    }
  CATCH (ex, RETURN_MASK_ALL)
    {
      /* Remove the partially set up target.  */
      unpush_target (&tfile_ops);
      throw_exception (ex);
    }
Esempio n. 13
0
static unsigned int
dict_hash (const char *string0)
{
  /* The Ada-encoded version of a name P1.P2...Pn has either the form
     P1__P2__...Pn<suffix> or _ada_P1__P2__...Pn<suffix> (where the Pi
     are lower-cased identifiers).  The <suffix> (which can be empty)
     encodes additional information about the denoted entity.  This
     routine hashes such names to msymbol_hash_iw(Pn).  It actually
     does this for a superset of both valid Pi and of <suffix>, but 
     in other cases it simply returns msymbol_hash_iw(STRING0).  */

  const char *string;
  unsigned int hash;

  string = string0;
  if (*string == '_')
    {
      if (startswith (string, "_ada_"))
	string += 5;
      else
	return msymbol_hash_iw (string0);
    }

  hash = 0;
  while (*string)
    {
      /* Ignore "TKB" suffixes.

	 These are used by Ada for subprograms implementing a task body.
	 For instance for a task T inside package Pck, the name of the
	 subprogram implementing T's body is `pck__tTKB'.  We need to
	 ignore the "TKB" suffix because searches for this task body
	 subprogram are going to be performed using `pck__t' (the encoded
	 version of the natural name `pck.t').  */
      if (strcmp (string, "TKB") == 0)
	return hash;

      switch (*string)
	{
	case '$':
	case '.':
	case 'X':
	  if (string0 == string)
	    return msymbol_hash_iw (string0);
	  else
	    return hash;
	case ' ':
	case '(':
	  return msymbol_hash_iw (string0);
	case '_':
	  if (string[1] == '_' && string != string0)
	    {
	      int c = string[2];

	      if ((c < 'a' || c > 'z') && c != 'O')
		return hash;
	      hash = 0;
	      string += 2;
	      break;
	    }
	  /* FALL THROUGH */
	default:
	  hash = SYMBOL_HASH_NEXT (hash, *string);
	  string += 1;
	  break;
	}
    }
  return hash;
}
Esempio n. 14
0
static int
gnuv3_is_operator_name (const char *name)
{
  return startswith (name, "operator");
}
Esempio n. 15
0
static int list_x11_keymaps(DBusConnection *bus, char **args, unsigned n) {
        _cleanup_fclose_ FILE *f = NULL;
        _cleanup_strv_free_ char **list = NULL;
        char line[LINE_MAX];
        enum {
                NONE,
                MODELS,
                LAYOUTS,
                VARIANTS,
                OPTIONS
        } state = NONE, look_for;
        int r;

        if (n > 2) {
                log_error("Too many arguments.");
                return -EINVAL;
        }

        f = fopen("/usr/share/X11/xkb/rules/base.lst", "re");
        if (!f) {
                log_error("Failed to open keyboard mapping list. %m");
                return -errno;
        }

        if (streq(args[0], "list-x11-keymap-models"))
                look_for = MODELS;
        else if (streq(args[0], "list-x11-keymap-layouts"))
                look_for = LAYOUTS;
        else if (streq(args[0], "list-x11-keymap-variants"))
                look_for = VARIANTS;
        else if (streq(args[0], "list-x11-keymap-options"))
                look_for = OPTIONS;
        else
                assert_not_reached("Wrong parameter");

        FOREACH_LINE(line, f, break) {
                char *l, *w;

                l = strstrip(line);

                if (isempty(l))
                        continue;

                if (l[0] == '!') {
                        if (startswith(l, "! model"))
                                state = MODELS;
                        else if (startswith(l, "! layout"))
                                state = LAYOUTS;
                        else if (startswith(l, "! variant"))
                                state = VARIANTS;
                        else if (startswith(l, "! option"))
                                state = OPTIONS;
                        else
                                state = NONE;

                        continue;
                }

                if (state != look_for)
                        continue;

                w = l + strcspn(l, WHITESPACE);

                if (n > 1) {
                        char *e;

                        if (*w == 0)
                                continue;

                        *w = 0;
                        w++;
                        w += strspn(w, WHITESPACE);

                        e = strchr(w, ':');
                        if (!e)
                                continue;

                        *e = 0;

                        if (!streq(w, args[1]))
                                continue;
                } else
                        *w = 0;

                 r = strv_extend(&list, l);
                 if (r < 0)
                         return log_oom();
        }

        if (strv_isempty(list)) {
                log_error("Couldn't find any entries.");
                return -ENOENT;
        }

        strv_sort(list);
        strv_uniq(list);

        pager_open_if_enabled();

        strv_print(list);
        return 0;
}
Esempio n. 16
0
int main(int argc, char *argv[]) {
    _cleanup_strv_free_ char **disks_done = NULL;
    _cleanup_fclose_ FILE *f = NULL;
    unsigned n = 0;
    int r = EXIT_FAILURE, r2 = EXIT_FAILURE;
    char **i;

    if (argc > 1 && argc != 4) {
        log_error("This program takes three or no arguments.");
        return EXIT_FAILURE;
    }

    if (argc > 1)
        arg_dest = argv[1];

    log_set_target(LOG_TARGET_SAFE);
    log_parse_environment();
    log_open();

    umask(0022);

    if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
        goto cleanup;

    if (!arg_enabled) {
        r = r2 = EXIT_SUCCESS;
        goto cleanup;
    }

    strv_uniq(arg_disks);

    if (arg_read_crypttab) {
        struct stat st;

        f = fopen("/etc/crypttab", "re");
        if (!f) {
            if (errno == ENOENT)
                r = EXIT_SUCCESS;
            else
                log_error("Failed to open /etc/crypttab: %m");

            goto next;
        }

        if (fstat(fileno(f), &st) < 0) {
            log_error("Failed to stat /etc/crypttab: %m");
            goto next;
        }

        /* If we readd support for specifying passphrases
         * directly in crypttabe we should upgrade the warning
         * below, though possibly only if a passphrase is
         * specified directly. */
        if (st.st_mode & 0005)
            log_debug("/etc/crypttab is world-readable. This is usually not a good idea.");

        for (;;) {
            char line[LINE_MAX], *l;
            _cleanup_free_ char *name = NULL, *device = NULL, *password = NULL, *options = NULL;
            int k;

            if (!fgets(line, sizeof(line), f))
                break;

            n++;

            l = strstrip(line);
            if (*l == '#' || *l == 0)
                continue;

            k = sscanf(l, "%ms %ms %ms %ms", &name, &device, &password, &options);
            if (k < 2 || k > 4) {
                log_error("Failed to parse /etc/crypttab:%u, ignoring.", n);
                continue;
            }

            /*
              If options are specified on the kernel commandline, let them override
              the ones from crypttab.
            */
            STRV_FOREACH(i, arg_options) {
                _cleanup_free_ char *proc_uuid = NULL, *proc_options = NULL;
                const char *p = *i;

                k = sscanf(p, "%m[0-9a-fA-F-]=%ms", &proc_uuid, &proc_options);
                if (k == 2 && streq(proc_uuid, device + 5)) {
                    free(options);
                    options = strdup(p);
                    if (!proc_options) {
                        log_oom();
                        goto cleanup;
                    }
                }
            }

            if (arg_disks) {
                /*
                  If luks UUIDs are specified on the kernel command line, use them as a filter
                  for /etc/crypttab and only generate units for those.
                */
                STRV_FOREACH(i, arg_disks) {
                    _cleanup_free_ char *proc_device = NULL, *proc_name = NULL;
                    const char *p = *i;

                    if (startswith(p, "luks-"))
                        p += 5;

                    proc_name = strappend("luks-", p);
                    proc_device = strappend("UUID=", p);

                    if (!proc_name || !proc_device) {
                        log_oom();
                        goto cleanup;
                    }

                    if (streq(proc_device, device) || streq(proc_name, name)) {
                        if (create_disk(name, device, password, options) < 0)
                            goto cleanup;

                        if (strv_extend(&disks_done, p) < 0) {
                            log_oom();
                            goto cleanup;
                        }
                    }
                }
            } else if (create_disk(name, device, password, options) < 0)
Esempio n. 17
0
char *
handle_line_of_input (struct buffer *cmd_line_buffer,
		      char *rl, int repeat, char *annotation_suffix)
{
  struct ui *ui = current_ui;
  int from_tty = ui->instream == ui->stdin_stream;
  char *p1;
  char *cmd;

  if (rl == NULL)
    return (char *) EOF;

  cmd = command_line_append_input_line (cmd_line_buffer, rl);
  if (cmd == NULL)
    return NULL;

  /* We have a complete command line now.  Prepare for the next
     command, but leave ownership of memory to the buffer .  */
  cmd_line_buffer->used_size = 0;

  if (from_tty && annotation_level > 1)
    {
      printf_unfiltered (("\n\032\032post-"));
      puts_unfiltered (annotation_suffix);
      printf_unfiltered (("\n"));
    }

#define SERVER_COMMAND_PREFIX "server "
  if (startswith (cmd, SERVER_COMMAND_PREFIX))
    {
      /* Note that we don't set `saved_command_line'.  Between this
         and the check in dont_repeat, this insures that repeating
         will still do the right thing.  */
      return cmd + strlen (SERVER_COMMAND_PREFIX);
    }

  /* Do history expansion if that is wished.  */
  if (history_expansion_p && from_tty && input_interactive_p (current_ui))
    {
      char *history_value;
      int expanded;

      expanded = history_expand (cmd, &history_value);
      if (expanded)
	{
	  size_t len;

	  /* Print the changes.  */
	  printf_unfiltered ("%s\n", history_value);

	  /* If there was an error, call this function again.  */
	  if (expanded < 0)
	    {
	      xfree (history_value);
	      return cmd;
	    }

	  /* history_expand returns an allocated string.  Just replace
	     our buffer with it.  */
	  len = strlen (history_value);
	  xfree (buffer_finish (cmd_line_buffer));
	  cmd_line_buffer->buffer = history_value;
	  cmd_line_buffer->buffer_size = len + 1;
	  cmd = history_value;
	}
    }

  /* If we just got an empty line, and that is supposed to repeat the
     previous command, return the previously saved command.  */
  for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++)
    ;
  if (repeat && *p1 == '\0')
    return saved_command_line;

  /* Add command to history if appropriate.  Note: lines consisting
     solely of comments are also added to the command history.  This
     is useful when you type a command, and then realize you don't
     want to execute it quite yet.  You can comment out the command
     and then later fetch it from the value history and remove the
     '#'.  The kill ring is probably better, but some people are in
     the habit of commenting things out.  */
  if (*cmd != '\0' && from_tty && input_interactive_p (current_ui))
    gdb_add_history (cmd);

  /* Save into global buffer if appropriate.  */
  if (repeat)
    {
      xfree (saved_command_line);
      saved_command_line = xstrdup (cmd);
      return saved_command_line;
    }
  else
    return cmd;
}
Esempio n. 18
0
static struct dirent * readdir_tarfs(fs_node_t *node, uint32_t index) {
	if (index == 0) {
		struct dirent * out = malloc(sizeof(struct dirent));
		memset(out, 0x00, sizeof(struct dirent));
		out->ino = 0;
		strcpy(out->name, ".");
		return out;
	}

	if (index == 1) {
		struct dirent * out = malloc(sizeof(struct dirent));
		memset(out, 0x00, sizeof(struct dirent));
		out->ino = 0;
		strcpy(out->name, "..");
		return out;
	}

	index -= 2;

	struct tarfs * self = node->device;

	/* Go through each file and pick the ones are at the root */
	/* Root files will have no /, so this is easy */
	unsigned int offset = node->inode;

	/* Read myself */
	struct ustar * file = malloc(sizeof(struct ustar));
	int status = ustar_from_offset(self, node->inode, file);
	char my_filename[256];

	/* Figure out my own filename, with forward slash */
	memset(my_filename, 0, 256);
	strncat(my_filename, file->prefix, 155);
	strncat(my_filename, file->filename, 100);

	while (offset < self->length) {
		ustar_from_offset(self, offset, file);

		if (!status) {
			free(file);
			return NULL;
		}

		char filename_workspace[256];
		memset(filename_workspace, 0, 256);
		strncat(filename_workspace, file->prefix, 155);
		strncat(filename_workspace, file->filename, 100);

		if (startswith(filename_workspace, my_filename)) {
			if (!count_slashes(filename_workspace + strlen(my_filename))) {
				if (strlen(filename_workspace + strlen(my_filename))) {
					if (index == 0) {
						char * slash = strstr(filename_workspace+strlen(my_filename),"/");
						if (slash) *slash = '\0'; /* remove trailing slash */
						struct dirent * out = malloc(sizeof(struct dirent));
						memset(out, 0x00, sizeof(struct dirent));
						out->ino = offset;
						strcpy(out->name, filename_workspace+strlen(my_filename));
						free(file);
						return out;
					} else {
						index--;
					}
				}
			}
		}

		offset += 512;
		offset += round_to_512(interpret_size(file));
	}

	free(file);
	return NULL;
}
Esempio n. 19
0
/*
 * See if left->addr or left->next is %defaultroute and change it to IP.
 *
 * Returns:
 * -1: failure
 *  0: done
 *  1: please call again: more to do
 */
static int resolve_defaultroute_one(struct starter_end *host,
				struct starter_end *peer)
{
	/*
	 * "left="         == host->addrtype and host->addr
	 * "leftnexthop="  == host->nexttype and host->nexthop
	 */

	/* What kind of result are we seeking? */
	bool seeking_src = (host->addrtype == KH_DEFAULTROUTE);
	bool seeking_gateway = (host->nexttype == KH_DEFAULTROUTE);

	char msgbuf[RTNL_BUFSIZE];
	bool has_dst = FALSE;
	int query_again = 0;

	if (!seeking_src && !seeking_gateway)
		return 0;	/* this end already figured out */

	/* Fill netlink request */
	netlink_query_init(msgbuf, host->addr_family);
	if (host->nexttype == KH_IPADDR) {
		/*
		 * My nexthop (gateway) is specified.
		 * We need to figure out our source IP to get there.
		 */
		netlink_query_add(msgbuf, RTA_DST, &host->nexthop);
		has_dst = TRUE;
	} else if (peer->addrtype == KH_IPADDR) {
		/*
		 * Peer IP is specified.
		 * We may need to figure out source IP
		 * and gateway IP to get there.
		 */
		netlink_query_add(msgbuf, RTA_DST, &peer->addr);
		has_dst = TRUE;
		if (seeking_src && seeking_gateway &&
			host->addr_family == AF_INET) {
			/*
			 * If we have only peer IP and no gateway/src we must
			 * do two queries:
			 * 1) find out gateway for dst
			 * 2) find out src for that gateway
			 * Doing both in one query returns src for dst.
			 *
			 * (IPv6 returns link-local for gateway so we can and
			 * do seek both in one query.)
			 */
			seeking_src = FALSE;
			query_again = 1;
		}
	}
	if (has_dst && host->addrtype == KH_IPADDR) {
		/* SRC works only with DST */
		netlink_query_add(msgbuf, RTA_SRC, &host->addr);
	}

	/*
	 * If we have for example host=%defaultroute + peer=%any
	 * (no destination) the netlink reply will be full routing table.
	 * We must do two queries:
	 * 1) find out default gateway
	 * 2) find out src for that default gateway
	 */
	if (!has_dst && seeking_src && seeking_gateway) {
		seeking_src = FALSE;
		query_again = 1;
	}
	if (seeking_gateway) {
		struct nlmsghdr *nlmsg = (struct nlmsghdr *)msgbuf;

		nlmsg->nlmsg_flags |= NLM_F_DUMP;
	}

	if (verbose)
		printf("\nseeking_src = %d, seeking_gateway = %d, has_dst = %d\n",
			seeking_src, seeking_gateway, has_dst);

	/* Send netlink get_route request */

	ssize_t len = netlink_query(msgbuf);

	if (len < 0)
		return -1;

	/* Parse reply */
	struct nlmsghdr *nlmsg = (struct nlmsghdr *)msgbuf;

	/*
	 * The cast to unsigned short is to dodge an error in
	 * netlink.h:NLMSG_OK() which triggers a GCC warning in recent
	 * versions of GCC (2014 August):
	 * error: comparison between signed and unsigned integer expressions
	 * Note: as long as RTNL_BUFSIZE <= USHRT_MAX, this is safe.
	 */
	for (; NLMSG_OK(nlmsg, (unsigned short)len); nlmsg = NLMSG_NEXT(nlmsg, len)) {
		char r_interface[IF_NAMESIZE+1];
		char r_source[ADDRTOT_BUF];
		char r_gateway[ADDRTOT_BUF];
		char r_destination[ADDRTOT_BUF];

		if (nlmsg->nlmsg_type == NLMSG_DONE)
			break;

		if (nlmsg->nlmsg_type == NLMSG_ERROR) {
			printf("netlink error\n");
			return -1;
		}

		/* ignore all but IPv4 and IPv6 */
		struct rtmsg *rtmsg = (struct rtmsg *) NLMSG_DATA(nlmsg);

		if (rtmsg->rtm_family != AF_INET &&
			rtmsg->rtm_family != AF_INET6)
			continue;

		/* Parse one route entry */
		zero(&r_interface);
		r_source[0] = r_gateway[0] = r_destination[0] = '\0';

		struct rtattr *rtattr = (struct rtattr *) RTM_RTA(rtmsg);
		int rtlen = RTM_PAYLOAD(nlmsg);

		while (RTA_OK(rtattr, rtlen)) {
			switch (rtattr->rta_type) {
			case RTA_OIF:
				if_indextoname(*(int *)RTA_DATA(rtattr),
					r_interface);
				break;

			case RTA_PREFSRC:
				inet_ntop(rtmsg->rtm_family, RTA_DATA(rtattr),
					r_source, sizeof(r_source));
				break;

			case RTA_GATEWAY:
				inet_ntop(rtmsg->rtm_family, RTA_DATA(rtattr),
					r_gateway, sizeof(r_gateway));
				break;

			case RTA_DST:
				inet_ntop(rtmsg->rtm_family, RTA_DATA(rtattr),
					r_destination,
					sizeof(r_destination));
				break;
			}
			rtattr = RTA_NEXT(rtattr, rtlen);
		}

		/*
		 * Ignore if not main table.
		 * Ignore ipsecX or mastX interfaces.
		 */
		bool ignore = rtmsg->rtm_table != RT_TABLE_MAIN ||
			startswith(r_interface, "ipsec") ||
			startswith(r_interface, "mast");

		if (verbose) {
			printf("dst %s via %s dev %s src %s table %d%s\n",
				r_destination,
				r_gateway,
				r_interface,
				r_source, rtmsg->rtm_table,
				ignore ? "" : " (ignored)");
		}

		if (ignore)
			continue;

		if (seeking_src && r_source[0] != '\0') {
			err_t err = tnatoaddr(r_source, 0, rtmsg->rtm_family,
					&host->addr);

			if (err == NULL) {
				host->addrtype = KH_IPADDR;
				seeking_src = FALSE;
				if (verbose)
					printf("set addr: %s\n", r_source);
			} else if (verbose) {
				printf("unknown source results from kernel (%s): %s\n",
					r_source, err);
			}
		}

		if (seeking_gateway && r_destination[0] == '\0' &&
			(has_dst || r_source[0] == '\0')) {
			if (r_gateway[0] == '\0' && r_interface[0] != '\0') {
				/*
				 * Point-to-Point default gw without "via IP"
				 * Attempt to find r_gateway as the IP address
				 * on the interface.
				 */
				resolve_ppp_peer(r_interface, host->addr_family,
						 r_gateway);
			}
			if (r_gateway[0] != '\0') {
				err_t err = tnatoaddr(r_gateway, 0,
						rtmsg->rtm_family,
						&host->nexthop);

				if (err != NULL) {
					printf("unknown gateway results from kernel: %s\n",
						err);
				} else {
					/* Note: Use first even if multiple */
					host->nexttype = KH_IPADDR;
					seeking_gateway = FALSE;
					if (verbose)
						printf("set nexthop: %s\n",
							r_gateway);
				}
			}
		}
	}
	return query_again;
}
Esempio n. 20
0
static DBusHandlerResult locale_message_handler(
                DBusConnection *connection,
                DBusMessage *message,
                void *userdata) {

        DBusMessage *reply = NULL, *changed = NULL;
        DBusError error;
        int r;

        assert(connection);
        assert(message);

        dbus_error_init(&error);

        if (dbus_message_is_method_call(message, "org.freedesktop.locale1", "SetLocale")) {
                char **l = NULL, **i;
                dbus_bool_t interactive;
                DBusMessageIter iter;
                bool modified = false;
                bool passed[_PROP_MAX];
                int p;

                if (!dbus_message_iter_init(message, &iter))
                        return bus_send_error_reply(connection, message, NULL, -EINVAL);

                r = bus_parse_strv_iter(&iter, &l);
                if (r < 0) {
                        if (r == -ENOMEM)
                                goto oom;

                        return bus_send_error_reply(connection, message, NULL, r);
                }

                if (!dbus_message_iter_next(&iter) ||
                    dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BOOLEAN)  {
                        strv_free(l);
                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
                }

                dbus_message_iter_get_basic(&iter, &interactive);

                zero(passed);

                /* Check whether a variable changed and if so valid */
                STRV_FOREACH(i, l) {
                        bool valid = false;

                        for (p = 0; p < _PROP_MAX; p++) {
                                size_t k;

                                k = strlen(names[p]);
                                if (startswith(*i, names[p]) &&
                                    (*i)[k] == '=' &&
                                    string_is_safe((*i) + k + 1)) {
                                        valid = true;
                                        passed[p] = true;

                                        if (!streq_ptr(*i + k + 1, data[p]))
                                                modified = true;

                                        break;
                                }
                        }

                        if (!valid) {
                                strv_free(l);
                                return bus_send_error_reply(connection, message, NULL, -EINVAL);
                        }
                }
Esempio n. 21
0
enum nss_status _nss_myhostname_gethostbyname3_r(
                const char *name,
                int af,
                struct hostent *host,
                char *buffer, size_t buflen,
                int *errnop, int *h_errnop,
                int32_t *ttlp,
                char **canonp) {

        _cleanup_free_ struct local_address *addresses = NULL;
        const char *canonical, *additional = NULL;
        _cleanup_free_ char *hn = NULL;
        uint32_t local_address_ipv4 = 0;
        int n_addresses = 0;

        PROTECT_ERRNO;
        BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);

        assert(name);
        assert(host);
        assert(buffer);
        assert(errnop);
        assert(h_errnop);

        if (af == AF_UNSPEC)
                af = AF_INET;

        if (!IN_SET(af, AF_INET, AF_INET6)) {
                *errnop = EAFNOSUPPORT;
                *h_errnop = NO_DATA;
                return NSS_STATUS_UNAVAIL;
        }

        if (is_localhost(name)) {
                canonical = "localhost";
                local_address_ipv4 = htobe32(INADDR_LOOPBACK);

        } else if (is_gateway_hostname(name)) {

                n_addresses = local_gateways(NULL, 0, af, &addresses);
                if (n_addresses <= 0) {
                        *h_errnop = HOST_NOT_FOUND;
                        return NSS_STATUS_NOTFOUND;
                }

                canonical = "_gateway";

        } else {
                hn = gethostname_malloc();
                if (!hn) {
                        *errnop = ENOMEM;
                        *h_errnop = NO_RECOVERY;
                        return NSS_STATUS_TRYAGAIN;
                }

                if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
                        *h_errnop = HOST_NOT_FOUND;
                        return NSS_STATUS_NOTFOUND;
                }

                n_addresses = local_addresses(NULL, 0, af, &addresses);
                if (n_addresses < 0)
                        n_addresses = 0;

                canonical = hn;
                additional = n_addresses <= 0 && af == AF_INET6 ? "localhost" : NULL;
                local_address_ipv4 = LOCALADDRESS_IPV4;
        }

        return fill_in_hostent(
                        canonical, additional,
                        af,
                        addresses, n_addresses,
                        local_address_ipv4,
                        host,
                        buffer, buflen,
                        errnop, h_errnop,
                        ttlp,
                        canonp);
}
Esempio n. 22
0
const char* start_website( int fd, char* url, char* ip ) {
    static char error_msg[64] = "";
    website_t* website;
    website_data_t* website_data;

    if ( ( website = website_get_by_full_url( url, ip ) ) )
        return "FAIL website already exists";

    int exlisnfd = zsocket( inet_addr( ip ), get_port_from_url( url ), ZSOCK_LISTEN, exsock_event_hdlr, startswith( url, "https://" ) );
    if ( exlisnfd == -1 ) {
        sprintf( error_msg, "FAIL error opening external socket: %s, %s", ip, strerror( errno ) );
        return error_msg;
    }

    website = website_add( fd, url, ip );

    syslog( LOG_INFO, "website: starting \"%s\" on \"%s\"", website->full_url, website->ip );

    website_data = (website_data_t*) malloc( sizeof( website_data_t ) );
    website->udata = website_data;

    website_data->exlisnfd = exlisnfd;

    zs_set_read( website_data->exlisnfd );
    return "OK";
}
Esempio n. 23
0
int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
        uint64_t missing;
        int r;

        assert(c);
        assert(c->allocated);

        missing = mask & ~c->mask;
        if (missing == 0)
                return 0;

        /* Try to retrieve PID from creds if it wasn't passed to us */
        if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
                pid = c->pid;

        if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
                tid = c->pid;

        /* Without pid we cannot do much... */
        if (pid <= 0)
                return 0;

        if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID |
                       SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
                       SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {

                _cleanup_fclose_ FILE *f = NULL;
                char line[LINE_MAX];
                const char *p;

                p = procfs_file_alloca(pid, "status");

                f = fopen(p, "re");
                if (!f)
                        return errno == ENOENT ? -ESRCH : -errno;

                FOREACH_LINE(line, f, return -errno) {
                        truncate_nl(line);

                        if (missing & SD_BUS_CREDS_UID) {
                                p = startswith(line, "Uid:");
                                if (p) {
                                        unsigned long uid;

                                        p += strspn(p, WHITESPACE);
                                        if (sscanf(p, "%lu", &uid) != 1)
                                                return -EIO;

                                        c->uid = (uid_t) uid;
                                        c->mask |= SD_BUS_CREDS_UID;
                                        continue;
                                }
                        }

                        if (missing & SD_BUS_CREDS_GID) {
                                p = startswith(line, "Gid:");
                                if (p) {
                                        unsigned long gid;

                                        p += strspn(p, WHITESPACE);
                                        if (sscanf(p, "%lu", &gid) != 1)
                                                return -EIO;

                                        c->gid = (uid_t) gid;
                                        c->mask |= SD_BUS_CREDS_GID;
                                        continue;
                                }
                        }

                        if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
                                p = startswith(line, "CapEff:");
                                if (p) {
                                        r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
                                        if (r < 0)
                                                return r;

                                        c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
                                        continue;
                                }
                        }

                        if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
                                p = startswith(line, "CapPrm:");
                                if (p) {
                                        r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
                                        if (r < 0)
                                                return r;

                                        c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
                                        continue;
                                }
                        }

                        if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
                                p = startswith(line, "CapInh:");
                                if (p) {
                                        r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
                                        if (r < 0)
                                                return r;

                                        c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
                                        continue;
                                }
                        }

                        if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
                                p = startswith(line, "CapBnd:");
                                if (p) {
                                        r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
                                        if (r < 0)
                                                return r;

                                        c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
                                        continue;
                                }
                        }
                }
        }
Esempio n. 24
0
void exread( int sockfd ) {
    void* ptr;
    conn_data_t* conn_data = connections[ sockfd ];

    if ( !conn_data->buffer ) {
        conn_data->buffer = malloc(PACK_DATA_SIZE);
        conn_data->bufferlen = 0;
        memset( conn_data->buffer, 0, PACK_DATA_SIZE );
    }

    website_t* website;

    ssize_t len = zs_read( sockfd, conn_data->buffer + conn_data->bufferlen, PACK_DATA_SIZE - conn_data->bufferlen );

    // TODO: wait for entire header before looking up website
    if ( len <= 0 ) {
cleanup:
        // cleanup
        cleanup_connection( sockfd );
        return;
    }

    if ( conn_data->postlen == -1 ) /* if we have received all the data already, ignore */
        return;

    conn_data->bufferlen += len;
    //printf( "%d: read %zu\n", sockfd, len );

    ptr = conn_data->buffer;

    if ( conn_data->website_sockfd == -1 ) {
        /* If req_info is NULL this is the start of a request and the
           HTTP request headers need to be parsed. */
        struct hostent* hp;
        hp = NULL;//gethostbyaddr( (char*) &conn_data->addr, sizeof( conn_data->addr ), AF_INET );

        char* endofhdrs;
        if ( !( endofhdrs = strnstr( conn_data->buffer, HTTP_HDR_ENDL HTTP_HDR_ENDL, PACK_DATA_SIZE ) ) ) {
            if ( conn_data->bufferlen == PACK_DATA_SIZE ) {
                /* If the end of the headers was not found the request was either
                   malformatted or too long, DO NOT send to website. */
                zs_write( sockfd, html_error_414, sizeof( html_error_414 ) );
                syslog( LOG_WARNING, "exread: headers to long" );
                goto cleanup;
            }
            // Have not received the full header yet, wait
            zs_set_read( sockfd );
            return;
        }
        endofhdrs += sizeof( HTTP_HDR_ENDL HTTP_HDR_ENDL ) - 1;
        /* Get HTTP request type */
        if ( startswith( conn_data->buffer, HTTP_GET ) )
            conn_data->request_type = HTTP_GET_TYPE;
        else if ( startswith( conn_data->buffer, HTTP_POST ) )
            conn_data->request_type = HTTP_POST_TYPE;
        else {
            zs_write( sockfd, html_error_400, sizeof( html_error_400 ) );
            goto cleanup;
        }

        /* Find website for request from HTTP header */
        char urlbuf[ PACK_DATA_SIZE ];
        if ( !get_url_from_http_header( conn_data->buffer, urlbuf, sizeof( urlbuf ) ) ) {
            //syslog( LOG_WARNING, "exread: no url found in http request headers: %s %s",
            //  inet_ntoa( conn_data->addr.sin_addr ), hp ? hp->h_name : "" );
            zs_write( sockfd, html_error_400, sizeof( html_error_400 ) );
            goto cleanup;
        }

        if ( !( website = website_find( urlbuf, conn_data->is_https ? "https://" : "http://",
                                        inet_ntoa( zs_get_addr( conn_data->exlisnfd )->sin_addr ) ) ) ) {
            //syslog( LOG_WARNING, "exread: no website to service request: %s %s %s",
            //  inet_ntoa( conn_data->addr.sin_addr ), hp ? hp->h_name : "", urlbuf );
            zs_write( sockfd, html_error_404, sizeof( html_error_404 ) );
            goto cleanup;
        }

        /* Set the website id so that furthur sections of this
           request can check if the website is still alive. */
        conn_data->website_sockfd = website->sockfd;

        /* Check the websites socket to make sure the request came in on
           the right socket. */
        website_data_t* website_data = website->udata;

        if ( website_data->exlisnfd != conn_data->exlisnfd ) {
            //syslog( LOG_WARNING, "exread: no website to service request: %s %s %s",
            //  inet_ntoa( conn_data->addr.sin_addr ), hp ? hp->h_name : "", urlbuf );
            zs_write( sockfd, html_error_404, sizeof( html_error_404 ) );
            goto cleanup;
        }
        //printf( "%s\n", buffer );

        /* Create a new message to send the request to the corresponding
           website. The msgid should be set to the external file descriptor
           to send the response back to. */
        conn_data->msgid = msg_open( website->sockfd, sockfd );
        zs_set_write( sockfd );

        // If request_type is POST check if there is content after the HTTP header
        char postlenbuf[ 32 ];
        memset( postlenbuf, 0, sizeof( postlenbuf ) );
        if ( conn_data->request_type == HTTP_POST_TYPE && ( ptr = strnstr( conn_data->buffer, "Content-Length: ", PACK_DATA_SIZE ) ) ) {
            char* tmp = strnstr( ptr + 16, HTTP_HDR_ENDL, PACK_DATA_SIZE - ( (long)ptr + 16 - (long)conn_data->buffer ) );
            if ( !tmp ) {
                zs_write( sockfd, html_error_400, sizeof( html_error_400 ) );
                goto cleanup;
            }
            memcpy( postlenbuf, ptr + 16, (long) tmp - (long) ( ptr + 16 ) );
            conn_data->postlen = strtoumax( postlenbuf, NULL, 0 );
            if ( conn_data->postlen < 0 ) {
                zs_write( sockfd, html_error_400, sizeof( html_error_400 ) );
                goto cleanup;
            }
        }

        // Write the message length
        size_t msglen = ( endofhdrs - conn_data->buffer ) + conn_data->postlen + sizeof( conn_data->addr.sin_addr ) + 1;
        if ( hp ) msglen += strlen( hp->h_name );
        if ( msg_write( website->sockfd, conn_data->msgid, (void*) &msglen, sizeof( size_t ) ) == -1 ) {
            zs_write( sockfd, html_error_502, sizeof( html_error_502 ) );
            goto cleanup;
        }

        // Write the ip address and hostname of the request
        if ( msg_write( website->sockfd, conn_data->msgid, (void*) &conn_data->addr.sin_addr, sizeof( conn_data->addr.sin_addr ) ) == -1
                || ( hp && msg_write( website->sockfd, conn_data->msgid, (void*) hp->h_name, strlen( hp->h_name ) ) == -1 )
                || msg_write( website->sockfd, conn_data->msgid, (void*) "\0", 1 ) == -1 ) {
            zs_write( sockfd, html_error_502, sizeof( html_error_502 ) );
            goto cleanup;
        }

        // Send the whole header to the website
        if ( msg_write( website->sockfd, conn_data->msgid, (void*) conn_data->buffer, ( endofhdrs - conn_data->buffer ) ) == -1 ) {
            zs_write( sockfd, html_error_502, sizeof( html_error_502 ) );
            goto cleanup;
        }

        ptr = endofhdrs;
    }

    else {
        if ( !( website = website_get_by_sockfd( conn_data->website_sockfd ) ) ) {
            //	syslog( LOG_WARNING, "exread: no website to service request" );
            zs_write( sockfd, html_error_502, sizeof( html_error_502 ) );
            goto cleanup;
        }
    }

    if ( conn_data->request_type == HTTP_POST_TYPE && conn_data->postlen ) {
        int left = conn_data->bufferlen - ( ptr - (void*)conn_data->buffer );

        if ( left > conn_data->postlen )
            conn_data->postlen = left;

        if ( msg_write( website->sockfd, conn_data->msgid, (void*) ptr, left ) == -1 ) {
            zs_write( sockfd, html_error_502, sizeof( html_error_502 ) );
            goto cleanup;
        }

        conn_data->postlen -= left;
    }

    if ( !conn_data->postlen ) { /* If there isn't more data coming, */
        msg_flush( website->sockfd, conn_data->msgid );

        /* must make sure to keep sockfd in read mode to detect a connection close from
           the other end */
        conn_data->postlen = -1;
        zs_set_read( sockfd );
    } else
        msg_set_write( website->sockfd, conn_data->msgid );

    free( conn_data->buffer );
    conn_data->buffer = NULL;
    //printf( "%d: still needs %d post data\n", sockfd, conn_data->postlen );
}
Esempio n. 25
0
int pull_find_old_etags(
                const char *url,
                const char *image_root,
                int dt,
                const char *prefix,
                const char *suffix,
                char ***etags) {

        _cleanup_free_ char *escaped_url = NULL;
        _cleanup_closedir_ DIR *d = NULL;
        _cleanup_strv_free_ char **l = NULL;
        struct dirent *de;
        int r;

        assert(url);
        assert(etags);

        if (!image_root)
                image_root = "/var/lib/machines";

        escaped_url = xescape(url, FILENAME_ESCAPE);
        if (!escaped_url)
                return -ENOMEM;

        d = opendir(image_root);
        if (!d) {
                if (errno == ENOENT) {
                        *etags = NULL;
                        return 0;
                }

                return -errno;
        }

        FOREACH_DIRENT_ALL(de, d, return -errno) {
                const char *a, *b;
                char *u;

                if (de->d_type != DT_UNKNOWN &&
                    de->d_type != dt)
                        continue;

                if (prefix) {
                        a = startswith(de->d_name, prefix);
                        if (!a)
                                continue;
                } else
                        a = de->d_name;

                a = startswith(a, escaped_url);
                if (!a)
                        continue;

                a = startswith(a, ".");
                if (!a)
                        continue;

                if (suffix) {
                        b = endswith(de->d_name, suffix);
                        if (!b)
                                continue;
                } else
                        b = strchr(de->d_name, 0);

                if (a >= b)
                        continue;

                r = cunescape_length(a, b - a, 0, &u);
                if (r < 0)
                        return r;

                if (!http_etag_is_valid(u)) {
                        free(u);
                        continue;
                }

                r = strv_consume(&l, u);
                if (r < 0)
                        return r;
        }

        *etags = l;
        l = NULL;

        return 0;
}
Esempio n. 26
0
int proc_cmdline_get_key(const char *key, unsigned flags, char **value) {
        _cleanup_free_ char *line = NULL, *ret = NULL;
        bool found = false;
        const char *p;
        int r;

        /* Looks for a specific key on the kernel command line. Supports two modes:
         *
         * a) The "value" parameter is used. In this case a parameter beginning with the "key" string followed by "="
         *    is searched, and the value following this is returned in "value".
         *
         * b) as above, but the PROC_CMDLINE_VALUE_OPTIONAL flag is set. In this case if the key is found as a
         *    separate word (i.e. not followed by "=" but instead by whitespace or the end of the command line), then
         *    this is also accepted, and "value" is returned as NULL.
         *
         * c) The "value" parameter is NULL. In this case a search for the exact "key" parameter is performed.
         *
         * In all three cases, > 0 is returned if the key is found, 0 if not. */

        if (isempty(key))
                return -EINVAL;

        if ((flags & PROC_CMDLINE_VALUE_OPTIONAL) && !value)
                return -EINVAL;

        r = proc_cmdline(&line);
        if (r < 0)
                return r;

        p = line;
        for (;;) {
                _cleanup_free_ char *word = NULL;
                const char *e;

                r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
                if (r < 0)
                        return r;
                if (r == 0)
                        break;

                /* Automatically filter out arguments that are intended only for the initrd, if we are not in the
                 * initrd. */
                if (!in_initrd() && startswith(word, "rd."))
                        continue;

                if (value) {
                        e = proc_cmdline_key_startswith(word, key);
                        if (!e)
                                continue;

                        if (*e == '=') {
                                r = free_and_strdup(&ret, e+1);
                                if (r < 0)
                                        return r;

                                found = true;

                        } else if (*e == 0 && (flags & PROC_CMDLINE_VALUE_OPTIONAL))
                                found = true;

                } else {
                        if (streq(word, key))
                                found = true;
                }
        }

        if (value)
                *value = TAKE_PTR(ret);

        return found;
}
Esempio n. 27
0
static int adm_builtin(struct udev *udev, int argc, char *argv[])
{
        static const struct option options[] = {
                { "help", no_argument, NULL, 'h' },
                {}
        };
        char *command = NULL;
        char *syspath = NULL;
        char filename[UTIL_PATH_SIZE];
        struct udev_device *dev = NULL;
        enum udev_builtin_cmd cmd;
        int rc = EXIT_SUCCESS, c;

        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
                switch (c) {
                case 'h':
                        help(udev);
                        goto out;
                }

        command = argv[optind++];
        if (command == NULL) {
                fprintf(stderr, "command missing\n");
                help(udev);
                rc = 2;
                goto out;
        }

        syspath = argv[optind++];
        if (syspath == NULL) {
                fprintf(stderr, "syspath missing\n");
                rc = 3;
                goto out;
        }

        udev_builtin_init(udev);

        cmd = udev_builtin_lookup(command);
        if (cmd >= UDEV_BUILTIN_MAX) {
                fprintf(stderr, "unknown command '%s'\n", command);
                help(udev);
                rc = 5;
                goto out;
        }

        /* add /sys if needed */
        if (!startswith(syspath, "/sys"))
                strscpyl(filename, sizeof(filename), "/sys", syspath, NULL);
        else
                strscpy(filename, sizeof(filename), syspath);
        util_remove_trailing_chars(filename, '/');

        dev = udev_device_new_from_syspath(udev, filename);
        if (dev == NULL) {
                fprintf(stderr, "unable to open device '%s'\n\n", filename);
                rc = 4;
                goto out;
        }

        rc = udev_builtin_run(dev, cmd, command, true);
        if (rc < 0) {
                fprintf(stderr, "error executing '%s', exit code %i\n\n", command, rc);
                rc = 6;
        }
out:
        udev_device_unref(dev);
        udev_builtin_exit(udev);
        return rc;
}
Esempio n. 28
0
static int parse_proc_cmdline(char ***arg_proc_cmdline_disks, char ***arg_proc_cmdline_options, char **arg_proc_cmdline_keyfile) {
        _cleanup_free_ char *line = NULL;
        char *w = NULL, *state = NULL;
        int r;
        size_t l;

        if (detect_container(NULL) > 0)
                return 0;

        r = read_one_line_file("/proc/cmdline", &line);
        if (r < 0) {
                log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
                return 0;
        }

        FOREACH_WORD_QUOTED(w, l, line, state) {
                _cleanup_free_ char *word = NULL;

                word = strndup(w, l);
                if (!word)
                        return log_oom();

                if (startswith(word, "luks=")) {
                        r = parse_boolean(word + 5);
                        if (r < 0)
                                log_warning("Failed to parse luks switch %s. Ignoring.", word + 5);
                        else
                                arg_enabled = r;

                } else if (startswith(word, "rd.luks=")) {

                        if (in_initrd()) {
                                r = parse_boolean(word + 8);
                                if (r < 0)
                                        log_warning("Failed to parse luks switch %s. Ignoring.", word + 8);
                                else
                                        arg_enabled = r;
                        }

                } else if (startswith(word, "luks.crypttab=")) {
                        r = parse_boolean(word + 14);
                        if (r < 0)
                                log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 14);
                        else
                                arg_read_crypttab = r;

                } else if (startswith(word, "rd.luks.crypttab=")) {

                        if (in_initrd()) {
                                r = parse_boolean(word + 17);
                                if (r < 0)
                                        log_warning("Failed to parse luks crypttab switch %s. Ignoring.", word + 17);
                                else
                                        arg_read_crypttab = r;
                        }

                } else if (startswith(word, "luks.uuid=")) {
                        if (strv_extend(arg_proc_cmdline_disks, word + 10) < 0)
                                return log_oom();

                } else if (startswith(word, "rd.luks.uuid=")) {

                        if (in_initrd()) {
                                if (strv_extend(arg_proc_cmdline_disks, word + 13) < 0)
                                        return log_oom();
                        }

                } else if (startswith(word, "luks.options=")) {
                        if (strv_extend(arg_proc_cmdline_options, word + 13) < 0)
                                return log_oom();

                } else if (startswith(word, "rd.luks.options=")) {

                        if (in_initrd()) {
                                if (strv_extend(arg_proc_cmdline_options, word + 16) < 0)
                                        return log_oom();
                        }

                } else if (startswith(word, "luks.key=")) {
                        if (*arg_proc_cmdline_keyfile)
                                free(*arg_proc_cmdline_keyfile);
                        *arg_proc_cmdline_keyfile = strdup(word + 9);
                        if (!*arg_proc_cmdline_keyfile)
                                return log_oom();

                } else if (startswith(word, "rd.luks.key=")) {

                        if (in_initrd()) {
                                if (*arg_proc_cmdline_keyfile)
                                        free(*arg_proc_cmdline_keyfile);
                                *arg_proc_cmdline_keyfile = strdup(word + 12);
                                if (!*arg_proc_cmdline_keyfile)
                                        return log_oom();
                        }

                } else if (startswith(word, "luks.") ||
                           (in_initrd() && startswith(word, "rd.luks."))) {

                        log_warning("Unknown kernel switch %s. Ignoring.", word);
                }
        }
Esempio n. 29
0
int parse_nsec(const char *t, nsec_t *nsec) {
        static const struct {
                const char *suffix;
                nsec_t nsec;
        } table[] = {
                { "seconds", NSEC_PER_SEC },
                { "second", NSEC_PER_SEC },
                { "sec", NSEC_PER_SEC },
                { "s", NSEC_PER_SEC },
                { "minutes", NSEC_PER_MINUTE },
                { "minute", NSEC_PER_MINUTE },
                { "min", NSEC_PER_MINUTE },
                { "months", NSEC_PER_MONTH },
                { "month", NSEC_PER_MONTH },
                { "msec", NSEC_PER_MSEC },
                { "ms", NSEC_PER_MSEC },
                { "m", NSEC_PER_MINUTE },
                { "hours", NSEC_PER_HOUR },
                { "hour", NSEC_PER_HOUR },
                { "hr", NSEC_PER_HOUR },
                { "h", NSEC_PER_HOUR },
                { "days", NSEC_PER_DAY },
                { "day", NSEC_PER_DAY },
                { "d", NSEC_PER_DAY },
                { "weeks", NSEC_PER_WEEK },
                { "week", NSEC_PER_WEEK },
                { "w", NSEC_PER_WEEK },
                { "years", NSEC_PER_YEAR },
                { "year", NSEC_PER_YEAR },
                { "y", NSEC_PER_YEAR },
                { "usec", NSEC_PER_USEC },
                { "us", NSEC_PER_USEC },
                { "nsec", 1ULL },
                { "ns", 1ULL },
                { "", 1ULL }, /* default is nsec */
        };

        const char *p, *s;
        nsec_t r = 0;
        bool something = false;

        assert(t);
        assert(nsec);

        p = t;

        p += strspn(p, WHITESPACE);
        s = startswith(p, "infinity");
        if (s) {
                s += strspn(s, WHITESPACE);
                if (*s != 0)
                        return -EINVAL;

                *nsec = NSEC_INFINITY;
                return 0;
        }

        for (;;) {
                long long l, z = 0;
                char *e;
                unsigned i, n = 0;

                p += strspn(p, WHITESPACE);

                if (*p == 0) {
                        if (!something)
                                return -EINVAL;

                        break;
                }

                errno = 0;
                l = strtoll(p, &e, 10);

                if (errno > 0)
                        return -errno;

                if (l < 0)
                        return -ERANGE;

                if (*e == '.') {
                        char *b = e + 1;

                        errno = 0;
                        z = strtoll(b, &e, 10);
                        if (errno > 0)
                                return -errno;

                        if (z < 0)
                                return -ERANGE;

                        if (e == b)
                                return -EINVAL;

                        n = e - b;

                } else if (e == p)
                        return -EINVAL;

                e += strspn(e, WHITESPACE);

                for (i = 0; i < ELEMENTSOF(table); i++)
                        if (startswith(e, table[i].suffix)) {
                                nsec_t k = (nsec_t) z * table[i].nsec;

                                for (; n > 0; n--)
                                        k /= 10;

                                r += (nsec_t) l * table[i].nsec + k;
                                p = e + strlen(table[i].suffix);

                                something = true;
                                break;
                        }

                if (i >= ELEMENTSOF(table))
                        return -EINVAL;

        }

        *nsec = r;

        return 0;
}
Esempio n. 30
0
static struct type *
gnuv3_rtti_type (struct value *value,
                 int *full_p, int *top_p, int *using_enc_p)
{
  struct gdbarch *gdbarch;
  struct type *values_type = check_typedef (value_type (value));
  struct value *vtable;
  struct minimal_symbol *vtable_symbol;
  const char *vtable_symbol_name;
  const char *class_name;
  struct type *run_time_type;
  LONGEST offset_to_top;
  char *atsign;

  /* We only have RTTI for class objects.  */
  if (TYPE_CODE (values_type) != TYPE_CODE_STRUCT)
    return NULL;

  /* Java doesn't have RTTI following the C++ ABI.  */
  if (TYPE_CPLUS_REALLY_JAVA (values_type))
    return NULL;

  /* Determine architecture.  */
  gdbarch = get_type_arch (values_type);

  if (using_enc_p)
    *using_enc_p = 0;

  vtable = gnuv3_get_vtable (gdbarch, values_type,
			     value_as_address (value_addr (value)));
  if (vtable == NULL)
    return NULL;

  /* Find the linker symbol for this vtable.  */
  vtable_symbol
    = lookup_minimal_symbol_by_pc (value_address (vtable)
                                   + value_embedded_offset (vtable)).minsym;
  if (! vtable_symbol)
    return NULL;
  
  /* The symbol's demangled name should be something like "vtable for
     CLASS", where CLASS is the name of the run-time type of VALUE.
     If we didn't like this approach, we could instead look in the
     type_info object itself to get the class name.  But this way
     should work just as well, and doesn't read target memory.  */
  vtable_symbol_name = MSYMBOL_DEMANGLED_NAME (vtable_symbol);
  if (vtable_symbol_name == NULL
      || !startswith (vtable_symbol_name, "vtable for "))
    {
      warning (_("can't find linker symbol for virtual table for `%s' value"),
	       TYPE_SAFE_NAME (values_type));
      if (vtable_symbol_name)
	warning (_("  found `%s' instead"), vtable_symbol_name);
      return NULL;
    }
  class_name = vtable_symbol_name + 11;

  /* Strip off @plt and version suffixes.  */
  atsign = strchr (class_name, '@');
  if (atsign != NULL)
    {
      char *copy;

      copy = alloca (atsign - class_name + 1);
      memcpy (copy, class_name, atsign - class_name);
      copy[atsign - class_name] = '\0';
      class_name = copy;
    }

  /* Try to look up the class name as a type name.  */
  /* FIXME: chastain/2003-11-26: block=NULL is bogus.  See pr gdb/1465.  */
  run_time_type = cp_lookup_rtti_type (class_name, NULL);
  if (run_time_type == NULL)
    return NULL;

  /* Get the offset from VALUE to the top of the complete object.
     NOTE: this is the reverse of the meaning of *TOP_P.  */
  offset_to_top
    = value_as_long (value_field (vtable, vtable_field_offset_to_top));

  if (full_p)
    *full_p = (- offset_to_top == value_embedded_offset (value)
               && (TYPE_LENGTH (value_enclosing_type (value))
                   >= TYPE_LENGTH (run_time_type)));
  if (top_p)
    *top_p = - offset_to_top;
  return run_time_type;
}