#include "config.h"
#include "system.h"
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#ifdef HAVE_SYS_TIMES_H
# include <sys/times.h>
#endif
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "genindex.h"
#define DEBUG_INDEXING 1
#define MAX_INDEX_FILENAME_SIZE 1024
int flag_dump_symbols = 0;
int flag_gen_index = 0;
int flag_gen_index_original = 0;
static int skip_index_generation = 0;
static int recursion_depth = 0;
static int indexed_header_list_dirty = 0;
int index_socket_fd = -1;
char *index_host_name = 0;
char *index_port_string = 0;
unsigned index_port_number = 0;
static int MAX_BEGIN_COUNT = 256;
int begin_header_count = 0;
char **begin_header_stack = NULL;
int flag_check_indexed_header_list = 0;
char *index_header_list_filename = 0;
struct indexed_header
{
struct indexed_header *next;
char *name;
time_t timestamp;
int timestamp_status;
int status;
};
enum {
INDEX_TIMESTAMP_INVALID,
INDEX_TIMESTAMP_NOT_VALIDATED,
INDEX_TIMESTAMP_VALID
};
static struct indexed_header *indexed_header_list = NULL;
int
connect_to_socket (hostname, port_number)
char *hostname;
unsigned port_number;
{
int socket_fd;
struct sockaddr_in addr;
bzero ((char *)&addr, sizeof (addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = (hostname == NULL) ?
INADDR_LOOPBACK :
inet_addr (hostname);
addr.sin_port = htons (port_number);
socket_fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (socket_fd < 0)
{
warning("Can not create socket: %s", strerror (errno));
return -1;
}
if (connect (socket_fd, (struct sockaddr *)&addr, sizeof (addr)) < 0)
{
warning("Can not connect to socket: %s", strerror (errno));
return -1;
}
return socket_fd;
}
#if 0
void
dump_symbol_info (info, name, number)
char *info;
char *name;
int number;
{
if (info && c_language == -1)
fprintf (stderr, "%s",info);
else
fprintf (stderr, "%s%d ",info, c_language);
if (!name && number == -1)
return;
if (name)
fprintf (stderr, "%s",name);
if (!info && number == -1)
return;
if (number != -1)
fprintf(stderr," %u\n",number);
else
fprintf(stderr,"\n");
}
#else
void
dump_symbol_info_1 (info, name, number)
char *info;
char *name;
int number;
{
char buf[25];
if (info)
{
write (index_socket_fd, (void *) info, strlen(info));
if (c_language != -1)
{
sprintf(&buf[0],"%d ",c_language);
write (index_socket_fd, (void *) buf, strlen(buf));
}
}
if (!name && number == -1)
return;
if (name)
write (index_socket_fd, (void *) name, strlen(name));
if (!info && number == -1)
return;
if (number != -1)
sprintf(&buf[0]," %u\n",number);
else
sprintf(&buf[0],"\n");
write (index_socket_fd, (void *) buf, strlen (buf));
}
char *index_buffer = NULL;
int index_buffer_count = 0;
#define INDEX_BUFFER_SIZE 16000
void
allocate_index_buffer ()
{
if (index_buffer == NULL)
index_buffer = (char *) calloc (INDEX_BUFFER_SIZE, sizeof (char));
}
void
flush_index_buffer ()
{
int l = 0;
l = write (index_socket_fd, (void *)index_buffer, strlen (index_buffer));
if (l < strlen (index_buffer))
warning("WRITE CAN NOT WRITE ALL THE INFORMATION.\n");
free (index_buffer);
index_buffer_count = 0;
index_buffer = NULL;
}
void
maybe_flush_index_buffer (int i)
{
if ((index_buffer_count + i) > (INDEX_BUFFER_SIZE - 20))
flush_index_buffer();
allocate_index_buffer ();
}
void
dump_symbol_info (info, name, number)
char *info;
char *name;
int number;
{
int length = 12;
int info_length;
int name_length;
char nbuf[12];
if (info)
{
info_length = strlen (info);
maybe_flush_index_buffer (info_length);
strcat (index_buffer, info);
index_buffer_count += info_length;
if (c_language != -1)
{
sprintf(&nbuf[0],"%d ",c_language);
strcat (index_buffer, nbuf);
index_buffer_count += strlen (nbuf);
}
}
if (name)
{
name_length = strlen (name);
maybe_flush_index_buffer (name_length);
strcat (index_buffer, name);
index_buffer_count += name_length;
}
if (number != -1)
{
sprintf (&nbuf[0]," %u\n", number);
strcat (index_buffer, nbuf);
index_buffer_count += strlen (nbuf);
}
else if (info && name)
{
bcopy("\n", &index_buffer[index_buffer_count], 1);
index_buffer_count++;
index_buffer [index_buffer_count] = NULL;
}
}
#endif
int
read_indexed_header_list ()
{
char buffer[MAX_INDEX_FILENAME_SIZE];
struct indexed_header *cursor;
FILE *file;
char *name = NULL;
time_t timestamp;
int i, length = 0;
file = fopen (index_header_list_filename, "r");
if (!file)
return 0;
while (fgets (buffer, MAX_INDEX_FILENAME_SIZE, file))
{
length = strlen (buffer);
while (length > 0 && buffer [length - 1] <= ' ')
buffer [-- length] = '\0';
for (i = 0; i < length; i++)
{
if (buffer [i] == ' ')
{
name = &buffer [i+1];
buffer [i] = NULL;
timestamp = atol (buffer);
break;
}
}
cursor = add_index_header (name, timestamp);
if (cursor)
{
cursor->status = PB_INDEX_DONE;
cursor->timestamp_status = INDEX_TIMESTAMP_NOT_VALIDATED;
}
}
indexed_header_list_dirty = 0;
fclose (file);
return 1;
}
void
write_indexed_header_list ()
{
FILE *file;
struct indexed_header *cursor;
if (indexed_header_list_dirty == 0)
return;
file = fopen (index_header_list_filename, "w");
if (!file)
return;
for (cursor = indexed_header_list;
cursor != NULL;
cursor = cursor->next)
{
if (cursor->timestamp_status != INDEX_TIMESTAMP_INVALID
&& cursor->status == PB_INDEX_DONE)
fprintf (file, "%ld %s\n", cursor->timestamp, cursor->name);
}
fclose (file);
}
struct indexed_header *
add_index_header_name (str)
char *str;
{
struct stat buf;
if (!str)
return NULL;
if (stat(str, &buf))
return NULL;
return add_index_header (str, buf.st_mtime);
}
struct indexed_header *
add_index_header (str, timestamp)
char *str;
time_t timestamp;
{
struct indexed_header *h;
h = (struct indexed_header *) xmalloc (sizeof (struct indexed_header));
if (!h)
return NULL;
h->name = (char *) xmalloc (sizeof (char) * (strlen (str) + 1));
if (!h->name)
return NULL;
strcpy (h->name,str);
h->timestamp = timestamp;
h->next = indexed_header_list;
indexed_header_list = h;
indexed_header_list_dirty = 1;
return h;
}
void
print_indexed_header_list ()
{
struct indexed_header *cursor;
for (cursor = indexed_header_list; cursor != NULL; cursor = cursor->next)
{
fprintf (stderr, "%d", cursor->timestamp_status);
switch (cursor->status)
{
case PB_INDEX_UNKNOWN:
fprintf (stderr, " PB_INDEX_UNKNOWN"); break;
case PB_INDEX_SEEN:
fprintf (stderr, " PB_INDEX_SEEN"); break;
case PB_INDEX_RECURSIVE:
fprintf (stderr, " PB_INDEX_RECURSIVE"); break;
case PB_INDEX_DONE:
fprintf (stderr, " PB_INDEX_DONE"); break;
default:
fprintf (stderr, " Invalid status"); break;
}
if (cursor->name)
fprintf (stderr, " %s\n", cursor->name);
else
fprintf (stderr, " Invalid names\n");
}
}
void
free_indexed_header_list ()
{
struct indexed_header *cursor;
struct indexed_header *next_cursor;
cursor = next_cursor = indexed_header_list;
for ( ; next_cursor != NULL; )
{
next_cursor = cursor->next;
free (cursor->name);
free (cursor);
}
return;
}
void
update_header_status (header, when, found)
struct indexed_header *header;
int when;
int found;
{
if (header == NULL)
return;
if (when == PB_INDEX_BEGIN)
{
if (found == 1)
{
skip_index_generation++;
flag_gen_index = 0;
}
else
{
switch (header->status)
{
case PB_INDEX_UNKNOWN:
if (skip_index_generation == 0)
{
header->status = PB_INDEX_SEEN;
flag_gen_index = 1;
}
else
{
skip_index_generation++;
header->status = PB_INDEX_DONE;
flag_gen_index = 0;
}
break;
case PB_INDEX_SEEN:
case PB_INDEX_RECURSIVE:
recursion_depth++;
header->status = PB_INDEX_RECURSIVE;
flag_gen_index = 0;
break;
case PB_INDEX_DONE:
warning("Invalid index header status PB_INDEX_DONE encountered.");
warning("Indexing information is not generated properly.");
break;
default:
warning("Invalid index header status encountered.");
warning("Indexing information is not generated properly.");
break;
}
}
}
else if (when == PB_INDEX_END)
{
if (found == 1)
{
skip_index_generation--;
}
else
{
switch (header->status)
{
case PB_INDEX_UNKNOWN:
case PB_INDEX_SEEN:
header->status = PB_INDEX_DONE;
break;
case PB_INDEX_RECURSIVE:
recursion_depth--;
header->status = PB_INDEX_SEEN;
break;
case PB_INDEX_DONE:
warning("Invalid index header status PB_INDEX_DONE encountered.");
warning("Indexing information is not generated properly.");
break;
default:
warning("Invalid index header status encountered.");
warning("Indexing information is not generated properly.");
break;
}
}
if (skip_index_generation == 0 && recursion_depth == 0)
flag_gen_index = 1;
else if (skip_index_generation < 0)
{
warning("Invalid skip header index count.");
warning("Indexing information is not generated properly.");
}
else if (recursion_depth < 0)
{
warning("Invalid recursion depth count.");
warning("Indexing information is not generated properly.");
}
}
}
void
allocate_begin_header_stack ()
{
begin_header_stack = malloc (sizeof (char *) * MAX_BEGIN_COUNT);
}
void
reallocate_begin_header_stack ()
{
begin_header_stack = realloc (begin_header_stack, MAX_BEGIN_COUNT);
}
char *
pop_begin_header_stack ()
{
if (begin_header_count < 0)
{
warning("Invalid begin_header_count");
warning("Indexing information is not generated properly.");
return NULL;
}
begin_header_count--;
return begin_header_stack [ begin_header_count];
}
void
push_begin_header_stack (name)
char *name;
{
if (begin_header_count == 0)
allocate_begin_header_stack ();
else if (begin_header_count >= MAX_BEGIN_COUNT)
{
MAX_BEGIN_COUNT = 2 * MAX_BEGIN_COUNT;
reallocate_begin_header_stack ();
}
begin_header_stack [ begin_header_count ] = name;
begin_header_count++;
return;
}
int
process_header_indexing (name, when)
char *name;
int when;
{
struct indexed_header *cursor = NULL;
struct stat buf;
int found = 0;
if (!name)
return 0;
#if 1
if (when == PB_INDEX_BEGIN)
push_begin_header_stack (name);
else if (when == PB_INDEX_END)
name = pop_begin_header_stack ();
#endif
for (cursor = indexed_header_list; cursor != NULL; cursor = cursor->next)
{
if (!strcmp (cursor->name, name))
{
if (cursor->timestamp_status == INDEX_TIMESTAMP_VALID)
{
if (cursor->status == PB_INDEX_DONE)
found = 1;
break;
}
else if (cursor->timestamp_status == INDEX_TIMESTAMP_INVALID)
{
found = 0;
}
else if (!stat(name, &buf) && buf.st_mtime == cursor->timestamp)
{
cursor->timestamp_status = INDEX_TIMESTAMP_VALID;
if (cursor->status == PB_INDEX_DONE)
found = 1;
break;
}
else
{
cursor->timestamp_status = INDEX_TIMESTAMP_INVALID;
found = 0;
}
}
}
if (!found)
{
if (!cursor)
{
cursor = add_index_header_name (name);
if (cursor)
{
cursor->status = PB_INDEX_UNKNOWN;
cursor->timestamp_status = INDEX_TIMESTAMP_VALID;
}
}
}
update_header_status (cursor, when, found);
return found;
}