swap.c revision 1.20
1/*	$OpenBSD: swap.c,v 1.20 2007/09/01 19:32:19 deraadt Exp $	*/
2/*	$NetBSD: swap.c,v 1.9 1998/12/26 07:05:08 marc Exp $	*/
3
4/*-
5 * Copyright (c) 1997 Matthew R. Green.  All rights reserved.
6 * Copyright (c) 1980, 1992, 1993
7 *	The Regents of the University of California.  All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35#if 0
36static char sccsid[] = "@(#)swap.c	8.3 (Berkeley) 4/29/95";
37#endif
38static char rcsid[] = "$OpenBSD: swap.c,v 1.20 2007/09/01 19:32:19 deraadt Exp $";
39#endif /* not lint */
40
41#include <sys/cdefs.h>
42#include <sys/param.h>
43#include <sys/buf.h>
44#include <sys/conf.h>
45#include <sys/ioctl.h>
46#include <sys/stat.h>
47#include <sys/swap.h>
48
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#include <errno.h>
53#include <unistd.h>
54
55#include "systat.h"
56#include "extern.h"
57
58static	long blocksize;
59static	int hlen, nswap, rnswap;
60static	int first = 1;
61static	struct swapent *swap_devices;
62
63WINDOW *
64openswap(void)
65{
66	return (subwin(stdscr, LINES-1-2, 0, 2, 0));
67}
68
69void
70closeswap(WINDOW *w)
71{
72	if (w == NULL)
73		return;
74	wclear(w);
75	wrefresh(w);
76	delwin(w);
77}
78
79/* do nothing */
80int
81initswap(void)
82{
83	return (1);
84}
85
86void
87fetchswap(void)
88{
89	int	update_label = 0;
90
91	first = 0;
92	nswap = swapctl(SWAP_NSWAP, 0, 0);
93	if (nswap < 0)
94		error("error: %s", strerror(errno));
95	if (nswap == 0)
96		return;
97	update_label = (nswap != rnswap);
98
99	if (swap_devices)
100		(void)free(swap_devices);
101	swap_devices = (struct swapent *)calloc(nswap, sizeof(*swap_devices));
102	if (swap_devices == NULL)
103		/* XXX */ ;	/* XXX systat doesn't do errors! */
104
105	rnswap = swapctl(SWAP_STATS, (void *)swap_devices, nswap);
106	if (nswap < 0)
107		/* XXX */ ;	/* XXX systat doesn't do errors! */
108	if (nswap != rnswap)
109		/* XXX */ ;	/* XXX systat doesn't do errors! */
110	if (update_label)
111		labelswap();
112}
113
114void
115labelswap(void)
116{
117	char	*header;
118	int	row;
119
120	row = 0;
121	wmove(wnd, row, 0);
122	wclrtobot(wnd);
123	if (first)
124		fetchswap();
125	if (nswap == 0) {
126		mvwprintw(wnd, row++, 0, "No swap");
127		return;
128	}
129	header = getbsize(&hlen, &blocksize);
130	mvwprintw(wnd, row++, 0, "%-5s%*s%9s  %55s",
131	    "Disk", hlen, header, "Used",
132	    "/0%  /10% /20% /30% /40% /50% /60% /70% /80% /90% /100%");
133}
134
135void
136showswap(void)
137{
138	int	col, div, i, j, avail, used, xsize, free;
139	struct	swapent *sep;
140	char	*p;
141
142	div = blocksize / 512;
143	free = avail = 0;
144	for (sep = swap_devices, i = 0; i < nswap; i++, sep++) {
145		if (sep == NULL)
146			continue;
147
148		p = strrchr(sep->se_path, '/');
149		p = p ? p+1 : sep->se_path;
150
151		mvwprintw(wnd, i + 1, 0, "%-5s", p);
152
153		col = 5;
154		mvwprintw(wnd, i + 1, col, "%*d", hlen, sep->se_nblks / div);
155
156		col += hlen;
157		xsize = sep->se_nblks;
158		used = sep->se_inuse;
159		avail += xsize;
160		free += xsize - used;
161		mvwprintw(wnd, i + 1, col, "%9d  ", used / div);
162		for (j = (100 * used / xsize + 1) / 2; j > 0; j--)
163			waddch(wnd, 'X');
164		wclrtoeol(wnd);
165	}
166	/* do total if necessary */
167	if (nswap > 1) {
168		used = avail - free;
169		mvwprintw(wnd, i + 1, 0, "%-5s%*d%9d  ",
170		    "Total", hlen, avail / div, used / div);
171		for (j = (100 * used / avail + 1) / 2; j > 0; j--)
172			waddch(wnd, 'X');
173		wclrtoeol(wnd);
174	}
175}
176