Files
lcdproc/server/main.c
T
ppokorny 00cc9fca23 + Changed protocol to 0.3 because we now accept both -foo and foo
as argument introducers.  in 0.4-pre10, these were changed
   from foo to -foo and this broke many clients.  This change
   should fix that and be backward/forward compatible.
 + Added a noop function to the protocol.  This is useful for writing
   shell script clients of LCDproc.
 + Changed the shared sock_send_string function to NOT send the
   ending NUL ('\0') byte with the string.  This was confusing
   in Perl clients which saw NUL's as the first character of
   each reply.  WARNING: The LCDPROC client depended on this
   behavior, your client may too.  Use the newline instead.
   See the code in clients/lcdproc/main.c (look for "switch(buf[i])")
   to see one way to handle this.  This should allow new clients
   to connect to old servers and vice-versa.
 + Messed with include structure in .c files.  It should no longer
   be necessary to specify ../.. to get to shared code headers.
   Also, since we are using automake, the global config.h can be
   found with just #include "config.h" as it's location is included
   in a -I to the compilers.  As a result "make distcheck" now works.
2001-05-25 03:14:27 +00:00

319 lines
8.3 KiB
C

/*
main.c for LCDd
Contains main(), plus signal callback functions and a help screen.
Program init, command-line handling, and the main loop are
implemented here. Also, minimal data about the program such as
the revision number.
Some of this stuff should probably be move elsewhere eventually,
such as command-line handling and the main loop. main() is supposed
to be "dumb".
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include "shared/debug.h"
#include "drivers/lcd.h"
#include "sock.h"
#include "clients.h"
#include "screenlist.h"
#include "screen.h"
#include "parse.h"
#include "render.h"
#include "serverscreens.h"
#include "input.h"
#include "main.h"
char *version = VERSION;
char *protocol_version = PROTOCOL_VERSION;
char *build_date = __DATE__;
/* no longer needed
static screen_size sizes[] =
{
{"16x2", 16, 2},
{"16x4", 16, 4},
{"20x2", 20, 2},
{"20x4", 20, 4},
{"40x2", 40, 2},
{"40x4", 40, 4},
{NULL , 0, 0},
};
*/
// This is currently only a list of available arguments, but doesn't
// really *do* anything. It just helps to figure out which parameters
// go to the server, and which ones go to individual drivers...
static parameter args[] = {
{"-h", "--help"},
{"-d", "--driver"},
{"-t", "--type"},
{"-f", "--foreground"},
{"-b", "--backlight"},
{"-i", "--serverinfo"},
{NULL, NULL},
};
void exit_program (int val);
void HelpScreen ();
int
main (int argc, char **argv)
{
// TODO: Use a config file!
//char cfgfile[256] = "/etc/LCDd.cf";
int i, err;
int daemon_mode = 1;
int disable_server_screen = 1;
screen *s = NULL;
char *str, *ing; // strings for commandline handling
// screen_size *size = &sizes[0]; // No longer needed
// Ctrl-C will cause a clean exit...
signal (SIGINT, exit_program);
// and "kill"...
signal (SIGTERM, exit_program);
// and "kill -HUP" (hangup)...
signal (SIGHUP, exit_program);
// and just in case, "kill -KILL" (which cannot be trapped; but oh well)
signal (SIGKILL, exit_program);
// If no paramaters given, give the help screen.
if (argc == 1)
HelpScreen ();
// Don't spawn a child if we're using the curses driver
for (i = 1; i < argc; i++) {
if (0 == strcmp (argv[i], "-f") || 0 == strcmp (argv[i], "--foreground") || 0 == strcmp (argv[i], "curses"))
daemon_mode = 0;
}
// Now, go into daemon mode...
#ifndef DEBUG
if (daemon_mode) {
int child;
if ((child = fork ()) != 0) {
usleep (1500000); // Wait for child to initialize
exit (0); /* PARENT EXITS */
}
// This line removed because it eats error messages...
//setsid(); /* RELEASE TTY */
}
#endif
// Set up lcd driver base system
lcd_init ("");
// Parse the command line now...
// TODO: Move this to a separate function?
for (i = 1; i < argc; i++) {
if (0 == strcmp (argv[i], "-d") || 0 == strcmp (argv[i], "--driver")) {
if (argc <= i + 1)
HelpScreen ();
str = argv[++i];
ing = NULL;
// Check to see if the next parameter is intended for LCDd,
// or if it should be passed to the driver...
if (argc > i + 1) {
int j, skip = 0;
for (j = 1; args[j].lg; j++) // check each option except "help"
if (!strcmp (argv[i + 1], args[j].sh) || !strcmp (argv[i + 1], args[j].lg))
skip = 1;
if (!skip) {
ing = argv[++i];
}
//else i++;
}
err = lcd_add_driver (str, ing);
if (err <= 0) {
printf ("Error loading driver %s. Continuing anyway...\n", str);
}
if ((err > 0) && (0 == strcmp (str, "curses")))
daemon_mode = 0;
} else if (0 == strcmp (argv[i], "-h") || 0 == strcmp (argv[i], "--help")) {
HelpScreen ();
}
// Redundant, but it prevents errors...
else if (0 == strcmp (argv[i], "-f") || 0 == strcmp (argv[i], "--foreground")) {
daemon_mode = 0;
} else if (0 == strcmp (argv[i], "-b") || 0 == strcmp (argv[i], "--backlight")) {
if (argc <= i + 1)
HelpScreen ();
str = argv[++i];
if (0 == strcmp (str, "off"))
backlight_state = backlight = BACKLIGHT_OFF;
else if (0 == strcmp (str, "on"))
backlight_state = backlight = BACKLIGHT_ON;
else if (0 == strcmp (str, "open"))
backlight = BACKLIGHT_OPEN;
else
HelpScreen ();
} else if (0 == strcmp (argv[i], "-t") || 0 == strcmp (argv[i], "--type")) {
if (i + 1 > argc)
HelpScreen ();
else {
int wid, hgt;
i++;
sscanf (argv[i], "%ix%i", &wid, &hgt);
if (wid > 80 || wid < 16 || hgt > 25 || hgt < 2) {
fprintf (stderr, "LCDd: Invalid lcd size \"%s\". Using 20x4.\n", argv[i]);
lcd.wid = 20;
lcd.hgt = 4;
} else {
lcd.wid = wid;
lcd.hgt = hgt;
}
/* no longer needed
int j=0, valid=0;
i++;
for(j=0; sizes[j].size; j++)
{
if(0 == strcmp(sizes[j].size, argv[i]))
{
valid = 1;
size = &sizes[j];
lcd.wid = size->wid;
lcd.hgt = size->hgt;
}
}
if(!valid)
{
fprintf(stderr, "LCDd: Invalid lcd size \"%s\". Using 20x4.\n", argv[i]);
}
*/
}
} else if (0 == strcmp (argv[i], "-i") || 0 == strcmp (argv[i], "--serverinfo")) {
if (i + 1 > argc)
HelpScreen ();
else {
i++;
if (0 == strcmp (argv[i], "off"))
disable_server_screen = 1;
if (0 == strcmp (argv[i], "on"))
disable_server_screen = 0;
}
} else {
// otherwise... Get help!
printf ("Invalid parameter: %s\n", argv[i]);
HelpScreen ();
}
}
// Now init a bunch of required stuff...
if (sock_create_server () <= 0) {
printf ("Error opening socket.\n");
return 1;
}
if (client_init () < 0) {
printf ("Error initializing client list\n");
return 1;
}
if (screenlist_init () < 0) {
printf ("Error initializing screen list\n");
return 1;
}
// Make sure the server screen shows up every once in a while..
if (server_screen_init () < 0) {
printf ("Error initializing server screens\n");
return 1;
} else if (disable_server_screen) {
server_screen->priority = 256;
}
// Main loop...
while (1) {
sock_poll_clients ();
parse_all_client_messages ();
handle_input ();
// TODO: Move this code to screenlist.c...
// ... it should just say "handle_screens();"
// Timer gets reset by screenlist_next()
timer++;
// this line's here because s was getting overwritten at one time...
//s = screenlist_current();
if (s && (timer >= s->duration)) {
screenlist_next ();
}
// Just in case it gets out of hand...
if (timer >= 0x10000)
timer = 0;
update_server_screen (timer);
s = screenlist_current ();
// render something here...
if (s)
draw_screen (s, timer);
else
no_screen_screen (timer);
usleep (TIME_UNIT);
}
// Quit!
exit_program (0);
return 0;
}
void
exit_program (int val)
{
// TODO: These things shouldn't be so interdependent. The order
// things are shut down in shouldn't matter...
// Say goodbye!
goodbye_screen ();
// Can go anywhere...
lcd_shutdown ();
// Must come before screenlist_shutdown
client_shutdown ();
// Must come after client_shutdown
screenlist_shutdown ();
// Should come after client_shutdown
sock_close_all ();
exit (0);
}
void
HelpScreen ()
{
printf ("LCDproc server daemon, %s\n", version);
printf ("Copyright (c) 1999 Scott Scriven, William Ferrell, and misc contributors\n");
printf ("This program is freely redistributable under the terms of the GNU Public License\n\n");
printf ("Usage: LCDd [options]\n");
printf ("\tOptions in []'s are optional. Available options are:\n");
printf ("\t-h\t--help\n\t\t\tDisplay this help screen\n");
printf ("\t-t\t--type <size>\n\t\t\tSelect an LCD size (20x4, 16x2, etc...)\n");
printf ("\t-d\t--driver <driver> [args]\n\t\t\tAdd a driver to use:\n");
printf ("\t\t\tCFontz, curses, HD44780, irmanin, joy,\n\t\t\tMtxOrb, LB216, text\n");
printf ("\t\t\t(args will be passed to the driver for init)\n");
printf ("\t-f\t--foreground\n\t\t\tRun in the foreground (no daemon)\n");
printf ("\t-b\t--backlight <mode>\n\t\t\tSet backlight mode (on, off, open)\n");
printf ("\t-i\t--serverinfo off\n\t\t\tSet the server screen to low priority\n");
printf ("\n");
printf ("\tUse \"man LCDd\" for more info.\n");
printf ("\tHelp on each driver's parameters are obtained upon request:\n\t\t\"LCDd -d driver --help\"\n");
printf ("Example:\n");
printf ("\tLCDd -d MtxOrb \"--device /dev/lcd --contrast 200\" -d joy\n");
printf ("\n");
exit (0);
}