//---------------------------------------------------------------------------
bool SMBSlave::browse_stat_path(const SMBUrl &_url, UDSEntry &udsentry, bool ignore_errors)
// Returns: true on success, false on failure
{
    UDSAtom udsatom;

    SMBUrl url = _url;

    if(cache_stat(url, &st) == 0)
    {
        if(!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
        {
            kdDebug(KIO_SMB) << "SMBSlave::browse_stat_path mode: " << st.st_mode << endl;
            warning(i18n("%1:\n"
                         "Unknown file type, neither directory or file.")
                        .arg(url.prettyURL()));
            return false;
        }

        udsatom.m_uds = KIO::UDS_FILE_TYPE;
        udsatom.m_long = st.st_mode & S_IFMT;
        udsentry.append(udsatom);

        udsatom.m_uds = KIO::UDS_SIZE;
        udsatom.m_long = st.st_size;
        udsentry.append(udsatom);

        udsatom.m_uds = KIO::UDS_USER;
        uid_t uid = st.st_uid;
        struct passwd *user = getpwuid(uid);
        if(user)
            udsatom.m_str = user->pw_name;
        else
            udsatom.m_str = QString::number(uid);
        udsentry.append(udsatom);

        udsatom.m_uds = KIO::UDS_GROUP;
        gid_t gid = st.st_gid;
        struct group *grp = getgrgid(gid);
        if(grp)
            udsatom.m_str = grp->gr_name;
        else
            udsatom.m_str = QString::number(gid);
        udsentry.append(udsatom);

        udsatom.m_uds = KIO::UDS_ACCESS;
        udsatom.m_long = st.st_mode & 07777;
        udsentry.append(udsatom);

        udsatom.m_uds = UDS_MODIFICATION_TIME;
        udsatom.m_long = st.st_mtime;
        udsentry.append(udsatom);

        udsatom.m_uds = UDS_ACCESS_TIME;
        udsatom.m_long = st.st_atime;
        udsentry.append(udsatom);

        udsatom.m_uds = UDS_CREATION_TIME;
        udsatom.m_long = st.st_ctime;
        udsentry.append(udsatom);
    }
    else
    {
        if(!ignore_errors)
        {
            if(errno == EPERM || errno == EACCES)
                if(checkPassword(url))
                {
                    redirection(url);
                    return false;
                }

            reportError(url);
        }
        else if(errno == ENOENT || errno == ENOTDIR)
        {
            warning(i18n("File does not exist: %1").arg(url.url()));
        }
        kdDebug(KIO_SMB) << "SMBSlave::browse_stat_path ERROR!!" << endl;
        return false;
    }

    return true;
}
Beispiel #2
0
//===========================================================================
void SMBSlave::get( const KURL& kurl )
{
    char        buf[MAX_XFER_BUF_SIZE];
    int         filefd          = 0;
    ssize_t     bytesread       = 0;
    // time_t      curtime         = 0;
    time_t      lasttime        = 0;
    time_t      starttime       = 0;
    KIO::filesize_t totalbytesread  = 0;
    QByteArray  filedata;
    SMBUrl      url;

    kdDebug(KIO_SMB) << "SMBSlave::get on " << kurl << endl;

    // check (correct) URL
    KURL kvurl = checkURL(kurl);
    // if URL is not valid we have to redirect to correct URL
    if (kvurl != kurl) {
        redirection(kvurl);
        finished();
        return;
    }

    if(!auth_initialize_smbc())
        return;


    // Stat
    url = kurl;
    if(cache_stat(url,&st) == -1 )
    {
        if ( errno == EACCES )
           error( KIO::ERR_ACCESS_DENIED, url.prettyURL());
        else
           error( KIO::ERR_DOES_NOT_EXIST, url.prettyURL());
        return;
    }
    if ( S_ISDIR( st.st_mode ) ) {
        error( KIO::ERR_IS_DIRECTORY, url.prettyURL());
        return;
    }

    // Set the total size
    totalSize( st.st_size );

    // Open and read the file
    filefd = smbc_open(url.toSmbcUrl(),O_RDONLY,0);
    if(filefd >= 0)
    {
        if(buf)
        {
	    bool isFirstPacket = true;
            lasttime = starttime = time(NULL);
            while(1)
            {
                bytesread = smbc_read(filefd, buf, MAX_XFER_BUF_SIZE);
                if(bytesread == 0)
                {
                    // All done reading
                    break;
                }
                else if(bytesread < 0)
                {
                    error( KIO::ERR_COULD_NOT_READ, url.prettyURL());
                    return;
                }

                filedata.setRawData(buf,bytesread);
		if (isFirstPacket)
		{
                    // We need a KMimeType::findByNameAndContent(filename,data)
                    // For now we do: find by extension, and if not found (or extension not reliable)
                    // then find by content.
                    bool accurate = false;
                    KMimeType::Ptr mime = KMimeType::findByURL( kurl, st.st_mode, false, true, &accurate );
                    if ( !mime || mime->name() == KMimeType::defaultMimeType()
                         || !accurate )
                    {
                        KMimeType::Ptr p_mimeType = KMimeType::findByContent(filedata);
                        if ( p_mimeType && p_mimeType->name() != KMimeType::defaultMimeType() )
                            mime = p_mimeType;
                    }
		    mimeType(mime->name());
		    isFirstPacket = false;
		}
                data( filedata );
                filedata.resetRawData(buf,bytesread);

                // increment total bytes read
                totalbytesread += bytesread;

		processedSize(totalbytesread);
            }
        }

        smbc_close(filefd);
        data( QByteArray() );
        processedSize(static_cast<KIO::filesize_t>(st.st_size));

    }
    else
    {
          error( KIO::ERR_CANNOT_OPEN_FOR_READING, url.prettyURL());
	  return;
    }

    finished();
}
void SMBSlave::reportError(const SMBUrl &url)
{
    kdDebug(KIO_SMB) << "reportError " << url << " " << perror << endl;
    switch(errno)
    {
        case ENOENT:
            if(url.getType() == SMBURLTYPE_ENTIRE_NETWORK)
                error(ERR_SLAVE_DEFINED, i18n("Unable to find any workgroups in your local network. This might be caused by an enabled firewall."));
            else
                error(ERR_DOES_NOT_EXIST, url.prettyURL());
            break;
#ifdef ENOMEDIUM
        case ENOMEDIUM:
            error(ERR_SLAVE_DEFINED, i18n("No media in device for %1").arg(url.prettyURL()));
            break;
#endif
#ifdef EHOSTDOWN
        case EHOSTDOWN:
#endif
        case ECONNREFUSED:
            error(ERR_SLAVE_DEFINED, i18n("Could not connect to host for %1").arg(url.prettyURL()));
            break;
        case ENOTDIR:
            error(ERR_CANNOT_ENTER_DIRECTORY, url.prettyURL());
            break;
        case EFAULT:
        case EINVAL:
            error(ERR_DOES_NOT_EXIST, url.prettyURL());
            break;
        case EPERM:
        case EACCES:
            error(ERR_ACCESS_DENIED, url.prettyURL());
            break;
        case EIO:
        case ENETUNREACH:
            if(url.getType() == SMBURLTYPE_ENTIRE_NETWORK || url.getType() == SMBURLTYPE_WORKGROUP_OR_SERVER)
                error(ERR_SLAVE_DEFINED, i18n("Error while connecting to server responsible for %1").arg(url.prettyURL()));
            else
                error(ERR_CONNECTION_BROKEN, url.prettyURL());
            break;
        case ENOMEM:
            error(ERR_OUT_OF_MEMORY, url.prettyURL());
            break;
        case ENODEV:
            error(ERR_SLAVE_DEFINED, i18n("Share could not be found on given server"));
            break;
        case EBADF:
            error(ERR_INTERNAL, i18n("BAD File descriptor"));
            break;
        case ETIMEDOUT:
            error(ERR_SERVER_TIMEOUT, url.host());
            break;
#ifdef ENOTUNIQ
        case ENOTUNIQ:
            error(ERR_SLAVE_DEFINED, i18n("The given name could not be resolved to a unique server. "
                                          "Make sure your network is setup without any name conflicts "
                                          "between names used by Windows and by UNIX name resolution."));
            break;
#endif
        case 0: // success
            error(ERR_INTERNAL, i18n("libsmbclient reported an error, but did not specify "
                                     "what the problem is. This might indicate a severe problem "
                                     "with your network - but also might indicate a problem with "
                                     "libsmbclient.\n"
                                     "If you want to help us, please provide a tcpdump of the "
                                     "network interface while you try to browse (be aware that "
                                     "it might contain private data, so do not post it if you are "
                                     "unsure about that - you can send it privately to the developers "
                                     "if they ask for it)"));
            break;
        default:
            error(ERR_INTERNAL, i18n("Unknown error condition in stat: %1").arg(QString::fromLocal8Bit(strerror(errno))));
    }
}