Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Это упрощенная версия сервера с последовательной обработкой запросов,
- т. е. пока обслуживается один клиент, остальные ждут своей очереди.
- */
- #include <errno.h>
- #include <pthread.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/iomsg.h>
- #include <sys/neutrino.h>
- #include "httpd_pid.h"
- const char HELP_MESSAGE[ ] = "\
- OS Lab 5 Server v1.2 Lite\n\
- \n\
- Available commands:\n\
- help\n\
- ls\n\
- cat\n\
- cp\n\
- rm\n\
- echo\n\
- delay\n\
- calc\n\
- ";
- const char ERROR_MESSAGE[ ] = "Invalid command; use 'help' for more information\n"
- const size_t BUFFER_SIZE = 65535;
- const size_t RESPONSE_SIZE = 65535;
- enum {
- CMD_ERROR,
- CMD_SHELL,
- CMD_HELP,
- CMD_ECHO,
- CMD_DELAY,
- CMD_CALC,
- };
- short CheckCommand(const char cmd[ ]) {
- switch (cmd[0]) {
- case 'c': {
- if (cmd[1] == 'a') {
- if (cmd[2] == 'l') {
- if (!strncmp(cmd + 3, "c ", 2))
- return CMD_CALC;
- } else if (!strncmp(cmd + 2, "t ", 2))
- return CMD_SHELL;
- } else if (!strncmp(cmd + 1, "p ", 2))
- return CMD_SHELL;
- break;
- }
- case 'd': {
- if (!strncmp(cmd + 1, "elay ", 5))
- return CMD_DELAY;
- break;
- }
- case 'e': {
- if (!strncmp(cmd + 1, "cho ", 4))
- return CMD_ECHO;
- break;
- }
- case 'h': {
- if (!strcmp(cmd + 1, "elp"))
- return CMD_HELP;
- break;
- }
- case 'l': {
- if (cmd[1] == 's' && (cmd[2] == ' ' || !cmd[2]))
- return CMD_SHELL;
- break;
- }
- case 'r': {
- if (!strncmp(cmd + 1, "m ", 2))
- return CMD_SHELL;
- }
- }
- return CMD_ERROR;
- }
- void ProcessClient(int clientId, const char _msg[ ], char* buffer, size_t maxLength) {
- const char* response = buffer;
- size_t responseSize;
- const char* msg = _msg;
- short cmd;
- while ((cmd = CheckCommand(msg)) == CMD_DELAY) {
- double delay;
- int offset;
- msg += 6;
- if (sscanf(msg, "%lf%n", &delay, &offset) != 1) {
- cmd = CMD_ERROR;
- break;
- }
- usleep((useconds_t)(delay * 1e6));
- msg += offset + 1;
- }
- switch (cmd) {
- case CMD_ERROR: {
- response = ERROR_MESSAGE;
- responseSize = sizeof ERROR_MESSAGE;
- break;
- }
- case CMD_SHELL: {
- FILE* p = popen(msg, "r");
- responseSize = fread(buffer, sizeof(char), maxLength, p);
- buffer[responseSize / sizeof(char)] = '\0';
- responseSize += sizeof(char);
- pclose(p);
- break;
- }
- case CMD_HELP: {
- response = HELP_MESSAGE;
- responseSize = sizeof HELP_MESSAGE;
- break;
- }
- case CMD_ECHO: {
- puts(msg + 5);
- *buffer = '\0';
- responseSize = sizeof(char);
- break;
- }
- case CMD_CALC: {
- double a, b;
- char op, guard;
- if (sscanf(msg + 5, "%lf %1[-+*/] %lf %c", &a, &op, &b, &guard) == 3) {
- switch (op) {
- case '+': { a += b; break; }
- case '-': { a -= b; break; }
- case '*': { a *= b; break; }
- case '/': { a /= b; break; }
- }
- if (a == (int)a)
- responseSize = sprintf(buffer, "%d", (int)a);
- else
- responseSize = sprintf(buffer, "%lf", a);
- responseSize = (responseSize + 1) * sizeof(char);
- } else {
- response = ERROR_MESSAGE;
- responseSize = sizeof ERROR_MESSAGE;
- }
- }
- }
- MsgReply(clientId, EOK, response, responseSize);
- }
- char buffer[BUFFER_SIZE];
- int main(void) {
- int channelId = ChannelCreate(0);
- FILE* f = fopen(HTTPD_PID, "w");
- if (!f) {
- fputs("Cannot open \"" HTTPD_PID "\"\n", stderr);
- return 1;
- }
- fprintf(f, "0/%d/%d\n", getpid(), channelId);
- fclose(f);
- fputs(HELP_MESSAGE, stdout);
- while (true) {
- int clientId = MsgReceive(channelId, buffer, BUFFER_SIZE * sizeof(char), NULL);
- ProcessClient(clientId, buffer, buffer, BUFFER_SIZE);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement