/* count.c */ /* Usage: count.cgi "keyword" */ /* */ /* This is a CGI program of access counter. You can copy, re-compile, use, and modify this source freely for your home pages at your own risk. */ /* John Kohji Suguiyama ¿ù»³ ¸÷»ù mailto:sugiyama@cr.scphys.kyoto-u.ac.jp http://www-cr.scphys.kyoto-u.ac.jp/member/sugiyama/ */ #include #include #include #include #include #include void Err( char *x ) { fputs("Content-type: text/html\n\n", stdout ) ; fputs("503 Service Unavailable\n", stdout ) ; fputs("

Access Counter Error : ", stdout ) ; fputs( x, stdout ) ; fputs("

\n\nBack to Home Page\n\n", stdout ) ; } /* Data file name to record access number */ #define DIR_COUNT "../../data" #define FILE_COUNT "count.dat" #define SOCKET_COUNT "countsrv.soc" #define COUNT_SERV_PROGRAM "./countsrv &" /* Max file size = 4KB, max records = 256 */ #define DATA_NUM 256 #define MAX_WORD_LEN 15 #define REFERENCE_LEN 95 #define REMOTE_LEN 63 #define DATA_BUF_SIZE 180 #define DATA_LEN_MIN 45 /* Find "keyword" from data file, return the number, and add 1 */ /* If "keyword" doesn't exist, return 0 and record "1" */ unsigned long guest_count( char *keyword ) { unsigned long count = 0L ; int wl, soc_id ; char buf[DATA_BUF_SIZE] ; char *env_ref, *env_remote ; struct sockaddr socket_name ; /* "keyword" length <= MAX_WORD_LEN */ strncpy( buf, keyword, MAX_WORD_LEN ) ; buf[MAX_WORD_LEN] = '\0'; strcat( buf," ") ; wl = strlen( buf ) ; /* Remote host */ if( (env_remote = getenv("REMOTE_HOST"))==NULL ) env_remote = "localhost"; strncat( buf, env_remote, REMOTE_LEN ) ; buf[wl + REMOTE_LEN] = '\0'; wl = strlen( buf ) ; /* Referred from ? */ if( (env_ref = getenv("HTTP_REFERER"))!=NULL ) { strcat( buf," ") ; strncat( buf, env_ref, REFERENCE_LEN ) ; buf[wl + 1 + REFERENCE_LEN] = '\0'; } wl = strlen( buf ) + 1 ; if( (soc_id = socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ) { Err("socket"); return 0L ; } bzero( (char *)&socket_name, sizeof( struct sockaddr ) ) ; socket_name.sa_family = PF_UNIX ; strcpy( socket_name.sa_data, SOCKET_COUNT ) ; if( connect( soc_id, &socket_name, sizeof( struct sockaddr ) )!= 0 ) { system( COUNT_SERV_PROGRAM ) ; sleep( 1 ) ; if( connect( soc_id, &socket_name, sizeof( struct sockaddr ) )!= 0 ) { Err("connect") ; close( soc_id ) ; return 0L ; } } write( soc_id, buf, wl ) ; wl = read( soc_id, &count, sizeof(u_long) ) ; close( soc_id ) ; if( wl == sizeof(u_long) ) return count ; else return 0L ; } #define XBMP_HIGHT 16 /* Output bitmap image of number 'n' */ void xbmp_num( unsigned long n ) { static unsigned char bmp_fig[10][XBMP_HIGHT] = { {0xff, 0xff, 0xff, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xff, 0xff, 0xff}, /* 0 */ {0xff, 0xff, 0xff, 0xcf, 0xc7, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xff, 0xff, 0xff}, /* 1 */ {0xff, 0xff, 0xff, 0xc3, 0x99, 0x9f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xf9, 0x81, 0xff, 0xff, 0xff}, /* 2 */ {0xff, 0xff, 0xff, 0xc3, 0x99, 0x9f, 0x9f, 0xc7, 0x9f, 0x9f, 0x9f, 0x99, 0xc3, 0xff, 0xff, 0xff}, /* 3 */ {0xff, 0xff, 0xff, 0xcf, 0xcf, 0xc7, 0xc7, 0xcb, 0xcb, 0xcd, 0x81, 0xcf, 0x87, 0xff, 0xff, 0xff}, /* 4 */ {0xff, 0xff, 0xff, 0x81, 0xf9, 0xf9, 0xf9, 0xc1, 0x9f, 0x9f, 0x9f, 0x99, 0xc3, 0xff, 0xff, 0xff}, /* 5 */ {0xff, 0xff, 0xff, 0xc7, 0xf3, 0xf9, 0xf9, 0xc1, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xff, 0xff, 0xff}, /* 6 */ {0xff, 0xff, 0xff, 0x81, 0x99, 0x9f, 0x9f, 0xcf, 0xcf, 0xe7, 0xe7, 0xf3, 0xf3, 0xff, 0xff, 0xff}, /* 7 */ {0xff, 0xff, 0xff, 0xc3, 0x99, 0x99, 0x99, 0xc3, 0x99, 0x99, 0x99, 0x99, 0xc3, 0xff, 0xff, 0xff}, /* 8 */ {0xff, 0xff, 0xff, 0xc3, 0x99, 0x99, 0x99, 0x99, 0x83, 0x9f, 0x9f, 0xcf, 0xe3, 0xff, 0xff, 0xff} /* 9 */ } ; char str_fig[16] ; int digit, i, j ; sprintf( str_fig,"%lu", n ) ; digit = strlen( str_fig ) ; /* Output Header */ fputs("Content-type: image/x-xbitmap\n\n", stdout ) ; fprintf( stdout,"#define count_width %d\n", digit*8 ) ; fprintf( stdout,"#define count_height %d\n", XBMP_HIGHT ) ; /* Output bitmap */ fputs("static char count_bits[] = {\n", stdout ) ; for( j=0 ; j < XBMP_HIGHT-1 ; j++ ) { for( i=0 ; iAccess counter data\n\n

Access counter data (count.dat)

\n", stdout ) ; fputs("
\nDaily stats: keyword =\n\n\n
\n", stdout ) ; fputs("
\n", stdout ) ;
		if( (f = fopen( FILE_COUNT,"rt"))== NULL )
		{	fputs("

Data file error

\n", stdout ) ; exit(1) ; } while( fgets( ibuf, FILE_BUF_SIZE, f )!= NULL ) { strncpy( obuf, ibuf, DATA_LEN_MIN ) ; if( (ref = strtok( ibuf+DATA_LEN_MIN," \n\r"))== NULL ) strcpy( obuf+DATA_LEN_MIN,"\n") ; else sprintf( obuf+DATA_LEN_MIN,"%s\n",ref,ref ); fputs( obuf, stdout ) ; } fclose( f ) ; fputs("\n", stdout ) ; /* Normal use : Add counter : count.cgi?keyword */ }else{ xbmp_num( guest_count( argv[1] ) ) ; } }