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 /*
2212508Samw@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
235331Samw */
245331Samw
2510966SJordan.Brown@Sun.COM #include <smbsrv/smb_kproto.h>
265331Samw
275331Samw /*
288670SJose.Borrego@Sun.COM * smb_com_search
298670SJose.Borrego@Sun.COM * smb_com_find, smb_com_find_close
308670SJose.Borrego@Sun.COM * smb_find_unique
315331Samw *
328670SJose.Borrego@Sun.COM * These commands are used for directory searching. They share the same
338670SJose.Borrego@Sun.COM * message formats, defined below:
345331Samw *
358670SJose.Borrego@Sun.COM * Client Request Description
368670SJose.Borrego@Sun.COM * ---------------------------------- ---------------------------------
375331Samw *
388670SJose.Borrego@Sun.COM * UCHAR WordCount; Count of parameter words = 2
398670SJose.Borrego@Sun.COM * USHORT MaxCount; Number of dir. entries to return
408670SJose.Borrego@Sun.COM * USHORT SearchAttributes;
418670SJose.Borrego@Sun.COM * USHORT ByteCount; Count of data bytes; min = 5
428670SJose.Borrego@Sun.COM * UCHAR BufferFormat1; 0x04 -- ASCII
438670SJose.Borrego@Sun.COM * UCHAR FileName[]; File name, may be null
448670SJose.Borrego@Sun.COM * UCHAR BufferFormat2; 0x05 -- Variable block
458670SJose.Borrego@Sun.COM * USHORT ResumeKeyLength; Length of resume key, may be 0
468670SJose.Borrego@Sun.COM * UCHAR ResumeKey[]; Resume key
475331Samw *
488670SJose.Borrego@Sun.COM * FileName specifies the file to be sought. SearchAttributes indicates
498670SJose.Borrego@Sun.COM * the attributes that the file must have. If SearchAttributes is
508670SJose.Borrego@Sun.COM * zero then only normal files are returned. If the system file, hidden or
518670SJose.Borrego@Sun.COM * directory attributes are specified then the search is inclusive - both the
528670SJose.Borrego@Sun.COM * specified type(s) of files and normal files are returned. If the volume
538670SJose.Borrego@Sun.COM * label attribute is specified then the search is exclusive, and only the
548670SJose.Borrego@Sun.COM * volume label entry is returned.
558670SJose.Borrego@Sun.COM *
568670SJose.Borrego@Sun.COM * MaxCount specifies the number of directory entries to be returned.
578670SJose.Borrego@Sun.COM *
588670SJose.Borrego@Sun.COM * Server Response Description
598670SJose.Borrego@Sun.COM * ---------------------------------- ---------------------------------
605331Samw *
618670SJose.Borrego@Sun.COM * UCHAR WordCount; Count of parameter words = 1
628670SJose.Borrego@Sun.COM * USHORT Count; Number of entries returned
638670SJose.Borrego@Sun.COM * USHORT ByteCount; Count of data bytes; min = 3
648670SJose.Borrego@Sun.COM * UCHAR BufferFormat; 0x05 -- Variable block
658670SJose.Borrego@Sun.COM * USHORT DataLength; Length of data
668670SJose.Borrego@Sun.COM * UCHAR DirectoryInformationData[]; Data
675331Samw *
688670SJose.Borrego@Sun.COM * The response will contain one or more directory entries as determined by
698670SJose.Borrego@Sun.COM * the Count field. No more than MaxCount entries will be returned. Only
708670SJose.Borrego@Sun.COM * entries that match the sought FileName and SearchAttributes combination
718670SJose.Borrego@Sun.COM * will be returned.
728670SJose.Borrego@Sun.COM *
738670SJose.Borrego@Sun.COM * ResumeKey must be null (length = 0) on the initial search request.
748670SJose.Borrego@Sun.COM * Subsequent search requests intended to continue a search must contain
758670SJose.Borrego@Sun.COM * the ResumeKey field extracted from the last directory entry of the
768670SJose.Borrego@Sun.COM * previous response. ResumeKey is self-contained, for calls containing
778670SJose.Borrego@Sun.COM * a non-zero ResumeKey neither the SearchAttributes or FileName fields
788670SJose.Borrego@Sun.COM * will be valid in the request. ResumeKey has the following format:
798670SJose.Borrego@Sun.COM *
808670SJose.Borrego@Sun.COM * Resume Key Field Description
818670SJose.Borrego@Sun.COM * ---------------------------------- ---------------------------------
825331Samw *
838670SJose.Borrego@Sun.COM * UCHAR Reserved; bit 7 - consumer use
848670SJose.Borrego@Sun.COM * bits 5,6 - system use (must preserve)
858670SJose.Borrego@Sun.COM * bits 0-4 - server use (must preserve)
868670SJose.Borrego@Sun.COM * UCHAR FileName[11]; Name of the returned file
878670SJose.Borrego@Sun.COM * UCHAR ReservedForServer[5]; Client must not modify
888670SJose.Borrego@Sun.COM * byte 0 - uniquely identifies find
898670SJose.Borrego@Sun.COM * through find_close
908670SJose.Borrego@Sun.COM * bytes 1-4 - available for server use
918670SJose.Borrego@Sun.COM * (must be non-zero)
928670SJose.Borrego@Sun.COM * UCHAR ReservedForConsumer[4]; Server must not modify
938670SJose.Borrego@Sun.COM *
948670SJose.Borrego@Sun.COM * FileName is 8.3 format, with the three character extension left
958670SJose.Borrego@Sun.COM * justified into FileName[9-11].
965331Samw *
978670SJose.Borrego@Sun.COM * There may be multiple matching entries in response to a single request
988670SJose.Borrego@Sun.COM * as wildcards are supported in the last component of FileName of the
998670SJose.Borrego@Sun.COM * initial request.
1008670SJose.Borrego@Sun.COM *
1018670SJose.Borrego@Sun.COM * Returned directory entries in the DirectoryInformationData field of the
1028670SJose.Borrego@Sun.COM * response each have the following format:
1038670SJose.Borrego@Sun.COM *
1048670SJose.Borrego@Sun.COM * Directory Information Field Description
1058670SJose.Borrego@Sun.COM * ---------------------------------- ---------------------------------
1065331Samw *
1078670SJose.Borrego@Sun.COM * SMB_RESUME_KEY ResumeKey; Described above
1088670SJose.Borrego@Sun.COM * UCHAR FileAttributes; Attributes of the found file
1098670SJose.Borrego@Sun.COM * SMB_TIME LastWriteTime; Time file was last written
1108670SJose.Borrego@Sun.COM * SMB_DATE LastWriteDate; Date file was last written
1118670SJose.Borrego@Sun.COM * ULONG FileSize; Size of the file
1128670SJose.Borrego@Sun.COM * UCHAR FileName[13]; ASCII, space-filled null terminated
1138670SJose.Borrego@Sun.COM *
1148670SJose.Borrego@Sun.COM * FileName must conform to 8.3 rules, and is padded after the extension
1158670SJose.Borrego@Sun.COM * with 0x20 characters if necessary.
1165331Samw *
1178670SJose.Borrego@Sun.COM * As can be seen from the above structure, these commands cannot return
1188670SJose.Borrego@Sun.COM * long filenames, and cannot return UNICODE filenames.
1198670SJose.Borrego@Sun.COM *
1208670SJose.Borrego@Sun.COM * Files which have a size greater than 2^32 bytes should have the least
1218670SJose.Borrego@Sun.COM * significant 32 bits of their size returned in FileSize.
1225331Samw *
1238670SJose.Borrego@Sun.COM * smb_com_search
1248670SJose.Borrego@Sun.COM * --------------
1258670SJose.Borrego@Sun.COM *
1268670SJose.Borrego@Sun.COM * If the client is prior to the LANMAN1.0 dialect, the returned FileName
1278670SJose.Borrego@Sun.COM * should be uppercased.
1288670SJose.Borrego@Sun.COM * If the client has negotiated a dialect prior to the LANMAN1.0 dialect,
1298670SJose.Borrego@Sun.COM * or if bit0 of the Flags2 SMB header field of the request is clear,
1308670SJose.Borrego@Sun.COM * the returned FileName should be uppercased.
1315331Samw *
1328670SJose.Borrego@Sun.COM * SMB_COM_SEARCH terminates when either the requested maximum number of
1338670SJose.Borrego@Sun.COM * entries that match the named file are found, or the end of directory is
1348670SJose.Borrego@Sun.COM * reached without the maximum number of matches being found. A response
1358670SJose.Borrego@Sun.COM * containing no entries indicates that no matching entries were found
1368670SJose.Borrego@Sun.COM * between the starting point of the search and the end of directory.
1378670SJose.Borrego@Sun.COM *
1388670SJose.Borrego@Sun.COM *
1398670SJose.Borrego@Sun.COM * The find, find_close and find_unique protocols may be used in place of
1408670SJose.Borrego@Sun.COM * the core "search" protocol when LANMAN 1.0 dialect has been negotiated.
1415331Samw *
1428670SJose.Borrego@Sun.COM * smb_com_find
1438670SJose.Borrego@Sun.COM * ------------
1448670SJose.Borrego@Sun.COM *
1458670SJose.Borrego@Sun.COM * The find protocol is used to match the find OS/2 system call.
1468670SJose.Borrego@Sun.COM *
1478670SJose.Borrego@Sun.COM * The format of the find protocol is the same as the core "search" protocol.
1488670SJose.Borrego@Sun.COM * The difference is that the directory is logically Opened with a find protocol
1498670SJose.Borrego@Sun.COM * and logically closed with the find close protocol.
1508670SJose.Borrego@Sun.COM * As is true of a failing open, if a find request (find "first" request where
1515331Samw * resume_key is null) fails (no entries are found), no find close protocol is
1525331Samw * expected.
1535331Samw *
1548670SJose.Borrego@Sun.COM * If no global characters are present, a "find unique" protocol should be used
1555331Samw * (only one entry is expected and find close need not be sent).
1565331Samw *
1578670SJose.Borrego@Sun.COM * A find request will terminate when either the requested maximum number of
1588670SJose.Borrego@Sun.COM * entries that match the named file are found, or the end of directory is
1598670SJose.Borrego@Sun.COM * reached without the maximum number of matches being found. A response
1608670SJose.Borrego@Sun.COM * containing no entries indicates that no matching entries were found between
1618670SJose.Borrego@Sun.COM * the starting point of the search and the end of directory.
1625331Samw *
1638670SJose.Borrego@Sun.COM * If a find requests more data than can be placed in a message of the
1645331Samw * max-xmit-size for the TID specified, the server will return only the number
1655331Samw * of entries which will fit.
1665331Samw *
1678670SJose.Borrego@Sun.COM *
1688670SJose.Borrego@Sun.COM * smb_com_find_close
1698670SJose.Borrego@Sun.COM * ------------------
1708670SJose.Borrego@Sun.COM *
1718670SJose.Borrego@Sun.COM * The find close protocol is used to match the find close OS/2 system call.
1728670SJose.Borrego@Sun.COM *
1738670SJose.Borrego@Sun.COM * Whereas the first find protocol logically opens the directory, subsequent
1748670SJose.Borrego@Sun.COM * find protocols presenting a resume_key further "read" the directory, the
1758670SJose.Borrego@Sun.COM * find close protocol "closes" the directory allowing the server to free any
1768670SJose.Borrego@Sun.COM * resources held in support of the directory search.
1775331Samw *
1788670SJose.Borrego@Sun.COM * In our implementation this translates to closing the odir.
1798670SJose.Borrego@Sun.COM *
1808670SJose.Borrego@Sun.COM *
1818670SJose.Borrego@Sun.COM * smb_com_find_unique
1828670SJose.Borrego@Sun.COM * -------------------
1835331Samw *
1848670SJose.Borrego@Sun.COM * The format of the find unique protocol is the same as the core "search"
1858670SJose.Borrego@Sun.COM * protocol. The difference is that the directory is logically opened, any
1868670SJose.Borrego@Sun.COM * matching entries returned, and then the directory is logically closed.
1878670SJose.Borrego@Sun.COM *
1888670SJose.Borrego@Sun.COM * The resume search key key will be returned as in the find protocol and
1898670SJose.Borrego@Sun.COM * search protocol however it may NOT be returned to continue the search.
1908670SJose.Borrego@Sun.COM * Only one buffer of entries is expected and find close need not be sent.
1915331Samw *
1928670SJose.Borrego@Sun.COM * If a find unique requests more data than can be placed in a message of the
1938670SJose.Borrego@Sun.COM * max-xmit-size for the TID specified, the server will abort the virtual
1948670SJose.Borrego@Sun.COM * circuit to the consumer.
1955331Samw */
1968670SJose.Borrego@Sun.COM
19712508Samw@Sun.COM #define SMB_NAME83_BUFLEN 12
19812508Samw@Sun.COM static void smb_name83(const char *, char *, size_t);
19912508Samw@Sun.COM
2008670SJose.Borrego@Sun.COM /* *** smb_com_search *** */
2018670SJose.Borrego@Sun.COM
2028670SJose.Borrego@Sun.COM smb_sdrc_t
smb_pre_search(smb_request_t * sr)2038670SJose.Borrego@Sun.COM smb_pre_search(smb_request_t *sr)
2048670SJose.Borrego@Sun.COM {
2058670SJose.Borrego@Sun.COM DTRACE_SMB_1(op__Search__start, smb_request_t *, sr);
2068670SJose.Borrego@Sun.COM return (SDRC_SUCCESS);
2078670SJose.Borrego@Sun.COM }
2088670SJose.Borrego@Sun.COM
2098670SJose.Borrego@Sun.COM void
smb_post_search(smb_request_t * sr)2108670SJose.Borrego@Sun.COM smb_post_search(smb_request_t *sr)
2118670SJose.Borrego@Sun.COM {
2128670SJose.Borrego@Sun.COM DTRACE_SMB_1(op__Search__done, smb_request_t *, sr);
2138670SJose.Borrego@Sun.COM }
2148670SJose.Borrego@Sun.COM
2158670SJose.Borrego@Sun.COM smb_sdrc_t
smb_com_search(smb_request_t * sr)2168670SJose.Borrego@Sun.COM smb_com_search(smb_request_t *sr)
2178670SJose.Borrego@Sun.COM {
2188670SJose.Borrego@Sun.COM int rc;
2198670SJose.Borrego@Sun.COM uint16_t count, maxcount, index;
2208670SJose.Borrego@Sun.COM uint16_t sattr, odid;
2218670SJose.Borrego@Sun.COM uint16_t key_len;
2228670SJose.Borrego@Sun.COM uint32_t client_key;
2238670SJose.Borrego@Sun.COM char name[SMB_SHORTNAMELEN];
22412508Samw@Sun.COM char name83[SMB_SHORTNAMELEN];
22511963SAfshin.Ardakani@Sun.COM smb_pathname_t *pn;
2268670SJose.Borrego@Sun.COM unsigned char resume_char;
2278670SJose.Borrego@Sun.COM unsigned char type;
2288670SJose.Borrego@Sun.COM boolean_t find_first, to_upper;
2298670SJose.Borrego@Sun.COM smb_tree_t *tree;
2308670SJose.Borrego@Sun.COM smb_odir_t *od;
2318670SJose.Borrego@Sun.COM smb_fileinfo_t fileinfo;
2328670SJose.Borrego@Sun.COM smb_odir_resume_t odir_resume;
2338670SJose.Borrego@Sun.COM boolean_t eos;
2348670SJose.Borrego@Sun.COM
2358670SJose.Borrego@Sun.COM to_upper = B_FALSE;
2368670SJose.Borrego@Sun.COM if ((sr->session->dialect <= LANMAN1_0) ||
2378670SJose.Borrego@Sun.COM ((sr->smb_flg2 & SMB_FLAGS2_KNOWS_LONG_NAMES) == 0)) {
2388670SJose.Borrego@Sun.COM to_upper = B_TRUE;
2398670SJose.Borrego@Sun.COM }
2408670SJose.Borrego@Sun.COM
2418670SJose.Borrego@Sun.COM /* We only handle 8.3 name here */
2428670SJose.Borrego@Sun.COM sr->smb_flg2 &= ~SMB_FLAGS2_KNOWS_LONG_NAMES;
2438670SJose.Borrego@Sun.COM sr->smb_flg &= ~SMB_FLAGS_CASE_INSENSITIVE;
2448670SJose.Borrego@Sun.COM
2458670SJose.Borrego@Sun.COM if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
2468670SJose.Borrego@Sun.COM return (SDRC_ERROR);
2478670SJose.Borrego@Sun.COM
24811963SAfshin.Ardakani@Sun.COM pn = &sr->arg.dirop.fqi.fq_path;
24911963SAfshin.Ardakani@Sun.COM rc = smbsr_decode_data(sr, "%Abw", sr, &pn->pn_path, &type, &key_len);
2508670SJose.Borrego@Sun.COM if ((rc != 0) || (type != 0x05))
2518670SJose.Borrego@Sun.COM return (SDRC_ERROR);
2528670SJose.Borrego@Sun.COM
25311963SAfshin.Ardakani@Sun.COM smb_pathname_init(sr, pn, pn->pn_path);
25411963SAfshin.Ardakani@Sun.COM if (!smb_pathname_validate(sr, pn) ||
25511963SAfshin.Ardakani@Sun.COM smb_is_stream_name(pn->pn_path)) {
25611963SAfshin.Ardakani@Sun.COM smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
25711963SAfshin.Ardakani@Sun.COM ERRDOS, ERROR_NO_MORE_FILES);
25811963SAfshin.Ardakani@Sun.COM return (SDRC_ERROR);
25911963SAfshin.Ardakani@Sun.COM }
26011963SAfshin.Ardakani@Sun.COM
2618670SJose.Borrego@Sun.COM tree = sr->tid_tree;
2628670SJose.Borrego@Sun.COM
2638670SJose.Borrego@Sun.COM /* Volume information only */
2648670SJose.Borrego@Sun.COM if ((sattr == FILE_ATTRIBUTE_VOLUME) && (key_len != 21)) {
2658670SJose.Borrego@Sun.COM (void) memset(name, ' ', sizeof (name));
2668670SJose.Borrego@Sun.COM (void) strncpy(name, tree->t_volume, sizeof (name));
2678670SJose.Borrego@Sun.COM
2688670SJose.Borrego@Sun.COM if (key_len >= 21) {
2698670SJose.Borrego@Sun.COM (void) smb_mbc_decodef(&sr->smb_data, "17.l",
2708670SJose.Borrego@Sun.COM &client_key);
2718670SJose.Borrego@Sun.COM } else {
2728670SJose.Borrego@Sun.COM client_key = 0;
2738670SJose.Borrego@Sun.COM }
2748670SJose.Borrego@Sun.COM
2758670SJose.Borrego@Sun.COM (void) smb_mbc_encodef(&sr->reply, "bwwbwb11c5.lb8.13c",
27611963SAfshin.Ardakani@Sun.COM 1, 0, VAR_BCC, 5, 0, 0, pn->pn_path+1,
2778670SJose.Borrego@Sun.COM client_key, sattr, name);
2788670SJose.Borrego@Sun.COM
2798670SJose.Borrego@Sun.COM rc = (sr->reply.chain_offset - sr->cur_reply_offset) - 8;
2808670SJose.Borrego@Sun.COM (void) smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
2818670SJose.Borrego@Sun.COM 1, 1, rc+3, 5, rc);
2828670SJose.Borrego@Sun.COM
2838670SJose.Borrego@Sun.COM return (SDRC_SUCCESS);
2848670SJose.Borrego@Sun.COM }
2858670SJose.Borrego@Sun.COM
2868670SJose.Borrego@Sun.COM if ((key_len != 0) && (key_len != 21))
2878670SJose.Borrego@Sun.COM return (SDRC_ERROR);
2888670SJose.Borrego@Sun.COM
2898670SJose.Borrego@Sun.COM find_first = (key_len == 0);
2908670SJose.Borrego@Sun.COM resume_char = 0;
2918670SJose.Borrego@Sun.COM client_key = 0;
2928670SJose.Borrego@Sun.COM
2938670SJose.Borrego@Sun.COM if (find_first) {
29411963SAfshin.Ardakani@Sun.COM odid = smb_odir_open(sr, pn->pn_path, sattr, 0);
2958670SJose.Borrego@Sun.COM if (odid == 0) {
2968670SJose.Borrego@Sun.COM if (sr->smb_error.status == NT_STATUS_ACCESS_DENIED)
2978670SJose.Borrego@Sun.COM smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
2988670SJose.Borrego@Sun.COM ERRDOS, ERROR_NO_MORE_FILES);
2998670SJose.Borrego@Sun.COM return (SDRC_ERROR);
3008670SJose.Borrego@Sun.COM }
3018670SJose.Borrego@Sun.COM } else {
3028670SJose.Borrego@Sun.COM if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
3038670SJose.Borrego@Sun.COM &resume_char, &index, &odid, &client_key) != 0) {
3048670SJose.Borrego@Sun.COM return (SDRC_ERROR);
3058670SJose.Borrego@Sun.COM }
3068670SJose.Borrego@Sun.COM }
3078670SJose.Borrego@Sun.COM
3088670SJose.Borrego@Sun.COM od = smb_tree_lookup_odir(sr->tid_tree, odid);
3098670SJose.Borrego@Sun.COM if (od == NULL) {
3108670SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
3118670SJose.Borrego@Sun.COM ERRDOS, ERROR_INVALID_HANDLE);
3128670SJose.Borrego@Sun.COM return (SDRC_ERROR);
3138670SJose.Borrego@Sun.COM }
3148670SJose.Borrego@Sun.COM
3158670SJose.Borrego@Sun.COM if (!find_first) {
3168670SJose.Borrego@Sun.COM odir_resume.or_type = SMB_ODIR_RESUME_IDX;
3178670SJose.Borrego@Sun.COM odir_resume.or_idx = index;
3188670SJose.Borrego@Sun.COM smb_odir_resume_at(od, &odir_resume);
3198670SJose.Borrego@Sun.COM }
3208670SJose.Borrego@Sun.COM
3218670SJose.Borrego@Sun.COM (void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
3228670SJose.Borrego@Sun.COM
3238670SJose.Borrego@Sun.COM rc = 0;
3248670SJose.Borrego@Sun.COM index = 0;
3258670SJose.Borrego@Sun.COM count = 0;
3268670SJose.Borrego@Sun.COM if (maxcount > SMB_MAX_SEARCH)
3278670SJose.Borrego@Sun.COM maxcount = SMB_MAX_SEARCH;
3288670SJose.Borrego@Sun.COM
3298670SJose.Borrego@Sun.COM while (count < maxcount) {
3308670SJose.Borrego@Sun.COM rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
3318670SJose.Borrego@Sun.COM if ((rc != 0 || (eos == B_TRUE)))
3328670SJose.Borrego@Sun.COM break;
3338670SJose.Borrego@Sun.COM
3348845Samw@Sun.COM if (*fileinfo.fi_shortname == '\0') {
335*12890SJoyce.McIntosh@Sun.COM if (smb_needs_mangled(fileinfo.fi_name))
336*12890SJoyce.McIntosh@Sun.COM continue;
33712508Samw@Sun.COM (void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
3388845Samw@Sun.COM SMB_SHORTNAMELEN - 1);
3398670SJose.Borrego@Sun.COM if (to_upper)
34012508Samw@Sun.COM (void) smb_strupr(fileinfo.fi_shortname);
3418670SJose.Borrego@Sun.COM }
34212508Samw@Sun.COM smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
3438670SJose.Borrego@Sun.COM
34412508Samw@Sun.COM (void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
34512508Samw@Sun.COM resume_char, name83, index, odid, client_key,
3468670SJose.Borrego@Sun.COM fileinfo.fi_dosattr & 0xff,
34710504SKeyur.Desai@Sun.COM smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
3488670SJose.Borrego@Sun.COM (int32_t)fileinfo.fi_size,
34912508Samw@Sun.COM fileinfo.fi_shortname);
3508670SJose.Borrego@Sun.COM
3518670SJose.Borrego@Sun.COM smb_odir_save_cookie(od, index, fileinfo.fi_cookie);
3528670SJose.Borrego@Sun.COM
3538670SJose.Borrego@Sun.COM count++;
3548670SJose.Borrego@Sun.COM index++;
3558670SJose.Borrego@Sun.COM }
3568670SJose.Borrego@Sun.COM
3578670SJose.Borrego@Sun.COM if (rc != 0) {
3588670SJose.Borrego@Sun.COM smb_odir_close(od);
3599635SJoyce.McIntosh@Sun.COM smb_odir_release(od);
3608670SJose.Borrego@Sun.COM return (SDRC_ERROR);
3618670SJose.Borrego@Sun.COM }
3628670SJose.Borrego@Sun.COM
3638670SJose.Borrego@Sun.COM if (count == 0 && find_first) {
3648670SJose.Borrego@Sun.COM smb_odir_close(od);
3659635SJoyce.McIntosh@Sun.COM smb_odir_release(od);
3668670SJose.Borrego@Sun.COM smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
3678670SJose.Borrego@Sun.COM ERRDOS, ERROR_NO_MORE_FILES);
3688670SJose.Borrego@Sun.COM return (SDRC_ERROR);
3698670SJose.Borrego@Sun.COM }
3708670SJose.Borrego@Sun.COM
3718670SJose.Borrego@Sun.COM rc = (sr->reply.chain_offset - sr->cur_reply_offset) - 8;
3728670SJose.Borrego@Sun.COM if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
3738670SJose.Borrego@Sun.COM 1, count, rc+3, 5, rc) < 0) {
3748670SJose.Borrego@Sun.COM smb_odir_close(od);
3759635SJoyce.McIntosh@Sun.COM smb_odir_release(od);
3768670SJose.Borrego@Sun.COM return (SDRC_ERROR);
3778670SJose.Borrego@Sun.COM }
3788670SJose.Borrego@Sun.COM
3799635SJoyce.McIntosh@Sun.COM smb_odir_release(od);
3808670SJose.Borrego@Sun.COM return (SDRC_SUCCESS);
3818670SJose.Borrego@Sun.COM }
3828670SJose.Borrego@Sun.COM
3838670SJose.Borrego@Sun.COM
3848670SJose.Borrego@Sun.COM /* *** smb_com_find *** */
3858670SJose.Borrego@Sun.COM
3866030Sjb150015 smb_sdrc_t
smb_pre_find(smb_request_t * sr)3876139Sjb150015 smb_pre_find(smb_request_t *sr)
3886139Sjb150015 {
3896139Sjb150015 DTRACE_SMB_1(op__Find__start, smb_request_t *, sr);
3906139Sjb150015 return (SDRC_SUCCESS);
3916139Sjb150015 }
3926139Sjb150015
3936139Sjb150015 void
smb_post_find(smb_request_t * sr)3946139Sjb150015 smb_post_find(smb_request_t *sr)
3956139Sjb150015 {
3966139Sjb150015 DTRACE_SMB_1(op__Find__done, smb_request_t *, sr);
3976139Sjb150015 }
3986139Sjb150015
3996139Sjb150015 smb_sdrc_t
smb_com_find(smb_request_t * sr)4006139Sjb150015 smb_com_find(smb_request_t *sr)
4015331Samw {
4025331Samw int rc;
4038670SJose.Borrego@Sun.COM uint16_t count, maxcount, index;
4048670SJose.Borrego@Sun.COM uint16_t sattr, odid;
4058670SJose.Borrego@Sun.COM uint16_t key_len;
4068670SJose.Borrego@Sun.COM uint32_t client_key;
40712508Samw@Sun.COM char name83[SMB_SHORTNAMELEN];
4088670SJose.Borrego@Sun.COM smb_odir_t *od;
4098670SJose.Borrego@Sun.COM smb_fileinfo_t fileinfo;
4108670SJose.Borrego@Sun.COM boolean_t eos;
4118670SJose.Borrego@Sun.COM
41211963SAfshin.Ardakani@Sun.COM smb_pathname_t *pn;
4137348SJose.Borrego@Sun.COM unsigned char resume_char;
4145331Samw unsigned char type;
4157348SJose.Borrego@Sun.COM boolean_t find_first = B_TRUE;
4168670SJose.Borrego@Sun.COM smb_odir_resume_t odir_resume;
4175331Samw
4186030Sjb150015 if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
4196139Sjb150015 return (SDRC_ERROR);
4205331Samw
42111963SAfshin.Ardakani@Sun.COM pn = &sr->arg.dirop.fqi.fq_path;
42211963SAfshin.Ardakani@Sun.COM rc = smbsr_decode_data(sr, "%Abw", sr, &pn->pn_path, &type, &key_len);
4236030Sjb150015 if ((rc != 0) || (type != 0x05))
4246139Sjb150015 return (SDRC_ERROR);
4255331Samw
4268670SJose.Borrego@Sun.COM if ((key_len != 0) && (key_len != 21))
4278670SJose.Borrego@Sun.COM return (SDRC_ERROR);
4288670SJose.Borrego@Sun.COM
42911963SAfshin.Ardakani@Sun.COM smb_pathname_init(sr, pn, pn->pn_path);
43011963SAfshin.Ardakani@Sun.COM if (!smb_pathname_validate(sr, pn))
43111963SAfshin.Ardakani@Sun.COM return (SDRC_ERROR);
43211963SAfshin.Ardakani@Sun.COM
43311963SAfshin.Ardakani@Sun.COM if (smb_is_stream_name(pn->pn_path)) {
43411963SAfshin.Ardakani@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
43511963SAfshin.Ardakani@Sun.COM ERRDOS, ERROR_INVALID_NAME);
43611963SAfshin.Ardakani@Sun.COM return (SDRC_ERROR);
43711963SAfshin.Ardakani@Sun.COM }
43811963SAfshin.Ardakani@Sun.COM
4398670SJose.Borrego@Sun.COM find_first = (key_len == 0);
4408670SJose.Borrego@Sun.COM resume_char = 0;
4418670SJose.Borrego@Sun.COM client_key = 0;
4428670SJose.Borrego@Sun.COM
4438670SJose.Borrego@Sun.COM if (find_first) {
44411963SAfshin.Ardakani@Sun.COM odid = smb_odir_open(sr, pn->pn_path, sattr, 0);
4458670SJose.Borrego@Sun.COM if (odid == 0)
4466139Sjb150015 return (SDRC_ERROR);
4478670SJose.Borrego@Sun.COM } else {
4487348SJose.Borrego@Sun.COM if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
4498670SJose.Borrego@Sun.COM &resume_char, &index, &odid, &client_key) != 0) {
4506139Sjb150015 return (SDRC_ERROR);
4515331Samw }
4528670SJose.Borrego@Sun.COM }
4535331Samw
4548670SJose.Borrego@Sun.COM od = smb_tree_lookup_odir(sr->tid_tree, odid);
4558670SJose.Borrego@Sun.COM if (od == NULL) {
4568670SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
4578670SJose.Borrego@Sun.COM ERRDOS, ERROR_INVALID_HANDLE);
4588670SJose.Borrego@Sun.COM return (SDRC_ERROR);
4598670SJose.Borrego@Sun.COM }
4605331Samw
4618670SJose.Borrego@Sun.COM if (!find_first) {
4628670SJose.Borrego@Sun.COM odir_resume.or_type = SMB_ODIR_RESUME_IDX;
4638670SJose.Borrego@Sun.COM odir_resume.or_idx = index;
4648670SJose.Borrego@Sun.COM smb_odir_resume_at(od, &odir_resume);
4655331Samw }
4665331Samw
4677052Samw (void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
4685331Samw
4698670SJose.Borrego@Sun.COM rc = 0;
4707348SJose.Borrego@Sun.COM index = 0;
4715331Samw count = 0;
4727348SJose.Borrego@Sun.COM if (maxcount > SMB_MAX_SEARCH)
4737348SJose.Borrego@Sun.COM maxcount = SMB_MAX_SEARCH;
4747348SJose.Borrego@Sun.COM
4755331Samw while (count < maxcount) {
4768670SJose.Borrego@Sun.COM rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
4778670SJose.Borrego@Sun.COM if ((rc != 0 || (eos == B_TRUE)))
4785331Samw break;
4795331Samw
4808845Samw@Sun.COM if (*fileinfo.fi_shortname == '\0') {
481*12890SJoyce.McIntosh@Sun.COM if (smb_needs_mangled(fileinfo.fi_name))
482*12890SJoyce.McIntosh@Sun.COM continue;
48312508Samw@Sun.COM (void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
4848845Samw@Sun.COM SMB_SHORTNAMELEN - 1);
4858670SJose.Borrego@Sun.COM }
48612508Samw@Sun.COM smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
4878670SJose.Borrego@Sun.COM
48812508Samw@Sun.COM (void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
48912508Samw@Sun.COM resume_char, name83, index, odid, client_key,
4908670SJose.Borrego@Sun.COM fileinfo.fi_dosattr & 0xff,
49110504SKeyur.Desai@Sun.COM smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
4928670SJose.Borrego@Sun.COM (int32_t)fileinfo.fi_size,
49312508Samw@Sun.COM fileinfo.fi_shortname);
4947348SJose.Borrego@Sun.COM
4958670SJose.Borrego@Sun.COM smb_odir_save_cookie(od, index, fileinfo.fi_cookie);
4968670SJose.Borrego@Sun.COM
4975331Samw count++;
4987348SJose.Borrego@Sun.COM index++;
4995331Samw }
5005331Samw
5018670SJose.Borrego@Sun.COM if (rc != 0) {
5028670SJose.Borrego@Sun.COM smb_odir_close(od);
5039635SJoyce.McIntosh@Sun.COM smb_odir_release(od);
5046139Sjb150015 return (SDRC_ERROR);
5055331Samw }
5065331Samw
5077348SJose.Borrego@Sun.COM if (count == 0 && find_first) {
5088670SJose.Borrego@Sun.COM smb_odir_close(od);
5099635SJoyce.McIntosh@Sun.COM smb_odir_release(od);
5107348SJose.Borrego@Sun.COM smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
5117348SJose.Borrego@Sun.COM ERRDOS, ERROR_NO_MORE_FILES);
5126139Sjb150015 return (SDRC_ERROR);
5135331Samw }
5145331Samw
5155331Samw rc = (MBC_LENGTH(&sr->reply) - sr->cur_reply_offset) - 8;
5167052Samw if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
5176030Sjb150015 1, count, rc+3, 5, rc) < 0) {
5188670SJose.Borrego@Sun.COM smb_odir_close(od);
5199635SJoyce.McIntosh@Sun.COM smb_odir_release(od);
5206139Sjb150015 return (SDRC_ERROR);
5215331Samw }
5225331Samw
5239635SJoyce.McIntosh@Sun.COM smb_odir_release(od);
5246139Sjb150015 return (SDRC_SUCCESS);
5255331Samw }
5265331Samw
5278670SJose.Borrego@Sun.COM
5288670SJose.Borrego@Sun.COM /* *** smb_com_find_close *** */
5298670SJose.Borrego@Sun.COM
5306030Sjb150015 smb_sdrc_t
smb_pre_find_close(smb_request_t * sr)5316139Sjb150015 smb_pre_find_close(smb_request_t *sr)
5326139Sjb150015 {
5336139Sjb150015 DTRACE_SMB_1(op__FindClose__start, smb_request_t *, sr);
5346139Sjb150015 return (SDRC_SUCCESS);
5356139Sjb150015 }
5366139Sjb150015
5376139Sjb150015 void
smb_post_find_close(smb_request_t * sr)5386139Sjb150015 smb_post_find_close(smb_request_t *sr)
5396139Sjb150015 {
5406139Sjb150015 DTRACE_SMB_1(op__FindClose__done, smb_request_t *, sr);
5416139Sjb150015 }
5426139Sjb150015
5436139Sjb150015 smb_sdrc_t
smb_com_find_close(smb_request_t * sr)5446139Sjb150015 smb_com_find_close(smb_request_t *sr)
5455331Samw {
5468670SJose.Borrego@Sun.COM int rc;
5478670SJose.Borrego@Sun.COM uint16_t maxcount, index;
5488670SJose.Borrego@Sun.COM uint16_t sattr, odid;
5498670SJose.Borrego@Sun.COM uint16_t key_len;
5508670SJose.Borrego@Sun.COM uint32_t client_key;
5518670SJose.Borrego@Sun.COM char *path;
5528670SJose.Borrego@Sun.COM unsigned char resume_char;
5538670SJose.Borrego@Sun.COM unsigned char type;
5548670SJose.Borrego@Sun.COM smb_odir_t *od;
5555331Samw
5566030Sjb150015 if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
5576139Sjb150015 return (SDRC_ERROR);
5585331Samw
5595331Samw rc = smbsr_decode_data(sr, "%Abw", sr, &path, &type, &key_len);
5606030Sjb150015 if ((rc != 0) || (type != 0x05))
5616139Sjb150015 return (SDRC_ERROR);
5625331Samw
5638670SJose.Borrego@Sun.COM if (key_len == 0) {
5648670SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
5658670SJose.Borrego@Sun.COM ERRDOS, ERROR_INVALID_HANDLE);
5668670SJose.Borrego@Sun.COM return (SDRC_ERROR);
5678670SJose.Borrego@Sun.COM } else if (key_len != 21) {
5688670SJose.Borrego@Sun.COM return (SDRC_ERROR);
5698670SJose.Borrego@Sun.COM }
5708670SJose.Borrego@Sun.COM
5718670SJose.Borrego@Sun.COM odid = 0;
5728670SJose.Borrego@Sun.COM if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
5738670SJose.Borrego@Sun.COM &resume_char, &index, &odid, &client_key) != 0) {
5748670SJose.Borrego@Sun.COM return (SDRC_ERROR);
5758670SJose.Borrego@Sun.COM }
5768670SJose.Borrego@Sun.COM
5778670SJose.Borrego@Sun.COM od = smb_tree_lookup_odir(sr->tid_tree, odid);
5788670SJose.Borrego@Sun.COM if (od == NULL) {
5798670SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
5808670SJose.Borrego@Sun.COM ERRDOS, ERROR_INVALID_HANDLE);
5816139Sjb150015 return (SDRC_ERROR);
5825331Samw }
5835331Samw
5849635SJoyce.McIntosh@Sun.COM smb_odir_close(od);
5858670SJose.Borrego@Sun.COM smb_odir_release(od);
5868670SJose.Borrego@Sun.COM
5878670SJose.Borrego@Sun.COM if (smbsr_encode_result(sr, 1, 3, "bwwbw", 1, 0, 3, 5, 0))
5888670SJose.Borrego@Sun.COM return (SDRC_ERROR);
5898670SJose.Borrego@Sun.COM
5908670SJose.Borrego@Sun.COM return (SDRC_SUCCESS);
5918670SJose.Borrego@Sun.COM }
5928670SJose.Borrego@Sun.COM
5938670SJose.Borrego@Sun.COM
5948670SJose.Borrego@Sun.COM /* *** smb_com_find_unique *** */
5958670SJose.Borrego@Sun.COM
5968670SJose.Borrego@Sun.COM smb_sdrc_t
smb_pre_find_unique(smb_request_t * sr)5978670SJose.Borrego@Sun.COM smb_pre_find_unique(smb_request_t *sr)
5988670SJose.Borrego@Sun.COM {
5998670SJose.Borrego@Sun.COM DTRACE_SMB_1(op__FindUnique__start, smb_request_t *, sr);
6008670SJose.Borrego@Sun.COM return (SDRC_SUCCESS);
6018670SJose.Borrego@Sun.COM }
6028670SJose.Borrego@Sun.COM
6038670SJose.Borrego@Sun.COM void
smb_post_find_unique(smb_request_t * sr)6048670SJose.Borrego@Sun.COM smb_post_find_unique(smb_request_t *sr)
6058670SJose.Borrego@Sun.COM {
6068670SJose.Borrego@Sun.COM DTRACE_SMB_1(op__FindUnique__done, smb_request_t *, sr);
6078670SJose.Borrego@Sun.COM }
6088670SJose.Borrego@Sun.COM
6098670SJose.Borrego@Sun.COM smb_sdrc_t
smb_com_find_unique(struct smb_request * sr)6108670SJose.Borrego@Sun.COM smb_com_find_unique(struct smb_request *sr)
6118670SJose.Borrego@Sun.COM {
6128670SJose.Borrego@Sun.COM int rc;
6138670SJose.Borrego@Sun.COM uint16_t count, maxcount, index;
6148670SJose.Borrego@Sun.COM uint16_t sattr, odid;
61511963SAfshin.Ardakani@Sun.COM smb_pathname_t *pn;
6168670SJose.Borrego@Sun.COM unsigned char resume_char = '\0';
6178670SJose.Borrego@Sun.COM uint32_t client_key = 0;
61812508Samw@Sun.COM char name83[SMB_SHORTNAMELEN];
6198670SJose.Borrego@Sun.COM smb_odir_t *od;
6208670SJose.Borrego@Sun.COM smb_fileinfo_t fileinfo;
6218670SJose.Borrego@Sun.COM boolean_t eos;
6228934SJose.Borrego@Sun.COM smb_vdb_t *vdb;
6238670SJose.Borrego@Sun.COM
6248670SJose.Borrego@Sun.COM if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
6258670SJose.Borrego@Sun.COM return (SDRC_ERROR);
6268670SJose.Borrego@Sun.COM
62711963SAfshin.Ardakani@Sun.COM pn = &sr->arg.dirop.fqi.fq_path;
6288934SJose.Borrego@Sun.COM vdb = kmem_alloc(sizeof (smb_vdb_t), KM_SLEEP);
62911963SAfshin.Ardakani@Sun.COM if ((smbsr_decode_data(sr, "%AV", sr, &pn->pn_path, vdb) != 0) ||
6308934SJose.Borrego@Sun.COM (vdb->vdb_len != 0)) {
6318934SJose.Borrego@Sun.COM kmem_free(vdb, sizeof (smb_vdb_t));
6328670SJose.Borrego@Sun.COM return (SDRC_ERROR);
6338670SJose.Borrego@Sun.COM }
6348934SJose.Borrego@Sun.COM kmem_free(vdb, sizeof (smb_vdb_t));
6358670SJose.Borrego@Sun.COM
63611963SAfshin.Ardakani@Sun.COM smb_pathname_init(sr, pn, pn->pn_path);
63711963SAfshin.Ardakani@Sun.COM if (!smb_pathname_validate(sr, pn))
63811963SAfshin.Ardakani@Sun.COM return (SDRC_ERROR);
63911963SAfshin.Ardakani@Sun.COM
64011963SAfshin.Ardakani@Sun.COM if (smb_is_stream_name(pn->pn_path)) {
64111963SAfshin.Ardakani@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
64211963SAfshin.Ardakani@Sun.COM ERRDOS, ERROR_INVALID_NAME);
64311963SAfshin.Ardakani@Sun.COM return (SDRC_ERROR);
64411963SAfshin.Ardakani@Sun.COM }
64511963SAfshin.Ardakani@Sun.COM
6468670SJose.Borrego@Sun.COM (void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
6478670SJose.Borrego@Sun.COM
64811963SAfshin.Ardakani@Sun.COM odid = smb_odir_open(sr, pn->pn_path, sattr, 0);
6498670SJose.Borrego@Sun.COM if (odid == 0)
6508670SJose.Borrego@Sun.COM return (SDRC_ERROR);
6518670SJose.Borrego@Sun.COM od = smb_tree_lookup_odir(sr->tid_tree, odid);
6528670SJose.Borrego@Sun.COM if (od == NULL)
6538670SJose.Borrego@Sun.COM return (SDRC_ERROR);
6548670SJose.Borrego@Sun.COM
6558670SJose.Borrego@Sun.COM rc = 0;
6568670SJose.Borrego@Sun.COM count = 0;
6578670SJose.Borrego@Sun.COM index = 0;
6588670SJose.Borrego@Sun.COM if (maxcount > SMB_MAX_SEARCH)
6598670SJose.Borrego@Sun.COM maxcount = SMB_MAX_SEARCH;
6608670SJose.Borrego@Sun.COM
6618670SJose.Borrego@Sun.COM while (count < maxcount) {
6628670SJose.Borrego@Sun.COM rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
6638670SJose.Borrego@Sun.COM if ((rc != 0 || (eos == B_TRUE)))
6648670SJose.Borrego@Sun.COM break;
6658670SJose.Borrego@Sun.COM
6668845Samw@Sun.COM if (*fileinfo.fi_shortname == '\0') {
667*12890SJoyce.McIntosh@Sun.COM if (smb_needs_mangled(fileinfo.fi_name))
668*12890SJoyce.McIntosh@Sun.COM continue;
66912508Samw@Sun.COM (void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
6708845Samw@Sun.COM SMB_SHORTNAMELEN - 1);
6715331Samw }
67212508Samw@Sun.COM smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
6735331Samw
67412508Samw@Sun.COM (void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
67512508Samw@Sun.COM resume_char, name83, index, odid, client_key,
6768670SJose.Borrego@Sun.COM fileinfo.fi_dosattr & 0xff,
67710504SKeyur.Desai@Sun.COM smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
6788670SJose.Borrego@Sun.COM (int32_t)fileinfo.fi_size,
67912508Samw@Sun.COM fileinfo.fi_shortname);
6808670SJose.Borrego@Sun.COM
6818670SJose.Borrego@Sun.COM count++;
6828670SJose.Borrego@Sun.COM index++;
6838670SJose.Borrego@Sun.COM }
6848670SJose.Borrego@Sun.COM
6859635SJoyce.McIntosh@Sun.COM smb_odir_close(od);
6868670SJose.Borrego@Sun.COM smb_odir_release(od);
6878670SJose.Borrego@Sun.COM
6888670SJose.Borrego@Sun.COM if (rc != 0)
6898670SJose.Borrego@Sun.COM return (SDRC_ERROR);
6908670SJose.Borrego@Sun.COM
6918670SJose.Borrego@Sun.COM if (count == 0) {
6928670SJose.Borrego@Sun.COM smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
6938670SJose.Borrego@Sun.COM ERRDOS, ERROR_NO_MORE_FILES);
6946139Sjb150015 return (SDRC_ERROR);
6955331Samw }
6965331Samw
6978670SJose.Borrego@Sun.COM rc = (MBC_LENGTH(&sr->reply) - sr->cur_reply_offset) - 8;
6988670SJose.Borrego@Sun.COM if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset,
6998670SJose.Borrego@Sun.COM "bwwbw", 1, count, rc+3, 5, rc) < 0) {
7006139Sjb150015 return (SDRC_ERROR);
7018670SJose.Borrego@Sun.COM }
7028670SJose.Borrego@Sun.COM
7036139Sjb150015 return (SDRC_SUCCESS);
7045331Samw }
70512508Samw@Sun.COM
70612508Samw@Sun.COM /*
70712508Samw@Sun.COM * smb_name83
70812508Samw@Sun.COM *
70912508Samw@Sun.COM * Format the filename for inclusion in the resume key. The filename
71012508Samw@Sun.COM * returned in the resume key is 11 bytes:
71112508Samw@Sun.COM * - up to 8 bytes of filename, space padded to 8 bytes
71212508Samw@Sun.COM * - up to 3 bytes of ext, space padded to 3 bytes
71312508Samw@Sun.COM *
71412508Samw@Sun.COM * The name passed to smb_name83 should be a shortname or a name that
71512508Samw@Sun.COM * doesn't require mangling.
71612508Samw@Sun.COM *
71712508Samw@Sun.COM * Examples:
71812508Samw@Sun.COM * "fname.txt" -> "FNAME TXT"
71912508Samw@Sun.COM * "fname.tx" -> "FNAME TX "
72012508Samw@Sun.COM * "filename" -> "FILENAME "
72112508Samw@Sun.COM * "filename.txt" -> "FILENAMETXT"
72212508Samw@Sun.COM * "FILE~1.TXT" -> "FILE~1 TXT"
72312508Samw@Sun.COM */
72412508Samw@Sun.COM static void
smb_name83(const char * name,char * buf,size_t buflen)72512508Samw@Sun.COM smb_name83(const char *name, char *buf, size_t buflen)
72612508Samw@Sun.COM {
72712508Samw@Sun.COM const char *p;
72812508Samw@Sun.COM char *pbuf;
72912508Samw@Sun.COM int i;
73012508Samw@Sun.COM
73112508Samw@Sun.COM ASSERT(name && buf && (buflen >= SMB_NAME83_BUFLEN));
73212508Samw@Sun.COM
73312508Samw@Sun.COM (void) strlcpy(buf, " ", SMB_NAME83_BUFLEN);
73412508Samw@Sun.COM
73512508Samw@Sun.COM /* Process "." and ".." up front */
73612508Samw@Sun.COM if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) {
73712508Samw@Sun.COM (void) strncpy(buf, name, strlen(name));
73812508Samw@Sun.COM return;
73912508Samw@Sun.COM }
74012508Samw@Sun.COM
74112508Samw@Sun.COM ASSERT(smb_needs_mangled(name) == B_FALSE);
74212508Samw@Sun.COM
74312508Samw@Sun.COM /* Process basename */
74412508Samw@Sun.COM for (i = 0, p = name, pbuf = buf;
74512508Samw@Sun.COM (i < SMB_NAME83_BASELEN) && (*p != '\0') && (*p != '.'); ++i)
74612508Samw@Sun.COM *pbuf++ = *p++;
74712508Samw@Sun.COM
74812508Samw@Sun.COM /* Process the extension from the last dot in name */
74912508Samw@Sun.COM if ((p = strchr(name, '.')) != NULL) {
75012508Samw@Sun.COM ++p;
75112508Samw@Sun.COM pbuf = &buf[SMB_NAME83_BASELEN];
75212508Samw@Sun.COM for (i = 0; (i < SMB_NAME83_EXTLEN) && (*p != '\0'); ++i)
75312508Samw@Sun.COM *pbuf++ = *p++;
75412508Samw@Sun.COM }
75512508Samw@Sun.COM
75612508Samw@Sun.COM (void) smb_strupr(buf);
75712508Samw@Sun.COM }
758