X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Fua_cmds.c;h=2baa3438e3d8a62facca795c3cee1639ab0c0315;hb=9f01506e19567ce5c8fae5699016a1d512647f55;hp=1a5b426a3a768ee48f711d4d1b9d86b4fe824d54;hpb=790890265aebc2a7f7f43610df5eef29c5bbea29;p=bacula%2Fbacula diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 1a5b426a3a..2baa3438e3 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -8,7 +8,7 @@ */ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2000-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 @@ -39,6 +39,7 @@ extern struct s_res resources[]; extern char my_name[]; extern jobq_t job_queue; /* job queue */ + extern char *list_pool; /* Imported functions */ @@ -47,7 +48,8 @@ extern int list_cmd(UAContext *ua, char *cmd); extern int llist_cmd(UAContext *ua, char *cmd); extern int show_cmd(UAContext *ua, char *cmd); extern int messagescmd(UAContext *ua, char *cmd); -extern int autodisplaycmd(UAContext *ua, char *cmd); +extern int autodisplay_cmd(UAContext *ua, char *cmd); +extern int gui_cmd(UAContext *ua, char *cmd); extern int sqlquerycmd(UAContext *ua, char *cmd); extern int querycmd(UAContext *ua, char *cmd); extern int run_cmd(UAContext *ua, char *cmd); @@ -64,6 +66,7 @@ static int add_cmd(UAContext *ua, char *cmd); static int create_cmd(UAContext *ua, char *cmd); static int cancel_cmd(UAContext *ua, char *cmd); static int setdebug_cmd(UAContext *ua, char *cmd); +static int trace_cmd(UAContext *ua, char *cmd); static int var_cmd(UAContext *ua, char *cmd); static int estimate_cmd(UAContext *ua, char *cmd); static int help_cmd(UAContext *ua, char *cmd); @@ -71,6 +74,7 @@ static int delete_cmd(UAContext *ua, char *cmd); static int use_cmd(UAContext *ua, char *cmd), unmount_cmd(UAContext *ua, char *cmd); static int version_cmd(UAContext *ua, char *cmd), automount_cmd(UAContext *ua, char *cmd); static int time_cmd(UAContext *ua, char *cmd); +static int reload_cmd(UAContext *ua, char *cmd); static int update_volume(UAContext *ua); static int update_pool(UAContext *ua); static int delete_volume(UAContext *ua); @@ -80,6 +84,7 @@ static int mount_cmd(UAContext *ua, char *cmd); static int release_cmd(UAContext *ua, char *cmd); static int update_cmd(UAContext *ua, char *cmd); static int wait_cmd(UAContext *ua, char *cmd); +static int setip_cmd(UAContext *ua, char *cmd); int quit_cmd(UAContext *ua, char *cmd); @@ -87,15 +92,16 @@ int quit_cmd(UAContext *ua, char *cmd); struct cmdstruct { char *key; int (*func)(UAContext *ua, char *cmd); char *help; }; static struct cmdstruct commands[] = { { N_("add"), add_cmd, _("add media to a pool")}, - { N_("autodisplay"), autodisplaycmd, _("autodisplay [on/off] -- console messages")}, + { N_("autodisplay"), autodisplay_cmd, _("autodisplay [on/off] -- console messages")}, { N_("automount"), automount_cmd, _("automount [on/off] -- after label")}, { N_("cancel"), cancel_cmd, _("cancel job=nnn -- cancel a job")}, { N_("create"), create_cmd, _("create DB Pool from resource")}, { N_("delete"), delete_cmd, _("delete [pool= | media volume=]")}, { N_("estimate"), estimate_cmd, _("performs FileSet estimate, listing gives full listing")}, { N_("exit"), quit_cmd, _("exit = quit")}, + { N_("gui"), gui_cmd, _("gui [on/off] -- non-interactive gui mode")}, { N_("help"), help_cmd, _("print this command")}, - { N_("list"), list_cmd, _("list [pools | jobs | jobtotals | media | files job=]; from catalog")}, + { N_("list"), list_cmd, _("list [pools | jobs | jobtotals | media | files jobid=]; from catalog")}, { N_("label"), label_cmd, _("label a tape")}, { N_("llist"), llist_cmd, _("full or long list like list command")}, { N_("messages"), messagescmd, _("messages")}, @@ -107,12 +113,15 @@ static struct cmdstruct commands[] = { { N_("restore"), restore_cmd, _("restore files")}, { N_("relabel"), relabel_cmd, _("relabel a tape")}, { N_("release"), release_cmd, _("release ")}, + { N_("reload"), reload_cmd, _("reload conf file")}, { N_("run"), run_cmd, _("run ")}, { N_("status"), status_cmd, _("status [storage | client]=")}, { N_("setdebug"), setdebug_cmd, _("sets debug level")}, + { N_("setip"), setip_cmd, _("sets new client address -- if authorized")}, { N_("show"), show_cmd, _("show (resource records) [jobs | pools | ... | all]")}, { N_("sqlquery"), sqlquerycmd, _("use SQL to query catalog")}, { N_("time"), time_cmd, _("print current time")}, + { N_("trace"), trace_cmd, _("turn on/off trace to file")}, { N_("unmount"), unmount_cmd, _("unmount ")}, { N_("update"), update_cmd, _("update Volume or Pool")}, { N_("use"), use_cmd, _("use catalog xxx")}, @@ -129,12 +138,11 @@ int do_a_command(UAContext *ua, char *cmd) { unsigned int i; int len, stat; - int found; + bool found = false; - found = 0; stat = 1; - Dmsg1(120, "Command: %s\n", ua->UA_sock->msg); + Dmsg1(200, "Command: %s\n", ua->UA_sock->msg); if (ua->argc == 0) { return 1; } @@ -142,15 +150,16 @@ int do_a_command(UAContext *ua, char *cmd) len = strlen(ua->argk[0]); for (i=0; iargk[0], _(commands[i].key), len) == 0) { + if (!acl_access_ok(ua, Command_ACL, ua->argk[0], len)) { + break; + } stat = (*commands[i].func)(ua, cmd); /* go execute command */ - found = 1; + found = true; break; } } if (!found) { - pm_strcat(&ua->UA_sock->msg, _(": is an illegal command\n")); - ua->UA_sock->msglen = strlen(ua->UA_sock->msg); - bnet_send(ua->UA_sock); + bnet_fsend(ua->UA_sock, _("%s: is an illegal command.\n"), ua->argk[0]); } return stat; } @@ -184,7 +193,7 @@ static int add_cmd(UAContext *ua, char *cmd) int first_id = 0; char name[MAX_NAME_LENGTH]; STORE *store; - int slot = 0; + int Slot = 0, InChanger = 0; bsendmsg(ua, _( "You probably don't want to be using this command since it\n" @@ -287,13 +296,18 @@ getVolName: if (!get_pint(ua, _("Enter slot (0 for none): "))) { return 1; } - slot = ua->pint32_val; + Slot = ua->pint32_val; + if (!get_yesno(ua, _("InChanger? yes/no: "))) { + return 1; + } + InChanger = ua->pint32_val; } set_pool_dbr_defaults_in_media_dbr(&mr, &pr); for (i=startnum; i < num+startnum; i++) { bsnprintf(mr.VolumeName, sizeof(mr.VolumeName), name, i); - mr.Slot = slot++; + mr.Slot = Slot++; + mr.InChanger = InChanger; Dmsg1(200, "Create Volume %s\n", mr.VolumeName); if (!db_create_media_record(ua->jcr, ua->db, &mr)) { bsendmsg(ua, db_strerror(ua->db)); @@ -343,9 +357,8 @@ int automount_cmd(UAContext *ua, char *cmd) */ static int cancel_cmd(UAContext *ua, char *cmd) { - int i; + int i, ret; int njobs = 0; - BSOCK *sd, *fd; JCR *jcr = NULL; char JobName[MAX_NAME_LENGTH]; @@ -355,11 +368,13 @@ static int cancel_cmd(UAContext *ua, char *cmd) for (i=1; iargc; i++) { if (strcasecmp(ua->argk[i], _("jobid")) == 0) { + uint32_t JobId; if (!ua->argv[i]) { break; } - if (!(jcr=get_jcr_by_id(atoi(ua->argv[i])))) { - bsendmsg(ua, _("JobId %d is not running.\n"), atoi(ua->argv[i])); + JobId = str_to_int64(ua->argv[i]); + if (!(jcr=get_jcr_by_id(JobId))) { + bsendmsg(ua, _("JobId %d is not running.\n"), JobId); return 1; } break; @@ -380,13 +395,13 @@ static int cancel_cmd(UAContext *ua, char *cmd) if (!jcr) { /* Count Jobs running */ lock_jcr_chain(); - for (jcr=NULL; (jcr=get_next_jcr(jcr)); njobs++) { + foreach_jcr(jcr) { if (jcr->JobId == 0) { /* this is us */ free_locked_jcr(jcr); - njobs--; continue; } free_locked_jcr(jcr); + njobs++; } unlock_jcr_chain(); @@ -396,7 +411,7 @@ static int cancel_cmd(UAContext *ua, char *cmd) } start_prompt(ua, _("Select Job:\n")); lock_jcr_chain(); - for (jcr=NULL; (jcr=get_next_jcr(jcr)); ) { + foreach_jcr(jcr) { if (jcr->JobId == 0) { /* this is us */ free_locked_jcr(jcr); continue; @@ -414,72 +429,18 @@ static int cancel_cmd(UAContext *ua, char *cmd) return 1; } } + /* NOTE! This increments the ref_count */ jcr = get_jcr_by_full_name(JobName); if (!jcr) { bsendmsg(ua, _("Job %s not found.\n"), JobName); return 1; } } - - switch (jcr->JobStatus) { - case JS_Created: - case JS_WaitJobRes: - case JS_WaitClientRes: - case JS_WaitStoreRes: - case JS_WaitPriority: - case JS_WaitMaxJobs: - case JS_WaitStartTime: - set_jcr_job_status(jcr, JS_Canceled); - bsendmsg(ua, _("JobId %d, Job %s marked to be canceled.\n"), - jcr->JobId, jcr->Job); - jobq_remove(&job_queue, jcr); /* attempt to remove it from queue */ - free_jcr(jcr); /* this decrements the use count only */ - return 1; - - default: - set_jcr_job_status(jcr, JS_Canceled); - - /* Cancel File daemon */ - if (jcr->file_bsock) { - ua->jcr->client = jcr->client; - if (!connect_to_file_daemon(ua->jcr, 10, FDConnectTimeout, 1)) { - bsendmsg(ua, _("Failed to connect to File daemon.\n")); - free_jcr(jcr); - return 1; - } - Dmsg0(200, "Connected to file daemon\n"); - fd = ua->jcr->file_bsock; - bnet_fsend(fd, "cancel Job=%s\n", jcr->Job); - while (bnet_recv(fd) >= 0) { - bsendmsg(ua, "%s", fd->msg); - } - bnet_sig(fd, BNET_TERMINATE); - bnet_close(fd); - ua->jcr->file_bsock = NULL; - } - /* Cancel Storage daemon */ - if (jcr->store_bsock) { - ua->jcr->store = jcr->store; - if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) { - bsendmsg(ua, _("Failed to connect to Storage daemon.\n")); - free_jcr(jcr); - return 1; - } - Dmsg0(200, "Connected to storage daemon\n"); - sd = ua->jcr->store_bsock; - bnet_fsend(sd, "cancel Job=%s\n", jcr->Job); - while (bnet_recv(sd) >= 0) { - bsendmsg(ua, "%s", sd->msg); - } - bnet_sig(sd, BNET_TERMINATE); - bnet_close(sd); - ua->jcr->store_bsock = NULL; - } - } + ret = cancel_job(ua, jcr); free_jcr(jcr); - return 1; + return ret; } /* @@ -576,8 +537,8 @@ static int create_cmd(UAContext *ua, char *cmd) switch (create_pool(ua->jcr, ua->db, pool, POOL_OP_CREATE)) { case 0: - bsendmsg(ua, _("Error: Pool %s already exists.\n\ -Use update to change it.\n"), pool->hdr.name); + bsendmsg(ua, _("Error: Pool %s already exists.\n" + "Use update to change it.\n"), pool->hdr.name); break; case -1: @@ -592,6 +553,35 @@ Use update to change it.\n"), pool->hdr.name); } +/* + * Set a new address in a Client resource. We do this only + * if the Console name is the same as the Client name + * and the Console can access the client. + */ +static int setip_cmd(UAContext *ua, char *cmd) +{ + CLIENT *client; + if (!ua->cons || !acl_access_ok(ua, Client_ACL, ua->cons->hdr.name)) { + bsendmsg(ua, _("Illegal command from this console.\n")); + return 1; + } + LockRes(); + client = (CLIENT *)GetResWithName(R_CLIENT, ua->cons->hdr.name); + + if (!client) { + bsendmsg(ua, _("Client \"%s\" not found.\n"), ua->cons->hdr.name); + goto get_out; + } + if (client->address) { + free(client->address); + } + client->address = bstrdup(inet_ntoa(ua->UA_sock->client_addr.sin_addr)); + bsendmsg(ua, _("Client \"%s\" address set to %s\n"), + client->hdr.name, client->address); +get_out: + UnlockRes(); + return 1; +} /* @@ -602,6 +592,8 @@ Use update to change it.\n"), pool->hdr.name); * updates pool from Pool resource * update media pool= volume= * changes pool info for volume + * update slots [scan=...] + * updates autochanger slots */ static int update_cmd(UAContext *ua, char *cmd) { @@ -794,7 +786,7 @@ static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr) if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { - bsendmsg(ua, _("New recycle flag is: %s\n"), + bsendmsg(ua, _("New Recycle flag is: %s\n"), mr->Recycle==1?_("yes"):_("no")); } free_pool_memory(query); @@ -805,21 +797,49 @@ static void update_volpool(UAContext *ua, char *val, MEDIA_DBR *mr) { POOL_DBR pr; POOLMEM *query; + memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, val, sizeof(pr.Name)); if (!get_pool_dbr(ua, &pr)) { return; } + mr->PoolId = pr.PoolId; /* set new PoolId */ + /* + */ query = get_pool_memory(PM_MESSAGE); - Mmsg(&query, "UPDATE Media SET PoolId=%u WHERE MediaId=%u", pr.PoolId, mr->MediaId); + db_lock(ua->db); + Mmsg(&query, "UPDATE Media SET PoolId=%d WHERE MediaId=%u", + mr->PoolId, mr->MediaId); if (!db_sql_query(ua->db, query, NULL, NULL)) { bsendmsg(ua, "%s", db_strerror(ua->db)); } else { bsendmsg(ua, _("New Pool is: %s\n"), pr.Name); } + db_make_inchanger_unique(ua->jcr, ua->db, mr); + db_unlock(ua->db); free_pool_memory(query); } +static void update_volfrompool(UAContext *ua, MEDIA_DBR *mr) +{ + POOL_DBR pr; + char VolStatus[50]; + + memset(&pr, 0, sizeof(pr)); + pr.PoolId = mr->PoolId; + if (!get_pool_dbr(ua, &pr)) { + return; + } + bstrncpy(VolStatus, mr->VolStatus, sizeof(VolStatus)); + set_pool_dbr_defaults_in_media_dbr(mr, &pr); + bstrncpy(mr->VolStatus, VolStatus, sizeof(mr->VolStatus)); + if (!db_update_media_record(ua->jcr, ua->db, mr)) { + bsendmsg(ua, _("Error updating Volume record: ERR=%s"), db_strerror(ua->db)); + } else { + bsendmsg(ua, _("Volume defaults updated from Pool record.\n")); + } +} + /* * Update a media record -- allows you to change the * Volume status. E.g. if you want Bacula to stop @@ -842,6 +862,7 @@ static int update_volume(UAContext *ua) N_("MaxVolBytes"), /* 5 */ N_("Recycle"), /* 6 */ N_("Pool"), /* 7 */ + N_("FromPool"), /* 8 */ NULL }; for (int i=0; kw[i]; i++) { @@ -874,6 +895,10 @@ static int update_volume(UAContext *ua) break; case 7: update_volpool(ua, ua->argv[j], &mr); + break; + case 8: + update_volfrompool(ua, &mr); + break; } done = true; } @@ -893,6 +918,7 @@ static int update_volume(UAContext *ua) add_prompt(ua, _("Maximum Volume Bytes")); add_prompt(ua, _("Recycle Flag")); add_prompt(ua, _("Slot")); + add_prompt(ua, _("InChanger Flag")); add_prompt(ua, _("Volume Files")); add_prompt(ua, _("Pool")); add_prompt(ua, _("Done")); @@ -969,7 +995,7 @@ static int update_volume(UAContext *ua) break; case 7: /* Slot */ - int slot; + int Slot; memset(&pr, 0, sizeof(POOL_DBR)); pr.PoolId = mr.PoolId; @@ -981,24 +1007,43 @@ static int update_volume(UAContext *ua) if (!get_pint(ua, _("Enter new Slot: "))) { return 0; } - slot = ua->pint32_val; - if (pr.MaxVols > 0 && slot > (int)pr.MaxVols) { + Slot = ua->pint32_val; + if (pr.MaxVols > 0 && Slot > (int)pr.MaxVols) { bsendmsg(ua, _("Invalid slot, it must be between 0 and %d\n"), pr.MaxVols); break; } - query = get_pool_memory(PM_MESSAGE); - Mmsg(&query, "UPDATE Media SET Slot=%d WHERE MediaId=%u", - slot, mr.MediaId); - if (!db_sql_query(ua->db, query, NULL, NULL)) { - bsendmsg(ua, "%s", db_strerror(ua->db)); + mr.Slot = Slot; + /* + * Make sure to use db_update... rather than doing this directly, + * so that any Slot is handled correctly. + */ + if (!db_update_media_record(ua->jcr, ua->db, &mr)) { + bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db)); } else { - bsendmsg(ua, "New Slot is: %d\n", slot); + bsendmsg(ua, _("New Slot is: %d\n"), mr.Slot); + } + break; + + case 8: /* InChanger */ + bsendmsg(ua, _("Current InChanger flag is: %d\n"), mr.InChanger); + if (!get_yesno(ua, _("Set InChanger flag? yes/no: "))) { + return 0; + } + mr.InChanger = ua->pint32_val; + /* + * Make sure to use db_update... rather than doing this directly, + * so that any Slot is handled correctly. + */ + if (!db_update_media_record(ua->jcr, ua->db, &mr)) { + bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db)); + } else { + bsendmsg(ua, _("New InChanger flag is: %d\n"), mr.InChanger); } - free_pool_memory(query); break; - case 8: /* Volume Files */ + + case 9: /* Volume Files */ int32_t VolFiles; bsendmsg(ua, _("Warning changing Volume Files can result\n" "in loss of data on your Volume\n\n")); @@ -1024,7 +1069,7 @@ static int update_volume(UAContext *ua) free_pool_memory(query); break; - case 9: /* Volume's Pool */ + case 10: /* Volume's Pool */ memset(&pr, 0, sizeof(POOL_DBR)); pr.PoolId = mr.PoolId; if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { @@ -1037,6 +1082,7 @@ static int update_volume(UAContext *ua) } update_volpool(ua, ua->cmd, &mr); return 1; + default: /* Done or error */ bsendmsg(ua, "Selection done.\n"); return 1; @@ -1082,7 +1128,7 @@ static int update_pool(UAContext *ua) } -static void do_storage_setdebug(UAContext *ua, STORE *store, int level) +static void do_storage_setdebug(UAContext *ua, STORE *store, int level, int trace_flag) { BSOCK *sd; @@ -1096,7 +1142,7 @@ static void do_storage_setdebug(UAContext *ua, STORE *store, int level) } Dmsg0(120, _("Connected to storage daemon\n")); sd = ua->jcr->store_bsock; - bnet_fsend(sd, "setdebug=%d\n", level); + bnet_fsend(sd, "setdebug=%d trace=%d\n", level, trace_flag); if (bnet_recv(sd) >= 0) { bsendmsg(ua, "%s", sd->msg); } @@ -1106,7 +1152,7 @@ static void do_storage_setdebug(UAContext *ua, STORE *store, int level) return; } -static void do_client_setdebug(UAContext *ua, CLIENT *client, int level) +static void do_client_setdebug(UAContext *ua, CLIENT *client, int level, int trace_flag) { BSOCK *fd; @@ -1122,7 +1168,7 @@ static void do_client_setdebug(UAContext *ua, CLIENT *client, int level) } Dmsg0(120, "Connected to file daemon\n"); fd = ua->jcr->file_bsock; - bnet_fsend(fd, "setdebug=%d\n", level); + bnet_fsend(fd, "setdebug=%d trace=%d\n", level, trace_flag); if (bnet_recv(fd) >= 0) { bsendmsg(ua, "%s", fd->msg); } @@ -1133,7 +1179,7 @@ static void do_client_setdebug(UAContext *ua, CLIENT *client, int level) } -static void do_all_setdebug(UAContext *ua, int level) +static void do_all_setdebug(UAContext *ua, int level, int trace_flag) { STORE *store, **unique_store; CLIENT *client, **unique_client; @@ -1170,7 +1216,7 @@ static void do_all_setdebug(UAContext *ua, int level) /* Call each unique Storage daemon */ for (j=0; jpint32_val; } + /* Look for trace flag. -1 => not change */ + i = find_arg_with_value(ua, _("trace")); + if (i >= 0) { + trace_flag = atoi(ua->argv[i]); + if (trace_flag > 0) { + trace_flag = 1; + } + } + /* General debug? */ for (i=1; iargc; i++) { if (strcasecmp(ua->argk[i], _("all")) == 0) { - do_all_setdebug(ua, level); + do_all_setdebug(ua, level, trace_flag); return 1; } if (strcasecmp(ua->argk[i], _("dir")) == 0 || strcasecmp(ua->argk[i], _("director")) == 0) { debug_level = level; + set_trace(trace_flag); return 1; } if (strcasecmp(ua->argk[i], _("client")) == 0 || @@ -1251,13 +1308,13 @@ static int setdebug_cmd(UAContext *ua, char *cmd) if (ua->argv[i]) { client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); if (client) { - do_client_setdebug(ua, client, level); + do_client_setdebug(ua, client, level, trace_flag); return 1; } } client = select_client_resource(ua); if (client) { - do_client_setdebug(ua, client, level); + do_client_setdebug(ua, client, level, trace_flag); return 1; } } @@ -1269,13 +1326,13 @@ static int setdebug_cmd(UAContext *ua, char *cmd) if (ua->argv[i]) { store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]); if (store) { - do_storage_setdebug(ua, store, level); + do_storage_setdebug(ua, store, level, trace_flag); return 1; } } store = get_storage_resource(ua, 0); if (store) { - do_storage_setdebug(ua, store, level); + do_storage_setdebug(ua, store, level, trace_flag); return 1; } } @@ -1292,21 +1349,22 @@ static int setdebug_cmd(UAContext *ua, char *cmd) switch(do_prompt(ua, "", _("Select daemon type to set debug level"), NULL, 0)) { case 0: /* Director */ debug_level = level; + set_trace(trace_flag); break; case 1: store = get_storage_resource(ua, 0); if (store) { - do_storage_setdebug(ua, store, level); + do_storage_setdebug(ua, store, level, trace_flag); } break; case 2: client = select_client_resource(ua); if (client) { - do_client_setdebug(ua, client, level); + do_client_setdebug(ua, client, level, trace_flag); } break; case 3: - do_all_setdebug(ua, level); + do_all_setdebug(ua, level, trace_flag); break; default: break; @@ -1314,6 +1372,27 @@ static int setdebug_cmd(UAContext *ua, char *cmd) return 1; } +/* + * Turn debug tracing to file on/off + */ +static int trace_cmd(UAContext *ua, char *cmd) +{ + char *onoff; + + if (ua->argc != 2) { + if (!get_cmd(ua, _("Turn on or off? "))) { + return 1; + } + onoff = ua->cmd; + } else { + onoff = ua->argk[1]; + } + + set_trace((strcasecmp(onoff, _("off")) == 0) ? false : true); + return 1; + +} + static int var_cmd(UAContext *ua, char *cmd) { POOLMEM *val = get_pool_memory(PM_FNAME); @@ -1442,13 +1521,25 @@ static int time_cmd(UAContext *ua, char *cmd) return 1; } +/* + * reload the conf file + */ +extern void reload_config(int sig); + +static int reload_cmd(UAContext *ua, char *cmd) +{ + reload_config(1); + return 1; +} + /* * Delete Pool records (should purge Media with it). * * delete pool= - * delete media pool= volume= + * delete volume pool= volume= + * delete job jobid=xxx */ static int delete_cmd(UAContext *ua, char *cmd) { @@ -1456,14 +1547,14 @@ static int delete_cmd(UAContext *ua, char *cmd) N_("volume"), N_("pool"), N_("job"), + N_("jobid"), NULL}; if (!open_db(ua)) { return 1; } - - switch (find_arg_keyword(ua, keywords)) { + switch (find_arg_keyword(ua, keywords)) { case 0: delete_volume(ua); return 1; @@ -1471,7 +1562,12 @@ static int delete_cmd(UAContext *ua, char *cmd) delete_pool(ua); return 1; case 2: - delete_job(ua); + case 3: + int i; + while ((i=find_arg(ua, _("jobid"))) > 0) { + delete_job(ua); + *ua->argk[i] = 0; /* zap keyword already visited */ + } return 1; default: break; @@ -1503,7 +1599,7 @@ static int delete_job(UAContext *ua) POOLMEM *query = get_pool_memory(PM_MESSAGE); JobId_t JobId; - int i = find_arg_with_value(ua, "jobid"); + int i = find_arg_with_value(ua, _("jobid")); if (i >= 0) { JobId = str_to_int64(ua->argv[i]); } else if (!get_pint(ua, _("Enter JobId to delete: "))) { @@ -1669,13 +1765,14 @@ int quit_cmd(UAContext *ua, char *cmd) */ int wait_cmd(UAContext *ua, char *cmd) { + JCR *jcr; bmicrosleep(0, 200000); /* let job actually start */ - for (int running=1; running; ) { - running = 0; + for (bool running=true; running; ) { + running = false; lock_jcr_chain(); - for (JCR *jcr=NULL; (jcr=get_next_jcr(jcr)); ) { + foreach_jcr(jcr) { if (jcr->JobId != 0) { - running = 1; + running = true; free_locked_jcr(jcr); break; } @@ -1755,6 +1852,9 @@ void close_db(UAContext *ua) { if (ua->db) { db_close_database(ua->jcr, ua->db); + ua->db = NULL; + if (ua->jcr) { + ua->jcr->db = NULL; + } } - ua->db = NULL; }