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

📄 jk_util.c

📁 精通tomcat书籍原代码,希望大家共同学习
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *  Copyright 1999-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/***************************************************************************
 * Description: Utility functions (mainly configuration)                   *
 * Author:      Gal Shachor <shachor@il.ibm.com>                           *
 * Author:      Henri Gomez <hgomez@apache.org>                            *
 * Version:     $Revision: 386592 $                                          *
 ***************************************************************************/


#include "jk_util.h"
#include "jk_ajp12_worker.h"
#include "jk_ajp13_worker.h"
#include "jk_ajp14_worker.h"
#include "jk_lb_worker.h"
#include "jk_mt.h"

#define SYSPROPS_OF_WORKER          ("sysprops")
#define STDERR_OF_WORKER            ("stderr")
#define STDOUT_OF_WORKER            ("stdout")
#define SECRET_OF_WORKER            ("secret")
#define CONF_OF_WORKER              ("conf")
#define MX_OF_WORKER                ("mx")
#define MS_OF_WORKER                ("ms")
#define CP_OF_WORKER                ("class_path")
#define BRIDGE_OF_WORKER            ("bridge")
#define JVM_OF_WORKER               ("jvm_lib")
#define LIBPATH_OF_WORKER           ("ld_path")
#define CMD_LINE_OF_WORKER          ("cmd_line")
#define NATIVE_LIB_OF_WORKER        ("native_lib")
#define HOST_OF_WORKER              ("host")
#define PORT_OF_WORKER              ("port")
#define TYPE_OF_WORKER              ("type")
#define CACHE_OF_WORKER_DEPRECATED  ("cachesize")
#define CACHE_OF_WORKER             ("connection_pool_size")
#define CACHE_TIMEOUT_OF_WORKER     ("cache_timeout")
#define RECOVERY_OPTS_OF_WORKER     ("recovery_options")
#define CONNECT_TIMEOUT_OF_WORKER   ("connect_timeout")
#define PREPOST_TIMEOUT_OF_WORKER   ("prepost_timeout")
#define REPLY_TIMEOUT_OF_WORKER     ("reply_timeout")
#define SOCKET_TIMEOUT_OF_WORKER    ("socket_timeout")
#define SOCKET_BUFFER_OF_WORKER     ("socket_buffer")
#define SOCKET_KEEPALIVE_OF_WORKER  ("socket_keepalive")
#define RECYCLE_TIMEOUT_OF_WORKER   ("recycle_timeout")
#define LOAD_FACTOR_OF_WORKER       ("lbfactor")
/* deprecated directive. Use balance_workers instead */
#define BALANCED_WORKERS            ("balanced_workers")
#define BALANCE_WORKERS             ("balance_workers")
#define STICKY_SESSION              ("sticky_session")
#define STICKY_SESSION_FORCE        ("sticky_session_force")
#define DOMAIN_OF_WORKER            ("domain")
#define REDIRECT_OF_WORKER          ("redirect")
#define MOUNT_OF_WORKER             ("mount")
#define METHOD_OF_WORKER            ("method")
#define LOCK_OF_WORKER              ("lock")
#define IS_WORKER_DISABLED          ("disabled")
#define IS_WORKER_STOPPED           ("stopped")
#define WORKER_RECOVER_TIME         ("recover_time")


#define DEFAULT_WORKER_TYPE         JK_AJP13_WORKER_NAME
#define SECRET_KEY_OF_WORKER        ("secretkey")
#define RETRIES_OF_WORKER           ("retries")

#define DEFAULT_WORKER              JK_AJP13_WORKER_NAME
#define WORKER_LIST_PROPERTY_NAME     ("worker.list")
#define WORKER_MAINTAIN_PROPERTY_NAME ("worker.maintain")
#define DEFAULT_MAINTAIN_TIME       (60)
#define DEFAULT_LB_FACTOR           (1)
#define LOG_FORMAT                  ("log_format")

#define TOMCAT32_BRIDGE_NAME        ("tomcat32")
#define TOMCAT33_BRIDGE_NAME        ("tomcat33")
#define TOMCAT40_BRIDGE_NAME        ("tomcat40")
#define TOMCAT41_BRIDGE_NAME        ("tomcat41")
#define TOMCAT50_BRIDGE_NAME        ("tomcat5")

#define HUGE_BUFFER_SIZE (8*1024)
#define LOG_LINE_SIZE    (1024)

#define MAKE_WORKER_PARAM(P)     \
        strcpy(buf, "worker.");  \
        strcat(buf, wname);      \
        strcat(buf, ".");        \
        strcat(buf, P)

/*
 * define the log format, we're using by default the one from error.log
 *
 * [Mon Mar 26 19:44:48 2001] [jk_uri_worker_map.c (155)]: Into jk_uri_worker_map_t::uri_worker_map_alloc
 * log format used by apache in error.log
 */
#ifndef JK_TIME_FORMAT
#define JK_TIME_FORMAT "[%a %b %d %H:%M:%S %Y] "
#endif

/* Visual C++ Toolkit 2003 support */
#if defined (_MSC_VER) && (_MSC_VER == 1310)
    extern long _ftol(double); /* defined by VC6 C libs */
    extern long _ftol2(double dblSource) { return _ftol(dblSource); }
#endif

static const char *jk_level_werbs[] = {
    "[" JK_LOG_TRACE_VERB "] ",
    "[" JK_LOG_DEBUG_VERB "] ",
    "[" JK_LOG_INFO_VERB  "]  ",
    "[" JK_LOG_WARNING_VERB  "]  ",
    "[" JK_LOG_ERROR_VERB "] ",
    "[" JK_LOG_EMERG_VERB "] ",
    NULL
};

const char *jk_log_fmt = JK_TIME_FORMAT;

static void set_time_str(char *str, int len)
{
    time_t t = time(NULL);
    struct tm *tms;

    tms = localtime(&t);
    strftime(str, len, jk_log_fmt, tms);
}

/* Write at most n characters to the buffer in str, return the
 * number of chars written or -1 if the buffer would have been
 * overflowed.
 *
 * This is portable to any POSIX-compliant system that has /dev/null
 */
#if !defined(HAVE_VSNPRINTF) && !defined(HAVE_APR)
static FILE *f = NULL;
static int vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
{
    int res;

    if (f == NULL)
        f = fopen("/dev/null", "w");
    if (f == NULL)
        return -1;

    setvbuf(f, str, _IOFBF, n);

    res = vfprintf(f, fmt, ap);

    if (res > 0 && res < n) {
        res = vsprintf(str, fmt, ap);
    }
    return res;
}
#endif
#if !defined(HAVE_SNPRINTF) && !defined(HAVE_APR)
static int snprintf(char *str, size_t n, const char *fmt, ...)
{
    va_list ap;
    int res;

    va_start(ap, fmt);
    res = vsnprintf(str, n, fmt, ap);
    va_end(ap);
    return res;
}
#endif

static int JK_METHOD log_to_file(jk_logger_t *l, int level, const char *what)
{
    if (l &&
        (l->level <= level || level == JK_LOG_REQUEST_LEVEL) &&
        l->logger_private && what) {
        size_t sz = strlen(what);
        if (sz) {
            file_logger_t *p = l->logger_private;
            fwrite(what, 1, sz, p->logfile);
            fputc('\n', p->logfile);
            /* [V] Flush the dam' thing! */
            if (l->level < JK_LOG_INFO_LEVEL)
                fflush(p->logfile);
        }

        return JK_TRUE;
    }

    return JK_FALSE;
}

int jk_parse_log_level(const char *level)
{
    if (0 == strcasecmp(level, JK_LOG_TRACE_VERB)) {
        return JK_LOG_TRACE_LEVEL;
    }

    if (0 == strcasecmp(level, JK_LOG_DEBUG_VERB)) {
        return JK_LOG_DEBUG_LEVEL;
    }

    if (0 == strcasecmp(level, JK_LOG_INFO_VERB)) {
        return JK_LOG_INFO_LEVEL;
    }

    if (0 == strcasecmp(level, JK_LOG_WARNING_VERB)) {
        return JK_LOG_WARNING_LEVEL;
    }

    if (0 == strcasecmp(level, JK_LOG_ERROR_VERB)) {
        return JK_LOG_ERROR_LEVEL;
    }

    if (0 == strcasecmp(level, JK_LOG_EMERG_VERB)) {
        return JK_LOG_EMERG_LEVEL;
    }

    return JK_LOG_INFO_LEVEL;
}

int jk_open_file_logger(jk_logger_t **l, const char *file, int level)
{
    if (l && file) {
        jk_logger_t *rc = (jk_logger_t *)malloc(sizeof(jk_logger_t));
        file_logger_t *p = (file_logger_t *) malloc(sizeof(file_logger_t));
        if (rc && p) {
            rc->log = log_to_file;
            rc->level = level;
            rc->logger_private = p;
#ifdef AS400
            p->logfile = fopen(file, "a+, o_ccsid=0");
#else
            p->logfile = fopen(file, "a+");
#endif
            if (p->logfile) {
                *l = rc;
                return JK_TRUE;
            }
        }
        if (rc) {
            free(rc);
        }
        if (p) {
            free(p);
        }

        *l = NULL;
    }
    return JK_FALSE;
}

int jk_close_file_logger(jk_logger_t **l)
{
    if (l && *l) {
        file_logger_t *p = (*l)->logger_private;
        if (p) {
            fflush(p->logfile);
            fclose(p->logfile);
            free(p);
        }
        free(*l);
        *l = NULL;

        return JK_TRUE;
    }
    return JK_FALSE;
}

int jk_log(jk_logger_t *l,
           const char *file, int line, const char *funcname, int level,
           const char *fmt, ...)
{
    int rc = 0;
    if (!l || !file || !fmt) {
        return -1;
    }

    if ((l->level <= level) || (level == JK_LOG_REQUEST_LEVEL)) {
#ifdef NETWARE
/* On NetWare, this can get called on a thread that has a limited stack so */
/* we will allocate and free the temporary buffer in this function         */
        char *buf;
#else
        char buf[HUGE_BUFFER_SIZE];
#endif
        char *f = (char *)(file + strlen(file) - 1);
        va_list args;
        size_t used = 0;

        while (f != file && '\\' != *f && '/' != *f) {
            f--;
        }
        if (f != file) {
            f++;
        }

#ifdef NETWARE
        buf = (char *)malloc(HUGE_BUFFER_SIZE);
        if (NULL == buf)
            return -1;
#endif
        set_time_str(buf, HUGE_BUFFER_SIZE);
        used = strlen(buf);

        /* Log [pid:threadid] for debug and trace levels */
        if (l->level < JK_LOG_INFO_LEVEL) {
#ifdef USE_SPRINTF              /* until we get a snprintf function */
            used += sprintf(&buf[used], "[%04d:%04d] ", getpid(),
                            jk_gettid());
#else
            used += snprintf(&buf[used], HUGE_BUFFER_SIZE - used,
                             "[%04d:%04d] ", getpid(), jk_gettid());
#endif
            if (used < 0) {
                return 0;
            }
        }
        if (line) {
            strcat(buf, jk_level_werbs[level]);
            used += 8;

            if (funcname) {
                strcat(buf, funcname);
                strcat(buf, "::");
                used += strlen(funcname) + 2;
            }
        }

#ifdef USE_SPRINTF              /* until we get a snprintf function */
        if (line)
            used += sprintf(&buf[used], "%s (%d): ", f, line);
#else
        if (line)
            used += snprintf(&buf[used], HUGE_BUFFER_SIZE - used,
                             "%s (%d): ", f, line);
#endif
        if (used < 0) {
            return 0;           /* [V] not sure what to return... */
        }

        va_start(args, fmt);
#ifdef USE_VSPRINTF             /* until we get a vsnprintf function */
        rc = vsprintf(buf + used, fmt, args);
#else
        rc = vsnprintf(buf + used, HUGE_BUFFER_SIZE - used, fmt, args);
#endif
        va_end(args);
        l->log(l, level, buf);
#ifdef NETWARE
        free(buf);
#endif
    }

    return rc;
}

const char *jk_get_worker_type(jk_map_t *m, const char *wname)
{
    char buf[1024];

    if (!m || !wname) {
        return NULL;
    }
    MAKE_WORKER_PARAM(TYPE_OF_WORKER);
    return jk_map_get_string(m, buf, DEFAULT_WORKER_TYPE);
}

const char *jk_get_worker_domain(jk_map_t *m, const char *wname, const char *def)
{
    char buf[1024];
    if (!m || !wname) {
        return NULL;
    }
    MAKE_WORKER_PARAM(DOMAIN_OF_WORKER);
    return jk_map_get_string(m, buf, def);
}

const char *jk_get_worker_redirect(jk_map_t *m, const char *wname, const char *def)
{
    char buf[1024];
    if (!m || !wname) {
        return NULL;
    }
   MAKE_WORKER_PARAM(REDIRECT_OF_WORKER);
    return jk_map_get_string(m, buf, def);
}

const char *jk_get_worker_secret(jk_map_t *m, const char *wname)
{
    char buf[1024];

    if (!m || !wname) {
        return NULL;
    }

    MAKE_WORKER_PARAM(SECRET_OF_WORKER);

    return jk_map_get_string(m, buf, NULL);
}

/* [V] I suggest that the following general purpose functions be used.       */
/*     More should be added (double etc.), but now these were enough for me. */
/*     Functions that can be simulated with these should be "deprecated".    */

int jk_get_worker_str_prop(jk_map_t *m,
                           const char *wname, const char *pname, const char **prop)
{
    char buf[1024];

    if (m && prop && wname && pname) {
        MAKE_WORKER_PARAM(pname);

⌨️ 快捷键说明

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