xref: /plan9/sys/src/cmd/aquarela/smbcomrename.c (revision 3e5d0078acdadead679c94c0daec143041c4b41e)
1 #include "headers.h"
2 
3 SmbProcessResult
smbcomrename(SmbSession * s,SmbHeader * h,uchar *,SmbBuffer * b)4 smbcomrename(SmbSession *s, SmbHeader *h, uchar *, SmbBuffer *b)
5 {
6 	int rv;
7 	char *old,     *new;
8 	char *oldpath = nil;
9 	char *newpath = nil;
10 	char *olddir, *newdir;
11 	char *oldname, *newname;
12 	uchar oldfmt, newfmt;
13 	SmbTree *t;
14 	Dir d;
15 	SmbProcessResult pr;
16 
17 	if (h->wordcount != 1)
18 		return SmbProcessResultFormat;
19 	if (!smbbuffergetb(b, &oldfmt) || oldfmt != 0x04 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &old)
20 		|| !smbbuffergetb(b, &newfmt) || newfmt != 0x04 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &new))
21 		return SmbProcessResultFormat;
22 
23 	t = smbidmapfind(s->tidmap, h->tid);
24 	if (t == nil) {
25 		smbseterror(s, ERRSRV, ERRinvtid);
26 		return SmbProcessResultError;
27 	}
28 	smbstringprint(&oldpath, "%s%s", t->serv->path, old);
29 	smbstringprint(&newpath, "%s%s", t->serv->path, new);
30 
31 	smblogprint(h->command, "smbcomrename: %s to %s\n", oldpath, newpath);
32 	smbpathsplit(oldpath, &olddir, &oldname);
33 	smbpathsplit(newpath, &newdir, &newname);
34 	if (strcmp(olddir, newdir) != 0) {
35 		smblogprint(h->command, "smbcomrename: directories differ\n");
36 		goto noaccess;
37 	}
38 	memset(&d, 0xff, sizeof(d));
39 	d.uid = d.gid = d.muid = nil;
40 	d.name = newname;
41 	rv = dirwstat(oldpath, &d);
42 	if (rv < 0) {
43 		smblogprint(h->command, "smbcomrename failed: %r\n");
44 	noaccess:
45 		smbseterror(s, ERRDOS, ERRnoaccess);
46 		pr =  SmbProcessResultError;
47 	}
48 	else
49 		pr = smbbufferputack(s->response, h, &s->peerinfo);
50 	free(oldpath);
51 	free(olddir);
52 	free(oldname);
53 	free(newpath);
54 	free(newdir);
55 	free(newname);
56 	return pr;
57 }
58