many others, a complete list can be found in the file AUTHORS.
This program is Free Software; you can redistribute it and/or
modify it under the terms of version two of the GNU General Public
- License as published by the Free Software Foundation plus additions
- that are listed in the file LICENSE.
+ License as published by the Free Software Foundation and included
+ in the file LICENSE.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
/* Imported subroutines */
/* Imported variables */
-extern int r_first;
-extern int r_last;
-extern struct s_res resources[];
extern jobq_t job_queue; /* job queue */
{ NT_("list"), list_cmd, _("list [pools | jobs | jobtotals | media <pool=pool-name> | files <jobid=nn>]; from catalog")},
{ NT_("label"), label_cmd, _("label a tape")},
{ NT_("llist"), llist_cmd, _("full or long list like list command")},
- { NT_("memory"), memory_cmd, _("print current memory usage")},
{ NT_("messages"), messagescmd, _("messages")},
+ { NT_("memory"), memory_cmd, _("print current memory usage")},
{ NT_("mount"), mount_cmd, _("mount <storage-name>")},
{ NT_("prune"), prunecmd, _("prune expired records from catalog")},
{ NT_("purge"), purgecmd, _("purge records from catalog")},
/*
* Execute a command from the UA
*/
-int do_a_command(UAContext *ua, const char *cmd)
+bool do_a_command(UAContext *ua)
{
unsigned int i;
- int len, stat;
+ int len;
bool ok = false;
bool found = false;
BSOCK *user = ua->UA_sock;
- stat = 1;
Dmsg1(900, "Command: %s\n", ua->UA_sock->msg);
if (ua->argc == 0) {
- return 1;
+ return false;
}
while (ua->jcr->wstorage->size()) {
break;
}
if (ua->api) user->signal(BNET_CMD_BEGIN);
- ok = (*commands[i].func)(ua, cmd); /* go execute command */
+ ok = (*commands[i].func)(ua, ua->cmd); /* go execute command */
found = true;
break;
}
}
if (!found) {
- user->fsend(_("%s: is an invalid command.\n"), ua->argk[0]);
+ ua->error_msg(_("%s: is an invalid command.\n"), ua->argk[0]);
+ ok = false;
}
if (ua->api) user->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED);
return ok;
while (pr.MaxVols > 0 && pr.NumVols >= pr.MaxVols) {
ua->warning_msg(_("Pool already has maximum volumes=%d\n"), pr.MaxVols);
- for (;;) {
- if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) {
- return 1;
- }
- pr.MaxVols = ua->pint32_val;
+ if (!get_pint(ua, _("Enter new maximum (zero for unlimited): "))) {
+ return 1;
}
+ pr.MaxVols = ua->pint32_val;
}
/* Get media type */
}
break;
}
-getVolName:
- if (num == 0) {
- if (!get_cmd(ua, _("Enter Volume name: "))) {
- return 1;
+
+ for (;;) {
+ if (num == 0) {
+ if (!get_cmd(ua, _("Enter Volume name: "))) {
+ return 1;
+ }
+ } else {
+ if (!get_cmd(ua, _("Enter base volume name: "))) {
+ return 1;
+ }
}
- } else {
- if (!get_cmd(ua, _("Enter base volume name: "))) {
- return 1;
+ /* Don't allow | in Volume name because it is the volume separator character */
+ if (!is_volume_name_legal(ua, ua->cmd)) {
+ continue;
}
- }
- /* Don't allow | in Volume name because it is the volume separator character */
- if (!is_volume_name_legal(ua, ua->cmd)) {
- goto getVolName;
- }
- if (strlen(ua->cmd) >= MAX_NAME_LENGTH-10) {
- ua->warning_msg(_("Volume name too long.\n"));
- goto getVolName;
- }
- if (strlen(ua->cmd) == 0) {
- ua->warning_msg(_("Volume name must be at least one character long.\n"));
- goto getVolName;
+ if (strlen(ua->cmd) >= MAX_NAME_LENGTH-10) {
+ ua->warning_msg(_("Volume name too long.\n"));
+ continue;
+ }
+ if (strlen(ua->cmd) == 0) {
+ ua->warning_msg(_("Volume name must be at least one character long.\n"));
+ continue;
+ }
+ break;
}
bstrncpy(name, ua->cmd, sizeof(name));
if (do_prompt(ua, _("Job"), _("Choose Job to cancel"), buf, sizeof(buf)) < 0) {
return 1;
}
- if (njobs == 1) {
- if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) {
+ if (ua->api && njobs == 1) {
+ char nbuf[1000];
+ bsnprintf(nbuf, sizeof(nbuf), _("Cancel: %s\n\n%s"), buf,
+ _("Confirm cancel?"));
+ if (!get_yesno(ua, nbuf) || ua->pint32_val == 0) {
return 1;
}
+ } else {
+ if (njobs == 1) {
+ if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) {
+ return 1;
+ }
+ }
}
sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName);
jcr = get_jcr_by_full_name(JobName);
strcasecmp(ua->argk[i], NT_("fd")) == 0) {
if (ua->argv[i]) {
client = GetClientResWithName(ua->argv[i]);
+ if (!client) {
+ ua->error_msg(_("Client \"%s\" not found.\n"), ua->argv[i]);
+ return 1;
+ }
continue;
}
}
if (strcasecmp(ua->argk[i], NT_("job")) == 0) {
if (ua->argv[i]) {
job = GetJobResWithName(ua->argv[i]);
- if (job && !acl_access_ok(ua, Job_ACL, job->name())) {
+ if (!job) {
+ ua->error_msg(_("Job \"%s\" not found.\n"), ua->argv[i]);
+ return 1;
+ }
+ if (!acl_access_ok(ua, Job_ACL, job->name())) {
ua->error_msg(_("No authorization for Job \"%s\"\n"), job->name());
return 1;
}
if (strcasecmp(ua->argk[i], NT_("fileset")) == 0) {
if (ua->argv[i]) {
fileset = GetFileSetResWithName(ua->argv[i]);
- if (fileset && !acl_access_ok(ua, FileSet_ACL, fileset->name())) {
+ if (!fileset) {
+ ua->error_msg(_("Fileset \"%s\" not found.\n"), ua->argv[i]);
+ return 1;
+ }
+ if (!acl_access_ok(ua, FileSet_ACL, fileset->name())) {
ua->error_msg(_("No authorization for FileSet \"%s\"\n"), fileset->name());
return 1;
}
jcr->client = client;
jcr->fileset = fileset;
close_db(ua);
- ua->catalog = client->catalog;
+ if (job->pool->catalog) {
+ ua->catalog = job->pool->catalog;
+ } else {
+ ua->catalog = client->catalog;
+ }
if (!open_db(ua)) {
return 1;
get_level_since_time(ua->jcr, since, sizeof(since));
ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
- job->client->name(), job->client->address, job->client->FDport);
+ jcr->client->name(), jcr->client->address, jcr->client->FDport);
if (!connect_to_file_daemon(jcr, 1, 15, 0)) {
ua->error_msg(_("Failed to connect to Client.\n"));
return 1;
static int delete_volume(UAContext *ua)
{
MEDIA_DBR mr;
+ char buf[1000];
if (!select_media_dbr(ua, &mr)) {
return 1;
"and all Jobs saved on that volume from the Catalog\n"),
mr.VolumeName);
- if (!get_yesno(ua, _("Are you sure you want to delete this Volume? (yes/no): "))) {
+ bsnprintf(buf, sizeof(buf), _("Are you sure you want to delete Volume \"%s\"? (yes/no): "),
+ mr.VolumeName);
+ if (!get_yesno(ua, buf)) {
return 1;
}
if (ua->pint32_val) {
static int delete_pool(UAContext *ua)
{
POOL_DBR pr;
+ char buf[200];
memset(&pr, 0, sizeof(pr));
if (!get_pool_dbr(ua, &pr)) {
return 1;
}
- if (!get_yesno(ua, _("Are you sure you want to delete this Pool? (yes/no): "))) {
+ bsnprintf(buf, sizeof(buf), _("Are you sure you want to delete Pool \"%s\"? (yes/no): "),
+ pr.Name);
+ if (!get_yesno(ua, buf)) {
return 1;
}
if (ua->pint32_val) {
int memory_cmd(UAContext *ua, const char *cmd)
{
list_dir_status_header(ua);
- sm_dump(false);
+ sm_dump(false, true);
return 1;
}
Dmsg2(120, "%s: %s\n", command, ua->UA_sock->msg);
store.store = get_storage_resource(ua, true/*arg is storage*/);
- pm_strcpy(store.store_source, _("unknown source"));
if (!store.store) {
return;
}
+ pm_strcpy(store.store_source, _("unknown source"));
set_wstorage(jcr, &store);
drive = get_storage_drive(ua, store.store);
if (strcmp(command, "mount") == 0) {
{
JCR *jcr;
- /* no args
+ /*
+ * no args
* Wait until no job is running
*/
if (ua->argc == 1) {
}
/*
- * We wait the end of job
+ * We wait the end of a specific job
*/
bmicrosleep(0, 200000); /* let job actually start */
return 1;
}
+#if 1
static int version_cmd(UAContext *ua, const char *cmd)
{
ua->send_msg(_("%s Version: %s (%s) %s %s %s\n"), my_name, VERSION, BDATE,
HOST_OS, DISTNAME, DISTVER);
return 1;
}
+#else
+/*
+ * Test code -- turned on only for debug testing
+ */
+static int version_cmd(UAContext *ua, const char *cmd)
+{
+ dbid_list ids;
+ POOL_MEM query(PM_MESSAGE);
+ open_db(ua);
+ Mmsg(query, "select MediaId from Media,Pool where Pool.PoolId=Media.PoolId and Pool.Name='Full'");
+ db_get_query_dbids(ua->jcr, ua->db, query, ids);
+ ua->send_msg("num_ids=%d max_ids=%d tot_ids=%d\n", ids.num_ids, ids.max_ids, ids.tot_ids);
+ for (int i=0; i < ids.num_ids; i++) {
+ ua->send_msg("id=%d\n", ids.DBId[i]);
+ }
+ close_db(ua);
+ return 1;
+}
+#endif
/*
* This call explicitly checks for a catalog=xxx and
ua->jcr->catalog = ua->catalog;
Dmsg0(100, "UA Open database\n");
- ua->db = db_init_database(ua->jcr, ua->catalog->db_name, ua->catalog->db_user,
+ ua->db = db_init(ua->jcr, ua->catalog->db_driver, ua->catalog->db_name,
+ ua->catalog->db_user,
ua->catalog->db_password, ua->catalog->db_address,
ua->catalog->db_port, ua->catalog->db_socket,
ua->catalog->mult_db_connections);