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

📄 visitors.c

📁 web服务器访问统计
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Returns true if 'year' is a leap year. */int isleap(int year){	int conda, condb, condc;	conda = (year%4) == 0;	condb = (year%100) == 0;	condc = (year%400) == 0;	return conda && !(condb && !condc);}#endif/* URL decoding and white spaces trimming function. * Input: the encoded string 's'. * Output: the decoded string written at 'd' that has room for at least 'n' * bytes of data. */void vi_urldecode(char *d, char *s, int n){	char *start = d;	if (n < 1) return;	while(*s && n > 1) {		int c = *s;		switch(c) {		case '+': c = ' '; break;		case '%':			  if (*(s+1) && *(s+2)) {				  int high = toupper(*(s+1));				  int low = toupper(*(s+2));				  if (high <= '9') high -= '0';				  else high = (high - 'A') + 10;				  if (low <= '9') low -= '0';				  else low = (low - 'A') + 10;				  c = (high << 4)+low;				  s += 2;			  }			  break;		}		if (c != ' ' || d != start) {			*d++ = c;			n--;		}		s++;	}	/* Right trim */	*d = '\0';	d--;	while (d >= start && *d == ' ') {		*d = '\0';		d--;	}}/* URL encoding function * Input: the unencoded string 's'. * Output: the url-encoded string written at 'd' that has room for at least 'n' * bytes of data. */void vi_urlencode(char *d, char *s, int n){	if (n < 1) return;	n--;	while(*s && n > 0) {		int c = *s;		if ((c >= 'A' && c <= 'Z') ||		    (c >= 'a' && c <= 'z') ||		    (c >= '0' && c <= '9'))		{			*d++ = c;			n--;		} else if (c == ' ') {			*d++ = '+';			n--;		} else if (c == '\n') {			if (n < 6) break;			memcpy(d, "%0d%0a", 6);			d += 6;			n -= 6;		} else {			unsigned int t;			char *hexset = "0123456789abcdef";			if (n < 3) break;			t = (unsigned) c;			*d++ = '%';			*d++ = hexset [(t & 0xF0) >> 4];			*d++ = hexset [(t & 0x0F)];			n -= 3;		}		s++;	}	*d = '\0';}/* Convert a nul-term string to lowercase in place */void vi_strtolower(char *s){	while (*s) {		*s = tolower(*s);		s++;	}}/* Note: the following function strlcat and strlcpy are (possibly) modified * version of OpenBSD's functions. Original copyright notice: * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> * Originally under the BSD license. */int vi_strlcpy(char *dst, char *src, int siz){        char *d = dst;        const char *s = src;        int n = siz;        /* Copy as many bytes as will fit */        if (n != 0 && --n != 0) {                do {                        if ((*d++ = *s++) == 0)                                break;                } while (--n != 0);        }        /* Not enough room in dst, add NUL and traverse rest of src */        if (n == 0) {                if (siz != 0)                        *d = '\0';              /* NUL-terminate dst */                while (*s++)                        ;        }        return(s - src - 1);    /* count does not include NUL */}int vi_strlcat(char *dst, const char *src, int siz){        char *d = dst;        const char *s = src;        size_t n = siz;        size_t dlen;        /* Find the end of dst and adjust bytes left but don't go past end */        while (n-- != 0 && *d != '\0')                d++;        dlen = d - dst;        n = siz - dlen;        if (n == 0)                return(dlen + strlen(s));        while (*s != '\0') {                if (n != 1) {                        *d++ = *s;                        n--;                }                s++;        }        *d = '\0';        return(dlen + (s - src));       /* count does not include NUL */}/* Returns non-zero if the url matches one of the keywords in * blacklist.h, otherwise zero is returned. Warning!!! This function * run time is proportional to the size of blacklist.h, so it is * very slow. */int vi_is_blacklisted_url(struct vih *vih, char *url){    unsigned int i;    for (i = 0; i < VI_BLACKLIST_LEN; i++) {        if (strstr(url, vi_blacklist[i])) {            vih->blacklisted++;            return 1;        }    }    return 0;}/* Glob-style pattern matching. */int vi_match_len(const char *pattern, int patternLen,        const char *string, int stringLen, int nocase){    while(patternLen) {        switch(pattern[0]) {        case '*':            while (pattern[1] == '*') {                pattern++;                patternLen--;            }            if (patternLen == 1)                return 1; /* match */            while(stringLen) {                if (vi_match_len(pattern+1, patternLen-1,                            string, stringLen, nocase))                    return 1; /* match */                string++;                stringLen--;            }            return 0; /* no match */            break;        case '?':            if (stringLen == 0)                return 0; /* no match */            string++;            stringLen--;            break;        case '[':        {            int not, match;            pattern++;            patternLen--;            not = pattern[0] == '^';            if (not) {                pattern++;                patternLen--;            }            match = 0;            while(1) {                if (pattern[0] == '\\') {                    pattern++;                    patternLen--;                    if (pattern[0] == string[0])                        match = 1;                } else if (pattern[0] == ']') {                    break;                } else if (patternLen == 0) {                    pattern--;                    patternLen++;                    break;                } else if (pattern[1] == '-' && patternLen >= 3) {                    int start = pattern[0];                    int end = pattern[2];                    int c = string[0];                    if (start > end) {                        int t = start;                        start = end;                        end = t;                    }                    if (nocase) {                        start = tolower(start);                        end = tolower(end);                        c = tolower(c);                    }                    pattern += 2;                    patternLen -= 2;                    if (c >= start && c <= end)                        match = 1;                } else {                    if (!nocase) {                        if (pattern[0] == string[0])                            match = 1;                    } else {                        if (tolower((int)pattern[0]) == tolower((int)string[0]))                            match = 1;                    }                }                pattern++;                patternLen--;            }            if (not)                match = !match;            if (!match)                return 0; /* no match */            string++;            stringLen--;            break;        }        case '\\':            if (patternLen >= 2) {                pattern++;                patternLen--;            }            /* fall through */        default:            if (!nocase) {                if (pattern[0] != string[0])                    return 0; /* no match */            } else {                if (tolower((int)pattern[0]) != tolower((int)string[0]))                    return 0; /* no match */            }            string++;            stringLen--;            break;        }        pattern++;        patternLen--;        if (stringLen == 0) {            while(*pattern == '*') {                pattern++;                patternLen--;            }            break;        }    }    if (patternLen == 0 && stringLen == 0)        return 1;    return 0;}/* Like vi_match_len but more handly if used against nul-term strings. */int vi_match(const char *pattern, const char *string, int nocase){    int patternLen = strlen(pattern);    int stringLen = strlen(string);    return vi_match_len(pattern, patternLen, string, stringLen, nocase);}/*-------------------------- visitors handler functions --------------------- *//* Init the hashtable with methods suitable for an "occurrences counter" */void vi_ht_init(struct hashtable *ht){	ht_init(ht);	ht_set_hash(ht, ht_hash_string);	ht_set_key_destructor(ht, ht_destructor_free);	ht_set_val_destructor(ht, ht_no_destructor);	ht_set_key_compare(ht, ht_compare_string);}/* Reset the weekday/hour info in the visitors handler. */void vi_reset_combined_maps(struct vih *vih){	int i, j;	for (i = 0; i < 24; i++) {		vih->hour[i] = 0;		for (j = 0; j < 7; j++)			vih->weekdayhour[j][i] = 0;	}	for (i = 0; i < 7; i++) vih->weekday[i] = 0;	for (i = 0; i < 31; i++)		for (j = 0; j < 12; j++)			vih->monthday[j][i] = 0;}/* Reset the hashtables from the handler, that are left * in a reusable state (but all empty). */void vi_reset_hashtables(struct vih *vih){	ht_destroy(&vih->visitors);	ht_destroy(&vih->googlevisitors);	ht_destroy(&vih->pages);	ht_destroy(&vih->images);	ht_destroy(&vih->error404);	ht_destroy(&vih->pageviews);	ht_destroy(&vih->pageviews_grouped);	ht_destroy(&vih->referers);	ht_destroy(&vih->referersage);	ht_destroy(&vih->agents);	ht_destroy(&vih->googled);	ht_destroy(&vih->adsensed);	ht_destroy(&vih->googlekeyphrases);	ht_destroy(&vih->googlekeyphrasesage);	ht_destroy(&vih->googlevisits);	ht_destroy(&vih->trails);	ht_destroy(&vih->tld);	ht_destroy(&vih->os);	ht_destroy(&vih->browsers);	ht_destroy(&vih->date);	ht_destroy(&vih->googledate);	ht_destroy(&vih->month);	ht_destroy(&vih->googlemonth);	ht_destroy(&vih->robots);	ht_destroy(&vih->googlehumanlanguage);	ht_destroy(&vih->screenres);	ht_destroy(&vih->screendepth);}/* Reset handler informations to support --reset option in * stream mode. */void vi_reset(struct vih *vih){	vi_reset_combined_maps(vih);	vi_reset_hashtables(vih);}/* Return a new visitors handle. * On out of memory NULL is returned. * The handle obtained with this call must be released with vi_free() * when no longer useful. */struct vih *vi_new(void){	struct vih *vih;	if ((vih = malloc(sizeof(*vih))) == NULL)		return NULL;	/* Initialization */	vih->startt = vih->endt = time(NULL);	vih->processed = 0;	vih->invalid = 0;        vih->blacklisted = 0;	vi_reset_combined_maps(vih);	vih->error = NULL;	vi_ht_init(&vih->visitors);	vi_ht_init(&vih->googlevisitors);	vi_ht_init(&vih->pages);	vi_ht_init(&vih->images);	vi_ht_init(&vih->error404);	vi_ht_init(&vih->pageviews);	vi_ht_init(&vih->pageviews_grouped);	vi_ht_init(&vih->referers);	vi_ht_init(&vih->referersage);	vi_ht_init(&vih->agents);	vi_ht_init(&vih->googled);	vi_ht_init(&vih->adsensed);	vi_ht_init(&vih->googlevisits);	vi_ht_init(&vih->googlekeyphrases);	vi_ht_init(&vih->googlekeyphrasesage);	vi_ht_init(&vih->trails);	vi_ht_init(&vih->tld);	vi_ht_init(&vih->os);	vi_ht_init(&vih->browsers);	vi_ht_init(&vih->date);	vi_ht_init(&vih->month);	vi_ht_init(&vih->googledate);	vi_ht_init(&vih->googlemonth);	vi_ht_init(&vih->robots);	vi_ht_init(&vih->googlehumanlanguage);	vi_ht_init(&vih->screenres);	vi_ht_init(&vih->screendepth);	return vih;}/* Free an handle created with vi_new(). */void vi_free(struct vih *vih){	if (!vih) return;	vi_reset_hashtables(vih);	vi_clear_error(vih);	free(vih);}/* Add a new entry in the counter hashtable. If the key does not * exists creates a new entry with "1" as number of hits, otherwise * increment the old value. * * Return the value of hits after the increment or creation. If the * returned value is greater than one, the key was already seen. * * Return 0 on out of memory. * * NOTE: the pointer of the "value" part of the hashtable entry is * used as a counter casting it to a "long" integer. */int vi_counter_incr(struct hashtable *ht, char *key){	char *k;	unsigned int idx;	int r;	long val;		r = ht_search(ht, key, &idx);	if (r == HT_NOTFOUND) {		k = strdup(key);		if (k == NULL) return 0;		if (ht_add(ht, k, (void*)1) != HT_OK) {			free(k);			return 0;		}		return 1;	} else {		val = (long) ht_value(ht, idx);		val++;		ht_value(ht, idx) = (void*) val;		return val;	}}/* Similar to vi_counter_incr, but only read the old value of * the counter without to alter it. If the specified key does not * exists zero is returned. */int vi_counter_val(struct hashtable *ht, char *key){	unsigned int idx;	int r;	long val;	

⌨️ 快捷键说明

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