e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync/* Copyright (c) 2001, Stanford University
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * All rights reserved
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * See the file LICENSE.txt for information on redistributing this software.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <stdlib.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <stdio.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <fcntl.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <sys/stat.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef WINDOWS
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <io.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include <unistd.h>
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_error.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_mem.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_string.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_bufpool.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_net.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_endian.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "cr_threads.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#include "net_internals.h"
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynctypedef enum {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRFileMemory,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRFileMemoryBig
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync} CRFileBufferKind;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#define CR_FILE_BUFFER_MAGIC 0x89134539
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifndef WINDOWS
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#define O_BINARY 0
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynctypedef struct CRFileBuffer {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int magic;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRFileBufferKind kind;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int len;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int allocated;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int pad;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync} CRFileBuffer;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic struct {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int initialized;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int num_conns;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRConnection **conns;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRBufferPool *bufpool;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRmutex mutex;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRNetReceiveFuncList *recv_list;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRNetCloseFuncList *close_list;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync} cr_file;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileReadExact( CRConnection *conn, void *buf, unsigned int len )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync char *dst = (char *) buf;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync while ( len > 0 )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int num_read = read( conn->fd, buf, len );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( num_read < 0 )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crError( "Bad bad bad file error!" );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (num_read == 0)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crError( "END OF FILE!" );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync dst += num_read;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync len -= num_read;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileWriteExact( CRConnection *conn, const void *buf, unsigned int len )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int retval = write( conn->fd, buf, len );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( retval < (int) len )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crError( "crFileWriteExact: %s (tried to write %d bytes, actually wrote %d)", conn->filename, len, retval );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileAccept( CRConnection *conn, const char *hostname, unsigned short port )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->file_direction = CR_FILE_READ;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->fd = open( conn->filename, O_RDONLY | O_BINARY );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (conn->fd < 0)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crError( "Couldn't open %s for reading!", conn->filename );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (void) port;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync*crFileAlloc( CRConnection *conn )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRFileBuffer *buf;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&cr_file.mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync buf = (CRFileBuffer *) crBufferPoolPop( cr_file.bufpool, conn->buffer_size );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( buf == NULL )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crDebug( "Buffer pool was empty, so I allocated %d bytes",
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (int)(sizeof(CRFileBuffer) + conn->buffer_size) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync buf = (CRFileBuffer *)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crAlloc( sizeof(CRFileBuffer) + conn->buffer_size );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync buf->magic = CR_FILE_BUFFER_MAGIC;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync buf->kind = CRFileMemory;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync buf->pad = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync buf->allocated = conn->buffer_size;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&cr_file.mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return (void *)( buf + 1 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileSingleRecv( CRConnection *conn, void *buf, unsigned int len )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFileReadExact( conn, buf, len );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileSend( CRConnection *conn, void **bufp, const void *start, unsigned int len )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRFileBuffer *file_buffer;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int *lenp;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( bufp == NULL )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* we are doing synchronous sends from user memory, so no need
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * to get fancy. Simply write the length & the payload and
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * return. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (conn->swap)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync len = SWAP32(len);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFileWriteExact( conn, &len, sizeof(len) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFileWriteExact( conn, start, len );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync file_buffer = (CRFileBuffer *)(*bufp) - 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT( file_buffer->magic == CR_FILE_BUFFER_MAGIC );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* All of the buffers passed to the send function were allocated
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * with crFileAlloc(), which includes a header with a 4 byte
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * length field, to insure that we always have a place to write
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * the length field, even when start == *bufp. */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync lenp = (unsigned int *) start - 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *lenp = len;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFileWriteExact(conn, lenp, len + sizeof(int) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* reclaim this pointer for reuse and try to keep the client from
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync accidentally reusing it directly */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&cr_file.mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crBufferPoolPush( cr_file.bufpool, file_buffer, conn->buffer_size );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&cr_file.mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *bufp = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileFree( CRConnection *conn, void *buf )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRFileBuffer *file_buffer = (CRFileBuffer *) buf - 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT( file_buffer->magic == CR_FILE_BUFFER_MAGIC );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->recv_credits += file_buffer->len;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync switch ( file_buffer->kind )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case CRFileMemory:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crLockMutex(&cr_file.mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crBufferPoolPush( cr_file.bufpool, file_buffer, conn->buffer_size );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crUnlockMutex(&cr_file.mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync case CRFileMemoryBig:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFree( file_buffer );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync break;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync default:
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crError( "Weird buffer kind trying to free in crFileFree: %d", file_buffer->kind );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncint
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileRecv( void )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRMessage *msg;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int i;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (!cr_file.num_conns)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync for ( i = 0; i < cr_file.num_conns; i++ )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRFileBuffer *file_buffer;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int len;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRConnection *conn = cr_file.conns[i];
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFileReadExact( conn, &len, sizeof( len ) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT( len > 0 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if ( len <= conn->buffer_size )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync file_buffer = (CRFileBuffer *) crFileAlloc( conn ) - 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync file_buffer = (CRFileBuffer *)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crAlloc( sizeof(*file_buffer) + len );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync file_buffer->magic = CR_FILE_BUFFER_MAGIC;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync file_buffer->kind = CRFileMemoryBig;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync file_buffer->pad = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync file_buffer->len = len;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFileReadExact( conn, file_buffer + 1, len );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->recv_credits -= len;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync msg = (CRMessage *) (file_buffer + 1);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crNetDispatchMessage( cr_file.recv_list, conn, msg, len );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* CR_MESSAGE_OPCODES is freed in
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * crserverlib/server_stream.c
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * OOB messages are the programmer's problem. -- Humper 12/17/01 */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (msg->header.type != CR_MESSAGE_OPCODES && msg->header.type != CR_MESSAGE_OOB)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFileFree( conn, file_buffer + 1 );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileHandleNewMessage( CRConnection *conn, CRMessage *msg,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync unsigned int len )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRFileBuffer *buf = ((CRFileBuffer *) msg) - 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* build a header so we can delete the message later */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync buf->magic = CR_FILE_BUFFER_MAGIC;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync buf->kind = CRFileMemory;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync buf->len = len;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync buf->pad = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crNetDispatchMessage( cr_file.recv_list, conn, msg, len );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileInstantReclaim( CRConnection *conn, CRMessage *mess )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crFileFree( conn, mess );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileInit( CRNetReceiveFuncList *rfl, CRNetCloseFuncList *cfl, unsigned int mtu )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (void) mtu;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_file.recv_list = rfl;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_file.close_list = cfl;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (cr_file.initialized)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_file.num_conns = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_file.conns = NULL;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef CHROMIUM_THREADSAFE
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crInitMutex(&cr_file.mutex);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_file.bufpool = crBufferPoolInit(16);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_file.initialized = 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic int
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileDoConnect( CRConnection *conn )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->file_direction = CR_FILE_WRITE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync /* NOTE: the third parameter (file permissions) is only used/required when
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * we specify O_CREAT as part of the flags. The permissions will be
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync * masked according to the effective user's umask setting.
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync */
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#ifdef WINDOWS
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->fd = open( conn->filename, O_CREAT | O_WRONLY | O_BINARY |
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync S_IREAD | S_IWRITE);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#else
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->fd = open( conn->filename, O_CREAT | O_WRONLY | O_BINARY,
c3de4bcdf53b13328f67423fccb8bbb9e4c79ac0vboxsync S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync#endif
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync if (conn->fd < 0)
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync {
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crWarning( "Couldn't open %s for writing!", conn->filename );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync }
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return 1;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncstatic void
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileDoDisconnect( CRConnection *conn )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync close( conn->fd );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->type = CR_NO_CONNECTION;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crMemcpy( cr_file.conns + conn->index, cr_file.conns + conn->index+1,
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync (cr_file.num_conns - conn->index - 1)*sizeof(*(cr_file.conns)) );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_file.num_conns--;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncvoid
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileConnection( CRConnection *conn )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync int n_bytes;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync CRASSERT( cr_file.initialized );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->type = CR_FILE;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->Alloc = crFileAlloc;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->Send = crFileSend;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->SendExact = crFileWriteExact;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->Recv = crFileSingleRecv;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->Free = crFileFree;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->Accept = crFileAccept;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->Connect = crFileDoConnect;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->Disconnect = crFileDoDisconnect;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->InstantReclaim = crFileInstantReclaim;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->HandleNewMessage = crFileHandleNewMessage;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->index = cr_file.num_conns;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->sizeof_buffer_header = sizeof( CRFileBuffer );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->actual_network = 0;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync conn->filename = crStrdup( conn->hostname );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync n_bytes = ( cr_file.num_conns + 1 ) * sizeof(*cr_file.conns);
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync crRealloc( (void **) &cr_file.conns, n_bytes );
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync cr_file.conns[cr_file.num_conns++] = conn;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsyncCRConnection**
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsynccrFileDump( int* num )
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync{
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync *num = cr_file.num_conns;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync return cr_file.conns;
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync}
e0e0c19eefceaf5d4ec40f9466b58a771f50e799vboxsync