18ccd4a63SDavid du Colombier #include "headers.h"
28ccd4a63SDavid du Colombier
38ccd4a63SDavid du Colombier SmbProcessResult
smbtrans2setfileinformation(SmbSession * s,SmbHeader * h)48ccd4a63SDavid du Colombier smbtrans2setfileinformation(SmbSession *s, SmbHeader *h)
58ccd4a63SDavid du Colombier {
68ccd4a63SDavid du Colombier SmbTree *t;
78ccd4a63SDavid du Colombier ushort infolevel;
88ccd4a63SDavid du Colombier SmbBuffer *b;
98ccd4a63SDavid du Colombier SmbProcessResult pr;
108ccd4a63SDavid du Colombier ushort fid;
118ccd4a63SDavid du Colombier SmbFile *f;
128ccd4a63SDavid du Colombier vlong newsize;
138ccd4a63SDavid du Colombier uvlong atime, mtime;
148ccd4a63SDavid du Colombier ulong attr;
158ccd4a63SDavid du Colombier ulong mode;
168ccd4a63SDavid du Colombier
178ccd4a63SDavid du Colombier t = smbidmapfind(s->tidmap, h->tid);
188ccd4a63SDavid du Colombier if (t == nil) {
198ccd4a63SDavid du Colombier smbseterror(s, ERRSRV, ERRinvtid);
208ccd4a63SDavid du Colombier pr = SmbProcessResultError;
218ccd4a63SDavid du Colombier goto done;
228ccd4a63SDavid du Colombier }
238ccd4a63SDavid du Colombier b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
248ccd4a63SDavid du Colombier if (!smbbuffergets(b, &fid) || !smbbuffergets(b, &infolevel)) {
258ccd4a63SDavid du Colombier misc:
268ccd4a63SDavid du Colombier pr = SmbProcessResultMisc;
278ccd4a63SDavid du Colombier goto done;
288ccd4a63SDavid du Colombier }
298ccd4a63SDavid du Colombier
308ccd4a63SDavid du Colombier f = smbidmapfind(s->fidmap, fid);
318ccd4a63SDavid du Colombier if (f == nil) {
328ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRbadfid);
338ccd4a63SDavid du Colombier pr = SmbProcessResultError;
348ccd4a63SDavid du Colombier goto done;
358ccd4a63SDavid du Colombier }
368ccd4a63SDavid du Colombier
378ccd4a63SDavid du Colombier switch (infolevel) {
388ccd4a63SDavid du Colombier case SMB_SET_FILE_ALLOCATION_INFO:
398ccd4a63SDavid du Colombier case SMB_SET_FILE_END_OF_FILE_INFO:
408ccd4a63SDavid du Colombier if (s->transaction.in.tdcount < 8)
418ccd4a63SDavid du Colombier goto misc;
428ccd4a63SDavid du Colombier newsize = smbnhgetv(s->transaction.in.data);
438ccd4a63SDavid du Colombier pr = smbtruncatefile(s, f, newsize);
448ccd4a63SDavid du Colombier if (pr == SmbProcessResultReply && !smbbufferputs(s->transaction.out.parameters, 0))
458ccd4a63SDavid du Colombier goto misc;
468ccd4a63SDavid du Colombier break;
478ccd4a63SDavid du Colombier
488ccd4a63SDavid du Colombier case SMB_SET_FILE_BASIC_INFO:
498ccd4a63SDavid du Colombier if (s->transaction.in.tdcount < 4 * 8 + 4)
508ccd4a63SDavid du Colombier goto misc;
518ccd4a63SDavid du Colombier atime = smbnhgetv(s->transaction.in.data + 8);
528ccd4a63SDavid du Colombier mtime = smbnhgetv(s->transaction.in.data + 24);
538ccd4a63SDavid du Colombier attr = smbnhgetv(s->transaction.in.data + 32);
548ccd4a63SDavid du Colombier if (attr) {
558ccd4a63SDavid du Colombier Dir *od = dirfstat(f->fd);
568ccd4a63SDavid du Colombier if (od == nil)
578ccd4a63SDavid du Colombier goto noaccess;
588ccd4a63SDavid du Colombier mode = smbdosattr2plan9wstatmode(od->mode, attr);
598ccd4a63SDavid du Colombier free(od);
608ccd4a63SDavid du Colombier }
618ccd4a63SDavid du Colombier else
628ccd4a63SDavid du Colombier mode = 0xffffffff;
638ccd4a63SDavid du Colombier if (atime || mtime || mode != 0xffffffff) {
648ccd4a63SDavid du Colombier Dir d;
658ccd4a63SDavid du Colombier memset(&d, 0xff, sizeof(d));
668ccd4a63SDavid du Colombier d.name = d.uid = d.gid = d.muid = nil;
678ccd4a63SDavid du Colombier if (atime)
688ccd4a63SDavid du Colombier d.atime = smbtime2plan9time(atime);
698ccd4a63SDavid du Colombier if (mtime)
708ccd4a63SDavid du Colombier d.mtime = smbtime2plan9time(mtime);
718ccd4a63SDavid du Colombier d.mode = mode;
728ccd4a63SDavid du Colombier if (dirfwstat(f->fd, &d) < 0) {
738ccd4a63SDavid du Colombier noaccess:
748ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRnoaccess);
758ccd4a63SDavid du Colombier pr = SmbProcessResultError;
768ccd4a63SDavid du Colombier goto done;
778ccd4a63SDavid du Colombier }
788ccd4a63SDavid du Colombier }
798ccd4a63SDavid du Colombier if (!smbbufferputs(s->transaction.out.parameters, 0))
808ccd4a63SDavid du Colombier goto misc;
818ccd4a63SDavid du Colombier pr = SmbProcessResultReply;
828ccd4a63SDavid du Colombier break;
838ccd4a63SDavid du Colombier
848ccd4a63SDavid du Colombier case SMB_SET_FILE_DISPOSITION_INFO:
858ccd4a63SDavid du Colombier if (s->transaction.in.tdcount < 1)
868ccd4a63SDavid du Colombier goto misc;
878ccd4a63SDavid du Colombier f->sf->deleteonclose = *s->transaction.in.data;
881066d6deSDavid du Colombier if (!smbbufferputs(s->transaction.out.parameters, 0))
891066d6deSDavid du Colombier goto misc;
908ccd4a63SDavid du Colombier pr = SmbProcessResultReply;
918ccd4a63SDavid du Colombier break;
928ccd4a63SDavid du Colombier
938ccd4a63SDavid du Colombier default:
948ccd4a63SDavid du Colombier smblogprint(-1, "smbtrans2setfileinformation: infolevel 0x%.4ux not implemented\n", infolevel);
958ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRunknownlevel);
968ccd4a63SDavid du Colombier pr = SmbProcessResultError;
978ccd4a63SDavid du Colombier break;
988ccd4a63SDavid du Colombier }
998ccd4a63SDavid du Colombier done:
1008ccd4a63SDavid du Colombier smbbufferfree(&b);
1018ccd4a63SDavid du Colombier return pr;
1028ccd4a63SDavid du Colombier }
10386a363ceSDavid du Colombier
10486a363ceSDavid du Colombier SmbProcessResult
smbtrans2setpathinformation(SmbSession * s,SmbHeader * h)10586a363ceSDavid du Colombier smbtrans2setpathinformation(SmbSession *s, SmbHeader *h)
10686a363ceSDavid du Colombier {
10786a363ceSDavid du Colombier char *fullpath, *path;
10886a363ceSDavid du Colombier SmbTree *t;
10986a363ceSDavid du Colombier ushort infolevel;
11086a363ceSDavid du Colombier SmbBuffer *b;
11186a363ceSDavid du Colombier SmbProcessResult pr;
11286a363ceSDavid du Colombier ushort atime, adate, mtime, mdate;
11386a363ceSDavid du Colombier ulong attr;
11486a363ceSDavid du Colombier ulong mode;
11586a363ceSDavid du Colombier ulong size;
116*fa70af91SDavid du Colombier // uvlong length;
11786a363ceSDavid du Colombier
11886a363ceSDavid du Colombier t = smbidmapfind(s->tidmap, h->tid);
11986a363ceSDavid du Colombier if (t == nil) {
12086a363ceSDavid du Colombier smbseterror(s, ERRSRV, ERRinvtid);
12186a363ceSDavid du Colombier pr = SmbProcessResultError;
12286a363ceSDavid du Colombier goto done;
12386a363ceSDavid du Colombier }
12486a363ceSDavid du Colombier b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount);
12586a363ceSDavid du Colombier path = nil;
12686a363ceSDavid du Colombier if (!smbbuffergets(b, &infolevel) || !smbbuffergetbytes(b, nil, 4)
12786a363ceSDavid du Colombier || !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) {
12886a363ceSDavid du Colombier misc:
12986a363ceSDavid du Colombier pr = SmbProcessResultMisc;
13086a363ceSDavid du Colombier goto done;
13186a363ceSDavid du Colombier }
13286a363ceSDavid du Colombier
13386a363ceSDavid du Colombier fullpath = nil;
13486a363ceSDavid du Colombier smbstringprint(&fullpath, "%s%s", t->serv->path, path);
13586a363ceSDavid du Colombier
13686a363ceSDavid du Colombier translogprint(s->transaction.in.setup[0], "path %s\n", path);
13786a363ceSDavid du Colombier translogprint(s->transaction.in.setup[0], "infolevel 0x%.4ux\n", infolevel);
13886a363ceSDavid du Colombier translogprint(s->transaction.in.setup[0], "fullpath %s\n", fullpath);
13986a363ceSDavid du Colombier
14086a363ceSDavid du Colombier switch (infolevel) {
14186a363ceSDavid du Colombier case SMB_INFO_STANDARD:
14286a363ceSDavid du Colombier if (s->transaction.in.tdcount < 6 * 4 + 2 * 2)
14386a363ceSDavid du Colombier goto misc;
14486a363ceSDavid du Colombier adate = smbnhgets(s->transaction.in.data + 6);
14586a363ceSDavid du Colombier atime = smbnhgets(s->transaction.in.data + 4);
14686a363ceSDavid du Colombier mdate = smbnhgets(s->transaction.in.data + 10);
14786a363ceSDavid du Colombier mtime = smbnhgets(s->transaction.in.data + 8);
14886a363ceSDavid du Colombier size = smbnhgetl(s->transaction.in.data + 12);
14986a363ceSDavid du Colombier attr = smbnhgets(s->transaction.in.data + 20);
15086a363ceSDavid du Colombier if (attr) {
15186a363ceSDavid du Colombier Dir *od = dirstat(fullpath);
15286a363ceSDavid du Colombier if (od == nil)
15386a363ceSDavid du Colombier goto noaccess;
15486a363ceSDavid du Colombier mode = smbdosattr2plan9wstatmode(od->mode, attr);
15586a363ceSDavid du Colombier free(od);
15686a363ceSDavid du Colombier }
15786a363ceSDavid du Colombier else
15886a363ceSDavid du Colombier mode = 0xffffffff;
15986a363ceSDavid du Colombier translogprint(s->transaction.in.setup[0], "mode 0%od\n", mode);
16086a363ceSDavid du Colombier
161*fa70af91SDavid du Colombier // if (size)
162*fa70af91SDavid du Colombier // length = size;
163*fa70af91SDavid du Colombier // else
164*fa70af91SDavid du Colombier // length = ~0LL;
16586a363ceSDavid du Colombier
16686a363ceSDavid du Colombier translogprint(s->transaction.in.setup[0], "size %lld\n", size);
16786a363ceSDavid du Colombier translogprint(s->transaction.in.setup[0], "adate %d atime %d", adate, atime);
16886a363ceSDavid du Colombier translogprint(s->transaction.in.setup[0], "mdate %d mtime %d\n", mdate, mtime);
16986a363ceSDavid du Colombier
17086a363ceSDavid du Colombier if (size || adate || atime || mdate || mtime || mode != 0xffffffff) {
17186a363ceSDavid du Colombier Dir d;
17286a363ceSDavid du Colombier memset(&d, 0xff, sizeof(d));
17386a363ceSDavid du Colombier d.name = d.uid = d.gid = d.muid = nil;
17486a363ceSDavid du Colombier if (adate || atime)
17586a363ceSDavid du Colombier d.atime = smbdatetime2plan9time(adate, atime, s->tzoff);
17686a363ceSDavid du Colombier if (mdate || mtime)
17786a363ceSDavid du Colombier d.mtime = smbdatetime2plan9time(mdate, mtime, s->tzoff);
17886a363ceSDavid du Colombier d.mode = mode;
17986a363ceSDavid du Colombier d.length = size;
18086a363ceSDavid du Colombier if (dirwstat(fullpath, &d) < 0) {
18186a363ceSDavid du Colombier noaccess:
18286a363ceSDavid du Colombier smbseterror(s, ERRDOS, ERRnoaccess);
18386a363ceSDavid du Colombier pr = SmbProcessResultError;
18486a363ceSDavid du Colombier goto done;
18586a363ceSDavid du Colombier }
18686a363ceSDavid du Colombier }
18786a363ceSDavid du Colombier if (!smbbufferputs(s->transaction.out.parameters, 0))
18886a363ceSDavid du Colombier goto misc;
18986a363ceSDavid du Colombier pr = SmbProcessResultReply;
19086a363ceSDavid du Colombier break;
19186a363ceSDavid du Colombier
19286a363ceSDavid du Colombier default:
19386a363ceSDavid du Colombier smblogprint(-1, "smbtrans2setpathinformation: infolevel 0x%.4ux not implemented\n", infolevel);
19486a363ceSDavid du Colombier smbseterror(s, ERRDOS, ERRunknownlevel);
19586a363ceSDavid du Colombier pr = SmbProcessResultError;
19686a363ceSDavid du Colombier break;
19786a363ceSDavid du Colombier }
19886a363ceSDavid du Colombier done:
19986a363ceSDavid du Colombier smbbufferfree(&b);
20086a363ceSDavid du Colombier return pr;
20186a363ceSDavid du Colombier }
202