Green Telnet
by Jeremy Blackburn and Ken Christensen


Listing One

 1. void recv_data(int s_client, int recv_data_fd, pid_t send_data_pid) {
 2.   struct gserver_msg client_message;
 3.   char gt_packet[BUF_SIZE];
 4.   char * p;
 5.   int bytes_read = 0;
 6.   int i = 0;
 7.   char last = 1;
 8.   char *iacptr;
 9.   char tb[1];
10.   int temp_bytes_read = 0;
11.
12.   while ((bytes_read = read(s_client, gt_packet, sizeof(gt_packet))) > 0) {
13.     iacptr = memchr(gt_packet, 255, bytes_read);
14.     if (!iacptr) {
15.       write(recv_data_fd, gt_packet, bytes_read);
16.     } else if (iacptr && iacptr > gt_packet) {
17.       if (iacptr == &gt_packet[BUF_SIZE - 1]) {
18.         write(recv_data_fd, gt_packet, bytes_read - 1);
19.         temp_bytes_read = read(s_client, tb, 1);
20.         if ((unsigned char)tb[0] == 255) {
21.           bytes_read = read(s_client, &client_message, sizeof(client_message));
22.           if (client_message.command == gtWSLE) {
23.             (void)kill(send_data_pid, SIGALRM);
24.             return;
25.           }
26.         } else {
27.           write(recv_data_fd, tb, temp_bytes_read);
28.         }
29.       }
30.     } else if (iacptr) {
31.       if (*((unsigned char *)(iacptr + 1)) == 255) {
32.         if ((iacptr + 1 + sizeof(client_message)) <= &gt_packet[BUF_SIZE - 1]) {
33.           p = (char *)&client_message;
34.           iacptr+= 2;
35.           for (i = 0; i < sizeof(client_message); i++) {
36.             *p = *iacptr;
37.             p++;
38.             iacptr++;
39.           }
40.         }
41.         if (client_message.command == gtWSLE) {
42.           (void)kill(send_data_pid, SIGALRM);
43.           return;
44.         }
45.       }
46.     }
47.   }
48.   if (bytes_read < 1)
49.     exit(1);
40.   return;
41. }


Listing Two

 1. void send_data(int s_client, int send_data_fd, struct replay_buffer *replay_buff) {
 2.   struct gqnode dequeued_data;
 3.   struct stat   queue_stats;
 4.   struct flock  fl;
 5.   char gt_packet[BUF_SIZE + 2];
 6.   char data_notifier;
 7.   char *p;
 8.   char c;
 9.   long queue_file_size;
10.   int temp = 0;
11.   int bytes_written = 0;
12.   int queue_fd;
13.   int status;
14.   int messages_written;
15.   int bytes_read = 0;
16.   int i = 0;
17.
18.   while (!client_wants_sleep &&
19.     read(send_data_fd, &data_notifier, sizeof(data_notifier)) > 0) {
20.     queue_fd = open (queue_file_path, O_RDWR);
21.     fl = acquire_queue_lock (queue_fd);
22.     while (read(queue_fd, &dequeued_data, sizeof(dequeued_data)) > 0) {
23.       if (!client_wants_sleep &&
24.        (bytes_written = write (s_client, dequeued_data.buf, dequeued_data.nbytes)) > 0);
25.       replay_buff->byte_count = replay_buff->byte_count + bytes_written;
26.       for (i = 0; i < bytes_written; i++) {
27.         replay_buff->buffer[replay_buff->index] = dequeued_data.buf[i];
28.         replay_buff->index = (replay_buff->index + 1) % RB_MAX;
29.       }
30.       if (client_wants_sleep) {
31.         status = fstat (queue_fd, &queue_stats);
32.         queue_file_size = queue_stats.st_size;
33.         temp_queue_fd = open (queue_file_path, O_RDWR);
34.         messages_written = 0;
35.         while (read(queue_fd, &dequeued_data, sizeof (dequeued_data)) > 0) {
36.           write(temp_queue_fd, &dequeued_data, sizeof (dequeued_data));
37.           messages_written++;
38.         }
39.         close(temp_queue_fd);
40.         ftruncate(queue_fd, messages_written*sizeof(dequeued_data));
41.         release_queue_lock(queue_fd, fl);
42.         close(queue_fd);
43.         return;
44.       }
45.     }
46.     ftruncate(queue_fd, 0);
47.     release_queue_lock(queue_fd, fl);
48.     close(queue_fd);
49.   }
50.   return;
51. }


2


