void add_implied_include(const char *arg)
{
	filter_rule *rule;
	int arg_len, saw_wild = 0, backslash_cnt = 0;
	int slash_cnt = 1; /* We know we're adding a leading slash. */
	const char *cp;
	char *p;
	if (old_style_args || list_only || filesfrom_host != NULL)
		return;
	if (relative_paths) {
		cp = strstr(arg, "/./");
		if (cp)
			arg = cp+3;
	} else {
		if ((cp = strrchr(arg, '/')) != NULL)
			arg = cp + 1;
	}
	arg_len = strlen(arg);
	if (arg_len) {
		if (strpbrk(arg, "*[?")) {
			/* We need to add room to escape backslashes if wildcard chars are present. */
			cp = arg;
			while ((cp = strchr(cp, '\\')) != NULL) {
				arg_len++;
				cp++;
			}
			saw_wild = 1;
		}
		arg_len++; /* Leave room for the prefixed slash */
		rule = new0(filter_rule);
		if (!implied_filter_list.head)
			implied_filter_list.head = implied_filter_list.tail = rule;
		else {
			rule->next = implied_filter_list.head;
			implied_filter_list.head = rule;
		}
		rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0);
		p = rule->pattern = new_array(char, arg_len + 1);
		*p++ = '/';
		cp = arg;
		while (*cp) {
			switch (*cp) {
			  case '\\':
				backslash_cnt++;
				if (saw_wild)
					*p++ = '\\';
				*p++ = *cp++;
				break;
			  case '/':
				if (p[-1] == '/') /* This is safe because of the initial slash. */
					break;
				if (relative_paths) {
					filter_rule const *ent;
					int found = 0;
					*p = '\0';
					for (ent = implied_filter_list.head; ent; ent = ent->next) {
						if (ent != rule && strcmp(ent->pattern, rule->pattern) == 0)
							found = 1;
					}
					if (!found) {
						filter_rule *R_rule = new0(filter_rule);
						R_rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0);
						R_rule->pattern = strdup(rule->pattern);
						R_rule->u.slash_cnt = slash_cnt;
						R_rule->next = implied_filter_list.head;
						implied_filter_list.head = R_rule;
					}
				}
				slash_cnt++;
				*p++ = *cp++;
				break;
			  default:
				*p++ = *cp++;
				break;
			}
		}
		*p = '\0';
		rule->u.slash_cnt = slash_cnt;
		arg = (const char *)rule->pattern;
	}

	if (recurse || xfer_dirs) {
		/* Now create a rule with an added "/" & "**" or "*" at the end */
		rule = new0(filter_rule);
		if (recurse)
			rule->rflags = FILTRULE_INCLUDE | FILTRULE_WILD | FILTRULE_WILD2;
		else
			rule->rflags = FILTRULE_INCLUDE | FILTRULE_WILD;
		/* A +4 in the len leaves enough room for / * * \0 or / * \0 \0 */
		if (!saw_wild && backslash_cnt) {
			/* We are appending a wildcard, so now the backslashes need to be escaped. */
			p = rule->pattern = new_array(char, arg_len + backslash_cnt + 3 + 1);
			cp = arg;
			while (*cp) {
				if (*cp == '\\')
					*p++ = '\\';
				*p++ = *cp++;
			}
		} else {
			p = rule->pattern = new_array(char, arg_len + 3 + 1);
			if (arg_len) {
				memcpy(p, arg, arg_len);
				p += arg_len;
			}
		}
		if (p[-1] != '/')
			*p++ = '/';
		*p++ = '*';
		if (recurse)
			*p++ = '*';
		*p = '\0';
		rule->u.slash_cnt = slash_cnt + 1;
		rule->next = implied_filter_list.head;
		implied_filter_list.head = rule;
	}
}
void add_implied_include(const char *arg)
{
	filter_rule *rule;
	int arg_len, saw_wild = 0, backslash_cnt = 0;
	int slash_cnt = 1;  
	const char *cp;
	char *p;
	if (old_style_args || list_only || filesfrom_host != NULL)
		return;
	if (relative_paths) {
		cp = strstr(arg, "/./");
		if (cp)
			arg = cp+3;
	} else {
		if ((cp = strrchr(arg, '/')) != NULL)
			arg = cp + 1;
	}
	arg_len = strlen(arg);
	if (arg_len) {
		if (strpbrk(arg, "*[?")) {
			 
			cp = arg;
			while ((cp = strchr(cp, '\\')) != NULL) {
				arg_len++;
				cp++;
			}
			saw_wild = 1;
		}
		arg_len++;  
		rule = new0(filter_rule);
		if (!implied_filter_list.head)
			implied_filter_list.head = implied_filter_list.tail = rule;
		else {
			rule->next = implied_filter_list.head;
			implied_filter_list.head = rule;
		}
		rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0);
		p = rule->pattern = new_array(char, arg_len + 1);
		*p++ = '/';
		cp = arg;
		while (*cp) {
			switch (*cp) {
			  case '\\':
				backslash_cnt++;
				if (saw_wild)
					*p++ = '\\';
				*p++ = *cp++;
				break;
			  case '/':
				if (p[-1] == '/')  
					break;
				if (relative_paths) {
					filter_rule const *ent;
					int found = 0;
					*p = '\0';
					for (ent = implied_filter_list.head; ent; ent = ent->next) {
						if (ent != rule && strcmp(ent->pattern, rule->pattern) == 0)
							found = 1;
					}
					if (!found) {
						filter_rule *R_rule = new0(filter_rule);
						R_rule->rflags = FILTRULE_INCLUDE + (saw_wild ? FILTRULE_WILD : 0);
						R_rule->pattern = strdup(rule->pattern);
						R_rule->u.slash_cnt = slash_cnt;
						R_rule->next = implied_filter_list.head;
						implied_filter_list.head = R_rule;
					}
				}
				slash_cnt++;
				*p++ = *cp++;
				break;
			  default:
				*p++ = *cp++;
				break;
			}
		}
		*p = '\0';
		rule->u.slash_cnt = slash_cnt;
		arg = (const char *)rule->pattern;
	}

	if (recurse || xfer_dirs) {
		 
		rule = new0(filter_rule);
		if (recurse)
			rule->rflags = FILTRULE_INCLUDE | FILTRULE_WILD | FILTRULE_WILD2;
		else
			rule->rflags = FILTRULE_INCLUDE | FILTRULE_WILD;
		 
		if (!saw_wild && backslash_cnt) {
			 
			p = rule->pattern = new_array(char, arg_len + backslash_cnt + 3 + 1);
			cp = arg;
			while (*cp) {
				if (*cp == '\\')
					*p++ = '\\';
				*p++ = *cp++;
			}
		} else {
			p = rule->pattern = new_array(char, arg_len + 3 + 1);
			if (arg_len) {
				memcpy(p, arg, arg_len);
				p += arg_len;
			}
		}
		if (p[-1] != '/')
			*p++ = '/';
		*p++ = '*';
		if (recurse)
			*p++ = '*';
		*p = '\0';
		rule->u.slash_cnt = slash_cnt + 1;
		rule->next = implied_filter_list.head;
		implied_filter_list.head = rule;
	}
}