xref: /plan9/sys/src/cmd/aquarela/smbstring.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include "headers.h"
2*8ccd4a63SDavid du Colombier 
3*8ccd4a63SDavid du Colombier Rune
smbruneconvert(Rune r,ulong flags)4*8ccd4a63SDavid du Colombier smbruneconvert(Rune r, ulong flags)
5*8ccd4a63SDavid du Colombier {
6*8ccd4a63SDavid du Colombier 	if (r >= 'a' && r <= 'z' && (flags & SMB_STRING_UPCASE))
7*8ccd4a63SDavid du Colombier 		r = toupper(r);
8*8ccd4a63SDavid du Colombier 	else if (r == '/' && (flags & SMB_STRING_REVPATH))
9*8ccd4a63SDavid du Colombier 		r = '\\';
10*8ccd4a63SDavid du Colombier 	else if (r == '\\' && (flags & SMB_STRING_PATH))
11*8ccd4a63SDavid du Colombier 		r = '/';
12*8ccd4a63SDavid du Colombier 	else if (r == 0xa0 && (flags & SMB_STRING_REVPATH) && smbglobals.convertspace)
13*8ccd4a63SDavid du Colombier 		r = ' ';
14*8ccd4a63SDavid du Colombier 	else if (r == ' ' && (flags & SMB_STRING_PATH) && smbglobals.convertspace)
15*8ccd4a63SDavid du Colombier 		r = 0xa0;
16*8ccd4a63SDavid du Colombier 	return r;
17*8ccd4a63SDavid du Colombier }
18*8ccd4a63SDavid du Colombier 
19*8ccd4a63SDavid du Colombier int
smbucs2len(char * string)20*8ccd4a63SDavid du Colombier smbucs2len(char *string)
21*8ccd4a63SDavid du Colombier {
22*8ccd4a63SDavid du Colombier 	return (string ? utflen(string) : 0) * 2 + 2;
23*8ccd4a63SDavid du Colombier }
24*8ccd4a63SDavid du Colombier 
25*8ccd4a63SDavid du Colombier int
smbstrlen(char * string)26*8ccd4a63SDavid du Colombier smbstrlen(char *string)
27*8ccd4a63SDavid du Colombier {
28*8ccd4a63SDavid du Colombier 	return (string ? strlen(string) : 0) + 1;
29*8ccd4a63SDavid du Colombier }
30*8ccd4a63SDavid du Colombier 
31*8ccd4a63SDavid du Colombier int
smbstringlen(SmbPeerInfo * i,char * string)32*8ccd4a63SDavid du Colombier smbstringlen(SmbPeerInfo *i, char *string)
33*8ccd4a63SDavid du Colombier {
34*8ccd4a63SDavid du Colombier 	if (smbglobals.unicode && (i == nil || (i->capabilities & CAP_UNICODE) != 0))
35*8ccd4a63SDavid du Colombier 		return smbucs2len(string);
36*8ccd4a63SDavid du Colombier 	return  smbstrlen(string);
37*8ccd4a63SDavid du Colombier }
38*8ccd4a63SDavid du Colombier 
39*8ccd4a63SDavid du Colombier char *
smbstrinline(uchar ** bdatap,uchar * edata)40*8ccd4a63SDavid du Colombier smbstrinline(uchar **bdatap, uchar *edata)
41*8ccd4a63SDavid du Colombier {
42*8ccd4a63SDavid du Colombier 	char *p;
43*8ccd4a63SDavid du Colombier 	uchar *np;
44*8ccd4a63SDavid du Colombier 	np = memchr(*bdatap, 0, edata - *bdatap);
45*8ccd4a63SDavid du Colombier 	if (np == nil)
46*8ccd4a63SDavid du Colombier 		return nil;
47*8ccd4a63SDavid du Colombier 	p = (char *)*bdatap;
48*8ccd4a63SDavid du Colombier 	*bdatap = np + 1;
49*8ccd4a63SDavid du Colombier 	return p;
50*8ccd4a63SDavid du Colombier }
51*8ccd4a63SDavid du Colombier 
52*8ccd4a63SDavid du Colombier char *
smbstrdup(uchar ** bdatap,uchar * edata)53*8ccd4a63SDavid du Colombier smbstrdup(uchar **bdatap, uchar *edata)
54*8ccd4a63SDavid du Colombier {
55*8ccd4a63SDavid du Colombier 	char *p;
56*8ccd4a63SDavid du Colombier 	uchar *np;
57*8ccd4a63SDavid du Colombier 	np = memchr(*bdatap, 0, edata - *bdatap);
58*8ccd4a63SDavid du Colombier 	if (np == nil)
59*8ccd4a63SDavid du Colombier 		return nil;
60*8ccd4a63SDavid du Colombier 	p = smbestrdup((char *)(*bdatap));
61*8ccd4a63SDavid du Colombier 	*bdatap = np + 1;
62*8ccd4a63SDavid du Colombier 	return p;
63*8ccd4a63SDavid du Colombier }
64*8ccd4a63SDavid du Colombier 
65*8ccd4a63SDavid du Colombier char *
smbstringdup(SmbHeader * h,uchar * base,uchar ** bdatap,uchar * edata)66*8ccd4a63SDavid du Colombier smbstringdup(SmbHeader *h, uchar *base, uchar **bdatap, uchar *edata)
67*8ccd4a63SDavid du Colombier {
68*8ccd4a63SDavid du Colombier 	char *p;
69*8ccd4a63SDavid du Colombier 	if (h && h->flags2 & SMB_FLAGS2_UNICODE) {
70*8ccd4a63SDavid du Colombier 		uchar *bdata = *bdatap;
71*8ccd4a63SDavid du Colombier 		uchar *savebdata;
72*8ccd4a63SDavid du Colombier 		Rune r;
73*8ccd4a63SDavid du Colombier 		int l;
74*8ccd4a63SDavid du Colombier 		char *q;
75*8ccd4a63SDavid du Colombier 
76*8ccd4a63SDavid du Colombier 		l = 0;
77*8ccd4a63SDavid du Colombier 		if ((bdata - base) & 1)
78*8ccd4a63SDavid du Colombier 			bdata++;
79*8ccd4a63SDavid du Colombier 		savebdata = bdata;
80*8ccd4a63SDavid du Colombier 		do {
81*8ccd4a63SDavid du Colombier 			if (bdata + 2 > edata)
82*8ccd4a63SDavid du Colombier 				return nil;
83*8ccd4a63SDavid du Colombier 			r = smbnhgets(bdata); bdata += 2;
84*8ccd4a63SDavid du Colombier 			l += runelen(r);
85*8ccd4a63SDavid du Colombier 		} while (r != 0);
86*8ccd4a63SDavid du Colombier 		p = smbemalloc(l);
87*8ccd4a63SDavid du Colombier 		bdata = savebdata;
88*8ccd4a63SDavid du Colombier 		q = p;
89*8ccd4a63SDavid du Colombier 		do {
90*8ccd4a63SDavid du Colombier 			r = smbnhgets(bdata); bdata += 2;
91*8ccd4a63SDavid du Colombier 			q += runetochar(q, &r);
92*8ccd4a63SDavid du Colombier 		} while (r != 0);
93*8ccd4a63SDavid du Colombier 		*bdatap = bdata;
94*8ccd4a63SDavid du Colombier 		return p;
95*8ccd4a63SDavid du Colombier 	}
96*8ccd4a63SDavid du Colombier 	return smbstrdup(bdatap, edata);
97*8ccd4a63SDavid du Colombier }
98*8ccd4a63SDavid du Colombier 
99*8ccd4a63SDavid du Colombier int
smbstrnput(uchar * buf,ushort n,ushort maxlen,char * string,ushort size,int upcase)100*8ccd4a63SDavid du Colombier smbstrnput(uchar *buf, ushort n, ushort maxlen, char *string, ushort size, int upcase)
101*8ccd4a63SDavid du Colombier {
102*8ccd4a63SDavid du Colombier 	uchar *p = buf + n;
103*8ccd4a63SDavid du Colombier 	int l;
104*8ccd4a63SDavid du Colombier 	l = strlen(string);
105*8ccd4a63SDavid du Colombier 	if (l + 1 > size)
106*8ccd4a63SDavid du Colombier 		l = size - 1;
107*8ccd4a63SDavid du Colombier 	if (n + l + 1 > maxlen)
108*8ccd4a63SDavid du Colombier 		return 0;
109*8ccd4a63SDavid du Colombier 	if (upcase) {
110*8ccd4a63SDavid du Colombier 		int x;
111*8ccd4a63SDavid du Colombier 		for (x = 0; x < l; x++)
112*8ccd4a63SDavid du Colombier 			p[x] = toupper(string[x]);
113*8ccd4a63SDavid du Colombier 	}
114*8ccd4a63SDavid du Colombier 	else
115*8ccd4a63SDavid du Colombier 		memcpy(p, string, l);
116*8ccd4a63SDavid du Colombier 
117*8ccd4a63SDavid du Colombier 	p += l;
118*8ccd4a63SDavid du Colombier 	while (l++ < size)
119*8ccd4a63SDavid du Colombier 		*p++ = 0;
120*8ccd4a63SDavid du Colombier 	return size;
121*8ccd4a63SDavid du Colombier }
122*8ccd4a63SDavid du Colombier 
123*8ccd4a63SDavid du Colombier int
smbstrput(ulong flags,uchar * buf,ushort n,ushort maxlen,char * string)124*8ccd4a63SDavid du Colombier smbstrput(ulong flags, uchar *buf, ushort n, ushort maxlen, char *string)
125*8ccd4a63SDavid du Colombier {
126*8ccd4a63SDavid du Colombier 	uchar *p = buf + n;
127*8ccd4a63SDavid du Colombier 	int l;
128*8ccd4a63SDavid du Colombier 	l = string ? strlen(string) : 0;
129*8ccd4a63SDavid du Colombier 	if (n + l + ((flags & SMB_STRING_UNTERMINATED) == 0 ? 1 : 0) > maxlen)
130*8ccd4a63SDavid du Colombier 		return 0;
131*8ccd4a63SDavid du Colombier 	memcpy(p, string, l);
132*8ccd4a63SDavid du Colombier 	if (flags & (SMB_STRING_UPCASE | SMB_STRING_PATH | SMB_STRING_REVPATH)) {
133*8ccd4a63SDavid du Colombier 		uchar *q;
134*8ccd4a63SDavid du Colombier 		for (q = p; q < p + l; q++)
135*8ccd4a63SDavid du Colombier 			if (*q >= 'a' && *q <= 'z' && (flags & SMB_STRING_UPCASE))
136*8ccd4a63SDavid du Colombier 				*q = toupper(*q);
137*8ccd4a63SDavid du Colombier 			else if (*q == '/' && (flags & SMB_STRING_REVPATH))
138*8ccd4a63SDavid du Colombier 				*q = '\\';
139*8ccd4a63SDavid du Colombier 			else if (*q == '\\' && (flags & SMB_STRING_PATH))
140*8ccd4a63SDavid du Colombier 				*q = '/';
141*8ccd4a63SDavid du Colombier 	}
142*8ccd4a63SDavid du Colombier 	p += l;
143*8ccd4a63SDavid du Colombier 	if ((flags & SMB_STRING_UNTERMINATED) == 0)
144*8ccd4a63SDavid du Colombier 		*p++ = 0;
145*8ccd4a63SDavid du Colombier 	return p - (buf + n);
146*8ccd4a63SDavid du Colombier }
147*8ccd4a63SDavid du Colombier 
148*8ccd4a63SDavid du Colombier int
smbucs2put(ulong flags,uchar * buf,ushort n,ushort maxlen,char * string)149*8ccd4a63SDavid du Colombier smbucs2put(ulong flags, uchar *buf, ushort n, ushort maxlen, char *string)
150*8ccd4a63SDavid du Colombier {
151*8ccd4a63SDavid du Colombier 	uchar *p = buf + n;
152*8ccd4a63SDavid du Colombier 	int l;
153*8ccd4a63SDavid du Colombier 	int align;
154*8ccd4a63SDavid du Colombier 	align = (flags & SMB_STRING_UNALIGNED) == 0 && (n & 1) != 0;
155*8ccd4a63SDavid du Colombier 	l = string ? utflen(string) * 2 : 0;
156*8ccd4a63SDavid du Colombier 	if (n + l + ((flags & SMB_STRING_UNTERMINATED) ? 0 : 2) + align > maxlen)
157*8ccd4a63SDavid du Colombier 		return 0;
158*8ccd4a63SDavid du Colombier 	if (align)
159*8ccd4a63SDavid du Colombier 		*p++ = 0;
160*8ccd4a63SDavid du Colombier 	while (string && *string) {
161*8ccd4a63SDavid du Colombier 		Rune r;
162*8ccd4a63SDavid du Colombier 		int i;
163*8ccd4a63SDavid du Colombier 		i = chartorune(&r, string);
164*8ccd4a63SDavid du Colombier 		if (flags & SMB_STRING_CONVERT_MASK)
165*8ccd4a63SDavid du Colombier 			r = smbruneconvert(r, flags);
166*8ccd4a63SDavid du Colombier 		smbhnputs(p, r);
167*8ccd4a63SDavid du Colombier 		p += 2;
168*8ccd4a63SDavid du Colombier 		string += i;
169*8ccd4a63SDavid du Colombier 	}
170*8ccd4a63SDavid du Colombier 	if ((flags & SMB_STRING_UNTERMINATED) == 0) {
171*8ccd4a63SDavid du Colombier 		smbhnputs(p, 0);
172*8ccd4a63SDavid du Colombier 		p += 2;
173*8ccd4a63SDavid du Colombier 	}
174*8ccd4a63SDavid du Colombier 	assert(p <= buf + maxlen);
175*8ccd4a63SDavid du Colombier 	return p - (buf + n);
176*8ccd4a63SDavid du Colombier }
177*8ccd4a63SDavid du Colombier 
178*8ccd4a63SDavid du Colombier int
smbstringput(SmbPeerInfo * p,ulong flags,uchar * buf,ushort n,ushort maxlen,char * string)179*8ccd4a63SDavid du Colombier smbstringput(SmbPeerInfo *p, ulong flags, uchar *buf, ushort n, ushort maxlen, char *string)
180*8ccd4a63SDavid du Colombier {
181*8ccd4a63SDavid du Colombier 	if (flags & SMB_STRING_UNICODE)
182*8ccd4a63SDavid du Colombier 		return smbucs2put(flags, buf, n, maxlen, string);
183*8ccd4a63SDavid du Colombier 	if (flags & SMB_STRING_ASCII)
184*8ccd4a63SDavid du Colombier 		return smbstrput(flags, buf, n, maxlen, string);
185*8ccd4a63SDavid du Colombier 	if (p && (p->capabilities & CAP_UNICODE) != 0)
186*8ccd4a63SDavid du Colombier 		return smbucs2put(flags, buf, n, maxlen, string);
187*8ccd4a63SDavid du Colombier 	return smbstrput(flags, buf, n, maxlen, string);
188*8ccd4a63SDavid du Colombier }
189*8ccd4a63SDavid du Colombier 
190*8ccd4a63SDavid du Colombier void
smbstringprint(char ** p,char * fmt,...)191*8ccd4a63SDavid du Colombier smbstringprint(char **p, char *fmt, ...)
192*8ccd4a63SDavid du Colombier {
193*8ccd4a63SDavid du Colombier 	va_list arg;
194*8ccd4a63SDavid du Colombier 	if (*p) {
195*8ccd4a63SDavid du Colombier 		free(*p);
196*8ccd4a63SDavid du Colombier 		*p = nil;
197*8ccd4a63SDavid du Colombier 	}
198*8ccd4a63SDavid du Colombier 	va_start(arg, fmt);
199*8ccd4a63SDavid du Colombier 	*p = vsmprint(fmt, arg);
200*8ccd4a63SDavid du Colombier 	va_end(arg);
201*8ccd4a63SDavid du Colombier }
202