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