📄 client.c
字号:
if (ctx->recurse) attribute |= FILE_ATTRIBUTE_DIRECTORY; for (i = 1; args[i]; i++) { mget_mask = talloc_strdup(ctx,ctx->remote_cur_dir); if(mget_mask[strlen(mget_mask)-1]!='\\') mget_mask = talloc_append_string(ctx, mget_mask, "\\"); mget_mask = talloc_strdup(ctx, args[i]); if (mget_mask[0] != '\\') mget_mask = talloc_append_string(ctx, mget_mask, "\\"); do_list(ctx, mget_mask, attribute,do_mget,false,true); talloc_free(mget_mask); } if (mget_mask == NULL) { mget_mask = talloc_asprintf(ctx, "%s\\*", ctx->remote_cur_dir); do_list(ctx, mget_mask, attribute,do_mget,false,true); talloc_free(mget_mask); } return 0;}/****************************************************************************make a directory of name "name"****************************************************************************/static NTSTATUS do_mkdir(struct smbclient_context *ctx, char *name){ NTSTATUS status; if (NT_STATUS_IS_ERR(status = smbcli_mkdir(ctx->cli->tree, name))) { d_printf("%s making remote directory %s\n", smbcli_errstr(ctx->cli->tree),name); return status; } return status;}/**************************************************************************** Exit client.****************************************************************************/static int cmd_quit(struct smbclient_context *ctx, const char **args){ talloc_free(ctx); exit(0); /* NOTREACHED */ return 0;}/**************************************************************************** make a directory ****************************************************************************/static int cmd_mkdir(struct smbclient_context *ctx, const char **args){ char *mask, *p; if (!args[1]) { if (!ctx->recurse) d_printf("mkdir <dirname>\n"); return 1; } mask = talloc_asprintf(ctx, "%s%s", ctx->remote_cur_dir,args[1]); if (ctx->recurse) { dos_clean_name(mask); trim_string(mask,".",NULL); for (p = strtok(mask,"/\\"); p; p = strtok(p, "/\\")) { char *parent = talloc_strndup(ctx, mask, PTR_DIFF(p, mask)); if (NT_STATUS_IS_ERR(smbcli_chkpath(ctx->cli->tree, parent))) { do_mkdir(ctx, parent); } talloc_free(parent); } } else { do_mkdir(ctx, mask); } return 0;}/****************************************************************************show 8.3 name of a file****************************************************************************/static int cmd_altname(struct smbclient_context *ctx, const char **args){ const char *altname; char *name; if (!args[1]) { d_printf("altname <file>\n"); return 1; } name = talloc_asprintf(ctx, "%s%s", ctx->remote_cur_dir, args[1]); if (!NT_STATUS_IS_OK(smbcli_qpathinfo_alt_name(ctx->cli->tree, name, &altname))) { d_printf("%s getting alt name for %s\n", smbcli_errstr(ctx->cli->tree),name); return(false); } d_printf("%s\n", altname); return 0;}/**************************************************************************** put a single file ****************************************************************************/static int do_put(struct smbclient_context *ctx, char *rname, char *lname, bool reput){ int fnum; XFILE *f; size_t start = 0; off_t nread = 0; uint8_t *buf = NULL; int maxwrite = ctx->io_bufsize; int rc = 0; struct timeval tp_start; GetTimeOfDay(&tp_start); if (reput) { fnum = smbcli_open(ctx->cli->tree, rname, O_RDWR|O_CREAT, DENY_NONE); if (fnum >= 0) { if (NT_STATUS_IS_ERR(smbcli_qfileinfo(ctx->cli->tree, fnum, NULL, &start, NULL, NULL, NULL, NULL, NULL)) && NT_STATUS_IS_ERR(smbcli_getattrE(ctx->cli->tree, fnum, NULL, &start, NULL, NULL, NULL))) { d_printf("getattrib: %s\n",smbcli_errstr(ctx->cli->tree)); return 1; } } } else { fnum = smbcli_open(ctx->cli->tree, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE); } if (fnum == -1) { d_printf("%s opening remote file %s\n",smbcli_errstr(ctx->cli->tree),rname); return 1; } /* allow files to be piped into smbclient jdblair 24.jun.98 Note that in this case this function will exit(0) rather than returning. */ if (!strcmp(lname, "-")) { f = x_stdin; /* size of file is not known */ } else { f = x_fopen(lname,O_RDONLY, 0); if (f && reput) { if (x_tseek(f, start, SEEK_SET) == -1) { d_printf("Error seeking local file\n"); return 1; } } } if (!f) { d_printf("Error opening local file %s\n",lname); return 1; } DEBUG(1,("putting file %s as %s ",lname, rname)); buf = (uint8_t *)malloc(maxwrite); if (!buf) { d_printf("ERROR: Not enough memory!\n"); return 1; } while (!x_feof(f)) { int n = maxwrite; int ret; if ((n = readfile(buf,n,f,ctx->translation)) < 1) { if((n == 0) && x_feof(f)) break; /* Empty local file. */ d_printf("Error reading local file: %s\n", strerror(errno)); rc = 1; break; } ret = smbcli_write(ctx->cli->tree, fnum, 0, buf, nread + start, n); if (n != ret) { d_printf("Error writing file: %s\n", smbcli_errstr(ctx->cli->tree)); rc = 1; break; } nread += n; } if (NT_STATUS_IS_ERR(smbcli_close(ctx->cli->tree, fnum))) { d_printf("%s closing remote file %s\n",smbcli_errstr(ctx->cli->tree),rname); x_fclose(f); SAFE_FREE(buf); return 1; } if (f != x_stdin) { x_fclose(f); } SAFE_FREE(buf); { struct timeval tp_end; int this_time; GetTimeOfDay(&tp_end); this_time = (tp_end.tv_sec - tp_start.tv_sec)*1000 + (tp_end.tv_usec - tp_start.tv_usec)/1000; put_total_time_ms += this_time; put_total_size += nread; DEBUG(1,("(%3.1f kb/s) (average %3.1f kb/s)\n", nread / (1.024*this_time + 1.0e-4), put_total_size / (1.024*put_total_time_ms))); } if (f == x_stdin) { talloc_free(ctx); exit(0); } return rc;} /**************************************************************************** put a file ****************************************************************************/static int cmd_put(struct smbclient_context *ctx, const char **args){ char *lname; char *rname; if (!args[1]) { d_printf("put <filename> [<remotename>]\n"); return 1; } lname = talloc_strdup(ctx, args[1]); if (args[2]) rname = talloc_strdup(ctx, args[2]); else rname = talloc_asprintf(ctx, "%s\\%s", ctx->remote_cur_dir, lname); dos_clean_name(rname); /* allow '-' to represent stdin jdblair, 24.jun.98 */ if (!file_exist(lname) && (strcmp(lname,"-"))) { d_printf("%s does not exist\n",lname); return 1; } return do_put(ctx, rname, lname, false);}/************************************* 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); SAFE_FREE(tmp->file_path); SAFE_FREE(tmp); }}/**************************************************************************** seek in a directory/file list until you get something that doesn't start with the specified name ****************************************************************************/static bool seek_list(struct file_list *list, char *name){ 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 ****************************************************************************/static int cmd_select(struct smbclient_context *ctx, const char **args){ talloc_free(ctx->fileselection); ctx->fileselection = talloc_strdup(NULL, args[1]); return 0;}/******************************************************************* A readdir wrapper which just returns the file name. ********************************************************************/static const char *readdirname(DIR *p){ struct dirent *ptr; char *dname; if (!p) return(NULL); ptr = (struct dirent *)readdir(p); if (!ptr) return(NULL); dname = ptr->d_name;#ifdef NEXT2 if (telldir(p) < 0) return(NULL);#endif#ifdef HAVE_BROKEN_READDIR /* using /usr/ucb/cc is BAD */ dname = dname - 2;#endif { static char *buf; int len = NAMLEN(ptr); buf = talloc_strndup(NULL, dname, len); dname = buf; } return(dname);}/**************************************************************************** Recursive file matching function act as find match must be always set to true when calling this function****************************************************************************/static int file_find(struct smbclient_context *ctx, 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; const char *dname; dir = opendir(directory); if (!dir) return -1; while ((dname = readdirname(dir))) { if (ISDOT(dname) || ISDOTDOT(dname)) { continue; } if (asprintf(&path, "%s/%s", directory, dname) <= 0) { continue; } isdir = false; if (!match || !gen_fnmatch(expression, dname)) { if (ctx->recurse) { ret = stat(path, &statbuf); if (ret == 0) { if (S_ISDIR(statbuf.st_mode)) { isdir = true; ret = file_find(ctx, list, path, expression, false); } } else { d_printf("file_find: cannot stat file %s\n", path); } if (ret == -1) { SAFE_FREE(path); closedir(dir); return -1; } } entry = malloc_p(struct file_list); if (!entry) { d_printf("Out of memory in file_find\n"); closedir(dir); return -1; } entry->file_path = path; entry->isdir = isdir; DLIST_ADD(*list, entry); } else { SAFE_FREE(path); } } closedir(dir); return 0;}/**************************************************************************** mput some files ****************************************************************************/static int cmd_mput(struct smbclient_context *ctx, const char **args){ int i; for (i = 1; args[i]; i++) { int ret; struct file_list *temp_list; char *quest, *lname, *rname; printf("%s\n", args[i]); file_list = NULL; ret = file_find(ctx, &file_list, ".", args[i], true); if (ret) { free_file_list(file_list); continue; } quest = NULL; lname = NULL; rname = NULL; for (temp_list = file_list; temp_list; temp_list = temp_list->next) { SAFE_FREE(lname); if (asprintf(&lname, "%s/", temp_list->file_path) <= 0) continue; trim_string(lname, "./", "/"); /* check if it's a directory */ if (temp_list->isdir) { /* if (!recurse) continue; */ SAFE_FREE(quest); if (asprintf(&quest, "Put directory %s? ", lname) < 0) break; if (ctx->prompt && !yesno(quest)) { /* No */ /* Skip the directory */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -