📄 client.c
字号:
}}static char *do_list_queue_head(void){ return do_list_queue + do_list_queue_start;}static void remove_do_list_queue_head(void){ if (do_list_queue_end > do_list_queue_start) { do_list_queue_start += strlen(do_list_queue_head()) + 1; adjust_do_list_queue(); DEBUG(4,("removed head of do_list_queue (start=%d, end=%d)\n", (int)do_list_queue_start, (int)do_list_queue_end)); }}static int do_list_queue_empty(void){ return (! (do_list_queue && *do_list_queue));}/****************************************************************************a helper for do_list ****************************************************************************/static void do_list_helper(struct clilist_file_info *f, const char *mask, void *state){ struct smbclient_context *ctx = (struct smbclient_context *)state; if (f->attrib & FILE_ATTRIBUTE_DIRECTORY) { if (do_list_dirs && do_this_one(ctx, f)) { do_list_fn(ctx, f); } if (do_list_recurse && !ISDOT(f->name) && !ISDOTDOT(f->name)) { char *mask2; char *p; mask2 = talloc_strdup(NULL, mask); p = strrchr_m(mask2,'\\'); if (!p) return; p[1] = 0; mask2 = talloc_asprintf_append_buffer(mask2, "%s\\*", f->name); add_to_do_list_queue(mask2); } return; } if (do_this_one(ctx, f)) { do_list_fn(ctx, f); }}/****************************************************************************a wrapper around smbcli_list that adds recursion ****************************************************************************/static void do_list(struct smbclient_context *ctx, const char *mask,uint16_t attribute, void (*fn)(struct smbclient_context *, struct clilist_file_info *),bool rec, bool dirs){ static int in_do_list = 0; if (in_do_list && rec) { fprintf(stderr, "INTERNAL ERROR: do_list called recursively when the recursive flag is true\n"); exit(1); } in_do_list = 1; do_list_recurse = rec; do_list_dirs = dirs; do_list_fn = fn; if (rec) { init_do_list_queue(); add_to_do_list_queue(mask); while (! do_list_queue_empty()) { /* * Need to copy head so that it doesn't become * invalid inside the call to smbcli_list. This * would happen if the list were expanded * during the call. * Fix from E. Jay Berkenbilt (ejb@ql.org) */ char *head; head = do_list_queue_head(); smbcli_list(ctx->cli->tree, head, attribute, do_list_helper, ctx); remove_do_list_queue_head(); if ((! do_list_queue_empty()) && (fn == display_finfo)) { char* next_file = do_list_queue_head(); char* save_ch = 0; if ((strlen(next_file) >= 2) && (next_file[strlen(next_file) - 1] == '*') && (next_file[strlen(next_file) - 2] == '\\')) { save_ch = next_file + strlen(next_file) - 2; *save_ch = '\0'; } d_printf("\n%s\n",next_file); if (save_ch) { *save_ch = '\\'; } } } } else { if (smbcli_list(ctx->cli->tree, mask, attribute, do_list_helper, ctx) == -1) { d_printf("%s listing %s\n", smbcli_errstr(ctx->cli->tree), mask); } } in_do_list = 0; reset_do_list_queue();}/**************************************************************************** get a directory listing ****************************************************************************/static int cmd_dir(struct smbclient_context *ctx, const char **args){ uint16_t attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; char *mask; int rc; dir_total = 0; mask = talloc_strdup(ctx, ctx->remote_cur_dir); if(mask[strlen(mask)-1]!='\\') mask = talloc_append_string(ctx, mask,"\\"); if (args[1]) { mask = talloc_strdup(ctx, args[1]); if (mask[0] != '\\') mask = talloc_append_string(ctx, mask, "\\"); dos_format(mask); } else { if (ctx->cli->tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1) { mask = talloc_append_string(ctx, mask, "*.*"); } else { mask = talloc_append_string(ctx, mask, "*"); } } do_list(ctx, mask, attribute, display_finfo, ctx->recurse, true); rc = do_dskattr(ctx); DEBUG(3, ("Total bytes listed: %.0f\n", dir_total)); return rc;}/**************************************************************************** get a directory listing ****************************************************************************/static int cmd_du(struct smbclient_context *ctx, const char **args){ uint16_t attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; int rc; char *mask; dir_total = 0; if (args[1]) { if (args[1][0] == '\\') mask = talloc_strdup(ctx, args[1]); else mask = talloc_asprintf(ctx, "%s\\%s", ctx->remote_cur_dir, args[1]); dos_format(mask); } else { mask = talloc_asprintf(ctx, "%s\\*", ctx->remote_cur_dir); } do_list(ctx, mask, attribute, do_du, ctx->recurse, true); talloc_free(mask); rc = do_dskattr(ctx); d_printf("Total number of bytes: %.0f\n", dir_total); return rc;}/**************************************************************************** get a file from rname to lname ****************************************************************************/static int do_get(struct smbclient_context *ctx, char *rname, const char *lname, bool reget){ int handle = 0, fnum; bool newhandle = false; uint8_t *data; struct timeval tp_start; int read_size = ctx->io_bufsize; uint16_t attr; size_t size; off_t start = 0; off_t nread = 0; int rc = 0; GetTimeOfDay(&tp_start); if (ctx->lowercase) { strlower(discard_const_p(char, lname)); } fnum = smbcli_open(ctx->cli->tree, rname, O_RDONLY, DENY_NONE); if (fnum == -1) { d_printf("%s opening remote file %s\n",smbcli_errstr(ctx->cli->tree),rname); return 1; } if(!strcmp(lname,"-")) { handle = fileno(stdout); } else { if (reget) { handle = open(lname, O_WRONLY|O_CREAT, 0644); if (handle >= 0) { start = lseek(handle, 0, SEEK_END); if (start == -1) { d_printf("Error seeking local file\n"); return 1; } } } else { handle = open(lname, O_WRONLY|O_CREAT|O_TRUNC, 0644); } newhandle = true; } if (handle < 0) { d_printf("Error opening local file %s\n",lname); return 1; } if (NT_STATUS_IS_ERR(smbcli_qfileinfo(ctx->cli->tree, fnum, &attr, &size, NULL, NULL, NULL, NULL, NULL)) && NT_STATUS_IS_ERR(smbcli_getattrE(ctx->cli->tree, fnum, &attr, &size, NULL, NULL, NULL))) { d_printf("getattrib: %s\n",smbcli_errstr(ctx->cli->tree)); return 1; } DEBUG(2,("getting file %s of size %.0f as %s ", rname, (double)size, lname)); if(!(data = (uint8_t *)malloc(read_size))) { d_printf("malloc fail for size %d\n", read_size); smbcli_close(ctx->cli->tree, fnum); return 1; } while (1) { int n = smbcli_read(ctx->cli->tree, fnum, data, nread + start, read_size); if (n <= 0) break; if (writefile(handle,data, n, ctx->translation) != n) { d_printf("Error writing local file\n"); rc = 1; break; } nread += n; } if (nread + start < size) { DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n", rname, (long)nread)); rc = 1; } SAFE_FREE(data); if (NT_STATUS_IS_ERR(smbcli_close(ctx->cli->tree, fnum))) { d_printf("Error %s closing remote file\n",smbcli_errstr(ctx->cli->tree)); rc = 1; } if (newhandle) { close(handle); } if (ctx->archive_level >= 2 && (attr & FILE_ATTRIBUTE_ARCHIVE)) { smbcli_setatr(ctx->cli->tree, rname, attr & ~(uint16_t)FILE_ATTRIBUTE_ARCHIVE, 0); } { 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; get_total_time_ms += this_time; get_total_size += nread; DEBUG(2,("(%3.1f kb/s) (average %3.1f kb/s)\n", nread / (1.024*this_time + 1.0e-4), get_total_size / (1.024*get_total_time_ms))); } return rc;}/**************************************************************************** get a file ****************************************************************************/static int cmd_get(struct smbclient_context *ctx, const char **args){ const char *lname; char *rname; if (!args[1]) { d_printf("get <filename>\n"); return 1; } rname = talloc_asprintf(ctx, "%s\\%s", ctx->remote_cur_dir, args[1]); if (args[2]) lname = args[2]; else lname = args[1]; dos_clean_name(rname); return do_get(ctx, rname, lname, false);}/**************************************************************************** Put up a yes/no prompt.****************************************************************************/static bool yesno(char *p){ char ans[4]; printf("%s",p); if (!fgets(ans,sizeof(ans)-1,stdin)) return(false); if (*ans == 'y' || *ans == 'Y') return(true); return(false);}/**************************************************************************** do a mget operation on one file ****************************************************************************/static void do_mget(struct smbclient_context *ctx, struct clilist_file_info *finfo){ char *rname; char *quest; char *mget_mask; char *saved_curdir; if (ISDOT(finfo->name) || ISDOTDOT(finfo->name)) return; if (finfo->attrib & FILE_ATTRIBUTE_DIRECTORY) asprintf(&quest, "Get directory %s? ",finfo->name); else asprintf(&quest, "Get file %s? ",finfo->name); if (ctx->prompt && !yesno(quest)) return; SAFE_FREE(quest); if (!(finfo->attrib & FILE_ATTRIBUTE_DIRECTORY)) { asprintf(&rname, "%s%s",ctx->remote_cur_dir,finfo->name); do_get(ctx, rname, finfo->name, false); SAFE_FREE(rname); return; } /* handle directories */ saved_curdir = talloc_strdup(NULL, ctx->remote_cur_dir); ctx->remote_cur_dir = talloc_asprintf_append_buffer(NULL, "%s\\", finfo->name); string_replace(discard_const_p(char, finfo->name), '\\', '/'); if (ctx->lowercase) { strlower(discard_const_p(char, finfo->name)); } if (!directory_exist(finfo->name) && mkdir(finfo->name,0777) != 0) { d_printf("failed to create directory %s\n",finfo->name); return; } if (chdir(finfo->name) != 0) { d_printf("failed to chdir to directory %s\n",finfo->name); return; } mget_mask = talloc_asprintf(NULL, "%s*", ctx->remote_cur_dir); do_list(ctx, mget_mask, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY,do_mget,false, true); chdir(".."); talloc_free(ctx->remote_cur_dir); ctx->remote_cur_dir = saved_curdir;}/****************************************************************************view the file using the pager****************************************************************************/static int cmd_more(struct smbclient_context *ctx, const char **args){ char *rname; char *pager_cmd; char *lname; char *pager; int fd; int rc = 0; lname = talloc_asprintf(ctx, "%s/smbmore.XXXXXX",tmpdir()); fd = mkstemp(lname); if (fd == -1) { d_printf("failed to create temporary file for more\n"); return 1; } close(fd); if (!args[1]) { d_printf("more <filename>\n"); unlink(lname); return 1; } rname = talloc_asprintf(ctx, "%s%s", ctx->remote_cur_dir, args[1]); dos_clean_name(rname); rc = do_get(ctx, rname, lname, false); pager=getenv("PAGER"); pager_cmd = talloc_asprintf(ctx, "%s %s",(pager? pager:PAGER), lname); system(pager_cmd); unlink(lname); return rc;}/****************************************************************************do a mget command****************************************************************************/static int cmd_mget(struct smbclient_context *ctx, const char **args){ uint16_t attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; char *mget_mask = NULL; int i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -