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