Программа на C, выдающая странный вывод из HTML GET input и печатающая внизу HTML страницы - PullRequest
0 голосов
/ 09 мая 2019

Я сделал веб-сервер на C, который может отображать HTML-страницу и затем получать данные из текстового поля.До сих пор он работал для отображения основных команд, таких как ls, но по какой-то причине, когда я ввожу в текстовое поле команду ls -l | wc -l, она будет действовать только так, как если бы я набрал ls -l | w, и не будет обрабатывать команду из-за этого.Исходя из того, как я токенизирую, я не понимаю, почему он не пройдет эту линию?В текстовом поле, которое заканчивается вводом, оно выглядит как ls+-l+%7C+wc+-l, поэтому мне пришлось разделить его таким образом.Кроме того, мой вывод отображается в нижней части HTML-страницы, как я могу разместить его в правильных областях вывода?

Server.c

<code>#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <poll.h>

#define PORT "3838" //port being connected to 
#define MAXLEN 800
#define BACKLOG 10 //number of pending connections to be held in queue

//format of html page 

char header []= 
"HTTP/1.1 200 Ok\r\n"
"Content-Type: text/html; charset=UTF-8\r\n\r\n"
"<!DOCTYPE html>\r\n"
"<html>\n"
"<head>\n"
"<title>Web-Based Remote Command Server</title>\r\n"
"</head>\n"
"<body>\n\n";
char input []=
"<form action= \"/run\" method= \"GET\"> \n"
"Command: <input type=\"text\" size=\"100\" name=\"command\">\n"
"<input type=\"submit\" value=\"Run\">\n"
"</form>";
char output []=
"<p>Command that was run and testing this:</p>\n"
"<pre>Your server will include the command that was just run here.
\ n \ n ""

Стандартный вывод:

\ n ""
Your server will include the stdout results here.
\ n \ n "; char outputerr [] ="

Стандартная ошибка:

\ n ""
Your server will include the stderr results here.
\ r \ n \ r\ n "" \ r \ n "" \ r \ n "; char * buff = header; void sigchld_handler (int s) {(void) s; // тихое предупреждение о неиспользуемой переменной // waitpid () может перезаписать errno, поэтому мы сохраняем и восстанавливаем его: int save_errno = errno; while (waitpid (-1, NULL, WNOHANG)> 0); errno = save_errno;} void * get_in_addr (struct sockaddr * sa) {if (sa-> sa_family == AF_INET) {return & (((struct sockaddr_in *) sa) -> sin_addr);} return & (((struct sockaddr_in6 *) sa) -> sin6_addr);} char * parse (команда char *){char * newCommand = (char *) malloc (sizeof (char) * 50); int tgt = 0; newCommand = strtok (команда, ""); // printf ("% s \ n", newCommand); newCommand =strtok (NULL, "/ run? command ="); // printf ("% s \ n", newCommand); for (int src = 0; src fd = piper [0];poll_fd-> events = POLLIN;// ожидание (NULL);// Е ( "Done \ п");// printf ("AAA% s", вывод);if (poll (poll_fd, 1, 0) == 1) {// считывание проверки данных канала (piper [0], output, 1000);} // printf («команда% s \ n», вывод);// чтение (& output, output, piper [0]);// printf ("% s \ n", piper [0]);// dup2 (piper [1], 1);// close (0)} else {// dup2 (piper [1], 1);// printf ("run:% s", команда);закрыть (1);DUP (волынщик [1]);// близко (0);execlp (команда, команда, NULL);выход (1);} // dup2 выполняем и распечатываем его в родительском // if (* (команды + 1)! = NULL) // перенаправляем stdout до тех пор, пока не было в последней строке // {// dup2 (piper [1],1);// закрыть (piper [0]);//} return output;} int main (void) {int sockfd;int new_fd;struct addrinfo hints;struct addrinfo * serverinfo;struct addrinfo * p;struct sockaddr_storage client_addr;socklen_t addrsize;struct sigaction sa;int yes = 1;char s [INET6_ADDRSTRLEN];статус int;memset (& hints, 0, sizeof hints);// делает структуру пустой hints.ai_family = AF_UNSPEC;// IPv4 или v6 hints.ai_socktype = SOCK_STREAM;// Тип TCP нужен hints.ai_flags = AI_PASSIVE;// Заполните IP для нас// если не получается получить информацию об ошибке адреса if ((status = getaddrinfo (NULL, PORT, & hints, & serverinfo))! = 0) { fprintf (stderr, "getaddrinfo:% s \ n", gai_strerror (status)); возврат 1; } for (p = serverinfo; p! = NULL; p = p-> ai_next) { if ((sockfd = socket (p-> ai_family, p-> ai_socktype, p-> ai_protocol)) == -1) { perror ("сервер: сокет"); Продолжить; } if (setsockopt (sockfd, SOL_SOCKET, SO_REUSEADDR и & yes, sizeof (int)) == -1) { PError ( "setsockopt"); выход (1); } if (bind (sockfd, p-> ai_addr, p-> ai_addrlen) == -1) { близко (sockfd); perror ("server: bind"); Продолжить; } перерыв; } freeaddrinfo (serverinfo); if (p == NULL) { fprintf (stderr, "сервер: не удалось связать \ n"); выход (1); } if (listen (sockfd, BACKLOG) == -1) { PError ( "слушать"); выход (1); } sa.sa_handler = sigchld_handler; // пожинаем все мертвые процессы sigemptyset (& sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction (SIGCHLD, & sa, NULL) == -1) { PError ( "sigaction"); выход (1); } printf ("сервер: ожидание соединений .... \ n"); в то время как (1) { addrsize = sizeof client_addr; new_fd = accept (sockfd, (struct sockaddr *) & client_addr, & addrsize); if (new_fd == -1) { perror («Не принимал»); Продолжить; } inet_ntop (client_addr.ss_family, get_in_addr ((struct sockaddr *) & client_addr), s, sizeof s); printf ("сервер: получено соединение от% s \ n", s); если (! вилка ()) { близко (sockfd); int bufsize = 1024; char * buffer = malloc (bufsize); recv (new_fd, buffer, bufsize, 0); send (new_fd, header, bufsize, 0); // printf ("% s \ n", буфер); // printf ("% s \ n", parse (buffer)); // printf ("% s \ n", выполнение (parse (buffer))); // int length = strlen (output); // output [length + 1] = выполнение (parse (buffer)); // write (new_fd, "HTTP / 1.1 200 OK \ n", 16); // write (new_fd, "Content-length: 46 \ n", 19); // write (new_fd, "Content-type: text / html \ n \ n", 25); // write (new_fd, " \ n \ n Веб-страница CAvengers \ n \ n ", 46); if (send (new_fd, выполнение (анализ (буфер)), 1000, 0) == -1) PError ( "отправить"); близко (new_fd); Выход (0); } близко (new_fd); } вернуть 0; }
...