소스 검색

Working telnet echo off.

Also have raw mode/character mode instead of line mode.
Fixed drain so it works with syncterm.
Fixed CRNL combination, so that also works/displays correctly.
Steve Thielemann 3 년 전
부모
커밋
628283c65d
3개의 변경된 파일221개의 추가작업 그리고 175개의 파일을 삭제
  1. 5 2
      door/door.go
  2. 213 170
      door32.c
  3. 3 3
      testdoor/testdoor.go

+ 5 - 2
door/door.go

@@ -13,6 +13,8 @@ import (
 	"golang.org/x/sys/unix"
 )
 
+const CRNL = "\r\n"
+
 /*
 door32.sys:
 
@@ -218,7 +220,7 @@ func (d *Door) detect() {
 	d.Write("\x1b[0;30;40m\x1b[2J\x1b[H") // black on black, clrscr, go home
 	d.Write("\x03\x04\x1b[6n")            // hearts and diamonds does CP437 work?
 
-	d.Write("\n\r" + "\u2615\x1b[6n")
+	d.Write(CRNL + "\u2615\x1b[6n")
 	d.Write("\x1b[999C\x1b[999B\x1b[6n" + Reset + "\x1b[2J\x1b[H") // goto end of screen + cursor pos
 	// time.Sleep(50 * time.Millisecond)
 	time.Sleep(250 * time.Millisecond)
@@ -306,7 +308,8 @@ func (d *Door) Init() {
 	// putting the linux terminal into raw mode ...
 	// requires golang.org/x/sys/unix  unix.Ioctlgetermios, etc.
 
-	// I'm still getting terminal echo, terminal still not in raw mode (needs CR to submit)
+	// telnet: getting terminal echo, terminal still not in raw mode (needs CR to submit)
+	// syncterm: weird cursor movement (delays before doing CR?), but otherwise "works".
 	a, _ := tcgetattr(uintptr(d.READFD))
 	cfmakeraw(a)
 	_ = tcsetattr(uintptr(d.READFD), TCSANOW, a)

+ 213 - 170
door32.c

@@ -1,187 +1,230 @@
-#include <stdio.h>
-#include <stdlib.h>
-
 #include <netdb.h>
 #include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 #include <termios.h>
 #include <unistd.h>
 
-#include <string.h>
-
-void doprocessing (int sock);
-char * cmds[10];
+void doprocessing(int sock);
+char *cmds[10];
 
 void set_raw(int fd) {
-   struct termios tio_raw;
-   tcgetattr(fd, &tio_raw);
-   cfmakeraw(&tio_raw);
-   tcsetattr(fd, TCSANOW, &tio_raw);
+  struct termios tio_raw;
+  tcgetattr(fd, &tio_raw);
+  cfmakeraw(&tio_raw);
+  tcsetattr(fd, TCSANOW, &tio_raw);
 }
 
-int main( int argc, char *argv[] ) {
-   int sockfd, newsockfd, portno, clilen;
-   char buffer[256];
-   struct sockaddr_in serv_addr, cli_addr;
-   int n, pid;
-   
-   /* First call to socket() function */
-   sockfd = socket(AF_INET, SOCK_STREAM, 0);
-   
-   if (sockfd < 0) {
-      perror("ERROR opening socket");
-      exit(1);
-   }
-
-   if (argc != 3) {
-	printf("I need a listening port number, and command/door to call.\n");
-        exit(2);
-   }
-   
-   int listen_port = atoi(argv[1]);
-   char * command = strdup(argv[2]);
-   char * cp;
-   int cmd_count;
-   cp = command;
-   cmds[cmd_count] = cp;
-   cmd_count++;
-   while (*cp != 0) {
-      if (*cp == ' ') {
-	*cp = 0;
-	cp++;
-	cmds[cmd_count] = cp;
-        cmd_count++;
-	continue;
-      }
-      cp++;
-   }
-   cmds[cmd_count] = (char *)NULL;
-
-   if (listen_port ==0) {
-      printf("I need a listening port number as a parameter.\n");
-      exit(2);
-   }
-
-   /* Initialize socket structure */
-   bzero((char *) &serv_addr, sizeof(serv_addr));
-   portno = listen_port;
-   
-   serv_addr.sin_family = AF_INET;
-   serv_addr.sin_addr.s_addr = INADDR_ANY;
-   serv_addr.sin_port = htons(portno);
-
-   int flag = 1;  
-   if (-1 == setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag))) {  
-      perror("setsockopt fail");  
-   }  
-
-   /* Now bind the host address using bind() call.*/
-   if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
-      perror("ERROR on binding");
-      exit(1);
-   }
-   
-   /* Now start listening for the clients, here
-      * process will go in sleep mode and will wait
-      * for the incoming connection
-   */
-   printf("Listening for connections on %d\n", listen_port);
-
-   listen(sockfd,5);
-   clilen = sizeof(cli_addr);
-   
-   while (1) {
-      newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
-		
-      if (newsockfd < 0) {
-         perror("ERROR on accept");
-         exit(1);
-      }
-      
-      set_raw(newsockfd);
-
-      /* Create child process */
-      pid = fork();
-		
-      if (pid < 0) {
-         perror("ERROR on fork");
-         exit(1);
-      }
-      
-      if (pid == 0) {
-         /* This is the client process */
-         close(sockfd);
-         doprocessing(newsockfd);
-         exit(0);
-      }
-      else {
-         close(newsockfd);
-      }
-		
-   } /* end of while */
-   free((void*)command);
+int drain(int fd) {
+  struct timeval tv;
+  fd_set set;
+  int ret;
+  char buffer[21];
+  int total = 0;
+
+   printf("draining... \n");
+
+  do {
+    FD_ZERO(&set);
+    FD_SET(fd, &set);
+    tv.tv_sec = 0;
+    // 50,000 works for syncterm
+    tv.tv_usec = 50000;
+
+    ret = select(fd + 1, &set, NULL, NULL, &tv);
+    if (ret == 1) {
+      total += read(fd, buffer, 20);
+    }
+  } while (ret != 0);
+  printf(" [%d]\n", total);
+  return total;
 }
 
-void doprocessing (int sock) {
-   int n;
-   char buffer[256];
-   // raw mode
-   set_raw(sock);
-   /*
-   struct termios tio_raw;
-   tcgetattr(sock, &tio_raw);
-   cfmakeraw(&tio_raw);
-   tcsetattr(sock, TCSANOW, &tio_raw);
+int main(int argc, char *argv[]) {
+  int sockfd, newsockfd, portno, clilen;
+  char buffer[256];
+  struct sockaddr_in serv_addr, cli_addr;
+  int n, pid;
+
+  /* First call to socket() function */
+  sockfd = socket(AF_INET, SOCK_STREAM, 0);
+
+  if (sockfd < 0) {
+    perror("ERROR opening socket");
+    exit(1);
+  }
+
+  if (argc != 3) {
+    printf("I need a listening port number, and command/door to call.\n");
+    exit(2);
+  }
+
+  int listen_port = atoi(argv[1]);
+  char *command = strdup(argv[2]);
+  char *cp;
+  int cmd_count;
+  cp = command;
+  cmds[cmd_count] = cp;
+  cmd_count++;
+  while (*cp != 0) {
+    if (*cp == ' ') {
+      *cp = 0;
+      cp++;
+      cmds[cmd_count] = cp;
+      cmd_count++;
+      continue;
+    }
+    cp++;
+  }
+  cmds[cmd_count] = (char *)NULL;
+
+  if (listen_port == 0) {
+    printf("I need a listening port number as a parameter.\n");
+    exit(2);
+  }
+
+  /* Initialize socket structure */
+  bzero((char *)&serv_addr, sizeof(serv_addr));
+  portno = listen_port;
+
+  serv_addr.sin_family = AF_INET;
+  serv_addr.sin_addr.s_addr = INADDR_ANY;
+  serv_addr.sin_port = htons(portno);
+
+  int flag = 1;
+  if (-1 == setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag))) {
+    perror("setsockopt fail");
+  }
+
+  /* Now bind the host address using bind() call.*/
+  if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
+    perror("ERROR on binding");
+    exit(1);
+  }
+
+  /* Now start listening for the clients, here
+   * process will go in sleep mode and will wait
+   * for the incoming connection
    */
+  printf("Listening for connections on %d\n", listen_port);
+
+  listen(sockfd, 5);
+  clilen = sizeof(cli_addr);
+
+  while (1) {
+    newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen);
 
-   // telnet client into character mode
-   // sprintf(buffer, "\377\375\042\377\373\001Welcome socket %d\n\r", sock);
-   sprintf(buffer, "Welcome socket %d\n\r", sock);
-   write(sock, buffer, strlen(buffer) );
-
-   // can I read the buffer until empty, maybe?
-
-   FILE * fp;
-
-   fp = fopen("door32.sys", "w");
-   if ( fp == NULL) {
-      return;
-   }
-
-   fprintf(fp, "%d\n", 2);
-   fprintf(fp, "%d\n", sock);
-   fprintf(fp, "38400\n");
-   fprintf(fp, "Fake Door32 BBS\n");
-   fprintf(fp, "1\n");
-   fprintf(fp, "%s\n%s\n", "Bugz Laundry", "Bugz");
-   fprintf(fp, "%d\n", 100);
-   fprintf(fp, "%d\n", 120);
-   fprintf(fp, "1\n1\n");
-   fclose(fp);
-
-   // This resets the termios ??  
-   // execl("./testdoor", "testdoor", "-d", "door32.sys", (const char *)NULL);
-   execv(cmds[0], cmds);
-
-   // step1:  write out door32.sys file
-   // exec / replace this with our door
-
-   /*
-   bzero(buffer,256);
-   
-   n = read(sock,buffer,255);
-   
-   if (n < 0) {
-      perror("ERROR reading from socket");
+    if (newsockfd < 0) {
+      perror("ERROR on accept");
       exit(1);
-   }
-   
-   printf("Here is the message: %s\n",buffer);
-   n = write(sock,"I got your message",18);
-   
-   if (n < 0) {
-      perror("ERROR writing to socket");
+    }
+
+    set_raw(newsockfd);
+
+    /* Create child process */
+    pid = fork();
+
+    if (pid < 0) {
+      perror("ERROR on fork");
       exit(1);
-   }
-   */
+    }
+
+    if (pid == 0) {
+      /* This is the client process */
+      close(sockfd);
+      doprocessing(newsockfd);
+      exit(0);
+    } else {
+      close(newsockfd);
+    }
+
+  } /* end of while */
+  free((void *)command);
+}
 
+#define CRNL "\r\n"
+
+void doprocessing(int sock) {
+  int n;
+  char buffer[256];
+  // raw mode
+  // set_raw(sock);
+  /*
+      std::string ayt = std::string((const char *)"\x00\xff\xfd\xf6", 4);
+      std::string ayt_resp = std::string((const char *)"\xff\xfb\x00", 3);
+      std::string ayt2 = std::string((const char *)"\xff\xfb\x00", 3);
+      std::string ayt2_resp = std::string((const char *)"\xff\xfd\x00", 3);
+
+  */
+  // write(sock, "\x00\xff\xfd\xf6", 4);
+  // write(sock, "\xff\xfb\x00", 3);
+  write(sock, "\xff\xfb\x01", 3);
+  // drain(sock);
+  write(sock, "\xff\xfb\x03", 3);
+  // drain(sock);
+  write(sock, "\xff\xfd\x10", 3);
+  // write(sock, "\xff\xfc\x22", 3);
+
+  // syncterm is slow.  It needs time to drain.  :()
+  
+  drain(sock);
+  // drain(sock);
+  /*
+  struct termios tio_raw;
+  tcgetattr(sock, &tio_raw);
+  cfmakeraw(&tio_raw);
+  tcsetattr(sock, TCSANOW, &tio_raw);
+  */
+
+  // telnet client into character mode
+  // sprintf(buffer, "\377\375\042\377\373\001Welcome socket %d\n\r", sock);
+  sprintf(buffer, "Welcome socket %d" CRNL, sock);
+  write(sock, buffer, strlen(buffer));
+
+  // can I read the buffer until empty, maybe?
+
+  FILE *fp;
+
+  fp = fopen("door32.sys", "w");
+  if (fp == NULL) {
+    return;
+  }
+
+  fprintf(fp, "%d\n", 2);
+  fprintf(fp, "%d\n", sock);
+  fprintf(fp, "38400\n");
+  fprintf(fp, "Fake Door32 BBS\n");
+  fprintf(fp, "1\n");
+  fprintf(fp, "%s\n%s\n", "Bugz Laundry", "Bugz");
+  fprintf(fp, "%d\n", 100);
+  fprintf(fp, "%d\n", 120);
+  fprintf(fp, "1\n1\n");
+  fclose(fp);
+
+  // This resets the termios ??
+  // execl("./testdoor", "testdoor", "-d", "door32.sys", (const char *)NULL);
+  execv(cmds[0], cmds);
+
+  // step1:  write out door32.sys file
+  // exec / replace this with our door
+
+  /*
+  bzero(buffer,256);
+
+  n = read(sock,buffer,255);
+
+  if (n < 0) {
+     perror("ERROR reading from socket");
+     exit(1);
+  }
+
+  printf("Here is the message: %s\n",buffer);
+  n = write(sock,"I got your message",18);
+
+  if (n < 0) {
+     perror("ERROR writing to socket");
+     exit(1);
+  }
+  */
 }

+ 3 - 3
testdoor/testdoor.go

@@ -13,11 +13,11 @@ func main() {
 	reset := door.Reset
 	bold := door.Color(1, 37, 40)
 	bolder := door.ColorText("BLI BOLD YEL ON BLUE")
-	d.Write("Welcome to " + bolder + "door32.sys" + reset + "\n\r...\n\r")
+	d.Write("Welcome to " + bolder + "door32.sys" + reset + door.CRNL + "..." + door.CRNL)
 	key := d.Getch()
-	message := fmt.Sprintf("Key %s%d / %x%s\n\r", bold, key, key, reset)
+	message := fmt.Sprintf("Key %s%d / %x%s"+door.CRNL, bold, key, key, reset)
 	d.Write(message)
-	d.Write("Returning you to the BBS...\n\r")
+	d.Write("Returning you to the BBS..." + door.CRNL)
 	d.SleepKey(3)
 	fmt.Println("Ending testdoor.go")
 }