xref: /onnv-gate/usr/src/cmd/wbem/provider/tools/rds/rdlist.c (revision 0:68f95e015346)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2000-2003 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include "rdlist.h"
30 #include "rdtable.h"
31 
32 static int	list_read(int listt, int elemn);
33 static int	lwp_write(list_t *list);
34 static int	lwp_read(int lwpn);
35 
36 /*
37  * This procedure stores the current state of the lists (lwps, processes,
38  * users and project) into the file defined by 'file'.
39  * param file - the file name to be used
40  * return 0, or -1 on error and store the error message in
41  *		the global buffer 'errmsg'.
42  */
43 int
list_store(char * file)44 list_store(char *file)
45 {
46 	int	storefd;
47 	time_t  tv;
48 	char 	*tstr;
49 	int 	ret = -1;
50 
51 	if ((storefd = open(file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR))
52 			== -1) {
53 		format_err("can't open list db: %s\n", file);
54 		(void) fprintf(stderr, errmsg);
55 		return (-1);
56 	}
57 	log_msg("writing persistence file: %s\n", file);
58 
59 	/*
60 	 * the next do {..} while (false); statement is a replacement
61 	 * of goto;
62 	 */
63 	do {
64 		if (open_prot(storefd, "w") == -1) {
65 			format_err("can't open list db: %s\n", file);
66 			(void) fprintf(stderr, errmsg);
67 			break;
68 		}
69 		(void) time(&tv);
70 		tstr = ctime(&tv);
71 		if (wr_string("# RDS data base file generated on: ") == -1)
72 			break;
73 		if (wr_string(tstr) == -1)
74 			break;
75 		if (wr_value(LTDB_VERSION_KEY, LTDB_VERSION) == -1)
76 			break;
77 		if (wr_value(LTDB_TIMESTAMP, tv) == -1)
78 			break;
79 		/* we will write 4 lists */
80 		if (wr_lshead(4) != 0) {
81 			format_err("can't write into list db: %s\n",
82 					"./listdb");
83 			break;
84 		}
85 		if (list_write(L_LWP, 0) == -1)
86 			break;
87 		if (list_write(L_PRC_SI, 0) == -1)
88 			break;
89 		if (list_write(L_USR_SI, 0) == -1)
90 			break;
91 		if (list_write(L_PRJ_SI, 0) == -1)
92 			break;
93 		ret = 0;
94 	} while (ret);
95 
96 	if (ret == 0) {
97 		struct stat stat_buf;
98 		(void) fstat(storefd, &stat_buf);
99 		log_msg("wrote: %ld bytes\n", stat_buf.st_size);
100 	}
101 
102 	/* close_prot(); */
103 	(void) close(storefd);
104 
105 	return (ret);
106 }
107 
108 /*
109  * This procedure restores the last state of the lists (lwps, processes,
110  * users and project) from the file defined by 'file'.
111  * param file - the file name to be used
112  * return 0, or -1 on error and store the error message in
113  *		the global buffer 'errmsg'.
114  */
115 int
list_restore(char * file)116 list_restore(char *file)
117 {
118 	int	storefd;
119 	int	listt, elemn, listn;
120 	int64_t	timestamp;
121 	time_t  tv;
122 	int	version;
123 	int 	ret = -1;
124 
125 	if ((storefd = open(file, O_RDONLY)) == -1)
126 		return (ret);
127 	log_msg("reading persistence file: %s\n", file);
128 
129 	/*
130 	 * the next do {..} while (false); statement is a replacement
131 	 * of goto;
132 	 */
133 	do {
134 		if (open_prot(storefd, "r") == -1)
135 			break;
136 		if (skip_line() == -1)
137 			break;
138 		if ((version = r_value(LTDB_VERSION_KEY)) == -1)
139 			break;
140 		if (version != LTDB_VERSION) {
141 			(void) fprintf(stderr,
142 				"wrong version %d of db file %s\n",
143 				version, file);
144 			break;
145 		}
146 		if ((timestamp = r_value(LTDB_TIMESTAMP)) == -1)
147 			break;
148 		/* check the file decay time is expired */
149 		(void) time(&tv);
150 		if ((tv - timestamp) > LTDB_DECAYTIME)
151 			break;
152 		if ((listn = r_lshead()) == -1)
153 			break;
154 		while (listn-- > 0) {
155 			if ((elemn = r_lhead(&listt)) == -1)
156 				break;
157 			if (list_read(listt, elemn) != 0) {
158 				break;
159 			}
160 		}
161 		ret = 0;
162 	} while (ret);
163 
164 	if (ret == 0) {
165 		struct stat stat_buf;
166 		(void) fstat(storefd, &stat_buf);
167 		log_msg("read: %ld bytes\n", stat_buf.st_size);
168 	}
169 
170 	/* close_prot(); */
171 	(void) close(storefd);
172 	(void) unlink(file);
173 	return (ret);
174 }
175 
176 /*
177  * This procedure writes a list of type 'listt' according to the
178  * rds interface protocol. It uses the already opened and initialized
179  * protocol module (see file protocol.[c,h]).
180  * param listt	- the type of the list, see rdimpl.h
181  * param Po	- print option, if 1 the list will be also printed on stdout.
182  * return 0, or -1 on error and store the error message in
183  *		the global buffer 'errmsg'.
184  */
185 int
list_write(int listt,int Po)186 list_write(int listt, int Po)
187 {
188 	char		idstr[P_MAXVAL];
189 	list_t 		*list;
190 	id_info_t	*id = NULL, *nextid;
191 
192 	if (listt == L_LWP) {
193 		return (lwp_write(&lwps));
194 	} else if (listt == L_SYSTEM) {
195 		if (wr_lhead(listt, 1) != 0) {
196 			format_err(
197 				"RDS protocol error: cannot write list header");
198 			return (-1);
199 		}
200 		(void) snprintf(idstr, sizeof (idstr), "%s", sys_info.name);
201 		if (wr_element(listt, (char *)(&sys_info), idstr) != 0) {
202 			format_err(
203 				"RDS protocol error: cannot write list header");
204 			return (-1);
205 		}
206 
207 	} else {
208 		switch (listt) {
209 		case L_PRC_SI : list =  &processes;
210 				break;
211 		case L_AC_USR :
212 		case L_USR_SI : list =  &users;
213 				break;
214 		case L_AC_PRJ :
215 		case L_PRJ_SI : list =  &projects;
216 				break;
217 		}
218 		id = list->l_head;
219 
220 		if (wr_lhead(listt, list->l_count) != 0) {
221 			format_err(
222 				"RDS protocol error: cannot write list header");
223 			return (-1);
224 		}
225 		while (id != NULL) {
226 			switch (listt) {
227 			case L_PRC_SI :
228 				(void) sprintf(idstr, "%d", id->id_pid);
229 				break;
230 			case L_AC_USR :
231 			case L_USR_SI :
232 				(void) sprintf(idstr, "%d", id->id_uid);
233 				break;
234 			case L_AC_PRJ :
235 			case L_PRJ_SI :
236 				(void) snprintf(idstr, sizeof (idstr), "%s",
237 				    id->id_name);
238 				break;
239 			}
240 			if (wr_element(listt, (char *)id, idstr) != 0) {
241 					format_err(
242 				"RDS protocol error: cannot write list header");
243 			}
244 			if (Po == 1)
245 				prtelement(stderr, id);
246 			nextid = id->id_next;
247 			id = nextid;
248 		}
249 	}
250 	return (0);
251 }
252 
253 /*
254  * This procedure prints out all list elements on stdout. The elements
255  * int the list must be of type id_info_t.
256  * param list - the list to be printed
257  */
258 void
list_print(list_t * list,int xid)259 list_print(list_t *list, int xid)
260 {
261 
262 	id_info_t *id = list->l_head;
263 	id_info_t *nextid;
264 
265 	while (id) {
266 		if (xid == -1) {
267 			prtelement(stdout, id);
268 		} else {
269 			switch (list->l_type) {
270 			case LT_PROCESS : if (xid == id->id_pid)
271 						prtelement(stdout, id);
272 					break;
273 			case LT_USERS 	: if (xid == id->id_uid)
274 						prtelement(stdout, id);
275 					break;
276 			case LT_PROJECTS : if (xid == id->id_projid)
277 						prtelement(stdout, id);
278 					break;
279 			default: prtelement(stdout, id);
280 			}
281 		}
282 		nextid = id->id_next;
283 		id = nextid;
284 	}
285 
286 }
287 
288 static int
list_read(int listt,int elemn)289 list_read(int listt, int elemn)
290 {
291 	char	idstr[P_MAXVAL];
292 	list_t	*list;
293 	id_info_t *id;
294 
295 	if (listt == L_LWP)
296 		return (lwp_read(elemn));
297 
298 	while (elemn-- > 0) {
299 		switch (listt) {
300 			case L_PRC_SI 	: list = &processes;
301 					break;
302 			case L_USR_SI 	: list = &users;
303 					break;
304 			case L_PRJ_SI 	: list = &projects;
305 					break;
306 		}
307 
308 		if (list->l_head == NULL) { /* first element */
309 			list->l_head = list->l_tail = id =
310 					Zalloc(sizeof (id_info_t));
311 			list->l_count++;
312 		} else {
313 			/* a new element */
314 			id = list->l_tail;
315 			id->id_next = Zalloc(sizeof (id_info_t));
316 			id->id_next->id_prev = list->l_tail;
317 			id->id_next->id_next = NULL;
318 			list->l_tail = id->id_next;
319 			id = list->l_tail;
320 			list->l_count++;
321 		}
322 		if (r_element((char *)id, idstr) == -1) {
323 			list_clear(list);
324 			return (-1);
325 		}
326 	}
327 	return (0);
328 }
329 
330 static int
lwp_write(list_t * list)331 lwp_write(list_t *list)
332 {
333 	lwpinfo_t	lwpsi;
334 	lwp_info_t	*li = NULL, *nextli;
335 
336 	li = list->l_head;
337 
338 	if (wr_lhead(L_LWP, list->l_count) != 0) {
339 		format_err(
340 			"RDS protocol error: cannot write list header");
341 		err_exit();
342 	}
343 	while (li != NULL) {
344 		lwpsi.pr_pid	= li->li_psinfo->pr_pid;
345 		lwpsi.pr_lwpid	= li->li_lwpsinfo->pr_lwpid;
346 
347 		if (wr_element(L_LWP__I, (char *)&lwpsi, "lwpi") != 0) {
348 			format_err(
349 			"RDS protocol error: cannot write list header");
350 		}
351 		if (wr_element(L_LWP__U, (char *)&(li->li_usage), "lwpu")
352 				!= 0) {
353 			format_err(
354 			"RDS protocol error: cannot write list header");
355 		}
356 		if (wr_element(L_LWP, (char *)li, "lwp") != 0) {
357 			format_err(
358 			"RDS protocol error: cannot write list header");
359 		}
360 		nextli = li->li_next;
361 		li = nextli;
362 	}
363 	return (0);
364 }
365 
366 static int
lwp_read(int lwpn)367 lwp_read(int lwpn)
368 {
369 	lwp_info_t	*lwp;
370 	lwpinfo_t	lwpsi;
371 
372 	char		idstr[P_MAXVAL];
373 
374 	while (lwpn-- > 0) {
375 		if (r_element((char *)&lwpsi, idstr) == -1) {
376 			return (-1);
377 		}
378 		lwp = list_add_lwp(&lwps, lwpsi.pr_pid, lwpsi.pr_lwpid);
379 		lwp->li_psinfo->pr_pid		= lwpsi.pr_pid;
380 		lwp->li_lwpsinfo->pr_lwpid	= lwpsi.pr_lwpid;
381 		if (r_element((char *)&(lwp->li_usage), idstr) == -1) {
382 			return (-1);
383 		}
384 		if (r_element((char *)lwp, idstr) == -1) {
385 			return (-1);
386 		}
387 
388 	}
389 	return (0);
390 }
391