/* pmad.c * * This is the server of pma. * It basically reads from an established socket, * writes what it gets to a shell in the background, * reads the output from the shell, and then sends it * back to the client via the socket. * */ #include #include #include int in, cnt, pipin, sockfd, newsockfd, passok = 0; char buf[5000], passwd[50], iname[20], oname[20]; FILE *log; main(int argc, char *argv[]) { int port, cpid; /* Daemonize - System V style */ if ((cpid = fork()) < 0) exit(system("echo start up fork error >> pma.org")); else if (cpid > 0) exit(0); setpgrp(); chdir("/tmp"); /* temp work space */ signal(SIGCHLD, SIG_IGN); /* Don't create zombies */ if (argc != 2) exit(printf("Specify port\n")); port = atoi(argv[1]); sockfd = socket_declare(port); if (sockfd == -1) /* Say we are here at user given port */ exit(system("echo socket_declare failed >> pma.org")); strcpy(passwd, "HELO\n"); /* Simple password */ while (1) { newsockfd = socket_accept(sockfd); /* Wait for connection */ if (newsockfd == -1) exit(system("echo socket_accept failed >> pma.org")); if ((cpid = fork()) < 0) /* Got one, fork off child */ exit(system("echo fork error >> pma.org")); else if (cpid > 0) { close(newsockfd); continue; /* Wait for next user */ } do_child(); } } int do_child() { /* We now have an established socket. * Read from it and write to the shell */ int opid; close(sockfd); opid = do_csh(); system("date >> pma.org"); while (1) { cnt = read(newsockfd, buf, sizeof(buf)); if (cnt <= 0) exit(kill(opid, 9)); buf[cnt] = '\0'; /* logit(buf) */ seewhat(); cnt = write(pipin, buf, strlen(buf)); } } int do_csh() { /* First create some pipes. * Next fire up csh in prompt mode (-i) * doing its IO from the pipes. * The fork off another child that sets * the prompt to "PMA> " and then * endlessly reads from the shell and * writes to the socket. */ char sbuf[100]; int pid; pid = getpid(); sprintf(iname, "inpipe%d", pid); sprintf(oname, "outpipe%d", pid); sprintf(sbuf, "/etc/mknod %s p; /etc/mknod %s p", iname, oname); system(sbuf); pipin = open(iname, O_RDWR, 0); sprintf(sbuf, "csh -i <%s >%s 2>&1 &", iname, oname); system(sbuf); in = open(oname, O_RDONLY, 0); if ((pid = fork()) < 0) exit(system("echo fork error in do_csh >> pma.org")); else if (pid > 0) return(pid); read(in, buf, sizeof(buf)); strcpy(buf, "set prompt='PMA> '\n"); write(pipin, buf, strlen(buf)); read(in, buf, sizeof(buf)); while (1) getoutput(); } int getoutput() { cnt = read(in, buf, sizeof(buf)); write(newsockfd, buf, cnt); } int seewhat() { /* Don't let 'em do anything until they type in the dumb password */ if (passok) return; if (!strcmp(buf, passwd)) passok = (int) strcpy(buf, "echo ok\n"); else strcpy(buf, "echo nope\n"); } int logit(char *msg) { /* Sonetimes useful when debugging */ log = fopen("pma.org", "a"); fprintf(log, "%s", msg); fclose(log); }