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

📄 lpdsend.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <sys/types.h>#include <unistd.h>#include <sys/stat.h>#include <sys/param.h>#include <stdlib.h>#include <fcntl.h>#include <stdio.h>#include <string.h>#include <signal.h>#define	REDIALTIMEOUT	15#ifdef PLAN9#include <Plan9libnet.h>#endif#define TIMEOUT 600char tmpfilename[L_tmpnam+1];int alarmstate = 0;int debugflag = 0;int killflag = 0;int statflag = 0;voidcleanup(void) {	unlink(tmpfilename);}#define SBSIZE 8192unsigned char sendbuf[SBSIZE];voiddebug(char *str) {	if (debugflag)		fprintf(stderr, "%s", str);}voidalarmhandler(int sig) {	fprintf(stderr, "timeout occurred, check printer.\n");	exit(2);}/* send a message after each WARNPC percent of data sent */#define WARNPC	5intcopyfile(int in, int out, long tosend) {	int n;	int sent = 0;	int percent = 0;	if (debugflag)		fprintf(stderr, "lpdsend: copyfile(%d,%d,%ld)\n",			in, out, tosend);	while ((n=read(in, sendbuf, SBSIZE)) > 0) {		if (debugflag)			fprintf(stderr, "lpdsend: copyfile read %d bytes from %d\n",				n, in);		alarm(TIMEOUT); alarmstate = 1;		if (write(out, sendbuf, n) != n) {			alarm(0);			fprintf(stderr, "write to fd %d failed\n", out);			return(0);		}		alarm(0);		if (debugflag)			fprintf(stderr, "lpdsend: copyfile wrote %d bytes to %d\n",				n, out);		sent += n;		if (tosend && ((sent*100/tosend)>=(percent+WARNPC))) {			percent += WARNPC;			fprintf(stderr, ": %5.2f%% sent\n", sent*100.0/tosend);		}	}	if (debugflag)		fprintf(stderr, "lpdsend: copyfile read %d bytes from %d\n",			n, in);	return(!n);}char  strbuf[120];char hostname[MAXHOSTNAMELEN], *username, *printername, *killarg;char *inputname;char filetype = 'o';	/* 'o' is for PostScript */int seqno = 0;char *seqfilename;voidkilljob(int printerfd) {	int strlength;	if (printername==0) {		fprintf(stderr, "no printer name\n");		exit(1);	}	if (username==0) {		fprintf(stderr, "no user name given\n");		exit(1);	}	if (killarg==0) {		fprintf(stderr, "no job to kill\n");		exit(1);	}	sprintf(strbuf, "%c%s %s %s\n", '\5', printername, username, killarg);	strlength = strlen(strbuf);	if (write(printerfd, strbuf, strlength) != strlength) {		fprintf(stderr, "write(printer) error\n");		exit(1);	}	copyfile(printerfd, 2, 0L);}voidcheckqueue(int printerfd) {	int n, strlength;	unsigned char sendbuf[1];	sprintf(strbuf, "%c%s\n", '\4', printername);	strlength = strlen(strbuf);	if (write(printerfd, strbuf, strlength) != strlength) {		fprintf(stderr, "write(printer) error\n");		exit(1);	}	copyfile(printerfd, 2, 0L);/*	while ((n=read(printerfd, sendbuf, 1)) > 0) {		write(2, sendbuf, n);	}*/}voidgetack(int printerfd, int as) {	char resp;	int rv;	alarm(TIMEOUT); alarmstate = as;	if ((rv=read(printerfd, &resp, 1)) != 1 || resp != '\0') {		fprintf(stderr, "getack failed: read returned %d, read value (if any) %d, alarmstate=%d\n",			rv, resp, alarmstate);		exit(1);	}	alarm(0);}/* send control file */voidsendctrl(int printerfd) {	char cntrlstrbuf[256];	int strlength, cntrlen;	sprintf(cntrlstrbuf, "H%s\nP%s\n%cdfA%3.3d%s\n", hostname, username, filetype, seqno, hostname);	cntrlen = strlen(cntrlstrbuf);	sprintf(strbuf, "%c%d cfA%3.3d%s\n", '\2', cntrlen, seqno, hostname);	strlength = strlen(strbuf);	if (write(printerfd, strbuf, strlength) != strlength) {		fprintf(stderr, "write(printer) error\n");		exit(1);	}	getack(printerfd, 3);	if (write(printerfd, cntrlstrbuf, cntrlen) != cntrlen) {		fprintf(stderr, "write(printer) error\n");		exit(1);	}	if (write(printerfd, "\0", 1) != 1) {		fprintf(stderr, "write(printer) error\n");		exit(1);	}	getack(printerfd, 4);}/* send data file */voidsenddata(int inputfd, int printerfd, long size) {	int strlength;	sprintf(strbuf, "%c%d dfA%3.3d%s\n", '\3', size, seqno, hostname);	strlength = strlen(strbuf);	if (write(printerfd, strbuf, strlength) != strlength) {		fprintf(stderr, "write(printer) error\n");		exit(1);	}	getack(printerfd, 5);	if (!copyfile(inputfd, printerfd, size)) {		fprintf(stderr, "failed to send file to printer\n");		exit(1);	}	if (write(printerfd, "\0", 1) != 1) {		fprintf(stderr, "write(printer) error\n");		exit(1);	}	fprintf(stderr, "%d bytes sent, status: waiting for end of job\n", size);	getack(printerfd, 6);}voidsendjob(int inputfd, int printerfd) {	struct stat statbuf;	int strlength;	if (fstat(inputfd, &statbuf) < 0) {		fprintf(stderr, "fstat(%s) failed\n", inputname);		exit(1);	}	sprintf(strbuf, "%c%s\n", '\2', printername);	strlength = strlen(strbuf);	if (write(printerfd, strbuf, strlength) != strlength) {		fprintf(stderr, "write(printer) error\n");		exit(1);	}	getack(printerfd, 2);	debug("send data\n");	senddata(inputfd, printerfd, statbuf.st_size);	debug("send control info\n");	sendctrl(printerfd);	fprintf(stderr, "%ld bytes sent, status: end of job\n", statbuf.st_size);}/* *  make an address, add the defaults */char *netmkaddr(char *linear, char *defnet, char *defsrv){	static char addr[512];	char *cp;	/*	 *  dump network name	 */	cp = strchr(linear, '!');	if(cp == 0){		if(defnet==0){			if(defsrv)				snprintf(addr, sizeof addr, "net!%s!%s", linear, defsrv);			else				snprintf(addr, sizeof addr, "net!%s", linear);		}		else {			if(defsrv)				snprintf(addr, sizeof addr, "%s!%s!%s", defnet, linear, defsrv);			else				snprintf(addr, sizeof addr, "%s!%s", defnet, linear);		}		return addr;	}	/*	 *  if there is already a service, use it	 */	cp = strchr(cp+1, '!');	if(cp)		return linear;	/*	 *  add default service	 */	if(defsrv == 0)		return linear;	sprintf(addr, "%s!%s", linear, defsrv);	return addr;}main(int argc, char *argv[]) {	int c, usgflg = 0;	char *desthostname;	char *hnend;	int printerfd;	int inputfd;	int sendport;	char portstr[4];	if (signal(SIGALRM, alarmhandler) == SIG_ERR) {		fprintf(stderr, "failed to set alarm handler\n");		exit(1);	}	while ((c = getopt(argc, argv, "Dd:k:qs:t:H:P:")) != -1)		switch (c) {		case 'D':			debugflag = 1;			debug("debugging on\n");			break;		case 'd':			printername = optarg;			break;		case 'k':			if (statflag) {				fprintf(stderr, "cannot have both -k and -q flags\n");				exit(1);			}				killflag = 1;			killarg = optarg;			break;		case 'q':			if (killflag) {				fprintf(stderr, "cannot have both -q and -k flags\n");				exit(1);			}				statflag = 1;			break;		case 's':			seqno = strtol(optarg, NULL, 10);			if (seqno < 0 || seqno > 999)				seqno = 0;			break;		case 't':			switch (filetype) {			case 'c':			case 'd':			case 'f':			case 'g':			case 'l':			case 'n':			case 'o':			case 'p':			case 'r':			case 't':			case 'v':			case 'z':				filetype = optarg[0];				break;			default:				usgflg++;				break;			}			break;		case 'H':			strncpy(hostname, optarg, MAXHOSTNAMELEN);			break;		case 'P':			username = optarg;			break;		default:		case '?':			fprintf(stderr, "unknown option %c\n", c);			usgflg++;		}	if (argc < 2) usgflg++;	if (optind < argc) {		desthostname = argv[optind++];	} else		usgflg++;	if (usgflg) {		fprintf(stderr, "usage: to send a job - %s -d printer -H hostname -P username [-s seqno] [-t[cdfgklnoprtvz]] desthost [filename]\n", argv[0]);		fprintf(stderr, "     to check status - %s -d printer -q desthost\n", argv[0]);		fprintf(stderr, "       to kill a job - %s -d printer -P username -k jobname desthost\n", argv[0]);		exit(1);	}/* make sure the file to send is here and ready * otherwise the TCP connection times out. */	if (!statflag && !killflag) {		if (optind < argc) {			inputname = argv[optind++];			debug("open("); debug(inputname); debug(")\n");			inputfd = open(inputname, O_RDONLY);			if (inputfd < 0) {				fprintf(stderr, "open(%s) failed\n", inputname);				exit(1);			}		} else {			inputname = "stdin";			tmpnam(tmpfilename);			debug("using stdin\n");			if ((inputfd = open(tmpfilename, O_RDWR|O_CREAT, 0600)) < 0) {				fprintf(stderr, "open(%s) failed\n", tmpfilename);				exit(1);			}			atexit(cleanup);			debug("copy input to temp file ");			debug(tmpfilename);			debug("\n");			if (!copyfile(0, inputfd, 0L)) {				fprintf(stderr, "failed to copy file to temporary file\n");				exit(1);			}			if (lseek(inputfd, 0L, 0) < 0) {				fprintf(stderr, "failed to seek back to the beginning of the temporary file\n");				exit(1);			}		}	}	sprintf(strbuf, "%s", netmkaddr(desthostname, "tcp", "printer"));	fprintf(stderr, "connecting to %s\n", strbuf);	for (sendport=721; sendport<=731; sendport++) {		sprintf(portstr, "%3.3d", sendport);		fprintf(stderr, " trying from port %s...", portstr);		debug(" dial("); debug(strbuf); debug(", "); debug(portstr); debug(", 0, 0) ...");		printerfd = dial(strbuf, portstr, 0, 0);		if (printerfd >= 0) {			fprintf(stderr, "connected\n");			break;		}		fprintf(stderr, "failed\n");		sleep(REDIALTIMEOUT);	}	if (printerfd < 0) {		fprintf(stderr, "Cannot open a valid port!\n");		fprintf(stderr, "-  All source ports [721-731] may be busy.\n");		fprintf(stderr, "-  Is recipient ready and online?\n");		fprintf(stderr, "-  If all else fails, cycle the power!\n");		exit(1);	}/*	hostname[8] = '\0'; */#ifndef PLAN9	if (gethostname(hostname, sizeof(hostname)) < 0) {		perror("gethostname");		exit(1);	}#endif/*	if ((hnend = strchr(hostname, '.')) != NULL)		*hnend = '\0'; */	if (statflag) {		checkqueue(printerfd);	} else if (killflag) {		killjob(printerfd);	} else {		sendjob(inputfd, printerfd);	}	exit(0);}

⌨️ 快捷键说明

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