diff --git a/src/gpgme-json.c b/src/gpgme-json.c index e38f9d89..e5c84bb7 100644 --- a/src/gpgme-json.c +++ b/src/gpgme-json.c @@ -56,7 +56,8 @@ static char *error_object_string (const char *message, /* True if interactive mode is active. */ static int opt_interactive; - +/* True is debug mode is active. */ +static int opt_debug; /* @@ -754,9 +755,10 @@ op_help (cjson_t request, cjson_t result) /* Process a request and return the response. The response is a newly - * allocated staring or NULL in case of an error. */ + * allocated staring or NULL in case of an error. With NM_MODE set + * the actual request is taken from a "message" object. */ static char * -process_request (const char *request) +process_request (const char *request, int nm_mode) { static struct { const char *op; @@ -770,6 +772,7 @@ process_request (const char *request) { NULL } }; size_t erroff; + cjson_t json_orig; cjson_t json; cjson_t j_tmp, j_op; cjson_t response; @@ -780,7 +783,7 @@ process_request (const char *request) response = xjson_CreateObject (); - json = cJSON_Parse (request, &erroff); + json = json_orig = cJSON_Parse (request, &erroff); if (!json) { log_string (GPGRT_LOGLVL_INFO, request); @@ -788,6 +791,16 @@ process_request (const char *request) error_object (response, "invalid JSON object at offset %zu\n", erroff); goto leave; } + if (nm_mode) + { + json = cJSON_GetObjectItem (json, "message"); + if (!json) + { + log_info ("no \"message\" object in request\n"); + error_object (response, "no \"message\" object in request\n"); + goto leave; + } + } j_tmp = cJSON_GetObjectItem (json, "help"); helpmode = (j_tmp && cjson_is_true (j_tmp)); @@ -844,8 +857,7 @@ process_request (const char *request) } leave: - cJSON_Delete (json); - json = NULL; + cJSON_Delete (json_orig); if (opt_interactive) res = cJSON_Print (response); else @@ -930,7 +942,7 @@ process_meta_commands (const char *request) "\"\\nMeta commands:\\n" " ,help This help\\n" " ,quit Terminate process\"" - "}"); + "}", 0); else if (!strncmp (request, "quit", 4) && (spacep (request+4) || !request[4])) exit (0); else @@ -1029,7 +1041,7 @@ interactive_repl (void) } else if (request) { - response = process_request (request); + response = process_request (request, 0); } xfree (request); request = NULL; @@ -1072,7 +1084,7 @@ interactive_repl (void) } -/* Read and process asingle request. */ +/* Read and process a single request. */ static void read_and_process_single_request (void) { @@ -1093,7 +1105,7 @@ read_and_process_single_request (void) if (request) { xfree (response); - response = process_request (request); + response = process_request (request, 0); if (response) { es_fputs (response, es_stdout); @@ -1126,6 +1138,7 @@ native_messaging_repl (void) * binary mode. */ es_set_binary (es_stdin); es_set_binary (es_stdout); + es_setbuf (es_stdin, NULL); for (;;) { @@ -1149,7 +1162,7 @@ native_messaging_repl (void) { log_error ("error reading request: request too long (%zu MiB)\n", (size_t)nrequest / (1024*1024)); - /* Fixme: Shall we read the request t the bit bucket and + /* Fixme: Shall we read the request to the bit bucket and * return an error reponse or just return an error reponse * and terminate? Needs some testing. */ break; @@ -1181,8 +1194,12 @@ native_messaging_repl (void) } else /* Process request */ { + if (opt_debug) + log_debug ("request='%s'\n", request); xfree (response); - response = process_request (request); + response = process_request (request, 1); + if (opt_debug) + log_debug ("response='%s'\n", response); } nresponse = strlen (response); @@ -1263,12 +1280,18 @@ main (int argc, char *argv[]) enum { CMD_DEFAULT = 0, CMD_INTERACTIVE = 'i', CMD_SINGLE = 's', - CMD_LIBVERSION = 501 + CMD_LIBVERSION = 501, } cmd = CMD_DEFAULT; + enum { + OPT_DEBUG = 600 + }; + static gpgrt_opt_t opts[] = { ARGPARSE_c (CMD_INTERACTIVE, "interactive", "Interactive REPL"), ARGPARSE_c (CMD_SINGLE, "single", "Single request mode"), ARGPARSE_c (CMD_LIBVERSION, "lib-version", "Show library version"), + ARGPARSE_s_n(OPT_DEBUG, "debug", "Flyswatter"), + ARGPARSE_end() }; gpgrt_argparse_t pargs = { &argc, &argv}; @@ -1298,6 +1321,8 @@ main (int argc, char *argv[]) cmd = pargs.r_opt; break; + case OPT_DEBUG: opt_debug = 1; break; + default: pargs.err = ARGPARSE_PRINT_WARNING; break; @@ -1305,6 +1330,29 @@ main (int argc, char *argv[]) } gpgrt_argparse (NULL, &pargs, NULL); + if (!opt_debug) + { + const char *s = getenv ("GPGME_JSON_DEBUG"); + if (s && atoi (s) > 0) + opt_debug = 1; + } + + if (opt_debug) + { + const char *home = getenv ("HOME"); + char *file = xstrconcat ("socket://", + home? home:"/tmp", + "/.gnupg/S.gpgme-json.log", NULL); + log_set_file (file); + xfree (file); + } + + if (opt_debug) + { int i; + for (i=0; argv[i]; i++) + log_debug ("argv[%d]='%s'\n", i, argv[i]); + } + switch (cmd) { case CMD_DEFAULT: @@ -1327,6 +1375,9 @@ main (int argc, char *argv[]) break; } + if (opt_debug) + log_debug ("ready"); + #endif /* This is a modern libgp-error. */ return 0; }