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.h>
24 #include <glibtop/error.h>
25 #include <glibtop/sysdeps.h>
26 #include <glibtop/open.h>
27 #include <glibtop/parameter.h>
28 #include <glibtop/init_hooks.h>
29 #include <glibtop/machine.h>
30 
31 
32 #ifndef DEFAULT_PORT
33 #define DEFAULT_PORT 42800
34 #endif
35 
36 static glibtop _glibtop_global_server;
37 glibtop *glibtop_global_server = &_glibtop_global_server;
38 
39 static void
_init_server(glibtop * server,const unsigned features)40 _init_server (glibtop *server, const unsigned features)
41 {
42 	char *command, *temp;
43 
44 	/* Try to get server command, but don't override if already
45 	 * set via glibtop_set_parameter () */
46 
47 	if (server->server_command == NULL) {
48 		const char *temp = getenv ("LIBGTOP_SERVER") ?
49 			getenv ("LIBGTOP_SERVER") : LIBGTOP_SERVER;
50 
51 		server->server_command = g_strdup (temp);
52 	}
53 
54 	if (server->server_rsh == NULL) {
55 		const char *temp = getenv ("LIBGTOP_RSH") ?
56 			getenv ("LIBGTOP_RSH") : "/usr/bin/ssh";
57 
58 		server->server_rsh = g_strdup (temp);
59 	}
60 
61 	/* Try to get server method, but don't override if already
62 	 * set via  glibtop_set_parameter () */
63 
64 	if (server->method) return;
65 
66 	/* If server->command doesn't start with a colon, then it is
67 	 * the full pathname of the server executable. */
68 
69 	if (server->server_command [0] != ':') {
70 		if (features & glibtop_server_features) {
71 			/* We really need the server. */
72 			server->method = GLIBTOP_METHOD_PIPE;
73 		} else {
74 			/* Fine. No server is needed, so we call the
75 			 * sysdeps functions directly. */
76 			server->method = GLIBTOP_METHOD_DIRECT;
77 		}
78 
79 		return;
80 	}
81 
82 
83 	/* If the first character of 'server_command' is a colon,
84 	 * the first field is the method to connect to the server. */
85 
86 	/* Everything up to the next colon is the method. */
87 
88 	command = g_strdup (server->server_command+1);
89 	temp = strstr (command, ":");
90 	if (temp) *temp = 0;
91 
92 	/* Dispatch method. */
93 
94 	if (!strcmp (command, "direct")) {
95 		/* Use sysdeps dir instead of connecting to server
96 		 * even if using the server would be required on
97 		 * the current system. */
98 		server->method = GLIBTOP_METHOD_DIRECT;
99 
100 	} else if (!strcmp (command, "inet")) {
101 
102 		server->method = GLIBTOP_METHOD_INET;
103 
104 		/* Connect to internet server. */
105 
106 		if (temp == NULL) {
107 			/* If no value was set, we use 'localhost'. */
108 			if (server->server_host == NULL)
109 				server->server_host = g_strdup ("localhost");
110 		} else {
111 			char *temp2 = strstr (temp+1, ":");
112 			if (temp2) *temp2 = 0;
113 
114 			/* Override default. */
115 			if (server->server_host)
116 				g_free ((char *) server->server_host);
117 
118 			server->server_host = g_strdup (temp+1);
119 
120 			temp = temp2;
121 		}
122 
123 		if (temp == NULL) {
124 			/* If no value was set, we use DEFAULT_PORT. */
125 			if (server->server_port == 0)
126 				server->server_port = DEFAULT_PORT;
127 		} else {
128 			char *temp2 = strstr (temp+1, ":");
129 			if (temp2) *temp2 = 0;
130 
131 			if (sscanf (temp+1, "%ld", &server->server_port) != 1)
132 				server->server_port = DEFAULT_PORT;
133 
134 			temp = temp2 ? temp2 + 1 : temp2;
135 		}
136 
137 	} else if (!strcmp (command, "unix")) {
138 
139 		/* Connect to unix domain socket. */
140 		server->method = GLIBTOP_METHOD_UNIX;
141 
142 	} else if (!strcmp (command, "pipe")) {
143 
144 		/* Open pipe to server. */
145 		server->method = GLIBTOP_METHOD_PIPE;
146 		server->server_command = g_strdup(LIBGTOP_SERVER);
147 	} else {
148 
149 		glibtop_error_r (server, "Unknown server method '%s'",
150 				 server->server_command+1);
151 
152 	}
153 
154 	g_free (command);
155 }
156 
157 glibtop *
glibtop_init_r(glibtop ** server_ptr,unsigned long features,unsigned flags)158 glibtop_init_r (glibtop **server_ptr, unsigned long features, unsigned flags)
159 {
160 	glibtop *server;
161 
162 	if (server_ptr == NULL)
163 		return NULL;
164 
165 	if (*server_ptr == NULL)
166 		*server_ptr = glibtop_global_server;
167 
168 	server = *server_ptr;
169 
170 	/* Should we do the initialization? */
171 
172 	if (flags & GLIBTOP_INIT_NO_INIT)
173 		return server;
174 
175 	/* Do the initialization, but only if not already initialized. */
176 
177 	if ((server->flags & _GLIBTOP_INIT_STATE_INIT) == 0) {
178 
179 		glibtop_machine_new (server);
180 
181 		if (flags & GLIBTOP_FEATURES_EXCEPT)
182 			features = ~features & GLIBTOP_SYSDEPS_ALL;
183 
184 		if (features == 0)
185 			features = GLIBTOP_SYSDEPS_ALL;
186 
187 		if (flags & GLIBTOP_FEATURES_NO_SERVER) {
188 			server->method = GLIBTOP_METHOD_DIRECT;
189 			features = 0;
190 		}
191 
192 		server->features = features;
193 
194 		_init_server (server, features);
195 
196 		server->flags |= _GLIBTOP_INIT_STATE_INIT;
197 
198 		switch (server->method) {
199 		case GLIBTOP_METHOD_PIPE:
200 		case GLIBTOP_METHOD_UNIX:
201 			if (glibtop_server_features & features)
202 				break;
203 
204 			server->method = GLIBTOP_METHOD_DIRECT;
205 			break;
206 		}
207 	}
208 
209 	/* Should we open the server? */
210 
211 	if (flags & GLIBTOP_INIT_NO_OPEN)
212 		return server;
213 
214 	/* Open server, but only if not already opened. */
215 
216 	if ((server->flags & _GLIBTOP_INIT_STATE_OPEN) == 0)
217 		glibtop_open_l (server, "glibtop",
218 				features, flags);
219 
220 	return server;
221 }
222 
223 glibtop *
glibtop_init_s(glibtop ** server_ptr,unsigned long features,unsigned flags)224 glibtop_init_s (glibtop **server_ptr, unsigned long features, unsigned flags)
225 {
226 	glibtop *server;
227 	const _glibtop_init_func_t *init_fkt;
228 
229 	glibtop_debug("init_s with features=%#0lx and flags=%#0x", features, flags);
230 
231 	if (server_ptr == NULL)
232 		return NULL;
233 
234 	if (*server_ptr == NULL)
235 		*server_ptr = glibtop_global_server;
236 
237 	server = *server_ptr;
238 
239 	/* Should we do the initialization? */
240 
241 	if (flags & GLIBTOP_INIT_NO_INIT)
242 		return server;
243 
244 	/* Do the initialization, but only if not already initialized. */
245 
246 	if ((server->flags & _GLIBTOP_INIT_STATE_SYSDEPS) == 0) {
247 		glibtop_open_s (server, "glibtop", features, flags);
248 
249 		for (init_fkt = _glibtop_init_hook_s; *init_fkt; init_fkt++)
250 			(*init_fkt) (server);
251 
252 		server->flags |= _GLIBTOP_INIT_STATE_SYSDEPS;
253 	}
254 
255 	return server;
256 }
257