SmbProcessResult smbtrans2setpathinformation(SmbSession *s, SmbHeader *h) { char *fullpath, *path; SmbTree *t; ushort infolevel; SmbBuffer *b; SmbProcessResult pr; ushort atime, adate, mtime, mdate; ulong attr; ulong mode; ulong size; // uvlong length; t = smbidmapfind(s->tidmap, h->tid); if (t == nil) { smbseterror(s, ERRSRV, ERRinvtid); pr = SmbProcessResultError; goto done; } b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount); path = nil; if (!smbbuffergets(b, &infolevel) || !smbbuffergetbytes(b, nil, 4) || !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) { misc: pr = SmbProcessResultMisc; goto done; } fullpath = nil; smbstringprint(&fullpath, "%s%s", t->serv->path, path); translogprint(s->transaction.in.setup[0], "path %s\n", path); translogprint(s->transaction.in.setup[0], "infolevel 0x%.4ux\n", infolevel); translogprint(s->transaction.in.setup[0], "fullpath %s\n", fullpath); switch (infolevel) { case SMB_INFO_STANDARD: if (s->transaction.in.tdcount < 6 * 4 + 2 * 2) goto misc; adate = smbnhgets(s->transaction.in.data + 6); atime = smbnhgets(s->transaction.in.data + 4); mdate = smbnhgets(s->transaction.in.data + 10); mtime = smbnhgets(s->transaction.in.data + 8); size = smbnhgetl(s->transaction.in.data + 12); attr = smbnhgets(s->transaction.in.data + 20); if (attr) { Dir *od = dirstat(fullpath); if (od == nil) goto noaccess; mode = smbdosattr2plan9wstatmode(od->mode, attr); free(od); } else mode = 0xffffffff; translogprint(s->transaction.in.setup[0], "mode 0%od\n", mode); // if (size) // length = size; // else // length = ~0LL; translogprint(s->transaction.in.setup[0], "size %lld\n", size); translogprint(s->transaction.in.setup[0], "adate %d atime %d", adate, atime); translogprint(s->transaction.in.setup[0], "mdate %d mtime %d\n", mdate, mtime); if (size || adate || atime || mdate || mtime || mode != 0xffffffff) { Dir d; memset(&d, 0xff, sizeof(d)); d.name = d.uid = d.gid = d.muid = nil; if (adate || atime) d.atime = smbdatetime2plan9time(adate, atime, s->tzoff); if (mdate || mtime) d.mtime = smbdatetime2plan9time(mdate, mtime, s->tzoff); d.mode = mode; d.length = size; if (dirwstat(fullpath, &d) < 0) { noaccess: smbseterror(s, ERRDOS, ERRnoaccess); pr = SmbProcessResultError; goto done; } } if (!smbbufferputs(s->transaction.out.parameters, 0)) goto misc; pr = SmbProcessResultReply; break; default: smblogprint(-1, "smbtrans2setpathinformation: infolevel 0x%.4ux not implemented\n", infolevel); smbseterror(s, ERRDOS, ERRunknownlevel); pr = SmbProcessResultError; break; } done: smbbufferfree(&b); return pr; }
SmbProcessResult smbcomsetinformation2(SmbSession *s, SmbHeader *h, uint8_t *pdata, SmbBuffer *) { uint16_t fid, adate, atime, mdate, mtime; SmbTree *t; SmbFile *f; Dir d; if (h->wordcount != 7) return SmbProcessResultFormat; fid = smbnhgets(pdata); adate = smbnhgets(pdata + 6); atime = smbnhgets(pdata + 8); mdate = smbnhgets(pdata + 10); mtime = smbnhgets(pdata + 12); smblogprint(h->command, "smbcomsetinformation2: fid 0x%.4ux adate 0x%.4ux atime 0x%.4ux mdate 0x%.4ux mtime 0x%.4ux\n", fid, adate, atime, mdate, mtime); t = smbidmapfind(s->tidmap, h->tid); if (t == nil) { smbseterror(s, ERRSRV, ERRinvtid); return SmbProcessResultError; } f = smbidmapfind(s->fidmap, fid); if (f == nil) { smbseterror(s, ERRDOS, ERRbadfid); return SmbProcessResultError; } memset(&d, 0xff, sizeof(d)); d.name = d.uid = d.gid = d.muid = nil; if (adate || atime || mdate || mtime) { //smblogprint(-1, "smbcomsetinformation2: changing times not implemented\n"); // return SmbProcessResultUnimp; /* something to change */ if (!(adate && atime && mdate && mtime)) { /* some null entries */ uint16_t odate, otime; Dir *od = dirfstat(f->fd); if (od == nil) { smbseterror(s, ERRDOS, ERRnoaccess); return SmbProcessResultError; } if (adate || atime) { /* something changed in access time */ if (!(adate && atime)) { /* some nulls in access time */ smbplan9time2datetime(d.atime, s->tzoff, &odate, &otime); if (adate == 0) adate = odate; if (atime == 0) atime = otime; } d.atime = smbdatetime2plan9time(adate, atime, s->tzoff); } if (mdate || mtime) { /* something changed in modify time */ if (!(mdate && mtime)) { /* some nulls in modify time */ smbplan9time2datetime(d.mtime, s->tzoff, &odate, &otime); if (mdate == 0) mdate = odate; if (mtime == 0) mtime = otime; } d.mtime = smbdatetime2plan9time(mdate, mtime, s->tzoff); } free(od); } if (dirfwstat(f->fd, &d) < 0) { smbseterror(s, ERRDOS, ERRnoaccess); return SmbProcessResultError; } } return smbbufferputack(s->response, h, &s->peerinfo); }