diff --git a/src/dird/ua_cmds.c b/src/dird/ua_cmds.c index 715dee726d5..bb894c974bd 100644 --- a/src/dird/ua_cmds.c +++ b/src/dird/ua_cmds.c @@ -106,7 +106,7 @@ static struct cmdstruct commands[] = { { NT_("automount"), automount_cmd, _("Automount after label"), NT_("on | off"), false }, { NT_("cancel"), cancel_cmd, _("Cancel a job"), - NT_("storage= jobid= job= ujobid="), false }, + NT_("storage= | jobid= | job= | ujobid= | state= | all yes"), false }, { NT_("create"), create_cmd, _("Create DB Pool from resource"), NT_("pool="), false }, { NT_("delete"), delete_cmd, _("Delete volume, pool or job"), @@ -189,7 +189,9 @@ static struct cmdstruct commands[] = { { NT_("status"), status_cmd, _("Report status"), NT_("all | dir= | director | client= | storage= slots | days=nnn"), true }, { NT_("setbandwidth"), setbwlimit_cmd, _("Sets bandwidth"), - NT_("storage= limit= client= jobid= job= ujobid="), true }, + NT_("client= | storage= | jobid= |\n" + "\tjob= | ujobid= state= | all\n" + "\tlimit= yes"), true }, { NT_("setdebug"), setdebug_cmd, _("Sets debug level"), NT_("level= trace=0/1 client= | dir | storage= | all"), true }, { NT_("setip"), setip_cmd, _("Sets new client address -- if authorized"), @@ -476,7 +478,7 @@ static inline int cancel_storage_daemon_job(UAContext *ua, const char *cmd) /* * See what JobId to cancel on the storage daemon. */ - i = find_arg_with_value(ua, "jobid"); + i = find_arg_with_value(ua, NT_("jobid")); if (i >= 0) { if (!is_a_number(ua->argv[i])) { ua->warning_msg(_("JobId %s not a number\n"), ua->argv[i]); @@ -529,7 +531,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd) /* * See if we need to explicitly cancel a storage daemon Job. */ - i = find_arg_with_value(ua, "storage"); + i = find_arg_with_value(ua, NT_("storage")); if (i >= 0) { return cancel_storage_daemon_job(ua, cmd); } else { @@ -820,11 +822,13 @@ static int setbwlimit_cmd(UAContext *ua, const char *cmd) "job", "jobid", "ujobid", + "all", + "state", NULL }; memset(Job, 0, sizeof(Job)); - i = find_arg_with_value(ua, "limit"); + i = find_arg_with_value(ua, NT_("limit")); if (i >= 0) { limit = atoi(ua->argv[i]) * 1024; } @@ -869,7 +873,7 @@ static int setbwlimit_cmd(UAContext *ua, const char *cmd) } delete selection; - } else if (find_arg(ua, "storage") >= 0) { + } else if (find_arg(ua, NT_("storage")) >= 0) { store = get_storage_resource(ua, false /* no default */); } else { client = get_client_resource(ua); @@ -1117,7 +1121,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd) Dmsg1(120, "setdebug:%s:\n", cmd); level = -1; - i = find_arg_with_value(ua, "level"); + i = find_arg_with_value(ua, NT_("level")); if (i >= 0) { level = atoi(ua->argv[i]); } @@ -1129,7 +1133,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd) } /* Look for trace flag. -1 => not change */ - i = find_arg_with_value(ua, "trace"); + i = find_arg_with_value(ua, NT_("trace")); if (i >= 0) { trace_flag = atoi(ua->argv[i]); if (trace_flag > 0) { @@ -1138,7 +1142,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd) } /* Look for hangup (debug only)flag. -1 => not change */ - i = find_arg_with_value(ua, "hangup"); + i = find_arg_with_value(ua, NT_("hangup")); if (i >= 0) { hangup = atoi(ua->argv[i]); } diff --git a/src/dird/ua_select.c b/src/dird/ua_select.c index 6b8944b448d..fa9cb00642c 100644 --- a/src/dird/ua_select.c +++ b/src/dird/ua_select.c @@ -290,7 +290,7 @@ JOBRES *select_job_resource(UAContext *ua) JOBRES *get_restore_job(UAContext *ua) { JOBRES *job; - int i = find_arg_with_value(ua, "restorejob"); + int i = find_arg_with_value(ua, NT_("restorejob")); if (i >= 0 && acl_access_ok(ua, Job_ACL, ua->argv[i])) { job = (JOBRES *)GetResWithName(R_JOB, ua->argv[i]); if (job && job->JobType == JT_RESTORE) { @@ -592,7 +592,7 @@ int select_media_dbr(UAContext *ua, MEDIA_DBR *mr) *err=0; mr->clear(); - i = find_arg_with_value(ua, "volume"); + i = find_arg_with_value(ua, NT_("volume")); if (i >= 0) { if (is_name_valid(ua->argv[i], &err)) { bstrncpy(mr->VolumeName, ua->argv[i], sizeof(mr->VolumeName)); @@ -670,7 +670,7 @@ POOLRES *get_pool_resource(UAContext *ua) POOLRES *pool = NULL; int i; - i = find_arg_with_value(ua, "pool"); + i = find_arg_with_value(ua, NT_("pool")); if (i >= 0 && acl_access_ok(ua, Pool_ACL, ua->argv[i])) { pool = (POOLRES *)GetResWithName(R_POOL, ua->argv[i]); if (pool) { @@ -1001,7 +1001,7 @@ int get_storage_drive(UAContext *ua, STORERES *store) char drivename[10]; /* Get drive for autochanger if possible */ - i = find_arg_with_value(ua, "drive"); + i = find_arg_with_value(ua, NT_("drive")); if (i >= 0) { drive = atoi(ua->argv[i]); } else if (store && store->autochanger) { @@ -1034,7 +1034,7 @@ int get_storage_slot(UAContext *ua, STORERES *store) { int i, slot = -1; /* Get slot for autochanger if possible */ - i = find_arg_with_value(ua, "slot"); + i = find_arg_with_value(ua, NT_("slot")); if (i >=0) { slot = atoi(ua->argv[i]); } else if (store && store->autochanger) { @@ -1062,7 +1062,7 @@ int get_media_type(UAContext *ua, char *MediaType, int max_media) STORERES *store; int i; - i = find_arg_with_value(ua, "mediatype"); + i = find_arg_with_value(ua, NT_("mediatype")); if (i >= 0) { bstrncpy(MediaType, ua->argv[i], max_media); return 1; @@ -1129,8 +1129,8 @@ alist *select_jobs(UAContext *ua, const char *reason) int cnt = 0; int njobs = 0; JCR *jcr = NULL; - char JobName[MAX_NAME_LENGTH]; - char temp[256]; + bool select_all = false; + bool select_by_state = false; alist *selected_jobids; const char *lst[] = { "job", @@ -1138,9 +1138,34 @@ alist *select_jobs(UAContext *ua, const char *reason) "ujobid", NULL }; + enum { + none, + all_jobs, + created_jobs, + blocked_jobs, + waiting_jobs, + running_jobs + } selection_criterium; + /* + * Allocate a list for holding the selected JobIds. + */ selected_jobids = New(alist(10, owned_by_alist)); + /* + * See if "all" is given. + */ + if (find_arg(ua, NT_("all")) > 0) { + select_all = true; + } + + /* + * See if "state=" is given. + */ + if (find_arg_with_value(ua, NT_("state")) > 0) { + select_by_state = true; + } + /* * See if there are any jobid, job or ujobid keywords. */ @@ -1189,23 +1214,29 @@ alist *select_jobs(UAContext *ua, const char *reason) } } + /* + * If we didn't select any Jobs using jobid, job or ujobid keywords try other selections. + */ if (cnt == 0) { char buf[1000]; - int tjobs = 0; /* total # number jobs */ - /* Count Jobs running */ + int tjobs = 0; /* Total # number jobs */ + + /* + * Count Jobs running + */ foreach_jcr(jcr) { - if (jcr->JobId == 0) { /* this is us */ + if (jcr->JobId == 0) { /* This is us */ continue; } - tjobs++; /* count of all jobs */ + tjobs++; /* Count of all jobs */ if (!acl_access_ok(ua, Job_ACL, jcr->res.job->name())) { - continue; /* skip not authorized */ + continue; /* Skip not authorized */ } - njobs++; /* count of authorized jobs */ + njobs++; /* Count of authorized jobs */ } endeach_jcr(jcr); - if (njobs == 0) { /* no authorized */ + if (njobs == 0) { /* No authorized */ if (tjobs == 0) { ua->send_msg(_("No Jobs running.\n")); } else { @@ -1214,49 +1245,152 @@ alist *select_jobs(UAContext *ua, const char *reason) goto bail_out; } - start_prompt(ua, _("Select Job:\n")); - foreach_jcr(jcr) { - char ed1[50]; - if (jcr->JobId == 0) { /* this is us */ - continue; + if (select_all || select_by_state) { + /* + * Set selection criterium. + */ + if (select_all) { + selection_criterium = all_jobs; + } else { + i = find_arg_with_value(ua, NT_("state")); + if (i > 0) { + selection_criterium = none; + + if (bstrcasecmp(ua->argv[i], NT_("created"))) { + selection_criterium = created_jobs; + } + + if (bstrcasecmp(ua->argv[i], NT_("blocked"))) { + selection_criterium = blocked_jobs; + } + + if (bstrcasecmp(ua->argv[i], NT_("waiting"))) { + selection_criterium = waiting_jobs; + } + + if (bstrcasecmp(ua->argv[i], NT_("running"))) { + selection_criterium = running_jobs; + } + + if (selection_criterium == none) { + ua->error_msg(_("Illegal state either created, blocked, waiting or running\n")); + goto bail_out; + } + } } - if (!acl_access_ok(ua, Job_ACL, jcr->res.job->name())) { - continue; /* skip not authorized */ + + /* + * Select from all available Jobs the Jobs matching the selection criterium. + */ + foreach_jcr(jcr) { + if (jcr->JobId == 0) { /* This is us */ + continue; + } + + if (!acl_access_ok(ua, Job_ACL, jcr->res.job->name())) { + continue; /* Skip not authorized */ + } + + /* + * See if we need to select this JobId. + */ + switch (selection_criterium) { + case all_jobs: + break; + case created_jobs: + if (jcr->JobStatus != JS_Created) { + continue; + } + break; + case blocked_jobs: + if (!jcr->job_started || jcr->JobStatus != JS_Blocked) { + continue; + } + break; + case waiting_jobs: + if (!job_waiting(jcr)) { + continue; + } + break; + case running_jobs: + if (!jcr->job_started || jcr->JobStatus != JS_Running) { + continue; + } + break; + default: + break; + } + + insert_selected_jobid(selected_jobids, jcr->JobId); + ua->send_msg(_("Selected Job %d for cancelling\n") , jcr->JobId); } - bsnprintf(buf, sizeof(buf), _("JobId=%s Job=%s"), edit_int64(jcr->JobId, ed1), jcr->Job); - add_prompt(ua, buf); - } - endeach_jcr(jcr); - bsnprintf(temp, sizeof(temp), _("Choose Job to %s"), _(reason)); - if (do_prompt(ua, _("Job"), temp, buf, sizeof(buf)) < 0) { - goto bail_out; - } - if (bstrcmp(reason, "cancel")) { - 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) { + + if (selected_jobids->empty()) { + ua->send_msg(_("No Jobs selected.\n")); + goto bail_out; + } + + /* + * Only ask for confirmation when not in batch mode and there is no yes on the cmdline. + */ + if (!ua->batch && find_arg(ua, NT_("yes")) == -1) { + if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) { goto bail_out; } - } else { - if (njobs == 1) { - if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) { + } + } else { + char temp[256]; + char JobName[MAX_NAME_LENGTH]; + + /* + * Interactivly select a Job. + */ + start_prompt(ua, _("Select Job:\n")); + foreach_jcr(jcr) { + char ed1[50]; + if (jcr->JobId == 0) { /* This is us */ + continue; + } + if (!acl_access_ok(ua, Job_ACL, jcr->res.job->name())) { + continue; /* Skip not authorized */ + } + bsnprintf(buf, sizeof(buf), _("JobId=%s Job=%s"), edit_int64(jcr->JobId, ed1), jcr->Job); + add_prompt(ua, buf); + } + endeach_jcr(jcr); + + bsnprintf(temp, sizeof(temp), _("Choose Job to %s"), _(reason)); + if (do_prompt(ua, _("Job"), temp, buf, sizeof(buf)) < 0) { + goto bail_out; + } + + if (bstrcmp(reason, "cancel")) { + 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) { goto bail_out; } + } else { + if (njobs == 1) { + if (!get_yesno(ua, _("Confirm cancel (yes/no): ")) || ua->pint32_val == 0) { + goto bail_out; + } + } } } - } - sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName); - jcr = get_jcr_by_full_name(JobName); - if (!jcr) { - ua->warning_msg(_("Job \"%s\" not found.\n"), JobName); - goto bail_out; - } - insert_selected_jobid(selected_jobids, jcr->JobId); + sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName); + jcr = get_jcr_by_full_name(JobName); + if (!jcr) { + ua->warning_msg(_("Job \"%s\" not found.\n"), JobName); + goto bail_out; + } - free_jcr(jcr); + insert_selected_jobid(selected_jobids, jcr->JobId); + free_jcr(jcr); + } } return selected_jobids;