int get_real_filename(connection_struct *conn, const char *path, const char *name, TALLOC_CTX *mem_ctx, char **found_name) { struct smb_Dir *cur_dir; const char *dname; bool mangled; char *unmangled_name = NULL; long curpos; /* open the directory */ if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); TALLOC_FREE(unmangled_name); return -1; } /* now scan for matching names */ curpos = 0; while ((dname = ReadDirName(cur_dir, &curpos, NULL))) { /* Is it dot or dot dot. */ if (ISDOT(dname) || ISDOTDOT(dname)) { continue; } /* * At this point dname is the unmangled name. * name is either mangled or not, depending on the state * of the "mangled" variable. JRA. */ /* * Check mangled name against mangled name, or unmangled name * against unmangled name. */ if ((mangled && mangled_equal(name,dname,conn->params)) || fname_equal(name, dname, conn->case_sensitive)) { /* we've found the file, change it's name and return */ *found_name = talloc_strdup(mem_ctx, dname); TALLOC_FREE(unmangled_name); TALLOC_FREE(cur_dir); if (!*found_name) { errno = ENOMEM; return -1; } return 0; } } TALLOC_FREE(unmangled_name); TALLOC_FREE(cur_dir); errno = ENOENT; return -1; }
static int findpty(char **slave) { int master; static fstring line; void *dirp; char *dpname; #if defined(HAVE_GRANTPT) /* Try to open /dev/ptmx. If that fails, fall through to old method. */ if ((master = sys_open("/dev/ptmx", O_RDWR, 0)) >= 0) { grantpt(master); unlockpt(master); *slave = (char *)ptsname(master); if (*slave == NULL) { DEBUG(0,("findpty: Unable to create master/slave pty pair.\n")); /* Stop fd leak on error. */ close(master); return -1; } else { DEBUG(10, ("findpty: Allocated slave pty %s\n", *slave)); return (master); } } #endif /* HAVE_GRANTPT */ fstrcpy( line, "/dev/ptyXX" ); dirp = OpenDir(NULL, "/dev", False); if (!dirp) return(-1); while ((dpname = ReadDirName(dirp)) != NULL) { if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) { DEBUG(3,("pty: try to open %s, line was %s\n", dpname, line ) ); line[8] = dpname[3]; line[9] = dpname[4]; if ((master = sys_open(line, O_RDWR, 0)) >= 0) { DEBUG(3,("pty: opened %s\n", line ) ); line[5] = 't'; *slave = line; CloseDir(dirp); return (master); } } } CloseDir(dirp); return (-1); }
void FSDrive::find_first_file(char *pattern) { #ifndef __riscos__ DIR *dir; struct dirent *de; // Open directory for reading and skip '.' and '..' if ((dir = opendir(dir_path)) == NULL) return; de = readdir(dir); while (de && (0 == strcmp(".", de->d_name) || 0 == strcmp("..", de->d_name))) de = readdir(dir); while (de) { // Match found? Then copy real file name if (match(pattern, de->d_name)) { strncpy(pattern, de->d_name, NAMEBUF_LENGTH); closedir(dir); return; } // Get next directory entry de = readdir(dir); } closedir(dir); #else dir_env de; char Buffer[NAMEBUF_LENGTH]; de.offset = 0; de.buffsize = NAMEBUF_LENGTH; de.match = name; do { de.readno = 1; if (ReadDirName(dir_path,Buffer,&de) != NULL) de.offset = -1; else if (de.offset != -1 && match(name,Buffer)) { strncpy(name, Buffer, NAMEBUF_LENGTH); return; } } while (de.readno > 0); #endif }
static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp) { connection_struct *conn = fsp->conn; struct smb_filename *smb_dname = fsp->fsp_name; int ret; SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname)); /* Might be a symlink. */ if(SMB_VFS_LSTAT(conn, smb_dname) != 0) { return map_nt_error_from_unix(errno); } if (S_ISLNK(smb_dname->st.st_ex_mode)) { /* Is what it points to a directory ? */ if(SMB_VFS_STAT(conn, smb_dname) != 0) { return map_nt_error_from_unix(errno); } if (!(S_ISDIR(smb_dname->st.st_ex_mode))) { return NT_STATUS_NOT_A_DIRECTORY; } ret = SMB_VFS_UNLINK(conn, smb_dname); } else { ret = SMB_VFS_RMDIR(conn, smb_dname->base_name); } if (ret == 0) { notify_fname(conn, NOTIFY_ACTION_REMOVED, FILE_NOTIFY_CHANGE_DIR_NAME, smb_dname->base_name); return NT_STATUS_OK; } if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), SNUM(conn))) { /* * Check to see if the only thing in this directory are * vetoed files/directories. If so then delete them and * retry. If we fail to delete any of them (and we *don't* * do a recursive delete) then fail the rmdir. */ SMB_STRUCT_STAT st; const char *dname = NULL; char *talloced = NULL; long dirpos = 0; struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0); if(dir_hnd == NULL) { errno = ENOTEMPTY; goto err; } while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) { if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) { TALLOC_FREE(talloced); continue; } if (!is_visible_file(conn, smb_dname->base_name, dname, &st, false)) { TALLOC_FREE(talloced); continue; } if(!IS_VETO_PATH(conn, dname)) { TALLOC_FREE(dir_hnd); TALLOC_FREE(talloced); errno = ENOTEMPTY; goto err; } TALLOC_FREE(talloced); } /* We only have veto files/directories. * Are we allowed to delete them ? */ if(!lp_delete_veto_files(SNUM(conn))) { TALLOC_FREE(dir_hnd); errno = ENOTEMPTY; goto err; } /* Do a recursive delete. */ RewindDir(dir_hnd,&dirpos); while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) { struct smb_filename *smb_dname_full = NULL; char *fullname = NULL; bool do_break = true; if (ISDOT(dname) || ISDOTDOT(dname)) { TALLOC_FREE(talloced); continue; } if (!is_visible_file(conn, smb_dname->base_name, dname, &st, false)) { TALLOC_FREE(talloced); continue; } fullname = talloc_asprintf(ctx, "%s/%s", smb_dname->base_name, dname); if(!fullname) { errno = ENOMEM; goto err_break; } smb_dname_full = synthetic_smb_fname( talloc_tos(), fullname, NULL, NULL); if (smb_dname_full == NULL) { errno = ENOMEM; goto err_break; } if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) { goto err_break; } if(smb_dname_full->st.st_ex_mode & S_IFDIR) { if(!recursive_rmdir(ctx, conn, smb_dname_full)) { goto err_break; } if(SMB_VFS_RMDIR(conn, smb_dname_full->base_name) != 0) { goto err_break; } } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) { goto err_break; } /* Successful iteration. */ do_break = false; err_break: TALLOC_FREE(fullname); TALLOC_FREE(smb_dname_full); TALLOC_FREE(talloced); if (do_break) break; } TALLOC_FREE(dir_hnd); /* Retry the rmdir */ ret = SMB_VFS_RMDIR(conn, smb_dname->base_name); } err: if (ret != 0) { DEBUG(3,("rmdir_internals: couldn't remove directory %s : " "%s\n", smb_fname_str_dbg(smb_dname), strerror(errno))); return map_nt_error_from_unix(errno); } notify_fname(conn, NOTIFY_ACTION_REMOVED, FILE_NOTIFY_CHANGE_DIR_NAME, smb_dname->base_name); return NT_STATUS_OK; }
bool recursive_rmdir(TALLOC_CTX *ctx, connection_struct *conn, struct smb_filename *smb_dname) { const char *dname = NULL; char *talloced = NULL; bool ret = True; long offset = 0; SMB_STRUCT_STAT st; struct smb_Dir *dir_hnd; SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname)); dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0); if(dir_hnd == NULL) return False; while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) { struct smb_filename *smb_dname_full = NULL; char *fullname = NULL; bool do_break = true; if (ISDOT(dname) || ISDOTDOT(dname)) { TALLOC_FREE(talloced); continue; } if (!is_visible_file(conn, smb_dname->base_name, dname, &st, false)) { TALLOC_FREE(talloced); continue; } /* Construct the full name. */ fullname = talloc_asprintf(ctx, "%s/%s", smb_dname->base_name, dname); if (!fullname) { errno = ENOMEM; goto err_break; } smb_dname_full = synthetic_smb_fname(talloc_tos(), fullname, NULL, NULL); if (smb_dname_full == NULL) { errno = ENOMEM; goto err_break; } if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) { goto err_break; } if(smb_dname_full->st.st_ex_mode & S_IFDIR) { if(!recursive_rmdir(ctx, conn, smb_dname_full)) { goto err_break; } if(SMB_VFS_RMDIR(conn, smb_dname_full->base_name) != 0) { goto err_break; } } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) { goto err_break; } /* Successful iteration. */ do_break = false; err_break: TALLOC_FREE(smb_dname_full); TALLOC_FREE(fullname); TALLOC_FREE(talloced); if (do_break) { ret = false; break; } } TALLOC_FREE(dir_hnd); return ret; }
static int get_real_filename_full_scan(connection_struct *conn, const char *path, const char *name, bool mangled, TALLOC_CTX *mem_ctx, char **found_name) { struct smb_Dir *cur_dir; const char *dname = NULL; char *talloced = NULL; char *unmangled_name = NULL; long curpos; /* handle null paths */ if ((path == NULL) || (*path == 0)) { path = "."; } /* If we have a case-sensitive filesystem, it doesn't do us any * good to search for a name. If a case variation of the name was * there, then the original stat(2) would have found it. */ if (!mangled && !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) { errno = ENOENT; return -1; } /* * The incoming name can be mangled, and if we de-mangle it * here it will not compare correctly against the filename (name2) * read from the directory and then mangled by the name_to_8_3() * call. We need to mangle both names or neither. * (JRA). * * Fix for bug found by Dina Fine. If in case sensitive mode then * the mangle cache is no good (3 letter extension could be wrong * case - so don't demangle in this case - leave as mangled and * allow the mangling of the directory entry read (which is done * case insensitively) to match instead. This will lead to more * false positive matches but we fail completely without it. JRA. */ if (mangled && !conn->case_sensitive) { mangled = !mangle_lookup_name_from_8_3(talloc_tos(), name, &unmangled_name, conn->params); if (!mangled) { /* Name is now unmangled. */ name = unmangled_name; } } /* open the directory */ if (!(cur_dir = OpenDir(talloc_tos(), conn, path, NULL, 0))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); TALLOC_FREE(unmangled_name); return -1; } /* now scan for matching names */ curpos = 0; while ((dname = ReadDirName(cur_dir, &curpos, NULL, &talloced))) { /* Is it dot or dot dot. */ if (ISDOT(dname) || ISDOTDOT(dname)) { TALLOC_FREE(talloced); continue; } /* * At this point dname is the unmangled name. * name is either mangled or not, depending on the state * of the "mangled" variable. JRA. */ /* * Check mangled name against mangled name, or unmangled name * against unmangled name. */ if ((mangled && mangled_equal(name,dname,conn->params)) || fname_equal(name, dname, conn->case_sensitive)) { /* we've found the file, change it's name and return */ *found_name = talloc_strdup(mem_ctx, dname); TALLOC_FREE(unmangled_name); TALLOC_FREE(cur_dir); if (!*found_name) { errno = ENOMEM; TALLOC_FREE(talloced); return -1; } TALLOC_FREE(talloced); return 0; } TALLOC_FREE(talloced); } TALLOC_FREE(unmangled_name); TALLOC_FREE(cur_dir); errno = ENOENT; return -1; }
static BOOL scan_directory(connection_struct *conn, const char *path, char *name, size_t maxlength) { struct smb_Dir *cur_dir; const char *dname; BOOL mangled; long curpos; mangled = mangle_is_mangled(name, conn->params); /* handle null paths */ if (*path == 0) path = "."; /* If we have a case-sensitive filesystem, it doesn't do us any * good to search for a name. If a case variation of the name was * there, then the original stat(2) would have found it. */ if (!(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) { errno = ENOENT; return False; } /* * The incoming name can be mangled, and if we de-mangle it * here it will not compare correctly against the filename (name2) * read from the directory and then mangled by the mangle_map() * call. We need to mangle both names or neither. * (JRA). * * Fix for bug found by Dina Fine. If in case sensitive mode then * the mangle cache is no good (3 letter extension could be wrong * case - so don't demangle in this case - leave as mangled and * allow the mangling of the directory entry read (which is done * case insensitively) to match instead. This will lead to more * false positive matches but we fail completely without it. JRA. */ if (mangled && !conn->case_sensitive) { mangled = !mangle_check_cache( name, maxlength, conn->params); } /* open the directory */ if (!(cur_dir = OpenDir(conn, path, NULL, 0))) { DEBUG(3,("scan dir didn't open dir [%s]\n",path)); return(False); } /* now scan for matching names */ curpos = 0; while ((dname = ReadDirName(cur_dir, &curpos))) { /* Is it dot or dot dot. */ if ((dname[0] == '.') && (!dname[1] || (dname[1] == '.' && !dname[2]))) { continue; } /* * At this point dname is the unmangled name. * name is either mangled or not, depending on the state of the "mangled" * variable. JRA. */ /* * Check mangled name against mangled name, or unmangled name * against unmangled name. */ if ((mangled && mangled_equal(name,dname,conn->params)) || fname_equal(name, dname, conn->case_sensitive)) { /* we've found the file, change it's name and return */ safe_strcpy(name, dname, maxlength); CloseDir(cur_dir); return(True); } } CloseDir(cur_dir); errno = ENOENT; return(False); }
static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags, struct change_data *data, struct change_data *old_data) { SMB_STRUCT_STAT st; pstring full_name; char *p; char *fname; size_t remaining_len; size_t fullname_len; void *dp; ZERO_STRUCTP(data); if(vfs_stat(conn,path, &st) == -1) return False; data->modify_time = st.st_mtime; data->status_time = st.st_ctime; if (old_data) { /* * Shortcut to avoid directory scan if the time * has changed - we always must return true then. */ if (old_data->modify_time != data->modify_time || old_data->status_time != data->status_time ) { return True; } } /* * If we are to watch for changes that are only stored * in inodes of files, not in the directory inode, we must * scan the directory and produce a unique identifier with * which we can determine if anything changed. We use the * modify and change times from all the files in the * directory, added together (ignoring wrapping if it's * larger than the max time_t value). */ dp = OpenDir(conn, path, True); if (dp == NULL) return False; data->num_entries = 0; pstrcpy(full_name, path); pstrcat(full_name, "/"); fullname_len = strlen(full_name); remaining_len = sizeof(full_name) - fullname_len - 1; p = &full_name[fullname_len]; while ((fname = ReadDirName(dp))) { if(strequal(fname, ".") || strequal(fname, "..")) continue; data->num_entries++; safe_strcpy(p, fname, remaining_len); ZERO_STRUCT(st); /* * Do the stat - but ignore errors. */ vfs_stat(conn,full_name, &st); /* * Always sum the times. */ data->total_time += (st.st_mtime + st.st_ctime); /* * If requested hash the names. */ if (flags & (FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_FILE)) { int i; unsigned char tmp_hash[16]; mdfour(tmp_hash, (unsigned char *)fname, strlen(fname)); for (i=0;i<16;i++) data->name_hash[i] ^= tmp_hash[i]; } /* * If requested sum the mode_t's. */ if (flags & (FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_SECURITY)) data->mode_sum = st.st_mode; } CloseDir(dp); return True; }