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

📄 util.c

📁 友善之臂SBC-2410X开发板所使用的测试程序包
💻 C
字号:
/* *  Boa, an http server *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com> *  Some changes Copyright (C) 1996,97 Larry Doolittle <ldoolitt@boa.org> *  Some changes Copyright (C) 1996 Charles F. Randall <crandall@goldsys.com> *  Some changes Copyright (C) 1996-99 Jon Nelson <jnelson@boa.org> * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 1, or (at your option) *  any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *//* $Id: util.c,v 1.61.2.3 2002/07/07 23:22:18 jnelson Exp $ */#include "boa.h"#define HEX_TO_DECIMAL(char1, char2)	\    (((char1 >= 'A') ? (((char1 & 0xdf) - 'A') + 10) : (char1 - '0')) * 16) + \    (((char2 >= 'A') ? (((char2 & 0xdf) - 'A') + 10) : (char2 - '0')))const char month_tab[48] =    "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ";const char day_tab[] = "Sun,Mon,Tue,Wed,Thu,Fri,Sat,";/* * Name: clean_pathname * * Description: Replaces unsafe/incorrect instances of: *  //[...] with / *  /./ with / *  /../ with / (technically not what we want, but browsers should deal *   with this, not servers) */void clean_pathname(char *pathname){    char *cleanpath, c;    cleanpath = pathname;    while ((c = *pathname++)) {        if (c == '/') {            while (1) {                if (*pathname == '/')                    pathname++;                else if (*pathname == '.' && *(pathname + 1) == '/')                    pathname += 2;                else if (*pathname == '.' && *(pathname + 1) == '.' &&                         *(pathname + 2) == '/') {                    pathname += 3;                } else                    break;            }            c = '/';        }        *cleanpath++ = c;    }    *cleanpath = '\0';}/* * Name: get_commonlog_time * * Description: Returns the current time in common log format in a static * char buffer. * * commonlog time is exactly 25 characters long * because this is only used in logging, we add " [" before and "] " after * making 29 characters * "[27/Feb/1998:20:20:04 +0000] " * * Constrast with rfc822 time: * "Sun, 06 Nov 1994 08:49:37 GMT" * * Altered 10 Jan 2000 by Jon Nelson ala Drew Streib for non UTC logging * */char *get_commonlog_time(void){    struct tm *t;    char *p;    unsigned int a;    static char buf[30];    int time_offset;    if (use_localtime) {        t = localtime(&current_time);        time_offset = TIMEZONE_OFFSET(t);    } else {        t = gmtime(&current_time);        time_offset = 0;    }    p = buf + 29;    *p-- = '\0';    *p-- = ' ';    *p-- = ']';    a = abs(time_offset / 60);    *p-- = '0' + a % 10;    a /= 10;    *p-- = '0' + a % 6;    a /= 6;    *p-- = '0' + a % 10;    *p-- = '0' + a / 10;    *p-- = (time_offset >= 0) ? '+' : '-';    *p-- = ' ';    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 */    *p-- = '/';    p -= 2;    memcpy(p--, month_tab + 4 * (t->tm_mon), 3);    *p-- = '/';    a = t->tm_mday;    *p-- = '0' + a % 10;    *p-- = '0' + a / 10;    *p = '[';    return p;                   /* should be same as returning buf */}/* * Name: month2int * * Description: Turns a three letter month into a 0-11 int * * Note: This function is from wn-v1.07 -- it's clever and fast */int month2int(char *monthname){    switch (*monthname) {    case 'A':        return (*++monthname == 'p' ? 3 : 7);    case 'D':        return (11);    case 'F':        return (1);    case 'J':        if (*++monthname == 'a')            return (0);        return (*++monthname == 'n' ? 5 : 6);    case 'M':        return (*(monthname + 2) == 'r' ? 2 : 4);    case 'N':        return (10);    case 'O':        return (9);    case 'S':        return (8);    default:        return (-1);    }}/* * Name: modified_since * Description: Decides whether a file's mtime is newer than the * If-Modified-Since header of a request. * Sun, 06 Nov 1994 08:49:37 GMT    ; RFC 822, updated by RFC 1123 Sunday, 06-Nov-94 08:49:37 GMT   ; RFC 850, obsoleted by RFC 1036 Sun Nov  6 08:49:37 1994         ; ANSI C's asctime() format 31 September 2000 23:59:59 GMT   ; non-standard * RETURN VALUES: *  0: File has not been modified since specified time. *  1: File has been. * -1: Error! */int modified_since(time_t * mtime, char *if_modified_since){    struct tm *file_gmt;    char *ims_info;    char monthname[10 + 1];    int day, month, year, hour, minute, second;    int comp;    ims_info = if_modified_since;    while (*ims_info != ' ' && *ims_info != '\0')        ++ims_info;    if (*ims_info != ' ')        return -1;    /* the pre-space in the third scanf skips whitespace for the string */    if (sscanf(ims_info, "%d %3s %d %d:%d:%d GMT", /* RFC 1123 */               &day, monthname, &year, &hour, &minute, &second) == 6);    else if (sscanf(ims_info, "%d-%3s-%d %d:%d:%d GMT", /* RFC 1036 */                    &day, monthname, &year, &hour, &minute, &second) == 6)        year += 1900;    else if (sscanf(ims_info, " %3s %d %d:%d:%d %d", /* asctime() format */                    monthname, &day, &hour, &minute, &second, &year) == 6);    /*  allow this non-standard date format: 31 September 2000 23:59:59 GMT */    /* NOTE: Use if_modified_since here, because the date *starts*     *       with the day, versus a throwaway item     */    else if (sscanf(if_modified_since, "%d %10s %d %d:%d:%d GMT",                    &day, monthname, &year, &hour, &minute, &second) == 6);    else {        log_error_time();        fprintf(stderr, "Error in %s, line %d: Unable to sscanf \"%s\"\n",                __FILE__, __LINE__, ims_info);        return -1;              /* error */    }    file_gmt = gmtime(mtime);    month = month2int(monthname);    /* Go through from years to seconds -- if they are ever unequal,     we know which one is newer and can return */    if ((comp = 1900 + file_gmt->tm_year - year))        return (comp > 0);    if ((comp = file_gmt->tm_mon - month))        return (comp > 0);    if ((comp = file_gmt->tm_mday - day))        return (comp > 0);    if ((comp = file_gmt->tm_hour - hour))        return (comp > 0);    if ((comp = file_gmt->tm_min - minute))        return (comp > 0);    if ((comp = file_gmt->tm_sec - second))        return (comp > 0);    return 0;                   /* this person must really be into the latest/greatest */}/* * Name: to_upper * * Description: Turns a string into all upper case (for HTTP_ header forming) * AND changes - into _ */char *to_upper(char *str){    char *start = str;    while (*str) {        if (*str == '-')            *str = '_';        else            *str = toupper(*str);        str++;    }    return start;}/* * Name: unescape_uri * * Description: Decodes a uri, changing %xx encodings with the actual * character.  The query_string should already be gone. * * 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);            else                return 0;       /* NULL in chars to be decoded */        } else if (c == '?') { /* query string */            if (query_string)                *query_string = ++uri_old;            /* stop here */            *uri = '\0';            return(1);            break;        } 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(&current_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 + 1;}/* I don't "do" negative conversions * Therefore, -1 indicates error */int boa_atoi(char *s){    int retval;    char *reconv;    if (!isdigit(*s))        return -1;    retval = atoi(s);    if (retval < 0)        return -1;    reconv = simple_itoa(retval);    if (memcmp(s,reconv,strlen(s)) != 0) {        return -1;    }    return retval;}int create_temporary_file(short want_unlink, char *storage, 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) {        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);}/* * Name: normalize_path * * Description: Makes sure relative paths are made absolute * */#define DIRBUF_SIZE MAX_PATH_LENGTH * 2 + 1char * normalize_path(char *path){    char dirbuf[DIRBUF_SIZE];    int len1, len2;    char *endpath;    if (path[0] == '/') {        endpath = strdup(path);    } else {#ifndef HAVE_GETCWD        perror("boa: getcwd() not defined. Aborting.");        exit(1);#endif        if (getcwd(dirbuf, DIRBUF_SIZE) == NULL) {            if (errno == ERANGE)                perror                    ("boa: getcwd() failed - unable to get working directory. "                     "Aborting.");            else if (errno == EACCES)                perror("boa: getcwd() failed - No read access in current "                       "directory. Aborting.");            else                perror("boa: getcwd() failed - unknown error. Aborting.");            exit(1);        }        /* OK, now the hard part. */        len1 = strlen(dirbuf);        len2 = strlen(path);        if (len1 + len2 > MAX_PATH_LENGTH * 2) {            perror("boa: eek. unable to normalize pathname");            exit(1);        }        if (strcmp(path,".") != 0) {            memcpy(dirbuf + len1, "/", 1);            memcpy(dirbuf + len1 + 1, path, len2 + 1);        }        /* fprintf(stderr, "boa: normalize gets \"%s\"\n", dirbuf); */        endpath = strdup(dirbuf);    }    if (endpath == NULL) {        fprintf(stderr,                "boa: Cannot strdup path. Aborting.\n");        exit(1);    }    return endpath;}int real_set_block_fd(int fd){    int flags;    flags = fcntl(fd, F_GETFL);    if (flags == -1)        return -1;    flags &= ~O_NONBLOCK;    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 |= O_NONBLOCK;    flags = fcntl(fd, F_SETFL, flags);    return flags;}

⌨️ 快捷键说明

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