Exemple #1
0
static bool bvfs_parse_arg_version(UAContext *ua, char **client, DBId_t *fnid, bool *versions, bool *copies)
{
   *fnid = 0;
   *client = NULL;
   *versions = false;
   *copies = false;

   for (int i = 1; i < ua->argc; i++) {
      if (bstrcasecmp(ua->argk[i], NT_("fnid")) ||
          bstrcasecmp(ua->argk[i], NT_("filenameid"))) {
         if (is_a_number(ua->argv[i])) {
            *fnid = str_to_int64(ua->argv[i]);
         }
      }

      if (bstrcasecmp(ua->argk[i], NT_("client"))) {
         *client = ua->argv[i];
      }

      if (copies && bstrcasecmp(ua->argk[i], NT_("copies"))) {
         *copies = true;
      }

      if (versions && bstrcasecmp(ua->argk[i], NT_("versions"))) {
         *versions = true;
      }
   }

   return (*client && *fnid > 0);
}
Exemple #2
0
bool configure_cmd(UAContext *ua, const char *cmd)
{
   bool result = false;

   if (!(my_config->is_using_config_include_dir())) {
      ua->warning_msg(_(
               "It seems that the configuration is not adapted to the include directory structure. "
               "This means, that the configure command may not work as expected. "
               "Your configuration changes may not survive a reload/restart. "
               "Please see %s for details.\n"),
               MANUAL_CONFIG_DIR_URL);
   }

   if (ua->argc < 3) {
      ua->error_msg(_("usage:\n"
                      "  configure add <resourcetype> <key1>=<value1> ...\n"
                      "  configure export client=<clientname>\n"));
      return false;
   }

   if (bstrcasecmp(ua->argk[1], NT_("add"))) {
      result = configure_add(ua, 2);
   } else if (bstrcasecmp(ua->argk[1], NT_("export"))) {
      result = configure_export(ua);
   } else {
      ua->error_msg(_("invalid subcommand %s.\n"), ua->argk[1]);
      return false;
   }

   return result;
}
Exemple #3
0
/*
 * Parse a boolean value e.g. check if its yes or true anything else translates to false.
 */
static inline bool parse_boolean(const char *argument_value)
{
   if (bstrcasecmp(argument_value, "yes") ||
       bstrcasecmp(argument_value, "true")) {
      return true;
   } else {
      return false;
   }
}
Exemple #4
0
/*
 * Store a bool in a bit field
 */
void store_bool(LEX *lc, RES_ITEM *item, int index, int pass)
{
   lex_get_token(lc, T_NAME);
   if (bstrcasecmp(lc->str, "yes") || bstrcasecmp(lc->str, "true")) {
      *(bool *)(item->value) = true;
   } else if (bstrcasecmp(lc->str, "no") || bstrcasecmp(lc->str, "false")) {
      *(bool *)(item->value) = false;
   } else {
      scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
      return;
   }
   scan_to_eol(lc);
   set_bit(index, res_all.hdr.item_present);
}
Exemple #5
0
static bool bvfs_parse_arg(UAContext *ua, DBId_t *pathid, char **path, char **jobid, int *limit, int *offset)
{
   *pathid = 0;
   *limit = 2000;
   *offset = 0;
   *path = NULL;
   *jobid = NULL;

   for (int i = 1; i < ua->argc; i++) {
      if (bstrcasecmp(ua->argk[i], NT_("pathid"))) {
         if (is_a_number(ua->argv[i])) {
            *pathid = str_to_int64(ua->argv[i]);
         }
      }

      if (bstrcasecmp(ua->argk[i], NT_("path"))) {
         *path = ua->argv[i];
      }

      if (bstrcasecmp(ua->argk[i], NT_("jobid"))) {
         if (is_a_number_list(ua->argv[i])) {
            *jobid = ua->argv[i];
         }
      }

      if (bstrcasecmp(ua->argk[i], NT_("limit"))) {
         if (is_a_number(ua->argv[i])) {
            *limit = str_to_int64(ua->argv[i]);
         }
      }

      if (bstrcasecmp(ua->argk[i], NT_("offset"))) {
         if (is_a_number(ua->argv[i])) {
            *offset = str_to_int64(ua->argv[i]);
         }
      }
   }

   if (!((*pathid || *path) && *jobid)) {
      return false;
   }

   if (!open_client_db(ua, true)) {
      return false;
   }

   return true;
}
Exemple #6
0
static inline bool script_dir_allowed(JCR *jcr, RUNSCRIPT *script, alist *allowed_script_dirs)
{
   char *bp, *allowed_script_dir;
   bool allowed = false;
   POOL_MEM script_dir(PM_FNAME);

   /*
    * If there is no explicit list of allowed dirs allow any dir.
    */
   if (!allowed_script_dirs) {
      return true;
   }

   /*
    * Determine the dir the script is in.
    */
   pm_strcpy(script_dir, script->command);
   if ((bp = strrchr(script_dir.c_str(), '/'))) {
      *bp = '\0';
   }

   /*
    * Match the path the script is in against the list of allowed script directories.
    */
   foreach_alist(allowed_script_dir, allowed_script_dirs) {
      if (bstrcasecmp(script_dir.c_str(), allowed_script_dir)) {
         allowed = true;
         break;
      }
   }

   return allowed;
}
/*
 * Open a directory on the object store and find out size information for a file.
 */
static inline size_t object_store_get_file_size(dpl_ctx_t *ctx, const char *filename)
{
   void *dir_hdl;
   dpl_status_t status;
   dpl_dirent_t dirent;
   size_t filesize = -1;

   status = dpl_opendir(ctx, ".", &dir_hdl);
   switch (status) {
   case DPL_SUCCESS:
      break;
   default:
      return -1;
   }

   while (!dpl_eof(dir_hdl)) {
      if (bstrcasecmp(dirent.name, filename)) {
         filesize = dirent.size;
         break;
      }
   }

   dpl_closedir(dir_hdl);

   return filesize;
}
Exemple #8
0
/*
 * New style options come here
 */
static void store_opts(LEX *lc, RES_ITEM *item, int index, int pass)
{
   int i;
   int keyword;
   char inc_opts[100];

   inc_opts[0] = 0;
   keyword = INC_KW_NONE;
   /* Look up the keyword */
   for (i=0; FS_option_kw[i].name; i++) {
      if (bstrcasecmp(item->name, FS_option_kw[i].name)) {
         keyword = FS_option_kw[i].token;
         break;
      }
   }
   if (keyword == INC_KW_NONE) {
      scan_err1(lc, _("Expected a FileSet keyword, got: %s"), lc->str);
   }
   /* Now scan for the value */
   scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts));
   if (pass == 1) {
      bstrncat(res_incexe.current_opts->opts, inc_opts, MAX_FOPTS);
      Dmsg2(900, "new pass=%d incexe opts=%s\n", pass, res_incexe.current_opts->opts);
   }
   scan_to_eol(lc);
}
Exemple #9
0
static inline backend_interface_mapping_t *lookup_backend_interface_mapping(const char *interface_name)
{
   backend_interface_mapping_t *backend_interface_mapping;

   for (backend_interface_mapping = backend_interface_mappings;
        backend_interface_mapping->interface_name != NULL;
        backend_interface_mapping++) {

      Dmsg3(100, "db_init_database: Trying to find mapping of given interfacename %s to mapping interfacename %s, partly_compare = %s\n",
            interface_name, backend_interface_mapping->interface_name, (backend_interface_mapping->partly_compare) ? "true" : "false");

      /*
       * See if this is a match.
       */
      if (backend_interface_mapping->partly_compare) {
         if (bstrncasecmp(interface_name, backend_interface_mapping->interface_name,
                              strlen(backend_interface_mapping->interface_name))) {
            return backend_interface_mapping;
         }
      } else {
         if (bstrcasecmp(interface_name, backend_interface_mapping->interface_name)) {
            return backend_interface_mapping;
         }
      }
   }

   return NULL;
}
Exemple #10
0
/*
 * Store a yes/no in a bit field
 */
static void store_bit(LEX *lc, RES_ITEM *item, int index, int pass)
{
   URES *res_all = (URES *)my_config->m_res_all;

   lex_get_token(lc, T_NAME);
   if (bstrcasecmp(lc->str, "yes") || bstrcasecmp(lc->str, "true")) {
      *(item->ui32value) |= item->code;
   } else if (bstrcasecmp(lc->str, "no") || bstrcasecmp(lc->str, "false")) {
      *(item->ui32value) &= ~(item->code);
   } else {
      scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str); /* YES and NO must not be translated */
      return;
   }
   scan_to_eol(lc);
   set_bit(index, res_all->hdr.item_present);
}
Exemple #11
0
static bool try_open(struct MPContext *mpctx, char *filename)
{
    struct bstr bfilename = bstr0(filename);
    // Avoid trying to open itself or another .cue file. Best would be
    // to check the result of demuxer auto-detection, but the demuxer
    // API doesn't allow this without opening a full demuxer.
    if (bstr_case_endswith(bfilename, bstr0(".cue"))
        || bstrcasecmp(bstr0(mpctx->demuxer->filename), bfilename) == 0)
        return false;

    struct stream *s = stream_open(filename, mpctx->opts);
    if (!s)
        return false;
    struct demuxer *d = demux_open(s, NULL, NULL, mpctx->opts);
    // Since .bin files are raw PCM data with no headers, we have to explicitly
    // open them. Also, try to avoid to open files that are most likely not .bin
    // files, as that would only play noise. Checking the file extension is
    // fragile, but it's about the only way we have.
    // TODO: maybe also could check if the .bin file is a multiple of the Audio
    //       CD sector size (2352 bytes)
    if (!d && bstr_case_endswith(bfilename, bstr0(".bin"))) {
        mp_msg(MSGT_CPLAYER, MSGL_WARN, "CUE: Opening as BIN file!\n");
        d = demux_open(s, "rawaudio", NULL, mpctx->opts);
    }
    if (d) {
        add_source(mpctx, d);
        return true;
    }
    mp_msg(MSGT_CPLAYER, MSGL_ERR, "Could not open source '%s'!\n", filename);
    free_stream(s);
    return false;
}
Exemple #12
0
/*
 * Check if the current line contains Storage="xxx", and compare the
 * result to the current storage. We use UAContext to analyse the bsr
 * string.
 *
 * Returns true if we need to change the storage, and it set the new
 * Storage resource name in "storage" arg.
 */
static inline bool check_for_new_storage(JCR *jcr, bootstrap_info &info)
{
   UAContext *ua = info.ua;

   parse_ua_args(ua);
   if (ua->argc != 1) {
      return false;
   }

   if (bstrcasecmp(ua->argk[0], "Storage")) {
      /*
       * Continue if this is a volume from the same storage.
       */
      if (is_on_same_storage(jcr, ua->argv[0])) {
         return false;
      }

      /*
       * Note the next storage name
       */
      bstrncpy(info.storage, ua->argv[0], MAX_NAME_LENGTH);
      Dmsg1(5, "Change storage to %s\n", info.storage);
      return true;
   }

   return false;
}
Exemple #13
0
static bool try_open(struct timeline *tl, char *filename)
{
    struct bstr bfilename = bstr0(filename);
    // Avoid trying to open itself or another .cue file. Best would be
    // to check the result of demuxer auto-detection, but the demuxer
    // API doesn't allow this without opening a full demuxer.
    if (bstr_case_endswith(bfilename, bstr0(".cue"))
        || bstrcasecmp(bstr0(tl->demuxer->filename), bfilename) == 0)
        return false;

    struct demuxer *d = demux_open_url(filename, NULL, tl->cancel, tl->global);
    // Since .bin files are raw PCM data with no headers, we have to explicitly
    // open them. Also, try to avoid to open files that are most likely not .bin
    // files, as that would only play noise. Checking the file extension is
    // fragile, but it's about the only way we have.
    // TODO: maybe also could check if the .bin file is a multiple of the Audio
    //       CD sector size (2352 bytes)
    if (!d && bstr_case_endswith(bfilename, bstr0(".bin"))) {
        MP_WARN(tl, "CUE: Opening as BIN file!\n");
        struct demuxer_params p = {.force_format = "rawaudio"};
        d = demux_open_url(filename, &p, tl->cancel, tl->global);
    }
    if (d) {
        add_source(tl, d);
        return true;
    }
    MP_ERR(tl, "Could not open source '%s'!\n", filename);
    return false;
}
Exemple #14
0
int demux_info_add_bstr(demuxer_t *demuxer, struct bstr opt, struct bstr param)
{
    char **info = demuxer->info;
    int n = 0;


    for (n = 0; info && info[2 * n] != NULL; n++) {
        if (!bstrcasecmp(opt, bstr(info[2*n]))) {
            if (!bstrcmp(param, bstr(info[2*n + 1]))) {
                mp_msg(MSGT_DEMUX, MSGL_V, "Demuxer info %.*s set to unchanged value %.*s\n",
                       BSTR_P(opt), BSTR_P(param));
                return 0;
            }
            mp_tmsg(MSGT_DEMUX, MSGL_INFO, "Demuxer info %.*s changed to %.*s\n",
                    BSTR_P(opt), BSTR_P(param));
            talloc_free(info[2*n + 1]);
            info[2*n + 1] = talloc_strndup(demuxer->info, param.start, param.len);
            return 0;
        }
    }

    info = demuxer->info = talloc_realloc(demuxer, info, char *, 2 * (n + 2));
    info[2*n]     = talloc_strndup(demuxer->info, opt.start,   opt.len);
    info[2*n + 1] = talloc_strndup(demuxer->info, param.start, param.len);
    memset(&info[2 * (n + 1)], 0, 2 * sizeof(char *));

    return 1;
}
Exemple #15
0
/*
 * Create a connection string for connecting to the master database.
 */
static void set_ado_connect_string(bpContext *ctx)
{
   POOL_MEM ado_connect_string(PM_NAME);
   plugin_ctx *p_ctx = (plugin_ctx *)ctx->pContext;

   if (bstrcasecmp(p_ctx->instance, DEFAULT_INSTANCE)) {
      pm_strcpy(ado_connect_string,
                "Provider=SQLOLEDB.1;Data Source=localhost;Initial Catalog=master");
   } else {
      Mmsg(ado_connect_string,
           "Provider=SQLOLEDB.1;Data Source=localhost\\%s;Initial Catalog=master",
           p_ctx->instance);
   }

   /*
    * See if we need to use a username/password or a trusted connection.
    */
   if (p_ctx->username && p_ctx->password) {
      POOL_MEM temp(PM_NAME);

      Mmsg(temp, ";User Id=%s;Password=%s;",
            p_ctx->username, p_ctx->password);
      pm_strcat(ado_connect_string, temp.c_str());
   } else {
      pm_strcat(ado_connect_string, ";Integrated Security=SSPI;");
   }

   Dmsg(ctx, dbglvl, "set_ado_connect_string: ADO Connect String '%s'\n", ado_connect_string.c_str());

   if (p_ctx->ado_connect_string) {
      free(p_ctx->ado_connect_string);
   }
   p_ctx->ado_connect_string = bstrdup(ado_connect_string.c_str());
}
Exemple #16
0
/*
 * Verifies a list of common names against the certificate
 * commonName attribute.
 *  Returns: true on success
 *           false on failure
 */
bool tls_postconnect_verify_cn(JCR *jcr, TLS_CONNECTION *tls, alist *verify_list)
{
   SSL *ssl = tls->openssl;
   X509 *cert;
   X509_NAME *subject;
   bool auth_success = false;
   char data[256];

   /* Check if peer provided a certificate */
   if (!(cert = SSL_get_peer_certificate(ssl))) {
      Qmsg0(jcr, M_ERROR, 0, _("Peer failed to present a TLS certificate\n"));
      return false;
   }

   if ((subject = X509_get_subject_name(cert)) != NULL) {
      if (X509_NAME_get_text_by_NID(subject, NID_commonName, data, sizeof(data)) > 0) {
         char *cn;
         /* NULL terminate data */
         data[255] = 0;

         /* Try all the CNs in the list */
         foreach_alist(cn, verify_list) {
            if (bstrcasecmp(data, cn)) {
               auth_success = true;
            }
         }
      }
   }
Exemple #17
0
static bool test_ext_list(bstr ext, const char *const *list)
{
    for (int n = 0; list[n]; n++) {
        if (bstrcasecmp(bstr0(list[n]), ext) == 0)
            return true;
    }
    return false;
}
Exemple #18
0
static bool is_sub_ext(bstr ext)
{
    for (int n = 0; sub_exts[n]; n++) {
        if (bstrcasecmp(bstr0(sub_exts[n]), ext) == 0)
            return true;
    }
    return false;
}
Exemple #19
0
String StringUtil::DecodeFileUrl(const String& input) {
  Url url;
  if (!url_parse(url, input.data(), input.size())) {
    return null_string;
  }
  if (bstrcasecmp(url.scheme.data(), url.scheme.size(),
        "file", sizeof("file")-1) != 0) {
    // Not file scheme
    return null_string;
  }
  if (url.host.size() > 0
      && bstrcasecmp(url.host.data(), url.host.size(),
        "localhost", sizeof("localhost")-1) != 0) {
    // Not localhost or empty host
    return null_string;
  }
  return url_raw_decode(url.path.data(), url.path.size());
}
Exemple #20
0
/*
 * Given one keyword, find the first one that is in the argument list.
 *
 * Returns: argk index (always gt 0)
 *          -1 if not found
 */
int find_arg(UAContext *ua, const char *keyword)
{
   for (int i = 1; i < ua->argc; i++) {
      if (bstrcasecmp(keyword, ua->argk[i])) {
         return i;
      }
   }

   return -1;
}
Exemple #21
0
bool mp_replace_legacy_cmd(void *t, bstr *s)
{
    for (const struct legacy_cmd *entry = legacy_cmds; entry->old; entry++) {
        bstr old = bstr0(entry->old);
        if (bstrcasecmp(bstr_splice(*s, 0, old.len), old) == 0) {
            bstr rest = bstr_cut(*s, old.len);
            *s = bstr0(talloc_asprintf(t, "%s%.*s", entry->new, BSTR_P(rest)));
            return true;
        }
    }
Exemple #22
0
/*
 * Given a list of keywords, find the first one that is in the argument list.
 *
 * Returns: -1 if not found
 *          index into list (base 0) on success
 */
int find_arg_keyword(UAContext *ua, const char **list)
{
   for (int i = 1; i < ua->argc; i++) {
      for (int j = 0; list[j]; j++) {
         if (bstrcasecmp(list[j], ua->argk[i])) {
            return j;
         }
      }
   }

   return -1;
}
Exemple #23
0
RES_TABLE *CONFIG::get_resource_table(const char *resource_type)
{
   RES_TABLE *result = NULL;
   int i;

   for (i = 0; m_resources[i].name; i++) {
      if (bstrcasecmp(m_resources[i].name, resource_type)) {
         result = &m_resources[i];
      }
   }

   return result;
}
Exemple #24
0
/*
 * Get a particular item from the items list
 */
int ConfigFile::get_item(const char *name)
{
   if (!items) {
      return -1;
   }

   for (int i = 0; i < MAX_INI_ITEMS && items[i].name; i++) {
      if (bstrcasecmp(name, items[i].name)) {
         return i;
      }
   }
   return -1;
}
Exemple #25
0
int CONFIG::get_resource_item_index(RES_ITEM *items, const char *item)
{
   int result = -1;
   int i;

   for (i = 0; items[i].name; i++) {
      if (bstrcasecmp(items[i].name, item)) {
         result = i;
         break;
      }
   }

   return result;
}
Exemple #26
0
/*
 * Given a single keyword, find it in the argument list, but it must have a value
 *
 * Returns: -1 if not found or no value
 *           list index (base 0) on success
 */
int find_arg_with_value(UAContext *ua, const char *keyword)
{
   for (int i = 1; i < ua->argc; i++) {
      if (bstrcasecmp(keyword, ua->argk[i])) {
         if (ua->argv[i]) {
            return i;
         } else {
            return -1;
         }
      }
   }

   return -1;
}
Exemple #27
0
static bool ini_store_bool(LEX *lc, ConfigFile *inifile, ini_items *item)
{
   if (!lc) {
      Mmsg(inifile->edit, "%s", item->val.boolval?"yes":"no");
      return true;
   }
   if (lex_get_token(lc, T_NAME) == T_ERROR) {
      return false;
   }
   if (bstrcasecmp(lc->str, "yes") || bstrcasecmp(lc->str, "true")) {
      item->val.boolval = true;
   } else if (bstrcasecmp(lc->str, "no") || bstrcasecmp(lc->str, "false")) {
      item->val.boolval = false;
   } else {
      /*
       * YES and NO must not be translated
       */
      scan_err2(lc, _("Expect %s, got: %s"), "YES, NO, TRUE, or FALSE", lc->str);
      return false;
   }
   scan_to_eol(lc);
   return true;
}
Exemple #28
0
/*
 * Get a catalog resource from prompt list
 */
CATRES *get_catalog_resource(UAContext *ua)
{
   CATRES *catalog = NULL;
   char name[MAX_NAME_LENGTH];

   for (int i = 1; i < ua->argc; i++) {
      if (bstrcasecmp(ua->argk[i], NT_("catalog")) && ua->argv[i]) {
         if (acl_access_ok(ua, Catalog_ACL, ua->argv[i])) {
            catalog = (CATRES *)GetResWithName(R_CATALOG, ua->argv[i]);
            break;
         }
      }
   }

   if (ua->gui && !catalog) {
      LockRes();
      catalog = (CATRES *)GetNextRes(R_CATALOG, NULL);
      UnlockRes();

      if (!catalog) {
         ua->error_msg(_("Could not find a Catalog resource\n"));
         return NULL;
      } else if (!acl_access_ok(ua, Catalog_ACL, catalog->name())) {
         ua->error_msg(_("You must specify a \"use <catalog-name>\" command before continuing.\n"));
         return NULL;
      }

      return catalog;
   }

   if (!catalog) {
      start_prompt(ua, _("The defined Catalog resources are:\n"));

      LockRes();
      foreach_res(catalog, R_CATALOG) {
         if (acl_access_ok(ua, Catalog_ACL, catalog->name())) {
            add_prompt(ua, catalog->name());
         }
      }
      UnlockRes();

      if (do_prompt(ua, _("Catalog"),  _("Select Catalog resource"), name, sizeof(name)) < 0) {
         return NULL;
      }

      catalog = (CATRES *)GetResWithName(R_CATALOG, name);
   }
Exemple #29
0
static inline bool script_dir_allowed(JCR *jcr, RUNSCRIPT *script, alist *allowed_script_dirs)
{
   char *bp, *allowed_script_dir;
   bool allowed = false;
   POOL_MEM script_dir(PM_FNAME);

   /*
    * If there is no explicit list of allowed dirs allow any dir.
    */
   if (!allowed_script_dirs) {
      return true;
   }

   /*
    * Determine the dir the script is in.
    */
   pm_strcpy(script_dir, script->command);
   if ((bp = strrchr(script_dir.c_str(), '/'))) {
      *bp = '\0';
   }

   /*
    * Make sure there are no relative path elements in script dir by which the
    * user tries to escape the allowed dir checking. For scripts we only allow
    * absolute paths.
    */
   if (strstr(script_dir.c_str(), "..")) {
      Dmsg1(200, "script_dir_allowed: relative pathnames not allowed: %s\n", script_dir.c_str());
      return false;
   }

   /*
    * Match the path the script is in against the list of allowed script directories.
    */
   foreach_alist(allowed_script_dir, allowed_script_dirs) {
      if (bstrcasecmp(script_dir.c_str(), allowed_script_dir)) {
         allowed = true;
         break;
      }
   }

   Dmsg2(200, "script_dir_allowed: script %s %s allowed by Allowed Script Dir setting",
         script->command, (allowed) ? "" : "NOT");

   return allowed;
}
Exemple #30
0
/*
 * Scan for message types and add them to the message
 * destination. The basic job here is to connect message types
 *  (WARNING, ERROR, FATAL, INFO, ...) with an appropriate
 *  destination (MAIL, FILE, OPERATOR, ...)
 */
static void scan_types(LEX *lc, MSGSRES *msg, int dest_code, char *where, char *cmd)
{
   int i;
   bool found, is_not;
   int msg_type = 0;
   char *str;

   for ( ;; ) {
      lex_get_token(lc, T_NAME);            /* expect at least one type */
      found = false;
      if (lc->str[0] == '!') {
         is_not = true;
         str = &lc->str[1];
      } else {
         is_not = false;
         str = &lc->str[0];
      }
      for (i = 0; msg_types[i].name; i++) {
         if (bstrcasecmp(str, msg_types[i].name)) {
            msg_type = msg_types[i].token;
            found = true;
            break;
         }
      }
      if (!found) {
         scan_err1(lc, _("message type: %s not found"), str);
         return;
      }

      if (msg_type == M_MAX+1) {         /* all? */
         for (i = 1; i <= M_MAX; i++) {      /* yes set all types */
            add_msg_dest(msg, dest_code, i, where, cmd);
         }
      } else if (is_not) {
         rem_msg_dest(msg, dest_code, msg_type, where);
      } else {
         add_msg_dest(msg, dest_code, msg_type, where, cmd);
      }
      if (lc->ch != ',') {
         break;
      }
      Dmsg0(900, "call lex_get_token() to eat comma\n");
      lex_get_token(lc, T_ALL);          /* eat comma */
   }
   Dmsg0(900, "Done scan_types()\n");
}