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