sendpage.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:7k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: sendpage.c++,v 1.3 2009/09/29 11:46:02 faxguy Exp $ */
  2. /*
  3.  * Copyright (c) 1994-1996 Sam Leffler
  4.  * Copyright (c) 1994-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 "SNPPClient.h"
  27. #include "Sys.h"
  28. #include "config.h"
  29. #if HAS_LOCALE
  30. extern "C" {
  31. #include <locale.h>
  32. }
  33. #endif
  34. class sendPageApp : public SNPPClient {
  35. public:
  36. private:
  37.     fxStr appName; // for error messages
  38.     fxStr msgFile; // file containing any text
  39. protected:
  40.     void copyToTemporary(int fin, fxStr& tmpl);
  41.     void vprintError(const char* fmt, va_list ap);
  42.     void vprintWarning(const char* fmt, va_list ap);
  43.     void fatal(const char* fmt ...);
  44.     void usage();
  45. public:
  46.     sendPageApp();
  47.     ~sendPageApp();
  48.     bool run(int argc, char** argv);
  49. };
  50. sendPageApp::sendPageApp()
  51. {
  52.     setupConfig();
  53. }
  54. sendPageApp::~sendPageApp()
  55. {
  56.     if (msgFile != "")
  57. Sys::unlink(msgFile);
  58. }
  59. bool
  60. sendPageApp::run(int argc, char** argv)
  61. {
  62.     extern int optind;
  63.     extern char* optarg;
  64.     int c;
  65.     appName = argv[0];
  66.     u_int l = appName.length();
  67.     appName = appName.tokenR(l, '/');
  68.     resetConfig();
  69.     readConfig(FAX_SYSCONF);
  70.     readConfig(FAX_LIBDATA "/sendpage.conf");
  71.     readConfig(FAX_USERCONF);
  72.     fxStr emsg;
  73.     bool noText = false; // default is to assume message text
  74.     SNPPJob& proto = getProtoJob();
  75.     while ((c = Sys::getopt(argc, argv, "a:De:f:h:i:I:l:nNO:p:qRs:t:T:v")) != -1)
  76. switch (c) {
  77. case 'a': // time at which to transmit page
  78.     if (!proto.setHoldTime(optarg, emsg)) {
  79. printError("Invalid hold time "%s": %s",
  80.     optarg, (const char*) emsg);
  81. exit(-1);
  82.     }
  83.     break;
  84. case 'D': // notify when done
  85.     proto.setNotification("when done");
  86.     break;
  87. case 'f': // sender's identity
  88.     setFromIdentity(optarg);
  89.     break;
  90. case 'h': // server's host
  91.     setHost(optarg);
  92.     break;
  93. case 's': // user-specified job identifier
  94.     proto.setSubject(optarg);
  95.     break;
  96. case 'I': // fixed retry time
  97.     proto.setRetryTime(atoi(optarg));
  98.     break;
  99. case 'l': // service level
  100.     proto.setServiceLevel(atoi(optarg));
  101.     break;
  102. case 'n': // numeric-only page, no message text
  103.     noText = true;
  104.     break;
  105. case 'N': // no notification
  106.     proto.setNotification("none");
  107.     break;
  108. case 'O':
  109.     readConfigItem(optarg);
  110.     break;
  111. case 'p': // PIN
  112.     addJob().setPIN(optarg);
  113.     break;
  114. case 'q': // queue job and don't wait
  115.     proto.setQueued(true);
  116.     break;
  117. case 'R': // notify when requeued or done
  118.     proto.setNotification("when requeued");
  119.     break;
  120. case 't': // times to try sending
  121.     proto.setMaxTries(atoi(optarg));
  122.     break;
  123. case 'T': // times to dial telephone
  124.     proto.setMaxDials(atoi(optarg));
  125.     break;
  126. case 'v': // client-server protocol tracing
  127.     setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
  128.     setVerbose(true);
  129.     break;
  130. case '?':
  131.     usage();
  132.     /*NOTREACHED*/
  133. }
  134.     if (getNumberOfJobs() == 0) {
  135. fprintf(stderr, "%s: No pager identification number (PIN) specified.n",
  136.     (const char*) appName);
  137. usage();
  138.     }
  139.     if (!noText) { // collect message text ...
  140. if (optind < argc) { // ... from command line
  141.     fxStr msg;
  142.     for (; optind < argc; optind++) {
  143. if (msg.length() > 0)
  144.     msg.append(' ');
  145. msg.append(argv[optind]);
  146.     }
  147.     setPagerMsg(msg);
  148. } else { // ... from standard input
  149.     copyToTemporary(fileno(stdin), msgFile);
  150.     setPagerMsgFile(msgFile);
  151. }
  152.     }
  153.     bool status = false;
  154.     if (callServer(emsg)) {
  155. status = login(NULL, NULL, emsg)
  156.       && prepareForJobSubmissions(emsg)
  157.       && submitJobs(emsg);
  158. hangupServer();
  159.     }
  160.     if (!status)
  161. printError("%s", (const char*) emsg);
  162.     return (status);
  163. }
  164. void
  165. sendPageApp::usage()
  166. {
  167.     fxFatal("usage: %s"
  168. " -p PIN [-p PIN ...]n"
  169. " [-a time-to-send]"
  170. " [-l service-level]"
  171. " [-s message-subject]n"
  172. "    "
  173. " [-h host[:modem]]"
  174. " [-f from]n"
  175. "    "
  176. " [-I retry-time]"
  177. " [-t max-tries]"
  178. " [-T max-dials]"
  179. " [-nqvDNR]"
  180. " [msgs ...]",
  181. (const char*) appName);
  182. }
  183. /*
  184.  * Copy data from fin to a temporary file.
  185.  */
  186. void
  187. sendPageApp::copyToTemporary(int fin, fxStr& tmpl)
  188. {
  189.     const char* templ = _PATH_TMP "/sndpageXXXXXX";
  190.     char* buff = strcpy(new char[strlen(templ) + 1], templ);
  191.     int fd = Sys::mkstemp(buff);
  192.     tmpl = buff;
  193.     delete [] buff;
  194.     if (fd >= 0) {
  195. int cc;
  196. char buf[16*1024];
  197.     while ((cc = Sys::read(fin, buf, sizeof (buf))) > 0) {
  198.         if (Sys::write(fd, buf, cc) != cc) {
  199.             Sys::unlink(tmpl);
  200.             fatal("%s: write error", (const char*) tmpl);
  201.         }
  202.     }
  203. Sys::close(fd);
  204.     } else
  205. fatal("%s: Can not create temporary file", (const char*) tmpl);
  206. }
  207. void
  208. sendPageApp::vprintError(const char* fmt, va_list ap)
  209. {
  210.     fprintf(stderr, "%s: ", (const char*) appName);
  211.     SNPPClient::vprintError(fmt, ap);
  212. }
  213. void
  214. sendPageApp::vprintWarning(const char* fmt, va_list ap)
  215. {
  216.     fprintf(stderr, "%s: ", (const char*) appName);
  217.     SNPPClient::vprintWarning(fmt, ap);
  218. }
  219. #include <signal.h>
  220. static sendPageApp* app = NULL;
  221. static void
  222. cleanup()
  223. {
  224.     sendPageApp* a = app;
  225.     app = NULL;
  226.     delete a;
  227. }
  228. static void
  229. sigDone(int)
  230. {
  231.     cleanup();
  232.     exit(-1);
  233. }
  234. int
  235. main(int argc, char** argv)
  236. {
  237. #ifdef LC_CTYPE
  238.     setlocale(LC_CTYPE, ""); // for <ctype.h> calls
  239. #endif
  240. #ifdef LC_TIME
  241.     setlocale(LC_TIME, ""); // for strftime calls
  242. #endif
  243.     signal(SIGHUP, fxSIGHANDLER(sigDone));
  244.     signal(SIGINT, fxSIGHANDLER(sigDone));
  245.     signal(SIGTERM, fxSIGHANDLER(sigDone));
  246.     signal(SIGCHLD, fxSIGHANDLER(SIG_DFL));    // by YC
  247.     app = new sendPageApp;
  248.     if (!app->run(argc, argv))
  249. sigDone(0);
  250.     signal(SIGHUP, fxSIGHANDLER(SIG_IGN));
  251.     signal(SIGINT, fxSIGHANDLER(SIG_IGN));
  252.     signal(SIGTERM, fxSIGHANDLER(SIG_IGN));
  253.     cleanup();
  254.     return (0);
  255. }
  256. static void
  257. vfatal(FILE* fd, const char* fmt, va_list ap)
  258. {
  259.     vfprintf(fd, fmt, ap);
  260.     va_end(ap); //???
  261.     fputs(".n", fd);
  262.     sigDone(0);
  263. }
  264. void
  265. fxFatal(const char* va_alist ...)
  266. #define fmt va_alist
  267. {
  268.     va_list ap;
  269.     va_start(ap, fmt);
  270.     vfatal(stderr, fmt, ap);
  271.     /*NOTREACHED*/
  272. }
  273. #undef fmt
  274. void
  275. sendPageApp::fatal(const char* va_alist ...)
  276. #define fmt va_alist
  277. {
  278.     fprintf(stderr, "%s: ", (const char*) appName);
  279.     va_list ap;
  280.     va_start(ap, fmt);
  281.     vfatal(stderr, fmt, ap);
  282.     /*NOTREACHED*/
  283. }
  284. #undef fmt