Ejemplo n.º 1
0
    bool report_matches(const wchar_t *arg) {
        // Note: --all is a no-op for glob matching since the pattern is always matched against the
        // entire argument.
        bool match;

        if (opts.ignore_case) {
            wcstring s = arg;
            for (size_t i = 0; i < s.length(); i++) {
                s[i] = towlower(s[i]);
            }
            match = wildcard_match(s, wcpattern, false);
        } else {
            match = wildcard_match(arg, wcpattern, false);
        }
        if (match ^ opts.invert_match) {
            total_matched++;

            if (!opts.quiet) {
                if (opts.index) {
                    streams.out.append_format(L"1 %lu\n", wcslen(arg));
                } else {
                    streams.out.append(arg);
                    streams.out.append(L'\n');
                }
            }
        }
        return true;
    }
Ejemplo n.º 2
0
static bool
mail_export_filter_match_ip(const struct mail_export_filter *filter,
			    const struct mail_ip *ip)
{
	struct mail_session *s;
	bool connected = FALSE, user_ok = FALSE, domain_ok = FALSE;

	if (filter->connected || filter->ip_bits > 0) {
		for (s = ip->sessions; s != NULL; s = s->ip_next) {
			if (!s->disconnected)
				connected = TRUE;
			if (filter->user != NULL &&
			    wildcard_match(s->user->name, filter->user))
				user_ok = TRUE;
			if (filter->domain != NULL &&
			    wildcard_match(s->user->domain->name, filter->domain))
				domain_ok = TRUE;
		}
		if (filter->connected && !connected)
			return FALSE;
		if (filter->user != NULL && !user_ok)
			return FALSE;
		if (filter->domain != NULL && !domain_ok)
			return FALSE;
	}
	if (filter->since > ip->last_update.tv_sec)
		return FALSE;
	if (filter->ip_bits > 0 &&
	    !net_is_in_network(&ip->ip, &filter->ip, filter->ip_bits))
		return FALSE;
	return TRUE;
}
Ejemplo n.º 3
0
static bool fts_autoindex_exclude_match(struct mailbox *box)
{
	const char *const *exclude_list;
	unsigned int i;
	const struct mailbox_settings *set;
	const char *const *special_use;
	struct mail_user *user = box->storage->user;

	exclude_list = fts_exclude_get_patterns(user);
	if (exclude_list == NULL)
		return FALSE;

	set = mailbox_settings_find(mailbox_get_namespace(box),
				    mailbox_get_vname(box));
	special_use = set == NULL ? NULL :
		t_strsplit_spaces(set->special_use, " ");
	for (i = 0; exclude_list[i] != NULL; i++) {
		if (exclude_list[i][0] == '\\') {
			/* \Special-use flag */
			if (str_array_icase_find(special_use, exclude_list[i]))
				return TRUE;
		} else {
			/* mailbox name with wildcards */
			if (wildcard_match(box->name, exclude_list[i]))
				return TRUE;
		}
	}
	return FALSE;
}
Ejemplo n.º 4
0
void wildcard_expander_t::expand_intermediate_segment(const wcstring &base_dir, DIR *base_dir_fp,
                                                      const wcstring &wc_segment,
                                                      const wchar_t *wc_remainder,
                                                      const wcstring &prefix) {
    wcstring name_str;
    while (!interrupted() && wreaddir_for_dirs(base_dir_fp, &name_str)) {
        // Note that it's critical we ignore leading dots here, else we may descend into . and ..
        if (!wildcard_match(name_str, wc_segment, true)) {
            // Doesn't match the wildcard for this segment, skip it.
            continue;
        }

        wcstring full_path = base_dir + name_str;
        struct stat buf;
        if (0 != wstat(full_path, &buf) || !S_ISDIR(buf.st_mode)) {
            // We either can't stat it, or we did but it's not a directory.
            continue;
        }

        const file_id_t file_id = file_id_t::from_stat(buf);
        if (!this->visited_files.insert(file_id).second) {
            // Symlink loop! This directory was already visited, so skip it.
            continue;
        }

        // We made it through. Perform normal wildcard expansion on this new directory, starting at
        // our tail_wc, which includes the ANY_STRING_RECURSIVE guy.
        full_path.push_back(L'/');
        this->expand(full_path, wc_remainder, prefix + wc_segment + L'/');

        // Now remove the visited file. This is for #2414: only directories "beneath" us should be
        // considered visited.
        this->visited_files.erase(file_id);
    }
}
Ejemplo n.º 5
0
static DCPluginSyncFilterResult
apply_block_domains(DCPluginDNSPacket *dcp_packet, Blocking * const blocking,
                    ldns_pkt * const packet)
{
    StrList  *scanned;
    ldns_rr  *question;
    char     *owner_str;
    size_t    owner_str_len;

    scanned = blocking->domains;
    question = ldns_rr_list_rr(ldns_pkt_question(packet), 0U);
    if ((owner_str = ldns_rdf2str(ldns_rr_owner(question))) == NULL) {
        return DCP_SYNC_FILTER_RESULT_FATAL;
    }
    owner_str_len = strlen(owner_str);
    if (owner_str_len > (size_t) 1U && owner_str[--owner_str_len] == '.') {
        owner_str[owner_str_len] = 0;
    }
    do {
        if (wildcard_match(owner_str, scanned->str)) {
            LDNS_RCODE_SET(dcplugin_get_wire_data(dcp_packet),
                           LDNS_RCODE_REFUSED);
            break;
        }
    } while ((scanned = scanned->next) != NULL);
    free(owner_str);

    return DCP_SYNC_FILTER_RESULT_OK;
}
Ejemplo n.º 6
0
static bool
dsync_mailbox_info_is_excluded(const struct mailbox_info *info,
			       const char *const *exclude_mailboxes)
{
	const char *const *info_specialuses;
	unsigned int i;

	if (exclude_mailboxes == NULL)
		return FALSE;

	info_specialuses = info->special_use == NULL ? NULL :
		t_strsplit(info->special_use, " ");
	for (i = 0; exclude_mailboxes[i] != NULL; i++) {
		const char *exclude = exclude_mailboxes[i];

		if (exclude[0] == '\\') {
			/* special-use */
			if (info_specialuses != NULL &&
			    str_array_icase_find(info_specialuses, exclude))
				return TRUE;
		} else {
			/* mailbox with wildcards */
			if (wildcard_match(info->vname, exclude))
				return TRUE;
		}
	}
	return FALSE;
}
Ejemplo n.º 7
0
void wildcard_expansion(std::vector<std::string> &my_args, const std::string &pattern, std::ofstream &logfile) {
  int count_matches = 0;
  if (pattern.find("*") != std::string::npos) {
    std::cout << "WILDCARD DETECTED:" << pattern << std::endl;
    char buf[DIR_PATH_MAX];
    getcwd( buf, DIR_PATH_MAX );
    DIR* dir = opendir(buf);
    assert (dir != NULL);
    struct dirent *ent;
    while (1) {
      ent = readdir(dir);
      if (ent == NULL) break;
      std::string thing = ent->d_name;
      if (wildcard_match(pattern,thing,logfile)) {
	std::cout << "   MATCHED! " << thing << std::endl;
	validate_filename(thing);
	my_args.push_back(thing);
	count_matches++;
     }
    }
    closedir(dir);
  } else {
    my_args.push_back(pattern);
  }
  if (count_matches == 0) {
    logfile << "WARNING: No matches to wildcard pattern: " << pattern << std::endl;
  }
}
Ejemplo n.º 8
0
static int
client_input_status(struct doveadm_connection *client, const char *const *args)
{
	struct replicator_queue_iter *iter;
	struct replicator_user *user;
	const char *mask = args[0];
	string_t *str = t_str_new(128);

	if (mask == NULL)
		return client_input_status_overview(client);

	iter = replicator_queue_iter_init(client->queue);
	while ((user = replicator_queue_iter_next(iter)) != NULL) {
		if (!wildcard_match(user->username, mask))
			continue;

		str_truncate(str, 0);
		str_append_tabescaped(str, user->username);
		str_append_c(str, '\t');
		str_append(str, replicator_priority_to_str(user->priority));
		str_printfa(str, "\t%lld\t%lld\t%d\n",
			    (long long)user->last_fast_sync,
			    (long long)user->last_full_sync,
			    user->last_sync_failed);
		o_stream_send(client->conn.output, str_data(str), str_len(str));
	}
	replicator_queue_iter_deinit(&iter);
	o_stream_send(client->conn.output, "\n", 1);
	return 0;
}
Ejemplo n.º 9
0
static bool
mail_export_filter_match_user_common(const struct mail_export_filter *filter,
				     const struct mail_user *user)
{
	struct mail_session *s;
	bool connected = FALSE, ip_ok = FALSE;

	if (filter->user != NULL &&
	    !wildcard_match(user->name, filter->user))
		return FALSE;

	if (filter->connected || filter->ip_bits > 0) {
		for (s = user->sessions; s != NULL; s = s->user_next) {
			if (!s->disconnected)
				connected = TRUE;
			if (filter->ip_bits > 0 &&
			    net_is_in_network(&s->ip->ip, &filter->ip,
					      filter->ip_bits))
				ip_ok = TRUE;

		}
		if (filter->connected && !connected)
			return FALSE;
		if (filter->ip_bits > 0 && !ip_ok)
			return FALSE;
	}
	return TRUE;
}
Ejemplo n.º 10
0
void test_wildcard_match(void)
{
	unsigned int i;

	test_begin("wildcard_match()");
	for (i = 0; i < N_ELEMENTS(tests); i++) {
		test_assert_idx(wildcard_match(tests[i].data, tests[i].mask) == tests[i].result, i);
	}
	test_end();
}
Ejemplo n.º 11
0
static bool
mail_export_filter_match_session(const struct mail_export_filter *filter,
				 const struct mail_session *session)
{
	if (filter->connected && session->disconnected)
		return FALSE;
	if (filter->since > session->last_update.tv_sec)
		return FALSE;
	if (filter->user != NULL &&
	    !wildcard_match(session->user->name, filter->user))
		return FALSE;
	if (filter->domain != NULL &&
	    !wildcard_match(session->user->domain->name, filter->domain))
		return FALSE;
	if (filter->ip_bits > 0 &&
	    !net_is_in_network(&session->ip->ip, &filter->ip, filter->ip_bits))
		return FALSE;
	return TRUE;
}
Ejemplo n.º 12
0
static bool
mail_export_filter_match_user(const struct mail_export_filter *filter,
			      const struct mail_user *user)
{
	if (filter->since > user->last_update.tv_sec)
		return FALSE;
	if (filter->domain != NULL &&
	    !wildcard_match(user->domain->name, filter->domain))
		return FALSE;
	return mail_export_filter_match_user_common(filter, user);
}
Ejemplo n.º 13
0
/* Compare using wildcards. */
static int equal_wildcard(const unsigned char *pattern, size_t pattern_len,
			  const unsigned char *subject, size_t subject_len)
	{
	const unsigned char *star = wildcard_find_star(pattern, pattern_len);
	if (star == NULL)
		return equal_nocase(pattern, pattern_len,
				    subject, subject_len);
	return wildcard_match(pattern, star - pattern,
			      star + 1, (pattern + pattern_len) - star - 1,
			      subject, subject_len);
	}
Ejemplo n.º 14
0
void wildcard_expander_t::expand_last_segment(const wcstring &base_dir, DIR *base_dir_fp,
                                              const wcstring &wc, const wcstring &prefix) {
    wcstring name_str;
    while (wreaddir(base_dir_fp, name_str)) {
        if (flags & EXPAND_FOR_COMPLETIONS) {
            this->try_add_completion_result(base_dir + name_str, name_str, wc, prefix);
        } else {
            // Normal wildcard expansion, not for completions.
            if (wildcard_match(name_str, wc, true /* skip files with leading dots */)) {
                this->add_expansion_result(base_dir + name_str);
            }
        }
    }
}
Ejemplo n.º 15
0
void safemode::set_rule( const rules_class rule_in, const std::string name_in, rule_state rs_in )
{
    static std::vector<Creature::Attitude> attitude_any = {{Creature::A_HOSTILE, Creature::A_NEUTRAL, Creature::A_FRIENDLY}};

    if( !rule_in.rule.empty() && rule_in.active && wildcard_match( name_in, rule_in.rule ) ) {
        if( rule_in.attitude == Creature::A_ANY ) {
            for( auto &att : attitude_any ) {
                safemode_rules[ name_in ][ att ] = rule_state_class( rs_in, rule_in.proximity );
            }
        } else {
            safemode_rules[ name_in ][ rule_in.attitude ] = rule_state_class( rs_in, rule_in.proximity );
        }
    }
}
Ejemplo n.º 16
0
/**************************************************************************************************
	CHECK_XFER
	If the "xfer" column exists in the soa table, it should contain a list of wildcards separated
	by commas.  In order for this zone transfer to continue, one of the wildcards must match
	the client's IP address.
**************************************************************************************************/
static void
check_xfer(TASK *t, MYDNS_SOA *soa) {
  SQL_RES	*res = NULL;
  SQL_ROW	row = NULL;
  char		ip[256];
  char		*query = NULL;
  size_t	querylen = 0;
  int		ok = 0;

  memset(&ip, 0, sizeof(ip));

  if (!mydns_soa_use_xfer)
    return;

  strncpy(ip, clientaddr(t), sizeof(ip)-1);

  querylen = sql_build_query(&query, "SELECT xfer FROM %s WHERE id=%u%s%s%s;",
			     mydns_soa_table_name, soa->id,
			     (mydns_rr_use_active)? " AND active='" : "",
			     (mydns_rr_use_active)? mydns_rr_active_types[0] : "",
			     (mydns_rr_use_active)? "'" : "");

  res = sql_query(sql, query, querylen);
  RELEASE(query);
  if (!res) {
    ErrSQL(sql, "%s: %s", desctask(t), _("error loading zone transfer access rules"));
  }

  if ((row = sql_getrow(res, NULL))) {
    char *wild = NULL, *r = NULL;

    for (r = row[0]; !ok && (wild = strsep(&r, ",")); )	{
      if (strchr(wild, '/')) {
	if (t->family == AF_INET)
	  ok = in_cidr(wild, t->addr4.sin_addr);
      }	else if (wildcard_match(wild, ip))
	ok = 1;
    }
  }
  sql_free(res);

  if (!ok) {
    dnserror(t, DNS_RCODE_REFUSED, ERR_NO_AXFR);
    axfr_reply(t);
    axfr_error(t, _("access denied"));
  }
}
Ejemplo n.º 17
0
static bool
mail_export_filter_match_domain(const struct mail_export_filter *filter,
				const struct mail_domain *domain)
{
	struct mail_user *user;

	if (filter->since > domain->last_update.tv_sec)
		return FALSE;
	if (filter->domain != NULL &&
	    !wildcard_match(domain->name, filter->domain))
		return FALSE;

	if (filter->user != NULL || filter->connected || filter->ip_bits > 0) {
		for (user = domain->users; user != NULL; user = user->domain_next) {
			if (mail_export_filter_match_user_common(filter, user))
				break;
		}
		if (user == NULL)
			return FALSE;
	}
	return TRUE;
}
Ejemplo n.º 18
0
/**************************************************************************************************
	MATCH_AFTER_STAR
	Recursively call wildcard_match() with final segment of PATTERN and of TEXT.
**************************************************************************************************/
static int
match_after_star(register char *p, register char *t)
{
	register int match = 0, nextp;

	while (*p == '?' || *p == '*')
	{
		if (*p == '?')
		{
			if (!*t++)
				return _WC_MATCH_ABORT;
		}
		p++;
	}

	if (!*p)
		return _WC_MATCH_VALID;

	nextp = *p;
	if (nextp == '\\')
	{
		nextp = p[1];

		if (!nextp)
			return _WC_MATCH_PATTERN;
	}

	do
	{
		if (nextp == *t || nextp == '[')
			match = wildcard_match(p, t);

		if (!*t++)
			match = _WC_MATCH_ABORT;
	}
	while (match != _WC_MATCH_VALID && match != _WC_MATCH_ABORT && match != _WC_MATCH_PATTERN);

	return match;
}
Ejemplo n.º 19
0
static int
client_input_replicate(struct doveadm_connection *client, const char *const *args)
{
	struct replicator_queue_iter *iter;
	struct replicator_user *user;
	const char *usermask;
	enum replication_priority priority;
	unsigned int match_count;

	/* <priority> <username>|<mask> */
	if (str_array_length(args) != 2) {
		i_error("%s: REPLICATE: Invalid parameters", client->conn.name);
		return -1;
	}
	if (replication_priority_parse(args[0], &priority) < 0) {
		o_stream_send_str(client->conn.output, "-Invalid priority\n");
		return 0;
	}
	usermask = args[1];
	if (strchr(usermask, '*') == NULL && strchr(usermask, '?') == NULL) {
		replicator_queue_add(client->queue, usermask, priority);
		o_stream_send_str(client->conn.output, "+1\n");
		return 0;
	}

	match_count = 0;
	iter = replicator_queue_iter_init(client->queue);
	while ((user = replicator_queue_iter_next(iter)) != NULL) {
		if (!wildcard_match(user->username, usermask))
			continue;
		replicator_queue_add(client->queue, user->username, priority);
		match_count++;
	}
	replicator_queue_iter_deinit(&iter);
	o_stream_send_str(client->conn.output,
			  t_strdup_printf("+%u\n", match_count));
	return 0;
}
Ejemplo n.º 20
0
/**
   The real implementation of wildcard expansion is in this
   function. Other functions are just wrappers around this one.

   This function traverses the relevant directory tree looking for
   matches, and recurses when needed to handle wildcrards spanning
   multiple components and recursive wildcards.

   Because this function calls itself recursively with substrings,
   it's important that the parameters be raw pointers instead of wcstring,
   which would be too expensive to construct for all substrings.
 */
static int wildcard_expand_internal(const wchar_t *wc,
                                    const wchar_t * const base_dir,
                                    expand_flags_t flags,
                                    std::vector<completion_t> *out,
                                    std::set<wcstring> &completion_set,
                                    std::set<file_id_t> &visited_files)
{
    /* Variables for traversing a directory */
    DIR *dir;

    /* The result returned */
    int res = 0;


    //  debug( 3, L"WILDCARD_EXPAND %ls in %ls", wc, base_dir );

    if (is_main_thread() ? reader_interrupted() : reader_thread_job_is_stale())
    {
        return -1;
    }

    if (!wc || !base_dir)
    {
        debug(2, L"Got null string on line %d of file %s", __LINE__, __FILE__);
        return 0;
    }

    const size_t base_dir_len = wcslen(base_dir);
    const size_t wc_len = wcslen(wc);

    if (flags & ACCEPT_INCOMPLETE)
    {
        /*
           Avoid excessive number of returned matches for wc ending with a *
        */
        if (wc_len > 0 && (wc[wc_len-1]==ANY_STRING))
        {
            wchar_t * foo = wcsdup(wc);
            foo[wc_len-1]=0;
            int res = wildcard_expand_internal(foo, base_dir, flags, out, completion_set, visited_files);
            free(foo);
            return res;
        }
    }

    /* Determine if we are the last segment */
    const wchar_t * const next_slash = wcschr(wc,L'/');
    const bool is_last_segment = (next_slash == NULL);
    const size_t wc_segment_len = next_slash ? next_slash - wc : wc_len;
    const wcstring wc_segment = wcstring(wc, wc_segment_len);
    
    /* Maybe this segment has no wildcards at all. If this is not the last segment, and it has no wildcards, then we don't need to match against the directory contents, and in fact we don't want to match since we may not be able to read it anyways (#2099). Don't even open the directory! */
    const bool segment_has_wildcards = wildcard_has(wc_segment, true /* internal, i.e. look for ANY_CHAR instead of ? */);
    if (! segment_has_wildcards && ! is_last_segment)
    {
        wcstring new_base_dir = make_path(base_dir, wc_segment);
        new_base_dir.push_back(L'/');
        
        /* Skip multiple separators */
        assert(next_slash != NULL);
        const wchar_t *new_wc = next_slash;
        while (*new_wc==L'/')
        {
            new_wc++;
        }
        /* Early out! */
        return wildcard_expand_internal(new_wc, new_base_dir.c_str(), flags, out, completion_set, visited_files);
    }
    
    /* Test for recursive match string in current segment */
    const bool is_recursive = (wc_segment.find(ANY_STRING_RECURSIVE) != wcstring::npos);
    

    const wchar_t *base_dir_or_cwd = (base_dir[0] == L'\0') ? L"." : base_dir;
    if (!(dir = wopendir(base_dir_or_cwd)))
    {
        return 0;
    }
    
    /*
      Is this segment of the wildcard the last?
    */
    if (is_last_segment)
    {
        /*
          Wildcard segment is the last segment,

          Insert all matching files/directories
        */
        if (wc[0]=='\0')
        {
            /*
              The last wildcard segment is empty. Insert everything if
              completing, the directory itself otherwise.
            */
            if (flags & ACCEPT_INCOMPLETE)
            {
                wcstring next;
                while (wreaddir(dir, next))
                {
                    if (next[0] != L'.')
                    {
                        wcstring long_name = make_path(base_dir, next);

                        if (test_flags(long_name.c_str(), flags))
                        {
                            wildcard_completion_allocate(out, long_name, next, L"", flags);
                        }
                    }
                }
            }
            else
            {
                res = 1;
                insert_completion_if_missing(base_dir, out, &completion_set);
            }
        }
        else
        {
            /* This is the last wildcard segment, and it is not empty. Match files/directories. */
            wcstring name_str;
            while (wreaddir(dir, name_str))
            {
                if (flags & ACCEPT_INCOMPLETE)
                {

                    const wcstring long_name = make_path(base_dir, name_str);

                    /* Test for matches before stating file, so as to minimize the number of calls to the much slower stat function. The only expand flag we care about is EXPAND_FUZZY_MATCH; we have no complete flags. */
                    std::vector<completion_t> test;
                    if (wildcard_complete(name_str, wc, L"", NULL, &test, flags & EXPAND_FUZZY_MATCH, 0))
                    {
                        if (test_flags(long_name.c_str(), flags))
                        {
                            wildcard_completion_allocate(out, long_name, name_str, wc, flags);

                        }
                    }
                }
                else
                {
                    if (wildcard_match(name_str, wc, true /* skip files with leading dots */))
                    {
                        const wcstring long_name = make_path(base_dir, name_str);
                        int skip = 0;

                        if (is_recursive)
                        {
                            /*
                              In recursive mode, we are only
                              interested in adding files -directories
                              will be added in the next pass.
                            */
                            struct stat buf;
                            if (!wstat(long_name, &buf))
                            {
                                skip = S_ISDIR(buf.st_mode);
                            }
                        }
                        if (! skip)
                        {
                            insert_completion_if_missing(long_name, out, &completion_set);
                        }
                        res = 1;
                    }
                }
            }
        }
    }

    if ((! is_last_segment) || is_recursive)
    {
        /*
          Wilcard segment is not the last segment.  Recursively call
          wildcard_expand for all matching subdirectories.
        */

        /*
          In recursive mode, we look through the directory twice. If
          so, this rewind is needed.
        */
        rewinddir(dir);

        /* new_dir is a scratch area containing the full path to a file/directory we are iterating over */
        wcstring new_dir = base_dir;

        wcstring name_str;
        while (wreaddir(dir, name_str))
        {
            /*
              Test if the file/directory name matches the whole
              wildcard element, i.e. regular matching.
            */
            bool whole_match = wildcard_match(name_str, wc_segment, true /* ignore leading dots */);
            bool partial_match = false;

            /*
               If we are doing recursive matching, also check if this
               directory matches the part up to the recusrive
               wildcard, if so, then we can search all subdirectories
               for matches.
            */
            if (is_recursive)
            {
                const wchar_t *end = wcschr(wc, ANY_STRING_RECURSIVE);
                wchar_t *wc_sub = wcsndup(wc, end-wc+1);
                partial_match = wildcard_match(name_str, wc_sub, true /* ignore leading dots */);
                free(wc_sub);
            }

            if (whole_match || partial_match)
            {
                struct stat buf;
                int new_res;

                // new_dir is base_dir + some other path components
                // Replace everything after base_dir with the new path component
                new_dir.replace(base_dir_len, wcstring::npos, name_str);

                int stat_res = wstat(new_dir, &buf);

                if (!stat_res)
                {
                    // Insert a "file ID" into visited_files
                    // If the insertion fails, we've already visited this file (i.e. a symlink loop)
                    // If we're not recursive, insert anyways (in case we loop back around in a future recursive segment), but continue on; the idea being that literal path components should still work
                    const file_id_t file_id = file_id_t::file_id_from_stat(&buf);
                    if (S_ISDIR(buf.st_mode) && (visited_files.insert(file_id).second || ! is_recursive))
                    {
                        new_dir.push_back(L'/');

                        /*
                          Regular matching
                        */
                        if (whole_match)
                        {
                            const wchar_t *new_wc = L"";
                            if (next_slash)
                            {
                                new_wc=next_slash+1;
                                /*
                                  Accept multiple '/' as a single directory separator
                                */
                                while (*new_wc==L'/')
                                {
                                    new_wc++;
                                }
                            }

                            new_res = wildcard_expand_internal(new_wc,
                                                               new_dir.c_str(),
                                                               flags,
                                                               out,
                                                               completion_set,
                                                               visited_files);

                            if (new_res == -1)
                            {
                                res = -1;
                                break;
                            }
                            res |= new_res;

                        }

                        /*
                          Recursive matching
                        */
                        if (partial_match)
                        {

                            new_res = wildcard_expand_internal(wcschr(wc, ANY_STRING_RECURSIVE),
                                                               new_dir.c_str(),
                                                               flags | WILDCARD_RECURSIVE,
                                                               out,
                                                               completion_set,
                                                               visited_files);

                            if (new_res == -1)
                            {
                                res = -1;
                                break;
                            }
                            res |= new_res;

                        }
                    }
                }
            }
        }
    }
    closedir(dir);

    return res;
}
Ejemplo n.º 21
0
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
// show crate status, using crates in 'crate.db' file
//-------------------------------------------------------------------------
int ShowCrate()
{
	char			colorENH[9], colorON[9];
	char tmp[7]; char tmp2[11];
	int				enhanced, i, j, online, moduleFound, numOfCrates, numOfModules;
	int				crateStatus;
	int				status;
	struct Crate_	Cr8, *pCr8;
	struct Module_	Mod, *pMod;

	static DESCRIPTOR( crate_p,  "MODULE" );
	static DESCRIPTOR( heading1, " CRATE   ONL LAM PRV ENH" );
	static DESCRIPTOR( heading2, "=======  === === === ===" );

	static DYNAMIC_DESCRIPTOR( wild );
	static DYNAMIC_DESCRIPTOR( crate );

	if( ScsiSystemStatus() == 0 ) {
		status = SUCCESS;			// this is the function's status
		printf("scsi system is %sdown!%s\n", RED, NORMAL);
		goto ShowCrate_Exit;
	}
	if( MSGLVL(DETAILS) ) printf("scsi system is %sup!%s\n", GREEN, NORMAL);

	// user input
	cli_get_value( &crate_p, &wild );
	str_upcase( &wild, &wild );

	// check to see if crate db file memory mapped
	if( CRATEdbFileIsMapped == FALSE ) {				// is not, so try
		if( map_data_file(CRATE_DB) != SUCCESS ) {		// we're dead in the water
			if( MSGLVL(IMPORTANT) )
				fprintf( stderr, "error memory mapping crate.db file\n" );

			status = FAILURE;		// MAP_ERROR;		[2001.07.12]
			goto ShowCrate_Exit;
		}
	}

	// check to see if module db file memory mapped
	if( CTSdbFileIsMapped == FALSE ) {					// is not, so try
		if( map_data_file(CTS_DB) != SUCCESS ) {		// we're dead in the water
			if( MSGLVL(IMPORTANT) )
				fprintf( stderr, "error memory mapping cts.db file\n" );

			status = FAILURE;		// MAP_ERROR;		[2001.07.12]
			goto ShowCrate_Exit;
		}
	}

	printf( "%s\n", heading1.pointer );					// header
	printf( "%s\n", heading2.pointer );					// header

	pCr8 = &Cr8;										// point to some actual storage
	pMod = &Mod;

	// get number of crates in db file
	if( (numOfCrates = get_file_count(CRATE_DB)) > 0 ) {	// possibly something to show
		if( (numOfModules = get_file_count(CTS_DB)) > 0 ) {	// maybe some crates controllers ..
			for( i = 0; i < numOfCrates; i++ ) {
				parse_crate_db(CRATEdb+i, pCr8);
				if(  wildcard_match( wild.pointer, pCr8->name, 0,0,0 ) ) {
				  //					moduleFound = FALSE;
				  //
				  //					for( j = 0; j < numOfModules; ++j ) {
				  //						parse_cts_db(CTSdb+j, pMod);
				  //						sprintf(tmp, "GK%c%d%02d",
				  //							pMod->adapter + 'A',
				  //							pMod->id,
				  //							pMod->crate
				  //							);
				  //
				  //						if( strcmp(tmp, pCr8->name) == EQUAL ) {
				  //							if( pMod->slot == 30 ) {	// found a crate controller
				  //								moduleFound = TRUE;
				  //								break;
				  //							}
				  //						}
				  //					} // end of for(modules) ...
				  moduleFound = TRUE;
				  if( moduleFound ) {
				    crateStatus = 0;
				    
				    if(MSGLVL(8)) 
				      printf("checking '%s'\n", pCr8->name);
				    
				    status = get_crate_status(pCr8->name, &crateStatus);
				    
				    if( MSGLVL(DETAILS) )
				      printf("gcs(%s) returned %d, crate 0x%x\n", pCr8->name, status, crateStatus);
				    
				    if( status == SUCCESS ) {
				      //							online = !(crateStatus & 0x3c00)    ? TRUE  : FALSE;				// [2002.12.09]
				      //							online = !(crateStatus & 0x1000)    ? TRUE  : FALSE;				// [2002.12.09]
				      online = ((crateStatus & 0x1000) != 0x1000)    ? TRUE  : FALSE;				// [2002.12.09]
				      if( !crateStatus || crateStatus == 0x3 )	// [2001.09.10]			// [2002.12.09]
					online = FALSE;													// [2002.12.09]
				      sprintf(colorON,  "%s", (online)    ? GREEN : RED);
				      
				      //							enhanced = (online && (crateStatus & 0x4030)) ? TRUE  : FALSE;		// [2002.12.09]
				      enhanced = (online && (crateStatus & 0x4000)) ? TRUE  : FALSE;		// [2002.12.09]
				      sprintf(colorENH, "%s", (enhanced)  ? GREEN : RED);
				      
				      printf("%s:   %s%c%s   .   .   %s%c%s",
					     pCr8->name,
					     colorON,  (online)   ? '*' : 'X', NORMAL,
					     colorENH, (enhanced) ? '*' : '-', NORMAL
					     );
				      if( MSGLVL(4) )
					printf( "  0x%04x", crateStatus );
				      printf("\n");
				    }
				  } // end of if(moduleFound) ...
				  else {
				    printf("%.6s:   .   .   .   .\n", pCr8->name);
				  }
				} // end of if(wildcard) ...
			} // end of for(crates) ...
		} // crates, but no modules (ie no controllers)
	}
	printf( "%s\n", heading2.pointer );					// header

	status = SUCCESS;		// always (???)

ShowCrate_Exit:
	return status;
}
Ejemplo n.º 22
0
void tftp_request(struct listener *listen, time_t now)
{
  ssize_t len;
  char *packet = daemon->packet;
  char *filename, *mode, *p, *end, *opt;
  union mysockaddr addr, peer;
  struct msghdr msg;
  struct iovec iov;
  struct ifreq ifr;
  int is_err = 1, if_index = 0, mtu = 0;
  struct iname *tmp;
  struct tftp_transfer *transfer;
  int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
  int mtuflag = IP_PMTUDISC_DONT;
#endif
  char namebuff[IF_NAMESIZE];
  char *name = NULL;
  char *prefix = daemon->tftp_prefix;
  struct tftp_prefix *pref;
  union all_addr addra;
  /* Can always get recvd interface for IPv6 */
  int check_dest = !option_bool(OPT_NOWILD) || listen->family == AF_INET6;
  union {
    struct cmsghdr align; /* this ensures alignment */
    char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
#if defined(HAVE_LINUX_NETWORK)
    char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
#elif defined(HAVE_SOLARIS_NETWORK)
    char control[CMSG_SPACE(sizeof(unsigned int))];
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
    char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
#endif
  } control_u; 

  msg.msg_controllen = sizeof(control_u);
  msg.msg_control = control_u.control;
  msg.msg_flags = 0;
  msg.msg_name = &peer;
  msg.msg_namelen = sizeof(peer);
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;

  iov.iov_base = packet;
  iov.iov_len = daemon->packet_buff_sz;

  /* we overwrote the buffer... */
  daemon->srv_save = NULL;

  if ((len = recvmsg(listen->tftpfd, &msg, 0)) < 2)
    return;

  /* Can always get recvd interface for IPv6 */
  if (!check_dest)
    {
      if (listen->iface)
	{
	  addr = listen->iface->addr;
	  name = listen->iface->name;
	  mtu = listen->iface->mtu;
	  if (daemon->tftp_mtu != 0 && daemon->tftp_mtu < mtu)
	    mtu = daemon->tftp_mtu;
	}
      else
	{
	  /* we're listening on an address that doesn't appear on an interface,
	     ask the kernel what the socket is bound to */
	  socklen_t tcp_len = sizeof(union mysockaddr);
	  if (getsockname(listen->tftpfd, (struct sockaddr *)&addr, &tcp_len) == -1)
	    return;
	}
    }
  else
    {
      struct cmsghdr *cmptr;

      if (msg.msg_controllen < sizeof(struct cmsghdr))
        return;
      
      addr.sa.sa_family = listen->family;
      
#if defined(HAVE_LINUX_NETWORK)
      if (listen->family == AF_INET)
	for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
	  if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
	    {
	      union {
		unsigned char *c;
		struct in_pktinfo *p;
	      } p;
	      p.c = CMSG_DATA(cmptr);
	      addr.in.sin_addr = p.p->ipi_spec_dst;
	      if_index = p.p->ipi_ifindex;
	    }
      
#elif defined(HAVE_SOLARIS_NETWORK)
      if (listen->family == AF_INET)
	for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
	  {
	    union {
	      unsigned char *c;
	      struct in_addr *a;
	      unsigned int *i;
	    } p;
	    p.c = CMSG_DATA(cmptr);
	    if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
	    addr.in.sin_addr = *(p.a);
	    else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
	    if_index = *(p.i);
	  }
      
#elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF)
      if (listen->family == AF_INET)
	for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
	  {
	    union {
	      unsigned char *c;
	      struct in_addr *a;
	      struct sockaddr_dl *s;
	    } p;
	    p.c = CMSG_DATA(cmptr);
	    if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR)
	      addr.in.sin_addr = *(p.a);
	    else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
	      if_index = p.s->sdl_index;
	  }
	  
#endif

      if (listen->family == AF_INET6)
        {
          for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
            if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
              {
                union {
                  unsigned char *c;
                  struct in6_pktinfo *p;
                } p;
                p.c = CMSG_DATA(cmptr);
                  
                addr.in6.sin6_addr = p.p->ipi6_addr;
                if_index = p.p->ipi6_ifindex;
              }
        }
      
      if (!indextoname(listen->tftpfd, if_index, namebuff))
	return;

      name = namebuff;
      
      addra.addr4 = addr.in.sin_addr;

      if (listen->family == AF_INET6)
	addra.addr6 = addr.in6.sin6_addr;

      if (daemon->tftp_interfaces)
	{
	  /* dedicated tftp interface list */
	  for (tmp = daemon->tftp_interfaces; tmp; tmp = tmp->next)
	    if (tmp->name && wildcard_match(tmp->name, name))
	      break;

	  if (!tmp)
	    return;
	}
      else
	{
	  /* Do the same as DHCP */
	  if (!iface_check(listen->family, &addra, name, NULL))
	    {
	      if (!option_bool(OPT_CLEVERBIND))
		enumerate_interfaces(0); 
	      if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) &&
		  !label_exception(if_index, listen->family, &addra))
		return;
	    }
	  
#ifdef HAVE_DHCP      
	  /* allowed interfaces are the same as for DHCP */
	  for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
	    if (tmp->name && wildcard_match(tmp->name, name))
	      return;
#endif
	}

      safe_strncpy(ifr.ifr_name, name, IF_NAMESIZE);
      if (ioctl(listen->tftpfd, SIOCGIFMTU, &ifr) != -1)
	{
	  mtu = ifr.ifr_mtu;  
	  if (daemon->tftp_mtu != 0 && daemon->tftp_mtu < mtu)
	    mtu = daemon->tftp_mtu;    
	}
    }

  /* Failed to get interface mtu - can use configured value. */
  if (mtu == 0)
    mtu = daemon->tftp_mtu;

  if (name)
    {
      /* check for per-interface prefix */ 
      for (pref = daemon->if_prefix; pref; pref = pref->next)
	if (strcmp(pref->interface, name) == 0)
	  prefix = pref->prefix;  
    }

  if (listen->family == AF_INET)
    {
      addr.in.sin_port = htons(port);
#ifdef HAVE_SOCKADDR_SA_LEN
      addr.in.sin_len = sizeof(addr.in);
#endif
    }
  else
    {
      addr.in6.sin6_port = htons(port);
      addr.in6.sin6_flowinfo = 0;
      addr.in6.sin6_scope_id = 0;
#ifdef HAVE_SOCKADDR_SA_LEN
      addr.in6.sin6_len = sizeof(addr.in6);
#endif
    }

  if (!(transfer = whine_malloc(sizeof(struct tftp_transfer))))
    return;
  
  if ((transfer->sockfd = socket(listen->family, SOCK_DGRAM, 0)) == -1)
    {
      free(transfer);
      return;
    }
  
  transfer->peer = peer;
  transfer->timeout = now + 2;
  transfer->backoff = 1;
  transfer->block = 1;
  transfer->blocksize = 512;
  transfer->offset = 0;
  transfer->file = NULL;
  transfer->opt_blocksize = transfer->opt_transize = 0;
  transfer->netascii = transfer->carrylf = 0;
 
  prettyprint_addr(&peer, daemon->addrbuff);
  
  /* if we have a nailed-down range, iterate until we find a free one. */
  while (1)
    {
      if (bind(transfer->sockfd, &addr.sa, sa_len(&addr)) == -1 ||
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
	  setsockopt(transfer->sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &mtuflag, sizeof(mtuflag)) == -1 ||
#endif
	  !fix_fd(transfer->sockfd))
	{
	  if (errno == EADDRINUSE && daemon->start_tftp_port != 0)
	    {
	      if (++port <= daemon->end_tftp_port)
		{ 
		  if (listen->family == AF_INET)
		    addr.in.sin_port = htons(port);
		  else
		    addr.in6.sin6_port = htons(port);
		  
		  continue;
		}
	      my_syslog(MS_TFTP | LOG_ERR, _("unable to get free port for TFTP"));
	    }
	  free_transfer(transfer);
	  return;
	}
      break;
    }
  
  p = packet + 2;
  end = packet + len;

  if (ntohs(*((unsigned short *)packet)) != OP_RRQ ||
      !(filename = next(&p, end)) ||
      !(mode = next(&p, end)) ||
      (strcasecmp(mode, "octet") != 0 && strcasecmp(mode, "netascii") != 0))
    {
      len = tftp_err(ERR_ILL, packet, _("unsupported request from %s"), daemon->addrbuff);
      is_err = 1;
    }
  else
    {
      if (strcasecmp(mode, "netascii") == 0)
	transfer->netascii = 1;
      
      while ((opt = next(&p, end)))
	{
	  if (strcasecmp(opt, "blksize") == 0)
	    {
	      if ((opt = next(&p, end)) && !option_bool(OPT_TFTP_NOBLOCK))
		{
		  /* 32 bytes for IP, UDP and TFTP headers, 52 bytes for IPv6 */
		  int overhead = (listen->family == AF_INET) ? 32 : 52;
		  transfer->blocksize = atoi(opt);
		  if (transfer->blocksize < 1)
		    transfer->blocksize = 1;
		  if (transfer->blocksize > (unsigned)daemon->packet_buff_sz - 4)
		    transfer->blocksize = (unsigned)daemon->packet_buff_sz - 4;
		  if (mtu != 0 && transfer->blocksize > (unsigned)mtu - overhead)
		    transfer->blocksize = (unsigned)mtu - overhead;
		  transfer->opt_blocksize = 1;
		  transfer->block = 0;
		}
	    }
	  else if (strcasecmp(opt, "tsize") == 0 && next(&p, end) && !transfer->netascii)
	    {
	      transfer->opt_transize = 1;
	      transfer->block = 0;
	    }
	}

      /* cope with backslashes from windows boxen. */
      for (p = filename; *p; p++)
	if (*p == '\\')
	  *p = '/';
	else if (option_bool(OPT_TFTP_LC))
	  *p = tolower(*p);
		
      strcpy(daemon->namebuff, "/");
      if (prefix)
	{
	  if (prefix[0] == '/')
	    daemon->namebuff[0] = 0;
	  strncat(daemon->namebuff, prefix, (MAXDNAME-1) - strlen(daemon->namebuff));
	  if (prefix[strlen(prefix)-1] != '/')
	    strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));

	  if (option_bool(OPT_TFTP_APREF_IP))
	    {
	      size_t oldlen = strlen(daemon->namebuff);
	      struct stat statbuf;
	      
	      strncat(daemon->namebuff, daemon->addrbuff, (MAXDNAME-1) - strlen(daemon->namebuff));
	      strncat(daemon->namebuff, "/", (MAXDNAME-1) - strlen(daemon->namebuff));
	      
	      /* remove unique-directory if it doesn't exist */
	      if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
		daemon->namebuff[oldlen] = 0;
	    }
	  
	  if (option_bool(OPT_TFTP_APREF_MAC))
	    {
	      unsigned char *macaddr = NULL;
	      unsigned char macbuf[DHCP_CHADDR_MAX];
	      
#ifdef HAVE_DHCP
	      if (daemon->dhcp && peer.sa.sa_family == AF_INET)
	        {
		  /* Check if the client IP is in our lease database */
		  struct dhcp_lease *lease = lease_find_by_addr(peer.in.sin_addr);
		  if (lease && lease->hwaddr_type == ARPHRD_ETHER && lease->hwaddr_len == ETHER_ADDR_LEN)
		    macaddr = lease->hwaddr;
		}
#endif
	      
	      /* If no luck, try to find in ARP table. This only works if client is in same (V)LAN */
	      if (!macaddr && find_mac(&peer, macbuf, 1, now) > 0)
		macaddr = macbuf;
	      
	      if (macaddr)
	        {
		  size_t oldlen = strlen(daemon->namebuff);
		  struct stat statbuf;

		  snprintf(daemon->namebuff + oldlen, (MAXDNAME-1) - oldlen, "%.2x-%.2x-%.2x-%.2x-%.2x-%.2x/",
			   macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]);
		  
		  /* remove unique-directory if it doesn't exist */
		  if (stat(daemon->namebuff, &statbuf) == -1 || !S_ISDIR(statbuf.st_mode))
		    daemon->namebuff[oldlen] = 0;
		}
	    }
	  
	  /* Absolute pathnames OK if they match prefix */
	  if (filename[0] == '/')
	    {
	      if (strstr(filename, daemon->namebuff) == filename)
		daemon->namebuff[0] = 0;
	      else
		filename++;
	    }
	}
      else if (filename[0] == '/')
	daemon->namebuff[0] = 0;
      strncat(daemon->namebuff, filename, (MAXDNAME-1) - strlen(daemon->namebuff));
      
      /* check permissions and open file */
      if ((transfer->file = check_tftp_fileperm(&len, prefix)))
	{
	  if ((len = get_block(packet, transfer)) == -1)
	    len = tftp_err_oops(packet, daemon->namebuff);
	  else
	    is_err = 0;
	}
    }
  
  while (sendto(transfer->sockfd, packet, len, 0, 
		(struct sockaddr *)&peer, sa_len(&peer)) == -1 && errno == EINTR);
  
  if (is_err)
    free_transfer(transfer);
  else
    {
      transfer->next = daemon->tftp_trans;
      daemon->tftp_trans = transfer;
    }
}
Ejemplo n.º 23
0
int complete_is_valid_option( const wchar_t *str,
							  const wchar_t *opt,
							  array_list_t *errors )
{
	complete_entry_t *i;
	complete_entry_opt_t *o;
	wchar_t *cmd, *path;
	int found_match = 0;
	int authoritative = 1;
	int opt_found=0;
	hash_table_t gnu_match_hash;
	int is_gnu_opt=0;
	int is_old_opt=0;
	int is_short_opt=0;
	int is_gnu_exact=0;
	int gnu_opt_len=0;
	char *short_validated;

	void *context;

	CHECK( str, 0 );
	CHECK( opt, 0 );

	/*
	  Check some generic things like -- and - options.
	*/
	switch( wcslen(opt ) )
	{

		case 0:
		case 1:
		{
			return 1;
		}

		case 2:
		{
			if( wcscmp( L"--", opt ) == 0 )
			{
				return 1;
			}
			break;
		}
	}

	if( opt[0] != L'-' )
	{
		if( errors )
		{
			al_push( errors, wcsdup(L"Option does not begin with a '-'") );
		}
		return 0;
	}

	context = halloc( 0, 0 );

	if( !(short_validated = halloc( context, wcslen( opt ) )))
	{
		DIE_MEM();
	}



	memset( short_validated, 0, wcslen( opt ) );

	hash_init( &gnu_match_hash,
			   &hash_wcs_func,
			   &hash_wcs_cmp );

	is_gnu_opt = opt[1]==L'-';
	if( is_gnu_opt )
	{
		wchar_t *opt_end = wcschr(opt, L'=' );
		if( opt_end )
		{
			gnu_opt_len = (opt_end-opt)-2;
		}
		else
		{
			gnu_opt_len = wcslen(opt)-2;
		}
	}

	parse_cmd_string( context, str, &path, &cmd );

	/*
	  Make sure completions are loaded for the specified command
	*/
	complete_load( cmd, 0 );

	for( i=first_entry; i; i=i->next )
	{
		wchar_t *match = i->cmd_type?path:cmd;
		const wchar_t *a;

		if( !wildcard_match( match, i->cmd ) )
		{
			continue;
		}

		found_match = 1;

		if( !i->authoritative )
		{
			authoritative = 0;
			break;
		}


		if( is_gnu_opt )
		{

			for( o = i->first_option; o; o=o->next )
			{
				if( o->old_mode )
				{
					continue;
				}

				if( wcsncmp( &opt[2], o->long_opt, gnu_opt_len )==0)
				{
					hash_put( &gnu_match_hash, o->long_opt, L"" );
					if( (wcsncmp( &opt[2],
								  o->long_opt,
								  wcslen( o->long_opt) )==0) )
					{
						is_gnu_exact=1;
					}
				}
			}
		}
		else
		{
			/* Check for old style options */
			for( o = i->first_option; o; o=o->next )
			{
				if( !o->old_mode )
					continue;


				if( wcscmp( &opt[1], o->long_opt )==0)
				{
					opt_found = 1;
					is_old_opt = 1;
					break;
				}

			}

			if( is_old_opt )
				break;


			for( a = &opt[1]; *a; a++ )
			{

				wchar_t *str_pos = wcschr(i->short_opt_str, *a);

				if  (str_pos )
				{
					if( *(str_pos +1)==L':' )
					{
						/*
						  This is a short option with an embedded argument,
						  call complete_is_valid_argument on the argument.
						*/
						wchar_t nopt[3];
						nopt[0]=L'-';
						nopt[1]=opt[1];
						nopt[2]=L'\0';

						short_validated[a-opt] =
							complete_is_valid_argument( str, nopt, &opt[2]);
					}
					else
					{
						short_validated[a-opt]=1;
					}
				}
			}
		}
	}

	if( authoritative )
	{

		if( !is_gnu_opt && !is_old_opt )
			is_short_opt = 1;


		if( is_short_opt )
		{
			int j;

			opt_found=1;
			for( j=1; j<wcslen(opt); j++)
			{
				if ( !short_validated[j])
				{
					if( errors )
					{
						wchar_t str[2];
						str[0] = opt[j];
						str[1]=0;
						al_push( errors,
								 wcsdupcat(_( L"Unknown option: " ), L"'", str, L"'" ) );
					}

					opt_found = 0;
					break;
				}

			}
		}

		if( is_gnu_opt )
		{
			opt_found = is_gnu_exact || (hash_get_count( &gnu_match_hash )==1);
			if( errors && !opt_found )
			{
				if( hash_get_count( &gnu_match_hash )==0)
				{
					al_push( errors,
							 wcsdupcat( _(L"Unknown option: "), L"'", opt, L"\'" ) );
				}
				else
				{
					al_push( errors,
							 wcsdupcat( _(L"Multiple matches for option: "), L"'", opt, L"\'" ) );
				}
			}
		}
	}

	hash_destroy( &gnu_match_hash );

	halloc_free( context );

	return (authoritative && found_match)?opt_found:1;
}
Ejemplo n.º 24
0
void dhcp_packet(time_t now, int pxe_fd)
{
  int fd = pxe_fd ? daemon->pxefd : daemon->dhcpfd;
  struct dhcp_packet *mess;
  struct dhcp_context *context;
  struct dhcp_relay *relay;
  int is_relay_reply = 0;
  struct iname *tmp;
  struct ifreq ifr;
  struct msghdr msg;
  struct sockaddr_in dest;
  struct cmsghdr *cmptr;
  struct iovec iov;
  ssize_t sz; 
  int iface_index = 0, unicast_dest = 0, is_inform = 0;
  struct in_addr iface_addr;
  struct iface_param parm;
#ifdef HAVE_LINUX_NETWORK
  struct arpreq arp_req;
#endif
  
  union {
    struct cmsghdr align; /* this ensures alignment */
#if defined(HAVE_LINUX_NETWORK)
    char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
#elif defined(HAVE_SOLARIS_NETWORK)
    char control[CMSG_SPACE(sizeof(unsigned int))];
#elif defined(HAVE_BSD_NETWORK) 
    char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
#endif
  } control_u;
  struct dhcp_bridge *bridge, *alias;

  msg.msg_controllen = sizeof(control_u);
  msg.msg_control = control_u.control;
  msg.msg_name = &dest;
  msg.msg_namelen = sizeof(dest);
  msg.msg_iov = &daemon->dhcp_packet;
  msg.msg_iovlen = 1;
  
  if ((sz = recv_dhcp_packet(fd, &msg)) == -1 || 
      (sz < (ssize_t)(sizeof(*mess) - sizeof(mess->options)))) 
    return;
    
  #if defined (HAVE_LINUX_NETWORK)
  if (msg.msg_controllen >= sizeof(struct cmsghdr))
    for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
      if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO)
	{
	  union {
	    unsigned char *c;
	    struct in_pktinfo *p;
	  } p;
	  p.c = CMSG_DATA(cmptr);
	  iface_index = p.p->ipi_ifindex;
	  if (p.p->ipi_addr.s_addr != INADDR_BROADCAST)
	    unicast_dest = 1;
	}

#elif defined(HAVE_BSD_NETWORK) 
  if (msg.msg_controllen >= sizeof(struct cmsghdr))
    for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
      if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
        {
	  union {
            unsigned char *c;
            struct sockaddr_dl *s;
          } p;
	  p.c = CMSG_DATA(cmptr);
	  iface_index = p.s->sdl_index;
	}
  
#elif defined(HAVE_SOLARIS_NETWORK) 
  if (msg.msg_controllen >= sizeof(struct cmsghdr))
    for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
      if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
	{
	  union {
	    unsigned char *c;
	    unsigned int *i;
	  } p;
	  p.c = CMSG_DATA(cmptr);
	  iface_index = *(p.i);
	}
#endif
	
  if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name))
    return;

#ifdef HAVE_LINUX_NETWORK
  /* ARP fiddling uses original interface even if we pretend to use a different one. */
  strncpy(arp_req.arp_dev, ifr.ifr_name, 16);
#endif 

  /* If the interface on which the DHCP request was received is an
     alias of some other interface (as specified by the
     --bridge-interface option), change ifr.ifr_name so that we look
     for DHCP contexts associated with the aliased interface instead
     of with the aliasing one. */
  for (bridge = daemon->bridges; bridge; bridge = bridge->next)
    {
      for (alias = bridge->alias; alias; alias = alias->next)
	if (wildcard_matchn(alias->iface, ifr.ifr_name, IF_NAMESIZE))
	  {
	    if (!(iface_index = if_nametoindex(bridge->iface)))
	      {
		my_syslog(MS_DHCP | LOG_WARNING,
			  _("unknown interface %s in bridge-interface"),
			  bridge->iface);
		return;
	      }
	    else 
	      {
		strncpy(ifr.ifr_name,  bridge->iface, IF_NAMESIZE);
		break;
	      }
	  }
      
      if (alias)
	break;
    }

#ifdef MSG_BCAST
  /* OpenBSD tells us when a packet was broadcast */
  if (!(msg.msg_flags & MSG_BCAST))
    unicast_dest = 1;
#endif
  
  if ((relay = relay_reply4((struct dhcp_packet *)daemon->dhcp_packet.iov_base, ifr.ifr_name)))
    {
      /* Reply from server, using us as relay. */
      iface_index = relay->iface_index;
      if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name))
	return;
      is_relay_reply = 1; 
      iov.iov_len = sz;
#ifdef HAVE_LINUX_NETWORK
      strncpy(arp_req.arp_dev, ifr.ifr_name, 16);
#endif 
    }
  else
    {
      ifr.ifr_addr.sa_family = AF_INET;
      if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 )
	iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
      else
	{
	  my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
	  return;
	}
      
      for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
	if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
	  return;
      
      /* unlinked contexts/relays are marked by context->current == context */
      for (context = daemon->dhcp; context; context = context->next)
	context->current = context;
      
      for (relay = daemon->relay4; relay; relay = relay->next)
	relay->current = relay;
      
      parm.current = NULL;
      parm.relay = NULL;
      parm.relay_local.s_addr = 0;
      parm.ind = iface_index;
      
      if (!iface_check(AF_INET, (struct all_addr *)&iface_addr, ifr.ifr_name, NULL))
	{
	  /* If we failed to match the primary address of the interface, see if we've got a --listen-address
	     for a secondary */
	  struct match_param match;
	  
	  match.matched = 0;
	  match.ind = iface_index;
	  
	  if (!daemon->if_addrs ||
	      !iface_enumerate(AF_INET, &match, check_listen_addrs) ||
	      !match.matched)
	    return;
	  
	  iface_addr = match.addr;
	  /* make sure secondary address gets priority in case
	     there is more than one address on the interface in the same subnet */
	  complete_context(match.addr, iface_index, NULL, match.netmask, match.broadcast, &parm);
	}    
      
      if (!iface_enumerate(AF_INET, &parm, complete_context))
	return;

      /* We're relaying this request */
      if  (parm.relay_local.s_addr != 0 &&
	   relay_upstream4(parm.relay, (struct dhcp_packet *)daemon->dhcp_packet.iov_base, (size_t)sz, iface_index))
	return;

      /* May have configured relay, but not DHCP server */
      if (!daemon->dhcp)
	return;

      lease_prune(NULL, now); /* lose any expired leases */
      iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz, 
			       now, unicast_dest, &is_inform, pxe_fd, iface_addr);
      lease_update_file(now);
      lease_update_dns(0);
      
      if (iov.iov_len == 0)
	return;
    }
  
  msg.msg_name = &dest;
  msg.msg_namelen = sizeof(dest);
  msg.msg_control = NULL;
  msg.msg_controllen = 0;
  msg.msg_iov = &iov;
  iov.iov_base = daemon->dhcp_packet.iov_base;
  
  /* packet buffer may have moved */
  mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
  
#ifdef HAVE_SOCKADDR_SA_LEN
  dest.sin_len = sizeof(struct sockaddr_in);
#endif
  
  if (pxe_fd)
    { 
      if (mess->ciaddr.s_addr != 0)
	dest.sin_addr = mess->ciaddr;
    }
  else if (mess->giaddr.s_addr && !is_relay_reply)
    {
      /* Send to BOOTP relay  */
      dest.sin_port = htons(daemon->dhcp_server_port);
      dest.sin_addr = mess->giaddr; 
    }
  else if (mess->ciaddr.s_addr)
    {
      /* If the client's idea of its own address tallys with
	 the source address in the request packet, we believe the
	 source port too, and send back to that.  If we're replying 
	 to a DHCPINFORM, trust the source address always. */
      if ((!is_inform && dest.sin_addr.s_addr != mess->ciaddr.s_addr) ||
	  dest.sin_port == 0 || dest.sin_addr.s_addr == 0 || is_relay_reply)
	{
	  dest.sin_port = htons(daemon->dhcp_client_port); 
	  dest.sin_addr = mess->ciaddr;
	}
    } 
#if defined(HAVE_LINUX_NETWORK)
  else
    {
      /* fill cmsg for outbound interface (both broadcast & unicast) */
      struct in_pktinfo *pkt;
      msg.msg_control = control_u.control;
      msg.msg_controllen = sizeof(control_u);
      cmptr = CMSG_FIRSTHDR(&msg);
      pkt = (struct in_pktinfo *)CMSG_DATA(cmptr);
      pkt->ipi_ifindex = iface_index;
      pkt->ipi_spec_dst.s_addr = 0;
      msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
      cmptr->cmsg_level = IPPROTO_IP;
      cmptr->cmsg_type = IP_PKTINFO;

      if ((ntohs(mess->flags) & 0x8000) || mess->hlen == 0 ||
         mess->hlen > sizeof(ifr.ifr_addr.sa_data) || mess->htype == 0)
        {
          /* broadcast to 255.255.255.255 (or mac address invalid) */
          dest.sin_addr.s_addr = INADDR_BROADCAST;
          dest.sin_port = htons(daemon->dhcp_client_port);
        }
      else
        {
          /* unicast to unconfigured client. Inject mac address direct into ARP cache.
          struct sockaddr limits size to 14 bytes. */
          dest.sin_addr = mess->yiaddr;
          dest.sin_port = htons(daemon->dhcp_client_port);
          memcpy(&arp_req.arp_pa, &dest, sizeof(struct sockaddr_in));
          arp_req.arp_ha.sa_family = mess->htype;
          memcpy(arp_req.arp_ha.sa_data, mess->chaddr, mess->hlen);
          /* interface name already copied in */
          arp_req.arp_flags = ATF_COM;
          if (ioctl(daemon->dhcpfd, SIOCSARP, &arp_req) == -1)
            my_syslog(MS_DHCP | LOG_ERR, _("ARP-cache injection failed: %s"), strerror(errno));
        }
    }
#elif defined(HAVE_SOLARIS_NETWORK)
  else if ((ntohs(mess->flags) & 0x8000) || mess->hlen != ETHER_ADDR_LEN || mess->htype != ARPHRD_ETHER)
Ejemplo n.º 25
0
void safemode::test_pattern( const int tab_in, const int row_in )
{
    std::vector<std::string> creature_list;
    std::string creature_name;

    auto &temp_rules = ( tab_in == GLOBAL_TAB ) ? global_rules : character_rules;

    if( temp_rules[row_in].rule.empty() ) {
        return;
    }

    if( g->u.name.empty() ) {
        popup( _( "No monsters loaded. Please start a game first." ) );
        return;
    }

    //Loop through all monster mtypes
    for( const auto &mtype : MonsterGenerator::generator().get_all_mtypes() ) {
        creature_name = mtype.nname();
        if( wildcard_match( creature_name, temp_rules[row_in].rule ) ) {
            creature_list.push_back( creature_name );
        }
    }

    const int offset_x = 15 + ( ( TERMX > FULL_SCREEN_WIDTH ) ? ( TERMX - FULL_SCREEN_WIDTH ) / 2 : 0 );
    const int offset_y = 5 + ( ( TERMY > FULL_SCREEN_HEIGHT ) ? ( TERMY - FULL_SCREEN_HEIGHT ) / 2 :
                               0 );

    int start_pos = 0;
    const int content_height = FULL_SCREEN_HEIGHT - 8;
    const int content_width = FULL_SCREEN_WIDTH - 30;

    WINDOW *w_test_rule_border = newwin( content_height + 2, content_width, offset_y, offset_x );
    WINDOW_PTR w_test_rule_borderptr( w_test_rule_border );
    WINDOW *w_test_rule_content = newwin( content_height, content_width - 2, 1 + offset_y,
                                          1 + offset_x );
    WINDOW_PTR w_test_rule_contentptr( w_test_rule_content );

    draw_border( w_test_rule_border );

    int nmatch = creature_list.size();
    std::string buf = string_format( ngettext( "%1$d monster matches: %2$s",
                                     "%1$d monsters match: %2$s",
                                     nmatch ), nmatch, temp_rules[row_in].rule.c_str() );
    mvwprintz( w_test_rule_border, 0, content_width / 2 - utf8_width( buf ) / 2, hilite( c_white ),
               "%s", buf.c_str() );

    mvwprintz( w_test_rule_border, content_height + 1, 1, red_background( c_white ),
               _( "Lists monsters regardless of their attitude." ) );

    wrefresh( w_test_rule_border );

    int line = 0;

    input_context ctxt( "SAFEMODE_TEST" );
    ctxt.register_updown();
    ctxt.register_action( "QUIT" );

    while( true ) {
        // Clear the lines
        for( int i = 0; i < content_height; i++ ) {
            for( int j = 0; j < 79; j++ ) {
                mvwputch( w_test_rule_content, i, j, c_black, ' ' );
            }
        }

        calcStartPos( start_pos, line, content_height, creature_list.size() );

        // display safe mode
        for( int i = start_pos; i < ( int )creature_list.size(); i++ ) {
            if( i >= start_pos &&
                i < start_pos + std::min( content_height, static_cast<int>( creature_list.size() ) ) ) {
                nc_color line_color = c_white;

                mvwprintz( w_test_rule_content, i - start_pos, 0, line_color, "%d", i + 1 );
                mvwprintz( w_test_rule_content, i - start_pos, 4, line_color, "" );

                wprintz( w_test_rule_content, c_yellow, ( line == i ) ? ">> " : "   " );

                wprintz( w_test_rule_content, ( line == i ) ? hilite( line_color ) : line_color, "%s",
                         creature_list[i].c_str() );
            }
        }

        wrefresh( w_test_rule_content );

        const std::string action = ctxt.handle_input();
        if( action == "DOWN" ) {
            line++;
            if( line >= ( int )creature_list.size() ) {
                line = 0;
            }
        } else if( action == "UP" ) {
            line--;
            if( line < 0 ) {
                line = creature_list.size() - 1;
            }
        } else {
            break;
        }
    }
}