static bool reg_match_one(struct smbcli_state *cli, const char *pattern, const char *file) { /* oh what a weird world this is */ if (old_list && strcmp(pattern, "*.*") == 0) return true; if (ISDOT(pattern)) return false; if (ISDOTDOT(file)) file = "."; return ms_fnmatch(pattern, file, cli->transport->negotiate.protocol)==0; }
/* read a directory and find all matching file names and stat info returned names are separate unix and DOS names. The returned names are relative to the directory */ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req, const char *unix_path) { char *p, *mask; struct svfs_dir *dir; DIR *odir; struct dirent *dent; unsigned int allocated = 0; char *low_mask; dir = talloc(mem_ctx, struct svfs_dir); if (!dir) { return NULL; } dir->count = 0; dir->files = 0; /* find the base directory */ p = strrchr(unix_path, '/'); if (!p) { return NULL; } dir->unix_dir = talloc_strndup(mem_ctx, unix_path, PTR_DIFF(p, unix_path)); if (!dir->unix_dir) { return NULL; } /* the wildcard pattern is the last part */ mask = p+1; low_mask = talloc_strdup(mem_ctx, mask); if (!low_mask) { return NULL; } strlower(low_mask); odir = opendir(dir->unix_dir); if (!odir) { return NULL; } while ((dent = readdir(odir))) { unsigned int i = dir->count; char *full_name; char *low_name; if (strchr(dent->d_name, ':') && !strchr(unix_path, ':')) { /* don't show streams in dir listing */ continue; } low_name = talloc_strdup(mem_ctx, dent->d_name); if (!low_name) { continue; } strlower(low_name); /* check it matches the wildcard pattern */ if (ms_fnmatch(low_mask, low_name, PROTOCOL_NT1) != 0) { continue; } if (dir->count >= allocated) { allocated = (allocated + 100) * 1.2; dir->files = talloc_realloc(dir, dir->files, struct svfs_dirfile, allocated); if (!dir->files) { closedir(odir); return NULL; } } dir->files[i].name = low_name; if (!dir->files[i].name) { continue; } asprintf(&full_name, "%s/%s", dir->unix_dir, dir->files[i].name); if (!full_name) { continue; } if (stat(full_name, &dir->files[i].st) == 0) { dir->count++; } free(full_name); }
/**************************************************************************** interpret a single element from a interfaces= config line This handles the following different forms: 1) wildcard interface name 2) DNS name 3) IP/masklen 4) ip/mask 5) bcast/mask ****************************************************************************/ static void interpret_interface(char *token) { struct in_addr ip, nmask; char *p; int i, added=0; zero_ip(&ip); zero_ip(&nmask); /* first check if it is an interface name */ for (i=0;i<total_probed;i++) { if (ms_fnmatch(token, probed_ifaces[i].name) == 0) { add_interface(probed_ifaces[i].ip, probed_ifaces[i].netmask); added = 1; } } if (added) return; /* maybe it is a DNS name */ p = strchr(token,'/'); if (!p) { ip = *interpret_addr2(token); for (i=0;i<total_probed;i++) { if (ip.s_addr == probed_ifaces[i].ip.s_addr && !ip_equal(allones_ip, probed_ifaces[i].netmask)) { add_interface(probed_ifaces[i].ip, probed_ifaces[i].netmask); return; } } DEBUG(2,("can't determine netmask for %s\n", token)); return; } /* parse it into an IP address/netmasklength pair */ *p++ = 0; ip = *interpret_addr2(token); if (strlen(p) > 2) { nmask = *interpret_addr2(p); } else { nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES)); } /* maybe the first component was a broadcast address */ if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) || ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) { for (i=0;i<total_probed;i++) { if (same_net(ip, probed_ifaces[i].ip, nmask)) { add_interface(probed_ifaces[i].ip, nmask); return; } } DEBUG(2,("Can't determine ip for broadcast address %s\n", token)); return; } add_interface(ip, nmask); }
/* a generic fnmatch function - uses for non-CIFS pattern matching */ int gen_fnmatch(const char *pattern, const char *string) { return ms_fnmatch(pattern, string, PROTOCOL_NT1, False); }
/* return the next entry */ const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs) { struct dirent *de; enum protocol_types protocol = dir->pvfs->ntvfs->ctx->protocol; /* non-wildcard searches are easy */ if (dir->no_wildcard) { dir->end_of_search = True; if (*ofs != 0) return NULL; (*ofs)++; return dir->single_name; } /* . and .. are handled separately as some unix systems will not return them first in a directory, but windows client may assume that these entries always appear first */ if (*ofs == DIR_OFFSET_DOT) { (*ofs) = DIR_OFFSET_DOTDOT; dir->offset = *ofs; if (ms_fnmatch(dir->pattern, ".", protocol) == 0) { dcache_add(dir, "."); return "."; } } if (*ofs == DIR_OFFSET_DOTDOT) { (*ofs) = DIR_OFFSET_BASE; dir->offset = *ofs; if (ms_fnmatch(dir->pattern, "..", protocol) == 0) { dcache_add(dir, ".."); return ".."; } } if (*ofs == DIR_OFFSET_BASE) { rewinddir(dir->dir); } else if (*ofs != dir->offset) { seekdir(dir->dir, (*ofs) - DIR_OFFSET_BASE); } dir->offset = *ofs; while ((de = readdir(dir->dir))) { const char *dname = de->d_name; if (ISDOT(dname) || ISDOTDOT(dname)) { continue; } if (ms_fnmatch(dir->pattern, dname, protocol) != 0) { char *short_name = pvfs_short_name_component(dir->pvfs, dname); if (short_name == NULL || ms_fnmatch(dir->pattern, short_name, protocol) != 0) { talloc_free(short_name); continue; } talloc_free(short_name); } dir->offset = telldir(dir->dir) + DIR_OFFSET_BASE; (*ofs) = dir->offset; dcache_add(dir, dname); return dname; } dir->end_of_search = True; return NULL; }