This is vlink_io.c in view mode; [Download] [Up]
#include "archied.h"
#define CHECK_IO(x)\
if( x < 0 )\
{\
perror("Error: I/O failed on tcp socket");\
exit(1);\
}
#define CHECK_BSIZE\
if( buffer_pos >= buffer_size )\
{\
fprintf(stderr, "Error: I/O buffer underflow\n");\
exit(1);\
}
/* The buffer into which the records are saved when reading or
writing to the TCP socket */
static char *tcp_io_buffer = NULL;
static int buffer_pos = 0, buffer_size = 0;
int init_buffer_from_stream(int stream)
{
char bsize[sizeof(int)+1];
int bytes_read, length, position;
/* First read the amount of data to be buffered */
length = sizeof(int);
bytes_read = read(stream, bsize, length);
while( bytes_read != length )
{
length -= bytes_read;
position = bytes_read;
bytes_read = read(stream, &bsize[position], length);
}
buffer_size = *( (int *) bsize );
D(fprintf(stderr, "init_buffer_from_stream: bsize = %d\n", buffer_size));
if( buffer_size < 0 )
{
fprintf(stderr, "Invalid buffer size read from request stream\n");
exit(1);
}
else if( buffer_size == 0 )
return -1;
/* Initialize the buffer */
if( tcp_io_buffer != NULL )
free(tcp_io_buffer);
tcp_io_buffer = (char *) malloc(buffer_size);
if( tcp_io_buffer == NULL )
{
perror("Error: failed to malloc() I/O buffer");
exit(1);
}
buffer_pos = 0;
return 0;
}
void check_bsize(int length)
{
if( buffer_pos + length >= buffer_size )
{ /* Double the buffer size */
buffer_size *= 2;
tcp_io_buffer = (char *) realloc(tcp_io_buffer, buffer_size);
if( tcp_io_buffer == NULL )
{
perror("Error realloc()ing I/O buffer");
exit(1);
}
}
}
void buffer_string(char *string)
{
int length;
length = strlen(string);
check_bsize(length);
strcpy(&tcp_io_buffer[buffer_pos], string);
buffer_pos += length;
tcp_io_buffer[buffer_pos ++] = NIL;
D(fprintf(stderr, "buffer_string: string = %s; bp = %d\n", string, buffer_pos));
}
void buffer_char(char c)
{
int length;
length = 1;
check_bsize(length);
tcp_io_buffer[buffer_pos] = c;
buffer_pos ++;
D(fprintf(stderr, "buffer_char: c = %d; bp = %d\n", c, buffer_pos));
}
void buffer_int(int i)
{
int length;
length = sizeof(int);
check_bsize(length);
*( (int *) &tcp_io_buffer[buffer_pos] ) = i;
buffer_pos += sizeof(int);
D(fprintf(stderr, "buffer_intr: i = %d; bp = %d\n", i, buffer_pos));
}
void write_record(int request_socket)
{
int bytes_wrote, length, position;
/* Start with the buffer length so the client knows how much data to read */
write(request_socket, &buffer_pos, sizeof(int));
/* Write out the buffered record */
length = buffer_pos;
position = 0;
while( length > 0 )
{
bytes_wrote = write(request_socket, &tcp_io_buffer[position], length);
CHECK_IO( bytes_wrote )
length -= bytes_wrote;
position += bytes_wrote;
}
D(fprintf(stderr, "write_record: record size = %d\n", buffer_pos));
}
void read_record(int request_socket)
{
int bytes_read, length, position;
/* Read the record into the I/O buffer */
length = buffer_size;
position = 0;
while( length > 0 )
{
bytes_read = read(request_socket, &tcp_io_buffer[position], length);
CHECK_IO( bytes_read )
length -= bytes_read;
position += bytes_read;
}
D(fprintf(stderr, "read_record: record size = %d\n", position));
}
void unbuffer_string(char **string)
{
char *next_string;
int length;
CHECK_BSIZE
next_string = &tcp_io_buffer[buffer_pos];
length = strlen(next_string);
*string = (char *) malloc(length + 1);
if( *string == NULL )
{
perror("Error: failed to alloc() memory for string");
exit(1);
}
strcpy(*string, next_string);
buffer_pos += (length + 1);
}
void unbuffer_char(char *c)
{
CHECK_BSIZE
*c = tcp_io_buffer[buffer_pos];
buffer_pos ++;
}
void unbuffer_int(int *i)
{
CHECK_BSIZE
*i = *( (int *) &tcp_io_buffer[buffer_pos] );
buffer_pos += sizeof(int);
}
void archive_vlink(VLINK vlink, int request_socket)
{
int bytes_wrote, length, position;
PATTRIB info;
/* Initialize the buffer */
if( tcp_io_buffer == NULL )
{
buffer_size = 1024;
tcp_io_buffer = (char *) malloc(buffer_size);
if( tcp_io_buffer == NULL )
{
perror("Error: failed to malloc() I/O buffer");
exit(1);
}
}
buffer_pos = 0;
/* Save the record list in the buffer */
while( vlink != NULL )
{
/* Name */
buffer_string(vlink->name);
free(vlink->name);
/* Filename */
buffer_string(vlink->filename);
free(vlink->filename);
/* Hostname */
buffer_string(vlink->host);
free(vlink->host);
/* File type */
buffer_string(vlink->type);
free(vlink->type);
/* File attributes */
info = vlink->lattrib;
while( info != NULL )
{
buffer_string(info->aname);
buffer_string(info->value.ascii);
free(info->aname);
free(info->value.ascii);
info = info->next;
if( info != NULL && info->previous != NULL )
free(info->previous);
}
/* End of VLINK marker */
buffer_string("VLINK_END");
/* Next record */
vlink = vlink->next;
if( vlink != NULL && vlink->previous != NULL )
free(vlink->previous);
}
/* Write the buffer to the tcp stream */
write_record(request_socket);
} /* End archive_vlink() */
VLINK unarchive_vlink(int request_socket)
{
VLINK vlink_head, vlink, next_vlink;
PATTRIB info, next_info;
/* Read the VLINK response from the tcp stream into the I/O buffer */
if( init_buffer_from_stream(request_socket) < 0 )
return NULL;
/* Read the record from the tcp stream */
read_record(request_socket);
/* Read the record from the buffer */
vlink = (VLINK) malloc(sizeof(VLINK_ST));
vlink_head = vlink;
while( buffer_pos < buffer_size )
{
/* Name */
unbuffer_string(&vlink->name);
/* Filename */
unbuffer_string(&vlink->filename);
/* Hostname */
unbuffer_string(&vlink->host);
/* File type */
unbuffer_string(&vlink->type);
/* File attributes */
info = (PATTRIB) malloc(sizeof(PATTRIB_ST));
vlink->lattrib = info;
while( 1 )
{
char *attr_name;
unbuffer_string(&attr_name);
if( strcmp("VLINK_END", attr_name) == 0 )
break;
info->aname = attr_name;
unbuffer_string(&info->value.ascii);
next_info = (PATTRIB) malloc(sizeof(PATTRIB_ST));
next_info->next = NULL;
next_info->previous = info;
info->next = next_info;
info = next_info;
}
/* Free last element in the list */
next_info = info->previous;
free( next_info->next );
next_info->next = NULL;
/* Next record */
if( buffer_pos < buffer_size )
{
next_vlink = (VLINK) malloc(sizeof(VLINK_ST));
next_vlink->next = NULL;
next_vlink->previous = vlink;
vlink->next = next_vlink;
vlink = next_vlink;
}
}
return vlink_head;
} /* End unarchive_vlink() */
int write_request(QueryRequestPtr query, int request_socket)
{
/* Initialize the buffer */
if( tcp_io_buffer == NULL )
{
buffer_size = 1024;
tcp_io_buffer = (char *) malloc(buffer_size);
if( tcp_io_buffer == NULL )
{
perror("Error: failed to malloc() I/O buffer");
exit(1);
}
}
buffer_pos = 0;
/* Save the record list to the buffer */
buffer_string(query->host);
buffer_string(query->qstring);
buffer_int(query->max_hits);
buffer_char(query->query);
buffer_int(query->flags);
/* Write the buffer to the tcp stream */
write_record(request_socket);
} /* End write_request() */
int read_request(QueryRequestPtr query, int request_socket)
{
int bytes_read, length, position;
if( init_buffer_from_stream(request_socket) < 0 )
return -1;
/* Read the record from the socket */
read_record(request_socket);
/* Read the record from the buffer */
unbuffer_string(&query->host);
unbuffer_string(&query->qstring);
unbuffer_int(&query->max_hits);
unbuffer_char(&query->query);
unbuffer_int(&query->flags);
return 0;
} /* End read_request() */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.