summaryrefslogtreecommitdiffstats
path: root/src/ivcall.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ivcall.c')
-rw-r--r--src/ivcall.c597
1 files changed, 427 insertions, 170 deletions
diff --git a/src/ivcall.c b/src/ivcall.c
index 28cf890..549d56f 100644
--- a/src/ivcall.c
+++ b/src/ivcall.c
@@ -22,6 +22,7 @@
#include "config.h"
#endif
+#include <assert.h>
#include <termios.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -38,85 +39,108 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/select.h>
+#include <inttypes.h>
+
+#ifdef HAVE_SPANDSP
+#include <tiffio.h>
+#include <spandsp.h>
+#endif
#include "util.h"
#include "lock.h"
+#include "g711.h"
-// Those nifty DLE-sequences
+/* Those nifty DLE-sequences*/
#define DLE 0x10
#define ETX 0x03
#define DC4 0x14
-// Baudrate for the TTY. Should be greater the 64000.
+/* Baudrate for the TTY. Should be greater the 64000.*/
#define BAUD_RATE B115200
-// Every single commands gets a timeout of 2 seconds.
+/* Every single commands gets a timeout of 2 seconds.*/
#define COMMAND_TIMEOUT 2
-// The default timeout for waiting that the call gets accepted.
+/* The default timeout for waiting that the call gets accepted.*/
#define DEFAULT_TIMEOUT 30
-// Initialisation of the modem
+#define BUFSIZE 10240
+
+/* Initialisation of the modem*/
const char *at_commands[] = {
"AT&F\n", "OK\r\n",
"ATI\n", "Linux ISDN\r\nOK",
"AT&B128\n", "OK\r\n",
"AT+FCLASS=8\n", "OK\r\n",
+ "AT+VIP\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=1\n", "OK\r\n",
+ "ATS13.4=0\n", "OK\r\n",
+ "ATS13.0=1\n", "OK\r\n",
+ "ATS16=1\n", "OK\r\n",
"ATS23=1\n", "OK\r\n",
0
};
-// Local MSN
+#ifdef HAVE_SPANDSP
+/* Tiff file to send */
+char *fax_tiff_file = NULL;
+
+/* Do fax */
+int fax_enabled = 0;
+
+/* Local identifier for fax */
+char *fax_ident = NULL;
+#endif
+
+/* Local MSN*/
char *source_msn = NULL;
-// Remote MSN
+/* Remote MSN*/
char *destination_msn = NULL;
-// Modem-device
+/* Modem-device*/
char *device = NULL;
-// Our name
+/* Our name*/
char *appname = NULL;
-// The default timeout
+/* The default timeout*/
int timeout = DEFAULT_TIMEOUT;
-// Enable debug-mode or not?
+/* Enable debug-mode or not?*/
int debug = 0;
-// We got a ctrl-c
+/* We got a ctrl-c*/
volatile int interrupted = 0;
-// Got an SIGARLM?
+/* Got an SIGARLM?*/
volatile int alarmed = 0;
-// Shall we wait for a call?
+/* Shall we wait for a call?*/
int answer = 0;
-// After how many RINGs we shall answer?
+/* After how many RINGs we shall answer?*/
int rings = 1;
-// Saved TTY configuration
+/* Saved TTY configuration*/
struct termios saved_termios;
-// Our ctrl-c handler
+/* Our ctrl-c handler */
void sigint(int sig) {
- const char *s = "Got SIGINT\n";
- write(2, s, strlen(s));
+ const char s[] = "Got SIGINT\n";
+ loop_write(2, s, strlen(s));
interrupted = 1;
}
void sigalrm(int sig) {
- const char *s = "Timeout\n";
- write(2, s, strlen(s));
+ const char s[] = "Timeout\n";
+ loop_write(2, s, strlen(s));
alarmed = 1;
}
-// Waits for a certain string from the modem up to a certain time.
+/* Waits for a certain string from the modem up to a certain time.*/
int tty_waitfor(int fd, const char *what, int t) {
static char buf[256];
char *p = buf;
@@ -160,7 +184,7 @@ int tty_waitfor(int fd, const char *what, int t) {
return r;
}
-// Write a string to the modem
+/* Write a string to the modem*/
int tty_puts(int fd, const char *s) {
int l = strlen(s);
@@ -176,14 +200,14 @@ int tty_puts(int fd, const char *s) {
return 0;
}
-// Issue a command to the modem an wait for an answer
+/* Issue a command to the modem an wait for an answer */
int tty_command(int fd, const char *cmd, const char* resp, int t) {
tcflush(fd, TCIFLUSH);
tty_puts(fd, cmd);
return tty_waitfor(fd, resp, t);
}
-// Hang up the modem
+/* Hang up the modem */
int hard_hangup(int fd) {
struct termios pts;
@@ -211,7 +235,7 @@ int hard_hangup(int fd) {
return 0;
}
-// Opens the modem and sets the baud rate
+/* Opens the modem and sets the baud rate*/
int tty_open(const char *device) {
struct termios pts, pts2;
int fd = -1, n;
@@ -256,14 +280,14 @@ fail:
return -1;
}
-// Closes the modem device and resets the baudrate
+/* Closes the modem device and resets the baudrate*/
void tty_close(int fd) {
tcflush(fd, TCIOFLUSH);
tcsetattr(fd, TCSANOW, &saved_termios);
close(fd);
}
-// Detects the DCD line
+/* Detects the DCD line*/
int detect_carrier(int fd) {
unsigned int arg;
@@ -273,15 +297,21 @@ int detect_carrier(int fd) {
return arg & TIOCM_CAR ? 1 : 0;
}
-// Filters out DLE-sequences from modem
-char *filter_dle(unsigned char *data, int *size, int *flag, int *quit) {
- unsigned char *ret, *m, *s, *d;
- int l;
+/* Filters out DLE-sequences from modem */
+uint8_t *filter_dle(uint8_t *data, size_t size, size_t *ret_size, int *flag, int *quit) {
+ uint8_t *ret, *s, *d;
+ size_t l;
+
+ assert(data);
+ assert(size > 0);
+ assert(ret_size);
+ assert(flag);
+ assert(quit);
- if (!(ret = malloc(*size)))
+ if (!(ret = malloc(size)))
return NULL;
- for (l = *size, s = data, d = ret; l > 0; l--, s++) {
+ for (l = size, s = data, d = ret; l > 0; l--, s++) {
if (*flag) {
switch (*s) {
case DLE :
@@ -294,54 +324,47 @@ char *filter_dle(unsigned char *data, int *size, int *flag, int *quit) {
break;
default :
- // We recieved some DTMF signals, but we ignore them.
+ /* We received some DTMF signals, but we ignore them. */
break;
}
*flag = 0;
- continue;
- }
-
- if (*s == DLE)
+ } else if (*s == DLE)
*flag = 1;
else
*(d++) = *s;
-
}
- *size = d-ret;
+ *ret_size = d-ret;
- if (!(m = realloc(ret, *size))) {
- free(ret);
- return NULL;
- }
-
- return m;
+ return ret;
}
-// Escape DLE-bytes for sending data to the modem
-char* escape_dle(unsigned char *data, int *size) {
- unsigned char *ret, *m, *s, *d;
- int l, ms;
+/* Escape DLE-bytes for sending data to the modem */
+uint8_t* escape_dle(uint8_t *data, size_t size, size_t *ret_size) {
+ uint8_t *ret, *s, *d;
+ size_t l, ms;
- if (!(ret = malloc(ms = (int) (*size*1.05))))
+ if (!(ret = malloc(ms = (size_t) (size*1.05))))
return NULL;
+
+ *ret_size = size;
- for (l = *size, s = data, d = ret; l > 0; l--, s++) {
+ for (l = size, s = data, d = ret; l > 0; l--, s++) {
if (*s == DLE) {
*(d++) = DLE;
- (*size)++;
+ (*ret_size)++;
- if (ms < *size) {
+ if (ms < *ret_size) {
int n = d-ret;
+ uint8_t *m;
- fprintf(stderr, "REALLOC!\n");
-
- if (!(m = realloc(ret, ms = (int) (*size*1.05)))) {
+ if (!(m = realloc(ret, ms = (size_t) (*ret_size*1.05)))) {
free(ret);
return NULL;
}
+
ret = m;
d = ret+n;
}
@@ -350,79 +373,17 @@ char* escape_dle(unsigned char *data, int *size) {
*(d++) = *s;
}
- if (!(m = realloc(ret, *size))) {
- free(ret);
- return NULL;
- }
-
- return m;
+ return ret;
}
-
-// The function that does the modem work
-int go(void) {
- int i, flag, warned = 0, r = -1, fd = -1, quit;
- char *incoming = NULL, *outgoing = NULL;
- int incoming_idx = 0, incoming_len = 0,
+static int cat_loop(int fd) {
+ uint8_t *incoming = NULL, *outgoing = NULL;
+ ssize_t incoming_idx = 0, incoming_len = 0,
outgoing_idx = 0, outgoing_len = 0;
- int fm;
- char fn[PATH_MAX];
- static char buf[1024];
+ int warned = 0;
+ int fm, r = -1, flag = 0, quit = 0;
+ uint8_t buf[BUFSIZE];
- if ((device ? device_lock(device, appname) : device_lock_first(appname, fn, sizeof(fn))) < 0) {
- fprintf(stderr, "Could not get lock on device: %s\n", strerror(errno));
- goto fail;
- }
-
- if (!device)
- if (!(device = strdup(fn))) {
- fprintf(stderr, "Out of memory!\n");
- goto fail;
- }
-
- if ((fd = tty_open(device)) < 0) {
- fprintf(stderr, "Could not open device: %s\n", strerror(errno));
- goto fail;
- }
-
- for (i = 0; at_commands[i] != 0; i+=2)
- if (tty_command(fd, at_commands[i], at_commands[i+1], COMMAND_TIMEOUT) < 0) {
- fprintf(stderr, "Initialisation failure.\n");
- goto fail;
- }
-
- if (answer) {
- snprintf(buf, sizeof(buf), "AT&L%s\n", source_msn);
- if (tty_command(fd, buf, "OK\r\n", COMMAND_TIMEOUT) < 0) {
- fprintf(stderr, "Initialisation failure.\n");
- goto fail;
- }
- } else {
- snprintf(buf, sizeof(buf), "AT&E%s\n", source_msn);
- if (tty_command(fd, buf, "OK\r\n", COMMAND_TIMEOUT) < 0) {
- fprintf(stderr, "Initialisation failure.\n");
- goto fail;
- }
- }
-
- if (answer)
- snprintf(buf, sizeof(buf), "ATS0=%i\n", rings);
- else
- snprintf(buf, sizeof(buf), "ATD%s\n", destination_msn);
-
- if (tty_command(fd, buf, "VCON\r\n", timeout) < 0) {
- fprintf(stderr, "Failed to accept connection.\n");
- r = -2;
- goto fail;
- }
-
- if (tty_command(fd, "AT+VTX+VRX\n", "CONNECT\r\n\r\nCONNECT\r\n", COMMAND_TIMEOUT) < 0) {
- fprintf(stderr, "Could not switch to full-duplex audio: %s\n", strerror(errno));
- goto fail;
- }
-
- flag = quit= 0;
-
if (fd > 1)
fm = fd+1;
else
@@ -435,12 +396,10 @@ int go(void) {
if ((c = detect_carrier(fd)) < 0) {
if (errno != EIO)
fprintf(stderr, "Failure reading DCD line: %s\n", strerror(errno));
- goto fail;
+ goto finish;
} else if (!c) {
- if (outgoing) {
- free(outgoing);
- outgoing = NULL;
- }
+ free(outgoing);
+ outgoing = NULL;
quit = 1;
break;
}
@@ -476,20 +435,20 @@ int go(void) {
continue;
fprintf(stderr, "select(): %s\n", strerror(errno));
- goto fail;
+ goto finish;
}
if (!outgoing && FD_ISSET(0, &rfds)) {
if ((outgoing_len = read(0, buf, sizeof(buf))) < 0) {
fprintf(stderr, "read(): %s\n", strerror(errno));
- goto fail;
+ goto finish;
}
if (!outgoing_len)
quit = 1;
else {
- outgoing = escape_dle(buf, &outgoing_len);
+ outgoing = escape_dle(buf, outgoing_len, (size_t*) &outgoing_len);
outgoing_idx = 0;
}
}
@@ -498,7 +457,7 @@ int go(void) {
ssize_t l;
if ((l = write(fd, outgoing+outgoing_idx, outgoing_len-outgoing_idx)) < 0) {
fprintf(stderr, "write(): %s\n", strerror(errno));
- goto fail;
+ goto finish;
}
if (!l)
@@ -518,13 +477,13 @@ int go(void) {
if (!incoming && FD_ISSET(fd, &rfds)) {
if ((incoming_len = read(fd, buf, sizeof(buf))) < 0) {
fprintf(stderr, "read(): %s\n", strerror(errno));
- goto fail;
+ goto finish;
}
if (!incoming_len)
quit = 1;
else {
- incoming = filter_dle(buf, &incoming_len, &flag, &quit);
+ incoming = filter_dle(buf, incoming_len, (size_t*) &incoming_len, &flag, &quit);
incoming_idx = 0;
}
}
@@ -544,7 +503,7 @@ int go(void) {
} else {
if ((l = write(1, incoming+incoming_idx, incoming_len-incoming_idx)) < 0) {
fprintf(stderr, "write(1): %s\n", strerror(errno));
- goto fail;
+ goto finish;
}
if (!l)
@@ -561,12 +520,286 @@ int go(void) {
}
}
}
+
+ r = 0;
+
+finish:
+
+ free(incoming);
+ free(outgoing);
+
+ return r;
+}
+
+#ifdef HAVE_SPANDSP
+
+#define NSAMPLES 240
+
+static void phase_e_handler(t30_state_t *s, void *user_data, int result) {
+ t30_stats_t t;
+ char local_ident[21];
+ char far_ident[21];
+
+ if (!result) {
+ fprintf(stderr, "Phase E not successful.\n");
+ return;
+ }
+
+ fax_get_transfer_statistics(s, &t);
+ fax_get_far_ident(s, far_ident);
+ fax_get_local_ident(s, local_ident);
+
+ fprintf(stderr,
+ "* Remote station ID: %s\n"
+ "* Local station ID: %s\n"
+ "* Pages transferred: %i\n"
+ "* Image resolution: %ix%i\n"
+ "* Transfer rate: %i\n",
+ far_ident,
+ local_ident,
+ t.pages_transferred,
+ t.column_resolution, t.row_resolution,
+ t.bit_rate);
+}
+
+static void phase_d_handler(t30_state_t *s, void *user_data, int result) {
+ t30_stats_t t;
+
+ if (!result) {
+ fprintf(stderr, "Phase D not sucessful.\n");
+ return;
+ }
+
+ fax_get_transfer_statistics(s, &t);
+ fprintf(stderr,
+ "* Pages transferred: %i\n"
+ "* Image size: %ix%i\n"
+ "* Image resolution: %ix%i\n"
+ "* Transfer rate: %i\n"
+ "* Bad rows: %i\n"
+ "* Longest bad row run: %i\n"
+ "* Compression type: %i\n"
+ "* Image size: %i\n",
+ t.pages_transferred,
+ t.columns, t.rows,
+ t.column_resolution, t.row_resolution,
+ t.bit_rate,
+ t.bad_rows,
+ t.longest_bad_row_run,
+ t.encoding,
+ t.image_size);
+}
+
+static int fax_loop(int fd) {
+ t30_state_t fax;
+ uint8_t *incoming_ulaw = NULL, *outgoing_raw = NULL;
+ size_t outgoing_raw_index = 0, outgoing_raw_length = 0;
+ int r = -1;
+ int flag = 0, quit = 0;
+
+ assert(fd >= 0);
+
+ fax_init(&fax, !answer, NULL);
+ if (fax_ident)
+ fax_set_local_ident(&fax, fax_ident);
+
+ if (answer)
+ fax_set_rx_file(&fax, fax_tiff_file);
+ else
+ fax_set_tx_file(&fax, fax_tiff_file);
+
+ fax_set_phase_e_handler(&fax, phase_e_handler, NULL);
+ fax_set_phase_d_handler(&fax, phase_d_handler, NULL);
+
+ while (!quit && !interrupted) {
+ int q;
+ struct timeval tv;
+ fd_set rfds;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 10000;
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+
+ if (select(fd+1, &rfds, NULL, NULL, &tv) < 0) {
+ fprintf(stderr, "select(): %s\n", strerror(errno));
+ goto finish;
+ }
+
+/* putchar('.'); */
+/* fflush(stdout); */
+
+ if (FD_ISSET(fd, &rfds)) {
+ uint8_t incoming_raw[NSAMPLES];
+ int16_t samples[NSAMPLES];
+ size_t nsamples, i;
+ ssize_t rx;
+ if ((rx = read(fd, incoming_raw, NSAMPLES)) <= 0) {
+ fprintf(stderr, "read(): %s\n", rx < 0 ? strerror(errno) : "EOF");
+ goto finish;
+ }
+
+ if (!(incoming_ulaw = filter_dle(incoming_raw, (size_t) rx, &nsamples, &flag, &quit)))
+ goto finish;
+
+ assert(nsamples <= NSAMPLES);
+
+ for (i = 0; i < nsamples; i++)
+ samples[i] = st_ulaw2linear16(incoming_ulaw[i]);
+
+ free(incoming_ulaw);
+ incoming_ulaw = NULL;
+
+ if (fax_rx_process(&fax, samples, nsamples) != 0) {
+ fprintf(stderr, "Got FAX EOF\n");
+ break;
+ }
+
+/* putchar('x'); */
+/* fflush(stdout); */
+
+
+/* fprintf(stderr, "Processing %i RX samples\n", nsamples); */
+ }
+
+ if (ioctl(fd, TIOCOUTQ, &q) < 0) {
+ fprintf(stderr, "TIOCOUTQ failed: %s\n", strerror(errno));
+ goto finish;
+ }
+
+ if (q < NSAMPLES) {
+
+ if (!outgoing_raw) {
+ int16_t samples[NSAMPLES];
+ size_t nsamples;
+
+ if ((nsamples = fax_tx_process(&fax, samples, NSAMPLES)) > 0) {
+ uint8_t outgoing_ulaw[NSAMPLES];
+ size_t i;
+
+/* putchar('o'); */
+/* fflush(stdout); */
+
+/* fprintf(stderr, "Produced %i TX samples\n", nsamples); */
+
+ for (i = 0; i < nsamples; i++)
+ outgoing_ulaw[i] = st_14linear2ulaw(samples[i] >> 2);
+
+ if (!(outgoing_raw = escape_dle(outgoing_ulaw, nsamples, &outgoing_raw_length)))
+ goto finish;
+
+ outgoing_raw_index = 0;
+ }
+ }
+
+ if (outgoing_raw) {
+ ssize_t tx;
+ size_t t = outgoing_raw_length - outgoing_raw_index;
+
+ assert(outgoing_raw_index < outgoing_raw_length);
+ assert(t > 0);
+
+ if ((tx = write(fd, outgoing_raw + outgoing_raw_index, t)) < 0) {
+ fprintf(stderr, "write(): %s\n", strerror(errno));
+ goto finish;
+ }
+
+ outgoing_raw_index += tx;
+
+ if (outgoing_raw_index >= outgoing_raw_length) {
+ free(outgoing_raw);
+ outgoing_raw = NULL;
+
+ outgoing_raw_index = outgoing_raw_length = 0;
+ }
+ }
+ }
+
+
+ }
+
+ r = 0;
+
+finish:
+
+ free(incoming_ulaw);
+ free(outgoing_raw);
+
+ return r;
+}
+
+#endif
+
+/* The function that does the modem work*/
+int go(void) {
+ int i, r = -1, fd = -1;
+ char fn[PATH_MAX];
+ char buf[64];
+
+ if ((device ? device_lock(device, appname) : device_lock_first(appname, fn, sizeof(fn))) < 0) {
+ fprintf(stderr, "Could not get lock on device: %s\n", strerror(errno));
+ goto fail;
+ }
+
+ if (!device)
+ if (!(device = strdup(fn))) {
+ fprintf(stderr, "Out of memory!\n");
+ goto fail;
+ }
+
+ if ((fd = tty_open(device)) < 0) {
+ fprintf(stderr, "Could not open device: %s\n", strerror(errno));
+ goto fail;
+ }
+
+ for (i = 0; at_commands[i] != 0; i+=2)
+ if (tty_command(fd, at_commands[i], at_commands[i+1], COMMAND_TIMEOUT) < 0) {
+ fprintf(stderr, "Initialisation failure.\n");
+ goto fail;
+ }
+
+ if (answer) {
+ snprintf(buf, sizeof(buf), "AT&L%s\n", source_msn);
+ if (tty_command(fd, buf, "OK\r\n", COMMAND_TIMEOUT) < 0) {
+ fprintf(stderr, "Initialisation failure.\n");
+ goto fail;
+ }
+ } else {
+ snprintf(buf, sizeof(buf), "AT&E%s\n", source_msn);
+ if (tty_command(fd, buf, "OK\r\n", COMMAND_TIMEOUT) < 0) {
+ fprintf(stderr, "Initialisation failure.\n");
+ goto fail;
+ }
+ }
+
+ if (answer)
+ snprintf(buf, sizeof(buf), "ATS0=%i\n", rings);
+ else
+ snprintf(buf, sizeof(buf), "ATD%s\n", destination_msn);
+
+ if (tty_command(fd, buf, "VCON\r\n", timeout) < 0) {
+ fprintf(stderr, "Failed to accept connection.\n");
+ r = -2;
+ goto fail;
+ }
+
+ if (tty_command(fd, "AT+VTX+VRX\n", "CONNECT\r\n\r\nCONNECT\r\n", COMMAND_TIMEOUT) < 0) {
+ fprintf(stderr, "Could not switch to full-duplex audio: %s\n", strerror(errno));
+ goto fail;
+ }
+
+
+#ifdef HAVE_SPANDSP
+ if ((fax_enabled ? fax_loop(fd) : cat_loop(fd)) < 0)
+ goto fail;
+#else
+ if (cat_loop(fd) < 0)
+ goto fail;
+#endif
- buf[0] = DLE;
- buf[1] = DC4;
- buf[2] = DLE;
- buf[3] = ETX;
+ buf[0] = DLE; buf[1] = DC4; buf[2] = DLE; buf[3] = ETX;
loop_write(fd, buf, 4);
tcdrain(fd);
tty_puts(fd, "ATH\n");
@@ -575,12 +808,6 @@ int go(void) {
fail:
- if (incoming)
- free(incoming);
-
- if (outgoing)
- free(outgoing);
-
if (fd >= 0) {
hard_hangup(fd);
tty_puts(fd, "AT&F\n");
@@ -599,37 +826,50 @@ struct option long_options[] = {
{"answer", 0, 0, 'a'},
{"ring", 1, 0, 'r'},
{"version", 0, 0, 'V'},
+#ifdef HAVE_SPANDSP
+ {"fax", 1, 0, 'F'},
+ {"local-ident", 1, 0, 'n'},
+#endif
{0, 0, 0, 0}
};
-// Most important part of the program
+/* Most important part of the program*/
void usage() {
printf("Usage: %s [options] <source-msn> <destination-msn>\n"
" %s -a [options] <msn>\n"
"\n"
"Options:\n"
- " -h, --help Shows this usage information\n"
- " -t, --timeout=TIMEOUT Sets a timeout (%i)\n"
- " -d, --device=DEVICE Selects a device (if not specified, the first available /dev/ttyInn is used)\n"
- " -v, --verbose Enables debug mode (%s)\n"
- " -a, --answer Wait for incoming call instead of calling out (%s)\n"
- " -r, --ring=RINGS On incoming call answer after given RINGs (%i)\n"
- " -V, --version Show %s version number\n",
- appname, appname,
+ " -h, --help Shows this usage information\n"
+ " -t, --timeout=TIMEOUT Sets a timeout (%i)\n"
+ " -d, --device=DEVICE Selects a device (if not specified, the first available /dev/ttyInn is used)\n"
+ " -v, --verbose Enables debug mode (%s)\n"
+ " -a, --answer Wait for incoming call instead of calling out (%s)\n"
+ " -r, --ring=RINGS On incoming call answer after given RINGs (%i)\n"
+ " -V, --version Show %s version number\n"
+#ifdef HAVE_SPANDSP
+ " -F, --fax=FILE Send/Receive facsimile in the specified TIFF file (%s)\n"
+ " -n, --local-ident=IDENT Identification string for local peer during facsimile transmission (%s)\n"
+#endif
+ , appname, appname,
timeout,
debug ? "on" : "off",
answer ? "on" : "off",
rings,
- appname);
+ appname
+#ifdef HAVE_SPANDSP
+ , fax_tiff_file,
+ fax_ident
+#endif
+ );
}
-// Parses command line and executes go()
+/* Parses command line and executes go()*/
int main (int argc, char *argv[]) {
int c, r = 1;
- appname = basename(argv[0]);
+ appname = get_filename(argv[0]);
- while((c = getopt_long(argc, argv, "ht:d:var:V", long_options, NULL)) >= 0) {
+ while((c = getopt_long(argc, argv, "ht:d:var:VF:n:", long_options, NULL)) >= 0) {
switch (c) {
case 'V' :
@@ -656,10 +896,8 @@ int main (int argc, char *argv[]) {
case 'd' :
if (optarg) {
- if (device)
- free(device);
- else
- device = strdup(optarg);
+ free(device);
+ device = strdup(optarg);
} else {
fprintf(stderr, "Expected argument on device option.\n");
goto finish;
@@ -687,6 +925,20 @@ int main (int argc, char *argv[]) {
}
break;
+#ifdef HAVE_SPANDSP
+ case 'F':
+ free(fax_tiff_file);
+ fax_tiff_file = strdup(optarg);
+
+ fax_enabled = 1;
+ break;
+
+ case 'n':
+ free(fax_ident);
+ fax_ident = strdup(optarg);
+ break;
+#endif
+
case '?' :
goto finish;
}
@@ -724,9 +976,14 @@ int main (int argc, char *argv[]) {
finish:
- if (source_msn) free (source_msn);
- if (destination_msn) free(destination_msn);
- if (device) free(device);
+ free(source_msn);
+ free(destination_msn);
+ free(device);
+
+#ifdef HAVE_SPANDSP
+ free(fax_ident);
+ free(fax_tiff_file);
+#endif
return r;
}