/***************************************************** a wrapper for utime *******************************************************/ int smbw_utime(const char *fname, void *buf) { char path[PATH_MAX]; smbw_fix_path(fname, path); return smbc_utime(path, buf); }
int main(int argc, char * argv[]) { int debug = 0; char m_time[32]; char c_time[32]; char a_time[32]; const char * pSmbPath = NULL; time_t t = time(NULL); struct stat st; struct utimbuf utimbuf; if (argc == 1) { pSmbPath = "smb://RANDOM/Public/small"; } else if (argc == 2) { pSmbPath = argv[1]; } else if (argc == 3) { pSmbPath = argv[1]; t = (time_t) strtol(argv[2], NULL, 10); } else { printf("usage: " "%s [ smb://path/to/file [ mtime ] ]\n", argv[0]); return 1; } smbc_init(get_auth_data_fn, debug); if (smbc_stat(pSmbPath, &st) < 0) { perror("smbc_stat"); return 1; } printf("Before\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n", st.st_mtime, ctime_r(&st.st_mtime, m_time), st.st_ctime, ctime_r(&st.st_ctime, c_time), st.st_atime, ctime_r(&st.st_atime, a_time)); utimbuf.actime = t; /* unchangable (wont change) */ utimbuf.modtime = t; /* this one should succeed */ if (smbc_utime(pSmbPath, &utimbuf) < 0) { perror("smbc_utime"); return 1; } if (smbc_stat(pSmbPath, &st) < 0) { perror("smbc_stat"); return 1; } printf("After\n mtime:%lu/%s ctime:%lu/%s atime:%lu/%s\n", st.st_mtime, ctime_r(&st.st_mtime, m_time), st.st_ctime, ctime_r(&st.st_ctime, c_time), st.st_atime, ctime_r(&st.st_atime, a_time)); return 0; }
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(); }