⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch21.htm

📁 CGI programming is the hottest stuff to look out for in this book
💻 HTM
📖 第 1 页 / 共 5 页
字号:
// * # 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>
//&nbsp;&nbsp;&nbsp;&nbsp;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 &lt;stdio.h&gt;<BR>
#include &lt;string.h&gt;<BR>
#include &lt;stdlib.h&gt;<BR>
<BR>
#include &quot;linklist.h&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// Linked List Header Files<BR>
<BR>
#include &quot;linklist.cpp&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
Linked List Source Code<BR>
<BR>
// DEFINES AND STRUCTURES *********************************************
<BR>
<BR>
#define MAX_STRING&nbsp;&nbsp;256<BR>
#define DATE_STRING 32<BR>
#define HOUR_STRING 5<BR>
<BR>
#define LOG_FILE &quot;./test-access-log&quot;<BR>
<BR>
typedef struct<BR>
{&nbsp;&nbsp;&nbsp;char hostname[MAX_STRING];<BR>
&nbsp;&nbsp;&nbsp;&nbsp;int num_access;<BR>
} sHOSTNAME;<BR>
<BR>
typedef struct<BR>
{&nbsp;&nbsp;&nbsp;char filename[MAX_STRING];<BR>
&nbsp;&nbsp;&nbsp;&nbsp;int num_access;<BR>
} sFILENAME;<BR>
<BR>
typedef struct<BR>
{&nbsp;&nbsp;&nbsp;char hour[HOUR_STRING];<BR>
&nbsp;&nbsp;&nbsp;&nbsp;int num_access;<BR>
} sHOUR;<BR>
<BR>
typedef struct<BR>
{&nbsp;&nbsp;&nbsp;char date[DATE_STRING];<BR>
&nbsp;&nbsp;&nbsp;&nbsp;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>
&nbsp;&nbsp;&nbsp;&nbsp;// Opens the access log file, parses the
information into a linked list<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// internal data representation, then
sends the summary of the output to<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// stdout.<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;Content-type: text/html\n\n&quot;);
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;&lt;HTML&gt;&lt;TITLE&gt;Access
Log Summary&lt;/TITLE&gt;&lt;BODY&gt;\n&quot;);<BR>
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;&lt;H1&gt;Access Log Summary&lt;/H1&gt;\n&quot;);
<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;FILE * fp;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;fp = fopen( LOG_FILE, &quot;r&quot; );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
open the access log file<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! fp )<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;printf(&quot;ERROR:
Couldn't load log file!&quot;);&nbsp;&nbsp;&nbsp;&nbsp;// abort
painlessly<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;//
if able to load file...<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;char line[512];<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InitAll();<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(;;)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;//
fetch lines until EOF encountered<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(
fgets( line, 511, fp ) == NULL ) break;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessLine(
line );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// extract
the important information<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PrintOutput();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
send the output to stdout<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;DestroyAll();<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;&lt;/ul&gt;&lt;/BODY&gt;&lt;/HTML&gt;\n&quot;);&nbsp;&nbsp;&nbsp;&nbsp;//
end the HTML file<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;return(0);&nbsp;&nbsp;&nbsp;&nbsp;// terminate
gracefully<BR>
}<BR>
void InitAll(void)<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Initialize the heads for each of the
linked lists<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;InitHead( &amp;link_hostname );<BR>
&nbsp;&nbsp;&nbsp;&nbsp;InitHead( &amp;link_filename );<BR>
&nbsp;&nbsp;&nbsp;&nbsp;InitHead( &amp;link_hour );<BR>
&nbsp;&nbsp;&nbsp;&nbsp;InitHead( &amp;link_date );<BR>
}<BR>
<BR>
void DestroyAll(void)<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Destroy each of the linked lists (to
free memory)<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;DestroyList( &amp;link_hostname );<BR>
&nbsp;&nbsp;&nbsp;&nbsp;DestroyList( &amp;link_filename );<BR>
&nbsp;&nbsp;&nbsp;&nbsp;DestroyList( &amp;link_hour );<BR>
&nbsp;&nbsp;&nbsp;&nbsp;DestroyList( &amp;link_date );<BR>
}<BR>
<BR>
<BR>
void ProcessLine( char * line )<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Parse a single line of a standard web
server access log<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;sHOSTNAME hn;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;sFILENAME fn;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;sHOUR hr;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;sDATE dt;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;char * left, * right;<BR>
&nbsp;&nbsp;&nbsp;&nbsp;sLINK * l;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;left = line;<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;right = strchr( left, ' ' );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
find the first space<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! right ) return;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
bad entry<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;memcpy( hn.hostname, left, right-left
);&nbsp;&nbsp;&nbsp;&nbsp;// get the first one<BR>
&nbsp;&nbsp;&nbsp;&nbsp;*(hn.hostname + (right-left) ) = '\0';
<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;l = FindNode( link_hostname, (void *)
&amp;hn, 0, strlen( hn.hostname ) );<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! l )<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;hn.num_access = 1;
<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddNode( link_hostname,
(void *) &amp;hn, sizeof( sHOSTNAME ) );<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;else<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;((sHOSTNAME *) l-&gt;data)-&gt;num_access++;
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;left = right+1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// skip the space<BR>
&nbsp;&nbsp;&nbsp;&nbsp;right = strchr( left, ' ');&nbsp;&nbsp;&nbsp;&nbsp;
// find the next space (rfc931)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! right ) return;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// bad entry<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;left = right+1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// skip the space<BR>
&nbsp;&nbsp;&nbsp;&nbsp;right = strchr( left, ' ');&nbsp;&nbsp;&nbsp;&nbsp;
// find the next space (authuser)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! right ) return;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// bad entry<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;left = right+1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// skip the space<BR>
&nbsp;&nbsp;&nbsp;&nbsp;right = strchr( left, ':');&nbsp;&nbsp;&nbsp;&nbsp;
// find the colon (date delimiter)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! right ) return;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// bad entry<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;left++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// skip the leading '['<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;memcpy( dt.date, left, right-left );&nbsp;&nbsp;&nbsp;&nbsp;//
get the first one<BR>
&nbsp;&nbsp;&nbsp;&nbsp;*(dt.date + (right-left) ) = '\0';<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;l = FindNode( link_date, (void *) &amp;dt,
0, strlen( dt.date ) );<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! l )<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;dt.num_access = 1;
<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddNode( link_date,
(void *) &amp;dt, sizeof( sDATE ) );<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;else<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;((sDATE *) l-&gt;data)-&gt;num_access++;
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;left = right+1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// skip the colon<BR>
&nbsp;&nbsp;&nbsp;&nbsp;right = strchr( left, ':');&nbsp;&nbsp;&nbsp;&nbsp;
// find the next colon (hour delimeter)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! right ) return;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// bad entry<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;memcpy( hr.hour, left, right-left );&nbsp;&nbsp;&nbsp;&nbsp;//
get the first one<BR>
&nbsp;&nbsp;&nbsp;&nbsp;*(hr.hour + (right-left) ) = '\0';<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;l = FindNode( link_hour, (void *) &amp;hr,
0, strlen( hr.hour ) );<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! l )<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;hr.num_access = 1;
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddNode( link_hour,
(void *) &amp;hr, sizeof( sHOUR ) );<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;else<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;((sHOUR *) l-&gt;data)-&gt;num_access++;
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;left = strchr( line, '\&quot;' );&nbsp;&nbsp;&nbsp;&nbsp;//
find the beginning of the request<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! left ) return;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//
bad entry<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;right = strchr( left, ' ' );&nbsp;&nbsp;&nbsp;&nbsp;//
find the first space (Query Type)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! right ) return;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// bad entry<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;left = right+1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// skip the space<BR>
&nbsp;&nbsp;&nbsp;&nbsp;right = strchr( left, ' ' );&nbsp;&nbsp;&nbsp;&nbsp;//
find the next space (filename with path)<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! right ) return;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// bad entry<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;memcpy( fn.filename, left, right-left
);&nbsp;&nbsp;&nbsp;&nbsp;// get the first one<BR>
&nbsp;&nbsp;&nbsp;&nbsp;*(fn.filename + (right-left) ) = '\0';
<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;l = FindNode( link_filename, (void *)
&amp;fn, 0, strlen( fn.filename ) );<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;if( ! l )<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;fn.num_access = 1;
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AddNode( link_filename,
(void *) &amp;fn, sizeof( sFILENAME ) );<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
&nbsp;&nbsp;&nbsp;&nbsp;else<BR>
&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;((sFILENAME *) l-&gt;data)-&gt;num_access++;
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;}<BR>
}<BR>
<BR>
<BR>
void PrintOutput( void )<BR>
{<BR>
&nbsp;&nbsp;&nbsp;&nbsp;// Send the output from the program to
stdout<BR>
<BR>
&nbsp;&nbsp;&nbsp;&nbsp;sLINK * l;<BR>
<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -