char *webhook_exec( webhooks_data_t *wh_data, char *wh_endpoint ){ if ( wh_data->webhooks_parsed == NULL ) return "Error: webhooks haven't been parsed"; wh_data->wh_exec_data = cJSON_GetObjectItemCaseSensitive( wh_data->webhooks_parsed, wh_endpoint ); if ( wh_data->wh_exec_data == NULL ) return "Error: no such webhook found"; wh_data->wh_command = cJSON_GetObjectItemCaseSensitive( wh_data->wh_exec_data, "cmd" ); if ( wh_data->wh_command == NULL || (uint64_t)strlen(wh_data->wh_command->valuestring) <= 0 ){ wh_data->wh_exec_data = NULL; return "Error: no command set for given webhook"; } wh_data->wh_response = cJSON_GetObjectItemCaseSensitive( wh_data->wh_exec_data, "response" ); if ( wh_data->wh_response == NULL || (uint64_t)strlen(wh_data->wh_response->valuestring) <= 0 ){ wh_data->wh_command = NULL; wh_data->wh_exec_data = NULL; return "Error: no response specified"; } if ( strcmp((const char*)wh_data->wh_response->valuestring, "output") != 0 ){ system( wh_data->wh_command->valuestring ); wh_data->wh_command = NULL; wh_data->wh_exec_data = NULL; return wh_data->wh_response->valuestring; } wh_data->wh_response = NULL; wh_data->wh_output = (char*)calloc( (size_t)MAX_WEBHOOK_OUTPUT_LENGTH, sizeof(char) ); if ( wh_data->wh_output == NULL ){ wh_data->wh_command = NULL; wh_data->wh_output = NULL; return "Error: failed to allocate memory for command output"; } FILE *wh_proc = popen( wh_data->wh_command->valuestring, "r" ); if ( wh_proc == NULL ){ free( wh_data->wh_output ); wh_data->wh_output = NULL; wh_data->wh_command = NULL; wh_data->wh_exec_data = NULL; return "Error: failed to execute webhook command"; } size_t read_bytes = 0; char *current_line = (char*)calloc( 8192, sizeof(char) ); if ( current_line == NULL ){ free( wh_data->wh_output ); wh_data->wh_output = NULL; wh_data->wh_command = NULL; wh_data->wh_exec_data = NULL; return "Error: failed to allocate memory for reading command output"; } while ( fgets(current_line, (size_t)(8192 * sizeof(char)), wh_proc) != NULL ){ if ( (size_t)((size_t)strnlen(current_line, (size_t)(8192 * sizeof(char))) + read_bytes) > (size_t)MAX_WEBHOOK_OUTPUT_LENGTH ) break; strncat( wh_data->wh_output, current_line, (size_t)strnlen(current_line, (size_t)(8192 * sizeof(char))) ); read_bytes += (size_t)strnlen( current_line, (size_t)(8192 * sizeof(char)) ); memset( current_line, 0, (size_t)(8192 * sizeof(char)) ); } free( current_line ); pclose( wh_proc ); if ( wh_data->wh_output == NULL || (size_t)strnlen(wh_data->wh_output, (size_t)MAX_WEBHOOK_OUTPUT_LENGTH) <= 0 ) return "Error: failed to get output"; return wh_data->wh_output; } void free_wh_output( webhooks_data_t *hooksdata ){ if ( hooksdata->wh_output != NULL ){ free( hooksdata->wh_output ); hooksdata->wh_output = NULL; } if ( hooksdata->wh_response != NULL ) hooksdata->wh_response = NULL; return; }