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

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: faxalter.c++,v 1.11 2009/09/29 11:46:01 faxguy Exp $ */
  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 "Sys.h"
  28. #include "config.h"
  29. extern int
  30. parseAtSyntax(const char* s, const struct tm& ref, struct tm& at0, fxStr& emsg);
  31. class faxAlterApp : public FaxClient {
  32. private:
  33.     bool groups; // group or job id's
  34.     fxStr script; // commands to send for each job
  35.     void usage();
  36. public:
  37.     faxAlterApp();
  38.     ~faxAlterApp();
  39.     int run(int argc, char** argv);
  40.     bool duplicate ();
  41. };
  42. faxAlterApp::faxAlterApp() { groups = false; }
  43. faxAlterApp::~faxAlterApp() {}
  44. bool faxAlterApp::duplicate ()
  45. {
  46.     /*
  47.      * Before we dup the job, we need to get the list of documents
  48.      * Documents are sent as continuations to the 213, like:
  49.      * -> JPARM document
  50.      * 213-PS docq/doc281.ps
  51.      * 213-PS docq/doc283.ps
  52.      * 213-PS docq/doc284.ps
  53.      * 213 End of documents.
  54.      */
  55.     command("JPARM document");
  56.     fxStr docs = getLastContinuation();
  57.     fxStr jid, gid, emsg;
  58.     if (! newJob(jid, gid, emsg) ) {
  59. printError("%s", (const char*) emsg);
  60. return false;
  61.     }
  62.     for ( u_int pos = 0, next; (next = docs.next(pos, 'n')) < docs.length(); )
  63.     {
  64. /*
  65.  * The document is in the form "<TYPE> <filename>"
  66.  * - separate it and resubmit the document
  67.  */
  68. fxStr tmp = docs.extract(pos, next-pos);
  69. int c = tmp.find(0, " ");
  70. if (c)
  71.     jobDocument(&tmp[c+1]);
  72. pos = next+1;
  73.     }
  74.     return true;
  75. }
  76. int
  77. faxAlterApp::run(int argc, char** argv)
  78. {
  79.     resetConfig();
  80.     readConfig(FAX_SYSCONF);
  81.     readConfig(FAX_USERCONF);
  82.     fxStr emsg;
  83.     time_t now = Sys::now();
  84.     struct tm tts = *localtime(&now);
  85.     struct tm when;
  86.     bool useadmin = false;
  87.     bool resubmit = false;
  88.     char *owner = NULL;
  89.     char *pass = NULL;
  90.     char *adminpass = NULL;
  91.     int c, rc = 0;
  92.     while ((c = Sys::getopt(argc, argv, "a:C:d:h:k:m:n:O:P:t:u:U:ADQRgprv")) != -1)
  93. switch (c) {
  94. case 'A': // connect with administrative privileges
  95.     useadmin = true;
  96.     break;
  97. case 'C': // a user-specified command
  98.     script.append(optarg);
  99.             script.append("n");
  100.     break;
  101. case 'D': // set notification to when done
  102.         script.append(groups ? "JGPARM " : "JPARM ");
  103.         script.append("NOTIFY DONEn");
  104.     break;
  105. case 'Q': // no notification (quiet)
  106.         script.append(groups ? "JGPARM " : "JPARM ");
  107.         script.append("NOTIFY DONEn");
  108.     break;
  109. case 'R': // set notification to when requeued
  110.         script.append(groups ? "JGPARM " : "JPARM ");
  111.         script.append("NOTIFY DONE+REQUEUEn");
  112.     break;
  113. case 'a': // send at specified time
  114.     if (strcasecmp(optarg, "NOW")) {
  115. if (!parseAtSyntax(optarg, *localtime(&now), tts, emsg)) {
  116.     printError("%s", (const char*) emsg);
  117.     return (1);
  118. }
  119. now = mktime(&tts);
  120. when = *gmtime(&now); // NB: must be relative to GMT
  121.         script.append(groups ? "JGPARM " : "JPARM ");
  122. script.append("SENDTIME ");
  123.             {
  124.                 fxStr tmpbuf = fxStr::format(
  125.                     "%d%02d%02d%02d%02d"
  126.             , when.tm_year+1900
  127.             , when.tm_mon+1
  128.             , when.tm_mday
  129.             , when.tm_hour
  130.             , when.tm_min
  131.         );
  132.                 script.append(tmpbuf);
  133.                 script.append("n");
  134.             }
  135.     } else {
  136.             script.append(groups ? "JGPARM " : "JPARM ");
  137.             script.append("SENDTIME NOWn");
  138.         }
  139.     break;
  140. case 'd': // destination number
  141.             script.append(groups ? "JGPARM " : "JPARM ");
  142.     script.append("EXTERNAL ");
  143.             script.append(optarg);
  144.             script.append("n");
  145.             script.append(groups ? "JGPARM " : "JPARM ");
  146.     script.append("DIALSTRING ");
  147.             script.append(optarg);
  148.             script.append("n");
  149.     break;
  150. case 'g': // apply to groups, not jobs
  151.     groups = true;
  152.     break;
  153. case 'h': // server's host
  154.     setHost(optarg);
  155.     break;
  156. case 'k': // kill job at specified time
  157.     if (!parseAtSyntax(optarg, tts, when, emsg)) {
  158. printError("%s", optarg, (const char*) emsg);
  159. return (1);
  160.     }
  161.     { time_t tv = mktime(&when) - now;
  162.           script.append(groups ? "JGPARM " : "JPARM ");
  163.       script.append("LASTTIME ");
  164.       fxStr tmpbuf = fxStr::format(
  165.              "%02d%02d%02d"
  166.      , tv/(24*60*60)
  167.      , (tv/(60*60))%24
  168.      , (tv/60)%60
  169.       );
  170.           script.append(tmpbuf);
  171.           script.append("n");
  172.     }
  173.     break;
  174. case 'm': // modem
  175.         script.append(groups ? "JGPARM " : "JPARM ");
  176.     script.append("MODEM ");
  177.         script.append(optarg);
  178.         script.append("n");
  179.     break;
  180. case 'n': // set notification
  181.         script.append(groups ? "JGPARM " : "JPARM ");
  182.     script.append("NOTIFY ");
  183. if (strcasecmp(optarg, "done") == 0) {
  184.             script.append("DONEn");
  185.         } else if (strcasecmp(optarg, "requeued") == 0) {
  186.             script.append("DONE+REQUEUEn");
  187.         } else {
  188.             script.append(optarg);
  189.             script.append("n");
  190.         }
  191.     break;
  192. case 'O':
  193.     readConfigItem(optarg);
  194.     break;
  195. case 'p': // send now (push)
  196.         script.append(groups ? "JGPARM " : "JPARM ");
  197.     script.append("SENDTIME NOWn");
  198.     break;
  199. case 'P': // scheduling priority
  200.     if ((u_int) atoi(optarg) > 255)
  201. fxFatal("Invalid job priority %s;"
  202.     " values must be in the range [0,255]", optarg);
  203.         script.append(groups ? "JGPARM " : "JPARM ");
  204.     script.append("SCHEDPRI ");
  205.     script.append(optarg);
  206.             script.append("n");
  207.     break;
  208. case 'r':
  209.     resubmit = true;
  210.     break;
  211. case 't': // set max number of retries
  212.     if (atoi(optarg) < 0)
  213. fxFatal("Bad number of retries for -t option: %s", optarg);
  214.         script.append(groups ? "JGPARM " : "JPARM ");
  215.     script.append("MAXDIALS ");
  216.     script.append(optarg);
  217.             script.append("n");
  218.     break;
  219. case 'u': // specify login
  220.     owner = optarg;
  221.     break;
  222. case 'U': // specify pass:adminpass
  223.     {
  224. char* pp = strchr(optarg, ':');
  225. if (pp && *(pp + 1) != '') {
  226.     *pp = '';
  227.     adminpass = pp + 1;
  228. }
  229.     }
  230.     pass = optarg;
  231.     break;
  232. case 'v': // trace protocol
  233.     setVerbose(true);
  234.     break;
  235. case '?':
  236.     usage();
  237. }
  238.     if (optind >= argc)
  239. usage();
  240.     if (script == "" && !resubmit)
  241. fxFatal("No job parameters specified for alteration.");
  242.     if (callServer(emsg)) {
  243. if (login(owner, pass, emsg) &&
  244.     (!useadmin || admin(adminpass, emsg))) {
  245.     for (; optind < argc; optind++) {
  246. const char* jobid = argv[optind];
  247. if (setCurrentJob(jobid)) {
  248.     /*
  249.      * We take the approach that if we can't do the work on a
  250.      * job, we continue on to the next
  251.      */
  252.     if (resubmit) {
  253. if (! duplicate()) {
  254.     rc = 3;
  255.     continue;
  256. }
  257. const char* old_job = jobid;
  258. jobid = getCurrentJob();
  259. printf("Job %s: duplicated as job %s.n", old_job, jobid);
  260.     } else if (! jobSuspend(jobid)) {
  261. emsg = getLastResponse();
  262. printError("%s", (const char*) emsg);
  263. rc = 3;
  264. continue;
  265.     }
  266.     if (!runScript(script, script.length(), "<stdin>", emsg)) {
  267. printError("%s", (const char*) emsg);
  268. rc = 3;
  269. continue;
  270.     }
  271.     if (!jobSubmit(jobid)) {
  272. emsg = getLastResponse();
  273. printError("%s", (const char*) emsg);
  274. rc = 3;
  275. continue;
  276.     }
  277.     printf("Job %s: done.n", jobid);
  278. } else {
  279.     emsg = getLastResponse();
  280.     printError("%s", (const char*) emsg);
  281.     rc = 3;
  282.     continue;
  283. }
  284.     }
  285. } else {
  286.     printError("%s", (const char*) emsg);
  287.     rc = 2;
  288. }
  289. hangupServer();
  290.     } else {
  291. printError("%s", (const char*) emsg);
  292. rc = 2;
  293.     }
  294.     return (rc);
  295. }
  296. void
  297. faxAlterApp::usage()
  298. {
  299.     fxFatal("usage: faxalter"
  300.       " [-h server-host]"
  301.       " [-a time]"
  302.       " [-C command]"
  303.       " [-d number]"
  304.       " [-k time]"
  305.       " [-m modem]"
  306.       " [-n notify]"
  307.       " [-P priority]"
  308.       " [-t tries]"
  309.       " [-u user]"
  310.       " [-U pass[:adminpass]]"
  311.       " [-A]"
  312.       " [-g]"
  313.       " [-p]"
  314.       " [-r]"
  315.       " [-v]"
  316.       " [-DQR]"
  317.       " jobID...");
  318. }
  319. int
  320. main(int argc, char** argv)
  321. {
  322.     faxAlterApp app;
  323.     return (app.run(argc, argv));
  324. }