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