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