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

📄 util.c

📁 嵌入式linux下web服务器, 解压后运行mymk即可,在arm-linux3.4.1下测试通过.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Boa, an http server *  Copyright (C) 1995 Paul Phillips <paulp@go2net.com> *  Some changes Copyright (C) 1996 Charles F. Randall <crandall@goldsys.com> *  Copyright (C) 1996-1999 Larry Doolittle <ldoolitt@boa.org> *  Copyright (C) 1996-2005 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.22 2005/02/22 14:11:29 jnelson Exp $ */#include "boa.h"static int date_to_tm(struct tm *file_gmt, const char *cmtime);/* Don't need or want the trailing nul for these character arrays */static const char month_tab[48] =    "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ";static const char day_tab[28] = "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';}#if 0char *new_clean_pathname(char *pathname){    static char *segment[50];    int seg_count = 0;    char *a, *cleanpath, c;    a = pathname;    segment[seg_count] = pathname;    cleanpath = pathname;    while ((c = *pathname++)) {        if (c == '/') {         /* /?? */            while (1) {         /* everything in this loop gets eliminated */                if (*pathname == '/') /* // */                    pathname++;                else if (*pathname == '.') { /* /. */                    if (*(pathname + 1) == '/') /* /./ */                        pathname += 2;                    else if (*(pathname + 1) == '\0') /* /.$ */                        pathname += 1;                    else if (*(pathname + 1) == '.') { /* /.. */                        if (*(pathname + 2) == '/') /* /../ */                            pathname += 3;                        else if (*(pathname + 1) == '\0') /* /..$ */                            pathname += 2;                        /*                           cleanpath goes *back* one                         */                        if (seg_count)                            cleanpath = segment[--seg_count];                        else {                            *a = '\0';                            return a;                        }                    } else {    /* /.blah */                        break;                    }                } else {        /* we have /something */                    break;                }            }            if (seg_count > 49) { /* we can store in spots 0...49 */                *a = '\0';                return a;            }            *cleanpath = '/';            segment[seg_count++] = cleanpath++;        } else            *cleanpath++ = c;    }    *cleanpath = '\0';    return a;}#endif/* * 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] " * * Contrast 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(const 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: date_to_seconds * Description: * 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: *  -1 for error, 0 for success */static int date_to_tm(struct tm *parsed_gmt, const char *cmtime){    char monthname[10 + 1];    const char *cmtime_start = cmtime;    int day, year, hour, minute, second;    /* we don't use the weekday portion, so skip over it */    while (*cmtime != ' ' && *cmtime != '\0')        ++cmtime;    if (*cmtime != ' ')        return -1;    /* the pre-space in the third scanf skips whitespace for the string */    if (sscanf(cmtime, "%d %3s %d %d:%d:%d GMT", /* RFC 1123 */               &day, monthname, &year, &hour, &minute, &second) == 6) {    } else if (sscanf(cmtime, "%d-%3s-%d %d:%d:%d GMT", /* RFC 1036 */                      &day, monthname, &year, &hour, &minute, &second) == 6) {    } else if (sscanf(cmtime, "%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 'cmtime_start' instead of 'cmtime' here, because the date *starts*         *       with the day, versus a throwaway item         */    } else if (sscanf(cmtime_start, "%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__, cmtime);        return -1;              /* error */    }    if (year < 70)        year += 100;    if (year > 1900)        year -= 1900;    parsed_gmt->tm_sec = second;    parsed_gmt->tm_min = minute;    parsed_gmt->tm_hour = hour;    parsed_gmt->tm_mday = day;    parsed_gmt->tm_mon = month2int(monthname);    parsed_gmt->tm_year = year;    parsed_gmt->tm_wday = 0;    parsed_gmt->tm_yday = 0;    parsed_gmt->tm_isdst = 0;    if (parsed_gmt->tm_mon == -1) {        log_error_time();        fprintf(stderr, "Invalid month name: \"%s\"\n", monthname);        return -1;    }    /* adapted from Squid 2.5 */    if (parsed_gmt->tm_sec < 0 || parsed_gmt->tm_sec > 59)        return -1;    if (parsed_gmt->tm_min < 0 || parsed_gmt->tm_min > 59)        return -1;    if (parsed_gmt->tm_hour < 0 || parsed_gmt->tm_hour > 23)        return -1;    if (parsed_gmt->tm_mday < 1 || parsed_gmt->tm_mday > 31)        return -1;    if (parsed_gmt->tm_mon < 0 || parsed_gmt->tm_mon > 11)        return -1;    if (parsed_gmt->tm_year < 70 || parsed_gmt->tm_year > 120)        return -1;    return 0;}/* * Name: modified_since * Description: Decides whether a file's mtime is newer than the * If-Modified-Since header of a request. * * RETURN VALUES: *  0: File has not been modified since specified time. *  >0: File has been (and value is the converted_time) * -1: Error! */int modified_since(time_t * mtime, const char *if_modified_since){    struct tm *file_gmt;    struct tm parsed_gmt;    int comp;    if (date_to_tm(&parsed_gmt, if_modified_since) != 0) {        return -1;    }    file_gmt = gmtime(mtime);    /* Go through from years to seconds -- if they are ever unequal,       we know which one is newer and can return */    if ((comp = file_gmt->tm_year - parsed_gmt.tm_year))        return (comp > 0);    if ((comp = file_gmt->tm_mon - parsed_gmt.tm_mon))        return (comp > 0);    if ((comp = file_gmt->tm_mday - parsed_gmt.tm_mday))        return (comp > 0);    if ((comp = file_gmt->tm_hour - parsed_gmt.tm_hour))        return (comp > 0);    if ((comp = file_gmt->tm_min - parsed_gmt.tm_min))        return (comp > 0);    if ((comp = file_gmt->tm_sec - parsed_gmt.tm_sec))        return (comp > 0);    /* this person must really be into the latest/greatest */    return 0;}/* * 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. *

⌨️ 快捷键说明

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