smbstring.c 4.1 KB

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