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

📄 lpscomm.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
	    }	}	if (LP_C_probe(OtherFD)) {#ifdef DEBUG	if (debug>4) fprintf(stderr,"O%s	%s: input on otherFD while waiting.\n",		progName, LPStime());#endif DEBUG	    Status = LP_C_recv(OtherFD, Opcode, &MesgID, Length, Data);	    if (Status < 0) return(FALSE);	    if ( (dproc) !=  0) {		(*dproc)(FALSE, Opcode, MesgID, *Length, Data);	    	    }	}    }    return(TRUE);		/* in theory this is unreachable */}/* * *		L P _ C _ s e n d * * This routine composes and sends a message to the print server. The * message format is specified by the "Print Server Protocol". * * Inputs:		ServerFD (integer)	FD to send to *			Opcode (string)		opcode *			mdata (string)		what to send *			ID (integer)		message number, or zero *			count (int)		byte count, or zero * Outputs:		none * Returns:		ID (integer)		generated message number * * If the byte count is zero, then we use strlen() to count bytes. If it * is nonzero, then the data can contain nulls. */int SequenceID=0;		/* integer sequence ID number */int LP_C_send(ServerFD, Opcode, mdata, ID, mlen)int ServerFD;char *Opcode, *mdata;int ID;{ char packetBuffer[2*RELAY_MAX_FRAME];  char *ic,*jc;  static int pow10[10]=    {1,1,10,100,1000,10000,100000,1000000,10000000,100000000};  int nlen,tlen,i,n,r;  int fixedLength;			/* size of fixed part of packet */  int packetLength;    jc = packetBuffer;    if (mdata == (char *) 0)        ic = "";    else        ic = mdata;    if (ID == 0) ID = ++SequenceID;/* Build the outgoing frame, laboriously by hand. We used to do this with   sprintf, but it used too much cpu time and was actually limiting the   printer speed on loaded microvax clients. */    *jc++ = (char) RELAY_SOM;    for (i=0;i<strlen(Opcode);i++) *jc++ = Opcode[i];    *jc++ = ' ';        r = ID;    for(n=fakelog10(r); n>0; n--) {	/* the frame ID */        *jc++ = '0'+ (r / pow10[n]);	r %= pow10[n];    }    *jc++ = ' '; *jc = (char) NULL;    fixedLength = strlen(packetBuffer);    fixedLength += fakelog10(RELAY_MAX_FRAME-fixedLength);    if (mlen == 0) mlen = strlen(ic);    nlen = mlen;    if (nlen + fixedLength >= RELAY_MAX_FRAME)        nlen = RELAY_MAX_FRAME - fixedLength - 1;    tlen = nlen;    for(n=fakelog10(tlen); n>0; n--) {	/* the size */        *jc++ = '0'+ (tlen / pow10[n]);	tlen %= pow10[n];    }    *jc++ = ' ';    strncpy(jc,ic,nlen);		/* the data */    ic += nlen;    jc += nlen;    packetLength = (int) (jc - packetBuffer);    *jc++ = (char) NULL;    #ifdef DEBUGif (debug > 8) {    fprintf(stderr, "O%s	%s: %d<-smsg(%s)\n",	    progName, LPStime(),ServerFD,packetBuffer);}#endif DEBUG    signal(SIGPIPE, SIG_IGN);#ifdef DEBUG    if (strlen(packetBuffer) > RELAY_MAX_FRAME) {        fprintf(stderr,"O%s	%s: assertion failed, send(%d chars)\n",	      progName, LPStime(), strlen(packetBuffer));    }#endif DEBUG    if (send(ServerFD, packetBuffer, packetLength, sendFlag) < 0) {	sprintf(errbuf,"%s	%s: LP_C_send(%d) failed",		progName, LPStime(),ServerFD);	perror(errbuf);	if (jump_write_error) {	    longjmp(write_error, ServerFD);	}    }    /* Check to see if we fragmented, and do something about it */    if (mlen > nlen) {#ifdef DEBUG	if (debug > 3) fprintf(stderr,"O%s	%s: frame fragmented.\n",		progName, LPStime());#endif DEBUG        LP_C_send(ServerFD, Opcode, ic, ID, mlen-nlen);    }    return(ID);}/* * *		L P _ C _ s e n d _ u r g e n t * * This routine composes and sends an urgent message to the print server. * It is identical to LP_C_send (see above) save that it sends an OP_NULL * with the urgent flag turned on before sending the real message. This * Is accomplished by setting the MSG_OOB flag bit in the socket. Note that * the bytes that are sent as "urgent" are not actually the ones that we * are trying to expedite, but are, rather, a "sentinel" that comes before * them to clear out the path. * * Inputs:		ServerFD (integer) *			Opcode (string) *			mdata (string) *			ID (integer) *			mlen (integer) * * Returns:		ID (integer) * */int LP_C_send_urgent(ServerFD, Opcode, mdata, ID, mlen)int ServerFD;char *Opcode, *mdata;int ID,mlen;{    int retval;    sendFlag = MSG_OOB;		/* enable TCP Urgent Data */    LP_C_send(ServerFD, OP_NULL, " ", 0, 1);    sendFlag = 0;		/* disable TCP Urgent Data */    retval=LP_C_send(ServerFD, Opcode, mdata, ID, mlen);    return(retval);}/* *		L P _ C _ c l o s e * * Shut down a communication channel and release all of the resources * associated with it. * * Inputs:		int FD		FD to close * Outputs: 		none * Returns:		none * Action:		close the FD and release the buffers */void LP_C_close(FD)int FD;{    if (FD < 0) return;    close(FD);    free(inputBuffers[FD]);    inputBuffers[FD] = (char *) 0;    lastByteIn[FD] = -1;    probeCache[FD] = FALSE;    return;} /* *		A s s i g n D i r e c t * * This routine is called to establish a direct connection to the printer. *  * Inputs:		nodename		string name of printer node * Outputs:		none * Returns:		socket FD open on printer  * Actions:		allocates FD, opens connection to printer, *			and binds that FD to the connection. * */AssignDirect(nodename)char *nodename;{    int  AFD;			/* FD to connect to printer server */    int connected;		/* true when we have made a connection */    int failureCount;		/* number of times we have failed to connect */    int haddr;    struct hostent *hp;    struct servent *sp;    struct sockaddr_in sin;    char hostString[256];    char serviceName[128];		/* get the host address and port number */    strcpy(serviceName,"print-srv");    sscanf(nodename,"%[^/]/%[^/]",hostString, serviceName);    haddr = inet_addr(hostString);    if (haddr != -1) {	sin.sin_addr.s_addr = haddr;    } else {    	hp = gethostbyname(hostString);	if (hp == (struct hostent *) NULL) {	    fprintf(stderr,"O%s	%s: Unknown host %s\n",		progName, LPStime(), hostString);	    exit(1);	}	sin.sin_addr.s_addr = (haddr = *(int *) hp->h_addr);    }    sp = getservbyname(serviceName, "tcp");    if (sp == (struct servent *) NULL) {        fprintf(stderr,"O%s	%s: Unknown service %s\n", 	    progName, LPStime(), serviceName);	exit(1);    }    sin.sin_family = AF_INET;    sin.sin_port = sp->s_port;    connected = FALSE;    failureCount = 0;    while (!connected) {	    	/* get a socket */	AFD = socket(AF_INET, SOCK_STREAM, 0);	if (AFD < 0) {	    sprintf(errbuf,"O%s	%s: cannot allocate socket",progName, LPStime());	    perror(errbuf);	    exit(1);	}#ifdef DEBUG	if (debug > 1) fprintf(stderr,"O%s	%s: connecting to socket %d on  %s (%s)\n",	    progName, LPStime(), ntohs(sp->s_port), inet_ntoa(sin.sin_addr),hostString);			       #endif DEBUG    /* keep trying forever to connect to server. Back off retry interval  */	if (connect(AFD, (caddr_t) &sin, sizeof(sin)) < 0) {	    sprintf(errbuf,"O%s	%s: unable to connect to '%s'",	        progName,LPStime(), hostString);	    perror(errbuf);	    close(AFD);	    if (failureCount > 0) {	        sleep(failureCount < 8 ? (1<<failureCount) : 360);	    }	    failureCount++;	    continue;	}	connected = TRUE;    }#ifdef DEBUG	if (debug > 1) fprintf(stderr,"O%s	%s: connected.\n",	    progName, LPStime());			       #endif DEBUG    return(AFD);}/* *		E n a b l e K e e p a l i v e * * Turn on the TCP socket option that does a "keep alive" protocol between * the two ends of a socket. We turn it on here in a separate subroutine, * rather than when the socket is created, because there are so many different * places where connections are made and it's easier just to wait until the * connection is made and then set the option. * * Inputs:		AFD		the socket file descriptor * Outputs:		none * Returns:		none * */EnableKeepalive(AFD)int AFD;{    int one=1;    int retval;    retval=setsockopt(AFD, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));    if (retval == 0) return;    fprintf(stderr,"O%s	%s: setsockopt(%d) failed to enable keepalive.\n",	progName, LPStime(), AFD);    return;}/*  * *		f a k e l o g 1 0 * * Quick and dirty integer log10 * * Inputs:		int N * Outputs:		none * Returns:		ceiling(log10(N)) * Side effects:	none */int fakelog10(N)int N;{    if (N<10) return(1);    if (N<100) return(2);    if (N<1000) return(3);    if (N<10000) return(4);    if (N<100000) return(5);    if (N<1000000) return(6);    if (N<10000000) return(7);    if (N<100000000) return(8);    if (N<1000000000) return(9);    return(13);			/* log10(32-bit infinity) */}/* *		g e t v a r * * Get the value of a variable out of a frame symbol list, with exactly * the same mechanism as "getenv" uses to get a variable out of the * environment. * * Inputs:		char *envstring		list to pick apart *			char *target		var name to search for * Outputs:		none * Returns		char *result * * Action: searches "envstring" for a name that matches "target". * (envstring is a string like "NAME=value^ANAME1=value1") * Getvar returns a pointer to the first character of "value" if "target" * matches "NAME". If no match is found, it returns NULL; * * The returned value is a pointer to a static string inside getvar, and * you must use it or copy it before calling getvar again. * */char *getvar(envstring, target)char *envstring;char *target;{    int i,j,k,l;    int slen;			/* length of source string "envstring" */    int tlen;			/* length of target string "target" */    static char valueString[RELAY_MAX_FRAME];    slen = strlen(envstring);    tlen = strlen(target);    for (i=0; i<=slen; i++) {	/* for each variable */	for (j=0; j<=tlen; j++) {	    if ((target[j] == (char) NULL) &&	        (envstring[i+j] == '=')) {   /* it matches. Copy to static string and return a pointer to it. */		    l=0;   		    for(k=i+j+1; k<=slen; k++) {		        valueString[l++] = envstring[k];			if ((envstring[k] == RELAY_ARG_SEP) ||			    (envstring[k] == (char) NULL)) break;		    }		    valueString[--l] = (char) NULL;		    return(valueString);	    }	    if (target[j] == envstring[i+j]) continue; /* so far, so good */   /* mismatch. abort inner loop and fast-forward outer loop */   	    for (k=i; k<=slen; k++) {	        if ((envstring[k] == RELAY_ARG_SEP)) {		    i = k;		    break;		}		if ((envstring[k] == (char) NULL)) {		    return ((char *) NULL);		}	    }	    break;	}    }    return( (char *) NULL);}/* * *		s m a t c h * * String matcher. Return a pointer to the location at which string b * is found as a substring in string a, or else return null if it is not * found. * * Before you get excited that this is not a Boyer-Moore matcher, or some * other high-powered scheme, please look at the places where it is used * and realize that it doesn't need to be fast. * * Inputs		char *a; char *b; * Outputs:		none * Result:		pointer to location in a of first char of b * Side effects:	none * */char *smatch(a,b)char *a,*b;{    int alen,blen,i,j;    alen = strlen(a);    blen = strlen(b);    if (blen > alen) return((char *) NULL);    if (alen == 0 && blen == 0) return(a);    for (j=0; j<=alen; j++) {        for (i=0; i<blen; i++) {	    if (a[j+i] != b[i]) goto breaker;	}	return(&a[j]);breaker: ;    }    return((char *) NULL);}

⌨️ 快捷键说明

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