+
+
+/* not all in alphabetical order. New commands are added after existing commands with similar letters
+ to prevent breakage of existing user scripts. */
+struct debugtags {
+ const char *tag; /* command */
+ int64_t bit; /* bit to set */
+ const char *help; /* main purpose */
+};
+
+/* setdebug tag=all,-plugin */
+static struct debugtags debug_tags[] = {
+ { NT_("lock"), DT_LOCK, _("Debug lock information")},
+ { NT_("network"), DT_NETWORK, _("Debug network information")},
+ { NT_("plugin"), DT_PLUGIN, _("Debug plugin information")},
+ { NT_("volume"), DT_VOLUME, _("Debug volume information")},
+ { NT_("sql"), DT_SQL, _("Debug SQL queries")},
+ { NT_("bvfs"), DT_BVFS, _("Debug BVFS queries")},
+ { NT_("memory"), DT_MEMORY, _("Debug memory allocation")},
+ { NT_("scheduler"), DT_SCHEDULER,_("Debug scheduler information")},
+ { NT_("protocol"), DT_PROTOCOL, _("Debug protocol information")},
+ { NT_("snapshot"), DT_SNAPSHOT, _("Debug snapshots")},
+ { NT_("asx"), DT_ASX, _("ASX personal's debugging")},
+ { NT_("all"), DT_ALL, _("Debug all information")},
+ { NULL, 0, NULL}
+};
+
+#define MAX_TAG (sizeof(debug_tags) / sizeof(struct debugtags))
+
+const char *debug_get_tag(uint32_t pos, const char **desc)
+{
+ if (pos < MAX_TAG) {
+ if (desc) {
+ *desc = debug_tags[pos].help;
+ }
+ return debug_tags[pos].tag;
+ }
+ return NULL;
+}
+
+/* Allow +-, */
+bool debug_find_tag(const char *tagname, bool add, int64_t *current_level)
+{
+ Dmsg3(010, "add=%d tag=%s level=%lld\n", add, tagname, *current_level);
+ if (!*tagname) {
+ /* Nothing in the buffer */
+ return true;
+ }
+ for (int i=0; debug_tags[i].tag ; i++) {
+ if (strcasecmp(debug_tags[i].tag, tagname) == 0) {
+ if (add) {
+ *current_level |= debug_tags[i].bit;
+ } else {
+ *current_level &= ~(debug_tags[i].bit);
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+bool debug_parse_tags(const char *options, int64_t *current_level)
+{
+ bool operation; /* + => true, - false */
+ char *p, *t, tag[256];
+ int max = sizeof(tag) - 1;
+ bool ret=true;
+ int64_t level= *current_level;
+
+ t = tag;
+ *tag = 0;
+ operation = true; /* add by default */
+
+ if (!options) {
+ Dmsg0(100, "No options for tags\n");
+ return false;
+ }
+
+ for (p = (char *)options; *p ; p++) {
+ if (*p == ',' || *p == '+' || *p == '-' || *p == '!') {
+ /* finish tag keyword */
+ *t = 0;
+ /* handle tag */
+ ret &= debug_find_tag(tag, operation, &level);
+
+ if (*p == ',') {
+ /* reset tag */
+ t = tag;
+ *tag = 0;
+ operation = true;
+
+ } else {
+ /* reset tag */
+ t = tag;
+ *tag = 0;
+ operation = (*p == '+');
+ }
+
+ } else if (isalpha(*p) && (t - tag) < max) {
+ *t++ = *p;
+
+ } else { /* not isalpha or too long */
+ Dmsg1(010, "invalid %c\n", *p);
+ return false;
+ }
+ }
+
+ /* At the end, finish the string and look it */
+ *t = 0;
+ if (t > tag) { /* something found */
+ /* handle tag */
+ ret &= debug_find_tag(tag, operation, &level);
+ }
+
+ *current_level = level;
+ return ret;
+}
+
+int generate_daemon_event(JCR *jcr, const char *event) { return 0; }
+
+void setup_daemon_message_queue()
+{
+ static MQUEUE_ITEM *item = NULL;
+ daemon_msg_queue = New(dlist(item, &item->link));
+}
+
+void free_daemon_message_queue()
+{
+ P(daemon_msg_queue_mutex);
+ daemon_msg_queue->destroy();
+ free(daemon_msg_queue);
+ V(daemon_msg_queue_mutex);
+}