18ccd4a63SDavid du Colombier #include "headers.h"
28ccd4a63SDavid du Colombier
38ccd4a63SDavid du Colombier SmbProcessResult
smbcomrename(SmbSession * s,SmbHeader * h,uchar *,SmbBuffer * b)48ccd4a63SDavid du Colombier smbcomrename(SmbSession *s, SmbHeader *h, uchar *, SmbBuffer *b)
58ccd4a63SDavid du Colombier {
68ccd4a63SDavid du Colombier int rv;
79b004bddSDavid du Colombier char *old, *new;
89b004bddSDavid du Colombier char *oldpath = nil;
99b004bddSDavid du Colombier char *newpath = nil;
108ccd4a63SDavid du Colombier char *olddir, *newdir;
118ccd4a63SDavid du Colombier char *oldname, *newname;
128ccd4a63SDavid du Colombier uchar oldfmt, newfmt;
13*3e5d0078SDavid du Colombier SmbTree *t;
148ccd4a63SDavid du Colombier Dir d;
158ccd4a63SDavid du Colombier SmbProcessResult pr;
168ccd4a63SDavid du Colombier
178ccd4a63SDavid du Colombier if (h->wordcount != 1)
188ccd4a63SDavid du Colombier return SmbProcessResultFormat;
199b004bddSDavid du Colombier if (!smbbuffergetb(b, &oldfmt) || oldfmt != 0x04 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &old)
209b004bddSDavid du Colombier || !smbbuffergetb(b, &newfmt) || newfmt != 0x04 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &new))
218ccd4a63SDavid du Colombier return SmbProcessResultFormat;
229b004bddSDavid du Colombier
23*3e5d0078SDavid du Colombier t = smbidmapfind(s->tidmap, h->tid);
24*3e5d0078SDavid du Colombier if (t == nil) {
25*3e5d0078SDavid du Colombier smbseterror(s, ERRSRV, ERRinvtid);
26*3e5d0078SDavid du Colombier return SmbProcessResultError;
27*3e5d0078SDavid du Colombier }
28*3e5d0078SDavid du Colombier smbstringprint(&oldpath, "%s%s", t->serv->path, old);
29*3e5d0078SDavid du Colombier smbstringprint(&newpath, "%s%s", t->serv->path, new);
309b004bddSDavid du Colombier
318ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomrename: %s to %s\n", oldpath, newpath);
328ccd4a63SDavid du Colombier smbpathsplit(oldpath, &olddir, &oldname);
338ccd4a63SDavid du Colombier smbpathsplit(newpath, &newdir, &newname);
348ccd4a63SDavid du Colombier if (strcmp(olddir, newdir) != 0) {
358ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomrename: directories differ\n");
368ccd4a63SDavid du Colombier goto noaccess;
378ccd4a63SDavid du Colombier }
388ccd4a63SDavid du Colombier memset(&d, 0xff, sizeof(d));
398ccd4a63SDavid du Colombier d.uid = d.gid = d.muid = nil;
408ccd4a63SDavid du Colombier d.name = newname;
418ccd4a63SDavid du Colombier rv = dirwstat(oldpath, &d);
428ccd4a63SDavid du Colombier if (rv < 0) {
438ccd4a63SDavid du Colombier smblogprint(h->command, "smbcomrename failed: %r\n");
448ccd4a63SDavid du Colombier noaccess:
458ccd4a63SDavid du Colombier smbseterror(s, ERRDOS, ERRnoaccess);
468ccd4a63SDavid du Colombier pr = SmbProcessResultError;
478ccd4a63SDavid du Colombier }
488ccd4a63SDavid du Colombier else
498ccd4a63SDavid du Colombier pr = smbbufferputack(s->response, h, &s->peerinfo);
508ccd4a63SDavid du Colombier free(oldpath);
518ccd4a63SDavid du Colombier free(olddir);
528ccd4a63SDavid du Colombier free(oldname);
538ccd4a63SDavid du Colombier free(newpath);
548ccd4a63SDavid du Colombier free(newdir);
558ccd4a63SDavid du Colombier free(newname);
568ccd4a63SDavid du Colombier return pr;
578ccd4a63SDavid du Colombier }
58