1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
  24  * Copyright (c) 2017 by Delphix. All rights reserved.
  25  */
  26 
  27 #ifndef _SMBSRV_STRING_H
  28 #define _SMBSRV_STRING_H
  29 
  30 #include <sys/types.h>
  31 
  32 #ifdef __cplusplus
  33 extern "C" {
  34 #endif
  35 
  36 #define _smb_between(l, c, u) ((l) <= (c) && (c) <= (u))
  37 
  38 #define smb_isalpha(c)  (smb_islower(c) || smb_isupper(c))
  39 #define smb_isdigit(c)  _smb_between('0', (c), '9')
  40 #define smb_isalnum(c)  (smb_isalpha(c) || smb_isdigit(c))
  41 #define smb_isxdigit(c) (smb_isdigit(c) ||                      \
  42     _smb_between('a', (c), 'f') ||                              \
  43     _smb_between('A', (c), 'F'))
  44 #define smb_isblank(c)  ((c) == ' ' || (c) == '\t')
  45 #define smb_isspace(c)  ((c) == ' ' ||          \
  46             (c) == '\t' ||                      \
  47             (c) == '\n' ||                      \
  48             (c) == '\r' ||                      \
  49             (c) == '\f')
  50 #define smb_isascii(c)  (!((c) &~ 0x7F))
  51 
  52 /* These macros only apply to ASCII */
  53 #define smb_isalpha_ascii(c)    \
  54         (_smb_between('a', (c), 'z') || _smb_between('A', (c), 'Z'))
  55 #define smb_isalnum_ascii(c)    (smb_isalpha_ascii(c) || smb_isdigit(c))
  56 
  57 #define smb_isprint(c)  _smb_between('!', (c), '~')
  58 #define smb_iscntrl(c)  ((((c) >= 0) && ((c) <= 0x1f)) || ((c) == 0x7f))
  59 #define smb_ispunct(c)  (smb_isprint(c) && !smb_isxdigit(c) && !smb_isspace(c))
  60 
  61 /*
  62  * These id's should correspond to oemcpg_table smb_oem.c.
  63  */
  64 typedef enum codepage_id {
  65         OEM_CPG_850 = 0,
  66         OEM_CPG_950,
  67         OEM_CPG_1252,
  68         OEM_CPG_949,
  69         OEM_CPG_936,
  70         OEM_CPG_932,
  71         OEM_CPG_852,
  72         OEM_CPG_1250,
  73         OEM_CPG_1253,
  74         OEM_CPG_737,
  75         OEM_CPG_1254,
  76         OEM_CPG_857,
  77         OEM_CPG_1251,
  78         OEM_CPG_866,
  79         OEM_CPG_1255,
  80         OEM_CPG_862,
  81         OEM_CPG_1256,
  82         OEM_CPG_720
  83 } codepage_id_t;
  84 
  85 /*
  86  * Maximum number of bytes per multi-byte character.
  87  */
  88 #define MTS_MB_CUR_MAX          4
  89 #define MTS_MB_CHAR_MAX         MTS_MB_CUR_MAX
  90 
  91 typedef uint16_t smb_wchar_t;
  92 
  93 /*
  94  * Labels to define whether a code page table entry is an uppercase
  95  * character, a lowercase character or neither. One of these values
  96  * should appear in the ctype field of the code page tables.
  97  */
  98 #define CODEPAGE_ISNONE         0x00
  99 #define CODEPAGE_ISUPPER        0x01
 100 #define CODEPAGE_ISLOWER        0x02
 101 
 102 /*
 103  * The structure of a code page entry. Each code page table will
 104  * consist of an array of 256 codepage entries.
 105  *
 106  * ctype indicates case of the value.
 107  * upper indicates the uppercase equivalent value.
 108  * lower indicates the lowercase equivalent value.
 109  */
 110 typedef struct smb_codepage {
 111         unsigned char ctype;
 112         smb_wchar_t upper;
 113         smb_wchar_t lower;
 114 } smb_codepage_t;
 115 
 116 void smb_codepage_init(void);
 117 void smb_codepage_fini(void);
 118 
 119 int smb_isupper(int);
 120 int smb_islower(int);
 121 uint32_t smb_toupper(uint32_t);
 122 uint32_t smb_tolower(uint32_t);
 123 char *smb_strupr(char *);
 124 char *smb_strlwr(char *);
 125 int smb_isstrupr(const char *);
 126 int smb_isstrlwr(const char *);
 127 int smb_strcasecmp(const char *, const char *, size_t);
 128 
 129 boolean_t smb_match(const char *, const char *, boolean_t);
 130 
 131 size_t smb_mbstowcs(smb_wchar_t *, const char *, size_t);
 132 size_t smb_wcstombs(char *, const smb_wchar_t *, size_t);
 133 int smb_mbtowc(uint32_t *, const char *, size_t);
 134 int smb_wctomb(char *, uint32_t);
 135 
 136 size_t smb_wcequiv_strlen(const char *);
 137 size_t smb_sbequiv_strlen(const char *);
 138 
 139 int smb_oemtombs(char *, const uint8_t *, int);
 140 int smb_mbstooem(uint8_t *, const char *, int);
 141 
 142 size_t ucstooem(char *, const smb_wchar_t *, size_t, uint32_t);
 143 size_t oemtoucs(smb_wchar_t *, const char *, size_t, uint32_t);
 144 
 145 char *strsubst(char *, char, char);
 146 char *strsep(char **, const char *);
 147 char *strcanon(char *, const char *);
 148 
 149 typedef struct smb_unc {
 150         char             *unc_server;
 151         char             *unc_share;
 152         char             *unc_path;
 153         char             *unc_buf;
 154 } smb_unc_t;
 155 
 156 int smb_unc_init(const char *, smb_unc_t *);
 157 void smb_unc_free(smb_unc_t *);
 158 
 159 #ifdef __cplusplus
 160 }
 161 #endif
 162 
 163 #endif  /* _SMBSRV_STRING_H */