From 285f7ad7d0aed48cd5cb13a2437e80d26fffc254 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 3 Mar 2004 01:25:46 +0000 Subject: commit initial release git-svn-id: file:///home/lennart/svn/public/pgets/trunk@3 768266df-afd4-0310-94a7-d396c829e022 --- src/pgets.c | 294 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) create mode 100644 src/pgets.c (limited to 'src/pgets.c') 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 +#include +#include +#include +#include +#include + +#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; +} -- cgit