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 >
Text File  |  1993-12-21  |  11KB  |  530 lines

  1. head    1.5;
  2. access;
  3. symbols
  4.     OCT93:1.5;
  5. locks;
  6. comment    @ * @;
  7.  
  8.  
  9. 1.5
  10. date    93.10.25.02.18.43;    author Rhialto;    state Exp;
  11. branches;
  12. next    1.4;
  13.  
  14. 1.4
  15. date    93.09.18.20.29.19;    author Rhialto;    state Exp;
  16. branches;
  17. next    1.3;
  18.  
  19. 1.3
  20. date    93.07.13.05.49.47;    author Rhialto;    state Exp;
  21. branches;
  22. next    1.2;
  23.  
  24. 1.2
  25. date    93.06.11.16.31.57;    author Rhialto;    state Exp;
  26. branches;
  27. next    1.1;
  28.  
  29. 1.1
  30. date    93.06.11.15.16.34;    author Rhialto;    state Exp;
  31. branches;
  32. next    ;
  33.  
  34.  
  35. desc
  36. @Receive a fax from the modem
  37. @
  38.  
  39.  
  40. 1.5
  41. log
  42. @Make +FBOR flexible.
  43. @
  44. text
  45. @/* $Id: receive.c,v 1.4 1993/09/18 20:29:19 Rhialto Exp $
  46.  * $Log: receive.c,v $
  47.  * Revision 1.4  1993/09/18  20:29:19  Rhialto
  48.  * Call faxmodem_sync() explicitly.
  49.  * Further, a second attempt at polling.
  50.  *
  51.  * Revision 1.3  1993/07/13  05:49:47  Rhialto
  52.  * First attempt at polling for faxes. Does not work.
  53.  *
  54.  * Revision 1.2  1993/06/11  16:31:57  Rhialto
  55.  * First real RCS checkin
  56.  *
  57.  */
  58. /*
  59.  * This file is part of El Cheapo Fax. All modifications relative to the
  60.  * base source are (C) Copyright 1993 by Olaf 'Rhialto' Seibert.
  61.  * All rights reserved. The GNU General Public License applies.
  62.  */
  63. /*
  64.   This file is part of the NetFax system.
  65.  
  66.   (c) Copyright 1989 by David M. Siegel.
  67.       All rights reserved.
  68.  
  69.     This program is free software; you can redistribute it and/or modify
  70.     it under the terms of the GNU General Public License as published by
  71.     the Free Software Foundation.
  72.  
  73.     This program is distributed in the hope that it will be useful,
  74.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  75.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  76.     GNU General Public License for more details.
  77.  
  78.     You should have received a copy of the GNU General Public License
  79.     along with this program; if not, write to the Free Software
  80.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  81. */
  82.  
  83. #include <stdio.h>
  84. #include <stdlib.h>
  85. #include <time.h>
  86. #include <fcntl.h>
  87. #include <sys/stat.h>
  88.  
  89. #define MAXPATHLEN    128
  90.  
  91. #include "libfax.h"
  92. #include "seq.h"
  93.  
  94. char           *in_qdir = INCOMING_QUEUE;
  95. FaxModem    fm;
  96. int        verbose;
  97. int        immediate;
  98.  
  99. #define EXIT_ERROR        21
  100. #define EXIT_NO_FILE        22
  101. #define EXIT_OPEN_FAILED    23
  102. #define EXIT_CALL_FAILED    24
  103. #define EXIT_SEND_FAILED    25
  104. #define EXIT_FINISH_FAILED    26
  105.  
  106. /*
  107.  * This should also write stuff to the modem.
  108.  */
  109. int
  110. recv_enable(int fd)
  111. {
  112.     /*
  113.      * Make sure nothing is left to read.
  114.      */
  115.     tcflush(fd, TCIFLUSH);
  116.     return 0;
  117. }
  118.  
  119. static void
  120. print_fdcs_params(FaxModem *f, FILE *fp)
  121. {
  122.     if (FAX_ISSET(f, FAX_F_FDCS)) {
  123.     fprintf(fp, " vr=%s br=%s wd=%s ln=%s",
  124.         t30_vr_string(&f->fdcs_params),
  125.         t30_br_string(&f->fdcs_params),
  126.         t30_wd_string(&f->fdcs_params),
  127.         t30_ln_string(&f->fdcs_params));
  128.       }
  129. }
  130.  
  131. static int
  132. receive_pages(FaxModem *fmp, char *in_dir, FILE *info_fp)
  133. {
  134.     int page = 0;
  135.  
  136.     for (;;) {
  137.     time_t start = time(0);
  138.     char file[MAXPATHLEN];
  139.     int fd;
  140.  
  141.     /*
  142.      * Tell the modem we are ready to go.
  143.      */
  144.     switch (faxmodem_start_recv(fmp)) {
  145.       case RECV_OK:
  146.         break;
  147.       case RECV_FAILED:
  148.         fprintf(info_fp, "  page %d failed\n", page+1);
  149.         fprintf(info_fp, "\nReceived %d pages succesfully\n", page);
  150.         return (-1);
  151.       case RECV_DONE:
  152.         fprintf(info_fp, "\nReceived %d pages succesfully\n", page);
  153.         return (page);
  154.     }
  155.  
  156.     /*
  157.      * Open the file to hold the G3 data.
  158.      */
  159.     sprintf(file, "%s%d", in_dir, page++);
  160.     if ((fd = open(file, O_WRONLY|O_CREAT, 0666)) < 0) {
  161.         log(L_ALERT, "output file open failed: %m");
  162.         fprintf(info_fp, "  page %d failed\n", page);
  163.         return (-1);
  164.     }
  165.  
  166.     /*
  167.      * Read in the page.
  168.      */
  169.     if (faxmodem_recv_page(fmp, fd) < 0) {
  170.         log(L_WARNING, "receive of page failed");
  171.         fprintf(info_fp, "  page %d failed\n", page);
  172.         close(fd);
  173.         return (-1);
  174.     }
  175.  
  176.     /*
  177.      * All done with the page.
  178.      */
  179.     log(L_INFO, "received page %d", page);
  180.     fprintf(info_fp, "  page %d ok", page);
  181.     print_fdcs_params(fmp, info_fp);
  182.     fprintf(info_fp, " time=%d\n", time(0) - start);
  183.     close(fd);
  184.     }
  185. }
  186.  
  187. /*
  188.  * This function does the bulk of the work for receiving a new
  189.  * fax.  It answers the modem, reads the fax, writes the G3 files,
  190.  * and mails notification.
  191.  */
  192. static int
  193. handle_incoming_fax(FaxModem *fmp)
  194. {
  195.     time_t start = time(0);
  196.     char in_dir[MAXPATHLEN];
  197.     char seq_file[MAXPATHLEN];
  198.     char info_file[MAXPATHLEN];
  199.     FILE *info_fp;
  200.     int seq;
  201.     int rc;
  202.  
  203.     log(L_INFO, "handling an incoming fax");
  204.  
  205.     if (faxmodem_answer(fmp) < 0) {
  206.     log(L_NOTICE, "can't anwser the phone");
  207.     faxmodem_hangup(fmp);
  208.     return (-1);
  209.     }
  210.  
  211.     sprintf(seq_file, "%s%s", in_qdir, SEQ_FILE);
  212.     if ((seq = seq_next(seq_file)) < 0) {
  213.     log(L_ALERT, "can't get incoming sequence number: %m");
  214.     faxmodem_hangup(fmp);
  215.     return (-1);
  216.     }
  217.  
  218.     sprintf(in_dir, "%s%d", in_qdir, seq);
  219.     if (mkdir(in_dir, 0755) < 0) {
  220.     log(L_ALERT, "can't make incoming directory: %m");
  221.     faxmodem_hangup(fmp);
  222.     return (-1);
  223.     }
  224.     sprintf(in_dir, "%s%d/", in_qdir, seq);
  225.  
  226.     sprintf(info_file, "%sLOG", in_dir);
  227.     if ((info_fp = fopen(info_file, "w+")) == NULL) {
  228.     log(L_ALERT, "can't make info file: %m");
  229.     faxmodem_hangup(fmp);
  230.     return (-1);
  231.     }
  232.  
  233.     /*
  234.      * Print the header for the info file.
  235.      */
  236.     fprintf(info_fp, "Reception of fax %d started at %s", seq, ctime(&start));
  237.     faxmodem_print_id_strings(fmp, info_fp);
  238.     fprintf(info_fp, "\n");
  239.  
  240.     /*
  241.      * Receive the pages.
  242.      */
  243.     rc = receive_pages(fmp, in_dir, info_fp);
  244.     fprintf(info_fp, "\nTotal connect time was %d seconds.\n",
  245.         time(0) - start);
  246.  
  247.     /*
  248.      * All done.
  249.      */
  250.     faxmodem_hangup(fmp);
  251.     fclose(info_fp);
  252.     return (rc);
  253. }
  254.  
  255. static int
  256. poll_for_fax(char *fax_device, char *phone)
  257. {
  258.     time_t start;
  259.  
  260.     log(L_INFO, "polling for fax at %s\n", phone);
  261.     if (verbose)
  262.     printf("polling for fax at %s\n", phone);
  263.  
  264.     if (faxmodem_open(&fm, fax_device) < 0 ||
  265.     faxmodem_sync(&fm, 10) < 0) {
  266.     fprintf(stderr, "open of fax failed\n");
  267.     exit(EXIT_OPEN_FAILED);
  268.     }
  269.  
  270.     if (faxmodem_want_poll(&fm) < 0) {
  271.     fprintf(stderr, "faxmodem won't poll\n");
  272.     exit(EXIT_OPEN_FAILED);
  273.     }
  274.  
  275.     if (faxmodem_initiate_call(&fm, phone) < 0 || !FAX_CONNECTED(&fm)) {
  276.     fprintf(stderr, "call to %s failed\n", phone);
  277.     exit(EXIT_CALL_FAILED);
  278.     }
  279.  
  280.     start = time(0);
  281.  
  282.     if (verbose) {
  283.     printf("connected to %s\n", phone);
  284.     faxmodem_print_id_strings(&fm, stdout);
  285.     }
  286.  
  287.     if (fm.flags & FAX_F_FPOLL) {
  288.     fm.flags |= FAX_F_CONNECT;   /* Don't ATZ/ATA */
  289.     if (handle_incoming_fax(&fm) < 0)
  290.         return -1;
  291.     } else {
  292.     fprintf(stderr, "no document ready to be polled\n");
  293.     }
  294.  
  295.     if (faxmodem_hangup(&fm) < 0) {
  296.     fprintf(stderr, "hangup failed\n");
  297.     exit(EXIT_FINISH_FAILED);
  298.     }
  299.  
  300.     if (verbose)
  301.     printf("total connect time was %d seconds\n", time(0) - start);
  302.  
  303.     return 0;
  304. }
  305.  
  306. /* ARGSUSED */
  307. static int
  308. recv_handler(FaxModem *fm)
  309. {
  310.     log(L_INFO, "the phone is (probably) ringing");
  311.  
  312.     handle_incoming_fax(fm);
  313.  
  314.     /*
  315.      * Resync resync the modem, just in case.
  316.      */
  317.     if (faxmodem_sync(fm, FAXMODEM_SYNC_TRIES) < 0)
  318.       log(L_EMERG, "can't resync to the modem");
  319.  
  320.     /*
  321.      * All done!
  322.      */
  323.     return (0);
  324. }
  325.  
  326. void
  327. cleanup(void)
  328. {
  329.     if (fm.fd >= 0) {
  330.     faxmodem_hangup(&fm);
  331.     faxmodem_close(&fm);
  332.     }
  333. }
  334.  
  335. /*
  336.  * Setup for incoming faxes.  Basically, we read from the serial
  337.  * device If any data arrives on the fd, we know
  338.  * we have an incoming fax, and we handle the call.
  339.  */
  340. int
  341. init_for_recv(char *fax_device)
  342. {
  343.     if (faxmodem_open(&fm, fax_device) >= 0) {
  344.     char c;
  345.     int rc;
  346.  
  347.     recv_enable(fm.fd);
  348.  
  349.     if (!FAX_ISSET(&fm, FAX_F_SYNC)) {
  350.         if (faxmodem_sync(&fm, FAXMODEM_SYNC_TRIES) < 0) {
  351.         log(L_EMERG, "can't sync to the modem");
  352.         return -1;
  353.         }
  354.     }
  355.     for (;;) {
  356.         if (immediate) {
  357.         rc = immediate;
  358.         immediate = -1;     /* receive only one fax */
  359.         } else
  360.         rc = tread(fm.fd, &c, 1, 60*60);   /* 1 hour timeout */
  361.         if (rc > 0)
  362.         recv_handler(&fm);
  363.         else if (rc < 0)
  364.         break;
  365.     }
  366.     faxmodem_close(&fm);
  367.     fm.fd = -1;
  368.     immediate = 0;
  369.     }
  370. }
  371.  
  372. int
  373. main(int argc, char **argv)
  374. {
  375.     int         c;
  376.     extern char    *optarg;
  377.     extern int        optind;
  378.     extern int        getopt(int, char **, char *);
  379.     int         errflg = 0;
  380.     char       *fax_device = FAX_DEVICE;
  381.     struct stat     statbuf;
  382.  
  383.     log_set_level(LOG_WARNING);
  384.  
  385.     while ((c = getopt(argc, argv, "b:d:l:vf:i")) != -1) {
  386.     switch (c) {
  387.     case 'b':
  388.         bor_value = atoi(optarg);
  389.         break;
  390.     case 'd':
  391.         in_qdir = optarg;
  392.         break;
  393.     case 'l':
  394.         log_set_level(atoi(optarg));
  395.         break;
  396.     case 'v':
  397.         verbose = TRUE;
  398.         break;
  399.     case 'f':
  400.         fax_device = optarg;
  401.         break;
  402.     case 'i':
  403.         immediate++;
  404.         if (immediate == 2) {
  405.         fm.flags |= FAX_F_SYNC | FAX_F_CONNECT;   /* Don't ATZ/ATA */
  406.         }
  407.         break;
  408.     case '?':
  409.         errflg++;
  410.         break;
  411.     }
  412.     }
  413.  
  414.     if (errflg || optind > argc) {
  415.     fprintf(stderr,
  416. "Usage: %s [-d queuedir/] [-f faxdevice] [-l loglevel] [-v] [-i]\n"
  417. "       [-b bitorder]\n", argv[0]);
  418.     exit(EXIT_FAILURE);
  419.     }
  420.  
  421.     if (stat(in_qdir, &statbuf) < 0 || (statbuf.st_mode & S_IFMT) != S_IFDIR) {
  422.     fprintf(stderr, "queuedir %s nonexistent or not a directory\n", in_qdir);
  423.     exit(EXIT_FAILURE);
  424.     }
  425.     atexit(cleanup);
  426.  
  427.     if (optind < argc) {
  428.     errflg = poll_for_fax(fax_device, argv[optind++]);
  429.     } else {
  430.     errflg = init_for_recv(fax_device);
  431.     }
  432.  
  433.     return errflg >= 0? EXIT_SUCCESS: EXIT_FAILURE;
  434. }
  435. @
  436.  
  437.  
  438. 1.4
  439. log
  440. @Call faxmodem_sync() explicitly.
  441. Further, a second attempt at polling.
  442. @
  443. text
  444. @d1 1
  445. a1 1
  446. /* $Id: receive.c,v 1.3 1993/07/13 05:49:47 Rhialto Exp $
  447. d3 4
  448. d337 1
  449. a337 1
  450.     struct stat        statbuf;
  451. d341 1
  452. a341 1
  453.     while ((c = getopt(argc, argv, "d:l:vf:i")) != -1) {
  454. d343 3
  455. d372 2
  456. a373 1
  457. "Usage: %s [-d queuedir/] [-f faxdevice] [-l loglevel] [-v] [-i]\n", argv[0]);
  458. @
  459.  
  460.  
  461. 1.3
  462. log
  463. @First attempt at polling for faxes. Does not work.
  464. @
  465. text
  466. @d1 1
  467. a1 1
  468. /* $Id: receive.c,v 1.2 1993/06/11 16:31:57 Rhialto Exp $
  469. d3 3
  470. d216 2
  471. a217 1
  472.     if (faxmodem_open(&fm, fax_device) < 0) {
  473. d222 5
  474. d239 7
  475. a245 3
  476.     fm.flags |= FAX_F_CONNECT;   /* Don't ATZ/ATA */
  477.     if (handle_incoming_fax(&fm) < 0)
  478.     return -1;
  479. @
  480.  
  481.  
  482. 1.2
  483. log
  484. @First real RCS checkin
  485. @
  486. text
  487. @d1 5
  488. a5 2
  489. /* $Id$
  490.  * $Log$
  491. d36 1
  492. d48 7
  493. d204 41
  494. d268 2
  495. a269 1
  496.     if (fm.fd >= 0)
  497. d271 1
  498. a285 1
  499.     atexit(cleanup);
  500. d320 1
  501. d341 1
  502. a341 1
  503.         fm.flags |= FAX_F_SYNC;   /* Don't ATZ/ATA */
  504. d356 13
  505. a368 1
  506.     return init_for_recv(fax_device) >= 0? EXIT_SUCCESS: EXIT_FAILURE;
  507. @
  508.  
  509.  
  510. 1.1
  511. log
  512. @Initial revision
  513. @
  514. text
  515. @d1 3
  516. d156 1
  517. a156 1
  518.     sprintf(in_dir, "%s%d/", in_qdir, seq);
  519. d162 1
  520. d235 1
  521. a235 1
  522.     if (!FAX_ISSET(&fm, FAX_F_FCON)) {
  523. d287 1
  524. a287 1
  525.         fm.flags |= FAX_F_FCON;   /* Don't ATZ/ATA */
  526. d298 1
  527. a298 1
  528. "Usage: %s -d queuedir/ -f faxdevice -l loglevel -v -i\n", argv[0]);
  529. @
  530.