Fossil SCM
Add /json/settings/get and set APIs, per discussion in [forum:04b7159d63d4abe4|forum post 04b7159d63d4abe4].
Commit
a80f27485a0aab56c4ddb71c976f39fca94d9642c885783bdb31e37f119095a0
Parent
61bd0c9b113c0f0…
16 files changed
+14
-6
+2
-2
+5
-5
+219
-5
+2
-2
+1
-1
+4
-4
+1
-1
+4
-4
+1
-1
+11
-11
+9
-9
+7
-7
+13
-13
+127
+1
~
src/json.c
~
src/json_artifact.c
~
src/json_branch.c
~
src/json_config.c
~
src/json_detail.h
~
src/json_diff.c
~
src/json_dir.c
~
src/json_finfo.c
~
src/json_login.c
~
src/json_query.c
~
src/json_report.c
~
src/json_timeline.c
~
src/json_user.c
~
src/json_wiki.c
~
www/json-api/api-settings.md
~
www/json-api/index.md
+14
-6
| --- src/json.c | ||
| +++ src/json.c | ||
| @@ -288,11 +288,11 @@ | ||
| 288 | 288 | va_list vargs; |
| 289 | 289 | va_start(vargs,fmt); |
| 290 | 290 | zStr = vmprintf(fmt,vargs); |
| 291 | 291 | va_end(vargs); |
| 292 | 292 | v = cson_value_new_string(zStr, strlen(zStr)); |
| 293 | - free(zStr); | |
| 293 | + fossil_free(zStr); | |
| 294 | 294 | return v; |
| 295 | 295 | } |
| 296 | 296 | |
| 297 | 297 | cson_value * json_new_int( i64 v ){ |
| 298 | 298 | return cson_value_new_integer((cson_int_t)v); |
| @@ -630,13 +630,20 @@ | ||
| 630 | 630 | ** is not called to flush the output. |
| 631 | 631 | ** |
| 632 | 632 | ** If g.json.jsonp is not NULL then the content type is set to |
| 633 | 633 | ** text/javascript and the output is wrapped in a jsonp |
| 634 | 634 | ** wrapper. |
| 635 | +** | |
| 636 | +** This function works only the first time it is called. It "should | |
| 637 | +** not" ever be called more than once but certain calling | |
| 638 | +** constellations might trigger that, in which case the second and | |
| 639 | +** subsequent calls are no-ops. | |
| 635 | 640 | */ |
| 636 | 641 | void json_send_response( cson_value const * pResponse ){ |
| 642 | + static int once = 0; | |
| 637 | 643 | assert( NULL != pResponse ); |
| 644 | + if( once++ ) return; | |
| 638 | 645 | if( g.isHTTP ){ |
| 639 | 646 | cgi_reset_content(); |
| 640 | 647 | if( g.json.jsonp ){ |
| 641 | 648 | cgi_set_content_type("text/javascript"); |
| 642 | 649 | cgi_printf("%s(",g.json.jsonp); |
| @@ -844,11 +851,11 @@ | ||
| 844 | 851 | char * msg; |
| 845 | 852 | va_start(vargs,fmt); |
| 846 | 853 | msg = vmprintf(fmt,vargs); |
| 847 | 854 | va_end(vargs); |
| 848 | 855 | cson_object_set(obj,"text", cson_value_new_string(msg,strlen(msg))); |
| 849 | - free(msg); | |
| 856 | + fossil_free(msg); | |
| 850 | 857 | } |
| 851 | 858 | } |
| 852 | 859 | |
| 853 | 860 | /* |
| 854 | 861 | ** Splits zStr (which must not be NULL) into tokens separated by the |
| @@ -1623,11 +1630,11 @@ | ||
| 1623 | 1630 | ** |
| 1624 | 1631 | ** code must be in the inclusive range 1000..9999. |
| 1625 | 1632 | */ |
| 1626 | 1633 | int json_set_err( int code, char const * fmt, ... ){ |
| 1627 | 1634 | assert( (code>=1000) && (code<=9999) ); |
| 1628 | - free(g.zErrMsg); | |
| 1635 | + fossil_free(g.zErrMsg); | |
| 1629 | 1636 | g.json.resultCode = code; |
| 1630 | 1637 | if(!fmt || !*fmt){ |
| 1631 | 1638 | g.zErrMsg = mprintf("%s", json_err_cstr(code)); |
| 1632 | 1639 | }else{ |
| 1633 | 1640 | va_list vargs; |
| @@ -1771,11 +1778,11 @@ | ||
| 1771 | 1778 | char * tags = info_tags_of_checkin(rid, propagatingOnly); |
| 1772 | 1779 | if(tags){ |
| 1773 | 1780 | if(*tags){ |
| 1774 | 1781 | v = json_string_split2(tags,',',0); |
| 1775 | 1782 | } |
| 1776 | - free(tags); | |
| 1783 | + fossil_free(tags); | |
| 1777 | 1784 | } |
| 1778 | 1785 | return v; |
| 1779 | 1786 | } |
| 1780 | 1787 | |
| 1781 | 1788 | /* |
| @@ -2006,14 +2013,14 @@ | ||
| 2006 | 2013 | jv = cson_value_new_object(); |
| 2007 | 2014 | jo = cson_value_get_object(jv); |
| 2008 | 2015 | |
| 2009 | 2016 | zTmp = db_get("project-name",NULL); |
| 2010 | 2017 | cson_object_set(jo, "projectName", json_new_string(zTmp)); |
| 2011 | - free(zTmp); | |
| 2018 | + fossil_free(zTmp); | |
| 2012 | 2019 | zTmp = db_get("project-description",NULL); |
| 2013 | 2020 | cson_object_set(jo, "projectDescription", json_new_string(zTmp)); |
| 2014 | - free(zTmp); | |
| 2021 | + fossil_free(zTmp); | |
| 2015 | 2022 | zTmp = NULL; |
| 2016 | 2023 | fsize = file_size(g.zRepositoryName, ExtFILE); |
| 2017 | 2024 | cson_object_set(jo, "repositorySize", |
| 2018 | 2025 | cson_value_new_integer((cson_int_t)fsize)); |
| 2019 | 2026 | |
| @@ -2247,10 +2254,11 @@ | ||
| 2247 | 2254 | {"logout",json_page_logout,0}, |
| 2248 | 2255 | {"query",json_page_query,0}, |
| 2249 | 2256 | {"rebuild",json_page_rebuild,0}, |
| 2250 | 2257 | {"report", json_page_report, 0}, |
| 2251 | 2258 | {"resultCodes", json_page_resultCodes,0}, |
| 2259 | +{"settings",json_page_settings,0}, | |
| 2252 | 2260 | {"stat",json_page_stat,0}, |
| 2253 | 2261 | {"status", json_page_status, 0}, |
| 2254 | 2262 | {"tag", json_page_tag,0}, |
| 2255 | 2263 | /*{"ticket", json_page_nyi,0},*/ |
| 2256 | 2264 | {"timeline", json_page_timeline,0}, |
| 2257 | 2265 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -288,11 +288,11 @@ | |
| 288 | va_list vargs; |
| 289 | va_start(vargs,fmt); |
| 290 | zStr = vmprintf(fmt,vargs); |
| 291 | va_end(vargs); |
| 292 | v = cson_value_new_string(zStr, strlen(zStr)); |
| 293 | free(zStr); |
| 294 | return v; |
| 295 | } |
| 296 | |
| 297 | cson_value * json_new_int( i64 v ){ |
| 298 | return cson_value_new_integer((cson_int_t)v); |
| @@ -630,13 +630,20 @@ | |
| 630 | ** is not called to flush the output. |
| 631 | ** |
| 632 | ** If g.json.jsonp is not NULL then the content type is set to |
| 633 | ** text/javascript and the output is wrapped in a jsonp |
| 634 | ** wrapper. |
| 635 | */ |
| 636 | void json_send_response( cson_value const * pResponse ){ |
| 637 | assert( NULL != pResponse ); |
| 638 | if( g.isHTTP ){ |
| 639 | cgi_reset_content(); |
| 640 | if( g.json.jsonp ){ |
| 641 | cgi_set_content_type("text/javascript"); |
| 642 | cgi_printf("%s(",g.json.jsonp); |
| @@ -844,11 +851,11 @@ | |
| 844 | char * msg; |
| 845 | va_start(vargs,fmt); |
| 846 | msg = vmprintf(fmt,vargs); |
| 847 | va_end(vargs); |
| 848 | cson_object_set(obj,"text", cson_value_new_string(msg,strlen(msg))); |
| 849 | free(msg); |
| 850 | } |
| 851 | } |
| 852 | |
| 853 | /* |
| 854 | ** Splits zStr (which must not be NULL) into tokens separated by the |
| @@ -1623,11 +1630,11 @@ | |
| 1623 | ** |
| 1624 | ** code must be in the inclusive range 1000..9999. |
| 1625 | */ |
| 1626 | int json_set_err( int code, char const * fmt, ... ){ |
| 1627 | assert( (code>=1000) && (code<=9999) ); |
| 1628 | free(g.zErrMsg); |
| 1629 | g.json.resultCode = code; |
| 1630 | if(!fmt || !*fmt){ |
| 1631 | g.zErrMsg = mprintf("%s", json_err_cstr(code)); |
| 1632 | }else{ |
| 1633 | va_list vargs; |
| @@ -1771,11 +1778,11 @@ | |
| 1771 | char * tags = info_tags_of_checkin(rid, propagatingOnly); |
| 1772 | if(tags){ |
| 1773 | if(*tags){ |
| 1774 | v = json_string_split2(tags,',',0); |
| 1775 | } |
| 1776 | free(tags); |
| 1777 | } |
| 1778 | return v; |
| 1779 | } |
| 1780 | |
| 1781 | /* |
| @@ -2006,14 +2013,14 @@ | |
| 2006 | jv = cson_value_new_object(); |
| 2007 | jo = cson_value_get_object(jv); |
| 2008 | |
| 2009 | zTmp = db_get("project-name",NULL); |
| 2010 | cson_object_set(jo, "projectName", json_new_string(zTmp)); |
| 2011 | free(zTmp); |
| 2012 | zTmp = db_get("project-description",NULL); |
| 2013 | cson_object_set(jo, "projectDescription", json_new_string(zTmp)); |
| 2014 | free(zTmp); |
| 2015 | zTmp = NULL; |
| 2016 | fsize = file_size(g.zRepositoryName, ExtFILE); |
| 2017 | cson_object_set(jo, "repositorySize", |
| 2018 | cson_value_new_integer((cson_int_t)fsize)); |
| 2019 | |
| @@ -2247,10 +2254,11 @@ | |
| 2247 | {"logout",json_page_logout,0}, |
| 2248 | {"query",json_page_query,0}, |
| 2249 | {"rebuild",json_page_rebuild,0}, |
| 2250 | {"report", json_page_report, 0}, |
| 2251 | {"resultCodes", json_page_resultCodes,0}, |
| 2252 | {"stat",json_page_stat,0}, |
| 2253 | {"status", json_page_status, 0}, |
| 2254 | {"tag", json_page_tag,0}, |
| 2255 | /*{"ticket", json_page_nyi,0},*/ |
| 2256 | {"timeline", json_page_timeline,0}, |
| 2257 |
| --- src/json.c | |
| +++ src/json.c | |
| @@ -288,11 +288,11 @@ | |
| 288 | va_list vargs; |
| 289 | va_start(vargs,fmt); |
| 290 | zStr = vmprintf(fmt,vargs); |
| 291 | va_end(vargs); |
| 292 | v = cson_value_new_string(zStr, strlen(zStr)); |
| 293 | fossil_free(zStr); |
| 294 | return v; |
| 295 | } |
| 296 | |
| 297 | cson_value * json_new_int( i64 v ){ |
| 298 | return cson_value_new_integer((cson_int_t)v); |
| @@ -630,13 +630,20 @@ | |
| 630 | ** is not called to flush the output. |
| 631 | ** |
| 632 | ** If g.json.jsonp is not NULL then the content type is set to |
| 633 | ** text/javascript and the output is wrapped in a jsonp |
| 634 | ** wrapper. |
| 635 | ** |
| 636 | ** This function works only the first time it is called. It "should |
| 637 | ** not" ever be called more than once but certain calling |
| 638 | ** constellations might trigger that, in which case the second and |
| 639 | ** subsequent calls are no-ops. |
| 640 | */ |
| 641 | void json_send_response( cson_value const * pResponse ){ |
| 642 | static int once = 0; |
| 643 | assert( NULL != pResponse ); |
| 644 | if( once++ ) return; |
| 645 | if( g.isHTTP ){ |
| 646 | cgi_reset_content(); |
| 647 | if( g.json.jsonp ){ |
| 648 | cgi_set_content_type("text/javascript"); |
| 649 | cgi_printf("%s(",g.json.jsonp); |
| @@ -844,11 +851,11 @@ | |
| 851 | char * msg; |
| 852 | va_start(vargs,fmt); |
| 853 | msg = vmprintf(fmt,vargs); |
| 854 | va_end(vargs); |
| 855 | cson_object_set(obj,"text", cson_value_new_string(msg,strlen(msg))); |
| 856 | fossil_free(msg); |
| 857 | } |
| 858 | } |
| 859 | |
| 860 | /* |
| 861 | ** Splits zStr (which must not be NULL) into tokens separated by the |
| @@ -1623,11 +1630,11 @@ | |
| 1630 | ** |
| 1631 | ** code must be in the inclusive range 1000..9999. |
| 1632 | */ |
| 1633 | int json_set_err( int code, char const * fmt, ... ){ |
| 1634 | assert( (code>=1000) && (code<=9999) ); |
| 1635 | fossil_free(g.zErrMsg); |
| 1636 | g.json.resultCode = code; |
| 1637 | if(!fmt || !*fmt){ |
| 1638 | g.zErrMsg = mprintf("%s", json_err_cstr(code)); |
| 1639 | }else{ |
| 1640 | va_list vargs; |
| @@ -1771,11 +1778,11 @@ | |
| 1778 | char * tags = info_tags_of_checkin(rid, propagatingOnly); |
| 1779 | if(tags){ |
| 1780 | if(*tags){ |
| 1781 | v = json_string_split2(tags,',',0); |
| 1782 | } |
| 1783 | fossil_free(tags); |
| 1784 | } |
| 1785 | return v; |
| 1786 | } |
| 1787 | |
| 1788 | /* |
| @@ -2006,14 +2013,14 @@ | |
| 2013 | jv = cson_value_new_object(); |
| 2014 | jo = cson_value_get_object(jv); |
| 2015 | |
| 2016 | zTmp = db_get("project-name",NULL); |
| 2017 | cson_object_set(jo, "projectName", json_new_string(zTmp)); |
| 2018 | fossil_free(zTmp); |
| 2019 | zTmp = db_get("project-description",NULL); |
| 2020 | cson_object_set(jo, "projectDescription", json_new_string(zTmp)); |
| 2021 | fossil_free(zTmp); |
| 2022 | zTmp = NULL; |
| 2023 | fsize = file_size(g.zRepositoryName, ExtFILE); |
| 2024 | cson_object_set(jo, "repositorySize", |
| 2025 | cson_value_new_integer((cson_int_t)fsize)); |
| 2026 | |
| @@ -2247,10 +2254,11 @@ | |
| 2254 | {"logout",json_page_logout,0}, |
| 2255 | {"query",json_page_query,0}, |
| 2256 | {"rebuild",json_page_rebuild,0}, |
| 2257 | {"report", json_page_report, 0}, |
| 2258 | {"resultCodes", json_page_resultCodes,0}, |
| 2259 | {"settings",json_page_settings,0}, |
| 2260 | {"stat",json_page_stat,0}, |
| 2261 | {"status", json_page_status, 0}, |
| 2262 | {"tag", json_page_tag,0}, |
| 2263 | /*{"ticket", json_page_nyi,0},*/ |
| 2264 | {"timeline", json_page_timeline,0}, |
| 2265 |
+2
-2
| --- src/json_artifact.c | ||
| +++ src/json_artifact.c | ||
| @@ -246,11 +246,11 @@ | ||
| 246 | 246 | ** If the "format" (CLI: -f) flag is set function returns the same as |
| 247 | 247 | ** json_wiki_get_content_format_flag(), else it returns true (non-0) |
| 248 | 248 | ** if either the includeContent (HTTP) or -content|-c boolean flags |
| 249 | 249 | ** (CLI) are set. |
| 250 | 250 | */ |
| 251 | -static int json_artifact_get_content_format_flag(){ | |
| 251 | +static int json_artifact_get_content_format_flag(void){ | |
| 252 | 252 | enum { MagicValue = -9 }; |
| 253 | 253 | int contentFormat = json_wiki_get_content_format_flag(MagicValue); |
| 254 | 254 | if(MagicValue == contentFormat){ |
| 255 | 255 | contentFormat = json_find_option_bool("includeContent","content","c",0) /* deprecated */ ? -1 : 0; |
| 256 | 256 | } |
| @@ -398,11 +398,11 @@ | ||
| 398 | 398 | |
| 399 | 399 | /* |
| 400 | 400 | ** Impl of /json/artifact. This basically just determines the type of |
| 401 | 401 | ** an artifact and forwards the real work to another function. |
| 402 | 402 | */ |
| 403 | -cson_value * json_page_artifact(){ | |
| 403 | +cson_value * json_page_artifact(void){ | |
| 404 | 404 | cson_object * pay = NULL; |
| 405 | 405 | char const * zName = NULL; |
| 406 | 406 | char const * zType = NULL; |
| 407 | 407 | char const * zUuid = NULL; |
| 408 | 408 | cson_value * entry = NULL; |
| 409 | 409 |
| --- src/json_artifact.c | |
| +++ src/json_artifact.c | |
| @@ -246,11 +246,11 @@ | |
| 246 | ** If the "format" (CLI: -f) flag is set function returns the same as |
| 247 | ** json_wiki_get_content_format_flag(), else it returns true (non-0) |
| 248 | ** if either the includeContent (HTTP) or -content|-c boolean flags |
| 249 | ** (CLI) are set. |
| 250 | */ |
| 251 | static int json_artifact_get_content_format_flag(){ |
| 252 | enum { MagicValue = -9 }; |
| 253 | int contentFormat = json_wiki_get_content_format_flag(MagicValue); |
| 254 | if(MagicValue == contentFormat){ |
| 255 | contentFormat = json_find_option_bool("includeContent","content","c",0) /* deprecated */ ? -1 : 0; |
| 256 | } |
| @@ -398,11 +398,11 @@ | |
| 398 | |
| 399 | /* |
| 400 | ** Impl of /json/artifact. This basically just determines the type of |
| 401 | ** an artifact and forwards the real work to another function. |
| 402 | */ |
| 403 | cson_value * json_page_artifact(){ |
| 404 | cson_object * pay = NULL; |
| 405 | char const * zName = NULL; |
| 406 | char const * zType = NULL; |
| 407 | char const * zUuid = NULL; |
| 408 | cson_value * entry = NULL; |
| 409 |
| --- src/json_artifact.c | |
| +++ src/json_artifact.c | |
| @@ -246,11 +246,11 @@ | |
| 246 | ** If the "format" (CLI: -f) flag is set function returns the same as |
| 247 | ** json_wiki_get_content_format_flag(), else it returns true (non-0) |
| 248 | ** if either the includeContent (HTTP) or -content|-c boolean flags |
| 249 | ** (CLI) are set. |
| 250 | */ |
| 251 | static int json_artifact_get_content_format_flag(void){ |
| 252 | enum { MagicValue = -9 }; |
| 253 | int contentFormat = json_wiki_get_content_format_flag(MagicValue); |
| 254 | if(MagicValue == contentFormat){ |
| 255 | contentFormat = json_find_option_bool("includeContent","content","c",0) /* deprecated */ ? -1 : 0; |
| 256 | } |
| @@ -398,11 +398,11 @@ | |
| 398 | |
| 399 | /* |
| 400 | ** Impl of /json/artifact. This basically just determines the type of |
| 401 | ** an artifact and forwards the real work to another function. |
| 402 | */ |
| 403 | cson_value * json_page_artifact(void){ |
| 404 | cson_object * pay = NULL; |
| 405 | char const * zName = NULL; |
| 406 | char const * zType = NULL; |
| 407 | char const * zUuid = NULL; |
| 408 | cson_value * entry = NULL; |
| 409 |
+5
-5
| --- src/json_branch.c | ||
| +++ src/json_branch.c | ||
| @@ -22,12 +22,12 @@ | ||
| 22 | 22 | #if INTERFACE |
| 23 | 23 | #include "json_detail.h" |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | 26 | |
| 27 | -static cson_value * json_branch_list(); | |
| 28 | -static cson_value * json_branch_create(); | |
| 27 | +static cson_value * json_branch_list(void); | |
| 28 | +static cson_value * json_branch_create(void); | |
| 29 | 29 | /* |
| 30 | 30 | ** Mapping of /json/branch/XXX commands/paths to callbacks. |
| 31 | 31 | */ |
| 32 | 32 | static const JsonPageDef JsonPageDefs_Branch[] = { |
| 33 | 33 | {"create", json_branch_create, 0}, |
| @@ -40,11 +40,11 @@ | ||
| 40 | 40 | /* |
| 41 | 41 | ** Implements the /json/branch family of pages/commands. Far from |
| 42 | 42 | ** complete. |
| 43 | 43 | ** |
| 44 | 44 | */ |
| 45 | -cson_value * json_page_branch(){ | |
| 45 | +cson_value * json_page_branch(void){ | |
| 46 | 46 | return json_page_dispatch_helper(&JsonPageDefs_Branch[0]); |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | 49 | /* |
| 50 | 50 | ** Impl for /json/branch/list |
| @@ -60,11 +60,11 @@ | ||
| 60 | 60 | ** HTTP mode options: |
| 61 | 61 | ** |
| 62 | 62 | ** "range" GET/POST.payload parameter. FIXME: currently we also use |
| 63 | 63 | ** POST, but really want to restrict this to POST.payload. |
| 64 | 64 | */ |
| 65 | -static cson_value * json_branch_list(){ | |
| 65 | +static cson_value * json_branch_list(void){ | |
| 66 | 66 | cson_value * payV; |
| 67 | 67 | cson_object * pay; |
| 68 | 68 | cson_value * listV; |
| 69 | 69 | cson_array * list; |
| 70 | 70 | char const * range = NULL; |
| @@ -313,11 +313,11 @@ | ||
| 313 | 313 | |
| 314 | 314 | |
| 315 | 315 | /* |
| 316 | 316 | ** Impl of /json/branch/create. |
| 317 | 317 | */ |
| 318 | -static cson_value * json_branch_create(){ | |
| 318 | +static cson_value * json_branch_create(void){ | |
| 319 | 319 | cson_value * payV = NULL; |
| 320 | 320 | cson_object * pay = NULL; |
| 321 | 321 | int rc = 0; |
| 322 | 322 | BranchCreateOptions opt; |
| 323 | 323 | char * zUuid = NULL; |
| 324 | 324 |
| --- src/json_branch.c | |
| +++ src/json_branch.c | |
| @@ -22,12 +22,12 @@ | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | |
| 27 | static cson_value * json_branch_list(); |
| 28 | static cson_value * json_branch_create(); |
| 29 | /* |
| 30 | ** Mapping of /json/branch/XXX commands/paths to callbacks. |
| 31 | */ |
| 32 | static const JsonPageDef JsonPageDefs_Branch[] = { |
| 33 | {"create", json_branch_create, 0}, |
| @@ -40,11 +40,11 @@ | |
| 40 | /* |
| 41 | ** Implements the /json/branch family of pages/commands. Far from |
| 42 | ** complete. |
| 43 | ** |
| 44 | */ |
| 45 | cson_value * json_page_branch(){ |
| 46 | return json_page_dispatch_helper(&JsonPageDefs_Branch[0]); |
| 47 | } |
| 48 | |
| 49 | /* |
| 50 | ** Impl for /json/branch/list |
| @@ -60,11 +60,11 @@ | |
| 60 | ** HTTP mode options: |
| 61 | ** |
| 62 | ** "range" GET/POST.payload parameter. FIXME: currently we also use |
| 63 | ** POST, but really want to restrict this to POST.payload. |
| 64 | */ |
| 65 | static cson_value * json_branch_list(){ |
| 66 | cson_value * payV; |
| 67 | cson_object * pay; |
| 68 | cson_value * listV; |
| 69 | cson_array * list; |
| 70 | char const * range = NULL; |
| @@ -313,11 +313,11 @@ | |
| 313 | |
| 314 | |
| 315 | /* |
| 316 | ** Impl of /json/branch/create. |
| 317 | */ |
| 318 | static cson_value * json_branch_create(){ |
| 319 | cson_value * payV = NULL; |
| 320 | cson_object * pay = NULL; |
| 321 | int rc = 0; |
| 322 | BranchCreateOptions opt; |
| 323 | char * zUuid = NULL; |
| 324 |
| --- src/json_branch.c | |
| +++ src/json_branch.c | |
| @@ -22,12 +22,12 @@ | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | |
| 27 | static cson_value * json_branch_list(void); |
| 28 | static cson_value * json_branch_create(void); |
| 29 | /* |
| 30 | ** Mapping of /json/branch/XXX commands/paths to callbacks. |
| 31 | */ |
| 32 | static const JsonPageDef JsonPageDefs_Branch[] = { |
| 33 | {"create", json_branch_create, 0}, |
| @@ -40,11 +40,11 @@ | |
| 40 | /* |
| 41 | ** Implements the /json/branch family of pages/commands. Far from |
| 42 | ** complete. |
| 43 | ** |
| 44 | */ |
| 45 | cson_value * json_page_branch(void){ |
| 46 | return json_page_dispatch_helper(&JsonPageDefs_Branch[0]); |
| 47 | } |
| 48 | |
| 49 | /* |
| 50 | ** Impl for /json/branch/list |
| @@ -60,11 +60,11 @@ | |
| 60 | ** HTTP mode options: |
| 61 | ** |
| 62 | ** "range" GET/POST.payload parameter. FIXME: currently we also use |
| 63 | ** POST, but really want to restrict this to POST.payload. |
| 64 | */ |
| 65 | static cson_value * json_branch_list(void){ |
| 66 | cson_value * payV; |
| 67 | cson_object * pay; |
| 68 | cson_value * listV; |
| 69 | cson_array * list; |
| 70 | char const * range = NULL; |
| @@ -313,11 +313,11 @@ | |
| 313 | |
| 314 | |
| 315 | /* |
| 316 | ** Impl of /json/branch/create. |
| 317 | */ |
| 318 | static cson_value * json_branch_create(void){ |
| 319 | cson_value * payV = NULL; |
| 320 | cson_object * pay = NULL; |
| 321 | int rc = 0; |
| 322 | BranchCreateOptions opt; |
| 323 | char * zUuid = NULL; |
| 324 |
+219
-5
| --- src/json_config.c | ||
| +++ src/json_config.c | ||
| @@ -21,12 +21,12 @@ | ||
| 21 | 21 | |
| 22 | 22 | #if INTERFACE |
| 23 | 23 | #include "json_detail.h" |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | -static cson_value * json_config_get(); | |
| 27 | -static cson_value * json_config_save(); | |
| 26 | +static cson_value * json_config_get(void); | |
| 27 | +static cson_value * json_config_save(void); | |
| 28 | 28 | |
| 29 | 29 | /* |
| 30 | 30 | ** Mapping of /json/config/XXX commands/paths to callbacks. |
| 31 | 31 | */ |
| 32 | 32 | static const JsonPageDef JsonPageDefs_Config[] = { |
| @@ -34,18 +34,38 @@ | ||
| 34 | 34 | {"save", json_config_save, 0}, |
| 35 | 35 | /* Last entry MUST have a NULL name. */ |
| 36 | 36 | {NULL,NULL,0} |
| 37 | 37 | }; |
| 38 | 38 | |
| 39 | +static cson_value * json_settings_get(void); | |
| 40 | +static cson_value * json_settings_set(void); | |
| 41 | +/* | |
| 42 | +** Mapping of /json/settings/XXX commands/paths to callbacks. | |
| 43 | +*/ | |
| 44 | +static const JsonPageDef JsonPageDefs_Settings[] = { | |
| 45 | +{"get", json_settings_get, 0}, | |
| 46 | +{"set", json_settings_set, 0}, | |
| 47 | +/* Last entry MUST have a NULL name. */ | |
| 48 | +{NULL,NULL,0} | |
| 49 | +}; | |
| 50 | + | |
| 39 | 51 | |
| 40 | 52 | /* |
| 41 | 53 | ** Implements the /json/config family of pages/commands. |
| 42 | 54 | ** |
| 43 | 55 | */ |
| 44 | -cson_value * json_page_config(){ | |
| 56 | +cson_value * json_page_config(void){ | |
| 45 | 57 | return json_page_dispatch_helper(&JsonPageDefs_Config[0]); |
| 46 | 58 | } |
| 59 | + | |
| 60 | +/* | |
| 61 | +** Implements the /json/settings family of pages/commands. | |
| 62 | +** | |
| 63 | +*/ | |
| 64 | +cson_value * json_page_settings(void){ | |
| 65 | + return json_page_dispatch_helper(&JsonPageDefs_Settings[0]); | |
| 66 | +} | |
| 47 | 67 | |
| 48 | 68 | |
| 49 | 69 | /* |
| 50 | 70 | ** JSON-internal mapping of config options to config groups. This is |
| 51 | 71 | ** mostly a copy of the config options in configure.c, but that data |
| @@ -105,11 +125,11 @@ | ||
| 105 | 125 | |
| 106 | 126 | /* |
| 107 | 127 | ** Impl of /json/config/get. Requires setup rights. |
| 108 | 128 | ** |
| 109 | 129 | */ |
| 110 | -static cson_value * json_config_get(){ | |
| 130 | +static cson_value * json_config_get(void){ | |
| 111 | 131 | cson_object * pay = NULL; |
| 112 | 132 | Stmt q = empty_Stmt; |
| 113 | 133 | Blob sql = empty_blob; |
| 114 | 134 | char const * zName = NULL; |
| 115 | 135 | int confMask = 0; |
| @@ -181,10 +201,204 @@ | ||
| 181 | 201 | /* |
| 182 | 202 | ** Impl of /json/config/save. |
| 183 | 203 | ** |
| 184 | 204 | ** TODOs: |
| 185 | 205 | */ |
| 186 | -static cson_value * json_config_save(){ | |
| 206 | +static cson_value * json_config_save(void){ | |
| 187 | 207 | json_set_err(FSL_JSON_E_NYI, NULL); |
| 188 | 208 | return NULL; |
| 189 | 209 | } |
| 210 | + | |
| 211 | +/* | |
| 212 | +** Impl of /json/settings/get. | |
| 213 | +*/ | |
| 214 | +static cson_value * json_settings_get(void){ | |
| 215 | + cson_object * pay = cson_new_object(); /* output payload */ | |
| 216 | + int nSetting, i; /* setting count and loop var */ | |
| 217 | + const Setting *aSetting = setting_info(&nSetting); | |
| 218 | + const char * zRevision = 0; /* revision to look for | |
| 219 | + versioned settings in */ | |
| 220 | + char * zUuid = 0; /* Resolved UUID of zRevision */ | |
| 221 | + Stmt q = empty_Stmt; /* Config-search query */ | |
| 222 | + Stmt qFoci = empty_Stmt; /* foci query */ | |
| 223 | + | |
| 224 | + if( !g.perm.Read ){ | |
| 225 | + json_set_err( FSL_JSON_E_DENIED, "Fetching settings requires 'o' access." ); | |
| 226 | + return NULL; | |
| 227 | + } | |
| 228 | + zRevision = json_find_option_cstr("version",NULL,NULL); | |
| 229 | + if( 0!=zRevision ){ | |
| 230 | + int rid = name_to_uuid2(zRevision, "ci", &zUuid); | |
| 231 | + if(rid<=0){ | |
| 232 | + json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND, | |
| 233 | + "Cannot find the given version."); | |
| 234 | + return NULL; | |
| 235 | + } | |
| 236 | + db_multi_exec("CREATE VIRTUAL TABLE IF NOT EXISTS " | |
| 237 | + "temp.foci USING files_of_checkin;"); | |
| 238 | + db_prepare(&qFoci, | |
| 239 | + "SELECT uuid FROM temp.foci WHERE " | |
| 240 | + "checkinID=%d AND filename='.fossil-settings/' || :name", | |
| 241 | + rid); | |
| 242 | + } | |
| 243 | + zRevision = 0; | |
| 244 | + | |
| 245 | + if( g.localOpen ){ | |
| 246 | + db_prepare(&q, | |
| 247 | + "SELECT 'checkout', value FROM vvar WHERE name=:name" | |
| 248 | + " UNION ALL " | |
| 249 | + "SELECT 'repo', value FROM config WHERE name=:name" | |
| 250 | + ); | |
| 251 | + }else{ | |
| 252 | + db_prepare(&q, | |
| 253 | + "SELECT 'repo', value FROM config WHERE name=:name" | |
| 254 | + ); | |
| 255 | + } | |
| 256 | + for(i=0; i<nSetting; ++i){ | |
| 257 | + const Setting *pSet = &aSetting[i]; | |
| 258 | + cson_object * jSet; | |
| 259 | + cson_value * pVal = 0, * pSrc = 0; | |
| 260 | + jSet = cson_new_object(); | |
| 261 | + cson_object_set(pay, pSet->name, cson_object_value(jSet)); | |
| 262 | + cson_object_set(jSet, "versionable", cson_value_new_bool(pSet->versionable)); | |
| 263 | + cson_object_set(jSet, "sensitive", cson_value_new_bool(pSet->sensitive)); | |
| 264 | + cson_object_set(jSet, "defaultValue", (pSet->def && pSet->def[0]) | |
| 265 | + ? json_new_string(pSet->def) | |
| 266 | + : cson_value_null()); | |
| 267 | + if( 0==pSet->sensitive || 0!=g.perm.Setup ){ | |
| 268 | + if( pSet->versionable ){ | |
| 269 | + /* Check to see if this is overridden by a versionable | |
| 270 | + ** settings file */ | |
| 271 | + if( 0!=zUuid ){ | |
| 272 | + /* Attempt to find a versioned setting stored in the given | |
| 273 | + ** check-in version. */ | |
| 274 | + db_bind_text(&qFoci, ":name", pSet->name); | |
| 275 | + if( SQLITE_ROW==db_step(&qFoci) ){ | |
| 276 | + int frid = fast_uuid_to_rid(db_column_text(&qFoci, 0)); | |
| 277 | + Blob content; | |
| 278 | + blob_zero(&content); | |
| 279 | + if( 0!=content_get(frid, &content) ){ | |
| 280 | + pSrc = json_new_string("versioned"); | |
| 281 | + pVal = json_new_string(blob_str(&content)); | |
| 282 | + } | |
| 283 | + blob_reset(&content); | |
| 284 | + } | |
| 285 | + db_reset(&qFoci); | |
| 286 | + } | |
| 287 | + if( 0==pSrc && g.localOpen ){ | |
| 288 | + /* Pull value from a checkout-local .fossil-settings/X file, | |
| 289 | + ** if one exists. */ | |
| 290 | + Blob versionedPathname; | |
| 291 | + blob_zero(&versionedPathname); | |
| 292 | + blob_appendf(&versionedPathname, "%s.fossil-settings/%s", | |
| 293 | + g.zLocalRoot, pSet->name); | |
| 294 | + if( file_size(blob_str(&versionedPathname), ExtFILE)>=0 ){ | |
| 295 | + Blob content; | |
| 296 | + blob_zero(&content); | |
| 297 | + blob_read_from_file(&content, blob_str(&versionedPathname), ExtFILE); | |
| 298 | + pSrc = json_new_string("versioned"); | |
| 299 | + pVal = json_new_string(blob_str(&content)); | |
| 300 | + blob_reset(&content); | |
| 301 | + } | |
| 302 | + blob_reset(&versionedPathname); | |
| 303 | + } | |
| 304 | + } | |
| 305 | + if( 0==pSrc ){ | |
| 306 | + /* Setting is not versionable or we had no versioned value, so | |
| 307 | + ** use the value from localdb.vvar or repository.config (in | |
| 308 | + ** that order). */ | |
| 309 | + db_bind_text(&q, ":name", pSet->name); | |
| 310 | + if( SQLITE_ROW==db_step(&q) ){ | |
| 311 | + pSrc = json_new_string(db_column_text(&q, 0)); | |
| 312 | + pVal = json_new_string(db_column_text(&q, 1)); | |
| 313 | + } | |
| 314 | + db_reset(&q); | |
| 315 | + } | |
| 316 | + } | |
| 317 | + cson_object_set(jSet, "valueSource", pSrc ? pSrc : cson_value_null()); | |
| 318 | + cson_object_set(jSet, "value", pVal ? pVal : cson_value_null()); | |
| 319 | + }/*aSetting loop*/ | |
| 320 | + db_finalize(&q); | |
| 321 | + db_finalize(&qFoci); | |
| 322 | + fossil_free(zUuid); | |
| 323 | + return cson_object_value(pay); | |
| 324 | +} | |
| 325 | + | |
| 326 | +/* | |
| 327 | +** Impl of /json/settings/set. | |
| 328 | +** | |
| 329 | +** Input payload is an object mapping setting names to values. All | |
| 330 | +** values are set in the repository.config table. It has no response | |
| 331 | +** payload. | |
| 332 | +*/ | |
| 333 | +static cson_value * json_settings_set(void){ | |
| 334 | + Stmt q = empty_Stmt; /* Config-set query */ | |
| 335 | + cson_object_iterator objIter = cson_object_iterator_empty; | |
| 336 | + cson_kvp * pKvp; | |
| 337 | + int nErr = 0, nProp = 0; | |
| 338 | + | |
| 339 | + if( 0==g.perm.Setup ){ | |
| 340 | + json_set_err( FSL_JSON_E_DENIED, "Setting settings requires 's' access." ); | |
| 341 | + return NULL; | |
| 342 | + } | |
| 343 | + else if( 0==g.json.reqPayload.o ){ | |
| 344 | + json_set_err(FSL_JSON_E_MISSING_ARGS, | |
| 345 | + "Missing payload of setting-to-value mappings."); | |
| 346 | + return NULL; | |
| 347 | + } | |
| 348 | + | |
| 349 | + db_unprotect(PROTECT_CONFIG); | |
| 350 | + db_prepare(&q, | |
| 351 | + "INSERT OR REPLACE INTO config (name, value, mtime) " | |
| 352 | + "VALUES(:name, :value, CAST(strftime('%%s') AS INT))" | |
| 353 | + ); | |
| 354 | + db_begin_transaction(); | |
| 355 | + cson_object_iter_init( g.json.reqPayload.o, &objIter ); | |
| 356 | + while( (pKvp = cson_object_iter_next(&objIter)) ){ | |
| 357 | + char const * zKey = cson_string_cstr( cson_kvp_key(pKvp) ); | |
| 358 | + cson_value * pVal; | |
| 359 | + const Setting *pSetting = db_find_setting( zKey, 0 ); | |
| 360 | + if( 0==pSetting ){ | |
| 361 | + nErr = json_set_err(FSL_JSON_E_INVALID_ARGS, | |
| 362 | + "Unknown setting: %s", zKey); | |
| 363 | + break; | |
| 364 | + } | |
| 365 | + pVal = cson_kvp_value(pKvp); | |
| 366 | + switch( cson_value_type_id(pVal) ){ | |
| 367 | + case CSON_TYPE_NULL: | |
| 368 | + db_multi_exec("DELETE FROM config WHERE name=%Q", pSetting->name); | |
| 369 | + continue; | |
| 370 | + case CSON_TYPE_BOOL: | |
| 371 | + db_bind_int(&q, ":value", cson_value_get_bool(pVal) ? 1 : 0); | |
| 372 | + break; | |
| 373 | + case CSON_TYPE_INTEGER: | |
| 374 | + db_bind_int64(&q, ":value", cson_value_get_integer(pVal)); | |
| 375 | + break; | |
| 376 | + case CSON_TYPE_DOUBLE: | |
| 377 | + db_bind_double(&q, ":value", cson_value_get_double(pVal)); | |
| 378 | + break; | |
| 379 | + case CSON_TYPE_STRING: | |
| 380 | + db_bind_text(&q, ":value", cson_value_get_cstr(pVal)); | |
| 381 | + break; | |
| 382 | + default: | |
| 383 | + nErr = json_set_err(FSL_JSON_E_USAGE, | |
| 384 | + "Invalid value type for setting '%s'.", | |
| 385 | + pSetting->name); | |
| 386 | + break; | |
| 387 | + } | |
| 388 | + if( 0!=nErr ) break; | |
| 389 | + db_bind_text(&q, ":name", zKey); | |
| 390 | + db_step(&q); | |
| 391 | + db_reset(&q); | |
| 392 | + ++nProp; | |
| 393 | + } | |
| 394 | + db_finalize(&q); | |
| 395 | + if( 0==nErr && 0==nProp ){ | |
| 396 | + nErr = json_set_err(FSL_JSON_E_INVALID_ARGS, | |
| 397 | + "Payload contains no settings to set."); | |
| 398 | + } | |
| 399 | + db_end_transaction(nErr); | |
| 400 | + db_protect_pop(); | |
| 401 | + return NULL; | |
| 402 | +} | |
| 403 | + | |
| 190 | 404 | #endif /* FOSSIL_ENABLE_JSON */ |
| 191 | 405 |
| --- src/json_config.c | |
| +++ src/json_config.c | |
| @@ -21,12 +21,12 @@ | |
| 21 | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | static cson_value * json_config_get(); |
| 27 | static cson_value * json_config_save(); |
| 28 | |
| 29 | /* |
| 30 | ** Mapping of /json/config/XXX commands/paths to callbacks. |
| 31 | */ |
| 32 | static const JsonPageDef JsonPageDefs_Config[] = { |
| @@ -34,18 +34,38 @@ | |
| 34 | {"save", json_config_save, 0}, |
| 35 | /* Last entry MUST have a NULL name. */ |
| 36 | {NULL,NULL,0} |
| 37 | }; |
| 38 | |
| 39 | |
| 40 | /* |
| 41 | ** Implements the /json/config family of pages/commands. |
| 42 | ** |
| 43 | */ |
| 44 | cson_value * json_page_config(){ |
| 45 | return json_page_dispatch_helper(&JsonPageDefs_Config[0]); |
| 46 | } |
| 47 | |
| 48 | |
| 49 | /* |
| 50 | ** JSON-internal mapping of config options to config groups. This is |
| 51 | ** mostly a copy of the config options in configure.c, but that data |
| @@ -105,11 +125,11 @@ | |
| 105 | |
| 106 | /* |
| 107 | ** Impl of /json/config/get. Requires setup rights. |
| 108 | ** |
| 109 | */ |
| 110 | static cson_value * json_config_get(){ |
| 111 | cson_object * pay = NULL; |
| 112 | Stmt q = empty_Stmt; |
| 113 | Blob sql = empty_blob; |
| 114 | char const * zName = NULL; |
| 115 | int confMask = 0; |
| @@ -181,10 +201,204 @@ | |
| 181 | /* |
| 182 | ** Impl of /json/config/save. |
| 183 | ** |
| 184 | ** TODOs: |
| 185 | */ |
| 186 | static cson_value * json_config_save(){ |
| 187 | json_set_err(FSL_JSON_E_NYI, NULL); |
| 188 | return NULL; |
| 189 | } |
| 190 | #endif /* FOSSIL_ENABLE_JSON */ |
| 191 |
| --- src/json_config.c | |
| +++ src/json_config.c | |
| @@ -21,12 +21,12 @@ | |
| 21 | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | static cson_value * json_config_get(void); |
| 27 | static cson_value * json_config_save(void); |
| 28 | |
| 29 | /* |
| 30 | ** Mapping of /json/config/XXX commands/paths to callbacks. |
| 31 | */ |
| 32 | static const JsonPageDef JsonPageDefs_Config[] = { |
| @@ -34,18 +34,38 @@ | |
| 34 | {"save", json_config_save, 0}, |
| 35 | /* Last entry MUST have a NULL name. */ |
| 36 | {NULL,NULL,0} |
| 37 | }; |
| 38 | |
| 39 | static cson_value * json_settings_get(void); |
| 40 | static cson_value * json_settings_set(void); |
| 41 | /* |
| 42 | ** Mapping of /json/settings/XXX commands/paths to callbacks. |
| 43 | */ |
| 44 | static const JsonPageDef JsonPageDefs_Settings[] = { |
| 45 | {"get", json_settings_get, 0}, |
| 46 | {"set", json_settings_set, 0}, |
| 47 | /* Last entry MUST have a NULL name. */ |
| 48 | {NULL,NULL,0} |
| 49 | }; |
| 50 | |
| 51 | |
| 52 | /* |
| 53 | ** Implements the /json/config family of pages/commands. |
| 54 | ** |
| 55 | */ |
| 56 | cson_value * json_page_config(void){ |
| 57 | return json_page_dispatch_helper(&JsonPageDefs_Config[0]); |
| 58 | } |
| 59 | |
| 60 | /* |
| 61 | ** Implements the /json/settings family of pages/commands. |
| 62 | ** |
| 63 | */ |
| 64 | cson_value * json_page_settings(void){ |
| 65 | return json_page_dispatch_helper(&JsonPageDefs_Settings[0]); |
| 66 | } |
| 67 | |
| 68 | |
| 69 | /* |
| 70 | ** JSON-internal mapping of config options to config groups. This is |
| 71 | ** mostly a copy of the config options in configure.c, but that data |
| @@ -105,11 +125,11 @@ | |
| 125 | |
| 126 | /* |
| 127 | ** Impl of /json/config/get. Requires setup rights. |
| 128 | ** |
| 129 | */ |
| 130 | static cson_value * json_config_get(void){ |
| 131 | cson_object * pay = NULL; |
| 132 | Stmt q = empty_Stmt; |
| 133 | Blob sql = empty_blob; |
| 134 | char const * zName = NULL; |
| 135 | int confMask = 0; |
| @@ -181,10 +201,204 @@ | |
| 201 | /* |
| 202 | ** Impl of /json/config/save. |
| 203 | ** |
| 204 | ** TODOs: |
| 205 | */ |
| 206 | static cson_value * json_config_save(void){ |
| 207 | json_set_err(FSL_JSON_E_NYI, NULL); |
| 208 | return NULL; |
| 209 | } |
| 210 | |
| 211 | /* |
| 212 | ** Impl of /json/settings/get. |
| 213 | */ |
| 214 | static cson_value * json_settings_get(void){ |
| 215 | cson_object * pay = cson_new_object(); /* output payload */ |
| 216 | int nSetting, i; /* setting count and loop var */ |
| 217 | const Setting *aSetting = setting_info(&nSetting); |
| 218 | const char * zRevision = 0; /* revision to look for |
| 219 | versioned settings in */ |
| 220 | char * zUuid = 0; /* Resolved UUID of zRevision */ |
| 221 | Stmt q = empty_Stmt; /* Config-search query */ |
| 222 | Stmt qFoci = empty_Stmt; /* foci query */ |
| 223 | |
| 224 | if( !g.perm.Read ){ |
| 225 | json_set_err( FSL_JSON_E_DENIED, "Fetching settings requires 'o' access." ); |
| 226 | return NULL; |
| 227 | } |
| 228 | zRevision = json_find_option_cstr("version",NULL,NULL); |
| 229 | if( 0!=zRevision ){ |
| 230 | int rid = name_to_uuid2(zRevision, "ci", &zUuid); |
| 231 | if(rid<=0){ |
| 232 | json_set_err(FSL_JSON_E_RESOURCE_NOT_FOUND, |
| 233 | "Cannot find the given version."); |
| 234 | return NULL; |
| 235 | } |
| 236 | db_multi_exec("CREATE VIRTUAL TABLE IF NOT EXISTS " |
| 237 | "temp.foci USING files_of_checkin;"); |
| 238 | db_prepare(&qFoci, |
| 239 | "SELECT uuid FROM temp.foci WHERE " |
| 240 | "checkinID=%d AND filename='.fossil-settings/' || :name", |
| 241 | rid); |
| 242 | } |
| 243 | zRevision = 0; |
| 244 | |
| 245 | if( g.localOpen ){ |
| 246 | db_prepare(&q, |
| 247 | "SELECT 'checkout', value FROM vvar WHERE name=:name" |
| 248 | " UNION ALL " |
| 249 | "SELECT 'repo', value FROM config WHERE name=:name" |
| 250 | ); |
| 251 | }else{ |
| 252 | db_prepare(&q, |
| 253 | "SELECT 'repo', value FROM config WHERE name=:name" |
| 254 | ); |
| 255 | } |
| 256 | for(i=0; i<nSetting; ++i){ |
| 257 | const Setting *pSet = &aSetting[i]; |
| 258 | cson_object * jSet; |
| 259 | cson_value * pVal = 0, * pSrc = 0; |
| 260 | jSet = cson_new_object(); |
| 261 | cson_object_set(pay, pSet->name, cson_object_value(jSet)); |
| 262 | cson_object_set(jSet, "versionable", cson_value_new_bool(pSet->versionable)); |
| 263 | cson_object_set(jSet, "sensitive", cson_value_new_bool(pSet->sensitive)); |
| 264 | cson_object_set(jSet, "defaultValue", (pSet->def && pSet->def[0]) |
| 265 | ? json_new_string(pSet->def) |
| 266 | : cson_value_null()); |
| 267 | if( 0==pSet->sensitive || 0!=g.perm.Setup ){ |
| 268 | if( pSet->versionable ){ |
| 269 | /* Check to see if this is overridden by a versionable |
| 270 | ** settings file */ |
| 271 | if( 0!=zUuid ){ |
| 272 | /* Attempt to find a versioned setting stored in the given |
| 273 | ** check-in version. */ |
| 274 | db_bind_text(&qFoci, ":name", pSet->name); |
| 275 | if( SQLITE_ROW==db_step(&qFoci) ){ |
| 276 | int frid = fast_uuid_to_rid(db_column_text(&qFoci, 0)); |
| 277 | Blob content; |
| 278 | blob_zero(&content); |
| 279 | if( 0!=content_get(frid, &content) ){ |
| 280 | pSrc = json_new_string("versioned"); |
| 281 | pVal = json_new_string(blob_str(&content)); |
| 282 | } |
| 283 | blob_reset(&content); |
| 284 | } |
| 285 | db_reset(&qFoci); |
| 286 | } |
| 287 | if( 0==pSrc && g.localOpen ){ |
| 288 | /* Pull value from a checkout-local .fossil-settings/X file, |
| 289 | ** if one exists. */ |
| 290 | Blob versionedPathname; |
| 291 | blob_zero(&versionedPathname); |
| 292 | blob_appendf(&versionedPathname, "%s.fossil-settings/%s", |
| 293 | g.zLocalRoot, pSet->name); |
| 294 | if( file_size(blob_str(&versionedPathname), ExtFILE)>=0 ){ |
| 295 | Blob content; |
| 296 | blob_zero(&content); |
| 297 | blob_read_from_file(&content, blob_str(&versionedPathname), ExtFILE); |
| 298 | pSrc = json_new_string("versioned"); |
| 299 | pVal = json_new_string(blob_str(&content)); |
| 300 | blob_reset(&content); |
| 301 | } |
| 302 | blob_reset(&versionedPathname); |
| 303 | } |
| 304 | } |
| 305 | if( 0==pSrc ){ |
| 306 | /* Setting is not versionable or we had no versioned value, so |
| 307 | ** use the value from localdb.vvar or repository.config (in |
| 308 | ** that order). */ |
| 309 | db_bind_text(&q, ":name", pSet->name); |
| 310 | if( SQLITE_ROW==db_step(&q) ){ |
| 311 | pSrc = json_new_string(db_column_text(&q, 0)); |
| 312 | pVal = json_new_string(db_column_text(&q, 1)); |
| 313 | } |
| 314 | db_reset(&q); |
| 315 | } |
| 316 | } |
| 317 | cson_object_set(jSet, "valueSource", pSrc ? pSrc : cson_value_null()); |
| 318 | cson_object_set(jSet, "value", pVal ? pVal : cson_value_null()); |
| 319 | }/*aSetting loop*/ |
| 320 | db_finalize(&q); |
| 321 | db_finalize(&qFoci); |
| 322 | fossil_free(zUuid); |
| 323 | return cson_object_value(pay); |
| 324 | } |
| 325 | |
| 326 | /* |
| 327 | ** Impl of /json/settings/set. |
| 328 | ** |
| 329 | ** Input payload is an object mapping setting names to values. All |
| 330 | ** values are set in the repository.config table. It has no response |
| 331 | ** payload. |
| 332 | */ |
| 333 | static cson_value * json_settings_set(void){ |
| 334 | Stmt q = empty_Stmt; /* Config-set query */ |
| 335 | cson_object_iterator objIter = cson_object_iterator_empty; |
| 336 | cson_kvp * pKvp; |
| 337 | int nErr = 0, nProp = 0; |
| 338 | |
| 339 | if( 0==g.perm.Setup ){ |
| 340 | json_set_err( FSL_JSON_E_DENIED, "Setting settings requires 's' access." ); |
| 341 | return NULL; |
| 342 | } |
| 343 | else if( 0==g.json.reqPayload.o ){ |
| 344 | json_set_err(FSL_JSON_E_MISSING_ARGS, |
| 345 | "Missing payload of setting-to-value mappings."); |
| 346 | return NULL; |
| 347 | } |
| 348 | |
| 349 | db_unprotect(PROTECT_CONFIG); |
| 350 | db_prepare(&q, |
| 351 | "INSERT OR REPLACE INTO config (name, value, mtime) " |
| 352 | "VALUES(:name, :value, CAST(strftime('%%s') AS INT))" |
| 353 | ); |
| 354 | db_begin_transaction(); |
| 355 | cson_object_iter_init( g.json.reqPayload.o, &objIter ); |
| 356 | while( (pKvp = cson_object_iter_next(&objIter)) ){ |
| 357 | char const * zKey = cson_string_cstr( cson_kvp_key(pKvp) ); |
| 358 | cson_value * pVal; |
| 359 | const Setting *pSetting = db_find_setting( zKey, 0 ); |
| 360 | if( 0==pSetting ){ |
| 361 | nErr = json_set_err(FSL_JSON_E_INVALID_ARGS, |
| 362 | "Unknown setting: %s", zKey); |
| 363 | break; |
| 364 | } |
| 365 | pVal = cson_kvp_value(pKvp); |
| 366 | switch( cson_value_type_id(pVal) ){ |
| 367 | case CSON_TYPE_NULL: |
| 368 | db_multi_exec("DELETE FROM config WHERE name=%Q", pSetting->name); |
| 369 | continue; |
| 370 | case CSON_TYPE_BOOL: |
| 371 | db_bind_int(&q, ":value", cson_value_get_bool(pVal) ? 1 : 0); |
| 372 | break; |
| 373 | case CSON_TYPE_INTEGER: |
| 374 | db_bind_int64(&q, ":value", cson_value_get_integer(pVal)); |
| 375 | break; |
| 376 | case CSON_TYPE_DOUBLE: |
| 377 | db_bind_double(&q, ":value", cson_value_get_double(pVal)); |
| 378 | break; |
| 379 | case CSON_TYPE_STRING: |
| 380 | db_bind_text(&q, ":value", cson_value_get_cstr(pVal)); |
| 381 | break; |
| 382 | default: |
| 383 | nErr = json_set_err(FSL_JSON_E_USAGE, |
| 384 | "Invalid value type for setting '%s'.", |
| 385 | pSetting->name); |
| 386 | break; |
| 387 | } |
| 388 | if( 0!=nErr ) break; |
| 389 | db_bind_text(&q, ":name", zKey); |
| 390 | db_step(&q); |
| 391 | db_reset(&q); |
| 392 | ++nProp; |
| 393 | } |
| 394 | db_finalize(&q); |
| 395 | if( 0==nErr && 0==nProp ){ |
| 396 | nErr = json_set_err(FSL_JSON_E_INVALID_ARGS, |
| 397 | "Payload contains no settings to set."); |
| 398 | } |
| 399 | db_end_transaction(nErr); |
| 400 | db_protect_pop(); |
| 401 | return NULL; |
| 402 | } |
| 403 | |
| 404 | #endif /* FOSSIL_ENABLE_JSON */ |
| 405 |
+2
-2
| --- src/json_detail.h | ||
| +++ src/json_detail.h | ||
| @@ -149,11 +149,11 @@ | ||
| 149 | 149 | ** almost certainly will corrupt any HTTP response headers. Output |
| 150 | 150 | ** sent to stderr ends up in my apache log, so that might be useful |
| 151 | 151 | ** for debugging in some cases, but no such code should be left |
| 152 | 152 | ** enabled for non-debugging builds. |
| 153 | 153 | */ |
| 154 | -typedef cson_value * (*fossil_json_f)(); | |
| 154 | +typedef cson_value * (*fossil_json_f)(void); | |
| 155 | 155 | |
| 156 | 156 | /* |
| 157 | 157 | ** Holds name-to-function mappings for JSON page/command dispatching. |
| 158 | 158 | ** |
| 159 | 159 | ** Internally we model page dispatching lists as arrays of these |
| @@ -260,14 +260,14 @@ | ||
| 260 | 260 | ** |
| 261 | 261 | ** Whether or not we need to take args from CLI or POST data makes a |
| 262 | 262 | ** difference in argument/parameter handling in many JSON routines, |
| 263 | 263 | ** and thus this distinction. |
| 264 | 264 | */ |
| 265 | -int fossil_has_json(); | |
| 265 | +int fossil_has_json(void); | |
| 266 | 266 | |
| 267 | 267 | enum json_get_changed_files_flags { |
| 268 | 268 | json_get_changed_files_ELIDE_PARENT = 1 << 0 |
| 269 | 269 | }; |
| 270 | 270 | |
| 271 | 271 | #endif /* !defined(_RC_COMPILE_) */ |
| 272 | 272 | #endif/*FOSSIL_JSON_DETAIL_H_INCLUDED*/ |
| 273 | 273 | #endif /* FOSSIL_ENABLE_JSON */ |
| 274 | 274 |
| --- src/json_detail.h | |
| +++ src/json_detail.h | |
| @@ -149,11 +149,11 @@ | |
| 149 | ** almost certainly will corrupt any HTTP response headers. Output |
| 150 | ** sent to stderr ends up in my apache log, so that might be useful |
| 151 | ** for debugging in some cases, but no such code should be left |
| 152 | ** enabled for non-debugging builds. |
| 153 | */ |
| 154 | typedef cson_value * (*fossil_json_f)(); |
| 155 | |
| 156 | /* |
| 157 | ** Holds name-to-function mappings for JSON page/command dispatching. |
| 158 | ** |
| 159 | ** Internally we model page dispatching lists as arrays of these |
| @@ -260,14 +260,14 @@ | |
| 260 | ** |
| 261 | ** Whether or not we need to take args from CLI or POST data makes a |
| 262 | ** difference in argument/parameter handling in many JSON routines, |
| 263 | ** and thus this distinction. |
| 264 | */ |
| 265 | int fossil_has_json(); |
| 266 | |
| 267 | enum json_get_changed_files_flags { |
| 268 | json_get_changed_files_ELIDE_PARENT = 1 << 0 |
| 269 | }; |
| 270 | |
| 271 | #endif /* !defined(_RC_COMPILE_) */ |
| 272 | #endif/*FOSSIL_JSON_DETAIL_H_INCLUDED*/ |
| 273 | #endif /* FOSSIL_ENABLE_JSON */ |
| 274 |
| --- src/json_detail.h | |
| +++ src/json_detail.h | |
| @@ -149,11 +149,11 @@ | |
| 149 | ** almost certainly will corrupt any HTTP response headers. Output |
| 150 | ** sent to stderr ends up in my apache log, so that might be useful |
| 151 | ** for debugging in some cases, but no such code should be left |
| 152 | ** enabled for non-debugging builds. |
| 153 | */ |
| 154 | typedef cson_value * (*fossil_json_f)(void); |
| 155 | |
| 156 | /* |
| 157 | ** Holds name-to-function mappings for JSON page/command dispatching. |
| 158 | ** |
| 159 | ** Internally we model page dispatching lists as arrays of these |
| @@ -260,14 +260,14 @@ | |
| 260 | ** |
| 261 | ** Whether or not we need to take args from CLI or POST data makes a |
| 262 | ** difference in argument/parameter handling in many JSON routines, |
| 263 | ** and thus this distinction. |
| 264 | */ |
| 265 | int fossil_has_json(void); |
| 266 | |
| 267 | enum json_get_changed_files_flags { |
| 268 | json_get_changed_files_ELIDE_PARENT = 1 << 0 |
| 269 | }; |
| 270 | |
| 271 | #endif /* !defined(_RC_COMPILE_) */ |
| 272 | #endif/*FOSSIL_JSON_DETAIL_H_INCLUDED*/ |
| 273 | #endif /* FOSSIL_ENABLE_JSON */ |
| 274 |
+1
-1
| --- src/json_diff.c | ||
| +++ src/json_diff.c | ||
| @@ -83,11 +83,11 @@ | ||
| 83 | 83 | ** |
| 84 | 84 | ** Can come from GET, POST.payload, CLI -v1/-v2 or as positional |
| 85 | 85 | ** parameters following the command name (in HTTP and CLI modes). |
| 86 | 86 | ** |
| 87 | 87 | */ |
| 88 | -cson_value * json_page_diff(){ | |
| 88 | +cson_value * json_page_diff(void){ | |
| 89 | 89 | cson_object * pay = NULL; |
| 90 | 90 | cson_value * v = NULL; |
| 91 | 91 | char const * zFrom; |
| 92 | 92 | char const * zTo; |
| 93 | 93 | int nContext = 0; |
| 94 | 94 |
| --- src/json_diff.c | |
| +++ src/json_diff.c | |
| @@ -83,11 +83,11 @@ | |
| 83 | ** |
| 84 | ** Can come from GET, POST.payload, CLI -v1/-v2 or as positional |
| 85 | ** parameters following the command name (in HTTP and CLI modes). |
| 86 | ** |
| 87 | */ |
| 88 | cson_value * json_page_diff(){ |
| 89 | cson_object * pay = NULL; |
| 90 | cson_value * v = NULL; |
| 91 | char const * zFrom; |
| 92 | char const * zTo; |
| 93 | int nContext = 0; |
| 94 |
| --- src/json_diff.c | |
| +++ src/json_diff.c | |
| @@ -83,11 +83,11 @@ | |
| 83 | ** |
| 84 | ** Can come from GET, POST.payload, CLI -v1/-v2 or as positional |
| 85 | ** parameters following the command name (in HTTP and CLI modes). |
| 86 | ** |
| 87 | */ |
| 88 | cson_value * json_page_diff(void){ |
| 89 | cson_object * pay = NULL; |
| 90 | cson_value * v = NULL; |
| 91 | char const * zFrom; |
| 92 | char const * zTo; |
| 93 | int nContext = 0; |
| 94 |
+4
-4
| --- src/json_dir.c | ||
| +++ src/json_dir.c | ||
| @@ -21,11 +21,11 @@ | ||
| 21 | 21 | |
| 22 | 22 | #if INTERFACE |
| 23 | 23 | #include "json_detail.h" |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | -static cson_value * json_page_dir_list(); | |
| 26 | +static cson_value * json_page_dir_list(void); | |
| 27 | 27 | /* |
| 28 | 28 | ** Mapping of /json/wiki/XXX commands/paths to callbacks. |
| 29 | 29 | */ |
| 30 | 30 | #if 0 /* TODO: Not used? */ |
| 31 | 31 | static const JsonPageDef JsonPageDefs_Dir[] = { |
| @@ -33,11 +33,11 @@ | ||
| 33 | 33 | {NULL,NULL,0} |
| 34 | 34 | }; |
| 35 | 35 | #endif |
| 36 | 36 | |
| 37 | 37 | #if 0 /* TODO: Not used? */ |
| 38 | -static char const * json_dir_path_extra(){ | |
| 38 | +static char const * json_dir_path_extra(void){ | |
| 39 | 39 | static char const * zP = NULL; |
| 40 | 40 | if( !zP ){ |
| 41 | 41 | zP = g.zExtra; |
| 42 | 42 | while(zP && *zP && ('/'==*zP)){ |
| 43 | 43 | ++zP; |
| @@ -49,11 +49,11 @@ | ||
| 49 | 49 | |
| 50 | 50 | /* |
| 51 | 51 | ** Impl of /json/dir. 98% of it was taken directly |
| 52 | 52 | ** from browse.c::page_dir() |
| 53 | 53 | */ |
| 54 | -static cson_value * json_page_dir_list(){ | |
| 54 | +static cson_value * json_page_dir_list(void){ | |
| 55 | 55 | cson_object * zPayload = NULL; /* return value */ |
| 56 | 56 | cson_array * zEntries = NULL; /* accumulated list of entries. */ |
| 57 | 57 | cson_object * zEntry = NULL; /* a single dir/file entry. */ |
| 58 | 58 | cson_array * keyStore = NULL; /* garbage collector for shared strings. */ |
| 59 | 59 | cson_string * zKeyName = NULL; |
| @@ -281,14 +281,14 @@ | ||
| 281 | 281 | |
| 282 | 282 | /* |
| 283 | 283 | ** Implements the /json/dir family of pages/commands. |
| 284 | 284 | ** |
| 285 | 285 | */ |
| 286 | -cson_value * json_page_dir(){ | |
| 286 | +cson_value * json_page_dir(void){ | |
| 287 | 287 | #if 1 |
| 288 | 288 | return json_page_dir_list(); |
| 289 | 289 | #else |
| 290 | 290 | return json_page_dispatch_helper(&JsonPageDefs_Dir[0]); |
| 291 | 291 | #endif |
| 292 | 292 | } |
| 293 | 293 | |
| 294 | 294 | #endif /* FOSSIL_ENABLE_JSON */ |
| 295 | 295 |
| --- src/json_dir.c | |
| +++ src/json_dir.c | |
| @@ -21,11 +21,11 @@ | |
| 21 | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | static cson_value * json_page_dir_list(); |
| 27 | /* |
| 28 | ** Mapping of /json/wiki/XXX commands/paths to callbacks. |
| 29 | */ |
| 30 | #if 0 /* TODO: Not used? */ |
| 31 | static const JsonPageDef JsonPageDefs_Dir[] = { |
| @@ -33,11 +33,11 @@ | |
| 33 | {NULL,NULL,0} |
| 34 | }; |
| 35 | #endif |
| 36 | |
| 37 | #if 0 /* TODO: Not used? */ |
| 38 | static char const * json_dir_path_extra(){ |
| 39 | static char const * zP = NULL; |
| 40 | if( !zP ){ |
| 41 | zP = g.zExtra; |
| 42 | while(zP && *zP && ('/'==*zP)){ |
| 43 | ++zP; |
| @@ -49,11 +49,11 @@ | |
| 49 | |
| 50 | /* |
| 51 | ** Impl of /json/dir. 98% of it was taken directly |
| 52 | ** from browse.c::page_dir() |
| 53 | */ |
| 54 | static cson_value * json_page_dir_list(){ |
| 55 | cson_object * zPayload = NULL; /* return value */ |
| 56 | cson_array * zEntries = NULL; /* accumulated list of entries. */ |
| 57 | cson_object * zEntry = NULL; /* a single dir/file entry. */ |
| 58 | cson_array * keyStore = NULL; /* garbage collector for shared strings. */ |
| 59 | cson_string * zKeyName = NULL; |
| @@ -281,14 +281,14 @@ | |
| 281 | |
| 282 | /* |
| 283 | ** Implements the /json/dir family of pages/commands. |
| 284 | ** |
| 285 | */ |
| 286 | cson_value * json_page_dir(){ |
| 287 | #if 1 |
| 288 | return json_page_dir_list(); |
| 289 | #else |
| 290 | return json_page_dispatch_helper(&JsonPageDefs_Dir[0]); |
| 291 | #endif |
| 292 | } |
| 293 | |
| 294 | #endif /* FOSSIL_ENABLE_JSON */ |
| 295 |
| --- src/json_dir.c | |
| +++ src/json_dir.c | |
| @@ -21,11 +21,11 @@ | |
| 21 | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | static cson_value * json_page_dir_list(void); |
| 27 | /* |
| 28 | ** Mapping of /json/wiki/XXX commands/paths to callbacks. |
| 29 | */ |
| 30 | #if 0 /* TODO: Not used? */ |
| 31 | static const JsonPageDef JsonPageDefs_Dir[] = { |
| @@ -33,11 +33,11 @@ | |
| 33 | {NULL,NULL,0} |
| 34 | }; |
| 35 | #endif |
| 36 | |
| 37 | #if 0 /* TODO: Not used? */ |
| 38 | static char const * json_dir_path_extra(void){ |
| 39 | static char const * zP = NULL; |
| 40 | if( !zP ){ |
| 41 | zP = g.zExtra; |
| 42 | while(zP && *zP && ('/'==*zP)){ |
| 43 | ++zP; |
| @@ -49,11 +49,11 @@ | |
| 49 | |
| 50 | /* |
| 51 | ** Impl of /json/dir. 98% of it was taken directly |
| 52 | ** from browse.c::page_dir() |
| 53 | */ |
| 54 | static cson_value * json_page_dir_list(void){ |
| 55 | cson_object * zPayload = NULL; /* return value */ |
| 56 | cson_array * zEntries = NULL; /* accumulated list of entries. */ |
| 57 | cson_object * zEntry = NULL; /* a single dir/file entry. */ |
| 58 | cson_array * keyStore = NULL; /* garbage collector for shared strings. */ |
| 59 | cson_string * zKeyName = NULL; |
| @@ -281,14 +281,14 @@ | |
| 281 | |
| 282 | /* |
| 283 | ** Implements the /json/dir family of pages/commands. |
| 284 | ** |
| 285 | */ |
| 286 | cson_value * json_page_dir(void){ |
| 287 | #if 1 |
| 288 | return json_page_dir_list(); |
| 289 | #else |
| 290 | return json_page_dispatch_helper(&JsonPageDefs_Dir[0]); |
| 291 | #endif |
| 292 | } |
| 293 | |
| 294 | #endif /* FOSSIL_ENABLE_JSON */ |
| 295 |
+1
-1
| --- src/json_finfo.c | ||
| +++ src/json_finfo.c | ||
| @@ -25,11 +25,11 @@ | ||
| 25 | 25 | |
| 26 | 26 | /* |
| 27 | 27 | ** Implements the /json/finfo page/command. |
| 28 | 28 | ** |
| 29 | 29 | */ |
| 30 | -cson_value * json_page_finfo(){ | |
| 30 | +cson_value * json_page_finfo(void){ | |
| 31 | 31 | cson_object * pay = NULL; |
| 32 | 32 | cson_array * checkins = NULL; |
| 33 | 33 | char const * zFilename = NULL; |
| 34 | 34 | Blob sql = empty_blob; |
| 35 | 35 | Stmt q = empty_Stmt; |
| 36 | 36 |
| --- src/json_finfo.c | |
| +++ src/json_finfo.c | |
| @@ -25,11 +25,11 @@ | |
| 25 | |
| 26 | /* |
| 27 | ** Implements the /json/finfo page/command. |
| 28 | ** |
| 29 | */ |
| 30 | cson_value * json_page_finfo(){ |
| 31 | cson_object * pay = NULL; |
| 32 | cson_array * checkins = NULL; |
| 33 | char const * zFilename = NULL; |
| 34 | Blob sql = empty_blob; |
| 35 | Stmt q = empty_Stmt; |
| 36 |
| --- src/json_finfo.c | |
| +++ src/json_finfo.c | |
| @@ -25,11 +25,11 @@ | |
| 25 | |
| 26 | /* |
| 27 | ** Implements the /json/finfo page/command. |
| 28 | ** |
| 29 | */ |
| 30 | cson_value * json_page_finfo(void){ |
| 31 | cson_object * pay = NULL; |
| 32 | cson_array * checkins = NULL; |
| 33 | char const * zFilename = NULL; |
| 34 | Blob sql = empty_blob; |
| 35 | Stmt q = empty_Stmt; |
| 36 |
+4
-4
| --- src/json_login.c | ||
| +++ src/json_login.c | ||
| @@ -26,11 +26,11 @@ | ||
| 26 | 26 | |
| 27 | 27 | /* |
| 28 | 28 | ** Implementation of the /json/login page. |
| 29 | 29 | ** |
| 30 | 30 | */ |
| 31 | -cson_value * json_page_login(){ | |
| 31 | +cson_value * json_page_login(void){ | |
| 32 | 32 | char preciseErrors = /* if true, "complete" JSON error codes are used, |
| 33 | 33 | else they are "dumbed down" to a generic login |
| 34 | 34 | error code. |
| 35 | 35 | */ |
| 36 | 36 | #if 1 |
| @@ -181,11 +181,11 @@ | ||
| 181 | 181 | |
| 182 | 182 | /* |
| 183 | 183 | ** Impl of /json/logout. |
| 184 | 184 | ** |
| 185 | 185 | */ |
| 186 | -cson_value * json_page_logout(){ | |
| 186 | +cson_value * json_page_logout(void){ | |
| 187 | 187 | cson_value const *token = g.json.authToken; |
| 188 | 188 | /* Remember that json_bootstrap_late() replaces the login cookie |
| 189 | 189 | with the JSON auth token if the request contains it. If the |
| 190 | 190 | request is missing the auth token then this will fetch fossil's |
| 191 | 191 | original cookie. Either way, it's what we want :). |
| @@ -207,11 +207,11 @@ | ||
| 207 | 207 | } |
| 208 | 208 | |
| 209 | 209 | /* |
| 210 | 210 | ** Implementation of the /json/anonymousPassword page. |
| 211 | 211 | */ |
| 212 | -cson_value * json_page_anon_password(){ | |
| 212 | +cson_value * json_page_anon_password(void){ | |
| 213 | 213 | cson_value * v = cson_value_new_object(); |
| 214 | 214 | cson_object * o = cson_value_get_object(v); |
| 215 | 215 | unsigned const int seed = captcha_seed(); |
| 216 | 216 | char const * zCaptcha = captcha_decode(seed); |
| 217 | 217 | cson_object_set(o, "seed", |
| @@ -226,11 +226,11 @@ | ||
| 226 | 226 | |
| 227 | 227 | |
| 228 | 228 | /* |
| 229 | 229 | ** Implements the /json/whoami page/command. |
| 230 | 230 | */ |
| 231 | -cson_value * json_page_whoami(){ | |
| 231 | +cson_value * json_page_whoami(void){ | |
| 232 | 232 | cson_value * payload = NULL; |
| 233 | 233 | cson_object * obj = NULL; |
| 234 | 234 | Stmt q; |
| 235 | 235 | if(!g.json.authToken && g.userUid==0){ |
| 236 | 236 | /* assume we just logged out. */ |
| 237 | 237 |
| --- src/json_login.c | |
| +++ src/json_login.c | |
| @@ -26,11 +26,11 @@ | |
| 26 | |
| 27 | /* |
| 28 | ** Implementation of the /json/login page. |
| 29 | ** |
| 30 | */ |
| 31 | cson_value * json_page_login(){ |
| 32 | char preciseErrors = /* if true, "complete" JSON error codes are used, |
| 33 | else they are "dumbed down" to a generic login |
| 34 | error code. |
| 35 | */ |
| 36 | #if 1 |
| @@ -181,11 +181,11 @@ | |
| 181 | |
| 182 | /* |
| 183 | ** Impl of /json/logout. |
| 184 | ** |
| 185 | */ |
| 186 | cson_value * json_page_logout(){ |
| 187 | cson_value const *token = g.json.authToken; |
| 188 | /* Remember that json_bootstrap_late() replaces the login cookie |
| 189 | with the JSON auth token if the request contains it. If the |
| 190 | request is missing the auth token then this will fetch fossil's |
| 191 | original cookie. Either way, it's what we want :). |
| @@ -207,11 +207,11 @@ | |
| 207 | } |
| 208 | |
| 209 | /* |
| 210 | ** Implementation of the /json/anonymousPassword page. |
| 211 | */ |
| 212 | cson_value * json_page_anon_password(){ |
| 213 | cson_value * v = cson_value_new_object(); |
| 214 | cson_object * o = cson_value_get_object(v); |
| 215 | unsigned const int seed = captcha_seed(); |
| 216 | char const * zCaptcha = captcha_decode(seed); |
| 217 | cson_object_set(o, "seed", |
| @@ -226,11 +226,11 @@ | |
| 226 | |
| 227 | |
| 228 | /* |
| 229 | ** Implements the /json/whoami page/command. |
| 230 | */ |
| 231 | cson_value * json_page_whoami(){ |
| 232 | cson_value * payload = NULL; |
| 233 | cson_object * obj = NULL; |
| 234 | Stmt q; |
| 235 | if(!g.json.authToken && g.userUid==0){ |
| 236 | /* assume we just logged out. */ |
| 237 |
| --- src/json_login.c | |
| +++ src/json_login.c | |
| @@ -26,11 +26,11 @@ | |
| 26 | |
| 27 | /* |
| 28 | ** Implementation of the /json/login page. |
| 29 | ** |
| 30 | */ |
| 31 | cson_value * json_page_login(void){ |
| 32 | char preciseErrors = /* if true, "complete" JSON error codes are used, |
| 33 | else they are "dumbed down" to a generic login |
| 34 | error code. |
| 35 | */ |
| 36 | #if 1 |
| @@ -181,11 +181,11 @@ | |
| 181 | |
| 182 | /* |
| 183 | ** Impl of /json/logout. |
| 184 | ** |
| 185 | */ |
| 186 | cson_value * json_page_logout(void){ |
| 187 | cson_value const *token = g.json.authToken; |
| 188 | /* Remember that json_bootstrap_late() replaces the login cookie |
| 189 | with the JSON auth token if the request contains it. If the |
| 190 | request is missing the auth token then this will fetch fossil's |
| 191 | original cookie. Either way, it's what we want :). |
| @@ -207,11 +207,11 @@ | |
| 207 | } |
| 208 | |
| 209 | /* |
| 210 | ** Implementation of the /json/anonymousPassword page. |
| 211 | */ |
| 212 | cson_value * json_page_anon_password(void){ |
| 213 | cson_value * v = cson_value_new_object(); |
| 214 | cson_object * o = cson_value_get_object(v); |
| 215 | unsigned const int seed = captcha_seed(); |
| 216 | char const * zCaptcha = captcha_decode(seed); |
| 217 | cson_object_set(o, "seed", |
| @@ -226,11 +226,11 @@ | |
| 226 | |
| 227 | |
| 228 | /* |
| 229 | ** Implements the /json/whoami page/command. |
| 230 | */ |
| 231 | cson_value * json_page_whoami(void){ |
| 232 | cson_value * payload = NULL; |
| 233 | cson_object * obj = NULL; |
| 234 | Stmt q; |
| 235 | if(!g.json.authToken && g.userUid==0){ |
| 236 | /* assume we just logged out. */ |
| 237 |
+1
-1
| --- src/json_query.c | ||
| +++ src/json_query.c | ||
| @@ -38,11 +38,11 @@ | ||
| 38 | 38 | ** (default) creates each row as an Object. |
| 39 | 39 | ** |
| 40 | 40 | ** TODO: in CLI mode (only) use -S FILENAME to read the sql |
| 41 | 41 | ** from a file. |
| 42 | 42 | */ |
| 43 | -cson_value * json_page_query(){ | |
| 43 | +cson_value * json_page_query(void){ | |
| 44 | 44 | char const * zSql = NULL; |
| 45 | 45 | cson_value * payV; |
| 46 | 46 | char const * zFmt; |
| 47 | 47 | Stmt q = empty_Stmt; |
| 48 | 48 | int check; |
| 49 | 49 |
| --- src/json_query.c | |
| +++ src/json_query.c | |
| @@ -38,11 +38,11 @@ | |
| 38 | ** (default) creates each row as an Object. |
| 39 | ** |
| 40 | ** TODO: in CLI mode (only) use -S FILENAME to read the sql |
| 41 | ** from a file. |
| 42 | */ |
| 43 | cson_value * json_page_query(){ |
| 44 | char const * zSql = NULL; |
| 45 | cson_value * payV; |
| 46 | char const * zFmt; |
| 47 | Stmt q = empty_Stmt; |
| 48 | int check; |
| 49 |
| --- src/json_query.c | |
| +++ src/json_query.c | |
| @@ -38,11 +38,11 @@ | |
| 38 | ** (default) creates each row as an Object. |
| 39 | ** |
| 40 | ** TODO: in CLI mode (only) use -S FILENAME to read the sql |
| 41 | ** from a file. |
| 42 | */ |
| 43 | cson_value * json_page_query(void){ |
| 44 | char const * zSql = NULL; |
| 45 | cson_value * payV; |
| 46 | char const * zFmt; |
| 47 | Stmt q = empty_Stmt; |
| 48 | int check; |
| 49 |
+11
-11
| --- src/json_report.c | ||
| +++ src/json_report.c | ||
| @@ -22,15 +22,15 @@ | ||
| 22 | 22 | #if INTERFACE |
| 23 | 23 | #include "json_detail.h" |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | 26 | |
| 27 | -static cson_value * json_report_create(); | |
| 28 | -static cson_value * json_report_get(); | |
| 29 | -static cson_value * json_report_list(); | |
| 30 | -static cson_value * json_report_run(); | |
| 31 | -static cson_value * json_report_save(); | |
| 27 | +static cson_value * json_report_create(void); | |
| 28 | +static cson_value * json_report_get(void); | |
| 29 | +static cson_value * json_report_list(void); | |
| 30 | +static cson_value * json_report_run(void); | |
| 31 | +static cson_value * json_report_save(void); | |
| 32 | 32 | |
| 33 | 33 | /* |
| 34 | 34 | ** Mapping of /json/report/XXX commands/paths to callbacks. |
| 35 | 35 | */ |
| 36 | 36 | static const JsonPageDef JsonPageDefs_Report[] = { |
| @@ -45,11 +45,11 @@ | ||
| 45 | 45 | /* |
| 46 | 46 | ** Implementation of the /json/report page. |
| 47 | 47 | ** |
| 48 | 48 | ** |
| 49 | 49 | */ |
| 50 | -cson_value * json_page_report(){ | |
| 50 | +cson_value * json_page_report(void){ | |
| 51 | 51 | if(!g.perm.RdTkt && !g.perm.NewTkt ){ |
| 52 | 52 | json_set_err(FSL_JSON_E_DENIED, |
| 53 | 53 | "Requires 'r' or 'n' permissions."); |
| 54 | 54 | return NULL; |
| 55 | 55 | } |
| @@ -77,16 +77,16 @@ | ||
| 77 | 77 | } |
| 78 | 78 | } |
| 79 | 79 | return nReport; |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | -static cson_value * json_report_create(){ | |
| 82 | +static cson_value * json_report_create(void){ | |
| 83 | 83 | json_set_err(FSL_JSON_E_NYI, NULL); |
| 84 | 84 | return NULL; |
| 85 | 85 | } |
| 86 | 86 | |
| 87 | -static cson_value * json_report_get(){ | |
| 87 | +static cson_value * json_report_get(void){ | |
| 88 | 88 | int nReport; |
| 89 | 89 | Stmt q = empty_Stmt; |
| 90 | 90 | cson_value * pay = NULL; |
| 91 | 91 | |
| 92 | 92 | if(!g.perm.TktFmt){ |
| @@ -122,11 +122,11 @@ | ||
| 122 | 122 | } |
| 123 | 123 | |
| 124 | 124 | /* |
| 125 | 125 | ** Impl of /json/report/list. |
| 126 | 126 | */ |
| 127 | -static cson_value * json_report_list(){ | |
| 127 | +static cson_value * json_report_list(void){ | |
| 128 | 128 | Blob sql = empty_blob; |
| 129 | 129 | cson_value * pay = NULL; |
| 130 | 130 | if(!g.perm.RdTkt){ |
| 131 | 131 | json_set_err(FSL_JSON_E_DENIED, |
| 132 | 132 | "Requires 'r' privileges."); |
| @@ -158,11 +158,11 @@ | ||
| 158 | 158 | ** limit=int (CLI: -limit # or -n #) -n is for compat. with other commands. |
| 159 | 159 | ** |
| 160 | 160 | ** format=a|o Specifies result format: a=each row is an arry, o=each |
| 161 | 161 | ** row is an object. Default=o. |
| 162 | 162 | */ |
| 163 | -static cson_value * json_report_run(){ | |
| 163 | +static cson_value * json_report_run(void){ | |
| 164 | 164 | int nReport; |
| 165 | 165 | Stmt q = empty_Stmt; |
| 166 | 166 | cson_object * pay = NULL; |
| 167 | 167 | cson_array * tktList = NULL; |
| 168 | 168 | char const * zFmt; |
| @@ -255,9 +255,9 @@ | ||
| 255 | 255 | |
| 256 | 256 | return pay ? cson_object_value(pay) : NULL; |
| 257 | 257 | |
| 258 | 258 | } |
| 259 | 259 | |
| 260 | -static cson_value * json_report_save(){ | |
| 260 | +static cson_value * json_report_save(void){ | |
| 261 | 261 | return NULL; |
| 262 | 262 | } |
| 263 | 263 | #endif /* FOSSIL_ENABLE_JSON */ |
| 264 | 264 |
| --- src/json_report.c | |
| +++ src/json_report.c | |
| @@ -22,15 +22,15 @@ | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | |
| 27 | static cson_value * json_report_create(); |
| 28 | static cson_value * json_report_get(); |
| 29 | static cson_value * json_report_list(); |
| 30 | static cson_value * json_report_run(); |
| 31 | static cson_value * json_report_save(); |
| 32 | |
| 33 | /* |
| 34 | ** Mapping of /json/report/XXX commands/paths to callbacks. |
| 35 | */ |
| 36 | static const JsonPageDef JsonPageDefs_Report[] = { |
| @@ -45,11 +45,11 @@ | |
| 45 | /* |
| 46 | ** Implementation of the /json/report page. |
| 47 | ** |
| 48 | ** |
| 49 | */ |
| 50 | cson_value * json_page_report(){ |
| 51 | if(!g.perm.RdTkt && !g.perm.NewTkt ){ |
| 52 | json_set_err(FSL_JSON_E_DENIED, |
| 53 | "Requires 'r' or 'n' permissions."); |
| 54 | return NULL; |
| 55 | } |
| @@ -77,16 +77,16 @@ | |
| 77 | } |
| 78 | } |
| 79 | return nReport; |
| 80 | } |
| 81 | |
| 82 | static cson_value * json_report_create(){ |
| 83 | json_set_err(FSL_JSON_E_NYI, NULL); |
| 84 | return NULL; |
| 85 | } |
| 86 | |
| 87 | static cson_value * json_report_get(){ |
| 88 | int nReport; |
| 89 | Stmt q = empty_Stmt; |
| 90 | cson_value * pay = NULL; |
| 91 | |
| 92 | if(!g.perm.TktFmt){ |
| @@ -122,11 +122,11 @@ | |
| 122 | } |
| 123 | |
| 124 | /* |
| 125 | ** Impl of /json/report/list. |
| 126 | */ |
| 127 | static cson_value * json_report_list(){ |
| 128 | Blob sql = empty_blob; |
| 129 | cson_value * pay = NULL; |
| 130 | if(!g.perm.RdTkt){ |
| 131 | json_set_err(FSL_JSON_E_DENIED, |
| 132 | "Requires 'r' privileges."); |
| @@ -158,11 +158,11 @@ | |
| 158 | ** limit=int (CLI: -limit # or -n #) -n is for compat. with other commands. |
| 159 | ** |
| 160 | ** format=a|o Specifies result format: a=each row is an arry, o=each |
| 161 | ** row is an object. Default=o. |
| 162 | */ |
| 163 | static cson_value * json_report_run(){ |
| 164 | int nReport; |
| 165 | Stmt q = empty_Stmt; |
| 166 | cson_object * pay = NULL; |
| 167 | cson_array * tktList = NULL; |
| 168 | char const * zFmt; |
| @@ -255,9 +255,9 @@ | |
| 255 | |
| 256 | return pay ? cson_object_value(pay) : NULL; |
| 257 | |
| 258 | } |
| 259 | |
| 260 | static cson_value * json_report_save(){ |
| 261 | return NULL; |
| 262 | } |
| 263 | #endif /* FOSSIL_ENABLE_JSON */ |
| 264 |
| --- src/json_report.c | |
| +++ src/json_report.c | |
| @@ -22,15 +22,15 @@ | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | |
| 27 | static cson_value * json_report_create(void); |
| 28 | static cson_value * json_report_get(void); |
| 29 | static cson_value * json_report_list(void); |
| 30 | static cson_value * json_report_run(void); |
| 31 | static cson_value * json_report_save(void); |
| 32 | |
| 33 | /* |
| 34 | ** Mapping of /json/report/XXX commands/paths to callbacks. |
| 35 | */ |
| 36 | static const JsonPageDef JsonPageDefs_Report[] = { |
| @@ -45,11 +45,11 @@ | |
| 45 | /* |
| 46 | ** Implementation of the /json/report page. |
| 47 | ** |
| 48 | ** |
| 49 | */ |
| 50 | cson_value * json_page_report(void){ |
| 51 | if(!g.perm.RdTkt && !g.perm.NewTkt ){ |
| 52 | json_set_err(FSL_JSON_E_DENIED, |
| 53 | "Requires 'r' or 'n' permissions."); |
| 54 | return NULL; |
| 55 | } |
| @@ -77,16 +77,16 @@ | |
| 77 | } |
| 78 | } |
| 79 | return nReport; |
| 80 | } |
| 81 | |
| 82 | static cson_value * json_report_create(void){ |
| 83 | json_set_err(FSL_JSON_E_NYI, NULL); |
| 84 | return NULL; |
| 85 | } |
| 86 | |
| 87 | static cson_value * json_report_get(void){ |
| 88 | int nReport; |
| 89 | Stmt q = empty_Stmt; |
| 90 | cson_value * pay = NULL; |
| 91 | |
| 92 | if(!g.perm.TktFmt){ |
| @@ -122,11 +122,11 @@ | |
| 122 | } |
| 123 | |
| 124 | /* |
| 125 | ** Impl of /json/report/list. |
| 126 | */ |
| 127 | static cson_value * json_report_list(void){ |
| 128 | Blob sql = empty_blob; |
| 129 | cson_value * pay = NULL; |
| 130 | if(!g.perm.RdTkt){ |
| 131 | json_set_err(FSL_JSON_E_DENIED, |
| 132 | "Requires 'r' privileges."); |
| @@ -158,11 +158,11 @@ | |
| 158 | ** limit=int (CLI: -limit # or -n #) -n is for compat. with other commands. |
| 159 | ** |
| 160 | ** format=a|o Specifies result format: a=each row is an arry, o=each |
| 161 | ** row is an object. Default=o. |
| 162 | */ |
| 163 | static cson_value * json_report_run(void){ |
| 164 | int nReport; |
| 165 | Stmt q = empty_Stmt; |
| 166 | cson_object * pay = NULL; |
| 167 | cson_array * tktList = NULL; |
| 168 | char const * zFmt; |
| @@ -255,9 +255,9 @@ | |
| 255 | |
| 256 | return pay ? cson_object_value(pay) : NULL; |
| 257 | |
| 258 | } |
| 259 | |
| 260 | static cson_value * json_report_save(void){ |
| 261 | return NULL; |
| 262 | } |
| 263 | #endif /* FOSSIL_ENABLE_JSON */ |
| 264 |
+9
-9
| --- src/json_timeline.c | ||
| +++ src/json_timeline.c | ||
| @@ -22,13 +22,13 @@ | ||
| 22 | 22 | |
| 23 | 23 | #if INTERFACE |
| 24 | 24 | #include "json_detail.h" |
| 25 | 25 | #endif |
| 26 | 26 | |
| 27 | -static cson_value * json_timeline_branch(); | |
| 28 | -static cson_value * json_timeline_ci(); | |
| 29 | -static cson_value * json_timeline_ticket(); | |
| 27 | +static cson_value * json_timeline_branch(void); | |
| 28 | +static cson_value * json_timeline_ci(void); | |
| 29 | +static cson_value * json_timeline_ticket(void); | |
| 30 | 30 | /* |
| 31 | 31 | ** Mapping of /json/timeline/XXX commands/paths to callbacks. |
| 32 | 32 | */ |
| 33 | 33 | static const JsonPageDef JsonPageDefs_Timeline[] = { |
| 34 | 34 | /* the short forms are only enabled in CLI mode, to avoid |
| @@ -49,11 +49,11 @@ | ||
| 49 | 49 | /* |
| 50 | 50 | ** Implements the /json/timeline family of pages/commands. Far from |
| 51 | 51 | ** complete. |
| 52 | 52 | ** |
| 53 | 53 | */ |
| 54 | -cson_value * json_page_timeline(){ | |
| 54 | +cson_value * json_page_timeline(void){ | |
| 55 | 55 | #if 0 |
| 56 | 56 | /* The original timeline code does not require 'h' access, |
| 57 | 57 | but it arguably should. For JSON mode i think one could argue |
| 58 | 58 | that History permissions are required. |
| 59 | 59 | */ |
| @@ -364,11 +364,11 @@ | ||
| 364 | 364 | } |
| 365 | 365 | db_finalize(&q); |
| 366 | 366 | return rowsV; |
| 367 | 367 | } |
| 368 | 368 | |
| 369 | -static cson_value * json_timeline_branch(){ | |
| 369 | +static cson_value * json_timeline_branch(void){ | |
| 370 | 370 | cson_value * pay = NULL; |
| 371 | 371 | Blob sql = empty_blob; |
| 372 | 372 | Stmt q = empty_Stmt; |
| 373 | 373 | int limit = 0; |
| 374 | 374 | if(!g.perm.Read){ |
| @@ -445,11 +445,11 @@ | ||
| 445 | 445 | ** Implementation of /json/timeline/ci. |
| 446 | 446 | ** |
| 447 | 447 | ** Still a few TODOs (like figuring out how to structure |
| 448 | 448 | ** inheritance info). |
| 449 | 449 | */ |
| 450 | -static cson_value * json_timeline_ci(){ | |
| 450 | +static cson_value * json_timeline_ci(void){ | |
| 451 | 451 | cson_value * payV = NULL; |
| 452 | 452 | cson_object * pay = NULL; |
| 453 | 453 | cson_value * tmp = NULL; |
| 454 | 454 | cson_value * listV = NULL; |
| 455 | 455 | cson_array * list = NULL; |
| @@ -526,11 +526,11 @@ | ||
| 526 | 526 | |
| 527 | 527 | /* |
| 528 | 528 | ** Implementation of /json/timeline/event. |
| 529 | 529 | ** |
| 530 | 530 | */ |
| 531 | -cson_value * json_timeline_event(){ | |
| 531 | +cson_value * json_timeline_event(void){ | |
| 532 | 532 | /* This code is 95% the same as json_timeline_ci(), by the way. */ |
| 533 | 533 | cson_value * payV = NULL; |
| 534 | 534 | cson_object * pay = NULL; |
| 535 | 535 | cson_array * list = NULL; |
| 536 | 536 | int check = 0; |
| @@ -582,11 +582,11 @@ | ||
| 582 | 582 | |
| 583 | 583 | /* |
| 584 | 584 | ** Implementation of /json/timeline/wiki. |
| 585 | 585 | ** |
| 586 | 586 | */ |
| 587 | -cson_value * json_timeline_wiki(){ | |
| 587 | +cson_value * json_timeline_wiki(void){ | |
| 588 | 588 | /* This code is 95% the same as json_timeline_ci(), by the way. */ |
| 589 | 589 | cson_value * payV = NULL; |
| 590 | 590 | cson_object * pay = NULL; |
| 591 | 591 | cson_array * list = NULL; |
| 592 | 592 | int check = 0; |
| @@ -643,11 +643,11 @@ | ||
| 643 | 643 | |
| 644 | 644 | /* |
| 645 | 645 | ** Implementation of /json/timeline/ticket. |
| 646 | 646 | ** |
| 647 | 647 | */ |
| 648 | -static cson_value * json_timeline_ticket(){ | |
| 648 | +static cson_value * json_timeline_ticket(void){ | |
| 649 | 649 | /* This code is 95% the same as json_timeline_ci(), by the way. */ |
| 650 | 650 | cson_value * payV = NULL; |
| 651 | 651 | cson_object * pay = NULL; |
| 652 | 652 | cson_value * tmp = NULL; |
| 653 | 653 | cson_value * listV = NULL; |
| 654 | 654 |
| --- src/json_timeline.c | |
| +++ src/json_timeline.c | |
| @@ -22,13 +22,13 @@ | |
| 22 | |
| 23 | #if INTERFACE |
| 24 | #include "json_detail.h" |
| 25 | #endif |
| 26 | |
| 27 | static cson_value * json_timeline_branch(); |
| 28 | static cson_value * json_timeline_ci(); |
| 29 | static cson_value * json_timeline_ticket(); |
| 30 | /* |
| 31 | ** Mapping of /json/timeline/XXX commands/paths to callbacks. |
| 32 | */ |
| 33 | static const JsonPageDef JsonPageDefs_Timeline[] = { |
| 34 | /* the short forms are only enabled in CLI mode, to avoid |
| @@ -49,11 +49,11 @@ | |
| 49 | /* |
| 50 | ** Implements the /json/timeline family of pages/commands. Far from |
| 51 | ** complete. |
| 52 | ** |
| 53 | */ |
| 54 | cson_value * json_page_timeline(){ |
| 55 | #if 0 |
| 56 | /* The original timeline code does not require 'h' access, |
| 57 | but it arguably should. For JSON mode i think one could argue |
| 58 | that History permissions are required. |
| 59 | */ |
| @@ -364,11 +364,11 @@ | |
| 364 | } |
| 365 | db_finalize(&q); |
| 366 | return rowsV; |
| 367 | } |
| 368 | |
| 369 | static cson_value * json_timeline_branch(){ |
| 370 | cson_value * pay = NULL; |
| 371 | Blob sql = empty_blob; |
| 372 | Stmt q = empty_Stmt; |
| 373 | int limit = 0; |
| 374 | if(!g.perm.Read){ |
| @@ -445,11 +445,11 @@ | |
| 445 | ** Implementation of /json/timeline/ci. |
| 446 | ** |
| 447 | ** Still a few TODOs (like figuring out how to structure |
| 448 | ** inheritance info). |
| 449 | */ |
| 450 | static cson_value * json_timeline_ci(){ |
| 451 | cson_value * payV = NULL; |
| 452 | cson_object * pay = NULL; |
| 453 | cson_value * tmp = NULL; |
| 454 | cson_value * listV = NULL; |
| 455 | cson_array * list = NULL; |
| @@ -526,11 +526,11 @@ | |
| 526 | |
| 527 | /* |
| 528 | ** Implementation of /json/timeline/event. |
| 529 | ** |
| 530 | */ |
| 531 | cson_value * json_timeline_event(){ |
| 532 | /* This code is 95% the same as json_timeline_ci(), by the way. */ |
| 533 | cson_value * payV = NULL; |
| 534 | cson_object * pay = NULL; |
| 535 | cson_array * list = NULL; |
| 536 | int check = 0; |
| @@ -582,11 +582,11 @@ | |
| 582 | |
| 583 | /* |
| 584 | ** Implementation of /json/timeline/wiki. |
| 585 | ** |
| 586 | */ |
| 587 | cson_value * json_timeline_wiki(){ |
| 588 | /* This code is 95% the same as json_timeline_ci(), by the way. */ |
| 589 | cson_value * payV = NULL; |
| 590 | cson_object * pay = NULL; |
| 591 | cson_array * list = NULL; |
| 592 | int check = 0; |
| @@ -643,11 +643,11 @@ | |
| 643 | |
| 644 | /* |
| 645 | ** Implementation of /json/timeline/ticket. |
| 646 | ** |
| 647 | */ |
| 648 | static cson_value * json_timeline_ticket(){ |
| 649 | /* This code is 95% the same as json_timeline_ci(), by the way. */ |
| 650 | cson_value * payV = NULL; |
| 651 | cson_object * pay = NULL; |
| 652 | cson_value * tmp = NULL; |
| 653 | cson_value * listV = NULL; |
| 654 |
| --- src/json_timeline.c | |
| +++ src/json_timeline.c | |
| @@ -22,13 +22,13 @@ | |
| 22 | |
| 23 | #if INTERFACE |
| 24 | #include "json_detail.h" |
| 25 | #endif |
| 26 | |
| 27 | static cson_value * json_timeline_branch(void); |
| 28 | static cson_value * json_timeline_ci(void); |
| 29 | static cson_value * json_timeline_ticket(void); |
| 30 | /* |
| 31 | ** Mapping of /json/timeline/XXX commands/paths to callbacks. |
| 32 | */ |
| 33 | static const JsonPageDef JsonPageDefs_Timeline[] = { |
| 34 | /* the short forms are only enabled in CLI mode, to avoid |
| @@ -49,11 +49,11 @@ | |
| 49 | /* |
| 50 | ** Implements the /json/timeline family of pages/commands. Far from |
| 51 | ** complete. |
| 52 | ** |
| 53 | */ |
| 54 | cson_value * json_page_timeline(void){ |
| 55 | #if 0 |
| 56 | /* The original timeline code does not require 'h' access, |
| 57 | but it arguably should. For JSON mode i think one could argue |
| 58 | that History permissions are required. |
| 59 | */ |
| @@ -364,11 +364,11 @@ | |
| 364 | } |
| 365 | db_finalize(&q); |
| 366 | return rowsV; |
| 367 | } |
| 368 | |
| 369 | static cson_value * json_timeline_branch(void){ |
| 370 | cson_value * pay = NULL; |
| 371 | Blob sql = empty_blob; |
| 372 | Stmt q = empty_Stmt; |
| 373 | int limit = 0; |
| 374 | if(!g.perm.Read){ |
| @@ -445,11 +445,11 @@ | |
| 445 | ** Implementation of /json/timeline/ci. |
| 446 | ** |
| 447 | ** Still a few TODOs (like figuring out how to structure |
| 448 | ** inheritance info). |
| 449 | */ |
| 450 | static cson_value * json_timeline_ci(void){ |
| 451 | cson_value * payV = NULL; |
| 452 | cson_object * pay = NULL; |
| 453 | cson_value * tmp = NULL; |
| 454 | cson_value * listV = NULL; |
| 455 | cson_array * list = NULL; |
| @@ -526,11 +526,11 @@ | |
| 526 | |
| 527 | /* |
| 528 | ** Implementation of /json/timeline/event. |
| 529 | ** |
| 530 | */ |
| 531 | cson_value * json_timeline_event(void){ |
| 532 | /* This code is 95% the same as json_timeline_ci(), by the way. */ |
| 533 | cson_value * payV = NULL; |
| 534 | cson_object * pay = NULL; |
| 535 | cson_array * list = NULL; |
| 536 | int check = 0; |
| @@ -582,11 +582,11 @@ | |
| 582 | |
| 583 | /* |
| 584 | ** Implementation of /json/timeline/wiki. |
| 585 | ** |
| 586 | */ |
| 587 | cson_value * json_timeline_wiki(void){ |
| 588 | /* This code is 95% the same as json_timeline_ci(), by the way. */ |
| 589 | cson_value * payV = NULL; |
| 590 | cson_object * pay = NULL; |
| 591 | cson_array * list = NULL; |
| 592 | int check = 0; |
| @@ -643,11 +643,11 @@ | |
| 643 | |
| 644 | /* |
| 645 | ** Implementation of /json/timeline/ticket. |
| 646 | ** |
| 647 | */ |
| 648 | static cson_value * json_timeline_ticket(void){ |
| 649 | /* This code is 95% the same as json_timeline_ci(), by the way. */ |
| 650 | cson_value * payV = NULL; |
| 651 | cson_object * pay = NULL; |
| 652 | cson_value * tmp = NULL; |
| 653 | cson_value * listV = NULL; |
| 654 |
+7
-7
| --- src/json_user.c | ||
| +++ src/json_user.c | ||
| @@ -21,13 +21,13 @@ | ||
| 21 | 21 | |
| 22 | 22 | #if INTERFACE |
| 23 | 23 | #include "json_detail.h" |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | -static cson_value * json_user_get(); | |
| 27 | -static cson_value * json_user_list(); | |
| 28 | -static cson_value * json_user_save(); | |
| 26 | +static cson_value * json_user_get(void); | |
| 27 | +static cson_value * json_user_list(void); | |
| 28 | +static cson_value * json_user_save(void); | |
| 29 | 29 | |
| 30 | 30 | /* |
| 31 | 31 | ** Mapping of /json/user/XXX commands/paths to callbacks. |
| 32 | 32 | */ |
| 33 | 33 | static const JsonPageDef JsonPageDefs_User[] = { |
| @@ -41,19 +41,19 @@ | ||
| 41 | 41 | |
| 42 | 42 | /* |
| 43 | 43 | ** Implements the /json/user family of pages/commands. |
| 44 | 44 | ** |
| 45 | 45 | */ |
| 46 | -cson_value * json_page_user(){ | |
| 46 | +cson_value * json_page_user(void){ | |
| 47 | 47 | return json_page_dispatch_helper(&JsonPageDefs_User[0]); |
| 48 | 48 | } |
| 49 | 49 | |
| 50 | 50 | |
| 51 | 51 | /* |
| 52 | 52 | ** Impl of /json/user/list. Requires admin/setup rights. |
| 53 | 53 | */ |
| 54 | -static cson_value * json_user_list(){ | |
| 54 | +static cson_value * json_user_list(void){ | |
| 55 | 55 | cson_value * payV = NULL; |
| 56 | 56 | Stmt q; |
| 57 | 57 | if(!g.perm.Admin && !g.perm.Setup){ |
| 58 | 58 | json_set_err(FSL_JSON_E_DENIED, |
| 59 | 59 | "Requires 'a' or 's' privileges."); |
| @@ -122,11 +122,11 @@ | ||
| 122 | 122 | |
| 123 | 123 | |
| 124 | 124 | /* |
| 125 | 125 | ** Impl of /json/user/get. Requires admin or setup rights. |
| 126 | 126 | */ |
| 127 | -static cson_value * json_user_get(){ | |
| 127 | +static cson_value * json_user_get(void){ | |
| 128 | 128 | cson_value * payV = NULL; |
| 129 | 129 | char const * pUser = NULL; |
| 130 | 130 | if(!g.perm.Admin && !g.perm.Setup){ |
| 131 | 131 | json_set_err(FSL_JSON_E_DENIED, |
| 132 | 132 | "Requires 'a' or 's' privileges."); |
| @@ -393,11 +393,11 @@ | ||
| 393 | 393 | |
| 394 | 394 | |
| 395 | 395 | /* |
| 396 | 396 | ** Impl of /json/user/save. |
| 397 | 397 | */ |
| 398 | -static cson_value * json_user_save(){ | |
| 398 | +static cson_value * json_user_save(void){ | |
| 399 | 399 | /* try to get user info from GET/CLI args and construct |
| 400 | 400 | a JSON form of it... */ |
| 401 | 401 | cson_object * u = cson_new_object(); |
| 402 | 402 | char const * str = NULL; |
| 403 | 403 | int b = -1; |
| 404 | 404 |
| --- src/json_user.c | |
| +++ src/json_user.c | |
| @@ -21,13 +21,13 @@ | |
| 21 | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | static cson_value * json_user_get(); |
| 27 | static cson_value * json_user_list(); |
| 28 | static cson_value * json_user_save(); |
| 29 | |
| 30 | /* |
| 31 | ** Mapping of /json/user/XXX commands/paths to callbacks. |
| 32 | */ |
| 33 | static const JsonPageDef JsonPageDefs_User[] = { |
| @@ -41,19 +41,19 @@ | |
| 41 | |
| 42 | /* |
| 43 | ** Implements the /json/user family of pages/commands. |
| 44 | ** |
| 45 | */ |
| 46 | cson_value * json_page_user(){ |
| 47 | return json_page_dispatch_helper(&JsonPageDefs_User[0]); |
| 48 | } |
| 49 | |
| 50 | |
| 51 | /* |
| 52 | ** Impl of /json/user/list. Requires admin/setup rights. |
| 53 | */ |
| 54 | static cson_value * json_user_list(){ |
| 55 | cson_value * payV = NULL; |
| 56 | Stmt q; |
| 57 | if(!g.perm.Admin && !g.perm.Setup){ |
| 58 | json_set_err(FSL_JSON_E_DENIED, |
| 59 | "Requires 'a' or 's' privileges."); |
| @@ -122,11 +122,11 @@ | |
| 122 | |
| 123 | |
| 124 | /* |
| 125 | ** Impl of /json/user/get. Requires admin or setup rights. |
| 126 | */ |
| 127 | static cson_value * json_user_get(){ |
| 128 | cson_value * payV = NULL; |
| 129 | char const * pUser = NULL; |
| 130 | if(!g.perm.Admin && !g.perm.Setup){ |
| 131 | json_set_err(FSL_JSON_E_DENIED, |
| 132 | "Requires 'a' or 's' privileges."); |
| @@ -393,11 +393,11 @@ | |
| 393 | |
| 394 | |
| 395 | /* |
| 396 | ** Impl of /json/user/save. |
| 397 | */ |
| 398 | static cson_value * json_user_save(){ |
| 399 | /* try to get user info from GET/CLI args and construct |
| 400 | a JSON form of it... */ |
| 401 | cson_object * u = cson_new_object(); |
| 402 | char const * str = NULL; |
| 403 | int b = -1; |
| 404 |
| --- src/json_user.c | |
| +++ src/json_user.c | |
| @@ -21,13 +21,13 @@ | |
| 21 | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | static cson_value * json_user_get(void); |
| 27 | static cson_value * json_user_list(void); |
| 28 | static cson_value * json_user_save(void); |
| 29 | |
| 30 | /* |
| 31 | ** Mapping of /json/user/XXX commands/paths to callbacks. |
| 32 | */ |
| 33 | static const JsonPageDef JsonPageDefs_User[] = { |
| @@ -41,19 +41,19 @@ | |
| 41 | |
| 42 | /* |
| 43 | ** Implements the /json/user family of pages/commands. |
| 44 | ** |
| 45 | */ |
| 46 | cson_value * json_page_user(void){ |
| 47 | return json_page_dispatch_helper(&JsonPageDefs_User[0]); |
| 48 | } |
| 49 | |
| 50 | |
| 51 | /* |
| 52 | ** Impl of /json/user/list. Requires admin/setup rights. |
| 53 | */ |
| 54 | static cson_value * json_user_list(void){ |
| 55 | cson_value * payV = NULL; |
| 56 | Stmt q; |
| 57 | if(!g.perm.Admin && !g.perm.Setup){ |
| 58 | json_set_err(FSL_JSON_E_DENIED, |
| 59 | "Requires 'a' or 's' privileges."); |
| @@ -122,11 +122,11 @@ | |
| 122 | |
| 123 | |
| 124 | /* |
| 125 | ** Impl of /json/user/get. Requires admin or setup rights. |
| 126 | */ |
| 127 | static cson_value * json_user_get(void){ |
| 128 | cson_value * payV = NULL; |
| 129 | char const * pUser = NULL; |
| 130 | if(!g.perm.Admin && !g.perm.Setup){ |
| 131 | json_set_err(FSL_JSON_E_DENIED, |
| 132 | "Requires 'a' or 's' privileges."); |
| @@ -393,11 +393,11 @@ | |
| 393 | |
| 394 | |
| 395 | /* |
| 396 | ** Impl of /json/user/save. |
| 397 | */ |
| 398 | static cson_value * json_user_save(void){ |
| 399 | /* try to get user info from GET/CLI args and construct |
| 400 | a JSON form of it... */ |
| 401 | cson_object * u = cson_new_object(); |
| 402 | char const * str = NULL; |
| 403 | int b = -1; |
| 404 |
+13
-13
| --- src/json_wiki.c | ||
| +++ src/json_wiki.c | ||
| @@ -21,16 +21,16 @@ | ||
| 21 | 21 | |
| 22 | 22 | #if INTERFACE |
| 23 | 23 | #include "json_detail.h" |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | -static cson_value * json_wiki_create(); | |
| 27 | -static cson_value * json_wiki_get(); | |
| 28 | -static cson_value * json_wiki_list(); | |
| 29 | -static cson_value * json_wiki_preview(); | |
| 30 | -static cson_value * json_wiki_save(); | |
| 31 | -static cson_value * json_wiki_diff(); | |
| 26 | +static cson_value * json_wiki_create(void); | |
| 27 | +static cson_value * json_wiki_get(void); | |
| 28 | +static cson_value * json_wiki_list(void); | |
| 29 | +static cson_value * json_wiki_preview(void); | |
| 30 | +static cson_value * json_wiki_save(void); | |
| 31 | +static cson_value * json_wiki_diff(void); | |
| 32 | 32 | /* |
| 33 | 33 | ** Mapping of /json/wiki/XXX commands/paths to callbacks. |
| 34 | 34 | */ |
| 35 | 35 | static const JsonPageDef JsonPageDefs_Wiki[] = { |
| 36 | 36 | {"create", json_wiki_create, 0}, |
| @@ -47,11 +47,11 @@ | ||
| 47 | 47 | |
| 48 | 48 | /* |
| 49 | 49 | ** Implements the /json/wiki family of pages/commands. |
| 50 | 50 | ** |
| 51 | 51 | */ |
| 52 | -cson_value * json_page_wiki(){ | |
| 52 | +cson_value * json_page_wiki(void){ | |
| 53 | 53 | return json_page_dispatch_helper(JsonPageDefs_Wiki); |
| 54 | 54 | } |
| 55 | 55 | |
| 56 | 56 | /* |
| 57 | 57 | ** Returns the UUID for the given wiki blob RID, or NULL if not |
| @@ -244,11 +244,11 @@ | ||
| 244 | 244 | |
| 245 | 245 | /* |
| 246 | 246 | ** Implementation of /json/wiki/get. |
| 247 | 247 | ** |
| 248 | 248 | */ |
| 249 | -static cson_value * json_wiki_get(){ | |
| 249 | +static cson_value * json_wiki_get(void){ | |
| 250 | 250 | char const * zPageName; |
| 251 | 251 | char const * zSymName = NULL; |
| 252 | 252 | int contentFormat = -1; |
| 253 | 253 | if( !g.perm.RdWiki && !g.perm.Read ){ |
| 254 | 254 | json_set_err(FSL_JSON_E_DENIED, |
| @@ -274,11 +274,11 @@ | ||
| 274 | 274 | } |
| 275 | 275 | |
| 276 | 276 | /* |
| 277 | 277 | ** Implementation of /json/wiki/preview. |
| 278 | 278 | */ |
| 279 | -static cson_value * json_wiki_preview(){ | |
| 279 | +static cson_value * json_wiki_preview(void){ | |
| 280 | 280 | char const * zContent = NULL; |
| 281 | 281 | char const * zMime = NULL; |
| 282 | 282 | cson_string * sContent = NULL; |
| 283 | 283 | cson_value * pay = NULL; |
| 284 | 284 | Blob contentOrig = empty_blob; |
| @@ -449,26 +449,26 @@ | ||
| 449 | 449 | } |
| 450 | 450 | |
| 451 | 451 | /* |
| 452 | 452 | ** Implementation of /json/wiki/create. |
| 453 | 453 | */ |
| 454 | -static cson_value * json_wiki_create(){ | |
| 454 | +static cson_value * json_wiki_create(void){ | |
| 455 | 455 | return json_wiki_create_or_save(1,0); |
| 456 | 456 | } |
| 457 | 457 | |
| 458 | 458 | /* |
| 459 | 459 | ** Implementation of /json/wiki/save. |
| 460 | 460 | */ |
| 461 | -static cson_value * json_wiki_save(){ | |
| 461 | +static cson_value * json_wiki_save(void){ | |
| 462 | 462 | char const createIfNotExists = json_getenv_bool("createIfNotExists",0); |
| 463 | 463 | return json_wiki_create_or_save(0,createIfNotExists); |
| 464 | 464 | } |
| 465 | 465 | |
| 466 | 466 | /* |
| 467 | 467 | ** Implementation of /json/wiki/list. |
| 468 | 468 | */ |
| 469 | -static cson_value * json_wiki_list(){ | |
| 469 | +static cson_value * json_wiki_list(void){ | |
| 470 | 470 | cson_value * listV = NULL; |
| 471 | 471 | cson_array * list = NULL; |
| 472 | 472 | char const * zGlob = NULL; |
| 473 | 473 | Stmt q = empty_Stmt; |
| 474 | 474 | Blob sql = empty_blob; |
| @@ -531,11 +531,11 @@ | ||
| 531 | 531 | end: |
| 532 | 532 | db_finalize(&q); |
| 533 | 533 | return listV; |
| 534 | 534 | } |
| 535 | 535 | |
| 536 | -static cson_value * json_wiki_diff(){ | |
| 536 | +static cson_value * json_wiki_diff(void){ | |
| 537 | 537 | char const * zV1 = NULL; |
| 538 | 538 | char const * zV2 = NULL; |
| 539 | 539 | cson_object * pay = NULL; |
| 540 | 540 | int argPos = g.json.dispatchDepth; |
| 541 | 541 | int r1 = 0, r2 = 0; |
| 542 | 542 | |
| 543 | 543 | ADDED www/json-api/api-settings.md |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -21,16 +21,16 @@ | |
| 21 | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | static cson_value * json_wiki_create(); |
| 27 | static cson_value * json_wiki_get(); |
| 28 | static cson_value * json_wiki_list(); |
| 29 | static cson_value * json_wiki_preview(); |
| 30 | static cson_value * json_wiki_save(); |
| 31 | static cson_value * json_wiki_diff(); |
| 32 | /* |
| 33 | ** Mapping of /json/wiki/XXX commands/paths to callbacks. |
| 34 | */ |
| 35 | static const JsonPageDef JsonPageDefs_Wiki[] = { |
| 36 | {"create", json_wiki_create, 0}, |
| @@ -47,11 +47,11 @@ | |
| 47 | |
| 48 | /* |
| 49 | ** Implements the /json/wiki family of pages/commands. |
| 50 | ** |
| 51 | */ |
| 52 | cson_value * json_page_wiki(){ |
| 53 | return json_page_dispatch_helper(JsonPageDefs_Wiki); |
| 54 | } |
| 55 | |
| 56 | /* |
| 57 | ** Returns the UUID for the given wiki blob RID, or NULL if not |
| @@ -244,11 +244,11 @@ | |
| 244 | |
| 245 | /* |
| 246 | ** Implementation of /json/wiki/get. |
| 247 | ** |
| 248 | */ |
| 249 | static cson_value * json_wiki_get(){ |
| 250 | char const * zPageName; |
| 251 | char const * zSymName = NULL; |
| 252 | int contentFormat = -1; |
| 253 | if( !g.perm.RdWiki && !g.perm.Read ){ |
| 254 | json_set_err(FSL_JSON_E_DENIED, |
| @@ -274,11 +274,11 @@ | |
| 274 | } |
| 275 | |
| 276 | /* |
| 277 | ** Implementation of /json/wiki/preview. |
| 278 | */ |
| 279 | static cson_value * json_wiki_preview(){ |
| 280 | char const * zContent = NULL; |
| 281 | char const * zMime = NULL; |
| 282 | cson_string * sContent = NULL; |
| 283 | cson_value * pay = NULL; |
| 284 | Blob contentOrig = empty_blob; |
| @@ -449,26 +449,26 @@ | |
| 449 | } |
| 450 | |
| 451 | /* |
| 452 | ** Implementation of /json/wiki/create. |
| 453 | */ |
| 454 | static cson_value * json_wiki_create(){ |
| 455 | return json_wiki_create_or_save(1,0); |
| 456 | } |
| 457 | |
| 458 | /* |
| 459 | ** Implementation of /json/wiki/save. |
| 460 | */ |
| 461 | static cson_value * json_wiki_save(){ |
| 462 | char const createIfNotExists = json_getenv_bool("createIfNotExists",0); |
| 463 | return json_wiki_create_or_save(0,createIfNotExists); |
| 464 | } |
| 465 | |
| 466 | /* |
| 467 | ** Implementation of /json/wiki/list. |
| 468 | */ |
| 469 | static cson_value * json_wiki_list(){ |
| 470 | cson_value * listV = NULL; |
| 471 | cson_array * list = NULL; |
| 472 | char const * zGlob = NULL; |
| 473 | Stmt q = empty_Stmt; |
| 474 | Blob sql = empty_blob; |
| @@ -531,11 +531,11 @@ | |
| 531 | end: |
| 532 | db_finalize(&q); |
| 533 | return listV; |
| 534 | } |
| 535 | |
| 536 | static cson_value * json_wiki_diff(){ |
| 537 | char const * zV1 = NULL; |
| 538 | char const * zV2 = NULL; |
| 539 | cson_object * pay = NULL; |
| 540 | int argPos = g.json.dispatchDepth; |
| 541 | int r1 = 0, r2 = 0; |
| 542 | |
| 543 | DDED www/json-api/api-settings.md |
| --- src/json_wiki.c | |
| +++ src/json_wiki.c | |
| @@ -21,16 +21,16 @@ | |
| 21 | |
| 22 | #if INTERFACE |
| 23 | #include "json_detail.h" |
| 24 | #endif |
| 25 | |
| 26 | static cson_value * json_wiki_create(void); |
| 27 | static cson_value * json_wiki_get(void); |
| 28 | static cson_value * json_wiki_list(void); |
| 29 | static cson_value * json_wiki_preview(void); |
| 30 | static cson_value * json_wiki_save(void); |
| 31 | static cson_value * json_wiki_diff(void); |
| 32 | /* |
| 33 | ** Mapping of /json/wiki/XXX commands/paths to callbacks. |
| 34 | */ |
| 35 | static const JsonPageDef JsonPageDefs_Wiki[] = { |
| 36 | {"create", json_wiki_create, 0}, |
| @@ -47,11 +47,11 @@ | |
| 47 | |
| 48 | /* |
| 49 | ** Implements the /json/wiki family of pages/commands. |
| 50 | ** |
| 51 | */ |
| 52 | cson_value * json_page_wiki(void){ |
| 53 | return json_page_dispatch_helper(JsonPageDefs_Wiki); |
| 54 | } |
| 55 | |
| 56 | /* |
| 57 | ** Returns the UUID for the given wiki blob RID, or NULL if not |
| @@ -244,11 +244,11 @@ | |
| 244 | |
| 245 | /* |
| 246 | ** Implementation of /json/wiki/get. |
| 247 | ** |
| 248 | */ |
| 249 | static cson_value * json_wiki_get(void){ |
| 250 | char const * zPageName; |
| 251 | char const * zSymName = NULL; |
| 252 | int contentFormat = -1; |
| 253 | if( !g.perm.RdWiki && !g.perm.Read ){ |
| 254 | json_set_err(FSL_JSON_E_DENIED, |
| @@ -274,11 +274,11 @@ | |
| 274 | } |
| 275 | |
| 276 | /* |
| 277 | ** Implementation of /json/wiki/preview. |
| 278 | */ |
| 279 | static cson_value * json_wiki_preview(void){ |
| 280 | char const * zContent = NULL; |
| 281 | char const * zMime = NULL; |
| 282 | cson_string * sContent = NULL; |
| 283 | cson_value * pay = NULL; |
| 284 | Blob contentOrig = empty_blob; |
| @@ -449,26 +449,26 @@ | |
| 449 | } |
| 450 | |
| 451 | /* |
| 452 | ** Implementation of /json/wiki/create. |
| 453 | */ |
| 454 | static cson_value * json_wiki_create(void){ |
| 455 | return json_wiki_create_or_save(1,0); |
| 456 | } |
| 457 | |
| 458 | /* |
| 459 | ** Implementation of /json/wiki/save. |
| 460 | */ |
| 461 | static cson_value * json_wiki_save(void){ |
| 462 | char const createIfNotExists = json_getenv_bool("createIfNotExists",0); |
| 463 | return json_wiki_create_or_save(0,createIfNotExists); |
| 464 | } |
| 465 | |
| 466 | /* |
| 467 | ** Implementation of /json/wiki/list. |
| 468 | */ |
| 469 | static cson_value * json_wiki_list(void){ |
| 470 | cson_value * listV = NULL; |
| 471 | cson_array * list = NULL; |
| 472 | char const * zGlob = NULL; |
| 473 | Stmt q = empty_Stmt; |
| 474 | Blob sql = empty_blob; |
| @@ -531,11 +531,11 @@ | |
| 531 | end: |
| 532 | db_finalize(&q); |
| 533 | return listV; |
| 534 | } |
| 535 | |
| 536 | static cson_value * json_wiki_diff(void){ |
| 537 | char const * zV1 = NULL; |
| 538 | char const * zV2 = NULL; |
| 539 | cson_object * pay = NULL; |
| 540 | int argPos = g.json.dispatchDepth; |
| 541 | int r1 = 0, r2 = 0; |
| 542 | |
| 543 | DDED www/json-api/api-settings.md |
+127
| --- a/www/json-api/api-settings.md | ||
| +++ b/www/json-api/api-settings.md | ||
| @@ -0,0 +1,127 @@ | ||
| 1 | +# JSON API: /settings | |
| 2 | +([⬑JSON API Index](index.md)) | |
| 3 | + | |
| 4 | +Jump to: | |
| 5 | + | |
| 6 | +* [Fetch Settings](#get) | |
| 7 | +* [Set Settings](#set) | |
| 8 | + | |
| 9 | +--- | |
| 10 | + | |
| 11 | +<a id="get"></a> | |
| 12 | +# Fetch Settings | |
| 13 | + | |
| 14 | +**Status:** Implemented 20230120 | |
| 15 | + | |
| 16 | +**Required permissions:** "o" | |
| 17 | + | |
| 18 | +**Request:** `/json/settings/get[?version=X]` | |
| 19 | + | |
| 20 | +**Response payload example:** | |
| 21 | + | |
| 22 | +```json | |
| 23 | +{ | |
| 24 | + "access-log":{ | |
| 25 | + "versionable":false, | |
| 26 | + "sensitive":false, | |
| 27 | + "defaultValue":"off", | |
| 28 | + "valueSource":null, | |
| 29 | + "value":null | |
| 30 | + }, | |
| 31 | +... | |
| 32 | + "binary-glob":{ | |
| 33 | + "versionable":true, | |
| 34 | + "sensitive":false, | |
| 35 | + "defaultValue":null, | |
| 36 | + "valueSource":"versioned", | |
| 37 | + "value":"*.gif\n*.ico\n*.jpg\n*.odp\n*.dia\n*.pdf\n*.png\n*.wav..." | |
| 38 | + }, | |
| 39 | +... | |
| 40 | + "web-browser":{ | |
| 41 | + "versionable":false, | |
| 42 | + "sensitive":true, | |
| 43 | + "defaultValue":null, | |
| 44 | + "valueSource":"repo", | |
| 45 | + "value":"firefox" | |
| 46 | + } | |
| 47 | +} | |
| 48 | +``` | |
| 49 | + | |
| 50 | +Each key in the payload is the name of a fossil-recognized setting, | |
| 51 | +modeled as an object. The keys of that are: | |
| 52 | + | |
| 53 | + | |
| 54 | +- `defaultValue`: the setting's default value, or `null` if no default | |
| 55 | + is defined. | |
| 56 | +- `value`: The current value of that setting. | |
| 57 | +- `valueSource`: one of (`"repo"`, `"checkout"`, `"versioned"`, or | |
| 58 | + `null`), specifying the data source where the setting was found. The | |
| 59 | + settings sources are checked in this order and the first one found | |
| 60 | + is the result: | |
| 61 | + - If `version=X` is provided, check-in `X` is searched for a | |
| 62 | + versionable-settings file. If found, its value is used and | |
| 63 | + `valueSource` will be `"versioned"`. If `X` is not a checkin, an | |
| 64 | + error response is produced with code `FOSSIL-3006`. | |
| 65 | + - If a versionable setting is found in the current checkout, its | |
| 66 | + value is used and `valueSource` will be `"versioned"` | |
| 67 | + - If the setting is found in checkout database's `vvar` table, its | |
| 68 | + value is used and `valueSource` will be `"checkout"`. | |
| 69 | + - If the setting is found in repository's `config` table, its | |
| 70 | + value is used and `valueSource` will be `"repo"`. | |
| 71 | + - If no value is found, `null` is used for both the `value` and | |
| 72 | + `valueSource` results. Note that _global settings are never | |
| 73 | + checked_ because they can leak information which have nothing | |
| 74 | + specifically to do with the given repository. | |
| 75 | +- `sensitive`: a value which fossil has flagged as sensitive can only | |
| 76 | + be fetched by a Setup user. For other users, they will always have | |
| 77 | + a `value` and `valueSource` of `null`. | |
| 78 | +- `versionable`: `true` if the setting is tagged as versionable, else | |
| 79 | + `false`. | |
| 80 | + | |
| 81 | +Note that settings are internally stored as strings, even if they're | |
| 82 | +semantically treated as numbers. The way settings are stored and | |
| 83 | +handled does not give us enough information to recognize their exact | |
| 84 | +data type here so they are passed on as-is. | |
| 85 | + | |
| 86 | + | |
| 87 | +<a id="set"></a> | |
| 88 | +# Set Settings | |
| 89 | + | |
| 90 | +**Status:** Implemented 20230120 | |
| 91 | + | |
| 92 | +**Required permissions:** "s" | |
| 93 | + | |
| 94 | +**Request:** `/json/settings/set` | |
| 95 | + | |
| 96 | +This call requires that the input payload be an object containing a | |
| 97 | +mapping of fossil-known configuration keys (case-sensitive) to | |
| 98 | +values. For example: | |
| 99 | + | |
| 100 | +```json | |
| 101 | +{ | |
| 102 | + "editor": "emacs", | |
| 103 | + "admin-log": true, | |
| 104 | + "auto-captcha": false | |
| 105 | +} | |
| 106 | +``` | |
| 107 | + | |
| 108 | +It iterates through each property, which must have a data type of | |
| 109 | +`null`, boolean, number, or string. A value of `null` _unsets_ | |
| 110 | +(deletes) the setting. Boolean values are stored as integer 0 | |
| 111 | +or 1. All other types are stored as-is. It only updates the | |
| 112 | +`repository.config` database and never updates a checkout or global | |
| 113 | +config database, nor is it capable of updating versioned settings | |
| 114 | +(^Updating versioned settings requires creating a full check-in.). | |
| 115 | + | |
| 116 | +It has no result payload but this may be changed in the future it | |
| 117 | +practice shows that it should return something specific. | |
| 118 | + | |
| 119 | +Error responses include: | |
| 120 | + | |
| 121 | +- `FOSSIL-2002`: called without "setup" permissions. | |
| 122 | +- `FOSSIL-3002`: called without a payload object. | |
| 123 | +- `FOSSIL-3001`: passed an unknown config option. | |
| 124 | +- `FOSSIL-3000`: a value has an unsupported data type. | |
| 125 | + | |
| 126 | +If an error is triggered, any settings made by this call up until that | |
| 127 | +point are discarded. |
| --- a/www/json-api/api-settings.md | |
| +++ b/www/json-api/api-settings.md | |
| @@ -0,0 +1,127 @@ | |
| --- a/www/json-api/api-settings.md | |
| +++ b/www/json-api/api-settings.md | |
| @@ -0,0 +1,127 @@ | |
| 1 | # JSON API: /settings |
| 2 | ([⬑JSON API Index](index.md)) |
| 3 | |
| 4 | Jump to: |
| 5 | |
| 6 | * [Fetch Settings](#get) |
| 7 | * [Set Settings](#set) |
| 8 | |
| 9 | --- |
| 10 | |
| 11 | <a id="get"></a> |
| 12 | # Fetch Settings |
| 13 | |
| 14 | **Status:** Implemented 20230120 |
| 15 | |
| 16 | **Required permissions:** "o" |
| 17 | |
| 18 | **Request:** `/json/settings/get[?version=X]` |
| 19 | |
| 20 | **Response payload example:** |
| 21 | |
| 22 | ```json |
| 23 | { |
| 24 | "access-log":{ |
| 25 | "versionable":false, |
| 26 | "sensitive":false, |
| 27 | "defaultValue":"off", |
| 28 | "valueSource":null, |
| 29 | "value":null |
| 30 | }, |
| 31 | ... |
| 32 | "binary-glob":{ |
| 33 | "versionable":true, |
| 34 | "sensitive":false, |
| 35 | "defaultValue":null, |
| 36 | "valueSource":"versioned", |
| 37 | "value":"*.gif\n*.ico\n*.jpg\n*.odp\n*.dia\n*.pdf\n*.png\n*.wav..." |
| 38 | }, |
| 39 | ... |
| 40 | "web-browser":{ |
| 41 | "versionable":false, |
| 42 | "sensitive":true, |
| 43 | "defaultValue":null, |
| 44 | "valueSource":"repo", |
| 45 | "value":"firefox" |
| 46 | } |
| 47 | } |
| 48 | ``` |
| 49 | |
| 50 | Each key in the payload is the name of a fossil-recognized setting, |
| 51 | modeled as an object. The keys of that are: |
| 52 | |
| 53 | |
| 54 | - `defaultValue`: the setting's default value, or `null` if no default |
| 55 | is defined. |
| 56 | - `value`: The current value of that setting. |
| 57 | - `valueSource`: one of (`"repo"`, `"checkout"`, `"versioned"`, or |
| 58 | `null`), specifying the data source where the setting was found. The |
| 59 | settings sources are checked in this order and the first one found |
| 60 | is the result: |
| 61 | - If `version=X` is provided, check-in `X` is searched for a |
| 62 | versionable-settings file. If found, its value is used and |
| 63 | `valueSource` will be `"versioned"`. If `X` is not a checkin, an |
| 64 | error response is produced with code `FOSSIL-3006`. |
| 65 | - If a versionable setting is found in the current checkout, its |
| 66 | value is used and `valueSource` will be `"versioned"` |
| 67 | - If the setting is found in checkout database's `vvar` table, its |
| 68 | value is used and `valueSource` will be `"checkout"`. |
| 69 | - If the setting is found in repository's `config` table, its |
| 70 | value is used and `valueSource` will be `"repo"`. |
| 71 | - If no value is found, `null` is used for both the `value` and |
| 72 | `valueSource` results. Note that _global settings are never |
| 73 | checked_ because they can leak information which have nothing |
| 74 | specifically to do with the given repository. |
| 75 | - `sensitive`: a value which fossil has flagged as sensitive can only |
| 76 | be fetched by a Setup user. For other users, they will always have |
| 77 | a `value` and `valueSource` of `null`. |
| 78 | - `versionable`: `true` if the setting is tagged as versionable, else |
| 79 | `false`. |
| 80 | |
| 81 | Note that settings are internally stored as strings, even if they're |
| 82 | semantically treated as numbers. The way settings are stored and |
| 83 | handled does not give us enough information to recognize their exact |
| 84 | data type here so they are passed on as-is. |
| 85 | |
| 86 | |
| 87 | <a id="set"></a> |
| 88 | # Set Settings |
| 89 | |
| 90 | **Status:** Implemented 20230120 |
| 91 | |
| 92 | **Required permissions:** "s" |
| 93 | |
| 94 | **Request:** `/json/settings/set` |
| 95 | |
| 96 | This call requires that the input payload be an object containing a |
| 97 | mapping of fossil-known configuration keys (case-sensitive) to |
| 98 | values. For example: |
| 99 | |
| 100 | ```json |
| 101 | { |
| 102 | "editor": "emacs", |
| 103 | "admin-log": true, |
| 104 | "auto-captcha": false |
| 105 | } |
| 106 | ``` |
| 107 | |
| 108 | It iterates through each property, which must have a data type of |
| 109 | `null`, boolean, number, or string. A value of `null` _unsets_ |
| 110 | (deletes) the setting. Boolean values are stored as integer 0 |
| 111 | or 1. All other types are stored as-is. It only updates the |
| 112 | `repository.config` database and never updates a checkout or global |
| 113 | config database, nor is it capable of updating versioned settings |
| 114 | (^Updating versioned settings requires creating a full check-in.). |
| 115 | |
| 116 | It has no result payload but this may be changed in the future it |
| 117 | practice shows that it should return something specific. |
| 118 | |
| 119 | Error responses include: |
| 120 | |
| 121 | - `FOSSIL-2002`: called without "setup" permissions. |
| 122 | - `FOSSIL-3002`: called without a payload object. |
| 123 | - `FOSSIL-3001`: passed an unknown config option. |
| 124 | - `FOSSIL-3000`: a value has an unsupported data type. |
| 125 | |
| 126 | If an error is triggered, any settings made by this call up until that |
| 127 | point are discarded. |
| --- www/json-api/index.md | ||
| +++ www/json-api/index.md | ||
| @@ -28,10 +28,11 @@ | ||
| 28 | 28 | * [Diffs](api-diff.md) |
| 29 | 29 | * [Directory Listing](api-dir.md) |
| 30 | 30 | * [File Info](api-finfo.md) |
| 31 | 31 | * [The Obligatory Misc. Category](api-misc.md) |
| 32 | 32 | * [Repository Stats](api-stat.md) |
| 33 | +* [Settings](api-settings.md) | |
| 33 | 34 | * [SQL Query](api-query.md) |
| 34 | 35 | * [Tags](api-tag.md) |
| 35 | 36 | * [Tickets](api-ticket.md) |
| 36 | 37 | * [Timeline](api-timeline.md) |
| 37 | 38 | * [User Management](api-user.md) |
| 38 | 39 |
| --- www/json-api/index.md | |
| +++ www/json-api/index.md | |
| @@ -28,10 +28,11 @@ | |
| 28 | * [Diffs](api-diff.md) |
| 29 | * [Directory Listing](api-dir.md) |
| 30 | * [File Info](api-finfo.md) |
| 31 | * [The Obligatory Misc. Category](api-misc.md) |
| 32 | * [Repository Stats](api-stat.md) |
| 33 | * [SQL Query](api-query.md) |
| 34 | * [Tags](api-tag.md) |
| 35 | * [Tickets](api-ticket.md) |
| 36 | * [Timeline](api-timeline.md) |
| 37 | * [User Management](api-user.md) |
| 38 |
| --- www/json-api/index.md | |
| +++ www/json-api/index.md | |
| @@ -28,10 +28,11 @@ | |
| 28 | * [Diffs](api-diff.md) |
| 29 | * [Directory Listing](api-dir.md) |
| 30 | * [File Info](api-finfo.md) |
| 31 | * [The Obligatory Misc. Category](api-misc.md) |
| 32 | * [Repository Stats](api-stat.md) |
| 33 | * [Settings](api-settings.md) |
| 34 | * [SQL Query](api-query.md) |
| 35 | * [Tags](api-tag.md) |
| 36 | * [Tickets](api-ticket.md) |
| 37 | * [Timeline](api-timeline.md) |
| 38 | * [User Management](api-user.md) |
| 39 |