1 /* $Id$ */
2 /*
3 * Copyright (c) 1990-1996 Sam Leffler
4 * Copyright (c) 1991-1996 Silicon Graphics, Inc.
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and
7 * its documentation for any purpose is hereby granted without fee, provided
8 * that (i) the above copyright notices and this permission notice appear in
9 * all copies of the software and related documentation, and (ii) the names of
10 * Sam Leffler and Silicon Graphics may not be used in any advertising or
11 * publicity relating to the software without the specific, prior written
12 * permission of Sam Leffler and Silicon Graphics.
13 *
14 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
16 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
17 *
18 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
19 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
22 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
23 * OF THIS SOFTWARE.
24 */
25 #include <stdio.h>
26 #include <string.h>
27 #include <syslog.h>
28 #include <stdarg.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33
34 #include "config.h"
35 #include "port.h"
36
37 static void
fatal(char * fmt,...)38 fatal(char* fmt, ...)
39 {
40 va_list ap;
41 va_start(ap, fmt);
42 if (isatty(fileno(stderr))) {
43 vfprintf(stderr, fmt, ap);
44 putc('\n', stderr);
45 } else {
46 vsyslog(LOG_ERR, fmt, ap);
47 }
48 va_end(ap);
49 exit(-1);
50 }
51
52 extern int cvtFacility(const char*, int*);
53
54 static const char*
modemstate(const char * arg)55 modemstate(const char* arg)
56 {
57 static struct {
58 const char* tag;
59 const char* state;
60 } modemstates[] = {
61 { "busy", "B" },
62 { "ready", "R" }, { "up", "R" },
63 { "down", "D" }, { "disable", "D" },
64 { NULL }
65 };
66 int i;
67
68 for (i = 0; modemstates[i].tag != NULL; i++)
69 if (strcmp(modemstates[i].tag, arg) == 0)
70 return (modemstates[i].state);
71 fatal("Bad modem ready state `%s'; use one of busy, ready, and down", arg);
72 /*NOTREACHED*/
73 return (NULL);
74 }
75
76 int
main(int argc,char ** argv)77 main(int argc, char** argv)
78 {
79 extern int optind;
80 extern char* optarg;
81 int fifo, c;
82 char* spooldir = FAX_SPOOLDIR;
83 const char* arg = modemstate("ready");
84 char fifoname[256];
85 char devid[256];
86 int cmdlen;
87 char cmd[80];
88 char* appname;
89 char* usage = "[-s state] [-q queue-dir] [-n]";
90 char* cp;
91 int facility = LOG_DAEMON;
92 int nofaxgetty = 0;
93
94 (void) cvtFacility(LOG_FAX, &facility);
95 openlog(argv[0], LOG_PID|LOG_ODELAY, facility);
96 appname = strrchr(argv[0], '/');
97 if (appname)
98 appname++;
99 else
100 appname = argv[0];
101 while ((c = getopt(argc, argv, "s:q:n")) != -1)
102 switch (c) {
103 case 'n':
104 nofaxgetty = 1;
105 break;
106 case 's':
107 arg = modemstate(optarg);
108 break;
109 case 'q':
110 spooldir = optarg;
111 break;
112 case '?':
113 fatal("usage: %s %s devid", argv[0], usage);
114 /*NOTREACHED*/
115 }
116 if (optind != argc-1) {
117 fatal("usage: %s %s modem", argv[0], usage);
118 }
119 if (strlen(argv[optind]) < sizeof(devid)) {
120 strcpy(devid, argv[optind]);
121 } else {
122 fatal("Argument is too large: %s", argv[optind]);
123 }
124 for (cp = devid; (cp = strchr(cp, '/')); *cp++ = '_')
125 ;
126 if (chdir(spooldir) < 0)
127 fatal("%s: chdir: %s", spooldir, strerror(errno));
128 if (nofaxgetty) {
129 /*
130 * No faxgetty process, contact faxq directly and emulate
131 * what faxgetty would send.
132 */
133 fifo = open(FAX_FIFO, O_WRONLY|O_NDELAY);
134 if (fifo < 0) {
135 fatal("%s: open: %s", FAX_FIFO, strerror(errno));
136 }
137 cmdlen = snprintf(cmd, sizeof(cmd), "+%s:%s", devid, arg);
138 if (cmdlen < 0 || cmdlen >= sizeof(cmd) || write(fifo, cmd, cmdlen) != cmdlen) {
139 fatal("FIFO write failed for command (%s)", strerror(errno));
140 }
141 } else {
142 snprintf(fifoname, sizeof(fifoname), "%s.%.*s", FAX_FIFO,
143 sizeof (fifoname) - sizeof (FAX_FIFO), devid);
144 fifo = open(fifoname, O_WRONLY|O_NDELAY);
145 if (fifo < 0) {
146 fatal("%s: open: %s", fifoname, strerror(errno));
147 }
148 cmdlen = snprintf(cmd, sizeof(cmd), "S%s", arg);
149 if (cmdlen < 0 || cmdlen >= sizeof(cmd) || write(fifo, cmd, cmdlen) != cmdlen) {
150 fatal("FIFO write failed for command (%s)", strerror(errno));
151 }
152 }
153 (void) close(fifo);
154 return 0;
155 }
156