smbbuffer.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  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. #define BUFFER 1
  11. #define STRUCT 2
  12. #define PUSHED 4
  13. struct SmbBuffer {
  14. uint8_t *buf;
  15. uint32_t realmaxlen;
  16. uint32_t maxlen;
  17. uint32_t rn;
  18. uint32_t wn;
  19. uint32_t savewn;
  20. int flags;
  21. };
  22. void
  23. smbbufferreset(SmbBuffer *s)
  24. {
  25. if (s == nil)
  26. return;
  27. s->rn = 0;
  28. s->wn = 0;
  29. s->flags &= ~PUSHED;
  30. }
  31. void
  32. smbbuffersetbuf(SmbBuffer *s, void *p, uint32_t maxlen)
  33. {
  34. s->realmaxlen = s->maxlen = maxlen;
  35. if (s->buf) {
  36. if (s->flags & BUFFER)
  37. free(s->buf);
  38. s->buf = nil;
  39. }
  40. s->flags &= ~BUFFER;
  41. if (p)
  42. s->buf = p;
  43. else {
  44. s->buf = smbemalloc(maxlen);
  45. s->flags |= BUFFER;
  46. }
  47. smbbufferreset(s);
  48. }
  49. SmbBuffer *
  50. smbbufferinit(void *base, void *bdata, uint32_t blen)
  51. {
  52. SmbBuffer *b;
  53. b = smbemalloc(sizeof(*b));
  54. b->buf = base;
  55. b->flags = STRUCT;
  56. b->rn = (uint8_t *)bdata - (uint8_t *)base;
  57. b->wn = b->rn + blen;
  58. b->realmaxlen = b->maxlen = b->wn;
  59. return b;
  60. }
  61. int
  62. smbbufferalignl2(SmbBuffer *s, int al2)
  63. {
  64. uint32_t mask, newn;
  65. mask = (1 << al2) - 1;
  66. newn = (s->wn + mask) & ~mask;
  67. if (newn != s->wn) {
  68. if (newn > s->maxlen)
  69. return 0;
  70. s->wn = newn;
  71. }
  72. return 1;
  73. }
  74. int
  75. smbbufferputb(SmbBuffer *s, uint8_t b)
  76. {
  77. if (s->wn >= s->maxlen)
  78. return 0;
  79. s->buf[s->wn++] = b;
  80. return 1;
  81. }
  82. uint32_t
  83. smbbufferspace(SmbBuffer *sess)
  84. {
  85. return sess->maxlen - sess->wn;
  86. }
  87. int
  88. smbbufferoffsetputs(SmbBuffer *sess, uint32_t offset, uint16_t s)
  89. {
  90. if (offset + 2 > sess->wn)
  91. return 0;
  92. smbhnputs(sess->buf + offset, s);
  93. return 1;
  94. }
  95. int
  96. smbbufferputs(SmbBuffer *sess, uint16_t s)
  97. {
  98. if (sess->wn + sizeof(uint16_t) > sess->maxlen)
  99. return 0;
  100. smbhnputs(sess->buf + sess->wn, s);
  101. sess->wn += sizeof(uint16_t);
  102. return 1;
  103. }
  104. int
  105. smbbufferputl(SmbBuffer *s, uint32_t l)
  106. {
  107. if (s->wn + sizeof(uint32_t) > s->maxlen)
  108. return 0;
  109. smbhnputl(s->buf + s->wn, l);
  110. s->wn += sizeof(uint32_t);
  111. return 1;
  112. }
  113. int
  114. smbbufferputv(SmbBuffer *s, int64_t v)
  115. {
  116. if (s->wn + sizeof(int64_t) > s->maxlen)
  117. return 0;
  118. smbhnputv(s->buf + s->wn, v);
  119. s->wn += sizeof(int64_t);
  120. return 1;
  121. }
  122. int
  123. smbbufferputbytes(SmbBuffer *s, void *data, uint32_t datalen)
  124. {
  125. if (s->wn + datalen > s->maxlen)
  126. return 0;
  127. if (data)
  128. memcpy(s->buf + s->wn, data, datalen);
  129. s->wn += datalen;
  130. return 1;
  131. }
  132. int
  133. smbbufferputstring(SmbBuffer *b, SmbPeerInfo *p, uint32_t flags,
  134. char *string)
  135. {
  136. int n = smbstringput(p, flags, b->buf, b->wn, b->maxlen, string);
  137. if (n <= 0)
  138. return 0;
  139. b->wn += n;
  140. return 1;
  141. }
  142. int
  143. smbbufferputstrn(SmbBuffer *s, char *string, int size, int upcase)
  144. {
  145. int n = smbstrnput(s->buf, s->wn, s->maxlen, string, size, upcase);
  146. if (n <= 0)
  147. return 0;
  148. s->wn += n;
  149. return 1;
  150. }
  151. uint32_t
  152. smbbufferwriteoffset(SmbBuffer *s)
  153. {
  154. return s->wn;
  155. }
  156. uint32_t
  157. smbbufferwritemaxoffset(SmbBuffer *s)
  158. {
  159. return s->maxlen;
  160. }
  161. uint32_t
  162. smbbufferreadoffset(SmbBuffer *s)
  163. {
  164. return s->rn;
  165. }
  166. void *
  167. smbbufferreadpointer(SmbBuffer *s)
  168. {
  169. return s->buf + s->rn;
  170. }
  171. void *
  172. smbbufferwritepointer(SmbBuffer *s)
  173. {
  174. return s->buf + s->wn;
  175. }
  176. uint32_t
  177. smbbufferwritespace(SmbBuffer *b)
  178. {
  179. return b->maxlen - b->wn;
  180. }
  181. SmbBuffer *
  182. smbbuffernew(uint32_t maxlen)
  183. {
  184. SmbBuffer *b;
  185. b = smbemalloc(sizeof(SmbBuffer));
  186. b->buf = smbemalloc(maxlen);
  187. b->realmaxlen = b->maxlen = maxlen;
  188. b->rn = 0;
  189. b->wn = 0;
  190. b->flags = STRUCT | BUFFER;
  191. return b;
  192. }
  193. void
  194. smbbufferfree(SmbBuffer **bp)
  195. {
  196. SmbBuffer *b = *bp;
  197. if (b) {
  198. if (b->flags & BUFFER) {
  199. free(b->buf);
  200. b->buf = nil;
  201. b->flags &= ~BUFFER;
  202. }
  203. if (b->flags & STRUCT)
  204. free(b);
  205. *bp = nil;
  206. }
  207. }
  208. uint8_t *
  209. smbbufferbase(SmbBuffer *b)
  210. {
  211. return b->buf;
  212. }
  213. int
  214. smbbuffergetbytes(SmbBuffer *b, void *buf, uint32_t len)
  215. {
  216. if (b->rn + len > b->wn)
  217. return 0;
  218. if (buf)
  219. memcpy(buf, b->buf + b->rn, len);
  220. b->rn += len;
  221. return 1;
  222. }
  223. void
  224. smbbuffersetreadlen(SmbBuffer *b, uint32_t len)
  225. {
  226. b->wn = b->rn + len;
  227. }
  228. int
  229. smbbuffertrimreadlen(SmbBuffer *b, uint32_t len)
  230. {
  231. if (b->rn + len > b->wn)
  232. return 0;
  233. else if (b->rn + len < b->wn)
  234. b->wn = b->rn + len;
  235. return 1;
  236. }
  237. int
  238. smbbuffergets(SmbBuffer *b, uint16_t *sp)
  239. {
  240. if (b->rn + 2 > b->wn)
  241. return 0;
  242. *sp = smbnhgets(b->buf + b->rn);
  243. b->rn += 2;
  244. return 1;
  245. }
  246. int
  247. smbbuffergetstrn(SmbBuffer *b, uint16_t size, char **sp)
  248. {
  249. uint8_t *np;
  250. if (size > b->wn - b->rn)
  251. return 0;
  252. np = memchr(b->buf + b->rn, 0, size);
  253. if (np == nil)
  254. return 0;
  255. *sp = strdup((char *)b->buf + b->rn);
  256. b->rn += size;
  257. return 1;
  258. }
  259. int
  260. smbbuffergetstr(SmbBuffer *b, uint32_t flags, char **sp)
  261. {
  262. int c;
  263. char *p;
  264. uint8_t *np;
  265. np = memchr(b->buf + b->rn, 0, b->wn - b->rn);
  266. if (np == nil)
  267. return 0;
  268. *sp = strdup((char *)b->buf + b->rn);
  269. for (p = *sp; *p != 0; p++) {
  270. c = *p;
  271. if (c >= 'a' && c <= 'z' && (flags & SMB_STRING_UPCASE))
  272. *p = toupper(c);
  273. else if (c == '/' && (flags & SMB_STRING_REVPATH))
  274. *p = '\\';
  275. else if (c == '\\' && (flags & SMB_STRING_PATH))
  276. *p = '/';
  277. else if (smbglobals.convertspace){
  278. if (c == 0xa0 && (flags & SMB_STRING_REVPATH))
  279. *p = ' ';
  280. else if (c == ' ' && (flags & SMB_STRING_PATH))
  281. *p = 0xa0;
  282. }
  283. }
  284. b->rn = np - b->buf + 1;
  285. return 1;
  286. }
  287. int
  288. smbbuffergetstrinline(SmbBuffer *b, char **sp)
  289. {
  290. uint8_t *np;
  291. np = memchr(b->buf + b->rn, 0, b->wn - b->rn);
  292. if (np == nil)
  293. return 0;
  294. *sp = (char *)b->buf + b->rn;
  295. b->rn = np - b->buf + 1;
  296. return 1;
  297. }
  298. int
  299. smbbuffergetucs2(SmbBuffer *b, uint32_t flags, char **sp)
  300. {
  301. uint8_t *bdata = b->buf + b->rn;
  302. uint8_t *edata = b->buf + b->wn;
  303. Rune r;
  304. int l;
  305. char *p, *q;
  306. uint8_t *savebdata;
  307. int first;
  308. l = 0;
  309. if ((flags & SMB_STRING_UNALIGNED) == 0 && (bdata - b->buf) & 1)
  310. bdata++;
  311. savebdata = bdata;
  312. first = 1;
  313. do {
  314. if (bdata + 2 > edata) {
  315. l++;
  316. break;
  317. }
  318. r = smbnhgets(bdata); bdata += 2;
  319. if (first && (flags & SMB_STRING_PATH) && r != '\\')
  320. l++;
  321. first = 0;
  322. if (flags & SMB_STRING_CONVERT_MASK)
  323. r = smbruneconvert(r, flags);
  324. l += runelen(r);
  325. } while (r != 0);
  326. p = smbemalloc(l);
  327. bdata = savebdata;
  328. q = p;
  329. first = 1;
  330. do {
  331. if (bdata + 2 > edata) {
  332. *q = 0;
  333. break;
  334. }
  335. r = smbnhgets(bdata); bdata += 2;
  336. if (first && (flags & SMB_STRING_PATH) && r != '\\')
  337. *q++ = '/';
  338. first = 0;
  339. if (flags & SMB_STRING_CONVERT_MASK)
  340. r = smbruneconvert(r, flags);
  341. q += runetochar(q, &r);
  342. } while (r != 0);
  343. b->rn = bdata - b->buf;
  344. *sp = p;
  345. return 1;
  346. }
  347. int
  348. smbbuffergetstring(SmbBuffer *b, SmbHeader *h, uint32_t flags, char **sp)
  349. {
  350. if (flags & SMB_STRING_UNICODE)
  351. return smbbuffergetucs2(b, flags, sp);
  352. else if (flags & SMB_STRING_ASCII)
  353. return smbbuffergetstr(b, flags, sp);
  354. else if (h->flags2 & SMB_FLAGS2_UNICODE)
  355. return smbbuffergetucs2(b, flags, sp);
  356. else
  357. return smbbuffergetstr(b, flags, sp);
  358. }
  359. void *
  360. smbbufferpointer(SmbBuffer *b, uint32_t offset)
  361. {
  362. return b->buf + offset;
  363. }
  364. int
  365. smbbuffergetb(SmbBuffer *b, uint8_t *bp)
  366. {
  367. if (b->rn < b->wn) {
  368. *bp = b->buf[b->rn++];
  369. return 1;
  370. }
  371. return 0;
  372. }
  373. int
  374. smbbuffergetl(SmbBuffer *b, uint32_t *lp)
  375. {
  376. if (b->rn + 4 <= b->wn) {
  377. *lp = smbnhgetl(b->buf + b->rn);
  378. b->rn += 4;
  379. return 1;
  380. }
  381. return 0;
  382. }
  383. int
  384. smbbuffergetv(SmbBuffer *b, int64_t *vp)
  385. {
  386. if (b->rn + 8 <= b->wn) {
  387. *vp = smbnhgetv(b->buf + b->rn);
  388. b->rn += 8;
  389. return 1;
  390. }
  391. return 0;
  392. }
  393. uint32_t
  394. smbbufferreadspace(SmbBuffer *b)
  395. {
  396. return b->wn - b->rn;
  397. }
  398. void
  399. smbbufferwritelimit(SmbBuffer *b, uint32_t limit)
  400. {
  401. if (b->rn + limit < b->maxlen)
  402. b->maxlen = b->rn + limit;
  403. }
  404. int
  405. smbbufferreadskipto(SmbBuffer *b, uint32_t offset)
  406. {
  407. if (offset < b->rn || offset >= b->wn)
  408. return 0;
  409. b->rn = offset;
  410. return 1;
  411. }
  412. int
  413. smbbufferpushreadlimit(SmbBuffer *b, uint32_t limit)
  414. {
  415. if (b->flags & PUSHED)
  416. return 0;
  417. if (limit > b->wn || limit < b->rn)
  418. return 0;
  419. b->savewn = b->wn;
  420. b->wn = limit;
  421. b->flags |= PUSHED;
  422. return 1;
  423. }
  424. int
  425. smbbufferpopreadlimit(SmbBuffer *b)
  426. {
  427. if ((b->flags & PUSHED) == 0)
  428. return 0;
  429. b->wn = b->savewn;
  430. b->flags &= ~PUSHED;
  431. return 1;
  432. }
  433. int
  434. smbbufferwritebackup(SmbBuffer *b, uint32_t offset)
  435. {
  436. if (offset >= b->rn && offset <= b->wn) {
  437. b->wn = offset;
  438. return 1;
  439. }
  440. return 0;
  441. }
  442. int
  443. smbbufferreadbackup(SmbBuffer *b, uint32_t offset)
  444. {
  445. if (offset <= b->rn) {
  446. b->rn = offset;
  447. return 1;
  448. }
  449. return 0;
  450. }
  451. int
  452. smbbufferfixuprelatives(SmbBuffer *b, uint32_t fixupoffset)
  453. {
  454. uint32_t fixval;
  455. if (fixupoffset < b->rn || fixupoffset > b->wn - 2)
  456. return 0;
  457. fixval = b->wn - fixupoffset - 2;
  458. if (fixval > 65535)
  459. return 0;
  460. smbhnputs(b->buf + fixupoffset, fixval);
  461. return 1;
  462. }
  463. int
  464. smbbufferfixuprelativel(SmbBuffer *b, uint32_t fixupoffset)
  465. {
  466. uint32_t fixval;
  467. if (fixupoffset < b->rn || fixupoffset > b->wn - 4)
  468. return 0;
  469. fixval = b->wn - fixupoffset - 4;
  470. smbhnputl(b->buf + fixupoffset, fixval);
  471. return 1;
  472. }
  473. int
  474. smbbufferfixupabsolutes(SmbBuffer *b, uint32_t fixupoffset)
  475. {
  476. if (fixupoffset < b->rn || fixupoffset > b->wn - 2)
  477. return 0;
  478. if (b->wn > 65535)
  479. return 0;
  480. smbhnputs(b->buf + fixupoffset, b->wn);
  481. return 1;
  482. }
  483. int
  484. smbbufferfixupl(SmbBuffer *b, uint32_t fixupoffset, uint32_t fixupval)
  485. {
  486. if (fixupoffset < b->rn || fixupoffset > b->wn - 4)
  487. return 0;
  488. smbhnputl(b->buf + fixupoffset, fixupval);
  489. return 1;
  490. }
  491. int
  492. smbbufferfixupabsolutel(SmbBuffer *b, uint32_t fixupoffset)
  493. {
  494. if (fixupoffset < b->rn || fixupoffset > b->wn - 2)
  495. return 0;
  496. smbhnputl(b->buf + fixupoffset, b->wn);
  497. return 1;
  498. }
  499. int
  500. smbbufferfixuprelativeinclusivel(SmbBuffer *b, uint32_t fixupoffset)
  501. {
  502. if (fixupoffset < b->rn || fixupoffset > b->wn - 4)
  503. return 0;
  504. smbhnputl(b->buf + fixupoffset, b->wn - fixupoffset);
  505. return 1;
  506. }
  507. int
  508. smbbufferfill(SmbBuffer *b, uint8_t val, uint32_t len)
  509. {
  510. if (b->maxlen - b->wn < len)
  511. return 0;
  512. memset(b->buf + b->wn, val, len);
  513. b->wn += len;
  514. return 1;
  515. }
  516. int
  517. smbbufferoffsetgetb(SmbBuffer *b, uint32_t offset, uint8_t *bp)
  518. {
  519. if (offset >= b->rn && offset + 1 <= b->wn) {
  520. *bp = b->buf[b->rn + offset];
  521. return 1;
  522. }
  523. return 0;
  524. }
  525. int
  526. smbbuffercopy(SmbBuffer *to, SmbBuffer *from, uint32_t amount)
  527. {
  528. if (smbbufferreadspace(from) < amount)
  529. return 0;
  530. if (smbbufferputbytes(to, smbbufferreadpointer(from), amount)) {
  531. assert(smbbuffergetbytes(from, nil, amount));
  532. return 1;
  533. }
  534. return 0;
  535. }
  536. int
  537. smbbufferoffsetcopystr(SmbBuffer *b, uint32_t offset, char *buf,
  538. int buflen,
  539. int *lenp)
  540. {
  541. uint8_t *np;
  542. if (offset < b->rn || offset >= b->wn)
  543. return 0;
  544. np = memchr(b->buf + offset, 0, b->wn - offset);
  545. if (np == nil)
  546. return 0;
  547. *lenp = np - (b->buf + offset) + 1;
  548. if (*lenp > buflen)
  549. return 0;
  550. memcpy(buf, b->buf + offset, *lenp);
  551. return 1;
  552. }