/* pma.c * * This is the client of pma. * Basically all it does is get a string from the terminal and write it out * to an established socket. * * Tested on: * HP/UX 10.0.1 * AIX 4.0 * SunOS 4.1.3 * Solaris 2.5 * DG/UX 5.4.2 * */ #include #include #include #include char buf[5000], tbuf[100]; int sockfd, vimode = 0; struct sgttyb tty_mode; main(int argc, char *argv[]) { int cnt, port, pid, idx = 0; FILE *lout; if (argc < 3) { fprintf(stderr, "Specify host and port.\n"); exit(0); } signal(SIGCHLD, SIG_IGN); /* Don't create any zombie */ ioctl(0, TIOCGETP, &tty_mode); fprintf(stderr, "Trying..."); port = atoi(argv[2]); /* See if there is a server on the user give host and port */ sockfd = socket_connect(argv[1], port); if (sockfd == -1) { fprintf(stderr, "\nsocket_connect(pms) failed.\n"); exit (1); } fprintf(stderr, "\nConnected.\n"); pid = forkio(); cnt = write(sockfd, buf, strlen(buf)); while (1) { if (!vimode) { gets(&buf[idx]); idx = 0; } else { buf[0] = getchar(); vimode = checkmode(); if (!vimode) { idx = 1; continue; } buf[1] = '\0'; } checkcmd(pid); cnt = write(sockfd, buf, strlen(buf)); } } int forkio() { int pid; /* Fork off a child which endlessly reads from the socket and * writes to the terminal. */ if ((pid = fock()) < 0) exit(system("echo fork error in fockio >> pma.org")); else if (pid > 0) return(pid); while (1) rdsock(); } int rdsock() { /* If we see the prompt, "PMA> ", it means that we could be coming out * vi mode, so turn on echo and turn off raw mode. Note that our * parent will get to the getchar() before it see that echo is back * on. This means that the first character typed after exiting from * vi will not go to the gets() like we would really want. That * first character can be flakey sometimes, but it basically works */ int cnt; cnt = read(sockfd, buf, sizeof(buf)); buf[cnt] = '\0'; fprintf(stderr, "%s", buf); if (!strcmp(&buf[strlen(buf) - 5], "PMA> ")) echo(); } int checkmode() { struct sgttyb tty_mode; int mode; ioctl(0, TIOCGETP, &tty_mode); if (tty_mode.sg_flags & ECHO) mode = 0 else mode = 1; return(mode); } int noecho() { /* system("stty -echo;stty raw"); */ tty_mode.sg_flags &= ~ECHO; tty_mode.sg_flags |= RAW; ioctl(0, TIOCSETP, &tty_mode); } int echo() { /* system("stty -echo;stty cooked"); */ tty_mode.sg_flags |= ECHO; tty_mode.sg_flags &= ~RAW; ioctl(0, TIOCSETP, &tty_mode); } int checkcmd(int pid) { if (!strcmp(buf, "done")) exit(kill(pid, 9)); if (!vimode) strcat(buf, "\n"); if (!strncmp(buf, "vi ", 3)) { noecho(); vimode = 1; strcpy(tbuf, "vi -w24"); strcat(tbuf, &buf[2]); strcpy(buf, tbuf); } }