2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Director -- Update command processing
31 * Split from ua_cmds.c March 2005
33 * Kern Sibbald, September MM
41 /* Forward referenced functions */
42 static int update_volume(UAContext *ua);
43 static bool update_pool(UAContext *ua);
44 static bool update_job(UAContext *ua);
45 static bool update_stats(UAContext *ua);
48 * Update a Pool Record in the database.
49 * It is always updated from the Resource record.
51 * update pool=<pool-name>
52 * updates pool from Pool resource
53 * update media pool=<pool-name> volume=<volume-name>
54 * changes pool info for volume
55 * update slots [scan=...]
56 * updates autochanger slots
57 * update stats [days=...]
58 * updates long term statistics
60 int update_cmd(UAContext *ua, const char *cmd)
62 static const char *kw[] = {
64 NT_("volume"), /* 1 */
71 if (!open_client_db(ua)) {
75 switch (find_arg_keyword(ua, kw)) {
96 start_prompt(ua, _("Update choice:\n"));
97 add_prompt(ua, _("Volume parameters"));
98 add_prompt(ua, _("Pool from resource"));
99 add_prompt(ua, _("Slots from autochanger"));
100 add_prompt(ua, _("Long term statistics"));
101 switch (do_prompt(ua, _("item"), _("Choose catalog item to update"), NULL, 0)) {
120 static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr)
122 POOL_MEM query(PM_MESSAGE);
137 for (i=0; kw[i]; i++) {
138 if (strcasecmp(val, kw[i]) == 0) {
144 ua->error_msg(_("Invalid VolStatus specified: %s\n"), val);
147 bstrncpy(mr->VolStatus, kw[i], sizeof(mr->VolStatus));
148 Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%s",
149 mr->VolStatus, edit_int64(mr->MediaId,ed1));
150 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
151 ua->error_msg("%s", db_strerror(ua->db));
153 ua->info_msg(_("New Volume status is: %s\n"), mr->VolStatus);
158 static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr)
160 char ed1[150], ed2[50];
161 POOL_MEM query(PM_MESSAGE);
162 if (!duration_to_utime(val, &mr->VolRetention)) {
163 ua->error_msg(_("Invalid retention period specified: %s\n"), val);
166 Mmsg(query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%s",
167 edit_uint64(mr->VolRetention, ed1), edit_int64(mr->MediaId,ed2));
168 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
169 ua->error_msg("%s", db_strerror(ua->db));
171 ua->info_msg(_("New retention period is: %s\n"),
172 edit_utime(mr->VolRetention, ed1, sizeof(ed1)));
176 static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr)
178 char ed1[150], ed2[50];
179 POOL_MEM query(PM_MESSAGE);
181 if (!duration_to_utime(val, &mr->VolUseDuration)) {
182 ua->error_msg(_("Invalid use duration specified: %s\n"), val);
185 Mmsg(query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%s",
186 edit_uint64(mr->VolUseDuration, ed1), edit_int64(mr->MediaId,ed2));
187 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
188 ua->error_msg("%s", db_strerror(ua->db));
190 ua->info_msg(_("New use duration is: %s\n"),
191 edit_utime(mr->VolUseDuration, ed1, sizeof(ed1)));
195 static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr)
197 POOL_MEM query(PM_MESSAGE);
199 Mmsg(query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%s",
200 val, edit_int64(mr->MediaId,ed1));
201 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
202 ua->error_msg("%s", db_strerror(ua->db));
204 ua->info_msg(_("New max jobs is: %s\n"), val);
208 static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr)
210 POOL_MEM query(PM_MESSAGE);
212 Mmsg(query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%s",
213 val, edit_int64(mr->MediaId, ed1));
214 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
215 ua->error_msg("%s", db_strerror(ua->db));
217 ua->info_msg(_("New max files is: %s\n"), val);
221 static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr)
224 char ed1[50], ed2[50];
225 POOL_MEM query(PM_MESSAGE);
227 if (!size_to_uint64(val, strlen(val), &maxbytes)) {
228 ua->error_msg(_("Invalid max. bytes specification: %s\n"), val);
231 Mmsg(query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%s",
232 edit_uint64(maxbytes, ed1), edit_int64(mr->MediaId, ed2));
233 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
234 ua->error_msg("%s", db_strerror(ua->db));
236 ua->info_msg(_("New Max bytes is: %s\n"), edit_uint64(maxbytes, ed1));
240 static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
245 POOL_MEM query(PM_MESSAGE);
246 if (!is_yesno(val, &recycle)) {
247 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
250 Mmsg(query, "UPDATE Media SET Recycle=%d WHERE MediaId=%s",
251 recycle, edit_int64(mr->MediaId, ed1));
252 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
253 ua->error_msg("%s", db_strerror(ua->db));
255 ua->info_msg(_("New Recycle flag is: %s\n"),
256 recycle==1?_("yes"):_("no"));
260 static void update_volinchanger(UAContext *ua, char *val, MEDIA_DBR *mr)
265 POOL_MEM query(PM_MESSAGE);
266 if (!is_yesno(val, &InChanger)) {
267 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
270 Mmsg(query, "UPDATE Media SET InChanger=%d WHERE MediaId=%s",
271 InChanger, edit_int64(mr->MediaId, ed1));
272 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
273 ua->error_msg("%s", db_strerror(ua->db));
275 ua->info_msg(_("New InChanger flag is: %s\n"),
276 InChanger==1?_("yes"):_("no"));
281 static void update_volslot(UAContext *ua, char *val, MEDIA_DBR *mr)
285 memset(&pr, 0, sizeof(POOL_DBR));
286 pr.PoolId = mr->PoolId;
287 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
288 ua->error_msg("%s", db_strerror(ua->db));
291 mr->Slot = atoi(val);
292 if (pr.MaxVols > 0 && mr->Slot > (int)pr.MaxVols) {
293 ua->error_msg(_("Invalid slot, it must be between 0 and MaxVols=%d\n"),
298 * Make sure to use db_update... rather than doing this directly,
299 * so that any Slot is handled correctly.
301 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
302 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
304 ua->info_msg(_("New Slot is: %d\n"), mr->Slot);
308 /* Modify the Pool in which this Volume is located */
309 void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr)
312 POOL_MEM query(PM_MESSAGE);
313 char ed1[50], ed2[50];
315 memset(&pr, 0, sizeof(pr));
316 bstrncpy(pr.Name, val, sizeof(pr.Name));
317 if (!get_pool_dbr(ua, &pr)) {
320 mr->PoolId = pr.PoolId; /* set new PoolId */
324 Mmsg(query, "UPDATE Media SET PoolId=%s WHERE MediaId=%s",
325 edit_int64(mr->PoolId, ed1), edit_int64(mr->MediaId, ed2));
326 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
327 ua->error_msg("%s", db_strerror(ua->db));
329 ua->info_msg(_("New Pool is: %s\n"), pr.Name);
331 if (!db_update_pool_record(ua->jcr, ua->db, opr)) {
332 ua->error_msg("%s", db_strerror(ua->db));
335 if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
336 ua->error_msg("%s", db_strerror(ua->db));
342 /* Modify the RecyclePool of a Volume */
343 void update_vol_recyclepool(UAContext *ua, char *val, MEDIA_DBR *mr)
346 POOL_MEM query(PM_MESSAGE);
347 char ed1[50], ed2[50], *poolname;
349 if(val && *val) { /* update volume recyclepool="Scratch" */
350 /* If a pool name is given, look up the PoolId */
351 memset(&pr, 0, sizeof(pr));
352 bstrncpy(pr.Name, val, sizeof(pr.Name));
353 if (!get_pool_dbr(ua, &pr, NT_("recyclepool"))) {
356 /* pool = select_pool_resource(ua); */
357 mr->RecyclePoolId = pr.PoolId; /* get the PoolId */
360 } else { /* update volume recyclepool="" */
361 /* If no pool name is given, set the PoolId to 0 (the default) */
362 mr->RecyclePoolId = 0;
363 poolname = _("*None*");
367 Mmsg(query, "UPDATE Media SET RecyclePoolId=%s WHERE MediaId=%s",
368 edit_int64(mr->RecyclePoolId, ed1), edit_int64(mr->MediaId, ed2));
369 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
370 ua->error_msg("%s", db_strerror(ua->db));
372 ua->info_msg(_("New RecyclePool is: %s\n"), poolname);
378 * Refresh the Volume information from the Pool record
380 static void update_vol_from_pool(UAContext *ua, MEDIA_DBR *mr)
384 memset(&pr, 0, sizeof(pr));
385 pr.PoolId = mr->PoolId;
386 if (!db_get_pool_record(ua->jcr, ua->db, &pr) ||
387 !acl_access_ok(ua, Pool_ACL, pr.Name)) {
390 set_pool_dbr_defaults_in_media_dbr(mr, &pr);
391 if (!db_update_media_defaults(ua->jcr, ua->db, mr)) {
392 ua->error_msg(_("Error updating Volume record: ERR=%s"), db_strerror(ua->db));
394 ua->info_msg(_("Volume defaults updated from \"%s\" Pool record.\n"),
400 * Refresh the Volume information from the Pool record
403 static void update_all_vols_from_pool(UAContext *ua, const char *pool_name)
408 memset(&pr, 0, sizeof(pr));
409 memset(&mr, 0, sizeof(mr));
411 bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
412 if (!get_pool_dbr(ua, &pr)) {
415 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
416 mr.PoolId = pr.PoolId;
417 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
418 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
420 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
425 static void update_all_vols(UAContext *ua)
432 memset(&pr, 0, sizeof(pr));
433 memset(&mr, 0, sizeof(mr));
435 if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) {
436 ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db));
440 for (i=0; i<num_pools; i++) {
442 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { /* ***FIXME*** use acl? */
443 ua->warning_msg(_("Updating all pools, but skipped PoolId=%d. ERR=%s\n"), db_strerror(ua->db));
447 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
448 mr.PoolId = pr.PoolId;
450 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
451 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
453 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
461 static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
463 mr->Enabled = get_enabled(ua, val);
464 if (mr->Enabled < 0) {
467 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
468 ua->error_msg(_("Error updating media record Enabled: ERR=%s"),
469 db_strerror(ua->db));
471 ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled);
475 static void update_vol_actiononpurge(UAContext *ua, char *val, MEDIA_DBR *mr)
478 if (strcasecmp(val, "truncate") == 0) {
479 mr->ActionOnPurge = AOP_TRUNCATE;
481 mr->ActionOnPurge = 0;
484 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
485 ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"),
486 db_strerror(ua->db));
488 ua->info_msg(_("New ActionOnPurge is: %d\n"),
489 aop_to_str(mr->ActionOnPurge, ret));
494 * Update a media record -- allows you to change the
495 * Volume status. E.g. if you want Bacula to stop
496 * writing on the volume, set it to anything other
499 static int update_volume(UAContext *ua)
511 NT_("VolStatus"), /* 0 */
512 NT_("VolRetention"), /* 1 */
513 NT_("VolUse"), /* 2 */
514 NT_("MaxVolJobs"), /* 3 */
515 NT_("MaxVolFiles"), /* 4 */
516 NT_("MaxVolBytes"), /* 5 */
517 NT_("Recycle"), /* 6 */
518 NT_("InChanger"), /* 7 */
521 NT_("FromPool"), /* 10 */
522 NT_("AllFromPool"), /* 11 !!! see below !!! */
523 NT_("Enabled"), /* 12 */
524 NT_("RecyclePool"), /* 13 */
525 NT_("ActionOnPurge"), /* 14 */
528 #define AllFromPool 11 /* keep this updated with above */
530 for (i=0; kw[i]; i++) {
534 if ((j=find_arg_with_value(ua, kw[i])) > 0) {
535 /* If all from pool don't select a media record */
536 if (i != AllFromPool && !select_media_dbr(ua, &mr)) {
541 update_volstatus(ua, ua->argv[j], &mr);
544 update_volretention(ua, ua->argv[j], &mr);
547 update_voluseduration(ua, ua->argv[j], &mr);
550 update_volmaxjobs(ua, ua->argv[j], &mr);
553 update_volmaxfiles(ua, ua->argv[j], &mr);
556 update_volmaxbytes(ua, ua->argv[j], &mr);
559 update_volrecycle(ua, ua->argv[j], &mr);
562 update_volinchanger(ua, ua->argv[j], &mr);
565 update_volslot(ua, ua->argv[j], &mr);
568 memset(&pr, 0, sizeof(POOL_DBR));
569 pr.PoolId = mr.PoolId;
570 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
571 ua->error_msg("%s", db_strerror(ua->db));
574 update_vol_pool(ua, ua->argv[j], &mr, &pr);
577 update_vol_from_pool(ua, &mr);
580 update_all_vols_from_pool(ua, ua->argv[j]);
583 update_volenabled(ua, ua->argv[j], &mr);
586 update_vol_recyclepool(ua, ua->argv[j], &mr);
589 update_vol_actiononpurge(ua, ua->argv[j], &mr);
596 /* Allow user to simply update all volumes */
597 if (find_arg(ua, NT_("fromallpools")) > 0) {
603 start_prompt(ua, _("Parameters to modify:\n"));
604 add_prompt(ua, _("Volume Status")); /* 0 */
605 add_prompt(ua, _("Volume Retention Period")); /* 1 */
606 add_prompt(ua, _("Volume Use Duration")); /* 2 */
607 add_prompt(ua, _("Maximum Volume Jobs")); /* 3 */
608 add_prompt(ua, _("Maximum Volume Files")); /* 4 */
609 add_prompt(ua, _("Maximum Volume Bytes")); /* 5 */
610 add_prompt(ua, _("Recycle Flag")); /* 6 */
611 add_prompt(ua, _("Slot")); /* 7 */
612 add_prompt(ua, _("InChanger Flag")); /* 8 */
613 add_prompt(ua, _("Volume Files")); /* 9 */
614 add_prompt(ua, _("Pool")); /* 10 */
615 add_prompt(ua, _("Volume from Pool")); /* 11 */
616 add_prompt(ua, _("All Volumes from Pool")); /* 12 */
617 add_prompt(ua, _("All Volumes from all Pools")); /* 13 */
618 add_prompt(ua, _("Enabled")), /* 14 */
619 add_prompt(ua, _("RecyclePool")), /* 15 */
620 add_prompt(ua, _("Action On Purge")), /* 16 */
621 add_prompt(ua, _("Done")); /* 17 */
622 i = do_prompt(ua, "", _("Select parameter to modify"), NULL, 0);
624 /* For All Volumes, All Volumes from Pool, and Done, we don't need
626 if ( i != 12 && i != 13 && i != 17) {
627 if (!select_media_dbr(ua, &mr)) { /* Get Volume record */
630 ua->info_msg(_("Updating Volume \"%s\"\n"), mr.VolumeName);
633 case 0: /* Volume Status */
634 /* Modify Volume Status */
635 ua->info_msg(_("Current Volume status is: %s\n"), mr.VolStatus);
636 start_prompt(ua, _("Possible Values are:\n"));
637 add_prompt(ua, NT_("Append"));
638 add_prompt(ua, NT_("Archive"));
639 add_prompt(ua, NT_("Disabled"));
640 add_prompt(ua, NT_("Full"));
641 add_prompt(ua, NT_("Used"));
642 add_prompt(ua, NT_("Cleaning"));
643 if (strcmp(mr.VolStatus, NT_("Purged")) == 0) {
644 add_prompt(ua, NT_("Recycle"));
646 add_prompt(ua, NT_("Read-Only"));
647 if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
650 update_volstatus(ua, ua->cmd, &mr);
652 case 1: /* Retention */
653 ua->info_msg(_("Current retention period is: %s\n"),
654 edit_utime(mr.VolRetention, ed1, sizeof(ed1)));
655 if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
658 update_volretention(ua, ua->cmd, &mr);
661 case 2: /* Use Duration */
662 ua->info_msg(_("Current use duration is: %s\n"),
663 edit_utime(mr.VolUseDuration, ed1, sizeof(ed1)));
664 if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
667 update_voluseduration(ua, ua->cmd, &mr);
670 case 3: /* Max Jobs */
671 ua->info_msg(_("Current max jobs is: %u\n"), mr.MaxVolJobs);
672 if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
675 update_volmaxjobs(ua, ua->cmd, &mr);
678 case 4: /* Max Files */
679 ua->info_msg(_("Current max files is: %u\n"), mr.MaxVolFiles);
680 if (!get_pint(ua, _("Enter new Maximum Files: "))) {
683 update_volmaxfiles(ua, ua->cmd, &mr);
686 case 5: /* Max Bytes */
687 ua->info_msg(_("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
688 if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
691 update_volmaxbytes(ua, ua->cmd, &mr);
695 case 6: /* Recycle */
696 ua->info_msg(_("Current recycle flag is: %s\n"),
697 mr.Recycle==1?_("yes"):_("no"));
698 if (!get_yesno(ua, _("Enter new Recycle status: "))) {
701 update_volrecycle(ua, ua->cmd, &mr);
705 ua->info_msg(_("Current Slot is: %d\n"), mr.Slot);
706 if (!get_pint(ua, _("Enter new Slot: "))) {
709 update_volslot(ua, ua->cmd, &mr);
712 case 8: /* InChanger */
713 ua->info_msg(_("Current InChanger flag is: %d\n"), mr.InChanger);
714 bsnprintf(buf, sizeof(buf), _("Set InChanger flag for Volume \"%s\": yes/no: "),
716 if (!get_yesno(ua, buf)) {
719 mr.InChanger = ua->pint32_val;
721 * Make sure to use db_update... rather than doing this directly,
722 * so that any Slot is handled correctly.
724 if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
725 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
727 ua->info_msg(_("New InChanger flag is: %d\n"), mr.InChanger);
732 case 9: /* Volume Files */
734 ua->warning_msg(_("Warning changing Volume Files can result\n"
735 "in loss of data on your Volume\n\n"));
736 ua->info_msg(_("Current Volume Files is: %u\n"), mr.VolFiles);
737 if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
740 VolFiles = ua->pint32_val;
741 if (VolFiles != (int)(mr.VolFiles + 1)) {
742 ua->warning_msg(_("Normally, you should only increase Volume Files by one!\n"));
743 if (!get_yesno(ua, _("Increase Volume Files? (yes/no): ")) || ua->pint32_val == 0) {
747 query = get_pool_memory(PM_MESSAGE);
748 Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%s",
749 VolFiles, edit_int64(mr.MediaId, ed1));
750 if (!db_sql_query(ua->db, query, NULL, NULL)) {
751 ua->error_msg("%s", db_strerror(ua->db));
753 ua->info_msg(_("New Volume Files is: %u\n"), VolFiles);
755 free_pool_memory(query);
758 case 10: /* Volume's Pool */
759 memset(&pr, 0, sizeof(POOL_DBR));
760 pr.PoolId = mr.PoolId;
761 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
762 ua->error_msg("%s", db_strerror(ua->db));
765 ua->info_msg(_("Current Pool is: %s\n"), pr.Name);
766 if (!get_cmd(ua, _("Enter new Pool name: "))) {
769 update_vol_pool(ua, ua->cmd, &mr, &pr);
773 update_vol_from_pool(ua, &mr);
776 pool = select_pool_resource(ua);
778 update_all_vols_from_pool(ua, pool->name());
787 ua->info_msg(_("Current Enabled is: %d\n"), mr.Enabled);
788 if (!get_cmd(ua, _("Enter new Enabled: "))) {
791 if (strcasecmp(ua->cmd, "yes") == 0 || strcasecmp(ua->cmd, "true") == 0) {
793 } else if (strcasecmp(ua->cmd, "no") == 0 || strcasecmp(ua->cmd, "false") == 0) {
795 } else if (strcasecmp(ua->cmd, "archived") == 0) {
798 mr.Enabled = atoi(ua->cmd);
800 update_volenabled(ua, ua->cmd, &mr);
804 memset(&pr, 0, sizeof(POOL_DBR));
805 pr.PoolId = mr.RecyclePoolId;
806 if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
807 ua->info_msg(_("Current RecyclePool is: %s\n"), pr.Name);
809 ua->info_msg(_("No current RecyclePool\n"));
811 if (!select_pool_dbr(ua, &pr, NT_("recyclepool"))) {
814 update_vol_recyclepool(ua, pr.Name, &mr);
819 ua->info_msg(_("Current ActionOnPurge is: %s\n"),
820 aop_to_str(mr.ActionOnPurge, ret));
821 if (!get_cmd(ua, _("Enter new ActionOnPurge: (one of: Truncate, None) "))) {
825 update_vol_actiononpurge(ua, ua->cmd, &mr);
828 default: /* Done or error */
829 ua->info_msg(_("Selection terminated.\n"));
837 * Update long term statistics
839 static bool update_stats(UAContext *ua)
841 int i = find_arg_with_value(ua, NT_("days"));
845 since = atoi(ua->argv[i]) * 24*60*60;
848 int nb = db_update_stats(ua->jcr, ua->db, since);
849 ua->info_msg(_("Updating %i job(s).\n"), nb);
855 * Update pool record -- pull info from current POOL resource
857 static bool update_pool(UAContext *ua)
865 pool = get_pool_resource(ua);
870 memset(&pr, 0, sizeof(pr));
871 bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
872 if (!get_pool_dbr(ua, &pr)) {
876 set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */
877 set_pooldbr_references(ua->jcr, ua->db, &pr, pool);
879 id = db_update_pool_record(ua->jcr, ua->db, &pr);
881 ua->error_msg(_("db_update_pool_record returned %d. ERR=%s\n"),
882 id, db_strerror(ua->db));
884 query = get_pool_memory(PM_MESSAGE);
885 Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1));
886 db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
887 free_pool_memory(query);
888 ua->info_msg(_("Pool DB record updated from resource.\n"));
893 * Update a Job record -- allows you to change the
894 * date fields in a Job record. This helps when
895 * providing migration from other vendors.
897 static bool update_job(UAContext *ua)
900 char ed1[50], ed2[50];
901 POOL_MEM cmd(PM_MESSAGE);
905 char *client_name = NULL;
906 char *start_time = NULL;
908 NT_("starttime"), /* 0 */
909 NT_("client"), /* 1 */
912 Dmsg1(200, "cmd=%s\n", ua->cmd);
913 i = find_arg_with_value(ua, NT_("jobid"));
915 ua->error_msg(_("Expect JobId keyword, not found.\n"));
918 memset(&jr, 0, sizeof(jr));
919 memset(&cr, 0, sizeof(cr));
920 jr.JobId = str_to_int64(ua->argv[i]);
921 if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
922 ua->error_msg("%s", db_strerror(ua->db));
926 for (i=0; kw[i]; i++) {
928 if ((j=find_arg_with_value(ua, kw[i])) >= 0) {
930 case 0: /* start time */
931 start_time = ua->argv[j];
933 case 1: /* Client name */
934 client_name = ua->argv[j];
939 if (!client_name && !start_time) {
940 ua->error_msg(_("Neither Client nor StartTime specified.\n"));
944 if (!get_client_dbr(ua, &cr)) {
947 jr.ClientId = cr.ClientId;
952 StartTime = str_to_utime(start_time);
953 if (StartTime == 0) {
954 ua->error_msg(_("Improper date format: %s\n"), ua->argv[i]);
957 delta_start = StartTime - jr.StartTime;
958 Dmsg3(200, "ST=%lld jr.ST=%lld delta=%lld\n", StartTime,
959 (utime_t)jr.StartTime, delta_start);
960 jr.StartTime = (time_t)StartTime;
961 jr.SchedTime += (time_t)delta_start;
962 jr.EndTime += (time_t)delta_start;
963 jr.JobTDate += delta_start;
964 /* Convert to DB times */
965 bstrutime(jr.cStartTime, sizeof(jr.cStartTime), jr.StartTime);
966 bstrutime(jr.cSchedTime, sizeof(jr.cSchedTime), jr.SchedTime);
967 bstrutime(jr.cEndTime, sizeof(jr.cEndTime), jr.EndTime);
969 Mmsg(cmd, "UPDATE Job SET ClientId=%s,StartTime='%s',SchedTime='%s',"
970 "EndTime='%s',JobTDate=%s WHERE JobId=%s",
971 edit_int64(jr.ClientId, ed1),
975 edit_uint64(jr.JobTDate, ed1),
976 edit_int64(jr.JobId, ed2));
977 if (!db_sql_query(ua->db, cmd.c_str(), NULL, NULL)) {
978 ua->error_msg("%s", db_strerror(ua->db));