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