void file_info_to_attrib(LPBY_HANDLE_FILE_INFORMATION file_info, FILE_ID_INFO *fileid_info, Attrib *a)
{
	attrib_clear(a);
	a->flags = 0;
	a->flags |= SSH2_FILEXFER_ATTR_SIZE;
	a->size = (file_info->nFileSizeHigh * (MAXDWORD+1)) + file_info->nFileSizeLow;
	a->flags |= SSH2_FILEXFER_ATTR_UIDGID;
	a->uid = 0;
	a->gid = 0;
	a->flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
	a->perm = 0644;
	
	if ( file_info->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
		a->perm = 0755;
		a->perm ^= S_IFDIR;
	} else {
		a->perm ^= S_IFREG;
	}
	
	if ( file_info->dwFileAttributes & FILE_ATTRIBUTE_READONLY )
		a->perm &= ~0222;
	
	a->flags |= SSH2_FILEXFER_ATTR_ACMODTIME;
	a->atime = filetime_to_time_t( file_info->ftLastAccessTime );
	a->mtime = filetime_to_time_t( file_info->ftLastWriteTime );
	
}
Beispiel #2
0
int mingw_fstat(int fd, struct stat *buf)
{
	HANDLE fh = (HANDLE)_get_osfhandle(fd);
	BY_HANDLE_FILE_INFORMATION fdata;

	if (fh == INVALID_HANDLE_VALUE) {
		errno = EBADF;
		return -1;
	}
	/* direct non-file handles to MS's fstat() */
	if (GetFileType(fh) != FILE_TYPE_DISK)
		return _fstati64(fd, buf);

	if (GetFileInformationByHandle(fh, &fdata)) {
		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		buf->st_size = fdata.nFileSizeLow |
			(((off_t)fdata.nFileSizeHigh)<<32);
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		return 0;
	}
	errno = EBADF;
	return -1;
}
Beispiel #3
0
int mingw_fstat(int fd, struct mingw_stat *buf)
{
	HANDLE fh = (HANDLE)_get_osfhandle(fd);
	BY_HANDLE_FILE_INFORMATION fdata;

	if (fh == INVALID_HANDLE_VALUE) {
		errno = EBADF;
		return -1;
	}
	/* direct non-file handles to MS's fstat() */
	if (GetFileType(fh) != FILE_TYPE_DISK) {
		struct stat st;
		if (fstat(fd, &st))
			return -1;
		buf->st_ino = st.st_ino;
		buf->st_gid = st.st_gid;
		buf->st_uid = st.st_uid;
		buf->st_mode = st.st_mode;
		buf->st_size = st.st_size;
		buf->st_blocks = size_to_blocks(buf->st_size);
		buf->st_dev = st.st_dev;
		buf->st_atime = st.st_atime;
		buf->st_mtime = st.st_mtime;
		buf->st_ctime = st.st_ctime;
		return 0;
	}

	if (GetFileInformationByHandle(fh, &fdata)) {
		int fMode = S_IREAD;
		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			fMode |= S_IFDIR;
		else
			fMode |= S_IFREG;
		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			fMode |= S_IWRITE;

		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_mode = fMode;
		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
		buf->st_blocks = size_to_blocks(buf->st_size);
		buf->st_dev = _getdrive() - 1;
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		return 0;
	}
	errno = EBADF;
	return -1;
}
Beispiel #4
0
static int do_lstat(const char *file_name, struct stat *buf)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;
	wchar_t* fbuf = gitwin_to_utf16(file_name);

	if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) {
		int fMode = S_IREAD;

		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			fMode |= S_IFDIR;
		else
			fMode |= S_IFREG;

		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			fMode |= S_IWRITE;

		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
			fMode |= S_IFLNK;

		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = (mode_t)fMode;
		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
		buf->st_dev = buf->st_rdev = (_getdrive() - 1);
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));

		git__free(fbuf);
		return GIT_SUCCESS;
	}

	git__free(fbuf);

	switch (GetLastError()) {
		case ERROR_ACCESS_DENIED:
		case ERROR_SHARING_VIOLATION:
		case ERROR_LOCK_VIOLATION:
		case ERROR_SHARING_BUFFER_EXCEEDED:
			return GIT_EOSERR;

		case ERROR_BUFFER_OVERFLOW:
		case ERROR_NOT_ENOUGH_MEMORY:
			return GIT_ENOMEM;

		default:
			return GIT_EINVALIDPATH;
	}
}
Beispiel #5
0
/* We keep the do_lstat code in a separate function to avoid recursion.
 * When a path ends with a slash, the stat will fail with ENOENT. In
 * this case, we strip the trailing slashes and stat again.
 *
 * If follow is true then act like stat() and report on the link
 * target. Otherwise report on the link itself.
 */
static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf)
{
	int err;
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (!(err = get_file_attr(file_name, &fdata))) {
		int len = strlen(file_name);

		buf->st_ino = 0;
		buf->st_uid = DEFAULT_UID;
		buf->st_gid = DEFAULT_GID;
		buf->st_nlink = 1;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		if (len > 4 && (!strcasecmp(file_name+len-4, ".exe") ||
						!strcasecmp(file_name+len-4, ".com")))
			buf->st_mode |= S_IEXEC;
		buf->st_size = fdata.nFileSizeLow |
			(((off64_t)fdata.nFileSizeHigh)<<32);
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
			WIN32_FIND_DATAA findbuf;
			HANDLE handle = FindFirstFileA(file_name, &findbuf);
			if (handle != INVALID_HANDLE_VALUE) {
				if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
						(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
					if (follow) {
						char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
						buf->st_size = readlink(file_name, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
					} else {
						buf->st_mode = S_IFLNK;
					}
					buf->st_mode |= S_IREAD;
					if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
						buf->st_mode |= S_IWRITE;
				}
				FindClose(handle);
			}
		}

		/*
		 * Assume a block is 4096 bytes and calculate number of 512 byte
		 * sectors.
		 */
		buf->st_blksize = 4096;
		buf->st_blocks = ((buf->st_size+4095)>>12)<<3;
		return 0;
	}
Beispiel #6
0
static int do_lstat(const char *file_name, struct stat *buf)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;
	DWORD last_error;
	wchar_t* fbuf = gitwin_to_utf16(file_name);
	if (!fbuf)
		return -1;

	if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) {
		int fMode = S_IREAD;

		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			fMode |= S_IFDIR;
		else
			fMode |= S_IFREG;

		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			fMode |= S_IWRITE;

		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
			fMode |= S_IFLNK;

		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = (mode_t)fMode;
		buf->st_size = ((git_off_t)fdata.nFileSizeHigh << 32) + fdata.nFileSizeLow;
		buf->st_dev = buf->st_rdev = (_getdrive() - 1);
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));

		git__free(fbuf);
		return 0;
	}

	last_error = GetLastError();
	if (last_error == ERROR_FILE_NOT_FOUND)
		errno = ENOENT;
	else if (last_error == ERROR_PATH_NOT_FOUND)
		errno = ENOTDIR;

	git__free(fbuf);
	return -1;
}
Beispiel #7
0
/* We keep the do_lstat code in a separate function to avoid recursion.
 * When a path ends with a slash, the stat will fail with ENOENT. In
 * this case, we strip the trailing slashes and stat again.
 */
static int do_lstat(const char *file_name, struct stat *buf)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (GetFileAttributesExA(file_name, GetFileExInfoStandard, &fdata)) {
		int fMode = S_IREAD;
		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			fMode |= S_IFDIR;
		else
			fMode |= S_IFREG;
		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			fMode |= S_IWRITE;

		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_mode = fMode;
		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
		buf->st_blocks = size_to_blocks(buf->st_size);
		buf->st_dev = _getdrive() - 1;
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		errno = 0;
		return 0;
	}

	switch (GetLastError()) {
	case ERROR_ACCESS_DENIED:
	case ERROR_SHARING_VIOLATION:
	case ERROR_LOCK_VIOLATION:
	case ERROR_SHARING_BUFFER_EXCEEDED:
		errno = EACCES;
		break;
	case ERROR_BUFFER_OVERFLOW:
		errno = ENAMETOOLONG;
		break;
	case ERROR_NOT_ENOUGH_MEMORY:
		errno = ENOMEM;
		break;
	default:
		errno = ENOENT;
		break;
	}
	return -1;
}
Beispiel #8
0
int lstat(const char *path, struct stat *buffer)
{
    WIN32_FILE_ATTRIBUTE_DATA fdata;

    if (GetFileAttributesEx(path, GetFileExInfoStandard, &fdata))
    {
        int fMode = S_IREAD;
        if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            fMode |= S_IFDIR;
        else
            fMode |= S_IFREG;
        if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
            fMode |= S_IWRITE;

        buffer->st_ino = 0;
        buffer->st_gid = 0;
        buffer->st_uid = 0;
        buffer->st_nlink = 1;
        buffer->st_mode = fMode;
        buffer->st_size = fdata.nFileSizeLow;
        buffer->st_dev = buffer->st_rdev = 0;
        buffer->st_atime = filetime_to_time_t(&fdata.ftLastAccessTime);
        buffer->st_mtime = filetime_to_time_t(&fdata.ftLastWriteTime);
        buffer->st_ctime = filetime_to_time_t(&fdata.ftCreationTime);

        if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
        {
            WIN32_FIND_DATA find;
            HANDLE handle = FindFirstFile(path, &find);
            if (handle != INVALID_HANDLE_VALUE)
            {
                if ((find.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
                        (find.dwReserved0 == IO_REPARSE_TAG_SYMLINK))
                {
                    buffer->st_mode = S_IFLNK;
                }
            }
        }
        _set_errno(0);
        return 0;
    }

    errno = winErrorToPosix(GetLastError());
    return -1;
}
Beispiel #9
0
/* We keep the do_lstat code in a separate function to avoid recursion.
 * When a path ends with a slash, the stat will fail with ENOENT. In
 * this case, we strip the trailing slashes and stat again.
 */
static int do_lstat(const char *file_name, struct stat *buf)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (!(errno = get_file_attr(file_name, &fdata))) {
		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		return 0;
	}
	return -1;
}
Beispiel #10
0
/* We keep the do_lstat code in a separate function to avoid recursion.
 * When a path ends with a slash, the stat will fail with ENOENT. In
 * this case, we strip the trailing slashes and stat again.
 *
 * If follow is true then act like stat() and report on the link
 * target. Otherwise report on the link itself.
 */
static int do_lstat(int follow, const char *file_name, struct stat *buf)
{
	int err;
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (!(err = get_file_attr(file_name, &fdata))) {
		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		buf->st_size = fdata.nFileSizeLow |
			(((off_t)fdata.nFileSizeHigh)<<32);
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
			WIN32_FIND_DATAA findbuf;
			HANDLE handle = FindFirstFileA(file_name, &findbuf);
			if (handle != INVALID_HANDLE_VALUE) {
				if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
						(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
					if (follow) {
						char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
						buf->st_size = readlink(file_name, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
					} else {
						buf->st_mode = S_IFLNK;
					}
					buf->st_mode |= S_IREAD;
					if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
						buf->st_mode |= S_IWRITE;
				}
				FindClose(handle);
			}
		}
		return 0;
	}
	errno = err;
	return -1;
}
Beispiel #11
0
static int do_lstat(
	const char *file_name, struct stat *buf, int posix_enotdir)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;
	wchar_t fbuf[GIT_WIN_PATH], lastch;
	int flen;

	flen = git__utf8_to_16(fbuf, GIT_WIN_PATH, file_name);

	/* truncate trailing slashes */
	for (; flen > 0; --flen) {
		lastch = fbuf[flen - 1];
		if (WIN32_IS_WSEP(lastch))
			fbuf[flen - 1] = L'\0';
		else if (lastch != L'\0')
			break;
	}

	if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) {
		int fMode = S_IREAD;

		if (!buf)
			return 0;

		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			fMode |= S_IFDIR;
		else
			fMode |= S_IFREG;

		if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			fMode |= S_IWRITE;

		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
			fMode |= S_IFLNK;

		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = (mode_t)fMode;
		buf->st_size = ((git_off_t)fdata.nFileSizeHigh << 32) + fdata.nFileSizeLow;
		buf->st_dev = buf->st_rdev = (_getdrive() - 1);
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));

		/* Windows symlinks have zero file size, call readlink to determine
		 * the length of the path pointed to, which we expect everywhere else
		 */
		if (S_ISLNK(fMode)) {
			char target[GIT_WIN_PATH];
			int readlink_result;

			readlink_result = p_readlink(file_name, target, GIT_WIN_PATH);

			if (readlink_result == -1)
				return -1;

			buf->st_size = strlen(target);
		}

		return 0;
	}

	errno = ENOENT;

	/* We need POSIX behavior, then ENOTDIR must set when any of the folders in the
	 * file path is a regular file,otherwise ENOENT must be set.
	 */
	if (posix_enotdir) {
		/* scan up path until we find an existing item */
		while (1) {
			/* remove last directory component */
			for (--flen; flen > 0 && !WIN32_IS_WSEP(fbuf[flen]); --flen);

			if (flen <= 0)
				break;

			fbuf[flen] = L'\0';

			if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) {
				if (!(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
					errno = ENOTDIR;
				break;
			}
		}
	}

	return -1;
}
char *
win32_ls_file(const char *name, LPWIN32_FIND_DATA file, int remote, int si_units)
{
	int ulen, glen, sz = 0;
	//struct tm *ltime = localtime(&st->st_mtime);
	char *user, *group;
	char buf[1024], mode[11+1], tbuf[12+1], ubuf[11+1], gbuf[11+1];
	char sbuf[FMT_SCALED_STRSIZE];
	SYSTEMTIME now;
	SYSTEMTIME ftime;
	
	time_t mtime = filetime_to_time_t( file->ftLastWriteTime );
	BOOL time_conv_ok = FileTimeToSystemTime( &file->ftLastWriteTime, &ftime);
	struct tm *ltime = localtime( &mtime );
	
    if (!time_conv_ok) {
		error("Failed to convert file time to localtime");
	}
	
	strmode(0644, mode);
	if (!remote) {
		user = user_from_uid(0, 0);
	} else {
		snprintf(ubuf, sizeof ubuf, "%u", 0);
		user = ubuf;
	}
	
	if (!remote) {
		group = group_from_gid(0, 0);
	} else {
		snprintf(gbuf, sizeof gbuf, "%u", 0);
		group = gbuf;
	}
	
	if (time_conv_ok) {
		//now = time(NULL);
		GetSystemTime(&now);
		
		if ( (time_diff(now, ftime) / 10000000ULL) < (365*24*60*60) ) {
		//if (now - (365*24*60*60)/2 < st->st_mtime &&
		  //  now >= st->st_mtime)
			sz = strftime(tbuf, sizeof tbuf, "%b %e %H:%M", ltime);
		} else {
			sz = strftime(tbuf, sizeof tbuf, "%b %e  %Y", ltime);
		}
	}
	if (sz == 0)
		tbuf[0] = '\0';
	ulen = MAX(strlen(user), 8);
	glen = MAX(strlen(group), 8);
	long long size = (file->nFileSizeHigh * (MAXDWORD+1)) + file->nFileSizeLow;
		
	if (si_units) {
		fmt_scaled(size, sbuf);
		snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8s %s %s", mode,
		    1 /*nlink -- FIXME */, ulen, user, glen, group,
		    sbuf, tbuf, name);
	} else {
		snprintf(buf, sizeof buf, "%s %3u %-*s %-*s %8llu %s %s", mode,
		    1 /*nlink -- FIXME */, ulen, user, glen, group,
		    size, tbuf, name);
	}
	return xstrdup(buf);
}