PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/hello/system.c

https://bitbucket.org/ghsb/sequoia-vm
C | 402 lines | 328 code | 64 blank | 10 comment | 92 complexity | cac5fa64ef8002095cfc8273f4a4b7e0 MD5 | raw file
Possible License(s): Apache-2.0, CC-BY-4.0, BSD-3-Clause
  1. #include "system.h"
  2. typedef struct timeval TIMEVAL;
  3. int32_t
  4. current_connection_socket_,
  5. server_socket_;
  6. int32_t set_nonblock
  7. (int32_t socket)
  8. {
  9. return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL, 0) | O_NONBLOCK);
  10. }
  11. uint32_t recv_peek
  12. (int32_t socket)
  13. {
  14. char data;
  15. if (recv(socket, &data, 1, MSG_PEEK | MSG_DONTWAIT) != 0)
  16. return 1;
  17. return 0;
  18. }
  19. uint8_t is_connected
  20. (int32_t sock)
  21. {
  22. return recv_peek(sock);
  23. }
  24. int32_t read_data
  25. (int32_t sock, char *buffer )
  26. {
  27. int32_t
  28. bytes = 0;
  29. static size_t
  30. position = 0;
  31. char
  32. chr;
  33. do
  34. {
  35. bytes = recv(sock, &chr, 1, 0);
  36. if (bytes != SOCKET_ERROR && bytes > 0)
  37. {
  38. if (chr == '<' || position > SYSTEM_PACKET_LEN - 1)
  39. {
  40. position = 0;
  41. }
  42. else
  43. {
  44. if (chr == '>')
  45. {
  46. buffer[position] = '\0';
  47. return position-1;
  48. }
  49. buffer[position++] = chr;
  50. }
  51. }
  52. } while (bytes != SOCKET_ERROR && bytes > 0);
  53. return 0;
  54. }
  55. int32_t send_reply
  56. (char *buffer, int32_t len, char* message )
  57. {
  58. int32_t
  59. retval = 0;
  60. char
  61. *sndbuffer = malloc(len + 10 + strlen(message));
  62. if(sndbuffer==NULL)
  63. return -1;
  64. sprintf(sndbuffer, "<%s%s>", buffer,message);
  65. retval = send(current_connection_socket_, sndbuffer, strlen(sndbuffer), 0);
  66. free(sndbuffer);
  67. return retval;
  68. }
  69. int32_t send_pong
  70. ( void )
  71. {
  72. return send_reply("pong", strlen("pong"),"");
  73. }
  74. int execute(char *cmd)
  75. {
  76. FILE *fd;
  77. fd = popen(cmd, "r");
  78. if (!fd)
  79. return 1;
  80. char buffer[256];
  81. size_t chread;
  82. size_t comalloc = 256;
  83. size_t comlen = 0;
  84. char *comout = malloc(comalloc);
  85. while ((chread = fread(buffer, 1, sizeof(buffer), fd)) != 0)
  86. {
  87. if (comlen + chread >= comalloc)
  88. {
  89. comalloc *= 2;
  90. comout = realloc(comout, comalloc);
  91. }
  92. memmove(comout + comlen, buffer, chread);
  93. comlen += chread;
  94. }
  95. comout[comlen] = '\0';
  96. send_reply(comout, comlen, "");
  97. free(comout);
  98. pclose(fd);
  99. return 0;
  100. }
  101. int execute_wmsg(char *cmd, char *msg)
  102. {
  103. FILE *fd;
  104. fd = popen(cmd, "r");
  105. if (!fd)
  106. return 1;
  107. char buffer[256];
  108. size_t chread;
  109. size_t comalloc = 256;
  110. size_t comlen = 0;
  111. char *comout = malloc(comalloc);
  112. while ((chread = fread(buffer, 1, sizeof(buffer), fd)) != 0)
  113. {
  114. if (comlen + chread >= comalloc)
  115. {
  116. comalloc *= 2;
  117. comout = realloc(comout, comalloc);
  118. }
  119. memmove(comout + comlen, buffer, chread);
  120. comlen += chread;
  121. }
  122. comout[comlen] = '\0';
  123. if(comlen == 0)
  124. send_reply(comout, comlen, msg);
  125. else
  126. send_reply(comout, comlen, "");
  127. free(comout);
  128. pclose(fd);
  129. return 0;
  130. }
  131. void single_threaded_listener
  132. (void)
  133. {
  134. int32_t
  135. new_socket;
  136. struct sockaddr_in
  137. server,
  138. client;
  139. socklen_t
  140. c;
  141. char
  142. data[SYSTEM_PACKET_LEN],
  143. buffer[1024];
  144. fd_set
  145. readset;
  146. int32_t
  147. nfds = 0;
  148. TIMEVAL
  149. tv = { 0 };
  150. running_ = 1;
  151. //Create a socket
  152. if ((server_socket_ = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
  153. {
  154. printf("Could not create socket : %d", errno);
  155. fflush(stdout);
  156. exit(EXIT_FAILURE);
  157. }
  158. //Prepare the sockaddr_in structure
  159. server.sin_family = AF_INET;
  160. server.sin_addr.s_addr = INADDR_ANY;
  161. server.sin_port = htons(SYSTEM_SETTINGS_PORT);
  162. int yes=1;
  163. if (setsockopt(server_socket_, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(yes)) == SOCKET_ERROR)
  164. {
  165. printf("Reuse failed with error code : %d", errno);
  166. fflush(stdout);
  167. exit(EXIT_FAILURE);
  168. }
  169. //Bind
  170. if (bind(server_socket_, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
  171. {
  172. printf("Bind failed with error code : %d", errno);
  173. fflush(stdout);
  174. exit(EXIT_FAILURE);
  175. }
  176. if (listen(server_socket_, 1) <0)
  177. {
  178. printf("Listen failed with error code : %d",errno);
  179. fflush(stdout);
  180. exit(EXIT_FAILURE);
  181. }
  182. c = sizeof(struct sockaddr_in);
  183. if( (new_socket = accept(server_socket_, (struct sockaddr *)&client, &c)) != INVALID_SOCKET )
  184. {
  185. if (set_nonblock(new_socket) == 0)
  186. {
  187. current_connection_socket_ = new_socket;
  188. while (is_connected(new_socket) && running_ )
  189. {
  190. FD_ZERO(&readset);
  191. nfds = new_socket;
  192. FD_SET(new_socket, &readset);
  193. tv.tv_sec = 1;
  194. if (select(nfds + 1, &readset, NULL, NULL, &tv))
  195. {
  196. if (FD_ISSET(new_socket, &readset))
  197. {
  198. if (read_data(new_socket, data))
  199. {
  200. if (strcmp((char*)data, "ping") == 0)
  201. {
  202. send_pong();
  203. }
  204. else if (strcmp((char*)data, "terminate") == 0)
  205. {
  206. shutdown(server_socket_, 2);
  207. shutdown(new_socket, 2);
  208. close(server_socket_);
  209. close(new_socket);
  210. }
  211. else
  212. {
  213. if(strcmp("version",data)==0)
  214. {
  215. send_reply(VERSION,strlen(VERSION),"");
  216. }
  217. else if(strcmp("ipconfig",data)==0)
  218. {
  219. execute("interface=($(connmanctl services | grep ethernet | awk '{print $3}')); cat /var/lib/connman/$interface/settings | grep IPv4.method | cut -d= -f2");
  220. }
  221. else if(strcmp("mac eth0",data)==0)
  222. {
  223. execute("cat /sys/class/net/eth0/address");
  224. }
  225. else if(strcmp("ipaddr",data)==0)
  226. {
  227. execute("interface=($(connmanctl services | grep ethernet | awk '{print $3}')); connmanctl services $interface | awk '/IPv4 =/ {print $5}' | cut -d= -f2 | cut -d, -f1");
  228. }
  229. else if(strcmp("subnet mask",data)==0)
  230. {
  231. execute("interface=($(connmanctl services | grep ethernet | awk '{print $3}')); connmanctl services $interface | awk '/IPv4 =/ {print $6}' | cut -d= -f2 | cut -d, -f1");
  232. }
  233. else if(strcmp("gateway",data)==0)
  234. {
  235. execute("interface=($(connmanctl services | grep ethernet | awk '{print $3}')); connmanctl services $interface | awk '/IPv4 =/ {print $7}' | cut -d= -f2 | cut -d, -f1");
  236. }
  237. else if(strcmp("dns",data)==0)
  238. {
  239. execute("interface=($(connmanctl services | grep ethernet | awk '{print $3}')); connmanctl services $interface | awk '/Nameservers =/ {print $4}' | cut -d, -f1");
  240. }
  241. /* set commands network */
  242. // connmanctl config ethernet_00142d4a5979_cable --ipv4 manual 192.168.178.222 255.255.255.0 192.168.178.1
  243. else if(strncmp("set-ip ",data,7)==0)
  244. {
  245. sprintf(buffer,"interface=($(connmanctl services | grep ethernet | awk '{print $3}')); connmanctl config $interface --ipv4 %s ",&data[7]);
  246. send_reply("OK-RCNT",7,"");
  247. execute(buffer);
  248. break;
  249. }
  250. // connmanctl config ethernet_00142d259a48_cable --nameservers 8.8.8.8
  251. else if(strncmp("set-dns ",data,8)==0)
  252. {
  253. sprintf(buffer,"interface=($(connmanctl services | grep ethernet | awk '{print $3}')); connmanctl config $interface --nameservers %s ",&data[8]);
  254. execute_wmsg(buffer,"OK");
  255. }
  256. /* system usage */
  257. else if(strcmp("load core1",data)==0)
  258. {
  259. execute("loads=($(mpstat -P ALL 1 1 | awk '/Average:/ && $2 ~ /[0-9]/ {print $3}')); echo ${loads[0]}");
  260. }
  261. else if(strcmp("load core2",data)==0)
  262. {
  263. execute("loads=($(mpstat -P ALL 1 1 | awk '/Average:/ && $2 ~ /[0-9]/ {print $3}')); echo ${loads[1]}");
  264. }
  265. else if(strcmp("load percent",data)==0)
  266. {
  267. execute("grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage \"%\"}'");
  268. }
  269. else if(strcmp("ram usage",data)==0)
  270. {
  271. execute("free | grep Mem | awk '{print $3/$2 * 100.0}'");
  272. }
  273. else if(strcmp("memory usage",data)==0)
  274. {
  275. execute("df / | awk 'END{print $5}' | sed 's/%//'");
  276. }
  277. /* time */
  278. else if(strcmp("date",data)==0)
  279. {
  280. execute("date +%d/%m/%Y%t%H:%M:%S");
  281. }
  282. else if(strcmp("ntp",data)==0)
  283. {
  284. execute("timedatectl | grep Network | cut -d: -f2");
  285. }
  286. else if(strcmp("list timezones",data)==0)
  287. {
  288. execute("timedatectl list-timezones");
  289. }
  290. else if(strcmp("timezone",data)==0)
  291. {
  292. execute("timedatectl | grep 'Time zone' | awk '/Time zone/ {print $3}'");
  293. }
  294. /* time set cmds */
  295. else if(strcmp("set-ntp no",data)==0)
  296. {
  297. execute_wmsg("timedatectl set-ntp no","OK");
  298. }
  299. else if(strcmp("set-ntp yes",data)==0)
  300. {
  301. execute_wmsg("timedatectl set-ntp yes", "OK");
  302. }
  303. else if(strncmp("set-time ",data,9)==0)
  304. {
  305. sprintf(buffer,"timedatectl set-time '%s'",&data[9]);
  306. execute_wmsg(buffer,"OK");
  307. }
  308. else if(strncmp("set-timezone ",data,13)==0)
  309. {
  310. sprintf(buffer,"timedatectl set-timezone '%s'",&data[13]);
  311. execute_wmsg(buffer,"OK");
  312. }
  313. /* extra functions */
  314. else if(strcmp("reboot",data)==0)
  315. {
  316. execute("reboot");
  317. }
  318. else
  319. {
  320. send_reply("unknown command ",strlen("unknown command "),"");
  321. }
  322. }
  323. }
  324. }
  325. }
  326. }
  327. }
  328. shutdown(new_socket, 2);
  329. close(new_socket);
  330. }
  331. if (new_socket == INVALID_SOCKET)
  332. {
  333. printf("accept failed with error code : %d", errno);
  334. exit(EXIT_FAILURE);
  335. }
  336. close(server_socket_);
  337. running_ = 0;
  338. }