X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Fua_cmds.c;h=063127981d3599e7861495c3d78c909d63e3a233;hb=b9ac1b6c82fd69ecf139edce98585a889906db8b;hp=678e569d2b195e6703555cee25bbb6e0b9de4455;hpb=f839473bf1146fde5cf0a058e8c5baec879e301a;p=bacula%2Fbacula diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 678e569d2b..063127981d 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 @@ -80,6 +80,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); @@ -95,23 +96,24 @@ static struct cmdstruct commands[] = { { N_("estimate"), estimate_cmd, _("performs FileSet estimate, listing gives full listing")}, { N_("exit"), quit_cmd, _("exit = quit")}, { N_("help"), help_cmd, _("print this command")}, + { N_("list"), list_cmd, _("list [pools | jobs | jobtotals | media | files jobid=]; from catalog")}, { N_("label"), label_cmd, _("label a tape")}, - { N_("list"), list_cmd, _("list [pools | jobs | jobtotals | media | files job=]; from catalog")}, { N_("llist"), llist_cmd, _("full or long list like list command")}, { N_("messages"), messagescmd, _("messages")}, { N_("mount"), mount_cmd, _("mount ")}, { N_("prune"), prunecmd, _("prune expired records from catalog")}, { N_("purge"), purgecmd, _("purge records from catalog")}, - { N_("query"), querycmd, _("query catalog")}, { N_("quit"), quit_cmd, _("quit")}, + { N_("query"), querycmd, _("query catalog")}, + { N_("restore"), restore_cmd, _("restore files")}, { N_("relabel"), relabel_cmd, _("relabel a tape")}, { N_("release"), release_cmd, _("release ")}, - { N_("restore"), restore_cmd, _("restore files")}, { 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_("status"), status_cmd, _("status [storage | client]=")}, { N_("time"), time_cmd, _("print current time")}, { N_("unmount"), unmount_cmd, _("unmount ")}, { N_("update"), update_cmd, _("update Volume or Pool")}, @@ -129,12 +131,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 +143,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 +186,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 +289,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 +350,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 +361,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 +388,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 +404,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 +422,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 +530,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 +546,34 @@ 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; + } + client = (CLIENT *)GetResWithName(R_CLIENT, ua->cons->hdr.name); + + if (!client) { + bsendmsg(ua, _("Client \"%s\" not found.\n"), ua->cons->hdr.name); + return 1; + } + LockRes(); + 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); + UnlockRes(); + return 1; +} /* @@ -794,7 +776,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); @@ -804,20 +786,22 @@ static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr) 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; } - query = get_pool_memory(PM_MESSAGE); - Mmsg(&query, "UPDATE Media SET PoolId=%u WHERE MediaId=%u", pr.PoolId, mr->MediaId); - if (!db_sql_query(ua->db, query, NULL, NULL)) { - bsendmsg(ua, "%s", db_strerror(ua->db)); - } else { + mr->PoolId = pr.PoolId; /* set new PoolId */ + /* + * 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 Pool: ERR=%s"), db_strerror(ua->db)); + } else { bsendmsg(ua, _("New Pool is: %s\n"), pr.Name); } - free_pool_memory(query); } /* @@ -893,6 +877,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 +954,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 +966,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: %s\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 +1028,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 +1041,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; @@ -1245,7 +1250,8 @@ static int setdebug_cmd(UAContext *ua, char *cmd) debug_level = level; return 1; } - if (strcasecmp(ua->argk[i], _("client")) == 0) { + if (strcasecmp(ua->argk[i], _("client")) == 0 || + strcasecmp(ua->argk[i], _("fd")) == 0) { client = NULL; if (ua->argv[i]) { client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); @@ -1262,7 +1268,8 @@ static int setdebug_cmd(UAContext *ua, char *cmd) } if (strcasecmp(ua->argk[i], _("store")) == 0 || - strcasecmp(ua->argk[i], _("storage")) == 0) { + strcasecmp(ua->argk[i], _("storage")) == 0 || + strcasecmp(ua->argk[i], _("sd")) == 0) { store = NULL; if (ua->argv[i]) { store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]); @@ -1343,7 +1350,8 @@ static int estimate_cmd(UAContext *ua, char *cmd) char since[MAXSTRING]; for (int i=1; iargc; i++) { - if (strcasecmp(ua->argk[i], _("client")) == 0) { + if (strcasecmp(ua->argk[i], _("client")) == 0 || + strcasecmp(ua->argk[i], _("fd")) == 0) { if (ua->argv[i]) { client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]); continue; @@ -1666,13 +1674,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; } @@ -1691,12 +1700,11 @@ static int help_cmd(UAContext *ua, char *cmd) { unsigned int i; -/* usage(); */ bsendmsg(ua, _(" Command Description\n ======= ===========\n")); for (i=0; idb) { db_close_database(ua->jcr, ua->db); + ua->db = NULL; + if (ua->jcr) { + ua->jcr->db = NULL; + } } - ua->db = NULL; }