Самьюэл Алекс
Шрифт:
Листинг 11.6. (time.c) серверный модуль, отображающий текущее время
#include <assert.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include "server.h"
/* шаблон HTML-страницы, генерируемой данным модулем. */
static char* page_template =
"<html>\n"
" <head>\n"
" <meta http-equiv=\"refresh\" content=\"5\">\n"
" </head>\n"
" <body>\n"
" The current time is %s \n"
" </body>\n"
"</html>\n";
void module_generate(int fd) {
struct timeval tv;
struct tm* ptm;
char time_string[40];
FILE* fp;
/* Определение времени суток и заполнение структуры типа tm. */
gettimeofday(&tv, NULL);
ptm = localtime(&tv.tv_sec);
/* Получение строкового представления времени с точностью
до секунды. */
strftime(time_string, sizeof(time_string), "%H:%M:%S", ptm);
/* Создание файлового потока, соответствующего дескриптору
клиентского сокета. */
fp = fdopen(fd, "w");
assert(fp != NULL);
/* Запись HTML-страницы. */
fprintf(fp, page_template, time_string);
/* Очистка буфера потока */
fflush(fp);
}
Для удобства в этом модуле используются стандартные библиотечные функции ввода-вывода. Функция
fdopen
возвращает указатель потока (FILE*
), соответствующий дескриптору клиентского сокета (подробнее об этом рассказывается в приложении Б, "Низкоуровневый ввод-вывод"). Для отправки страницы клиенту вызывается обычная функция fprintf
, а функция fflush
предотвращает потерю данных в случае закрытия сокета. HTML-страница, возвращаемая модулем
time.so
, содержит в заголовке тэг <meta>
, который служит клиенту указанием перезагружать страницу каждые 5 секунд. Благодаря этому клиент всегда будет знать точное время. 11.3.2. Отображение версии Linux
Модуль
issue.so
(исходный текст приведен в листинге 11.7) выводит информацию о дистрибутиве Linux, с которым работает сервер. Традиционно эта информация хранится в файле /etc/issue
. Модель посылает клиенту Web-страницу с содержимым файла, заключенным в тэге <pre></pre>
. Листинг 11.7. (issue.c) Серверный модуль, отображающий информацию о дистрибутиве Linux
#include <fcntl.h>
#include <string.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "server.h"
/* HTML-код начала генерируемой страницы. */
static char* page_start =
"<html>\n"
" <body>\n"
" <pre>\n";
/* HTML-код конца генерируемой страницы. */
static char* page_end =
" </pre>\n"
" </body>\n"
"</html>\n";
/* HTML-код страницы, сообщающей о том, что
при открытии файла /etc/issue произошла ошибка. */
static char* error_page =
"<html>\n"
" <body>\n"
" Error: Could not open /etc/issue.\n"
" </body>\n"
"</html>\n";
/* Сообщение об ошибке. */
static char* error_message =
"Error reading /etc/issue.";
void module_generate(int fd) {
int input_fd;