summaryrefslogtreecommitdiff
path: root/source/client/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/client/client.c')
-rw-r--r--source/client/client.c235
1 files changed, 158 insertions, 77 deletions
diff --git a/source/client/client.c b/source/client/client.c
index be2e6238c3b..4969156f083 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -473,7 +473,7 @@ static int do_list_queue_empty(void)
/****************************************************************************
a helper for do_list
****************************************************************************/
-static void do_list_helper(file_info *f, const char *mask)
+static void do_list_helper(file_info *f, const char *mask, void *state)
{
if (f->mode & aDIR) {
if (do_list_dirs && do_this_one(f)) {
@@ -537,7 +537,7 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
*/
pstring head;
pstrcpy(head, do_list_queue_head());
- cli_list(cli, head, attribute, do_list_helper);
+ cli_list(cli, head, attribute, do_list_helper, NULL);
remove_do_list_queue_head();
if ((! do_list_queue_empty()) && (fn == display_finfo))
{
@@ -561,7 +561,7 @@ void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec,
}
else
{
- if (cli_list(cli, mask, attribute, do_list_helper) == -1)
+ if (cli_list(cli, mask, attribute, do_list_helper, NULL) == -1)
{
DEBUG(0, ("%s listing %s\n", cli_errstr(cli), mask));
}
@@ -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
****************************************************************************/
@@ -1147,90 +1170,146 @@ static void cmd_select(void)
next_token(NULL,fileselection,NULL,sizeof(fileselection));
}
+/****************************************************************************
+ 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)
+{
+ DIR *dir;
+ struct file_list *entry;
+ struct stat statbuf;
+ int ret;
+ char *path;
+ BOOL isdir;
+ char *dname;
+
+ dir = opendir(directory);
+ if (!dir) return -1;
+
+ while ((dname = readdirname(dir))) {
+ if (!strcmp("..", dname)) continue;
+ if (!strcmp(".", dname)) continue;
+
+ if (asprintf(&path, "%s/%s", directory, dname) <= 0) {
+ continue;
+ }
+
+ isdir = False;
+ if (!match || !ms_fnmatch(expression, dname)) {
+ if (recurse) {
+ ret = stat(path, &statbuf);
+ if (ret == 0) {
+ 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 == -1) {
+ free(path);
+ closedir(dir);
+ return -1;
+ }
+ }
+ entry = (struct file_list *) malloc(sizeof (struct file_list));
+ if (!entry) {
+ DEBUG(0,("Out of memory in file_find\n"));
+ closedir(dir);
+ return -1;
+ }
+ entry->file_path = path;
+ entry->isdir = isdir;
+ DLIST_ADD(*list, entry);
+ } else {
+ free(path);
+ }
+ }
+
+ closedir(dir);
+ 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);
}
}
@@ -1548,7 +1627,8 @@ static void cmd_lcd(void)
/****************************************************************************
list a share name
****************************************************************************/
-static void browse_fn(const char *name, uint32 m, const char *comment)
+static void browse_fn(const char *name, uint32 m,
+ const char *comment, void *state)
{
fstring typestr;
@@ -1581,7 +1661,7 @@ static BOOL browse_host(BOOL sort)
printf("\n\tSharename Type Comment\n");
printf("\t--------- ---- -------\n");
- if((ret = cli_RNetShareEnum(cli, browse_fn)) == -1)
+ if((ret = cli_RNetShareEnum(cli, browse_fn, NULL)) == -1)
printf("Error returning browse list: %s\n", cli_errstr(cli));
return (ret != -1);
@@ -1590,7 +1670,8 @@ static BOOL browse_host(BOOL sort)
/****************************************************************************
list a server name
****************************************************************************/
-static void server_fn(const char *name, uint32 m, const char *comment)
+static void server_fn(const char *name, uint32 m,
+ const char *comment, void *state)
{
printf("\t%-16.16s %s\n", name, comment);
}
@@ -1605,12 +1686,12 @@ static BOOL list_servers(char *wk_grp)
printf("\n\tServer Comment\n");
printf("\t--------- -------\n");
- cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn);
+ cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn, NULL);
printf("\n\tWorkgroup Master\n");
printf("\t--------- -------\n");
- cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, server_fn);
+ cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, server_fn, NULL);
return True;
}
@@ -1846,13 +1927,13 @@ static void process_stdin(void)
while (1) {
fstring tok;
- fstring prompt;
+ fstring the_prompt;
char *line;
int i;
/* display a prompt */
- slprintf(prompt, sizeof(prompt)-1, "smb: %s> ", cur_dir);
- line = smb_readline(prompt, readline_callback, completion_fn);
+ slprintf(the_prompt, sizeof(the_prompt)-1, "smb: %s> ", cur_dir);
+ line = smb_readline(the_prompt, readline_callback, completion_fn);
if (!line) break;