Skip to content

Commit

Permalink
refactor, simplify, use notify-send
Browse files Browse the repository at this point in the history
  • Loading branch information
pbrisbin committed May 30, 2012
1 parent b4630bd commit 3944f7f
Showing 1 changed file with 69 additions and 86 deletions.
155 changes: 69 additions & 86 deletions android-receiver.c
Expand Up @@ -2,6 +2,7 @@

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
Expand All @@ -10,17 +11,13 @@
#include <getopt.h>
#include <errno.h>

#define DEBUG 0
#define MAXBUF 1024
#define TOK "/"
#define FMTCALL " -!- Call from %s"
#define FMTOTHER " -!- %s"
#define MAXBUF 1024
#define SEP "/"

#define STREQ(a, b) strcmp((a),(b)) == 0
#define STRDUP(a, b) if ((b)) a = strdup((b))
#define STREQ(a, b) strcmp((a),(b)) == 0
#define STRDUP(a, b) if ((b)) a = strdup((b))

static int portno = 10600;
static char *handler;
static int portno = 10600;

enum etype {
Ring,
Expand All @@ -40,71 +37,47 @@ struct message_t {
char * event_contents;
};

static void error(char *msg) { /* {{{ */
perror(msg);
exit(EXIT_FAILURE);
}
/* }}} */

static void help_message() { /* {{{ */
fprintf(stderr, "usage: android-receiver [ -p <port> ] -h <handler> \n"
" -p, --port the port to listen on. optional, defaults to 10600. \n"
" -h, --handler an executable to handle the message. will be called with \n"
" the formatted message as its first and only argument. \n");

exit(EXIT_FAILURE);
}
/* }}} */

static int handle_options(int argc, char *argv[]) { /* {{{ */
static void parse_options(int argc, char *argv[]) {
int opt, option_index = 0;
char *token;

static struct option opts[] = {
{ "port" , required_argument, 0, 'p'},
{ "handler", required_argument, 0, 'h'},
{ "help" , no_argument, 0, 'h'},
{ 0 , 0 , 0, 0 }
};

while ((opt = getopt_long(argc, argv, "p:h:", opts, &option_index)) != -1) {
switch(opt) {
while ((opt = getopt_long(argc, argv, "hp:", opts, &option_index)) != -1) {
switch (opt) {
case 'p':
portno = strtol(optarg, &token, 10);
if (*token != '\0' || portno <= 0 || portno > 65535) {
fprintf(stderr, "error: invalid port number\n\n");
return 1;
fprintf(stderr, "invalid port number\n");
exit(EXIT_FAILURE);
}
break;

case 'h':
handler = optarg;
break;
printf("usage: android-receiver [ -p <port> ]\n");
exit(EXIT_SUCCESS);

default:
return 1;
fprintf(stderr, "invalid option, try -h or --help\n");
exit(EXIT_FAILURE);
}
}

if (!handler) {
fprintf(stderr, "error: handler is required\n\n");
return 1;
}

return 0;
}
/* }}} */

static struct message_t *parse_message(char *msg) { /* {{{ */
static struct message_t *parse_message(char *msg) {
struct message_t *message;
char *tmp;
char *tok;
char *tmp, *tok;
int field = 0;

message = malloc(sizeof *message);

/* v1: device_id / notification_id / event_type / event_contents */
/* v2: "v2" / device_id / notification_id / event_type / data / event_contents */
for (tok = strsep(&msg, TOK); ++field <= 5; tok = strsep(&msg, TOK)) {
for (tok = strsep(&msg, SEP); ++field <= 5; tok = strsep(&msg, SEP)) {
switch (field) {
case 1:
if (tok && STREQ(tok, "v2"))
Expand All @@ -113,7 +86,7 @@ static struct message_t *parse_message(char *msg) { /* {{{ */
/* rebuild a v1 msg to start parsing at field 2 */
message->version = 1;
tmp = strdup(msg);
strcat(tok, TOK);
strcat(tok, SEP);
strcat(tok, tmp);
msg = tok;
}
Expand All @@ -133,6 +106,7 @@ static struct message_t *parse_message(char *msg) { /* {{{ */
if (message->version == 1) {
/* for v1, grab everything else and return */
STRDUP(message->event_contents, msg);
message->data = "";
return message;
}
break;
Expand All @@ -146,79 +120,88 @@ static struct message_t *parse_message(char *msg) { /* {{{ */

return message;
}
/* }}} */

static void handle_message(struct message_t *message) { /* {{{ */
char *msg;
static void handle_message(char *msg) { /* {{{ */
printf("message received: %s\n", msg);

struct message_t *message;
char *title, *body;

message = parse_message(msg);

switch (message->event_type) {
case Ring:
asprintf(&msg, FMTCALL, message->event_contents);
asprintf(&title, "Call: %s", message->data);
break;

case SMS:
asprintf(&title, "SMS: %s", message->data);
break;
case MMS:
asprintf(&title, "MMS: %s", message->data);
break;
case Battery:
case Ping: /* todo: other type-specific formats */
asprintf(&msg, FMTOTHER, message->event_contents);
asprintf(&title, "Battery: %s", message->data);
break;
case Ping:
title = "Ping";
break;

default: msg = NULL;
default:
return;
}

if (!msg)
return;
asprintf(&body, "%s", message->event_contents);

char *flags[] = { "notify-send", title, body, (char *)NULL };

/* double-fork taken from dzen2/util.c; avoids zombie processes
* without requiring a signal handler. */
if (fork() == 0) {
if (fork() == 0) {
execvp("notify-send", flags);
exit(EXIT_SUCCESS);
}
exit(EXIT_SUCCESS);
}

char *flags[] = { handler, msg, (char *)NULL };
execvp(handler, flags);
wait(0);
}
/* }}} */

int main(int argc, char *argv[]) { /* {{{ */
int main(int argc, char *argv[]) {
char buf[MAXBUF];

struct message_t *message;
struct sockaddr_in server, from;
struct sockaddr_in server, from;

int sock, n;
unsigned int fromlen = sizeof from;

if (handle_options(argc, argv) != 0)
help_message();
parse_options(argc, argv);

if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
error("error opening socket");
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("error opening socket");
exit(EXIT_FAILURE);
}

memset(&server, '\0', sizeof server);

server.sin_family = AF_INET;
server.sin_port = htons(portno);
server.sin_addr.s_addr = INADDR_ANY;

if (bind(sock, (struct sockaddr *)&server, sizeof server) < 0)
error("error binding to socket");
if (bind(sock, (struct sockaddr *)&server, sizeof server) < 0) {
perror("error binding to socket");
exit(EXIT_FAILURE);
}

while (1) {
while ((n = recvfrom(sock, buf, 1024, 0, (struct sockaddr *)&from, &fromlen)) < 0 && errno == EINTR)
;

if (n < 0)
error("error receiving from socket");

if (DEBUG)
printf("message received: %s\n", buf);

/* double-fork taken from dzen2/util.c; avoids zombie processes
* without requiring a signal handler. */
if (fork() == 0) {
if (fork() == 0) {
message = parse_message(buf);
handle_message(message);
exit(EXIT_SUCCESS);
}
exit(EXIT_SUCCESS);
if (n < 0) {
perror("error receiving from socket");
exit(EXIT_FAILURE);
}
wait(0);

handle_message(buf);
}
}
/* }}} */

0 comments on commit 3944f7f

Please sign in to comment.