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

📄 lpsend.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#ifdef plan9#include <u.h>#include <libc.h>#define 	stderr	2#define RDNETIMEOUT	60000#define WRNETIMEOUT	60000#else/* not for plan 9 */#include <stdio.h>#include <errno.h>#include <time.h>#include <fcntl.h>#include <signal.h>#define	create	creat#define	seek	lseek#define	fprint	fprintf#define	sprint	sprintf#define	exits	exit#define	ORDWR	O_RDWR#define	OTRUNC	O_TRUNC#define	ORCLOSE	0#define RDNETIMEOUT	60#define WRNETIMEOUT	60#endif#define MIN(a,b)	((a<b)?a:b)#define	ACK(a)	write(a, "", 1)#define NAK(a)	write(a, "\001", 1)#define LPDAEMONLOG	"/tmp/lpdaemonl"#define LNBFSZ	4096char lnbuf[LNBFSZ];int dbgstate = 0;char *dbgstrings[] = {	"",	"rcvack1",	"send",	"rcvack2",	"response",	"done"};#ifdef plan9voiderror(int level, char *s1, ...){	va_list ap;	long thetime;	char *chartime;	char *args[8];	int argno = 0;	if (level == 0) {		time(&thetime);		chartime = ctime(thetime);		fprint(stderr, "%.15s ", &(chartime[4]));	}	va_start(ap, s1);	while(args[argno++] = va_arg(ap, char*));	va_end(ap);	fprint(stderr, s1, *args);	return;}intalarmhandler(void *foo, char *note) {	USED(foo);	if(strcmp(note, "alarm")==0) {		fprint(stderr, "alarm at %d - %s\n", dbgstate, dbgstrings[dbgstate]);		return(1);	} else return(0);}#elsevoiderror(int level, char *s1, ...){	time_t thetime;	char *chartime;	if (level == 0) {		time(&thetime);		chartime = ctime(&thetime);		fprintf(stderr, "%.15s ", &(chartime[4]));	}	fprintf(stderr, s1, (&s1+1));	return;}voidalarmhandler() {	fprintf(stderr, "alarm at %d - %s\n", dbgstate, dbgstrings[dbgstate]);}#endif/* get a line from inpfd using nonbuffered input.  The line is truncated if it is too * long for the buffer.  The result is left in lnbuf and the number of characters * read in is returned. */intreadline(int inpfd){	register char *ap;	register int i;	ap = lnbuf;	i = 0;	do {		if (read(inpfd, ap, 1) != 1) {			error(0, "read error in readline, fd=%d\n", inpfd);			break;		}	} while ((++i < LNBFSZ - 2) && *ap++ != '\n');	if (i == LNBFSZ - 2) {		*ap = '\n';		i++;	}	*ap = '\0';	return(i);}#define	RDSIZE 512char jobbuf[RDSIZE];intpass(int inpfd, int outfd, int bsize){	int bcnt = 0;	int rv = 0;	for(bcnt=bsize; bcnt > 0; bcnt -= rv) {		alarm(WRNETIMEOUT);	/* to break hanging */		if((rv=read(inpfd, jobbuf, MIN(bcnt,RDSIZE))) < 0) {			error(0, "read error during pass, %d remaining\n", bcnt);			break;		} else if((write(outfd, jobbuf, rv)) != rv) {			error(0, "write error during pass, %d remaining\n", bcnt);			break;		}	}	alarm(0);	return(bcnt);}	/* get whatever stdin has and put it into the temporary file. * return the file size. */intprereadfile(int inpfd){	int rv, bsize;	bsize = 0;	do {		if((rv=read(0, jobbuf, RDSIZE))<0) {			error(0, "read error while making temp file\n");			exits("read error while making temp file");		} else if((write(inpfd, jobbuf, rv)) != rv) {			error(0, "write error while making temp file\n");			exits("write error while making temp file");		}		bsize += rv;	} while (rv!=0);	return(bsize);}inttempfile(void){	static tindx = 0;	char tmpf[20];	int tmpfd;	sprint(tmpf, "/tmp/lp%d.%d", getpid(), tindx++);	if((tmpfd=create(tmpf,#ifdef plan9						ORDWR|OTRUNC,#endif												0666)) < 0) {		error(0, "cannot create temp file %s\n", tmpf);		exits("cannot create temp file");	}	close(tmpfd);	if((tmpfd=open(tmpf, ORDWR#ifdef plan9						|ORCLOSE|OTRUNC#endif									)) < 0) {		error(0, "cannot open temp file %s\n", tmpf);		exits("cannot open temp file");	}	return(tmpfd);}intrecvACK(int netfd){	int rv;	*jobbuf = '\0';	alarm(RDNETIMEOUT);	if (read(netfd, jobbuf, 1)!=1 || *jobbuf!='\0') {		error(0, "failed to receive ACK, ");		if (*jobbuf == '\0')			error(1, "read failed\n");		else			error(1, "received <0x%x> instead\n", *jobbuf);		rv = 0;	} else rv = 1;	alarm(0);	return(rv);}voidmain(int argc, char *argv[]){	char *devdir;	int i, rv, netfd, bsize;	int datafd;#ifndef plan9	void (*oldhandler)();#endif	/* make connection */	if (argc != 2) {		fprint(stderr, "usage: %s network!destination!service\n", argv[0]);		exits("incorrect number of arguments");	}	/* read options line from stdin into lnbuf */	i = readline(0);	/* read stdin into tempfile to get size */	datafd = tempfile();	bsize = prereadfile(datafd);	/* network connection is opened after data is in to avoid timeout */	if ((netfd=dial(argv[1], 0, 0, 0)) < 0) {		fprint(stderr, "dialing %s\n", devdir);		perror("dial");		exits("can't dial");	}	/* write out the options we read above */	if (write(netfd, lnbuf, i) != i) {		error(0, "write error while sending options\n");		exits("write error while sending options");	}	/* send the size of the file to be sent */	sprint(lnbuf, "%d\n", bsize);	i = strlen(lnbuf);	if ((rv=write(netfd, lnbuf, i)) != i) {		perror("write error while sending size");		error(0, "write returned %d\n", rv);		exits("write error while sending size");	}	if (seek(datafd, 0L, 0) < 0) {		error(0, "error seeking temp file\n");		exits("seek error");	}	/* mirror performance in readfile() in lpdaemon */#ifdef plan9	atnotify(alarmhandler, 1);#else	oldhandler = signal(SIGALRM, alarmhandler);#endif	dbgstate = 1;	if(!recvACK(netfd)) {		error(0, "failed to receive ACK before sending data\n");		exits("recv ack1 failed");	}	dbgstate = 2;	if ((i=pass(datafd, netfd, bsize)) != 0) {		NAK(netfd);		error(0, "failed to send %d bytes\n", i);		exits("send data failed");	}	ACK(netfd);	dbgstate = 3;	if(!recvACK(netfd)) {		error(0, "failed to receive ACK after sending data\n");		exits("recv ack2 failed");	}	/* get response, as from lp -q */	dbgstate = 4;	while((rv=read(netfd, jobbuf, RDSIZE)) > 0) {		if((write(1, jobbuf, rv)) != rv) {			error(0, "write error while sending to stdout\n");			exits("write error while sending to stdout");		}	}	dbgstate = 5;#ifdef plan9	atnotify(alarmhandler, 0);	/* close down network connections and go away */	exits("");#else	signal(SIGALRM, oldhandler);	exit(0);#endif}

⌨️ 快捷键说明

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