Beispiel #1
0
static bool posix_fcntl_lock(files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
{
	bool ret;

	DEBUG(8,("posix_fcntl_lock %d %d %.0f %.0f %d\n",fsp->fh->fd,op,(double)offset,(double)count,type));

	ret = SMB_VFS_LOCK(fsp, op, offset, count, type);

	if (!ret && ((errno == EFBIG) || (errno == ENOLCK) || (errno ==  EINVAL))) {

		DEBUG(0,("posix_fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n",
					(double)offset,(double)count));
		DEBUGADD(0,("an %s error. This can happen when using 64 bit lock offsets\n", strerror(errno)));
		DEBUGADD(0,("on 32 bit NFS mounted file systems.\n"));

		/*
		 * If the offset is > 0x7FFFFFFF then this will cause problems on
		 * 32 bit NFS mounted filesystems. Just ignore it.
		 */

		if (offset & ~((SMB_OFF_T)0x7fffffff)) {
			DEBUG(0,("Offset greater than 31 bits. Returning success.\n"));
			return True;
		}

		if (count & ~((SMB_OFF_T)0x7fffffff)) {
			/* 32 bit NFS file system, retry with smaller offset */
			DEBUG(0,("Count greater than 31 bits - retrying with 31 bit truncated length.\n"));
			errno = 0;
			count &= 0x7fffffff;
			ret = SMB_VFS_LOCK(fsp, op, offset, count, type);
		}
	}

	DEBUG(8,("posix_fcntl_lock: Lock call %s\n", ret ? "successful" : "failed"));
	return ret;
}
Beispiel #2
0
static NTSTATUS cmd_lock(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
	BOOL ret;
	int fd;
	int op;
	long offset;
	long count;
	int type;
	const char *typestr;
	
	if (argc != 6) {
		printf("Usage: lock <fd> <op> <offset> <count> <type>\n");
                printf("  ops: G = F_GETLK\n");
                printf("       S = F_SETLK\n");
                printf("       W = F_SETLKW\n");
                printf("  type: R = F_RDLCK\n");
                printf("        W = F_WRLCK\n");
                printf("        U = F_UNLCK\n");
		return NT_STATUS_OK;
	}

	if (sscanf(argv[1], "%d", &fd) == 0) {
		printf("lock: error=-1 (error parsing fd)\n");
		return NT_STATUS_UNSUCCESSFUL;
	}

	op = 0;
	switch (*argv[2]) {
	case 'G':
		op = F_GETLK;
		break;
	case 'S':
		op = F_SETLK;
		break;
	case 'W':
		op = F_SETLKW;
		break;
	default:
		printf("lock: error=-1 (invalid op flag!)\n");
		return NT_STATUS_UNSUCCESSFUL;
	}

	if (sscanf(argv[3], "%ld", &offset) == 0) {
		printf("lock: error=-1 (error parsing fd)\n");
		return NT_STATUS_UNSUCCESSFUL;
	}

	if (sscanf(argv[4], "%ld", &count) == 0) {
		printf("lock: error=-1 (error parsing fd)\n");
		return NT_STATUS_UNSUCCESSFUL;
	}

	type = 0;
	typestr = argv[5];
	while(*typestr) {
		switch (*typestr) {
		case 'R':
			type |= F_RDLCK;
			break;
		case 'W':
			type |= F_WRLCK;
			break;
		case 'U':
			type |= F_UNLCK;
			break;
		default:
			printf("lock: error=-1 (invalid type flag!)\n");
			return NT_STATUS_UNSUCCESSFUL;
		}
		typestr++;
	}

	printf("lock: debug lock(fd=%d, op=%d, offset=%ld, count=%ld, type=%d))\n", fd, op, offset, count, type);

	if ((ret = SMB_VFS_LOCK(vfs->files[fd], fd, op, offset, count, type)) == False) {
		printf("lock: error=%d (%s)\n", errno, strerror(errno));
		return NT_STATUS_UNSUCCESSFUL;
	}

	printf("lock: ok\n");
	return NT_STATUS_OK;
}