smbstring.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "headers.h"
  10. Rune
  11. smbruneconvert(Rune r, uint32_t flags)
  12. {
  13. if (r >= 'a' && r <= 'z' && (flags & SMB_STRING_UPCASE))
  14. r = toupper(r);
  15. else if (r == '/' && (flags & SMB_STRING_REVPATH))
  16. r = '\\';
  17. else if (r == '\\' && (flags & SMB_STRING_PATH))
  18. r = '/';
  19. else if (r == 0xa0 && (flags & SMB_STRING_REVPATH) && smbglobals.convertspace)
  20. r = ' ';
  21. else if (r == ' ' && (flags & SMB_STRING_PATH) && smbglobals.convertspace)
  22. r = 0xa0;
  23. return r;
  24. }
  25. int
  26. smbucs2len(char *string)
  27. {
  28. return (string ? utflen(string) : 0) * 2 + 2;
  29. }
  30. int
  31. smbstrlen(char *string)
  32. {
  33. return (string ? strlen(string) : 0) + 1;
  34. }
  35. int
  36. smbstringlen(SmbPeerInfo *i, char *string)
  37. {
  38. if (smbglobals.unicode && (i == nil || (i->capabilities & CAP_UNICODE) != 0))
  39. return smbucs2len(string);
  40. return smbstrlen(string);
  41. }
  42. char *
  43. smbstrinline(uint8_t **bdatap, uint8_t *edata)
  44. {
  45. char *p;
  46. uint8_t *np;
  47. np = memchr(*bdatap, 0, edata - *bdatap);
  48. if (np == nil)
  49. return nil;
  50. p = (char *)*bdatap;
  51. *bdatap = np + 1;
  52. return p;
  53. }
  54. char *
  55. smbstrdup(uint8_t **bdatap, uint8_t *edata)
  56. {
  57. char *p;
  58. uint8_t *np;
  59. np = memchr(*bdatap, 0, edata - *bdatap);
  60. if (np == nil)
  61. return nil;
  62. p = smbestrdup((char *)(*bdatap));
  63. *bdatap = np + 1;
  64. return p;
  65. }
  66. char *
  67. smbstringdup(SmbHeader *h, uint8_t *base, uint8_t **bdatap, uint8_t *edata)
  68. {
  69. char *p;
  70. if (h && h->flags2 & SMB_FLAGS2_UNICODE) {
  71. uint8_t *bdata = *bdatap;
  72. uint8_t *savebdata;
  73. Rune r;
  74. int l;
  75. char *q;
  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. int
  99. smbstrnput(uint8_t *buf, uint16_t n, uint16_t maxlen, char *string,
  100. uint16_t size, int upcase)
  101. {
  102. uint8_t *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. p += l;
  117. while (l++ < size)
  118. *p++ = 0;
  119. return size;
  120. }
  121. int
  122. smbstrput(uint32_t flags, uint8_t *buf, uint16_t n, uint16_t maxlen,
  123. char *string)
  124. {
  125. uint8_t *p = buf + n;
  126. int l;
  127. l = string ? strlen(string) : 0;
  128. if (n + l + ((flags & SMB_STRING_UNTERMINATED) == 0 ? 1 : 0) > maxlen)
  129. return 0;
  130. memcpy(p, string, l);
  131. if (flags & (SMB_STRING_UPCASE | SMB_STRING_PATH | SMB_STRING_REVPATH)) {
  132. uint8_t *q;
  133. for (q = p; q < p + l; q++)
  134. if (*q >= 'a' && *q <= 'z' && (flags & SMB_STRING_UPCASE))
  135. *q = toupper(*q);
  136. else if (*q == '/' && (flags & SMB_STRING_REVPATH))
  137. *q = '\\';
  138. else if (*q == '\\' && (flags & SMB_STRING_PATH))
  139. *q = '/';
  140. }
  141. p += l;
  142. if ((flags & SMB_STRING_UNTERMINATED) == 0)
  143. *p++ = 0;
  144. return p - (buf + n);
  145. }
  146. int
  147. smbucs2put(uint32_t flags, uint8_t *buf, uint16_t n, uint16_t maxlen,
  148. char *string)
  149. {
  150. uint8_t *p = buf + n;
  151. int l;
  152. int align;
  153. align = (flags & SMB_STRING_UNALIGNED) == 0 && (n & 1) != 0;
  154. l = string ? utflen(string) * 2 : 0;
  155. if (n + l + ((flags & SMB_STRING_UNTERMINATED) ? 0 : 2) + align > maxlen)
  156. return 0;
  157. if (align)
  158. *p++ = 0;
  159. while (string && *string) {
  160. Rune r;
  161. int i;
  162. i = chartorune(&r, string);
  163. if (flags & SMB_STRING_CONVERT_MASK)
  164. r = smbruneconvert(r, flags);
  165. smbhnputs(p, r);
  166. p += 2;
  167. string += i;
  168. }
  169. if ((flags & SMB_STRING_UNTERMINATED) == 0) {
  170. smbhnputs(p, 0);
  171. p += 2;
  172. }
  173. assert(p <= buf + maxlen);
  174. return p - (buf + n);
  175. }
  176. int
  177. smbstringput(SmbPeerInfo *p, uint32_t flags, uint8_t *buf, uint16_t n,
  178. uint16_t maxlen, char *string)
  179. {
  180. if (flags & SMB_STRING_UNICODE)
  181. return smbucs2put(flags, buf, n, maxlen, string);
  182. if (flags & SMB_STRING_ASCII)
  183. return smbstrput(flags, buf, n, maxlen, string);
  184. if (p && (p->capabilities & CAP_UNICODE) != 0)
  185. return smbucs2put(flags, buf, n, maxlen, string);
  186. return smbstrput(flags, buf, n, maxlen, string);
  187. }
  188. void
  189. smbstringprint(char **p, char *fmt, ...)
  190. {
  191. va_list arg;
  192. if (*p) {
  193. free(*p);
  194. *p = nil;
  195. }
  196. va_start(arg, fmt);
  197. *p = vsmprint(fmt, arg);
  198. va_end(arg);
  199. }