📄 clientgen.c
字号:
bwritten += SVAL(cli->inbuf, smb_vwv2); } while (received < issued && cli_receive_smb(cli)) { received++; } return bwritten;}/**************************************************************************** write to a file using a SMBwrite and not bypassing 0 byte writes****************************************************************************/ssize_t cli_smbwrite(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size){ char *p; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,5, 3 + size,True); CVAL(cli->outbuf,smb_com) = SMBwrite; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,fnum); SSVAL(cli->outbuf,smb_vwv1,size); SIVAL(cli->outbuf,smb_vwv2,offset); SSVAL(cli->outbuf,smb_vwv4,0); p = smb_buf(cli->outbuf); *p++ = 1; SSVAL(p, 0, size); memcpy(p+2, buf, size); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } if (CVAL(cli->inbuf,smb_rcls) != 0) { return -1; } return SVAL(cli->inbuf,smb_vwv0);}/****************************************************************************do a SMBgetattrE call****************************************************************************/BOOL cli_getattrE(struct cli_state *cli, int fd, uint16 *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time){ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,2,0,True); CVAL(cli->outbuf,smb_com) = SMBgetattrE; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,fd); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } if (CVAL(cli->inbuf,smb_rcls) != 0) { return False; } if (size) { *size = IVAL(cli->inbuf, smb_vwv6); } if (attr) { *attr = SVAL(cli->inbuf,smb_vwv10); } if (c_time) { *c_time = make_unix_date3(cli->inbuf+smb_vwv0); } if (a_time) { *a_time = make_unix_date3(cli->inbuf+smb_vwv2); } if (m_time) { *m_time = make_unix_date3(cli->inbuf+smb_vwv4); } return True;}/****************************************************************************do a SMBgetatr call****************************************************************************/BOOL cli_getatr(struct cli_state *cli, char *fname, uint16 *attr, size_t *size, time_t *t){ char *p; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,0,strlen(fname)+2,True); CVAL(cli->outbuf,smb_com) = SMBgetatr; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); *p = 4; pstrcpy(p+1, fname); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } if (CVAL(cli->inbuf,smb_rcls) != 0) { return False; } if (size) { *size = IVAL(cli->inbuf, smb_vwv3); } if (t) { *t = make_unix_date3(cli->inbuf+smb_vwv1); } if (attr) { *attr = SVAL(cli->inbuf,smb_vwv0); } return True;}/****************************************************************************do a SMBsetatr call****************************************************************************/BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t){ char *p; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,8,strlen(fname)+4,True); CVAL(cli->outbuf,smb_com) = SMBsetatr; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0, attr); put_dos_date3(cli->outbuf,smb_vwv1, t); p = smb_buf(cli->outbuf); *p = 4; pstrcpy(p+1, fname); p = skip_string(p,1); *p = 4; cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } if (CVAL(cli->inbuf,smb_rcls) != 0) { return False; } return True;}/****************************************************************************send a qpathinfo call****************************************************************************/BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, size_t *size, uint16 *mode){ int data_len = 0; int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; int count=8; BOOL ret; time_t (*date_fn)(void *); param_len = strlen(fname) + 7; memset(param, 0, param_len); SSVAL(param, 0, SMB_INFO_STANDARD); pstrcpy(¶m[6], fname); do { ret = (cli_send_trans(cli, SMBtrans2, NULL, 0, /* Name, length */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, data_len, cli->max_xmit /* data, length, max */ ) && cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)); if (!ret) { /* we need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; cli_error(cli, &eclass, &ecode, NULL); if (eclass != ERRSRV || ecode != ERRerror) break; msleep(100); } } while (count-- && ret==False); if (!ret || !rdata || data_len < 22) { return False; } if (cli->win95) { date_fn = make_unix_date; } else { date_fn = make_unix_date2; } if (c_time) { *c_time = date_fn(rdata+0); } if (a_time) { *a_time = date_fn(rdata+4); } if (m_time) { *m_time = date_fn(rdata+8); } if (size) { *size = IVAL(rdata, 12); } if (mode) { *mode = SVAL(rdata,l1_attrFile); } if (rdata) free(rdata); if (rparam) free(rparam); return True;}/****************************************************************************send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level****************************************************************************/BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, size_t *size, uint16 *mode, SMB_INO_T *ino){ int data_len = 0; int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; param_len = strlen(fname) + 7; memset(param, 0, param_len); SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); pstrcpy(¶m[6], fname); if (!cli_send_trans(cli, SMBtrans2, NULL, 0, /* name, length */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, data_len, cli->max_xmit /* data, length, max */ )) { return False; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { return False; } if (!rdata || data_len < 22) { return False; } if (c_time) { *c_time = interpret_long_date(rdata+0) - cli->serverzone; } if (a_time) { *a_time = interpret_long_date(rdata+8) - cli->serverzone; } if (m_time) { *m_time = interpret_long_date(rdata+16) - cli->serverzone; } if (w_time) { *w_time = interpret_long_date(rdata+24) - cli->serverzone; } if (mode) { *mode = SVAL(rdata, 32); } if (size) { *size = IVAL(rdata, 48); } if (ino) { *ino = IVAL(rdata, 64); } if (rdata) free(rdata); if (rparam) free(rparam); return True;}/****************************************************************************send a qfileinfo call****************************************************************************/BOOL cli_qfileinfo(struct cli_state *cli, int fnum, uint16 *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino){ int data_len = 0; int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; /* if its a win95 server then fail this - win95 totally screws it up */ if (cli->win95) return False; param_len = 4; memset(param, 0, param_len); SSVAL(param, 0, fnum); SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); if (!cli_send_trans(cli, SMBtrans2, NULL, 0, /* name, length */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ NULL, data_len, cli->max_xmit /* data, length, max */ )) { return False; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { return False; } if (!rdata || data_len < 68) { return False; } if (c_time) { *c_time = interpret_long_date(rdata+0) - cli->serverzone; } if (a_time) { *a_time = interpret_long_date(rdata+8) - cli->serverzone; } if (m_time) { *m_time = interpret_long_date(rdata+16) - cli->serverzone; } if (w_time) { *w_time = interpret_long_date(rdata+24) - cli->serverzone; } if (mode) { *mode = SVAL(rdata, 32); } if (size) { *size = IVAL(rdata, 48); } if (ino) { *ino = IVAL(rdata, 64); } if (rdata) free(rdata); if (rparam) free(rparam); return True;}/****************************************************************************interpret a long filename structure - this is mostly guesses at the momentThe length of the structure is returnedThe structure of a long filename depends on the info level. 260 is usedby NT and 2 is used by OS/2****************************************************************************/static int interpret_long_filename(int level,char *p,file_info *finfo){ extern file_info def_finfo; if (finfo) memcpy(finfo,&def_finfo,sizeof(*finfo)); switch (level) { case 1: /* OS/2 understands this */ if (finfo) { /* these dates are converted to GMT by make_unix_date */ finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); pstrcpy(finfo->name,p+27); } return(28 + CVAL(p,26)); case 2: /* this is what OS/2 uses mostly */ if (finfo) { /* these dates are converted to GMT by make_unix_date */ finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); pstrcpy(finfo->name,p+31); } return(32 + CVAL(p,30)); /* levels 3 and 4 are untested */ case 3: if (finfo) { /* these dates are probably like the other ones */ finfo->ctime = make_unix_date2(p+8); finfo->atime = make_unix_date2(p+12); finfo->mtime = make_unix_date2(p+16); finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); pstrcpy(finfo->name,p+33); } return(SVAL(p,4)+4); case 4: if (finfo) { /* these dates are probably like the other ones */ finfo->ctime = make_unix_date2(p+8); finfo->atime = make_unix_date2(p+12); finfo->mtime = make_unix_date2(p+16); finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); pstrcpy(finfo->name,p+37); } return(SVAL(p,4)+4); case 260: /* NT uses this, but also accepts 2 */ if (finfo) { int ret = SVAL(p,0); int namelen; p += 4; /* next entry offset */ p += 4; /* fileindex */ /* these dates appear to arrive in a weird way. It seems to be localtime plus the serverzone given in the initial connect. This is GMT when DST is not in effect and one hour from GMT otherwise. Can this really be right?? I suppose this could be called kludge-GMT. Is is the GMT you get by using the current DST setting on a different localtime. It will be cheap to calculate, I suppose, as no DST tables will be needed */ finfo->ctime = interpret_long_date(p); p += 8; finfo->atime = interpret_long_date(p); p += 8; finfo->mtime = interpret_long_date(p); p += 8; p += 8; finfo->size = IVAL(p,0); p += 8; p += 8; /* alloc size */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -