summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/clilist.c146
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);
+}