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

📄 lpcomm.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif VMS#ifdef VMS    if (debug > 7)	fprintf(stderr,"Entering LP_C_send, ast_completed[%d] = %d\n", ServerFD,	    ast_completed[ServerFD]);#endif VMS    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(DECNET_MAX_FRAME-fixedLength);    if (mlen == 0) mlen = strlen(ic);    nlen = mlen;    if (nlen + fixedLength >= DECNET_MAX_FRAME)        nlen = DECNET_MAX_FRAME - fixedLength - 1;    tlen = nlen;    for(n=fakelog10(tlen); n>0; n--) {	/* the size */        *jc++ = '0'+ (tlen / pow10[n]);	tlen %= pow10[n];    }    *jc++ = ' ';    memcpy(jc,ic,nlen);		/* the data */    ic += nlen;    jc += nlen;    packetLength = (int) (jc - packetBuffer);    *jc++ = (char) NULL;        if (debug > 6) {	fprintf(stderr, "%s  %s:  %d<-smsg(", progName, LPStime(),ServerFD);	/* Using fwrite to output the packet allows for imbeded NULLs */	fwrite(packetBuffer, sizeof(char), packetLength, stderr);	fputs(")\n", stderr); }     /* put closing parentheses on output */ #ifndef VMS    signal(SIGPIPE, SIG_IGN);#endif VMS    if (debug > 7 ) {	if (packetLength > DECNET_MAX_FRAME) {	    fprintf(stderr,"%s  %s:  assertion failed, send(%d chars)\n",		progName, LPStime(), packetLength);	}    }#ifndef VMS    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);	}    }#else VMS    /*     * The "send" should be "non-blocking", but for now, implement the same     * as it is in ULTRIX.     */    WriteStatus = SYS$QIOW(0, fd_map[ServerFD], IO$_WRITEVBLK, &iosb, 0, 0,	&packetBuffer, packetLength, 0, 0, 0, 0);    if (WriteStatus != SS$_NORMAL) {	fprintf(stderr,"%s  %s:  qiow(write chan = %d) failed, status = %d\n",	        progName,LPStime(),ServerFD,WriteStatus);	exit(0);    }    WriteStatus = iosb[0];    if (WriteStatus != SS$_NORMAL) {	fprintf(stderr,"%s  %s:  qiow(write chan = %d) failed, status = %d\n",	        progName,LPStime(),ServerFD,WriteStatus);	exit(0);    }#endif VMS    /* Check to see if we fragmented, and do something about it */    if (mlen > nlen) {	if (debug > 7)	    fprintf(stderr,"%s  %s:  frame fragmented.\n",		progName, LPStime());        LP_C_send(ServerFD, Opcode, ic, ID, mlen-nlen);    }#ifdef VMS    if (debug > 7)	fprintf(stderr,"Exiting LP_C_send, ast_completed[%d] = %d\n", ServerFD,	    ast_completed[ServerFD]);#endif VMS    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;#ifndef VMS    sendFlag = MSG_OOB;		/* enable TCP Urgent Data */#endif VMS    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;{    int status;    if (FD < 0) return;#ifndef VMS    close(FD);#else VMS    unmap_fd(FD);                  /* Mark "ULTIRX" FD empty */     status = sys$dassgn(fd_map[FD]);    if (debug > 0) {	fprintf(stderr,"%s  %s:  deassigned channel = %d, status is...\n",	    progName, LPStime(), fd_map[FD]);	get_message(status);		/* get message string into errbuf */	fprintf(stderr,"%s\n",errbuf);	fflush(stderr);	fsync(fileno(stderr));    }#endif VMS    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;{	return(open_channel(nodename));}/* *		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;#ifndef VMS    retval=setsockopt(AFD, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(int));    if (retval == 0) return;    fprintf(stderr,"%s  %s:  setsockopt(%d) failed to enable keepalive.\n",	progName, LPStime(), AFD);#endif VMS    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[DECNET_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 + -