<http://www.janw.easynet.be/index.html>
lirc@bartelmus.de
#define DEVDIR "/dev"
#define DEV_LIRCD "lircd"
#define LIRCD DEVDIR "/" DEV_LIRCD
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <getopt.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <errno.h>
#include <signal.h>
#include <limits.h>
#define PACKET_SIZE 256
#define TIMEOUT 3
int timeout = 0;
char *progname;
void
sigalrm (int sig)
{
timeout = 1;
}
void
usage ()
{
puts ("Usage : irtext [OPTION] TEXT ");
puts ("");
puts (" -cls : clear screen");
puts (" -line x : goto line x");
puts (" -time h m s : set time hour min sec");
puts (" -date d m c y : set date day month century year");
puts ("");
puts ("Examples :");
puts ("");
puts (" irtext -date 17 12 20 03 : set date to 17/12/2003 ");
puts (" irtext -cls -line 3 Test : clear screen,");
puts (" goto line 3,");
puts (" print Test");
puts ("");
exit (EXIT_FAILURE);
}
const char *
read_string (int fd)
{
static char buffer[PACKET_SIZE + 1] = "";
char *end;
static int ptr = 0;
ssize_t ret;
if (ptr > 0)
{
memmove (buffer, buffer + ptr, strlen (buffer + ptr) + 1);
ptr = strlen (buffer);
end = strchr (buffer, '\n');
}
else
{
end = NULL;
}
alarm (TIMEOUT);
while (end == NULL)
{
if (PACKET_SIZE <= ptr)
{
fprintf (stderr, "%s: bad packet\n", progname);
ptr = 0;
return (NULL);
}
ret = read (fd, buffer + ptr, PACKET_SIZE - ptr);
if (ret <= 0 || timeout)
{
if (timeout)
{
fprintf (stderr, "%s: timeout\n", progname);
}
else
{
alarm (0);
}
ptr = 0;
return (NULL);
}
buffer[ptr + ret] = 0;
ptr = strlen (buffer);
end = strchr (buffer, '\n');
}
alarm (0);
timeout = 0;
end[0] = 0;
ptr = strlen (buffer) + 1;
# ifdef DEBUG
printf ("buffer: -%s-\n", buffer);
# endif
return (buffer);
}
enum packet_state
{
P_BEGIN,
P_MESSAGE,
P_STATUS,
P_DATA,
P_N,
P_DATA_N,
P_END
};
int
send_char (int fd, const char *packet)
{
BUG
if (send_packet (fd, packet) == -1)
{
exit (EXIT_FAILURE);
}
}
int
send_packet (int fd, const char *packet)
{
int done, todo;
const char *string, *data;
char *endptr;
enum packet_state state;
int status, n;
unsigned long data_n = 0;
todo = strlen (packet);
data = packet;
while (todo > 0)
{
done = write (fd, (void *) data, todo);
if (done < 0)
{
fprintf (stderr, "%s: could not send packet\n", progname);
perror (progname);
return (-1);
}
data += done;
todo -= done;
}
status = 0;
state = P_BEGIN;
n = 0;
while (1)
{
string = read_string (fd);
if (string == NULL)
return (-1);
switch (state)
{
case P_BEGIN:
if (strcasecmp (string, "BEGIN") != 0)
{
continue;
}
state = P_MESSAGE;
break;
case P_MESSAGE:
if (strncasecmp (string, packet, strlen (string)) != 0 ||
strlen (string) + 1 != strlen (packet))
{
state = P_BEGIN;
continue;
}
state = P_STATUS;
break;
case P_STATUS:
if (strcasecmp (string, "SUCCESS") == 0)
{
status = 0;
}
else if (strcasecmp (string, "END") == 0)
{
status = 0;
return (status);
}
else if (strcasecmp (string, "ERROR") == 0)
{
fprintf (stderr, "%s: command failed: %s", progname, packet);
status = -1;
}
else
{
goto bad_packet;
}
state = P_DATA;
break;
case P_DATA:
if (strcasecmp (string, "END") == 0)
{
return (status);
}
else if (strcasecmp (string, "DATA") == 0)
{
state = P_N;
break;
}
goto bad_packet;
case P_N:
errno = 0;
data_n = strtoul (string, &endptr, 0);
if (!*string || *endptr)
{
goto bad_packet;
}
if (data_n == 0)
{
state = P_END;
}
else
{
state = P_DATA_N;
}
break;
case P_DATA_N:
fprintf (stderr, "%s: %s\n", progname, string);
n++;
if (n == data_n)
state = P_END;
break;
case P_END:
if (strcasecmp (string, "END") == 0)
{
return (status);
}
goto bad_packet;
break;
}
}
bad_packet:
fprintf (stderr, "%s: bad return packet\n", progname);
return (-1);
}
main (int arg_aantal, char *arg_tekst[])
{
int teller, cteller, ascii, speciaal;
int fd, space;
char unsigned *kar;
char dummy[PACKET_SIZE + 1];
struct sockaddr_un addr;
struct sigaction act;
if (arg_aantal < 2)
{
usage ();
}
act.sa_handler = sigalrm;
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
sigaction (SIGALRM, &act, NULL);
addr.sun_family = AF_UNIX;
strcpy (addr.sun_path, LIRCD);
fd = socket (AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
{
fprintf (stderr, "%s: could not open socket\n", progname);
perror (progname);
exit (EXIT_FAILURE);
};
if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) == -1)
{
fprintf (stderr, "%s: could not connect to socket\n", progname);
perror (progname);
exit (EXIT_FAILURE);
};
space = 0;
for (teller = 1; teller < arg_aantal; teller = teller + 1)
{
speciaal = 0;
if (space == 0)
{
space = 1;
}
else
{
sprintf (dummy, "send_once lcd ascii32\n");
send_char (fd, dummy);
}
if (strcmp (arg_tekst[teller], "-h") == 0)
{
usage ();
}
if (strcmp (arg_tekst[teller], "-cls") == 0)
{
speciaal = 255;
space = 0;
sprintf (dummy, "send_once lcd ascii0\n");
send_char (fd, dummy);
send_char (fd, dummy);
}
if (strcmp (arg_tekst[teller], "-line") == 0)
{
speciaal = 1;
space = 0;
sprintf (dummy, "send_once lcd ascii0\n");
send_char (fd, dummy);
}
if (strcmp (arg_tekst[teller], "-time") == 0)
{
speciaal = 3;
space = 0;
sprintf (dummy, "send_once lcd ascii0\n");
send_char (fd, dummy);
sprintf (dummy, "send_once lcd ascii5\n");
send_char (fd, dummy);
}
if (strcmp (arg_tekst[teller], "-date") == 0)
{
speciaal = 4;
space = 0;
sprintf (dummy, "send_once lcd ascii0\n");
send_char (fd, dummy);
sprintf (dummy, "send_once lcd ascii6\n");
send_char (fd, dummy);
}
if (speciaal == 0)
{
for (cteller = 0; cteller < strlen (arg_tekst[teller]);
cteller = cteller + 1)
{
kar = arg_tekst[teller] + cteller;
sprintf (dummy, "send_once lcd ascii%d\n", *kar);
send_char (fd, dummy);
}
}
else
{
if (speciaal < 255)
{
for (cteller = 0; cteller < speciaal; cteller = cteller + 1)
{
teller++;
if (teller >= arg_aantal)
{
usage ();
}
ascii = atoi (arg_tekst[teller]);
sprintf (dummy, "send_once lcd ascii%d\n", ascii);
send_char (fd, dummy);
}
}
}
}
}