13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 *
|
27 */ 28#include <sys/param.h> 29#include <sys/systm.h> 30#include <sys/kernel.h> 31#include <sys/clock.h> 32#include <sys/malloc.h> 33#include <sys/time.h> 34#include <sys/vnode.h> 35#include <sys/sysctl.h> 36#include <sys/iconv.h> 37 38#include <netsmb/smb.h> 39#include <netsmb/smb_conn.h> 40#include <netsmb/smb_subr.h> 41#include <netsmb/smb_rq.h> 42#include <netsmb/smb_dev.h> 43 44#include <fs/smbfs/smbfs.h> 45#include <fs/smbfs/smbfs_node.h> 46#include <fs/smbfs/smbfs_subr.h> 47 48MALLOC_DEFINE(M_SMBFSDATA, "smbfs_data", "SMBFS private data"); 49 50void 51smb_time_local2server(struct timespec *tsp, int tzoff, u_long *seconds) 52{ 53 *seconds = tsp->tv_sec - tzoff * 60 /*- tz_minuteswest * 60 - 54 (wall_cmos_clock ? adjkerntz : 0)*/; 55} 56 57void 58smb_time_server2local(u_long seconds, int tzoff, struct timespec *tsp) 59{ 60 tsp->tv_sec = seconds + tzoff * 60; 61 /*+ tz_minuteswest * 60 + (wall_cmos_clock ? adjkerntz : 0)*/; 62} 63 64/* 65 * Number of seconds between 1970 and 1601 year 66 */ 67static int64_t DIFF1970TO1601 = 11644473600ULL; 68 69/* 70 * Time from server comes as UTC, so no need to use tz 71 */ 72void 73smb_time_NT2local(int64_t nsec, int tzoff, struct timespec *tsp) 74{ 75 smb_time_server2local(nsec / 10000000 - DIFF1970TO1601, 0, tsp); 76} 77 78void 79smb_time_local2NT(struct timespec *tsp, int tzoff, int64_t *nsec) 80{ 81 u_long seconds; 82 83 smb_time_local2server(tsp, 0, &seconds); 84 *nsec = (((int64_t)(seconds) & ~1) + DIFF1970TO1601) * (int64_t)10000000; 85} 86 87void 88smb_time_unix2dos(struct timespec *tsp, int tzoff, u_int16_t *ddp, 89 u_int16_t *dtp, u_int8_t *dhp) 90{ 91 struct timespec tt; 92 u_long t; 93 94 tt = *tsp; 95 smb_time_local2server(tsp, tzoff, &t); 96 tt.tv_sec = t; 97 timespec2fattime(&tt, 1, ddp, dtp, dhp); 98} 99 100void 101smb_dos2unixtime(u_int dd, u_int dt, u_int dh, int tzoff, 102 struct timespec *tsp) 103{ 104 105 fattime2timespec(dd, dt, dh, 1, tsp); 106 smb_time_server2local(tsp->tv_sec, tzoff, tsp); 107} 108 109static int 110smb_fphelp(struct mbchain *mbp, struct smb_vc *vcp, struct smbnode *np, 111 int caseopt) 112{ 113 struct smbmount *smp= np->n_mount; 114 struct smbnode **npp = smp->sm_npstack; 115 int i, error = 0; 116 117/* simple_lock(&smp->sm_npslock);*/ 118 i = 0; 119 while (np->n_parent) { 120 if (i++ == SMBFS_MAXPATHCOMP) { 121/* simple_unlock(&smp->sm_npslock);*/ 122 return ENAMETOOLONG; 123 } 124 *npp++ = np; 125 if ((np->n_flag & NREFPARENT) == 0) 126 break; 127 np = VTOSMB(np->n_parent); 128 } 129/* if (i == 0) 130 return smb_put_dmem(mbp, vcp, "\\", 2, caseopt);*/ 131 while (i--) { 132 np = *--npp; 133 error = mb_put_uint8(mbp, '\\'); 134 if (error) 135 break; 136 error = smb_put_dmem(mbp, vcp, np->n_name, np->n_nmlen, caseopt); 137 if (error) 138 break; 139 } 140/* simple_unlock(&smp->sm_npslock);*/ 141 return error; 142} 143 144int 145smbfs_fullpath(struct mbchain *mbp, struct smb_vc *vcp, struct smbnode *dnp, 146 const char *name, int nmlen) 147{ 148 int caseopt = SMB_CS_NONE; 149 int error; 150 151 if (SMB_DIALECT(vcp) < SMB_DIALECT_LANMAN1_0) 152 caseopt |= SMB_CS_UPPER; 153 if (dnp != NULL) { 154 error = smb_fphelp(mbp, vcp, dnp, caseopt); 155 if (error) 156 return error; 157 } 158 if (name) { 159 error = mb_put_uint8(mbp, '\\'); 160 if (error) 161 return error; 162 error = smb_put_dmem(mbp, vcp, name, nmlen, caseopt); 163 if (error) 164 return error; 165 } 166 error = mb_put_uint8(mbp, 0); 167 return error; 168} 169 170int 171smbfs_fname_tolocal(struct smb_vc *vcp, char *name, int *nmlen, int caseopt) 172{ 173 int copt = (caseopt == SMB_CS_LOWER ? KICONV_FROM_LOWER : 174 (caseopt == SMB_CS_UPPER ? KICONV_FROM_UPPER : 0)); 175 int error = 0; 176 size_t ilen = *nmlen; 177 size_t olen; 178 char *ibuf = name; 179 char outbuf[SMB_MAXFNAMELEN]; 180 char *obuf = outbuf; 181 182 if (vcp->vc_tolocal) { 183 olen = sizeof(outbuf); 184 bzero(outbuf, sizeof(outbuf)); 185 186 /* 187 error = iconv_conv_case 188 (vcp->vc_tolocal, NULL, NULL, &obuf, &olen, copt); 189 if (error) return error; 190 */ 191 192 error = iconv_conv_case 193 (vcp->vc_tolocal, (const char **)&ibuf, &ilen, &obuf, &olen, copt); 194 if (!error) { 195 *nmlen = sizeof(outbuf) - olen; 196 memcpy(name, outbuf, *nmlen); 197 } 198 } 199 return error; 200}
|