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