"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "mod_rrd.c" between
mod_rrd-1.0.0.tar.bz2 and mod_rrd-1.0.1.tar.bz2

About: mod_rrd is an Apache httpd module to render RRD graphs via a webserver.

mod_rrd.c  (mod_rrd-1.0.0.tar.bz2):mod_rrd.c  (mod_rrd-1.0.1.tar.bz2)
skipping to change at line 32 skipping to change at line 32
* *
* <IfModule mod_rrd.c> * <IfModule mod_rrd.c>
* <Directory "/var/lib/collectd/rrd"> * <Directory "/var/lib/collectd/rrd">
* Require all granted * Require all granted
* </Directory> * </Directory>
* Alias /rrd /var/lib/collectd/rrd * Alias /rrd /var/lib/collectd/rrd
* <Location /rrd> * <Location /rrd>
* RRDGraph on * RRDGraph on
* RRDGraphOption title %{SERVER_NAME} * RRDGraphOption title %{SERVER_NAME}
* RRDGraphEnv METHODS %{REQUEST_METHOD} * RRDGraphEnv METHODS %{REQUEST_METHOD}
* RRDGraphElement DEF:xifOutOctets=monitor*.rrd:ifOutOctets:AVERAGE * RRDGraphElement DEF:xifOutOctets=monitor*.rrd:ifOutOctets:AVERAGE "option al/expression/monitor*.rrd" "/optional/path/prefix/"
* RRDGraphElement VDEF:xifOutOctetsmax=xifOutOctets+,MAXIMUM * RRDGraphElement VDEF:xifOutOctetsmax=xifOutOctets+,MAXIMUM
* RRDGraphElement CDEF:xcombined=xifOutOctets,1,+ * RRDGraphElement CDEF:xcombined=xifOutOctets,1,+
* RRDGraphElement LINE1:xifOutOctets#00ff00:Out+Octets :%{SERVER_NAME} * RRDGraphElement LINE1:xifOutOctets#00ff00:Out+Octets :%{SERVER_NAME}
* RRDGraphElement AREA:xifOutOctets#00ff00:Out+Octets :%{SERVER_NAME} * RRDGraphElement AREA:xifOutOctets#00ff00:Out+Octets :%{SERVER_NAME}
* RRDGraphElement TICK:xifOutOctets#00ff00:1.0:Failures :%{SERVER_NAME} * RRDGraphElement TICK:xifOutOctets#00ff00:1.0:Failures :%{SERVER_NAME}
* RRDGraphElement "VRULE:0#FF0000:dashed line:dashes" :%{SERVER_NAME} * RRDGraphElement "VRULE:0#FF0000:dashed line:dashes" :%{SERVER_NAME}
* RRDGraphElement "HRULE:0#FF0000:dashed line:dashes" :%{SERVER_NAME} * RRDGraphElement "HRULE:0#FF0000:dashed line:dashes" :%{SERVER_NAME}
* RRDGraphElement "COMMENT:Foo" %{env:METHODS} * RRDGraphElement "COMMENT:Foo" %{env:METHODS}
* </Location> * </Location>
* </IfModule> * </IfModule>
skipping to change at line 133 skipping to change at line 133
static apr_thread_mutex_t *rrd_mutex = NULL; static apr_thread_mutex_t *rrd_mutex = NULL;
#endif #endif
module AP_MODULE_DECLARE_DATA rrd_module; module AP_MODULE_DECLARE_DATA rrd_module;
typedef struct rrd_conf { typedef struct rrd_conf {
const char *location; const char *location;
apr_array_header_t *options; apr_array_header_t *options;
apr_array_header_t *elements; apr_array_header_t *elements;
apr_hash_t *env; apr_hash_t *env;
const char *format;
int graph; int graph;
unsigned int location_set:1; unsigned int location_set:1;
unsigned int format_set:1;
unsigned int graph_set:1; unsigned int graph_set:1;
} rrd_conf; } rrd_conf;
typedef struct rrd_ctx { typedef struct rrd_ctx {
apr_file_t *file; apr_file_t *file;
apr_bucket_brigade *bb; apr_bucket_brigade *bb;
} rrd_ctx; } rrd_ctx;
typedef enum rrd_conf_e { typedef enum rrd_conf_e {
RRD_CONF_DEF, RRD_CONF_DEF,
skipping to change at line 168 skipping to change at line 170
typedef struct rrd_cmd_t rrd_cmd_t; typedef struct rrd_cmd_t rrd_cmd_t;
typedef struct rrd_def_t { typedef struct rrd_def_t {
const char *vname; const char *vname;
const char *path; const char *path;
const char *dsname; const char *dsname;
const char *cf; const char *cf;
apr_pool_t *pool; apr_pool_t *pool;
apr_array_header_t *requests; apr_array_header_t *requests;
ap_expr_info_t *epath;
ap_expr_info_t *edirpath;
} rrd_def_t; } rrd_def_t;
typedef struct rrd_vdef_t { typedef struct rrd_vdef_t {
const char *vname; const char *vname;
const char *dsname; const char *dsname;
const char *rpn; const char *rpn;
rrd_cmd_t *ref; rrd_cmd_t *ref;
} rrd_vdef_t; } rrd_vdef_t;
typedef struct rrd_cdef_t { typedef struct rrd_cdef_t {
skipping to change at line 463 skipping to change at line 467
" </wadl:resource>\n" " </wadl:resource>\n"
" </wadl:resources>\n" " </wadl:resources>\n"
"</wadl:application>\n", "</wadl:application>\n",
conf->location ? conf->location : conf->location ? conf->location :
apr_pstrcat(r->pool, ap_http_scheme(r), "://", apr_pstrcat(r->pool, ap_http_scheme(r), "://",
r->server->server_hostname, r->uri, NULL)); r->server->server_hostname, r->uri, NULL));
return OK; return OK;
} }
static const char *lookup_content_type(const char *format)
{
switch(format[0]) {
case 'p':
case 'P':
if (strcasecmp(format, "PNG") == 0) {
return "image/png";
}
if (strcasecmp(format, "PDF") == 0) {
return "application/pdf";
}
break;
case 's':
case 'S':
if (strcasecmp(format, "SVG") == 0) {
return "image/svg+xml";
}
if (strcasecmp(format, "SSV") == 0) {
return "text/plain";
}
break;
case 'e':
case 'E':
if (strcasecmp(format, "EPS") == 0) {
return "application/eps";
}
break;
case 'x':
case 'X':
if (strcasecmp(format, "XML") == 0) {
return "application/xml";
}
if (strcasecmp(format, "XMLENUM") == 0) {
return "application/xml";
}
break;
case 'j':
case 'J':
if (strcasecmp(format, "JSON") == 0) {
return "application/json";
}
if (strcasecmp(format, "JSONTIME") == 0) {
return "application/json";
}
break;
case 'c':
case 'C':
if (strcasecmp(format, "CSV") == 0) {
return "text/csv";
}
break;
case 't':
case 'T':
if (strcasecmp(format, "TSV") == 0) {
return "text/tab-separated-values";
}
break;
}
return NULL;
}
static const char *parse_rrdgraph_suffix(request_rec *r) static const char *parse_rrdgraph_suffix(request_rec *r)
{ {
const char *fname = ap_strrchr_c(r->filename, '/'); const char *fname = ap_strrchr_c(r->filename, '/');
if (fname) { if (fname) {
/* PNG|SVG|EPS|PDF|XML|XMLENUM|JSON|JSONTIME|CSV|TSV|SSV */ /* PNG|SVG|EPS|PDF|XML|XMLENUM|JSON|JSONTIME|CSV|TSV|SSV */
const char *suffix = ap_strrchr_c(fname, '.'); const char *suffix = ap_strrchr_c(fname, '.');
if (suffix) { if (suffix) {
switch (suffix[1]) { switch (suffix[1]) {
case 'p': case 'p':
case 'P': case 'P':
if (strcasecmp(suffix, ".png") == 0) { if (strcasecmp(suffix, ".png") == 0) {
return "PNG"; return "PNG";
} }
if (strcasecmp(suffix, "pdf") == 0) { if (strcasecmp(suffix, ".pdf") == 0) {
return "PDF"; return "PDF";
} }
break; break;
case 's': case 's':
case 'S': case 'S':
if (strcasecmp(suffix, ".svg") == 0) { if (strcasecmp(suffix, ".svg") == 0) {
return "SVG"; return "SVG";
} }
if (strcasecmp(suffix, "ssv") == 0) { if (strcasecmp(suffix, ".ssv") == 0) {
return "SSV"; return "SSV";
} }
break; break;
case 'e': case 'e':
case 'E': case 'E':
if (strcasecmp(suffix, ".eps") == 0) { if (strcasecmp(suffix, ".eps") == 0) {
return "EPS"; return "EPS";
} }
break; break;
case 'x': case 'x':
skipping to change at line 532 skipping to change at line 597
if (strcasecmp(suffix, ".tsv") == 0) { if (strcasecmp(suffix, ".tsv") == 0) {
return "TSV"; return "TSV";
} }
break; break;
} }
} }
} }
return NULL; return NULL;
} }
static int parse_element(apr_pool_t *p, const char *element, ap_expr_info_t *ele static int parse_element(apr_pool_t *p, const char *element, ap_expr_info_t *exp
gend, r1,
apr_array_header_t *cmds) ap_expr_info_t *expr2, apr_array_header_t *cmds)
{ {
switch (element[0]) { switch (element[0]) {
case 'A': case 'A':
/* handle AREA sections */ /* handle AREA sections */
if (strncmp(element, "AREA:", 5) == 0) { if (strncmp(element, "AREA:", 5) == 0) {
char *vncol; char *vncol;
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_AREA; cmd->type = RRD_CONF_AREA;
element += 5; element += 5;
vncol = ap_getword(p, &element, ':'); vncol = ap_getword(p, &element, ':');
cmd->a.legend = getword_quote(p, &element, ':'); cmd->a.legend = getword_quote(p, &element, ':');
cmd->a.elegend = elegend; cmd->a.elegend = expr1;
cmd->a.args = element; cmd->a.args = element;
cmd->a.vname = apr_cstr_tokenize("#", &vncol); cmd->a.vname = apr_cstr_tokenize("#", &vncol);
cmd->a.colour = vncol; cmd->a.colour = vncol;
return 1; return 1;
} }
break; break;
case 'C': case 'C':
/* handle CDEF sections */ /* handle CDEF sections */
if (strncmp(element, "CDEF:", 5) == 0) { if (strncmp(element, "CDEF:", 5) == 0) {
char *rpn, *rpns; char *rpn, *rpns;
skipping to change at line 575 skipping to change at line 640
rp->rpn = rpn; rp->rpn = rpn;
} }
return 1; return 1;
} }
/* handle COMMENT sections */ /* handle COMMENT sections */
if (strncmp(element, "COMMENT:", 7) == 0) { if (strncmp(element, "COMMENT:", 7) == 0) {
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_COMMENT; cmd->type = RRD_CONF_COMMENT;
cmd->e.element = ap_getword(p, &element, ':'); cmd->e.element = ap_getword(p, &element, ':');
cmd->a.legend = getword_quote(p, &element, ':'); cmd->a.legend = getword_quote(p, &element, ':');
cmd->e.elegend = elegend; cmd->e.elegend = expr1;
return 1; return 1;
} }
break; break;
case 'D': case 'D':
/* handle DEF sections */ /* handle DEF sections */
if (strncmp(element, "DEF:", 4) == 0) { if (strncmp(element, "DEF:", 4) == 0) {
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_DEF; cmd->type = RRD_CONF_DEF;
element += 4; element += 4;
cmd->d.vname = ap_getword(p, &element, '='); cmd->d.vname = ap_getword(p, &element, '=');
cmd->d.path = ap_getword(p, &element, ':'); cmd->d.path = ap_getword(p, &element, ':');
cmd->d.dsname = ap_getword(p, &element, ':'); cmd->d.dsname = ap_getword(p, &element, ':');
cmd->d.cf = element; cmd->d.cf = element;
cmd->d.pool = p; cmd->d.pool = p;
cmd->d.requests = apr_array_make(p, 10, sizeof(request_rec *)); cmd->d.requests = apr_array_make(p, 10, sizeof(request_rec *));
cmd->d.epath = expr1;
cmd->d.edirpath = expr2;
return 1; return 1;
} }
break; break;
case 'G': case 'G':
/* handle GPRINT sections */ /* handle GPRINT sections */
if (strncmp(element, "GPRINT:", 7) == 0) { if (strncmp(element, "GPRINT:", 7) == 0) {
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_GPRINT; cmd->type = RRD_CONF_GPRINT;
element += 7; element += 7;
cmd->p.vname = ap_getword(p, &element, ':'); cmd->p.vname = ap_getword(p, &element, ':');
skipping to change at line 614 skipping to change at line 681
break; break;
case 'H': case 'H':
/* handle HRULE sections */ /* handle HRULE sections */
if (strncmp(element, "HRULE:", 6) == 0) { if (strncmp(element, "HRULE:", 6) == 0) {
char *vncol; char *vncol;
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_HRULE; cmd->type = RRD_CONF_HRULE;
element += 6; element += 6;
vncol = ap_getword(p, &element, ':'); vncol = ap_getword(p, &element, ':');
cmd->r.legend = getword_quote(p, &element, ':'); cmd->r.legend = getword_quote(p, &element, ':');
cmd->r.elegend = elegend; cmd->r.elegend = expr1;
cmd->r.args = element; cmd->r.args = element;
cmd->r.val = apr_cstr_tokenize("#", &vncol); cmd->r.val = apr_cstr_tokenize("#", &vncol);
cmd->r.colour = vncol; cmd->r.colour = vncol;
return 1; return 1;
} }
break; break;
case 'L': case 'L':
/* handle LINE sections */ /* handle LINE sections */
if (strncmp(element, "LINE", 4) == 0) { if (strncmp(element, "LINE", 4) == 0) {
char *vncol; char *vncol;
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_LINE; cmd->type = RRD_CONF_LINE;
cmd->l.line = ap_getword(p, &element, ':'); cmd->l.line = ap_getword(p, &element, ':');
vncol = ap_getword(p, &element, ':'); vncol = ap_getword(p, &element, ':');
cmd->l.legend = getword_quote(p, &element, ':'); cmd->l.legend = getword_quote(p, &element, ':');
cmd->l.elegend = elegend; cmd->l.elegend = expr1;
cmd->l.args = element; cmd->l.args = element;
cmd->l.vname = apr_cstr_tokenize("#", &vncol); cmd->l.vname = apr_cstr_tokenize("#", &vncol);
cmd->l.colour = vncol; cmd->l.colour = vncol;
cmd->l.elegend = elegend; cmd->l.elegend = expr1;
return 1; return 1;
} }
break; break;
case 'P': case 'P':
/* handle PRINT sections */ /* handle PRINT sections */
if (strncmp(element, "PRINT:", 6) == 0) { if (strncmp(element, "PRINT:", 6) == 0) {
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_PRINT; cmd->type = RRD_CONF_PRINT;
element += 6; element += 6;
cmd->p.vname = ap_getword(p, &element, ':'); cmd->p.vname = ap_getword(p, &element, ':');
skipping to change at line 670 skipping to change at line 737
case 'T': case 'T':
/* handle TICK sections */ /* handle TICK sections */
if (strncmp(element, "TICK:", 5) == 0) { if (strncmp(element, "TICK:", 5) == 0) {
char *vncol; char *vncol;
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_TICK; cmd->type = RRD_CONF_TICK;
element += 5; element += 5;
vncol = ap_getword(p, &element, ':'); vncol = ap_getword(p, &element, ':');
cmd->t.fraction = ap_getword(p, &element, ':'); cmd->t.fraction = ap_getword(p, &element, ':');
cmd->t.legend = getword_quote(p, &element, ':'); cmd->t.legend = getword_quote(p, &element, ':');
cmd->t.elegend = elegend; cmd->t.elegend = expr1;
cmd->t.args = element; cmd->t.args = element;
cmd->t.vname = apr_cstr_tokenize("#", &vncol); cmd->t.vname = apr_cstr_tokenize("#", &vncol);
cmd->t.colour = vncol; cmd->t.colour = vncol;
return 1; return 1;
} }
/* handle TEXTALIGN sections */ /* handle TEXTALIGN sections */
else if (strncmp(element, "TEXTALIGN:", 10) == 0) { else if (strncmp(element, "TEXTALIGN:", 10) == 0) {
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_TEXTALIGN; cmd->type = RRD_CONF_TEXTALIGN;
cmd->e.element = ap_getword(p, &element, ':'); cmd->e.element = ap_getword(p, &element, ':');
cmd->a.legend = getword_quote(p, &element, ':'); cmd->a.legend = getword_quote(p, &element, ':');
cmd->e.elegend = elegend; cmd->e.elegend = expr1;
return 1; return 1;
} }
break; break;
case 'V': case 'V':
/* handle VDEF sections */ /* handle VDEF sections */
if (strncmp(element, "VDEF:", 5) == 0) { if (strncmp(element, "VDEF:", 5) == 0) {
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_VDEF; cmd->type = RRD_CONF_VDEF;
element += 5; element += 5;
cmd->v.vname = ap_getword(p, &element, '='); cmd->v.vname = ap_getword(p, &element, '=');
skipping to change at line 705 skipping to change at line 772
return 1; return 1;
} }
/* handle VRULE sections */ /* handle VRULE sections */
if (strncmp(element, "VRULE:", 6) == 0) { if (strncmp(element, "VRULE:", 6) == 0) {
char *vncol; char *vncol;
rrd_cmd_t *cmd = apr_array_push(cmds); rrd_cmd_t *cmd = apr_array_push(cmds);
cmd->type = RRD_CONF_VRULE; cmd->type = RRD_CONF_VRULE;
element += 6; element += 6;
vncol = ap_getword(p, &element, ':'); vncol = ap_getword(p, &element, ':');
cmd->r.legend = getword_quote(p, &element, ':'); cmd->r.legend = getword_quote(p, &element, ':');
cmd->r.elegend = elegend; cmd->r.elegend = expr1;
cmd->r.args = element; cmd->r.args = element;
cmd->r.val = apr_cstr_tokenize("#", &vncol); cmd->r.val = apr_cstr_tokenize("#", &vncol);
cmd->r.colour = vncol; cmd->r.colour = vncol;
return 1; return 1;
} }
break; break;
} }
return 0; return 0;
} }
skipping to change at line 1103 skipping to change at line 1170
} }
element = apr_pstrdup(r->pool, apr_punescape_url(r->pool, arg, NULL, NUL L, 0)); element = apr_pstrdup(r->pool, apr_punescape_url(r->pool, arg, NULL, NUL L, 0));
if (!element) { if (!element) {
log_message(r, APR_SUCCESS, log_message(r, APR_SUCCESS,
apr_psprintf(r->pool, apr_psprintf(r->pool,
"The following element could not be unescaped: %s", arg) , NULL); "The following element could not be unescaped: %s", arg) , NULL);
return HTTP_BAD_REQUEST; return HTTP_BAD_REQUEST;
} }
if (parse_element(r->pool, element, NULL, cmds->cmds)) { if (parse_element(r->pool, element, NULL, NULL, cmds->cmds)) {
continue; continue;
} }
/* try parse options that take the form of name value pairs */ /* try parse options that take the form of name value pairs */
key = apr_cstr_tokenize("=", &element); key = apr_cstr_tokenize("=", &element);
val = element; val = element;
if (parse_option(r->pool, key, val, NULL, cmds->opts)) { if (parse_option(r->pool, key, val, NULL, cmds->opts)) {
continue; continue;
} }
skipping to change at line 1150 skipping to change at line 1217
} }
return NULL; return NULL;
} }
static int resolve_def(request_rec *r, rrd_cmd_t *cmd, rrd_cmds_t *cmds) static int resolve_def(request_rec *r, rrd_cmd_t *cmd, rrd_cmds_t *cmds)
{ {
ap_dir_match_t w; ap_dir_match_t w;
rrd_cb_t ctx; rrd_cb_t ctx;
apr_pool_t *ptemp; apr_pool_t *ptemp;
const char *last, *dirpath = r->filename; const char *last, *path, *dirpath = r->filename;
apr_hash_index_t *hi, *hi2; apr_hash_index_t *hi, *hi2;
apr_hash_t *set; apr_hash_t *set;
rrd_conf *conf = ap_get_module_config(r->per_dir_config, rrd_conf *conf = ap_get_module_config(r->per_dir_config,
&rrd_module); &rrd_module);
apr_pool_create(&ptemp, r->pool); apr_pool_create(&ptemp, r->pool);
/* process the wildcards */ /* process the wildcards */
ctx.r = r; ctx.r = r;
ctx.cmd = cmd; ctx.cmd = cmd;
w.prefix = "rrd path: "; w.prefix = "rrd path: ";
w.p = r->pool; w.p = r->pool;
w.ptemp = ptemp; w.ptemp = ptemp;
w.flags = AP_DIR_FLAG_OPTIONAL | AP_DIR_FLAG_RECURSIVE; w.flags = AP_DIR_FLAG_OPTIONAL | AP_DIR_FLAG_RECURSIVE;
w.cb = resolve_def_cb; w.cb = resolve_def_cb;
w.ctx = &ctx; w.ctx = &ctx;
w.depth = 0; w.depth = 0;
last = strrchr(r->filename, '/'); path = cmd->d.path;
if (last) { if (cmd->d.epath) {
dirpath = apr_pstrndup(ptemp, r->filename, last - r->filename); const char *err = NULL;
path = ap_expr_str_exec(r, cmd->d.epath, &err);
if (err) {
log_message(r, APR_SUCCESS,
apr_psprintf(r->pool,
"While evaluating an element expression: %s", err), NULL
);
return HTTP_INTERNAL_SERVER_ERROR;
}
} }
const char *err = ap_dir_fnmatch(&w, dirpath, cmd->d.path); if (cmd->d.edirpath) {
const char *err = NULL;
dirpath = ap_expr_str_exec(r, cmd->d.edirpath, &err);
if (err) {
log_message(r, APR_SUCCESS,
apr_psprintf(r->pool,
"While evaluating an element expression: %s", err), NULL
);
return HTTP_INTERNAL_SERVER_ERROR;
}
}
else {
last = strrchr(r->filename, '/');
if (last) {
dirpath = apr_pstrndup(ptemp, r->filename, last - r->filename);
}
}
ap_log_rerror(
APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r,
"mod_rrd: Attempting to match wildcard RRD path '%s' against base '%
s'",
path, dirpath);
const char *err = ap_dir_fnmatch(&w, dirpath, path);
if (err) { if (err) {
log_message(r, APR_SUCCESS, log_message(r, APR_SUCCESS,
apr_psprintf(r->pool, apr_psprintf(r->pool,
"While parsing DEF '%s': %s", cmd->d.path, err), NULL); "While parsing DEF path '%s': %s", path, err), NULL);
return HTTP_BAD_REQUEST; return HTTP_BAD_REQUEST;
} }
/* process the environment lookup */ /* process the environment lookup */
set = apr_hash_make(ptemp); set = apr_hash_make(ptemp);
for (hi = apr_hash_first(NULL, conf->env); hi; hi = apr_hash_next(hi)) { for (hi = apr_hash_first(NULL, conf->env); hi; hi = apr_hash_next(hi)) {
const char *err = NULL, *key, *val; const char *err = NULL, *key, *val;
ap_expr_info_t *eval; ap_expr_info_t *eval;
void *v; void *v;
const void *k; const void *k;
skipping to change at line 2143 skipping to change at line 2239
/* no results */ /* no results */
if (cmd->d.requests->nelts == 0) { if (cmd->d.requests->nelts == 0) {
/* output nothing */ /* output nothing */
} }
/* one result */ /* one result */
else if (cmd->d.requests->nelts == 1) { else if (cmd->d.requests->nelts == 1) {
request_rec *rr = APR_ARRAY_IDX(cmd->d.requests, 0, request_rec *); request_rec *rr = APR_ARRAY_IDX(cmd->d.requests, 0, request_rec *);
const char *arg = apr_psprintf(r->pool, "DEF:%s=%s:%s:%s", cmd->d.vname, const char *arg = apr_psprintf(r->pool, "DEF:%s=%s:%s:%s", cmd->d.vname,
rr->filename, cmd->d.dsname, cmd->d.cf); pescape_colon(r->pool, rr->filename), cmd->d.dsname, cmd- >d.cf);
APR_ARRAY_PUSH(args, const char *) = arg; APR_ARRAY_PUSH(args, const char *) = arg;
} }
/* more than one result */ /* more than one result */
else { else {
char *cdef; char *cdef;
int len = apr_snprintf(NULL, 0, "CDEF:%s=", cmd->d.vname); int len = apr_snprintf(NULL, 0, "CDEF:%s=", cmd->d.vname);
/* handle each DEF: line */ /* handle each DEF: line */
for (j = 0; j < cmd->d.requests->nelts; ++j) { for (j = 0; j < cmd->d.requests->nelts; ++j) {
request_rec *rr = APR_ARRAY_IDX(cmd->d.requests, j, request_rec *); request_rec *rr = APR_ARRAY_IDX(cmd->d.requests, j, request_rec *);
const char *arg = apr_psprintf(r->pool, "DEF:%sw%d=%s:%s:%s", cmd->d .vname, const char *arg = apr_psprintf(r->pool, "DEF:%sw%d=%s:%s:%s", cmd->d .vname,
j, rr->filename, cmd->d.dsname, cmd->d.cf); j, pescape_colon(r->pool, rr->filename), cmd->d.dsname, cmd->d.c f);
APR_ARRAY_PUSH(args, const char *) = arg; APR_ARRAY_PUSH(args, const char *) = arg;
len += apr_snprintf(NULL, 0, "%s%sw%d%s", j ? "," : "", cmd->d.vname , j, j ? ",+" : ""); len += apr_snprintf(NULL, 0, "%s%sw%d%s", j ? "," : "", cmd->d.vname , j, j ? ",+" : "");
} }
/* calculate the CDEF summary line */ /* calculate the CDEF summary line */
cdef = apr_palloc(r->pool, len + 1); cdef = apr_palloc(r->pool, len + 1);
APR_ARRAY_PUSH(args, const char *) = cdef; APR_ARRAY_PUSH(args, const char *) = cdef;
cdef += apr_snprintf(cdef, len, "CDEF:%s=", cmd->d.vname); cdef += apr_snprintf(cdef, len, "CDEF:%s=", cmd->d.vname);
for (j = 0; j < cmd->d.requests->nelts; ++j) { for (j = 0; j < cmd->d.requests->nelts; ++j) {
cdef += apr_snprintf(cdef, len, "%s%sw%d%s", j ? "," : "", cmd->d.vn ame, j, j ? ",+" : ""); cdef += apr_snprintf(cdef, len, "%s%sw%d%s", j ? "," : "", cmd->d.vn ame, j, j ? ",+" : "");
skipping to change at line 2179 skipping to change at line 2275
} }
return OK; return OK;
} }
static int generate_args(request_rec *r, rrd_cmds_t *cmds, apr_array_header_t ** pargs) static int generate_args(request_rec *r, rrd_cmds_t *cmds, apr_array_header_t ** pargs)
{ {
apr_array_header_t *args; apr_array_header_t *args;
rrd_cmd_t *cmd; rrd_cmd_t *cmd;
rrd_opt_t *opt; rrd_opt_t *opt;
const char *format;
int i, num = 4, ret = OK; int i, num = 4, ret = OK;
rrd_conf *conf = ap_get_module_config(r->per_dir_config,
&rrd_module);
/* count the options */ /* count the options */
for (i = 0; i < cmds->opts->nelts; ++i) { for (i = 0; i < cmds->opts->nelts; ++i) {
opt = &((rrd_opt_t *)cmds->opts->elts)[i]; opt = &((rrd_opt_t *)cmds->opts->elts)[i];
if (opt->val) { if (opt->val) {
num++; num++;
} }
num++; num++;
skipping to change at line 2204 skipping to change at line 2304
cmd = &APR_ARRAY_IDX(cmds->cmds, i, rrd_cmd_t); cmd = &APR_ARRAY_IDX(cmds->cmds, i, rrd_cmd_t);
if (cmd->def) { if (cmd->def) {
num += cmd->def->d.requests->nelts; num += cmd->def->d.requests->nelts;
} }
num++; num++;
} }
/* work out the format */
format = conf->format ? conf->format : parse_rrdgraph_suffix(r);
/* set the content type */
ap_set_content_type(r, lookup_content_type(format));
/* create arguments of the correct size */ /* create arguments of the correct size */
args = *pargs = apr_array_make(r->pool, num, sizeof(const char *)); args = *pargs = apr_array_make(r->pool, num, sizeof(const char *));
/* the argv array */ /* the argv array */
APR_ARRAY_PUSH(args, const char *) = "rrdgraph"; APR_ARRAY_PUSH(args, const char *) = "rrdgraph";
APR_ARRAY_PUSH(args, const char *) = "-"; APR_ARRAY_PUSH(args, const char *) = "-";
APR_ARRAY_PUSH(args, const char *) = "--imgformat"; APR_ARRAY_PUSH(args, const char *) = "--imgformat";
APR_ARRAY_PUSH(args, const char *) = parse_rrdgraph_suffix(r); APR_ARRAY_PUSH(args, const char *) = format;
/* first create the options */ /* first create the options */
for (i = 0; i < cmds->opts->nelts; ++i) { for (i = 0; i < cmds->opts->nelts; ++i) {
opt = &((rrd_opt_t *)cmds->opts->elts)[i]; opt = &((rrd_opt_t *)cmds->opts->elts)[i];
APR_ARRAY_PUSH(args, const char *) = APR_ARRAY_PUSH(args, const char *) =
apr_pstrcat(r->pool, "--", opt->key, NULL); apr_pstrcat(r->pool, "--", opt->key, NULL);
if (opt->eval) { if (opt->eval) {
const char *err = NULL; const char *err = NULL;
skipping to change at line 2391 skipping to change at line 2497
if (grinfo == NULL) { if (grinfo == NULL) {
log_message(r, APR_SUCCESS, "Call to rrd_graph_v failed", rrd_get_error( )); log_message(r, APR_SUCCESS, "Call to rrd_graph_v failed", rrd_get_error( ));
ret = HTTP_INTERNAL_SERVER_ERROR; ret = HTTP_INTERNAL_SERVER_ERROR;
} }
else { else {
/* grab the image data from the results */ /* grab the image data from the results */
while (grinfo) { while (grinfo) {
if (strcmp(grinfo->key, "image") == 0) { if (strcmp(grinfo->key, "image") == 0) {
apr_brigade_write(bb, NULL, NULL, (const char *)grinfo->value.u_ blo.ptr, apr_brigade_write(bb, NULL, NULL, (const char *)grinfo->value.u_ blo.ptr,
grinfo->value.u_blo.size); grinfo->value.u_blo.size);
ap_set_content_length(r, grinfo->value.u_blo.size);
break; break;
} }
/* skip anything else */ /* skip anything else */
grinfo = grinfo->next; grinfo = grinfo->next;
} }
rrd_info_free(grinfo); rrd_info_free(grinfo);
} }
rrd_clear_error(); rrd_clear_error();
#if APR_HAS_THREADS #if APR_HAS_THREADS
skipping to change at line 2432 skipping to change at line 2539
APLOG_MARK, APLOG_DEBUG, rv, r, "rrd_handler: ap_pass_brigad e returned %i", rv); APLOG_MARK, APLOG_DEBUG, rv, r, "rrd_handler: ap_pass_brigad e returned %i", rv);
return HTTP_INTERNAL_SERVER_ERROR; return HTTP_INTERNAL_SERVER_ERROR;
} }
} }
return ret; return ret;
} }
static int get_rrd(request_rec *r) static int get_rrd(request_rec *r)
{ {
rrd_conf *conf = ap_get_module_config(r->per_dir_config,
&rrd_module);
/* /*
* if a file does not exist, assume it is a request for a graph, otherwise * if a file does not exist, assume it is a request for a graph, otherwise
* go with the original file. * go with the original file.
*/ */
if (r->filename && r->finfo.filetype == APR_NOFILE && parse_rrdgraph_suffix( if ((conf->format) ||
r)) { (r->filename && r->finfo.filetype == APR_NOFILE && parse_rrdgraph
_suffix(r))) {
return get_rrdgraph(r); return get_rrdgraph(r);
} }
return DECLINED; return DECLINED;
} }
static int rrd_fixups(request_rec *r)
{
rrd_conf *conf = ap_get_module_config(r->per_dir_config,
&rrd_module);
if (!conf) {
return DECLINED;
}
if (conf->graph) {
r->handler = "rrdgraph";
return OK;
}
return DECLINED;
}
static int rrd_handler(request_rec *r) static int rrd_handler(request_rec *r)
{ {
rrd_conf *conf = ap_get_module_config(r->per_dir_config, rrd_conf *conf = ap_get_module_config(r->per_dir_config,
&rrd_module); &rrd_module);
if (!conf || !conf->graph) { if (!conf || !conf->graph) {
return DECLINED; return DECLINED;
} }
skipping to change at line 2503 skipping to change at line 2630
rrd_conf *add = (rrd_conf *) addv; rrd_conf *add = (rrd_conf *) addv;
rrd_conf *base = (rrd_conf *) basev; rrd_conf *base = (rrd_conf *) basev;
new->options = apr_array_append(p, add->options, base->options); new->options = apr_array_append(p, add->options, base->options);
new->elements = apr_array_append(p, add->elements, base->elements); new->elements = apr_array_append(p, add->elements, base->elements);
new->env = apr_hash_overlay(p, add->env, base->env); new->env = apr_hash_overlay(p, add->env, base->env);
new->location = (add->location_set == 0) ? base->location : add->location; new->location = (add->location_set == 0) ? base->location : add->location;
new->location_set = add->location_set || base->location_set; new->location_set = add->location_set || base->location_set;
new->format = (add->format_set == 0) ? base->format : add->format;
new->format_set = add->format_set || base->format_set;
new->graph = (add->graph_set == 0) ? base->graph : add->graph; new->graph = (add->graph_set == 0) ? base->graph : add->graph;
new->graph_set = add->graph_set || base->graph_set; new->graph_set = add->graph_set || base->graph_set;
return new; return new;
} }
static const char *set_rrd_graph_format(cmd_parms *cmd, void *dconf, const char
*format)
{
rrd_conf *conf = dconf;
conf->format = format;
conf->format_set = 1;
return NULL;
}
static const char *set_rrd_graph_option(cmd_parms *cmd, void *dconf, const char *key, const char *val) static const char *set_rrd_graph_option(cmd_parms *cmd, void *dconf, const char *key, const char *val)
{ {
rrd_conf *conf = dconf; rrd_conf *conf = dconf;
ap_expr_info_t *eval = NULL; ap_expr_info_t *eval = NULL;
const char *expr_err = NULL; const char *expr_err = NULL;
if (val) { if (val) {
eval = ap_expr_parse_cmd(cmd, val, AP_EXPR_FLAG_STRING_RESULT, eval = ap_expr_parse_cmd(cmd, val, AP_EXPR_FLAG_STRING_RESULT,
&expr_err, NULL); &expr_err, NULL);
skipping to change at line 2536 skipping to change at line 2676
} }
if (!parse_option(cmd->pool, key, val, eval, conf->options)) { if (!parse_option(cmd->pool, key, val, eval, conf->options)) {
return apr_pstrcat(cmd->pool, "Could not recognise option: ", key, NULL) ; return apr_pstrcat(cmd->pool, "Could not recognise option: ", key, NULL) ;
} }
return NULL; return NULL;
} }
static const char *set_rrd_graph_element(cmd_parms *cmd, void *dconf, static const char *set_rrd_graph_element(cmd_parms *cmd, void *dconf,
const char *element, const char *legend) const char *element, const char *val1, const char *val2)
{ {
rrd_conf *conf = dconf; rrd_conf *conf = dconf;
ap_expr_info_t *elegend = NULL; ap_expr_info_t *eval1 = NULL, *eval2 = NULL;
const char *expr_err = NULL; const char *expr_err = NULL;
if (legend) { if (val1) {
eval1 = ap_expr_parse_cmd(cmd, val1, AP_EXPR_FLAG_STRING_RESULT,
&expr_err, NULL);
if (expr_err) {
return apr_pstrcat(cmd->temp_pool,
"Cannot parse expression '", val1, "': ",
expr_err, NULL);
}
}
if (val2) {
elegend = ap_expr_parse_cmd(cmd, legend, AP_EXPR_FLAG_STRING_RESULT, eval2 = ap_expr_parse_cmd(cmd, val2, AP_EXPR_FLAG_STRING_RESULT,
&expr_err, NULL); &expr_err, NULL);
if (expr_err) { if (expr_err) {
return apr_pstrcat(cmd->temp_pool, return apr_pstrcat(cmd->temp_pool,
"Cannot parse expression '", legend, "': ", "Cannot parse expression '", val2, "': ",
expr_err, NULL); expr_err, NULL);
} }
} }
if (!parse_element(cmd->pool, element, elegend, conf->elements)) { if (!parse_element(cmd->pool, element, eval1, eval2, conf->elements)) {
return apr_psprintf(cmd->pool, return apr_psprintf(cmd->pool,
"RRDGraphElement was not recognised: %s", element); "RRDGraphElement was not recognised: %s", element);
} }
return NULL; return NULL;
} }
static const char *set_rrd_graph_env(cmd_parms *cmd, void *dconf, static const char *set_rrd_graph_env(cmd_parms *cmd, void *dconf,
const char *key, const char *val) const char *key, const char *val)
{ {
skipping to change at line 2597 skipping to change at line 2750
conf->graph = flag; conf->graph = flag;
conf->graph_set = 1; conf->graph_set = 1;
return NULL; return NULL;
} }
static const command_rec rrd_cmds[] = { static const command_rec rrd_cmds[] = {
AP_INIT_FLAG("RRDGraph", set_rrd_graph, NULL, RSRC_CONF | ACCESS_CONF, AP_INIT_FLAG("RRDGraph", set_rrd_graph, NULL, RSRC_CONF | ACCESS_CONF,
"Enable the rrdgraph image generator."), "Enable the rrdgraph image generator."),
AP_INIT_TAKE1("RRDGraphFormat", set_rrd_graph_format, NULL, RSRC_CONF | ACCE
SS_CONF,
"Explicitly set the image format. Takes any valid --imgformat value."),
AP_INIT_TAKE12("RRDGraphOption", set_rrd_graph_option, NULL, RSRC_CONF | ACC ESS_CONF, AP_INIT_TAKE12("RRDGraphOption", set_rrd_graph_option, NULL, RSRC_CONF | ACC ESS_CONF,
"Options for the rrdgraph image generator."), "Options for the rrdgraph image generator."),
AP_INIT_TAKE12("RRDGraphElement", set_rrd_graph_element, NULL, RSRC_CONF | A CCESS_CONF, AP_INIT_TAKE123("RRDGraphElement", set_rrd_graph_element, NULL, RSRC_CONF | ACCESS_CONF,
"Elements for the rrdgraph image generator. If specified, an optional ex pression can be set for the legend where appropriate."), "Elements for the rrdgraph image generator. If specified, an optional ex pression can be set for the legend where appropriate."),
AP_INIT_TAKE2("RRDGraphEnv", set_rrd_graph_env, NULL, RSRC_CONF | ACCESS_CON F, AP_INIT_TAKE2("RRDGraphEnv", set_rrd_graph_env, NULL, RSRC_CONF | ACCESS_CON F,
"Summarise environment variables from the RRD file requests."), { NULL } "Summarise environment variables from the RRD file requests."), { NULL }
}; };
static void register_hooks(apr_pool_t *p) static void register_hooks(apr_pool_t *p)
{ {
ap_hook_child_init(rrd_child_init,NULL,NULL,APR_HOOK_MIDDLE); ap_hook_child_init(rrd_child_init,NULL,NULL,APR_HOOK_MIDDLE);
ap_hook_handler(rrd_handler, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_fixups(rrd_fixups, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_handler(rrd_handler, NULL, NULL, APR_HOOK_FIRST);
} }
AP_DECLARE_MODULE(rrd) = { AP_DECLARE_MODULE(rrd) = {
STANDARD20_MODULE_STUFF, STANDARD20_MODULE_STUFF,
create_rrd_config, /* create per-directory config structure */ create_rrd_config, /* create per-directory config structure */
merge_rrd_config, /* merge per-directory config structures */ merge_rrd_config, /* merge per-directory config structures */
NULL, /* create per-server config structure */ NULL, /* create per-server config structure */
NULL, /* merge per-server config structures */ NULL, /* merge per-server config structures */
rrd_cmds, /* command apr_table_t */ rrd_cmds, /* command apr_table_t */
register_hooks /* register hooks */ register_hooks /* register hooks */
 End of changes. 43 change blocks. 
34 lines changed or deleted 195 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)