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