smbtrans2set.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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. SmbProcessResult
  11. smbtrans2setfileinformation(SmbSession *s, SmbHeader *h)
  12. {
  13. SmbTree *t;
  14. uint16_t infolevel;
  15. SmbBuffer *b;
  16. SmbProcessResult pr;
  17. uint16_t fid;
  18. SmbFile *f;
  19. int64_t newsize;
  20. uint64_t atime, mtime;
  21. uint32_t attr;
  22. uint32_t mode;
  23. t = smbidmapfind(s->tidmap, h->tid);
  24. if (t == nil) {
  25. smbseterror(s, ERRSRV, ERRinvtid);
  26. pr = SmbProcessResultError;
  27. goto done;
  28. }
  29. b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
  30. if (!smbbuffergets(b, &fid) || !smbbuffergets(b, &infolevel)) {
  31. misc:
  32. pr = SmbProcessResultMisc;
  33. goto done;
  34. }
  35. f = smbidmapfind(s->fidmap, fid);
  36. if (f == nil) {
  37. smbseterror(s, ERRDOS, ERRbadfid);
  38. pr = SmbProcessResultError;
  39. goto done;
  40. }
  41. switch (infolevel) {
  42. case SMB_SET_FILE_ALLOCATION_INFO:
  43. case SMB_SET_FILE_END_OF_FILE_INFO:
  44. if (s->transaction.in.tdcount < 8)
  45. goto misc;
  46. newsize = smbnhgetv(s->transaction.in.data);
  47. pr = smbtruncatefile(s, f, newsize);
  48. if (pr == SmbProcessResultReply && !smbbufferputs(s->transaction.out.parameters, 0))
  49. goto misc;
  50. break;
  51. case SMB_SET_FILE_BASIC_INFO:
  52. if (s->transaction.in.tdcount < 4 * 8 + 4)
  53. goto misc;
  54. atime = smbnhgetv(s->transaction.in.data + 8);
  55. mtime = smbnhgetv(s->transaction.in.data + 24);
  56. attr = smbnhgetv(s->transaction.in.data + 32);
  57. if (attr) {
  58. Dir *od = dirfstat(f->fd);
  59. if (od == nil)
  60. goto noaccess;
  61. mode = smbdosattr2plan9wstatmode(od->mode, attr);
  62. free(od);
  63. }
  64. else
  65. mode = 0xffffffff;
  66. if (atime || mtime || mode != 0xffffffff) {
  67. Dir d;
  68. memset(&d, 0xff, sizeof(d));
  69. d.name = d.uid = d.gid = d.muid = nil;
  70. if (atime)
  71. d.atime = smbtime2plan9time(atime);
  72. if (mtime)
  73. d.mtime = smbtime2plan9time(mtime);
  74. d.mode = mode;
  75. if (dirfwstat(f->fd, &d) < 0) {
  76. noaccess:
  77. smbseterror(s, ERRDOS, ERRnoaccess);
  78. pr = SmbProcessResultError;
  79. goto done;
  80. }
  81. }
  82. if (!smbbufferputs(s->transaction.out.parameters, 0))
  83. goto misc;
  84. pr = SmbProcessResultReply;
  85. break;
  86. case SMB_SET_FILE_DISPOSITION_INFO:
  87. if (s->transaction.in.tdcount < 1)
  88. goto misc;
  89. f->sf->deleteonclose = *s->transaction.in.data;
  90. if (!smbbufferputs(s->transaction.out.parameters, 0))
  91. goto misc;
  92. pr = SmbProcessResultReply;
  93. break;
  94. default:
  95. smblogprint(-1, "smbtrans2setfileinformation: infolevel 0x%.4x not implemented\n", infolevel);
  96. smbseterror(s, ERRDOS, ERRunknownlevel);
  97. pr = SmbProcessResultError;
  98. break;
  99. }
  100. done:
  101. smbbufferfree(&b);
  102. return pr;
  103. }
  104. SmbProcessResult
  105. smbtrans2setpathinformation(SmbSession *s, SmbHeader *h)
  106. {
  107. char *fullpath, *path;
  108. SmbTree *t;
  109. uint16_t infolevel;
  110. SmbBuffer *b;
  111. SmbProcessResult pr;
  112. uint16_t atime, adate, mtime, mdate;
  113. uint32_t attr;
  114. uint32_t mode;
  115. uint32_t size;
  116. // uint64_t length;
  117. t = smbidmapfind(s->tidmap, h->tid);
  118. if (t == nil) {
  119. smbseterror(s, ERRSRV, ERRinvtid);
  120. pr = SmbProcessResultError;
  121. goto done;
  122. }
  123. b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
  124. path = nil;
  125. if (!smbbuffergets(b, &infolevel) || !smbbuffergetbytes(b, nil, 4)
  126. || !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) {
  127. misc:
  128. pr = SmbProcessResultMisc;
  129. goto done;
  130. }
  131. fullpath = nil;
  132. smbstringprint(&fullpath, "%s%s", t->serv->path, path);
  133. translogprint(s->transaction.in.setup[0], "path %s\n", path);
  134. translogprint(s->transaction.in.setup[0], "infolevel 0x%.4x\n", infolevel);
  135. translogprint(s->transaction.in.setup[0], "fullpath %s\n", fullpath);
  136. switch (infolevel) {
  137. case SMB_INFO_STANDARD:
  138. if (s->transaction.in.tdcount < 6 * 4 + 2 * 2)
  139. goto misc;
  140. adate = smbnhgets(s->transaction.in.data + 6);
  141. atime = smbnhgets(s->transaction.in.data + 4);
  142. mdate = smbnhgets(s->transaction.in.data + 10);
  143. mtime = smbnhgets(s->transaction.in.data + 8);
  144. size = smbnhgetl(s->transaction.in.data + 12);
  145. attr = smbnhgets(s->transaction.in.data + 20);
  146. if (attr) {
  147. Dir *od = dirstat(fullpath);
  148. if (od == nil)
  149. goto noaccess;
  150. mode = smbdosattr2plan9wstatmode(od->mode, attr);
  151. free(od);
  152. }
  153. else
  154. mode = 0xffffffff;
  155. translogprint(s->transaction.in.setup[0], "mode 0%od\n", mode);
  156. // if (size)
  157. // length = size;
  158. // else
  159. // length = ~0LL;
  160. translogprint(s->transaction.in.setup[0], "size %lld\n", size);
  161. translogprint(s->transaction.in.setup[0], "adate %d atime %d", adate, atime);
  162. translogprint(s->transaction.in.setup[0], "mdate %d mtime %d\n", mdate, mtime);
  163. if (size || adate || atime || mdate || mtime || mode != 0xffffffff) {
  164. Dir d;
  165. memset(&d, 0xff, sizeof(d));
  166. d.name = d.uid = d.gid = d.muid = nil;
  167. if (adate || atime)
  168. d.atime = smbdatetime2plan9time(adate, atime, s->tzoff);
  169. if (mdate || mtime)
  170. d.mtime = smbdatetime2plan9time(mdate, mtime, s->tzoff);
  171. d.mode = mode;
  172. d.length = size;
  173. if (dirwstat(fullpath, &d) < 0) {
  174. noaccess:
  175. smbseterror(s, ERRDOS, ERRnoaccess);
  176. pr = SmbProcessResultError;
  177. goto done;
  178. }
  179. }
  180. if (!smbbufferputs(s->transaction.out.parameters, 0))
  181. goto misc;
  182. pr = SmbProcessResultReply;
  183. break;
  184. default:
  185. smblogprint(-1, "smbtrans2setpathinformation: infolevel 0x%.4x not implemented\n", infolevel);
  186. smbseterror(s, ERRDOS, ERRunknownlevel);
  187. pr = SmbProcessResultError;
  188. break;
  189. }
  190. done:
  191. smbbufferfree(&b);
  192. return pr;
  193. }