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