コード例 #1
0
int main(int argc, char **argv)
{
  DskDnsConfigFlags cfg_flags = DSK_DNS_CONFIG_FLAGS_INIT;
  dsk_boolean no_searchpath = DSK_FALSE;
  int i;
  dsk_cmdline_init ("perform DNS lookups",
                    "Perform DNS lookups with Dsk DNS client.\n",
                    "HOSTNAMES...",
                    0);
  dsk_cmdline_permit_extra_arguments (DSK_TRUE);
  dsk_cmdline_add_boolean ("ipv6", "Lookup names in the IPv6 namespace", NULL, 0, &use_ipv6);
  dsk_cmdline_add_boolean ("ipv4", "Lookup names in the IPv4 namespace", NULL, DSK_CMDLINE_REVERSED, &use_ipv6);
  dsk_cmdline_add_boolean ("cname", "Return CNAME or POINTER records if they arise", NULL, 0, &no_links);
  dsk_cmdline_add_string ("nameserver", "Specify the nameserver to use", "IP", 0, &nameserver);
  dsk_cmdline_add_boolean ("verbose", "Print extra messages", NULL, 0, &verbose);
  dsk_cmdline_add_boolean ("no-searchpath", "Do not use /etc/resolv.conf's searchpath", NULL, 0, &no_searchpath);
  dsk_cmdline_add_boolean ("fatal-errors", "Exit on first error", NULL, 0, &fatal_errors);
  dsk_cmdline_process_args (&argc, &argv);

  if (no_searchpath)
    cfg_flags &= ~DSK_DNS_CONFIG_USE_RESOLV_CONF_SEARCHPATH;

  if (nameserver == NULL)
    {
      /* just use default config */
    }
  else
    {
      DskIpAddress addr;
      cfg_flags &= ~DSK_DNS_CONFIG_USE_RESOLV_CONF_NS;
      if (!dsk_ip_address_parse_numeric (nameserver, &addr))
        dsk_error ("error parsing nameserver address (must be numeric)");
      dsk_dns_client_add_nameserver (&addr);
    }
  dsk_dns_client_config (cfg_flags);
  if (verbose)
    {
      dsk_dns_config_dump ();
    }

  if (argc == 1)
    dsk_error ("expected name to resolve");
  for (i = 1; i < argc; i++)
    {
      n_running++;
      dsk_dns_lookup (argv[i],
                      use_ipv6,
                      handle_dns_result,
                      argv[i]);
      while (n_running >= max_concurrent)
        dsk_main_run_once ();
    }
  dsk_dispatch_destroy_default ();
  return exit_status;
}
コード例 #2
0
ファイル: dsk-json-parser.c プロジェクト: davebenson/dsk
/* --- lexing --- */
dsk_boolean
dsk_json_parser_feed     (DskJsonParser *parser,
                          size_t         n_bytes,
                          const uint8_t *bytes,
                          DskError     **error)
{
  while (n_bytes > 0)
    {
      switch (parser->lex_state)
        {
        case JSON_LEX_STATE_INIT:
          while (n_bytes > 0 && dsk_ascii_isspace (*bytes))
            {
              if (*bytes == '\n')
                parser->line_no++;
              bytes++;
              n_bytes--;
            }
          if (n_bytes == 0)
            break;
          switch (*bytes)
            {
            case 't': case 'T':
              parser->lex_state = JSON_LEX_STATE_TRUE;
              parser->fixed_n_chars = 1;
              bytes++;
              n_bytes--;
              break;
            case 'f': case 'F':
              parser->lex_state = JSON_LEX_STATE_FALSE;
              parser->fixed_n_chars = 1;
              bytes++;
              n_bytes--;
              break;
            case 'n': case 'N':
              parser->lex_state = JSON_LEX_STATE_NULL;
              parser->fixed_n_chars = 1;
              bytes++;
              n_bytes--;
              break;
            case '"':
              parser->lex_state = JSON_LEX_STATE_IN_DQ;
              parser->str_len = 0;
              bytes++;
              n_bytes--;
              break;
            case '-': case '+':
            case '0': case '1': case '2': case '3': case '4': 
            case '5': case '6': case '7': case '8': case '9': 
              parser->lex_state = JSON_LEX_STATE_IN_NUMBER;
              parser->str_len = 0;
              append_to_string_buffer (parser, 1, bytes);
              bytes++;
              n_bytes--;
              break;

#define WRITE_CHAR_TOKEN_CASE(character, SHORTNAME) \
            case character: \
              if (!handle_token (parser, JSON_TOKEN_##SHORTNAME, error)) \
                return DSK_FALSE; \
              n_bytes--; \
              bytes++; \
              break
            WRITE_CHAR_TOKEN_CASE('{', LBRACE);
            WRITE_CHAR_TOKEN_CASE('}', RBRACE);
            WRITE_CHAR_TOKEN_CASE('[', LBRACKET);
            WRITE_CHAR_TOKEN_CASE(']', RBRACKET);
            WRITE_CHAR_TOKEN_CASE(',', COMMA);
            WRITE_CHAR_TOKEN_CASE(':', COLON);
#undef WRITE_CHAR_TOKEN_CASE

            case '\n':
              parser->line_no++;
              n_bytes--;
              bytes++;
              break;
            case '\t': case '\r': case ' ':
              n_bytes--;
              bytes++;
              break;
            default:
              dsk_set_error (error,
                             "unexpected character %s in json (line %u)",
                             dsk_ascii_byte_name (*bytes), parser->line_no);
              return DSK_FALSE;
            }
          break;

#define WRITE_FIXED_BAREWORD_CASE(SHORTNAME, lc, UC, length) \
        case JSON_LEX_STATE_##SHORTNAME: \
          if (parser->fixed_n_chars == length) \
            { \
              /* are we at end of string? */ \
              if (dsk_ascii_isalnum (*bytes)) \
                { \
                  dsk_set_error (error,  \
                                 "got %s after '%s' (line %u)", \
                                 dsk_ascii_byte_name (*bytes), lc, \
                                 parser->line_no); \
                  return DSK_FALSE; \
                } \
              else \
                { \
                  parser->lex_state = JSON_LEX_STATE_INIT; \
                  if (!handle_token (parser, JSON_TOKEN_##SHORTNAME, \
                                     error)) \
                    return DSK_FALSE; \
                } \
            } \
          else if (*bytes == lc[parser->fixed_n_chars] \
                || *bytes == UC[parser->fixed_n_chars]) \
            { \
              parser->fixed_n_chars += 1; \
              n_bytes--; \
              bytes++; \
            } \
          else \
            { \
              dsk_set_error (error, \
                           "unexpected character %s (parsing %s) (line %u)", \
                           dsk_ascii_byte_name (*bytes), UC, parser->line_no); \
              return DSK_FALSE; \
            } \
          break;
        WRITE_FIXED_BAREWORD_CASE(TRUE, "true", "TRUE", 4);
        WRITE_FIXED_BAREWORD_CASE(FALSE, "false", "FALSE", 5);
        WRITE_FIXED_BAREWORD_CASE(NULL, "null", "NULL", 4);
#undef WRITE_FIXED_BAREWORD_CASE

        case JSON_LEX_STATE_IN_DQ:
          if (*bytes == '"')
            {
              // TODO ASSERT utf16_surrogate == 0
              if (!handle_token (parser, JSON_TOKEN_STRING, error))
                return DSK_FALSE;
              bytes++;
              n_bytes--;
              parser->lex_state = JSON_LEX_STATE_INIT;
            }
          else if (*bytes == '\\')
            {
              n_bytes--;
              bytes++;
              parser->bs_sequence_len = 0;
              parser->lex_state = JSON_LEX_STATE_IN_DQ_BS;
            }
          else
            {
              // TODO ASSERT utf16_surrogate == 0
              unsigned i;
              if (*bytes == '\n')
                parser->line_no++;
              for (i = 1; i < n_bytes; i++)
                if (bytes[i] == '"' || bytes[i] == '\\')
                  break;
                else if (bytes[i] == '\n')
                  parser->line_no++;
              append_to_string_buffer (parser, i, bytes);
              n_bytes -= i;
              bytes += i;
            }
          break;
        case JSON_LEX_STATE_IN_DQ_BS:
          if (parser->bs_sequence_len == 0)
            {
              switch (*bytes)
                {
#define WRITE_BS_CHAR_CASE(bschar, cchar) \
                case bschar: \
                  /* TODO ASSERT utf16_surrogate == 0 */ \
                  append_char_to_string_buffer (parser, cchar); \
                  bytes++; \
                  n_bytes--; \
                  parser->lex_state = JSON_LEX_STATE_IN_DQ; \
                  break
                WRITE_BS_CHAR_CASE('b', '\b');
                WRITE_BS_CHAR_CASE('f', '\f');
                WRITE_BS_CHAR_CASE('n', '\n');
                WRITE_BS_CHAR_CASE('r', '\r');
                WRITE_BS_CHAR_CASE('t', '\t');
                WRITE_BS_CHAR_CASE('/', '/');
                WRITE_BS_CHAR_CASE('"', '"');
                WRITE_BS_CHAR_CASE('\\', '\\');
#undef WRITE_BS_CHAR_CASE
                case 'u':
                  parser->bs_sequence[parser->bs_sequence_len++] = *bytes++;
                  n_bytes--;
                  break;
                default:
                  dsk_set_error (error,
                               "invalid character %s after '\\' (line %u)",
                               dsk_ascii_byte_name (*bytes), parser->line_no);
                  return DSK_FALSE;
                }
            }
          else
            {
              /* must be \uxxxx (the only multi-character \ sequence) */
              if (!dsk_ascii_isxdigit (*bytes))
                {
                  dsk_set_error (error,
                               "expected 4 hex digits after \\u, got %s (line %u)",
                               dsk_ascii_byte_name (*bytes), parser->line_no);
                  return DSK_FALSE;
                }
              parser->bs_sequence[parser->bs_sequence_len++] = *bytes++;
              n_bytes--;
              if (parser->bs_sequence_len == 5)
                {
                  char utf8buf[8];
                  unsigned value;
                  parser->bs_sequence[5] = 0;
                  value = strtoul (parser->bs_sequence + 1, NULL, 16);
                  if (DSK_UTF16_LO_SURROGATE_START <= value
                   && value <= DSK_UTF16_LO_SURROGATE_END)
                    {
                      if (parser->utf16_surrogate == 0)
                        {
                          dsk_set_error (error,
                                       "low (second) half of surrogate pair was encountered without high-half, line %u",
                                       parser->line_no);
                          return DSK_FALSE;
                        }
                      uint32_t code = dsk_utf16_surrogate_pair_to_codepoint (parser->utf16_surrogate, value);
                      append_to_string_buffer (parser,
                                               dsk_utf8_encode_unichar (utf8buf, code),
                                               (const uint8_t *) utf8buf);
                      parser->utf16_surrogate = 0;
                    }
                  else if (DSK_UTF16_HI_SURROGATE_START <= value
                        && value <= DSK_UTF16_HI_SURROGATE_END)
                    {
                      if (parser->utf16_surrogate != 0)
                        {
                          dsk_set_error (error,
                                       "got two first-half surrogate pairs (UTF16 surrogate \\u%04u was followed by \\%04u), line %u",
                                       parser->utf16_surrogate, value, parser->line_no);
                          return DSK_FALSE;
                        }
                      parser->utf16_surrogate = value;
                    }
                  else
                    {
                      if (parser->utf16_surrogate != 0)
                        {
                          dsk_set_error (error,
                                       "second half of UTF16 surrogate \\u%04u was not preceded by utf16, line %u", 
                                       parser->utf16_surrogate, parser->line_no);
                          return DSK_FALSE;
                        }
                      append_to_string_buffer (parser,
                                               dsk_utf8_encode_unichar (utf8buf, value),
                                               (const uint8_t *) utf8buf);
                      parser->utf16_surrogate = 0;
                    }
                  parser->lex_state = JSON_LEX_STATE_IN_DQ;
                }
#if 0
              else
                {
                  dsk_set_error (error,
                               "internal error: expected 4 hex digits (line %u)",
                               parser->line_no);
                  return DSK_FALSE;
                }
#endif
            }
          break;
        case JSON_LEX_STATE_IN_NUMBER:
          if (dsk_ascii_isdigit (*bytes)
           || *bytes == '.'
           || *bytes == 'e'
           || *bytes == 'E'
           || *bytes == '+'
           || *bytes == '-')
            {
              append_to_string_buffer (parser, 1, bytes);
              bytes++;
              n_bytes--;
            }
          else
            {
              /* append the number token */
              if (!handle_token (parser, JSON_TOKEN_NUMBER, error))
                return DSK_FALSE;

              /* go back to init state (do not consume character) */
              parser->lex_state = JSON_LEX_STATE_INIT;
            }
          break;
        default:
          dsk_error ("unhandled lex state %u", parser->lex_state);
        }
    }
  return DSK_TRUE;
}