Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "headers.h"
2
 
3
SmbProcessResult
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
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
}