]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_update.c
kes Add back code to open tape device nonblocking, but if rewind fails
[bacula/bacula] / bacula / src / dird / ua_update.c
1 /*
2  *
3  *   Bacula Director -- Update command processing
4  *     Split from ua_cmds.c March 2005
5  *
6  *     Kern Sibbald, September MM
7  *
8  *   Version $Id$
9  */
10 /*
11    Copyright (C) 2000-2006 Kern Sibbald
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License
15    version 2 as amended with additional clauses defined in the
16    file LICENSE in the main source directory.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
21    the file LICENSE for additional details.
22
23  */
24
25 #include "bacula.h"
26 #include "dird.h"
27
28 /* Forward referenced functions */
29 static int update_volume(UAContext *ua);
30 static bool update_pool(UAContext *ua);
31
32 /*
33  * Update a Pool Record in the database.
34  *  It is always updated from the Resource record.
35  *
36  *    update pool=<pool-name>
37  *         updates pool from Pool resource
38  *    update media pool=<pool-name> volume=<volume-name>
39  *         changes pool info for volume
40  *    update slots [scan=...]
41  *         updates autochanger slots
42  */
43 int update_cmd(UAContext *ua, const char *cmd)
44 {
45    static const char *kw[] = {
46       NT_("media"),  /* 0 */
47       NT_("volume"), /* 1 */
48       NT_("pool"),   /* 2 */
49       NT_("slots"),  /* 3 */
50       NULL};
51
52    if (!open_db(ua)) {
53       return 1;
54    }
55
56    switch (find_arg_keyword(ua, kw)) {
57    case 0:
58    case 1:
59       update_volume(ua);
60       return 1;
61    case 2:
62       update_pool(ua);
63       return 1;
64    case 3:
65       update_slots(ua);
66       return 1;
67    default:
68       break;
69    }
70
71    start_prompt(ua, _("Update choice:\n"));
72    add_prompt(ua, _("Volume parameters"));
73    add_prompt(ua, _("Pool from resource"));
74    add_prompt(ua, _("Slots from autochanger"));
75    switch (do_prompt(ua, _("item"), _("Choose catalog item to update"), NULL, 0)) {
76    case 0:
77       update_volume(ua);
78       break;
79    case 1:
80       update_pool(ua);
81       break;
82    case 2:
83       update_slots(ua);
84       break;
85    default:
86       break;
87    }
88    return 1;
89 }
90
91 static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr)
92 {
93    POOL_MEM query(PM_MESSAGE);
94    const char *kw[] = {
95       NT_("Append"),
96       NT_("Archive"),
97       NT_("Disabled"),
98       NT_("Full"),
99       NT_("Used"),
100       NT_("Cleaning"),
101       NT_("Recycle"),
102       NT_("Read-Only"),
103       NULL};
104    bool found = false;
105    int i;
106
107    for (i=0; kw[i]; i++) {
108       if (strcasecmp(val, kw[i]) == 0) {
109          found = true;
110          break;
111       }
112    }
113    if (!found) {
114       bsendmsg(ua, _("Invalid VolStatus specified: %s\n"), val);
115    } else {
116       char ed1[50];
117       bstrncpy(mr->VolStatus, kw[i], sizeof(mr->VolStatus));
118       Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%s",
119          mr->VolStatus, edit_int64(mr->MediaId,ed1));
120       if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
121          bsendmsg(ua, "%s", db_strerror(ua->db));
122       } else {
123          bsendmsg(ua, _("New Volume status is: %s\n"), mr->VolStatus);
124       }
125    }
126 }
127
128 static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr)
129 {
130    char ed1[150], ed2[50];
131    POOL_MEM query(PM_MESSAGE);
132    if (!duration_to_utime(val, &mr->VolRetention)) {
133       bsendmsg(ua, _("Invalid retention period specified: %s\n"), val);
134       return;
135    }
136    Mmsg(query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%s",
137       edit_uint64(mr->VolRetention, ed1), edit_int64(mr->MediaId,ed2));
138    if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
139       bsendmsg(ua, "%s", db_strerror(ua->db));
140    } else {
141       bsendmsg(ua, _("New retention period is: %s\n"),
142          edit_utime(mr->VolRetention, ed1, sizeof(ed1)));
143    }
144 }
145
146 static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr)
147 {
148    char ed1[150], ed2[50];
149    POOL_MEM query(PM_MESSAGE);
150
151    if (!duration_to_utime(val, &mr->VolUseDuration)) {
152       bsendmsg(ua, _("Invalid use duration specified: %s\n"), val);
153       return;
154    }
155    Mmsg(query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%s",
156       edit_uint64(mr->VolUseDuration, ed1), edit_int64(mr->MediaId,ed2));
157    if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
158       bsendmsg(ua, "%s", db_strerror(ua->db));
159    } else {
160       bsendmsg(ua, _("New use duration is: %s\n"),
161          edit_utime(mr->VolUseDuration, ed1, sizeof(ed1)));
162    }
163 }
164
165 static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr)
166 {
167    POOL_MEM query(PM_MESSAGE);
168    char ed1[50];
169    Mmsg(query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%s",
170       val, edit_int64(mr->MediaId,ed1));
171    if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
172       bsendmsg(ua, "%s", db_strerror(ua->db));
173    } else {
174       bsendmsg(ua, _("New max jobs is: %s\n"), val);
175    }
176 }
177
178 static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr)
179 {
180    POOL_MEM query(PM_MESSAGE);
181    char ed1[50];
182    Mmsg(query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%s",
183       val, edit_int64(mr->MediaId, ed1));
184    if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
185       bsendmsg(ua, "%s", db_strerror(ua->db));
186    } else {
187       bsendmsg(ua, _("New max files is: %s\n"), val);
188    }
189 }
190
191 static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr)
192 {
193    uint64_t maxbytes;
194    char ed1[50], ed2[50];
195    POOL_MEM query(PM_MESSAGE);
196
197    if (!size_to_uint64(val, strlen(val), &maxbytes)) {
198       bsendmsg(ua, _("Invalid max. bytes specification: %s\n"), val);
199       return;
200    }
201    Mmsg(query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%s",
202       edit_uint64(maxbytes, ed1), edit_int64(mr->MediaId, ed2));
203    if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
204       bsendmsg(ua, "%s", db_strerror(ua->db));
205    } else {
206       bsendmsg(ua, _("New Max bytes is: %s\n"), edit_uint64(maxbytes, ed1));
207    }
208 }
209
210 static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
211 {
212    int recycle;
213    char ed1[50];
214
215    POOL_MEM query(PM_MESSAGE);
216    if (!is_yesno(val, &recycle)) {
217       bsendmsg(ua, _("Invalid value. It must be yes or no.\n"));
218       return;
219    }
220    Mmsg(query, "UPDATE Media SET Recycle=%d WHERE MediaId=%s",
221       recycle, edit_int64(mr->MediaId, ed1));
222    if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
223       bsendmsg(ua, "%s", db_strerror(ua->db));
224    } else {
225       bsendmsg(ua, _("New Recycle flag is: %s\n"),
226          mr->Recycle==1?_("yes"):_("no"));
227    }
228 }
229
230 static void update_volinchanger(UAContext *ua, char *val, MEDIA_DBR *mr)
231 {
232    int InChanger;
233    char ed1[50];
234
235    POOL_MEM query(PM_MESSAGE);
236    if (!is_yesno(val, &InChanger)) {
237       bsendmsg(ua, _("Invalid value. It must be yes or no.\n"));
238       return;
239    }
240    Mmsg(query, "UPDATE Media SET InChanger=%d WHERE MediaId=%s",
241       InChanger, edit_int64(mr->MediaId, ed1));
242    if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
243       bsendmsg(ua, "%s", db_strerror(ua->db));
244    } else {
245       bsendmsg(ua, _("New InChanger flag is: %s\n"),
246          mr->InChanger==1?_("yes"):_("no"));
247    }
248 }
249
250
251 static void update_volslot(UAContext *ua, char *val, MEDIA_DBR *mr)
252 {
253    POOL_DBR pr;
254
255    memset(&pr, 0, sizeof(POOL_DBR));
256    pr.PoolId = mr->PoolId;
257    if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
258       bsendmsg(ua, "%s", db_strerror(ua->db));
259       return;
260    }
261    mr->Slot = atoi(val);
262    if (pr.MaxVols > 0 && mr->Slot > (int)pr.MaxVols) {
263       bsendmsg(ua, _("Invalid slot, it must be between 0 and MaxVols=%d\n"),
264          pr.MaxVols);
265       return;
266    }
267    /*
268     * Make sure to use db_update... rather than doing this directly,
269     *   so that any Slot is handled correctly.
270     */
271    if (!db_update_media_record(ua->jcr, ua->db, mr)) {
272       bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
273    } else {
274       bsendmsg(ua, _("New Slot is: %d\n"), mr->Slot);
275    }
276 }
277
278 /* Modify the Pool in which this Volume is located */
279 static void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr)
280 {
281    POOL_DBR pr;
282    POOLMEM *query;
283    char ed1[50], ed2[50];
284
285    memset(&pr, 0, sizeof(pr));
286    bstrncpy(pr.Name, val, sizeof(pr.Name));
287    if (!get_pool_dbr(ua, &pr)) {
288       return;
289    }
290    mr->PoolId = pr.PoolId;            /* set new PoolId */
291    /*
292     */
293    query = get_pool_memory(PM_MESSAGE);
294    db_lock(ua->db);
295    Mmsg(query, "UPDATE Media SET PoolId=%s WHERE MediaId=%s",
296       edit_int64(mr->PoolId, ed1),
297       edit_int64(mr->MediaId, ed2));
298    if (!db_sql_query(ua->db, query, NULL, NULL)) {
299       bsendmsg(ua, "%s", db_strerror(ua->db));
300    } else {
301       bsendmsg(ua, _("New Pool is: %s\n"), pr.Name);
302       opr->NumVols--;
303       if (!db_update_pool_record(ua->jcr, ua->db, opr)) {
304          bsendmsg(ua, "%s", db_strerror(ua->db));
305       }
306       pr.NumVols++;
307       if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
308          bsendmsg(ua, "%s", db_strerror(ua->db));
309       }
310    }
311    db_unlock(ua->db);
312    free_pool_memory(query);
313 }
314
315 /*
316  * Refresh the Volume information from the Pool record
317  */
318 static void update_vol_from_pool(UAContext *ua, MEDIA_DBR *mr)
319 {
320    POOL_DBR pr;
321
322    memset(&pr, 0, sizeof(pr));
323    pr.PoolId = mr->PoolId;
324    if (!db_get_pool_record(ua->jcr, ua->db, &pr) ||
325        !acl_access_ok(ua, Pool_ACL, pr.Name)) {
326       return;
327    }
328    set_pool_dbr_defaults_in_media_dbr(mr, &pr);
329    if (!db_update_media_defaults(ua->jcr, ua->db, mr)) {
330       bsendmsg(ua, _("Error updating Volume record: ERR=%s"), db_strerror(ua->db));
331    } else {
332       bsendmsg(ua, _("Volume defaults updated from \"%s\" Pool record.\n"),
333          pr.Name);
334    }
335 }
336
337 /*
338  * Refresh the Volume information from the Pool record
339  *   for all Volumes
340  */
341 static void update_all_vols_from_pool(UAContext *ua)
342 {
343    POOL_DBR pr;
344    MEDIA_DBR mr;
345
346    memset(&pr, 0, sizeof(pr));
347    memset(&mr, 0, sizeof(mr));
348    if (!get_pool_dbr(ua, &pr)) {
349       return;
350    }
351    set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
352    mr.PoolId = pr.PoolId;
353    if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
354       bsendmsg(ua, _("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
355    } else {
356       bsendmsg(ua, _("All Volume defaults updated from Pool record.\n"));
357    }
358 }
359
360 static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
361 {
362    mr->Enabled = get_enabled(ua, val);
363    if (mr->Enabled < 0) {
364       return;
365    }
366    if (!db_update_media_record(ua->jcr, ua->db, mr)) {
367       bsendmsg(ua, _("Error updating media record Enabled: ERR=%s"), db_strerror(ua->db));
368    } else {
369       bsendmsg(ua, _("New Enabled is: %d\n"), mr->Enabled);
370    }
371 }
372
373
374
375 /*
376  * Update a media record -- allows you to change the
377  *  Volume status. E.g. if you want Bacula to stop
378  *  writing on the volume, set it to anything other
379  *  than Append.
380  */
381 static int update_volume(UAContext *ua)
382 {
383    MEDIA_DBR mr;
384    POOL_DBR pr;
385    POOLMEM *query;
386    char ed1[130];
387    bool done = false;
388    int i;
389    const char *kw[] = {
390       _("VolStatus"),                /* 0 */
391       _("VolRetention"),             /* 1 */
392       _("VolUse"),                   /* 2 */
393       _("MaxVolJobs"),               /* 3 */
394       _("MaxVolFiles"),              /* 4 */
395       _("MaxVolBytes"),              /* 5 */
396       _("Recycle"),                  /* 6 */
397       _("InChanger"),                /* 7 */
398       _("Slot"),                     /* 8 */
399       _("Pool"),                     /* 9 */
400       _("FromPool"),                 /* 10 */
401       _("AllFromPool"),              /* 11 !!! see below !!! */
402       _("Enabled"),                  /* 12 */
403       NULL };
404
405 #define AllFromPool 11               /* keep this updated with above */
406
407    for (i=0; kw[i]; i++) {
408       int j;
409       POOL_DBR pr;
410       if ((j=find_arg_with_value(ua, kw[i])) > 0) {
411          /* If all from pool don't select a media record */
412          if (i != AllFromPool && !select_media_dbr(ua, &mr)) {
413             return 0;
414          }
415          switch (i) {
416          case 0:
417             update_volstatus(ua, ua->argv[j], &mr);
418             break;
419          case 1:
420             update_volretention(ua, ua->argv[j], &mr);
421             break;
422          case 2:
423             update_voluseduration(ua, ua->argv[j], &mr);
424             break;
425          case 3:
426             update_volmaxjobs(ua, ua->argv[j], &mr);
427             break;
428          case 4:
429             update_volmaxfiles(ua, ua->argv[j], &mr);
430             break;
431          case 5:
432             update_volmaxbytes(ua, ua->argv[j], &mr);
433             break;
434          case 6:
435             update_volrecycle(ua, ua->argv[j], &mr);
436             break;
437          case 7:
438             update_volinchanger(ua, ua->argv[j], &mr);
439             break;
440          case 8:
441             update_volslot(ua, ua->argv[j], &mr);
442             break;
443          case 9:
444             memset(&pr, 0, sizeof(POOL_DBR));
445             pr.PoolId = mr.PoolId;
446             if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
447                bsendmsg(ua, "%s", db_strerror(ua->db));
448                break;
449             }
450             update_vol_pool(ua, ua->argv[j], &mr, &pr);
451             break;
452          case 10:
453             update_vol_from_pool(ua, &mr);
454             return 1;
455          case 11:
456             update_all_vols_from_pool(ua);
457             return 1;
458          case 12:
459             update_volenabled(ua, ua->argv[j], &mr);
460             break;
461          }
462          done = true;
463       }
464    }
465
466    for ( ; !done; ) {
467       start_prompt(ua, _("Parameters to modify:\n"));
468       add_prompt(ua, _("Volume Status"));              /* 0 */
469       add_prompt(ua, _("Volume Retention Period"));    /* 1 */
470       add_prompt(ua, _("Volume Use Duration"));        /* 2 */
471       add_prompt(ua, _("Maximum Volume Jobs"));        /* 3 */
472       add_prompt(ua, _("Maximum Volume Files"));       /* 4 */
473       add_prompt(ua, _("Maximum Volume Bytes"));       /* 5 */
474       add_prompt(ua, _("Recycle Flag"));               /* 6 */
475       add_prompt(ua, _("Slot"));                       /* 7 */
476       add_prompt(ua, _("InChanger Flag"));             /* 8 */
477       add_prompt(ua, _("Volume Files"));               /* 9 */
478       add_prompt(ua, _("Pool"));                       /* 10 */
479       add_prompt(ua, _("Volume from Pool"));           /* 11 */
480       add_prompt(ua, _("All Volumes from Pool"));      /* 12 */
481       add_prompt(ua, _("Enabled")),                    /* 13 */
482       add_prompt(ua, _("Done"));                       /* 14 */
483       i = do_prompt(ua, "", _("Select parameter to modify"), NULL, 0);  
484
485       /* For All Volumes from Pool and Done, we don't need a Volume record */
486       if (i != 12 && i != 14) {
487          if (!select_media_dbr(ua, &mr)) {  /* Get Volume record */
488             return 0;
489          }
490          bsendmsg(ua, _("Updating Volume \"%s\"\n"), mr.VolumeName);
491       }
492       switch (i) {
493       case 0:                         /* Volume Status */
494          /* Modify Volume Status */
495          bsendmsg(ua, _("Current Volume status is: %s\n"), mr.VolStatus);
496          start_prompt(ua, _("Possible Values are:\n"));
497          add_prompt(ua, NT_("Append")); 
498          add_prompt(ua, NT_("Archive"));
499          add_prompt(ua, NT_("Disabled"));
500          add_prompt(ua, NT_("Full"));
501          add_prompt(ua, NT_("Used"));
502          add_prompt(ua, NT_("Cleaning"));
503          if (strcmp(mr.VolStatus, NT_("Purged")) == 0) {
504             add_prompt(ua, NT_("Recycle"));
505          }
506          add_prompt(ua, NT_("Read-Only"));
507          if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
508             return 1;
509          }
510          update_volstatus(ua, ua->cmd, &mr);
511          break;
512       case 1:                         /* Retention */
513          bsendmsg(ua, _("Current retention period is: %s\n"),
514             edit_utime(mr.VolRetention, ed1, sizeof(ed1)));
515          if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
516             return 0;
517          }
518          update_volretention(ua, ua->cmd, &mr);
519          break;
520
521       case 2:                         /* Use Duration */
522          bsendmsg(ua, _("Current use duration is: %s\n"),
523             edit_utime(mr.VolUseDuration, ed1, sizeof(ed1)));
524          if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
525             return 0;
526          }
527          update_voluseduration(ua, ua->cmd, &mr);
528          break;
529
530       case 3:                         /* Max Jobs */
531          bsendmsg(ua, _("Current max jobs is: %u\n"), mr.MaxVolJobs);
532          if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
533             return 0;
534          }
535          update_volmaxjobs(ua, ua->cmd, &mr);
536          break;
537
538       case 4:                         /* Max Files */
539          bsendmsg(ua, _("Current max files is: %u\n"), mr.MaxVolFiles);
540          if (!get_pint(ua, _("Enter new Maximum Files: "))) {
541             return 0;
542          }
543          update_volmaxfiles(ua, ua->cmd, &mr);
544          break;
545
546       case 5:                         /* Max Bytes */
547          bsendmsg(ua, _("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
548          if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
549             return 0;
550          }
551          update_volmaxbytes(ua, ua->cmd, &mr);
552          break;
553
554
555       case 6:                         /* Recycle */
556          bsendmsg(ua, _("Current recycle flag is: %s\n"),
557             mr.Recycle==1?_("yes"):_("no"));
558          if (!get_yesno(ua, _("Enter new Recycle status: "))) {
559             return 0;
560          }
561          update_volrecycle(ua, ua->cmd, &mr);
562          break;
563
564       case 7:                         /* Slot */
565          bsendmsg(ua, _("Current Slot is: %d\n"), mr.Slot);
566          if (!get_pint(ua, _("Enter new Slot: "))) {
567             return 0;
568          }
569          update_volslot(ua, ua->cmd, &mr);
570          break;
571          
572       case 8:                         /* InChanger */
573          bsendmsg(ua, _("Current InChanger flag is: %d\n"), mr.InChanger);
574          if (!get_yesno(ua, _("Set InChanger flag? yes/no: "))) {
575             return 0;
576          }
577          mr.InChanger = ua->pint32_val;
578          /*
579           * Make sure to use db_update... rather than doing this directly,
580           *   so that any Slot is handled correctly.
581           */
582          if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
583             bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
584          } else {
585             bsendmsg(ua, _("New InChanger flag is: %d\n"), mr.InChanger);
586          }
587          break;
588
589
590       case 9:                         /* Volume Files */
591          int32_t VolFiles;
592          bsendmsg(ua, _("Warning changing Volume Files can result\n"
593                         "in loss of data on your Volume\n\n"));
594          bsendmsg(ua, _("Current Volume Files is: %u\n"), mr.VolFiles);
595          if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
596             return 0;
597          }
598          VolFiles = ua->pint32_val;
599          if (VolFiles != (int)(mr.VolFiles + 1)) {
600             bsendmsg(ua, _("Normally, you should only increase Volume Files by one!\n"));
601             if (!get_yesno(ua, _("Continue? (yes/no): ")) || ua->pint32_val == 0) {
602                break;
603             }
604          }
605          query = get_pool_memory(PM_MESSAGE);
606          Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%s",
607             VolFiles, edit_int64(mr.MediaId, ed1));
608          if (!db_sql_query(ua->db, query, NULL, NULL)) {
609             bsendmsg(ua, "%s", db_strerror(ua->db));
610          } else {
611             bsendmsg(ua, _("New Volume Files is: %u\n"), VolFiles);
612          }
613          free_pool_memory(query);
614          break;
615
616       case 10:                        /* Volume's Pool */
617          memset(&pr, 0, sizeof(POOL_DBR));
618          pr.PoolId = mr.PoolId;
619          if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
620             bsendmsg(ua, "%s", db_strerror(ua->db));
621             return 0;
622          }
623          bsendmsg(ua, _("Current Pool is: %s\n"), pr.Name);
624          if (!get_cmd(ua, _("Enter new Pool name: "))) {
625             return 0;
626          }
627          update_vol_pool(ua, ua->cmd, &mr, &pr);
628          return 1;
629
630       case 11:
631          update_vol_from_pool(ua, &mr);
632          return 1;
633       case 12:
634          update_all_vols_from_pool(ua);
635          return 1;
636
637       case 13:
638          bsendmsg(ua, _("Current Enabled is: %d\n"), mr.Enabled);
639          if (!get_cmd(ua, _("Enter new Enabled: "))) {
640             return 0;
641          }
642          if (strcasecmp(ua->cmd, "yes") == 0 || strcasecmp(ua->cmd, "true") == 0) {
643             mr.Enabled = 1;
644          } else if (strcasecmp(ua->cmd, "no") == 0 || strcasecmp(ua->cmd, "false") == 0) {
645             mr.Enabled = 0;
646          } else if (strcasecmp(ua->cmd, "archived") == 0) { 
647             mr.Enabled = 2;
648          } else {
649             mr.Enabled = atoi(ua->cmd);
650          }
651          update_volenabled(ua, ua->cmd, &mr);
652          break;
653
654       default:                        /* Done or error */
655          bsendmsg(ua, _("Selection terminated.\n"));
656          return 1;
657       }
658    }
659    return 1;
660 }
661
662 /*
663  * Update pool record -- pull info from current POOL resource
664  */
665 static bool update_pool(UAContext *ua)
666 {
667    POOL_DBR  pr;
668    int id;
669    POOL *pool;
670    POOLMEM *query;
671    char ed1[50];
672
673    pool = get_pool_resource(ua);
674    if (!pool) {
675       return false;
676    }
677
678    memset(&pr, 0, sizeof(pr));
679    bstrncpy(pr.Name, pool->hdr.name, sizeof(pr.Name));
680    if (!get_pool_dbr(ua, &pr)) {
681       return false;
682    }
683
684    set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */
685
686    id = db_update_pool_record(ua->jcr, ua->db, &pr);
687    if (id <= 0) {
688       bsendmsg(ua, _("db_update_pool_record returned %d. ERR=%s\n"),
689          id, db_strerror(ua->db));
690    }
691    query = get_pool_memory(PM_MESSAGE);
692    Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1));
693    db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
694    free_pool_memory(query);
695    bsendmsg(ua, _("Pool DB record updated from resource.\n"));
696    return true;
697 }