* Version $Id$
*/
/*
- Copyright (C) 2000-2003 Kern Sibbald and John Walker
+ Copyright (C) 2003-2004 Kern Sibbald and John Walker
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
-static int date_item(JCR *jcr, int code,
+static int date_item(JCR *jcr, int code,
const char **val_ptr, int *val_len, int *val_size)
{
struct tm tm;
bsnprintf(buf, sizeof(buf), "%d", val);
*val_ptr = bstrdup(buf);
*val_len = strlen(buf);
- *val_size = *val_len;
+ *val_size = *val_len + 1;
return 1;
}
-static int job_item(JCR *jcr, int code,
+static int job_item(JCR *jcr, int code,
const char **val_ptr, int *val_len, int *val_size)
{
- char *str = " ";
+ const char *str = " ";
char buf[20];
switch (code) {
case 6: /* Client */
str = jcr->client->hdr.name;
if (!str) {
- str = " ";
+ str = " ";
}
break;
case 7: /* NumVols */
str = buf;
break;
case 8: /* Pool */
- str = jcr->pool->hdr.name;
+ str = jcr->pool->hdr.name;
break;
case 9: /* Storage */
str = jcr->store->hdr.name;
}
*val_ptr = bstrdup(str);
*val_len = strlen(str);
- *val_size = *val_len;
+ *val_size = *val_len + 1;
return 1;
}
-struct s_built_in_vars {char *var_name; int code; int (*func)(JCR *jcr, int code,
+struct s_built_in_vars {const char *var_name; int code; int (*func)(JCR *jcr, int code,
const char **val_ptr, int *val_len, int *val_size);};
+/*
+ * Table of build in variables
+ */
static struct s_built_in_vars built_in_vars[] = {
{ N_("Year"), 1, date_item},
{ N_("Month"), 2, date_item},
};
-static var_rc_t lookup_built_in_var(var_t *ctx, void *my_ctx,
- const char *var_ptr, int var_len, int var_index,
+/*
+ * Search the table of built-in variables, and if found,
+ * call the appropriate subroutine to do the work.
+ */
+static var_rc_t lookup_built_in_var(var_t *ctx, void *my_ctx,
+ const char *var_ptr, int var_len, int var_index,
const char **val_ptr, int *val_len, int *val_size)
{
JCR *jcr = (JCR *)my_ctx;
/*
- * Search counter variables
+ * Search counter variables
*/
-static var_rc_t lookup_counter_var(var_t *ctx, void *my_ctx,
- const char *var_ptr, int var_len, int var_inc, int var_index,
+static var_rc_t lookup_counter_var(var_t *ctx, void *my_ctx,
+ const char *var_ptr, int var_len, int var_inc, int var_index,
const char **val_ptr, int *val_len, int *val_size)
{
char buf[MAXSTRING];
LockRes();
for (COUNTER *counter=NULL; (counter = (COUNTER *)GetNextRes(R_COUNTER, (RES *)counter)); ) {
if (strcmp(counter->hdr.name, buf) == 0) {
- bsnprintf(buf, sizeof(buf), "%d", counter->CurrentValue);
- *val_ptr = bstrdup(buf);
- *val_len = strlen(buf);
- *val_size = *val_len;
- if (var_inc) {
- COUNTER_DBR cr;
- JCR *jcr = (JCR *)my_ctx;
- memset(&cr, 0, sizeof(cr));
- bstrncpy(cr.Counter, counter->hdr.name, sizeof(cr.Counter));
- cr.MinValue = counter->MinValue;
- cr.MaxValue = counter->MaxValue;
+ Dmsg2(100, "Counter=%s val=%d\n", buf, counter->CurrentValue);
+ /* -1 => return size of array */
+ if (var_index == -1) {
+ bsnprintf(buf, sizeof(buf), "%d", counter->CurrentValue);
+ *val_len = bsnprintf(buf, sizeof(buf), "%d", strlen(buf));
+ *val_ptr = buf;
+ *val_size = 0; /* don't try to free val_ptr */
+ return VAR_OK;
+ } else {
+ bsnprintf(buf, sizeof(buf), "%d", counter->CurrentValue);
+ *val_ptr = bstrdup(buf);
+ *val_len = strlen(buf);
+ *val_size = *val_len + 1;
+ }
+ if (var_inc) { /* increment the variable? */
if (counter->CurrentValue == counter->MaxValue) {
counter->CurrentValue = counter->MinValue;
} else {
counter->CurrentValue++;
}
- cr.CurrentValue = counter->CurrentValue;
- if (counter->WrapCounter) {
- bstrncpy(cr.WrapCounter, counter->WrapCounter->hdr.name, sizeof(cr.WrapCounter));
- } else {
- cr.WrapCounter[0] = 0;
- }
- if (!db_update_counter_record(jcr, jcr->db, &cr)) {
- Jmsg(jcr, M_ERROR, 0, _("Count not update counter %s: ERR=%s\n"),
- counter->hdr.name, db_strerror(jcr->db));
+ if (counter->Catalog) { /* update catalog if need be */
+ COUNTER_DBR cr;
+ JCR *jcr = (JCR *)my_ctx;
+ memset(&cr, 0, sizeof(cr));
+ bstrncpy(cr.Counter, counter->hdr.name, sizeof(cr.Counter));
+ cr.MinValue = counter->MinValue;
+ cr.MaxValue = counter->MaxValue;
+ cr.CurrentValue = counter->CurrentValue;
+ Dmsg1(100, "New value=%d\n", cr.CurrentValue);
+ if (counter->WrapCounter) {
+ bstrncpy(cr.WrapCounter, counter->WrapCounter->hdr.name, sizeof(cr.WrapCounter));
+ } else {
+ cr.WrapCounter[0] = 0;
+ }
+ if (!db_update_counter_record(jcr, jcr->db, &cr)) {
+ Jmsg(jcr, M_ERROR, 0, _("Count not update counter %s: ERR=%s\n"),
+ counter->hdr.name, db_strerror(jcr->db));
+ }
}
- }
+ }
stat = VAR_OK;
break;
}
/*
- * Called here to look up a variable
+ * Called here from "core" expand code to look up a variable
*/
-static var_rc_t lookup_var(var_t *ctx, void *my_ctx,
- const char *var_ptr, int var_len, int var_inc, int var_index,
+static var_rc_t lookup_var(var_t *ctx, void *my_ctx,
+ const char *var_ptr, int var_len, int var_inc, int var_index,
const char **val_ptr, int *val_len, int *val_size)
{
char buf[MAXSTRING], *val, *p, *v;
var_rc_t stat;
int count;
+ /* Note, if val_size > 0 and val_ptr!=NULL, the core code will free() it */
if ((stat = lookup_built_in_var(ctx, my_ctx, var_ptr, var_len, var_index,
val_ptr, val_len, val_size)) == VAR_OK) {
return VAR_OK;
}
memcpy(buf, var_ptr, var_len + 1);
buf[var_len] = 0;
-// Dmsg1(000, "Var=%s\n", buf);
+ Dmsg1(100, "Var=%s\n", buf);
if ((val = getenv(buf)) == NULL) {
return VAR_ERR_UNDEFINED_VARIABLE;
}
- if (var_index == 0) {
- *val_ptr = val;
- *val_len = strlen(val);
- *val_size = 0;
- return VAR_OK;
- }
/* He wants to index the "array" */
- count = 0;
- /* Find the size of the "array"
- * each element is separated by a |
+ count = 1;
+ /* Find the size of the "array"
+ * each element is separated by a |
*/
for (p = val; *p; p++) {
if (*p == '|') {
count++;
}
}
- count++;
-// Dmsg3(000, "For %s, reqest index=%d have=%d\n",
-// buf, var_index, count);
- if (var_index < 0 || var_index > count) {
- return VAR_ERR_SUBMATCH_OUT_OF_RANGE;
+ Dmsg3(100, "For %s, reqest index=%d have=%d\n",
+ buf, var_index, count);
+
+ /* -1 => return size of array */
+ if (var_index == -1) {
+ int len;
+ if (count == 1) { /* if not array */
+ len = strlen(val); /* return length of string */
+ } else {
+ len = count; /* else return # array items */
+ }
+ *val_len = bsnprintf(buf, sizeof(buf), "%d", len);
+ *val_ptr = buf;
+ *val_size = 0; /* don't try to free val_ptr */
+ return VAR_OK;
+ }
+
+
+ if (var_index < -1 || var_index > --count) {
+// return VAR_ERR_SUBMATCH_OUT_OF_RANGE;
+ return VAR_ERR_UNDEFINED_VARIABLE;
}
/* Now find the particular item (var_index) he wants */
- count = 1;
+ count = 0;
for (p=val; *p; ) {
if (*p == '|') {
if (count < var_index) {
if (p-val > (int)sizeof(buf) - 1) {
return VAR_ERR_OUT_OF_MEMORY;
}
-// Dmsg2(000, "val=%s len=%d\n", val, p-val);
+ Dmsg2(100, "val=%s len=%d\n", val, p-val);
/* Make a copy of item, and pass it back */
v = (char *)malloc(p-val+1);
memcpy(v, val, p-val);
v[p-val] = 0;
*val_ptr = v;
*val_len = p-val;
- *val_size = p-val;
-// Dmsg1(000, "v=%s\n", v);
+ *val_size = p-val+1;
+ Dmsg1(100, "v=%s\n", v);
return VAR_OK;
}
* val_ptr points to the value string
* out_ptr points to string to be returned
*/
-static var_rc_t operate_var(var_t *var, void *my_ctx,
- const char *op_ptr, int op_len,
+static var_rc_t operate_var(var_t *var, void *my_ctx,
+ const char *op_ptr, int op_len,
const char *arg_ptr, int arg_len,
- const char *val_ptr, int val_len,
+ const char *val_ptr, int val_len,
char **out_ptr, int *out_len, int *out_size)
{
var_rc_t stat = VAR_ERR_UNDEFINED_OPERATION;
-// Dmsg0(000, "Enter operate_var\n");
+ Dmsg0(100, "Enter operate_var\n");
if (!val_ptr) {
*out_size = 0;
return stat;
}
memcpy(buf, arg_ptr, arg_len);
buf[arg_len] = 0;
-// Dmsg1(000, "Arg=%s\n", buf);
+ Dmsg1(100, "Arg=%s\n", buf);
memcpy(buf, val_ptr, val_len);
- buf[val_len] = 0;
-// Dmsg1(000, "Val=%s\n", buf);
+ buf[val_len] = 0;
+ Dmsg1(100, "Val=%s\n", buf);
LockRes();
for (COUNTER *counter=NULL; (counter = (COUNTER *)GetNextRes(R_COUNTER, (RES *)counter)); ) {
if (strcmp(counter->hdr.name, buf) == 0) {
-// Dmsg2(000, "counter=%s val=%s\n", counter->hdr.name, buf);
+ Dmsg2(100, "counter=%s val=%s\n", counter->hdr.name, buf);
break;
}
}
}
-/*
+/*
* Expand an input line and return it.
*
* Returns: 0 on failure
in_len = strlen(inp);
/* expand variables */
- if ((stat = var_expand(var_ctx, inp, in_len, &outp, &out_len, 1)) != VAR_OK) {
- Jmsg(jcr, M_ERROR, 0, _("Cannot expand LabelFormat \"%s\": ERR=%s\n"),
+ if ((stat = var_expand(var_ctx, inp, in_len, &outp, &out_len, 0)) != VAR_OK) {
+ Jmsg(jcr, M_ERROR, 0, _("Cannot expand expression \"%s\": ERR=%s\n"),
inp, var_strerror(var_ctx, stat));
goto bail_out;
}
pm_strcpy(exp, outp);
- rtn_stat = 1;
+ rtn_stat = 1;
bail_out:
/* destroy expansion context */