1 --- wmmon-1.0b2.orig/wmgeneral/wmgeneral.c
2 +++ wmmon-1.0b2/wmgeneral/wmgeneral.c
7 + 10/10/2003 (Simon Law, sfllaw@debian.org)
8 + * changed the parse_rcfile function to use getline instead of fgets.
9 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
10 * changed the read_rc_file to parse_rcfile, as suggester by Marcelo E. Magallon
11 * debugged the parse_rc file.
21 void parse_rcfile(const char *filename, rckeys *keys) {
26 + size_t line_size = 0;
27 char *tokens = " :\t\n";
31 fp = fopen(filename, "r");
33 - while (fgets(temp, 128, fp)) {
34 + while (getline(&line, &line_size, fp) >= 0) {
36 while (key >= 0 && keys[key].label) {
37 - if ((p = strstr(temp, keys[key].label))) {
38 + if ((p = strstr(line, keys[key].label))) {
39 p += strlen(keys[key].label);
40 p += strspn(p, tokens);
41 if ((i = strcspn(p, "#\n"))) p[i] = 0;
43 unsigned int borderwidth = 1;
45 char *display_name = NULL;
46 + char *geometry = NULL;
47 char *wname = argv[0];
52 for (i=1; argv[i]; i++) {
53 if (!strcmp(argv[i], "-display"))
54 - display_name = argv[i+1];
55 + display_name = argv[++i];
56 + else if (!strcmp(argv[i], "-geometry"))
57 + geometry = argv[++i];
60 if (!(display = XOpenDisplay(display_name))) {
62 fore_pix = GetColor("black");
64 XWMGeometry(display, screen, Geometry, NULL, borderwidth, &mysizehints,
65 - &mysizehints.x, &mysizehints.y,&mysizehints.width,&mysizehints.height, &dummy);
66 + &mysizehints.x, &mysizehints.y,
67 + &mysizehints.width, &mysizehints.height, &dummy);
69 + XParseGeometry(geometry, &mysizehints.x, &mysizehints.y,
70 + &mysizehints.width, &mysizehints.height);
72 mysizehints.width = 64;
73 mysizehints.height = 64;
75 XMapWindow(display, win);
79 +/* vim: sw=4 ts=4 columns=82
81 --- wmmon-1.0b2.orig/wmmon/wmmon.c
82 +++ wmmon-1.0b2/wmmon/wmmon.c
87 + 15/05/2004 (Simon Law, sfllaw@debian.org)
88 + * Support disabling of mode-cycling
89 + 23/10/2003 (Simon Law, sfllaw@debian.org)
90 + * Eliminated exploitable static buffers
91 + * Added -geometry support.
92 + * /proc/meminfo support for Linux 2.6
93 18/05/1998 (Antoine Nulle, warp@xs4all.nl)
94 * MEM/SWAP/UPTIME only updated when visible
95 * Using global file descriptors to reduce file
97 * First Working Version
104 @@ -100,31 +107,28 @@
105 /* Global Variables */
106 /********************/
109 int stat_current = 0; /* now global */
110 +int mode_cycling = 1; /* Allow mode-cycling */
118 void printversion(void);
119 void DrawStats(int *, int, int, int, int);
120 void DrawStats_io(int *, int, int, int, int);
122 void wmmon_routine(int, char **);
124 -void main(int argc, char *argv[]) {
125 +int main(int argc, char *argv[]) {
128 + char *name = argv[0];
131 /* Parse Command Line */
133 - ProgName = argv[0];
134 - if (strlen(ProgName) >= 5)
135 - ProgName += (strlen(ProgName) - 5);
137 for (i=1; i<argc; i++) {
140 @@ -132,13 +136,17 @@
143 if (strcmp(arg+1, "display")) {
154 + if (strcmp(arg+1, "geometry")) {
163 @@ -146,15 +154,20 @@
180 wmmon_routine(argc, argv);
186 /*******************************************************************************\
193 + char *conffile = NULL;
195 int xpm_X = 0, xpm_Y = 0;
197 @@ -246,16 +258,21 @@
198 if (RIGHT_ACTION) right_action = strdup(RIGHT_ACTION);
199 if (MIDDLE_ACTION) middle_action = strdup(MIDDLE_ACTION);
201 - strcpy(temp, "/etc/wmmonrc");
202 - parse_rcfile(temp, wmmon_keys);
203 + /* Scan through the .rc files */
204 + if (asprintf(&conffile, "/etc/wmmonrc") >= 0) {
205 + parse_rcfile(conffile, wmmon_keys);
209 - p = getenv("HOME");
211 - strcat(temp, "/.wmmonrc");
212 - parse_rcfile(temp, wmmon_keys);
214 - strcpy(temp, "/etc/wmmonrc.fixed");
215 - parse_rcfile(temp, wmmon_keys);
216 + if (asprintf(&conffile, "%s/.wmmonrc", getenv("HOME")) >= 0) {
217 + parse_rcfile(conffile, wmmon_keys);
221 + if (asprintf(&conffile, "/etc/wmmonrc.fixed") >= 0) {
222 + parse_rcfile(conffile, wmmon_keys);
226 stat_online = checksysdevs();
228 @@ -269,26 +286,36 @@
230 nexttime = starttime + 10;
232 + /* Collect information on each panel */
233 for (i=0; i<stat_online; i++) {
234 get_statistics(stat_device[i].name, &k, &istat, &idle);
235 stat_device[i].statlast = istat;
236 stat_device[i].idlelast = idle;
238 - if (stat_current == 0) DrawStats(stat_device[stat_current].his, 54, 40, 5, 58);
239 - if (stat_current == 1) {
240 - DrawStats_io(stat_device[stat_current].his, 54, 40, 5, 58);
242 - if (stat_current == 2) {
249 + /* Set the mask for the current window */
250 + switch (stat_current) {
263 + /* Draw statistics */
264 + if (stat_current == 0)
265 + DrawStats(stat_device[stat_current].his, 54, 40, 5, 58);
266 + if (stat_current == 1)
267 + DrawStats_io(stat_device[stat_current].his, 54, 40, 5, 58);
268 DrawActive(stat_device[stat_current].name);
272 + curtime = time(NULL);
274 waitpid(0, NULL, WNOHANG);
277 if (curtime >= nexttime) {
280 + if (curtime > nexttime) /* dont let APM suspends make this crazy */
281 + nexttime = curtime;
283 for (i=0; i<stat_online; i++) {
284 if (stat_device[i].his[54])
285 stat_device[i].his[54] /= stat_device[i].hisaddcnt;
289 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
290 - if (but_stat == i && but_stat >= 0) {
291 + if (but_stat == i && but_stat >= 0 && mode_cycling) {
294 switch (Event.xbutton.button) {
299 - printf("current stat is :%d\n", stat_current);
300 if (stat_current == stat_online)
303 @@ -499,43 +528,80 @@
305 void update_stat_mem(stat_dev *st, stat_dev *st2) {
308 + static char *line = NULL;
309 + static size_t line_size = 0;
311 + unsigned long swapfree;
312 unsigned long free, shared, buffers, cached;
314 freopen("/proc/meminfo", "r", fp_meminfo);
315 - while (fgets(temp, 128, fp_meminfo)) {
316 - if (strstr(temp, "Mem:")) {
317 - sscanf(temp, "Mem: %ld %ld %ld %ld %ld %ld",
318 - &st->rt_idle, &st->rt_stat,
319 - &free, &shared, &buffers, &cached);
320 - st->rt_idle >>= 10;
321 - st->rt_stat -= buffers+cached;
322 - st->rt_stat >>= 10;
325 - if (strstr(temp, "Swap:")) {
326 - sscanf(temp, "Swap: %ld %ld", &st2->rt_idle, &st2->rt_stat);
327 - st2->rt_idle >>= 10;
328 - st2->rt_stat >>= 10;
330 + while ((getline(&line, &line_size, fp_meminfo)) > 0) {
331 + /* The original format for the first two lines of /proc/meminfo was
332 + * Mem: total used free shared buffers cached
333 + * Swap: total used free
335 + * As of at least 2.5.47 these two lines were removed, so that the
336 + * required information has to come from the rest of the lines.
337 + * On top of that, used is no longer recorded - you have to work
338 + * this out yourself, from total - free.
340 + * So, these changes below should work. They should also work with
341 + * older kernels, too, since the new format has been available for
344 + if (strstr(line, "MemTotal:")) {
345 + sscanf(line, "MemTotal: %ld", &st->rt_idle);
347 + else if (strstr(line, "MemFree:")) {
348 + sscanf(line, "MemFree: %ld", &free);
350 + else if (strstr(line, "MemShared:")) {
351 + sscanf(line, "MemShared: %ld", &shared);
353 + else if (strstr(line, "Buffers:")) {
354 + sscanf(line, "Buffers: %ld", &buffers);
356 + else if (strstr(line, "Cached:")) {
357 + sscanf(line, "Cached: %ld", &cached);
359 + else if (strstr(line, "SwapTotal:")) {
360 + sscanf(line, "SwapTotal: %ld", &st2->rt_idle);
362 + else if (strstr(line, "SwapFree:")) {
363 + sscanf(line, "SwapFree: %ld", &swapfree);
367 + /* memory use - rt_stat is the amount used, it seems, and this isn't
368 + * recorded in current version of /proc/meminfo (as of 2.5.47), so we
369 + * calculate it from MemTotal - MemFree
371 + st->rt_stat = st->rt_idle - free;
372 + st->rt_stat -= buffers+cached;
373 + /* As with the amount of memory used, it's not recorded any more, so
374 + * we have to calculate it ourselves.
376 + st2->rt_stat = st2->rt_idle - swapfree;
379 void update_stat_swp(stat_dev *st) {
382 + static char *line = NULL;
383 + static size_t line_size = 0;
384 + unsigned long swapfree;
386 fseek(fp_meminfo, 0, SEEK_SET);
387 - while (fgets(temp, 128, fp_meminfo)) {
388 - if (strstr(temp, "Swap:")) {
389 - sscanf(temp, "Swap: %ld %ld", &st->rt_idle, &st->rt_stat);
390 - st->rt_idle >>= 10;
391 - st->rt_stat >>= 10;
393 + while ((getline(&line, &line_size, fp_meminfo)) > 0) {
394 + /* As with update_stat_mem(), the format change to /proc/meminfo has
395 + * forced some changes here. */
396 + if (strstr(line, "SwapTotal:")) {
397 + sscanf(line, "SwapTotal: %ld", &st->rt_idle);
399 + else if (strstr(line, "SwapFree:")) {
400 + sscanf(line, "SwapFree: %ld", &swapfree);
404 + st->rt_stat = st->rt_idle - swapfree;
407 /*******************************************************************************\
408 @@ -545,11 +611,11 @@
409 void get_statistics(char *devname, long *is, long *ds, long *idle) {
413 + static char *line = NULL;
414 + static size_t line_size = 0;
416 char *tokens = " \t\n";
424 if (!strncmp(devname, "cpu", 3)) {
425 fseek(fp_stat, 0, SEEK_SET);
426 - while (fgets(temp, 128, fp_stat)) {
427 - if (strstr(temp, "cpu")) {
428 - p = strtok(temp, tokens);
429 + while ((getline(&line, &line_size, fp_stat)) > 0) {
430 + if (strstr(line, "cpu ")) {
431 + p = strtok(line, tokens);
432 /* 1..3, 4 == idle, we don't want idle! */
433 for (i=0; i<3; i++) {
434 p = strtok(NULL, tokens);
435 @@ -577,17 +643,35 @@
436 if (!strncmp(devname, "i/o", 3)) {
438 fseek(fp_stat, 0, SEEK_SET);
439 - while (fgets(temp, 128, fp_stat)) {
440 - if (strstr(temp, "disk_rio") || strstr(temp, "disk_wio")) {
441 - p = strtok(temp, tokens);
442 + while ((getline(&line, &line_size, fp_stat)) > 0) {
443 + if (strstr(line, "disk_rio") || strstr(line, "disk_wio")) {
444 + p = strtok(line, tokens);
446 for (i=0; i<4; i++) {
447 p = strtok(NULL, tokens);
451 + else if (strstr(line, "disk_io")) {
453 + unsigned int a, b, c, d, e, h, g;
455 + p = strtok(line, tokens);
457 + while ((p = strtok(NULL, tokens))) {
459 + "(%d,%d):(%d,%d,%d,%d,%d)",
460 + &a, &b, &c, &d, &e, &h,
471 - if (*ds > maxdiskio) maxdiskio = *ds;
475 @@ -715,16 +799,17 @@
477 \*******************************************************************************/
481 - fprintf(stderr, "\nwmmon - programming: tijno, (de)bugging & design warp, webhosting: bobby\n\n");
482 - fprintf(stderr, "usage:\n");
483 - fprintf(stderr, "\t-display <display name>\n");
484 - fprintf(stderr, "\t-h\tthis screen\n");
485 - fprintf(stderr, "\t-v\tprint the version number\n");
486 - fprintf(stderr, "\t-i\tstartup in DiskIO mode\n");
487 - fprintf(stderr, "\t-s\tstartup in SysInfo mode\n");
488 - fprintf(stderr, "\n");
489 +void usage(char *name) {
490 + printf("Usage: %s [OPTION]...\n", name);
491 + printf("WindowMaker dockapp that displays system information.\n");
493 + printf(" -display DISPLAY contact the DISPLAY X server\n");
494 + printf(" -geometry GEOMETRY position the clock at GEOMETRY\n");
495 + printf(" -l locked view - cannot cycle modes\n");
496 + printf(" -i start in Disk I/O mode\n");
497 + printf(" -s start in System Info mode\n");
498 + printf(" -h display this help and exit\n");
499 + printf(" -v output version information and exit\n");
502 /*******************************************************************************\
505 void printversion(void) {
507 - if (!strcmp(ProgName, "wmmon")) {
508 - fprintf(stderr, "%s\n", WMMON_VERSION);
510 + printf("WMMon version %s\n", WMMON_VERSION);
512 +/* vim: sw=4 ts=4 columns=82
514 --- wmmon-1.0b2.orig/wmmon/wmmon.1
515 +++ wmmon-1.0b2/wmmon/wmmon.1
518 +.\" Man page for wmmon
519 +.\" Copyright (c) 2003 Software in the Public Interest, Inc.
521 +.\" This program is free software; you can redistribute it and/or modify
522 +.\" it under the terms of the GNU General Public License as published by
523 +.\" the Free Software Foundation; either version 2 of the License, or (at
524 +.\" your option) any later version.
526 +.\" This program is distributed in the hope that it will be useful, but
527 +.\" WITHOUT ANY WARRANTY; without even the implied warranty of
528 +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
529 +.\" General Public License for more details.
531 +.\" You should have received a copy of the GNU General Public License
532 +.\" along with this program; if not, write to the Free Software
533 +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
535 +.TH wmmon 1 "May 1998" "WMMON 1.0b2"
538 +wmmon \- Window Maker dockapp for monitoring system information
550 +monitors the realtime CPU load as well as the average system load,
551 +and gives you some nice additional features too. It is intended for
552 +docking in Window Maker.
554 +It currently provides:
557 +a realtime CPU stress meter;
559 +an auto-scaled average system load meter, like
564 +a realtime disk I/O stress meter;
566 +auto-scaled disk I/O load meter;
568 +realtime memory and swap usage meters;
570 +a display for system uptime;
572 +three user-defined commands to launch.
577 +.BI \-display \ display
578 +This option specifies the X server to contact; see
582 +.BI \-geometry \ geometry
583 +This option specifies the preferred position of clock; see
588 +Lock the mode, so that it cannot be cycled by clicking on the upper-left
589 +widget. You can use this to open multiple copies of
591 +each set to a different mode.
595 +Start in disk I/O mode, which displays instantaneous disk usage and
600 +Start in system information mode, which displays memory usage, swap usage,
605 +Show help information.
609 +Print the version number.
614 +display can be cycled between CPU, disk I/O, and system
615 +information displays by clicking on the upper-left widget. This
616 +displays CPU information by default.
618 +WMMon can also be used to launch programs. You may click either left,
619 +middle, or right mouse buttons in the average-load section of the
620 +window. The pre-configured program will be launched according to the
621 +mouse button clicked. (see
622 +.B CONFIGURATION FILE
627 +drag on the outer edges. These are not sensitive to mouse clicks.
629 +.SH "DOCKING IN WINDOW MANAGERS"
634 +Window Maker users should drag and drop the
636 +window on the Dock. Then, right-click on the border of the window and
637 +select \*(lqSettings...\*(rq. Check \*(lqStart when Window Maker
643 +AfterStep users should put the following in their
647 +Wharf wmmon \- MaxSwallow "wmmon" wmmon &
651 +Other window managers
654 +runs nicely as a 64x64 shaped icon on your desktop.
656 +.SH "CONFIGURATION FILE"
659 +can launch three user-defined commands, triggered by left, middle and
660 +right mouse button clicks. You can define the commands to launch in
678 +file, it will launch the appropriate command when you click on the clock.
680 +The system administrator can define default commands in
682 +The administrator may also choose to \*(lqfix\*(rq particular commands,
683 +making it impossible for users to change. These commands can be defined in
684 +.IR /etc/wmmonrc.fixed ,
685 +although this isn't a nice thing to do.
693 +.I /etc/wmmonrc.fixed
698 +was written by Martijn Pieterse and Antoine Nulle.
700 +This manual page was written by Simon Law <sfllaw@debian.org> for the
702 +system (but may be used by others). It is based on the documentation provided
703 +by the original program.
705 +This manual is free software; you can redistribute it and/or modify
706 +it under the terms of the GNU General Public License as published by
707 +the Free Software Foundation; either version 2 of the License, or (at
708 +your option) any later version.