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 /* 22*8934SJose.Borrego@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw */ 255331Samw 265331Samw /* 275331Samw * The seek message is sent to set the current file pointer for FID. 285331Samw * This request should generally only be used by clients wishing to 295331Samw * find the size of a file, since all read and write requests include 305331Samw * the read or write file position as part of the SMB. This request 315331Samw * is inappropriate for large files, as the offsets specified are only 325331Samw * 32 bits. 335331Samw * 345331Samw * The CIFS/1.0 (1996) spec contains the following incomplete statement: 355331Samw * 365331Samw * "A seek which results in an Offset which can not be expressed 375331Samw * in 32 bits returns the least significant." 385331Samw * 395331Samw * It would probably be a mistake to make an assumption about what this 405331Samw * statement means. So, for now, we return an error if the resultant 415331Samw * file offset is beyond the 32-bit limit. 425331Samw */ 435331Samw 445331Samw #include <smbsrv/smb_incl.h> 455331Samw 465331Samw 475331Samw /* 485331Samw * smb_com_seek 495331Samw * 505331Samw * Client Request Description 515331Samw * ================================== ================================= 525331Samw * UCHAR WordCount; Count of parameter words = 4 535331Samw * USHORT Fid; File handle 545331Samw * USHORT Mode; Seek mode: 0, 1 or 2 555331Samw * LONG Offset; Relative offset 565331Samw * USHORT ByteCount; Count of data bytes = 0 575331Samw * 585331Samw * The starting point of the seek is set by Mode: 595331Samw * 605331Samw * 0 seek from start of file 615331Samw * 1 seek from current current position 625331Samw * 2 seek from end of file 635331Samw * 645331Samw * The "current position" reflects the offset plus data length specified in 655331Samw * the previous read, write or seek request, and the pointer set by this 665331Samw * command will be replaced by the offset specified in the next read, write 675331Samw * or seek command. 685331Samw * 695331Samw * Server Response Description 705331Samw * ================================== ================================= 715331Samw * UCHAR WordCount; Count of parameter words = 2 725331Samw * ULONG Offset; Offset from start of file 735331Samw * USHORT ByteCount; Count of data bytes = 0 745331Samw * 755331Samw * The response returns the new file pointer in Offset, which is expressed 765331Samw * as the offset from the start of the file, and may be beyond the current 775331Samw * end of file. An attempt to seek before the start of the file sets the 785331Samw * current file pointer to the start of the file. 795331Samw */ 806030Sjb150015 smb_sdrc_t 816139Sjb150015 smb_pre_seek(smb_request_t *sr) 826139Sjb150015 { 836139Sjb150015 DTRACE_SMB_1(op__Seek__start, smb_request_t *, sr); 846139Sjb150015 return (SDRC_SUCCESS); 856139Sjb150015 } 866139Sjb150015 876139Sjb150015 void 886139Sjb150015 smb_post_seek(smb_request_t *sr) 896139Sjb150015 { 906139Sjb150015 DTRACE_SMB_1(op__Seek__done, smb_request_t *, sr); 916139Sjb150015 } 926139Sjb150015 936139Sjb150015 smb_sdrc_t 946139Sjb150015 smb_com_seek(smb_request_t *sr) 955331Samw { 965331Samw ushort_t mode; 975331Samw int32_t off; 985331Samw uint32_t off_ret; 995331Samw int rc; 1005331Samw 1016030Sjb150015 if (smbsr_decode_vwv(sr, "wwl", &sr->smb_fid, &mode, &off) != 0) 1026139Sjb150015 return (SDRC_ERROR); 1035331Samw 104*8934SJose.Borrego@Sun.COM smbsr_lookup_file(sr); 1055331Samw if (sr->fid_ofile == NULL) { 1065772Sas200622 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid); 1076139Sjb150015 return (SDRC_ERROR); 1085331Samw } 1095331Samw 1107961SNatalie.Li@Sun.COM sr->user_cr = smb_ofile_getcred(sr->fid_ofile); 1117961SNatalie.Li@Sun.COM 1126030Sjb150015 if (mode == SMB_SEEK_END) 1136600Sas200622 (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