📄 oldprotocol.c++
字号:
// purge links that will never get used do { const FaxItem& fitem = reqs[--i]; switch (fitem.op) { case FaxRequest::send_tiff: case FaxRequest::send_pdf: case FaxRequest::send_postscript: case FaxRequest::send_pcl: Sys::unlink(fitem.item); break; } } while (i != 0); dologout(1); /*NOTREACHED*/ } curJob->items.append(FaxItem(fitem.op, 0, "", &doc[1])); } else curJob->items.append(fitem); }}const char*OldProtocolServer::fileDesc(FaxSendOp type){ return type == FaxRequest::send_tiff ? "TIFF image" : type == FaxRequest::send_postscript ? "PostScript document" : "opaque data" ;}fxStrOldProtocolServer::dataTemplate(FaxSendOp type, int& dfd){ fxStr emsg; u_int seqnum = getDocumentNumber(emsg); if (seqnum == (u_int) -1) sendAndLogError("Could not create data temp file: %s.", (const char*) emsg); fxStr templ = fxStr::format("/" FAX_TMPDIR "/doc%u%s" , seqnum , type == FaxRequest::send_tiff ? ".tif" : type == FaxRequest::send_postscript ? ".ps" : type == FaxRequest::send_pdf ? ".pdf": "" ); dfd = Sys::open(templ, O_RDWR|O_CREAT|O_EXCL, 0660); if (dfd < 0) sendAndLogError("Could not create data temp file %s: %s.", (const char*) templ, strerror(errno)); tempFiles.append(templ); reqs.append(FaxItem(type, 0, "", templ)); return (templ);}voidOldProtocolServer::getData(FaxSendOp type, long cc){ if (cc > 0) { int dfd; fxStr templ = dataTemplate(type, dfd); long total = 0; while (cc > 0) { char buf[4096]; long n = fxmin(cc, (u_long) sizeof (buf)); if (fread(buf, (size_t) n, 1, stdin) != 1) protocolBotch("not enough data received: %u of %u bytes.", total, total+cc); if (Sys::write(dfd, buf, (u_int) n) != n) sendAndLogError("Error writing data file: %s.", strerror(errno)); cc -= n; total += n; } Sys::close(dfd); if (TRACE(PROTOCOL)) logDebug(templ | ": %ld-byte %s", total, fileDesc(type)); }}voidOldProtocolServer::getLZWData(FaxSendOp type, long cc){ if (cc > 0) { int dfd; fxStr templ = dataTemplate(type, dfd); FILE* fout = fdopen(dfd, "w"); setupLZW(); long total = decodeLZW(stdin, fout); if (total != cc) protocolBotch("not enough data received: expected %u, got %u.", cc, total); if (fflush(fout) != 0) sendAndLogError("Error writing data file: %s.", strerror(errno)); fclose(fout); if (TRACE(PROTOCOL)) logDebug(templ | ": %ld-byte compressed %s", cc, fileDesc(type)); }}#define MAXCODE(n) ((1L<<(n))-1)#define BITS_MIN 9 /* start with 9 bits */#define BITS_MAX 13 /* max of 13 bit strings */#define CSIZE (MAXCODE(BITS_MAX)+1)/* predefined codes */#define CODE_CLEAR 0 /* code to clear string table */#define CODE_EOI 1 /* end-of-information code */#define CODE_FIRST 256 /* first free code entry */#define CODE_MAX MAXCODE(BITS_MAX)typedef u_short hcode_t; /* codes fit in 16 bits */typedef struct code_ent { code_ent* next; u_short length; /* string len, including this token */ u_char value; /* data value */ u_char firstchar; /* first token of string */} code_t;voidOldProtocolServer::setupLZW(){ if (codetab == NULL) { codetab = new code_t[CSIZE]; for (int code = CODE_FIRST-1; code > CODE_EOI; code--) { codetab[code].value = code; codetab[code].firstchar = code; codetab[code].length = 1; codetab[code].next = NULL; } }}/* * Decode a "hunk of data". */#define GetNextCode(fin, code) { \ nextdata = (nextdata<<8) | getc(fin); \ if ((nextbits += 8) < nbits) { \ nextdata = (nextdata<<8) | getc(fin); \ nextbits += 8; \ } \ code = (hcode_t)((nextdata >> (nextbits-nbits))&nbitsmask); \ nextbits -= nbits; \}longOldProtocolServer::decodeLZW(FILE* fin, FILE* fout){ u_int nbits = BITS_MIN; u_int nextbits = 0; u_long nextdata = 0; u_long nbitsmask = MAXCODE(BITS_MIN); code_t* freep = &codetab[CODE_FIRST]; code_t* oldcodep = codetab-1; code_t* maxcodep = &codetab[nbitsmask-1]; long total = 0; for (;;) { hcode_t code; code_t* codep; GetNextCode(fin, code); if (code == CODE_EOI) return (total); if (code == CODE_CLEAR) { freep = &codetab[CODE_FIRST]; nbits = BITS_MIN; nbitsmask = MAXCODE(BITS_MIN); maxcodep = &codetab[nbitsmask-1]; GetNextCode(fin, code); if (code == CODE_EOI) return (total); putc(code, fout); total++; oldcodep = &codetab[code]; continue; } codep = &codetab[code]; /* * Add the new entry to the code table. */ freep->next = oldcodep; freep->firstchar = freep->next->firstchar; freep->length = freep->next->length+1; freep->value = (codep < freep) ? codep->firstchar : freep->firstchar; if (++freep > maxcodep) { nbits++; if (nbits > BITS_MAX) { protocolBotch("LZW code length overflow %s", "(invalid compressed data)"); /*NOTREACHED*/ } nbitsmask = MAXCODE(nbits); maxcodep = &codetab[nbitsmask-1]; } oldcodep = codep; if (code >= CODE_FIRST) { /* * Code maps to a string, copy string * value to output (written in reverse). */ char buf[1024]; u_int len = codep->length; char* tp = (len > sizeof (buf) ? (char*) malloc(len) : buf) + len; do { *--tp = codep->value; } while ((codep = codep->next)); fwrite(tp, len, 1, fout); total += len; if (tp != buf) free(tp); } else { putc(code, fout); total++; } }#ifdef notdef protocolBotch("not enough data received: out of data before EOI.");#endif /*NOTREACHED*/}void OldProtocolServer::getTIFFData(const char* tag) { getData(FaxRequest::send_tiff, atol(tag)); }void OldProtocolServer::getPostScriptData(const char* tag) { getData(FaxRequest::send_postscript, atol(tag)); }void OldProtocolServer::getOpaqueData(const char* tag) { getData(FaxRequest::send_data, atol(tag)); }void OldProtocolServer::getZPostScriptData(const char* tag) { getLZWData(FaxRequest::send_postscript, atol(tag)); }void OldProtocolServer::getZOpaqueData(const char* tag) { getLZWData(FaxRequest::send_data, atol(tag)); }voidOldProtocolServer::dologout(int status){ if (status != 0) { Sys::unlink(fxStr::format(FAX_DOCDIR "/doc%s.cover", (const char*) curJob->jobid)); if (curJob->qfile != "") Sys::unlink(curJob->qfile); } HylaFAXServer::dologout(status);}/* * Status support. */static voidgetConfig(const char* fileName, fxStr& number){ FILE* fd = fopen(fileName, "r"); if (fd != NULL) { char line[1024]; while (fgets(line, sizeof (line)-1, fd) != NULL) { char* cp = strchr(line, '#'); if (!cp) cp = strchr(line, '\n'); if (cp) *cp = '\0'; cp = strchr(line, ':'); if (cp) { for (*cp++ = '\0'; isspace(*cp); cp++) ; if (strcasecmp(line, "FAXNumber") == 0) { number = cp; break; } } } (void) fclose(fd); }}voidOldProtocolServer::sendServerStatus(const char*){ DIR* dir = opendir("."); if (!dir) sendAndLogError("Problem accessing spool directory: %s.", strerror(errno)); int fifo; if (version > 0) { Sys::close(fifo = Sys::open(FAX_FIFO, O_WRONLY|O_NDELAY)); sendClient("server", "all modems:" FAX_FIFO ":%s", fifo != -1 ? "Running" : "Not running"); } else sendClient("server", "all modems"); /* * Setup a prefix for matching potential FIFO files. */ fxStr match(FAX_FIFO "."); if (modem != MODEM_ANY) match.append(modem); struct dirent* dp; while ((dp = readdir(dir)) != 0) { if (strncmp(dp->d_name, match, match.length()) != 0) continue; fifo = Sys::open(dp->d_name, O_WRONLY|O_NDELAY); if (fifo != -1) { Sys::close(fifo); const char* cp = strchr(dp->d_name, '.') + 1; fxStr faxNumber; getConfig(fxStr::format(FAX_CONFIG ".%s", cp), faxNumber); if (version > 0) { fxStr status; getServerStatus(fxStr::format(FAX_STATUSDIR "/%s", cp), status); fxStr modemName(cp); canonModem(modemName); sendClient("server", "%s:%s:%s" , (const char*) faxNumber , (const char*) modemName , (const char*) status ); } else sendClient("server", "%s", (const char*) faxNumber); } } (void) closedir(dir);}voidOldProtocolServer::sendServerInfo1(const char* name){ fxStr modemFile(name); modemFile.resize(modemFile.next(0, '.')); // discard ``.info'' canonModem(modemFile); FILE* fd = fopen(fxStr::format(FAX_STATUSDIR "/%s", name), "r"); if (fd != NULL) { char line[1024]; while (fgets(line, sizeof (line), fd) != NULL) { char* tp = strchr(line, '\n'); if (tp) *tp = '\0'; sendClient("serverInfo", "%s:%s", (const char*) modemFile, line); } fclose(fd); }}voidOldProtocolServer::sendServerInfo(const char*){ if (modem == MODEM_ANY) { DIR* dir = opendir(FAX_STATUSDIR); if (!dir) sendAndLogError("Problem accessing status directory: %s.", strerror(errno)); struct dirent* dp; while ((dp = readdir(dir)) != 0) { const char* cp = strrchr(dp->d_name, '.'); if (cp && strcmp(cp+1, FAX_INFOSUF) == 0) sendServerInfo1(dp->d_name); } (void) closedir(dir); } else sendServerInfo1(modem | "." | FAX_INFOSUF);}voidOldProtocolServer::sendClientJobStatus(const Job& job){ if (version > 0) { if (job.tts != 0) Jprintf(stdout, "jobStatus:%j:%S:%Y:%e:%m:%s\n", job); else Jprintf(stdout, "jobStatus:%j:%S:asap:%e:%m:%s\n", job); } else Jprintf(stdout, "jobStatus:%j:%S:%Z:%%e\n", job);}voidOldProtocolServer::sendClientJobLocked(const Job& job){ if (version > 0) Jprintf(stdout, "jobStatus:%j:%S:locked:%e:%m:%s\n", job); else Jprintf(stdout, "jobLocked:%j:%S:%e\n", job);}voidOldProtocolServer::sendJobStatus(Job& job){ if (lockJob(job, LOCK_SH|LOCK_NB)) { sendClientJobStatus(job); unlockJob(job); } else sendClientJobLocked(job);}boolOldProtocolServer::modemMatch(const fxStr& a, const fxStr& b){ return (a == MODEM_ANY || b == MODEM_ANY || a == b);}voidOldProtocolServer::sendAllStatus(const char*){ if (jobs.size() == 0) readJobs(); for (JobDictIter iter(jobs); iter.notDone(); iter++) { Job& job = *iter.value(); if (!modemMatch(modem, job.modem)) continue; sendJobStatus(job); }}voidOldProtocolServer::sendJobStatus(const char* jobid){ fxStr emsg; Job* job = findJob(jobid, emsg); if (job && modemMatch(modem, job->modem)) sendJobStatus(*job);}voidOldProtocolServer::sendUserStatus(const char* sender){ if (jobs.size() == 0) readJobs(); for (JobDictIter iter(jobs); iter.notDone(); iter++) { Job& job = *iter.value(); if (!modemMatch(modem, job.modem)) continue; if (lockJob(job, LOCK_SH|LOCK_NB)) { sendClientJobLocked(job); unlockJob(job); } else if (job.sender == sender) sendJobStatus(job); }}voidOldProtocolServer::sendRecvStatus(const char*){ DIR* dir = opendir(FAX_RECVDIR); if (dir == NULL) sendAndLogError("Can not access receive queue directory \"%s\".", FAX_RECVDIR); fxStr path(FAX_RECVDIR "/"); struct dirent* dp; while ((dp = readdir(dir))) { const char* name = dp->d_name; if (name[0] != 'f' || name[1] != 'a' || name[2] != 'x') continue; RecvInfo ri(path | name); if (getRecvDocStatus(ri)) { struct stat sb; // XXX required by Rprintf if (version > 0) Rprintf(stdout, "recvJob:%X:%w:%l:%r:%p:%Y:%s\n", ri, sb); else Rprintf(stdout, "recvJob:%X:%w:%l:%r:%p:%Z:%s\n", ri, sb); } } closedir(dir);}#endif /* OLDPROTO_SUPPORT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -