1 /*
2
3 wminet.c
4 Multi-function system monitor
5 by Dave Clark (clarkd@skynet.ca) (http://www.neotokyo.org/illusion)
6 Martijn Pieterse (pieterse@xs4all.nl) (http://windowmaker.mezaway.org)
7 and Antoine Nulle (warp@xs4all.nl) (http://windowmaker.mezaway.org)
8
9 This software is licensed through the GNU General Public Lisence.
10
11 ProFTPD support by Mike Kershaw aka Dragorn (dragorn@melchior.nerv-un.ml.org)
12 ProFTPD support was made 64bit clean by Martijn Pieterse (pieterse@xs4all.nl)
13
14 see http://windowmaker.mezaway.org for more awesome wm dock apps :)
15
16 */
17
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <time.h>
22 #include <string.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25 #include <ctype.h>
26
27 #include <sys/wait.h>
28 #include <sys/stat.h>
29 #include <sys/param.h>
30 #include <sys/types.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
33
34 #include <dirent.h>
35
36 #include <X11/Xlib.h>
37 #include <X11/xpm.h>
38 #include <X11/extensions/shape.h>
39
40 #include "../wmgeneral/wmgeneral.h"
41 #include "../wmgeneral/misc.h"
42
43 #include "wmscript-master.xpm"
44 char wminet_mask_bits[64*64];
45 int wminet_mask_width = 64;
46 int wminet_mask_height = 64;
47
48 #define WMSCRIPT_VERSION "1.0"
49
50 #define CHAR_WIDTH 5
51 #define CHAR_HEIGHT 7
52
53 // Lame work-around... Sigh... when will they standardize the headers!?!?
54 #define TCP_ESTABLISHED 1
55
56 extern char **environ;
57
58 char *ProgName;
59
60 int loopinterval=1;
61
62 typedef struct
63 {
64 int pos;
65 char script[256];
66 char label[10];
67 char action[256];
68 int interval;
69 int value;
70 } script_t;
71 script_t scripts[6];
72
73 int timers[6];
74
75 char uconfig_file[256];
76
77 void usage(void);
78 void printversion(void);
79 void BlitString(char *name, int x, int y);
80 void BlitNum(int num, int x, int y);
81 void GetStats(int script);
82 void wminet_routine(int, char **);
83 int ReadConfigInt(FILE *fp, char *setting, int *value);
84 int ReadConfigString(FILE *fp, char *setting, char *value);
85 int Read_Config_File( char *filename );
86 int RunScript(const char* script);
87 char *GetAction(const int pos, char *action);
88 void CreateDisplay();
89 void debug(const char* buff);
90 void debugi(const int val);
91
92
main(int argc,char * argv[])93 int main(int argc, char *argv[]) {
94
95 int i;
96
97 uconfig_file[0] = 0;
98
99 /* Parse Command Line */
100
101 ProgName = argv[0];
102 if (strlen(ProgName) >= 5)
103 ProgName += (strlen(ProgName) - 5);
104
105 for (i=1; i<argc; i++) {
106 char *arg = argv[i];
107
108 if (*arg=='-') {
109 switch (arg[1]) {
110 case 'd' :
111 if (strcmp(arg+1, "display")) {
112 usage();
113 exit(1);
114 }
115 break;
116 case 'g' :
117 if (strcmp(arg+1, "geometry")) {
118 usage();
119 exit(1);
120 }
121 break;
122 case 'v' :
123 printversion();
124 exit(0);
125 break;
126 case 'c' :
127 if (argc > (i+1))
128 {
129 strcpy(uconfig_file, argv[i+1]);
130 i++;
131 }
132 break;
133 default:
134 usage();
135 exit(0);
136 break;
137 }
138 }
139 }
140
141 wminet_routine(argc, argv);
142
143 return 0;
144 }
145
146 /*******************************************************************************\
147 |* wminet_routine *|
148 \*******************************************************************************/
149
wminet_routine(int argc,char ** argv)150 void wminet_routine(int argc, char **argv)
151 {
152 int i;
153 XEvent Event;
154 int but_stat = -1;
155
156 time_t curtime;
157 time_t prevtime;
158
159 char config_file[512];
160
161 memset(&scripts, 0, sizeof(scripts));
162 memset(&timers, 0, sizeof(timers));
163
164 createXBMfromXPM(wminet_mask_bits, wminet_master_xpm, wminet_mask_width, wminet_mask_height);
165
166 openXwindow(argc, argv, wminet_master_xpm, wminet_mask_bits, wminet_mask_width, wminet_mask_height);
167
168 AddMouseRegion(0, 5, 6, 58, 16);
169 AddMouseRegion(1, 5, 16, 58, 26);
170 AddMouseRegion(2, 5, 26, 58, 36);
171 AddMouseRegion(3, 5, 36, 58, 46);
172 AddMouseRegion(4, 5, 46, 58, 56);
173
174 // Read config file
175
176 if (uconfig_file[0] != 0)
177 {
178 // user-specified config file
179 fprintf(stderr, "Using user-specified config file '%s'.\n", uconfig_file);
180 Read_Config_File(uconfig_file);
181 }
182 else
183 {
184 sprintf(config_file, "%s/.wmscriptrc", getenv("HOME"));
185
186 if (!Read_Config_File(config_file))
187 {
188 // Fall back to /etc/wmscriptrc
189 sprintf(config_file, "/etc/wmscriptrc");
190
191 Read_Config_File(config_file);
192 }
193 }
194
195 // Initial display
196 GetStats(0);
197 CreateDisplay();
198 RedrawWindow();
199
200 prevtime = time(0) - 1;
201
202 while (1)
203 {
204 curtime = time(0);
205 waitpid(0, NULL, WNOHANG);
206
207 if ( curtime >= prevtime + loopinterval)
208 {
209 int loop;
210 prevtime = curtime;
211
212 for (loop = 1;loop<6;loop++)
213 {
214 timers[loop]++;
215
216 if (timers[loop] >= scripts[loop].interval)
217 {
218 timers[loop] = 0;
219 // Get data to display
220 GetStats(loop);
221 CreateDisplay();
222 RedrawWindow();
223 }
224 }
225 }
226
227 // X Events
228 while (XPending(display))
229 {
230 XNextEvent(display, &Event);
231 switch (Event.type)
232 {
233 case Expose:
234 RedrawWindow();
235 break;
236 case DestroyNotify:
237 XCloseDisplay(display);
238 exit(0);
239 break;
240 case ButtonPress:
241 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
242
243 but_stat = i;
244 break;
245 case ButtonRelease:
246 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
247
248 if (but_stat == i && but_stat >= 0)
249 {
250 char action[256];
251 execCommand(GetAction(but_stat+1, action));
252 }
253 but_stat = -1;
254 // RedrawWindow();
255 break;
256 }
257 }
258
259 usleep(100000L);
260 }
261 }
262
263 // runs the script specified by the number passed in, zero for all
GetStats(int script)264 void GetStats(int script)
265 {
266 int loop, loop_start, loop_stop;
267
268 if (script == 0)
269 {
270 loop_start = 1;
271 loop_stop = 6;
272 }
273 else
274 {
275 loop_start = script;
276 loop_stop = script+1;
277 }
278
279 for (loop = loop_start; loop<loop_stop;loop++)
280 {
281 if (scripts[loop].pos != 0)
282 {
283 char script[256];
284 int len, ret;
285
286 len = strlen(scripts[loop].script);
287
288 strncpy(script, scripts[loop].script, len);
289 script[len] = '\0';
290
291 ret = RunScript (script);
292
293 scripts[loop].value = ret;
294
295 }
296 }
297 }
298
299
300 // Blits a string at given co-ordinates
BlitString(char * name,int x,int y)301 void BlitString(char *name, int x, int y)
302 {
303 int i;
304 int c;
305 int k;
306
307 k = x;
308 for (i=0; name[i]; i++)
309 {
310
311 c = toupper(name[i]);
312 if (c >= 'A' && c <= 'Z')
313 { // its a letter
314 c -= 'A';
315 copyXPMArea(c * 6, 74, 6, 8, k, y);
316 k += 6;
317 }
318 else
319 { // its a number or symbol
320 c -= '0';
321 copyXPMArea(c * 6, 64, 6, 8, k, y);
322 k += 6;
323 }
324 }
325
326 }
327
328
329 // Blits number to give coordinates.. two 0's, right justified
330
BlitNum(int num,int x,int y)331 void BlitNum(int num, int x, int y)
332 {
333 char buf[1024];
334 int newx=x;
335
336 if (num > 99)
337 {
338 newx -= CHAR_WIDTH;
339 }
340
341 if (num > 999)
342 {
343 num = 999;
344 }
345
346 sprintf(buf, "%02i", num);
347
348 BlitString(buf, newx, y);
349 }
350
351
352 // ReadConfigSetting
ReadConfigString(FILE * fp,char * setting,char * value)353 int ReadConfigString(FILE *fp, char *setting, char *value)
354 {
355 char str[1024];
356 char buf[1024];
357 int i;
358 int len;
359 int slen;
360 char *p=NULL;
361
362 if (!fp)
363 {
364 return 0;
365 }
366
367 sprintf(str, "%s=", setting);
368 slen = strlen(str);
369
370 fseek(fp, 0, SEEK_SET);
371
372 while ( !feof(fp) )
373 {
374
375 if (!fgets(buf, 512, fp))
376 break;
377
378 len = strlen(buf);
379
380 // strip linefeed
381 for (i=0; i!=len; i++)
382 {
383 if (buf[i] == '\n')
384 {
385 buf[i] = 0;
386 }
387 }
388
389 //printf("Scanning '%s'...\n", buf);
390 if ( strncmp(buf, str, strlen(str)) == 0)
391 {
392 // found our setting
393
394 for(i=0; i!=slen; i++)
395 {
396 if ( buf[i] == '=' )
397 {
398 p=buf+i+1;
399 strcpy(value, p);
400 return 1;
401 }
402 }
403
404 }
405 }
406
407 return 0;
408 }
409
ReadConfigInt(FILE * fp,char * setting,int * value)410 int ReadConfigInt(FILE *fp, char *setting, int *value)
411 {
412 char buf[1024];
413
414
415 if (ReadConfigString(fp, setting, (char *) &buf))
416 {
417 *value = atoi(buf);
418 return 1;
419 }
420
421 return 0;
422 }
423
Read_Config_File(char * filename)424 int Read_Config_File( char *filename )
425 {
426 FILE *fp;
427
428 fp = fopen(filename, "r");
429 if (fp)
430 {
431 int loop;
432
433 for (loop = 1; loop<6;loop++)
434 {
435 char pos[15], script[15], label[15], action[15], interval[17];
436 sprintf(pos,"script%d.pos",loop);
437 sprintf(script,"script%d.script",loop);
438 sprintf(label,"script%d.label",loop);
439 sprintf(action,"script%d.action",loop);
440 sprintf(interval,"script%d.interval",loop);
441
442 ReadConfigInt(fp, pos, &scripts[loop].pos);
443 ReadConfigString(fp, script, scripts[loop].script);
444 ReadConfigString(fp, label, scripts[loop].label);
445 ReadConfigString(fp, action, scripts[loop].action);
446 ReadConfigInt(fp, interval, &scripts[loop].interval);
447 }
448
449 fclose(fp);
450 return 1;
451 }
452 else
453 {
454 perror("Read_Config_File");
455 fprintf(stderr, "Unable to open %s, no settings read.\n", filename);
456 return 0;
457 }
458
459 }
460
461
RunScript(const char * script)462 int RunScript(const char* script)
463 {
464 int ret = -1, loop;
465 FILE *proc;
466 char buff[256];
467 char ch = '\0';
468
469 memset (buff, 0, 255);
470
471 proc = popen(script, "r");
472
473 if (proc != NULL)
474 {
475 for (loop = 0; loop<255 && ch != EOF;loop++)
476 {
477 ch = getc(proc);
478 if (ch != EOF)
479 buff[loop] = ch;
480 }
481
482 pclose (proc);
483 }
484 ret = atoi(buff);
485
486 return ret;
487 }
488
GetAction(const int pos,char * action)489 char *GetAction(const int pos, char *action)
490 {
491 int loop;
492
493 for (loop = 1; loop<6;loop++)
494 {
495
496 if (pos == scripts[loop].pos)
497 {
498 strcpy(action, scripts[loop].action);
499 }
500 }
501
502 return action;
503
504 }
505
506 /*******************************************************************************\
507 |* usage *|
508 \*******************************************************************************/
509
usage(void)510 void usage(void)
511 {
512 fprintf(stderr, "\nWMScript - Darren Greaves <darren@magma.dircon.co.uk>, illusion <clarkd@skyia.com>, warp <warp@xs4all.nl>\n & tijno <pieterse@xs4all.nl>\n\n");
513 fprintf(stderr, "usage:\n");
514 fprintf(stderr, " -display <display name>\n");
515 fprintf(stderr, " -geometry +XPOS+YPOS initial window position\n");
516 fprintf(stderr, " -c <filename> use specified config file\n");
517 fprintf(stderr, " -h this help screen\n");
518 fprintf(stderr, " -v print the version number\n");
519 fprintf(stderr, "\n");
520 }
521
522 /*******************************************************************************\
523 |* printversion *|
524 \*******************************************************************************/
525
printversion(void)526 void printversion(void)
527 {
528 fprintf(stderr, "wmscript v%s\n", WMSCRIPT_VERSION);
529 }
530
debug(const char * buff)531 void debug(const char* buff)
532 {
533 fprintf (stderr, buff);
534 fprintf (stderr, "\n");
535 }
536
debugi(const int val)537 void debugi(const int val)
538 {
539 char buff[256];
540
541 sprintf (buff, "%d",val);
542
543 fprintf (stderr, buff);
544 fprintf (stderr, "\n");
545 }
546
CreateDisplay()547 void CreateDisplay()
548 {
549 char buf[64];
550 int i,j,k;
551
552 for (i=1; i<6; i++)
553 {
554 for (j=1; j<6; j++)
555 {
556 if ( i == scripts[j].pos )
557 {
558 strncpy(buf, scripts[j].label, 5);
559
560 for (k=0; k<5; k++)
561 {
562 if (buf[k] == 0)
563 buf[k] = ' ';
564 }
565
566 buf[5] = ':';
567 buf[6] = 0;
568
569 BlitString(buf, 5, (11*(i-1)) + 5);
570 copyXPMArea(39, 84, (3*CHAR_WIDTH), 8, 39, (11*(i-1)) + 5);
571 BlitNum(scripts[j].value, 45, (11*(i-1)) + 5);
572 }
573 }
574 }
575 }
576