15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 225772Sas200622 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw */ 255331Samw 265331Samw #pragma ident "%Z%%M% %I% %E% SMI" 275331Samw 285331Samw /* 295331Samw * The seek message is sent to set the current file pointer for FID. 305331Samw * This request should generally only be used by clients wishing to 315331Samw * find the size of a file, since all read and write requests include 325331Samw * the read or write file position as part of the SMB. This request 335331Samw * is inappropriate for large files, as the offsets specified are only 345331Samw * 32 bits. 355331Samw * 365331Samw * The CIFS/1.0 (1996) spec contains the following incomplete statement: 375331Samw * 385331Samw * "A seek which results in an Offset which can not be expressed 395331Samw * in 32 bits returns the least significant." 405331Samw * 415331Samw * It would probably be a mistake to make an assumption about what this 425331Samw * statement means. So, for now, we return an error if the resultant 435331Samw * file offset is beyond the 32-bit limit. 445331Samw */ 455331Samw 465331Samw #include <smbsrv/smb_incl.h> 475331Samw 485331Samw 495331Samw /* 505331Samw * smb_com_seek 515331Samw * 525331Samw * Client Request Description 535331Samw * ================================== ================================= 545331Samw * UCHAR WordCount; Count of parameter words = 4 555331Samw * USHORT Fid; File handle 565331Samw * USHORT Mode; Seek mode: 0, 1 or 2 575331Samw * LONG Offset; Relative offset 585331Samw * USHORT ByteCount; Count of data bytes = 0 595331Samw * 605331Samw * The starting point of the seek is set by Mode: 615331Samw * 625331Samw * 0 seek from start of file 635331Samw * 1 seek from current current position 645331Samw * 2 seek from end of file 655331Samw * 665331Samw * The "current position" reflects the offset plus data length specified in 675331Samw * the previous read, write or seek request, and the pointer set by this 685331Samw * command will be replaced by the offset specified in the next read, write 695331Samw * or seek command. 705331Samw * 715331Samw * Server Response Description 725331Samw * ================================== ================================= 735331Samw * UCHAR WordCount; Count of parameter words = 2 745331Samw * ULONG Offset; Offset from start of file 755331Samw * USHORT ByteCount; Count of data bytes = 0 765331Samw * 775331Samw * The response returns the new file pointer in Offset, which is expressed 785331Samw * as the offset from the start of the file, and may be beyond the current 795331Samw * end of file. An attempt to seek before the start of the file sets the 805331Samw * current file pointer to the start of the file. 815331Samw */ 826030Sjb150015 smb_sdrc_t 836139Sjb150015 smb_pre_seek(smb_request_t *sr) 846139Sjb150015 { 856139Sjb150015 DTRACE_SMB_1(op__Seek__start, smb_request_t *, sr); 866139Sjb150015 return (SDRC_SUCCESS); 876139Sjb150015 } 886139Sjb150015 896139Sjb150015 void 906139Sjb150015 smb_post_seek(smb_request_t *sr) 916139Sjb150015 { 926139Sjb150015 DTRACE_SMB_1(op__Seek__done, smb_request_t *, sr); 936139Sjb150015 } 946139Sjb150015 956139Sjb150015 smb_sdrc_t 966139Sjb150015 smb_com_seek(smb_request_t *sr) 975331Samw { 985331Samw ushort_t mode; 995331Samw int32_t off; 1005331Samw uint32_t off_ret; 1015331Samw int rc; 1025331Samw 1036030Sjb150015 if (smbsr_decode_vwv(sr, "wwl", &sr->smb_fid, &mode, &off) != 0) 1046139Sjb150015 return (SDRC_ERROR); 1055331Samw 1065331Samw sr->fid_ofile = smb_ofile_lookup_by_fid(sr->tid_tree, sr->smb_fid); 1075331Samw if (sr->fid_ofile == NULL) { 1085772Sas200622 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid); 1096139Sjb150015 return (SDRC_ERROR); 1105331Samw } 1115331Samw 1126030Sjb150015 if (mode == SMB_SEEK_END) 113*6600Sas200622 (void) smb_set_file_size(sr, sr->fid_ofile->f_node); 1145331Samw 1155772Sas200622 if ((rc = smb_ofile_seek(sr->fid_ofile, mode, off, &off_ret)) != 0) { 1165772Sas200622 if (rc == EINVAL) { 1175772Sas200622 smbsr_error(sr, 0, ERRDOS, ERRbadfunc); 1186139Sjb150015 return (SDRC_ERROR); 1195772Sas200622 } else { 1205772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRerror); 1216139Sjb150015 return (SDRC_ERROR); 1225772Sas200622 } 1235331Samw } 1245331Samw 1256030Sjb150015 if (smbsr_encode_result(sr, 2, 0, "blw", 2, off_ret, 0)) 1266139Sjb150015 return (SDRC_ERROR); 1276030Sjb150015 1286139Sjb150015 return (SDRC_SUCCESS); 1295331Samw } 130