xref: /plan9/sys/src/cmd/aquarela/smbtrans2set.c (revision fa70af914bd0480af9c4b57059e37b4e3d9c5d24)
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