示例#1
0
static int
fudge_stat(const char *path, struct stat *st)
{
    Attrib *a;

    if (!(a = do_stat(cur.conn, (char *)path, 0)))
        return(-1);

    attrib_to_stat(a, st);

    return(0);
}
示例#2
0
void SFTP::process_fsetstat(void)
{
	Attrib a;
	u_int32_t id;
	int handle;
	int status = SSH2_FX_OK;

	id = get_int();
	handle = get_handle();
  a = get_attrib(this->iqueue);
	debug("request %u: fsetstat handle %d", id, handle);
	HANDLE fh = handle_to_fh(handle);
	if (fh == INVALID_HANDLE_VALUE) 
  {
		status = SSH2_FX_FAILURE;
	} 
  else 
  {
		if (status == SSH2_FX_OK
        && a.flags & SSH2_FILEXFER_ATTR_UIDGID) 
    {
#if 0
			logit("set \"%s\" owner %lu group %lu", name,
			    (u_long)a->uid, (u_long)a->gid);
#ifdef HAVE_FCHOWN
			ret = fchown(fd, a->uid, a->gid);
#else
			ret = chown(name, a->uid, a->gid);
#endif
			if (ret == -1)
				status = errno_to_portable(::GetLastError ());
#endif
      status = SSH2_FX_OP_UNSUPPORTED;
		}

		if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
			logit("set \"%s\" size %llu",
			    "???", (unsigned long long)a.size);

      LARGE_INTEGER largeOffset;
      largeOffset.QuadPart = a.size;
      if (!::SetFilePointerEx (fh, largeOffset, NULL, FILE_BEGIN)
          || !::SetEndOfFile (fh)
          )
      {
			  status = errno_to_portable(::GetLastError ());
      }
		}

    if (status == SSH2_FX_OK)
    {
      BY_HANDLE_FILE_INFORMATION stBefore;
      FILE_BASIC_INFO stAfter;
      WIN32_FILE_ATTRIBUTE_DATA stRequested;

		  if (::GetFileInformationByHandle (fh, &stBefore)) 
      {
        attrib_to_stat (&a, &stRequested);
        
        if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
        {
  			  logit("set \"%s\" mode %04o", "???", a.perm);
          stAfter.FileAttributes = stRequested.dwFileAttributes;
        }
        else
          stAfter.FileAttributes = stBefore.dwFileAttributes;
  
        if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME)
        {
			    /*char buf[64];
			    time_t t = a->mtime;

			    strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
			        localtime(&t));
			    logit("set \"%s\" modtime %s", name, buf);*/ //TODO

          COPY_TO_LARGE_INTEGER
            (stAfter.LastAccessTime,
             stRequested.ftLastAccessTime.dwLowDateTime,
             stRequested.ftLastAccessTime.dwHighDateTime);

          COPY_TO_LARGE_INTEGER
            (stAfter.LastWriteTime, 
             stRequested.ftLastWriteTime.dwLowDateTime,
             stRequested.ftLastWriteTime.dwHighDateTime);
        }
        else
        {
          COPY_TO_LARGE_INTEGER
            (stAfter.LastAccessTime,
              stBefore.ftLastAccessTime.dwLowDateTime,
              stBefore.ftLastAccessTime.dwHighDateTime);

          COPY_TO_LARGE_INTEGER
            (stAfter.LastWriteTime,
             stBefore.ftLastWriteTime.dwLowDateTime,
             stBefore.ftLastWriteTime.dwHighDateTime);
        }

        COPY_TO_LARGE_INTEGER
          (stAfter.CreationTime,
           stBefore.ftCreationTime.dwLowDateTime,
           stBefore.ftCreationTime.dwHighDateTime);

       SYSTEMTIME systemTime;
       FILETIME currentTime;
       ::GetSystemTime(&systemTime);
       ::SystemTimeToFileTime(&systemTime, &currentTime);
       COPY_TO_LARGE_INTEGER
          (stAfter.ChangeTime,
           currentTime.dwLowDateTime, 
           currentTime.dwHighDateTime);
    
        if (!::SetFileInformationByHandle
            (fh,
             FileBasicInfo,
             &stAfter,
             sizeof (stAfter)
             )
            )
			  status = errno_to_portable(::GetLastError ());

		  } 
      else
      {
			  status = errno_to_portable(::GetLastError ());
      }
    }
	}
	send_status(id, status);
}
示例#3
0
/* sftp ls.1 replacement which handles path globs */
static int
do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path,
    int lflag)
{
	glob_t g;
	u_int i, c = 1, colspace = 0, columns = 1;
	Attrib *a = NULL;

	memset(&g, 0, sizeof(g));

	if (remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE,
	    NULL, &g) || (g.gl_pathc && !g.gl_matchc)) {
		if (g.gl_pathc)
			globfree(&g);
		error("Can't ls: \"%s\" not found", path);
		return (-1);
	}

	if (interrupted)
		goto out;

	/*
	 * If the glob returns a single match and it is a directory,
	 * then just list its contents.
	 */
	if (g.gl_matchc == 1) {
		if ((a = do_lstat(conn, g.gl_pathv[0], 1)) == NULL) {
			globfree(&g);
			return (-1);
		}
		if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
		    S_ISDIR(a->perm)) {
			int err;

			err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag);
			globfree(&g);
			return (err);
		}
	}

	if (!(lflag & LS_SHORT_VIEW)) {
		u_int m = 0, width = 80;
		struct winsize ws;

		/* Count entries for sort and find longest filename */
		for (i = 0; g.gl_pathv[i]; i++)
			m = MAX(m, strlen(g.gl_pathv[i]));

		if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
			width = ws.ws_col;

		columns = width / (m + 2);
		columns = MAX(columns, 1);
		colspace = width / columns;
	}

	for (i = 0; g.gl_pathv[i] && !interrupted; i++, a = NULL) {
		char *fname;

		fname = path_strip(g.gl_pathv[i], strip_path);

		if (lflag & LS_LONG_VIEW) {
			char *lname;
			struct stat sb;

			/*
			 * XXX: this is slow - 1 roundtrip per path
			 * A solution to this is to fork glob() and
			 * build a sftp specific version which keeps the
			 * attribs (which currently get thrown away)
			 * that the server returns as well as the filenames.
			 */
			memset(&sb, 0, sizeof(sb));
			if (a == NULL)
				a = do_lstat(conn, g.gl_pathv[i], 1);
			if (a != NULL)
				attrib_to_stat(a, &sb);
			lname = ls_file(fname, &sb, 1);
			printf("%s\n", lname);
			xfree(lname);
		} else {
			printf("%-*s", colspace, fname);
			if (c >= columns) {
				printf("\n");
				c = 1;
			} else
				c++;
		}
		xfree(fname);
	}

	if (!(lflag & LS_LONG_VIEW) && (c != 1))
		printf("\n");

 out:
	if (g.gl_pathc)
		globfree(&g);

	return (0);
}
示例#4
0
void SFTP::process_setstat(void)
{
	Attrib a;
	u_int32_t id;
	char *utf8_name;
	int status = SSH2_FX_OK;
  WIN32_FILE_ATTRIBUTE_DATA st;

  try
  {
	  id = get_int();
	  utf8_name = (char*) get_string(NULL);
    a = get_attrib(this->iqueue);
	  debug("request %u: setstat name \"%s\"", id, utf8_name);

    const SFTPFilePath path = pathFact.create_path (utf8_name);
    attrib_to_stat (&a, &st);

	  if (a.flags & SSH2_FILEXFER_ATTR_SIZE) 
    {
#if 0
		  logit("set \"%s\" size %llu",
		      utf8_name, (unsigned long long)a->size);

      LARGE_INTEGER largeOffset;
      largeOffset.QuadPart = a->size;
      if (!::SetFilePointerEx (fh, largeOffset, NULL, FILE_BEGIN)
          || !::SetEndOfFile (fh)
          )
      {
			  status = errno_to_portable(::GetLastError ());
      }
#endif
      status = SSH2_FX_OP_UNSUPPORTED;
	  }

	  if (status == SSH2_FX_OK
        && a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) 
    {
#if 0
		  char buf[64];
		  time_t t = a->mtime;

		  strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
		      localtime(&t));
		  logit("set \"%s\" modtime %s", name, buf);
		  ret = utimes(name, attrib_to_tv(a));
		  if (ret == -1)
			  status = errno_to_portable(::GetLastError ());
#endif
      status = SSH2_FX_OP_UNSUPPORTED;
	  }

	  if (status == SSH2_FX_OK
        && a.flags & SSH2_FILEXFER_ATTR_UIDGID) 
    {
#if 0
		  logit("set \"%s\" owner %lu group %lu", name,
		      (u_long)a->uid, (u_long)a->gid);
		  ret = chown(name, a->uid, a->gid);
		  if (ret == -1)
			  status = errno_to_portable(::GetLastError ());
#endif
      status = SSH2_FX_OP_UNSUPPORTED;
	  }

    // access premissions
	  if (status == SSH2_FX_OK
        && a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) 
    {
		  logit("set \"%s\" mode %04o", utf8_name, a.perm);
      if (!::SetFileAttributesW
        (path.get_for_call ().c_str (),
             st.dwFileAttributes)
          )
      {
			  status = errno_to_portable(::GetLastError ());
      }
	  }
  }
  catch (Path::InvalidPath&)
  {
    //logit 
    status = SSH2_FX_FAILURE; 
    // TODO return the reason
  }
  catch (...)
  {
    status = SSH2_FX_FAILURE; 
    error ("unhandled exception in %s", __FUNCTION__);
  }

	send_status(id, status);
	if (utf8_name) xfree(utf8_name);
}
示例#5
0
/* sftp ls.1 replacement for directories */
static int
do_ls_dir(struct sftp_conn *conn, char *path, char *strip_path, int lflag)
{
	int n;
	u_int c = 1, colspace = 0, columns = 1;
	SFTP_DIRENT **d;

	if ((n = do_readdir(conn, path, &d)) != 0)
		return (n);

	if (!(lflag & LS_SHORT_VIEW)) {
		u_int m = 0, width = 80;
		struct winsize ws;
		char *tmp;

		/* Count entries for sort and find longest filename */
		for (n = 0; d[n] != NULL; n++) {
			if (d[n]->filename[0] != '.' || (lflag & LS_SHOW_ALL))
				m = MAX(m, strlen(d[n]->filename));
		}

		/* Add any subpath that also needs to be counted */
		tmp = path_strip(path, strip_path);
		m += strlen(tmp);
		xfree(tmp);

		if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
			width = ws.ws_col;

		columns = width / (m + 2);
		columns = MAX(columns, 1);
		colspace = width / columns;
		colspace = MIN(colspace, width);
	}

	if (lflag & SORT_FLAGS) {
		for (n = 0; d[n] != NULL; n++)
			;	/* count entries */
		sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);
		qsort(d, n, sizeof(*d), sdirent_comp);
	}

	for (n = 0; d[n] != NULL && !interrupted; n++) {
		char *tmp, *fname;

		if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL))
			continue;

		tmp = path_append(path, d[n]->filename);
		fname = path_strip(tmp, strip_path);
		xfree(tmp);

		if (lflag & LS_LONG_VIEW) {
			if (lflag & LS_NUMERIC_VIEW) {
				char *lname;
				struct stat sb;

				memset(&sb, 0, sizeof(sb));
				attrib_to_stat(&d[n]->a, &sb);
				lname = ls_file(fname, &sb, 1);
				printf("%s\n", lname);
				xfree(lname);
			} else
				printf("%s\n", d[n]->longname);
		} else {
			printf("%-*s", colspace, fname);
			if (c >= columns) {
				printf("\n");
				c = 1;
			} else
				c++;
		}

		xfree(fname);
	}

	if (!(lflag & LS_LONG_VIEW) && (c != 1))
		printf("\n");

	free_sftp_dirents(d);
	return (0);
}