示例#1
0
static void set_io_handler(RoadMapIO *io, GIOCondition condition, RoadMapInput callback)
{
   int i;
   int fd = io->os.file; /* All the same on UNIX. */

   if (io->subsystem == ROADMAP_IO_NET)
	fd = roadmap_net_get_fd(io->os.socket);

   for (i = 0; i < ROADMAP_MAX_IO; ++i) {
      if (RoadMapMainIo[i].io.subsystem == ROADMAP_IO_INVALID) {
	 io->data = &RoadMapMainIo[i];
         RoadMapMainIo[i].io = *io;
         RoadMapMainIo[i].callback = callback;
	 RoadMapMainIo[i].start_time = condition == G_IO_OUT ? time(NULL) : 0;
         RoadMapMainIo[i].id = add_io_handler(fd, condition, &RoadMapMainIo[i]);
         break;
      }
   }
}
示例#2
0
int main(int argc, char *argv[])
{
    FILE *tty = fopen(_PATH_TTY, "r+");
    if (tty == NULL && errno != ENOENT)
    {
        perror("can't open " _PATH_TTY);
        exit(EXIT_FAILURE);
    }

    char prog_name[PATH_MAX];
    if (neo4j_basename(argv[0], prog_name, sizeof(prog_name)) < 0)
    {
        perror("unexpected error");
        exit(EXIT_FAILURE);
    }

    uint8_t log_level = NEO4J_LOG_WARN;
    struct neo4j_logger_provider *provider = NULL;
    struct io_handler io_handlers[NEO4J_MAX_IO_ARGS];
    unsigned int nio_handlers = 0;

    neo4j_client_init();

    int result = EXIT_FAILURE;

    if (shell_state_init(&state, prog_name, stdin, stdout, stderr, tty))
    {
        neo4j_perror(stderr, errno, "unexpected error");
        goto cleanup;
    }

    state.interactive = isatty(STDIN_FILENO);

    char histfile[PATH_MAX];
    if (neo4j_dot_dir(histfile, sizeof(histfile), NEO4J_HISTORY_FILE) < 0)
    {
        neo4j_perror(state.err, (errno == ERANGE)? ENAMETOOLONG : errno,
                "unexpected error");
        goto cleanup;
    }
    state.histfile = histfile;

    if (isatty(fileno(stderr)))
    {
        state.error_colorize = ansi_error_colorization;
    }

    int c;
    while ((c = getopt_long(argc, argv, shortopts, longopts, NULL)) >= 0)
    {
        switch (c)
        {
        case 'h':
            usage(state.out, prog_name);
            result = EXIT_SUCCESS;
            goto cleanup;
        case 'v':
            ++log_level;
            break;
        case HISTFILE_OPT:
            state.histfile = (optarg[0] != '\0')? optarg : NULL;
            break;
        case CA_FILE_OPT:
            if (neo4j_config_set_TLS_ca_file(state.config, optarg))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case CA_DIRECTORY_OPT:
            if (neo4j_config_set_TLS_ca_dir(state.config, optarg))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case COLORIZE_OPT:
            state.error_colorize = ansi_error_colorization;
            break;
        case NO_COLORIZE_OPT:
            state.error_colorize = no_error_colorization;
            break;
        case INSECURE_OPT:
            state.connect_flags |= NEO4J_INSECURE;
            break;
        case NON_INTERACTIVE_OPT:
            state.interactive = false;
            if (tty != NULL)
            {
                fclose(tty);
                tty = NULL;
            }
            break;
        case 'u':
            if (neo4j_config_set_username(state.config, optarg))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case 'p':
            if (neo4j_config_set_password(state.config, optarg))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case 'P':
            if (tty == NULL)
            {
                fprintf(state.err,
                        "Cannot prompt for a password without a tty\n");
                goto cleanup;
            }
            state.password_prompt = true;
            break;
        case KNOWN_HOSTS_OPT:
            if (neo4j_config_set_known_hosts_file(state.config, optarg))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case NO_KNOWN_HOSTS_OPT:
            if (neo4j_config_set_trust_known_hosts(state.config, false))
            {
                neo4j_perror(state.err, errno, "unexpected error");
                goto cleanup;
            }
            break;
        case NOHIST_OPT:
            state.histfile = NULL;
            break;
        case PIPELINE_MAX_OPT:
            {
                int arg = atoi(optarg);
                if (arg < 1)
                {
                    fprintf(state.err, "Invalid pipeline-max '%s'\n", optarg);
                    goto cleanup;
                }
                state.pipeline_max = arg;
                neo4j_config_set_max_pipelined_requests(state.config, arg * 2);
            }
            break;
        case 'i':
            state.interactive = false;
            if (add_io_handler(io_handlers, &nio_handlers,
                        optarg, false, source))
            {
                goto cleanup;
            }
            break;
        case SOURCE_MAX_DEPTH_OPT:
            {
                int arg = atoi(optarg);
                if (arg < 1)
                {
                    fprintf(state.err, "Invalid source-max-depth '%s'\n",
                            optarg);
                    goto cleanup;
                }
                state.source_max_depth = arg;
            }
            break;
        case 'e':
            state.interactive = false;
            if (add_io_handler(io_handlers, &nio_handlers,
                        optarg, false, eval))
            {
                goto cleanup;
            }
            break;
        case 'o':
            if (add_io_handler(io_handlers, &nio_handlers,
                        optarg, true, redirect_output))
            {
                goto cleanup;
            }
            break;
        case VERSION_OPT:
            fprintf(state.out, "neo4j-client: %s\n", PACKAGE_VERSION);
            fprintf(state.out, "libneo4j-client: %s\n",
                    libneo4j_client_version());
            fprintf(state.out, "libcypher-parser: %s\n",
                    libcypher_parser_version());
            result = EXIT_SUCCESS;
            goto cleanup;
        default:
            usage(state.err, prog_name);
            goto cleanup;
        }
    }

    if (nio_handlers > 0 && io_handlers[nio_handlers-1].is_output)
    {
        fprintf(stderr,
                "--output/-o must be followed by --source/-i or --eval/-e\n");
        goto cleanup;
    }

    argc -= optind;
    argv += optind;

    if (argc > 2)
    {
        usage(state.err, prog_name);
        goto cleanup;
    }

    uint8_t logger_flags = 0;
    if (log_level < NEO4J_LOG_DEBUG)
    {
        logger_flags = NEO4J_STD_LOGGER_NO_PREFIX;
    }
    provider = neo4j_std_logger_provider(state.err, log_level, logger_flags);
    if (provider == NULL)
    {
        neo4j_perror(state.err, errno, "unexpected error");
        goto cleanup;
    }

    neo4j_config_set_logger_provider(state.config, provider);

    if (state.interactive)
    {
        state.password_prompt = true;
    }

    if (tty != NULL)
    {
        neo4j_config_set_unverified_host_callback(state.config,
                host_verification, &state);

        if (state.password_prompt)
        {
            neo4j_config_set_authentication_reattempt_callback(state.config,
                    auth_reattempt, &state);
        }
    }

    if (argc >= 1 && db_connect(&state, cypher_input_position_zero,
                argv[0], (argc > 1)? argv[1] : NULL))
    {
        goto cleanup;
    }

    // remove any password from the config
    if (neo4j_config_set_password(state.config, NULL))
    {
        // can't fail
    }

    if (signal(SIGINT, interrupt_handler) == SIG_ERR)
    {
        perror("unexpected error");
        goto cleanup;
    }

    if (state.interactive)
    {
        state.render = render_results_table;
        state.render_flags = NEO4J_RENDER_SHOW_NULLS;
        state.infile = "<interactive>";
        state.source_depth = 1;
        if (interact(&state))
        {
            goto cleanup;
        }
    }
    else if (nio_handlers > 0)
    {
        state.render = render_results_csv;
        for (unsigned int i = 0; i < nio_handlers; ++i)
        {
            if (io_handlers[i].handle(&state, io_handlers[i].arg))
            {
                goto cleanup;
            }
        }
    }
    else
    {
        state.render = render_results_csv;
        state.infile = "<stdin>";
        state.source_depth = 1;
        if (batch(&state, state.in))
        {
            goto cleanup;
        }
    }

    result = EXIT_SUCCESS;

cleanup:
    shell_state_destroy(&state);
    if (provider != NULL)
    {
        neo4j_std_logger_provider_free(provider);
    }
    for (unsigned int i = 0; i < nio_handlers; ++i)
    {
        free(io_handlers[i].arg);
    }
    if (tty != NULL)
    {
        fclose(tty);
    }
    neo4j_client_cleanup();
    return result;
}