summaryrefslogtreecommitdiffstats
path: root/src/pgets.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-03-03 01:25:46 +0000
committerLennart Poettering <lennart@poettering.net>2004-03-03 01:25:46 +0000
commit285f7ad7d0aed48cd5cb13a2437e80d26fffc254 (patch)
tree09dddce764a851f970cdaffd40abee0f6bd84dc0 /src/pgets.c
parent6f8db736a197520f88aab498eead8599641b10fe (diff)
commit initial release
git-svn-id: file:///home/lennart/svn/public/pgets/trunk@3 768266df-afd4-0310-94a7-d396c829e022
Diffstat (limited to 'src/pgets.c')
-rw-r--r--src/pgets.c294
1 files changed, 294 insertions, 0 deletions
diff --git a/src/pgets.c b/src/pgets.c
new file mode 100644
index 0000000..993111e
--- /dev/null
+++ b/src/pgets.c
@@ -0,0 +1,294 @@
+/* $Id$
+ *
+ * This file is part of pgets.
+ *
+ * pgets is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * pgets is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with pgets; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#define _GNU_SOURCE
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <signal.h>
+
+#include "lock.h"
+#include "modem.h"
+#include "util.h"
+#include "db.h"
+
+#define ETS_RESET ('$')
+#define ETS_NEXT ('%')
+
+int verbose = 1;
+volatile int quit = 0;
+
+void sigint(int s) {
+ const char *e = "\r*** Got SIGINT, exiting *** \n";
+ loop_write(2, e, strlen(e));
+ quit = 1;
+}
+
+int ets_reset(int fd) {
+ char c = ETS_RESET;
+ return (write(fd, &c, sizeof(c)) != sizeof(c)) ? -1 : 0;
+}
+
+int ets_next(int fd) {
+ char c = ETS_NEXT;
+ return (write(fd, &c, sizeof(c)) != sizeof(c)) ? -1 : 0;
+}
+
+int atoi_l(char *s, int l) {
+ char *p = strndup(s, l);
+ int r = atoi(p);
+ free(p);
+ return r;
+}
+
+int ets_parse(struct entry *entry, char *ln) {
+ int i, t;
+ memset(entry, 0, sizeof(struct entry));
+
+ if (ln[0] != '*')
+ for (i = 0; i <= 20; i++) {
+ if (ln[i] >= '0' && ln[i] <= '9')
+ entry->remote_msn[i] = ln[i];
+ else
+ break;
+ }
+
+ if (ln[25] >= '0' && ln[25] <= '9' && ln[26] >= '0' && ln[26] <= '9') {
+ entry->local_mm = atoi_l(ln+25, 2);
+
+ if (entry->local_mm <= 0) {
+ fprintf(stderr, "Corrupt local MM column.\n");
+ return -1;
+ }
+ }
+
+ if (ln[32] >= '0' && ln[32] <= '9' && ln[33] >= '0' && ln[33] <= '9') {
+ entry->participant = atoi_l(ln+32, 2);
+
+ if (!((entry->participant >= 31 && entry->participant <= 38) ||
+ (entry->participant >= 41 && entry->participant <= 48))) {
+ fprintf(stderr, "Corrupt participant column.\n");
+ return -1;
+ }
+ }
+
+ entry->incoming = ln[35] == 'K' ? 1 : 0;
+
+ if (!(ln[39] >= '0' && ln[39] <= '9' && ln[40] >= '0' && ln[40] <= '9')) {
+ fprintf(stderr, "Corrupt day column.\n");
+ return -1;
+ }
+
+ if (!(ln[42] >= '0' && ln[42] <= '9' && ln[43] >= '0' && ln[43] <= '9')) {
+ fprintf(stderr, "Corrupt month column.\n");
+ return -1;
+ }
+
+ if (!(ln[45] >= '0' && ln[45] <= '9' && ln[46] >= '0' && ln[46] <= '9')) {
+ fprintf(stderr, "Corrupt hour column.\n");
+ return -1;
+ }
+
+ if (!(ln[48] >= '0' && ln[48] <= '9' && ln[49] >= '0' && ln[49] <= '9')) {
+ fprintf(stderr, "Corrupt minute column.\n");
+ return -1;
+ }
+
+ entry->day = atoi_l(ln+39, 2);
+ entry->month = atoi_l(ln+42, 2);
+ entry->hour = atoi_l(ln+45, 2);
+ entry->minute = atoi_l(ln+48, 2);
+
+ if (entry->day < 1 || entry->day > 31 || entry->month < 1 || entry->month > 12 || entry->hour < 0 || entry->hour > 24 || entry->minute < 0 || entry->minute >= 60) {
+ fprintf(stderr, "Corrupt timespec column.\n");
+ return -1;
+ }
+
+ if (!((ln[51] == ' ' || (ln[51] >= '0' && ln[51] <= '9')) && (ln[52] == ' ' || (ln[52] >= '0' && ln[52] <= '9')) && ln[53] >= '0' && ln[53] <= '9')) {
+ fprintf(stderr, "Corrupt minute (duration) column.\n");
+ return -1;
+ }
+
+ if (!(ln[55] >= '0' && ln[55] <= '9' && ln[56] >= '0' && ln[56] <= '9')) {
+ fprintf(stderr, "Corrupt second (duration) column.\n");
+ return -1;
+ }
+
+ t = atoi_l(ln+55, 2);
+
+ if (t < 0 || t >= 60) {
+ fprintf(stderr, "Corrupt second (duration) column. (#2)\n");
+ return -1;
+ }
+
+ entry->duration = atoi_l(ln+51,3)*60 + t;
+
+ if (entry->duration < 0) {
+ fprintf(stderr, "Corrupt duration column.\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+int ets_read_entry(int fd, struct entry *entry) {
+ char ln[80];
+ int r;
+
+ if ((r = read_line(fd, ln, sizeof(ln))) != 74) {
+ if (r == 1 && ln[0] == '\n')
+ return -2;
+
+ fprintf(stderr, "Error while reading line (%i|%i).\n", r, (int) ln[0]);
+ return -1;
+ }
+
+ if (ln[73] != '\n') {
+ fprintf(stderr, "Corrupt line.\n");
+ return -1;
+ }
+
+ ln[73] = 0;
+
+ if (ln[37] == 'V')
+ return 0;
+
+ if (ets_parse(entry, ln) == 0)
+ return 1;
+
+ fprintf(stderr, "Failure in line [%s]\n", ln);
+ return -1;
+}
+
+
+void work(int fd, void *db) {
+ int n = 0, v = 0, a = 0;
+ if (ets_reset(fd) != 0) {
+ fprintf(stderr, "Could not reset PBX.\n");
+ return;
+ }
+
+ // Accelerate a bit
+ if (ets_next(fd) != 0)
+ return;
+
+ while (!quit) {
+ struct entry entry;
+ int r;
+
+ if ((r = ets_read_entry(fd, &entry)) < 0)
+ break;
+
+ if (r > 0) {
+ v++;
+
+ if ((r = db_write_entry(db, &entry)) < 0)
+ break;
+ else if (r == 0)
+ a++;
+ }
+
+ if (verbose) {
+ fprintf(stderr, "%3.1f%% done; %i of %i valid entries added.\r", (float)(++n)/10, a, v);
+ fflush(stdout);
+ }
+
+ if (ets_next(fd) != 0)
+ break;
+ }
+
+ if (verbose)
+ fprintf(stderr, "Finished; %i entries in PBX; %i of %i valid entries added.\n", n, a, v);
+}
+
+void help(const char *p) {
+ fprintf(stderr,
+ "%s [-h] [-q] [-d DEVICE] [-b DATABASE]\n"
+ " -h Shows this help\n"
+ " -q Disables verbose mode\n"
+ " -d DEVICE specifies the serial device to use\n"
+ " -b DATABASE specifies the database to use\n",
+ p);
+ exit(1);
+}
+
+int main(int argc, char *argv[]) {
+ int fd = -1, r = 1, locked = 0;
+ const char *dev = "/dev/ttyS1";
+ void *db = NULL;
+ char* dbspec = NULL;
+ int c;
+
+ while ((c = getopt (argc, argv, "hqd:b:")) != -1)
+ switch (c) {
+ case 'q':
+ verbose = 0;
+ break;
+
+ case 'b':
+ dbspec = optarg;
+ break;
+
+ case 'd':
+ dev = optarg;
+ break;
+
+ default:
+ help(basename(argv[0]));
+ break;
+ }
+
+ if (device_lock(dev, basename(argv[0])) != 0)
+ goto finish;
+
+ locked = 1;
+
+ if ((fd = modem_open(dev)) < 0)
+ goto finish;
+
+ //"dbname=pgets user=pgets_fill password=mahatma"
+ if (!(db = db_connect(dbspec)))
+ goto finish;
+
+ while (*dbspec)
+ *(dbspec++) = 'X';
+
+ signal(SIGINT, sigint);
+ siginterrupt(SIGINT, 0);
+
+ flush_data(fd);
+ work(fd, db);
+
+ r = 0;
+
+finish:
+ if (fd >= 0)
+ modem_close(fd);
+
+ if (db)
+ db_disconnect(db);
+
+ if (locked)
+ device_unlock(dev);
+
+ return r;
+}