📄 util.c
字号:
* Return values: * 1: success * 0: illegal string */int unescape_uri(char *uri, char **query_string){ char c, d; char *uri_old; uri_old = uri; while ((c = *uri_old)) { if (c == '%') { uri_old++; if ((c = *uri_old++) && (d = *uri_old++)) { *uri = HEX_TO_DECIMAL(c, d); if (*uri < 32 || *uri > 126) { /* control chars in URI */ *uri = '\0'; return 0; } } else { *uri = '\0'; return 0; } ++uri; } else if (c == '?') { /* query string */ if (query_string) *query_string = ++uri_old; /* stop here */ *uri = '\0'; return (1); } else if (c == '#') { /* fragment */ /* legal part of URL, but we do *not* care. * However, we still have to look for the query string */ if (query_string) { ++uri_old; while ((c = *uri_old)) { if (c == '?') { *query_string = ++uri_old; break; } ++uri_old; } } break; } else { *uri++ = c; uri_old++; } } *uri = '\0'; return 1;}/* rfc822 (1123) time is exactly 29 characters long * "Sun, 06 Nov 1994 08:49:37 GMT" */void rfc822_time_buf(char *buf, time_t s){ struct tm *t; char *p; unsigned int a; if (!s) { t = gmtime(¤t_time); } else t = gmtime(&s); p = buf + 28; /* p points to the last char in the buf */ p -= 3; /* p points to where the ' ' will go */ memcpy(p--, " GMT", 4); a = t->tm_sec; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ':'; a = t->tm_min; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ':'; a = t->tm_hour; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ' '; a = 1900 + t->tm_year; while (a) { *p-- = '0' + a % 10; a /= 10; } /* p points to an unused spot to where the space will go */ p -= 3; /* p points to where the first char of the month will go */ memcpy(p--, month_tab + 4 * (t->tm_mon), 4); *p-- = ' '; a = t->tm_mday; *p-- = '0' + a % 10; *p-- = '0' + a / 10; *p-- = ' '; p -= 3; memcpy(p, day_tab + t->tm_wday * 4, 4);}char *simple_itoa(unsigned int i){ /* 21 digits plus null terminator, good for 64-bit or smaller ints * for bigger ints, use a bigger buffer! * * 4294967295 is, incidentally, MAX_UINT (on 32bit systems at this time) * and is 10 bytes long */ static char local[22]; char *p = &local[21]; *p = '\0'; do { *--p = '0' + i % 10; i /= 10; } while (i != 0); return p;}/* I don't "do" negative conversions * Therefore, -1 indicates error */int boa_atoi(const char *s){ int retval; char *reconv; if (!isdigit(*s)) return -1; retval = atoi(s); if (retval < 0) return -1; reconv = simple_itoa((unsigned int) retval); if (memcmp(s, reconv, strlen(s)) != 0) { return -1; } return retval;}int create_temporary_file(short want_unlink, char *storage, unsigned int size){ static char boa_tempfile[MAX_PATH_LENGTH + 1]; int fd; snprintf(boa_tempfile, MAX_PATH_LENGTH, "%s/boa-temp.XXXXXX", tempdir); /* open temp file */ fd = mkstemp(boa_tempfile); if (fd == -1) { log_error_time(); perror("mkstemp"); return 0; } if (storage != NULL) { unsigned int len = strlen(boa_tempfile); if (len < size) { memcpy(storage, boa_tempfile, len + 1); } else { close(fd); fd = 0; log_error_time(); fprintf(stderr, "not enough memory for memcpy in storage\n"); want_unlink = 1; } } if (want_unlink) { if (unlink(boa_tempfile) == -1) { close(fd); fd = 0; log_error_time(); fprintf(stderr, "unlink temp file\n"); } } return (fd);}int real_set_block_fd(int fd){ int flags; flags = fcntl(fd, F_GETFL); if (flags == -1) return -1; flags &= ~NOBLOCK; flags = fcntl(fd, F_SETFL, flags); return flags;}int real_set_nonblock_fd(int fd){ int flags; flags = fcntl(fd, F_GETFL); if (flags == -1) return -1; flags |= NOBLOCK; flags = fcntl(fd, F_SETFL, flags); return flags;}/* Quoting from rfc1034:<domain> ::= <subdomain> | " "<subdomain> ::= <label> | <subdomain> "." <label><label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]<ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str><let-dig-hyp> ::= <let-dig> | "-"<let-dig> ::= <letter> | <digit><letter> ::= any one of the 52 alphabetic characters A through Z inupper case and a through z in lower case<digit> ::= any one of the ten digits 0 through 9andThe labels must follow the rules for ARPANET host names. They muststart with a letter, end with a letter or digit, and have as interiorcharacters only letters, digits, and hyphen. There are also somerestrictions on the length. Labels must be 63 characters or less.*/int check_host(const char *r){ /* a hostname can only consist of * chars and numbers, and sep. by only * one period. * It may not end with a period, and must * not start with a number. * * >0: correct * -1: error * 0: not returned * */ const char *c; short period_ok = 0; short len = 0; c = r; if (c == NULL) { return -1; } /* must start with a letter or number */ if (!isalnum(*c)) return -1; if (strlen(c) > 63) return -1; len = 1; while (*(++c) != '\0') { /* interior letters may be alphanumeric, '-', or '.' */ /* '.' may not follow '.' */ if (isalnum(*c) || *c == '-') period_ok = 1; else if (*c == '.' && period_ok) period_ok = 0; else return -1; ++len; } /* c points to '\0' */ --c; /* must end with a letter or digit */ if (!isalnum(*c)) return -1; return len;}void strlower(char *s){ while (*s != '\0') { *s = tolower(*s); ++s; }}#ifndef DISABLE_DEBUGstruct dbg { int level; const char *mesg;};static struct dbg debug_level_table[] = { {DEBUG_ALIAS, "Alias"}, {DEBUG_CGI_OUTPUT, "CGI Output"}, {DEBUG_CGI_INPUT, "CGI Input"}, {DEBUG_CGI_ENV, "CGI Environment"}, {DEBUG_HEADER_READ, "Header Read State"}, {DEBUG_PIPELINE, "Pipeline"}, {DEBUG_PLUGIN_ERRORS, "Plugin Error"}, {DEBUG_RANGE, "Range related"}, {DEBUG_CONFIG, "Configuration"}, {DEBUG_BUFFER_IO, "Buffer I/O"}, {DEBUG_BODY_READ, "Body Read State"}, {DEBUG_MMAP_CACHE, "mmap Cache"}, {DEBUG_REQUEST, "Generic Request"}, {DEBUG_HASH, "hash table"}};void print_debug_usage(void){ struct dbg *p; fprintf(stderr, " To calculate the debug level, logically 'or'\n" " some of the following values together to get a debug level:\n"); for (p = debug_level_table; p < debug_level_table + (sizeof (debug_level_table) / sizeof (struct dbg)); p++) { fprintf(stderr, "\t%d:\t%s\n", p->level, p->mesg); } fprintf(stderr, "\n");}void parse_debug(char *foo){ int i; struct dbg *p; if (!foo) return; log_error_time(); fprintf(stderr, "Before parse_debug, debug_level is: %d\n", debug_level); if (foo[0] == '-') { i = boa_atoi(foo + 1); if (i == -1) { /* error */ fprintf(stderr, "Invalid level specified.\n"); exit(EXIT_FAILURE); } i = -i; } else { i = boa_atoi(foo); if (i == -1) { /* error */ fprintf(stderr, "Invalid level specified.\n"); exit(EXIT_FAILURE); } } for (p = debug_level_table; p < debug_level_table + (sizeof (debug_level_table) / sizeof (struct dbg)); p++) { if (i > 0) { if (i & p->level) { log_error_time(); fprintf(stderr, "Enabling %s debug level.\n", p->mesg); debug_level |= p->level; } } else { if (-i & p->level) { log_error_time(); fprintf(stderr, "Disabling %s debug level.\n", p->mesg); debug_level &= ~(p->level); } } } log_error_time(); fprintf(stderr, "After parse_debug, debug_level is: %d\n", debug_level);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -