I'm developing an application written in C to communicate with an API web server using libcurl. I parsed successfully some JSON responses but I failed to parse this one (the simplest one).
- Code
void auth_parser(char* serverResponse,struct ParsedAuthResponse *responseP)
{
char* json_text;
json_t *root;
json_error_t error;
const char* error_text=NULL;
const char* message_text=NULL;
json_text=malloc(strlen(serverResponse)+strlen("[]")+1);
if (!json_text)
{
printf( "not enough memory\n");
return ;
}
strcpy(json_text,"[");
json_text=strcat(json_text,serverResponse);
json_text=strcat(json_text,"]");
root = json_loads(json_text, 0, &error);
SCM_FREE(json_text);
if(!json_is_array(root))
{
printf( "error: on line %d: %s\n", error.line, error.text);
return;
}
json_t *error_obj,*message_obj;
data = json_array_get(root, 0);
if(!json_is_object(data))
{
printf("error1 \n");
json_decref(root);
}
else
{
printf("OK1 \n");
}
error_obj= json_object_get(data, "error");
if(error_obj)
{
if(!json_is_string(error_obj))
{
printf( "error2 \n");
json_decref(root);
}
else
{
error_text=json_string_value(error_obj);
printf("error_text=%s",error_text);
}
message_obj=json_object_get(data, "message");
if(!json_is_string(message_obj))
{
printf( "error3 \n");
json_decref(root);
}
else
{
message_text=json_string_value(message_obj);
printf("message_text=%s",message_text);
printf("OK3 \n");
}
}
return;
}
This is the JSON object to parse :
{"error":4,"message":"Authentication Failed - You do not have
permissions to access the service"}
It fails at error2
You are checking if the value of the error key is a string and it is failing because it is an integer.
Try replacing :
if(!json_is_string(error_obj))
with
if(!json_is_integer(error_obj))
Related
This code has one problem. The problem is in
Problem in if-statement
if(all_digits(to_find) && strlen(to_find) == 13)
Whenever I enter 13 characters but not from the file then it gives me a message of else statement but printing Found. Hello World! also. Although Found. Hello World! is in if-statement. It should not be printed. How to make if-statement work correctly?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int all_digits(char *s){
for (; *s!=0; s++){
if (!isdigit(*s)){
return 0;
}
}
return 1;
}
Another part of code
int main(){
FILE * fr = fopen("file.csv", "r");
char save[500], line[200], to_find[50];
int oneByOne = 0, numberOfFields=8;
char *word = NULL;
printf("Enter the ID card number: ");
scanf("%s", to_find);
if(all_digits(to_find) && strlen(to_find) == 13){
while(fgets(line, 200, fr)){
word = strtok(line, "\n");
strcpy(save, line);
if (strstr(save, to_find)){
char *wordone = strtok(save, ",");
while (wordone != NULL){
printf("Here are your details: %s\n", wordone);
wordone = strtok(NULL, ",");
}
}
}
fclose(fr);
printf("Found. Hello World!\n");
}
else {
printf("enter correclty\n");
}
return 0;
}
To run multiple tests without cascading if-thens you can use an error flag along with a one-time loop like so:
int err = 0; /* Be optimistic! (0 indicates success) */
do {
if (!test1-passed) {
err = 1;
break;
}
if (!test2-passed) {
err = 2;
break;
}
...
if (!testN-passed) {
err = N;
break;
}
printf("Success! All tests passed");
} while (0);
if (err) {
printf("Test %d failed", err);
}
Applied to you particular problem the code might look like this
... /* definitions here */
int err = 0; /* Be optimistic! (0 indicates success) */
do {
... /* input here */
do {
if (!all_digits(to_find)) {
err = 1;
break;
}
if (strlen(to_find) != 13) {
err = 2;
break;
}
{
err = 3 /* be pessimistic! */
while(fgets(line, 200, fr)){
/* word = strtok(line, "\n"); */ /* word is not needed. */
strcpy(save, line); /* Introducing save here is not necessary,
all following operation can be applied to line. */
if (strstr(save, to_find)){
char *wordone = strtok(save, ",");
while (wordone != NULL){
printf("Here are your details: %s\n", wordone);
wordone = strtok(NULL, ",");
err = 0; /* Phew, we are lucky! */
}
}
}
if (err) {
break;
}
}
printf("Success! All tests passed");
} while (0);
if (err) {
printf("Test %d failed", err);
}
} while (err);
I have written the following function which works for all parameters well rather than calling InteractiveCredentialDispathcer. When this function called, loop executed again from the top and doing all checks again. How should I fix this issue?
void InteractiveMode()
{
char commands[MAX_PATH] = { 0 };
PrintColorful(0, "%s", PTH_CMD);
while (fgets(commands, MAX_PATH - 1, stdin) != NULL)
{
if (strstr(commands, "help") || strstr(commands, "?"))
{
ShowHelpMessage();
}
else if (strstr(commands, "clear"))
{
ClearConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE));
}
else if (strstr(commands, "privilege"))
{
ShowPrivilegeStatus();
}
else if (strstr(commands, "login"))
{
if (InteractiveCredentialDispatcher())
{
NormalMessage("%s\n", "Process has been spawned successfully");
}
else
{
ErrorMessage("%s\n", "Process has not been spawned successfully");
}
}
else if (strstr(commands, "version"))
{
ShowProgramVersion();
}
else if (strstr(commands, "exit"))
{
NormalMessage("%s\n", "Program has been finished.");
ProgramExit();
}
else
{
printf("\n");
ErrorMessage("%s\n\n", "The command isn't appropriate:");
printf("\t");
NormalMessage("%s\n", "You entered a blank input or a wrong command.");
printf("\t");
NormalMessage("%s\n\n", "Execute help or ? command to see the manual.");
}
PrintColorful(0, "%s", PTH_CMD);
}
}
The following code called when the function InteractiveCredentialDispatcher executed:
BOOL InteractiveCredentialDispatcher()
{
TCHAR l_tc_Username[MAX_PATH];
TCHAR l_tc_Domain[MAX_PATH];
TCHAR l_tc_HashNtlm[MAX_PATH];
TCHAR l_tc_ComputerName[MAX_PATH];
TCHAR l_tc_ProcessName[MAX_PATH];
printf("\n\t");
WarningMessage("%s\n", "Fill following information:");
printf("\n\t\tUsername: ");
wscanf(L"%ls", l_tc_Username);
printf("\t\tDomain: ");
wscanf(L"%ls", l_tc_Domain);
printf("\t\tNTLM Hash: ");
wscanf(L"%ls", l_tc_HashNtlm);
printf("\t\tComputer Name: ");
wscanf(L"%ls", l_tc_ComputerName);
wcscpy(l_tc_ProcessName, TEXT("FM.exe "));
wcscat(l_tc_ProcessName, l_tc_ComputerName);
if (InteractiveAuthticationOnWindows(l_tc_Username, l_tc_Domain, l_tc_HashNtlm, l_tc_ProcessName))
return TRUE;
else
return FALSE;
}
The problem belonged to using scanf rather fgets in the function InteractiveCredentialDispatcher. I have solved the problem with the usage of just fgets and fgetws variant in the program. After that, while loop never executed twice.
BOOL InteractiveCredentialDispatcher()
{
TCHAR l_tc_Username[MAX_PATH];
TCHAR l_tc_Domain[MAX_PATH];
TCHAR l_tc_HashNtlm[MAX_PATH];
TCHAR l_tc_ComputerName[MAX_PATH];
TCHAR l_tc_ProcessName[MAX_PATH];
printf("\n\t");
WarningMessage("%s\n", "Fill following information:");
printf("\n\t\tUsername: ");
fgetstr(l_tc_Username, MAX_PATH, stdin);
printf("\t\tDomain: ");
fgetstr(l_tc_Domain, MAX_PATH, stdin);
printf("\t\tNTLM Hash: ");
fgetstr(l_tc_HashNtlm, MAX_PATH, stdin);
printf("\t\tComputer Name: ");
fgetstr(l_tc_ComputerName, MAX_PATH, stdin);
wcscpy(l_tc_ProcessName, TEXT("PTH-FileManager.exe "));
wcscat(l_tc_ProcessName, l_tc_ComputerName);
if (InteractiveAuthticationOnWindows(l_tc_Username, l_tc_Domain, l_tc_HashNtlm, l_tc_ProcessName))
{
return TRUE;
}
else
{
return FALSE;
}
}
I have a json file. And, the file is successfully loaded.
but, i would like to change the value such as below
and save the json file with the modification.
But, the value is not changed and saved at all.
How could i do?
from /home/pi/desktop/test.json
{
"new_one": 1,
"new_two" : "do not",
"new_three" : true
}
to /home/pi/desktop/test.json
{
"new_one": 234,
"new_two" : "do",
"new_three" : false
}
So, i did
int main()
{
json_t *json;
json_error_t error;
char *pos;
json_t *obj = json_object();
int rc =0 ;
json = json_load_file("./test.json", 0, &error);
if (!json)
{
fprintf(stderr, "process : json error on line %d: %s\n", error.line, error.text);
rc = 1;
}
const char *key;
json_t *value;
void *iter = json_object_iter( json );
while( iter )
{
key = json_object_iter_key(iter);
value = json_object_iter_value(iter);
if(!strcmp(key, "new_one")){
printf("Change Value\n" );
json_object_set(iter, "new_one", json_integer(1234));
}
if(!strcmp(key, "new_three")){
printf("Change Value\n" );
json_object_set(iter, "new_three", json_string("alert"));
}
iter = json_object_iter_next(json, iter);
}
return 0;
}
You are missing a call to json_dump_file(), which will save your modified JSON contents to file.
So, after your while() loop, add this:
rc = json_dump_file(json, "./test.json", 0);
if (rc) {
fprintf(stderr, "cannot save json to file\n");
}
I'm doing Kaa project.
First, i have used Data Collection demo and then do some modification to my sensor. The data is send to platform every seconds(i can configure it).
And now, i want to create some service which if i send request(using ulfius framework), my device upload 1 data.
My problem is, i have to do more than 10 request to upload data, how can i solve it. Please Help.
Below is some of my code :
int callback_kaa(const struct _u_request * request,struct _u_response * response, void * user_data){
kaa_client_send(kaa_client, &kaa_add_log_record, (void *)kaa_client);
ulfius_set_string_body_response(response, 200, "Hello Kaa!");}
int main(/*int argc, char *argv[]*/){
printf("DHT11 Logging Demo\n");
if (wiringPiSetup() == -1) {
printf("Failed to initialize Pi wiring\n");
exit(1);}
if (ulfius_init_instance(&instance, PORT, NULL, NULL) != U_OK) {
fprintf(stderr, "Error ulfius_init_instance, abort\n");
return(1);}
ulfius_add_endpoint_by_val(&instance, "POST", "/kaaplatform", NULL, 0,&callback_kaa, NULL);
kaa_error_t error_code = kaa_client_create(&kaa_client, NULL);
KAA_RETURN_IF_ERROR(error_code, "Failed create Kaa client");
kaa_log_bucket_constraints_t bucket_sizes = {
.max_bucket_size = MAX_LOG_BUCKET_SIZE,
.max_bucket_log_count = 1,};
error_code = ext_unlimited_log_storage_create(&log_storage_context,
kaa_client_get_context(kaa_client)->logger);
KAA_RETURN_IF_ERROR(error_code, "Failed to create unlimited log storage");
error_code = ext_log_upload_strategy_create(kaa_client_get_context(kaa_client), &log_upload_strategy_context, THRESHOLD_COUNT_FLAG);
KAA_RETURN_IF_ERROR(error_code, "Failed to create log upload strategy");
error_code = ext_log_upload_strategy_set_threshold_count(log_upload_strategy_context, KAA_UPLOAD_COUNT_THRESHOLD);
KAA_RETURN_IF_ERROR(error_code, "Failed to set threshold log record count");
error_code = kaa_logging_init(kaa_client_get_context(kaa_client)>log_collector
, log_storage_context
, log_upload_strategy_context
, &bucket_sizes);
KAA_RETURN_IF_ERROR(error_code, "Failed to init Kaa log collector");
kaa_channel_manager_set_auth_failure_handler(
kaa_client_get_context(kaa_client)->channel_manager,
auth_failure_handler, kaa_client);
const uint8_t *endpoint_key_hash = NULL;
size_t endpoint_key_hash_length = 0;
ext_get_sha1_base64_public(&endpoint_key_hash, &endpoint_key_hash_length);
printf("Endpoint Key Hash: %.*s\n", (int)endpoint_key_hash_length,endpoint_key_hash);
if (ulfius_start_framework(&instance) == U_OK) {
printf("Start framework on port %d\n", instance.port);
getchar();
} else {
fprintf(stderr, "Error starting framework\n");
}
kaa_client_destroy(kaa_client);
printf("Data analytics demo stopped\n");
ulfius_stop_framework(&instance);
ulfius_clean_instance(&instance);
return error_code;
}
and also, i create some function (kaa_client_send) at file kaa_client.h :
void kaa_client_send(kaa_client_t *kaa_client,external_process_fn external_process, void *external_process_context)
{
KAA_RETURN_IF_NIL(kaa_client, KAA_ERR_BADPARAM);
kaa_error_t error_code = kaa_check_readiness(kaa_client->kaa_context);
if (error_code != KAA_ERR_NONE) {
KAA_LOG_ERROR(kaa_client->kaa_context->logger, error_code, "Cannot start Kaa client: Kaa context is not fully initialized");
return error_code;
}
kaa_client->external_process_fn = external_process;
kaa_client->external_process_context = external_process_context;
kaa_client->external_process_max_delay = 5;
kaa_client->external_process_last_call = KAA_TIME();
KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE, "Starting Kaa client...");
if (kaa_client->external_process_fn) {
kaa_client->external_process_fn(kaa_client->external_process_context);
kaa_client->external_process_last_call = KAA_TIME();
}
//Check Kaa channel is ready to transmit something
if (kaa_process_failover(kaa_client->kaa_context)) {
kaa_client->boostrap_complete = false;
} else {
if (kaa_client->channel_id > 0) {
if (kaa_client->channel_state == KAA_CLIENT_CHANNEL_STATE_NOT_CONNECTED) {
error_code = kaa_client_process_channel_disconnected(kaa_client);
} else if (kaa_client->channel_state == KAA_CLIENT_CHANNEL_STATE_CONNECTED) {
error_code = kaa_client_process_channel_connected(kaa_client);
if (error_code == KAA_ERR_TIMEOUT)
kaa_client_deinit_channel(kaa_client);
}
} else {
//No initialized channels
if (kaa_client->boostrap_complete) {
KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE,
"Channel [0x%08X] Boostrap complete, reinitializing to Operations ...", kaa_client->channel_id);
kaa_client->boostrap_complete = false;
kaa_client_deinit_channel(kaa_client);
error_code = kaa_client_init_channel(kaa_client, KAA_CLIENT_CHANNEL_TYPE_OPERATIONS);
if (error_code == KAA_ERR_BAD_STATE) {
kaa_client_deinit_channel(kaa_client);
kaa_client->boostrap_complete = false;
}
} else {
KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE,
"Channel [0x%08X] Operations error, reinitializing to Bootstrap ...", kaa_client->channel_id);
kaa_client->boostrap_complete = true;
kaa_client_deinit_channel(kaa_client);
kaa_client_init_channel(kaa_client, KAA_CLIENT_CHANNEL_TYPE_BOOTSTRAP);
}
}
}
KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE, "Kaa client stopped");
return error_code;
}
char IP[32] = "";
char PORT[4] = "0000";
int read_conf()
{
int i;
char line[25] = "";
FILE *fp;
char *str_ptr;
fp = fopen("client.conf","r");
for(i=1;(fgets(line,sizeof(line),fp));i++)
{
if(1==i)
{
str_ptr = strstr(line,"IP:");
if(str_ptr)
{
strcpy(IP,(str_ptr+3));
}
else
{
printf("Error in fetching IP \n");
exit(0);
}
}
else if(2==i)
{
str_ptr = strstr(line,"Port:");
if(str_ptr)
{
strcpy(PORT,(str_ptr+5));
}
else
{
printf("Error in fetching PORT \n");
exit(0);
}
}
}
return 1;
}
char *construct_url(int n,char * const argv[])
{
char * final_url;
int i,k=2;
int j = 0;
final_url = malloc(sizeof(char *)*300);
strcpy(final_url,"http://");
strcat(final_url,IP);
strcat(final_url,":");
strcat(final_url,PORT);
strcat(final_url,"/");
//printf("%s",final_url);
for(i=1;i<n,k>0;i++,k--)
{
strcat(final_url,argv[i]);
if(i==1)
{
strcat(final_url,"/");
}
else
{
strcat(final_url,"?");
}
}
return final_url;
}
In my above code it is adding a newline after IP and PORT value which is not correct URL construction. how do I avoid new line before concatenation.
client.conf consist
IP:10.12.130.216
Port:5200
Expected Result:
http://10.12.130.216:5200/
Getting Result:
http://10.12.130.216
:5200
/
read_conf can be written in simple as follows using fscanf.
char PORT[6] = "00000";//0-65535
int read_conf(void){
FILE *fp = fopen("client.conf","r");
if(1 != fscanf(fp, "IP:%31s\n", IP)){
printf("Error in fetching IP \n");
exit(0);
}
if(1 != fscanf(fp, "Port:%5s", PORT)){
printf("Error in fetching PORT \n");
exit(0);
}
fclose(fp);
return 1;
}
If you are sure that it is a new line, use:
strcat(final_url,IP);
strtok(final_url, "\n");
strcat(final_url,":");
strcat(final_url,PORT);
strtok(final_url, "\n");
strcat(final_url,"/");
or use strtock function separately for IP and PORT strings.