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