diff options
-rw-r--r-- | source3/client/client.c | 218 |
1 files changed, 152 insertions, 66 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index 9c167e20c2..a8f11fc659 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1117,27 +1117,50 @@ static void cmd_put(void) do_put(rname,lname); } +/************************************* + File list structure +*************************************/ + +static struct file_list { + struct file_list *prev, *next; + char *file_path; + BOOL isdir; +} *file_list; + +/**************************************************************************** + Free a file_list structure +****************************************************************************/ + +static void free_file_list (struct file_list * list) +{ + struct file_list *tmp; + + while (list) + { + tmp = list; + DLIST_REMOVE(list, list); + if (tmp->file_path) free(tmp->file_path); + free(tmp); + } +} /**************************************************************************** seek in a directory/file list until you get something that doesn't start with the specified name ****************************************************************************/ -static BOOL seek_list(FILE *f,char *name) +static BOOL seek_list(struct file_list *list, char *name) { - pstring s; - while (!feof(f)) { - if (!fgets(s,sizeof(s),f)) return(False); - trim_string(s,"./","\n"); - if (strncmp(s,name,strlen(name)) != 0) { - pstrcpy(name,s); + while (list) { + trim_string(list->file_path,"./","\n"); + if (strncmp(list->file_path, name, strlen(name)) != 0) { return(True); } + list = list->next; } return(False); } - /**************************************************************************** set the file selection mask ****************************************************************************/ @@ -1149,88 +1172,151 @@ static void cmd_select(void) /**************************************************************************** + Recursive file matching function act as find + match must be always set to True when calling this function +****************************************************************************/ + +static int file_find(struct file_list **list, const char *directory, + const char *expression, BOOL match) +{ + struct dirent **namelist; + struct file_list *entry; + struct stat statbuf; + int n, ret; + char *path; + BOOL isdir; + + n = scandir(directory, &namelist, 0, alphasort); + if (n == -1) return -1; + + while (n--) { + int len = NAMLEN(namelist[n]); + char *dname = malloc(len+1); + if (!dname) continue; + + memcpy(dname, namelist[n]->d_name, len); + dname[len] = 0; + + if (!strcmp("..", dname)) continue; + if (!strcmp(".", dname)) continue; + + if (asprintf(&path, "%s/%s", directory, dname) <= 0) { + free(dname); + continue; + } + + isdir = False; + if (!match || !ms_fnmatch(expression, dname)) { + if (recurse) { + ret = stat(path, &statbuf); + if (!ret) { + if (S_ISDIR(statbuf.st_mode)) { + isdir = True; + ret = file_find(list, path, expression, False); + } + } else { + DEBUG(0,("file_find: cannot stat file %s\n", path)); + } + + if (ret) { + free(path); + free(dname); + return ret; + } + } + entry = (struct file_list *) malloc(sizeof (struct file_list)); + if (!entry) { + DEBUG(0,("Out of memory in file_find\n")); + return -4; + } + entry->file_path = path; + entry->isdir = isdir; + DLIST_ADD(*list, entry); + } else { + free(path); + } + free(dname); + } + return 0; +} + +/**************************************************************************** mput some files ****************************************************************************/ static void cmd_mput(void) { - pstring lname; - pstring rname; fstring buf; char *p=buf; while (next_token(NULL,p,NULL,sizeof(buf))) { - SMB_STRUCT_STAT st; - pstring cmd; - pstring tmpname; - FILE *f; - int fd; - - slprintf(tmpname,sizeof(tmpname)-1, "%s/ls.smb.XXXXXX", - tmpdir()); - fd = smb_mkstemp(tmpname); + int ret; + struct file_list *temp_list; + char *quest, *lname, *rname; + + file_list = NULL; - if (fd == -1) { - DEBUG(0,("Failed to create temporary file %s\n", tmpname)); + ret = file_find(&file_list, ".", p, True); + if (ret) { + free_file_list(file_list); continue; } - - if (recurse) - slprintf(cmd,sizeof(pstring)-1, - "find . -name \"%s\" -print > %s",p,tmpname); - else - slprintf(cmd,sizeof(pstring)-1, - "find . -maxdepth 1 -name \"%s\" -print > %s",p,tmpname); - system(cmd); - close(fd); - - f = sys_fopen(tmpname,"r"); - if (!f) continue; - while (!feof(f)) { - pstring quest; + quest = NULL; + lname = NULL; + rname = NULL; + + for (temp_list = file_list; temp_list; + temp_list = temp_list->next) { - if (!fgets(lname,sizeof(lname),f)) break; - trim_string(lname,"./","\n"); - - again1: + if (lname) free(lname); + if (asprintf(&lname, "%s/", temp_list->file_path) <= 0) + continue; + trim_string(lname, "./", "/"); /* check if it's a directory */ - if (directory_exist(lname,&st)) { - if (!recurse) continue; - slprintf(quest,sizeof(pstring)-1, - "Put directory %s? ",lname); - if (prompt && !yesno(quest)) { - pstrcat(lname,"/"); - if (!seek_list(f,lname)) - break; - goto again1; - } - - pstrcpy(rname,cur_dir); - pstrcat(rname,lname); - dos_format(rname); - if (!cli_chkpath(cli, rname) && !do_mkdir(rname)) { - pstrcat(lname,"/"); - if (!seek_list(f,lname)) - break; - goto again1; + if (temp_list->isdir) { + /* if (!recurse) continue; */ + + if (quest) free(quest); + asprintf(&quest, "Put directory %s? ", lname); + if (prompt && !yesno(quest)) { /* No */ + /* Skip the directory */ + lname[strlen(lname)-1] = '/'; + if (!seek_list(temp_list, lname)) + break; + } else { /* Yes */ + if (rname) free(rname); + asprintf(&rname, "%s%s", cur_dir, lname); + dos_format(rname); + if (!cli_chkpath(cli, rname) && + !do_mkdir(rname)) { + DEBUG (0, ("Unable to make dir, skipping...")); + /* Skip the directory */ + lname[strlen(lname)-1] = '/'; + if (!seek_list(temp_list, lname)) + break; + } } continue; } else { - slprintf(quest,sizeof(quest)-1, - "Put file %s? ",lname); - if (prompt && !yesno(quest)) continue; + if (quest) free(quest); + asprintf(&quest,"Put file %s? ", lname); + if (prompt && !yesno(quest)) /* No */ + continue; - pstrcpy(rname,cur_dir); - pstrcat(rname,lname); + /* Yes */ + if (rname) free(rname); + asprintf(&rname, "%s%s", cur_dir, lname); } dos_format(rname); - do_put(rname,lname); + do_put(rname, lname); } - fclose(f); - unlink(tmpname); + free_file_list(file_list); + if (quest) free(quest); + if (lname) free(lname); + if (rname) free(rname); } } |