codice:
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
// Define Variables
// Data Dir is the directory on your server that you wish to store the
// count files in. Each page that has the counter on it will have it's own
// file and a lock file will also be created in this directory.
const char data_dir[] = "/path/to/data/";
// Valid-URI allows you to set up the counter to only work under specific
// directories on your server. Include any of these directories as they
// appear in a URI, into this array. More information on URI's available in
// README. num_valid_uri is the number of valid URI's you have in the array.
// As it is currently set, both valid uri and invalid uri blank, all pages
// will be allowed.
const int num_valid_uri = 0;
const char valid_uri[num_valid_uri][128] = { };
// Invalid-URI allows the owner of this script to set up the counter so
// that certain portions of the web server that may be included in Valid-URI
// cannot use the program. Set num_invalid_uri to 0 and clear the array if
// you don't want to use this.
const int num_invalid_uri = 0;
const char invalid_uri[num_invalid_uri][128] = { };
/****************************************************************************/
// Set Options
// Show Link allows you to add a link around the counter to point to
// either instructions explaining to users how to set this up on the system
// (useful if a system administrator wants to allow anyone to set things up
// themselves). Setting it to "" will make no link, otherwise put the URL
// you want linked to the count here.
const char show_link[] = "http://www.scriptarchive.com/";
// When Auto-Create is enabled, users will be able to auto-create the
// count on their home pages by simply imbedding the Server Side Includes
// call. Setting auto_create to 1 enables it, 0 will disable it. Only
// users in @valid_uri will be allowed to auto create.
const int auto_create = 1;
// Show Date will show the date of when the count began if you set this
// option to 1. It will appear in yor document as [Count] hits since [Date].
// Set this to 0 and it will simply return the [Count].
const int show_date = 1;
// Lock Seconds will define the number of seconds the script should sit
// and wait for the lock file to be gone before it will overwrite it if it
// is still there. Every now and then a user will interrupt a page, causing
// the script to halt and leave a lock file in place before the lock file
// could be removed. This defines how long it waits. Nothing more than
// 2 or 3 seconds should be needed.
const int lock_sec = 2;
// Padding Size define how many numbers will be shown as your count. For
// instance, if you want your count to say 00065 and have the zeros padded
// up to five digits, then set pad_size = 5; If the number goes higher
// than the pad_size, don't worry, there just won't be any zero's tacked
// onto the front.
const int pad_size = 5;
/****************************************************************************/
void main() {
// Declare variables and subroutines
char *count_page, *count_file, *lock_file;
char c, date[32];
int i, count, count_page_len;
ifstream count_in;
ofstream count_out;
int check_uri(char []);
void error(char [], char []);
void check_lock(char []);
void create(char []);
void print_count(int);
// Print Content-type header for browser
cout << "Content-type: text/html\n\n";
// Get the page location from the DOCUMENT_URI or QUERY_STRING
// environment variables.
if (!getenv("DOCUMENT_URI") && !getenv("QUERY_STRING"))
error("no_uri","X");
// Get the count page's length and store the page name into count_page
if (strlen(getenv("QUERY_STRING")) > 0)
{
count_page_len = strlen(getenv("QUERY_STRING"));
count_page = new char[count_page_len];
strcat(count_page,getenv("QUERY_STRING"));
}
else
{
count_page_len = strlen(getenv("DOCUMENT_URI"));
count_page = new char[count_page_len];
strcat(count_page,getenv("DOCUMENT_URI"));
}
// Check Valid-URI to make sure user can use this program.
if (!check_uri(count_page))
error("bad_uri","X");
// Convert all non-alpha characters to _ to avoid security risks.
for (i = 0; i < count_page_len; i++)
if (!((count_page[i] > 96 && count_page[i] < 123) ||
(count_page[i] > 64 && count_page[i] < 91) ||
(count_page[i] > 47 && count_page[i] < 58)))
count_page[i] = '_';
// Generate the lock filename.
lock_file = new char[count_page_len + 4];
strcat(lock_file,data_dir);
strcat(lock_file,count_page);
strcat(lock_file,".lck");
// Check to see if file is locked by program already in use.
check_lock(lock_file);
// Generate the filename for the count page's data file.
count_file = new char[count_page_len + strlen(data_dir)];
strcat(count_file,data_dir);
strcat(count_file,count_page);
// If the file exists, get the date and count out of it. Otherwise, if
// auto_create is allowed, create a new account. If neither of these are
// true, return an error.
count_in.open(count_file);
if (!count_in.fail())
{
// Read in the current count.
count_in >> count;
// Skip a character and read in next one to begin loop.
count_in.get(c);
count_in.get(c);
// Read in the date until the end of file or a new line.
i = 0;
while (!count_in.eof() && c != '\n')
{
date[i] = c;
count_in.get(c);
i++;
}
}
else if (auto_create)
{
count_in.close();
create(count_file);
}
else
{
count_in.close();
error("page_not_found","X");
}
// If the program got this far, close the file, since it hasn't been yet.
count_in.close();
// Increment Count.
count++;
// Print the Count, Link and Date depending on what user has specified
// they wish to print.
if (strlen(show_link) > 0)
cout << "<a href=\"" << show_link << "\">";
print_count(count);
if (strlen(show_link) > 0)
cout << "</a>";
if (show_date)
cout << " hits since " << date;
// Open the count file and write the new count that has been incremented.
count_out.open(count_file);
if (count_out.fail())
error("could_not_increment",count_file);
else
count_out << count << " " << date;
count_out.close();
// Remove Lock File for next time script is run on that HTML page.
unlink(lock_file);
delete count_page;
delete count_file;
delete lock_file;
exit(0);
}
int check_uri(char uri[]) {
// Declare variables
int st = 0, uri_check = 0;
int valid_uri_len, invalid_uri_len, i, j;
// For each valid URI, check to see if the current uri is included in that
// valid URI. If so, set the uri check flag to 1 and break out of loop.
for (i = 0; i < num_valid_uri; i++)
{
valid_uri_len = strlen(valid_uri[i]);
for (j = 0; j < valid_uri_len; j++)
{
if (valid_uri[i][j] == uri[st])
st++;
else
st = 0;
if (st == valid_uri_len)
{
uri_check = 1;
break;
}
}
}
// Reset counter st.
st = 0;
// For each invalid URI, check to see if current uri is included in that
// invalid URI. If so, set the uri check flag to 0 and break out of loop.
for (i = 0; i < num_invalid_uri; i++)
{
invalid_uri_len = strlen(invalid_uri[i]);
for (j = 0; j < invalid_uri_len; j++)
{
if (invalid_uri[i][j] == uri[st])
st++;
else
st = 0;
if (st == invalid_uri_len)
{
uri_check = 0;
break;
}
}
}
// If both num_valid_uri and num_invalid_uri are set to 0, set the uri
// check flag to 1, because it is possible QUERY_STRING is being used.
if (!num_valid_uri && !num_invalid_uri)
uri_check = 1;
// Return the uri check flag value.
return uri_check;
}
void create(char count_file[])
{
// Declare variables and subroutines.
char *date;
char months[12][10] = { "January", "February", "March", "April", "May",
"June", "July", "August", "September", "October",
"November", "December" };
tm *ptm;
time_t *cur_time;
ofstream count_out;
void error(char [], char []);
void print_count(int);
// Set up the memory for the time and time time struct.
cur_time = new time_t;
ptm = new tm;
// Get the time, then create the struct with time values.
time(cur_time);
ptm = localtime(cur_time);
// Write to the file, sending back an error if it fails.
count_out.open(count_file);
if (count_out.fail())
error("count_not_created",count_file);
else
count_out << 1 << " " << months[ptm->tm_mon] << " " << ptm->tm_mday << ", " << ptm->tm_year + 1900;
count_out.close();
// Print the Count, Link and Date depending on what user has specified
// they wish to print.
if (strlen(show_link) > 0)
cout << "<a href=\"" << show_link << "\">";
print_count(1);
if (strlen(show_link) > 0)
cout << "</a>";
if (show_date)
cout << " hits since " << months[ptm->tm_mon] << " " << ptm->tm_mday << ", " << ptm->tm_year + 1900;
;
delete date;
delete ptm;
delete cur_time;
exit(0);
}
void print_count(int count)
{
// Declare variables.
int i, size = 0;
float count_tmp = count;
// This determines the size of the count integer by divinding by 10 until
// the result is less than 1.
while (count_tmp >= 1)
{
count_tmp /= 10;
size++;
}
// Pad the number with 0's if pad_size is greater than the count size.
for (i = 0; i < (pad_size - size); i++)
cout << 0;
// Print the count.
cout << count;
}
void error(char error[], char opt_file[])
{
// Determine which flag was set and output appropriate error.
if (strcmp(error,"page_not_found") == 0)
cout << "[TextCounter Fatal Error: This Page Not Found; Auto-Create Option Disabled]";
else if (strcmp(error,"no_uri") == 0)
cout << "[TextCounter Fatal Error: No Document URI or File Flag specified]";
else if (strcmp(error,"bad_uri") == 0)
cout << "[TextCounter Fatal Error: This Page Not In Valid URI]";
else if (strcmp(error,"count_not_created") == 0)
cout << "[TextCounter Fatal Error: Could Not Write to File " << opt_file << "]";
else if (strcmp(error,"could_not_increment") == 0)
cout << "[TextCounter Fatal Error: Could Not Increment Counter File " << opt_file << "]";
exit(0);
}
void check_lock(char lock_file[])
{
// Declare variables.
int i;
ifstream test_in;
ofstream test_out;
// For the number of seconds defined in lock_sec...
for (i = 1; i <= lock_sec; i++)
{
// Open the file for reading.
test_in.open(lock_file);
// If that fails, the lock file doesn't exis. We create the lock file
// and exit the loop. Otherwise sleep for a second.
if (test_in.fail())
{
test_out.open(lock_file);
test_out << 0;
test_out.close();
break;
}
else
sleep(1);
// Close the file if it is still open.
test_in.close();
}
}