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

📄 fd2tupkt.c

📁 ftam等标准协议服务器和客户端的源代码。
💻 C
字号:
/* fd2tpkt.c - read/write a TPDU thru a socket */#ifndef	lintstatic char *rcsid = "$Header: /f/iso/tsap/RCS/fd2tpkt.c,v 5.0 88/07/21 14:59:28 mrose Rel $";#endif/*  * $Header: /f/iso/tsap/RCS/fd2tpkt.c,v 5.0 88/07/21 14:59:28 mrose Rel $ * * * $Log$ *//* *				  NOTICE * *    Acquisition, use, and distribution of this module and related *    materials are subject to the restrictions of a license agreement. *    Consult the Preface in the User's Manual for the full terms of *    this agreement. * *//* LINTLIBRARY */#include <stdio.h>#include <signal.h>#include "tpkt.h"#include "tailor.h"/*  */struct tsapkt *fd2tpkt (fd, initfnx, readfnx)int	fd;IFP	initfnx,	readfnx;{    register struct tsapkt *t;    if ((t = newtpkt (0)) == NULL)	return NULL;    if ((t -> t_errno = fd2tpktaux (fd, t, initfnx, readfnx)) != OK) {	if (t -> t_vdata != NULL)	    free (t -> t_vdata), t -> t_vdata = NULL, t -> t_vlen = 0;	if (t -> t_qbuf)	    free ((char *) t -> t_qbuf), t -> t_qbuf = NULL;    }#ifdef	DEBUG    if (tsaplevel & ISODELOG_PDUS) {	if (strcmp (tsapfile, "-")) {	    char    file[BUFSIZ];	    FILE   *fp;	    (void) sprintf (file, tsapfile, getpid ());	    if (fp = fopen (file, "a")) {		tpkt2text (fp, t, 1);		(void) fclose (fp);	    }	}	else {	    (void) fflush (stdout);	    tpkt2text (stderr, t, 1);	}    }#endif    return t;}/*  */static int  fd2tpktaux (fd, t, initfnx, readfnx)int	fd;register struct tsapkt *t;IFP	initfnx,	readfnx;{    register int    code,                    len,                    vlen;    register char  *vptr;    if ((code = (*initfnx) (fd, t)) != OK)	return code;    if (t -> t_li > TPDU_MAXLEN (t))	return DR_LENGTH;    switch (TPDU_CODE (t)) {	case TPDU_CR:	case TPDU_CC:	    if (t -> t_li < TPDU_MINLEN (t, CR))		return DR_LENGTH;	    if (readx (fd, (char *) &t -> t_cr, CR_SIZE (t), readfnx)		    != CR_SIZE (t))		return DR_NETWORK;	    if (vlen = t -> t_vlen = t -> t_li - TPDU_MINLEN (t, CR)) {		if ((vptr = t -> t_vdata = malloc ((unsigned) vlen)) == NULL)		    return DR_CONGEST;		if (readx (fd, t -> t_vdata, t -> t_vlen, readfnx)			!= t -> t_vlen)		    return DR_NETWORK;		for (; vlen > 0; vptr += len, vlen -= len) {		    int	    ilen;		    		    if (vlen < 2)			return DR_LENGTH;		    code = *vptr++ & 0xff;		    len = *vptr++ & 0xff;		    if ((vlen -= 2) < len)			return DR_LENGTH;		    switch (code) {			case VDAT_TSAP_SRV:			    if ((ilen = len) > sizeof t -> t_called)				ilen = sizeof t -> t_called;			    bcopy (vptr, t -> t_called,					t -> t_calledlen = ilen);			    break;			case VDAT_TSAP_CLI:			    if ((ilen = len) > sizeof t -> t_calling)				ilen = sizeof t -> t_calling;			    bcopy (vptr, t -> t_calling,					t -> t_callinglen = ilen);			    break;			case VDAT_SIZE:			    if (len != 1)				return DR_LENGTH;			    t -> t_tpdusize = *vptr & 0xff;			    break;			case VDAT_OPTIONS:			    if (len != 1)				return DR_LENGTH;			    t -> t_options = *vptr & 0xff;			    break;			case VDAT_ALTERNATE:			    {				register int i;				register char *ap;				for (ap = vptr, i = len; i > 0; ap++, i--)				    t -> t_cr.cr_alternate |=						1 << ((*ap >> 4) & 0x0f);			    }			    break;			case VDAT_VRSN:			case VDAT_SECURITY:			case VDAT_CHECKSUM:			case VDAT_ACKTIME:			case VDAT_THROUGHPUT:			case VDAT_ERRORATE:			case VDAT_PRIORITY:			case VDAT_DELAY:			case VDAT_TTR:			    break;			default: 			    return DR_PROTOCOL;		    }		}	    }	    break;	case TPDU_DR:	    if (t -> t_li < TPDU_MINLEN (t, DR))		return DR_LENGTH;	    if (readx (fd, (char *) &t -> t_dr, DR_SIZE (t), readfnx)		    != DR_SIZE (t))		return DR_NETWORK;	    if (vlen = t -> t_vlen = t -> t_li - TPDU_MINLEN (t, DR)) {		if ((vptr = t -> t_vdata = malloc ((unsigned) vlen)) == NULL)		    return DR_CONGEST;		if (readx (fd, t -> t_vdata, t -> t_vlen, readfnx)			!= t -> t_vlen)		    return DR_NETWORK;		for (; vlen > 0; vptr += len, vlen -= len) {		    if (vlen < 2)			return DR_LENGTH;		    code = *vptr++ & 0xff;		    len = *vptr++ & 0xff;		    if ((vlen -= 2) < len)			return DR_LENGTH;		    switch (code) {			case VDAT_ADDITIONAL:			case VDAT_CHECKSUM:			    break;			default: 			    return DR_PROTOCOL;		    }		}	    }	    break;	case TPDU_DT:	    if (t -> t_li < TPDU_MINLEN (t, DT))		return DR_LENGTH;	    if (readx (fd, (char *) &t -> t_dt, DT_SIZE (t), readfnx)		    != DT_SIZE (t))		return DR_NETWORK;	    if (vlen = t -> t_vlen = t -> t_li - TPDU_MINLEN (t, DT)) {		if ((vptr = t -> t_vdata = malloc ((unsigned) vlen)) == NULL)		    return DR_CONGEST;		if (readx (fd, t -> t_vdata, t -> t_vlen, readfnx)			!= t -> t_vlen)		    return DR_NETWORK;		for (; vlen > 0; vptr += len, vlen -= len) {		    if (vlen < 2)			return DR_LENGTH;		    code = *vptr++ & 0xff;		    len = *vptr++ & 0xff;		    if ((vlen -= 2) < len)			return DR_LENGTH;		    switch (code) {			case VDAT_CHECKSUM:			    break;			default: 			    return DR_PROTOCOL;		    }		}	    }	    break;	case TPDU_ED: 	    if (t -> t_li < TPDU_MINLEN (t, ED))		return DR_LENGTH;	    if (readx (fd, (char *) &t -> t_ed, ED_SIZE (t), readfnx)		    != ED_SIZE (t))		return DR_NETWORK;	    t -> t_ed.ed_nr = ntohs (t -> t_ed.ed_nr);	    if (vlen = t -> t_vlen = t -> t_li - TPDU_MINLEN (t, ED)) {		if ((vptr = t -> t_vdata = malloc ((unsigned) vlen)) == NULL)		    return DR_CONGEST;		if (readx (fd, t -> t_vdata, t -> t_vlen, readfnx)			!= t -> t_vlen)		    return DR_NETWORK;		for (; vlen > 0; vptr += len, vlen -= len) {		    if (vlen < 2)			return DR_LENGTH;		    code = *vptr++ & 0xff;		    len = *vptr++ & 0xff;		    if ((vlen -= 2) < len)			return DR_LENGTH;		    switch (code) {			case VDAT_CHECKSUM:			case VDAT_SUBSEQ:			case VDAT_FLOWCTL:			    break;			default: 			    return DR_PROTOCOL;		    }		}	    }	    break;	case TPDU_ER:	    if (t -> t_li < TPDU_MINLEN (t, ER))		return DR_LENGTH;	    if (readx (fd, (char *) &t -> t_er, ER_SIZE (t), readfnx)		    != ER_SIZE (t))		return DR_NETWORK;	    if (vlen = t -> t_vlen = t -> t_li - TPDU_MINLEN (t, ER)) {		if ((vptr = t -> t_vdata = malloc ((unsigned) vlen)) == NULL)		    return DR_CONGEST;		if (readx (fd, t -> t_vdata, t -> t_vlen, readfnx)			!= t -> t_vlen)		    return DR_NETWORK;		for (; vlen > 0; vptr += len, vlen -= len) {		    if (vlen < 2)			return DR_LENGTH;		    code = *vptr++ & 0xff;		    len = *vptr++ & 0xff;		    if ((vlen -= 2) < len)			return DR_LENGTH;		    switch (code) {			case VDAT_INVALID:			case VDAT_CHECKSUM:			    break;			default: 			    return DR_PROTOCOL;		    }		}	    }	    break;	default: 	    return DR_PROTOCOL;    }    if (len = TPDU_USRLEN (t)) {	if ((t -> t_qbuf = (struct qbuf *)			    malloc (sizeof *t -> t_qbuf + (unsigned) len))		== NULL)	    return DR_CONGEST;	t -> t_qbuf -> qb_forw = t -> t_qbuf -> qb_back = t -> t_qbuf;	if (readx (fd, t -> t_qbuf -> qb_data = t -> t_qbuf -> qb_base,		t -> t_qbuf -> qb_len = len, readfnx) != len)	    return DR_NETWORK;    }    return OK;}/*  */static int  readx (fd, buffer, n, readfnx)int	fd;char    *buffer;int	n;IFP	readfnx;{    register int    i,                    cc;    register char   *bp;    for (bp = buffer, i = n; i > 0; bp += cc, i -= cc) {	switch (cc = (*readfnx) (fd, bp, i)) {	    case NOTOK: 		return (i = bp - buffer) ? i : NOTOK;	    case OK: 		break;	    default: 		continue;	}	break;    }    return (bp - buffer);}/*  */int	tpkt2fd (fd, t, writefnx)int	fd;register struct tsapkt *t;IFP	writefnx;{    SBV	    smask;    int     i,	    ilen,            ulen;    char   *cp,	   *vptr,           *outptr;    register struct udvec  *uv;    SFP	    pstat;    if (t -> t_errno != OK)	return t -> t_errno;    if (t -> t_vrsn != TPKT_VRSN)	if (t -> t_vrsn)	    return DR_PROTOCOL;	else	    t -> t_vrsn = TPKT_VRSN;    if (t -> t_vdata != NULL) {	free (t -> t_vdata);	t -> t_vdata = NULL;    }    t -> t_vlen = 0;    for (ulen = 0, uv = t -> t_udvec; uv -> uv_base; uv++)	ulen += uv -> uv_len;    switch (TPDU_CODE (t)) {	case TPDU_CR:	case TPDU_CC:	    if ((vptr = t -> t_vdata =		    malloc ((unsigned) (3 + 7 + (2 + t -> t_callinglen)				 + (2 + t -> t_calledlen) + 3))) == NULL)		return DR_CONGEST;	    if (t -> t_options) {		*vptr++ = VDAT_OPTIONS;		*vptr++ = 1;		*vptr++ = t -> t_options;		t -> t_vlen += 3;	    }	    if (CR_CLASS (t) != CR_CLASS_TP0 && t -> t_cr.cr_alternate) {		/* XXX: this doesn't preserve the order of alternates */		*vptr++ = VDAT_ALTERNATE;		cp = vptr++;		if (t -> t_cr.cr_alternate & ALT_TP0)		    *vptr++ = CR_CLASS_TP0;		if (t -> t_cr.cr_alternate & ALT_TP1)		    *vptr++ = CR_CLASS_TP1;		if (t -> t_cr.cr_alternate & ALT_TP2)		    *vptr++ = CR_CLASS_TP2;		if (t -> t_cr.cr_alternate & ALT_TP3)		    *vptr++ = CR_CLASS_TP3;		if (t -> t_cr.cr_alternate & ALT_TP4)		    *vptr++ = CR_CLASS_TP4;		i = (vptr - cp) - 1;		*cp = i & 0xff;		t -> t_vlen += (2 + i) & 0xff;	    }	    if (t -> t_callinglen > 0) {		*vptr++ = VDAT_TSAP_CLI;		*vptr++ = t -> t_callinglen;		bcopy (t -> t_calling, vptr, t -> t_callinglen);		vptr += t -> t_callinglen;		t -> t_vlen += 2 + t -> t_callinglen;	    }	    if (t -> t_calledlen > 0) {		*vptr++ = VDAT_TSAP_SRV;		*vptr++ = t -> t_calledlen;		bcopy (t -> t_called, vptr, t -> t_calledlen);		vptr += t -> t_calledlen;		t -> t_vlen += 2 + t -> t_calledlen;	    }	    if (t -> t_tpdusize) {		*vptr++ = VDAT_SIZE;		*vptr++ = 1;		*vptr++ = t -> t_tpdusize;		t -> t_vlen += 3;	    }	    if (t -> t_vlen == 0) {		free (t -> t_vdata);		t -> t_vdata = NULL;	    }	    t -> t_li = TPDU_MINLEN (t, CR) + t -> t_vlen;	    outptr = (char *) &t -> t_cr;	    ilen = CR_SIZE (t);	    break;	case TPDU_DR: 	    t -> t_li = TPDU_MINLEN (t, DR) + t -> t_vlen;	    outptr = (char *) &t -> t_dr;	    ilen = DR_SIZE (t);	    break;	case TPDU_DT: 	    t -> t_li = TPDU_MINLEN (t, DT) + t -> t_vlen;	    outptr = (char *) &t -> t_dt;	    ilen = DT_SIZE (t);	    break;	case TPDU_ED: 	    t -> t_li = TPDU_MINLEN (t, ED) + t -> t_vlen;	    t -> t_ed.ed_nr = htons (t -> t_ed.ed_nr);	    outptr = (char *) &t -> t_ed;	    ilen = ED_SIZE (t);	    break;	case TPDU_ER: 	    t -> t_li = TPDU_MINLEN (t, ER) + t -> t_vlen;	    outptr = (char *) &t -> t_er;	    ilen = ER_SIZE (t);	    if (ulen > 0)		return DR_PROTOCOL;	    break;	default: 	    return DR_PROTOCOL;    }    t -> t_length = htons (t -> t_li + 5 + ulen);#ifdef	DEBUG    if (tsaplevel & ISODELOG_PDUS) {	if (strcmp (tsapfile, "-")) {	    char    file[BUFSIZ];	    FILE   *fp;	    (void) sprintf (file, tsapfile, getpid ());	    if (fp = fopen (file, "a")) {		tpkt2text (fp, t, 0);		(void) fclose (fp);	    }	}	else {	    (void) fflush (stdout);	    tpkt2text (stderr, t, 0);	}    }#endif    pstat = signal (SIGPIPE, SIG_IGN);    smask = sigioblock ();    i = (*writefnx) (fd, t, outptr, ilen);    (void) sigiomask (smask);    (void) signal (SIGPIPE, pstat);    return (i != NOTOK ? OK : DR_NETWORK);}/*  */struct tsapkt *newtpkt (code)int	code;{    register struct tsapkt *t;    t = (struct tsapkt *) calloc (1, sizeof *t);    if (t == NULL)	return NULL;    t -> t_vrsn = TPKT_VRSN;    t -> t_code = code;    return t;}int	freetpkt (t)register struct tsapkt *t;{    if (t == NULL)	return;    if (t -> t_vdata)	free (t -> t_vdata);    if (t -> t_qbuf)	free ((char *) t -> t_qbuf);    free ((char *) t);}

⌨️ 快捷键说明

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