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.
2393bc28dbSGordon Ross * Copyright 2017 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
smb_pre_search(smb_request_t * sr)2047f667e74Sjose borrego smb_pre_search(smb_request_t *sr)
2057f667e74Sjose borrego {
20693bc28dbSGordon Ross DTRACE_SMB_START(op__Search, smb_request_t *, sr);
2077f667e74Sjose borrego return (SDRC_SUCCESS);
2087f667e74Sjose borrego }
2097f667e74Sjose borrego
2107f667e74Sjose borrego void
smb_post_search(smb_request_t * sr)2117f667e74Sjose borrego smb_post_search(smb_request_t *sr)
2127f667e74Sjose borrego {
21393bc28dbSGordon Ross DTRACE_SMB_DONE(op__Search, smb_request_t *, sr);
2147f667e74Sjose borrego }
2157f667e74Sjose borrego
2167f667e74Sjose borrego smb_sdrc_t
smb_com_search(smb_request_t * sr)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;
234a90cf9f2SGordon 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) {
296a90cf9f2SGordon Ross status = smb_odir_openpath(sr, pn->pn_path, sattr, 0, &od);
297a90cf9f2SGordon Ross if (status != 0) {
298a90cf9f2SGordon 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 }
303*d2488fe8SGordon Ross odid = od->d_odid;
3047f667e74Sjose borrego } else {
3057f667e74Sjose borrego if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
3067f667e74Sjose borrego &resume_char, &index, &odid, &client_key) != 0) {
3077f667e74Sjose borrego return (SDRC_ERROR);
3087f667e74Sjose borrego }
309a90cf9f2SGordon Ross od = smb_tree_lookup_odir(sr, odid);
3107f667e74Sjose borrego }
3117f667e74Sjose borrego
3127f667e74Sjose borrego if (od == NULL) {
3137f667e74Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
3147f667e74Sjose borrego ERRDOS, ERROR_INVALID_HANDLE);
3157f667e74Sjose borrego return (SDRC_ERROR);
3167f667e74Sjose borrego }
3177f667e74Sjose borrego
3187f667e74Sjose borrego if (!find_first) {
319a90cf9f2SGordon Ross if ((od->d_flags & SMB_ODIR_FLAG_WILDCARDS) == 0) {
320a90cf9f2SGordon Ross od->d_eof = B_TRUE;
321a90cf9f2SGordon Ross } else {
3227f667e74Sjose borrego odir_resume.or_type = SMB_ODIR_RESUME_IDX;
3237f667e74Sjose borrego odir_resume.or_idx = index;
3247f667e74Sjose borrego smb_odir_resume_at(od, &odir_resume);
3257f667e74Sjose borrego }
326a90cf9f2SGordon Ross }
3277f667e74Sjose borrego
3287f667e74Sjose borrego (void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
3297f667e74Sjose borrego
3307f667e74Sjose borrego rc = 0;
3317f667e74Sjose borrego index = 0;
3327f667e74Sjose borrego count = 0;
3337f667e74Sjose borrego if (maxcount > SMB_MAX_SEARCH)
3347f667e74Sjose borrego maxcount = SMB_MAX_SEARCH;
3357f667e74Sjose borrego
3367f667e74Sjose borrego while (count < maxcount) {
3377f667e74Sjose borrego rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
338bfbce3c1SGordon Ross if (rc != 0 || eos != 0)
3397f667e74Sjose borrego break;
3407f667e74Sjose borrego
341743a77edSAlan Wright if (*fileinfo.fi_shortname == '\0') {
342cb174861Sjoyce mcintosh if (smb_needs_mangled(fileinfo.fi_name))
343cb174861Sjoyce mcintosh continue;
344148c5f43SAlan Wright (void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
345743a77edSAlan Wright SMB_SHORTNAMELEN - 1);
3467f667e74Sjose borrego if (to_upper)
347148c5f43SAlan Wright (void) smb_strupr(fileinfo.fi_shortname);
3487f667e74Sjose borrego }
349148c5f43SAlan Wright smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
3507f667e74Sjose borrego
351148c5f43SAlan Wright (void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
352148c5f43SAlan Wright resume_char, name83, index, odid, client_key,
3537f667e74Sjose borrego fileinfo.fi_dosattr & 0xff,
354e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
3557f667e74Sjose borrego (int32_t)fileinfo.fi_size,
356148c5f43SAlan Wright fileinfo.fi_shortname);
3577f667e74Sjose borrego
3587f667e74Sjose borrego smb_odir_save_cookie(od, index, fileinfo.fi_cookie);
3597f667e74Sjose borrego
3607f667e74Sjose borrego count++;
3617f667e74Sjose borrego index++;
3627f667e74Sjose borrego }
363a90cf9f2SGordon Ross if (eos && rc == ENOENT)
364a90cf9f2SGordon Ross rc = 0;
3657f667e74Sjose borrego
3667f667e74Sjose borrego if (rc != 0) {
3677f667e74Sjose borrego smb_odir_close(od);
368a1511e6bSjoyce mcintosh smb_odir_release(od);
3697f667e74Sjose borrego return (SDRC_ERROR);
3707f667e74Sjose borrego }
3717f667e74Sjose borrego
3727f667e74Sjose borrego if (count == 0 && find_first) {
3737f667e74Sjose borrego smb_odir_close(od);
374a1511e6bSjoyce mcintosh smb_odir_release(od);
3757f667e74Sjose borrego smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
3767f667e74Sjose borrego ERRDOS, ERROR_NO_MORE_FILES);
3777f667e74Sjose borrego return (SDRC_ERROR);
3787f667e74Sjose borrego }
3797f667e74Sjose borrego
3807f667e74Sjose borrego rc = (sr->reply.chain_offset - sr->cur_reply_offset) - 8;
3817f667e74Sjose borrego if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
3827f667e74Sjose borrego 1, count, rc+3, 5, rc) < 0) {
3837f667e74Sjose borrego smb_odir_close(od);
384a1511e6bSjoyce mcintosh smb_odir_release(od);
3857f667e74Sjose borrego return (SDRC_ERROR);
3867f667e74Sjose borrego }
3877f667e74Sjose borrego
388a1511e6bSjoyce mcintosh smb_odir_release(od);
3897f667e74Sjose borrego return (SDRC_SUCCESS);
3907f667e74Sjose borrego }
3917f667e74Sjose borrego
3927f667e74Sjose borrego
3937f667e74Sjose borrego /* *** smb_com_find *** */
3947f667e74Sjose borrego
3957b59d02dSjb150015 smb_sdrc_t
smb_pre_find(smb_request_t * sr)396faa1795aSjb150015 smb_pre_find(smb_request_t *sr)
397faa1795aSjb150015 {
39893bc28dbSGordon Ross DTRACE_SMB_START(op__Find, smb_request_t *, sr);
399faa1795aSjb150015 return (SDRC_SUCCESS);
400faa1795aSjb150015 }
401faa1795aSjb150015
402faa1795aSjb150015 void
smb_post_find(smb_request_t * sr)403faa1795aSjb150015 smb_post_find(smb_request_t *sr)
404faa1795aSjb150015 {
40593bc28dbSGordon Ross DTRACE_SMB_DONE(op__Find, smb_request_t *, sr);
406faa1795aSjb150015 }
407faa1795aSjb150015
408faa1795aSjb150015 smb_sdrc_t
smb_com_find(smb_request_t * sr)409faa1795aSjb150015 smb_com_find(smb_request_t *sr)
410da6c28aaSamw {
411da6c28aaSamw int rc;
4127f667e74Sjose borrego uint16_t count, maxcount, index;
4137f667e74Sjose borrego uint16_t sattr, odid;
4147f667e74Sjose borrego uint16_t key_len;
4157f667e74Sjose borrego uint32_t client_key;
416148c5f43SAlan Wright char name83[SMB_SHORTNAMELEN];
4177f667e74Sjose borrego smb_odir_t *od;
4187f667e74Sjose borrego smb_fileinfo_t fileinfo;
419a90cf9f2SGordon Ross uint32_t status;
420bfbce3c1SGordon Ross uint16_t eos;
4217f667e74Sjose borrego
4229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *pn;
423c8ec8eeaSjose borrego unsigned char resume_char;
424da6c28aaSamw unsigned char type;
425c8ec8eeaSjose borrego boolean_t find_first = B_TRUE;
4267f667e74Sjose borrego smb_odir_resume_t odir_resume;
427da6c28aaSamw
4287b59d02dSjb150015 if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
429faa1795aSjb150015 return (SDRC_ERROR);
430da6c28aaSamw
4319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States pn = &sr->arg.dirop.fqi.fq_path;
4329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States rc = smbsr_decode_data(sr, "%Abw", sr, &pn->pn_path, &type, &key_len);
4337b59d02dSjb150015 if ((rc != 0) || (type != 0x05))
434faa1795aSjb150015 return (SDRC_ERROR);
435da6c28aaSamw
4367f667e74Sjose borrego if ((key_len != 0) && (key_len != 21))
437faa1795aSjb150015 return (SDRC_ERROR);
438da6c28aaSamw
4399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_init(sr, pn, pn->pn_path);
4409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (!smb_pathname_validate(sr, pn))
4419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (SDRC_ERROR);
4429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
4439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_is_stream_name(pn->pn_path)) {
4449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
4459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ERRDOS, ERROR_INVALID_NAME);
4469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (SDRC_ERROR);
4479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
4489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
4497f667e74Sjose borrego find_first = (key_len == 0);
4507f667e74Sjose borrego resume_char = 0;
4517f667e74Sjose borrego client_key = 0;
452da6c28aaSamw
4537f667e74Sjose borrego if (find_first) {
454a90cf9f2SGordon Ross status = smb_odir_openpath(sr, pn->pn_path, sattr, 0, &od);
455a90cf9f2SGordon Ross if (status != 0) {
456a90cf9f2SGordon Ross smbsr_error(sr, status, 0, 0);
4577f667e74Sjose borrego return (SDRC_ERROR);
458a90cf9f2SGordon Ross }
459*d2488fe8SGordon Ross odid = od->d_odid;
460da6c28aaSamw } else {
4617f667e74Sjose borrego if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
4627f667e74Sjose borrego &resume_char, &index, &odid, &client_key) != 0) {
463faa1795aSjb150015 return (SDRC_ERROR);
464da6c28aaSamw }
465a90cf9f2SGordon Ross od = smb_tree_lookup_odir(sr, odid);
4667f667e74Sjose borrego }
4677f667e74Sjose borrego
4687f667e74Sjose borrego if (od == NULL) {
4697f667e74Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
4707f667e74Sjose borrego ERRDOS, ERROR_INVALID_HANDLE);
4717f667e74Sjose borrego return (SDRC_ERROR);
4727f667e74Sjose borrego }
4737f667e74Sjose borrego
4747f667e74Sjose borrego if (!find_first) {
475a90cf9f2SGordon Ross if ((od->d_flags & SMB_ODIR_FLAG_WILDCARDS) == 0) {
476a90cf9f2SGordon Ross od->d_eof = B_TRUE;
477a90cf9f2SGordon Ross } else {
4787f667e74Sjose borrego odir_resume.or_type = SMB_ODIR_RESUME_IDX;
4797f667e74Sjose borrego odir_resume.or_idx = index;
4807f667e74Sjose borrego smb_odir_resume_at(od, &odir_resume);
4817f667e74Sjose borrego }
482a90cf9f2SGordon Ross }
483da6c28aaSamw
4843db3f65cSamw (void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
485da6c28aaSamw
4867f667e74Sjose borrego rc = 0;
487c8ec8eeaSjose borrego index = 0;
488da6c28aaSamw count = 0;
489c8ec8eeaSjose borrego if (maxcount > SMB_MAX_SEARCH)
490c8ec8eeaSjose borrego maxcount = SMB_MAX_SEARCH;
491c8ec8eeaSjose borrego
492da6c28aaSamw while (count < maxcount) {
4937f667e74Sjose borrego rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
494bfbce3c1SGordon Ross if (rc != 0 || eos != 0)
495da6c28aaSamw break;
496da6c28aaSamw
497743a77edSAlan Wright if (*fileinfo.fi_shortname == '\0') {
498cb174861Sjoyce mcintosh if (smb_needs_mangled(fileinfo.fi_name))
499cb174861Sjoyce mcintosh continue;
500148c5f43SAlan Wright (void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
501743a77edSAlan Wright SMB_SHORTNAMELEN - 1);
5027f667e74Sjose borrego }
503148c5f43SAlan Wright smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
5047f667e74Sjose borrego
505148c5f43SAlan Wright (void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
506148c5f43SAlan Wright resume_char, name83, index, odid, client_key,
5077f667e74Sjose borrego fileinfo.fi_dosattr & 0xff,
508e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
5097f667e74Sjose borrego (int32_t)fileinfo.fi_size,
510148c5f43SAlan Wright fileinfo.fi_shortname);
511c8ec8eeaSjose borrego
5127f667e74Sjose borrego smb_odir_save_cookie(od, index, fileinfo.fi_cookie);
5137f667e74Sjose borrego
514da6c28aaSamw count++;
515c8ec8eeaSjose borrego index++;
516da6c28aaSamw }
517a90cf9f2SGordon Ross if (eos && rc == ENOENT)
518a90cf9f2SGordon Ross rc = 0;
5196537f381Sas200622
5207f667e74Sjose borrego if (rc != 0) {
5217f667e74Sjose borrego smb_odir_close(od);
522a1511e6bSjoyce mcintosh smb_odir_release(od);
523faa1795aSjb150015 return (SDRC_ERROR);
524da6c28aaSamw }
525da6c28aaSamw
526c8ec8eeaSjose borrego if (count == 0 && find_first) {
5277f667e74Sjose borrego smb_odir_close(od);
528a1511e6bSjoyce mcintosh smb_odir_release(od);
529c8ec8eeaSjose borrego smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
530c8ec8eeaSjose borrego ERRDOS, ERROR_NO_MORE_FILES);
531faa1795aSjb150015 return (SDRC_ERROR);
532da6c28aaSamw }
533da6c28aaSamw
534da6c28aaSamw rc = (MBC_LENGTH(&sr->reply) - sr->cur_reply_offset) - 8;
5353db3f65cSamw if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
5367b59d02dSjb150015 1, count, rc+3, 5, rc) < 0) {
5377f667e74Sjose borrego smb_odir_close(od);
538a1511e6bSjoyce mcintosh smb_odir_release(od);
539faa1795aSjb150015 return (SDRC_ERROR);
540da6c28aaSamw }
541da6c28aaSamw
542a1511e6bSjoyce mcintosh smb_odir_release(od);
543faa1795aSjb150015 return (SDRC_SUCCESS);
544da6c28aaSamw }
545da6c28aaSamw
5467f667e74Sjose borrego
5477f667e74Sjose borrego /* *** smb_com_find_close *** */
5487f667e74Sjose borrego
5497b59d02dSjb150015 smb_sdrc_t
smb_pre_find_close(smb_request_t * sr)550faa1795aSjb150015 smb_pre_find_close(smb_request_t *sr)
551faa1795aSjb150015 {
55293bc28dbSGordon Ross DTRACE_SMB_START(op__FindClose, smb_request_t *, sr);
553faa1795aSjb150015 return (SDRC_SUCCESS);
554faa1795aSjb150015 }
555faa1795aSjb150015
556faa1795aSjb150015 void
smb_post_find_close(smb_request_t * sr)557faa1795aSjb150015 smb_post_find_close(smb_request_t *sr)
558faa1795aSjb150015 {
55993bc28dbSGordon Ross DTRACE_SMB_DONE(op__FindClose, smb_request_t *, sr);
560faa1795aSjb150015 }
561faa1795aSjb150015
562faa1795aSjb150015 smb_sdrc_t
smb_com_find_close(smb_request_t * sr)563faa1795aSjb150015 smb_com_find_close(smb_request_t *sr)
564da6c28aaSamw {
5657f667e74Sjose borrego int rc;
5667f667e74Sjose borrego uint16_t maxcount, index;
5677f667e74Sjose borrego uint16_t sattr, odid;
5687f667e74Sjose borrego uint16_t key_len;
5697f667e74Sjose borrego uint32_t client_key;
570da6c28aaSamw char *path;
571c8ec8eeaSjose borrego unsigned char resume_char;
572da6c28aaSamw unsigned char type;
5737f667e74Sjose borrego smb_odir_t *od;
574da6c28aaSamw
5757b59d02dSjb150015 if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
576faa1795aSjb150015 return (SDRC_ERROR);
577da6c28aaSamw
578da6c28aaSamw rc = smbsr_decode_data(sr, "%Abw", sr, &path, &type, &key_len);
5797b59d02dSjb150015 if ((rc != 0) || (type != 0x05))
580faa1795aSjb150015 return (SDRC_ERROR);
581da6c28aaSamw
5827f667e74Sjose borrego if (key_len == 0) {
583dc20a302Sas200622 smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
5847f667e74Sjose borrego ERRDOS, ERROR_INVALID_HANDLE);
585faa1795aSjb150015 return (SDRC_ERROR);
5867f667e74Sjose borrego } else if (key_len != 21) {
587faa1795aSjb150015 return (SDRC_ERROR);
588da6c28aaSamw }
589da6c28aaSamw
5907f667e74Sjose borrego odid = 0;
5917f667e74Sjose borrego if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
5927f667e74Sjose borrego &resume_char, &index, &odid, &client_key) != 0) {
5937f667e74Sjose borrego return (SDRC_ERROR);
5947f667e74Sjose borrego }
5957f667e74Sjose borrego
5963b13a1efSThomas Keiser od = smb_tree_lookup_odir(sr, odid);
5977f667e74Sjose borrego if (od == NULL) {
5987f667e74Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
5997f667e74Sjose borrego ERRDOS, ERROR_INVALID_HANDLE);
6007f667e74Sjose borrego return (SDRC_ERROR);
6017f667e74Sjose borrego }
6027f667e74Sjose borrego
6037f667e74Sjose borrego smb_odir_close(od);
604a1511e6bSjoyce mcintosh smb_odir_release(od);
6057f667e74Sjose borrego
6067b59d02dSjb150015 if (smbsr_encode_result(sr, 1, 3, "bwwbw", 1, 0, 3, 5, 0))
607faa1795aSjb150015 return (SDRC_ERROR);
6087f667e74Sjose borrego
6097f667e74Sjose borrego return (SDRC_SUCCESS);
6107f667e74Sjose borrego }
6117f667e74Sjose borrego
6127f667e74Sjose borrego
6137f667e74Sjose borrego /* *** smb_com_find_unique *** */
6147f667e74Sjose borrego
6157f667e74Sjose borrego smb_sdrc_t
smb_pre_find_unique(smb_request_t * sr)6167f667e74Sjose borrego smb_pre_find_unique(smb_request_t *sr)
6177f667e74Sjose borrego {
61893bc28dbSGordon Ross DTRACE_SMB_START(op__FindUnique, smb_request_t *, sr);
6197f667e74Sjose borrego return (SDRC_SUCCESS);
6207f667e74Sjose borrego }
6217f667e74Sjose borrego
6227f667e74Sjose borrego void
smb_post_find_unique(smb_request_t * sr)6237f667e74Sjose borrego smb_post_find_unique(smb_request_t *sr)
6247f667e74Sjose borrego {
62593bc28dbSGordon Ross DTRACE_SMB_DONE(op__FindUnique, smb_request_t *, sr);
6267f667e74Sjose borrego }
6277f667e74Sjose borrego
6287f667e74Sjose borrego smb_sdrc_t
smb_com_find_unique(struct smb_request * sr)6297f667e74Sjose borrego smb_com_find_unique(struct smb_request *sr)
6307f667e74Sjose borrego {
6317f667e74Sjose borrego int rc;
6327f667e74Sjose borrego uint16_t count, maxcount, index;
633a90cf9f2SGordon Ross uint16_t sattr;
6349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_t *pn;
6357f667e74Sjose borrego unsigned char resume_char = '\0';
6367f667e74Sjose borrego uint32_t client_key = 0;
637148c5f43SAlan Wright char name83[SMB_SHORTNAMELEN];
6387f667e74Sjose borrego smb_odir_t *od;
6397f667e74Sjose borrego smb_fileinfo_t fileinfo;
640a90cf9f2SGordon Ross uint32_t status;
641bfbce3c1SGordon Ross uint16_t eos;
6422c2961f8Sjose borrego smb_vdb_t *vdb;
6437f667e74Sjose borrego
6447f667e74Sjose borrego if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
6457f667e74Sjose borrego return (SDRC_ERROR);
6467f667e74Sjose borrego
6479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States pn = &sr->arg.dirop.fqi.fq_path;
6482c2961f8Sjose borrego vdb = kmem_alloc(sizeof (smb_vdb_t), KM_SLEEP);
6499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((smbsr_decode_data(sr, "%AV", sr, &pn->pn_path, vdb) != 0) ||
6502c2961f8Sjose borrego (vdb->vdb_len != 0)) {
6512c2961f8Sjose borrego kmem_free(vdb, sizeof (smb_vdb_t));
6527f667e74Sjose borrego return (SDRC_ERROR);
6537f667e74Sjose borrego }
6542c2961f8Sjose borrego kmem_free(vdb, sizeof (smb_vdb_t));
6557f667e74Sjose borrego
6569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_init(sr, pn, pn->pn_path);
6579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (!smb_pathname_validate(sr, pn))
6589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (SDRC_ERROR);
6599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
6609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_is_stream_name(pn->pn_path)) {
6619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
6629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ERRDOS, ERROR_INVALID_NAME);
6639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (SDRC_ERROR);
6649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
6659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States
6667f667e74Sjose borrego (void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
6677f667e74Sjose borrego
668a90cf9f2SGordon Ross status = smb_odir_openpath(sr, pn->pn_path, sattr, 0, &od);
669a90cf9f2SGordon Ross if (status != 0) {
670a90cf9f2SGordon Ross smbsr_error(sr, status, 0, 0);
6717f667e74Sjose borrego return (SDRC_ERROR);
672a90cf9f2SGordon Ross }
6737f667e74Sjose borrego if (od == NULL)
6747f667e74Sjose borrego return (SDRC_ERROR);
6757f667e74Sjose borrego
6767f667e74Sjose borrego rc = 0;
6777f667e74Sjose borrego count = 0;
6787f667e74Sjose borrego index = 0;
6797f667e74Sjose borrego if (maxcount > SMB_MAX_SEARCH)
6807f667e74Sjose borrego maxcount = SMB_MAX_SEARCH;
6817f667e74Sjose borrego
6827f667e74Sjose borrego while (count < maxcount) {
6837f667e74Sjose borrego rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
684bfbce3c1SGordon Ross if (rc != 0 || eos != 0)
6857f667e74Sjose borrego break;
6867f667e74Sjose borrego
687743a77edSAlan Wright if (*fileinfo.fi_shortname == '\0') {
688cb174861Sjoyce mcintosh if (smb_needs_mangled(fileinfo.fi_name))
689cb174861Sjoyce mcintosh continue;
690148c5f43SAlan Wright (void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
691743a77edSAlan Wright SMB_SHORTNAMELEN - 1);
6927f667e74Sjose borrego }
693148c5f43SAlan Wright smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
6947f667e74Sjose borrego
695148c5f43SAlan Wright (void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
696*d2488fe8SGordon Ross resume_char, name83, index, od->d_odid, client_key,
697*d2488fe8SGordon Ross fileinfo.fi_dosattr & 0xff,
698e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
6997f667e74Sjose borrego (int32_t)fileinfo.fi_size,
700148c5f43SAlan Wright fileinfo.fi_shortname);
7017f667e74Sjose borrego
7027f667e74Sjose borrego count++;
7037f667e74Sjose borrego index++;
7047f667e74Sjose borrego }
705a90cf9f2SGordon Ross if (eos && rc == ENOENT)
706a90cf9f2SGordon Ross rc = 0;
7077f667e74Sjose borrego
7087f667e74Sjose borrego smb_odir_close(od);
709a1511e6bSjoyce mcintosh smb_odir_release(od);
7107f667e74Sjose borrego
7117f667e74Sjose borrego if (rc != 0)
7127f667e74Sjose borrego return (SDRC_ERROR);
7137f667e74Sjose borrego
7147f667e74Sjose borrego if (count == 0) {
7157f667e74Sjose borrego smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
7167f667e74Sjose borrego ERRDOS, ERROR_NO_MORE_FILES);
7177f667e74Sjose borrego return (SDRC_ERROR);
7187f667e74Sjose borrego }
7197f667e74Sjose borrego
7207f667e74Sjose borrego rc = (MBC_LENGTH(&sr->reply) - sr->cur_reply_offset) - 8;
7217f667e74Sjose borrego if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset,
7227f667e74Sjose borrego "bwwbw", 1, count, rc+3, 5, rc) < 0) {
7237f667e74Sjose borrego return (SDRC_ERROR);
7247f667e74Sjose borrego }
7257f667e74Sjose borrego
726faa1795aSjb150015 return (SDRC_SUCCESS);
727da6c28aaSamw }
728148c5f43SAlan Wright
729148c5f43SAlan Wright /*
730148c5f43SAlan Wright * smb_name83
731148c5f43SAlan Wright *
732148c5f43SAlan Wright * Format the filename for inclusion in the resume key. The filename
733148c5f43SAlan Wright * returned in the resume key is 11 bytes:
734148c5f43SAlan Wright * - up to 8 bytes of filename, space padded to 8 bytes
735148c5f43SAlan Wright * - up to 3 bytes of ext, space padded to 3 bytes
736148c5f43SAlan Wright *
737148c5f43SAlan Wright * The name passed to smb_name83 should be a shortname or a name that
738148c5f43SAlan Wright * doesn't require mangling.
739148c5f43SAlan Wright *
740148c5f43SAlan Wright * Examples:
741148c5f43SAlan Wright * "fname.txt" -> "FNAME TXT"
742148c5f43SAlan Wright * "fname.tx" -> "FNAME TX "
743148c5f43SAlan Wright * "filename" -> "FILENAME "
744148c5f43SAlan Wright * "filename.txt" -> "FILENAMETXT"
745148c5f43SAlan Wright * "FILE~1.TXT" -> "FILE~1 TXT"
746148c5f43SAlan Wright */
747148c5f43SAlan Wright static void
smb_name83(const char * name,char * buf,size_t buflen)748148c5f43SAlan Wright smb_name83(const char *name, char *buf, size_t buflen)
749148c5f43SAlan Wright {
750148c5f43SAlan Wright const char *p;
751148c5f43SAlan Wright char *pbuf;
752148c5f43SAlan Wright int i;
753148c5f43SAlan Wright
754148c5f43SAlan Wright ASSERT(name && buf && (buflen >= SMB_NAME83_BUFLEN));
755148c5f43SAlan Wright
756148c5f43SAlan Wright (void) strlcpy(buf, " ", SMB_NAME83_BUFLEN);
757148c5f43SAlan Wright
758148c5f43SAlan Wright /* Process "." and ".." up front */
759148c5f43SAlan Wright if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) {
760148c5f43SAlan Wright (void) strncpy(buf, name, strlen(name));
761148c5f43SAlan Wright return;
762148c5f43SAlan Wright }
763148c5f43SAlan Wright
764148c5f43SAlan Wright ASSERT(smb_needs_mangled(name) == B_FALSE);
765148c5f43SAlan Wright
766148c5f43SAlan Wright /* Process basename */
767148c5f43SAlan Wright for (i = 0, p = name, pbuf = buf;
768148c5f43SAlan Wright (i < SMB_NAME83_BASELEN) && (*p != '\0') && (*p != '.'); ++i)
769148c5f43SAlan Wright *pbuf++ = *p++;
770148c5f43SAlan Wright
771148c5f43SAlan Wright /* Process the extension from the last dot in name */
772148c5f43SAlan Wright if ((p = strchr(name, '.')) != NULL) {
773148c5f43SAlan Wright ++p;
774148c5f43SAlan Wright pbuf = &buf[SMB_NAME83_BASELEN];
775148c5f43SAlan Wright for (i = 0; (i < SMB_NAME83_EXTLEN) && (*p != '\0'); ++i)
776148c5f43SAlan Wright *pbuf++ = *p++;
777148c5f43SAlan Wright }
778148c5f43SAlan Wright
779148c5f43SAlan Wright (void) smb_strupr(buf);
780148c5f43SAlan Wright }
781