DBId_t PathId;
DBId_t FilenameId;
FileId_t FileId;
+ char *Sig;
+ int SigType;
};
*/
/*
- Copyright (C) 2000-2004 Kern Sibbald and John Walker
+ Copyright (C) 2000-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
/* The following is necessary so that we do not include
* the dummy external definition of DB.
*/
-#define __SQL_C /* indicate that this is sql.c */
+#define __SQL_C /* indicate that this is sql.c */
#include "bacula.h"
#include "cats.h"
*/
B_DB *
db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char *db_password,
- const char *db_address, int db_port, const char *db_socket,
- int mult_db_connections)
+ const char *db_address, int db_port, const char *db_socket,
+ int mult_db_connections)
{
B_DB *mdb;
Jmsg(jcr, M_FATAL, 0, _("A user name for MySQL must be supplied.\n"));
return NULL;
}
- P(mutex); /* lock DB queue */
+ P(mutex); /* lock DB queue */
/* Look to see if DB already open */
if (!mult_db_connections) {
for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
- if (strcmp(mdb->db_name, db_name) == 0) {
- Dmsg2(100, "DB REopen %d %s\n", mdb->ref_count, db_name);
- mdb->ref_count++;
- V(mutex);
- return mdb; /* already open */
- }
+ if (strcmp(mdb->db_name, db_name) == 0) {
+ Dmsg2(100, "DB REopen %d %s\n", mdb->ref_count, db_name);
+ mdb->ref_count++;
+ V(mutex);
+ return mdb; /* already open */
+ }
}
}
Dmsg0(100, "db_open first time\n");
mdb->fname = get_pool_memory(PM_FNAME);
mdb->path = get_pool_memory(PM_FNAME);
mdb->esc_name = get_pool_memory(PM_FNAME);
- qinsert(&db_list, &mdb->bq); /* put db in list */
+ qinsert(&db_list, &mdb->bq); /* put db in list */
V(mutex);
return mdb;
}
if ((errstat=rwl_init(&mdb->lock)) != 0) {
Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"),
- strerror(errstat));
+ strerror(errstat));
V(mutex);
return 0;
}
/* If connection fails, try at 5 sec intervals for 30 seconds. */
for (int retry=0; retry < 6; retry++) {
mdb->db = mysql_real_connect(
- &(mdb->mysql), /* db */
- mdb->db_address, /* default = localhost */
- mdb->db_user, /* login name */
- mdb->db_password, /* password */
- mdb->db_name, /* database name */
- mdb->db_port, /* default port */
- mdb->db_socket, /* default = socket */
- CLIENT_FOUND_ROWS); /* flags */
+ &(mdb->mysql), /* db */
+ mdb->db_address, /* default = localhost */
+ mdb->db_user, /* login name */
+ mdb->db_password, /* password */
+ mdb->db_name, /* database name */
+ mdb->db_port, /* default port */
+ mdb->db_socket, /* default = socket */
+ CLIENT_FOUND_ROWS); /* flags */
/* If no connect, try once more in case it is a timing problem */
if (mdb->db != NULL) {
- break;
+ break;
}
bmicrosleep(5,0);
}
Dmsg0(50, "mysql_real_connect done\n");
Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n", mdb->db_user, mdb->db_name,
- mdb->db_password==NULL?"(NULL)":mdb->db_password);
+ mdb->db_password==NULL?"(NULL)":mdb->db_password);
if (mdb->db == NULL) {
Mmsg2(&mdb->errmsg, _("Unable to connect to MySQL server. \n"
"Database=%s User=%s\n"
"It is probably not running or your password is incorrect.\n"),
- mdb->db_name, mdb->db_user);
+ mdb->db_name, mdb->db_user);
V(mutex);
return 0;
}
if (!mdb) {
return;
}
+ db_end_transaction(jcr, mdb);
P(mutex);
mdb->ref_count--;
#ifdef HAVE_TREAD_SAFE_MYSQL
if (mdb->ref_count == 0) {
qdchain(&mdb->bq);
if (mdb->connected && mdb->db) {
- sql_close(mdb);
+ sql_close(mdb);
#ifdef HAVE_EMBEDDED_MYSQL
- mysql_server_end();
+ mysql_server_end();
#endif
}
rwl_destroy(&mdb->lock);
free_pool_memory(mdb->path);
free_pool_memory(mdb->esc_name);
if (mdb->db_name) {
- free(mdb->db_name);
+ free(mdb->db_name);
}
if (mdb->db_user) {
- free(mdb->db_user);
+ free(mdb->db_user);
}
if (mdb->db_password) {
- free(mdb->db_password);
+ free(mdb->db_password);
}
if (mdb->db_address) {
- free(mdb->db_address);
+ free(mdb->db_address);
}
if (mdb->db_socket) {
- free(mdb->db_socket);
+ free(mdb->db_socket);
}
free(mdb);
}
* Escape strings so that MySQL is happy
*
* NOTE! len is the length of the old string. Your new
- * string must be long enough (max 2*old+1) to hold
- * the escaped output.
+ * string must be long enough (max 2*old+1) to hold
+ * the escaped output.
*/
void
db_escape_string(char *snew, char *old, int len)
while (len--) {
switch (*o) {
case 0:
- *n++= '\\';
- *n++= '0';
- o++;
- break;
+ *n++= '\\';
+ *n++= '0';
+ o++;
+ break;
case '\n':
- *n++= '\\';
- *n++= 'n';
- o++;
- break;
+ *n++= '\\';
+ *n++= 'n';
+ o++;
+ break;
case '\r':
- *n++= '\\';
- *n++= 'r';
- o++;
- break;
+ *n++= '\\';
+ *n++= 'r';
+ o++;
+ break;
case '\\':
- *n++= '\\';
- *n++= '\\';
- o++;
- break;
+ *n++= '\\';
+ *n++= '\\';
+ o++;
+ break;
case '\'':
- *n++= '\\';
- *n++= '\'';
- o++;
- break;
+ *n++= '\\';
+ *n++= '\'';
+ o++;
+ break;
case '"':
- *n++= '\\';
- *n++= '"';
- o++;
- break;
+ *n++= '\\';
+ *n++= '"';
+ o++;
+ break;
case '\032':
- *n++= '\\';
- *n++= 'Z';
- o++;
- break;
+ *n++= '\\';
+ *n++= 'Z';
+ o++;
+ break;
default:
- *n++= *o++;
+ *n++= *o++;
}
}
*n = 0;
}
if (result_handler != NULL) {
if ((mdb->result = sql_store_result(mdb)) != NULL) {
- int num_fields = sql_num_fields(mdb);
+ int num_fields = sql_num_fields(mdb);
- while ((row = sql_fetch_row(mdb)) != NULL) {
- if (result_handler(ctx, num_fields, row))
- break;
- }
+ while ((row = sql_fetch_row(mdb)) != NULL) {
+ if (result_handler(ctx, num_fields, row))
+ break;
+ }
- sql_free_result(mdb);
+ sql_free_result(mdb);
}
}
db_unlock(mdb);
*/
/*
- Copyright (C) 2003-2004 Kern Sibbald and John Walker
+ Copyright (C) 2003-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
/* The following is necessary so that we do not include
* the dummy external definition of DB.
*/
-#define __SQL_C /* indicate that this is sql.c */
+#define __SQL_C /* indicate that this is sql.c */
#include "bacula.h"
#include "cats.h"
*/
B_DB *
db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char *db_password,
- const char *db_address, int db_port, const char *db_socket,
- int mult_db_connections)
+ const char *db_address, int db_port, const char *db_socket,
+ int mult_db_connections)
{
B_DB *mdb;
Jmsg(jcr, M_FATAL, 0, _("A user name for PostgreSQL must be supplied.\n"));
return NULL;
}
- P(mutex); /* lock DB queue */
+ P(mutex); /* lock DB queue */
if (!mult_db_connections) {
/* Look to see if DB already open */
for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
- if (strcmp(mdb->db_name, db_name) == 0) {
- Dmsg2(100, "DB REopen %d %s\n", mdb->ref_count, db_name);
- mdb->ref_count++;
- V(mutex);
- return mdb; /* already open */
- }
+ if (strcmp(mdb->db_name, db_name) == 0) {
+ Dmsg2(100, "DB REopen %d %s\n", mdb->ref_count, db_name);
+ mdb->ref_count++;
+ V(mutex);
+ return mdb; /* already open */
+ }
}
}
Dmsg0(100, "db_open first time\n");
}
mdb->db_port = db_port;
mdb->have_insert_id = TRUE;
- mdb->errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */
+ mdb->errmsg = get_pool_memory(PM_EMSG); /* get error message buffer */
*mdb->errmsg = 0;
- mdb->cmd = get_pool_memory(PM_EMSG); /* get command buffer */
+ mdb->cmd = get_pool_memory(PM_EMSG); /* get command buffer */
mdb->cached_path = get_pool_memory(PM_FNAME);
mdb->cached_path_id = 0;
mdb->ref_count = 1;
- mdb->fname = get_pool_memory(PM_FNAME);
- mdb->path = get_pool_memory(PM_FNAME);
+ mdb->fname = get_pool_memory(PM_FNAME);
+ mdb->path = get_pool_memory(PM_FNAME);
mdb->esc_name = get_pool_memory(PM_FNAME);
mdb->allow_transactions = mult_db_connections;
- qinsert(&db_list, &mdb->bq); /* put db in list */
+ qinsert(&db_list, &mdb->bq); /* put db in list */
V(mutex);
return mdb;
}
if ((errstat=rwl_init(&mdb->lock)) != 0) {
Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"),
- strerror(errstat));
+ strerror(errstat));
V(mutex);
return 0;
}
for (int retry=0; retry < 6; retry++) {
/* connect to the database */
mdb->db = PQsetdbLogin(
- mdb->db_address, /* default = localhost */
- port, /* default port */
- NULL, /* pg options */
- NULL, /* tty, ignored */
- mdb->db_name, /* database name */
- mdb->db_user, /* login name */
- mdb->db_password); /* password */
+ mdb->db_address, /* default = localhost */
+ port, /* default port */
+ NULL, /* pg options */
+ NULL, /* tty, ignored */
+ mdb->db_name, /* database name */
+ mdb->db_user, /* login name */
+ mdb->db_password); /* password */
/* If no connect, try once more in case it is a timing problem */
if (PQstatus(mdb->db) == CONNECTION_OK) {
- break;
+ break;
}
bmicrosleep(5, 0);
}
Dmsg0(50, "pg_real_connect done\n");
Dmsg3(50, "db_user=%s db_name=%s db_password=%s\n", mdb->db_user, mdb->db_name,
- mdb->db_password==NULL?"(NULL)":mdb->db_password);
+ mdb->db_password==NULL?"(NULL)":mdb->db_password);
if (PQstatus(mdb->db) != CONNECTION_OK) {
Mmsg2(&mdb->errmsg, _("Unable to connect to PostgreSQL server.\n"
- "Database=%s User=%s\n"
- "It is probably not running or your password is incorrect.\n"),
- mdb->db_name, mdb->db_user);
+ "Database=%s User=%s\n"
+ "It is probably not running or your password is incorrect.\n"),
+ mdb->db_name, mdb->db_user);
V(mutex);
return 0;
}
if (!mdb) {
return;
}
+ db_end_transaction(jcr, mdb);
P(mutex);
mdb->ref_count--;
if (mdb->ref_count == 0) {
qdchain(&mdb->bq);
if (mdb->connected && mdb->db) {
- sql_close(mdb);
+ sql_close(mdb);
}
rwl_destroy(&mdb->lock);
free_pool_memory(mdb->errmsg);
free_pool_memory(mdb->path);
free_pool_memory(mdb->esc_name);
if (mdb->db_name) {
- free(mdb->db_name);
+ free(mdb->db_name);
}
if (mdb->db_user) {
- free(mdb->db_user);
+ free(mdb->db_user);
}
if (mdb->db_password) {
- free(mdb->db_password);
+ free(mdb->db_password);
}
if (mdb->db_address) {
- free(mdb->db_address);
+ free(mdb->db_address);
}
if (mdb->db_socket) {
- free(mdb->db_socket);
+ free(mdb->db_socket);
}
my_postgresql_free_result(mdb);
free(mdb);
* Escape strings so that PostgreSQL is happy
*
* NOTE! len is the length of the old string. Your new
- * string must be long enough (max 2*old+1) to hold
- * the escaped output.
+ * string must be long enough (max 2*old+1) to hold
+ * the escaped output.
*/
void
db_escape_string(char *snew, char *old, int len)
if (result_handler != NULL) {
Dmsg0(500, "db_sql_query invoking handler\n");
if ((mdb->result = sql_store_result(mdb)) != NULL) {
- int num_fields = sql_num_fields(mdb);
+ int num_fields = sql_num_fields(mdb);
- Dmsg0(500, "db_sql_query sql_store_result suceeded\n");
- while ((row = sql_fetch_row(mdb)) != NULL) {
+ Dmsg0(500, "db_sql_query sql_store_result suceeded\n");
+ while ((row = sql_fetch_row(mdb)) != NULL) {
- Dmsg0(500, "db_sql_query sql_fetch_row worked\n");
- if (result_handler(ctx, num_fields, row))
- break;
- }
+ Dmsg0(500, "db_sql_query sql_fetch_row worked\n");
+ if (result_handler(ctx, num_fields, row))
+ break;
+ }
- sql_free_result(mdb);
+ sql_free_result(mdb);
}
}
db_unlock(mdb);
Dmsg1(500, "we have need space of %d bytes\n", sizeof(char *) * mdb->num_fields);
if (mdb->row != NULL) {
- Dmsg0(500, "my_postgresql_fetch_row freeing space\n");
- free(mdb->row);
- mdb->row = NULL;
+ Dmsg0(500, "my_postgresql_fetch_row freeing space\n");
+ free(mdb->row);
+ mdb->row = NULL;
}
mdb->row = (POSTGRESQL_ROW) malloc(sizeof(char *) * mdb->num_fields);
Dmsg2(500, "my_postgresql_fetch_row row number '%d' is acceptable (0..%d)\n", mdb->row_number, mdb->num_rows);
// get each value from this row
for (j = 0; j < mdb->num_fields; j++) {
- mdb->row[j] = PQgetvalue(mdb->result, mdb->row_number, j);
- Dmsg2(500, "my_postgresql_fetch_row field '%d' has value '%s'\n", j, mdb->row[j]);
+ mdb->row[j] = PQgetvalue(mdb->result, mdb->row_number, j);
+ Dmsg2(500, "my_postgresql_fetch_row field '%d' has value '%s'\n", j, mdb->row[j]);
}
// increment the row number for the next call
mdb->row_number++;
max_length = 0;
for (i = 0; i < mdb->num_rows; i++) {
if (PQgetisnull(mdb->result, i, field_num)) {
- this_length = 4; // "NULL"
+ this_length = 4; // "NULL"
} else {
- this_length = strlen(PQgetvalue(mdb->result, i, field_num));
+ this_length = cstrlen(PQgetvalue(mdb->result, i, field_num));
}
if (max_length < this_length) {
- max_length = this_length;
+ max_length = this_length;
}
}
POSTGRESQL_FIELD * my_postgresql_fetch_field(B_DB *mdb)
{
- int i;
+ int i;
Dmsg0(500, "my_postgresql_fetch_field starts\n");
if (mdb->fields == NULL) {
mdb->fields = (POSTGRESQL_FIELD *)malloc(sizeof(POSTGRESQL_FIELD) * mdb->num_fields);
for (i = 0; i < mdb->num_fields; i++) {
- Dmsg1(500, "filling field %d\n", i);
- mdb->fields[i].name = PQfname(mdb->result, i);
- mdb->fields[i].max_length = my_postgresql_max_length(mdb, i);
- mdb->fields[i].type = PQftype(mdb->result, i);
- mdb->fields[i].flags = 0;
-
- Dmsg4(500, "my_postgresql_fetch_field finds field '%s' has length='%d' type='%d' and IsNull=%d\n",
- mdb->fields[i].name, mdb->fields[i].max_length, mdb->fields[i].type,
- mdb->fields[i].flags);
+ Dmsg1(500, "filling field %d\n", i);
+ mdb->fields[i].name = PQfname(mdb->result, i);
+ mdb->fields[i].max_length = my_postgresql_max_length(mdb, i);
+ mdb->fields[i].type = PQftype(mdb->result, i);
+ mdb->fields[i].flags = 0;
+
+ Dmsg4(500, "my_postgresql_fetch_field finds field '%s' has length='%d' type='%d' and IsNull=%d\n",
+ mdb->fields[i].name, mdb->fields[i].max_length, mdb->fields[i].type,
+ mdb->fields[i].flags);
} // end for
} // end if
// Obtain the current value of the sequence that
// provides the serial value for primary key of the table.
- // currval is local to our session. It is not affected by
+ // currval is local to our session. It is not affected by
// other transactions.
// Determine the name of the sequence.
char sequence[NAMEDATALEN-1];
char query [NAMEDATALEN+50];
PGresult *result;
- int id = 0;
+ int id = 0;
if (strcasecmp(table_name, "basefiles") == 0) {
bstrncpy(sequence, "basefiles_baseid", sizeof(sequence));
* Bacula Catalog Database interface routines
*
* Almost generic set of SQL database interface routines
- * (with a little more work)
+ * (with a little more work)
*
* Kern Sibbald, March 2000
*
/* The following is necessary so that we do not include
* the dummy external definition of B_DB.
*/
-#define __SQL_C /* indicate that this is sql.c */
+#define __SQL_C /* indicate that this is sql.c */
#include "bacula.h"
#include "cats.h"
db_sql_query(mdb, query, int_handler, (void *)&bacula_db_version);
if (bacula_db_version != BDB_VERSION) {
Mmsg(mdb->errmsg, "Version error for database \"%s\". Wanted %d, got %d\n",
- mdb->db_name, BDB_VERSION, bacula_db_version);
+ mdb->db_name, BDB_VERSION, bacula_db_version);
Jmsg(jcr, M_FATAL, 0, "%s", mdb->errmsg);
return 0;
}
/*
* Utility routine to do inserts
* Returns: 0 on failure
- * 1 on success
+ * 1 on success
*/
int
InsertDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
if (mdb->num_rows != 1) {
char ed1[30];
m_msg(file, line, &mdb->errmsg, _("Insertion problem: affected_rows=%s\n"),
- edit_uint64(mdb->num_rows, ed1));
+ edit_uint64(mdb->num_rows, ed1));
if (verbose) {
j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
}
/* Utility routine for updates.
* Returns: 0 on failure
- * 1 on success
+ * 1 on success
*/
int
UpdateDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
if (mdb->num_rows < 1) {
char ed1[30];
m_msg(file, line, &mdb->errmsg, _("Update problem: affected_rows=%s\n"),
- edit_uint64(mdb->num_rows, ed1));
+ edit_uint64(mdb->num_rows, ed1));
if (verbose) {
// j_msg(file, line, jcr, M_INFO, 0, "%s\n", cmd);
}
/* Utility routine for deletes
*
* Returns: -1 on error
- * n number of rows affected
+ * n number of rows affected
*/
int
DeleteDB(const char *file, int line, JCR *jcr, B_DB *mdb, char *cmd)
* No locking done
*
* Returns: -1 on failure
- * count on success
+ * count on success
*/
int get_sql_record_max(JCR *jcr, B_DB *mdb)
{
if (QUERY_DB(jcr, mdb, mdb->cmd)) {
if ((row = sql_fetch_row(mdb)) == NULL) {
Mmsg1(&mdb->errmsg, _("error fetching row: %s\n"), sql_strerror(mdb));
- stat = -1;
+ stat = -1;
} else {
- stat = str_to_int64(row[0]);
+ stat = str_to_int64(row[0]);
}
sql_free_result(mdb);
} else {
if ((errstat=rwl_writelock(&mdb->lock)) != 0) {
berrno be;
e_msg(file, line, M_ABORT, 0, "rwl_writelock failure. ERR=%s\n",
- be.strerror(errstat));
+ be.strerror(errstat));
}
}
if ((errstat=rwl_writeunlock(&mdb->lock)) != 0) {
berrno be;
e_msg(file, line, M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n",
- be.strerror(errstat));
+ be.strerror(errstat));
}
}
*/
void db_start_transaction(JCR *jcr, B_DB *mdb)
{
+ if (!jcr->attr) {
+ jcr->attr = get_pool_memory(PM_FNAME);
+ }
#ifdef HAVE_SQLITE
if (!mdb->allow_transactions) {
return;
{
/*
* This can be called during thread cleanup and
- * the db may already be closed. So simply return.
+ * the db may already be closed. So simply return.
*/
if (!mdb) {
return;
}
+ if (jcr->cached_attribute) {
+ if (!db_create_file_attributes_record(jcr, jcr->db, &jcr->ar)) {
+ Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db));
+ }
+ jcr->cached_attribute = false;
+ }
+ if (jcr->attr) {
+ free_pool_memory(jcr->attr);
+ }
#ifdef HAVE_SQLITE
if (!mdb->allow_transactions) {
return;
*/
for (p=f=fname; *p; p++) {
if (*p == '/') {
- f = p; /* set pos of last slash */
+ f = p; /* set pos of last slash */
}
}
if (*f == '/') { /* did we find a slash? */
- f++; /* yes, point to filename */
- } else { /* no, whole thing must be path name */
+ f++; /* yes, point to filename */
+ } else { /* no, whole thing must be path name */
f = p;
}
mdb->fnl = p - f;
if (mdb->fnl > 0) {
mdb->fname = check_pool_memory_size(mdb->fname, mdb->fnl+1);
- memcpy(mdb->fname, f, mdb->fnl); /* copy filename */
+ memcpy(mdb->fname, f, mdb->fnl); /* copy filename */
mdb->fname[mdb->fnl] = 0;
} else {
mdb->fname[0] = 0;
for (i = 0; i < sql_num_fields(mdb); i++) {
Dmsg1(800, "list_result processing field %d\n", i);
field = sql_fetch_field(mdb);
- col_len = strlen(field->name);
+ col_len = cstrlen(field->name);
if (type == VERT_LIST) {
- if (col_len > max_len) {
- max_len = col_len;
- }
+ if (col_len > max_len) {
+ max_len = col_len;
+ }
} else {
- if (IS_NUM(field->type) && (int)field->max_length > 0) { /* fixup for commas */
- field->max_length += (field->max_length - 1) / 3;
- }
- if (col_len < (int)field->max_length) {
- col_len = field->max_length;
- }
- if (col_len < 4 && !IS_NOT_NULL(field->flags)) {
+ if (IS_NUM(field->type) && (int)field->max_length > 0) { /* fixup for commas */
+ field->max_length += (field->max_length - 1) / 3;
+ }
+ if (col_len < (int)field->max_length) {
+ col_len = field->max_length;
+ }
+ if (col_len < 4 && !IS_NOT_NULL(field->flags)) {
col_len = 4; /* 4 = length of the word "NULL" */
- }
- field->max_length = col_len; /* reset column info */
+ }
+ field->max_length = col_len; /* reset column info */
}
}
sql_field_seek(mdb, 0);
send(ctx, "|");
for (i = 0; i < sql_num_fields(mdb); i++) {
- field = sql_fetch_field(mdb);
- if (row[i] == NULL) {
+ field = sql_fetch_field(mdb);
+ if (row[i] == NULL) {
bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, "NULL");
- } else if (IS_NUM(field->type) && !jcr->gui && is_an_integer(row[i])) {
+ } else if (IS_NUM(field->type) && !jcr->gui && is_an_integer(row[i])) {
bsnprintf(buf, sizeof(buf), " %*s |", (int)field->max_length,
- add_commas(row[i], ewc));
- } else {
+ add_commas(row[i], ewc));
+ } else {
bsnprintf(buf, sizeof(buf), " %-*s |", (int)field->max_length, row[i]);
- }
- send(ctx, buf);
+ }
+ send(ctx, buf);
}
send(ctx, "\n");
}
while ((row = sql_fetch_row(mdb)) != NULL) {
sql_field_seek(mdb, 0);
for (i = 0; i < sql_num_fields(mdb); i++) {
- field = sql_fetch_field(mdb);
- if (row[i] == NULL) {
+ field = sql_fetch_field(mdb);
+ if (row[i] == NULL) {
bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, "NULL");
- } else if (IS_NUM(field->type) && !jcr->gui && is_an_integer(row[i])) {
+ } else if (IS_NUM(field->type) && !jcr->gui && is_an_integer(row[i])) {
bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name,
- add_commas(row[i], ewc));
- } else {
+ add_commas(row[i], ewc));
+ } else {
bsnprintf(buf, sizeof(buf), " %*s: %s\n", max_len, field->name, row[i]);
- }
- send(ctx, buf);
+ }
+ send(ctx, buf);
}
send(ctx, "\n");
}
static int db_create_file_record(JCR *jcr, B_DB *mdb, ATTR_DBR *ar)
{
int stat;
+ static char *no_sig = "0";
+ char *sig;
ASSERT(ar->JobId);
ASSERT(ar->PathId);
ASSERT(ar->FilenameId);
+ if (ar->Sig == NULL) {
+ sig = no_sig;
+ } else {
+ sig = ar->Sig;
+ }
+
/* Must create it */
Mmsg(mdb->cmd,
"INSERT INTO File (FileIndex,JobId,PathId,FilenameId,"
- "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','0')",
+ "LStat,MD5) VALUES (%u,%u,%u,%u,'%s','%s')",
ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId,
- ar->attr);
+ ar->attr, sig);
if (!INSERT_DB(jcr, mdb, mdb->cmd)) {
Mmsg2(&mdb->errmsg, _("Create db File record %s failed. ERR=%s"),
*/
/*
- Copyright (C) 2002-2004 Kern Sibbald and John Walker
+ Copyright (C) 2002-2005 Kern Sibbald
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
/* The following is necessary so that we do not include
* the dummy external definition of DB.
*/
-#define __SQL_C /* indicate that this is sql.c */
+#define __SQL_C /* indicate that this is sql.c */
#include "bacula.h"
#include "cats.h"
*/
B_DB *
db_init_database(JCR *jcr, const char *db_name, const char *db_user, const char *db_password,
- const char *db_address, int db_port, const char *db_socket,
- int mult_db_connections)
+ const char *db_address, int db_port, const char *db_socket,
+ int mult_db_connections)
{
B_DB *mdb;
- P(mutex); /* lock DB queue */
+ P(mutex); /* lock DB queue */
/* Look to see if DB already open */
if (!mult_db_connections) {
for (mdb=NULL; (mdb=(B_DB *)qnext(&db_list, &mdb->bq)); ) {
- if (strcmp(mdb->db_name, db_name) == 0) {
+ if (strcmp(mdb->db_name, db_name) == 0) {
Dmsg2(300, "DB REopen %d %s\n", mdb->ref_count, db_name);
- mdb->ref_count++;
- V(mutex);
- return mdb; /* already open */
- }
+ mdb->ref_count++;
+ V(mutex);
+ return mdb; /* already open */
+ }
}
}
Dmsg0(300, "db_open first time\n");
mdb->path = get_pool_memory(PM_FNAME);
mdb->esc_name = get_pool_memory(PM_FNAME);
mdb->allow_transactions = mult_db_connections;
- qinsert(&db_list, &mdb->bq); /* put db in list */
+ qinsert(&db_list, &mdb->bq); /* put db in list */
V(mutex);
return mdb;
}
if ((errstat=rwl_init(&mdb->lock)) != 0) {
Mmsg1(&mdb->errmsg, _("Unable to initialize DB lock. ERR=%s\n"),
- strerror(errstat));
+ strerror(errstat));
V(mutex);
return 0;
}
strcat(db_name, ".db");
if (stat(db_name, &statbuf) != 0) {
Mmsg1(&mdb->errmsg, _("Database %s does not exist, please create it.\n"),
- db_name);
+ db_name);
free(db_name);
V(mutex);
return 0;
#else
mdb->db = sqlite_open(
- db_name, /* database name */
- 644, /* mode */
- &mdb->sqlite_errmsg); /* error message */
+ db_name, /* database name */
+ 644, /* mode */
+ &mdb->sqlite_errmsg); /* error message */
#endif
Dmsg0(300, "sqlite_open\n");
if (!mdb) {
return;
}
+ db_end_transaction(jcr, mdb);
P(mutex);
mdb->ref_count--;
if (mdb->ref_count == 0) {
qdchain(&mdb->bq);
if (mdb->connected && mdb->db) {
- sqlite_close(mdb->db);
+ sqlite_close(mdb->db);
}
rwl_destroy(&mdb->lock);
free_pool_memory(mdb->errmsg);
free_pool_memory(mdb->path);
free_pool_memory(mdb->esc_name);
if (mdb->db_name) {
- free(mdb->db_name);
+ free(mdb->db_name);
}
free(mdb);
}
* Escape strings so that SQLite is happy
*
* NOTE! len is the length of the old string. Your new
- * string must be long enough (max 2*old+1) to hold
- * the escaped output.
+ * string must be long enough (max 2*old+1) to hold
+ * the escaped output.
*/
void
db_escape_string(char *snew, char *old, int len)
case '\'':
*n++ = '\'';
*n++ = '\'';
- o++;
- break;
+ o++;
+ break;
case 0:
*n++ = '\\';
- *n++ = 0;
- o++;
- break;
+ *n++ = 0;
+ o++;
+ break;
default:
- *n++ = *o++;
- break;
+ *n++ = *o++;
+ break;
}
}
*n = 0;
mdb->sqlite_errmsg = NULL;
}
stat = sqlite_get_table(mdb->db, cmd, &mdb->result, &mdb->nrow, &mdb->ncolumn,
- &mdb->sqlite_errmsg);
- mdb->row = 0; /* row fetched */
+ &mdb->sqlite_errmsg);
+ mdb->row = 0; /* row fetched */
return stat;
}
if (mdb->fields_defined) {
for (i=0; i < sql_num_fields(mdb); i++) {
- free(mdb->fields[i]);
+ free(mdb->fields[i]);
}
free(mdb->fields);
mdb->fields_defined = false;
if (!mdb->fields_defined && sql_num_fields(mdb) > 0) {
mdb->fields = (SQL_FIELD **)malloc(sizeof(SQL_FIELD) * mdb->ncolumn);
for (i=0; i < sql_num_fields(mdb); i++) {
- mdb->fields[i] = (SQL_FIELD *)malloc(sizeof(SQL_FIELD));
- mdb->fields[i]->name = mdb->result[i];
- mdb->fields[i]->length = strlen(mdb->fields[i]->name);
- mdb->fields[i]->max_length = mdb->fields[i]->length;
- for (j=1; j <= mdb->nrow; j++) {
- int len;
- if (mdb->result[i + mdb->ncolumn *j]) {
- len = (uint32_t)strlen(mdb->result[i + mdb->ncolumn * j]);
- } else {
- len = 0;
- }
- if (len > mdb->fields[i]->max_length) {
- mdb->fields[i]->max_length = len;
- }
- }
- mdb->fields[i]->type = 0;
- mdb->fields[i]->flags = 1; /* not null */
+ mdb->fields[i] = (SQL_FIELD *)malloc(sizeof(SQL_FIELD));
+ mdb->fields[i]->name = mdb->result[i];
+ mdb->fields[i]->length = cstrlen(mdb->fields[i]->name);
+ mdb->fields[i]->max_length = mdb->fields[i]->length;
+ for (j=1; j <= mdb->nrow; j++) {
+ int len;
+ if (mdb->result[i + mdb->ncolumn *j]) {
+ len = (uint32_t)cstrlen(mdb->result[i + mdb->ncolumn * j]);
+ } else {
+ len = 0;
+ }
+ if (len > mdb->fields[i]->max_length) {
+ mdb->fields[i]->max_length = len;
+ }
+ }
+ mdb->fields[i]->type = 0;
+ mdb->fields[i]->flags = 1; /* not null */
}
mdb->fields_defined = TRUE;
}
int32_t Stream;
uint32_t FileIndex;
uint32_t data_len;
- char *p = bs->msg;
+ char *p;
int len;
char *fname, *attr;
- ATTR_DBR ar;
+ ATTR_DBR *ar = &jcr->ar;
if (!jcr->pool->catalog_files) {
return;
}
db_start_transaction(jcr, jcr->db); /* start transaction if not already open */
+ jcr->attr = check_pool_memory_size(jcr->attr, bs->msglen);
+ memcpy(jcr->attr, bs->msg, bs->msglen);
+ p = jcr->attr;
skip_nonspaces(&p); /* UpdCat */
skip_spaces(&p);
skip_nonspaces(&p); /* Job=nnn */
Dmsg2(400, "dird<stored: stream=%d %s\n", Stream, fname);
Dmsg1(400, "dird<stored: attr=%s\n", attr);
- ar.attr = attr;
- ar.fname = fname;
- ar.FileIndex = FileIndex;
- ar.Stream = Stream;
- ar.link = NULL;
- ar.JobId = jcr->JobId;
+ ar->attr = attr;
+ ar->fname = fname;
+ ar->FileIndex = FileIndex;
+ ar->Stream = Stream;
+ ar->link = NULL;
+ ar->JobId = jcr->JobId;
+ ar->Sig = NULL;
+ ar->SigType = 0;
Dmsg2(400, "dird<filed: stream=%d %s\n", Stream, fname);
Dmsg1(400, "dird<filed: attr=%s\n", attr);
- if (!db_create_file_attributes_record(jcr, jcr->db, &ar)) {
+ if (!db_create_file_attributes_record(jcr, jcr->db, ar)) {
Jmsg1(jcr, M_FATAL, 0, _("Attribute create error. %s"), db_strerror(jcr->db));
}
- /* Save values for SIG update */
- jcr->FileId = ar.FileId;
- jcr->FileIndex = FileIndex;
} else if (Stream == STREAM_MD5_SIGNATURE || Stream == STREAM_SHA1_SIGNATURE) {
fname = p;
- if (jcr->FileIndex != FileIndex) {
+ if (ar->FileIndex != FileIndex) {
Jmsg(jcr, M_WARNING, 0, "Got MD5/SHA1 but not same File as attributes\n");
} else {
/* Update signature in catalog */
}
bin_to_base64(SIGbuf, fname, len);
Dmsg3(400, "SIGlen=%d SIG=%s type=%d\n", strlen(SIGbuf), SIGbuf, Stream);
- if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIGbuf, type)) {
+ if (!db_add_SIG_to_file_record(jcr, jcr->db, ar->FileId, SIGbuf, type)) {
Jmsg(jcr, M_ERROR, 0, _("Catalog error updating MD5/SHA1. %s"),
db_strerror(jcr->db));
}
*/
int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time,
- int verbose)
+ int verbose)
{
BSOCK *fd;
if (!jcr->file_bsock) {
fd = bnet_connect(jcr, retry_interval, max_retry_time,
_("File daemon"), jcr->client->address,
- NULL, jcr->client->FDport, verbose);
+ NULL, jcr->client->FDport, verbose);
if (fd == NULL) {
- set_jcr_job_status(jcr, JS_ErrorTerminated);
- return 0;
+ set_jcr_job_status(jcr, JS_ErrorTerminated);
+ return 0;
}
Dmsg0(10, "Opened connection with File daemon\n");
} else {
- fd = jcr->file_bsock; /* use existing connection */
+ fd = jcr->file_bsock; /* use existing connection */
}
fd->res = (RES *)jcr->client; /* save resource in BSOCK */
jcr->file_bsock = fd;
Dmsg1(110, "<filed: %s", fd->msg);
if (strncmp(fd->msg, OKjob, strlen(OKjob)) != 0) {
Jmsg(jcr, M_FATAL, 0, _("File daemon \"%s\" rejected Job command: %s\n"),
- jcr->client->hdr.name, fd->msg);
- set_jcr_job_status(jcr, JS_ErrorTerminated);
- return 0;
+ jcr->client->hdr.name, fd->msg);
+ set_jcr_job_status(jcr, JS_ErrorTerminated);
+ return 0;
} else if (jcr->db) {
- CLIENT_DBR cr;
- memset(&cr, 0, sizeof(cr));
- bstrncpy(cr.Name, jcr->client->hdr.name, sizeof(cr.Name));
- cr.AutoPrune = jcr->client->AutoPrune;
- cr.FileRetention = jcr->client->FileRetention;
- cr.JobRetention = jcr->client->JobRetention;
- bstrncpy(cr.Uname, fd->msg+strlen(OKjob)+1, sizeof(cr.Uname));
- if (!db_update_client_record(jcr, jcr->db, &cr)) {
+ CLIENT_DBR cr;
+ memset(&cr, 0, sizeof(cr));
+ bstrncpy(cr.Name, jcr->client->hdr.name, sizeof(cr.Name));
+ cr.AutoPrune = jcr->client->AutoPrune;
+ cr.FileRetention = jcr->client->FileRetention;
+ cr.JobRetention = jcr->client->JobRetention;
+ bstrncpy(cr.Uname, fd->msg+strlen(OKjob)+1, sizeof(cr.Uname));
+ if (!db_update_client_record(jcr, jcr->db, &cr)) {
Jmsg(jcr, M_WARNING, 0, _("Error updating Client record. ERR=%s\n"),
- db_strerror(jcr->db));
- }
+ db_strerror(jcr->db));
+ }
}
} else {
Jmsg(jcr, M_FATAL, 0, _("FD gave bad response to JobId command: %s\n"),
- bnet_strerror(fd));
+ bnet_strerror(fd));
set_jcr_job_status(jcr, JS_ErrorTerminated);
return 0;
}
if (jcr->cloned) {
if ( jcr->stime && jcr->stime[0]) {
bstrncpy(since, ", since=", since_len);
- bstrncat(since, jcr->stime, since_len);
+ bstrncat(since, jcr->stime, since_len);
}
return;
}
/* Look up start time of last job */
jcr->jr.JobId = 0; /* flag for db_find_job_start time */
if (!db_find_job_start_time(jcr, jcr->db, &jcr->jr, &jcr->stime)) {
- /* No job found, so upgrade this one to Full */
+ /* No job found, so upgrade this one to Full */
Jmsg(jcr, M_INFO, 0, "%s", db_strerror(jcr->db));
Jmsg(jcr, M_INFO, 0, _("No prior or suitable Full backup found. Doing FULL backup.\n"));
bsnprintf(since, since_len, " (upgraded from %s)",
- level_to_str(jcr->JobLevel));
- jcr->JobLevel = jcr->jr.JobLevel = L_FULL;
+ level_to_str(jcr->JobLevel));
+ jcr->JobLevel = jcr->jr.JobLevel = L_FULL;
} else {
- if (jcr->job->rerun_failed_levels) {
- if (db_find_failed_job_since(jcr, jcr->db, &jcr->jr, jcr->stime, JobLevel)) {
+ if (jcr->job->rerun_failed_levels) {
+ if (db_find_failed_job_since(jcr, jcr->db, &jcr->jr, jcr->stime, JobLevel)) {
Jmsg(jcr, M_INFO, 0, _("Prior failed job found. Upgrading to %s.\n"),
- level_to_str(JobLevel));
+ level_to_str(JobLevel));
bsnprintf(since, since_len, " (upgraded from %s)",
- level_to_str(jcr->JobLevel));
- jcr->JobLevel = jcr->jr.JobLevel = JobLevel;
- jcr->jr.JobId = jcr->JobId;
- break;
- }
- }
+ level_to_str(jcr->JobLevel));
+ jcr->JobLevel = jcr->jr.JobLevel = JobLevel;
+ jcr->jr.JobId = jcr->JobId;
+ break;
+ }
+ }
bstrncpy(since, ", since=", since_len);
- bstrncat(since, jcr->stime, since_len);
+ bstrncat(since, jcr->stime, since_len);
}
jcr->jr.JobId = jcr->JobId;
break;
case L_SINCE:
default:
Jmsg2(jcr, M_FATAL, 0, _("Unimplemented backup level %d %c\n"),
- jcr->JobLevel, jcr->JobLevel);
+ jcr->JobLevel, jcr->JobLevel);
return 0;
}
Dmsg1(120, ">filed: %s", fd->msg);
for ( ;; ) {
if (include) {
- num = fileset->num_includes;
+ num = fileset->num_includes;
} else {
- num = fileset->num_excludes;
+ num = fileset->num_excludes;
}
for (int i=0; i<num; i++) {
- BPIPE *bpipe;
- FILE *ffd;
- char buf[2000];
- char *p;
- int optlen, stat;
- INCEXE *ie;
- int j, k;
-
- if (include) {
- ie = fileset->include_items[i];
+ BPIPE *bpipe;
+ FILE *ffd;
+ char buf[2000];
+ char *p;
+ int optlen, stat;
+ INCEXE *ie;
+ int j, k;
+
+ if (include) {
+ ie = fileset->include_items[i];
bnet_fsend(fd, "I\n");
- } else {
- ie = fileset->exclude_items[i];
+ } else {
+ ie = fileset->exclude_items[i];
bnet_fsend(fd, "E\n");
- }
- for (j=0; j<ie->num_opts; j++) {
- FOPTS *fo = ie->opts_list[j];
+ }
+ for (j=0; j<ie->num_opts; j++) {
+ FOPTS *fo = ie->opts_list[j];
bnet_fsend(fd, "O %s\n", fo->opts);
- for (k=0; k<fo->regex.size(); k++) {
+ for (k=0; k<fo->regex.size(); k++) {
bnet_fsend(fd, "R %s\n", fo->regex.get(k));
- }
- for (k=0; k<fo->regexdir.size(); k++) {
+ }
+ for (k=0; k<fo->regexdir.size(); k++) {
bnet_fsend(fd, "RD %s\n", fo->regexdir.get(k));
- }
- for (k=0; k<fo->regexfile.size(); k++) {
+ }
+ for (k=0; k<fo->regexfile.size(); k++) {
bnet_fsend(fd, "RF %s\n", fo->regexfile.get(k));
- }
- for (k=0; k<fo->wild.size(); k++) {
+ }
+ for (k=0; k<fo->wild.size(); k++) {
bnet_fsend(fd, "W %s\n", fo->wild.get(k));
- }
- for (k=0; k<fo->wilddir.size(); k++) {
+ }
+ for (k=0; k<fo->wilddir.size(); k++) {
bnet_fsend(fd, "WD %s\n", fo->wilddir.get(k));
- }
- for (k=0; k<fo->wildfile.size(); k++) {
+ }
+ for (k=0; k<fo->wildfile.size(); k++) {
bnet_fsend(fd, "WF %s\n", fo->wildfile.get(k));
- }
- for (k=0; k<fo->base.size(); k++) {
+ }
+ for (k=0; k<fo->base.size(); k++) {
bnet_fsend(fd, "B %s\n", fo->base.get(k));
- }
- for (k=0; k<fo->fstype.size(); k++) {
+ }
+ for (k=0; k<fo->fstype.size(); k++) {
bnet_fsend(fd, "X %s\n", fo->fstype.get(k));
- }
- if (fo->reader) {
+ }
+ if (fo->reader) {
bnet_fsend(fd, "D %s\n", fo->reader);
- }
- if (fo->writer) {
+ }
+ if (fo->writer) {
bnet_fsend(fd, "T %s\n", fo->writer);
- }
+ }
bnet_fsend(fd, "N\n");
- }
+ }
- for (j=0; j<ie->name_list.size(); j++) {
- p = (char *)ie->name_list.get(j);
- switch (*p) {
+ for (j=0; j<ie->name_list.size(); j++) {
+ p = (char *)ie->name_list.get(j);
+ switch (*p) {
case '|':
- p++; /* skip over the | */
+ p++; /* skip over the | */
fd->msg = edit_job_codes(jcr, fd->msg, p, "");
bpipe = open_bpipe(fd->msg, 0, "r");
- if (!bpipe) {
- berrno be;
+ if (!bpipe) {
+ berrno be;
Jmsg(jcr, M_FATAL, 0, _("Cannot run program: %s. ERR=%s\n"),
- p, be.strerror());
- goto bail_out;
- }
+ p, be.strerror());
+ goto bail_out;
+ }
bstrncpy(buf, "F ", sizeof(buf));
Dmsg1(500, "Opts=%s\n", buf);
- optlen = strlen(buf);
- while (fgets(buf+optlen, sizeof(buf)-optlen, bpipe->rfd)) {
+ optlen = strlen(buf);
+ while (fgets(buf+optlen, sizeof(buf)-optlen, bpipe->rfd)) {
fd->msglen = Mmsg(fd->msg, "%s", buf);
Dmsg2(500, "Inc/exc len=%d: %s", fd->msglen, fd->msg);
- if (!bnet_send(fd)) {
+ if (!bnet_send(fd)) {
Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n"));
- goto bail_out;
- }
- }
- if ((stat=close_bpipe(bpipe)) != 0) {
- berrno be;
+ goto bail_out;
+ }
+ }
+ if ((stat=close_bpipe(bpipe)) != 0) {
+ berrno be;
Jmsg(jcr, M_FATAL, 0, _("Error running program: %s. ERR=%s\n"),
- p, be.strerror(stat));
- goto bail_out;
- }
- break;
+ p, be.strerror(stat));
+ goto bail_out;
+ }
+ break;
case '<':
- p++; /* skip over < */
+ p++; /* skip over < */
if ((ffd = fopen(p, "r")) == NULL) {
- berrno be;
+ berrno be;
Jmsg(jcr, M_FATAL, 0, _("Cannot open included file: %s. ERR=%s\n"),
- p, be.strerror());
- goto bail_out;
- }
+ p, be.strerror());
+ goto bail_out;
+ }
bstrncpy(buf, "F ", sizeof(buf));
Dmsg1(500, "Opts=%s\n", buf);
- optlen = strlen(buf);
- while (fgets(buf+optlen, sizeof(buf)-optlen, ffd)) {
+ optlen = strlen(buf);
+ while (fgets(buf+optlen, sizeof(buf)-optlen, ffd)) {
fd->msglen = Mmsg(fd->msg, "%s", buf);
- if (!bnet_send(fd)) {
+ if (!bnet_send(fd)) {
Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n"));
- goto bail_out;
- }
- }
- fclose(ffd);
- break;
+ goto bail_out;
+ }
+ }
+ fclose(ffd);
+ break;
case '\\':
p++; /* skip over \ */
- /* Note, fall through wanted */
- default:
+ /* Note, fall through wanted */
+ default:
pm_strcpy(fd->msg, "F ");
- fd->msglen = pm_strcat(fd->msg, p);
+ fd->msglen = pm_strcat(fd->msg, p);
Dmsg1(500, "Inc/Exc name=%s\n", fd->msg);
- if (!bnet_send(fd)) {
+ if (!bnet_send(fd)) {
Jmsg(jcr, M_FATAL, 0, _(">filed: write error on socket\n"));
- goto bail_out;
- }
- break;
- }
- }
+ goto bail_out;
+ }
+ break;
+ }
+ }
bnet_fsend(fd, "N\n");
}
- if (!include) { /* If we just did excludes */
- break; /* all done */
+ if (!include) { /* If we just did excludes */
+ break; /* all done */
}
- include = false; /* Now do excludes */
+ include = false; /* Now do excludes */
}
- bnet_sig(fd, BNET_EOD); /* end of data */
+ bnet_sig(fd, BNET_EOD); /* end of data */
if (!response(jcr, fd, OKinc, "Include", DISPLAY_ERROR)) {
goto bail_out;
}
if (!bs) {
berrno be;
Jmsg(jcr, M_FATAL, 0, _("Could not open bootstrap file %s: ERR=%s\n"),
- jcr->RestoreBootstrap, be.strerror());
+ jcr->RestoreBootstrap, be.strerror());
set_jcr_job_status(jcr, JS_ErrorTerminated);
return 0;
}
bash_spaces(msg);
bnet_fsend(fd, runbefore, msg);
if (!response(jcr, fd, OKRunBefore, "ClientRunBeforeJob", DISPLAY_ERROR)) {
- set_jcr_job_status(jcr, JS_ErrorTerminated);
- free_pool_memory(msg);
- return 0;
+ set_jcr_job_status(jcr, JS_ErrorTerminated);
+ free_pool_memory(msg);
+ return 0;
}
}
if (jcr->job->ClientRunAfterJob) {
bash_spaces(msg);
bnet_fsend(fd, runafter, msg);
if (!response(jcr, fd, OKRunAfter, "ClientRunAfterJob", DISPLAY_ERROR)) {
- set_jcr_job_status(jcr, JS_ErrorTerminated);
- free_pool_memory(msg);
- return 0;
+ set_jcr_job_status(jcr, JS_ErrorTerminated);
+ free_pool_memory(msg);
+ return 0;
}
}
free_pool_memory(msg);
if ((len = sscanf(fd->msg, "%ld %d %s", &file_index, &stream, Opts_SIG)) != 3) {
Jmsg(jcr, M_FATAL, 0, _("<filed: bad attributes, expected 3 fields got %d\n"
"msglen=%d msg=%s\n"), len, fd->msglen, fd->msg);
- set_jcr_job_status(jcr, JS_ErrorTerminated);
- return 0;
+ set_jcr_job_status(jcr, JS_ErrorTerminated);
+ return 0;
}
p = fd->msg;
- skip_nonspaces(&p); /* skip FileIndex */
+ skip_nonspaces(&p); /* skip FileIndex */
skip_spaces(&p);
- skip_nonspaces(&p); /* skip Stream */
+ skip_nonspaces(&p); /* skip Stream */
skip_spaces(&p);
- skip_nonspaces(&p); /* skip Opts_SHA1 */
- p++; /* skip space */
+ skip_nonspaces(&p); /* skip Opts_SHA1 */
+ p++; /* skip space */
fn = jcr->fname;
while (*p != 0) {
- *fn++ = *p++; /* copy filename */
+ *fn++ = *p++; /* copy filename */
}
- *fn = *p++; /* term filename and point to attribs */
+ *fn = *p++; /* term filename and point to attribs */
attr = p;
if (stream == STREAM_UNIX_ATTRIBUTES || stream == STREAM_UNIX_ATTRIBUTES_EX) {
- jcr->JobFiles++;
- jcr->FileIndex = file_index;
- ar.attr = attr;
- ar.fname = jcr->fname;
- ar.FileIndex = file_index;
- ar.Stream = stream;
- ar.link = NULL;
- ar.JobId = jcr->JobId;
- ar.ClientId = jcr->ClientId;
- ar.PathId = 0;
- ar.FilenameId = 0;
+ jcr->JobFiles++;
+ jcr->FileIndex = file_index;
+ ar.attr = attr;
+ ar.fname = jcr->fname;
+ ar.FileIndex = file_index;
+ ar.Stream = stream;
+ ar.link = NULL;
+ ar.JobId = jcr->JobId;
+ ar.ClientId = jcr->ClientId;
+ ar.PathId = 0;
+ ar.FilenameId = 0;
+ ar.Sig = NULL;
+ ar.SigType = 0;
Dmsg2(111, "dird<filed: stream=%d %s\n", stream, jcr->fname);
Dmsg1(120, "dird<filed: attr=%s\n", attr);
- if (!db_create_file_attributes_record(jcr, jcr->db, &ar)) {
+ if (!db_create_file_attributes_record(jcr, jcr->db, &ar)) {
Jmsg1(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
- set_jcr_job_status(jcr, JS_Error);
- continue;
- }
- jcr->FileId = ar.FileId;
+ set_jcr_job_status(jcr, JS_Error);
+ continue;
+ }
+ jcr->FileId = ar.FileId;
} else if (stream == STREAM_MD5_SIGNATURE || stream == STREAM_SHA1_SIGNATURE) {
- if (jcr->FileIndex != (uint32_t)file_index) {
+ if (jcr->FileIndex != (uint32_t)file_index) {
Jmsg2(jcr, M_ERROR, 0, _("MD5/SHA1 index %d not same as attributes %d\n"),
- file_index, jcr->FileIndex);
- set_jcr_job_status(jcr, JS_Error);
- continue;
- }
- db_escape_string(SIG, Opts_SIG, strlen(Opts_SIG));
+ file_index, jcr->FileIndex);
+ set_jcr_job_status(jcr, JS_Error);
+ continue;
+ }
+ db_escape_string(SIG, Opts_SIG, strlen(Opts_SIG));
Dmsg2(120, "SIGlen=%d SIG=%s\n", strlen(SIG), SIG);
- if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIG,
- stream==STREAM_MD5_SIGNATURE?MD5_SIG:SHA1_SIG)) {
+ if (!db_add_SIG_to_file_record(jcr, jcr->db, jcr->FileId, SIG,
+ stream==STREAM_MD5_SIGNATURE?MD5_SIG:SHA1_SIG)) {
Jmsg1(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db));
- set_jcr_job_status(jcr, JS_Error);
- }
+ set_jcr_job_status(jcr, JS_Error);
+ }
}
jcr->jr.JobFiles = jcr->JobFiles = file_index;
jcr->jr.LastIndex = file_index;
}
if (is_bnet_error(fd)) {
Jmsg1(jcr, M_FATAL, 0, _("<filed: Network error getting attributes. ERR=%s\n"),
- bnet_strerror(fd));
+ bnet_strerror(fd));
set_jcr_job_status(jcr, JS_ErrorTerminated);
return 0;
}
*
* Basic tasks done here:
* Handle network signals (signals).
- * Signals always have return status 0 from bnet_recv() and
- * a zero or negative message length.
+ * Signals always have return status 0 from bnet_recv() and
+ * a zero or negative message length.
* Pass appropriate messages back to the caller (responses).
- * Responses always have a digit as the first character.
+ * Responses always have a digit as the first character.
* Handle requests for message and catalog services (requests).
- * Requests are any message that does not begin with a digit.
- * In affect, they are commands.
+ * Requests are any message that does not begin with a digit.
+ * In affect, they are commands.
*
* Version $Id$
*/
* in any other format, it will be returned.
*
* E.g. any message beginning with a digit will be passed
- * through to the caller.
+ * through to the caller.
* All other messages are expected begin with some identifier
* -- for the moment only the first character is checked, but
* at a later time, the whole identifier (e.g. Jmsg, CatReq, ...)
Dmsg2(900, "bget_dirmsg %d: %s", n, bs->msg);
if (is_bnet_stop(bs)) {
- return n; /* error or terminate */
+ return n; /* error or terminate */
}
- if (n == BNET_SIGNAL) { /* handle signal */
- /* BNET_SIGNAL (-1) return from bnet_recv() => network signal */
- switch (bs->msglen) {
- case BNET_EOD: /* end of data */
- return n;
- case BNET_EOD_POLL:
- bnet_fsend(bs, OK_msg);/* send response */
- return n; /* end of data */
- case BNET_TERMINATE:
- bs->terminated = 1;
- return n;
- case BNET_POLL:
- bnet_fsend(bs, OK_msg); /* send response */
- break;
- case BNET_HEARTBEAT:
-// encode_time(time(NULL), Job);
+ if (n == BNET_SIGNAL) { /* handle signal */
+ /* BNET_SIGNAL (-1) return from bnet_recv() => network signal */
+ switch (bs->msglen) {
+ case BNET_EOD: /* end of data */
+ return n;
+ case BNET_EOD_POLL:
+ bnet_fsend(bs, OK_msg);/* send response */
+ return n; /* end of data */
+ case BNET_TERMINATE:
+ bs->terminated = 1;
+ return n;
+ case BNET_POLL:
+ bnet_fsend(bs, OK_msg); /* send response */
+ break;
+ case BNET_HEARTBEAT:
+// encode_time(time(NULL), Job);
// Dmsg1(100, "%s got heartbeat.\n", Job);
- break;
- case BNET_HB_RESPONSE:
- break;
- case BNET_STATUS:
- /* *****FIXME***** Implement more completely */
+ break;
+ case BNET_HB_RESPONSE:
+ break;
+ case BNET_STATUS:
+ /* *****FIXME***** Implement more completely */
bnet_fsend(bs, "Status OK\n");
- bnet_sig(bs, BNET_EOD);
- break;
- case BNET_BTIME: /* send Bacula time */
- char ed1[50];
+ bnet_sig(bs, BNET_EOD);
+ break;
+ case BNET_BTIME: /* send Bacula time */
+ char ed1[50];
bnet_fsend(bs, "btime %s\n", edit_uint64(get_current_btime(),ed1));
- break;
- default:
+ break;
+ default:
Emsg1(M_WARNING, 0, _("bget_dirmsg: unknown bnet signal %d\n"), bs->msglen);
- return n;
- }
- continue;
+ return n;
+ }
+ continue;
}
/* Handle normal data */
- if (n > 0 && B_ISDIGIT(bs->msg[0])) { /* response? */
- return n; /* yes, return it */
+ if (n > 0 && B_ISDIGIT(bs->msg[0])) { /* response? */
+ return n; /* yes, return it */
}
/*
- * If we get here, it must be a request. Either
+ * If we get here, it must be a request. Either
* a message to dispatch, or a catalog request.
* Try to fulfill it.
*/
if (sscanf(bs->msg, "%020s Job=%127s ", MsgType, Job) != 2) {
Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
- continue;
+ continue;
}
if (strcmp(Job, "*System*") == 0) {
- jcr = NULL; /* No jcr */
+ jcr = NULL; /* No jcr */
} else if (!(jcr=get_jcr_by_full_name(Job))) {
Emsg1(M_ERROR, 0, _("Job not found: %s\n"), bs->msg);
- continue;
+ continue;
}
Dmsg1(900, "Getmsg got jcr 0x%x\n", jcr);
/* Skip past "Jmsg Job=nnn" */
if (!(msg=find_msg_start(bs->msg))) {
Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
- free_jcr(jcr);
- continue;
+ free_jcr(jcr);
+ continue;
}
/*
*/
if (bs->msg[0] == 'J') { /* Job message */
if (sscanf(bs->msg, "Jmsg Job=%127s type=%d level=%d",
- Job, &type, &level) != 3) {
+ Job, &type, &level) != 3) {
Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
- free_jcr(jcr);
- continue;
- }
+ free_jcr(jcr);
+ continue;
+ }
Dmsg1(900, "Got msg: %s\n", bs->msg);
- skip_spaces(&msg);
- skip_nonspaces(&msg); /* skip type=nnn */
- skip_spaces(&msg);
- skip_nonspaces(&msg); /* skip level=nnn */
+ skip_spaces(&msg);
+ skip_nonspaces(&msg); /* skip type=nnn */
+ skip_spaces(&msg);
+ skip_nonspaces(&msg); /* skip level=nnn */
if (*msg == ' ') {
- msg++; /* skip leading space */
- }
+ msg++; /* skip leading space */
+ }
Dmsg1(900, "Dispatch msg: %s", msg);
- dispatch_message(jcr, type, level, msg);
- free_jcr(jcr);
- continue;
+ dispatch_message(jcr, type, level, msg);
+ free_jcr(jcr);
+ continue;
}
/*
* Here we expact a CatReq message
*/
if (bs->msg[0] == 'C') { /* Catalog request */
Dmsg2(900, "Catalog req jcr 0x%x: %s", jcr, bs->msg);
- catalog_request(jcr, bs, msg);
+ catalog_request(jcr, bs, msg);
Dmsg1(900, "Calling freejcr 0x%x\n", jcr);
- free_jcr(jcr);
- continue;
+ free_jcr(jcr);
+ continue;
}
if (bs->msg[0] == 'U') { /* Catalog update */
Dmsg2(900, "Catalog upd jcr 0x%x: %s", jcr, bs->msg);
- catalog_update(jcr, bs, msg);
+ catalog_update(jcr, bs, msg);
Dmsg1(900, "Calling freejcr 0x%x\n", jcr);
- free_jcr(jcr);
- continue;
+ free_jcr(jcr);
+ continue;
}
if (bs->msg[0] == 'M') { /* Mount request */
Dmsg1(900, "Mount req: %s", bs->msg);
- mount_request(jcr, bs, msg);
- free_jcr(jcr);
- continue;
+ mount_request(jcr, bs, msg);
+ free_jcr(jcr);
+ continue;
}
if (bs->msg[0] == 'S') { /* Status change */
- int JobStatus;
- char Job[MAX_NAME_LENGTH];
- if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) {
- jcr->SDJobStatus = JobStatus; /* current status */
- } else {
+ int JobStatus;
+ char Job[MAX_NAME_LENGTH];
+ if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) {
+ jcr->SDJobStatus = JobStatus; /* current status */
+ } else {
Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
- }
- free_jcr(jcr);
- continue;
+ }
+ free_jcr(jcr);
+ continue;
}
-#ifdef needec
+#ifdef needed
/* No JCR for Device Updates! */
if (bs->msg[0] = 'D') { /* Device update */
- DEVICE *dev;
- POOL_MEM dev_name, changer_name, media_type, volume_name;
- int dev_open, dev_append, dev_read, dev_labeled;
- int dev_offline, dev_autochanger, dev_autoselect;
- int dev_num_writers, dev_max_writers, dev_reserved;
- uint64_t dev_PoolId;
+ DEVICE *dev;
+ POOL_MEM dev_name, changer_name, media_type, volume_name;
+ int dev_open, dev_append, dev_read, dev_labeled;
+ int dev_offline, dev_autochanger, dev_autoselect;
+ int dev_num_writers, dev_max_writers, dev_reserved;
+ uint64_t dev_PoolId;
Dmsg1(100, "<stored: %s", bs->msg);
- if (sscanf(bs->msg, Device_update,
- &Job, dev_name.c_str(),
- &dev_append, &dev_read,
- &dev_num_writers, &dev_open,
- &dev_labeled, &dev_offline, &dev_reserved,
- &dev_max_writers, &dev_autoselect,
- &dev_autochanger,
- changer_name.c_str(), media_type.c_str(),
- volume_name.c_str()) != 15) {
+ if (sscanf(bs->msg, Device_update,
+ &Job, dev_name.c_str(),
+ &dev_append, &dev_read,
+ &dev_num_writers, &dev_open,
+ &dev_labeled, &dev_offline, &dev_reserved,
+ &dev_max_writers, &dev_autoselect,
+ &dev_autochanger,
+ changer_name.c_str(), media_type.c_str(),
+ volume_name.c_str()) != 15) {
Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
- } else {
- unbash_spaces(dev_name);
- dev = (DEVICE *)GetResWithName(R_DEVICE, dev_name.c_str());
- if (!dev) {
- continue;
- }
- unbash_spaces(changer_name);
- unbash_spaces(media_type);
- unbash_spaces(volume_name);
- bstrncpy(dev->ChangerName, changer_name.c_str(), sizeof(dev->ChangerName));
- bstrncpy(dev->MediaType, media_type.c_str(), sizeof(dev->MediaType));
- bstrncpy(dev->VolumeName, volume_name.c_str(), sizeof(dev->VolumeName));
- /* Note, these are copied because they are boolean rather than
- * integer.
- */
- dev->open = dev_open;
- dev->append = dev_append;
- dev->read = dev_read;
- dev->labeled = dev_labeled;
- dev->offline = dev_offline;
- dev->autoselect = dev_autoselect;
- dev->autochanger = dev_autochanger > 0;
- dev->num_drives = dev_autochanger; /* does double duty */
- dev->PoolId = dev_PoolId;
- dev->num_writers = dev_num_writers;
- dev->max_writers = dev_max_writers;
- dev->reserved = dev_reserved;
- dev->found = true;
- }
- continue;
+ } else {
+ unbash_spaces(dev_name);
+ dev = (DEVICE *)GetResWithName(R_DEVICE, dev_name.c_str());
+ if (!dev) {
+ continue;
+ }
+ unbash_spaces(changer_name);
+ unbash_spaces(media_type);
+ unbash_spaces(volume_name);
+ bstrncpy(dev->ChangerName, changer_name.c_str(), sizeof(dev->ChangerName));
+ bstrncpy(dev->MediaType, media_type.c_str(), sizeof(dev->MediaType));
+ bstrncpy(dev->VolumeName, volume_name.c_str(), sizeof(dev->VolumeName));
+ /* Note, these are copied because they are boolean rather than
+ * integer.
+ */
+ dev->open = dev_open;
+ dev->append = dev_append;
+ dev->read = dev_read;
+ dev->labeled = dev_labeled;
+ dev->offline = dev_offline;
+ dev->autoselect = dev_autoselect;
+ dev->autochanger = dev_autochanger > 0;
+ dev->num_drives = dev_autochanger; /* does double duty */
+ dev->PoolId = dev_PoolId;
+ dev->num_writers = dev_num_writers;
+ dev->max_writers = dev_max_writers;
+ dev->reserved = dev_reserved;
+ dev->found = true;
+ }
+ continue;
}
#endif
return n;
{
char *p = msg;
- skip_nonspaces(&p); /* skip message type */
+ skip_nonspaces(&p); /* skip message type */
skip_spaces(&p);
- skip_nonspaces(&p); /* skip Job */
- skip_spaces(&p); /* after spaces come the message */
+ skip_nonspaces(&p); /* skip Job */
+ skip_spaces(&p); /* after spaces come the message */
return p;
}
* sent. Check that the response agrees with what we expect.
*
* Returns: false on failure
- * true on success
+ * true on success
*/
bool response(JCR *jcr, BSOCK *bs, char *resp, const char *cmd, e_prtmsg prtmsg)
{
if ((n = bget_dirmsg(bs)) >= 0) {
Dmsg0(900, bs->msg);
if (strcmp(bs->msg, resp) == 0) {
- return true;
+ return true;
}
Dmsg1(900, "Bad response: ERR=%s", bs->msg);
if (prtmsg == DISPLAY_ERROR) {
Jmsg(jcr, M_FATAL, 0, _("Bad response to %s command: wanted %s got: %s\n"),
- cmd, resp, bs->msg);
+ cmd, resp, bs->msg);
}
return false;
}
Jmsg(jcr, M_FATAL, 0, _("Socket error on %s command: ERR=%s\n"),
- cmd, bnet_strerror(bs));
+ cmd, bnet_strerror(bs));
return false;
}
bool write_part_after_job; /* Write part after job in SD */
bool needs_sd; /* set if SD needed by Job */
bool cloned; /* set if cloned */
+ bool cached_attribute; /* set if attribute is cached */
+ ATTR_DBR ar; /* DB attribute record */
+ POOLMEM *attr; /* Attribute string from SD */
#endif /* DIRECTOR_DAEMON */