1 /* Copyright (C) 1998-99 Martin Baulig
2    This file is part of LibGTop 1.0.
3 
4    Contributed by Martin Baulig <martin@home-of-linux.org>, April 1998.
5 
6    LibGTop is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License,
9    or (at your option) any later version.
10 
11    LibGTop is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14    for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with LibGTop; see the file COPYING. If not, write to the
18    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19    Boston, MA 02110-1301, USA.
20 */
21 
22 #include <config.h>
23 #include <glibtop/error.h>
24 #include <glibtop/read.h>
25 #include <glibtop/write.h>
26 #include <glibtop/read_data.h>
27 
28 #include <glibtop/command.h>
29 
30 void *
glibtop_call_l(glibtop * server,unsigned command,size_t send_size,const void * send_buf,size_t recv_size,void * recv_buf)31 glibtop_call_l (glibtop *server, unsigned command, size_t send_size,
32 		const void *send_buf, size_t recv_size, void *recv_buf)
33 {
34 	glibtop_command cmnd = {0};
35 	glibtop_response response = {0};
36 
37 	glibtop_init_r (&server, 0, 0);
38 
39 	g_assert(command >= GLIBTOP_CMND_QUIT && command < GLIBTOP_MAX_CMND);
40 
41 	switch (command) {
42 #define CHECK_CMND(CMND) case (CMND): glibtop_debug("CALL: command %s sending %lu bytes", #CMND, (unsigned long)send_size); break
43 	  CHECK_CMND(GLIBTOP_CMND_QUIT);
44 	  CHECK_CMND(GLIBTOP_CMND_SYSDEPS);
45 	  CHECK_CMND(GLIBTOP_CMND_CPU);
46 	  CHECK_CMND(GLIBTOP_CMND_MEM);
47 	  CHECK_CMND(GLIBTOP_CMND_SWAP);
48 	  CHECK_CMND(GLIBTOP_CMND_UPTIME);
49 	  CHECK_CMND(GLIBTOP_CMND_LOADAVG);
50 	  CHECK_CMND(GLIBTOP_CMND_SHM_LIMITS);
51 	  CHECK_CMND(GLIBTOP_CMND_MSG_LIMITS);
52 	  CHECK_CMND(GLIBTOP_CMND_SEM_LIMITS);
53 	  CHECK_CMND(GLIBTOP_CMND_PROCLIST);
54 	  CHECK_CMND(GLIBTOP_CMND_PROC_STATE);
55 	  CHECK_CMND(GLIBTOP_CMND_PROC_UID);
56 	  CHECK_CMND(GLIBTOP_CMND_PROC_MEM);
57 	  CHECK_CMND(GLIBTOP_CMND_PROC_TIME);
58 	  CHECK_CMND(GLIBTOP_CMND_PROC_SIGNAL);
59 	  CHECK_CMND(GLIBTOP_CMND_PROC_KERNEL);
60 	  CHECK_CMND(GLIBTOP_CMND_PROC_SEGMENT);
61 	  CHECK_CMND(GLIBTOP_CMND_PROC_ARGS);
62 	  CHECK_CMND(GLIBTOP_CMND_PROC_MAP);
63 	  CHECK_CMND(GLIBTOP_CMND_MOUNTLIST);
64 	  CHECK_CMND(GLIBTOP_CMND_FSUSAGE);
65 	  CHECK_CMND(GLIBTOP_CMND_NETLOAD);
66 	  CHECK_CMND(GLIBTOP_CMND_PPP);
67 	  CHECK_CMND(GLIBTOP_CMND_NETLIST);
68 	  CHECK_CMND(GLIBTOP_CMND_PROC_OPEN_FILES);
69 	  CHECK_CMND(GLIBTOP_CMND_PROC_WD);
70 	  CHECK_CMND(GLIBTOP_CMND_PROC_AFFINITY);
71 	  CHECK_CMND(GLIBTOP_CMND_PROC_IO);
72 	default:
73 	  glibtop_error_r(server, "CALL: command UNKNOWN(%d) sending %lu bytes", command, (unsigned long)send_size); break;
74 	}
75 #undef CHECK_CMND
76 
77 	cmnd.command = command;
78 
79 	/* If send_size is less than _GLIBTOP_PARAM_SIZE (normally 16 Bytes), we
80 	 * send it together with command, so we only need one system call instead
81 	 * of two. */
82 
83 	if (send_size <= _GLIBTOP_PARAM_SIZE) {
84 		memcpy (cmnd.parameter, send_buf, send_size);
85 		cmnd.size = send_size;
86 	} else {
87 		cmnd.data_size = send_size;
88 	}
89 
90 	glibtop_write_l (server, sizeof (glibtop_command), &cmnd);
91 
92 	glibtop_read_l (server, sizeof (glibtop_response), &response);
93 
94 	glibtop_debug ("RESPONSE: offset=%lu - data_size=%lu",
95 		 response.offset, response.data_size);
96 
97 	if (recv_buf)
98 		memcpy (recv_buf, ((char *) &response) + response.offset,
99 			recv_size);
100 
101 	if (response.data_size) {
102 		void *ptr = g_malloc (response.data_size);
103 
104 		glibtop_read_l (server, response.data_size, ptr);
105 
106 		return ptr;
107 	}
108 
109 	return NULL;
110 }
111