+ int len;
+ char *slash;
+
+ while (*arg == '.' && arg[1] == '/') {
+ if (fbpos < 0) {
+ ENSURE_MEMSPACE(glob.filt_buf, char, glob.fbsize, glob.absize);
+ memcpy(glob.filt_buf, glob.arg_buf, abpos + 1);
+ fbpos = abpos;
+ }
+ ENSURE_MEMSPACE(glob.arg_buf, char, glob.absize, abpos + 3);
+ glob.arg_buf[abpos++] = *arg++;
+ glob.arg_buf[abpos++] = *arg++;
+ glob.arg_buf[abpos] = '\0';
+ }
+ if ((slash = strchr(arg, '/')) != NULL) {
+ *slash = '\0';
+ len = slash - arg;
+ } else
+ len = strlen(arg);
+ if (strpbrk(arg, "*?[")) {
+ struct dirent *di;
+ DIR *d;
+
+ if (!(d = opendir(abpos ? glob.arg_buf : ".")))
+ return;
+ while ((di = readdir(d)) != NULL) {
+ char *dname = d_name(di);
+ if (dname[0] == '.' && (dname[1] == '\0'
+ || (dname[1] == '.' && dname[2] == '\0')))
+ continue;
+ if (!wildmatch(arg, dname))
+ continue;
+ call_glob_match(dname, strlen(dname), 1,
+ slash ? arg + len + 1 : NULL,
+ abpos, fbpos);
+ }
+ closedir(d);
+ } else {
+ call_glob_match(arg, len, 0,
+ slash ? arg + len + 1 : NULL,
+ abpos, fbpos);
+ }
+ if (slash)
+ *slash = '/';
+}
+
+static inline void call_glob_match(const char *name, int len, int from_glob,
+ char *arg, int abpos, int fbpos)
+{
+ char *use_buf;
+
+ ENSURE_MEMSPACE(glob.arg_buf, char, glob.absize, abpos + len + 2);
+ memcpy(glob.arg_buf + abpos, name, len);
+ abpos += len;
+ glob.arg_buf[abpos] = '\0';
+
+ if (fbpos >= 0) {
+ ENSURE_MEMSPACE(glob.filt_buf, char, glob.fbsize, fbpos + len + 2);
+ memcpy(glob.filt_buf + fbpos, name, len);
+ fbpos += len;
+ glob.filt_buf[fbpos] = '\0';
+ use_buf = glob.filt_buf;
+ } else
+ use_buf = glob.arg_buf;
+
+ if (from_glob || (arg && len)) {
+ STRUCT_STAT st;
+ int is_dir;
+
+ if (do_stat(glob.arg_buf, &st) != 0)
+ return;
+ is_dir = S_ISDIR(st.st_mode) != 0;
+ if (arg && !is_dir)
+ return;
+
+ if (daemon_filter_list.head
+ && check_filter(&daemon_filter_list, FLOG, use_buf, is_dir) < 0)
+ return;
+ }