summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2003-12-23 00:05:15 +0000
committerLennart Poettering <lennart@poettering.net>2003-12-23 00:05:15 +0000
commit33f01df1c95b43b66e2f0bab2b972dd9e03faeb5 (patch)
tree053f3bcff15d9161e6b2f0c942941052de5fb14f
parent51c0330ea15a28d2d7c83a746458dfd5cf1770bc (diff)
it compiles and works basically
git-svn-id: file:///home/lennart/svn/public/ivam2/trunk@9 dbf6933d-3bce-0310-9bcc-ed052ba35b35
-rw-r--r--src/Makefile6
-rw-r--r--src/buffio.c231
-rw-r--r--src/buffio.h15
-rw-r--r--src/dle.c7
-rw-r--r--src/dle.h8
-rw-r--r--src/exec.c118
-rw-r--r--src/exec.h4
-rw-r--r--src/lock.c18
-rw-r--r--src/main.c19
-rw-r--r--src/main.h2
-rw-r--r--src/modem.c377
-rw-r--r--src/modem.h12
-rw-r--r--src/modemman.c45
-rw-r--r--src/util.c9
-rw-r--r--src/util.h4
15 files changed, 581 insertions, 294 deletions
diff --git a/src/Makefile b/src/Makefile
index 7269fde..5aff207 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,8 +1,8 @@
CC=gcc
-CFLAGS=`pkg-config --cflags libdaemon shbuf` -Wall -O2 -pipe
-LIBS=`pkg-config --libs libdaemon shbuf`
+CFLAGS=`pkg-config --cflags libdaemon shbuf liboop` -Wall -O0 -pipe -g
+LIBS=`pkg-config --libs libdaemon shbuf liboop` -Wall -O0 -pipe -g
-ivamd: modem.o main.o
+ivamd: modem.o main.o modemman.o buffio.o exec.o dle.o lock.o util.o msntab.o
$(CC) $(LIBS) -o $@ $^
clean:
diff --git a/src/buffio.c b/src/buffio.c
index 2c3a7fb..25ba5a4 100644
--- a/src/buffio.c
+++ b/src/buffio.c
@@ -1,12 +1,25 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include <oop.h>
+
+#include <libdaemon/dlog.h>
+
#include "buffio.h"
+#include "main.h"
#define BUFSIZE 10240
-static void buffio_set_callbacks(struct buffio *b);
static void* buffio_read_cb(oop_source *source, int fd, oop_event event, void *user);
static void* buffio_write_cb(oop_source *source, int fd, oop_event event, void *user);
-struct buffio buffio_new(int fd) {
+static void buffio_set_input_callbacks(struct buffio *b);
+static void buffio_set_output_callbacks(struct buffio *b);
+
+struct buffio* buffio_new(int ifd, int ofd) {
struct buffio *b;
assert(b >= 0);
@@ -14,19 +27,21 @@ struct buffio buffio_new(int fd) {
assert(b);
memset(b, 0, sizeof(struct buffio));
- b->fd = fd;
+ b->ifd = ifd;
+ b->ofd = ofd;
b->input_buf = malloc(b->input_max_length = BUFSIZE);
assert(b->input_buf);
- b->input_buf_len = b->input_index = 0;
- b->input_watermark = 2; /* Read some more data if 2 or less bytes are in the input buffer */
+ b->input_length = b->input_index = 0;
+ b->input_watermark = b->input_max_length; /* Read some more data if possible */
b->output_buf = malloc(b->output_max_length = BUFSIZE);
assert(b->output_buf);
b->output_length = b->output_index = 0;
b->output_watermark = 1; /* Write some data if 1 or more bytes are in the output buffer */
- buffio_set_callbacks(b);
+ buffio_set_input_callbacks(b);
+ buffio_set_output_callbacks(b);
return b;
}
@@ -35,16 +50,18 @@ static void buffio_close_fd(struct buffio *b) {
assert(b);
if (b->b_read_cb)
- event_source->cancel_fd(event_source, b->fd, OOP_READ, buffio_read_cb, b);
+ event_source->cancel_fd(event_source, b->ifd, OOP_READ);
if (b->b_write_cb)
- event_source->cancel_fd(event_source, b->fd, OOP_WRITE, buffio_write_cb, b);
+ event_source->cancel_fd(event_source, b->ofd, OOP_WRITE);
- if (b->fd >= 0)
- close(b->fd);
+ if (b->ifd >= 0)
+ close(b->ifd);
+ if (b->ofd >= 0 && b->ofd != b->ifd)
+ close(b->ofd);
b->b_read_cb = b->b_write_cb = 0;
- b->fd = -1;
+ b->ifd = b->ofd = -1;
}
@@ -55,13 +72,69 @@ void buffio_free(struct buffio *b) {
free(b);
}
+#ifdef IODEBUG
+static void esc_print(const char*c, const uint8_t *b, size_t l) {
+ size_t i;
+ fprintf(stderr, "%s", c);
+ for (i = 0; i < l; i++, b++)
+ fputc(*b < 32 ? '.' : *b, stderr);
+
+ fprintf(stderr, "\n");
+};
+#endif
+
+static void buffio_normalize(struct buffio *b) {
+ assert(b);
+
+ assert(b->input_index < b->input_max_length);
+ assert(b->input_length <= b->input_max_length);
+
+ if (!b->input_length) /* This will optimize throughput a bit */
+ b->input_index = 0;
+
+ if (!b->output_length) /* This will optimize throughput a bit */
+ b->output_index = 0;
+}
+
+static void buffio_set_input_callbacks(struct buffio *b) {
+ assert(b && b->ifd >= 0 && event_source);
+
+ if (b->input_length <= b->input_watermark) {
+ if (!b->b_read_cb) { /* Enable the callback */
+ event_source->on_fd(event_source, b->ifd, OOP_READ, buffio_read_cb, b);
+ b->b_read_cb = 1;
+ }
+ } else {
+ if (b->b_read_cb) { /* Disable the callback */
+ event_source->cancel_fd(event_source, b->ifd, OOP_READ);
+ b->b_read_cb = 0;
+ }
+ }
+}
+
+static void buffio_set_output_callbacks(struct buffio *b) {
+ assert(b && b->ofd >= 0 && event_source);
+
+ if (b->output_length >= b->output_watermark) {
+ if (!b->b_write_cb) { /* Enable the callback */
+ event_source->on_fd(event_source, b->ofd, OOP_WRITE, buffio_write_cb, b);
+ b->b_write_cb = 1;
+ }
+ } else {
+ if (b->b_write_cb) { /* Disable the callback */
+ event_source->cancel_fd(event_source, b->ofd, OOP_WRITE);
+ b->b_write_cb = 0;
+ }
+ }
+}
+
static void* buffio_read_cb(oop_source *source, int fd, oop_event event, void *user) {
struct buffio *b = user;
- assert(source && b && b->fd == fd && event == OOP_READ);
+ assert(source && b && b->ifd == fd && event == OOP_READ);
if (b->input_length < b->input_max_length) {
ssize_t s;
- size_t m, l;
+ size_t m, i;
i = (b->input_index + b->input_length) % b->input_max_length;
@@ -74,6 +147,10 @@ static void* buffio_read_cb(oop_source *source, int fd, oop_event event, void *u
return OOP_HALT;
}
+#ifdef IODEBUG
+ esc_print("INPUT: ", b->input_buf+i, s);
+#endif
+
if (!s) {
buffio_close_fd(b);
if (b->eof_cb)
@@ -96,9 +173,9 @@ static void* buffio_read_cb(oop_source *source, int fd, oop_event event, void *u
static void* buffio_write_cb(oop_source *source, int fd, oop_event event, void *user) {
struct buffio *b = user;
- assert(source && b && b->fd == fd && event == OOP_WRITE);
+ assert(source && b && b->ofd == fd && event == OOP_WRITE);
- if (b->output_buf > 0) {
+ if (b->output_length > 0) {
ssize_t s;
size_t m;
@@ -111,6 +188,10 @@ static void* buffio_write_cb(oop_source *source, int fd, oop_event event, void *
return OOP_HALT;
}
+#ifdef IODEBUG
+ esc_print("OUTPUT: ", b->output_buf+b->output_index, s);
+#endif
+
if (!s) {
buffio_close_fd(b);
if (b->eof_cb)
@@ -120,7 +201,7 @@ static void* buffio_write_cb(oop_source *source, int fd, oop_event event, void *
assert(s <= m);
b->output_index = (b->output_index + s) % b->output_max_length;
- b->ouput_length -= s;
+ b->output_length -= s;
}
buffio_normalize(b);
@@ -133,51 +214,24 @@ static void* buffio_write_cb(oop_source *source, int fd, oop_event event, void *
}
-static void buffio_set_input_callbacks(struct buffio *b) {
- assert(b && b->fd >= 0 && event_source);
-
- if (b->input_length <= b->input_watermark) {
- if (!b->b_read_cb) { /* Enable the callback */
- event_source->on_fd(event_source, b->fd, OOP_READ, buffio_read_cb, b);
- b->b_read_cb = 1;
- }
- } else {
- if (b->read_cb) { /* Disable the callback */
- event_source->cancel_fd(event_source, b->fd, OOP_READ, buffio_read_cb, b);
- b->read_cb = 0;
- }
- }
-}
-
-static void buffio_set_output_callbacks(struct buffio *b) {
- assert(b && b->fd >= 0 && event_source);
-
- if (b->output_length >= b->output_watermark) {
- if (!b->b_write_cb) { /* Enable the callback */
- event_source->on_fd(event_source, b->fd, OOP_WRITE, buffio_write_cb, b);
- b->b_write_cb = 1;
- }
- } else {
- if (b->b_write_cb) { /* Disable the callback */
- event_source->cancel_fd(event_source, b->fd, OOP_WRITE, buffio_write_cb, b);
- b->b_write_cb = 0;
- }
- }
-}
int buffio_write(struct buffio *b, const uint8_t *d, size_t l) {
- assert(b && s && l);
+ assert(b && d && l);
- if (l < b->output_max_length - b->output_length) {
+ if (l > b->output_max_length - b->output_length) {
daemon_log(LOG_ERR, "buffio_write() with too much data called");
return -1;
}
+ while (l > 0) {
+ size_t m, i;
+
+ i = (b->output_index + b->output_length) % b->output_max_length;
- while (l >= 0) {
- i = (b->ouput_index + b->ouput_length) % b->ouput_max_length;
+ m = l;
+ if (m > b->output_max_length-b->output_length)
+ m = b->output_max_length-b->output_length;
- m = b->ouput_max_length-b->output_length;
if (m > b->output_max_length-i)
m = b->output_max_length-i;
@@ -188,7 +242,7 @@ int buffio_write(struct buffio *b, const uint8_t *d, size_t l) {
}
buffio_set_output_callbacks(b);
- buffio_normalize();
+ buffio_normalize(b);
return 0;
}
@@ -200,7 +254,7 @@ int buffio_print(struct buffio *b, const char *s) {
int buffio_command(struct buffio *b, const char *c) {
assert(b && c);
-
+
buffio_flush_input(b);
return buffio_print(b, c);
}
@@ -209,29 +263,19 @@ void buffio_flush_input(struct buffio *b) {
assert(b);
b->input_length = b->input_index = 0;
- buffio_set_callbacks(b);
+ buffio_set_input_callbacks(b);
}
-static void buffio_normalize(struct buffio *b) {
- assert(b);
-
- assert(b->input_index < b->input_max_length);
- assert(b->input_length <= b->input_max_length);
-
- if (!b->input_length) /* This will optimize throughput a bit */
- b->input_index = 0;
-}
-
int buffio_find_input(struct buffio *b, const char *c) {
- size_t l, cl, j;
+ size_t l, cl, i;
assert(b && c && *c);
-
+
cl = strlen(c);
for (i = b->input_index, l = b->input_length; l >= cl; i = (i+1) % b->input_max_length, l--) {
- char *p;
- size_t i;
+ const char *p;
+ size_t j;
for (j = i, p = c; *p && *p == b->input_buf[j]; p++, j = (j+1) % b->input_max_length);
@@ -240,6 +284,7 @@ int buffio_find_input(struct buffio *b, const char *c) {
b->input_length = l-cl;
buffio_normalize(b);
+ buffio_set_input_callbacks(b);
return 1;
}
}
@@ -248,3 +293,51 @@ int buffio_find_input(struct buffio *b, const char *c) {
}
+char *buffio_read_line(struct buffio *b, char *c, size_t l) {
+ size_t i;
+ assert(b && c && l);
+
+ /* Look for a \n */
+ for (i = 0; i < b->input_length && i < l-1; i++) {
+ if (b->input_buf[(b->input_index+i) % b->input_max_length] == '\n') {
+ size_t j;
+
+ /* Once again, now copy */
+ for (j = 0;; j++) {
+ c[j] = b->input_buf[(b->input_index+j) % b->input_max_length];
+
+ /* Finished? */
+ if (c[j] == '\n') {
+ c[j+1] = 0;
+
+ b->input_index = (b->input_index+j+1) % b->input_max_length;
+ b->input_length -= j+1;
+ buffio_set_input_callbacks(b);
+ buffio_normalize(b);
+ return c;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void buffio_dump(struct buffio *b) {
+ assert(b);
+ size_t i;
+
+ fprintf(stderr, "%p INPUT_BUFFER: [", b);
+ for (i = 0; i < b->input_length; i++) {
+ char c = b->input_buf[(i + b->input_index) % b->input_max_length];
+ fputc(c < 32 ? '.' : c, stderr);
+ }
+ fprintf(stderr, "]\n");
+
+ fprintf(stderr, "%p OUTPUT_BUFFER: [", b);
+ for (i = 0; i < b->output_length; i++) {
+ char c = b->output_buf[(i + b->output_index) % b->output_max_length];
+ fputc(c < 32 ? '.' : c, stderr);
+ }
+ fprintf(stderr, "]\n");
+}
diff --git a/src/buffio.h b/src/buffio.h
index a340385..e0a2d0a 100644
--- a/src/buffio.h
+++ b/src/buffio.h
@@ -1,14 +1,18 @@
#ifndef foobuffiohfoo
#define foobuffiohfoo
+#include <inttypes.h>
+#include <sys/types.h>
+
struct buffio {
- int fd;
+ int ifd;
+ int ofd;
uint8_t *input_buf;
- size_t input_max_length, input_index, input_length;
+ size_t input_max_length, input_index, input_length, input_watermark;
uint8_t *output_buf;
- size_t output_max_length, output_index, output_length;
+ size_t output_max_length, output_index, output_length, output_watermark;
int b_read_cb, b_write_cb;
@@ -19,7 +23,7 @@ struct buffio {
void (*input_ready_cb) (struct buffio *b, void *user);
};
-struct buffio buffio_new(int fd);
+struct buffio* buffio_new(int ifd, int ofd);
void buffio_free(struct buffio *b);
int buffio_write(struct buffio *b, const uint8_t *d, size_t l);
@@ -28,5 +32,8 @@ int buffio_print(struct buffio *b, const char *s);
int buffio_command(struct buffio *b, const char *c);
void buffio_flush_input(struct buffio *b);
int buffio_find_input(struct buffio *b, const char *c);
+char *buffio_read_line(struct buffio *b, char *c, size_t l);
+
+void buffio_dump(struct buffio *b);
#endif
diff --git a/src/dle.c b/src/dle.c
index 51b3c75..680c82f 100644
--- a/src/dle.c
+++ b/src/dle.c
@@ -1,9 +1,6 @@
-#include "dle.h"
+#include <assert.h>
-/* Those nifty DLE-sequences */
-#define DLE 0x10
-#define ETX 0x03
-#define DC4 0x14
+#include "dle.h"
size_t dle_decode(uint8_t* s, size_t ls, uint8_t* d, size_t *ld, void (*dle_func) (uint8_t c, void *user), void *user, int *dle_flag) {
size_t ns, nd;
diff --git a/src/dle.h b/src/dle.h
index 2e0e453..72bfd55 100644
--- a/src/dle.h
+++ b/src/dle.h
@@ -1,6 +1,14 @@
#ifndef foodlehfoo
#define foodlehfoo
+#include <sys/types.h>
+#include <inttypes.h>
+
+/* Those nifty DLE-sequences */
+#define DLE 0x10
+#define ETX 0x03
+#define DC4 0x14
+
size_t dle_decode(uint8_t* s, size_t ls, uint8_t* d, size_t *ld, void (*dle_func) (uint8_t c, void *user), void *user, int *dle_flag);
size_t dle_encode(uint8_t* s, size_t ls, uint8_t* d, size_t *ld);
diff --git a/src/exec.c b/src/exec.c
index d9d8e49..728c574 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -1,3 +1,13 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <libdaemon/dlog.h>
+
#include "exec.h"
#include "main.h"
@@ -6,13 +16,13 @@
struct process_info {
pid_t pid;
int killed;
- int child_pipe;
- process_exit_cb_t *cb;
+ int stderr_pipe;
+ process_exit_cb_t cb;
void *user;
struct process_info *next;
char *read_buf;
- size_t read_buf_size;
+ size_t read_buf_len;
};
static struct process_info *procs = NULL;
@@ -34,19 +44,20 @@ static void *oop_read_cb(oop_source *source, int fd, oop_event event, void *user
static void close_child_pipe(struct process_info *p) {
assert(p);
-
+
if (p->read_buf_len && p->read_buf) {
*(p->read_buf + p->read_buf_len) = 0;
daemon_log(LOG_INFO, "child(%lu): %s", (unsigned long) p->pid, p->read_buf);
p->read_buf_len = 0;
}
- if (p->child_pipe >= 0) {
+ if (p->stderr_pipe >= 0) {
assert(event_source && event_source->cancel_fd);
- event_source->cancel_fd(event_source, p->child_pipe, OOP_READ, oop_read_cb, p);
- close(p->child_pipe);
- p->child_pipe = -1;
+ event_source->cancel_fd(event_source, p->stderr_pipe, OOP_READ);
+ close(p->stderr_pipe);
+ p->stderr_pipe = -1;
}
+
}
@@ -97,8 +108,8 @@ static void *oop_sigchld_cb(oop_source *source, int sig, void *user) {
return OOP_HALT;
}
- if (!(p = find_process_by_pid(pid))) {
- daemon_log(LOG_WARN, "Got SIGCHLD for unknown process, reaping");
+ if (!(p = find_process(pid))) {
+ daemon_log(LOG_WARNING, "Got SIGCHLD for unknown process, reaping");
return OOP_CONTINUE;
}
@@ -121,7 +132,7 @@ static void *oop_read_cb(oop_source *source, int fd, oop_event event, void *user
assert(source && event == OOP_READ);
p = (struct process_info*) user;
- assert(p && p->child_pipe == fd && fd >= 0);
+ assert(p && p->stderr_pipe == fd && fd >= 0);
if (!p->read_buf) {
p->read_buf = malloc(CHILD_BUF_SIZE);
@@ -131,7 +142,7 @@ static void *oop_read_cb(oop_source *source, int fd, oop_event event, void *user
assert(p->read_buf);
start = p->read_buf+p->read_buf_len;
- if ((s = read(p->child_pipe, start, CHILD_BUF_SIZE-p->read_buf_len-1)) < 0) {
+ if ((s = read(fd, start, CHILD_BUF_SIZE-p->read_buf_len-1)) < 0) {
daemon_log(LOG_ERR, "Failed to read from child pipe: %s", strerror(errno));
return OOP_HALT;
}
@@ -165,20 +176,40 @@ static void *oop_read_cb(oop_source *source, int fd, oop_event event, void *user
return OOP_CONTINUE;
}
+static void pipe_close(int fds[]) {
+ close(fds[0]);
+ close(fds[1]);
+}
-pid_t child_process_create(const char *file, char *const argv[], process_exit_cb_t cb, void*user) {
+pid_t child_process_create(const char *file, char *const argv[], int *ifd, int *ofd, process_exit_cb_t cb, void *user) {
pid_t pid;
- int fds[2];
+ int stdin_fds[2];
+ int stdout_fds[2];
+ int stderr_fds[2];
+
+ if (pipe(stdin_fds) < 0) {
+ daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
+ return -1;
+ }
+
+ if (pipe(stdout_fds) < 0) {
+ daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
+ pipe_close(stdin_fds);
+ return -1;
+ }
- if (pipe(fds) < 0) {
+ if (pipe(stderr_fds) < 0) {
daemon_log(LOG_ERR, "pipe() failed: %s", strerror(errno));
+ pipe_close(stdin_fds);
+ pipe_close(stdout_fds);
return -1;
}
if ((pid = fork()) < 0) {
daemon_log(LOG_ERR, "fork() failed: %s", strerror(errno));
- close(fds[0]);
- close(fds[1]);
+ pipe_close(stdin_fds);
+ pipe_close(stdout_fds);
+ pipe_close(stderr_fds);
return -1;
}
@@ -195,11 +226,23 @@ pid_t child_process_create(const char *file, char *const argv[], process_exit_cb
p->next = procs;
p->killed = 0;
- p->client_pipe = fds[0];
- close(fds[1]);
+ p->stderr_pipe = stderr_fds[0];
+ close(stderr_fds[1]);
+
+ if (ifd)
+ *ifd = stdout_fds[0];
+ else
+ close(stdout_fds[0]);
+ close(stdout_fds[1]);
+
+ if (ofd)
+ *ofd = stdin_fds[1];
+ else
+ close(stdin_fds[1]);
+ close(stdin_fds[0]);
assert(event_source && event_source->on_fd);
- event_source->on_fd(event_source, p->client_pipe, oop_read_cb, p);
+ event_source->on_fd(event_source, p->stderr_pipe, OOP_READ, oop_read_cb, p);
procs = p;
@@ -207,27 +250,42 @@ pid_t child_process_create(const char *file, char *const argv[], process_exit_cb
} else {
/* child */
-
int fd;
- close(fds[0]);
+ close(stderr_fds[0]);
+ close(stdout_fds[0]);
+ close(stdin_fds[1]);
+
for (fd = 0; fd <= 2; fd++) {
- if (fd != fds[1])
+ if (fd != stderr_fds[1] && fd != stdout_fds[1] && fd != stdin_fds[0])
close(fd);
}
- if ((fds[1] != 1 && dup2(fds[1], 1) < 0) ||
- (fds[1] != 2 && dup2(fds[1], 2) < 0)) {
+ if ((stdin_fds[0] != 0 && dup2(stdin_fds[0], 0) < 0) ||
+ (stdout_fds[1] != 1 && dup2(stdout_fds[1], 1) < 0) ||
+ (stderr_fds[1] != 2 && dup2(stderr_fds[1], 2) < 0)) {
daemon_log(LOG_ERR, "dup2() failed: %s", strerror(errno));
exit(1);
}
- if (fds[1] != 1 && fds[1] != 2)
- close(fds[1]);
+ if (stdin_fds[0] > 2) close(stdin_fds[0]);
+ if (stdout_fds[1] > 2) close(stdout_fds[1]);
+ if (stderr_fds[1] > 2) close(stderr_fds[1]);
- if (open("/dev/null", O_RDONLY) != 0) {
- daemon_log(LOG_ERR, "open(\"/dev/null\") failed: %s", strerror(errno));
- exit(1);
+ if (!ifd) {
+ close(1);
+ if (open("/dev/null", O_WRONLY) != 1) {
+ daemon_log(LOG_ERR, "open(\"/dev/null\") failed: %s", strerror(errno));
+ exit(1);
+ }
+ }
+
+ if (!ofd) {
+ close(0);
+ if (open("/dev/null", O_RDONLY) != 0) {
+ daemon_log(LOG_ERR, "open(\"/dev/null\") failed: %s", strerror(errno));
+ exit(1);
+ }
}
execv(file, argv);
diff --git a/src/exec.h b/src/exec.h
index a08b838..32285d6 100644
--- a/src/exec.h
+++ b/src/exec.h
@@ -1,9 +1,11 @@
#ifndef fooexechfoo
#define fooexechfoo
+#include <sys/types.h>
+
typedef void (*process_exit_cb_t) (pid_t pid, int status, void *user);
-pid_t child_process_create(const char *file, char *const argv[], process_exit_cb_t cb, void *user);
+pid_t child_process_create(const char *file, char *const argv[], int *ifd, int *ofd, process_exit_cb_t cb, void *user);
int child_process_kill(pid_t pid);
int child_process_init(void);
void child_process_done(void);
diff --git a/src/lock.c b/src/lock.c
index 48c409f..42ad213 100644
--- a/src/lock.c
+++ b/src/lock.c
@@ -7,17 +7,20 @@
#include <signal.h>
#include <stdlib.h>
#include <string.h>
+#include <inttypes.h>
#include <libdaemon/dlog.h>
#include "lock.h"
+#include "util.h"
+#include "main.h"
/* Where do lockfiles reside? */
#define LOCK_PATH "/var/lock"
static const char *lockfile(const char *dev) {
static char lockfile[PATH_MAX];
- snprintf(lockfile, sizeof(lockfile), "%s/LCK..%s", LOCK_PATH, basename(dev));
+ snprintf(lockfile, sizeof(lockfile), "%s/LCK..%s", LOCK_PATH, basename((char*) dev));
return lockfile;
}
@@ -30,7 +33,7 @@ static const char *tempfile(const char *path) {
int device_lock(const char *dev) {
struct stat st;
int fd;
- char *path, *temp;
+ const char *path, *temp;
char buf[100];
if (stat(LOCK_PATH, &st) != 0 || !S_ISDIR(st.st_mode)) {
@@ -57,7 +60,7 @@ int device_lock(const char *dev) {
close(fd);
if (n < 0) {
- close(fd)
+ close(fd);
daemon_log(LOG_ERR, "Failed to read from lock file: %s", strerror(errno));
return -1;
}
@@ -68,13 +71,15 @@ int device_lock(const char *dev) {
if (n == 4)
pid = (pid_t) *((uint32_t*) buf);
else {
+ unsigned long v;
buf[n] = 0;
- sscanf(buf, "%lu", &pid);
+ sscanf(buf, "%lu", &v);
+ pid = (pid_t) v;
}
if (pid > 0) {
if (kill(pid, 0) < 0 && errno == ESRCH) {
- daemon_log(LOG_WARN, "Lockfile is stale. Overriding it.");
+ daemon_log(LOG_WARNING, "Lockfile is stale. Overriding it.");
/* Yes, here is a race condition */
unlink(path);
} else
@@ -90,7 +95,7 @@ int device_lock(const char *dev) {
snprintf(buf, sizeof(buf), "%10lu %s %.20s\n", (unsigned long) getpid(), appname, username);
if (loop_write(fd, buf, strlen(buf)) < 0) {
- daemon_log(LOG_ERR, "Failed to write to temporary lock file: %s", sterror(errno));
+ daemon_log(LOG_ERR, "Failed to write to temporary lock file: %s", strerror(errno));
close(fd);
return -1;
}
@@ -104,6 +109,7 @@ int device_lock(const char *dev) {
daemon_log(LOG_ERR, "Failed to link temporary lock file: %s", strerror(errno));
}
+ unlink(temp);
return 0;
}
diff --git a/src/main.c b/src/main.c
index 1d0d788..f80b605 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,11 +1,20 @@
+#include <signal.h>
+#include <assert.h>
#include <libdaemon/dlog.h>
#include "main.h"
+#include "exec.h"
+#include "modemman.h"
-#define CHANNELS (2)
+#define CHANNELS 1
oop_source* event_source = NULL;
+static void *oop_exit_cb(oop_source *source, int sig, void *user) {
+ daemon_log(LOG_ERR, "Recieved signal %s", sig == SIGINT ? "SIGINT" : (sig == SIGTERM ? "SIGTERM" : "UNKNWON"));
+ return OOP_HALT;
+}
+
int main_loop(void) {
int r = -1;
oop_source_sys *sys = NULL;
@@ -24,6 +33,9 @@ int main_loop(void) {
if (modem_manager_init(CHANNELS) < 0)
goto finish;
+ event_source->on_signal(event_source, SIGINT, oop_exit_cb, NULL);
+ event_source->on_signal(event_source, SIGTERM, oop_exit_cb, NULL);
+
if (oop_sys_run(sys) == OOP_ERROR) {
daemon_log(LOG_ERR, "oop_sys_new() returned OOP_ERROR");
goto finish;
@@ -32,6 +44,9 @@ int main_loop(void) {
r = 0;
finish:
+ event_source->cancel_signal(event_source, SIGTERM, oop_exit_cb, NULL);
+ event_source->cancel_signal(event_source, SIGINT, oop_exit_cb, NULL);
+
modem_manager_done();
child_process_done();
@@ -44,5 +59,5 @@ finish:
}
int main(int argc, char*argv[]) {
- return main_loop() < 0 : 1 : 0;
+ return main_loop() < 0 ? 1 : 0;
}
diff --git a/src/main.h b/src/main.h
index 3aef24b..aa2f35a 100644
--- a/src/main.h
+++ b/src/main.h
@@ -5,4 +5,6 @@
extern oop_source* event_source;
+const char *appname, *username;
+
#endif
diff --git a/src/modem.c b/src/modem.c
index 1269fbb..4cf9a49 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -1,9 +1,80 @@
+#include <stddef.h>
+#include <termios.h>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <time.h>
+#include <stdio.h>
+
+#include <oop.h>
+
+#include <libdaemon/dlog.h>
+
#include "modem.h"
#include "lock.h"
+#include "exec.h"
+#include "main.h"
+#include "msntab.h"
+#include "dle.h"
/* Baudrate for the TTY. Should be greater the 64000. */
#define BAUD_RATE B115200
+#define RESET_IDLE_TIME 2
+#define INIT_TIMEOUT 5
+#define ACCEPT_TIMEOUT 5
+#define BASIC_TIMEOUT 5
+
+#define INIT_AT_COMMANDS 12
+static const char* const init_at_commands[INIT_AT_COMMANDS*2] = {
+ "\nAT&F\n",
+ "OK\r\n",
+
+ "ATI\n",
+ "Linux ISDN\r\nOK\r\n",
+
+ "AT&B16\n",
+ "OK\r\n",
+
+ "AT+FCLASS=8\n",
+ "OK\r\n",
+
+ "AT+VSM=6\n",
+ "OK\r\n",
+
+ "ATS18=1\n",
+ "OK\r\n",
+
+ "ATS14=4\n",
+ "OK\r\n",
+
+ "ATS13.4=0\n",
+ "OK\r\n",
+
+ "ATS13.0=1\n",
+ "OK\r\n",
+
+ "ATS23=1\n",
+ "OK\r\n",
+
+ "ATS0=0\n",
+ "OK\r\n",
+
+ "AT&L%s\n",
+ "OK\r\n",
+};
+
+static void modem_output_empty_cb(struct buffio *b, void *user);
+static void modem_input_ready_cb(struct buffio *b, void *user);
+static void* oop_timeout_cb(oop_source *source, struct timeval tv, void *user);
+
+static void modem_init_cycle(struct modem *m);
+static void modem_timeout(struct modem *m, int t);
+
struct modem *modem_open(const char *dev) {
struct modem *m;
int fd = -1, n;
@@ -12,7 +83,7 @@ struct modem *modem_open(const char *dev) {
assert(dev);
if (device_lock(dev) != 0)
- return -1;
+ return NULL;
if ((fd = open(dev, O_RDWR|O_NDELAY)) < 0) {
daemon_log(LOG_ERR, "Failed to open device <%s>: %s", dev, strerror(errno));
@@ -43,9 +114,9 @@ struct modem *modem_open(const char *dev) {
goto fail;
}
- if (tcgetattr(fd, &ts2) < 0 || memcmp(&ts, &ts2) != 0) {
+ if (tcgetattr(fd, &ts2) < 0 || memcmp(&ts, &ts2, sizeof(ts)) != 0) {
daemon_log(LOG_ERR, "Failed to set TTY attributes");
- goto fail;
+ /*goto fail;*/ /* DON'T FORGET TO REMOVE THE COMMENT MARKS */
}
m = malloc(sizeof(struct modem));
@@ -53,14 +124,19 @@ struct modem *modem_open(const char *dev) {
memset(m, 0, sizeof(struct modem));
m->dev = strdup(dev);
assert(m->dev);
- m->buffio = buffio_new(fd);
+ m->buffio = buffio_new(fd, fd);
assert(m->buffio);
+
m->buffio->output_empty_cb = modem_output_empty_cb;
- m->buffio->input_ready_cb = modem_output_ready_cb;
+ m->buffio->input_ready_cb = modem_input_ready_cb;
+ m->buffio->user = m;
m->child_pid = -1;
- modem_init(m);
+ m->local_msn = "46";
+ m->tabentry = NULL;
+
+ modem_init_cycle(m);
return m;
@@ -77,124 +153,110 @@ fail:
void modem_close(struct modem *m) {
assert(m);
+ modem_timeout(m, 0);
+
+ if (m->tabentry)
+ msntab_unref(m->tabentry);
+
if (m->child_pid != -1)
child_process_kill(m->child_pid);
buffio_free(m->buffio);
device_unlock(m->dev);
free(m->dev);
+ free(m->caller_number);
+ free(m->ring_number);
free(m);
}
-static void* oop_timeout_cb(oop_source *source,struct timeval tv,void *user) {
- struct modem *m = (struct modem*) user;
- assert(source && user);
-
- daemon_log(LOG_ERR, "Timeout reached for device <%s>", m->device);
- return OOP_HALT;
-}
-
static void modem_timeout(struct modem *m, int t) {
- struct timeval tv = { t, 0 };
assert(m);
assert(event_source && event_source->on_time);
event_source->cancel_time(event_source, m->timeout, oop_timeout_cb, m);
if (t > 0) {
- gettimeofday(&m->timeout);
- m->tv_sec += t;
+ gettimeofday(&m->timeout, NULL);
+ m->timeout.tv_sec += t;
assert(event_source && event_source->on_time);
event_source->on_time(event_source, m->timeout, oop_timeout_cb, m);
}
}
-static void* oop_init_cb(oop_source *source, int fd, oop_event event, void *user) {
- struct modem *m = (struct modem*) user;
- assert(source && user);
- assert(m && m->fd == fd && m->mode == MODEM_STATE_INIT);
-
- if (event == OOP_READ) {
- if (modem_read(m) < 0)
- return OOP_HALT;
-
- } else if (event == OOP_WRITE) {
- modem_write(m);
- }
+static void modem_next_command(struct modem *m) {
+ const char *p;
+ char tmp[64];
+ assert(m && m->buffio && m->state == MODEM_STATE_INIT);
+ assert(m->command_index < INIT_AT_COMMANDS);
- return OOP_CONTINUE;
+ p = init_at_commands[m->command_index*2];
+
+ if (m->command_index == 11) {
+ snprintf(tmp, sizeof(tmp), p, m->local_msn);
+ p = tmp;
+ }
+
+ buffio_command(m->buffio, p);
}
-static void* oop_audio_simple_cb(oop_source *source, int fd, oop_event event, void *user) {
- struct modem *m = (struct modem*) user;
- assert(source && user);
- assert(m && m->mode == MODEM_STATE_AUDIO_SIMPLE);
+static void modem_init_cycle(struct modem *m) {
+ assert(m);
- if (event == OOP_READ) {
- modem_read(m);
- } else if (event == OOP_WRITE) {
- modem_write(m);
- }
+ daemon_log(LOG_INFO, "Initializing modem.");
+ m->state = MODEM_STATE_INIT;
+ m->command_index = 0;
+ modem_timeout(m, INIT_TIMEOUT);
+ modem_next_command(m);
+}
+
+void modem_force_hangup(struct modem *m) {
+ struct termios pts;
+ assert(m && m->buffio);
+
+ tcgetattr(m->buffio->ifd, &pts);
+ cfsetospeed(&pts, B0);
+ cfsetispeed(&pts, B0);
+ tcsetattr(m->buffio->ifd, TCSANOW, &pts);
- return OOP_CONTINUE;
+ tcgetattr(m->buffio->ifd, &pts);
+ cfsetospeed(&pts, BAUD_RATE);
+ cfsetispeed(&pts, BAUD_RATE);
+ tcsetattr(m->buffio->ifd, TCSANOW, &pts);
}
-static void* oop_audio_shbuf_cb(oop_source *source, int fd, oop_event event, void *user) {
+
+static void* oop_timeout_cb(oop_source *source, struct timeval tv, void *user) {
struct modem *m = (struct modem*) user;
assert(source && user);
- assert(m && m->mode == MODEM_STATE_AUDIO_SHBUF);
-
- if (event == OOP_READ) {
- modem_read(m);
- } else if (event == OOP_WRITE) {
- modem_write(m);
- }
- return OOP_CONTINUE;
-}
+ switch (m->state) {
+ case MODEM_STATE_INIT:
-#define INIT_AT_COMMANDS 12
+ case MODEM_STATE_CALLER_NUMBER:
+ case MODEM_STATE_RING_EXPECT:
+ case MODEM_STATE_RING:
+
+ daemon_log(LOG_ERR, "Timeout reached for device <%s>", m->dev);
+ return OOP_HALT;
-static const char* const init_at_commands[INIT_AT_COMMANDS*2] = {
- "\nAT&F\n",
- "OK\r\n",
-
- "ATI\n",
- "Linux ISDN\r\nOK\r\n",
-
- "AT&B16\n",
- "OK\r\n",
-
- "AT+FCLASS=8\n",
- "OK\r\n",
-
- "AT+VSM=6\n",
- "OK\r\n",
-
- "ATS18=1\n",
- "OK\r\n",
-
- "ATS14=4\n",
- "OK\r\n",
-
- "ATS13.4=0\n",
- "OK\r\n",
-
- "ATS13.0=1\n",
- "OK\r\n",
-
- "ATS23=1\n",
- "OK\r\n",
-
- "AT&E%s\n",
- "OK\r\n",
-
- "ATS0=0\n",
- "OK\r\n"
-};
+ case MODEM_STATE_ANSWER:
+ case MODEM_STATE_VTXVRX:
+ daemon_log(LOG_ERR, "Connection failed for device <%s>", m->dev);
+ m->state = MODEM_STATE_IDLE;
+ modem_timeout(m, RESET_IDLE_TIME);
+ return OOP_CONTINUE;
+ case MODEM_STATE_IDLE:
+
+ modem_init_cycle(m);
+ return OOP_CONTINUE;
+
+ default:
+ assert(0);
+ }
+}
static void modem_input_ready_cb(struct buffio *b, void *user) {
struct modem *m = user;
@@ -203,18 +265,19 @@ static void modem_input_ready_cb(struct buffio *b, void *user) {
switch (m->state) {
case MODEM_STATE_INIT: {
- char *p;
+ const char *p;
assert(m->command_index < INIT_AT_COMMANDS);
p = init_at_commands[m->command_index*2+1];
-
+
if (buffio_find_input(m->buffio, p)) {
m->command_index++;
if (m->command_index >= INIT_AT_COMMANDS) {
+ daemon_log(LOG_INFO, "Modem successfully initialised, waiting for calls.");
m->state = MODEM_STATE_CALLER_NUMBER_EXPECT;
modem_timeout(m, 0);
- modem_input_init_cb(b, user);
+ modem_input_ready_cb(b, user);
} else
modem_next_command(m);
}
@@ -226,7 +289,8 @@ static void modem_input_ready_cb(struct buffio *b, void *user) {
if (buffio_find_input(m->buffio, "CALLER NUMBER: ")) {
m->state = MODEM_STATE_CALLER_NUMBER;
- modem_input_init_cb(b, user);
+ modem_timeout(m, BASIC_TIMEOUT);
+ modem_input_ready_cb(b, user);
}
break;
@@ -236,12 +300,14 @@ static void modem_input_ready_cb(struct buffio *b, void *user) {
char c[64];
if (buffio_read_line(m->buffio, c, sizeof(c))) {
+
+ c[strcspn(c, "\n\r")] = 0;
free(m->caller_number);
m->caller_number = strdup(c);
assert(m->caller_number);
m->state = MODEM_STATE_RING_EXPECT;
- modem_input_init_cb(b, user);
+ modem_input_ready_cb(b, user);
}
break;
@@ -251,7 +317,7 @@ static void modem_input_ready_cb(struct buffio *b, void *user) {
if (buffio_find_input(m->buffio, "RING/")) {
m->state = MODEM_STATE_RING;
- modem_input_init_cb(b, user);
+ modem_input_ready_cb(b, user);
}
break;
@@ -260,16 +326,32 @@ static void modem_input_ready_cb(struct buffio *b, void *user) {
char c[64];
if (buffio_read_line(m->buffio, c, sizeof(c))) {
+ struct tabentry *t;
+
+ c[strcspn(c, "\n\r")] = 0;
free(m->ring_number);
m->ring_number = strdup(c);
assert(m->ring_number);
- if (msntab_check_call(m->ring_number, m->caller_number)) {
- modem_send_command(m, "ATA\n");
+ modem_timeout(m, 0);
+ daemon_log(LOG_INFO, "Incoming call from [%s] to [%s]", m->caller_number, m->ring_number);
+
+ if ((t = msntab_check_call(m->ring_number, m->caller_number)) && (t->action == CALL_ACTION_ACCEPT || t->action == CALL_ACTION_HANGUP)) {
+ if (m->tabentry)
+ msntab_unref(m->tabentry);
+ m->tabentry = t;
+ daemon_log(LOG_INFO, "Accepting call.");
+
m->state = MODEM_STATE_ANSWER;
+ modem_timeout(m, ACCEPT_TIMEOUT);
+
+ buffio_command(m->buffio, "ATA\n");
} else {
+ if (t)
+ msntab_unref(t);
+ daemon_log(LOG_INFO, "Ignoring call.");
m->state = MODEM_STATE_CALLER_NUMBER_EXPECT;
- modem_input_init_cb(b, user);
+ modem_input_ready_cb(b, user);
}
}
@@ -279,32 +361,65 @@ static void modem_input_ready_cb(struct buffio *b, void *user) {
case MODEM_STATE_ANSWER:
if (buffio_find_input(m->buffio, "VCON\r\n")) {
+ assert(m->tabentry);
- buffio_command(m->buffio, "AT+VTX+VRX");
- m->state = MODEM_STATE_VTXVRX;
+ if (m->tabentry->action == CALL_ACTION_ACCEPT) {
+ daemon_log(LOG_INFO, "Call accepted, changing to voice mode.");
+ buffio_command(m->buffio, "AT+VTX+VRX");
+ m->state = MODEM_STATE_VTXVRX;
+ } else if (m->tabentry->action == CALL_ACTION_HANGUP) {
+ modem_timeout(m, 0);
+
+ daemon_log(LOG_INFO, "Call accepted for hang up.");
+ m->state = MODEM_STATE_ATH;
+ modem_input_ready_cb(b, user);
+ } else
+ assert(0);
+ } else if (buffio_find_input(m->buffio, "NO CARRIER\n\n")) {
+ daemon_log(LOG_INFO, "Failed to accept call, carrier lost");
+ m->state = MODEM_STATE_IDLE;
+ modem_timeout(m, RESET_IDLE_TIME);
}
+
break;
case MODEM_STATE_VTXVRX:
if (buffio_find_input(m->buffio, "CONNECT\r\n\r\nCONNECT\r\n")) {
+ modem_timeout(m, 0);
+
m->state = MODEM_STATE_CONNECTION;
- modem_input_init_cb(b, user);
+ daemon_log(LOG_INFO, "Voice connection established.");
+ modem_input_ready_cb(b, user);
+ } else if (buffio_find_input(m->buffio, "NO CARRIER\n\n")) {
+ daemon_log(LOG_INFO, "Failed to accept call, carrier lost");
+ m->state = MODEM_STATE_IDLE;
+ modem_timeout(m, RESET_IDLE_TIME);
}
-
+
break;
case MODEM_STATE_CONNECTION:
-
m->state = MODEM_STATE_HANGUP;
+ modem_input_ready_cb(b, user);
break;
case MODEM_STATE_HANGUP: {
+ static const char hup[] = { DLE, DC4, DLE, ETX, 0 };
+ buffio_command(m->buffio, hup);
+
+ /* pass over ... */
+ }
- modem_send_command(m, { DLE, DC4, DLE, ETX, 0 });
+ case MODEM_STATE_ATH: {
+ daemon_log(LOG_INFO, "Hanging up.");
+ buffio_command(m->buffio, "ATH\n");
m->state = MODEM_STATE_FORCE_HANGUP;
break;
}
+
+ default:
+ break;
}
}
@@ -317,60 +432,16 @@ static void modem_output_empty_cb(struct buffio *b, void *user) {
case MODEM_STATE_FORCE_HANGUP:
modem_force_hangup(m);
- modem_init(m);
+ daemon_log(LOG_INFO, "Hang up successful, reinitializing in %i seconds.", RESET_IDLE_TIME);
+ m->state = MODEM_STATE_IDLE;
+ modem_timeout(m, RESET_IDLE_TIME);
break;
- }
-}
-
-void modem_force_hangup(struct modem *m) {
- struct termios pts;
- assert(m && m->buffio);
- tcgetattr(m->buffio->fd, &pts);
- cfsetospeed(&pts, B0);
- cfsetispeed(&pts, B0);
- tcsetattr(m->buffio->fd, TCSANOW, &pts);
-
- tcgetattr(m->buffio->fd, &pts);
- cfsetospeed(&pts, BAUD_RATE);
- cfsetispeed(&pts, BAUD_RATE);
- tcsetattr(m->buffio->fd, TCSANOW, &pts);
-}
-
-
-static void modem_send_command(struct modem *m, const char *p) {
- assert(m && m->buffio);
-
- buffio_input_flush(m->buffio);
- m->buffio->input_cb = modem_input_cb;
- buffio_print(m->buffio, p);
+ default:
+ break;
+ }
}
-static void modem_next_command(struct modem *m) {
- char *p;
- char tmp[64];
- assert(m && m->buffio && (m->state == MODEM_STATE_INIT || m->state == MODEM_STATE_DONE));
- assert(m->command_index < INIT_AT_COMMANDS)
-
- p = init_at_commands[m->command_index*2];
- if (m->command_index == 10) {
- snprintf(tmp, sizeof(tmp), p, m->local_msn);
- p = tmp;
- }
-
- buffio_input_flush(m->buffio);
-
- m->buffio->input_cb = modem_input_cb;
- buffio_command(m->buffio, p);
-}
-static void modem_init(struct modem *m) {
- assert(m);
- m->state = MODEM_STATE_INIT;
- m->command_index = 0;
-
- modem_timeout(m, 10);
- modem_next_command(m);
-}
diff --git a/src/modem.h b/src/modem.h
index 308d656..a19ff38 100644
--- a/src/modem.h
+++ b/src/modem.h
@@ -2,6 +2,7 @@
#define foomodemhfoo
#include "buffio.h"
+#include "msntab.h"
enum modem_state {
MODEM_STATE_INIT,
@@ -13,7 +14,10 @@ enum modem_state {
MODEM_STATE_VTXVRX,
MODEM_STATE_CONNECTION,
MODEM_STATE_CONNECTION_SHBUF,
- MODEM_STATE_DONE
+ MODEM_STATE_HANGUP,
+ MODEM_STATE_ATH,
+ MODEM_STATE_FORCE_HANGUP,
+ MODEM_STATE_IDLE
};
#define MODEM_BUF_LEN (10*1024)
@@ -31,6 +35,12 @@ struct modem {
struct timeval timeout;
int dle_flag;
+ char *local_msn;
+
+ char *ring_number;
+ char *caller_number;
+
+ struct tabentry *tabentry;
};
struct modem *modem_open(const char *dev);
diff --git a/src/modemman.c b/src/modemman.c
index c156e61..f7521e3 100644
--- a/src/modemman.c
+++ b/src/modemman.c
@@ -1,3 +1,11 @@
+#include <stddef.h>
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <libdaemon/dlog.h>
+
#include "modemman.h"
#include "modem.h"
@@ -12,27 +20,32 @@ struct llist {
static struct llist *llist = NULL;
static int n_llist = 0;
+static void modem_try_open(const char *dev) {
+ struct modem *m;
+
+ if ((m = modem_open(dev))) {
+ struct llist *l = malloc(sizeof(struct llist));
+ assert(l);
+
+ l->modem = m;
+ l->next = llist;
+ llist = l;
+ n_llist++;
+ }
+}
+
int modem_manager_init(int channels) {
int i;
assert(channels <= MAX_CHANNELS && channels > 0);
assert(n_llist == 0);
+
+ modem_try_open("/dev/ttyz0");
- for (i = TTY_START; i < TTY_START+MAX_CHANNLES && n_llist < channels; i++) {
+ for (i = TTY_START; i < TTY_START+MAX_CHANNELS && n_llist < channels; i++) {
char d[PATH_MAX];
- struct modem *m;
-
snprintf(d, sizeof(d), "/dev/ttyI%i", i);
-
- if (m = modem_open(d)) {
- struct llist *l = malloc(sizeof(struct llist));
- assert(l);
-
- l->modem = m;
- l->next = llist;
- llist = l;
- n_llist++;
- }
+ modem_try_open(d);
}
if (n_llist < channels) {
@@ -49,11 +62,11 @@ void modem_manager_done(void) {
while (llist) {
struct llist *l;
- modem_close(l->modem);
+ modem_close(llist->modem);
l = llist;
- llist = l->next;
+ llist = llist->next;
free(l);
- n_llist = 0;
+ n_llist--;
}
assert(!n_llist && !llist);
diff --git a/src/util.c b/src/util.c
index 415da09..d236253 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,9 +1,12 @@
+#include <string.h>
+#include <unistd.h>
+
#include "util.h"
-char *basename(const char *path) {
- const char *p;
+char *basename(char *path) {
+ char *p;
- if (p = strrchr(path, '/'))
+ if ((p = strrchr(path, '/')))
return p+1;
return path;
diff --git a/src/util.h b/src/util.h
index 2e0b2ae..262d26c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,7 +1,9 @@
#ifndef fooutilhfoo
#define fooutilhfoo
-char *basename(const char *path);
+#include <sys/types.h>
+
+char *basename(char *path);
ssize_t loop_read(int FILEDES, void *BUFFER, size_t SIZE);
ssize_t loop_write(int FILEDES, const void *BUFFER, size_t SIZE);