smbw.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,563 行 · 第 1/3 页
C
1,563 行
return NULL; } if (!cli_session_setup(&c, username, password, strlen(password), password, strlen(password), workgroup) && /* try an anonymous login if it failed */ !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) { cli_shutdown(&c); errno = EPERM; return NULL; } DEBUG(4,(" session setup ok\n")); if (!cli_send_tconX(&c, share, "?????", password, strlen(password)+1)) { errno = smbw_errno(&c); cli_shutdown(&c); return NULL; } smbw_setshared(ipenv,inet_ntoa(ip)); DEBUG(4,(" tconx ok\n")); srv = SMB_MALLOC_P(struct smbw_server); if (!srv) { errno = ENOMEM; goto failed; } ZERO_STRUCTP(srv); srv->cli = c; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); srv->server_name = SMB_STRDUP(server); if (!srv->server_name) { errno = ENOMEM; goto failed; } srv->share_name = SMB_STRDUP(share); if (!srv->share_name) { errno = ENOMEM; goto failed; } srv->workgroup = SMB_STRDUP(workgroup); if (!srv->workgroup) { errno = ENOMEM; goto failed; } srv->username = SMB_STRDUP(username); if (!srv->username) { errno = ENOMEM; goto failed; } /* some programs play with file descriptors fairly intimately. We try to get out of the way by duping to a high fd number */ if (fcntl(SMBW_CLI_FD + srv->cli.fd, F_GETFD) && errno == EBADF) { if (dup2(srv->cli.fd,SMBW_CLI_FD+srv->cli.fd) == srv->cli.fd+SMBW_CLI_FD) { close(srv->cli.fd); srv->cli.fd += SMBW_CLI_FD; } } DLIST_ADD(smbw_srvs, srv); return srv; failed: cli_shutdown(&c); if (!srv) return NULL; SAFE_FREE(srv->server_name); SAFE_FREE(srv->share_name); SAFE_FREE(srv); return NULL;}/***************************************************** map a fd to a smbw_file structure*******************************************************/struct smbw_file *smbw_file(int fd){ struct smbw_file *file; for (file=smbw_files;file;file=file->next) { if (file->fd == fd) return file; } return NULL;}/***************************************************** a wrapper for open()*******************************************************/int smbw_open(const char *fname, int flags, mode_t mode){ fstring server, share; pstring path; struct smbw_server *srv=NULL; int eno=0, fd = -1; struct smbw_file *file=NULL; smbw_init(); if (!fname) { errno = EINVAL; return -1; } smbw_busy++; /* work out what server they are after */ smbw_parse_path(fname, server, share, path); /* get a connection to the server */ srv = smbw_server(server, share); if (!srv) { /* smbw_server sets errno */ goto failed; } if (path[strlen(path)-1] == '\\') { fd = -1; } else { fd = cli_open(&srv->cli, path, flags, DENY_NONE); } if (fd == -1) { /* it might be a directory. Maybe we should use chkpath? */ eno = smbw_errno(&srv->cli); fd = smbw_dir_open(fname); if (fd == -1) errno = eno; smbw_busy--; return fd; } file = SMB_MALLOC_P(struct smbw_file); if (!file) { errno = ENOMEM; goto failed; } ZERO_STRUCTP(file); file->f = SMB_MALLOC_P(struct smbw_filedes); if (!file->f) { errno = ENOMEM; goto failed; } ZERO_STRUCTP(file->f); file->f->cli_fd = fd; file->f->fname = SMB_STRDUP(path); if (!file->f->fname) { errno = ENOMEM; goto failed; } file->srv = srv; file->fd = open(SMBW_DUMMY, O_WRONLY); if (file->fd == -1) { errno = EMFILE; goto failed; } if (bitmap_query(smbw_file_bmap, file->fd)) { DEBUG(0,("ERROR: fd used in smbw_open\n")); errno = EIO; goto failed; } file->f->ref_count=1; bitmap_set(smbw_file_bmap, file->fd); DLIST_ADD(smbw_files, file); DEBUG(4,("opened %s\n", fname)); smbw_busy--; return file->fd; failed: if (fd != -1) { cli_close(&srv->cli, fd); } if (file) { if (file->f) { SAFE_FREE(file->f->fname); SAFE_FREE(file->f); } SAFE_FREE(file); } smbw_busy--; return -1;}/***************************************************** a wrapper for pread()*******************************************************/ssize_t smbw_pread(int fd, void *buf, size_t count, off_t ofs){ struct smbw_file *file; int ret; smbw_busy++; file = smbw_file(fd); if (!file) { errno = EBADF; smbw_busy--; return -1; } ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, ofs, count); if (ret == -1) { errno = smbw_errno(&file->srv->cli); smbw_busy--; return -1; } smbw_busy--; return ret;}/***************************************************** a wrapper for read()*******************************************************/ssize_t smbw_read(int fd, void *buf, size_t count){ struct smbw_file *file; int ret; DEBUG(4,("smbw_read(%d, %d)\n", fd, (int)count)); smbw_busy++; file = smbw_file(fd); if (!file) { errno = EBADF; smbw_busy--; return -1; } ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, file->f->offset, count); if (ret == -1) { errno = smbw_errno(&file->srv->cli); smbw_busy--; return -1; } file->f->offset += ret; DEBUG(4,(" -> %d\n", ret)); smbw_busy--; return ret;} /***************************************************** a wrapper for write()*******************************************************/ssize_t smbw_write(int fd, void *buf, size_t count){ struct smbw_file *file; int ret; smbw_busy++; file = smbw_file(fd); if (!file) { errno = EBADF; smbw_busy--; return -1; } ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, file->f->offset, count); if (ret == -1) { errno = smbw_errno(&file->srv->cli); smbw_busy--; return -1; } file->f->offset += ret; smbw_busy--; return ret;}/***************************************************** a wrapper for pwrite()*******************************************************/ssize_t smbw_pwrite(int fd, void *buf, size_t count, off_t ofs){ struct smbw_file *file; int ret; smbw_busy++; file = smbw_file(fd); if (!file) { errno = EBADF; smbw_busy--; return -1; } ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, ofs, count); if (ret == -1) { errno = smbw_errno(&file->srv->cli); smbw_busy--; return -1; } smbw_busy--; return ret;}/***************************************************** a wrapper for close()*******************************************************/int smbw_close(int fd){ struct smbw_file *file; smbw_busy++; file = smbw_file(fd); if (!file) { int ret = smbw_dir_close(fd); smbw_busy--; return ret; } if (file->f->ref_count == 1 && !cli_close(&file->srv->cli, file->f->cli_fd)) { errno = smbw_errno(&file->srv->cli); smbw_busy--; return -1; } bitmap_clear(smbw_file_bmap, file->fd); close(file->fd); DLIST_REMOVE(smbw_files, file); file->f->ref_count--; if (file->f->ref_count == 0) { SAFE_FREE(file->f->fname); SAFE_FREE(file->f); } ZERO_STRUCTP(file); SAFE_FREE(file); smbw_busy--; return 0;}/***************************************************** a wrapper for fcntl()*******************************************************/int smbw_fcntl(int fd, int cmd, long arg){ return 0;}/***************************************************** a wrapper for access()*******************************************************/int smbw_access(const char *name, int mode){ struct stat st; DEBUG(4,("smbw_access(%s, 0x%x)\n", name, mode)); if (smbw_stat(name, &st)) return -1; if (((mode & R_OK) && !(st.st_mode & S_IRUSR)) || ((mode & W_OK) && !(st.st_mode & S_IWUSR)) || ((mode & X_OK) && !(st.st_mode & S_IXUSR))) { errno = EACCES; return -1; } return 0;}/***************************************************** a wrapper for realink() - needed for correct errno setting*******************************************************/int smbw_readlink(const char *path, char *buf, size_t bufsize){ struct stat st; int ret; ret = smbw_stat(path, &st); if (ret != 0) { DEBUG(4,("readlink(%s) failed\n", path)); return -1; } /* it exists - say it isn't a link */ DEBUG(4,("readlink(%s) not a link\n", path)); errno = EINVAL; return -1;}/***************************************************** a wrapper for unlink()*******************************************************/int smbw_unlink(const char *fname){ struct smbw_server *srv; fstring server, share; pstring path; if (!fname) { errno = EINVAL; return -1; } smbw_init(); smbw_busy++; /* work out what server they are after */ smbw_parse_path(fname, server, share, path); /* get a connection to the server */ srv = smbw_server(server, share); if (!srv) { /* smbw_server sets errno */ goto failed; } if (strncmp(srv->cli.dev, "LPT", 3) == 0) { int job = smbw_stat_printjob(srv, path, NULL, NULL); if (job == -1) { goto failed; } if (cli_printjob_del(&srv->cli, job) != 0) { goto failed; } } else if (!cli_unlink(&srv->cli, path)) { errno = smbw_errno(&srv->cli); goto failed; } smbw_busy--; return 0; failed: smbw_busy--; return -1;}/***************************************************** a wrapper for rename()*******************************************************/int smbw_rename(const char *oldname, const char *newname){ struct smbw_server *srv; fstring server1, share1; pstring path1; fstring server2, share2; pstring path2; if (!oldname || !newname) { errno = EINVAL; return -1; } smbw_init(); DEBUG(4,("smbw_rename(%s,%s)\n", oldname, newname)); smbw_busy++; /* work out what server they are after */ smbw_parse_path(oldname, server1, share1, path1); smbw_parse_path(newname, server2, share2, path2); if (strcmp(server1, server2) || strcmp(share1, share2)) { /* can't cross filesystems */ errno = EXDEV; return -1; } /* get a connection to the server */ srv = smbw_server(server1, share1); if (!srv) { /* smbw_server sets errno */ goto failed; } if (!cli_rename(&srv->cli, path1, path2)) { int eno = smbw_errno(&srv->cli); if (eno != EEXIST ||
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?