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

📄 printjob.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 4 页
字号:
static char xlator_call_flags[8];/****************************************************************//* This is the set of char pointers used by printcap_escapes, * note that the escapes are initialised by reference, so these * pointers may be changed in the course of execution, * This applies particularly to printer and AF, which have * #defines to keep the naming tidy and the information localised. */static char *es_percent =	"%";static char *es_null =		"";static char *es_space =		" ";static char *es_width =		width+2;static char *es_length =	length+2;static char *es_title =		title;static char *es_indent =	indent+2;static char *es_pxwidth =	pxwidth+2;static char *es_pxlength =	pxlength+2;#define      es_printer		printerstatic char *es_fromhost =	fromhost;static char *es_logname =	logname;static char *es_jobname =	jobname;static char *es_job_id =	job_id;#define      es_account_file	AFstatic char *es_datatype =	datatype;static char *es_orientation =	orientation;static char *es_pagesize =	pagesize;static char *es_xflags =	&xlator_call_flags[0];struct es_pair printcap_escapes[] = {	{ '%', &es_percent },	/* defines the escape character */	{ '0', &es_null },	/* the null string (for null arguments) */	{ '_', &es_space },	{ 'W', &es_width },	{ 'L', &es_length },	{ 'T', &es_title },	{ 'I', &es_indent },	{ 'X', &es_pxwidth },	{ 'Y', &es_pxlength },	{ 'P', &es_printer },	{ 'H', &es_fromhost },	{ 'U', &es_logname },	{ 'j', &es_jobname },	{ 'J', &es_job_id },	{ 'A', &es_account_file },	{ 'D', &es_datatype },	{ 'O', &es_orientation },	{ 'F', &es_pagesize },	{ 'x', &es_xflags },	{ '\0', 0 }};/* * Environment buffers for signal catching code */jmp_buf env, sigpipe_env;printjob(begin)int	begin;{	struct connection out_plug; /* output connection */	init();			/* set up capabilities */	(void) write(1, "", 1);	/* ack that daemon is started */	(void) close(1);	/* set up log file */	(void) close(2);	if((begin==1) && (RM==NULL))		{		inid = open(ininame,O_RDWR|O_CREAT,0660);	/* create a init file */		write(inid, "init file\n", 10);		(void) close(inid);		}	if (open(LF, O_WRONLY|O_APPEND) < 0)		(void) open("/dev/null", O_WRONLY);	dup(1);	pid = getpid();				/* for use with lprm */	setpgrp(0, pid);	dlog(0, "%s: daemon %d started", lpd_time(), pid);	init_features();	/* set flags for this printer version */	set_connection_type();	/* decide connection type */	cx_init(&out_plug, connection_type); /* initialise connection */	{		int signal_number;		if ((signal_number = setjmp(env)) != 0) {			final_cleanup(&out_plug, signal_number);			exit(1);		} else {			signal(SIGHUP, onintr);			signal(SIGINT, onintr);			signal(SIGQUIT, onquit);			signal(SIGTERM, onintr);			signal(SIGCHLD, SIG_DFL);		}	}	set_printer_type();	/* decide printer type (PS or not) */	/* If we're type PostScript, open Device Control Module archive */	switch (printer_type) {	    case pt_non_PS:		break;	    case pt_LN03R:	    case pt_LPS:		if (!DL) {			fatal("Dl must be specified for %s printer_type",			      PS_choices[(int)printer_type]);			exit(1);		}		if (ar_init(DL) != 0) {			fatal("archive %s not found\n", DL);		}		break;	}	/*	 * uses short form file names	 */	if (chdir(SD) < 0) {		log("cannot chdir to %s", SD);		exit(1);	}	lfd = open(LO, O_WRONLY|O_CREAT, 0644);	if (lfd < 0) {		log("cannot create %s", LO);		exit(1);	}	if (flock(lfd, LOCK_EX|LOCK_NB) < 0) {		if (errno == EWOULDBLOCK)	/* active deamon present */			exit(0);		log("cannot lock %s", LO);		exit(1);	}	ftruncate(lfd, 0);	/*	 * write process id for others to know	 */	sprintf(line, "%u\n", pid);	pidoff = strlen(line);	if (write(lfd, line, pidoff) != pidoff) {		log("cannot write daemon pid");		exit(1);	}	tof = !FO;	process_the_queue(&out_plug);	final_cleanup(&out_plug, 0);	exit(0);}/* * get_q_state -- find state of queue by checking lock file mode */static enum q_state_eget_q_state(){	struct stat stb;	if (fstat(lfd, &stb) == 0) {		if (stb.st_mode & 0100) {			return q_disabled;		} else if (stb.st_mode & 0001) {			if (fchmod(lfd, stb.st_mode & 0776) < 0)			    log("cannot chmod %s", LO);			return q_rebuild;		} else {			return q_enabled;		}	} else {		return q_disabled;	}}static voidprocess_the_queue(cxp)register CXP cxp;{	int count = 0;	int nitems = 0;	register struct queue *q, **qp;	struct queue **queue;	enum q_state_e q_state = get_q_state();	while (1) {		dlog(1, "process_the_queue: while");		if (q_state == q_disabled || (nitems = getq(&queue)) <= 0) {			dlog(1, "process_the_queue: getq -  nitems %d",nitems);			break;		}		q_state = q_enabled;		for (qp = queue; nitems--; ) {			dlog(1, "process_the_queue: for nitems %d",nitems);			q = *qp++;			switch(q_state) {			    case q_enabled:				dlog(1, "process_the_queue: q_enabled");				count += process_a_job(cxp, q->q_name);				q_state = get_q_state();				break;			    case q_disabled:			    case q_rebuild:				dlog(1, "process_the_queue: q_disabled");				break;			}			free((char *) q);		}		dlog(1, "process_the_queue:free");		free((char *) queue);	}	if (nitems < 0) {		log("can't scan spool directory %s", SD);	}	if (printer_type == pt_non_PS && count > 0) {		dlog(1, "process_the_queue: pt_non_ps");		switch (connection_type) {		    case con_dev:		    case con_lat:			if (!SF && !tof)			    (void) write(cxp->cx_out_fd,					 FF, strlen(FF));			if (TR != NULL)	/* output trailer */			    (void) write(cxp->cx_out_fd, TR, strlen(TR));			break;		    default:			dlog(1, "process_the_queue: default");			/* do nothing */			break;		}	}}static intprocess_a_job(cxp, command_file)register CXP cxp;char *command_file;{	struct stat stb;	register int i, n_retries;	register unsigned how_long;	enum job_status_e job_status;	if (stat(command_file, &stb) < 0)	    return 0;	(void) lseek(lfd, pidoff, 0);	(void) sprintf(line, "%s\n", command_file);	i = strlen(line);	if (write(lfd, line, i) != i) {		log("can't write (%d) control file name %s", errno, LO);		return 0;	}	how_long = MIN_RETRY_WAIT;	for (n_retries = 0; n_retries < PRINT_NRETRIES; n_retries++) {		dlog(1, "process_the_job: command file %s",command_file);		job_status = try_the_job(cxp, command_file);		switch (job_status) {		    case js_ok:			return 1; /* job ok and printed */		    case js_failed:		    default:			log("%s: Job %d aborted",			    lpd_time(), atoi(command_file+3));			(void)cx_close(cxp); /* close printer connection */			cleanup_job(command_file, js_failed);			return 0; /* job failed */		    case js_retry:			/* try reprinting the job after a sleep */			(void)cx_close(cxp); /* close printer connection */			log("%s: Job %d, Retry #%d in %d secs",			    lpd_time(), atoi(command_file+3), n_retries + 1,			    how_long);			status("Sleeping for %d seconds before retrying",			       how_long);			sleep(how_long);			break;		}		how_long = (((how_long * 2) > MAX_RETRY_WAIT)			    ? MAX_RETRY_WAIT : (how_long * 2));	}	log("Job %d abandonned after %d retries",	    atoi(command_file+3), n_retries);	cleanup_job(command_file, js_too_many_retries);	return 0;}static enum job_status_etry_the_job(cxp, command_file)register CXP cxp;char *command_file;{	enum job_status_e job_status = js_failed;	if (setjmp(sigpipe_env) == 0) {		signal(SIGPIPE, onsigpipe);		job_init();		switch(connection_type) {		    case con_dev:		    case con_lat:		    case con_tcp:			/*			 * actions associated with cx_open and cx_start			 * only happen if needed here since out_plug			 * maintains state and knows what to do			 */			(void)cx_open(cxp);			cx_start(cxp);			job_status = printit(cxp, command_file);			break;		    case con_remote:			/* open output if necessary */			(void)cx_open(cxp);			job_status = sendit(cxp, command_file);			break;		    case con_network:			job_status = printit(cxp, command_file);			break;		    case con_dqs:  /* for  dqs - print */			dlog(1, "try_the_job: connection type dqs");			job_status = startdqs(printer,cxp,command_file);			if(job_status == js_ok)			dlog(1, "try_the_job: job_status is OK exit child");			else			dlog(1, "try_the_job: job_status FAILED exit child");			exit(0);		    default:			log("Unknown connection type");			break;		}	} else {		int cx_ret_code;		stop_mon();		dlog(0, "caught SIGPIPE writing to output filter");		cx_ret_code = cx_close(cxp);		job_status = ((cx_ret_code == 1) ? js_retry : js_failed);	}	return job_status;}char	fonts[4][50];	/* fonts for troff */static char ifonts[4][18] = {	"/usr/lib/vfont/R",	"/usr/lib/vfont/I",	"/usr/lib/vfont/B",	"/usr/lib/vfont/S"};static voidcleanup_job(command_file, why)char *command_file;enum job_status_e why;{	FILE	*cfp;			/* control file */	/*	 * open control file	 */	if ((cfp = fopen(command_file, "r")) == NULL) {		log("open failure (%d) of control file %s",		    errno, command_file);		/* shouldn't happen, must have opened ok before */		return;	}	cf_pass2(cfp, why);	/*	 * clean-up incase another control file exists	 */	(void) fclose(cfp);	(void) unlink(command_file);}/* * cf_pass2 -- * * Second pass through command file called by printit and cleanup_job */intcf_pass2(cfp, job_status)FILE *cfp;			/* control file */enum job_status_e job_status;{	fseek(cfp, 0L, 0);	while (getline(cfp)) {		switch (line[0]) {		case 'M':			sendmail(line+1, fromhost, jobname, job_status);			continue;		case 'U':			(void) unlink(line+1);			continue;		    default:			continue;		}	}}/* build filter * Parse the string prog into filter elements, replace escapes if found, * If no escapes are found then add in default arguments * for backward compatibility (NB remember to terminate with 0) * The filter(s) are appended to the filter_chain *fcp. * The escapes are described by the escapes pointed to by esp. *//*VARARGS3*/voidbuild_filter(fcp, esp, prog, va_alist)FCP fcp;			/* filter chain we're building */ESP esp;			/* The escapes */char *prog;			/* Program string */va_dcl				/* Default arguments to filter 0 terminated */{	struct filter_chain filter_tmp;	int escapes_found = 0; /* return flag from do_escapes */	register char *p;	fc_init(&filter_tmp);	/* tmp: parsed first program put here */	/* parse the command in prog */	for (p = parse_prog(&filter_tmp, prog); p; ) {		p = parse_prog(&filter_tmp, p);	}	if (enable_printcap_escapes) {		escapes_found = do_escapes(&filter_tmp, esp);	}	/* append first command to filter chain */	fc_add_args_v(fcp, filter_tmp.fc_argv[0]);	if (!escapes_found) {		va_list args;		/* Add in default args to first command in pipeline		 */		va_start(args);		fc_add_args_va(fcp, args);		va_end(args);	}	fc_end_filter(fcp);			/* terminate 1st command */	{		int i;		/* loop index */		for (i = 1; i < filter_tmp.fc_nf; i++) {			/* append each command to filter chain */			fc_add_args_v(fcp, filter_tmp.fc_argv[i]);			fc_end_filter(fcp);		}	}	fc_delete(&filter_tmp, 0);}/* build_filter_chain * Set up filter chain *    [ {PR, PP} | ] [ IF | ] OF * or *    { RF, TF, NF, DF, CF, VF }. * * Instructions whether OF is needed is passed by return code. * * Changes: * (PP added to above description, AT 26-jan-88) * (semantics of IF changed, AT 28-jan-88) * Returns: */#define BFC_ERR			(-1) /* foul up */#define BFC_USE_OUTPUT_FILTER	1 /* use the output filter */#define BFC_BYPASS		0 /* don't use the output filter */static intbuild_filter_chain(format, fcp)int format;register FCP fcp;	/* filter constructed in here */{	int retcode = BFC_BYPASS;	struct escapes escapes;	/* escapes */	es_init(&escapes, printcap_escapes);	switch(format) {		int fd;		int i;		static char *vfpre = "/usr/lib/vfont/";	    case 'p':		/* print using pr-like filter */

⌨️ 快捷键说明

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