1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-11-04 20:38:50 +01:00

Keyserver access is now supported under W32

This commit is contained in:
Werner Koch 2001-03-13 13:00:10 +00:00
parent 5e79cb47e0
commit aaabc72ec0
27 changed files with 6579 additions and 6020 deletions

View File

@ -1,3 +1,7 @@
2001-03-13 Werner Koch <wk@gnupg.org>
* configure.in: Add copyright notice and -lwsock32.
2001-03-12 Werner Koch <wk@gnupg.org>
* INSTALL: Add a note to VPATH builds.

3
NEWS
View File

@ -32,6 +32,9 @@
* New option --ignore-crc-error
* Keyserver support for the W32 version.
Noteworthy changes in version 1.0.4 (2000-10-17)
------------------------------------------------

14
TODO
View File

@ -8,11 +8,6 @@
* Can we output things like the preferences?
** Check whether the use of -u and --clearsign created 2 signatures.
removed dups from the skclist.
* Replace mkinstalldir etc. with nnewer copies.
* We need another special packet at the end of a clearsign message to mark
it's end and allow for multiple signature for one message.
@ -23,23 +18,20 @@
* If there is no secure memory, allocate more memory for the secure
memory block or do it in all cases.
* List all UserID with GOODSIG?
* add a way to set expiration time for key signatures.
* add some minor things vor VMS.
* Don't get the ultimately trusted keys from the secring but store
it permanently in the trustdb. This way we don't need a secring at all.
[ Solved by re-introducing --trusted-key ]
[ currently solved by re-introducing --trusted-key ] Eventually we
will have commands --{add,remove}-trusted-key which keeps them in
special trustdb records.
* Use DSA keys with the test suite.
* g10/trustdb.c (make_sig_records): fix the fixme.
* No TCP support yet for W32? arggg - should go into a separate program
anyway.
* Replace Valid/Invalid by Known/Unknown?
* Fix the bug in the mips assembler code

View File

@ -1,5 +1,21 @@
dnl Configure script for GnuPG
dnl Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
dnl
dnl Configure template for GNUPG
dnl This file is part of GnuPG.
dnl
dnl GnuPG is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl GnuPG is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with this program; if not, write to the Free Software
dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
dnl
dnl (Process this file with autoconf to produce a configure script.)
AC_REVISION($Revision$)dnl
@ -693,6 +709,17 @@ GNUPG_DO_LINK_FILES
GNUPG_CHECK_GNUMAKE
# add some extra libs here so that previous tests don't fail for
# mysterious reasons - the final link step shoudl bail out.
case "${target}" in
*-*-mingw32*)
LIBS="$LIBS -lwsock32"
;;
*)
;;
esac
if test "$GCC" = yes; then
if test "$MAINTAINER_MODE" = "yes"; then
CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes"

View File

@ -1,3 +1,15 @@
2001-03-13 Werner Koch <wk@gnupg.org>
* ringedit.c (keyring_copy): flush the new iobuf chaces before
rename or remove operations. This is mainly needed for W32.
* hkp.c [HAVE_DOSISH_SYSTEM]: Removed the disabled code because we
have now W32 socket support in ../util/http.c
* skclist.c (key_present_in_sk_list): New.
(is_duplicated_entry): New.
(build_sk_list): Check for duplicates and do that before unlocking.
2001-03-12 Werner Koch <wk@gnupg.org>
* armor.c (parse_header_line): Removed double empty line check.

View File

@ -38,15 +38,6 @@
static int urlencode_filter( void *opaque, int control,
IOBUF a, byte *buf, size_t *ret_len);
#ifdef HAVE_DOSISH_SYSTEM
static void
not_implemented(void)
{
log_error("keyserver access is not yet available for MS-Windows\n");
}
#endif
/****************
* Try to import the key with KEYID from a keyserver but ask the user
* before doing so.
@ -58,10 +49,6 @@ not_implemented(void)
int
hkp_ask_import( u32 *keyid )
{
#ifdef HAVE_DOSISH_SYSTEM
not_implemented();
return -1;
#else
struct http_context hd;
char *request;
int rc;
@ -93,7 +80,6 @@ hkp_ask_import( u32 *keyid )
m_free( request );
return rc;
#endif
}
@ -101,10 +87,6 @@ hkp_ask_import( u32 *keyid )
int
hkp_import( STRLIST users )
{
#ifdef HAVE_DOSISH_SYSTEM
not_implemented();
return -1;
#else
if( !opt.keyserver_name ) {
log_error(_("no keyserver known (use option --keyserver)\n"));
return -1;
@ -125,17 +107,12 @@ hkp_import( STRLIST users )
log_inc_errorcount();
}
return 0;
#endif
}
int
hkp_export( STRLIST users )
{
#ifdef HAVE_DOSISH_SYSTEM
not_implemented();
return -1;
#else
int rc;
armor_filter_context_t afx;
IOBUF temp = iobuf_temp();
@ -211,7 +188,6 @@ hkp_export( STRLIST users )
}
http_close( &hd );
return rc;
#endif
}
static int

View File

@ -143,7 +143,8 @@ add_gpg_control( CTX c, PACKET *pkt )
}
else if ( pkt->pkt.gpg_control->control == 2 ) {
/* Pipemode control packet */
#warning We have to do some sanity checks all over the place
#warning the --pipemode does not yet work
/* FIXME: We have to do more sanity checks all over the place */
if ( pkt->pkt.gpg_control->datalen < 2 )
log_fatal ("invalid pipemode control packet length\n");
if (pkt->pkt.gpg_control->data[0] == 1) {

View File

@ -1529,6 +1529,8 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
/* rename and make backup file */
if( !rentry->secret ) { /* but not for secret keyrings */
iobuf_ioctl (NULL, 2, 0, bakfname );
iobuf_ioctl (NULL, 2, 0, rentry->fname );
#ifdef HAVE_DOSISH_SYSTEM
remove( bakfname );
#endif
@ -1539,6 +1541,8 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
goto leave;
}
}
iobuf_ioctl (NULL, 2, 0, tmpfname );
iobuf_ioctl (NULL, 2, 0, rentry->fname );
#ifdef HAVE_DOSISH_SYSTEM
remove( rentry->fname );
#endif

View File

@ -60,6 +60,27 @@ is_insecure( PKT_secret_key *sk )
}
static int
key_present_in_sk_list(SK_LIST sk_list, PKT_secret_key *sk)
{
for (; sk_list; sk_list = sk_list->next) {
if ( !cmp_secret_keys(sk_list->sk, sk) )
return 0;
}
return -1;
}
static int
is_duplicated_entry (STRLIST list, STRLIST item)
{
for(; list && list != item; list = list->next) {
if ( !strcmp (list->d, item->d) )
return 1;
}
return 0;
}
int
build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
unsigned use )
@ -78,6 +99,7 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
}
else if( !(rc=check_pubkey_algo2(sk->pubkey_algo, use)) ) {
SK_LIST r;
if( sk->version == 4 && (use & PUBKEY_USAGE_SIG)
&& sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
log_info("this is a PGP generated "
@ -103,17 +125,36 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
}
}
else {
STRLIST locusr_orig = locusr;
for(; locusr; locusr = locusr->next ) {
PKT_secret_key *sk;
rc = 0;
/* Do an early check agains duplicated entries. However this
* won't catch all duplicates because the user IDs may be
* specified in different ways.
*/
if ( is_duplicated_entry ( locusr_orig, locusr ) ) {
log_error(_("skipped `%s': duplicated\n"), locusr->d );
continue;
}
sk = m_alloc_clear( sizeof *sk );
sk->req_usage = use;
if( (rc = get_seckey_byname( sk, locusr->d, unlock )) ) {
if( (rc = get_seckey_byname( sk, locusr->d, 0 )) ) {
free_secret_key( sk ); sk = NULL;
log_error(_("skipped `%s': %s\n"), locusr->d, g10_errstr(rc) );
}
else if ( key_present_in_sk_list(sk_list, sk) == 0) {
free_secret_key(sk); sk = NULL;
log_debug(_("skipped: secret key already present\n"));
}
else if ( unlock && (rc = check_secret_key( sk, 0 )) ) {
free_secret_key( sk ); sk = NULL;
log_error(_("skipped `%s': %s\n"), locusr->d, g10_errstr(rc) );
}
else if( !(rc=check_pubkey_algo2(sk->pubkey_algo, use)) ) {
SK_LIST r;
if( sk->version == 4 && (use & PUBKEY_USAGE_SIG)
&& sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
log_info(_("skipped `%s': this is a PGP generated "

View File

@ -79,10 +79,12 @@ IOBUF iobuf_temp(void);
IOBUF iobuf_temp_with_content( const char *buffer, size_t length );
IOBUF iobuf_open( const char *fname );
IOBUF iobuf_fdopen( int fd, const char *mode );
IOBUF iobuf_sockopen( int fd, const char *mode );
IOBUF iobuf_fopen( const char *fname, const char *mode );
IOBUF iobuf_create( const char *fname );
IOBUF iobuf_append( const char *fname );
IOBUF iobuf_openrw( const char *fname );
int iobuf_ioctl ( IOBUF a, int cmd, int intval, void *ptrval );
int iobuf_close( IOBUF iobuf );
int iobuf_cancel( IOBUF iobuf );

870
po/da.po

File diff suppressed because it is too large Load Diff

833
po/de.po

File diff suppressed because it is too large Load Diff

870
po/eo.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

870
po/fr.po

File diff suppressed because it is too large Load Diff

870
po/id.po

File diff suppressed because it is too large Load Diff

870
po/it.po

File diff suppressed because it is too large Load Diff

870
po/ja.po

File diff suppressed because it is too large Load Diff

872
po/nl.po

File diff suppressed because it is too large Load Diff

870
po/pl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

876
po/ru.po

File diff suppressed because it is too large Load Diff

870
po/sv.po

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,14 @@
2001-03-13 Werner Koch <wk@gnupg.org>
* iobuf.c (iobuf_sockopen): New.
(sock_filter) [__MINGW32__]: New.
(iobuf_ioctl): New.
(file_filter): Implemented keep_open mode.
* http.c (http_open, http_wait_response): Replaced iobuf_fdopen by
iobuf_sockopen and use an iobuf_ioctl to avoid the dup().
(deinit_sockets, init_sockets) [__MINGW32__]: New.
(connect_server, write_server): Add code to work with W32 sockets.
2001-03-12 Werner Koch <wk@gnupg.org>
* strgutil.c (check_trailing_chars,check_trailing_ws): New.

View File

@ -26,8 +26,9 @@
#include <ctype.h>
#include <errno.h>
#ifndef HAVE_DOSISH_SYSTEM
#ifdef __MINGW32__
#include <windows.h>
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
@ -36,6 +37,7 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include "util.h"
#include "iobuf.h"
@ -43,6 +45,12 @@
#include "http.h"
#ifdef __MINGW32__
#define sock_close(a) closesocket(a)
#else
#define sock_close(a) close(a)
#endif
#define MAX_LINELEN 20000 /* max. length of a HTTP line */
#define VALID_URI_CHARS "abcdefghijklmnopqrstuvwxyz" \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
@ -67,6 +75,38 @@ static int parse_response( HTTP_HD hd );
static int connect_server( const char *server, ushort port );
static int write_server( int sock, const char *data, size_t length );
#ifdef __MINGW32__
static void
deinit_sockets (void)
{
WSACleanup();
}
static void
init_sockets (void)
{
static int initialized;
static WSADATA wsdata;
if (initialized)
return;
if( WSAStartup( 0x0101, &wsdata ) ) {
log_error ("error initializing socket library: ec=%d\n",
(int)WSAGetLastError () );
return;
}
if( wsdata.wVersion < 0x0001 ) {
log_error ("socket library version is %x.%x - but 1.1 needed\n",
LOBYTE(wsdata.wVersion), HIBYTE(wsdata.wVersion));
WSACleanup();
return;
}
atexit ( deinit_sockets );
initialized = 1;
}
#endif /*__MINGW32__*/
int
http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
@ -88,7 +128,7 @@ http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
if( !rc ) {
rc = send_request( hd );
if( !rc ) {
hd->fp_write = iobuf_fdopen( hd->sock , "w" );
hd->fp_write = iobuf_sockopen( hd->sock , "w" );
if( hd->fp_write )
return 0;
rc = G10ERR_GENERAL;
@ -96,7 +136,7 @@ http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url,
}
if( !hd->fp_read && !hd->fp_write && hd->sock != -1 )
close( hd->sock );
sock_close( hd->sock );
iobuf_close( hd->fp_read );
iobuf_close( hd->fp_write);
release_parsed_uri( hd->uri );
@ -124,15 +164,18 @@ http_wait_response( HTTP_HD hd, unsigned int *ret_status )
http_start_data( hd ); /* make sure that we are in the data */
iobuf_flush( hd->fp_write );
#if 0
hd->sock = dup( hd->sock );
if( hd->sock == -1 )
return G10ERR_GENERAL;
#endif
iobuf_ioctl (hd->fp_write, 1, 1, NULL); /* keep the socket open */
iobuf_close (hd->fp_write);
hd->fp_write = NULL;
shutdown( hd->sock, 1 );
hd->in_data = 0;
hd->fp_read = iobuf_fdopen( hd->sock , "r" );
hd->fp_read = iobuf_sockopen( hd->sock , "r" );
if( !hd->fp_read )
return G10ERR_GENERAL;
@ -169,7 +212,7 @@ http_close( HTTP_HD hd )
if( !hd || !hd->initialized )
return;
if( !hd->fp_read && !hd->fp_write && hd->sock != -1 )
close( hd->sock );
sock_close( hd->sock );
iobuf_close( hd->fp_read );
iobuf_close( hd->fp_write );
release_parsed_uri( hd->uri );
@ -606,13 +649,13 @@ start_server()
if( bind( fd, (struct sockaddr *)&mya, sizeof(mya)) ) {
log_error("bind to port 11371 failed: %s\n", strerror(errno) );
close( fd );
sock_close( fd );
return -1;
}
if( listen( fd, 5 ) ) {
log_error("listen failed: %s\n", strerror(errno) );
close( fd );
sock_close( fd );
return -1;
}
@ -645,7 +688,7 @@ start_server()
fclose(fp);
exit(0);
}
close( client );
sock_close( client );
}
@ -658,9 +701,51 @@ start_server()
static int
connect_server( const char *server, ushort port )
{
int sd;
#ifdef __MINGW32__
struct hostent *hp;
struct sockaddr_in ad;
unsigned long l;
init_sockets ();
memset (&ad, 0, sizeof(ad));
ad.sin_family = AF_INET;
ad.sin_port = htons(port);
if( (l = inet_addr (server)) != SOCKET_ERROR ) {
memcpy (&ad.sin_addr, &l, sizeof(l));
}
else if( (hp = gethostbyname (server)) ) {
if( hp->h_addrtype != AF_INET ) {
log_error ("%s: unknown address family\n", server);
return -1;
}
if ( hp->h_length != 4 ) {
log_error ("%s: illegal address length\n", server);
return -1;
}
memcpy (&ad.sin_addr, hp->h_addr, hp->h_length);
}
else {
log_error ("%s: host not found: ec=%d\n",
server, (int)WSAGetLastError ());
return -1;
}
if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
log_error ("error creating socket: ex=%d\n",
(int)WSAGetLastError ());
return -1;
}
if( connect (sd, (struct sockaddr *)&ad, sizeof (ad) ) ) {
sock_close (sd);
return -1;
}
#else
struct sockaddr_in addr;
struct hostent *host;
int sd;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
@ -675,10 +760,10 @@ connect_server( const char *server, ushort port )
return -1;
if( connect( sd, (struct sockaddr *)&addr, sizeof addr) == -1 ) {
close(sd);
sock_close(sd);
return -1;
}
#endif
return sd;
}
@ -686,11 +771,19 @@ connect_server( const char *server, ushort port )
static int
write_server( int sock, const char *data, size_t length )
{
int nleft, nwritten;
int nleft;
nleft = length;
while( nleft > 0 ) {
nwritten = write( sock, data, nleft );
#ifdef __MINGW32__
unsigned long nwritten;
if ( !WriteFile ( sock, data, nleft, &nwritten, NULL)) {
log_info ("write failed: ec=%d\n", (int)GetLastError ());
return G10ERR_NETWORK;
}
#else
int nwritten = write( sock, data, nleft );
if( nwritten == -1 ) {
if( errno == EINTR )
continue;
@ -705,6 +798,7 @@ write_server( int sock, const char *data, size_t length )
log_info("write failed: %s\n", strerror(errno));
return G10ERR_NETWORK;
}
#endif
nleft -=nwritten;
data += nwritten;
}
@ -712,8 +806,6 @@ write_server( int sock, const char *data, size_t length )
return 0;
}
#endif /* HAVE_DOSISH_SYSTEM */
/**** Test code ****/
#ifdef TEST

View File

@ -53,6 +53,7 @@
#define FILEP_OR_FD_FOR_STDOUT (stdout)
typedef struct {
FILE *fp; /* open file handle */
int keep_open;
int print_only_name; /* flags indicating that fname is not a real file*/
char fname[1]; /* name of the file */
} file_filter_ctx_t ;
@ -74,6 +75,7 @@
#endif
typedef struct {
FILEP_OR_FD fp; /* open file handle */
int keep_open;
int eof_seen;
int print_only_name; /* flags indicating that fname is not a real file*/
char fname[1]; /* name of the file */
@ -88,6 +90,15 @@
static CLOSE_CACHE close_cache;
#endif
#ifdef __MINGW32__
typedef struct {
int sock;
int keep_open;
int eof_seen;
int print_only_name; /* flags indicating that fname is not a real file*/
char fname[1]; /* name of the file */
} sock_filter_ctx_t ;
#endif /*__MINGW32__*/
/* The first partial length header block must be of size 512
* to make it easier (and efficienter) we use a min. block size of 512
@ -216,6 +227,7 @@ fd_cache_close (const char *fname, FILEP_OR_FD fp)
for (cc=close_cache; cc; cc = cc->next ) {
if ( cc->fp == INVALID_FP && !strcmp (cc->fname, fname) ) {
cc->fp = fp;
return;
}
}
/* add a new one */
@ -333,6 +345,7 @@ file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
*ret_len = nbytes;
}
else if( control == IOBUFCTRL_INIT ) {
a->keep_open = 0;
}
else if( control == IOBUFCTRL_DESC ) {
*(char**)buf = "file_filter";
@ -341,6 +354,7 @@ file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
if( f != stdin && f != stdout ) {
if( DBG_IOBUF )
log_debug("%s: close fd %d\n", a->fname, fileno(f) );
if (!a->keep_open)
fclose(f);
}
f = NULL;
@ -443,6 +457,7 @@ file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
}
else if ( control == IOBUFCTRL_INIT ) {
a->eof_seen = 0;
a->keep_open = 0;
}
else if ( control == IOBUFCTRL_DESC ) {
*(char**)buf = "file_filter(fd)";
@ -452,12 +467,14 @@ file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
if ( f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT ) {
if( DBG_IOBUF )
log_debug("%s: close handle %p\n", a->fname, f );
if (!a->keep_open)
fd_cache_close (a->fname, f);
}
#else
if ( (int)f != 0 && (int)f != 1 ) {
if( DBG_IOBUF )
log_debug("%s: close fd %d\n", a->fname, f );
if (!a->keep_open)
fd_cache_close (a->fname, f);
}
f = INVALID_FP;
@ -468,6 +485,78 @@ file_filter(void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
return rc;
}
#ifdef __MINGW32__
/* Becuase sockets are an special object under Lose32 we have to
* use a special filter */
static int
sock_filter (void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len)
{
sock_filter_ctx_t *a = opaque;
size_t size = *ret_len;
size_t nbytes = 0;
int rc = 0;
if( control == IOBUFCTRL_UNDERFLOW ) {
assert( size ); /* need a buffer */
if ( a->eof_seen) {
rc = -1;
*ret_len = 0;
}
else {
int nread;
nread = recv ( a->sock, buf, size, 0 );
if ( nread == SOCKET_ERROR ) {
int ec = (int)WSAGetLastError ();
log_error("socket read error: ec=%d\n", ec);
rc = G10ERR_READ_FILE;
}
else if ( !nread ) {
a->eof_seen = 1;
rc = -1;
}
else {
nbytes = nread;
}
*ret_len = nbytes;
}
}
else if( control == IOBUFCTRL_FLUSH ) {
if( size ) {
byte *p = buf;
int n;
nbytes = size;
do {
n = send (a->sock, p, nbytes, 0);
if ( n == SOCKET_ERROR ) {
int ec = (int)WSAGetLastError ();
log_error("socket write error: ec=%d\n", ec);
rc = G10ERR_WRITE_FILE;
break;
}
p += n;
nbytes -= n;
} while ( nbytes );
nbytes = p - buf;
}
*ret_len = nbytes;
}
else if ( control == IOBUFCTRL_INIT ) {
a->eof_seen = 0;
a->keep_open = 0;
}
else if ( control == IOBUFCTRL_DESC ) {
*(char**)buf = "sock_filter";
}
else if ( control == IOBUFCTRL_FREE ) {
if (!a->keep_open)
closesocket (a->sock);
m_free (a); /* we can free our context now */
}
return rc;
}
#endif /*__MINGW32__*/
/****************
* This is used to implement the block write mode.
@ -790,7 +879,6 @@ iobuf_alloc(int use, size_t bufsize)
return a;
}
int
iobuf_close ( IOBUF a )
{
@ -996,6 +1084,32 @@ iobuf_fdopen( int fd, const char *mode )
return a;
}
IOBUF
iobuf_sockopen ( int fd, const char *mode )
{
#ifdef __MINGW32__
IOBUF a;
sock_filter_ctx_t *scx;
size_t len;
a = iobuf_alloc( strchr( mode, 'w')? 2:1, 8192 );
scx = m_alloc( sizeof *scx + 25 );
scx->sock = fd;
scx->print_only_name = 1;
sprintf(scx->fname, "[sock %d]", fd );
a->filter = sock_filter;
a->filter_ov = scx;
sock_filter( scx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
sock_filter( scx, IOBUFCTRL_INIT, NULL, NULL, &len );
if( DBG_IOBUF )
log_debug("iobuf-%d.%d: sockopen `%s'\n", a->no, a->subno, scx->fname);
return a;
#else
return iobuf_fdopen (fd, mode);
#endif
}
/****************
* create an iobuf for writing to a file; the file will be created.
*/
@ -1133,6 +1247,35 @@ iobuf_fopen( const char *fname, const char *mode )
return a;
}
int
iobuf_ioctl ( IOBUF a, int cmd, int intval, void *ptrval )
{
if ( cmd == 1 ) { /* keep system filepointer/descriptor open */
for( ; a; a = a->chain )
if( !a->chain && a->filter == file_filter ) {
file_filter_ctx_t *b = a->filter_ov;
b->keep_open = intval;
return 0;
}
#ifdef __MINGW32__
else if( !a->chain && a->filter == sock_filter ) {
sock_filter_ctx_t *b = a->filter_ov;
b->keep_open = intval;
return 0;
}
#endif
}
else if ( cmd == 2 ) { /* invalidate cache */
if ( !a && !intval && ptrval ) {
#ifndef FILE_FILTER_USES_STDIO
fd_cache_invalidate (ptrval);
#endif
return 0;
}
}
return -1;
}
/****************