home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
comm
/
misc
/
elcheapofax
/
faxcmd
/
rcs
/
receive.c,v
< prev
next >
Wrap
Text File
|
1993-12-21
|
11KB
|
530 lines
head 1.5;
access;
symbols
OCT93:1.5;
locks;
comment @ * @;
1.5
date 93.10.25.02.18.43; author Rhialto; state Exp;
branches;
next 1.4;
1.4
date 93.09.18.20.29.19; author Rhialto; state Exp;
branches;
next 1.3;
1.3
date 93.07.13.05.49.47; author Rhialto; state Exp;
branches;
next 1.2;
1.2
date 93.06.11.16.31.57; author Rhialto; state Exp;
branches;
next 1.1;
1.1
date 93.06.11.15.16.34; author Rhialto; state Exp;
branches;
next ;
desc
@Receive a fax from the modem
@
1.5
log
@Make +FBOR flexible.
@
text
@/* $Id: receive.c,v 1.4 1993/09/18 20:29:19 Rhialto Exp $
* $Log: receive.c,v $
* Revision 1.4 1993/09/18 20:29:19 Rhialto
* Call faxmodem_sync() explicitly.
* Further, a second attempt at polling.
*
* Revision 1.3 1993/07/13 05:49:47 Rhialto
* First attempt at polling for faxes. Does not work.
*
* Revision 1.2 1993/06/11 16:31:57 Rhialto
* First real RCS checkin
*
*/
/*
* This file is part of El Cheapo Fax. All modifications relative to the
* base source are (C) Copyright 1993 by Olaf 'Rhialto' Seibert.
* All rights reserved. The GNU General Public License applies.
*/
/*
This file is part of the NetFax system.
(c) Copyright 1989 by David M. Siegel.
All rights reserved.
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <sys/stat.h>
#define MAXPATHLEN 128
#include "libfax.h"
#include "seq.h"
char *in_qdir = INCOMING_QUEUE;
FaxModem fm;
int verbose;
int immediate;
#define EXIT_ERROR 21
#define EXIT_NO_FILE 22
#define EXIT_OPEN_FAILED 23
#define EXIT_CALL_FAILED 24
#define EXIT_SEND_FAILED 25
#define EXIT_FINISH_FAILED 26
/*
* This should also write stuff to the modem.
*/
int
recv_enable(int fd)
{
/*
* Make sure nothing is left to read.
*/
tcflush(fd, TCIFLUSH);
return 0;
}
static void
print_fdcs_params(FaxModem *f, FILE *fp)
{
if (FAX_ISSET(f, FAX_F_FDCS)) {
fprintf(fp, " vr=%s br=%s wd=%s ln=%s",
t30_vr_string(&f->fdcs_params),
t30_br_string(&f->fdcs_params),
t30_wd_string(&f->fdcs_params),
t30_ln_string(&f->fdcs_params));
}
}
static int
receive_pages(FaxModem *fmp, char *in_dir, FILE *info_fp)
{
int page = 0;
for (;;) {
time_t start = time(0);
char file[MAXPATHLEN];
int fd;
/*
* Tell the modem we are ready to go.
*/
switch (faxmodem_start_recv(fmp)) {
case RECV_OK:
break;
case RECV_FAILED:
fprintf(info_fp, " page %d failed\n", page+1);
fprintf(info_fp, "\nReceived %d pages succesfully\n", page);
return (-1);
case RECV_DONE:
fprintf(info_fp, "\nReceived %d pages succesfully\n", page);
return (page);
}
/*
* Open the file to hold the G3 data.
*/
sprintf(file, "%s%d", in_dir, page++);
if ((fd = open(file, O_WRONLY|O_CREAT, 0666)) < 0) {
log(L_ALERT, "output file open failed: %m");
fprintf(info_fp, " page %d failed\n", page);
return (-1);
}
/*
* Read in the page.
*/
if (faxmodem_recv_page(fmp, fd) < 0) {
log(L_WARNING, "receive of page failed");
fprintf(info_fp, " page %d failed\n", page);
close(fd);
return (-1);
}
/*
* All done with the page.
*/
log(L_INFO, "received page %d", page);
fprintf(info_fp, " page %d ok", page);
print_fdcs_params(fmp, info_fp);
fprintf(info_fp, " time=%d\n", time(0) - start);
close(fd);
}
}
/*
* This function does the bulk of the work for receiving a new
* fax. It answers the modem, reads the fax, writes the G3 files,
* and mails notification.
*/
static int
handle_incoming_fax(FaxModem *fmp)
{
time_t start = time(0);
char in_dir[MAXPATHLEN];
char seq_file[MAXPATHLEN];
char info_file[MAXPATHLEN];
FILE *info_fp;
int seq;
int rc;
log(L_INFO, "handling an incoming fax");
if (faxmodem_answer(fmp) < 0) {
log(L_NOTICE, "can't anwser the phone");
faxmodem_hangup(fmp);
return (-1);
}
sprintf(seq_file, "%s%s", in_qdir, SEQ_FILE);
if ((seq = seq_next(seq_file)) < 0) {
log(L_ALERT, "can't get incoming sequence number: %m");
faxmodem_hangup(fmp);
return (-1);
}
sprintf(in_dir, "%s%d", in_qdir, seq);
if (mkdir(in_dir, 0755) < 0) {
log(L_ALERT, "can't make incoming directory: %m");
faxmodem_hangup(fmp);
return (-1);
}
sprintf(in_dir, "%s%d/", in_qdir, seq);
sprintf(info_file, "%sLOG", in_dir);
if ((info_fp = fopen(info_file, "w+")) == NULL) {
log(L_ALERT, "can't make info file: %m");
faxmodem_hangup(fmp);
return (-1);
}
/*
* Print the header for the info file.
*/
fprintf(info_fp, "Reception of fax %d started at %s", seq, ctime(&start));
faxmodem_print_id_strings(fmp, info_fp);
fprintf(info_fp, "\n");
/*
* Receive the pages.
*/
rc = receive_pages(fmp, in_dir, info_fp);
fprintf(info_fp, "\nTotal connect time was %d seconds.\n",
time(0) - start);
/*
* All done.
*/
faxmodem_hangup(fmp);
fclose(info_fp);
return (rc);
}
static int
poll_for_fax(char *fax_device, char *phone)
{
time_t start;
log(L_INFO, "polling for fax at %s\n", phone);
if (verbose)
printf("polling for fax at %s\n", phone);
if (faxmodem_open(&fm, fax_device) < 0 ||
faxmodem_sync(&fm, 10) < 0) {
fprintf(stderr, "open of fax failed\n");
exit(EXIT_OPEN_FAILED);
}
if (faxmodem_want_poll(&fm) < 0) {
fprintf(stderr, "faxmodem won't poll\n");
exit(EXIT_OPEN_FAILED);
}
if (faxmodem_initiate_call(&fm, phone) < 0 || !FAX_CONNECTED(&fm)) {
fprintf(stderr, "call to %s failed\n", phone);
exit(EXIT_CALL_FAILED);
}
start = time(0);
if (verbose) {
printf("connected to %s\n", phone);
faxmodem_print_id_strings(&fm, stdout);
}
if (fm.flags & FAX_F_FPOLL) {
fm.flags |= FAX_F_CONNECT; /* Don't ATZ/ATA */
if (handle_incoming_fax(&fm) < 0)
return -1;
} else {
fprintf(stderr, "no document ready to be polled\n");
}
if (faxmodem_hangup(&fm) < 0) {
fprintf(stderr, "hangup failed\n");
exit(EXIT_FINISH_FAILED);
}
if (verbose)
printf("total connect time was %d seconds\n", time(0) - start);
return 0;
}
/* ARGSUSED */
static int
recv_handler(FaxModem *fm)
{
log(L_INFO, "the phone is (probably) ringing");
handle_incoming_fax(fm);
/*
* Resync resync the modem, just in case.
*/
if (faxmodem_sync(fm, FAXMODEM_SYNC_TRIES) < 0)
log(L_EMERG, "can't resync to the modem");
/*
* All done!
*/
return (0);
}
void
cleanup(void)
{
if (fm.fd >= 0) {
faxmodem_hangup(&fm);
faxmodem_close(&fm);
}
}
/*
* Setup for incoming faxes. Basically, we read from the serial
* device If any data arrives on the fd, we know
* we have an incoming fax, and we handle the call.
*/
int
init_for_recv(char *fax_device)
{
if (faxmodem_open(&fm, fax_device) >= 0) {
char c;
int rc;
recv_enable(fm.fd);
if (!FAX_ISSET(&fm, FAX_F_SYNC)) {
if (faxmodem_sync(&fm, FAXMODEM_SYNC_TRIES) < 0) {
log(L_EMERG, "can't sync to the modem");
return -1;
}
}
for (;;) {
if (immediate) {
rc = immediate;
immediate = -1; /* receive only one fax */
} else
rc = tread(fm.fd, &c, 1, 60*60); /* 1 hour timeout */
if (rc > 0)
recv_handler(&fm);
else if (rc < 0)
break;
}
faxmodem_close(&fm);
fm.fd = -1;
immediate = 0;
}
}
int
main(int argc, char **argv)
{
int c;
extern char *optarg;
extern int optind;
extern int getopt(int, char **, char *);
int errflg = 0;
char *fax_device = FAX_DEVICE;
struct stat statbuf;
log_set_level(LOG_WARNING);
while ((c = getopt(argc, argv, "b:d:l:vf:i")) != -1) {
switch (c) {
case 'b':
bor_value = atoi(optarg);
break;
case 'd':
in_qdir = optarg;
break;
case 'l':
log_set_level(atoi(optarg));
break;
case 'v':
verbose = TRUE;
break;
case 'f':
fax_device = optarg;
break;
case 'i':
immediate++;
if (immediate == 2) {
fm.flags |= FAX_F_SYNC | FAX_F_CONNECT; /* Don't ATZ/ATA */
}
break;
case '?':
errflg++;
break;
}
}
if (errflg || optind > argc) {
fprintf(stderr,
"Usage: %s [-d queuedir/] [-f faxdevice] [-l loglevel] [-v] [-i]\n"
" [-b bitorder]\n", argv[0]);
exit(EXIT_FAILURE);
}
if (stat(in_qdir, &statbuf) < 0 || (statbuf.st_mode & S_IFMT) != S_IFDIR) {
fprintf(stderr, "queuedir %s nonexistent or not a directory\n", in_qdir);
exit(EXIT_FAILURE);
}
atexit(cleanup);
if (optind < argc) {
errflg = poll_for_fax(fax_device, argv[optind++]);
} else {
errflg = init_for_recv(fax_device);
}
return errflg >= 0? EXIT_SUCCESS: EXIT_FAILURE;
}
@
1.4
log
@Call faxmodem_sync() explicitly.
Further, a second attempt at polling.
@
text
@d1 1
a1 1
/* $Id: receive.c,v 1.3 1993/07/13 05:49:47 Rhialto Exp $
d3 4
d337 1
a337 1
struct stat statbuf;
d341 1
a341 1
while ((c = getopt(argc, argv, "d:l:vf:i")) != -1) {
d343 3
d372 2
a373 1
"Usage: %s [-d queuedir/] [-f faxdevice] [-l loglevel] [-v] [-i]\n", argv[0]);
@
1.3
log
@First attempt at polling for faxes. Does not work.
@
text
@d1 1
a1 1
/* $Id: receive.c,v 1.2 1993/06/11 16:31:57 Rhialto Exp $
d3 3
d216 2
a217 1
if (faxmodem_open(&fm, fax_device) < 0) {
d222 5
d239 7
a245 3
fm.flags |= FAX_F_CONNECT; /* Don't ATZ/ATA */
if (handle_incoming_fax(&fm) < 0)
return -1;
@
1.2
log
@First real RCS checkin
@
text
@d1 5
a5 2
/* $Id$
* $Log$
d36 1
d48 7
d204 41
d268 2
a269 1
if (fm.fd >= 0)
d271 1
a285 1
atexit(cleanup);
d320 1
d341 1
a341 1
fm.flags |= FAX_F_SYNC; /* Don't ATZ/ATA */
d356 13
a368 1
return init_for_recv(fax_device) >= 0? EXIT_SUCCESS: EXIT_FAILURE;
@
1.1
log
@Initial revision
@
text
@d1 3
d156 1
a156 1
sprintf(in_dir, "%s%d/", in_qdir, seq);
d162 1
d235 1
a235 1
if (!FAX_ISSET(&fm, FAX_F_FCON)) {
d287 1
a287 1
fm.flags |= FAX_F_FCON; /* Don't ATZ/ATA */
d298 1
a298 1
"Usage: %s -d queuedir/ -f faxdevice -l loglevel -v -i\n", argv[0]);
@