cinap / sources — update cifs Reference: /n/atom/patch/applied2013/cifsupd Date: Tue Jun 18 02:34:45 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/cifs/trans2.c Tue Jun 18 02:34:25 2013 +++ /sys/src/cmd/cifs/trans2.c Tue Jun 18 02:34:25 2013 @@ -15,7 +15,7 @@ p->tbase = pl16(p, 0); /* 0 Total parameter bytes to be sent, filled later */ pl16(p, 0); /* 2 Total data bytes to be sent, filled later */ pl16(p, 64); /* 4 Max parameter to return */ - pl16(p, (MTU - T2HDRLEN)-64); /* 6 Max data to return */ + pl16(p, (s->mtu - T2HDRLEN)-64); /* 6 Max data to return */ p8(p, 0); /* 8 Max setup count to return */ p8(p, 0); /* 9 Reserved */ pl16(p, 0); /* 10 Flags */ --- /sys/src/cmd/cifs/trans.c Tue Jun 18 02:34:25 2013 +++ /sys/src/cmd/cifs/trans.c Tue Jun 18 02:34:25 2013 @@ -16,7 +16,7 @@ p->tbase = pl16(p, 0); /* 0 Total parameter bytes to be sent, filled later */ pl16(p, 0); /* 2 Total data bytes to be sent, filled later */ pl16(p, 64); /* 4 Max parameter to return */ - pl16(p, MTU - T2HDRLEN - 128); /* 6 Max data to return */ + pl16(p, s->mtu - T2HDRLEN - 128); /* 6 Max data to return */ pl16(p, 1); /* 8 Max setup count to return */ pl16(p, 0); /* 10 Flags */ pl32(p, 1000); /* 12 Timeout (ms) */ @@ -126,7 +126,7 @@ pascii(p, REMSmb_NetShareEnum_P); /* request descriptor */ pascii(p, REMSmb_share_info_0); /* reply descriptor */ pl16(p, 0); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, s->mtu - 1024); /* receive buffer length */ ptdata(p); if(trpc(p) == -1){ @@ -160,8 +160,7 @@ } if(ngot < navail) - fprint(2, "%s: %d share names too long for RAP (>13 chars)\n", - argv0, navail - ngot); + fprint(2, "%s: %d/%d - share list incomplete\n", argv0, ngot, navail); free(p); return ngot; @@ -184,7 +183,7 @@ pascii(p, REMSmb_share_info_2); /* reply descriptor */ pascii(p, share); pl16(p, 1); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, s->mtu - 1024); /* receive buffer length */ ptdata(p); @@ -253,7 +252,7 @@ pascii(p, REMSmb_NetSessionEnum_P); /* request descriptor */ pascii(p, REMSmb_session_info_10); /* reply descriptor */ pl16(p, 10); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, s->mtu - 1024); /* receive buffer length */ ptdata(p); if(trpc(p) == -1){ @@ -279,19 +278,18 @@ } q = *sip + ngot; - while(nret-- > 0){ + while(nret-- != 0){ gconv(p, conv, tmp, sizeof tmp); q->wrkstn = estrdup9p(tmp); gconv(p, conv, tmp, sizeof tmp); q->user = estrdup9p(tmp); q->sesstime = gl32(p); q->idletime = gl32(p); - q++; ngot++; + q++; } if(ngot < navail) - fprint(2, "warning: %d/%d - incomplete session list sent\n", - ngot, navail); + fprint(2, "warning: %d/%d - session list incomplete\n", ngot, navail); free(p); return ngot; } @@ -314,7 +312,7 @@ pascii(p, REMSmb_NetGroupEnum_P); /* request descriptor */ pascii(p, REMSmb_group_info_0); /* reply descriptor */ pl16(p, 0); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, s->mtu - 1024); /* receive buffer length */ ptdata(p); if(trpc(p) == -1){ @@ -338,13 +336,13 @@ memset(*nlp, 0, sizeof(Namelist) * navail); q = *nlp + ngot; - while(ngot < navail && nret-- > 0){ + while(ngot < navail && nret--){ gmem(p, tmp, 21); tmp[21] = 0; q->name = estrdup9p(tmp); - q++; ngot++; - if(p->pos >= p->eop) /* Windows seems to lie sometimes */ + q++; + if(p->pos >= p->eop) /* Windows seems to lie somtimes */ break; } free(p); @@ -370,7 +368,7 @@ pascii(p, REMSmb_user_info_0); /* reply descriptor */ pascii(p, group); /* group name for list */ pl16(p, 0); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, s->mtu - 1024); /* receive buffer length */ ptdata(p); if(trpc(p) == -1){ @@ -394,13 +392,13 @@ memset(*nlp, 0, sizeof(Namelist) * navail); q = *nlp + ngot; - while(ngot < navail && nret-- > 0){ + while(ngot < navail && nret--){ gmem(p, tmp, 21); tmp[21] = 0; q->name = estrdup9p(tmp); - q++; ngot++; - if(p->pos >= p->eop) /* Windows seems to lie sometimes */ + q++; + if(p->pos >= p->eop) /* Windows seems to lie somtimes */ break; } free(p); @@ -424,7 +422,7 @@ pascii(p, REMSmb_NetUserEnum_P); /* request descriptor */ pascii(p, REMSmb_user_info_0); /* reply descriptor */ pl16(p, 0); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, s->mtu - 1024); /* receive buffer length */ ptdata(p); if(trpc(p) == -1){ @@ -448,13 +446,13 @@ memset(*nlp, 0, sizeof(Namelist) * navail); q = *nlp + ngot; - while(ngot < navail && nret-- > 0){ + while(ngot < navail && nret--){ gmem(p, tmp, 21); tmp[21] = 0; q->name = estrdup9p(tmp); - q++; ngot++; - if(p->pos >= p->eop) /* Windows seems to lie sometimes */ + q++; + if(p->pos >= p->eop) /* Windows seems to lie somtimes */ break; } free(p); @@ -480,7 +478,7 @@ pascii(p, REMSmb_NetUserEnum2_P); /* request descriptor */ pascii(p, REMSmb_user_info_0); /* reply descriptor */ pl16(p, 0); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, s->mtu - 1024); /* receive buffer length */ pl32(p, resume); /* resume key to allow multiple fetches */ ptdata(p); @@ -507,13 +505,13 @@ memset(*nlp, 0, sizeof(Namelist) * navail); } q = *nlp + ngot; - while(ngot < navail && nret-- > 0){ + while(ngot < navail && nret--){ gmem(p, tmp, 21); tmp[21] = 0; q->name = estrdup9p(tmp); - q++; ngot++; - if(p->pos >= p->eop) /* Windows seems to lie sometimes */ + q++; + if(p->pos >= p->eop) /* Windows seems to lie somtimes */ break; } free(p); @@ -538,7 +536,7 @@ pascii(p, REMSmb_user_info_10); /* reply descriptor */ pascii(p, user); /* username */ pl16(p, 10); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, s->mtu - 1024); /* receive buffer length */ ptdata(p); if(trpc(p) == -1){ @@ -594,7 +592,7 @@ pascii(p, REMSmb_NetServerEnum2_P); /* request descriptor */ pascii(p, REMSmb_server_info_1); /* reply descriptor */ pl16(p, 1); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, s->mtu - 1024); /* receive buffer length */ pl32(p, type); pascii(p, workgroup); @@ -657,7 +655,7 @@ pascii(p, REMSmb_NetServerEnum3_P); /* request descriptor */ pascii(p, REMSmb_server_info_1); /* reply descriptor */ pl16(p, 1); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, s->mtu - 1024); /* receive buffer length */ pl32(p, type); pascii(p, workgroup); pascii(p, first); @@ -702,8 +700,8 @@ free(q->comment); continue; } - q++; ngot++; + q++; } free(p); if(ngot < navail) @@ -729,11 +727,11 @@ ptparam(p); pl16(p, API_WFileEnum2); pascii(p, REMSmb_NetFileEnum2_P); /* request descriptor */ - pascii(p, REMSmb_file_info_3); /* reply descriptor */ + pascii(p, REMSmb_file_info_1); /* reply descriptor */ pascii(p, path); pascii(p, user); - pl16(p, 3); /* detail level */ - pl16(p, MTU - 200); /* receive buffer length */ + pl16(p, 1); /* detail level */ + pl16(p, s->mtu - 1024); /* receive buffer length */ pl32(p, resume); /* resume key */ /* FIXME: maybe the padding and resume key are the wrong way around? */ pl32(p, 0); /* padding ? */ --- /sys/src/cmd/cifs/cifs.c Tue Jun 18 02:34:25 2013 +++ /sys/src/cmd/cifs/cifs.c Tue Jun 18 02:34:25 2013 @@ -39,9 +39,13 @@ s->seq = 0; s->seqrun = 0; s->secmode = SECMODE_SIGN_ENABLED; /* hope for the best */ - s->flags2 = FL2_KNOWS_LONG_NAMES | FL2_HAS_LONG_NAMES | FL2_PAGEING_IO | FL2_UNICODE; + s->flags2 = FL2_KNOWS_LONG_NAMES | FL2_HAS_LONG_NAMES | FL2_PAGEING_IO; + s->macidx = -1; + if(s->mtu > MTU) + s->mtu = MTU; + return s; } @@ -76,6 +80,7 @@ p->buf = (uchar *)p + sizeof(Pkt); p->s = s; + p->request = cmd; /* for debug */ qlock(&s->seqlock); if(s->seqrun){ @@ -137,11 +142,12 @@ int cifsrpc(Pkt *p) { - int got, err; + int reply, got, err; uint tid, uid, seq; uchar *pos; char m[nelem(magic)]; + pos = p->pos; if(p->bytebase){ p->pos = p->bytebase; @@ -155,8 +161,11 @@ qlock(&p->s->rpclock); got = nbtrpc(p); qunlock(&p->s->rpclock); - if(got == -1) + + if(got < 32+NBHDRLEN){ + werrstr("cifs packet too small (%d < %d)\n", got, 32+NBHDRLEN); return -1; + } gmem(p, m, nelem(magic)); if(memcmp(m, magic, nelem(magic)) != 0){ @@ -165,7 +174,7 @@ return -1; } - g8(p); /* cmd */ + reply = g8(p); /* cmd */ err = gl32(p); /* errcode */ g8(p); /* flags */ p->flags2 = gl16(p); /* flags2 */ @@ -179,6 +188,12 @@ gl16(p); /* mid */ g8(p); /* word count */ + if(reply != p->request){ + fprint(2, "unexpected reply (cmd=%x/%x seq=%d/%d)\n", + reply, p->request, seq, p->seq); + return -1; + } + if(p->s->secmode & SECMODE_SIGN_ENABLED){ if(macsign(p, p->seq+1) != 0 && p->s->seqrun){ werrstr("cifsrpc: invalid packet signature"); @@ -196,7 +211,7 @@ * catch that too. */ if(p->s->seqrun && seq != p->seq && seq != 0){ - print("%ux != %ux bad sequence number\n", seq, p->seq); + werrstr("bad sequence number (%d != %d)\n", p->seq, seq); return -1; } } @@ -243,7 +258,22 @@ }; Pkt *p; + /* + * This should not be necessary, however the XP seems to use + * Unicode strings in its Negoiate response, but not set the + * Flags2 UNICODE flag. + * + * It does however echo back the FL_UNICODE flag we set in the + * flags2 negoiate request. + * + * The bodge is to force FL_UNICODE for this single request, + * clearing it after. Later we set FL2_UNICODE if the server + * agrees to CAP_UNICODE as it "should" be done. + */ + s->flags2 |= FL2_UNICODE; p = cifshdr(s, nil, SMB_COM_NEGOTIATE); + s->flags2 &= ~FL2_UNICODE; + pbytes(p); for(i = 0; i < nelem(dialects); i++){ p8(p, STR_DIALECT); --- /sys/src/cmd/cifs/cifs.h Tue Jun 18 02:34:25 2013 +++ /sys/src/cmd/cifs/cifs.h Tue Jun 18 02:34:25 2013 @@ -378,6 +378,7 @@ int tid; /* tree ID received from server */ int seq; /* sequence number expected in reply */ + int request; /* request cmd no (for debug) */ int flags2; /* flags2 received with this packet */ uchar *seqbase; /* cifs: pos of sequence number in packet */ @@ -484,156 +485,150 @@ extern Share Shares[MAX_SHARES]; extern int Nshares; -/* main.c */ -Qid mkqid(char *, int, long, int, long); - /* auth.c */ -Auth *getauth(char *, char *, char *, int, uchar *, int); -void autherr(void); -int macsign(Pkt *, int); +extern void autherr(void); +extern Auth *getauth(char *name, char *windom, char *keyp, int secmode, uchar *chal, int len); +extern int macsign(Pkt *p, int seq); /* cifs.c */ -Session *cifsdial(char *, char *, char *); -void cifsclose(Session *); -Pkt *cifshdr(Session *, Share *, int); -void pbytes(Pkt *); -int cifsrpc(Pkt *); -int CIFSnegotiate(Session *, long *, char *, int, char *, int); -int CIFSsession(Session *); -int CIFStreeconnect(Session *, char *, char *, Share *); -int CIFSlogoff(Session *); -int CIFStreedisconnect(Session *, Share *); -int CIFSdeletefile(Session *, Share *, char *); -int CIFSdeletedirectory(Session *, Share *, char *); -int CIFScreatedirectory(Session *, Share *, char *); -int CIFSrename(Session *, Share *, char *, char *); -int CIFS_NT_opencreate(Session *, Share *, char *, int, int, int, int, int, int, int *, FInfo *); -int CIFS_SMB_opencreate(Session *, Share *, char *, int, int, int, int *); -vlong CIFSwrite(Session *, Share *, int, uvlong, void *, vlong); -vlong CIFSread(Session *, Share *, int, uvlong, void *, vlong, vlong); -int CIFSflush(Session *, Share *, int); -int CIFSclose(Session *, Share *, int); -int CIFSfindclose2(Session *, Share *, int); -int CIFSecho(Session *); -int CIFSsetinfo(Session *, Share *, char *, FInfo *); -void goff(Pkt *, uchar *, char *, int); +extern Session *cifsdial(char *host, char *called, char *sysname); +extern void cifsclose(Session *s); +extern Pkt *cifshdr(Session *s, Share *sp, int cmd); +extern void pbytes(Pkt *p); +extern int cifsrpc(Pkt *p); +extern int CIFSnegotiate(Session *s, long *svrtime, char *domain, int domlen, char *cname, int cnamlen); +extern int CIFSsession(Session *s); +extern int CIFStreeconnect(Session *s, char *cname, char *tree, Share *sp); +extern int CIFSlogoff(Session *s); +extern int CIFStreedisconnect(Session *s, Share *sp); +extern int CIFSdeletefile(Session *s, Share *sp, char *name); +extern int CIFSdeletedirectory(Session *s, Share *sp, char *name); +extern int CIFScreatedirectory(Session *s, Share *sp, char *name); +extern int CIFSrename(Session *s, Share *sp, char *old, char *new); +extern int CIFS_NT_opencreate(Session *s, Share *sp, char *name, int flags, int options, int attrs, int access, int share, int action, int *result, FInfo *fi); +extern int CIFS_SMB_opencreate(Session *s, Share *sp, char *name, int access, int attrs, int action, int *result); +extern vlong CIFSwrite(Session *s, Share *sp, int fh, uvlong off, void *buf, vlong n); +extern vlong CIFSread(Session *s, Share *sp, int fh, uvlong off, void *buf, vlong n, vlong minlen); +extern int CIFSflush(Session *s, Share *sp, int fh); +extern int CIFSclose(Session *s, Share *sp, int fh); +extern int CIFSfindclose2(Session *s, Share *sp, int sh); +extern int CIFSecho(Session *s); +extern int CIFSsetinfo(Session *s, Share *sp, char *path, FInfo *fip); /* dfs.c */ -char *mapfile(char *); -int mapshare(char *, Share **); -int redirect(Session *, Share *s, char *); -int dfscacheinfo(Fmt *); -char *trimshare(char *); +extern int dfscacheinfo(Fmt *f); +extern char *trimshare(char *s); +extern char *mapfile(char *opath); +extern int mapshare(char *path, Share **osp); +extern int redirect(Session *s, Share *sp, char *path); /* doserrstr.c */ -char *doserrstr(uint); +extern char *doserrstr(uint err); /* fs.c */ -int shareinfo(Fmt *); -int conninfo(Fmt *); -int sessioninfo(Fmt *); -int userinfo(Fmt *); -int groupinfo(Fmt *); -int domaininfo(Fmt *); -int workstationinfo(Fmt *); -int dfsrootinfo(Fmt *); -int openfileinfo(Fmt *); -int dfsrootinfo(Fmt *); -int filetableinfo(Fmt *); /* is in main.c due to C scope */ +extern int shareinfo(Fmt *f); +extern int openfileinfo(Fmt *f); +extern int conninfo(Fmt *f); +extern int sessioninfo(Fmt *f); +extern int dfsrootinfo(Fmt *f); +extern int userinfo(Fmt *f); +extern int groupinfo(Fmt *f); +extern int domaininfo(Fmt *f); +extern int workstationinfo(Fmt *f); /* info.c */ -int walkinfo(char *); -int numinfo(void); -int dirgeninfo(int, Dir *); -int makeinfo(int); -int readinfo(int, char *, int, int); -void freeinfo(int); +extern int walkinfo(char *name); +extern int numinfo(void); +extern int dirgeninfo(int slot, Dir *d); +extern int makeinfo(int path); +extern int readinfo(int path, char *buf, int len, int off); +extern void freeinfo(int path); /* main.c */ -void usage(void); -void dmpkey(char *, void *, int); -void main(int, char **); +extern void setup(void); +extern int filetableinfo(Fmt *f); +extern Qid mkqid(char *s, int is_dir, long vers, int subtype, long path); +extern int rdonly(Session *s, Share *sp, char *path, int rdonly); +extern void usage(void); +extern void dmpkey(char *s, void *v, int n); +extern void main(int argc, char **argv); /* misc.c */ -char *strupr(char *); -char *strlwr(char *); +extern char *strupr(char *s); +extern char *strlwr(char *s); /* netbios.c */ -void Gmem(uchar **, void *, int); -int calledname(char *, char *); -int nbtdial(char *, char *, char *); -void nbthdr(Pkt *); -int nbtrpc(Pkt *); -void xd(char *, void *, int); +extern void Gmem(uchar **p, void *v, int n); +extern int calledname(char *host, char *name); +extern int nbtdial(char *addr, char *called, char *sysname); +extern void nbthdr(Pkt *p); +extern int nbtrpc(Pkt *p); +extern void xd(char *str, void *buf, int n); /* nterrstr.c */ -char *nterrstr(uint); +extern char *nterrstr(uint err); /* pack.c */ -void *pmem(Pkt *, void *, int); -void *ppath(Pkt *, char *); -void *pstr(Pkt *, char *); -void *pascii(Pkt *, char *); -void *pl64(Pkt *, uvlong); -void *pb32(Pkt *, uint); -void *pl32(Pkt *, uint); -void *pb16(Pkt *, uint); -void *pl16(Pkt *, uint); -void *p8(Pkt *, uint); -void *pname(Pkt *, char *, char); -void *pvtime(Pkt *, uvlong); -void *pdatetime(Pkt *, long); -void gmem(Pkt *, void *, int); -void gstr(Pkt *, char *, int); -void gascii(Pkt *, char *, int); -uvlong gl64(Pkt *); -uvlong gb48(Pkt *); -uint gb32(Pkt *); -uint gl32(Pkt *); -uint gb16(Pkt *); -uint gl16(Pkt *); -uint g8(Pkt *); -long gdatetime(Pkt *); -long gvtime(Pkt *); -void gconv(Pkt *, int, char *, int); +extern void *pmem(Pkt *p, void *v, int len); +extern void *ppath(Pkt *p, char *str); +extern void *pstr(Pkt *p, char *str); +extern void *pascii(Pkt *p, char *str); +extern void *pl64(Pkt *p, uvlong n); +extern void *pb32(Pkt *p, uint n); +extern void *pl32(Pkt *p, uint n); +extern void *pb16(Pkt *p, uint n); +extern void *pl16(Pkt *p, uint n); +extern void *p8(Pkt *p, uint n); +extern void *pname(Pkt *p, char *name, char pad); +extern void *pvtime(Pkt *p, uvlong n); +extern void *pdatetime(Pkt *p, long utc); +extern void gmem(Pkt *p, void *v, int n); +extern void gstr(Pkt *p, char *str, int n); +extern void gascii(Pkt *p, char *str, int n); +extern uvlong gl64(Pkt *p); +extern uvlong gb48(Pkt *p); +extern uint gb32(Pkt *p); +extern uint gl32(Pkt *p); +extern uint gb16(Pkt *p); +extern uint gl16(Pkt *p); +extern uint g8(Pkt *p); +extern long gdatetime(Pkt *p); +extern long gvtime(Pkt *p); +extern void gconv(Pkt *p, int conv, char *str, int n); +extern void goff(Pkt *p, uchar *base, char *str, int n); + +/* ping.c */ +extern int ping(char *host, int timeout); /* raperrstr.c */ -char *raperrstr(uint); +extern char *raperrstr(uint err); /* sid2name.c */ -void upd_names(Session *, Share *, char *, Dir *); +extern void upd_names(Session *s, Share *sp, char *path, Dir *d); /* trans.c */ -int RAPshareenum(Session *, Share *, Share **); -int RAPshareinfo(Session *, Share *, char *, Shareinfo2 *); - -int RAPsessionenum(Session *, Share *, Sessinfo **); - -int RAPgroupenum(Session *, Share *, Namelist **); -int RAPgroupusers(Session *, Share *, char *, Namelist **); - -int RAPuserenum(Session *, Share *, Namelist **); -int RAPuserenum2(Session *, Share *, Namelist **); -int RAPuserinfo(Session *, Share *, char *, Userinfo *); - -int RAPServerenum2(Session *, Share *, char *, int, int *, Serverinfo **); -int RAPServerenum3(Session *, Share *, char *, int, int, Serverinfo *); - -int RAPFileenum2(Session *, Share *, char *, char *, Fileinfo **); +extern int RAPshareenum(Session *s, Share *sp, Share **ent); +extern int RAPshareinfo(Session *s, Share *sp, char *share, Shareinfo2 *si2p); +extern int RAPsessionenum(Session *s, Share *sp, Sessinfo **sip); +extern int RAPgroupenum(Session *s, Share *sp, Namelist **nlp); +extern int RAPgroupusers(Session *s, Share *sp, char *group, Namelist **nlp); +extern int RAPuserenum(Session *s, Share *sp, Namelist **nlp); +extern int RAPuserenum2(Session *s, Share *sp, Namelist **nlp); +extern int RAPuserinfo(Session *s, Share *sp, char *user, Userinfo *uip); +extern int RAPServerenum2(Session *s, Share *sp, char *workgroup, int type, int *more, Serverinfo **si); +extern int RAPServerenum3(Session *s, Share *sp, char *workgroup, int type, int last, Serverinfo *si); +extern int RAPFileenum2(Session *s, Share *sp, char *user, char *path, Fileinfo **fip); /* trans2.c */ -int T2findfirst(Session *, Share *, int, char *, int *, long *, FInfo *); -int T2findnext(Session *, Share *, int, char *, int *, long *, FInfo *, int); -int T2queryall(Session *, Share *, char *, FInfo *); -int T2querystandard(Session *, Share *, char *, FInfo *); -int T2setpathinfo(Session *, Share *, char *, FInfo *); -int T2setfilelength(Session *, Share *, int, FInfo *); -int T2fsvolumeinfo(Session *, Share *, long *, long *, char *, int); -int T2fssizeinfo(Session *, Share *, uvlong *, uvlong *); -int T2getdfsreferral(Session *, Share *, char *, int *, int *, Refer *, int); +extern int T2findfirst(Session *s, Share *sp, int slots, char *path, int *got, long *resume, FInfo *fip); +extern int T2findnext(Session *s, Share *sp, int slots, char *path, int *got, long *resume, FInfo *fip, int sh); +extern int T2queryall(Session *s, Share *sp, char *path, FInfo *fip); +extern int T2querystandard(Session *s, Share *sp, char *path, FInfo *fip); +extern int T2setpathinfo(Session *s, Share *sp, char *path, FInfo *fip); +extern int T2setfilelength(Session *s, Share *sp, int fh, FInfo *fip); +extern int T2fsvolumeinfo(Session *s, Share *sp, long *created, long *serialno, char *label, int labellen); +extern int T2fssizeinfo(Session *s, Share *sp, uvlong *total, uvlong *unused); +extern int T2getdfsreferral(Session *s, Share *sp, char *path, int *gflags, int *used, Refer *re, int nent); /* transnt.c */ -int TNTquerysecurity(Session *, Share *, int, char **, char **); - -/* ping.c */ -int ping(char *, int); +extern int TNTquerysecurity(Session *s, Share *sp, int fh, char **usid, char **gsid); --- /sys/src/cmd/cifs/dfs.c Tue Jun 18 02:34:25 2013 +++ /sys/src/cmd/cifs/dfs.c Tue Jun 18 02:34:25 2013 @@ -5,7 +5,7 @@ * * The domain.dom is resolved in XP/Win2k etc using AD to do * a lookup (this is a consensus view, I don't think anyone - * has proved it). I cannot do this as AD needs Kerberos and + * has proved it). I cannot do this as AD needs Kerberos and * LDAP which I don't have. * * Instead I just use the NetBios names passed in the paths @@ -15,33 +15,34 @@ * * I have not added support for starting another instance of * cifs to connect to other servers referenced in DFS links, - * this is not a problem for me and I think it hides a load + * this is not a problem for me and I think it hides a load * of problems of its own wrt plan9's private namespaces. * * The proximity of my test server (AD enabled) is always 0 but some - * systems may report more meaningful values. The expiry time my is - * similarly zero so I guess at 5 mins. + * systems may report more meaningful values. The expiry time is + * similarly zero, so I guess at 5 mins. * - * If the redirection points to a "hidden" share (I.E. its name + * If the redirection points to a "hidden" share (i.e., its name * ends in a $) then the type of the redirection is 0 (unknown) even * though it is a CIFS share. * * It would be nice to add a check for which subnet a server is on * so our first choice is always the the server on the same subnet - * as us which replies to a ping (I.E. is up). This could short - * circuit the tests as the a server on the same sumnet will always + * as us which replies to a ping (i.e., is up). This could short- + * circuit the tests as the a server on the same subnet will always * be the fastest to get to. * * If I set Flags2_DFS then I don't see DFS links, I just get - * path not found (?!). + * path not found (?!). * * If I do a QueryFileInfo of a DFS link point (IE when I'am doing a walk) * Then I just see a directory, its not until I try to walk another level - * That I get "IO reparse tag not handled" error rather than "Path not covered". + * That I get "IO reparse tag not handled" error rather than + * "Path not covered". * * If I check the extended attributes of the QueryFileInfo in walk() then I can - * see this is a reparse point and so I can get the referral. The only problem here - * is that samba and the like may not support this. + * see this is a reparse point and so I can get the referral. The only + * problem here is that samba and the like may not support this. */ #include #include @@ -57,19 +58,19 @@ Exactmatch, /* perfect match found */ Badmatch /* matched but wrong case */ }; - -#define SINT_MAX (0x7fffffff) + +#define SINT_MAX 0x7fffffff typedef struct Dfscache Dfscache; struct Dfscache { - Dfscache *next; /* next entry */ - char *src; - char *host; - char *share; - char *path; - long expiry; /* expiry time in sec */ - long rtt; /* round trip time, nsec */ - int prox; /* proximity, lower = closer */ + Dfscache*next; /* next entry */ + char *src; + char *host; + char *share; + char *path; + long expiry; /* expiry time in sec */ + long rtt; /* round trip time, nsec */ + int prox; /* proximity, lower = closer */ }; Dfscache *Cache; @@ -138,23 +139,21 @@ char * mapfile(char *opath) { + int exact; Dfscache *cp; char *p, *path; static char npath[MAX_DFS_PATH]; path = opath; - if((cp = lookup(path, nil)) != nil){ - snprint(npath, sizeof(npath), "/%s%s%s%s", - cp->share, - (*cp->path)? "/": "", - cp->path, - path+strlen(cp->src)); + if((cp = lookup(path, &exact)) != nil){ + snprint(npath, sizeof npath, "/%s%s%s%s", cp->share, + *cp->path? "/": "", cp->path, path + strlen(cp->src)); path = npath; } if((p = strchr(path+1, '/')) == nil) p = "/"; - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print("mapfile src=%q => dst=%q\n", opath, p); return p; } @@ -177,33 +176,35 @@ continue; if(Checkcase && strcmp(cp->share, s) != 0) continue; - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print("mapshare, already connected, src=%q => dst=%q\n", path, sp->name); *osp = sp; return 0; } /* - * Try to autoconnect to share if it is not known. Note even if you didn't - * specify any shares and let the system autoconnect you may not already have - * the share you need as RAP (which we use) throws away names > 12 chars long. - * If we where to use RPC then this block of code would be less important, - * though it would still be useful to catch Shares added since cifs(1) was started. + * Try to autoconnect to share if it is not known. Note even if you + * didn't specify any shares and let the system autoconnect you may + * not already have the share you need as RAP (which we use) throws + * away names > 12 chars long. If we where to use RPC then this block + * of code would be less important, though it would still be useful + * to catch Shares added since cifs(1) was started. */ - sp = Shares+Nshares; + sp = Shares + Nshares; for(i = 0; i < 2; i++){ try = smprint("%s%s", cp->share, tail[i]); if(CIFStreeconnect(Sess, Sess->cname, try, sp) == 0){ sp->name = try; *osp = sp; Nshares++; - if(Debug && strstr(Debug, "dfs")) - print("mapshare connected, src=%q dst=%q\n", path, cp->share); + if(Debug && strstr(Debug, "dfs") != nil) + print("mapshare connected, src=%q dst=%q\n", + path, cp->share); return 0; } free(try); } - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print("mapshare failed src=%s\n", path); werrstr("not found"); return -1; @@ -213,7 +214,7 @@ * Rtt_tol is the fractional tollerance for RTT comparisons. * If a later (further down the list) host's RTT is less than * 1/Rtt_tol better than my current best then I don't bother - * with it. This biases me towards entries at the top of the list + * with it. This biases me towards entries at the top of the list * which Active Directory has already chosen for me and prevents * noise in RTTs from pushing me to more distant machines. */ @@ -231,7 +232,7 @@ Rtt_tol = 10 }; - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print(" remap %s\n", re->addr); for(p = re->addr; *p; p++) @@ -239,24 +240,24 @@ *p = '/'; if(cp->prox < re->prox){ - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print(" remap %d < %d\n", cp->prox, re->prox); return -1; } if((n = getfields(re->addr, a, sizeof(a), 0, "/")) < 3){ - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print(" remap nfields=%d\n", n); return -1; } if((rtt = ping(a[Hostname], Dfstout)) == -1){ - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print(" remap ping failed\n"); return -1; } if(cp->rtt < rtt && (rtt/labs(rtt-cp->rtt)) < Rtt_tol){ - if(Debug && strstr(Debug, "dfs")) - print(" remap bad ping %ld < %ld && %ld < %d\n", cp->rtt, - rtt, (rtt/labs(rtt-cp->rtt)), Rtt_tol); + if(Debug && strstr(Debug, "dfs") != nil) + print(" remap bad ping %ld < %ld && %ld < %d\n", + cp->rtt, rtt, (rtt/labs(rtt-cp->rtt)), Rtt_tol); return -1; } @@ -274,8 +275,8 @@ cp->host = estrdup9p(a[Hostname]); cp->share = estrdup9p(trimshare(a[Sharename])); cp->path = estrdup9p(a[Pathname]); - if(Debug && strstr(Debug, "dfs")) - print(" remap ping OK prox=%d host=%s share=%s path=%s\n", + if(Debug && strstr(Debug, "dfs") != nil) + print(" remap ping OK prox=%d host=%s share=%s path=%s\n", cp->prox, cp->host, cp->share, cp->path); return 0; } @@ -289,7 +290,8 @@ if(level > 8) return -1; - if((n = T2getdfsreferral(s, &Ipc, path, &gflags, &used, retab, nelem(retab))) == -1) + if((n = T2getdfsreferral(s, &Ipc, path, &gflags, &used, retab, + nelem(retab))) == -1) return -1; if(! (gflags & DFS_HEADER_ROOT)) @@ -297,25 +299,23 @@ found = 0; for(re = retab; re < retab+n; re++){ - if(Debug && strstr(Debug, "dfs")) - print("referal level=%d prox=%d path=%q addr=%q\n", + if(Debug && strstr(Debug, "dfs") != nil) + print("referal level=%d prox=%d path=%q addr=%q\n", level, re->prox, re->path, re->addr); if(gflags & DFS_HEADER_STORAGE){ if(remap(cp, re) == 0) found = 1; - } - else{ - if(redir1(s, re->addr, cp, level+1) != -1) /* ???? */ - + } else{ + if(redir1(s, re->addr, cp, level+1) != -1) /* ???? */ found = 1; } free(re->addr); free(re->path); } - - if(Debug && strstr(Debug, "dfs")) - print("referal level=%d path=%q found=%d used=%d\n", + + if(Debug && strstr(Debug, "dfs") != nil) + print("referal level=%d path=%q found=%d used=%d\n", level, path, found, used); if(!found) return -1; @@ -334,7 +334,7 @@ char *unc; Dfscache *cp; - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print("redirect name=%q path=%q\n", sp->name, path); cp = lookup(path, &match); @@ -343,47 +343,40 @@ if(cp && match == Exactmatch){ if(cp->expiry >= time(nil)){ /* cache hit */ - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print("redirect cache=hit src=%q => share=%q path=%q\n", cp->src, cp->share, cp->path); return 0; - } - else{ /* cache hit, but entry stale */ + } else{ /* cache hit, but entry stale */ cp->rtt = SINT_MAX; cp->prox = SINT_MAX; - - unc = smprint("//%s/%s/%s%s%s", - s->auth->windom, - cp->share, - cp->path, - (*cp->path)? "/": "", - path +strlen(cp->src)+1); + + unc = smprint("//%s/%s/%s%s%s", s->auth->windom, + cp->share, cp->path, *cp->path? "/": "", + path + strlen(cp->src) + 1); if(unc == nil) sysfatal("no memory: %r"); if(redir1(s, unc, cp, 1) == -1){ - if(Debug && strstr(Debug, "dfs")) - print("redirect refresh failed unc=%q\n", unc); + if(Debug && strstr(Debug, "dfs") != nil) + print("redirect refresh failed unc=%q\n", + unc); free(unc); return -1; } free(unc); - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print("redirect refresh cache=stale src=%q => share=%q path=%q\n", cp->src, cp->share, cp->path); return 0; } } - + /* in-exact match or complete miss */ if(cp) - unc = smprint("//%s/%s/%s%s%s", - s->auth->windom, - cp->share, - cp->path, - (*cp->path)? "/": "", - path +strlen(cp->src)+1); + unc = smprint("//%s/%s/%s%s%s", s->auth->windom, cp->share, + cp->path, *cp->path? "/": "", path + strlen(cp->src) + 1); else unc = smprint("//%s%s", s->auth->windom, path); if(unc == nil) @@ -395,7 +388,7 @@ cp->prox = SINT_MAX; if(redir1(s, unc, cp, 1) == -1){ - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print("redirect new failed unc=%q\n", unc); free(unc); free(cp); @@ -406,7 +399,7 @@ cp->src = estrdup9p(path); cp->next = Cache; Cache = cp; - if(Debug && strstr(Debug, "dfs")) + if(Debug && strstr(Debug, "dfs") != nil) print("redirect cache=miss src=%q => share=%q path=%q\n", cp->src, cp->share, cp->path); return 0; --- /sys/src/cmd/cifs/fs.c Tue Jun 18 02:34:25 2013 +++ /sys/src/cmd/cifs/fs.c Tue Jun 18 02:34:25 2013 @@ -8,7 +8,6 @@ static char *period(long sec); - int shareinfo(Fmt *f) { @@ -36,13 +35,13 @@ if(RAPshareinfo(Sess, sp, sp->name, &si2) != -1){ switch(si2.type){ - case STYPE_DISKTREE: type = "disk"; break; - case STYPE_PRINTQ: type = "printq"; break; - case STYPE_DEVICE: type = "device"; break; - case STYPE_IPC: type = "ipc"; break; - case STYPE_SPECIAL: type = "special"; break; - case STYPE_TEMP: type = "temp"; break; - default: type = "unknown"; break; + case STYPE_DISKTREE: type = "disk"; break; + case STYPE_PRINTQ: type = "printq"; break; + case STYPE_DEVICE: type = "device"; break; + case STYPE_IPC: type = "ipc"; break; + case STYPE_SPECIAL: type = "special"; break; + case STYPE_TEMP: type = "temp"; break; + default: type = "unknown"; break; } fmtprint(f, "%-8s %5d/%-5d %s", type, @@ -89,11 +88,10 @@ { int i; typedef struct { - int val; - char *name; + int val; + char *name; } Tab; - - Tab captab[] = { + static Tab captab[] = { { 1, "raw-mode" }, { 2, "mpx-mode" }, { 4, "unicode" }, @@ -113,8 +111,7 @@ { 0x40000000, "compressed" }, { 0x80000000, "extended-security" }, }; - - Tab sectab[] = { + static Tab sectab[] = { { 1, "user-auth" }, { 2, "challange-response" }, { 4, "signing-available" }, @@ -124,7 +121,7 @@ fmtprint(f, "%q %q %q %q %+ldsec %dmtu %s\n", Sess->auth->user, Sess->cname, Sess->auth->windom, Sess->remos, - Sess->slip, Sess->mtu, (Sess->isguest)? "as guest": ""); + Sess->slip, Sess->mtu, Sess->isguest? "as guest": ""); fmtprint(f, "caps: "); for(i = 0; i < nelem(captab); i++) @@ -177,11 +174,11 @@ * names of the domain controllers for that domain. * * We get a DNS domain name for each domain controller as well as a - * netbios name. I THINK I am correct in saying that a name - * containing a dot ('.') must be a DNS name as the NetBios - * name munging cannot encode one. Thus names which contain no + * netbios name. I THINK I am correct in saying that a name + * containing a dot ('.') must be a DNS name, as the NetBios + * name munging cannot encode one. Thus names which contain no * dots must be netbios names. - * + * */ static void dfsredir(Fmt *f, char *path, int depth) @@ -189,7 +186,8 @@ Refer *re, retab[128]; int n, used, flags; - if((n = T2getdfsreferral(Sess, &Ipc, path, &flags, &used, retab, nelem(retab))) == -1) + n = T2getdfsreferral(Sess, &Ipc, path, &flags, &used, retab, nelem(retab)); + if(n == -1) return; for(re = retab; re < retab+n; re++){ if(strcmp(path, re->path) != 0) @@ -228,8 +226,7 @@ fmtprint(f, "%-24q ", nl[i].name); if(RAPuserinfo(Sess, &Ipc, nl[i].name, &ui) != -1){ - fmtprint(f, "%-48q %q", - ui.fullname, ui.comment); + fmtprint(f, "%-48q %q", ui.fullname, ui.comment); free(ui.user); free(ui.comment); free(ui.fullname); @@ -276,32 +273,32 @@ { int more, got, i, j; Serverinfo *si; - char *types[] = { + static char *types[] = { [0] "workstation", [1] "server", - [2] "SQL", + [2] "SQL server", [3] "DC", - [4] "BDC", - [5] "time", - [6] "Apple", - [7] "NetWare", - [8] nil, // domain member + [4] "backup DC", + [5] "time source", + [6] "Apple server", + [7] "Novell server", + [8] "domain member", [9] "printer server", [10] "dial-up server", [11] "Unix", [12] "NT", [13] "WFW", - [14] "MFPN", // DEC pathworks ? + [14] "MFPN (?)", [15] "NT server", - [16] nil, // potential master browser - [17] "BMB", + [16] "potential browser", + [17] "backup browser", [18] "LMB", [19] "DMB", [20] "OSF Unix", [21] "VMS", [22] "Win95", [23] "DFS", - [24] "Cluster", + [24] "NT cluster", [25] "Terminal server", [26] "[26]", [27] "[27]", @@ -309,12 +306,14 @@ }; si = nil; - if((got = RAPServerenum2(Sess, &Ipc, Sess->auth->windom, type, &more, &si)) == -1){ + if((got = RAPServerenum2(Sess, &Ipc, Sess->auth->windom, type, &more, + &si)) == -1){ fmtprint(f, "RAPServerenum2: %r\n"); return 0; } if(more) - if((got = RAPServerenum3(Sess, &Ipc, Sess->auth->windom, type, got-1, si)) == -1){ + if((got = RAPServerenum3(Sess, &Ipc, Sess->auth->windom, type, + got-1, si)) == -1){ fmtprint(f, "RAPServerenum3: %r\n"); return 0; } @@ -353,7 +352,7 @@ int days, hrs, min; static char when[32]; - days = sec / (60L * 60L * 24L); + days = sec / (60L * 60L * 24L); sec -= days * (60L * 60L * 24L); hrs = sec / (60L * 60L); sec -= hrs * (60L * 60L); @@ -365,5 +364,3 @@ snprint(when, sizeof(when), "%d:%d:%ld ", hrs, min, sec); return when; } - - --- /sys/src/cmd/cifs/main.c Tue Jun 18 02:34:25 2013 +++ /sys/src/cmd/cifs/main.c Tue Jun 18 02:34:25 2013 @@ -25,9 +25,9 @@ }; extern int chatty9p; -extern int Checkcase = 1; -int Dfstout = 100; /* timeout (in ms) for ping of dfs servers (assume they are local) */ +int Checkcase = 1; /* enforce case significance on filenames */ +int Dfstout = 100; /* timeout (in ms) for ping of dfs servers (assume they are local) */ int Billtrog = 1; /* enable file owner/group resolution */ int Attachpid; /* pid of proc that attaches (ugh !) */ char *Debug = nil; /* messages */ @@ -41,6 +41,8 @@ Aux *Auxroot = nil; /* linked list of Aux structs */ char *Host = nil; /* host we are connected to */ +static char *Ipcname = "IPC$"; + #define ptype(x) (((x) & 0xf)) #define pindex(x) (((x) & 0xff0) >> 4) @@ -94,12 +96,14 @@ } u; sha1((uchar *)s, strlen(s), u.digest, nil); - q.type = is_dir? QTDIR: 0; + q.type = (is_dir)? QTDIR: 0; q.vers = vers; if(subtype){ q.path = *((uvlong *)u.digest) & ~0xfffL; - q.path |= (path & 0xff) << 4 | (subtype & 0xf); - }else + q.path |= ((path & 0xff) << 4); + q.path |= (subtype & 0xf); + } + else q.path = *((uvlong *)u.digest) & ~0xfL; return q; } @@ -188,12 +192,15 @@ static int dirgen(int slot, Dir *d, void *aux) { - int numinf = numinfo(), rc, got; - int slots = min(Sess->mtu, MTU) / sizeof(FInfo); long off; - char *npath; - Aux *a = aux; FInfo *fi; + int rc, got; + Aux *a = aux; + char *npath; + int numinf = numinfo(); + int slots; + + slots = 128; /* number of dir entries to fetch at one time */ if(strcmp(a->path, "/") == 0){ if(slot < numinf){ @@ -268,9 +275,9 @@ static void fsattach(Req *r) { - char *spec = r->ifcall.aname; Aux *a; static int first = 1; + char *spec = r->ifcall.aname; if(first) setup(); @@ -354,36 +361,33 @@ return 1; if(strcmp(winpath, "/") == 0){ share = trimshare(sp->name); - if(cistrcmp(want, share) == 0){ - if(strcmp(want, share) == 0) - return 1; - else - return 0; - } + if(cistrcmp(want, share) == 0) + return strcmp(want, share) == 0; /* * OK, a DFS redirection points us from a directory XXX - * to a share named YYY. There is no casechecking we can - * do so we allow either case - its all we can do + * to a share named YYY. There is no case checking we can + * do so we allow either case - it's all we can do. */ return 1; } if(cistrcmp(found, want) != 0) return 0; - if(! Checkcase) + if(!Checkcase) return 1; if(strcmp(found, want) == 0) return 1; return 0; } + static char* fswalk1(Fid *fid, char *name, Qid *qid) { + FInfo fi; int rc, n, i; - char *p, *npath, *winpath; Aux *a = fid->aux; - FInfo fi; static char e[ERRMAX]; + char *p, *npath, *winpath; *e = 0; npath = newpath(a->path, name); @@ -399,7 +403,7 @@ if((n = walkinfo(name)) != -1){ /* info file */ *qid = mkqid(npath, 0, 1, Pinfo, n); } - else { /* share name */ + else { /* volume name */ for(i = 0; i < Nshares; i++){ n = strlen(Shares[i].name); if(cistrncmp(npath+1, Shares[i].name, n) != 0) @@ -454,7 +458,7 @@ p = fi.name; else p++; - + if(! validfile(p, name, winpath, a->sp)){ free(npath); return "not found"; @@ -538,15 +542,8 @@ access = 2; break; case OEXEC: - werrstr("will not exec via cifs"); - return -1; - /* Files called ls or cat are possible on a Windows share, - * however they are unlikely to be plan9 exeutables, - * so we fail attempts to exec(2) them. - * - * access = 3; - * break; - */ + access = 3; + break; default: werrstr("%d bad open mode", mode & OMASK); return -1; @@ -622,15 +619,8 @@ access = GENERIC_ALL; break; case OEXEC: - werrstr("will not exec via cifs"); - return -1; - /* Files called ls or cat are possible on a Windows share, - * however they are unlikely to be plan9 exeutables. - * so we fail attempts to exec(2) them. - * - * access = GENERIC_EXECUTE; - * break; - */ + access = GENERIC_EXECUTE; + break; default: werrstr("%d bad open mode", mode & OMASK); return -1; @@ -672,10 +662,10 @@ static void fscreate(Req *r) { + FInfo fi; int rc, is_dir; char *npath; Aux *a = r->fid->aux; - FInfo fi; a->end = a->off = 0; a->cache = emalloc9p(max(Sess->mtu, MTU)); @@ -743,9 +733,11 @@ static void fswrite(Req *r) { - vlong n, m, got, len = r->ifcall.count, off = r->ifcall.offset; - char *buf = r->ifcall.data; + vlong n, m, got; Aux *a = r->fid->aux; + vlong len = r->ifcall.count; + vlong off = r->ifcall.offset; + char *buf = r->ifcall.data; got = 0; n = Sess->mtu -OVERHEAD; @@ -767,9 +759,11 @@ static void fsread(Req *r) { - vlong n, m, got, len = r->ifcall.count, off = r->ifcall.offset; - char *buf = r->ofcall.data; + vlong n, m, got; Aux *a = r->fid->aux; + char *buf = r->ofcall.data; + vlong len = r->ifcall.count; + vlong off = r->ifcall.offset; if(ptype(r->fid->qid.path) == Pinfo){ r->ofcall.count = readinfo(pindex(r->fid->qid.path), buf, len, @@ -903,9 +897,9 @@ fswstat(Req *r) { int fh, result, rc; + FInfo fi, tmpfi; char *p, *from, *npath; Aux *a = r->fid->aux; - FInfo fi, tmpfi; if(ptype(r->fid->qid.path) == Proot || ptype(r->fid->qid.path) == Pshare){ @@ -1025,11 +1019,12 @@ * always update the readonly flag as * we may have cleared it above. */ - if(~r->d.mode) + if(~r->d.mode){ if(r->d.mode & 0222) fi.attribs &= ~ATTR_READONLY; else fi.attribs |= ATTR_READONLY; + } if(rdonly(Sess, a->sp, mapfile(a->path), fi.attribs & ATTR_READONLY) == -1){ werrstr("(set info) - %r"); responderrstr(r); @@ -1094,9 +1089,9 @@ static void keepalive(void) { - int fd, i, rc = 0; - uvlong tot, fre; char buf[32]; + uvlong tot, fre; + int fd, i, slot, rc; snprint(buf, sizeof buf, "#p/%d/args", getpid()); if((fd = open(buf, OWRITE)) >= 0){ @@ -1104,13 +1099,19 @@ close(fd); } + rc = 0; + slot = 0; do{ sleep(6000); if(Active-- != 0) continue; - for(i = 0; i < Nshares; i++) - if((rc = T2fssizeinfo(Sess, Shares+i, &tot, &fre)) != -1) + + for(i = 0; i < Nshares; i++){ + if((rc = T2fssizeinfo(Sess, &Shares[slot], &tot, &fre)) == 0) break; + if(++slot >= Nshares) + slot = 0; + } }while(rc != -1); postnote(PNPROC, Attachpid, "die"); } @@ -1129,7 +1130,7 @@ dmpkey(char *s, void *v, int n) { int i; - uchar *p = (uchar *)v; + unsigned char *p = (unsigned char *)v; print("%s", s); for(i = 0; i < n; i++) @@ -1178,7 +1179,7 @@ break; case 'n': strncpy(cname, EARGF(usage()), sizeof(cname)); - cname[sizeof(cname) -1] = 0; + cname[sizeof(cname) - 1] = 0; break; case 's': svs = EARGF(usage()); @@ -1213,6 +1214,7 @@ if((Sess = cifsdial(Host, Host, sysname)) != nil || (Sess = cifsdial(Host, "*SMBSERVER", sysname)) != nil) goto connected; + sysfatal("%s - cannot dial, %r\n", Host); connected: if(CIFSnegotiate(Sess, &svrtime, windom, sizeof windom, cname, sizeof cname) == -1) @@ -1229,10 +1231,10 @@ sysfatal("session authentication failed, %r\n"); Sess->slip = svrtime - time(nil); - Sess->cname = strlwr(estrdup9p(cname)); + Sess->cname = estrdup9p(cname); - if(CIFStreeconnect(Sess, cname, "IPC$", &Ipc) == -1) - fprint(2, "%s, %r - can't connect\n", "IPC$"); + if(CIFStreeconnect(Sess, cname, Ipcname, &Ipc) == -1) + fprint(2, "%s, %r - can't connect\n", Ipcname); Nshares = 0; if(argc == 1){ @@ -1245,6 +1247,7 @@ for(i = 0; i < n; i++){ #ifdef NO_HIDDEN_SHARES int l = strlen(sip[i].name); + if(l > 1 && sip[i].name[l-1] == '$'){ free(sip[i].name); continue; @@ -1253,6 +1256,8 @@ memcpy(Shares+Nshares, sip+i, sizeof(Share)); if(CIFStreeconnect(Sess, Sess->cname, Shares[Nshares].name, Shares+Nshares) == -1){ + fprint(2, "%s: %s %q - can't connect to share" + ", %r\n", argv0, Host, Shares[Nshares].name); free(Shares[Nshares].name); continue; } @@ -1263,11 +1268,11 @@ for(i = 1; i < argc; i++){ if(CIFStreeconnect(Sess, Sess->cname, argv[i], Shares+Nshares) == -1){ - fprint(2, "%s: %s %q - can't connect to share" + fprint(2, "%s: %s %q - can't connect to share" ", %r\n", argv0, Host, argv[i]); continue; } - Shares[Nshares].name = estrdup9p(argv[i]); + Shares[Nshares].name = strlwr(estrdup9p(argv[i])); Nshares++; } --- /sys/src/cmd/cifs/mkfile Tue Jun 18 02:34:25 2013 +++ /sys/src/cmd/cifs/mkfile Tue Jun 18 02:34:25 2013 @@ -11,4 +11,3 @@ auth.$O dfs.$O ping.$O flags2 & FL2_UNICODE){ + if(((p->pos - p->buf) % 2) != 0) + g8(p); /* strip padding to even offset */ + i = 0; while(*p->pos && n && p->pos < p->eop){ r = gl16(p);