1 /* $Id$ */
2 /*
3 * Copyright (c) 1990-1996 Sam Leffler
4 * Copyright (c) 1991-1996 Silicon Graphics, Inc.
5 * HylaFAX is a trademark of Silicon Graphics
6 *
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
14 *
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 *
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 * OF THIS SOFTWARE.
25 */
26 #include "FaxClient.h"
27 #include "StrArray.h"
28 #include "Sys.h"
29 #include "NLS.h"
30 #include "config.h"
31
32 #include <errno.h>
33
34 class faxStatApp : public FaxClient {
35 private:
36 fxStr header;
37
38 bool listWithHeader(const fxStr& dir, fxStr& emsg);
39 public:
40 faxStatApp();
41 ~faxStatApp();
42
43 void run(int argc, char** argv);
44 };
faxStatApp()45 faxStatApp::faxStatApp() {}
~faxStatApp()46 faxStatApp::~faxStatApp() {}
47
48 static bool
writeStdout(int,const char * buf,int cc,fxStr &)49 writeStdout(int, const char* buf, int cc, fxStr&)
50 {
51 (void) Sys::write(STDOUT_FILENO, buf, cc);
52 return (true);
53 }
54
55 void
run(int argc,char ** argv)56 faxStatApp::run(int argc, char** argv)
57 {
58 resetConfig();
59 readConfig(FAX_SYSCONF);
60 readConfig(FAX_USERCONF);
61
62 fxStrArray dirs;
63 dirs.append(FAX_STATUSDIR); // server status
64 bool checkInfo = false;
65 int c;
66 while ((c = Sys::getopt(argc, argv, "h:adgfilrsv")) != -1)
67 switch (c) {
68 case 'a': // display archived jobs
69 dirs.append(FAX_ARCHDIR);
70 break;
71 case 'd': // display jobs in done queue
72 dirs.append(FAX_DONEDIR);
73 break;
74 case 'f': // display queued documents
75 dirs.append(FAX_DOCDIR);
76 break;
77 case 'g': // use GMT for dates & times
78 setTimeZone(TZ_GMT);
79 break;
80 case 'h': // server's host
81 setHost(optarg);
82 break;
83 case 'i': // display any.info file
84 checkInfo = true;
85 break;
86 case 'l': // use local timezone for dates & times
87 setTimeZone(TZ_LOCAL);
88 break;
89 case 'r': // display receive queue
90 dirs.append(FAX_RECVDIR);
91 break;
92 case 's': // display jobs in send queue
93 dirs.append(FAX_SENDDIR);
94 break;
95 case 'v': // enable protocol tracing
96 setVerbose(true);
97 break;
98 case '?':
99 fxFatal(_("usage: faxstat [-h server-host] [-adfgilrsv]"));
100 }
101 fxStr emsg;
102 if (callServer(emsg)) {
103 if (login(NULL, emsg)) {
104 if (checkInfo)
105 (void) recvData(writeStdout, 0, emsg, 0,
106 "RETR " FAX_STATUSDIR "/any." FAX_INFOSUF);
107 for (u_int i = 0, n = dirs.length(); i < n; i++) {
108 header = (i > 0 ? "\n" : "");
109 if (dirs[i] == FAX_SENDDIR || dirs[i] == FAX_DONEDIR) {
110 getJobStatusHeader(header);
111 header.append('\n');
112 } else if (dirs[i] == FAX_RECVDIR) {
113 getRecvStatusHeader(header);
114 header.append('\n');
115 } else if (dirs[i] == FAX_STATUSDIR) {
116 fxStr notused;
117 getModemStatusHeader(notused);
118 }
119 if (!listWithHeader(dirs[i], emsg))
120 break;
121 }
122 }
123 hangupServer();
124 }
125 if (emsg != "")
126 printError("%s", (const char*) emsg);
127 }
128
129 bool
listWithHeader(const fxStr & dir,fxStr & emsg)130 faxStatApp::listWithHeader(const fxStr& dir, fxStr& emsg)
131 {
132 if (!setMode(MODE_S))
133 goto bad;
134 if (!initDataConn(emsg))
135 goto bad;
136 if (command("LIST " | dir) != PRELIM)
137 goto bad;
138 if (!openDataConn(emsg))
139 goto bad;
140 u_long byte_count; byte_count = 0; // XXX for __GNUC__
141 for (;;) {
142 char buf[16*1024];
143 int cc = read(getDataFd(), buf, sizeof (buf));
144 if (cc == 0) {
145 closeDataConn();
146 return (getReply(false) == COMPLETE);
147 }
148 if (cc < 0) {
149 emsg = fxStr::format(_("Data Connection: %s"), strerror(errno));
150 (void) getReply(false);
151 break;
152 }
153 if (byte_count == 0 && header.length() > 0)
154 (void) Sys::write(STDOUT_FILENO, header, header.length());
155 byte_count += cc;
156 (void) Sys::write(STDOUT_FILENO, buf, cc);
157 }
158 bad:
159 closeDataConn();
160 return (false);
161 }
162
163 int
main(int argc,char ** argv)164 main(int argc, char** argv)
165 {
166 NLS::Setup("hylafax-client");
167 faxStatApp app;
168 app.run(argc, argv);
169 return 0;
170 }
171