smbtrans2set.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "headers.h"
  2. SmbProcessResult
  3. smbtrans2setfileinformation(SmbSession *s, SmbHeader *h)
  4. {
  5. SmbTree *t;
  6. ushort infolevel;
  7. SmbBuffer *b;
  8. SmbProcessResult pr;
  9. ushort fid;
  10. SmbFile *f;
  11. vlong newsize;
  12. uvlong atime, mtime;
  13. ulong attr;
  14. ulong mode;
  15. t = smbidmapfind(s->tidmap, h->tid);
  16. if (t == nil) {
  17. smbseterror(s, ERRSRV, ERRinvtid);
  18. pr = SmbProcessResultError;
  19. goto done;
  20. }
  21. b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
  22. if (!smbbuffergets(b, &fid) || !smbbuffergets(b, &infolevel)) {
  23. misc:
  24. pr = SmbProcessResultMisc;
  25. goto done;
  26. }
  27. f = smbidmapfind(s->fidmap, fid);
  28. if (f == nil) {
  29. smbseterror(s, ERRDOS, ERRbadfid);
  30. pr = SmbProcessResultError;
  31. goto done;
  32. }
  33. switch (infolevel) {
  34. case SMB_SET_FILE_ALLOCATION_INFO:
  35. case SMB_SET_FILE_END_OF_FILE_INFO:
  36. if (s->transaction.in.tdcount < 8)
  37. goto misc;
  38. newsize = smbnhgetv(s->transaction.in.data);
  39. pr = smbtruncatefile(s, f, newsize);
  40. if (pr == SmbProcessResultReply && !smbbufferputs(s->transaction.out.parameters, 0))
  41. goto misc;
  42. break;
  43. case SMB_SET_FILE_BASIC_INFO:
  44. if (s->transaction.in.tdcount < 4 * 8 + 4)
  45. goto misc;
  46. atime = smbnhgetv(s->transaction.in.data + 8);
  47. mtime = smbnhgetv(s->transaction.in.data + 24);
  48. attr = smbnhgetv(s->transaction.in.data + 32);
  49. if (attr) {
  50. Dir *od = dirfstat(f->fd);
  51. if (od == nil)
  52. goto noaccess;
  53. mode = smbdosattr2plan9wstatmode(od->mode, attr);
  54. free(od);
  55. }
  56. else
  57. mode = 0xffffffff;
  58. if (atime || mtime || mode != 0xffffffff) {
  59. Dir d;
  60. memset(&d, 0xff, sizeof(d));
  61. d.name = d.uid = d.gid = d.muid = nil;
  62. if (atime)
  63. d.atime = smbtime2plan9time(atime);
  64. if (mtime)
  65. d.mtime = smbtime2plan9time(mtime);
  66. d.mode = mode;
  67. if (dirfwstat(f->fd, &d) < 0) {
  68. noaccess:
  69. smbseterror(s, ERRDOS, ERRnoaccess);
  70. pr = SmbProcessResultError;
  71. goto done;
  72. }
  73. }
  74. if (!smbbufferputs(s->transaction.out.parameters, 0))
  75. goto misc;
  76. pr = SmbProcessResultReply;
  77. break;
  78. case SMB_SET_FILE_DISPOSITION_INFO:
  79. if (s->transaction.in.tdcount < 1)
  80. goto misc;
  81. f->sf->deleteonclose = *s->transaction.in.data;
  82. if (!smbbufferputs(s->transaction.out.parameters, 0))
  83. goto misc;
  84. pr = SmbProcessResultReply;
  85. break;
  86. default:
  87. smblogprint(-1, "smbtrans2setfileinformation: infolevel 0x%.4ux not implemented\n", infolevel);
  88. smbseterror(s, ERRDOS, ERRunknownlevel);
  89. pr = SmbProcessResultError;
  90. break;
  91. }
  92. done:
  93. smbbufferfree(&b);
  94. return pr;
  95. }