Merge branch 'master' of ssh+git://playfair.gnupg.org/git/gpgme
This commit is contained in:
commit
d0bb4ec4ec
@ -3065,6 +3065,11 @@ a message signed by a brand new key (which you naturally will not have
|
|||||||
on your local keyring), the operator can tell both your IP address and
|
on your local keyring), the operator can tell both your IP address and
|
||||||
the time when you verified the signature.
|
the time when you verified the signature.
|
||||||
|
|
||||||
|
@item "request-origin"
|
||||||
|
The string given in @var{value} is passed to the GnuPG engines to
|
||||||
|
request restrictions based on the origin of the request. Valid values
|
||||||
|
are documented in the GnuPG manual and the gpg man page under the
|
||||||
|
option ``--request-origin''.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@ -13,3 +13,4 @@ cl Common Lisp
|
|||||||
cpp C++
|
cpp C++
|
||||||
qt Qt-Framework API
|
qt Qt-Framework API
|
||||||
python Python 2 and 3 (module name: gpg)
|
python Python 2 and 3 (module name: gpg)
|
||||||
|
javascript Native messaging client for the gpgme-json server.
|
||||||
|
@ -26,7 +26,7 @@ m4datadir = $(datadir)/aclocal
|
|||||||
m4data_DATA = gpgme.m4
|
m4data_DATA = gpgme.m4
|
||||||
nodist_include_HEADERS = gpgme.h
|
nodist_include_HEADERS = gpgme.h
|
||||||
|
|
||||||
bin_PROGRAMS = gpgme-tool
|
bin_PROGRAMS = gpgme-tool gpgme-json
|
||||||
|
|
||||||
if BUILD_W32_GLIB
|
if BUILD_W32_GLIB
|
||||||
ltlib_gpgme_glib = libgpgme-glib.la
|
ltlib_gpgme_glib = libgpgme-glib.la
|
||||||
@ -95,13 +95,18 @@ if BUILD_W32_GLIB
|
|||||||
libgpgme_glib_la_SOURCES = $(main_sources) w32-glib-io.c
|
libgpgme_glib_la_SOURCES = $(main_sources) w32-glib-io.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# We use a global CFLAGS setting for all library
|
# We use a global CFLAGS setting for all libraries
|
||||||
# versions, because then every object file is only compiled once.
|
# versions, because then every object file is only compiled once.
|
||||||
AM_CFLAGS = @LIBASSUAN_CFLAGS@ @GLIB_CFLAGS@
|
AM_CFLAGS = @LIBASSUAN_CFLAGS@ @GLIB_CFLAGS@
|
||||||
|
|
||||||
gpgme_tool_SOURCES = gpgme-tool.c argparse.c argparse.h
|
gpgme_tool_SOURCES = gpgme-tool.c argparse.c argparse.h
|
||||||
gpgme_tool_LDADD = libgpgme.la @LIBASSUAN_LIBS@
|
gpgme_tool_LDADD = libgpgme.la @LIBASSUAN_LIBS@
|
||||||
|
|
||||||
|
gpgme_json_SOURCES = gpgme-json.c cJSON.c cJSON.h
|
||||||
|
gpgme_json_LDADD = -lm libgpgme.la $(GPG_ERROR_LIBS)
|
||||||
|
# We use -no-install temporary during development.
|
||||||
|
gpgme_json_LDFLAGS = -no-install
|
||||||
|
|
||||||
|
|
||||||
if HAVE_W32_SYSTEM
|
if HAVE_W32_SYSTEM
|
||||||
# Windows provides us with an endless stream of Tough Love. To spawn
|
# Windows provides us with an endless stream of Tough Love. To spawn
|
||||||
|
1404
src/cJSON.c
Normal file
1404
src/cJSON.c
Normal file
File diff suppressed because it is too large
Load Diff
187
src/cJSON.h
Normal file
187
src/cJSON.h
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
/* cJSON.h
|
||||||
|
* Copyright (c) 2009 Dave Gamble
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*
|
||||||
|
* Note that this code has been modified from the original code taken
|
||||||
|
* from cjson-code-58.zip.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef cJSON_h
|
||||||
|
#define cJSON_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#if 0 /*(to make Emacs auto-indent happy)*/
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* cJSON Types: */
|
||||||
|
#define cJSON_False 0
|
||||||
|
#define cJSON_True 1
|
||||||
|
#define cJSON_NULL 2
|
||||||
|
#define cJSON_Number 3
|
||||||
|
#define cJSON_String 4
|
||||||
|
#define cJSON_Array 5
|
||||||
|
#define cJSON_Object 6
|
||||||
|
|
||||||
|
#define cJSON_IsReference 256
|
||||||
|
|
||||||
|
/* The cJSON structure: */
|
||||||
|
typedef struct cJSON
|
||||||
|
{
|
||||||
|
/* next/prev allow you to walk array/object chains. Alternatively,
|
||||||
|
use GetArraySize/GetArrayItem/GetObjectItem */
|
||||||
|
struct cJSON *next, *prev;
|
||||||
|
|
||||||
|
/* An array or object item will have a child pointer pointing to a
|
||||||
|
chain of the items in the array/object. */
|
||||||
|
struct cJSON *child;
|
||||||
|
|
||||||
|
int type; /* The type of the item, as above. */
|
||||||
|
|
||||||
|
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||||
|
int valueint; /* The item's number, if type==cJSON_Number */
|
||||||
|
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||||
|
|
||||||
|
/* The item's name string, if this item is the child of, or is in
|
||||||
|
the list of subitems of an object. */
|
||||||
|
char *string;
|
||||||
|
} cJSON;
|
||||||
|
|
||||||
|
typedef struct cJSON *cjson_t;
|
||||||
|
|
||||||
|
/* Macros to test the type of an object. */
|
||||||
|
#define cjson_is_boolean(a) (!((a)->type & ~1))
|
||||||
|
#define cjson_is_false(a) ((a)->type == cJSON_False)
|
||||||
|
#define cjson_is_true(a) ((a)->type == cJSON_True)
|
||||||
|
#define cjson_is_null(a) ((a)->type == cJSON_NULL)
|
||||||
|
#define cjson_is_number(a) ((a)->type == cJSON_Number)
|
||||||
|
#define cjson_is_string(a) ((a)->type == cJSON_String)
|
||||||
|
#define cjson_is_array(a) ((a)->type == cJSON_Array)
|
||||||
|
#define cjson_is_object(a) ((a)->type == cJSON_Object)
|
||||||
|
|
||||||
|
/* Supply a block of JSON, and this returns a cJSON object you can
|
||||||
|
interrogate. Call cJSON_Delete when finished. */
|
||||||
|
extern cJSON *cJSON_Parse(const char *value, size_t *r_erroff);
|
||||||
|
|
||||||
|
/* Render a cJSON entity to text for transfer/storage. Free the char*
|
||||||
|
when finished. */
|
||||||
|
extern char *cJSON_Print(cJSON *item);
|
||||||
|
|
||||||
|
/* Render a cJSON entity to text for transfer/storage without any
|
||||||
|
formatting. Free the char* when finished. */
|
||||||
|
extern char *cJSON_PrintUnformatted(cJSON *item);
|
||||||
|
|
||||||
|
/* Delete a cJSON entity and all subentities. */
|
||||||
|
extern void cJSON_Delete(cJSON *c);
|
||||||
|
|
||||||
|
/* Returns the number of items in an array (or object). */
|
||||||
|
extern int cJSON_GetArraySize(cJSON *array);
|
||||||
|
|
||||||
|
/* Retrieve item number "item" from array "array". Returns NULL if
|
||||||
|
unsuccessful. */
|
||||||
|
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
|
||||||
|
|
||||||
|
/* Get item "string" from object. Case insensitive. */
|
||||||
|
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||||
|
|
||||||
|
/* These calls create a cJSON item of the appropriate type. */
|
||||||
|
extern cJSON *cJSON_CreateNull(void);
|
||||||
|
extern cJSON *cJSON_CreateTrue(void);
|
||||||
|
extern cJSON *cJSON_CreateFalse(void);
|
||||||
|
extern cJSON *cJSON_CreateBool(int b);
|
||||||
|
extern cJSON *cJSON_CreateNumber(double num);
|
||||||
|
extern cJSON *cJSON_CreateString(const char *string);
|
||||||
|
extern cJSON *cJSON_CreateStringConvey (char *string);
|
||||||
|
extern cJSON *cJSON_CreateArray(void);
|
||||||
|
extern cJSON *cJSON_CreateObject(void);
|
||||||
|
|
||||||
|
/* These utilities create an Array of count items. */
|
||||||
|
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
|
||||||
|
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
|
||||||
|
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
|
||||||
|
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
|
||||||
|
|
||||||
|
/* Append item to the specified array. */
|
||||||
|
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||||
|
|
||||||
|
/* Append item to the specified object. */
|
||||||
|
extern cJSON *cJSON_AddItemToObject(cJSON *object, const char *name,
|
||||||
|
cJSON *item);
|
||||||
|
extern cJSON *cJSON_AddNullToObject (cJSON *object, const char *name);
|
||||||
|
extern cJSON *cJSON_AddTrueToObject (cJSON *object, const char *name);
|
||||||
|
extern cJSON *cJSON_AddFalseToObject (cJSON *object, const char *name);
|
||||||
|
extern cJSON *cJSON_AddBoolToObject (cJSON *object, const char *name, int b);
|
||||||
|
extern cJSON *cJSON_AddNumberToObject (cJSON *object, const char *name,
|
||||||
|
double num);
|
||||||
|
extern cJSON *cJSON_AddStringToObject (cJSON *object, const char *name,
|
||||||
|
const char *string);
|
||||||
|
|
||||||
|
/* Append reference to item to the specified array/object. Use this
|
||||||
|
when you want to add an existing cJSON to a new cJSON, but don't
|
||||||
|
want to corrupt your existing cJSON. */
|
||||||
|
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||||
|
extern void cJSON_AddItemReferenceToObject(cJSON *object,
|
||||||
|
const char *string,cJSON *item);
|
||||||
|
|
||||||
|
/* Remove/Detatch items from Arrays/Objects. */
|
||||||
|
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
|
||||||
|
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||||
|
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||||
|
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||||
|
|
||||||
|
/* Update array items. */
|
||||||
|
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||||
|
extern void cJSON_ReplaceItemInObject(cJSON *object,
|
||||||
|
const char *string, cJSON *newitem);
|
||||||
|
|
||||||
|
/* Duplicate a cJSON item */
|
||||||
|
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
|
||||||
|
|
||||||
|
/* Duplicate will create a new, identical cJSON item to the one you
|
||||||
|
pass, in new memory that will need to be released. With recurse!=0,
|
||||||
|
it will duplicate any children connected to the item. The
|
||||||
|
item->next and ->prev pointers are always zero on return from
|
||||||
|
Duplicate. */
|
||||||
|
|
||||||
|
/* ParseWithOpts allows you to require (and check) that the JSON is
|
||||||
|
null terminated, and to retrieve the pointer to the final byte
|
||||||
|
parsed. */
|
||||||
|
extern cJSON *cJSON_ParseWithOpts(const char *value,
|
||||||
|
const char **return_parse_end,
|
||||||
|
int require_null_terminated,
|
||||||
|
size_t *r_erroff);
|
||||||
|
|
||||||
|
extern void cJSON_Minify(char *json);
|
||||||
|
|
||||||
|
/* When assigning an integer value, it needs to be propagated to
|
||||||
|
valuedouble too. */
|
||||||
|
#define cJSON_SetIntValue(object,val) \
|
||||||
|
((object)?(object)->valueint=(object)->valuedouble=(val):(val))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* cJSON_h */
|
270
src/cJSON.readme
Normal file
270
src/cJSON.readme
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2009 Dave Gamble
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Welcome to cJSON.
|
||||||
|
|
||||||
|
cJSON aims to be the dumbest possible parser that you can get your job
|
||||||
|
done with. It's a single file of C, and a single header file.
|
||||||
|
|
||||||
|
JSON is described best here: http://www.json.org/ It's like XML, but
|
||||||
|
fat-free. You use it to move data around, store things, or just
|
||||||
|
generally represent your program's state.
|
||||||
|
|
||||||
|
|
||||||
|
First up, how do I build? Add cJSON.c to your project, and put
|
||||||
|
cJSON.h somewhere in the header search path. For example, to build
|
||||||
|
the test app:
|
||||||
|
|
||||||
|
gcc cJSON.c test.c -o test -lm
|
||||||
|
./test
|
||||||
|
|
||||||
|
|
||||||
|
As a library, cJSON exists to take away as much legwork as it can, but
|
||||||
|
not get in your way. As a point of pragmatism (i.e. ignoring the
|
||||||
|
truth), I'm going to say that you can use it in one of two modes: Auto
|
||||||
|
and Manual. Let's have a quick run-through.
|
||||||
|
|
||||||
|
|
||||||
|
I lifted some JSON from this page: http://www.json.org/fatfree.html
|
||||||
|
That page inspired me to write cJSON, which is a parser that tries to
|
||||||
|
share the same philosophy as JSON itself. Simple, dumb, out of the
|
||||||
|
way.
|
||||||
|
|
||||||
|
Some JSON:
|
||||||
|
{
|
||||||
|
"name": "Jack (\"Bee\") Nimble",
|
||||||
|
"format": {
|
||||||
|
"type": "rect",
|
||||||
|
"width": 1920,
|
||||||
|
"height": 1080,
|
||||||
|
"interlace": false,
|
||||||
|
"frame rate": 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assume that you got this from a file, a webserver, or magic JSON
|
||||||
|
elves, whatever, you have a char * to it. Everything is a cJSON
|
||||||
|
struct. Get it parsed:
|
||||||
|
|
||||||
|
cJSON *root = cJSON_Parse(my_json_string);
|
||||||
|
|
||||||
|
This is an object. We're in C. We don't have objects. But we do have
|
||||||
|
structs. What's the framerate?
|
||||||
|
|
||||||
|
cJSON *format = cJSON_GetObjectItem(root,"format");
|
||||||
|
int framerate = cJSON_GetObjectItem(format,"frame rate")->valueint;
|
||||||
|
|
||||||
|
Want to change the framerate?
|
||||||
|
|
||||||
|
cJSON_GetObjectItem(format,"frame rate")->valueint=25;
|
||||||
|
|
||||||
|
Back to disk?
|
||||||
|
|
||||||
|
char *rendered=cJSON_Print(root);
|
||||||
|
|
||||||
|
Finished? Delete the root (this takes care of everything else).
|
||||||
|
|
||||||
|
cJSON_Delete(root);
|
||||||
|
|
||||||
|
That's AUTO mode. If you're going to use Auto mode, you really ought
|
||||||
|
to check pointers before you dereference them. If you want to see how
|
||||||
|
you'd build this struct in code?
|
||||||
|
|
||||||
|
cJSON *root,*fmt;
|
||||||
|
root=cJSON_CreateObject();
|
||||||
|
cJSON_AddItemToObject(root, "name",
|
||||||
|
cJSON_CreateString("Jack (\"Bee\") Nimble"));
|
||||||
|
cJSON_AddItemToObject(root, "format", fmt=cJSON_CreateObject());
|
||||||
|
cJSON_AddStringToObject(fmt,"type", "rect");
|
||||||
|
cJSON_AddNumberToObject(fmt,"width", 1920);
|
||||||
|
cJSON_AddNumberToObject(fmt,"height", 1080);
|
||||||
|
cJSON_AddFalseToObject (fmt,"interlace");
|
||||||
|
cJSON_AddNumberToObject(fmt,"frame rate", 24);
|
||||||
|
|
||||||
|
Hopefully we can agree that's not a lot of code? There's no overhead,
|
||||||
|
no unnecessary setup. Look at test.c for a bunch of nice examples,
|
||||||
|
mostly all ripped off the json.org site, and a few from elsewhere.
|
||||||
|
|
||||||
|
What about manual mode? First up you need some detail. Let's cover
|
||||||
|
how the cJSON objects represent the JSON data. cJSON doesn't
|
||||||
|
distinguish arrays from objects in handling; just type. Each cJSON
|
||||||
|
has, potentially, a child, siblings, value, a name.
|
||||||
|
|
||||||
|
- The root object has: Object Type and a Child
|
||||||
|
- The Child has name "name", with value "Jack ("Bee") Nimble", and a sibling:
|
||||||
|
- Sibling has type Object, name "format", and a child.
|
||||||
|
- That child has type String, name "type", value "rect", and a sibling:
|
||||||
|
- Sibling has type Number, name "width", value 1920, and a sibling:
|
||||||
|
- Sibling has type Number, name "height", value 1080, and a sibling:
|
||||||
|
- Sibling hs type False, name "interlace", and a sibling:
|
||||||
|
- Sibling has type Number, name "frame rate", value 24
|
||||||
|
|
||||||
|
Here's the structure:
|
||||||
|
|
||||||
|
typedef struct cJSON {
|
||||||
|
struct cJSON *next,*prev;
|
||||||
|
struct cJSON *child;
|
||||||
|
|
||||||
|
int type;
|
||||||
|
|
||||||
|
char *valuestring;
|
||||||
|
int valueint;
|
||||||
|
double valuedouble;
|
||||||
|
|
||||||
|
char *string;
|
||||||
|
} cJSON;
|
||||||
|
|
||||||
|
By default all values are 0 unless set by virtue of being meaningful.
|
||||||
|
|
||||||
|
next/prev is a doubly linked list of siblings. next takes you to your sibling,
|
||||||
|
prev takes you back from your sibling to you.
|
||||||
|
|
||||||
|
Only objects and arrays have a "child", and it's the head of the
|
||||||
|
doubly linked list.
|
||||||
|
|
||||||
|
A "child" entry will have prev==0, but next potentially points on. The
|
||||||
|
last sibling has next=0.
|
||||||
|
|
||||||
|
The type expresses Null/True/False/Number/String/Array/Object, all of
|
||||||
|
which are #defined in cJSON.h
|
||||||
|
|
||||||
|
A Number has valueint and valuedouble. If you're expecting an int,
|
||||||
|
read valueint, if not read valuedouble.
|
||||||
|
|
||||||
|
Any entry which is in the linked list which is the child of an object
|
||||||
|
will have a "string" which is the "name" of the entry. When I said
|
||||||
|
"name" in the above example, that's "string". "string" is the JSON
|
||||||
|
name for the 'variable name' if you will.
|
||||||
|
|
||||||
|
Now you can trivially walk the lists, recursively, and parse as you
|
||||||
|
please. You can invoke cJSON_Parse to get cJSON to parse for you, and
|
||||||
|
then you can take the root object, and traverse the structure (which
|
||||||
|
is, formally, an N-tree), and tokenise as you please. If you wanted to
|
||||||
|
build a callback style parser, this is how you'd do it (just an
|
||||||
|
example, since these things are very specific):
|
||||||
|
|
||||||
|
void parse_and_callback(cJSON *item,const char *prefix)
|
||||||
|
{
|
||||||
|
while (item)
|
||||||
|
{
|
||||||
|
char *newprefix=malloc(strlen(prefix)+strlen(item->name)+2);
|
||||||
|
sprintf(newprefix,"%s/%s",prefix,item->name);
|
||||||
|
int dorecurse=callback(newprefix, item->type, item);
|
||||||
|
if (item->child && dorecurse)
|
||||||
|
parse_and_callback(item->child,newprefix);
|
||||||
|
item=item->next;
|
||||||
|
free(newprefix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
The prefix process will build you a separated list, to simplify your
|
||||||
|
callback handling.
|
||||||
|
|
||||||
|
The 'dorecurse' flag would let the callback decide to handle
|
||||||
|
sub-arrays on it's own, or let you invoke it per-item. For the item
|
||||||
|
above, your callback might look like this:
|
||||||
|
|
||||||
|
int callback(const char *name,int type,cJSON *item)
|
||||||
|
{
|
||||||
|
if (!strcmp(name,"name")) { /* populate name */ }
|
||||||
|
else if (!strcmp(name,"format/type") { /* handle "rect" */ }
|
||||||
|
else if (!strcmp(name,"format/width") { /* 800 */ }
|
||||||
|
else if (!strcmp(name,"format/height") { /* 600 */ }
|
||||||
|
else if (!strcmp(name,"format/interlace") { /* false */ }
|
||||||
|
else if (!strcmp(name,"format/frame rate") { /* 24 */ }
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Alternatively, you might like to parse iteratively.
|
||||||
|
You'd use:
|
||||||
|
|
||||||
|
void parse_object(cJSON *item)
|
||||||
|
{
|
||||||
|
int i; for (i=0;i<cJSON_GetArraySize(item);i++)
|
||||||
|
{
|
||||||
|
cJSON *subitem=cJSON_GetArrayItem(item,i);
|
||||||
|
// handle subitem.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Or, for PROPER manual mode:
|
||||||
|
|
||||||
|
void parse_object(cJSON *item)
|
||||||
|
{
|
||||||
|
cJSON *subitem=item->child;
|
||||||
|
while (subitem)
|
||||||
|
{
|
||||||
|
// handle subitem
|
||||||
|
if (subitem->child) parse_object(subitem->child);
|
||||||
|
|
||||||
|
subitem=subitem->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Of course, this should look familiar, since this is just a
|
||||||
|
stripped-down version of the callback-parser.
|
||||||
|
|
||||||
|
This should cover most uses you'll find for parsing. The rest should
|
||||||
|
be possible to infer.. and if in doubt, read the source! There's not a
|
||||||
|
lot of it! ;)
|
||||||
|
|
||||||
|
|
||||||
|
In terms of constructing JSON data, the example code above is the
|
||||||
|
right way to do it. You can, of course, hand your sub-objects to
|
||||||
|
other functions to populate. Also, if you find a use for it, you can
|
||||||
|
manually build the objects. For instance, suppose you wanted to build
|
||||||
|
an array of objects?
|
||||||
|
|
||||||
|
cJSON *objects[24];
|
||||||
|
|
||||||
|
cJSON *Create_array_of_anything(cJSON **items,int num)
|
||||||
|
{
|
||||||
|
int i;cJSON *prev, *root=cJSON_CreateArray();
|
||||||
|
for (i=0;i<24;i++)
|
||||||
|
{
|
||||||
|
if (!i) root->child=objects[i];
|
||||||
|
else prev->next=objects[i], objects[i]->prev=prev;
|
||||||
|
prev=objects[i];
|
||||||
|
}
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
and simply: Create_array_of_anything(objects,24);
|
||||||
|
|
||||||
|
cJSON doesn't make any assumptions about what order you create things
|
||||||
|
in. You can attach the objects, as above, and later add children to
|
||||||
|
each of those objects.
|
||||||
|
|
||||||
|
As soon as you call cJSON_Print, it renders the structure to text.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
The test.c code shows how to handle a bunch of typical cases. If you
|
||||||
|
uncomment the code, it'll load, parse and print a bunch of test files,
|
||||||
|
also from json.org, which are more complex than I'd care to try and
|
||||||
|
stash into a const char array[].
|
||||||
|
|
||||||
|
|
||||||
|
Enjoy cJSON!
|
||||||
|
|
||||||
|
|
||||||
|
- Dave Gamble, Aug 2009
|
@ -145,6 +145,9 @@ struct gpgme_context
|
|||||||
/* The gpg specific override session key or NULL. */
|
/* The gpg specific override session key or NULL. */
|
||||||
char *override_session_key;
|
char *override_session_key;
|
||||||
|
|
||||||
|
/* The optional request origin. */
|
||||||
|
char *request_origin;
|
||||||
|
|
||||||
/* The locale for the pinentry. */
|
/* The locale for the pinentry. */
|
||||||
char *lc_ctype;
|
char *lc_ctype;
|
||||||
char *lc_messages;
|
char *lc_messages;
|
||||||
|
@ -96,6 +96,7 @@ struct engine_llass
|
|||||||
int gpg_agent:1; /* Assume this is a gpg-agent connection. */
|
int gpg_agent:1; /* Assume this is a gpg-agent connection. */
|
||||||
} opt;
|
} opt;
|
||||||
|
|
||||||
|
char request_origin[10]; /* Copy from the CTX. */
|
||||||
};
|
};
|
||||||
typedef struct engine_llass *engine_llass_t;
|
typedef struct engine_llass *engine_llass_t;
|
||||||
|
|
||||||
@ -365,6 +366,24 @@ llass_new (void **engine, const char *file_name, const char *home_dir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy flags from CTX into the engine object. */
|
||||||
|
static void
|
||||||
|
llass_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
|
||||||
|
{
|
||||||
|
engine_llass_t llass = engine;
|
||||||
|
|
||||||
|
if (ctx->request_origin)
|
||||||
|
{
|
||||||
|
if (strlen (ctx->request_origin) + 1 > sizeof llass->request_origin)
|
||||||
|
strcpy (llass->request_origin, "xxx"); /* Too long - force error */
|
||||||
|
else
|
||||||
|
strcpy (llass->request_origin, ctx->request_origin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*llass->request_origin = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
llass_set_locale (void *engine, int category, const char *value)
|
llass_set_locale (void *engine, int category, const char *value)
|
||||||
{
|
{
|
||||||
@ -660,6 +679,21 @@ start (engine_llass_t llass, const char *command)
|
|||||||
int nfds;
|
int nfds;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (*llass->request_origin && llass->opt.gpg_agent)
|
||||||
|
{
|
||||||
|
char *cmd;
|
||||||
|
|
||||||
|
cmd = _gpgme_strconcat ("OPTION pretend-request-origin=",
|
||||||
|
llass->request_origin, NULL);
|
||||||
|
if (!cmd)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
err = assuan_transact (llass->assuan_ctx, cmd, NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
free (cmd);
|
||||||
|
if (err && gpg_err_code (err) != GPG_ERR_UNKNOWN_OPTION)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* We need to know the fd used by assuan for reads. We do this by
|
/* We need to know the fd used by assuan for reads. We do this by
|
||||||
using the assumption that the first returned fd from
|
using the assumption that the first returned fd from
|
||||||
assuan_get_active_fds() is always this one. */
|
assuan_get_active_fds() is always this one. */
|
||||||
@ -775,6 +809,7 @@ struct engine_ops _gpgme_engine_ops_assuan =
|
|||||||
NULL, /* set_colon_line_handler */
|
NULL, /* set_colon_line_handler */
|
||||||
llass_set_locale,
|
llass_set_locale,
|
||||||
NULL, /* set_protocol */
|
NULL, /* set_protocol */
|
||||||
|
llass_set_engine_flags,
|
||||||
NULL, /* decrypt */
|
NULL, /* decrypt */
|
||||||
NULL, /* delete */
|
NULL, /* delete */
|
||||||
NULL, /* edit */
|
NULL, /* edit */
|
||||||
|
@ -61,6 +61,7 @@ struct engine_ops
|
|||||||
void *fnc_value);
|
void *fnc_value);
|
||||||
gpgme_error_t (*set_locale) (void *engine, int category, const char *value);
|
gpgme_error_t (*set_locale) (void *engine, int category, const char *value);
|
||||||
gpgme_error_t (*set_protocol) (void *engine, gpgme_protocol_t protocol);
|
gpgme_error_t (*set_protocol) (void *engine, gpgme_protocol_t protocol);
|
||||||
|
void (*set_engine_flags) (void *engine, gpgme_ctx_t ctx);
|
||||||
gpgme_error_t (*decrypt) (void *engine,
|
gpgme_error_t (*decrypt) (void *engine,
|
||||||
gpgme_decrypt_flags_t flags,
|
gpgme_decrypt_flags_t flags,
|
||||||
gpgme_data_t ciph,
|
gpgme_data_t ciph,
|
||||||
|
@ -790,6 +790,7 @@ struct engine_ops _gpgme_engine_ops_g13 =
|
|||||||
NULL, /* set_colon_line_handler */
|
NULL, /* set_colon_line_handler */
|
||||||
g13_set_locale,
|
g13_set_locale,
|
||||||
NULL, /* set_protocol */
|
NULL, /* set_protocol */
|
||||||
|
NULL, /* set_engine_flags */
|
||||||
NULL, /* decrypt */
|
NULL, /* decrypt */
|
||||||
NULL, /* delete */
|
NULL, /* delete */
|
||||||
NULL, /* edit */
|
NULL, /* edit */
|
||||||
|
@ -143,6 +143,7 @@ struct engine_gpg
|
|||||||
|
|
||||||
struct gpgme_io_cbs io_cbs;
|
struct gpgme_io_cbs io_cbs;
|
||||||
gpgme_pinentry_mode_t pinentry_mode;
|
gpgme_pinentry_mode_t pinentry_mode;
|
||||||
|
char request_origin[10];
|
||||||
|
|
||||||
/* NULL or the data object fed to --override_session_key-fd. */
|
/* NULL or the data object fed to --override_session_key-fd. */
|
||||||
gpgme_data_t override_session_key;
|
gpgme_data_t override_session_key;
|
||||||
@ -628,6 +629,24 @@ gpg_new (void **engine, const char *file_name, const char *home_dir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy flags from CTX into the engine object. */
|
||||||
|
static void
|
||||||
|
gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
|
||||||
|
{
|
||||||
|
engine_gpg_t gpg = engine;
|
||||||
|
|
||||||
|
if (ctx->request_origin && have_gpg_version (gpg, "2.2.6"))
|
||||||
|
{
|
||||||
|
if (strlen (ctx->request_origin) + 1 > sizeof gpg->request_origin)
|
||||||
|
strcpy (gpg->request_origin, "xxx"); /* Too long - force error */
|
||||||
|
else
|
||||||
|
strcpy (gpg->request_origin, ctx->request_origin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*gpg->request_origin = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
gpg_set_locale (void *engine, int category, const char *value)
|
gpg_set_locale (void *engine, int category, const char *value)
|
||||||
{
|
{
|
||||||
@ -856,7 +875,7 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
|
|||||||
argc++;
|
argc++;
|
||||||
if (!gpg->cmd.used)
|
if (!gpg->cmd.used)
|
||||||
argc++; /* --batch */
|
argc++; /* --batch */
|
||||||
argc += 1; /* --no-sk-comments */
|
argc += 2; /* --no-sk-comments, --request-origin */
|
||||||
|
|
||||||
argv = calloc (argc + 1, sizeof *argv);
|
argv = calloc (argc + 1, sizeof *argv);
|
||||||
if (!argv)
|
if (!argv)
|
||||||
@ -904,6 +923,20 @@ build_argv (engine_gpg_t gpg, const char *pgmname)
|
|||||||
argc++;
|
argc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*gpg->request_origin)
|
||||||
|
{
|
||||||
|
argv[argc] = _gpgme_strconcat ("--request-origin=",
|
||||||
|
gpg->request_origin, NULL);
|
||||||
|
if (!argv[argc])
|
||||||
|
{
|
||||||
|
int saved_err = gpg_error_from_syserror ();
|
||||||
|
free (fd_data_map);
|
||||||
|
free_argv (argv);
|
||||||
|
return saved_err;
|
||||||
|
}
|
||||||
|
argc++;
|
||||||
|
}
|
||||||
|
|
||||||
if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0"))
|
if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0"))
|
||||||
{
|
{
|
||||||
const char *s = NULL;
|
const char *s = NULL;
|
||||||
@ -3090,6 +3123,7 @@ struct engine_ops _gpgme_engine_ops_gpg =
|
|||||||
gpg_set_colon_line_handler,
|
gpg_set_colon_line_handler,
|
||||||
gpg_set_locale,
|
gpg_set_locale,
|
||||||
NULL, /* set_protocol */
|
NULL, /* set_protocol */
|
||||||
|
gpg_set_engine_flags, /* set_engine_flags */
|
||||||
gpg_decrypt,
|
gpg_decrypt,
|
||||||
gpg_delete,
|
gpg_delete,
|
||||||
gpg_edit,
|
gpg_edit,
|
||||||
|
@ -1287,6 +1287,7 @@ struct engine_ops _gpgme_engine_ops_gpgconf =
|
|||||||
NULL, /* set_colon_line_handler */
|
NULL, /* set_colon_line_handler */
|
||||||
NULL, /* set_locale */
|
NULL, /* set_locale */
|
||||||
NULL, /* set_protocol */
|
NULL, /* set_protocol */
|
||||||
|
NULL, /* set_engine_flags */
|
||||||
NULL, /* decrypt */
|
NULL, /* decrypt */
|
||||||
NULL, /* delete */
|
NULL, /* delete */
|
||||||
NULL, /* edit */
|
NULL, /* edit */
|
||||||
|
@ -107,6 +107,8 @@ struct engine_gpgsm
|
|||||||
|
|
||||||
gpgme_data_t inline_data; /* Used to collect D lines. */
|
gpgme_data_t inline_data; /* Used to collect D lines. */
|
||||||
|
|
||||||
|
char request_origin[10];
|
||||||
|
|
||||||
struct gpgme_io_cbs io_cbs;
|
struct gpgme_io_cbs io_cbs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -521,6 +523,24 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Copy flags from CTX into the engine object. */
|
||||||
|
static void
|
||||||
|
gpgsm_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
|
||||||
|
{
|
||||||
|
engine_gpgsm_t gpgsm = engine;
|
||||||
|
|
||||||
|
if (ctx->request_origin)
|
||||||
|
{
|
||||||
|
if (strlen (ctx->request_origin) + 1 > sizeof gpgsm->request_origin)
|
||||||
|
strcpy (gpgsm->request_origin, "xxx"); /* Too long - force error */
|
||||||
|
else
|
||||||
|
strcpy (gpgsm->request_origin, ctx->request_origin);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*gpgsm->request_origin = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpgme_error_t
|
static gpgme_error_t
|
||||||
gpgsm_set_locale (void *engine, int category, const char *value)
|
gpgsm_set_locale (void *engine, int category, const char *value)
|
||||||
{
|
{
|
||||||
@ -1058,6 +1078,20 @@ start (engine_gpgsm_t gpgsm, const char *command)
|
|||||||
int nfds;
|
int nfds;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (*gpgsm->request_origin)
|
||||||
|
{
|
||||||
|
char *cmd;
|
||||||
|
|
||||||
|
cmd = _gpgme_strconcat ("OPTION request-origin=",
|
||||||
|
gpgsm->request_origin, NULL);
|
||||||
|
if (!cmd)
|
||||||
|
return gpg_error_from_syserror ();
|
||||||
|
err = gpgsm_assuan_simple_command (gpgsm, cmd, NULL, NULL);
|
||||||
|
free (cmd);
|
||||||
|
if (err && gpg_err_code (err) != GPG_ERR_UNKNOWN_OPTION)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* We need to know the fd used by assuan for reads. We do this by
|
/* We need to know the fd used by assuan for reads. We do this by
|
||||||
using the assumption that the first returned fd from
|
using the assumption that the first returned fd from
|
||||||
assuan_get_active_fds() is always this one. */
|
assuan_get_active_fds() is always this one. */
|
||||||
@ -2102,6 +2136,7 @@ struct engine_ops _gpgme_engine_ops_gpgsm =
|
|||||||
gpgsm_set_colon_line_handler,
|
gpgsm_set_colon_line_handler,
|
||||||
gpgsm_set_locale,
|
gpgsm_set_locale,
|
||||||
NULL, /* set_protocol */
|
NULL, /* set_protocol */
|
||||||
|
gpgsm_set_engine_flags,
|
||||||
gpgsm_decrypt,
|
gpgsm_decrypt,
|
||||||
gpgsm_delete, /* decrypt_verify */
|
gpgsm_delete, /* decrypt_verify */
|
||||||
NULL, /* edit */
|
NULL, /* edit */
|
||||||
|
@ -449,6 +449,7 @@ struct engine_ops _gpgme_engine_ops_spawn =
|
|||||||
NULL, /* set_colon_line_handler */
|
NULL, /* set_colon_line_handler */
|
||||||
NULL, /* set_locale */
|
NULL, /* set_locale */
|
||||||
NULL, /* set_protocol */
|
NULL, /* set_protocol */
|
||||||
|
NULL, /* set_engine_flags */
|
||||||
NULL, /* decrypt */
|
NULL, /* decrypt */
|
||||||
NULL, /* delete */
|
NULL, /* delete */
|
||||||
NULL, /* edit */
|
NULL, /* edit */
|
||||||
|
@ -1368,6 +1368,7 @@ struct engine_ops _gpgme_engine_ops_uiserver =
|
|||||||
uiserver_set_colon_line_handler,
|
uiserver_set_colon_line_handler,
|
||||||
uiserver_set_locale,
|
uiserver_set_locale,
|
||||||
uiserver_set_protocol,
|
uiserver_set_protocol,
|
||||||
|
NULL, /* set_engine_flags */
|
||||||
uiserver_decrypt,
|
uiserver_decrypt,
|
||||||
NULL, /* delete */
|
NULL, /* delete */
|
||||||
NULL, /* edit */
|
NULL, /* edit */
|
||||||
|
20
src/engine.c
20
src/engine.c
@ -651,6 +651,26 @@ _gpgme_engine_set_protocol (engine_t engine, gpgme_protocol_t protocol)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Pass information about the current context to the engine. The
|
||||||
|
* engine may use this context to retrieve context specific flags.
|
||||||
|
* Important: The engine is required to immediately copy the required
|
||||||
|
* flags to its own context!
|
||||||
|
*
|
||||||
|
* This function will eventually be used to reduce the number of
|
||||||
|
* explicit passed flags. */
|
||||||
|
void
|
||||||
|
_gpgme_engine_set_engine_flags (engine_t engine, gpgme_ctx_t ctx)
|
||||||
|
{
|
||||||
|
if (!engine)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!engine->ops->set_engine_flags)
|
||||||
|
return;
|
||||||
|
|
||||||
|
(*engine->ops->set_engine_flags) (engine->engine, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
_gpgme_engine_op_decrypt (engine_t engine,
|
_gpgme_engine_op_decrypt (engine_t engine,
|
||||||
gpgme_decrypt_flags_t flags,
|
gpgme_decrypt_flags_t flags,
|
||||||
|
@ -69,6 +69,7 @@ gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category,
|
|||||||
const char *value);
|
const char *value);
|
||||||
gpgme_error_t _gpgme_engine_set_protocol (engine_t engine,
|
gpgme_error_t _gpgme_engine_set_protocol (engine_t engine,
|
||||||
gpgme_protocol_t protocol);
|
gpgme_protocol_t protocol);
|
||||||
|
void _gpgme_engine_set_engine_flags (engine_t engine, gpgme_ctx_t ctx);
|
||||||
void _gpgme_engine_release (engine_t engine);
|
void _gpgme_engine_release (engine_t engine);
|
||||||
void _gpgme_engine_set_status_cb (engine_t engine,
|
void _gpgme_engine_set_status_cb (engine_t engine,
|
||||||
gpgme_status_cb_t cb, void *cb_value);
|
gpgme_status_cb_t cb, void *cb_value);
|
||||||
|
1332
src/gpgme-json.c
Normal file
1332
src/gpgme-json.c
Normal file
File diff suppressed because it is too large
Load Diff
21
src/gpgme.c
21
src/gpgme.c
@ -248,6 +248,7 @@ gpgme_release (gpgme_ctx_t ctx)
|
|||||||
free (ctx->lc_ctype);
|
free (ctx->lc_ctype);
|
||||||
free (ctx->lc_messages);
|
free (ctx->lc_messages);
|
||||||
free (ctx->override_session_key);
|
free (ctx->override_session_key);
|
||||||
|
free (ctx->request_origin);
|
||||||
_gpgme_engine_info_release (ctx->engine_info);
|
_gpgme_engine_info_release (ctx->engine_info);
|
||||||
ctx->engine_info = NULL;
|
ctx->engine_info = NULL;
|
||||||
DESTROY_LOCK (ctx->lock);
|
DESTROY_LOCK (ctx->lock);
|
||||||
@ -486,13 +487,8 @@ gpgme_get_armor (gpgme_ctx_t ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Set the flag NAME for CTX to VALUE. The supported flags are:
|
/* Set the flag NAME for CTX to VALUE. Please consult the manual for
|
||||||
*
|
* a description of the flags.
|
||||||
* - full-status :: With a value of "1" the status callback set by
|
|
||||||
* gpgme_set_status_cb returns all status lines
|
|
||||||
* except for PROGRESS lines. With the default of
|
|
||||||
* "0" the status callback is only called in certain
|
|
||||||
* situations.
|
|
||||||
*/
|
*/
|
||||||
gpgme_error_t
|
gpgme_error_t
|
||||||
gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
|
gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
|
||||||
@ -535,6 +531,13 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
|
|||||||
{
|
{
|
||||||
ctx->auto_key_retrieve = abool;
|
ctx->auto_key_retrieve = abool;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (name, "request-origin"))
|
||||||
|
{
|
||||||
|
free (ctx->request_origin);
|
||||||
|
ctx->request_origin = strdup (value);
|
||||||
|
if (!ctx->request_origin)
|
||||||
|
err = gpg_error_from_syserror ();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
err = gpg_error (GPG_ERR_UNKNOWN_NAME);
|
err = gpg_error (GPG_ERR_UNKNOWN_NAME);
|
||||||
|
|
||||||
@ -576,6 +579,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
|
|||||||
{
|
{
|
||||||
return ctx->auto_key_retrieve? "1":"";
|
return ctx->auto_key_retrieve? "1":"";
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (name, "request-origin"))
|
||||||
|
{
|
||||||
|
return ctx->request_origin? ctx->request_origin : "";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,8 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type)
|
|||||||
if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
|
if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
|
_gpgme_engine_set_engine_flags (ctx->engine, ctx);
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
{
|
{
|
||||||
err = _gpgme_engine_set_pinentry_mode (ctx->engine,
|
err = _gpgme_engine_set_pinentry_mode (ctx->engine,
|
||||||
|
@ -81,6 +81,7 @@ show_usage (int ex)
|
|||||||
" --cms use the CMS protocol\n"
|
" --cms use the CMS protocol\n"
|
||||||
" --export-session-key show the session key\n"
|
" --export-session-key show the session key\n"
|
||||||
" --override-session-key STRING use STRING as session key\n"
|
" --override-session-key STRING use STRING as session key\n"
|
||||||
|
" --request-origin STRING use STRING as request origin\n"
|
||||||
" --unwrap remove only the encryption layer\n"
|
" --unwrap remove only the encryption layer\n"
|
||||||
, stderr);
|
, stderr);
|
||||||
exit (ex);
|
exit (ex);
|
||||||
@ -102,6 +103,7 @@ main (int argc, char **argv)
|
|||||||
int print_status = 0;
|
int print_status = 0;
|
||||||
int export_session_key = 0;
|
int export_session_key = 0;
|
||||||
const char *override_session_key = NULL;
|
const char *override_session_key = NULL;
|
||||||
|
const char *request_origin = NULL;
|
||||||
int raw_output = 0;
|
int raw_output = 0;
|
||||||
|
|
||||||
if (argc)
|
if (argc)
|
||||||
@ -150,6 +152,14 @@ main (int argc, char **argv)
|
|||||||
override_session_key = *argv;
|
override_session_key = *argv;
|
||||||
argc--; argv++;
|
argc--; argv++;
|
||||||
}
|
}
|
||||||
|
else if (!strcmp (*argv, "--request-origin"))
|
||||||
|
{
|
||||||
|
argc--; argv++;
|
||||||
|
if (!argc)
|
||||||
|
show_usage (1);
|
||||||
|
request_origin = *argv;
|
||||||
|
argc--; argv++;
|
||||||
|
}
|
||||||
else if (!strcmp (*argv, "--unwrap"))
|
else if (!strcmp (*argv, "--unwrap"))
|
||||||
{
|
{
|
||||||
flags |= GPGME_DECRYPT_UNWRAP;
|
flags |= GPGME_DECRYPT_UNWRAP;
|
||||||
@ -199,7 +209,18 @@ main (int argc, char **argv)
|
|||||||
override_session_key);
|
override_session_key);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
fprintf (stderr, PGM ": error overriding session key: %s\n",
|
fprintf (stderr, PGM ": error setting overriding session key: %s\n",
|
||||||
|
gpgme_strerror (err));
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request_origin)
|
||||||
|
{
|
||||||
|
err = gpgme_set_ctx_flag (ctx, "request-origin", request_origin);
|
||||||
|
if (err)
|
||||||
|
{
|
||||||
|
fprintf (stderr, PGM ": error setting request_origin: %s\n",
|
||||||
gpgme_strerror (err));
|
gpgme_strerror (err));
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user