+static int zebra_select_register (ZebraHandle zh, const char *new_reg)
+{
+ if (zh->res && strcmp (zh->reg_name, new_reg) == 0)
+ return 0;
+ if (!zh->res)
+ {
+ assert (zh->reg == 0);
+ assert (*zh->reg_name == 0);
+ }
+ else
+ {
+ if (zh->reg)
+ {
+ resultSetInvalidate (zh);
+ zebra_register_close (zh->service, zh->reg);
+ zh->reg = 0;
+ }
+ zebra_close_res(zh);
+ }
+ xfree (zh->reg_name);
+ zh->reg_name = xstrdup (new_reg);
+
+ xfree (zh->path_reg);
+ zh->path_reg = 0;
+ if (zh->service->path_root)
+ {
+ zh->path_reg = xmalloc (strlen(zh->service->path_root) +
+ strlen(zh->reg_name) + 3);
+ strcpy (zh->path_reg, zh->service->path_root);
+ if (*zh->reg_name)
+ {
+ strcat (zh->path_reg, "/");
+ strcat (zh->path_reg, zh->reg_name);
+ }
+ }
+ zh->res = zebra_open_res (zh);
+
+ if (zh->lock_normal)
+ zebra_lock_destroy (zh->lock_normal);
+ zh->lock_normal = 0;
+
+ if (zh->lock_shadow)
+ zebra_lock_destroy (zh->lock_shadow);
+ zh->lock_shadow = 0;
+
+ if (zh->res)
+ {
+ char fname[512];
+ const char *lock_area =res_get (zh->res, "lockDir");
+
+ if (!lock_area && zh->path_reg)
+ res_put (zh->res, "lockDir", zh->path_reg);
+ sprintf (fname, "norm.%s.LCK", zh->reg_name);
+ zh->lock_normal =
+ zebra_lock_create (res_get(zh->res, "lockDir"), fname, 0);
+
+ sprintf (fname, "shadow.%s.LCK", zh->reg_name);
+ zh->lock_shadow =
+ zebra_lock_create (res_get(zh->res, "lockDir"), fname, 0);
+
+ }
+ return 1;
+}
+
+void map_basenames_func (void *vp, const char *name, const char *value)
+{
+ struct map_baseinfo *p = (struct map_baseinfo *) vp;
+ int i, no;
+ char fromdb[128], todb[8][128];
+
+ no =
+ sscanf (value, "%127s %127s %127s %127s %127s %127s %127s %127s %127s",
+ fromdb, todb[0], todb[1], todb[2], todb[3], todb[4],
+ todb[5], todb[6], todb[7]);
+ if (no < 2)
+ return ;
+ no--;
+ for (i = 0; i<p->num_bases; i++)
+ if (p->basenames[i] && !strcmp (p->basenames[i], fromdb))
+ {
+ p->basenames[i] = 0;
+ for (i = 0; i < no; i++)
+ {
+ if (p->new_num_bases == p->new_num_max)
+ return;
+ p->new_basenames[(p->new_num_bases)++] =
+ nmem_strdup (p->mem, todb[i]);
+ }
+ return;
+ }
+}
+
+void map_basenames (ZebraHandle zh, ODR stream,
+ int *num_bases, char ***basenames)
+{
+ struct map_baseinfo info;
+ struct map_baseinfo *p = &info;
+ int i;
+
+ info.zh = zh;
+ info.num_bases = *num_bases;
+ info.basenames = *basenames;
+ info.new_num_max = 128;
+ info.new_num_bases = 0;
+ info.new_basenames = (char **)
+ odr_malloc (stream, sizeof(*info.new_basenames) * info.new_num_max);
+ info.mem = stream->mem;
+
+ res_trav (zh->service->global_res, "mapdb", &info, map_basenames_func);
+
+ for (i = 0; i<p->num_bases; i++)
+ if (p->basenames[i] && p->new_num_bases < p->new_num_max)
+ {
+ p->new_basenames[(p->new_num_bases)++] =
+ nmem_strdup (p->mem, p->basenames[i]);
+ }
+ *num_bases = info.new_num_bases;
+ *basenames = info.new_basenames;
+ for (i = 0; i<*num_bases; i++)
+ logf (LOG_LOG, "base %s", (*basenames)[i]);
+}
+
+int zebra_select_database (ZebraHandle zh, const char *basename)
+{
+ return zebra_select_databases (zh, 1, &basename);
+}
+
+int zebra_select_databases (ZebraHandle zh, int num_bases,
+ const char **basenames)
+{
+ int i;
+ const char *cp;
+ int len = 0;
+ char *new_reg = 0;
+
+ if (num_bases < 1)
+ {
+ zh->errCode = 23;
+ return -1;
+ }
+ for (i = 0; i < zh->num_basenames; i++)
+ xfree (zh->basenames[i]);
+ xfree (zh->basenames);
+
+ zh->num_basenames = num_bases;
+ zh->basenames = xmalloc (zh->num_basenames * sizeof(*zh->basenames));
+ for (i = 0; i < zh->num_basenames; i++)
+ zh->basenames[i] = xstrdup (basenames[i]);
+
+ cp = strrchr(basenames[0], '/');
+ if (cp)
+ {
+ len = cp - basenames[0];
+ new_reg = xmalloc (len + 1);
+ memcpy (new_reg, basenames[0], len);
+ new_reg[len] = '\0';
+ }
+ else
+ new_reg = xstrdup ("");
+ for (i = 1; i<num_bases; i++)
+ {
+ const char *cp1;
+
+ cp1 = strrchr (basenames[i], '/');
+ if (cp)
+ {
+ if (!cp1)
+ {
+ zh->errCode = 23;
+ return -1;
+ }
+ if (len != cp1 - basenames[i] ||
+ memcmp (basenames[i], new_reg, len))
+ {
+ zh->errCode = 23;
+ return -1;
+ }
+ }
+ else
+ {
+ if (cp1)
+ {
+ zh->errCode = 23;
+ return -1;
+ }
+ }
+ }
+ zebra_select_register (zh, new_reg);
+ xfree (new_reg);
+ if (!zh->res)
+ {
+ zh->errCode = 109;
+ return -1;
+ }
+ return 0;
+}
+
+void zebra_search_rpn (ZebraHandle zh, ODR decode, ODR stream,
+ Z_RPNQuery *query, const char *setname, int *hits)