github.com/swiftstack/ProxyFS@v0.0.0-20210203235616-4017c267d62f/jrpcfs/test/client_test.c (about) 1 // Copyright (c) 2015-2021, NVIDIA CORPORATION. 2 // SPDX-License-Identifier: Apache-2.0 3 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <unistd.h> 7 #include <string.h> 8 #include <sys/types.h> 9 #include <sys/socket.h> 10 #include <netinet/in.h> 11 #include <netdb.h> 12 #include <json-c/json.h> 13 14 void error(const char *msg) 15 { 16 perror(msg); 17 //exit(0); 18 } 19 20 static int sockfd = 0; 21 static int portno = 12345; 22 static char* hostname = "localhost"; 23 24 int sock_open() { 25 struct sockaddr_in serv_addr; 26 struct hostent *server; 27 28 sockfd = socket(AF_INET, SOCK_STREAM, 0); 29 if (sockfd < 0) { 30 error("ERROR opening socket"); 31 return -1; 32 } 33 //printf("socket %s:%d opened successfully.\n",hostname,portno); 34 server = gethostbyname(hostname); 35 if (server == NULL) { 36 printf("ERROR, no such host\n"); 37 return -1; 38 } 39 //printf("got server for hostname %s.\n",hostname); 40 bzero((char *) &serv_addr, sizeof(serv_addr)); 41 serv_addr.sin_family = AF_INET; 42 bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length); 43 serv_addr.sin_port = htons(portno); 44 45 if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) { 46 //printf("ERROR connecting"); 47 error("ERROR connecting"); 48 return -1; 49 } 50 51 return 0; 52 } 53 54 int sock_close() { 55 close(sockfd); 56 57 return 0; 58 } 59 60 int sock_read(char* buf) { 61 int n = read(sockfd,buf,255); 62 if (n < 0) { 63 error("ERROR reading from socket"); 64 return -1; 65 } 66 return 0; 67 } 68 69 int sock_write(const char* buf) { 70 int n = write(sockfd,buf,strlen(buf)); 71 if (n < 0) { 72 error("ERROR writing to socket"); 73 return -1; 74 } 75 return 0; 76 } 77 78 /*printing the value corresponding to boolean, double, integer and strings*/ 79 void print_json_object(struct json_object *jobj, const char *msg) { 80 printf("\n%s: \n", msg); 81 printf("---\n%s\n---\n", json_object_to_json_string(jobj)); 82 } 83 84 struct json_object * find_something(struct json_object *jobj, const char *key) { 85 struct json_object *tmp; 86 87 json_object_object_get_ex(jobj, key, &tmp); 88 89 return tmp; 90 } 91 92 int get_jrpc_id(json_object* jobj) 93 { 94 json_object* obj = find_something(jobj, "id"); 95 96 enum json_type type = json_object_get_type(obj); 97 if (type != json_type_int) { 98 printf("Error, id field is not an int (type=%d)!\n",type); 99 return -1; 100 } 101 102 return json_object_get_int(obj); 103 } 104 105 int get_jrpc_error(json_object* jobj) 106 { 107 json_object* obj = NULL; 108 if (json_object_object_get_ex(jobj, "error", &obj)) { 109 // key was found, as it should be 110 enum json_type type = json_object_get_type(obj); 111 if (type == json_type_string) { 112 // Found an error 113 printf("Error value: %s\n", json_object_get_string(obj)); 114 return -1; 115 } 116 } else { 117 printf("Error field not found in response!\n"); 118 } 119 120 return 0; 121 } 122 123 json_object* get_jrpc_result(json_object* jobj) 124 { 125 return find_something(jobj, "result"); 126 } 127 128 uint64_t get_jrpc_mount_id(json_object* jobj) 129 { 130 json_object* obj = NULL; 131 // MountID is inside the result object 132 json_object* robj = get_jrpc_result(jobj); 133 if (!json_object_object_get_ex(robj, "MountID", &obj)) { 134 // key was not found 135 printf("MountID field not found in response!\n"); 136 return 0; 137 } 138 139 return json_object_get_int64(obj); 140 } 141 142 json_object* build_jrpc_request(int id, char* method) 143 { 144 // Create a new JSON object to populate and return 145 json_object* jobj = json_object_new_object(); 146 147 // Add the top-level key-value pairs 148 json_object_object_add(jobj, "id", json_object_new_int(id)); 149 json_object_object_add(jobj, "method", json_object_new_string(method)); 150 json_object_object_add(jobj, "jsonrpc", json_object_new_string("2.0")); 151 152 // Create the params array, consisting of key-value pairs 153 json_object* pobj = json_object_new_array(); 154 json_object* tmp = json_object_new_object(); 155 json_object_object_add(tmp, "VolumeName", json_object_new_string("CommonVolume")); 156 json_object_object_add(tmp, "MountOptions", json_object_new_int(0)); 157 json_object_object_add(tmp, "AuthUser", json_object_new_string("balajirao")); 158 json_object_array_add(pobj,tmp); 159 160 // Add the params array to the top-level object 161 json_object_object_add(jobj,"params",pobj); 162 163 return jobj; 164 } 165 166 167 int main(int argc, char *argv[]) 168 { 169 char buffer[256]; 170 int id = 1; 171 172 // Open socket 173 //printf("Opening socket.\n"); 174 if (sock_open() < 0) { 175 goto done; 176 } 177 178 // Build our request header 179 json_object* myobj = build_jrpc_request(id, "Server.RpcMount"); 180 181 // Send something 182 const char* writeBuf = json_object_to_json_string_ext(myobj, JSON_C_TO_STRING_PLAIN); 183 printf("Sending data: %s\n",writeBuf); 184 if (sock_write(writeBuf) < 0) { 185 printf("Error writing to socket.\n"); 186 goto sock_close_and_done; 187 } 188 189 // Read response 190 //printf("Reading from socket.\n"); 191 bzero(buffer,256); 192 if (sock_read(buffer) < 0) { 193 printf("Error reading from socket.\n"); 194 goto sock_close_and_done; 195 } 196 //printf("Read %s\n",buffer); 197 json_object* jobj = json_tokener_parse(buffer); 198 //printf("response:\n---\n%s\n---\n", json_object_to_json_string_ext(jobj, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY)); 199 200 // Get id from response 201 int rsp_id = get_jrpc_id(jobj); 202 if (rsp_id != id) { 203 printf("Error, expected id=%d, received id=%d", id, rsp_id); 204 } else { 205 // printf("Response id = %d\n",rsp_id); 206 } 207 208 // Was there an error? 209 if (get_jrpc_error(jobj) != 0) { 210 printf("Error was set in response.\n"); 211 } 212 213 // Try to find the mount ID 214 printf("Returned MountID: %lld\n", get_jrpc_mount_id(jobj)); 215 216 sock_close_and_done: 217 // Close socket 218 //printf("Closing socket.\n"); 219 sock_close(); 220 221 done: 222 return 0; 223 }