📄 io.c
字号:
/* io.c - ber general i/o routines */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
#include <stdio.h>
#include <ctype.h>
#if PGPSOCKETSLDAP /* jason */
#include "pgpSocketsLDAP.h"
#else
#if defined( DOS )
#include "msdos.h"
#endif /* DOS || _WIN32 */
#ifdef MACOS
#include <stdlib.h>
#include "macos.h"
#else /* MACOS */
#if defined(NeXT) || defined(VMS)
#include <stdlib.h>
#else /* next || vms */
#include <malloc.h>
#endif /* next || vms */
#include <errno.h>
#include <sys/types.h>
#ifndef WIN32 /* marcd */
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#ifdef PCNFS
#include <tklib.h>
#endif /* PCNFS */
#endif /* MACOS */
#ifndef VMS
#include <memory.h>
#endif
#ifdef _WIN32
#include <winsock.h>
#include <io.h>
#define EMSGSIZE WSAEMSGSIZE
#endif /* _WIN32 */
#endif /* PGPSOCKETSLDAP */
#include <string.h>
#include "lber.h"
/*#ifdef PGPKEYSERVER*/
/*#include "pgpSrvGlobals.h"*/
/*#endif*/
#ifdef NEEDPROTOS
static int ber_realloc( BerElement *ber, unsigned long len );
static int ber_filbuf( Sockbuf *sb, long len );
static long BerRead( Sockbuf *sb, char *buf, long len );
#ifdef PCNFS
static int BerWrite( Sockbuf *sb, char *buf, long len );
#endif /* PCNFS */
#else
int ber_filbuf();
long BerRead();
static int ber_realloc();
#endif /* NEEDPROTOS */
#define bergetc( sb, len ) ( sb->sb_ber.ber_end > sb->sb_ber.ber_ptr ? \
(unsigned char)*sb->sb_ber.ber_ptr++ : \
ber_filbuf( sb, len ))
#if PGPSOCKETSLDAP /* jason */
#define read( s, b, l ) PGPReceive( s, b, l, kPGPReceiveFlagNone )
#define MAX_WRITE MAX_PGPInt32
#define BerWrite( sb, b, l ) PGPSend( sb->sb_sd, b, l, kPGPSendFlagNone )
#else
#ifdef MACOS
/*
* MacTCP/OpenTransport
*/
#define read( s, b, l ) PGPReceive( s, b, l, kPGPReceiveFlagNone )
#define MAX_WRITE MAX_PGPInt32
#define BerWrite( sb, b, l ) PGPSend( sb->sb_sd, b, l, kPGPSendFlagNone )
#else /* MACOS */
#ifdef DOS
#ifdef PCNFS
/*
* PCNFS (under DOS)
*/
#define read( s, b, l ) recv( s, b, l, 0 )
#define BerWrite( s, b, l ) send( s->sb_sd, b, (int) l, 0 )
#endif /* PCNFS */
#ifdef NCSA
/*
* NCSA Telnet TCP/IP stack (under DOS)
*/
#define read( s, b, l ) nread( s, b, l )
#define BerWrite( s, b, l ) netwrite( s->sb_sd, b, l )
#endif /* NCSA */
#ifdef WINSOCK
/*
* Windows Socket API (under DOS/Windows 3.x)
*/
#define read( s, b, l ) recv( s, b, l, 0 )
#define BerWrite( s, b, l ) send( s->sb_sd, b, l, 0 )
#endif /* WINSOCK */
#else /* DOS */
#ifdef _WIN32
/*
* 32-bit Windows Socket API (under Windows NT or Windows 95)
*/
#define read( s, b, l ) recv( s, b, l, 0 )
#define BerWrite( s, b, l ) send( s->sb_sd, b, l, 0 )
#else /* _WIN32 */
#ifdef VMS
/*
* VMS -- each write must be 64K or smaller
*/
#define MAX_WRITE 65535
#define BerWrite( sb, b, l ) write( sb->sb_sd, b, (l<MAX_WRITE)? l : MAX_WRITE)
#else /* VMS */
/*
* everything else (Unix/BSD 4.3 socket API)
*/
#define BerWrite( sb, b, l ) write( sb->sb_sd, b, l )
#endif /* VMS */
#define udp_read( sb, b, l, al ) recvfrom(sb->sb_sd, (char *)b, l, 0, \
(struct sockaddr *)sb->sb_fromaddr, \
(al = sizeof(struct sockaddr), &al))
#define udp_write( sb, b, l ) sendto(sb->sb_sd, (char *)(b), l, 0, \
(struct sockaddr *)sb->sb_useaddr, sizeof(struct sockaddr))
#endif /* _WIN32 */
#endif /* DOS */
#endif /* MACOS */
#endif /* PGPSOCKETSLDAP */
#ifndef udp_read
#define udp_read( sb, b, l, al ) CLDAP NOT SUPPORTED
#define udp_write( sb, b, l ) CLDAP NOT SUPPORTED
#endif /* udp_read */
#define EXBUFSIZ 1024
int
ber_filbuf( Sockbuf *sb, long len )
{
short rc;
#ifdef CLDAP
int addrlen;
#endif /* CLDAP */
if ( sb->sb_ber.ber_buf == NULL ) {
if ( (sb->sb_ber.ber_buf = (char *) malloc( READBUFSIZ )) ==
NULL )
return( -1 );
sb->sb_ber.ber_ptr = sb->sb_ber.ber_buf;
sb->sb_ber.ber_end = sb->sb_ber.ber_buf;
}
if ( sb->sb_naddr > 0 ) {
#ifdef CLDAP
rc = udp_read(sb, sb->sb_ber.ber_buf, READBUFSIZ, addrlen );
#ifdef LDAP_DEBUG
if ( lber_debug ) {
fprintf( stderr, "ber_filbuf udp_read %d bytes\n",
rc );
if ( lber_debug > 1 && rc > 0 )
lber_bprint( sb->sb_ber.ber_buf, rc );
}
#endif /* LDAP_DEBUG */
#else /* CLDAP */
rc = -1;
#endif /* CLDAP */
} else {
/*#ifdef PGPKEYSERVER*/
PGPSocketsTimeValue timeWait;
PGPSocketSet ReadFDSet;
/* if (!sb->sb_bTLS) {*/
/* timeWait.tv_sec = pgpMax(g->timeTimeLimit * 2, 300);*/
timeWait.tv_sec = 300;
timeWait.tv_usec = 0;
PGPSOCKETSET_ZERO(&ReadFDSet);
PGPSOCKETSET_SET(sb->sb_sd, &ReadFDSet);
/* rc = PGPSelect(SocketRefToSocketNumber(sb->sb_sd) + 1, &ReadFDSet, */
rc = PGPSelect((int) sb->sb_sd + 1, &ReadFDSet,
NULL, NULL, &timeWait);
if (rc == 0)
return kPGPError_SocketsTimedOut;
else if (rc < 0)
return -1;
/* }*/
/*#endif*/
rc = read( sb->sb_sd, sb->sb_ber.ber_buf,
((sb->sb_options & LBER_NO_READ_AHEAD) &&
(len < READBUFSIZ)) ?
len : READBUFSIZ );
#if defined(WIN32) && !defined(PGPSOCKETSLDAP) /* jason */
if (rc == -1)
{
errno = WSAGetLastError();
}
#endif
}
if ( rc > 0 ) {
sb->sb_ber.ber_ptr = sb->sb_ber.ber_buf + 1;
sb->sb_ber.ber_end = sb->sb_ber.ber_buf + rc;
return( (unsigned char)*sb->sb_ber.ber_buf );
}
return( -1 );
}
long
BerRead( Sockbuf *sb, char *buf, long len )
{
int c;
long nread = 0;
while ( len > 0 ) {
if ( (c = bergetc( sb, len )) < 0 ) {
if ( nread > 0 )
break;
return( c );
}
*buf++ = c;
nread++;
len--;
}
return( nread );
}
long
ber_read( BerElement *ber, char *buf, unsigned long len )
{
unsigned long actuallen, nleft;
nleft = ber->ber_end - ber->ber_ptr;
actuallen = nleft < len ? nleft : len;
SAFEMEMCPY( buf, ber->ber_ptr, (size_t)actuallen );
ber->ber_ptr += actuallen;
return( (long)actuallen );
}
long
ber_write( BerElement *ber, char *buf, unsigned long len, int nosos )
{
if ( nosos || ber->ber_sos == NULL ) {
if ( ber->ber_ptr + len > ber->ber_end ) {
if ( ber_realloc( ber, len ) != 0 )
return( -1 );
}
SAFEMEMCPY( ber->ber_ptr, buf, (size_t)len );
ber->ber_ptr += len;
return( len );
} else {
if ( ber->ber_sos->sos_ptr + len > ber->ber_end ) {
if ( ber_realloc( ber, len ) != 0 )
return( -1 );
}
SAFEMEMCPY( ber->ber_sos->sos_ptr, buf, (size_t)len );
ber->ber_sos->sos_ptr += len;
ber->ber_sos->sos_clen += len;
return( len );
}
}
static int
ber_realloc( BerElement *ber, unsigned long len )
{
unsigned long need, have, total;
Seqorset *s;
long off;
char *oldbuf;
have = (ber->ber_end - ber->ber_buf) / EXBUFSIZ;
need = (len < EXBUFSIZ ? 1 : (len + (EXBUFSIZ - 1)) / EXBUFSIZ);
total = have * EXBUFSIZ + need * EXBUFSIZ;
oldbuf = ber->ber_buf;
if ( ber->ber_buf == NULL ) {
if ( (ber->ber_buf = (char *) malloc( (size_t)total )) == NULL )
return( -1 );
} else if ( (ber->ber_buf = (char *) realloc( ber->ber_buf,
(size_t)total )) == NULL )
return( -1 );
ber->ber_end = ber->ber_buf + total;
/*
* If the stinking thing was moved, we need to go through and
* reset all the sos and ber pointers. Offsets would've been
* a better idea... oh well.
*/
if ( ber->ber_buf != oldbuf ) {
ber->ber_ptr = ber->ber_buf + (ber->ber_ptr - oldbuf);
for ( s = ber->ber_sos; s != NULLSEQORSET; s = s->sos_next ) {
off = s->sos_first - oldbuf;
s->sos_first = ber->ber_buf + off;
off = s->sos_ptr - oldbuf;
s->sos_ptr = ber->ber_buf + off;
}
}
return( 0 );
}
void
ber_free( BerElement *ber, int freebuf )
{
if ( freebuf && ber->ber_buf != NULL )
free( ber->ber_buf );
free( (char *) ber );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -