xref: /titanic_51/usr/src/uts/common/fs/smbsrv/smb_find.c (revision a90cf9f29973990687fa61de9f1f6ea22e924e40)
1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21da6c28aaSamw /*
22148c5f43SAlan Wright  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23*a90cf9f2SGordon Ross  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
24da6c28aaSamw  */
25da6c28aaSamw 
26bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
27da6c28aaSamw 
28da6c28aaSamw /*
297f667e74Sjose borrego  * smb_com_search
307f667e74Sjose borrego  * smb_com_find, smb_com_find_close
317f667e74Sjose borrego  * smb_find_unique
32da6c28aaSamw  *
337f667e74Sjose borrego  * These commands are used for directory searching. They share the same
347f667e74Sjose borrego  * message formats, defined below:
35da6c28aaSamw  *
36da6c28aaSamw  * Client Request                     Description
377f667e74Sjose borrego  * ---------------------------------- ---------------------------------
38da6c28aaSamw  *
397f667e74Sjose borrego  * UCHAR WordCount;                   Count of parameter words = 2
407f667e74Sjose borrego  * USHORT MaxCount;                   Number of dir. entries to return
417f667e74Sjose borrego  * USHORT SearchAttributes;
427f667e74Sjose borrego  * USHORT ByteCount;                  Count of data bytes;  min = 5
437f667e74Sjose borrego  * UCHAR BufferFormat1;               0x04 -- ASCII
447f667e74Sjose borrego  * UCHAR FileName[];                  File name, may be null
457f667e74Sjose borrego  * UCHAR BufferFormat2;               0x05 -- Variable block
467f667e74Sjose borrego  * USHORT ResumeKeyLength;            Length of resume key, may be 0
477f667e74Sjose borrego  * UCHAR ResumeKey[];                 Resume key
48da6c28aaSamw  *
497f667e74Sjose borrego  * FileName specifies the file to be sought.  SearchAttributes indicates
507f667e74Sjose borrego  * the attributes that the file must have.  If  SearchAttributes is
517f667e74Sjose borrego  * zero then only normal files are returned.  If the system file, hidden or
527f667e74Sjose borrego  * directory attributes are specified then the search is inclusive - both the
537f667e74Sjose borrego  * specified type(s) of files and normal files are returned.  If the volume
547f667e74Sjose borrego  * label attribute is specified then the search is exclusive, and only the
557f667e74Sjose borrego  * volume label entry is returned.
567f667e74Sjose borrego  *
577f667e74Sjose borrego  * MaxCount specifies the number of directory entries to be returned.
58da6c28aaSamw  *
59da6c28aaSamw  * Server Response                    Description
607f667e74Sjose borrego  * ---------------------------------- ---------------------------------
61da6c28aaSamw  *
627f667e74Sjose borrego  * UCHAR WordCount;                   Count of parameter words = 1
637f667e74Sjose borrego  * USHORT Count;                      Number of entries returned
647f667e74Sjose borrego  * USHORT ByteCount;                  Count of data bytes;  min = 3
657f667e74Sjose borrego  * UCHAR BufferFormat;                0x05 -- Variable block
667f667e74Sjose borrego  * USHORT DataLength;                 Length of data
677f667e74Sjose borrego  * UCHAR DirectoryInformationData[];  Data
68da6c28aaSamw  *
697f667e74Sjose borrego  * The response will contain one or more directory entries as determined by
707f667e74Sjose borrego  * the Count field.  No more than MaxCount entries will be returned.  Only
717f667e74Sjose borrego  * entries that match the sought FileName and SearchAttributes combination
727f667e74Sjose borrego  * will be returned.
73da6c28aaSamw  *
747f667e74Sjose borrego  * ResumeKey must be null (length = 0) on the initial search request.
757f667e74Sjose borrego  * Subsequent search requests intended to continue a search must contain
767f667e74Sjose borrego  * the ResumeKey field extracted from the last directory entry of the
777f667e74Sjose borrego  * previous response.  ResumeKey is self-contained, for calls containing
787f667e74Sjose borrego  * a non-zero ResumeKey neither the SearchAttributes or FileName fields
797f667e74Sjose borrego  * will be valid in the request.  ResumeKey has the following format:
80da6c28aaSamw  *
817f667e74Sjose borrego  * Resume Key Field                   Description
827f667e74Sjose borrego  * ---------------------------------- ---------------------------------
837f667e74Sjose borrego  *
847f667e74Sjose borrego  * UCHAR Reserved;                    bit 7 - consumer use
857f667e74Sjose borrego  *                                    bits 5,6 - system use (must preserve)
867f667e74Sjose borrego  *                                    bits 0-4 - server use (must preserve)
877f667e74Sjose borrego  * UCHAR FileName[11];                Name of the returned file
887f667e74Sjose borrego  * UCHAR ReservedForServer[5];        Client must not modify
897f667e74Sjose borrego  *                                    byte 0 - uniquely identifies find
907f667e74Sjose borrego  *                                    through find_close
917f667e74Sjose borrego  *                                    bytes 1-4 - available for server use
92da6c28aaSamw  *                                    (must be non-zero)
937f667e74Sjose borrego  * UCHAR ReservedForConsumer[4];      Server must not modify
94da6c28aaSamw  *
957f667e74Sjose borrego  * FileName is 8.3 format, with the three character extension left
967f667e74Sjose borrego  * justified into FileName[9-11].
97da6c28aaSamw  *
987f667e74Sjose borrego  * There may be multiple matching entries in response to a single request
997f667e74Sjose borrego  * as wildcards are supported in the last component of FileName of the
1007f667e74Sjose borrego  * initial request.
101da6c28aaSamw  *
1027f667e74Sjose borrego  * Returned directory entries in the DirectoryInformationData field of the
1037f667e74Sjose borrego  * response each have the following format:
104da6c28aaSamw  *
1057f667e74Sjose borrego  * Directory Information Field        Description
1067f667e74Sjose borrego  * ---------------------------------- ---------------------------------
107da6c28aaSamw  *
1087f667e74Sjose borrego  * SMB_RESUME_KEY ResumeKey;          Described above
1097f667e74Sjose borrego  * UCHAR FileAttributes;              Attributes of the found file
1107f667e74Sjose borrego  * SMB_TIME LastWriteTime;            Time file was last written
1117f667e74Sjose borrego  * SMB_DATE LastWriteDate;            Date file was last written
1127f667e74Sjose borrego  * ULONG FileSize;                    Size of the file
1137f667e74Sjose borrego  * UCHAR FileName[13];                ASCII, space-filled null terminated
1147f667e74Sjose borrego  *
1157f667e74Sjose borrego  * FileName must conform to 8.3 rules, and is padded after the extension
1167f667e74Sjose borrego  * with 0x20 characters if necessary.
1177f667e74Sjose borrego  *
1187f667e74Sjose borrego  * As can be seen from the above structure, these commands cannot return
1197f667e74Sjose borrego  * long filenames, and cannot return UNICODE filenames.
1207f667e74Sjose borrego  *
1217f667e74Sjose borrego  * Files which have a size greater than 2^32 bytes should have the least
1227f667e74Sjose borrego  * significant 32 bits of their size returned in FileSize.
1237f667e74Sjose borrego  *
1247f667e74Sjose borrego  * smb_com_search
1257f667e74Sjose borrego  * --------------
1267f667e74Sjose borrego  *
1277f667e74Sjose borrego  * If the client is prior to the LANMAN1.0 dialect, the returned FileName
1287f667e74Sjose borrego  * should be uppercased.
1297f667e74Sjose borrego  * If the client has negotiated a dialect prior to the LANMAN1.0 dialect,
1307f667e74Sjose borrego  * or if bit0 of the Flags2 SMB header field of the request is clear,
1317f667e74Sjose borrego  * the returned FileName should be uppercased.
1327f667e74Sjose borrego  *
1337f667e74Sjose borrego  * SMB_COM_SEARCH terminates when either the requested maximum number of
1347f667e74Sjose borrego  * entries that match the named file are found, or the end of directory is
1357f667e74Sjose borrego  * reached without the maximum number of matches being found.  A response
1367f667e74Sjose borrego  * containing no entries indicates that no matching entries were found
1377f667e74Sjose borrego  * between the starting point of the search and the end of directory.
1387f667e74Sjose borrego  *
1397f667e74Sjose borrego  *
1407f667e74Sjose borrego  * The find, find_close and find_unique protocols may be used in place of
1417f667e74Sjose borrego  * the core "search" protocol when LANMAN 1.0 dialect has been negotiated.
1427f667e74Sjose borrego  *
1437f667e74Sjose borrego  * smb_com_find
1447f667e74Sjose borrego  * ------------
1457f667e74Sjose borrego  *
1467f667e74Sjose borrego  * The find protocol is used to match the find OS/2 system call.
1477f667e74Sjose borrego  *
1487f667e74Sjose borrego  * The format of the find protocol is the same as the core "search" protocol.
1497f667e74Sjose borrego  * The difference is that the directory is logically Opened with a find protocol
1507f667e74Sjose borrego  * and logically closed with the find close protocol.
1517f667e74Sjose borrego  * As is true of a failing open, if a find request (find "first" request where
152da6c28aaSamw  * resume_key is null) fails (no entries are found), no find close protocol is
153da6c28aaSamw  * expected.
154da6c28aaSamw  *
1557f667e74Sjose borrego  * If no global characters are present, a "find unique" protocol should be used
156da6c28aaSamw  * (only one entry is expected and find close need not be sent).
157da6c28aaSamw  *
1587f667e74Sjose borrego  * A find request will terminate when either the requested maximum number of
1597f667e74Sjose borrego  * entries that match the named file are found, or the end of directory is
1607f667e74Sjose borrego  * reached without the maximum number of matches being found. A response
1617f667e74Sjose borrego  * containing no entries indicates that no matching entries were found between
1627f667e74Sjose borrego  * the starting point of the search and the end of directory.
163da6c28aaSamw  *
1647f667e74Sjose borrego  * If a find requests more data than can be placed in a message of the
165da6c28aaSamw  * max-xmit-size for the TID specified, the server will return only the number
166da6c28aaSamw  * of entries which will fit.
167da6c28aaSamw  *
168da6c28aaSamw  *
1697f667e74Sjose borrego  * smb_com_find_close
1707f667e74Sjose borrego  * ------------------
171da6c28aaSamw  *
1727f667e74Sjose borrego  * The find close protocol is used to match the find close OS/2 system call.
173da6c28aaSamw  *
1747f667e74Sjose borrego  * Whereas the first find protocol logically opens the directory, subsequent
1757f667e74Sjose borrego  * find  protocols presenting a resume_key further "read" the directory, the
1767f667e74Sjose borrego  * find close  protocol "closes" the  directory allowing the server to free any
1777f667e74Sjose borrego  * resources held in support of the directory search.
178da6c28aaSamw  *
1797f667e74Sjose borrego  * In our implementation this translates to closing the odir.
180da6c28aaSamw  *
1817f667e74Sjose borrego  *
1827f667e74Sjose borrego  * smb_com_find_unique
1837f667e74Sjose borrego  * -------------------
1847f667e74Sjose borrego  *
1857f667e74Sjose borrego  * The format of the find unique protocol is the same as the core "search"
1867f667e74Sjose borrego  * protocol. The difference is that the directory is logically opened, any
1877f667e74Sjose borrego  * matching entries returned, and then the directory is logically closed.
1887f667e74Sjose borrego  *
1897f667e74Sjose borrego  * The resume search key key will be returned as in the find protocol and
1907f667e74Sjose borrego  * search protocol however it may NOT be returned to continue the search.
1917f667e74Sjose borrego  * Only one buffer of entries is expected and find close need not be sent.
1927f667e74Sjose borrego  *
1937f667e74Sjose borrego  * If a find unique requests more data than can be placed in a message of the
1947f667e74Sjose borrego  * max-xmit-size for the TID specified, the server will abort the virtual
1957f667e74Sjose borrego  * circuit to the consumer.
196da6c28aaSamw  */
1977f667e74Sjose borrego 
198148c5f43SAlan Wright #define	SMB_NAME83_BUFLEN	12
199148c5f43SAlan Wright static void smb_name83(const char *, char *, size_t);
200148c5f43SAlan Wright 
2017f667e74Sjose borrego /* *** smb_com_search *** */
2027f667e74Sjose borrego 
2037f667e74Sjose borrego smb_sdrc_t
2047f667e74Sjose borrego smb_pre_search(smb_request_t *sr)
2057f667e74Sjose borrego {
2067f667e74Sjose borrego 	DTRACE_SMB_1(op__Search__start, smb_request_t *, sr);
2077f667e74Sjose borrego 	return (SDRC_SUCCESS);
2087f667e74Sjose borrego }
2097f667e74Sjose borrego 
2107f667e74Sjose borrego void
2117f667e74Sjose borrego smb_post_search(smb_request_t *sr)
2127f667e74Sjose borrego {
2137f667e74Sjose borrego 	DTRACE_SMB_1(op__Search__done, smb_request_t *, sr);
2147f667e74Sjose borrego }
2157f667e74Sjose borrego 
2167f667e74Sjose borrego smb_sdrc_t
2177f667e74Sjose borrego smb_com_search(smb_request_t *sr)
2187f667e74Sjose borrego {
2197f667e74Sjose borrego 	int			rc;
2207f667e74Sjose borrego 	uint16_t		count, maxcount, index;
2217f667e74Sjose borrego 	uint16_t		sattr, odid;
2227f667e74Sjose borrego 	uint16_t		key_len;
2237f667e74Sjose borrego 	uint32_t		client_key;
2247f667e74Sjose borrego 	char			name[SMB_SHORTNAMELEN];
225148c5f43SAlan Wright 	char			name83[SMB_SHORTNAMELEN];
2269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_t		*pn;
2277f667e74Sjose borrego 	unsigned char		resume_char;
2287f667e74Sjose borrego 	unsigned char		type;
2297f667e74Sjose borrego 	boolean_t		find_first, to_upper;
2307f667e74Sjose borrego 	smb_tree_t		*tree;
2317f667e74Sjose borrego 	smb_odir_t		*od;
2327f667e74Sjose borrego 	smb_fileinfo_t		fileinfo;
2337f667e74Sjose borrego 	smb_odir_resume_t	odir_resume;
234*a90cf9f2SGordon Ross 	uint32_t		status;
235bfbce3c1SGordon Ross 	uint16_t		eos;
2367f667e74Sjose borrego 
2377f667e74Sjose borrego 	to_upper = B_FALSE;
2387f667e74Sjose borrego 	if ((sr->session->dialect <= LANMAN1_0) ||
2397f667e74Sjose borrego 	    ((sr->smb_flg2 & SMB_FLAGS2_KNOWS_LONG_NAMES) == 0)) {
2407f667e74Sjose borrego 		to_upper = B_TRUE;
2417f667e74Sjose borrego 	}
2427f667e74Sjose borrego 
2437f667e74Sjose borrego 	/* We only handle 8.3 name here */
2447f667e74Sjose borrego 	sr->smb_flg2 &= ~SMB_FLAGS2_KNOWS_LONG_NAMES;
2457f667e74Sjose borrego 	sr->smb_flg &= ~SMB_FLAGS_CASE_INSENSITIVE;
2467f667e74Sjose borrego 
2477f667e74Sjose borrego 	if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
2487f667e74Sjose borrego 		return (SDRC_ERROR);
2497f667e74Sjose borrego 
2509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pn = &sr->arg.dirop.fqi.fq_path;
2519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smbsr_decode_data(sr, "%Abw", sr, &pn->pn_path, &type, &key_len);
2527f667e74Sjose borrego 	if ((rc != 0) || (type != 0x05))
2537f667e74Sjose borrego 		return (SDRC_ERROR);
2547f667e74Sjose borrego 
2559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_init(sr, pn, pn->pn_path);
2569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_pathname_validate(sr, pn) ||
2579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    smb_is_stream_name(pn->pn_path)) {
2589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
2599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    ERRDOS, ERROR_NO_MORE_FILES);
2609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
2619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2637f667e74Sjose borrego 	tree = sr->tid_tree;
2647f667e74Sjose borrego 
2657f667e74Sjose borrego 	/* Volume information only */
2667f667e74Sjose borrego 	if ((sattr == FILE_ATTRIBUTE_VOLUME) && (key_len != 21)) {
2677f667e74Sjose borrego 		(void) memset(name, ' ', sizeof (name));
2687f667e74Sjose borrego 		(void) strncpy(name, tree->t_volume, sizeof (name));
2697f667e74Sjose borrego 
2707f667e74Sjose borrego 		if (key_len >= 21) {
2717f667e74Sjose borrego 			(void) smb_mbc_decodef(&sr->smb_data, "17.l",
2727f667e74Sjose borrego 			    &client_key);
2737f667e74Sjose borrego 		} else {
2747f667e74Sjose borrego 			client_key = 0;
2757f667e74Sjose borrego 		}
2767f667e74Sjose borrego 
2777f667e74Sjose borrego 		(void) smb_mbc_encodef(&sr->reply, "bwwbwb11c5.lb8.13c",
2789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    1, 0, VAR_BCC, 5, 0, 0, pn->pn_path+1,
2797f667e74Sjose borrego 		    client_key, sattr, name);
2807f667e74Sjose borrego 
2817f667e74Sjose borrego 		rc = (sr->reply.chain_offset - sr->cur_reply_offset) - 8;
2827f667e74Sjose borrego 		(void) smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
2837f667e74Sjose borrego 		    1, 1, rc+3, 5, rc);
2847f667e74Sjose borrego 
2857f667e74Sjose borrego 		return (SDRC_SUCCESS);
2867f667e74Sjose borrego 	}
2877f667e74Sjose borrego 
2887f667e74Sjose borrego 	if ((key_len != 0) && (key_len != 21))
2897f667e74Sjose borrego 		return (SDRC_ERROR);
2907f667e74Sjose borrego 
2917f667e74Sjose borrego 	find_first = (key_len == 0);
2927f667e74Sjose borrego 	resume_char = 0;
2937f667e74Sjose borrego 	client_key = 0;
2947f667e74Sjose borrego 
2957f667e74Sjose borrego 	if (find_first) {
296*a90cf9f2SGordon Ross 		status = smb_odir_openpath(sr, pn->pn_path, sattr, 0, &od);
297*a90cf9f2SGordon Ross 		if (status != 0) {
298*a90cf9f2SGordon Ross 			if (status == NT_STATUS_ACCESS_DENIED)
2997f667e74Sjose borrego 				smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
3007f667e74Sjose borrego 				    ERRDOS, ERROR_NO_MORE_FILES);
3017f667e74Sjose borrego 			return (SDRC_ERROR);
3027f667e74Sjose borrego 		}
3037f667e74Sjose borrego 	} else {
3047f667e74Sjose borrego 		if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
3057f667e74Sjose borrego 		    &resume_char, &index, &odid, &client_key) != 0) {
3067f667e74Sjose borrego 			return (SDRC_ERROR);
3077f667e74Sjose borrego 		}
308*a90cf9f2SGordon Ross 		od = smb_tree_lookup_odir(sr, odid);
3097f667e74Sjose borrego 	}
3107f667e74Sjose borrego 
3117f667e74Sjose borrego 	if (od == NULL) {
3127f667e74Sjose borrego 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
3137f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_HANDLE);
3147f667e74Sjose borrego 		return (SDRC_ERROR);
3157f667e74Sjose borrego 	}
3167f667e74Sjose borrego 
3177f667e74Sjose borrego 	if (!find_first) {
318*a90cf9f2SGordon Ross 		if ((od->d_flags & SMB_ODIR_FLAG_WILDCARDS) == 0) {
319*a90cf9f2SGordon Ross 			od->d_eof = B_TRUE;
320*a90cf9f2SGordon Ross 		} else {
3217f667e74Sjose borrego 			odir_resume.or_type = SMB_ODIR_RESUME_IDX;
3227f667e74Sjose borrego 			odir_resume.or_idx = index;
3237f667e74Sjose borrego 			smb_odir_resume_at(od, &odir_resume);
3247f667e74Sjose borrego 		}
325*a90cf9f2SGordon Ross 	}
3267f667e74Sjose borrego 
3277f667e74Sjose borrego 	(void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
3287f667e74Sjose borrego 
3297f667e74Sjose borrego 	rc = 0;
3307f667e74Sjose borrego 	index = 0;
3317f667e74Sjose borrego 	count = 0;
3327f667e74Sjose borrego 	if (maxcount > SMB_MAX_SEARCH)
3337f667e74Sjose borrego 		maxcount = SMB_MAX_SEARCH;
3347f667e74Sjose borrego 
3357f667e74Sjose borrego 	while (count < maxcount) {
3367f667e74Sjose borrego 		rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
337bfbce3c1SGordon Ross 		if (rc != 0 || eos != 0)
3387f667e74Sjose borrego 			break;
3397f667e74Sjose borrego 
340743a77edSAlan Wright 		if (*fileinfo.fi_shortname == '\0') {
341cb174861Sjoyce mcintosh 			if (smb_needs_mangled(fileinfo.fi_name))
342cb174861Sjoyce mcintosh 				continue;
343148c5f43SAlan Wright 			(void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
344743a77edSAlan Wright 			    SMB_SHORTNAMELEN - 1);
3457f667e74Sjose borrego 			if (to_upper)
346148c5f43SAlan Wright 				(void) smb_strupr(fileinfo.fi_shortname);
3477f667e74Sjose borrego 		}
348148c5f43SAlan Wright 		smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
3497f667e74Sjose borrego 
350148c5f43SAlan Wright 		(void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
351148c5f43SAlan Wright 		    resume_char, name83, index, odid, client_key,
3527f667e74Sjose borrego 		    fileinfo.fi_dosattr & 0xff,
353e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
3547f667e74Sjose borrego 		    (int32_t)fileinfo.fi_size,
355148c5f43SAlan Wright 		    fileinfo.fi_shortname);
3567f667e74Sjose borrego 
3577f667e74Sjose borrego 		smb_odir_save_cookie(od, index, fileinfo.fi_cookie);
3587f667e74Sjose borrego 
3597f667e74Sjose borrego 		count++;
3607f667e74Sjose borrego 		index++;
3617f667e74Sjose borrego 	}
362*a90cf9f2SGordon Ross 	if (eos && rc == ENOENT)
363*a90cf9f2SGordon Ross 		rc = 0;
3647f667e74Sjose borrego 
3657f667e74Sjose borrego 	if (rc != 0) {
3667f667e74Sjose borrego 		smb_odir_close(od);
367a1511e6bSjoyce mcintosh 		smb_odir_release(od);
3687f667e74Sjose borrego 		return (SDRC_ERROR);
3697f667e74Sjose borrego 	}
3707f667e74Sjose borrego 
3717f667e74Sjose borrego 	if (count == 0 && find_first) {
3727f667e74Sjose borrego 		smb_odir_close(od);
373a1511e6bSjoyce mcintosh 		smb_odir_release(od);
3747f667e74Sjose borrego 		smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
3757f667e74Sjose borrego 		    ERRDOS, ERROR_NO_MORE_FILES);
3767f667e74Sjose borrego 		return (SDRC_ERROR);
3777f667e74Sjose borrego 	}
3787f667e74Sjose borrego 
3797f667e74Sjose borrego 	rc = (sr->reply.chain_offset - sr->cur_reply_offset) - 8;
3807f667e74Sjose borrego 	if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
3817f667e74Sjose borrego 	    1, count, rc+3, 5, rc) < 0) {
3827f667e74Sjose borrego 		smb_odir_close(od);
383a1511e6bSjoyce mcintosh 		smb_odir_release(od);
3847f667e74Sjose borrego 		return (SDRC_ERROR);
3857f667e74Sjose borrego 	}
3867f667e74Sjose borrego 
387a1511e6bSjoyce mcintosh 	smb_odir_release(od);
3887f667e74Sjose borrego 	return (SDRC_SUCCESS);
3897f667e74Sjose borrego }
3907f667e74Sjose borrego 
3917f667e74Sjose borrego 
3927f667e74Sjose borrego /* *** smb_com_find *** */
3937f667e74Sjose borrego 
3947b59d02dSjb150015 smb_sdrc_t
395faa1795aSjb150015 smb_pre_find(smb_request_t *sr)
396faa1795aSjb150015 {
397faa1795aSjb150015 	DTRACE_SMB_1(op__Find__start, smb_request_t *, sr);
398faa1795aSjb150015 	return (SDRC_SUCCESS);
399faa1795aSjb150015 }
400faa1795aSjb150015 
401faa1795aSjb150015 void
402faa1795aSjb150015 smb_post_find(smb_request_t *sr)
403faa1795aSjb150015 {
404faa1795aSjb150015 	DTRACE_SMB_1(op__Find__done, smb_request_t *, sr);
405faa1795aSjb150015 }
406faa1795aSjb150015 
407faa1795aSjb150015 smb_sdrc_t
408faa1795aSjb150015 smb_com_find(smb_request_t *sr)
409da6c28aaSamw {
410da6c28aaSamw 	int			rc;
4117f667e74Sjose borrego 	uint16_t		count, maxcount, index;
4127f667e74Sjose borrego 	uint16_t		sattr, odid;
4137f667e74Sjose borrego 	uint16_t		key_len;
4147f667e74Sjose borrego 	uint32_t		client_key;
415148c5f43SAlan Wright 	char			name83[SMB_SHORTNAMELEN];
4167f667e74Sjose borrego 	smb_odir_t		*od;
4177f667e74Sjose borrego 	smb_fileinfo_t		fileinfo;
418*a90cf9f2SGordon Ross 	uint32_t		status;
419bfbce3c1SGordon Ross 	uint16_t		eos;
4207f667e74Sjose borrego 
4219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_t		*pn;
422c8ec8eeaSjose borrego 	unsigned char		resume_char;
423da6c28aaSamw 	unsigned char		type;
424c8ec8eeaSjose borrego 	boolean_t		find_first = B_TRUE;
4257f667e74Sjose borrego 	smb_odir_resume_t	odir_resume;
426da6c28aaSamw 
4277b59d02dSjb150015 	if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
428faa1795aSjb150015 		return (SDRC_ERROR);
429da6c28aaSamw 
4309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pn = &sr->arg.dirop.fqi.fq_path;
4319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smbsr_decode_data(sr, "%Abw", sr, &pn->pn_path, &type, &key_len);
4327b59d02dSjb150015 	if ((rc != 0) || (type != 0x05))
433faa1795aSjb150015 		return (SDRC_ERROR);
434da6c28aaSamw 
4357f667e74Sjose borrego 	if ((key_len != 0) && (key_len != 21))
436faa1795aSjb150015 		return (SDRC_ERROR);
437da6c28aaSamw 
4389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_init(sr, pn, pn->pn_path);
4399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_pathname_validate(sr, pn))
4409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
4419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_is_stream_name(pn->pn_path)) {
4439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
4449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    ERRDOS, ERROR_INVALID_NAME);
4459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
4469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
4479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4487f667e74Sjose borrego 	find_first = (key_len == 0);
4497f667e74Sjose borrego 	resume_char = 0;
4507f667e74Sjose borrego 	client_key = 0;
451da6c28aaSamw 
4527f667e74Sjose borrego 	if (find_first) {
453*a90cf9f2SGordon Ross 		status = smb_odir_openpath(sr, pn->pn_path, sattr, 0, &od);
454*a90cf9f2SGordon Ross 		if (status != 0) {
455*a90cf9f2SGordon Ross 			smbsr_error(sr, status, 0, 0);
4567f667e74Sjose borrego 			return (SDRC_ERROR);
457*a90cf9f2SGordon Ross 		}
458da6c28aaSamw 	} else {
4597f667e74Sjose borrego 		if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
4607f667e74Sjose borrego 		    &resume_char, &index, &odid, &client_key) != 0) {
461faa1795aSjb150015 			return (SDRC_ERROR);
462da6c28aaSamw 		}
463*a90cf9f2SGordon Ross 		od = smb_tree_lookup_odir(sr, odid);
4647f667e74Sjose borrego 	}
4657f667e74Sjose borrego 
4667f667e74Sjose borrego 	if (od == NULL) {
4677f667e74Sjose borrego 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
4687f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_HANDLE);
4697f667e74Sjose borrego 		return (SDRC_ERROR);
4707f667e74Sjose borrego 	}
4717f667e74Sjose borrego 
4727f667e74Sjose borrego 	if (!find_first) {
473*a90cf9f2SGordon Ross 		if ((od->d_flags & SMB_ODIR_FLAG_WILDCARDS) == 0) {
474*a90cf9f2SGordon Ross 			od->d_eof = B_TRUE;
475*a90cf9f2SGordon Ross 		} else {
4767f667e74Sjose borrego 			odir_resume.or_type = SMB_ODIR_RESUME_IDX;
4777f667e74Sjose borrego 			odir_resume.or_idx = index;
4787f667e74Sjose borrego 			smb_odir_resume_at(od, &odir_resume);
4797f667e74Sjose borrego 		}
480*a90cf9f2SGordon Ross 	}
481da6c28aaSamw 
4823db3f65cSamw 	(void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
483da6c28aaSamw 
4847f667e74Sjose borrego 	rc = 0;
485c8ec8eeaSjose borrego 	index = 0;
486da6c28aaSamw 	count = 0;
487c8ec8eeaSjose borrego 	if (maxcount > SMB_MAX_SEARCH)
488c8ec8eeaSjose borrego 		maxcount = SMB_MAX_SEARCH;
489c8ec8eeaSjose borrego 
490da6c28aaSamw 	while (count < maxcount) {
4917f667e74Sjose borrego 		rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
492bfbce3c1SGordon Ross 		if (rc != 0 || eos != 0)
493da6c28aaSamw 			break;
494da6c28aaSamw 
495743a77edSAlan Wright 		if (*fileinfo.fi_shortname == '\0') {
496cb174861Sjoyce mcintosh 			if (smb_needs_mangled(fileinfo.fi_name))
497cb174861Sjoyce mcintosh 				continue;
498148c5f43SAlan Wright 			(void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
499743a77edSAlan Wright 			    SMB_SHORTNAMELEN - 1);
5007f667e74Sjose borrego 		}
501148c5f43SAlan Wright 		smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
5027f667e74Sjose borrego 
503148c5f43SAlan Wright 		(void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
504148c5f43SAlan Wright 		    resume_char, name83, index, odid, client_key,
5057f667e74Sjose borrego 		    fileinfo.fi_dosattr & 0xff,
506e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
5077f667e74Sjose borrego 		    (int32_t)fileinfo.fi_size,
508148c5f43SAlan Wright 		    fileinfo.fi_shortname);
509c8ec8eeaSjose borrego 
5107f667e74Sjose borrego 		smb_odir_save_cookie(od, index, fileinfo.fi_cookie);
5117f667e74Sjose borrego 
512da6c28aaSamw 		count++;
513c8ec8eeaSjose borrego 		index++;
514da6c28aaSamw 	}
515*a90cf9f2SGordon Ross 	if (eos && rc == ENOENT)
516*a90cf9f2SGordon Ross 		rc = 0;
5176537f381Sas200622 
5187f667e74Sjose borrego 	if (rc != 0) {
5197f667e74Sjose borrego 		smb_odir_close(od);
520a1511e6bSjoyce mcintosh 		smb_odir_release(od);
521faa1795aSjb150015 		return (SDRC_ERROR);
522da6c28aaSamw 	}
523da6c28aaSamw 
524c8ec8eeaSjose borrego 	if (count == 0 && find_first) {
5257f667e74Sjose borrego 		smb_odir_close(od);
526a1511e6bSjoyce mcintosh 		smb_odir_release(od);
527c8ec8eeaSjose borrego 		smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
528c8ec8eeaSjose borrego 		    ERRDOS, ERROR_NO_MORE_FILES);
529faa1795aSjb150015 		return (SDRC_ERROR);
530da6c28aaSamw 	}
531da6c28aaSamw 
532da6c28aaSamw 	rc = (MBC_LENGTH(&sr->reply) - sr->cur_reply_offset) - 8;
5333db3f65cSamw 	if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
5347b59d02dSjb150015 	    1, count, rc+3, 5, rc) < 0) {
5357f667e74Sjose borrego 		smb_odir_close(od);
536a1511e6bSjoyce mcintosh 		smb_odir_release(od);
537faa1795aSjb150015 		return (SDRC_ERROR);
538da6c28aaSamw 	}
539da6c28aaSamw 
540a1511e6bSjoyce mcintosh 	smb_odir_release(od);
541faa1795aSjb150015 	return (SDRC_SUCCESS);
542da6c28aaSamw }
543da6c28aaSamw 
5447f667e74Sjose borrego 
5457f667e74Sjose borrego /* *** smb_com_find_close *** */
5467f667e74Sjose borrego 
5477b59d02dSjb150015 smb_sdrc_t
548faa1795aSjb150015 smb_pre_find_close(smb_request_t *sr)
549faa1795aSjb150015 {
550faa1795aSjb150015 	DTRACE_SMB_1(op__FindClose__start, smb_request_t *, sr);
551faa1795aSjb150015 	return (SDRC_SUCCESS);
552faa1795aSjb150015 }
553faa1795aSjb150015 
554faa1795aSjb150015 void
555faa1795aSjb150015 smb_post_find_close(smb_request_t *sr)
556faa1795aSjb150015 {
557faa1795aSjb150015 	DTRACE_SMB_1(op__FindClose__done, smb_request_t *, sr);
558faa1795aSjb150015 }
559faa1795aSjb150015 
560faa1795aSjb150015 smb_sdrc_t
561faa1795aSjb150015 smb_com_find_close(smb_request_t *sr)
562da6c28aaSamw {
5637f667e74Sjose borrego 	int		rc;
5647f667e74Sjose borrego 	uint16_t	maxcount, index;
5657f667e74Sjose borrego 	uint16_t	sattr, odid;
5667f667e74Sjose borrego 	uint16_t	key_len;
5677f667e74Sjose borrego 	uint32_t	client_key;
568da6c28aaSamw 	char		*path;
569c8ec8eeaSjose borrego 	unsigned char	resume_char;
570da6c28aaSamw 	unsigned char	type;
5717f667e74Sjose borrego 	smb_odir_t	*od;
572da6c28aaSamw 
5737b59d02dSjb150015 	if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
574faa1795aSjb150015 		return (SDRC_ERROR);
575da6c28aaSamw 
576da6c28aaSamw 	rc = smbsr_decode_data(sr, "%Abw", sr, &path, &type, &key_len);
5777b59d02dSjb150015 	if ((rc != 0) || (type != 0x05))
578faa1795aSjb150015 		return (SDRC_ERROR);
579da6c28aaSamw 
5807f667e74Sjose borrego 	if (key_len == 0) {
581dc20a302Sas200622 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
5827f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_HANDLE);
583faa1795aSjb150015 		return (SDRC_ERROR);
5847f667e74Sjose borrego 	} else if (key_len != 21) {
585faa1795aSjb150015 		return (SDRC_ERROR);
586da6c28aaSamw 	}
587da6c28aaSamw 
5887f667e74Sjose borrego 	odid = 0;
5897f667e74Sjose borrego 	if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
5907f667e74Sjose borrego 	    &resume_char, &index, &odid, &client_key) != 0) {
5917f667e74Sjose borrego 		return (SDRC_ERROR);
5927f667e74Sjose borrego 	}
5937f667e74Sjose borrego 
5943b13a1efSThomas Keiser 	od = smb_tree_lookup_odir(sr, odid);
5957f667e74Sjose borrego 	if (od == NULL) {
5967f667e74Sjose borrego 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
5977f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_HANDLE);
5987f667e74Sjose borrego 		return (SDRC_ERROR);
5997f667e74Sjose borrego 	}
6007f667e74Sjose borrego 
6017f667e74Sjose borrego 	smb_odir_close(od);
602a1511e6bSjoyce mcintosh 	smb_odir_release(od);
6037f667e74Sjose borrego 
6047b59d02dSjb150015 	if (smbsr_encode_result(sr, 1, 3, "bwwbw", 1, 0, 3, 5, 0))
605faa1795aSjb150015 		return (SDRC_ERROR);
6067f667e74Sjose borrego 
6077f667e74Sjose borrego 	return (SDRC_SUCCESS);
6087f667e74Sjose borrego }
6097f667e74Sjose borrego 
6107f667e74Sjose borrego 
6117f667e74Sjose borrego /* *** smb_com_find_unique *** */
6127f667e74Sjose borrego 
6137f667e74Sjose borrego smb_sdrc_t
6147f667e74Sjose borrego smb_pre_find_unique(smb_request_t *sr)
6157f667e74Sjose borrego {
6167f667e74Sjose borrego 	DTRACE_SMB_1(op__FindUnique__start, smb_request_t *, sr);
6177f667e74Sjose borrego 	return (SDRC_SUCCESS);
6187f667e74Sjose borrego }
6197f667e74Sjose borrego 
6207f667e74Sjose borrego void
6217f667e74Sjose borrego smb_post_find_unique(smb_request_t *sr)
6227f667e74Sjose borrego {
6237f667e74Sjose borrego 	DTRACE_SMB_1(op__FindUnique__done, smb_request_t *, sr);
6247f667e74Sjose borrego }
6257f667e74Sjose borrego 
6267f667e74Sjose borrego smb_sdrc_t
6277f667e74Sjose borrego smb_com_find_unique(struct smb_request *sr)
6287f667e74Sjose borrego {
6297f667e74Sjose borrego 	int			rc;
6307f667e74Sjose borrego 	uint16_t		count, maxcount, index;
631*a90cf9f2SGordon Ross 	uint16_t		sattr;
6329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_t		*pn;
6337f667e74Sjose borrego 	unsigned char		resume_char = '\0';
6347f667e74Sjose borrego 	uint32_t		client_key = 0;
635148c5f43SAlan Wright 	char			name83[SMB_SHORTNAMELEN];
6367f667e74Sjose borrego 	smb_odir_t		*od;
6377f667e74Sjose borrego 	smb_fileinfo_t		fileinfo;
638*a90cf9f2SGordon Ross 	uint32_t		status;
639bfbce3c1SGordon Ross 	uint16_t		eos;
6402c2961f8Sjose borrego 	smb_vdb_t		*vdb;
6417f667e74Sjose borrego 
6427f667e74Sjose borrego 	if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
6437f667e74Sjose borrego 		return (SDRC_ERROR);
6447f667e74Sjose borrego 
6459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pn = &sr->arg.dirop.fqi.fq_path;
6462c2961f8Sjose borrego 	vdb = kmem_alloc(sizeof (smb_vdb_t), KM_SLEEP);
6479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((smbsr_decode_data(sr, "%AV", sr, &pn->pn_path, vdb) != 0) ||
6482c2961f8Sjose borrego 	    (vdb->vdb_len != 0)) {
6492c2961f8Sjose borrego 		kmem_free(vdb, sizeof (smb_vdb_t));
6507f667e74Sjose borrego 		return (SDRC_ERROR);
6517f667e74Sjose borrego 	}
6522c2961f8Sjose borrego 	kmem_free(vdb, sizeof (smb_vdb_t));
6537f667e74Sjose borrego 
6549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_init(sr, pn, pn->pn_path);
6559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_pathname_validate(sr, pn))
6569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
6579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_is_stream_name(pn->pn_path)) {
6599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
6609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    ERRDOS, ERROR_INVALID_NAME);
6619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
6629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
6639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6647f667e74Sjose borrego 	(void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
6657f667e74Sjose borrego 
666*a90cf9f2SGordon Ross 	status = smb_odir_openpath(sr, pn->pn_path, sattr, 0, &od);
667*a90cf9f2SGordon Ross 	if (status != 0) {
668*a90cf9f2SGordon Ross 		smbsr_error(sr, status, 0, 0);
6697f667e74Sjose borrego 		return (SDRC_ERROR);
670*a90cf9f2SGordon Ross 	}
6717f667e74Sjose borrego 	if (od == NULL)
6727f667e74Sjose borrego 		return (SDRC_ERROR);
6737f667e74Sjose borrego 
6747f667e74Sjose borrego 	rc = 0;
6757f667e74Sjose borrego 	count = 0;
6767f667e74Sjose borrego 	index = 0;
6777f667e74Sjose borrego 	if (maxcount > SMB_MAX_SEARCH)
6787f667e74Sjose borrego 		maxcount = SMB_MAX_SEARCH;
6797f667e74Sjose borrego 
6807f667e74Sjose borrego 	while (count < maxcount) {
6817f667e74Sjose borrego 		rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
682bfbce3c1SGordon Ross 		if (rc != 0 || eos != 0)
6837f667e74Sjose borrego 			break;
6847f667e74Sjose borrego 
685743a77edSAlan Wright 		if (*fileinfo.fi_shortname == '\0') {
686cb174861Sjoyce mcintosh 			if (smb_needs_mangled(fileinfo.fi_name))
687cb174861Sjoyce mcintosh 				continue;
688148c5f43SAlan Wright 			(void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
689743a77edSAlan Wright 			    SMB_SHORTNAMELEN - 1);
6907f667e74Sjose borrego 		}
691148c5f43SAlan Wright 		smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
6927f667e74Sjose borrego 
693148c5f43SAlan Wright 		(void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
694*a90cf9f2SGordon Ross 		    resume_char, name83, index, od->d_odid,
695*a90cf9f2SGordon Ross 		    client_key, fileinfo.fi_dosattr & 0xff,
696e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
6977f667e74Sjose borrego 		    (int32_t)fileinfo.fi_size,
698148c5f43SAlan Wright 		    fileinfo.fi_shortname);
6997f667e74Sjose borrego 
7007f667e74Sjose borrego 		count++;
7017f667e74Sjose borrego 		index++;
7027f667e74Sjose borrego 	}
703*a90cf9f2SGordon Ross 	if (eos && rc == ENOENT)
704*a90cf9f2SGordon Ross 		rc = 0;
7057f667e74Sjose borrego 
7067f667e74Sjose borrego 	smb_odir_close(od);
707a1511e6bSjoyce mcintosh 	smb_odir_release(od);
7087f667e74Sjose borrego 
7097f667e74Sjose borrego 	if (rc != 0)
7107f667e74Sjose borrego 		return (SDRC_ERROR);
7117f667e74Sjose borrego 
7127f667e74Sjose borrego 	if (count == 0) {
7137f667e74Sjose borrego 		smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
7147f667e74Sjose borrego 		    ERRDOS, ERROR_NO_MORE_FILES);
7157f667e74Sjose borrego 		return (SDRC_ERROR);
7167f667e74Sjose borrego 	}
7177f667e74Sjose borrego 
7187f667e74Sjose borrego 	rc = (MBC_LENGTH(&sr->reply) - sr->cur_reply_offset) - 8;
7197f667e74Sjose borrego 	if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset,
7207f667e74Sjose borrego 	    "bwwbw", 1, count, rc+3, 5, rc) < 0) {
7217f667e74Sjose borrego 		return (SDRC_ERROR);
7227f667e74Sjose borrego 	}
7237f667e74Sjose borrego 
724faa1795aSjb150015 	return (SDRC_SUCCESS);
725da6c28aaSamw }
726148c5f43SAlan Wright 
727148c5f43SAlan Wright /*
728148c5f43SAlan Wright  * smb_name83
729148c5f43SAlan Wright  *
730148c5f43SAlan Wright  * Format the filename for inclusion in the resume key. The filename
731148c5f43SAlan Wright  * returned in the resume key is 11 bytes:
732148c5f43SAlan Wright  * - up to 8 bytes of filename, space padded to 8 bytes
733148c5f43SAlan Wright  * - up to 3 bytes of ext, space padded to 3 bytes
734148c5f43SAlan Wright  *
735148c5f43SAlan Wright  * The name passed to smb_name83 should be a shortname or a name that
736148c5f43SAlan Wright  * doesn't require mangling.
737148c5f43SAlan Wright  *
738148c5f43SAlan Wright  * Examples:
739148c5f43SAlan Wright  *	"fname.txt"    -> "FNAME   TXT"
740148c5f43SAlan Wright  *	"fname.tx"     -> "FNAME   TX "
741148c5f43SAlan Wright  *	"filename"     -> "FILENAME   "
742148c5f43SAlan Wright  *	"filename.txt" -> "FILENAMETXT"
743148c5f43SAlan Wright  *	"FILE~1.TXT"   -> "FILE~1  TXT"
744148c5f43SAlan Wright  */
745148c5f43SAlan Wright static void
746148c5f43SAlan Wright smb_name83(const char *name, char *buf, size_t buflen)
747148c5f43SAlan Wright {
748148c5f43SAlan Wright 	const char *p;
749148c5f43SAlan Wright 	char *pbuf;
750148c5f43SAlan Wright 	int i;
751148c5f43SAlan Wright 
752148c5f43SAlan Wright 	ASSERT(name && buf && (buflen >= SMB_NAME83_BUFLEN));
753148c5f43SAlan Wright 
754148c5f43SAlan Wright 	(void) strlcpy(buf, "           ", SMB_NAME83_BUFLEN);
755148c5f43SAlan Wright 
756148c5f43SAlan Wright 	/* Process "." and ".." up front */
757148c5f43SAlan Wright 	if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) {
758148c5f43SAlan Wright 		(void) strncpy(buf, name, strlen(name));
759148c5f43SAlan Wright 		return;
760148c5f43SAlan Wright 	}
761148c5f43SAlan Wright 
762148c5f43SAlan Wright 	ASSERT(smb_needs_mangled(name) == B_FALSE);
763148c5f43SAlan Wright 
764148c5f43SAlan Wright 	/* Process basename */
765148c5f43SAlan Wright 	for (i = 0, p = name, pbuf = buf;
766148c5f43SAlan Wright 	    (i < SMB_NAME83_BASELEN) && (*p != '\0') && (*p != '.'); ++i)
767148c5f43SAlan Wright 		*pbuf++ = *p++;
768148c5f43SAlan Wright 
769148c5f43SAlan Wright 	/* Process the extension from the last dot in name */
770148c5f43SAlan Wright 	if ((p = strchr(name, '.')) != NULL) {
771148c5f43SAlan Wright 		++p;
772148c5f43SAlan Wright 		pbuf = &buf[SMB_NAME83_BASELEN];
773148c5f43SAlan Wright 		for (i = 0; (i < SMB_NAME83_EXTLEN) && (*p != '\0'); ++i)
774148c5f43SAlan Wright 			*pbuf++ = *p++;
775148c5f43SAlan Wright 	}
776148c5f43SAlan Wright 
777148c5f43SAlan Wright 	(void) smb_strupr(buf);
778148c5f43SAlan Wright }
779