📄 jobs.c++
字号:
return; } state &= ~S_LOGTRIG; // just process events if (newTrigger(emsg, "J<%s>%04x", jobid, 1<<Trigger::JOB_DEAD)) { // XXX is lreply the right thing? lreply(216, "Waiting for job %s; use ABOR command to interrupt.", jobid); if (setjmp(urgcatch) == 0) { Dispatcher& disp = Dispatcher::instance(); for (state |= S_WAITTRIG; IS(WAITTRIG); disp.dispatch()) { /* * The trigger event handlers update our notion * of the job state asynchronously so we can just * monitor the job's state variable. Beware however * that the job may get removed/moved to the doneq * while we're monitoring its status; so we cannot * blindly hold a reference to the in-memory structure. */ job = findJob(jobid, emsg); if (!job || job->state == FaxRequest::state_done || job->state == FaxRequest::state_failed) break; } reply(216, "Wait for job %s completed.", jobid); } state &= ~S_WAITTRIG; (void) cancelTrigger(emsg); } else reply(504, "Cannot register trigger: %s.", (const char*) emsg); } else reply(500, "Cannot wait for job %s; %s.", jobid, (const char*) emsg);}/* * Do common work used in adding a document to a * job's set of documents that are to be sent. */boolHylaFAXServer::checkAddDocument(Job& job, Token type, const char* docname, FaxSendOp& op){ if (checkParm(job, type, A_WRITE)) { struct stat sb; if (!fileAccess(docname, R_OK, sb)) perror_reply(550, docname, errno); else if (!docType(docname, op)) reply(550, "%s: Document type not recognized.", docname); else return (true); } return (false);}/* * Add a cover document to the current job's * set of documents that are to be sent. */voidHylaFAXServer::addCoverDocument(Job& job, const char* docname){ FaxSendOp op; if (checkAddDocument(job, T_COVER, docname, op)) { fxStr covername = "/" FAX_DOCDIR "/cover" | job.jobid | ".cover"; if (Sys::link(docname, covername) >= 0) { // XXX mark as cover page job.items.append(FaxItem(op, 0, "", &covername[1])); reply(200, "Added cover page document %s as %s.", docname, &covername[1]); job.pagehandling = ""; // force recalculation } else reply(550, "Unable to link cover page document %s to %s: %s.", docname, (const char*) covername, strerror(errno)); }}/* * Add a non-cover document to the current * job's set of documents that are to be sent. */voidHylaFAXServer::addDocument(Job& job, const char* docname){ FaxSendOp op; if (checkAddDocument(job, T_DOCUMENT, docname, op)) { const char* cp = strrchr(docname, '/'); if (!cp) // relative name, e.g. doc123 cp = docname; fxStr document = fxStr::format("/" FAX_DOCDIR "%s.", cp) | job.jobid; if (Sys::link(docname, document) >= 0) { job.items.append(FaxItem(op, 0, "", &document[1])); reply(200, "Added document %s as %s.", docname, &document[1]); job.pagehandling = ""; // force recalculation } else reply(550, "Unable to link document %s to %s: %s.", docname, (const char*) document, strerror(errno)); }}/* * Add a polling operation to the current job. */voidHylaFAXServer::addPollOp(Job& job, const char* sep, const char* pwd){ if (checkParm(job, T_POLL, A_WRITE)) { job.items.append(FaxItem(FaxRequest::send_poll, 0, sep, pwd)); reply(200, "Added poll operation."); }}/* * Directory interface support for querying job status. */boolHylaFAXServer::isVisibleSendQFile(const char* filename, const struct stat&){ if (filename[0] == 'q') { fxStr emsg; Job* job = findJob(&filename[1], emsg); if (job && checkAccess(*job, T_JOB, A_READ)) return true; } return false;}#ifdef roundup#undef roundup#endif#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))/* * Return a compact notation for the specified * time. This notation is guaranteed to fit in * a 7-character field. We select one of 5 * representations based on how close the time * is to ``now''. */const char*HylaFAXServer::compactTime(time_t t){ time_t now = Sys::now(); if (t > now) { // already past static char buf[15]; const struct tm* tm = cvtTime(t); if (t < roundup(now, 24*60*60)) // today, use 19:37 strftime(buf, sizeof (buf), "%H:%M", tm); else if (t < now+7*24*60*60) // within a week, use Sun 6pm strftime(buf, sizeof (buf), "%a%I%p", tm); else // over a week, use 25Dec95 strftime(buf, sizeof (buf), "%d%b%y", tm); return (buf); } else return ("");}static const char jformat[] = { 's', // A (subaddr) 's', // B (passwd) 's', // C (company) 's', // D (totdials & maxdials) 'u', // E (desiredbr) 's', // F (tagline) 'u', // G (desiredst) 'u', // H (desireddf) 'u', // I (usrpri) 's', // J (jobtag) 'c', // K (desiredec as symbol) 's', // L (location) 's', // M (mailaddr) 'c', // N (desiredtl as symbol) 'c', // O (useccover as symbol) 's', // P (npages & total pages) 'u', // Q (minbr) 's', // R (receiver) 's', // S (sender) 's', // T (tottries & maxtries) 's', // U (chopthreshold) 's', // V (doneop) 's', // W (commid) 'c', // X (jobtype as symbol)#ifdef OLDPROTO_SUPPORT 's', // Y (tts in strftime %Y/%m/%d %H.%M.%S format) 'u', // Z (tts as decimal time_t)#else 'Y', // Y 'Z', // Z#endif '[', // [ '\\', // \ (must have something after the backslash) ']', // ] '^', // ^ '_', // _ '`', // ` 'c', // a (state as symbol) 'u', // b (ntries) 's', // c (client) 'u', // d (totdials) 's', // e (external) 'u', // f (ndials) 's', // g (groupid) 'c', // h (pagechop as symbol) 'u', // i (pri) 's', // j (jobid) 's', // k (killtime) 'u', // l (pagelength) 's', // m (modem) 'c', // n (notify as symbol) 's', // o (owner) 'u', // p (npages) 's', // q (retrytime) 'u', // r (resolution) 's', // s (notice a.k.a. status) 'u', // t (tottries) 'u', // u (maxtries) 's', // v (number a.k.a dialstring) 'u', // w (pagewidth) 'u', // x (maxdials) 'u', // y (total pages) 's', // z (tts) 'c', // 0 (usexvres as symbol)};/* * Print a formatted string with fields filled in from * the specified job's state. This functionality is * used to permit clients to get job state listings in * preferred formats. */voidHylaFAXServer::Jprintf(FILE* fd, const char* fmt, const Job& job){ /* * Check once to see if the client has access to * privileged job state. This typically is not * needed but doing it here eliminates the need to * do more work below (and the check should be fast). * * NB: This assumes that read access to T_DIALSTRING * implies read access to anything else in the * job state that is protected. */ bool haveAccess = checkAccess(job, T_DIALSTRING, A_READ); for (const char* cp = fmt; *cp; cp++) { if (*cp == '%') {#define MAXSPEC 20 char fspec[MAXSPEC]; char* fp = fspec; *fp++ = '%'; char c = *++cp; if (c == '-') *fp++ = c, c = *++cp; if (isdigit(c)) { do { *fp++ = c; } while (isdigit(c = *++cp) && fp < &fspec[MAXSPEC-3]); } if (c == '.') { do { *fp++ = c; } while (isdigit(c = *++cp) && fp < &fspec[MAXSPEC-2]); } if (!isalpha(c)) { if (c == '%') // %% -> % putc(c, fd); else fprintf(fd, "%.*s%c", fp-fspec, fspec, c); continue; } fp[0] = jformat[c-'A']; // printf format string fp[1] = '\0'; switch (c) { case 'A': fprintf(fd, fspec, (const char*) job.subaddr); break; case 'B': fprintf(fd, fspec, haveAccess ? (const char*) job.passwd : ""); break; case 'C': fprintf(fd, fspec, (const char*) job.company); break; case 'D': fprintf(fd, fspec, (const char*)fxStr::format("%2u:%-2u", job.totdials, job.maxdials)); break; case 'E': fprintf(fd, fspec, job.desiredbr); break; case 'F': fprintf(fd, fspec, (const char*) job.tagline); break; case 'G': fprintf(fd, fspec, job.desiredst); break; case 'H': fprintf(fd, fspec, job.desireddf); break; case 'I': fprintf(fd, fspec, job.usrpri); break; case 'J': fprintf(fd, fspec, (const char*) job.jobtag); break; case 'K': fprintf(fd, fspec, "D HF"[job.desiredec]); break; case 'L': fprintf(fd, fspec, (const char*) job.location); break; case 'M': fprintf(fd, fspec, (const char*) job.mailaddr); break; case 'N': fprintf(fd, fspec, " P"[job.desiredtl]); break; case 'O': fprintf(fd, fspec, "N "[job.useccover]); break; case 'P': fprintf(fd, fspec, (const char*)fxStr::format("%2u:%-2u", job.npages, job.totpages)); break; case 'Q': fprintf(fd, fspec, job.minbr); break; case 'R': fprintf(fd, fspec, (const char*) job.receiver); break; case 'S': fprintf(fd, fspec, (const char*) job.sender); break; case 'T': fprintf(fd, fspec, (const char*)fxStr::format("%2u:%-2u", job.tottries, job.maxtries)); break; case 'U': fprintf(fd, fspec, (const char*)fxStr::format("%.1f", job.chopthreshold)); break; case 'V': fprintf(fd, fspec, (const char*) job.doneop); break; case 'W': fprintf(fd, fspec, (const char*) job.commid); break; case 'X': fprintf(fd, fspec, toupper(job.jobtype[0])); break; case 'Y': { char buf[30]; // XXX HP C++ strftime(buf, sizeof (buf), "%Y/%m/%d %H.%M.%S", IS(USEGMT) ? gmtime(&job.tts) : localtime(&job.tts)); fprintf(fd, fspec, buf); } break; case 'Z': fprintf(fd, fspec, job.tts); break; case 'a': fprintf(fd, fspec, "?TPSBWRDF"[job.state]); break; case 'b': fprintf(fd, fspec, job.ntries); break; case 'c': fprintf(fd, fspec, (const char*) job.client); break; case 'd': fprintf(fd, fspec, job.totdials); break; case 'e': fprintf(fd, fspec, (const char*) job.external); break; case 'f': fprintf(fd, fspec, job.ndials); break; case 'g': fprintf(fd, fspec, (const char*) job.groupid); break; case 'h': fprintf(fd, fspec, " DAL"[job.pagechop]); break; case 'i': fprintf(fd, fspec, job.pri); break; case 'j': fprintf(fd, fspec, (const char*) job.jobid); break; case 'k': fprintf(fd, fspec, compactTime(job.killtime)); break; case 'l': fprintf(fd, fspec, job.pagelength); break; case 'm': fprintf(fd, fspec, (const char*) job.modem); break; case 'n': fprintf(fd, fspec, " DQA"[job.notify]); break; case 'o': fprintf(fd, fspec, (const char*) job.owner); break; case 'p': fprintf(fd, fspec, job.npages); break; case 'q': fprintf(fd, fspec, job.retrytime == 0 ? "" : fmtTime(job.retrytime)); break; case 'r': fprintf(fd, fspec, job.resolution); break; case 's': fprintf(fd, fspec, (const char*) job.notice); break; case 't': fprintf(fd, fspec, job.tottries); break; case 'u': fprintf(fd, fspec, job.maxtries); break; case 'v': fprintf(fd, fspec, haveAccess ? (const char*) job.number : ""); break; case 'w': fprintf(fd, fspec, job.pagewidth); break; case 'x': fprintf(fd, fspec, job.maxdials); break; case 'y': fprintf(fd, fspec, job.totpages); break; case 'z': fprintf(fd, fspec, compactTime(job.tts)); break; case '0': fprintf(fd, fspec, "N "[job.usexvres]); break; } } else putc(*cp, fd); }}voidHylaFAXServer::listSendQ(FILE* fd, const SpoolDir&, DIR* dir){ struct dirent* dp; while ((dp = readdir(dir))) if (dp->d_name[0] == 'q') { fxStr emsg; Job* job = findJob(&dp->d_name[1], emsg); if (job) { Jprintf(fd, jobFormat, *job); fputs("\r\n", fd); } }}voidHylaFAXServer::listSendQFile(FILE* fd, const SpoolDir& dir, const char* filename, const struct stat& sb){ fxStr emsg; Job* job = findJob(filename, emsg); if (job) Jprintf(fd, jobFormat, *job); else listUnixFile(fd, dir, filename, sb);}voidHylaFAXServer::nlstSendQ(FILE* fd, const SpoolDir&, DIR* dir){ struct dirent* dp; while ((dp = readdir(dir))) if (dp->d_name[0] == 'q') { fxStr emsg; Job* job = findJob(&dp->d_name[1], emsg); if (job) Jprintf(fd, "%j\r\n", *job); }}voidHylaFAXServer::nlstSendQFile(FILE* fd, const SpoolDir&, const char* filename, const struct stat&){ fxStr emsg; Job* job = findJob(filename, emsg); if (job) Jprintf(fd, "%j", *job); else fprintf(fd, "%s", filename);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -