diff options
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/clilist.c | 146 |
1 files changed, 144 insertions, 2 deletions
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index f2e42be523..74b908ae58 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -160,8 +160,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; - int param_len, data_len; - + int param_len, data_len; uint16 setup; pstring param; @@ -302,3 +301,146 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, return(total_received); } + + +/**************************************************************************** +interpret a short filename structure +The length of the structure is returned +****************************************************************************/ +static int interpret_short_filename(char *p,file_info *finfo) +{ + extern file_info def_finfo; + + *finfo = def_finfo; + + finfo->mode = CVAL(p,21); + + /* this date is converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date(p+22); + finfo->mtime = finfo->atime = finfo->ctime; + finfo->size = IVAL(p,26); + pstrcpy(finfo->name,p+30); + if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) + fstrcpy(finfo->short_name,finfo->name); + + return(DIR_STRUCT_SIZE); +} + + +/**************************************************************************** + do a directory listing, calling fn on each file found + this uses the old SMBsearch interface. It is needed for testing Samba, + but should otherwise not be used + ****************************************************************************/ +int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *)) +{ + char *p; + int received = 0; + BOOL first = True; + char status[21]; + int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; + int num_received = 0; + int i; + char *dirlist = NULL; + pstring mask; + + ZERO_ARRAY(status); + + pstrcpy(mask,Mask); + + while (1) { + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + if (first) + set_message(cli->outbuf,2,5 + strlen(mask),True); + else + set_message(cli->outbuf,2,5 + 21,True); + + CVAL(cli->outbuf,smb_com) = SMBffirst; + + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,num_asked); + SSVAL(cli->outbuf,smb_vwv1,attribute); + + p = smb_buf(cli->outbuf); + *p++ = 4; + + if (first) + pstrcpy(p,mask); + else + pstrcpy(p,""); + p += strlen(p) + 1; + + *p++ = 5; + if (first) { + SSVAL(p,0,0); + } else { + SSVAL(p,0,21); + p += 2; + memcpy(p,status,21); + } + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) break; + + received = SVAL(cli->inbuf,smb_vwv0); + if (received <= 0) break; + + first = False; + + dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + + if (!dirlist) + return 0; + + p = smb_buf(cli->inbuf) + 3; + + memcpy(dirlist+num_received*DIR_STRUCT_SIZE, + p,received*DIR_STRUCT_SIZE); + + memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21); + + num_received += received; + + if (CVAL(cli->inbuf,smb_rcls) != 0) break; + } + + if (!first) { + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,0,6,True); + CVAL(cli->outbuf,smb_com) = SMBfclose; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + + pstrcpy(p,""); + p += strlen(p) + 1; + + *p++ = 5; + SSVAL(p,0,21); + p += 2; + memcpy(p,status,21); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); + } + } + + for (p=dirlist,i=0;i<num_received;i++) { + file_info finfo; + p += interpret_short_filename(p,&finfo); + fn(&finfo, Mask); + } + + if (dirlist) free(dirlist); + return(num_received); +} |