mirror of
https://github.com/samba-team/samba.git
synced 2024-12-28 07:21:54 +03:00
several clientgen mods to support smbwrapper. In particular added
cli_list() for directory listing and expended some other functions a bit.
This commit is contained in:
parent
688d19de50
commit
9bae21abaf
@ -847,7 +847,6 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
create a directory
|
||||
****************************************************************************/
|
||||
@ -1259,7 +1258,8 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t)
|
||||
send a qpathinfo call
|
||||
****************************************************************************/
|
||||
BOOL cli_qpathinfo(struct cli_state *cli, char *fname,
|
||||
time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size)
|
||||
time_t *c_time, time_t *a_time, time_t *m_time,
|
||||
uint32 *size, int *mode)
|
||||
{
|
||||
int data_len = 0;
|
||||
int param_len = 0;
|
||||
@ -1305,6 +1305,9 @@ BOOL cli_qpathinfo(struct cli_state *cli, char *fname,
|
||||
if (size) {
|
||||
*size = IVAL(rdata, 12);
|
||||
}
|
||||
if (mode) {
|
||||
*mode = SVAL(rdata,l1_attrFile);
|
||||
}
|
||||
|
||||
if (rdata) free(rdata);
|
||||
if (rparam) free(rparam);
|
||||
@ -1376,7 +1379,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, char *fname,
|
||||
send a qfileinfo call
|
||||
****************************************************************************/
|
||||
BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
|
||||
time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size)
|
||||
time_t *c_time, time_t *a_time, time_t *m_time,
|
||||
uint32 *size, int *mode)
|
||||
{
|
||||
int data_len = 0;
|
||||
int param_len = 0;
|
||||
@ -1422,12 +1426,277 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
|
||||
if (size) {
|
||||
*size = IVAL(rdata, 12);
|
||||
}
|
||||
if (mode) {
|
||||
*mode = SVAL(rdata,l1_attrFile);
|
||||
}
|
||||
|
||||
if (rdata) free(rdata);
|
||||
if (rparam) free(rparam);
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
interpret a long filename structure - this is mostly guesses at the moment
|
||||
The length of the structure is returned
|
||||
The structure of a long filename depends on the info level. 260 is used
|
||||
by 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 */
|
||||
finfo->mode = CVAL(p,0); p += 4;
|
||||
namelen = IVAL(p,0); p += 4;
|
||||
p += 4; /* EA size */
|
||||
p += 2; /* short name len? */
|
||||
p += 24; /* short name? */
|
||||
StrnCpy(finfo->name,p,namelen);
|
||||
return(ret);
|
||||
}
|
||||
return(SVAL(p,0));
|
||||
}
|
||||
|
||||
DEBUG(1,("Unknown long filename format %d\n",level));
|
||||
return(SVAL(p,0));
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
do a directory listing, calling fn on each file found
|
||||
****************************************************************************/
|
||||
int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info *))
|
||||
{
|
||||
int max_matches = 512;
|
||||
/* NT uses 260, OS/2 uses 2. Both accept 1. */
|
||||
int info_level = cli->protocol<PROTOCOL_NT1?1:260;
|
||||
char *p, *p2;
|
||||
pstring mask;
|
||||
file_info finfo;
|
||||
int i;
|
||||
char *dirlist = NULL;
|
||||
int dirlist_len = 0;
|
||||
int total_received = 0;
|
||||
BOOL First = True;
|
||||
int ff_resume_key = 0;
|
||||
int ff_searchcount=0;
|
||||
int ff_eos=0;
|
||||
int ff_lastname=0;
|
||||
int ff_dir_handle=0;
|
||||
int loop_count = 0;
|
||||
char *rparam=NULL, *rdata=NULL;
|
||||
int param_len, data_len;
|
||||
|
||||
uint16 setup;
|
||||
pstring param;
|
||||
|
||||
pstrcpy(mask,Mask);
|
||||
|
||||
while (ff_eos == 0) {
|
||||
loop_count++;
|
||||
if (loop_count > 200) {
|
||||
DEBUG(0,("Error: Looping in FIND_NEXT??\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
param_len = 12+strlen(mask)+1;
|
||||
|
||||
if (First) {
|
||||
setup = TRANSACT2_FINDFIRST;
|
||||
SSVAL(param,0,attribute); /* attribute */
|
||||
SSVAL(param,2,max_matches); /* max count */
|
||||
SSVAL(param,4,8+4+2); /* resume required + close on end + continue */
|
||||
SSVAL(param,6,info_level);
|
||||
SIVAL(param,8,0);
|
||||
pstrcpy(param+12,mask);
|
||||
} else {
|
||||
setup = TRANSACT2_FINDNEXT;
|
||||
SSVAL(param,0,ff_dir_handle);
|
||||
SSVAL(param,2,max_matches); /* max count */
|
||||
SSVAL(param,4,info_level);
|
||||
SIVAL(param,6,ff_resume_key); /* ff_resume_key */
|
||||
SSVAL(param,10,8+4+2); /* resume required + close on end + continue */
|
||||
pstrcpy(param+12,mask);
|
||||
|
||||
DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
|
||||
ff_dir_handle,ff_resume_key,ff_lastname,mask));
|
||||
}
|
||||
|
||||
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, 0,
|
||||
cli->max_xmit /* data, length, max */
|
||||
)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!cli_receive_trans(cli, SMBtrans2,
|
||||
&rparam, ¶m_len,
|
||||
&rdata, &data_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* parse out some important return info */
|
||||
p = rparam;
|
||||
if (First) {
|
||||
ff_dir_handle = SVAL(p,0);
|
||||
ff_searchcount = SVAL(p,2);
|
||||
ff_eos = SVAL(p,4);
|
||||
ff_lastname = SVAL(p,8);
|
||||
} else {
|
||||
ff_searchcount = SVAL(p,0);
|
||||
ff_eos = SVAL(p,2);
|
||||
ff_lastname = SVAL(p,6);
|
||||
}
|
||||
|
||||
if (ff_searchcount == 0)
|
||||
break;
|
||||
|
||||
/* point to the data bytes */
|
||||
p = rdata;
|
||||
|
||||
/* we might need the lastname for continuations */
|
||||
if (ff_lastname > 0) {
|
||||
switch(info_level)
|
||||
{
|
||||
case 260:
|
||||
ff_resume_key =0;
|
||||
StrnCpy(mask,p+ff_lastname,
|
||||
data_len-ff_lastname);
|
||||
break;
|
||||
case 1:
|
||||
pstrcpy(mask,p + ff_lastname + 1);
|
||||
ff_resume_key = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
pstrcpy(mask,"");
|
||||
}
|
||||
|
||||
/* and add them to the dirlist pool */
|
||||
dirlist = Realloc(dirlist,dirlist_len + data_len);
|
||||
|
||||
if (!dirlist) {
|
||||
DEBUG(0,("Failed to expand dirlist\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
/* put in a length for the last entry, to ensure we can chain entries
|
||||
into the next packet */
|
||||
for (p2=p,i=0;i<(ff_searchcount-1);i++)
|
||||
p2 += interpret_long_filename(info_level,p2,NULL);
|
||||
SSVAL(p2,0,data_len - PTR_DIFF(p2,p));
|
||||
|
||||
/* grab the data for later use */
|
||||
memcpy(dirlist+dirlist_len,p,data_len);
|
||||
dirlist_len += data_len;
|
||||
|
||||
total_received += ff_searchcount;
|
||||
|
||||
if (rdata) free(rdata); rdata = NULL;
|
||||
if (rparam) free(rparam); rparam = NULL;
|
||||
|
||||
DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
|
||||
ff_searchcount,ff_eos,ff_resume_key));
|
||||
|
||||
First = False;
|
||||
}
|
||||
|
||||
for (p=dirlist,i=0;i<total_received;i++) {
|
||||
p += interpret_long_filename(info_level,p,&finfo);
|
||||
fn(&finfo);
|
||||
}
|
||||
|
||||
/* free up the dirlist buffer */
|
||||
if (dirlist) free(dirlist);
|
||||
return(total_received);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Send a SamOEMChangePassword command
|
||||
****************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user