SUMMARY ======= An Apache 2 only module serving link counting information via jpeg and png images. Configuration commands include font selection, font size, image type, image background and text color, digit width, reset, ignore, insert, access list database, and random. Direct support for RedHat 8.0, 9.0 and Fedora Core 1 (Yarrow) distribution with the required gd-1.8.4, zlib1.1.4, libjpeg6b, Berkeley DB 4.0.14, libpng-1.2.3, and Freetype 2.0.9 installed, via RPM. An port of pre Apache 2 mod_ometer to Apache 2. REQUIRES ======== gd-1.8.4 (gd-1.8.4.tar.gzgd-1.8.4-9.src.rpm) zlib-1.1.4 (zlib-1.1.4-4.src.rpm, most versions included with dist seem to be adequate) libjpeg6b (libjpeg-6b-21.src.rpm) Berkeley DB >= 4.0.14 (db-4.0.14.tar.gz, db-4.1.25.tar.gz, db4-4.0.14-14.src.rpm) Freetype 2.1.2 (FreeType-2.1.2-7.src.rpm, freetype-2.1.4.tar.gz) libpng-1.2.3 (libpng-1.2.2-6.src.rpm) libm (standard C math library) gcc. True Type fonts (use the web, grasshopper). Reading skills. If you cannot read, do not continue. USAGE ===== font=font Default font=FreeMono Specify the true type font for the counter image text/digits. A font error is indicated by "Efont". Do not include the trailing .ttf. width=counting_number Default width=0 Specify the number of digits/chars displayed. If the count requires more digits/chars, then "Eovr" is returned. Use with caution as some errors will be displayed as "Eovr" if width is only a couple of digits. A width=0 will use exactly the number of digits/chars required (default). Normally used with random command. The max value is 10. rand=[true,false,true_access] random=[true,false,true_access] random=false Default value. random=true Just displays a random number, the host is not entered into DB_ACCESS. If link is not in DB_COUNT, "NoLink" is returned. random=true_access Just displays a random number, the host, if not already in DB_ACCESS, is entered into DB_ACCESS. If link is not in DB_COUNT, "NoLink" is returned. reset=[access, delete, counting_number, init:counting_number] reset=access The links' access list is removed from the database. Success is indicated by the returned image "Arst". If link is not currently in the database, "NoLink" is returned. reset=delete The links' counter value is removed from the database. Success is indicated by the returned image "Cdel". If the link has an access list, it remains in the database. If the link is not currently in the database, "NoLink" is returned. reset=counting_number If the link exists in DB_COUNT, then the counter value is changed to counting_number, and the current counter value is returned. If the link does not exist in the database, "NoLink" is returned. reset=init:counting_number Insert the link into the counter database (DB_COUNT), set the the values on the command line as defaults, initialize the counter start value to counting_number, and return "Cadd". Any commands specified during the counter reset/ initialization phase will become the link defaults, and not be required on subsequent calls. On subsequent queries, compile time option COUNTM_INFORMATION_PRIORITY specifies if the command line values take priority, or if the database options take priority. Default is COUNTM_INFORMATION_PRIORITY_DATABASE. If the link is already present in the counter database (DB_COUNT), "Elink" is returned, and the current database values for the link are not changed. image=[jpeg, png] Specify the return image to be jpeg or png. If the module has been compiled with USE_PNG_IF_ACCEPTABLE, and the requesting client accepts png images, then a png image will be returned. point=number Specifies the point size of the font. link=linkname The linkname to be associated with this counter. ignore=[IPADDR, DOMAINNAME] For this query only, these cannot increment the counter. text=000000 The font color using "web color" rgb triplet notation (HEX, do not use a leading 0x). bgcolor=000000 The image background color, specified with "web color" rgb triplet notation (HEX, do not use a leading 0x). count=[inc, dec, norm_inc, norm_dec] count=inc This parameter has changed from prior releases! Specifies that the count should be incremented without checking DB_ACCESS. If host is not in DB_ACCESS, host is entered into DB_ACCESS. count=dec Specifies that the count should be decremented without checking DB_ACCESS. If host is not in DB_ACCESS, host is entered into DB_ACCESS. count=norm_inc Specifies that the count should be incremented if host is not in DB_ACCESS. If host is not in DB_ACCESS, host is entered into DB_ACCESS. count=norm_dec Specifies that the count should be decremented if host is not in DB_ACCESS. If host is not in DB_ACCESS, host is entered into DB_ACCESS. insert=hostname This hostname is added to DB_ACCESS. Only valid during reset=counting_number query if and only if the link is not in DB_COUNT. Multiple insert commands may be used. GETTING STARTED =============== After installation, the easiest way to get started is to access ex_enter.html and enter a link into the counter database. Once the link is entered, look at the other ex_*.html examples. DATABASE ======== The counter database maintains, for each link, a current count value (DB_COUNT) and an access list (DB_ACCESS). The links' counter value is incremented when a new hostname is added to the links' access list. The links' counter value may be changed with the reset command. The links' counter value may be deleted from the database with the reset=delete command. The links' access list may be deleted from the database with the reset=access command. CREDITS ======= Adapted to Apache 2 by <Byron Young> spamiccling@yahoo.com, bkyoung@users.sourceforge.net Adapted from mod_ometer by J Craig. See modules.apache.org for more information. COMMON ERRORS ============= Attempting to increment a link that has not be inserted into the database: <IMG src="www.counter.com/counter?link=linkname"> The image displays NoLink. Solution: <IMG src="www.counter.com/counter?link=linkname&reset=0"> The image will display "Cadd". <IMG src="www.counter.com/counter?link=linkname"> The image will display 0 if hostname is in the linknames' access list, and 1 if it is not. In general, avoid duplicate <IMG src=""> tags in a html page. Browsers tend to optimize resource retrievals, and could receive the count image out of desired order. If the error log continues to spew out Unlock failed messages, verify database lock file is not present. What is the difference between insert= and ignore=? Insert adds the hostname to DB_ACCESS, and ignore does not. Because ignore does not add hostnames to DB_ACCESS, the hostnames will only be valid for that query. However, because insert adds the hostnames to DB_ACCESS, subsequent queries will consider the hostnames to have already accesed the counter. After inserting counter into database, is there any way to insert new hostnames into DB_ACCESS? Yes, but not directly. Use a reset=number, and the current counter value will be returned. Then use a reset=delete to delete the counter from DB_COUNT. Finally, use a second reset=#, where # is the previously returned value, and each insert specified on the line will be added to DB_ACCESS.. After inserting counter into database, is there any way to adjust the counter default values? Yes, but not directly. See After inserting question above. URL FORMATION ============= Forming the URL is the same for all GET operations. Use a ? after the resource http://localhost/countm portion and start each command with an amperstand. COUNTER USAGE ============= Insert the link into the database and set the counter to the initial value: Note: All other commands specified during this query will become the defaults for future queries. <IMG src="www.counter.com/counter?link=linkname&reset=init:#"> The image will indicate success with "Cadd". If the link is already present in DB_COUNT, "Elink" is displayed. Display the counter, incrementing it first if necessary. <IMG src="www.counter.com/counter?link=linkname"> The image will display the count. If the link is not present in DB_COUNT, "NoLink" is displayed. Reset the counter to a arbitrary value: <IMG src="www.counter.com/counter?link=linkname&reset=#"> If the link is currently present in the database, the old value is displayed, and count in DB_COUNT is set to new value. If the link is not in DB_COUNT, "NoLink" is displayed. Reset the access list to empty: <IMG src="www.counter.com/counter?link=linkname&reset=access"> The image will display Arst (Access Reset). If the link is not present in DB_ACCESS, "NoLink" is displayed. Remove the link from the counter database. <IMG src="www.counter.com/counter?link=linkname&reset=delete"> The image will display Cdel. (Deleted) If the link is not in DB_COUNT, "NoLink" is displayed. COUNTER USAGE - A complete session ================================== Access ex_enter.html, just hit submit. The counter is entered into DB_COUNT. Access ex_query.html The counter is incremented by one, and the local host is entered into DB_ACCESS. Access ex_reset.html The count in DB_COUNT is reset, and the current value is returned. Access ex_delete.html The link information in DB_COUNT is deleted. Access ex_access.html The link information in DB_ACCESS is deleted. cd /var/counm/dbase dump -p count.db should indicate nothing in database. INSTALLATION ============ Review the included module configuration file for example configuration. Verify the required rpms are installed. rpm -i --test /usr/src/redhat/RPMS/i386/apache2-mod_countm-3.0-6yarrow.i386.rpm Install any missing requirements. Verify the server is not running. /etc/rc.d/init.d/httpd status If it is, then stop the server. /etc/rc.d/init.d/httpd stop Install the rpm. rpm -i apache2-mod_countm-3.0-6yarrow.i386.rpm Adjusting /etc/httpd/conf.d/mod_countm.conf should not be necessary. Restart the server. /etc/rc.d/init.d/httpd start Launch Netscape, and enter http://localhost/test/countm/ex_enter.html Automate httpd startup with: chkconfig httpd on see man mod_countm for more information. CHECK THE ERROR LOGS ==================== /var/log/httpd/error_log /var/countm/dbase/db.log QUICK DATABASE CHECK ==================== Assuming that db4-utils is installed. To quickly view the database: db_dump -p /var/countm/dbase/countm.db. See struct db_count_record in mod_countm.c for the format of a DB_COUNT entry. REMOVAL ======= rpm -e apache2-mod_countm DEVELOPMENT STATUS ================== The project is currently stable/production. The format of DB_ACCESS is stable. The format of DB_COUNT may change in future versions. The lockfile will probably be changed to db4 transaction locking in future versions. A redhat 8,9,Yarrow rpm is available for download from rpmfind.net (search for apache2-mod_countm), or from sourcforge project site. A mandrake cooker rpm is avialable (packaged by other persons- Thanks!!!) for download from rpmfind.net (search for apache2-mod_countm), or from sourceforge project site. OPERATING SYSTEM ================ RedHat 8.0 Linux/ Apache 2.0.44 RedHat 9.0 Linux/ Apache 2.0.44 Fedora Core 1 (Yarrow) Linux/ Apache 2.0.47 Mandrake Cooker SunOS 5.9 INTENDED AUDIENCE ================= As a simple page counter, the project is intended for small office/ home office system administrators anticipating low volume web traffic and interested in adding page counter capabilities to their Apache server. SOURCEFORGE.NET INFORMATION =========================== Development Status: 5-Stable/production Operating System: POSIX: Linux Topic: Internet: WWW/HTTP: Dynamic Content: Page Counters Intended Audience: Other Audience License: OSI Approved: BSD License Programming Language: C Environment: Web Environment Natural Language: English Project Unix Name: countm DISTRIBUTION FILES ================== Stable Release 3.0 (Release_3_0) mod_countm-3.0.tar.bz2 apache2-mod_countm-3.0-6yarrow.src.rpm apaceh2-mod_countm-3.0-6yarrow.i386.rpm Stable Release 2.1 (Release_2_1) mod_countm-2.1.tar.bz2 apache2-mod_countm-2.1-5yarrow.src.rpm apache2-mod_countm-2.1-5yarrow.i386.rpm Stable Release 2.0 (Release_2_0) mod_countm-2.0 apache2-mod_countm-2.0-3rh.src.rpm apache2-mod_countm-2.0-3rh.i386.rpm Alpha Relese 2.0 mod_countm-2.0.tar.bz2 mod_countm-2.0-3Beta.src.rpm mod_countm-2.0-3Beta.i386.rpm RELEASE DATE ============ 12-02-03 Released stable version 3.0 Yarrow 11-21-03 Released stable version 2.1 Yarrow. 11-09-03 advanced to stable 2.0 version RH9,RH8 4-14-03 released RH8.0 Alpha version. BUILDING THE MODULE =================== The following are commands for a recent BASH shell. Download the sources from CVS. CVSROOT=:pserver:anonymous@cvs.sourceforge.net:/cvsroot/countm export CVSROOT cvs login password: <just hit enter> cvs co -r Release_3_0 -d mod_count-3.0 countm cvs logout cd mod_countm-3.0 (The following may be out of date.) Determine the version of autoconf installed on your system. If autoconf --version == 2.13, then use configure.in. If autoconf --version == 2.53, then use configure.ac. The major difference between configure scripts produced is the variable passing method. The configure produced using 2.13 requires all variables be passed via global environmental variables. The configure produced using 2.53 will accept the variables defined on the configure script command line. Create the configure script. (2.13) autoconf configure.in (2.53) autoconf configure.ac Configure the build. This step will create mod_countm.conf and Makefile. ./configure The following commands are recognized by configure: --with-httpd directory(absolute) containing httpd.h (and other httpd header files) if not specified, or --with-httpd=yes, then is assumed to be in standard include path. For RedHat 8.0,9.0,Yarrow --with-httpd=/usr/lib/httpd --with-apxs The directory(absolute) containing apxs. If not specified, or --with-apxs=yes, then assumed to be in PATH. For RedHat 8.0,9.0,Yarrow --with-apxs=/usr/sbin --with-doxygen The directory(absolute) containing doxygen. For RedHat 8.0,9.0,Yarrow --with-doxygen=/usr/bin doxygen is optional. If doxygen configures properly, typing make dox will build some html files. libexecdir= Set libexecdir to the location to install the built module. Directory must exist, or build will fail (configuration may succeed). Set this variable. Almost no installations will work with the default value. For RedHat 8.0,9.0,Yarrow libexecdir=/usr/lib/httpd/modules sysconfdir= Directory to place module httpd configuration file. RedHat 8.0,9.0,Yarrow sysconfdir=/etc/httpd/conf.d localstatedir= Directory to place runtime database, lock, and log files. RedHat 8.0,9.0,Yarrow localstatedir=/var/countm mandir= Top level directory to place the manl/mod_countm.l manpage. For RedHat 8.0,9.0,Yarrow mandir=/usr/share/man The following variables are recognized by configure. For 2.53, they may be passed via the command line. APXS_CFLAGS= Use -Wc and -Wl to pass flags to the APXS compiler. For RedHat 8.0.9.0,Yarrow APXS_FLAGS="-Wc,-O2 -Wc,-Wall" DEBUG=-DDEBUG To activate debugging Specifying DEBUG will not include the -g in CFLAGS. APXS_LIBDIRS= The directories of the required libraries, if the libraries are not in standard location. Requires a -L prior to each library directory. example: APXS_LIBDIRS="-L/usr/lib/gd -L/usr/lib/db" Not required for RedHat 8.0,9.0,Yarrow The following variables are recognized by configure, but are used by the maintainer. TEST_HTML= The location of the html test pages. RedHat 8.0,9.0,Yarrow /var/www/html/test/countm APACHECTL= The apache control program. RedHat 8.0,9.0,Yarrow /etc/rc.d/init.d/httpd APACHEOWNER= The user id of the httpd daemon. RedHat 8.0,9.0,Yarrow apache APACHEGROUP= The group id of the httpd daemon. RedHat 8.0,9.0,Yarrow apache ERROR_LOG= The httpd error log. RedHat 8.0,9.0,Yarrow /var/log/httpd/error_log The following may or may not be required, depending on the type of tools used, and generally must be passed to the tool via a global environmental variable. LDFLAGS= if any of the required libraries are NOT in the standard library include paths, then pass their location to configure with LDFLAGS=-L/directory of library. Because of the way APXS builds the module, the library directory may need to be passed with APXS_CFLAGS using -Wl,-Ldir. For RedaHat 8.0,9.0,Yarrow LDFLAGS is not required. CFLAGS= Define to any extra flags you wish to send to the compilier. For RedHat 8.0,9.0,Yarrow using CFLAGS=-O2 avoids placing debugging information in the library. The complete command line for RedHat 8.0,9.0,Yarrow (autoconf 2.57) is: ./configure --with-httpd=/usr/include/httpd --with-apxs=/usr/sbin libexecdir=/usr/lib/httpd/modules CFLAGS= --with-doxygen=yes sysconfdir=/etc/httpd/conf.d localstatedir=/var/countm APXS_CFLAGS="-Wc,-O2 -Wc,-Wall" DEBUG= Because of APXS, the make part installs the module. The make install part installs the config file and the resources directory/files. make uninstall removes the module, the config file, and the resources directory/files. Use uninstall with caution!! DEBUGGING THE MODULE ==================== This information may not be completely accurate. The following are specific to Fedora Core 1, gcc-3.3.2, gdb-5.3.90. The rpmbuild process creates apache2-mod_countm-debuginfo-3.0.i386.rpm. This package contains the debug information for the apaceh2-mod_countm-3.0.i386.rpm package. The apaceh2-mod_countm-3.0.i386.rpm package object files are stripped. After installing the deguginfo package, the mod_countm.so may be debugged using gdb. The following is not the best method for debugging, but gets the job done. DEBUGGING THE MODULE - geting debuginfo files ============================================= Either figure out which deguginfo files you will need (at least httpd-debuginfo), or download all debuginfo files from download.fedora.redhat.com/pub/fedora/linux/core/1/i386/debug and install them. DEBUGGING THE MODULE - install the mod_countm debuginfo package ============================================================== rpm -i apache2-mod_countm-debuginfo-3.0.i386.rpm DEBUGGING THE MODULE - prelink httpd executable =============================================== The default build from httpd.spec creates pie httpd. In order to use gdb to debug it, it must be prelinked with prelink. /usr/sbin/prelink /usr/sbin/httpd Also, the directory /lib/tls was added to /etc/prelink.conf These should be run as root, so the cache file may be updated properly. DEBUGGING THE MODULE - Determine the httpd symbol start address =============================================================== [root$]objdump -f /usr/sbin/httpd /usr/sbin/httpd: file format elf32-i386 architecture: i386, flags 0x00000150: HAS_SYMS, DYNAMIC, D_PAGED start address 0x02bc3f30 The start address in this example is 0x02bc3f30 A "small" number start address usually indicates a non prelinked pie. DEBUGGING THE MODULE - Set LD_PRELOAD to preload mod_countm.so ============================================================== LD_PRELOAD=/usr/lib/httpd/modules/mod_countm.so export LD_PRELOAD DEBUGGING THE MODULE - the gdb session ============================================================== [root$]gdb /usr/sbin/httpd GNU gdb Red Hat Linux (5.3.90-0.20030710.41rh) Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) add-symbol-file /usr/sbin/httpd 0x2bc3f30 -readnow add symbol table from file "/usr/sbin/httpd" at .text_addr = 0x2bc3f30 (y or n) y Reading symbols from /usr/sbin/httpd...expanding to full symbols... Reading symbols from /usr/lib/debug//usr/sbin/httpd.debug... expanding to full symbols...done. done. (gdb) b main Breakpoint 1 at 0x2bd2025: file /usr/src/debug/httpd-2.0.47/server/main.c, line 443. (gdb) r -X Starting program: /usr/sbin/httpd -X [Thread debugging using libthread_db enabled] [New Thread -1085120384 (LWP 14302)] [Switching to Thread -1085120384 (LWP 14302)] Breakpoint 1, main (argc=2, argv=0xbff42484) at /usr/src/debug/httpd-2.0.47/server/main.c:443 443 ap_server_pre_read_config = apr_array_make(pcommands, 1, sizeof(char *)); (gdb) info shared From To Syms Read Shared Object Library 0x48abb330 0x48abdff8 Yes /usr/lib/httpd/modules/mod_countm.so 0x009c1820 0x009e4740 Yes /lib/libssl.so.4 0x007908b0 0x0082a0cc Yes /lib/libcrypto.so.4 0x00978e00 0x00984eb0 Yes /usr/lib/libgssapi_krb5.so.2 0x0088e610 0x008dd91c Yes /usr/lib/libkrb5.so.3 0x0087aa90 0x0087b1dc Yes /lib/libcom_err.so.2 0x008eb4e0 0x00900e40 Yes /usr/lib/libk5crypto.so.3 0x005298f0 0x00534070 Yes /lib/libresolv.so.2 0x004d0730 0x004da2d8 Yes /usr/lib/libz.so.1 0x00c49cb0 0x00c55b34 Yes /lib/libpcre.so.0 0x003c6a90 0x003c6f58 Yes /usr/lib/libpcreposix.so.0 0x02c9c250 0x02caa9a4 Yes /usr/lib/libaprutil-0.so.0 0x001fa890 0x0021d950 Yes /usr/lib/libldap.so.2 0x001e65e0 0x001edbac Yes /usr/lib/liblber.so.2 0x003f0430 0x003f3edc Yes /usr/lib/libgdbm.so.2 0x00a72e70 0x00b0db80 Yes /lib/tls/libdb-4.1.so 0x004f6320 0x004fdabc Yes /lib/tls/libpthread.so.0 0x005e3110 0x005f8de0 Yes /usr/lib/libexpat.so.0 0x02c7d600 0x02c91d1c Yes /usr/lib/libapr-0.so.0 0x0090de70 0x00913b14 Yes /lib/tls/librt.so.1 0x02c00500 0x02c17e3c Yes /lib/tls/libm.so.6 0x009899a0 0x0098c264 Yes /lib/libcrypt.so.1 0x0085cc30 0x00868bc8 Yes /lib/libnsl.so.1 0x003eae90 0x003ebd20 Yes /lib/libdl.so.2 0x002a0540 0x0039df20 Yes /lib/tls/libc.so.6 0x0011e9e0 0x00137cd4 Yes /usr/lib/libpng12.so.0 0x04d8d1b0 0x04d9c818 Yes /usr/lib/libgd.so.2 0x0066e4d0 0x00686c5c Yes /usr/lib/libjpeg.so.62 0x00de2f90 0x00df0318 Yes /usr/lib/libsasl2.so.2 0x00273c30 0x00285247 Yes /lib/ld-linux.so.2 0x009f1320 0x009fc084 Yes /usr/X11R6/lib/libXpm.so.4 0x00b32380 0x00ba2cb0 Yes /usr/X11R6/lib/libX11.so.6 0x00542c70 0x00580e9c Yes /usr/lib/libfreetype.so.6 0x004e48e0 0x004ee388 Yes /usr/X11R6/lib/libXext.so.6 (gdb) b countm_method_handler Breakpoint 2 at 0x48abc366 (gdb) c Continuing. Breakpoint 2, 0x48abc366 in countm_method_handler () from /usr/lib/httpd/modules/mod_countm.so (gdb) quit The program is running. Exit anyway? (y or n) y [root$] DEBUGGING THE MODULE - a few notes ================================== The gdb load process consumes large quantities of CPU cycles. Be patient. FILES CREATED/INSTALLED ======================= Assuming a default RedHat 8.0/9.0,Yarrow installation: /usr/lib/httpd/modules/mod_countm.so /etc/httpd/conf.d/mod_countm.conf /var/countm/fonts/FreeMono.ttf /var/countm/dbase /usr/share/man/manl/mod_countm.l /var/www/html/test/countm/ex*.html RUNTIME FILES ============= Assuming a default RedHat 8.0,9.0,Yarrow installation: /var/countm/countm.lock ( a temporary lock file, which should always be removed prior to module initialization) /var/countm/dbase/* (various db4 database files) /var/countm/dbase/db.log (the db4 database log file) /var/countm/countm.dlog (a DEBUG log of parsed configure options) /var/countm/dbg.dlog (a DEBUG log for the database)