⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oldprotocol.c++

📁 fax相关的东西
💻 C++
📖 第 1 页 / 共 3 页
字号:
    fflush(stdout);}/* * General job manipulation support. */#include <pwd.h>boolOldProtocolServer::_checkUser(const char* requestor, struct passwd* pwd){    char buf[1024];    char* cp;    buf[0] = '\0';    if (pwd->pw_gecos) {	if (pwd->pw_gecos[0] == '&') {	    strcpy(buf, pwd->pw_name);	    strcat(buf, pwd->pw_gecos+1);	    if (islower(buf[0]))		buf[0] = toupper(buf[0]);	} else	    strcpy(buf, pwd->pw_gecos);	if ((cp = strchr(buf,',')) != 0)	    *cp = '\0';	/* see FaxClient::setupUserIdentity; strip SysV junk */	if ((cp = strchr(buf,'(')) != 0)	    *cp = '\0';    } else	strcpy(buf, pwd->pw_name);    if (TRACE(PROTOCOL)) {	if (*buf)	     logDebug("%s user: \"%s\"", pwd->pw_name, buf);	else	     logDebug("name of %s user unknown", pwd->pw_name);    }    return (strcmp(requestor, buf) == 0);}boolOldProtocolServer::isAdmin(const char* requestor){    static bool checked = false;    static bool isadmin = false;    if (!checked) {	struct passwd* pwd = getpwuid(getuid());	if (!pwd) {	    logError("getpwuid failed for uid %d: %m", getuid());	    pwd = getpwuid(geteuid());	}	if (!pwd) {	    logError("getpwuid failed for effective uid %d: %m", geteuid());	    isadmin = false;	}	isadmin = _checkUser(requestor, pwd);	if (!isadmin) {					/* not fax user */	    pwd = getpwnam("root");	    if (!pwd) {		logError("getpwnam failed for \"root\": %m");		isadmin = false;	    } else		isadmin = _checkUser(requestor, pwd);	/* root user */	}	checked = true;    }    return (isadmin);}voidOldProtocolServer::applyToJob(const char* tag, const char* op,    void (OldProtocolServer::*f)(Job&, const char*)){    char* requestor = (char *) strchr(tag, ':');    if (!requestor)	protocolBotch("no requestor name for \"%s\" command.", op);    *requestor++ = '\0';    char* arg = strchr(requestor, ':');    if (arg)	*arg++ = '\0';    fxStr emsg;    Job* job = findJob(tag, emsg);    if (job) {	/*	 * Validate requestor is permitted to do op to the	 * requested job.  We permit the person that submitted	 * the job, the fax user, and root.  Using the GECOS	 * field in doing the comparison is a crock, but not	 * something to change now--leave it for a protocol	 * redesign.	 */	if (job->sender == requestor || isAdmin(requestor)) {	    if (TRACE(PROTOCOL))		logDebug("%s request by %s for %s", op, requestor, tag);	    (this->*f)(*job, arg);	} else	    sendClient("jobOwner", tag);    } else	sendClient("notQueued", tag);}voidOldProtocolServer::applyToJobGroup(const char* tag, const char* op,    void (OldProtocolServer::*f)(Job&, const char*)){    char* requestor = (char *) strchr(tag, ':');    if (!requestor)	protocolBotch("no requestor name for \"%s\" command.", op);    *requestor++ = '\0';    char* arg = strchr(requestor, ':');    if (arg)	*arg++ = '\0';    if (jobs.size() == 0)	readJobs();    u_int jobsDone = 0;    u_int jobsSkipped = 0;    for (JobDictIter iter(jobs); iter.notDone(); iter++) {	Job& job = *iter.value();	if (job.groupid != tag)	    continue;	/*	 * Validate requestor is permitted to do op to the	 * requested job.  We permit the person that submitted	 * the job, the fax user, and root.  Using the GECOS	 * field in doing the comparison is a crock, but not	 * something to change now--leave it for a protocol	 * redesign.	 */	if (job.sender == requestor || isAdmin(requestor)) {	    if (TRACE(PROTOCOL))		logDebug("%s request by %s for %s", op, requestor, tag);	    (this->*f)(job, arg);	    jobsDone++;	} else	    jobsSkipped++;    }    if (jobsDone == 0)	sendClient(jobsSkipped ? "jobOwner" : "notQueued", tag);}/* * Job parameter alteration support. */#define	DEFINE_Alter(param)						\void OldProtocolServer::alterJob##param(const char* tag)		\    { applyToJob(tag, "alter", &OldProtocolServer::reallyAlterJob##param); }\void OldProtocolServer::alterJobGroup##param(const char* tag)		\    { applyToJobGroup(tag, "alter", &OldProtocolServer::reallyAlterJob##param); }boolOldProtocolServer::alterSuspend(Job& job){    if (job.state == FaxRequest::state_active) {	sendClient("jobLocked", job.jobid);	// NB: maintain old semantics	return (false);    }    fxStr emsg;    if (!sendQueuerACK(emsg, "X%s", (const char*) job.jobid)) {	sendError("Unable to suspend job: %s", (const char*) emsg);	return (false);    }    return (true);}voidOldProtocolServer::alterResubmit(Job& job){    fxStr emsg;    const char* jobid = job.jobid;    if (updateJobOnDisk(job, emsg)) {		// update q file	if (sendQueuerACK(emsg, "S%s", jobid))	// resubmit job	    sendClient("altered", jobid);	else	    sendError("Could not resubmit job: %s", (const char*) emsg);    } else {	sendError("Could not update job state: %s", (const char*) emsg);	(void) sendQueuer(emsg, "S%s", jobid);    }}voidOldProtocolServer::reallyAlterJobTTS(Job& job, const char* spec){    time_t now = Sys::now();    time_t t = cvtTime(spec, localtime(&now), "time-to-send");    if (alterSuspend(job)) {	job.tts = t;	alterResubmit(job);    }}DEFINE_Alter(TTS)voidOldProtocolServer::reallyAlterJobKillTime(Job& job, const char* spec){    time_t now = Sys::now();    time_t t = cvtTime(spec, localtime(&now), "kill-time");    if (alterSuspend(job)) {	job.killtime = t;	alterResubmit(job);    }}DEFINE_Alter(KillTime)voidOldProtocolServer::reallyAlterJobModem(Job& job, const char* device){    if (alterSuspend(job)) {	job.modem = device;	alterResubmit(job);    }}DEFINE_Alter(Modem)voidOldProtocolServer::reallyAlterJobPriority(Job& job, const char* priority){    if (alterSuspend(job)) {	job.usrpri = atoi(priority);	alterResubmit(job);    }}DEFINE_Alter(Priority)voidOldProtocolServer::reallyAlterJobMaxDials(Job& job, const char* max){    if (alterSuspend(job)) {	job.maxdials = atoi(max);	alterResubmit(job);    }}DEFINE_Alter(MaxDials)voidOldProtocolServer::reallyAlterJobNotification(Job& job, const char* note){    if (alterSuspend(job)) {	job.checkNotifyValue(note);	alterResubmit(job);    }}DEFINE_Alter(Notification)/* * Job removal and aborting support. */voidOldProtocolServer::reallyRemoveJob(const char* op, Job& job){    /*     * First ask server to do removal.  If the job is being     * processed, it will first be aborted.  Otherwise, do     * the cleanup here.     */    fxStr emsg;    const char* cmd = (strcmp(op, "remove") == 0 ? "R" : "K");    if (sendQueuerACK(emsg, "%s%s", cmd, (const char*) job.jobid)) {	sendClient("removed", job.jobid);    } else if (lockJob(job, LOCK_EX|LOCK_NB, emsg)) {	for (u_int i = 0, n = job.items.length(); i < n; i++) {	    const FaxItem& fitem = job.items[i];	    switch (fitem.op) {	    case FaxRequest::send_tiff:	    case FaxRequest::send_tiff_saved:	    case FaxRequest::send_pdf:	    case FaxRequest::send_pdf_saved:	    case FaxRequest::send_postscript:	    case FaxRequest::send_postscript_saved:	    case FaxRequest::send_pcl:	    case FaxRequest::send_pcl_saved:		Sys::unlink(fitem.item);		break;	    case FaxRequest::send_fax:		if (job.isUnreferenced(i))		    Sys::unlink(fitem.item);		break;	    }	}	if (Sys::unlink(job.qfile) < 0) {	    logError("%s: unlink %s failed (%m)", op, (const char*) job.qfile);	    sendClient("unlinkFailed", job.jobid);	} else {	    logInfo("%s %s completed", 		strcmp(op, "remove") == 0 ? "REMOVE" : "KILL",		(const char*) job.jobid);	    sendClient("removed", job.jobid);	}	unlockJob(job);    }}voidOldProtocolServer::doremove(Job& job, const char*){    reallyRemoveJob("remove", job);}void OldProtocolServer::removeJob(const char* tag)    { applyToJob(tag, fxQUOTE(op), &OldProtocolServer::doremove); }void OldProtocolServer::removeJobGroup(const char* tag)    { applyToJobGroup(tag, fxQUOTE(op), &OldProtocolServer::doremove); }voidOldProtocolServer::dokill(Job& job, const char*){    reallyRemoveJob("kill", job);}void OldProtocolServer::killJob(const char* tag)    { applyToJob(tag, fxQUOTE(op), &OldProtocolServer::dokill); }void OldProtocolServer::killJobGroup(const char* tag)    { applyToJobGroup(tag, fxQUOTE(op), &OldProtocolServer::dokill); }/* * Job submission support. */static voidlower(char* cp){    while (*cp) {	if (isupper(*cp))	    *cp = tolower(*cp);	cp++;    }}voidOldProtocolServer::submitJob(const char*){    fxStr emsg;    curJob = &defJob;				// inherit from default    if (!newJob(emsg)) {	sendError("Can not create new job: %s.", (const char*) emsg);	dologout(1);    }    time_t t = Sys::now();    struct tm now = *localtime(&t);    Job& job = *curJob;    for (;;) {	char line[1024];	char* tag;	getCommandLine(line, tag);	if (isCmd("end") || isCmd(".")) {	    setupData();	    break;	}	lower(line);	u_int ix;	if (FaxRequest::isStrCmd(line, ix)) {	    if (isCmd("cover"))		coverProtocol(0, atoi(tag));	    else		job.*FaxRequest::strvals[ix].p = tag;	} else if (FaxRequest::isShortCmd(line, ix)) {	    job.*FaxRequest::shortvals[ix].p = atoi(tag);	} else if (isCmd("sendAt")) {	    job.tts = (time_t) cvtTime(tag, &now, "time-to-send");	} else if (isCmd("killtime")) {	    struct tm* tm;	    if (job.tts) {		// NB: assumes sendAt precedes killtime		t = job.tts;		tm = localtime(&t);	    } else		tm = &now;	    job.killtime = cvtTime(tag, tm, "kill-time");	} else if (isCmd("retrytime")) {	    job.retrytime = (time_t) atoi(tag);	} else if (isCmd("notify")) {	// email notification	    job.checkNotifyValue(tag);	} else if (isCmd("pagechop")) {	    job.checkChopValue(tag);	} else if (isCmd("chopthreshold")) {	    job.chopthreshold = atof(tag);	} else if (isCmd("zcover")) {	    coverProtocol(1, atoi(tag));	} else if (isCmd("page")) {	   job.items.append(FaxItem(FaxRequest::send_page, 0, "", tag));	} else if (isCmd("!page")) {	   job.items.append(FaxItem(FaxRequest::send_page_saved, 0, "", tag));	} else				// XXX discard unknown items	    logInfo("Unknown job item %s:%s", line, tag);    }    if (job.external == "")	job.external = job.number;    job.modem = modem;    if (!updateJobOnDisk(job, emsg))	sendError("%s", (const char*) emsg);    else {	setFileOwner(job.qfile);		// force ownership	FileCache::chmod(job.qfile, 0660);	// sync cache	if (sendQueuerACK(emsg, "S%s", (const char*) job.jobid))	    sendClient("job", version > 1 ? "%s:%s" : "%s",		(const char*) job.jobid, (const char*) job.groupid);	else	    sendError("Warning, no job scheduler appears to be running.");    }}voidOldProtocolServer::coverProtocol(int isLZW, int cc){    fxStr templ = fxStr::format(FAX_DOCDIR "/doc%s.cover",	(const char*) curJob->jobid);    FILE* fd = fopen(templ, "w");    if (fd == NULL)	sendAndLogError("Could not create cover sheet file %s.",	    (const char*) templ);    if (isLZW) {	/*	 * Cover sheet comes across as LZW-compressed data;	 * the version id is the count of the decompressed	 * data bytes to expect (sigh, what a hack!)	 */	setupLZW();	long total = decodeLZW(stdin, fd);	if (total != cc)	    protocolBotch("not enough data received: expected %u, got %u.",		cc, total);	if (TRACE(PROTOCOL))	    logDebug(templ | ": %ld-byte compressed %s",		cc, "PostScript document");    } else {	/*	 * Old-style, data comes across as	 * ascii terminated by "..".	 */	char line[1024];	char* tag;	for (;;) {	    getCommandLine(line, tag);	    if (isCmd(".."))		break;	    fprintf(fd, "%s\n", tag);	}    }    if (fflush(fd) != 0)	sendAndLogError("Error writing cover sheet data: %s.", strerror(errno));    fclose(fd);    curJob->items.append(	FaxItem(FaxRequest::send_postscript, 0, "", templ));}voidOldProtocolServer::setupData(void){    for (u_int i = 0, n = reqs.length(); i < n; i++) {	const FaxItem& fitem = reqs[i];	if (fitem.op != FaxRequest::send_poll) {	    const char* cp = strrchr(fitem.item, '/');	    if (!cp)				// relative name, e.g. doc123		cp = fitem.item;	    fxStr doc = fxStr::format("/" FAX_DOCDIR "%s.", cp) | curJob->jobid;	    if (Sys::link(fitem.item, doc) < 0) {		logError("Can not link document \"%s\": %s",		    (const char*) doc, strerror(errno));		sendError("Problem setting up document file: %s",		    strerror(errno));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -