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.