/***************************************************** a wrapper for pwrite() *******************************************************/ ssize_t smbw_pwrite(int smbw_fd, void *buf, size_t count, SMBW_OFF_T ofs) { int saved_errno; int client_fd; ssize_t ret; SMBW_OFF_T old_ofs; if (count == 0) { return 0; } client_fd = smbw_fd_map[smbw_fd]; if ((old_ofs = smbc_lseek(client_fd, 0, SEEK_CUR)) < 0 || smbc_lseek(client_fd, ofs, SEEK_SET) < 0) { return -1; } if ((ret = smbc_write(client_fd, buf, count)) < 0) { saved_errno = errno; (void) smbc_lseek(client_fd, old_ofs, SEEK_SET); errno = saved_errno; return -1; } return ret; }
static int open_f (stream_t *stream, int mode, void *opts, int* file_format) { struct stream_priv_s *p = (struct stream_priv_s*)opts; char *filename; mode_t m = 0; off_t len; int fd, err; filename = stream->url; if(mode == STREAM_READ) m = O_RDONLY; else if (mode == STREAM_WRITE) //who's gonna do that ? m = O_RDWR|O_CREAT|O_TRUNC; else { mp_msg(MSGT_OPEN, MSGL_ERR, "[smb] Unknown open mode %d\n", mode); m_struct_free (&stream_opts, opts); return STREAM_UNSUPPORTED; } if(!filename) { mp_msg(MSGT_OPEN,MSGL_ERR, "[smb] Bad url\n"); m_struct_free(&stream_opts, opts); return STREAM_ERROR; } err = smbc_init(smb_auth_fn, 1); if (err < 0) { mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_SMBInitError,err); m_struct_free(&stream_opts, opts); return STREAM_ERROR; } fd = smbc_open(filename, m,0644); if (fd < 0) { mp_msg(MSGT_OPEN,MSGL_ERR,MSGTR_SMBFileNotFound, filename); m_struct_free(&stream_opts, opts); return STREAM_ERROR; } stream->flags = mode; len = 0; if(mode == STREAM_READ) { len = smbc_lseek(fd,0,SEEK_END); smbc_lseek (fd, 0, SEEK_SET); } if(len > 0 || mode == STREAM_WRITE) { stream->flags |= MP_STREAM_SEEK; stream->seek = seek; if(mode == STREAM_READ) stream->end_pos = len; } stream->type = STREAMTYPE_SMB; stream->fd = fd; stream->fill_buffer = fill_buffer; stream->write_buffer = write_buffer; stream->close = close_f; stream->control = control; m_struct_free(&stream_opts, opts); return STREAM_OK; }
static int open_f (stream_t *stream, int mode) { char *filename; mode_t m = 0; int64_t len; int fd, err; struct priv *priv = talloc_zero(stream, struct priv); stream->priv = priv; filename = stream->url; if(mode == STREAM_READ) m = O_RDONLY; else if (mode == STREAM_WRITE) //who's gonna do that ? m = O_RDWR|O_CREAT|O_TRUNC; else { MP_ERR(stream, "[smb] Unknown open mode %d\n", mode); return STREAM_UNSUPPORTED; } if(!filename) { MP_ERR(stream, "[smb] Bad url\n"); return STREAM_ERROR; } err = smbc_init(smb_auth_fn, 1); if (err < 0) { MP_ERR(stream, "Cannot init the libsmbclient library: %d\n",err); return STREAM_ERROR; } fd = smbc_open(filename, m,0644); if (fd < 0) { MP_ERR(stream, "Could not open from LAN: '%s'\n", filename); return STREAM_ERROR; } stream->flags = mode; len = 0; if(mode == STREAM_READ) { len = smbc_lseek(fd,0,SEEK_END); smbc_lseek (fd, 0, SEEK_SET); } if(len > 0 || mode == STREAM_WRITE) { stream->flags |= MP_STREAM_SEEK; stream->seek = seek; if(mode == STREAM_READ) stream->end_pos = len; } priv->fd = fd; stream->fill_buffer = fill_buffer; stream->write_buffer = write_buffer; stream->close = close_f; stream->control = control; return STREAM_OK; }
static int control(stream_t *s, int cmd, void *arg) { switch(cmd) { case STREAM_CTRL_GET_SIZE: { off_t size = smbc_lseek(s->fd,0,SEEK_END); smbc_lseek(s->fd,s->pos,SEEK_SET); if(size != (off_t)-1) { *((off_t*)arg) = size; return 1; } } } return STREAM_UNSUPPORTED; }
int main(int argc, char** argv) { int err = -1; int fd = 0; bzero(g_workgroup,MAX_BUFF_SIZE); if ( argc == 4 ) { strncpy(g_workgroup,argv[1],strlen(argv[1])); strncpy(g_username,argv[2],strlen(argv[2])); strncpy(g_password,argv[3],strlen(argv[3])); smbc_init(auth_fn, 0); fd = -1; err = smbc_lseek(fd, 0, SEEK_SET); if ( err < 0 ) err = 1; else err = 0; } return err; }
int FSSmb::Seek( int fd, SEEK_FILE_MODE mode, seek_t pos, seek_t* pRet, int* err, FSCInfo* info ) { FREPARE_SMB_OPER( lock, info, &_param ); int whence = 0; switch ( mode ) { case FSEEK_POS: whence = SEEK_CUR; break; case FSEEK_END: whence = SEEK_END; break; case FSEEK_BEGIN: whence = SEEK_SET; break; default: whence = SEEK_SET; }; seek_t n = smbc_lseek( fd, pos, whence ); if ( n < 0 ) { SetError( err, errno ); return -1; } if ( pRet ) { *pRet = n; } return 0; }
static int seek(stream_t *s,int64_t newpos) { struct priv *p = s->priv; if(smbc_lseek(p->fd,newpos,SEEK_SET)<0) { return 0; } return 1; }
int main(int argc, char** argv) { int err = -1; int fd = 0; memset(g_workgroup, '\0', MAX_BUFF_SIZE); if ( argc == 4 ) { strncpy(g_workgroup,argv[1],strlen(argv[1])); strncpy(g_username,argv[2],strlen(argv[2])); strncpy(g_password,argv[3],strlen(argv[3])); smbc_init(auth_fn, 0); fd = -1; smbc_lseek(fd, 0, SEEK_SET); err = errno; } return err; }
int FileSeek( FHANDLE handle, long offset, int whence ) { int ret = 0; if( handle.dt == DT_CD ) { ret = fioLseek( handle.fh, offset, whence ); } else if( handle.dt == DT_HDD ) { ret = fileXioLseek( handle.fh, offset, whence ); } else if( handle.dt == DT_MC ) { ret = fioLseek( handle.fh, offset, whence ); } else if( handle.dt == DT_USB ) { ret = fioLseek( handle.fh, offset, whence ); } else if( handle.dt == DT_HOST ) { ret = fioLseek( handle.fh, offset, whence ); } else if( handle.dt == DT_SMB_SHARE ) { ret = smbc_lseek( handle.fh, offset, whence ); } return ret; }
static gint64 xmms_samba_seek (xmms_xform_t *xform, gint64 offset, xmms_xform_seek_mode_t whence, xmms_error_t *error) { xmms_samba_data_t *data; gint w = 0; off_t res; g_return_val_if_fail (xform, -1); data = xmms_xform_private_data_get (xform); g_return_val_if_fail (data, -1); switch (whence) { case XMMS_XFORM_SEEK_SET: w = SEEK_SET; break; case XMMS_XFORM_SEEK_END: w = SEEK_END; break; case XMMS_XFORM_SEEK_CUR: w = SEEK_CUR; break; } G_LOCK (mutex); res = smbc_lseek (data->fd, offset, w); G_UNLOCK (mutex); if (res == -1) { xmms_error_set (error, XMMS_ERROR_INVAL, "Couldn't seek"); } return res; }
static int seek(stream_t *s,off_t newpos) { s->pos = newpos; if(smbc_lseek(s->fd,s->pos,SEEK_SET)<0) { s->eof=1; return 0; } return 1; }
bool CFile::Open(const CStdString& strFileName, unsigned int flags) { Close(); // we can't open files like smb://file.f or smb://server/file.f // if a file matches the if below return false, it can't exist on a samba share. // if (!IsValidFile(url.GetFileName())) // { // XBMC->Log(LOG_NOTICE,"FileSmb->Open: Bad URL : '%s'",url.GetFileName().c_str()); // return false; // } m_fileName = strFileName; // opening a file to another computer share will create a new session // when opening smb://server xbms will try to find folder.jpg in all shares // listed, which will create lot's of open sessions. //CStdString strFileName; //m_fd = OpenFile(url, strFileName); m_fd = OpenFile(); //XBMC->Log(LOG_DEBUG,"CFile::Open - opened %s, fd=%d",url.GetFileName().c_str(), m_fd); XBMC->Log(LOG_DEBUG,"CFile::Open - opened %s, fd=%d", m_fileName.c_str(), m_fd); if (m_fd == -1) { // write error to logfile //#ifdef TARGET_WINDOWS // int nt_error = smb.ConvertUnixToNT(errno); // XBMC->Log(LOG_INFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' nt_err : '%x' error : '%s'", strFileName.c_str(), errno, nt_error, get_friendly_nt_error_msg(nt_error)); //#else XBMC->Log(LOG_INFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strFileName.c_str(), errno, strerror(errno)); //#endif return false; } CLockObject lock(smb); struct stat tmpBuffer; if (smbc_stat(strFileName, &tmpBuffer) < 0) { smbc_close(m_fd); m_fd = -1; return false; } m_fileSize = tmpBuffer.st_size; int64_t ret = smbc_lseek(m_fd, 0, SEEK_SET); if ( ret < 0 ) { smbc_close(m_fd); m_fd = -1; return false; } // We've successfully opened the file! return true; }
off_t smbc_wrapper_lseek(connection* con, int fd, off_t offset, int whence) { if(con->mode== SMB_BASIC) return smbc_lseek(fd, offset,whence); else if(con->mode == SMB_NTLM) return smbc_cli_lseek(con->smb_info->cli, fd, offset,whence); return -1; }
int64_t CFile::GetPosition() { if (m_fd == -1) return 0; smb.Init(); PLATFORM::CLockObject lock(smb); int64_t pos = smbc_lseek(m_fd, 0, SEEK_CUR); if ( pos < 0 ) return 0; return pos; }
int64_t GetPosition(void* context) { SMBContext* ctx = (SMBContext*)context; if (ctx->fd == -1) return 0; CSMB2::Get().Init(); PLATFORM::CLockObject lock(CSMB2::Get()); int64_t pos = smbc_lseek(ctx->fd, 0, SEEK_CUR); if ( pos < 0 ) return 0; return pos; }
static off_t _lseek(csync_vio_method_handle_t *fhandle, off_t offset, int whence) { smb_fhandle_t *handle = NULL; if (fhandle == NULL) { errno = EBADF; return (off_t) -1; } handle = (smb_fhandle_t *) fhandle; return smbc_lseek(handle->fd, offset, whence); }
int main(int argc, char** argv) { int err = -1; int fd = 0; int msg_len = 0; char url[MAX_BUFF_SIZE]; char* message; bzero(g_workgroup,MAX_BUFF_SIZE); bzero(url,MAX_BUFF_SIZE); if ( argc == 6 ) { strncpy(g_workgroup,argv[1],strlen(argv[1])); strncpy(g_username,argv[2],strlen(argv[2])); strncpy(g_password,argv[3],strlen(argv[3])); strncpy(url,argv[4],strlen(argv[4])); msg_len = strlen(argv[5])+1; message = malloc(msg_len); message[msg_len - 1] = 0; strncpy(message,argv[5],msg_len); smbc_init(auth_fn, 0); smbc_unlink(url); fd = smbc_open(url,O_RDWR | O_CREAT, 0666); smbc_close(fd); fd = smbc_open(url, O_RDWR, 0666); smbc_write(fd, message, msg_len); smbc_close(fd); fd = smbc_open(url, O_RDWR, 0666); err = smbc_lseek(fd,msg_len,SEEK_SET); smbc_close(fd); if ( err < 0 ) err = 1; else err = 0; free(message); } return err; }
int64_t CFile::Seek(int64_t iFilePosition, int iWhence) { if (m_fd == -1) return -1; CLockObject lock(smb); // Init not called since it has to be "inited" by now smb.SetActivityTime(); int64_t pos = smbc_lseek(m_fd, iFilePosition, iWhence); if ( pos < 0 ) { XBMC->Log(LOG_ERROR, "%s - Error( %"PRId64", %d, %s )", __FUNCTION__, pos, errno, strerror(errno)); return -1; } return (int64_t)pos; }
int64_t Seek(void* context, int64_t iFilePosition, int iWhence) { SMBContext* ctx = (SMBContext*)context; if (ctx->fd == -1) return -1; PLATFORM::CLockObject lock(CSMB2::Get()); // Init not called since it has to be "inited" by now CSMB2::Get().SetActivityTime(); int64_t pos = smbc_lseek(ctx->fd, iFilePosition, iWhence); if ( pos < 0 ) { XBMC->Log(ADDON::LOG_ERROR, "%s - Error( %"PRId64", %d, %s )", __FUNCTION__, pos, errno, strerror(errno)); return -1; } return (int64_t)pos; }
/***************************************************** a wrapper for lseek() *******************************************************/ SMBW_OFF_T smbw_lseek(int smbw_fd, SMBW_OFF_T offset, int whence) { int client_fd; SMBW_OFF_T ret; client_fd = smbw_fd_map[smbw_fd]; ret = smbc_lseek(client_fd, offset, whence); if (smbw_debug) { printf("smbw_lseek(%d/%d, 0x%llx) returned 0x%llx\n", smbw_fd, client_fd, (unsigned long long) offset, (unsigned long long) ret); } return ret; }
/***************************************************************************** * Seek: try to go at the right place *****************************************************************************/ static int Seek( stream_t *p_access, uint64_t i_pos ) { access_sys_t *p_sys = p_access->p_sys; int64_t i_ret; if( i_pos >= INT64_MAX ) return VLC_EGENERIC; msg_Dbg( p_access, "seeking to %"PRId64, i_pos ); i_ret = smbc_lseek( p_sys->i_smb, i_pos, SEEK_SET ); if( i_ret == -1 ) { msg_Err( p_access, "seek failed (%s)", vlc_strerror_c(errno) ); return VLC_EGENERIC; } return VLC_SUCCESS; }
static int smbcfs_read(const char* const path, char* const buf, const std::size_t size, const off_t offset, struct fuse_file_info* const fi) { const int fh = fi->fh; #ifdef MUTEX_LOCK pthread_mutex_lock(&mutex_lock); #endif const int ret_lseek = smbc_lseek(fh, offset, SEEK_SET); #ifdef MUTEX_LOCK pthread_mutex_unlock(&mutex_lock); #endif #ifdef SMBCFS_DEBUG fprintf(stderr, "[smbc_lseek] %d %lld %d => %d\n", fh, offset, SEEK_SET, ret_lseek); #endif if(ret_lseek<0) return ret_lseek; #ifdef MUTEX_LOCK pthread_mutex_lock(&mutex_lock); #endif const int ret_read = smbc_read(fh, buf, size); #ifdef MUTEX_LOCK pthread_mutex_unlock(&mutex_lock); #endif #ifdef SMBCFS_DEBUG fprintf(stderr, "[smbc_read] %d %p %ld => %d\n", fh, buf, size, ret_read); #endif return ret_read; }
/***************************************************************************** * Seek: try to go at the right place *****************************************************************************/ static int Seek( access_t *p_access, uint64_t i_pos ) { access_sys_t *p_sys = p_access->p_sys; int64_t i_ret; if( i_pos >= INT64_MAX ) return VLC_EGENERIC; msg_Dbg( p_access, "seeking to %"PRId64, i_pos ); i_ret = smbc_lseek( p_sys->i_smb, i_pos, SEEK_SET ); if( i_ret == -1 ) { msg_Err( p_access, "seek failed (%m)" ); return VLC_EGENERIC; } p_access->info.b_eof = false; p_access->info.i_pos = i_ret; return VLC_SUCCESS; }
bool CFile::Open(const CStdString& strFileName, unsigned int flags) { Close(); m_fileName = strFileName; m_fd = OpenFile(); XBMC->Log(LOG_DEBUG,"CFile::Open - opened %s, fd=%d", m_fileName.c_str(), m_fd); if (m_fd == -1) { // write error to logfile XBMC->Log(LOG_INFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", strFileName.c_str(), errno, strerror(errno)); return false; } CLockObject lock(smb); struct stat tmpBuffer; if (smbc_stat(strFileName, &tmpBuffer) < 0) { smbc_close(m_fd); m_fd = -1; return false; } m_fileSize = tmpBuffer.st_size; int64_t ret = smbc_lseek(m_fd, 0, SEEK_SET); if ( ret < 0 ) { smbc_close(m_fd); m_fd = -1; return false; } // We've successfully opened the file! return true; }
void* Open(VFSURL* url) { CSMB2::Get().Init(); CSMB2::Get().AddActiveConnection(); if (!IsValidFile(url->filename)) { XBMC->Log(ADDON::LOG_INFO, "FileSmb->Open: Bad URL : '%s'",url->redacted); return NULL; } int fd = -1; std::string filename = GetAuthenticatedPath(url); PLATFORM::CLockObject lock(CSMB2::Get()); fd = smbc_open(filename.c_str(), O_RDONLY, 0); if (fd == -1) { XBMC->Log(ADDON::LOG_INFO, "FileSmb->Open: Unable to open file : '%s'\nunix_err:'%x' error : '%s'", url->redacted, errno, strerror(errno)); return NULL; } XBMC->Log(ADDON::LOG_DEBUG,"CSMB2File::Open - opened %s, fd=%d", url->filename, fd); struct stat tmpBuffer; if (smbc_stat(filename.c_str(), &tmpBuffer) < 0) { smbc_close(fd); return NULL; } int64_t ret = smbc_lseek(fd, 0, SEEK_SET); if (ret < 0) { smbc_close(fd); return NULL; } SMBContext* result = new SMBContext; result->fd = fd; result->size = tmpBuffer.st_size; return result; }
void SMBSlave::smbCopyPut(const QUrl& ksrc, const QUrl& kdst, int permissions, KIO::JobFlags flags) { qCDebug(KIO_SMB) << "src = " << ksrc << ", dest = " << kdst; QFile srcFile (ksrc.toLocalFile()); const QFileInfo srcInfo (srcFile); if (srcInfo.exists()) { if (srcInfo.isDir()) { error(KIO::ERR_IS_DIRECTORY, ksrc.toDisplayString()); return; } } else { error(KIO::ERR_DOES_NOT_EXIST, ksrc.toDisplayString()); return; } if (!srcFile.open(QFile::ReadOnly)) { qCDebug(KIO_SMB) << "could not read from" << ksrc; switch (srcFile.error()) { case QFile::PermissionsError: error(KIO::ERR_WRITE_ACCESS_DENIED, ksrc.toDisplayString()); break; case QFile::OpenError: default: error(KIO::ERR_CANNOT_OPEN_FOR_READING, ksrc.toDisplayString()); break; } return; } totalSize(static_cast<filesize_t>(srcInfo.size())); bool bResume = false; bool bPartExists = false; const bool bMarkPartial = config()->readEntry("MarkPartial", true); const SMBUrl dstOrigUrl (kdst); if (bMarkPartial) { const int errNum = cache_stat(dstOrigUrl.partUrl(), &st); bPartExists = (errNum == 0); if (bPartExists) { if (!(flags & KIO::Overwrite) && !(flags & KIO::Resume)) { bResume = canResume(st.st_size); } else { bResume = (flags & KIO::Resume); } } } int dstfd = -1; int errNum = cache_stat(dstOrigUrl, &st); if (errNum == 0 && !(flags & KIO::Overwrite) && !(flags & KIO::Resume)) { if (S_ISDIR(st.st_mode)) { error( KIO::ERR_IS_DIRECTORY, dstOrigUrl.toDisplayString()); } else { error( KIO::ERR_FILE_ALREADY_EXIST, dstOrigUrl.toDisplayString()); } return; } KIO::filesize_t processed_size = 0; const SMBUrl dstUrl(bMarkPartial ? dstOrigUrl.partUrl() : dstOrigUrl); if (bResume) { // append if resuming qCDebug(KIO_SMB) << "resume" << dstUrl; dstfd = smbc_open(dstUrl.toSmbcUrl(), O_RDWR, 0 ); if (dstfd < 0) { errNum = errno; } else { const off_t offset = smbc_lseek(dstfd, 0, SEEK_END); if (offset == (off_t)-1) { error(KIO::ERR_COULD_NOT_SEEK, dstUrl.toDisplayString()); smbc_close(dstfd); return; } else { processed_size = offset; } } } else { mode_t mode; if (permissions == -1) { mode = 600; } else { mode = permissions | S_IRUSR | S_IWUSR; } qCDebug(KIO_SMB) << "NO resume" << dstUrl; dstfd = smbc_open(dstUrl.toSmbcUrl(), O_CREAT | O_TRUNC | O_WRONLY, mode); if (dstfd < 0) { errNum = errno; } } if (dstfd < 0) { if (errNum == EACCES) { qCDebug(KIO_SMB) << "access denied"; error( KIO::ERR_WRITE_ACCESS_DENIED, dstUrl.toDisplayString()); } else { qCDebug(KIO_SMB) << "can not open for writing"; error( KIO::ERR_CANNOT_OPEN_FOR_WRITING, dstUrl.toDisplayString()); } return; } bool isErr = false; if (processed_size == 0 || srcFile.seek(processed_size)) { // Perform the copy char buf[MAX_XFER_BUF_SIZE]; while (1) { const ssize_t bytesRead = srcFile.read(buf, MAX_XFER_BUF_SIZE); if (bytesRead <= 0) { if (bytesRead < 0) { error(KIO::ERR_COULD_NOT_READ, ksrc.toDisplayString()); isErr = true; } break; } const qint64 bytesWritten = smbc_write(dstfd, buf, bytesRead); if (bytesWritten == -1) { error(KIO::ERR_COULD_NOT_WRITE, kdst.toDisplayString()); isErr = true; break; } processed_size += bytesWritten; processedSize(processed_size); } } else { isErr = true; error(KIO::ERR_COULD_NOT_SEEK, ksrc.toDisplayString()); } // FINISHED if (smbc_close(dstfd) < 0) { qCDebug(KIO_SMB) << dstUrl << "could not write"; error( KIO::ERR_COULD_NOT_WRITE, dstUrl.toDisplayString()); return; } // Handle error condition. if (isErr) { if (bMarkPartial) { const int size = config()->readEntry("MinimumKeepSize", DEFAULT_MINIMUM_KEEP_SIZE); const int errNum = cache_stat(dstUrl, &st); if (errNum == 0 && st.st_size < size) { smbc_unlink(dstUrl.toSmbcUrl()); } } return; } // Rename partial file to its original name. if (bMarkPartial) { smbc_unlink(dstOrigUrl.toSmbcUrl()); if (smbc_rename(dstUrl.toSmbcUrl(), dstOrigUrl.toSmbcUrl()) < 0) { qCDebug(KIO_SMB) << "failed to rename" << dstUrl << "to" << dstOrigUrl << "->" << strerror(errno); error(ERR_CANNOT_RENAME_PARTIAL, dstUrl.toDisplayString()); return; } } #ifdef HAVE_UTIME_H // set modification time const QString mtimeStr = metaData( "modified" ); if (!mtimeStr.isEmpty() ) { QDateTime dt = QDateTime::fromString( mtimeStr, Qt::ISODate ); if ( dt.isValid() ) { struct utimbuf utbuf; utbuf.actime = st.st_atime; // access time, unchanged utbuf.modtime = dt.toTime_t(); // modification time smbc_utime( dstUrl.toSmbcUrl(), &utbuf ); } } #endif // We have done our job => finish finished(); }
//=========================================================================== void SMBSlave::put( const KURL& kurl, int permissions, bool overwrite, bool resume ) { void *buf; size_t bufsize; m_current_url = kurl; int filefd; bool exists; mode_t mode; QByteArray filedata; kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl << endl; exists = (cache_stat(m_current_url, &st) != -1 ); if ( exists && !overwrite && !resume) { if (S_ISDIR(st.st_mode)) { kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" already isdir !!"<< endl; error( KIO::ERR_DIR_ALREADY_EXIST, m_current_url.prettyURL()); } else { kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" already exist !!"<< endl; error( KIO::ERR_FILE_ALREADY_EXIST, m_current_url.prettyURL()); } return; } if (exists && !resume && overwrite) { kdDebug(KIO_SMB) << "SMBSlave::put exists try to remove " << m_current_url.toSmbcUrl()<< endl; // remove(m_current_url.url().local8Bit()); } if (resume) { // append if resuming kdDebug(KIO_SMB) << "SMBSlave::put resume " << m_current_url.toSmbcUrl()<< endl; filefd = smbc_open(m_current_url.toSmbcUrl(), O_RDWR, 0 ); smbc_lseek(filefd, 0, SEEK_END); } else { if (permissions != -1) { mode = permissions | S_IWUSR | S_IRUSR; } else { mode = 600;//0666; } kdDebug(KIO_SMB) << "SMBSlave::put NO resume " << m_current_url.toSmbcUrl()<< endl; filefd = smbc_open(m_current_url.toSmbcUrl(), O_CREAT | O_TRUNC | O_WRONLY, mode); } if ( filefd < 0 ) { if ( errno == EACCES ) { kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" access denied !!"<< endl; error( KIO::ERR_WRITE_ACCESS_DENIED, m_current_url.prettyURL()); } else { kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" can not open for writing !!"<< endl; error( KIO::ERR_CANNOT_OPEN_FOR_WRITING, m_current_url.prettyURL()); } finished(); return; } // Loop until we got 0 (end of data) while(1) { kdDebug(KIO_SMB) << "SMBSlave::put request data "<< endl; dataReq(); // Request for data kdDebug(KIO_SMB) << "SMBSlave::put write " << m_current_url.toSmbcUrl()<< endl; if (readData(filedata) <= 0) { kdDebug(KIO_SMB) << "readData <= 0" << endl; break; } kdDebug(KIO_SMB) << "SMBSlave::put write " << m_current_url.toSmbcUrl()<< endl; buf = filedata.data(); bufsize = filedata.size(); int size = smbc_write(filefd, buf, bufsize); if ( size < 0) { kdDebug(KIO_SMB) << "SMBSlave::put error " << kurl <<" could not write !!"<< endl; error( KIO::ERR_COULD_NOT_WRITE, m_current_url.prettyURL()); finished(); return; } kdDebug(KIO_SMB ) << "wrote " << size << endl; } kdDebug(KIO_SMB) << "SMBSlave::put close " << m_current_url.toSmbcUrl()<< endl; if(smbc_close(filefd)) { kdDebug(KIO_SMB) << "SMBSlave::put on " << kurl <<" could not write !!"<< endl; error( KIO::ERR_COULD_NOT_WRITE, m_current_url.prettyURL()); finished(); return; } // set final permissions, if the file was just created if ( permissions != -1 && !exists ) { // TODO: did the smbc_chmod fail? // TODO: put in call to chmod when it is working! // smbc_chmod(url.toSmbcUrl(),permissions); } // We have done our job => finish finished(); }
int main(int argc, char *argv[]) { int err, fd, dh1, dsize, dirc; const char *file = "smb://samba/public/testfile.txt"; const char *file2 = "smb://samba/public/testfile2.txt"; char buff[256]; char dirbuf[512]; char *dirp; struct stat st1, st2; err = smbc_init(get_auth_data_fn, 10); /* Initialize things */ if (err < 0) { fprintf(stderr, "Initializing the smbclient library ...: %s\n", strerror(errno)); } if (argc > 1) { if ((dh1 = smbc_opendir(argv[1]))<1) { fprintf(stderr, "Could not open directory: %s: %s\n", argv[1], strerror(errno)); exit(1); } fprintf(stdout, "Directory handle: %u\n", dh1); /* Now, list those directories, but in funny ways ... */ dirp = (char *)dirbuf; if ((dirc = smbc_getdents(dh1, (struct smbc_dirent *)dirp, sizeof(dirbuf))) < 0) { fprintf(stderr, "Problems getting directory entries: %s\n", strerror(errno)); exit(1); } /* Now, process the list of names ... */ fprintf(stdout, "Directory listing, size = %u\n", dirc); while (dirc > 0) { dsize = ((struct smbc_dirent *)dirp)->dirlen; fprintf(stdout, "Dir Ent, Type: %u, Name: %s, Comment: %s\n", ((struct smbc_dirent *)dirp)->smbc_type, ((struct smbc_dirent *)dirp)->name, ((struct smbc_dirent *)dirp)->comment); dirp += dsize; dirc -= dsize; } dirp = (char *)dirbuf; exit(1); } /* For now, open a file on a server that is hard coded ... later will * read from the command line ... */ fd = smbc_open(file, O_RDWR | O_CREAT | O_TRUNC, 0666); if (fd < 0) { fprintf(stderr, "Creating file: %s: %s\n", file, strerror(errno)); exit(0); } fprintf(stdout, "Opened or created file: %s\n", file); /* Now, write some date to the file ... */ memset(buff, '\0', sizeof(buff)); snprintf(buff, sizeof(buff), "%s", "Some test data for the moment ..."); err = smbc_write(fd, buff, sizeof(buff)); if (err < 0) { fprintf(stderr, "writing file: %s: %s\n", file, strerror(errno)); exit(0); } fprintf(stdout, "Wrote %lu bytes to file: %s\n", (unsigned long) sizeof(buff), buff); /* Now, seek the file back to offset 0 */ err = smbc_lseek(fd, SEEK_SET, 0); if (err < 0) { fprintf(stderr, "Seeking file: %s: %s\n", file, strerror(errno)); exit(0); } fprintf(stdout, "Completed lseek on file: %s\n", file); /* Now, read the file contents back ... */ err = smbc_read(fd, buff, sizeof(buff)); if (err < 0) { fprintf(stderr, "Reading file: %s: %s\n", file, strerror(errno)); exit(0); } fprintf(stdout, "Read file: %s\n", buff); /* Should check the contents */ fprintf(stdout, "Now fstat'ing file: %s\n", file); err = smbc_fstat(fd, &st1); if (err < 0) { fprintf(stderr, "Fstat'ing file: %s: %s\n", file, strerror(errno)); exit(0); } /* Now, close the file ... */ err = smbc_close(fd); if (err < 0) { fprintf(stderr, "Closing file: %s: %s\n", file, strerror(errno)); } /* Now, rename the file ... */ err = smbc_rename(file, file2); if (err < 0) { fprintf(stderr, "Renaming file: %s to %s: %s\n", file, file2, strerror(errno)); } fprintf(stdout, "Renamed file %s to %s\n", file, file2); /* Now, create a file and delete it ... */ fprintf(stdout, "Now, creating file: %s so we can delete it.\n", file); fd = smbc_open(file, O_RDWR | O_CREAT, 0666); if (fd < 0) { fprintf(stderr, "Creating file: %s: %s\n", file, strerror(errno)); exit(0); } fprintf(stdout, "Opened or created file: %s\n", file); err = smbc_close(fd); if (err < 0) { fprintf(stderr, "Closing file: %s: %s\n", file, strerror(errno)); exit(0); } /* Now, delete the file ... */ fprintf(stdout, "File %s created, now deleting ...\n", file); err = smbc_unlink(file); if (err < 0) { fprintf(stderr, "Deleting file: %s: %s\n", file, strerror(errno)); exit(0); } /* Now, stat the file, file 2 ... */ fprintf(stdout, "Now stat'ing file: %s\n", file); err = smbc_stat(file2, &st2); if (err < 0) { fprintf(stderr, "Stat'ing file: %s: %s\n", file, strerror(errno)); exit(0); } fprintf(stdout, "Stat'ed file: %s. Size = %d, mode = %04X\n", file2, (int)st2.st_size, (unsigned int)st2.st_mode); fprintf(stdout, " time: %s\n", ctime(&st2.st_atime)); fprintf(stdout, "Earlier stat: %s, Size = %d, mode = %04X\n", file, (int)st1.st_size, (unsigned int)st1.st_mode); fprintf(stdout, " time: %s\n", ctime(&st1.st_atime)); /* Now, make a directory ... */ fprintf(stdout, "Making directory smb://samba/public/make-dir\n"); if (smbc_mkdir("smb://samba/public/make-dir", 0666) < 0) { fprintf(stderr, "Error making directory: smb://samba/public/make-dir: %s\n", strerror(errno)); if (errno == EEXIST) { /* Try to delete the directory */ fprintf(stdout, "Trying to delete directory: smb://samba/public/make-dir\n"); if (smbc_rmdir("smb://samba/public/make-dir") < 0) { /* Error */ fprintf(stderr, "Error removing directory: smb://samba/public/make-dir: %s\n", strerror(errno)); exit(0); } fprintf(stdout, "Making directory: smb://samba/public/make-dir\n"); if (smbc_mkdir("smb://samba/public/make-dir", 666) < 0) { fprintf(stderr, "Error making directory: smb://samba/public/make-dir: %s\n", strerror(errno)); fprintf(stderr, "I give up!\n"); exit(1); } } exit(0); } fprintf(stdout, "Made dir: make-dir\n"); return 0; }
int smb_download_file(const char *base, const char *name, int recursive, int resume, char *outfile) { int remotehandle, localhandle; time_t start_time = time(NULL); const char *newpath; char path[SMB_MAXPATHLEN]; char checkbuf[2][RESUME_CHECK_SIZE]; char *readbuf = NULL; off_t offset_download = 0, offset_check = 0, curpos = 0, start_offset = 0; struct stat localstat, remotestat; snprintf(path, SMB_MAXPATHLEN-1, "%s%s%s", base, (*base && *name && name[0] != '/' && base[strlen(base)-1] != '/')?"/":"", name); remotehandle = smbc_open(path, O_RDONLY, 0755); if(remotehandle < 0) { switch(errno) { case EISDIR: if(!recursive) { fprintf(stderr, "%s is a directory. Specify -R to download recursively\n", path); return 0; } smb_download_dir(base, name, resume); return 0; case ENOENT: fprintf(stderr, "%s can't be found on the remote server\n", path); return 0; case ENOMEM: fprintf(stderr, "Not enough memory\n"); exit(1); return 0; case ENODEV: fprintf(stderr, "The share name used in %s does not exist\n", path); return 0; case EACCES: fprintf(stderr, "You don't have enough permissions to access %s\n", path); return 0; default: perror("smbc_open"); return 0; } } if(smbc_fstat(remotehandle, &remotestat) < 0) { fprintf(stderr, "Can't stat %s: %s\n", path, strerror(errno)); return 0; } if(outfile) newpath = outfile; else if(!name[0]) { newpath = strrchr(base, '/'); if(newpath)newpath++; else newpath = base; } else newpath = name; if(newpath[0] == '/')newpath++; /* Open local file and, if necessary, resume */ localhandle = open(newpath, O_CREAT | O_NONBLOCK | O_RDWR | (!resume?O_EXCL:0), 0755); if(localhandle < 0) { fprintf(stderr, "Can't open %s: %s\n", newpath, strerror(errno)); smbc_close(remotehandle); return 0; } fstat(localhandle, &localstat); start_offset = localstat.st_size; if(localstat.st_size && localstat.st_size == remotestat.st_size) { if(verbose)fprintf(stderr, "%s is already downloaded completely.\n", path); else if(!quiet)fprintf(stderr, "%s\n", path); smbc_close(remotehandle); close(localhandle); return 1; } if(localstat.st_size > RESUME_CHECK_OFFSET && remotestat.st_size > RESUME_CHECK_OFFSET) { offset_download = localstat.st_size - RESUME_DOWNLOAD_OFFSET; offset_check = localstat.st_size - RESUME_CHECK_OFFSET; if(verbose)printf("Trying to start resume of %s at "OFF_T_FORMAT"\n" "At the moment "OFF_T_FORMAT" of "OFF_T_FORMAT" bytes have been retrieved\n", newpath, offset_check, localstat.st_size, remotestat.st_size); } if(offset_check) { off_t off1, off2; /* First, check all bytes from offset_check to offset_download */ off1 = lseek(localhandle, offset_check, SEEK_SET); if(off1 < 0) { fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in local file %s\n", offset_check, newpath); smbc_close(remotehandle); close(localhandle); return 0; } off2 = smbc_lseek(remotehandle, offset_check, SEEK_SET); if(off2 < 0) { fprintf(stderr, "Can't seek to "OFF_T_FORMAT" in remote file %s\n", offset_check, newpath); smbc_close(remotehandle); close(localhandle); return 0; } if(off1 != off2) { fprintf(stderr, "Offset in local and remote files is different (local: "OFF_T_FORMAT", remote: "OFF_T_FORMAT")\n", off1, off2); return 0; } if(smbc_read(remotehandle, checkbuf[0], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { fprintf(stderr, "Can't read %d bytes from remote file %s\n", RESUME_CHECK_SIZE, path); smbc_close(remotehandle); close(localhandle); return 0; } if(read(localhandle, checkbuf[1], RESUME_CHECK_SIZE) != RESUME_CHECK_SIZE) { fprintf(stderr, "Can't read %d bytes from local file %s\n", RESUME_CHECK_SIZE, name); smbc_close(remotehandle); close(localhandle); return 0; } if(memcmp(checkbuf[0], checkbuf[1], RESUME_CHECK_SIZE) == 0) { if(verbose)printf("Current local and remote file appear to be the same. Starting download from offset "OFF_T_FORMAT"\n", offset_download); } else { fprintf(stderr, "Local and remote file appear to be different, not doing resume for %s\n", path); smbc_close(remotehandle); close(localhandle); return 0; } } readbuf = malloc(blocksize); /* Now, download all bytes from offset_download to the end */ for(curpos = offset_download; curpos < remotestat.st_size; curpos+=blocksize) { ssize_t bytesread = smbc_read(remotehandle, readbuf, blocksize); if(bytesread < 0) { fprintf(stderr, "Can't read %d bytes at offset "OFF_T_FORMAT", file %s\n", blocksize, curpos, path); smbc_close(remotehandle); close(localhandle); free(readbuf); return 0; } total_bytes += bytesread; if(write(localhandle, readbuf, bytesread) < 0) { fprintf(stderr, "Can't write %d bytes to local file %s at offset "OFF_T_FORMAT"\n", bytesread, path, curpos); free(readbuf); smbc_close(remotehandle); close(localhandle); return 0; } if(dots)fputc('.', stderr); else if(!quiet) { print_progress(newpath, start_time, time(NULL), start_offset, curpos, remotestat.st_size); } } free(readbuf); if(dots){ fputc('\n', stderr); printf("%s downloaded\n", path); } else if(!quiet) { int i; fprintf(stderr, "\r%s", path); if(columns) { for(i = strlen(path); i < columns; i++) { fputc(' ', stderr); } } fputc('\n', stderr); } if(keep_permissions) { if(fchmod(localhandle, remotestat.st_mode) < 0) { fprintf(stderr, "Unable to change mode of local file %s to %o\n", path, remotestat.st_mode); smbc_close(remotehandle); close(localhandle); return 0; } } smbc_close(remotehandle); close(localhandle); return 1; }
/* download file */ int SMB_download(char *serverpath, int index) { char buffer[4096] = {0}; int buflen; char *localpath = serverpath_to_localpath(serverpath, index); //char *localpath_td = my_malloc(strlen(localpath) + strlen(".asus.td") + 1); char *localpath_td = my_malloc(strlen(localpath) + 9); //2014.10.20 by sherry malloc申请内存是否成功 //if(localpath_td==NULL) // return NULL; sprintf(localpath_td, "%s%s", localpath, ".asus.td"); write_log(S_DOWNLOAD, "", serverpath, index); unsigned long long halfsize = 0; int dst_fd; if(access(localpath_td, F_OK) != 0) { dst_fd = open(localpath_td, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if(dst_fd < 0){ printf("open() - %s failed\n", localpath_td); return -1; } } else { dst_fd = open(localpath_td, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if(dst_fd < 0){ printf("open() - %s failed\n", localpath_td); return -1; } halfsize = lseek(dst_fd, 0L, SEEK_END); lseek(dst_fd, halfsize, SEEK_SET); } SMB_init(index); int fd = -1; if((fd = smbc_open(serverpath, O_RDONLY, FILE_MODE)) > 0) { unsigned long long cli_filesize = 0; unsigned long long smb_filesize = 0; smb_filesize = smbc_lseek(fd, 0L, SEEK_END); smbc_lseek(fd, halfsize, SEEK_SET); while((buflen = smbc_read(fd, buffer, sizeof(buffer))) > 0 && exit_loop == 0) { //2014.11.20 by sherry 判断是否write成功 write(dst_fd, buffer, buflen); cli_filesize += buflen; printf("\rDownload [%s] percent - %f ", serverpath, (float)cli_filesize/(float)smb_filesize); } if(cli_filesize == smb_filesize) { rename(localpath_td, localpath); free(localpath); free(localpath_td); smbc_close(fd); close(dst_fd); } else { free(localpath); free(localpath_td); smbc_close(fd); close(dst_fd); return -1; } } else { printf("smbc_open() - %s failed\n", serverpath); close(dst_fd); free(localpath); free(localpath_td); return COULD_NOT_CONNECNT_TO_SERVER; } return 0; }