Exemple #1
0
int impl_fuse_context::delete_file(LPCWSTR file_name,
								   PDOKAN_FILE_INFO dokan_file_info)
{
	if (!ops_.unlink)
		return -EINVAL;

	//Note: we do not try to resolve symlink target
	std::string fname=unixify(wchar_to_utf8_cstr(file_name));
	return ops_.unlink(fname.c_str());
}
Exemple #2
0
int impl_fuse_context::create_directory(LPCWSTR file_name,
										PDOKAN_FILE_INFO dokan_file_info)
{
	std::string fname=unixify(wchar_to_utf8_cstr(file_name));

	if (!ops_.mkdir)
		return -EINVAL;

	return ops_.mkdir(fname.c_str(),dirmask_);
}
Exemple #3
0
int impl_fuse_context::delete_file(LPCWSTR file_name,
                                   PDOKAN_FILE_INFO dokan_file_info) {
  std::string fname = unixify(wchar_to_utf8_cstr(file_name));

  if (!ops_.getattr)
    return -EINVAL;

  struct FUSE_STAT stbuf = {0};
  return ops_.getattr(fname.c_str(), &stbuf);
}
char * xstrdup_name (void)
{
  if (qualified(name_of_file + 1))
    *log_line = '\0';
  else
  {
    (void) getcwd(log_line, sizeof(log_line));
    strcat(log_line, PATH_SEP_STRING);
  }

  strcat(log_line, (char *) name_of_file + 1);
  unixify(log_line);
  return xstrdup(log_line);
}
Exemple #5
0
int impl_fuse_context::do_open_dir(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo)
{
	if (ops_.opendir)
	{
		fuse_file_info finfo={0};
		std::string fname=unixify(wchar_to_utf8_cstr(FileName));
		CHECKED(ops_.opendir(fname.c_str(),&finfo));

		DokanFileInfo->Context=reinterpret_cast<ULONG64>(new impl_file_handle(fname,true,&finfo));
		return 0;
	}

	DokanFileInfo->Context=0;
	return 0;
}
Exemple #6
0
int impl_fuse_context::do_open_file(LPCWSTR FileName, DWORD Flags,
									PDOKAN_FILE_INFO DokanFileInfo)
{
	if (!ops_.open) return -EINVAL;
	std::string fname=unixify(wchar_to_utf8_cstr(FileName));
	CHECKED(check_and_resolve(&fname));

	fuse_file_info finfo={0};
	//if ((ShareMode & FILE_SHARE_READ) || (ShareMode & FILE_SHARE_DELETE))
	//TODO: add sharing support?
	finfo.flags=convert_flags(Flags);

	CHECKED(ops_.open(fname.c_str(),&finfo));
	DokanFileInfo->Context=reinterpret_cast<ULONG64>(new impl_file_handle(fname,false,&finfo));
	return 0;
}
Exemple #7
0
int impl_fuse_context::set_file_attributes(LPCWSTR file_name,
                                           DWORD file_attributes,
                                           PDOKAN_FILE_INFO dokan_file_info) {
  // This method is unlikely to be implemented since we do not support
  // advanced properties
  // TODO: maybe use extended properties of underlying FS?

  // Just return 'success' since returning -EINVAL interferes with modification
  // time
  // setting from FAR Manager.
  if (ops_.win_set_attributes) {
    std::string fname = unixify(wchar_to_utf8_cstr(file_name));
    CHECKED(check_and_resolve(&fname));
    return ops_.win_set_attributes(fname.c_str(), file_attributes);
  }
  return 0;
}
Exemple #8
0
int impl_fuse_context::set_end_of_file(LPCWSTR file_name, LONGLONG byte_offset,
                                       PDOKAN_FILE_INFO dokan_file_info) {
  FUSE_OFF_T off;
  CHECKED(cast_from_longlong(byte_offset, &off));
  std::string fname = unixify(wchar_to_utf8_cstr(file_name));
  CHECKED(check_and_resolve(&fname));

  impl_file_handle *hndl =
      reinterpret_cast<impl_file_handle *>(dokan_file_info->Context);
  if (hndl && ops_.ftruncate) {
    fuse_file_info finfo(hndl->make_finfo());
    return ops_.ftruncate(hndl->get_name().c_str(), off, &finfo);
  }

  if (!ops_.truncate)
    return -EINVAL;
  return ops_.truncate(fname.c_str(), off);
}
Exemple #9
0
int impl_fuse_context::find_files(LPCWSTR file_name,
                                  PFillFindData fill_find_data,
                                  PDOKAN_FILE_INFO dokan_file_info) {
  if ((!ops_.readdir && !ops_.getdir) || !ops_.getattr)
    return -EINVAL;

  std::string fname = unixify(wchar_to_utf8_cstr(file_name));
  CHECKED(check_and_resolve(&fname));

  walk_data wd;
  wd.ctx = this;
  wd.dirname = fname;
  if (*fname.rbegin() != '/')
    wd.dirname.append("/");
  wd.delegate = fill_find_data;
  wd.DokanFileInfo = dokan_file_info;

  if (ops_.readdir) {
    impl_file_handle *hndl =
        reinterpret_cast<impl_file_handle *>(dokan_file_info->Context);
    if (hndl != NULL) {
      fuse_file_info finfo(hndl->make_finfo());
      return ops_.readdir(fname.c_str(), &wd, &walk_directory, 0, &finfo);
    } else
      return ops_.readdir(fname.c_str(), &wd, &walk_directory, 0, NULL);
  } else {
    CHECKED(
        ops_.getdir(fname.c_str(), (fuse_dirh_t)&wd, &walk_directory_getdir));
    // Convert returned data The getdir_data array will be filled during
    // getdir() call.
    // We emulate FUSE behavior and do not pass information directly to Dokan
    // in walk_directory_getdir callback. This can cause excessive network
    // traffic
    // in sshfs because it populates stat buffer cache AFTER calling our
    // callback.
    // See: cache.c file, function cache_dirfill() in SSHFS 2.2
    for (std::vector<std::string>::const_iterator f = wd.getdir_data.begin();
         f != wd.getdir_data.end(); ++f)
      CHECKED(walk_directory(&wd, f->c_str(), 0, 0));
  }

  return 0;
}
Exemple #10
0
int impl_fuse_context::do_open_file(LPCWSTR FileName, DWORD share_mode, DWORD Flags,
									PDOKAN_FILE_INFO DokanFileInfo)
{
	if (!ops_.open) return -EINVAL;
	std::string fname=unixify(wchar_to_utf8_cstr(FileName));
	CHECKED(check_and_resolve(&fname));

	std::auto_ptr<impl_file_handle> file;
	CHECKED(file_locks.get_file(fname,false,Flags,share_mode,file));

	fuse_file_info finfo={0};
	finfo.flags=convert_flags(Flags);

	CHECKED(ops_.open(fname.c_str(),&finfo));

	file->set_finfo(finfo);
	DokanFileInfo->Context=reinterpret_cast<ULONG64>(file.release());
	return 0;
}
Exemple #11
0
int impl_fuse_context::do_open_dir(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo)
{
	if (ops_.opendir)
	{
		std::string fname=unixify(wchar_to_utf8_cstr(FileName));
		std::auto_ptr<impl_file_handle> file;
		// TODO access_mode
		CHECKED(file_locks.get_file(fname,true,0,FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,file));

		fuse_file_info finfo={0};
		CHECKED(ops_.opendir(fname.c_str(),&finfo));

		file->set_finfo(finfo);
		DokanFileInfo->Context=reinterpret_cast<ULONG64>(file.release());
		return 0;
	}

	DokanFileInfo->Context=0;
	return 0;
}
Exemple #12
0
int impl_fuse_context::do_create_file(LPCWSTR FileName, DWORD Disposition,
                                      DWORD share_mode, DWORD Flags,
                                      PDOKAN_FILE_INFO DokanFileInfo)
// Kernel mappsings:
// Disposition = CreateDisposition
// Flags = DesiredAccess
// share_mode = ShareAccess
{
  std::string fname = unixify(wchar_to_utf8_cstr(FileName));

  // Create file?
  if (Disposition != FILE_CREATE && Disposition != FILE_SUPERSEDE &&
      Disposition != FILE_OPEN_IF && Disposition != FILE_OVERWRITE_IF) {
    SetLastError(ERROR_FILE_NOT_FOUND);
    return -ENOENT; // No, we're trying to open an existing file!
  }

  if (!ops_.create) {
    // Use mknod+open.
    if (!ops_.mknod || !ops_.open)
      return -EINVAL;

    CHECKED(ops_.mknod(fname.c_str(), filemask_, 0));

    return do_open_file(FileName, share_mode, Flags, DokanFileInfo);
  }

  std::unique_ptr<impl_file_handle> file;
  CHECKED(file_locks.get_file(fname, false, Flags, share_mode, file));

  fuse_file_info finfo = {0};
  finfo.flags =
      O_CREAT | O_EXCL |
      convert_flags(Flags); // TODO: these flags should be OK for new files?

  CHECKED(ops_.create(fname.c_str(), filemask_, &finfo));

  file->set_finfo(finfo);
  DokanFileInfo->Context = reinterpret_cast<ULONG64>(file.release());
  return 0;
}
Exemple #13
0
int impl_fuse_context::open_directory(LPCWSTR file_name,
                                      PDOKAN_FILE_INFO dokan_file_info) {
  std::string fname = unixify(wchar_to_utf8_cstr(file_name));

  if (ops_.opendir)
    return do_open_dir(file_name, dokan_file_info);

  // We don't have opendir(), so the most we can do is make sure
  // that the target is indeed a directory
  struct FUSE_STAT st = {0};
  CHECKED(ops_.getattr(fname.c_str(), &st));
  if (S_ISLNK(st.st_mode)) {
    std::string resolved;
    CHECKED(resolve_symlink(fname, &resolved));
    CHECKED(ops_.getattr(resolved.c_str(), &st));
  }

  // Not a directory
  if ((st.st_mode & S_IFDIR) != S_IFDIR)
    return -ENOTDIR;

  dokan_file_info->Context = (ULONG64)NULL; // Do not want to attach anything
  return 0; // Use readdir here?
}
Exemple #14
0
int impl_fuse_context::do_delete_directory(LPCWSTR file_name,
                                           PDOKAN_FILE_INFO dokan_file_info) {
  std::string fname = unixify(wchar_to_utf8_cstr(file_name));

  if (!ops_.rmdir || !ops_.getattr)
    return -EINVAL;

  // Make sure directory is NOT opened
  // TODO: potential race here - Unix filesystems typically allow
  // to delete open files and directories.
  impl_file_handle *hndl =
      reinterpret_cast<impl_file_handle *>(dokan_file_info->Context);
  if (hndl)
    return -EBUSY;

  // A special case: symlinks are deleted by unlink, not rmdir
  struct FUSE_STAT stbuf = {0};
  CHECKED(ops_.getattr(fname.c_str(), &stbuf));
  if (S_ISLNK(stbuf.st_mode) && ops_.unlink)
    return ops_.unlink(fname.c_str());

  // Ok, try to rmdir it.
  return ops_.rmdir(fname.c_str());
}
Exemple #15
0
win_error impl_fuse_context::create_file(LPCWSTR file_name, DWORD access_mode,
                                         DWORD share_mode,
                                         DWORD creation_disposition,
                                         DWORD flags_and_attributes,
                                         PDOKAN_FILE_INFO dokan_file_info) {
  std::string fname = unixify(wchar_to_utf8_cstr(file_name));
  dokan_file_info->Context = 0;

  if (!ops_.getattr)
    return -EINVAL;

  struct FUSE_STAT stbuf = {0};
  // Check if the target file/directory exists
  if (ops_.getattr(fname.c_str(), &stbuf) < 0) {
    // Nope.
    if (dokan_file_info->IsDirectory)
      return -EINVAL; // We can't create directories using CreateFile
    return do_create_file(file_name, creation_disposition, share_mode,
                          access_mode, dokan_file_info);
  } else {
    if (S_ISLNK(stbuf.st_mode)) {
      // Get link's target
      CHECKED(resolve_symlink(fname, &fname));
      CHECKED(ops_.getattr(fname.c_str(), &stbuf));
    }

    if ((stbuf.st_mode & S_IFDIR) == S_IFDIR) {
      // Existing directory
      // TODO: add access control
      dokan_file_info->IsDirectory = TRUE;
      return do_open_dir(file_name, dokan_file_info);
    } else {
      // Existing file
      // Check if we'll be able to truncate or delete the opened file
      // TODO: race condition here?
      if (creation_disposition == FILE_OVERWRITE) {
        if (!ops_.unlink)
          return -EINVAL;
        CHECKED(ops_.unlink(fname.c_str())); // Delete file
        // And create it!
        return do_create_file(file_name, creation_disposition, share_mode,
                              access_mode, dokan_file_info);
      } else if (creation_disposition == FILE_SUPERSEDE ||
                 creation_disposition == FILE_OVERWRITE_IF) {
        if (!ops_.truncate)
          return -EINVAL;
        CHECKED(ops_.truncate(fname.c_str(), 0));
      } else if (creation_disposition == FILE_CREATE) {
        SetLastError(ERROR_FILE_EXISTS);
        return win_error(STATUS_OBJECT_NAME_COLLISION, true);
      }

      if (creation_disposition == FILE_OVERWRITE_IF ||
          creation_disposition == FILE_OPEN_IF) {
          SetLastError(ERROR_ALREADY_EXISTS);
      }

      return do_open_file(file_name, share_mode, access_mode, dokan_file_info);
    }
  }
}
Exemple #16
0
boolean open_output (FILE ** f, const char * fopen_mode)
{
  unsigned temp_length;

  name_of_file[name_length + 1] = '\0';

  if (pseudo_tilde != 0 || pseudo_space !=  0)
    retwiddle(name_of_file + 1);

  /* 8 + 3 file names on Windows NT 95/Feb/20 */
  if (shorten_file_name)
    check_short_name(name_of_file + 1);

  if (prepend_path_if(name_of_file + 1, name_of_file + 1, ".dvi", dvi_directory) ||
      prepend_path_if(name_of_file + 1, name_of_file + 1, ".log", log_directory) ||
      prepend_path_if(name_of_file + 1, name_of_file + 1, ".aux", aux_directory) ||
      prepend_path_if(name_of_file + 1, name_of_file + 1, ".fmt", fmt_directory) ||
      prepend_path_if(name_of_file + 1, name_of_file + 1, ".pdf", pdf_directory))
  {
    if (open_trace_flag)
      printf("After prepend %s\n", name_of_file + 1);
  }

  if (open_trace_flag)
    printf(" Open `%s' for output ", name_of_file + 1);

  *f = fopen((char *) name_of_file + 1, fopen_mode);

  if (*f == NULL)
  {
    string temp_dir = kpse_var_value("TEXMFOUTPUT");

    if (temp_dir != NULL)
    {
      unsigned char temp_name[file_name_size];
      xconcat3((char *) temp_name, temp_dir, PATH_SEP_STRING, (char *) name_of_file + 1);

      if (deslash)
        unixify((char *) temp_name);
      
      *f = fopen((char *) temp_name, fopen_mode);

      if (*f)
        strcpy((char *) name_of_file + 1, (char *) temp_name);
    }
  }

#ifdef COMPACTFORMAT
  if (strstr((char *) name_of_file + 1, ".fmt") != NULL)
    gz_fmt_file = gzdopen(fileno(*f), "wb9");
#endif

  if (strstr((char *) name_of_file + 1, ".dvi") != NULL)
    dvi_file_name = xstrdup_name();
  else if (strstr((char *) name_of_file + 1, ".pdf") != NULL)
    pdf_file_name = xstrdup_name();
  else if (strstr((char *) name_of_file + 1, ".log") != NULL)
    log_file_name = xstrdup_name();

  temp_length = strlen((char *) name_of_file + 1);
  name_of_file[temp_length + 1] = ' ';

  if (*f)
    name_length = temp_length;
  
  return (*f != NULL);
}