source: npl/mediabox/lcdproc_edwin/src/clients/lcdproc/main.c @ c5c522c

gcc484ntopperl-5.22
Last change on this file since c5c522c was c5c522c, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

initial commit, transferred from cleaned syn3 svn tree

  • Property mode set to 100644
File size: 10.1 KB
Line 
1#include <stdio.h>
2#include <unistd.h>
3#include <string.h>
4#include <fcntl.h>
5#include <sys/time.h>
6#include <termios.h>
7#include <errno.h>
8#include <stdlib.h>
9#include <signal.h>
10#include <ctype.h>
11
12#include "main.h"
13#include "mode.h"
14#include "../../shared/sockets.h"
15#include "../../shared/debug.h"
16
17
18// TODO: Commenting...  Everything!
19
20
21int Quit = 0;
22int sock;
23
24char *version = VERSION;
25char *build_date = __DATE__;
26
27int lcd_wid;
28int lcd_hgt;
29int lcd_cellwid;
30int lcd_cellhgt;
31
32
33/*
34  Mode List:
35    See below...  (default_sequence[])
36*/
37
38void HelpScreen();
39void exit_program(int val);
40void main_loop(mode *sequence);
41
42#define MAX_SEQUENCE 256
43// 1/8th second is a single time unit...
44#define TIME_UNIT 125000
45
46
47// Contains a list of modes to run
48mode default_sequence[] =
49{
50// which on  off  inv  timer/visible 
51  { 'C', 1,   2,   0,  0xffff,0,},// [C]PU
52  { 'N', 1,   2,   0,  0xffff,0,},// [C]PU
53  { 'M', 4,   16,  0,  0xffff,0,},// [M]emory
54  { 'X', 64,  128, 1,  0xffff,0,},// [X]-load (load histogram)
55  { 'T', 4,   64,  0,  0xffff,0,},// [T]ime/Date
56  { 'A', 999,9999, 0,  0xffff,0,},// [A]bout (credits)
57
58  {  1 , 0,   0,   0,  0,0,},// Modes after this line will not be run by default...
59                    // ... all non-default modes must be in here!
60                    // ... they will not show up otherwise.
61  { 'O', 4,   64,  0,  0xffff,0,},// [O]ld Timescreen
62  { 'K', 4,   64,  0,  0xffff,0,},// big cloc[K]
63  { 'U', 4,   128, 0,  0xffff,0,},// Old [U]ptime Screen
64  { 'B', 32,  256, 1,  0xffff,0,},// [B]attery Status
65  { 'G', 1,   2,   0,  0xffff,0,},// Cpu histogram [G]raph
66  { 'S', 16,  256, 1,  0xffff,0,},// [S]ize of biggest programs
67  { 'D', 256, 256, 1,  0xffff,0,},// [D]isk stats
68  { 0,  0,    0,       0,0,},// No more..  all done.
69};
70
71// TODO: Clean up main()...  It is still way too big.
72
73// TODO: Config file; not just command line
74
75
76int main(int argc, char **argv)
77{
78   mode sequence[MAX_SEQUENCE];
79   char cfgfile[256] = "/etc/lcdproc.cf";
80   char server[256] = "localhost";
81   int port = LCDPORT;
82   int i, j, k;
83   int tmp;
84
85   memset(sequence, 0, sizeof(mode) * MAX_SEQUENCE);
86
87   // Ctrl-C will cause a clean exit...
88   signal(SIGINT, exit_program);
89   // and "kill"...
90   signal(SIGTERM, exit_program);
91   // and "kill -HUP" (hangup)...
92   signal(SIGHUP, exit_program);
93   // and just in case, "kill -KILL" (which cannot be trapped; but oh well)
94   signal(SIGKILL, exit_program);
95 
96
97 
98   // Command line
99   memcpy(sequence, default_sequence, sizeof(default_sequence));
100   for(i=1, j=0; i<argc; i++)
101   {
102      if(argv[i][0] == '-') switch(argv[i][1])
103      {
104         // s is for server
105         case 'S':
106         case 's': if(argc < i+1) HelpScreen();
107            strcpy(server, argv[++i]);
108            break;
109         // p is for port
110         case 'P':
111         case 'p': if(argc < i+1) HelpScreen();
112            port = atoi(argv[++i]);
113            if(port < 1  &&  port > 0xffff)
114               fprintf(stderr, "Warning:  Port %i outside of standard range\n",
115                       port);
116            break;
117     
118            // otherwise...  Get help!
119         default: HelpScreen(); break;
120      }
121      // Parse command line here...  read the man page.
122      else if(strlen(argv[i]) == 1)
123      {
124         // Grab the mode letter...
125         sequence[j].which = argv[i][0];
126
127         // If we have just a letter with no numbers...
128         // Set the defaults...
129         for(tmp=0, k=0; default_sequence[k].which; k++)
130         {
131            if(toupper(sequence[j].which) == default_sequence[k].which)
132            {
133               memcpy(&sequence[j], &default_sequence[k], sizeof(mode));
134               tmp=1;
135               break;
136            }
137         }
138         if(!tmp) { printf("Invalid Mode: %c\n", argv[i][0]); exit(0); }
139
140         j++;
141         // Set the last element to 0...
142         memset(sequence + j, 0, sizeof(mode));
143      } // End if(strlen(argv == 1))
144      else
145      {
146         // A multicharacter parameter by itself
147         //  is assumed to be a config file..
148         strcpy(cfgfile, argv[i]);
149         printf("Ignoring config file: %s\n", cfgfile);
150      }
151   }
152
153
154   // Connect to the server...
155   usleep(500000); // wait for the server to start up
156   sock = sock_connect(server, port);
157   if (sock <= 0)
158   {
159      printf("Error connecting to server %s on port %i.\n",
160             server, port);
161      return 0;
162   }
163   sock_send_string(sock, "hello\n");
164   usleep(500000); // wait for the server to say hi.
165   
166   
167   // We grab the real values below, from the "connect" line.
168   lcd_wid = 20;
169   lcd_hgt = 4;
170   lcd_cellwid = 5;
171   lcd_cellhgt = 8;
172   
173   // Init the status gatherers...
174   mode_init(sequence);
175
176   // And spew stuff!
177   main_loop(sequence);
178 
179   // Clean up
180   exit_program(0);
181   return 0;
182}
183
184
185void HelpScreen()
186{
187  printf("LCDproc, %s\n", version);
188  printf("Usage: lcdproc [-s server] [-p port] [modelist]\n");
189  printf("\tOptions in []'s are optional.\n");
190  printf("\tmodelist is \"mode [mode mode ...]\"\n");
191  printf("\tMode letters: \t[C]pu [G]raph [T]ime [M]emory [X]load [D]isk [B]attery\n\t\t\tproc_[S]izes [O]ld_time big_cloc[K] [U]ptime [A]bout\n");
192  printf("\n");
193  printf("\tUse \"man lcdproc\" for more info.\n");
194  printf("Example:\n");
195  printf("\tlcdproc -s my.lcdproc.server.com C M X -p 13666\n");
196  printf("\n");
197  exit(0);
198}
199
200
201///////////////////////////////////////////////////////////////////
202// Called upon TERM and INTR signals...
203//
204void exit_program(int val)
205{
206  Quit = 1;
207  sock_close(sock);
208  mode_close();
209  exit(0);
210}
211
212
213///////////////////////////////////////////////////////////////////
214// Main program loop...
215//
216void main_loop(mode *sequence)
217{
218   int i=0, j;
219   //int status=0;
220   char buf[8192];
221   char *argv[256];
222   int argc, newtoken;
223   int len;
224   
225   
226   // Main loop
227   // Run whatever screen we want, then wait.  Woo-hoo!
228   while(!Quit)
229   {
230      // Check for server input...
231      len = sock_recv(sock, buf, 8000);
232     
233      // Handle server input...
234      while(len > 0)
235      {
236         // Now split the string into tokens...
237         //for(i=0; i<argc; i++) argv[i]=NULL; // Get rid of old tokens
238         argc = 0; newtoken = 1;
239         for(i=0; i<len; i++)
240         {
241            if(buf[i])    // For regular letters, keep tokenizing...
242            {
243               switch(buf[i])
244               {
245                  case ' ':
246                     newtoken = 1;
247                     buf[i] = 0;
248                     break;
249                  case '\n':
250                     buf[i] = 0;
251                  default:
252                     if(newtoken)
253                     {
254                        argv[argc] = buf+i;
255                        argc++;
256                     }
257                     newtoken = 0;
258                     break;
259               }
260            }
261            else  // If we've got a zero, it's the end of a string...
262            {
263               if(argc > 0)
264               {
265                  //printf("%s %s\n", argv[0], argv[1]);
266                  if(0 == strcmp(argv[0], "listen"))
267                  {
268                     for(j=0; sequence[j].which; j++)
269                     {
270                        if(sequence[j].which == argv[1][0])
271                        {
272                           sequence[j].visible = 1;
273                           //debug("Listen %s\n", argv[1]);
274                        }
275                     }
276                  }
277                  else if(0 == strcmp(argv[0], "ignore"))
278                  {
279                     for(j=0; sequence[j].which; j++)
280                     {
281                        if(sequence[j].which == argv[1][0])
282                        {
283                           sequence[j].visible = 0;
284                           //debug("Ignore %s\n", argv[1]);
285                        }
286                     }
287                  }
288                  else if(0 == strcmp(argv[0], "key"))
289                  {
290                     debug("Key %s\n", argv[1]);
291                  }
292                  else if(0 == strcmp(argv[0], "menu"))
293                  {
294                  }
295                  else if(0 == strcmp(argv[0], "connect"))
296                  {
297                     int a;
298                     for(a=1; a<argc; a++)
299                     {
300                        if(0 == strcmp(argv[a], "wid"))
301                           lcd_wid = atoi(argv[++a]);
302                        else if(0 == strcmp(argv[a], "hgt"))
303                           lcd_hgt = atoi(argv[++a]);
304                        else if(0 == strcmp(argv[a], "cellwid"))
305                           lcd_cellwid = atoi(argv[++a]);
306                        else if(0 == strcmp(argv[a], "cellhgt"))
307                           lcd_cellhgt = atoi(argv[++a]);
308                     }
309                  }
310                  else if(0 == strcmp(argv[0], "bye"))
311                  {
312                     //printf("Exiting LCDproc\n");
313                     exit_program(0);
314                  }
315                  else
316                  {
317                     int j;
318                     for(j=0; j<argc; j++)
319                        printf("%s ", argv[j]);
320                     printf("\n");
321                  }
322               }
323               
324               argc = 0;  newtoken = 1;
325            }
326         }
327         
328         len = sock_recv(sock, buf, 8000);
329         //debug("\n");
330      }
331     
332      // Gather stats...
333      // Update screens...
334      for(i=0; sequence[i].which > 1; i++)
335      {
336         sequence[i].timer++;
337         if(sequence[i].visible)
338         {
339            if(sequence[i].timer >= sequence[i].on_time)
340            {
341               sequence[i].timer = 0;
342               // Now, update the screen...
343               update_screen(sequence+i, 1);
344            }
345         }
346         else
347         {
348            if(sequence[i].show_invisible)
349            {
350               if(sequence[i].timer >= sequence[i].off_time)
351               {
352                  sequence[i].timer = 0;
353                  // Now, update the screen...
354                  update_screen(sequence+i, 1);
355               }
356            }
357            else
358            {
359               if(sequence[i].timer >= sequence[i].off_time)
360               {
361                  sequence[i].timer = 0;
362                  // Now, update the screen...
363                  update_screen(sequence+i, 0);
364               }
365            }
366         }
367      }
368
369      // Now sleep...
370      usleep(TIME_UNIT);
371     
372/* Old stuff     
373      timer=0;
374      for(j=0; hold || (j<sequence[i].num_times && !Quit); j++)
375      {
376         switch(sequence[i].which)
377         {
378            case 'g':
379            case 'G': status = cpu_graph_screen(j); break;
380            case 'c':
381            case 'C': status = cpu_screen(j); break;
382            case 'o':
383            case 'O': status = clock_screen(j); break;
384            case 'k':
385            case 'K': status = big_clock_screen(j); break;
386            case 'm':
387            case 'M': status = mem_screen(j); break;
388            case 'u':
389            case 'U': status = uptime_screen(j); break;
390            case 't':
391            case 'T': status = time_screen(j); break;
392            case 'd':
393            case 'D': status = disk_screen(j); break;
394            case 'x':
395            case 'X': status = xload_screen(j); break;
396            case 'b':
397            case 'B': status = battery_screen(j); break;
398            case 'a':
399            case 'A': status = credit_screen(j); break;
400            default: status = dumbass_screen(j); break;
401         }
402         
403         
404         
405         
406         for(k=0; k<sequence[i].delay_time; k++)
407         {
408            usleep(TIME_UNIT);  timer++;
409            // Modify lcd status here...  (blinking, for example)
410            switch(status)
411            {
412               case BLINK_ON : blink=1; break;
413               case BLINK_OFF: blink=0; lcd.backlight(1); break;
414               case BACKLIGHT_OFF: blink=0; lcd.backlight(0); break;
415               case BACKLIGHT_ON : blink=0; lcd.backlight(1); break;
416               case CONTINUE    : hold=0; break;
417            }
418            status=0;
419           
420            if(blink) lcd.backlight(! ((timer&15) == 15));
421           
422            if(heartbeat)
423            {
424               // Set this to pulsate like a real heart beat...
425               // (binary is fun...  :)
426               lcd.icon(!((timer+4)&5), 0);
427               lcd.chr(lcd.wid, 1, 0);
428            }
429           
430            lcd.flush();
431           
432            PollSockets();
433         }
434      }
435      i++;
436      if(sequence[i].which < 2) i=0;
437*/
438   }
439}
440
441
Note: See TracBrowser for help on using the repository browser.