📄 ch21.htm
字号:
// * # of hits by file path<BR>
// * # of hits by day<BR>
// * # of hits by hour<BR>
//<BR>
// GENERAL ALGORITHM<BR>
//<BR>
// 1. For each domain and file path, dynamically create a linked
list<BR>
// for each value, and add 1 to the hit
count each time.<BR>
//<BR>
// 2. Create a linked list for each date, as well as each hour
also.<BR>
//<BR>
// 3. Send the output to stdout.<BR>
<BR>
// IncLUDES ***********************************************************
<BR>
<BR>
#include <stdio.h><BR>
#include <string.h><BR>
#include <stdlib.h><BR>
<BR>
#include "linklist.h"
// Linked List Header Files<BR>
<BR>
#include "linklist.cpp" //
Linked List Source Code<BR>
<BR>
// DEFINES AND STRUCTURES *********************************************
<BR>
<BR>
#define MAX_STRING 256<BR>
#define DATE_STRING 32<BR>
#define HOUR_STRING 5<BR>
<BR>
#define LOG_FILE "./test-access-log"<BR>
<BR>
typedef struct<BR>
{ char hostname[MAX_STRING];<BR>
int num_access;<BR>
} sHOSTNAME;<BR>
<BR>
typedef struct<BR>
{ char filename[MAX_STRING];<BR>
int num_access;<BR>
} sFILENAME;<BR>
<BR>
typedef struct<BR>
{ char hour[HOUR_STRING];<BR>
int num_access;<BR>
} sHOUR;<BR>
<BR>
typedef struct<BR>
{ char date[DATE_STRING];<BR>
int num_access;<BR>
} sDATE;<BR>
<BR>
<BR>
// FUncTION PROTOTYPES ************************************************
<BR>
<BR>
int main(int argc, char *argv[], char *env[]);<BR>
void ProcessLine( char * line );<BR>
void PrintOutput( void );<BR>
void InitAll(void);<BR>
void DestroyAll(void);<BR>
<BR>
// GLOBAL VARIABLES ***************************************************
<BR>
<BR>
sLINK * link_hostname;<BR>
sLINK * link_filename;<BR>
sLINK * link_hour;<BR>
sLINK * link_date;<BR>
<BR>
<BR>
// FUncTIONS **********************************************************
<BR>
<BR>
int main(int argc, char *argv[], char *env[])<BR>
{<BR>
// Opens the access log file, parses the
information into a linked list<BR>
// internal data representation, then
sends the summary of the output to<BR>
// stdout.<BR>
<BR>
printf("Content-type: text/html\n\n");
<BR>
printf("<HTML><TITLE>Access
Log Summary</TITLE><BODY>\n");<BR>
printf("<H1>Access Log Summary</H1>\n");
<BR>
<BR>
FILE * fp;<BR>
<BR>
fp = fopen( LOG_FILE, "r" ); //
open the access log file<BR>
<BR>
if( ! fp )<BR>
{ printf("ERROR:
Couldn't load log file!"); // abort
painlessly<BR>
}<BR>
else
//
if able to load file...<BR>
{ char line[512];<BR>
<BR>
InitAll();<BR>
<BR>
for(;;)<BR>
{ //
fetch lines until EOF encountered<BR>
<BR>
if(
fgets( line, 511, fp ) == NULL ) break;<BR>
<BR>
ProcessLine(
line ); // extract
the important information<BR>
}<BR>
<BR>
PrintOutput(); //
send the output to stdout<BR>
}<BR>
<BR>
DestroyAll();<BR>
<BR>
printf("</ul></BODY></HTML>\n"); //
end the HTML file<BR>
<BR>
return(0); // terminate
gracefully<BR>
}<BR>
void InitAll(void)<BR>
{<BR>
// Initialize the heads for each of the
linked lists<BR>
<BR>
InitHead( &link_hostname );<BR>
InitHead( &link_filename );<BR>
InitHead( &link_hour );<BR>
InitHead( &link_date );<BR>
}<BR>
<BR>
void DestroyAll(void)<BR>
{<BR>
// Destroy each of the linked lists (to
free memory)<BR>
<BR>
DestroyList( &link_hostname );<BR>
DestroyList( &link_filename );<BR>
DestroyList( &link_hour );<BR>
DestroyList( &link_date );<BR>
}<BR>
<BR>
<BR>
void ProcessLine( char * line )<BR>
{<BR>
// Parse a single line of a standard web
server access log<BR>
<BR>
sHOSTNAME hn;<BR>
sFILENAME fn;<BR>
sHOUR hr;<BR>
sDATE dt;<BR>
char * left, * right;<BR>
sLINK * l;<BR>
<BR>
left = line;<BR>
<BR>
right = strchr( left, ' ' ); //
find the first space<BR>
<BR>
if( ! right ) return; //
bad entry<BR>
<BR>
memcpy( hn.hostname, left, right-left
); // get the first one<BR>
*(hn.hostname + (right-left) ) = '\0';
<BR>
<BR>
l = FindNode( link_hostname, (void *)
&hn, 0, strlen( hn.hostname ) );<BR>
<BR>
if( ! l )<BR>
{ hn.num_access = 1;
<BR>
<BR>
AddNode( link_hostname,
(void *) &hn, sizeof( sHOSTNAME ) );<BR>
}<BR>
else<BR>
{ ((sHOSTNAME *) l->data)->num_access++;
<BR>
}<BR>
<BR>
left = right+1;
// skip the space<BR>
right = strchr( left, ' ');
// find the next space (rfc931)<BR>
if( ! right ) return;
// bad entry<BR>
<BR>
left = right+1;
// skip the space<BR>
right = strchr( left, ' ');
// find the next space (authuser)<BR>
if( ! right ) return;
// bad entry<BR>
<BR>
left = right+1;
// skip the space<BR>
right = strchr( left, ':');
// find the colon (date delimiter)<BR>
if( ! right ) return;
// bad entry<BR>
<BR>
left++;
// skip the leading '['<BR>
<BR>
memcpy( dt.date, left, right-left ); //
get the first one<BR>
*(dt.date + (right-left) ) = '\0';<BR>
<BR>
l = FindNode( link_date, (void *) &dt,
0, strlen( dt.date ) );<BR>
<BR>
if( ! l )<BR>
{ dt.num_access = 1;
<BR>
<BR>
AddNode( link_date,
(void *) &dt, sizeof( sDATE ) );<BR>
}<BR>
else<BR>
{ ((sDATE *) l->data)->num_access++;
<BR>
}<BR>
<BR>
left = right+1;
// skip the colon<BR>
right = strchr( left, ':');
// find the next colon (hour delimeter)<BR>
if( ! right ) return;
// bad entry<BR>
<BR>
memcpy( hr.hour, left, right-left ); //
get the first one<BR>
*(hr.hour + (right-left) ) = '\0';<BR>
<BR>
l = FindNode( link_hour, (void *) &hr,
0, strlen( hr.hour ) );<BR>
<BR>
if( ! l )<BR>
{ hr.num_access = 1;
<BR>
AddNode( link_hour,
(void *) &hr, sizeof( sHOUR ) );<BR>
}<BR>
else<BR>
{ ((sHOUR *) l->data)->num_access++;
<BR>
}<BR>
<BR>
left = strchr( line, '\"' ); //
find the beginning of the request<BR>
if( ! left ) return; //
bad entry<BR>
<BR>
right = strchr( left, ' ' ); //
find the first space (Query Type)<BR>
if( ! right ) return;
// bad entry<BR>
<BR>
left = right+1;
// skip the space<BR>
right = strchr( left, ' ' ); //
find the next space (filename with path)<BR>
if( ! right ) return;
// bad entry<BR>
<BR>
memcpy( fn.filename, left, right-left
); // get the first one<BR>
*(fn.filename + (right-left) ) = '\0';
<BR>
<BR>
l = FindNode( link_filename, (void *)
&fn, 0, strlen( fn.filename ) );<BR>
<BR>
if( ! l )<BR>
{ fn.num_access = 1;
<BR>
AddNode( link_filename,
(void *) &fn, sizeof( sFILENAME ) );<BR>
}<BR>
else<BR>
{ ((sFILENAME *) l->data)->num_access++;
<BR>
}<BR>
}<BR>
<BR>
<BR>
void PrintOutput( void )<BR>
{<BR>
// Send the output from the program to
stdout<BR>
<BR>
sLINK * l;<BR>
<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -