📄 libsmbclient.c
字号:
st->st_mode = SMBC_DIR_MODE; } else { st->st_mode = SMBC_FILE_MODE; } if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; st->st_size = size;#ifdef HAVE_STAT_ST_BLKSIZE st->st_blksize = 512;#endif#ifdef HAVE_STAT_ST_BLOCKS st->st_blocks = (size+511)/512;#endif st->st_uid = getuid(); st->st_gid = getgid(); if (IS_DOS_DIR(mode)) { st->st_nlink = 2; } else { st->st_nlink = 1; } if (st->st_ino == 0) { st->st_ino = smbc_inode(context, fname); } return True; /* FIXME: Is this needed ? */}/* * Routine to stat a file given a name */static intsmbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st){ SMBCSRV *srv; fstring server; fstring share; fstring user; fstring password; fstring workgroup; pstring path; time_t m_time = 0; time_t a_time = 0; time_t c_time = 0; SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; } if (!fname) { errno = EINVAL; return -1; } DEBUG(4, ("smbc_stat(%s)\n", fname)); if (smbc_parse_path(context, fname, server, sizeof(server), share, sizeof(share), path, sizeof(path), user, sizeof(user), password, sizeof(password), NULL, 0)) { errno = EINVAL; return -1; } if (user[0] == (char)0) fstrcpy(user, context->user); fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { return -1; /* errno set by smbc_server */ } if (!smbc_getatr(context, srv, path, &mode, &size, &c_time, &a_time, &m_time, &ino)) { errno = smbc_errno(context, &srv->cli); return -1; } st->st_ino = ino; smbc_setup_stat(context, st, path, size, mode); st->st_atime = a_time; st->st_ctime = c_time; st->st_mtime = m_time; st->st_dev = srv->dev; return 0;}/* * Routine to stat a file given an fd */static intsmbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st){ time_t c_time; time_t a_time; time_t m_time; SMB_OFF_T size; uint16 mode; fstring server; fstring share; fstring user; fstring password; pstring path; pstring targetpath; struct cli_state *targetcli; SMB_INO_T ino = 0; if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; return -1; } if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; } if (!file->file) { return context->fstatdir(context, file, st); } /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ if (smbc_parse_path(context, file->fname, server, sizeof(server), share, sizeof(share), path, sizeof(path), user, sizeof(user), password, sizeof(password), NULL, 0)) { errno = EINVAL; return -1; } /*d_printf(">>>fstat: resolving %s\n", path);*/ if (!cli_resolve_path("", &file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) { if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time)) { errno = EINVAL; return -1; } } st->st_ino = ino; smbc_setup_stat(context, st, file->fname, size, mode); st->st_atime = a_time; st->st_ctime = c_time; st->st_mtime = m_time; st->st_dev = file->srv->dev; return 0;}/* * Routine to open a directory * We accept the URL syntax explained in smbc_parse_path(), above. */static voidsmbc_remove_dir(SMBCFILE *dir){ struct smbc_dir_list *d,*f; d = dir->dir_list; while (d) { f = d; d = d->next; SAFE_FREE(f->dirent); SAFE_FREE(f); } dir->dir_list = dir->dir_end = dir->dir_next = NULL;}static intadd_dirent(SMBCFILE *dir, const char *name, const char *comment, uint32 type){ struct smbc_dirent *dirent; int size; int name_length = (name == NULL ? 0 : strlen(name)); int comment_len = (comment == NULL ? 0 : strlen(comment)); /* * Allocate space for the dirent, which must be increased by the * size of the name and the comment and 1 each for the null terminator. */ size = sizeof(struct smbc_dirent) + name_length + comment_len + 2; dirent = SMB_MALLOC(size); if (!dirent) { dir->dir_error = ENOMEM; return -1; } ZERO_STRUCTP(dirent); if (dir->dir_list == NULL) { dir->dir_list = SMB_MALLOC_P(struct smbc_dir_list); if (!dir->dir_list) { SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; } ZERO_STRUCTP(dir->dir_list); dir->dir_end = dir->dir_next = dir->dir_list; } else { dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list); if (!dir->dir_end->next) { SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; } ZERO_STRUCTP(dir->dir_end->next); dir->dir_end = dir->dir_end->next; } dir->dir_end->next = NULL; dir->dir_end->dirent = dirent; dirent->smbc_type = type; dirent->namelen = name_length; dirent->commentlen = comment_len; dirent->dirlen = size; strncpy(dirent->name, (name?name:""), dirent->namelen + 1); dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); return 0;}static voidlist_unique_wg_fn(const char *name, uint32 type, const char *comment, void *state){ SMBCFILE *dir = (SMBCFILE *)state; struct smbc_dir_list *dir_list; struct smbc_dirent *dirent; int dirent_type; int do_remove = 0; dirent_type = dir->dir_type; if (add_dirent(dir, name, comment, dirent_type) < 0) { /* An error occurred, what do we do? */ /* FIXME: Add some code here */ } /* Point to the one just added */ dirent = dir->dir_end->dirent; /* See if this was a duplicate */ for (dir_list = dir->dir_list; dir_list != dir->dir_end; dir_list = dir_list->next) { if (! do_remove && strcmp(dir_list->dirent->name, dirent->name) == 0) { /* Duplicate. End end of list need to be removed. */ do_remove = 1; } if (do_remove && dir_list->next == dir->dir_end) { /* Found the end of the list. Remove it. */ dir->dir_end = dir_list; free(dir_list->next); free(dirent); dir_list->next = NULL; break; } }}static voidlist_fn(const char *name, uint32 type, const char *comment, void *state){ SMBCFILE *dir = (SMBCFILE *)state; int dirent_type; /* * We need to process the type a little ... * * Disk share = 0x00000000 * Print share = 0x00000001 * Comms share = 0x00000002 (obsolete?) * IPC$ share = 0x00000003 * * administrative shares: * ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000 */ if (dir->dir_type == SMBC_FILE_SHARE) { switch (type) { case 0 | 0x80000000: case 0: dirent_type = SMBC_FILE_SHARE; break; case 1: dirent_type = SMBC_PRINTER_SHARE; break; case 2: dirent_type = SMBC_COMMS_SHARE; break; case 3 | 0x80000000: case 3: dirent_type = SMBC_IPC_SHARE; break; default: dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ break; } } else { dirent_type = dir->dir_type; } if (add_dirent(dir, name, comment, dirent_type) < 0) { /* An error occurred, what do we do? */ /* FIXME: Add some code here */ }}static voiddir_list_fn(const char *mnt, file_info *finfo, const char *mask, void *state){ if (add_dirent((SMBCFILE *)state, finfo->name, "", (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { /* Handle an error ... */ /* FIXME: Add some code ... */ } }static intnet_share_enum_rpc(struct cli_state *cli, void (*fn)(const char *name, uint32 type, const char *comment, void *state), void *state){ int i; WERROR result; ENUM_HND enum_hnd; uint32 info_level = 1; uint32 preferred_len = 0xffffffff; uint32 type; SRV_SHARE_INFO_CTR ctr; fstring name = ""; fstring comment = ""; void *mem_ctx; struct rpc_pipe_client *pipe_hnd; NTSTATUS nt_status; /* Open the server service pipe */ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); if (!pipe_hnd) { DEBUG(1, ("net_share_enum_rpc pipe open fail!\n")); return -1; } /* Allocate a context for parsing and for the entries in "ctr" */ mem_ctx = talloc_init("libsmbclient: net_share_enum_rpc"); if (mem_ctx == NULL) { DEBUG(0, ("out of memory for net_share_enum_rpc!\n")); cli_rpc_pipe_close(pipe_hnd); return -1; } /* Issue the NetShareEnum RPC call and retrieve the response */ init_enum_hnd(&enum_hnd, 0); result = rpccli_srvsvc_net_share_enum(pipe_hnd, mem_ctx, info_level, &ctr, preferred_len, &enum_hnd); /* Was it successful? */ if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { /* Nope. Go clean up. */ goto done; } /* For each returned entry... */ for (i = 0; i < ctr.num_entries; i++) { /* pull out the share name */ rpcstr_pull_unistr2_fstring( name, &ctr.share.info1[i].info_1_str.uni_netname); /* pull out the share's comment */ rpcstr_pull_unistr2_fstring( comment, &ctr.share.info1[i].info_1_str.uni_remark); /* Get the type value */ type = ctr.share.info1[i].info_1.type; /* Add this share to the list */ (*fn)(name, type, comment, state);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -