1*5331Samw /* 2*5331Samw * CDDL HEADER START 3*5331Samw * 4*5331Samw * The contents of this file are subject to the terms of the 5*5331Samw * Common Development and Distribution License (the "License"). 6*5331Samw * You may not use this file except in compliance with the License. 7*5331Samw * 8*5331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5331Samw * or http://www.opensolaris.org/os/licensing. 10*5331Samw * See the License for the specific language governing permissions 11*5331Samw * and limitations under the License. 12*5331Samw * 13*5331Samw * When distributing Covered Code, include this CDDL HEADER in each 14*5331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5331Samw * If applicable, add the following below this CDDL HEADER, with the 16*5331Samw * fields enclosed by brackets "[]" replaced with your own identifying 17*5331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 18*5331Samw * 19*5331Samw * CDDL HEADER END 20*5331Samw */ 21*5331Samw /* 22*5331Samw * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23*5331Samw * Use is subject to license terms. 24*5331Samw */ 25*5331Samw 26*5331Samw #pragma ident "%Z%%M% %I% %E% SMI" 27*5331Samw 28*5331Samw /* 29*5331Samw * The seek message is sent to set the current file pointer for FID. 30*5331Samw * This request should generally only be used by clients wishing to 31*5331Samw * find the size of a file, since all read and write requests include 32*5331Samw * the read or write file position as part of the SMB. This request 33*5331Samw * is inappropriate for large files, as the offsets specified are only 34*5331Samw * 32 bits. 35*5331Samw * 36*5331Samw * The CIFS/1.0 (1996) spec contains the following incomplete statement: 37*5331Samw * 38*5331Samw * "A seek which results in an Offset which can not be expressed 39*5331Samw * in 32 bits returns the least significant." 40*5331Samw * 41*5331Samw * It would probably be a mistake to make an assumption about what this 42*5331Samw * statement means. So, for now, we return an error if the resultant 43*5331Samw * file offset is beyond the 32-bit limit. 44*5331Samw */ 45*5331Samw 46*5331Samw #include <smbsrv/smb_incl.h> 47*5331Samw 48*5331Samw 49*5331Samw /* 50*5331Samw * smb_com_seek 51*5331Samw * 52*5331Samw * Client Request Description 53*5331Samw * ================================== ================================= 54*5331Samw * UCHAR WordCount; Count of parameter words = 4 55*5331Samw * USHORT Fid; File handle 56*5331Samw * USHORT Mode; Seek mode: 0, 1 or 2 57*5331Samw * LONG Offset; Relative offset 58*5331Samw * USHORT ByteCount; Count of data bytes = 0 59*5331Samw * 60*5331Samw * The starting point of the seek is set by Mode: 61*5331Samw * 62*5331Samw * 0 seek from start of file 63*5331Samw * 1 seek from current current position 64*5331Samw * 2 seek from end of file 65*5331Samw * 66*5331Samw * The "current position" reflects the offset plus data length specified in 67*5331Samw * the previous read, write or seek request, and the pointer set by this 68*5331Samw * command will be replaced by the offset specified in the next read, write 69*5331Samw * or seek command. 70*5331Samw * 71*5331Samw * Server Response Description 72*5331Samw * ================================== ================================= 73*5331Samw * UCHAR WordCount; Count of parameter words = 2 74*5331Samw * ULONG Offset; Offset from start of file 75*5331Samw * USHORT ByteCount; Count of data bytes = 0 76*5331Samw * 77*5331Samw * The response returns the new file pointer in Offset, which is expressed 78*5331Samw * as the offset from the start of the file, and may be beyond the current 79*5331Samw * end of file. An attempt to seek before the start of the file sets the 80*5331Samw * current file pointer to the start of the file. 81*5331Samw */ 82*5331Samw int 83*5331Samw smb_com_seek(struct smb_request *sr) 84*5331Samw { 85*5331Samw ushort_t mode; 86*5331Samw int32_t off; 87*5331Samw uint32_t off_ret; 88*5331Samw int rc; 89*5331Samw 90*5331Samw if (smbsr_decode_vwv(sr, "wwl", &sr->smb_fid, &mode, &off) != 0) { 91*5331Samw smbsr_decode_error(sr); 92*5331Samw /* NOTREACHED */ 93*5331Samw } 94*5331Samw 95*5331Samw sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid); 96*5331Samw if (sr->fid_ofile == NULL) { 97*5331Samw smbsr_raise_cifs_error(sr, NT_STATUS_INVALID_HANDLE, 98*5331Samw ERRDOS, ERRbadfid); 99*5331Samw /* NOTREACHED */ 100*5331Samw } 101*5331Samw 102*5331Samw if (mode == SMB_SEEK_END) { 103*5331Samw (void) smb_set_file_size(sr); 104*5331Samw } 105*5331Samw 106*5331Samw rc = smb_ofile_seek(sr->fid_ofile, mode, off, &off_ret); 107*5331Samw if (rc == 0) { 108*5331Samw smbsr_encode_result(sr, 2, 0, "blw", 2, off_ret, 0); 109*5331Samw return (SDRC_NORMAL_REPLY); 110*5331Samw } 111*5331Samw if (rc == EINVAL) { 112*5331Samw smbsr_raise_error(sr, ERRDOS, ERRbadfunc); 113*5331Samw /* NOTREACHED */ 114*5331Samw } 115*5331Samw if (rc == EOVERFLOW) { 116*5331Samw smbsr_raise_error(sr, ERRSRV, ERRerror); 117*5331Samw /* NOTREACHED */ 118*5331Samw } 119*5331Samw ASSERT(0); 120*5331Samw smbsr_raise_error(sr, ERRSRV, ERRerror); 121*5331Samw /* NOTREACHED */ 122*5331Samw 123*5331Samw /* 124*5331Samw * Although smbsr_raise_error() doesn't return and the compiler is 125*5331Samw * told so in smb_kproto.h it still has a problem if it doesn't 126*5331Samw * find here a return instruction with a value. 127*5331Samw */ 128*5331Samw return (0); 129*5331Samw } 130