Subject: Re: Sending faxes - How?

From: [email-masked] (Th. Blob (Dr.Serial))
Date: 16 Jun 1993 11:12:33 GMT

Joel M. Hoffman ([email-masked]) wrote:
: In article <[email-masked]> [email-masked] (Harvey J. Stein) writes:
: >
: >I want to send faxes from linux.  I have a fax modem, so if I can find
: >some fax software that runs under linux, I should be all set.  After
: >searching around a little, I picked up a copy of fax-3.2.1.tar.z from
: >the gnu directory on a local file server.  However, I can't get it to
: >compile.
: >
: > [...]
: >
: >So, has anyone has ported fax-3.2.1 to linux, or if there is any other
: >software that I should try.  Also, I'm running linux version .99, pl
: >8-3 (not sure about the -3), from SLS distribution 1.02.

: I have ported netfax, but I can't get it to work.  Everything
: compiles, and runs (well, mostly), but FAX's get aborted during send.
: I get the same problem with two other FAX sending methods, so I think
: there might be a problem with hardware flow control (I'm using
: 0.99.8).  Is this possible?

: As for the "port," it seems that the linux headers for stdarg and
: vararg don't like each other, so I had to muck around with that.
: Also, the copy of the source code I found was simply missing a line
: somewhere.

Are you using the patches to Net-Fax 3.2.1 ?  I am using NetFax on our local
Linux machine with success ! I have compiled the Clients to RS-6000 and
SUN-Sparc Systems. You must have a look at the Class 2 specifikation of
your Modem ! Not all Modems support the Class 2 Commands that NetFax uses.

Here ar the patches for Linux :
-------------------------------------------------------------------------

*** fax-3.2.1/cmd/faxenq/faxenq.c.org	Thu Jan 28 21:15:57 1993
--- fax-3.2.1/cmd/faxenq/faxenq.c	Thu Dec 31 23:22:22 1992
***************
*** 115,121 ****
--- 115,125 ----
       * Count the files and phone numbers given.
       */
      for (ind = optind; ind < argc; ind++) {
+ #ifdef LINUX
+ 	if (strcmp(argv[ind], "___") == 0) {
+ #else
  	if (strcmp(argv[ind], "---") == 0) {
+ #endif
  	    files = argc - ind - 1;
  	    break;
  	}
*** fax-3.2.1/cmd/faxps/faxps.c.org	Thu Jan 28 21:15:57 1993
--- fax-3.2.1/cmd/faxps/faxps.c	Thu Dec 31 23:21:51 1992
***************
*** 232,238 ****
--- 232,242 ----
      if (mail_notification)
        strcat(fax_cmd, " -m");
      strcat(fax_cmd, recips);
+ #ifdef LINUX
+     strcat(fax_cmd, " ___");
+ #else
      strcat(fax_cmd, " ---");
+ #endif
      if (coversheet)
        sprintf(&fax_cmd[strlen(fax_cmd)], " %s.g3.1", coversheet_base);
      sprintf(&fax_cmd[strlen(fax_cmd)], " %s.g3:%d", out_base, pages);
*** fax-3.2.1/cmd/faxspooler/process.c.org	Thu Jan 28 21:15:58 1993
--- fax-3.2.1/cmd/faxspooler/process.c	Sat Jan  9 14:48:14 1993
***************
*** 388,393 ****
--- 388,398 ----
  	time_t now = time(0);
  	int fm = get_modem(sd);
  
+ #ifdef LINUX
+         if (sd->qe == NULL)
+ 	  return (0) ;
+ #endif
+ 
  	/*
  	 * Assume we were left on the last recipient processed,
  	 * move on to the next one.  If we hit the last one,
*** fax-3.2.1/cmd/faxspooler/queue_entry.c.org	Thu Jan 28 21:15:58 1993
--- fax-3.2.1/cmd/faxspooler/queue_entry.c	Fri Jan  1 11:04:37 1993
***************
*** 326,331 ****
--- 326,335 ----
  	    }
  	}
      }
+ #ifdef LINUX
+     closedir(dirp) ; 
+ #endif
+ 
      if (rmdir(pathname) < 0) {
  	log(L_INFO, "error deleting %s: %m", pathname);
  	return (-1);
*** fax-3.2.1/cmd/faxspooler/faxspooler.c.org	Thu Jan 28 21:15:58 1993
--- fax-3.2.1/cmd/faxspooler/faxspooler.c	Thu Dec 31 21:21:06 1992
***************
*** 21,27 ****
--- 21,32 ----
  #include <stdio.h>
  #include <fcntl.h>
  #include <pwd.h>
+ #ifndef LINUX
  #include <syslog.h>
+ #else
+ #include <sys/syslog.h>
+ #endif
+ 
  #include <sys/ioctl.h>
  
  #include "../../lib/libfax/libfax.h"
*** fax-3.2.1/lib/libfax/log.c.org	Thu Jan 28 21:15:58 1993
--- fax-3.2.1/lib/libfax/log.c	Thu Dec 31 22:51:57 1992
***************
*** 20,32 ****
  
  #include <stdio.h>
  #include <errno.h>
- #include <varargs.h>
  #include <strings.h>
  #include <syslog.h>
  
  #include "log.h"
  
  extern char *sys_errlist[];
  extern int sys_nerr;
  static int log_level = LOG_DEBUG;
  static int use_syslog = 0;
--- 20,39 ----
  
  #include <stdio.h>
  #include <errno.h>
  #include <strings.h>
+ #ifndef LINUX
+ #include <varargs.h>
  #include <syslog.h>
+ #else
+ #include <syslog.h>
+ #include <varargs.h>
+ #endif
  
  #include "log.h"
  
+ #ifndef LINUX
  extern char *sys_errlist[];
+ #endif
  extern int sys_nerr;
  static int log_level = LOG_DEBUG;
  static int use_syslog = 0;
*** fax-3.2.1/lib/libfax/gen.c.org	Thu Jan 28 21:15:58 1993
--- fax-3.2.1/lib/libfax/gen.c	Sat Jan  9 17:12:43 1993
***************
*** 85,90 ****
--- 85,97 ----
  	fdprintf(f->fd, "ATS7=120 +FCR=1\r");
  	tcdrain(f->fd); sleep(1);
  
+ #ifdef SUPRA
+ /* Ziad added the next two lines to see if it can take dfaxhigh */
+ 	log(L_NOTICE, "setting DCE capabilities for SUPRA.") ; 
+ 	fdprintf(f->fd, "AT+FDCC=1,3\r");
+ 	tcdrain(f->fd); sleep(1);
+ #endif
+ 
  	/* flush any echoes or return codes */
  	tcflush(f->fd, TCIFLUSH);
  
*** fax-3.2.1/lib/libfax/write.c.org	Thu Jan 28 21:15:58 1993
--- fax-3.2.1/lib/libfax/write.c	Thu Dec 31 22:48:08 1992
***************
*** 21,29 ****
--- 21,35 ----
  #include <stdio.h>
  #include <sys/types.h>
  #include <sys/time.h>
+ #ifndef LINUX
  #include <varargs.h>
  
  #include "log.h"
+ #else
+ #include "log.h"
+ #include <varargs.h>
+ #endif
+ 
  #include "write.h"
  
  int nwrite(fd, buf, bufsize)
*** fax-3.2.1/lib/libfax/c2proto.h.org	Thu Jan 28 21:15:58 1993
--- fax-3.2.1/lib/libfax/c2proto.h	Sat Jan  9 16:59:48 1993
***************
*** 23,35 ****
   * Various timeouts are defined here, in seconds:
   */
  #define TIMEOUT_CONNECT	    60	/* wait for a connection		*/
! #define TIMEOUT_HANGUP	    5	/* wait for hangup to complete		*/
  #define TIMEOUT_ANSWER	    15	/* wait for phone to be answered	*/
  #define TIMEOUT_END_PAGE    120	/* wait for end of page to be acked	*/
  #define TIMEOUT_END_XMIT    120	/* wait for end of xmit to be acked	*/
! #define TIMEOUT_BIT_REVERSE 5	/* wait for bit reverse to be acked	*/
! #define TIMEOUT_BYTE_ALIGN  5   /* wait for byte align to be acked	*/
! #define TIMEOUT_SET_CAPABILITIES  5 /* wait for set capabilities ack	*/
  #define TIMEOUT_SEND_PAGE   60	/* final send of page timeout		*/
  #define TIMEOUT_RECV_PAGE   60	/* final recv page ack			*/
  
--- 23,35 ----
   * Various timeouts are defined here, in seconds:
   */
  #define TIMEOUT_CONNECT	    60	/* wait for a connection		*/
! #define TIMEOUT_HANGUP	    15	/*** wait for hangup to complete	*/
  #define TIMEOUT_ANSWER	    15	/* wait for phone to be answered	*/
  #define TIMEOUT_END_PAGE    120	/* wait for end of page to be acked	*/
  #define TIMEOUT_END_XMIT    120	/* wait for end of xmit to be acked	*/
! #define TIMEOUT_BIT_REVERSE 15	/**** wait for bit reverse to be acked	*/
! #define TIMEOUT_BYTE_ALIGN  15   /**** wait for byte align to be acked	*/
! #define TIMEOUT_SET_CAPABILITIES  15 /*** wait for set capabilities ack	*/
  #define TIMEOUT_SEND_PAGE   60	/* final send of page timeout		*/
  #define TIMEOUT_RECV_PAGE   60	/* final recv page ack			*/
  
*** fax-3.2.1/lib/libutil/tcp.c.org	Thu Jan 28 21:15:58 1993
--- fax-3.2.1/lib/libutil/tcp.c	Thu Dec 31 23:49:42 1992
***************
*** 44,60 ****
        return (-1);
  
      /* accept connections from any address on the given port */
      sin.sin_addr.s_addr = htonl(INADDR_ANY);
      sin.sin_port = port;
!     
      /* create the socket for listening */
      if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return (-1);
  
      if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) {
          close(s);
          return (-1);
      }
      
      /* bind address to the socket */
      if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
--- 44,69 ----
        return (-1);
  
      /* accept connections from any address on the given port */
+ #ifndef LINUX
      sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ #else
+     sin.sin_addr.s_addr= INADDR_ANY ; 
+     sin.sin_family = AF_INET ;
+ #endif
+ 
      sin.sin_port = port;
! 
! 
      /* create the socket for listening */
      if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return (-1);
  
+ #ifndef LINUX
      if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0) {
          close(s);
          return (-1);
      }
+ #endif
      
      /* bind address to the socket */
      if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
***************
*** 122,127 ****
--- 131,137 ----
      sin.sin_port = port;
      sin.sin_family = hp->h_addrtype;
      
+ 
      /* create the socket for the connection */
      if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0)
        return (-1);
*** fax-3.2.1/lib/libutil/dispatch.c.org	Thu Jan 28 21:15:59 1993
--- fax-3.2.1/lib/libutil/dispatch.c	Wed Jan  6 08:15:03 1993
***************
*** 31,36 ****
--- 31,40 ----
  #include "hash.h"
  #include "dispatch.h"
  
+ #ifdef LINUX
+ #define howmany(x, y)   (((x)+((y)-1))/(y))
+ #endif
+ 
  #define DIO_MASK_READ   0
  #define DIO_MASK_WRITE  1
  #define DIO_MASK_EXCEPT 2
***************
*** 102,108 ****
--- 106,114 ----
  init()
  {
      int dtbsz = getdtablesize();
+ #ifndef LINUX
      int cfree();
+ #endif
  
      if (dqueue_list == NULL)
        if ((dqueue_list = list_make(dqueue_cmp, NULL)) == NULL)
*** fax-3.2.1/lib/libutil/alarm.c.org	Thu Jan 28 21:15:59 1993
--- fax-3.2.1/lib/libutil/alarm.c	Thu Dec 31 19:40:25 1992
***************
*** 22,27 ****
--- 22,31 ----
  #include <signal.h>
  #include <sys/time.h>
  
+ #ifdef LINUX
+ #include <stdlib.h>
+ #endif
+ 
  #include "alloc.h"
  #include "list.h"
  #include "alarm.h"
***************
*** 46,52 ****
--- 50,58 ----
  char *data;
  {
      alarm_event *event;
+ #ifndef LINUX
      int cfree();
+ #endif
  
      if ((event = salloc(1, alarm_event)) == NULL)
        return (-1);
*** fax-3.2.1/include/conf.mk.org	Thu Jan 28 21:15:58 1993
--- fax-3.2.1/include/conf.mk	Sat Jan  9 16:51:53 1993
***************
*** 20,25 ****
  FAXLIBDIR = /usr/local/lib/fax
  FAXMANDIR = /usr/local/man
  
  OBJS = $(SRCS:.c=.o)
  
! LIBS = ../../lib/libfax/libfax.a ../../lib/libutil/libutil.a 
--- 20,27 ----
  FAXLIBDIR = /usr/local/lib/fax
  FAXMANDIR = /usr/local/man
  
+ CFLAGS = -DLINUX -DSUPRA -g
+ 
  OBJS = $(SRCS:.c=.o)
  
! LIBS = ../../lib/libfax/libfax.a ../../lib/libutil/libutil.a
*** fax-3.2.1/include/conf.h.org	Thu Jan 28 21:15:58 1993
--- fax-3.2.1/include/conf.h	Thu Dec 31 19:28:35 1992
***************
*** 26,43 ****
  /*
   * The service that clients use for connecting to the daemon:
   */
! #define FAX_SERVICE	    "1122"
  
  /*
   * The default fax spooler host:
   */
! #define FAX_HOST	    "wheat-chex.ai.mit.edu"
  
  /*
   * The queue directories:
   */
! #define OUTGOING_QUEUE 	    "/com/fax/outgoing"
! #define INCOMING_QUEUE      "/com/fax/incoming"
  
  /*
   * Base filename for sequence files:
--- 26,43 ----
  /*
   * The service that clients use for connecting to the daemon:
   */
! #define FAX_SERVICE	    "fax"
  
  /*
   * The default fax spooler host:
   */
! #define FAX_HOST	    "zodiac.slip.uiuc.edu"
  
  /*
   * The queue directories:
   */
! #define OUTGOING_QUEUE 	    "/usr/spool/fax/outgoing"
! #define INCOMING_QUEUE      "/usr/spool/fax/incoming"
  
  /*
   * Base filename for sequence files:
***************
*** 62,68 ****
  /*
   * Mail notification of incoming faxes to this address.
   */
! #define INCOMING_EMAIL_ADDR "[email-masked]"
  
  /*
   * How many times should I try to sync the modem?
--- 62,68 ----
  /*
   * Mail notification of incoming faxes to this address.
   */
! #define INCOMING_EMAIL_ADDR "[email-masked]"
  
  /*
   * How many times should I try to sync the modem?
*** fax-3.2.1/make/lib.mk.org	Thu Jan 28 21:15:59 1993
--- fax-3.2.1/make/lib.mk	Thu Dec 31 19:31:00 1992
***************
*** 11,20 ****
  
  $(OBJS:%=$(ARNAME)(%)): $(ARNAME)(%.o): %.c
  	$(CC) $(CFLAGS) -c $% $<
- 	ar rv $(ARNAME) $%
- 	rm -f $%
  
! $(ARNAME): $(OBJS:%=$(ARNAME)(%))
  	ranlib $@
  
  clean:
--- 11,21 ----
  
  $(OBJS:%=$(ARNAME)(%)): $(ARNAME)(%.o): %.c
  	$(CC) $(CFLAGS) -c $% $<
  
! # $(ARNAME): $(OBJS:%=$(ARNAME)(%))
! 
! $(ARNAME): $(OBJS)
! 	ar -rv $(ARNAME) $(OBJS)
  	ranlib $@
  
  clean:
-------------------------------------------------------------------------------

** Introduction:

   This is my port of netfax-3.2.1 to linux. Please see the License
   agreement in the file 'LICENSE'. It applies to the original source
   code and to my changes. 

   The port to linux was simple. once fd_set has been fixed in linux,
   this port is reduced to correcting few bugs and adjusting few
   header files. this port has been testing under linux 0.99pl2.
   Please not that I don't have another fax at my disposal for testing
   fax receive. I would appreciate it if you'll let me know how it
   goes if you can try it. I tried it once and got timeout errors. If
   you get the same errors tweeke the values in
   fax-3.2.1/lib/libfax/c2proto.h

   The rest of this file is instructions on how to install netfax on
   your system. Please also refer to the original documentations in
   the files "README" and "INSTALL". 

   All comments, bug reports, faxes :-) are welcome. 

 - Ziad Najem
   [email-masked]

-------------------------------------------------------------------------

** Prerequisites:
  
   The following must be installed on your system for netfax to work. 

   *) TCP/IP must be operational. You only need the loopback part of
      it.

   *) the RPC library and header files. This should be part of the NFS
      package. last seen on
      tsx11:/pub/linux/BETA/NFS/sunrpc-src-4.0.tar.Z 

   *) Ghostscript. 'dfaxhigh' and/or 'dfaxlow' devices must be
      compiled in. if you're not sure if they are or not, at your
      shell prompt, type:
       > echo 'devicenames ==' | gs -DNODISPLAY -q -
      the devices should be in the list printed. 

   *) If you plan to fax regular text files, you need a filter to
      translate text into postscript. Netfax assumes enscript is
      available but that can be trivially changed. I have nenscript
      which is a publicly available clone of enscript. It compiles out
      of the box. If you want just to fax postscript files (say using
      dvips) then you don't need anything for this step.

   *) Finally, the original NetFAX source files. Consult archie about
      fax-3.2.1.tar.Z if you don't have it.

** Installation. 
   1) tar xzf fax-3.2.1.tar.Z
   2) patch < fax-3.2.1.linux.diffs
   3) cd fax-3.2.1
   4) customize as specified in the next section.
   5) make. handful of warnings should be seen.
   6) You should be able to try it out before installing the files in
      their perminant places. The only exception is that
      cmd/faxenq/faxenq must be copied into its place as specified in
      include/conf.h using FAX_ENQ_PROG.
   7) start the fax spooler: "cmd/faxspooler/faxspooler". You may want
      to set the log level -l from 1..7
   8) First, see if you can talk to the spooler. do a "cmd/faxq/faxq",
      you shouldn't get "can't connect to fax daemon" 
   9) If every thing is working so far. try faxing a postscript file
      using: "cmd/faxps/faxps -p <phone> <postscript-filename>"
  10) Let me know how it goes. 

** Customization. 

   Most configuration is done in the file include/conf.h here is a
   description of these that you need to set before you can compile or
   run NetFAX.

   #define FAX_DEVICE		"/dev/fax"
     set this to the serial port of your modem or make a symbolic link
     from /dev/fax to /dev/ttys<number>

   #define FAX_SERVICE		"fax"
     Make sure to add the following line 
     fax   <XYZ>/tcp 
     to the tcp/ip services file (either /etc/sevices or
     /usr/etc/inet/services). <XYZ> is some unique integer which is
     not used in the services file.

   #define FAX_HOST		"zodiac.slip.uiuc.edu"
     Your machine's host name.

   #define OUTGOING_QUEUE 	"/usr/spool/fax/outgoing"
   #define INCOMING_QUEUE	"/usr/spool/fax/incoming"
     make sure that these directories (or what ever you set the above
     two to) do exist. 

   #define INCOMING_EMAIL_ADDR "[email-masked]"
     if you have Mail working set this up. If you don't just create a
     dummy script in /usr/ucb/Mail which does nothing. 

   #define FAX_ENQ_PROG		"/usr/local/lib/fax/faxenq"
      Once compiled, copy cmd/faxenq/faxenq to whereever you set the
      above before trying to fax.

   #define FAX_PS_PROG		"/usr/local/bin/faxps"
      Unless you'll be using cmd/fax/faxps, you don't need to worry
      about the above when testing.

   #define PS_PROG  "/usr/local/bin/gs -dNOPAUSE -q -sDEVICE=dfaxhigh "
      Just make sure that full path to ghostscript is specified above.
      Don't change any of the options except the DEVICE in case you
      need to send a low resolution faxes. 

   #define PS_TO_COVER_PROG "/usr/local/lib/fax/coverpage.ps"
      Set this if you'll be using the -c option when sending faxes. 

 Hope I haven't missing anything. 
-------------------------------------------------------------------------------

Hope that will help you !

--
 
 Thomas Blob             +49 6102 26063              (phone)
 Friedensallee 104       [email-masked]        (private)
 6078 Neu-Isenburg 1     [email-masked]    (university)