diff options
Diffstat (limited to 'kioslave/iso/kiso.cpp')
-rw-r--r-- | kioslave/iso/kiso.cpp | 460 |
1 files changed, 0 insertions, 460 deletions
diff --git a/kioslave/iso/kiso.cpp b/kioslave/iso/kiso.cpp deleted file mode 100644 index b19ec589b..000000000 --- a/kioslave/iso/kiso.cpp +++ /dev/null @@ -1,460 +0,0 @@ -/*************************************************************************** - kiso.cpp - ------------------- - begin : Oct 25 2002 - copyright : (C) 2002 by Szombathelyi Gy�gy - email : gyurco@users.sourceforge.net - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - - /* This file is heavily based on ktar.cpp from tdelibs (c) David Faure */ - -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <unistd.h> -#include <grp.h> -#include <pwd.h> -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include <tqcstring.h> -#include <tqdir.h> -#include <tqfile.h> -#include <kdebug.h> -#include <kurl.h> -#include <kmimetype.h> -#include <kconfig.h> -#include <kfilterdev.h> -#include <kfilterbase.h> - -#include "kiso.h" -#include "libisofs/isofs.h" -#include "qfilehack.h" - - -#ifdef __linux__ -#undef __STRICT_ANSI__ -#include <linux/cdrom.h> -#define __STRICT_ANSI__ -#include <sys/ioctl.h> -#include <fcntl.h> -#endif - -//////////////////////////////////////////////////////////////////////// -/////////////////////////// KIso /////////////////////////////////// -//////////////////////////////////////////////////////////////////////// - -/** - * puts the track layout of the device 'fname' into 'tracks' - * tracks structure: start sector, track number, ... - * tracks should be 100*2 entry long (this is the maximum in the CD-ROM standard) - * currently it's linux only, porters are welcome - */ -static int getTracks(const char *fname,int *tracks) { - int ret=0; - memset(tracks,0,200*sizeof(int)); - -#ifdef __linux__ - int fd,i; - struct cdrom_tochdr tochead; - struct cdrom_tocentry tocentry; - - kdDebug() << "getTracks open:" << fname << endl; - fd=open(fname, O_RDONLY | O_NONBLOCK); - if (fd > 0) { - if (ioctl(fd,CDROMREADTOCHDR,&tochead)!=-1) { - kdDebug() << "getTracks first track:" << tochead.cdth_trk0 - << " last track " << tochead.cdth_trk1 << endl; - for (i=tochead.cdth_trk0;i<=tochead.cdth_trk1;i++) { - if (ret>99) break; - memset(&tocentry,0,sizeof(struct cdrom_tocentry)); - tocentry.cdte_track=i; - tocentry.cdte_format=CDROM_LBA; - if (ioctl(fd,CDROMREADTOCENTRY,&tocentry)<0) break; - kdDebug() << "getTracks got track " << i << " starting at: " << - tocentry.cdte_addr.lba << endl; - if ((tocentry.cdte_ctrl & 0x4) == 0x4) { - tracks[ret<<1]=tocentry.cdte_addr.lba; - tracks[(ret<<1)+1]=i; - ret++; - } - } - } - close(fd); - } - -#endif - - return ret; -} - -class KIso::KIsoPrivate -{ -public: - KIsoPrivate() {} - TQStringList dirList; -}; - -KIso::KIso( const TQString& filename, const TQString & _mimetype ) - : KArchive( 0L ) -{ - m_startsec = -1; - m_filename = filename; - d = new KIsoPrivate; - TQString mimetype( _mimetype ); - bool forced = true; - if ( mimetype.isEmpty() ) - { - mimetype = KMimeType::findByFileContent( filename )->name(); - kdDebug() << "KIso::KIso mimetype=" << mimetype << endl; - - // Don't move to prepareDevice - the other constructor theoretically allows ANY filter - if ( mimetype == "application/x-tgz" || mimetype == "application/x-targz" || // the latter is deprecated but might still be around - mimetype == "application/x-webarchive" ) - // that's a gzipped tar file, so ask for gzip filter - mimetype = "application/x-gzip"; - else if ( mimetype == "application/x-tbz" ) // that's a bzipped2 tar file, so ask for bz2 filter - mimetype = "application/x-bzip2"; - else - { - // Something else. Check if it's not really gzip though (e.g. for KOffice docs) - TQFile file( filename ); - if ( file.open( IO_ReadOnly ) ) - { - unsigned char firstByte = file.getch(); - unsigned char secondByte = file.getch(); - unsigned char thirdByte = file.getch(); - if ( firstByte == 0037 && secondByte == 0213 ) - mimetype = "application/x-gzip"; - else if ( firstByte == 'B' && secondByte == 'Z' && thirdByte == 'h' ) - mimetype = "application/x-bzip2"; - else if ( firstByte == 'P' && secondByte == 'K' && thirdByte == 3 ) - { - unsigned char fourthByte = file.getch(); - if ( fourthByte == 4 ) - mimetype = "application/x-zip"; - } - } - } - forced = false; - } - - prepareDevice( filename, mimetype, forced ); -} - -void KIso::prepareDevice( const TQString & filename, - const TQString & mimetype, bool forced ) -{ - /* 'hack' for Qt's false assumption that only S_ISREG is seekable */ - if( "inode/blockdevice" == mimetype ) - setDevice( TQT_TQIODEVICE(new QFileHack( filename )) ); - else - { - if( "application/x-gzip" == mimetype - || "application/x-bzip2" == mimetype) - forced = true; - - TQIODevice *dev = KFilterDev::deviceForFile( filename, mimetype, forced ); - if( dev ) - setDevice( dev ); - } - -} - -KIso::KIso( TQIODevice * dev ) - : KArchive( dev ) -{ - d = new KIsoPrivate; -} - -KIso::~KIso() -{ - // mjarrett: Closes to prevent ~KArchive from aborting w/o device - if( isOpened() ) - close(); - if ( !m_filename.isEmpty() ) - delete device(); // we created it ourselves - delete d; -} - -/* callback function for libisofs */ -static int readf(char *buf, long long start, long long len,void *udata) { - - TQIODevice* dev = ( static_cast<KIso*> (udata) )->device(); - - if (dev->at(start<<11)) { - if ((dev->readBlock(buf, len<<11)) != -1) return (len); - } - kdDebug() << "KIso::ReadRequest failed start: " << start << " len: " << len << endl; - - return -1; -} - -/* callback function for libisofs */ -static int mycallb(struct iso_directory_record *idr,void *udata) { - - KIso *iso = static_cast<KIso*> (udata); - TQString path,user,group,symlink; - int i; - int access; - int time,cdate,adate; - rr_entry rr; - bool special=false; - KArchiveEntry *entry=NULL,*oldentry=NULL; - char z_algo[2],z_params[2]; - long long z_size=0; - - if ((idr->flags[0] & 1) && !iso->showhidden) return 0; - if (iso->level) { - if (isonum_711(idr->name_len)==1) { - switch (idr->name[0]) { - case 0: - path+=("."); - special=true; - break; - case 1: - path+=(".."); - special=true; - break; - } - } - if (iso->showrr && ParseRR(idr,&rr)>0) { - if (!special) path=rr.name; - symlink=rr.sl; - access=rr.mode; - time=rr.t_mtime; - adate=rr.t_atime; - cdate=rr.t_ctime; - user.setNum(rr.uid); - group.setNum(rr.gid); - z_algo[0]=rr.z_algo[0];z_algo[1]=rr.z_algo[1]; - z_params[0]=rr.z_params[0];z_params[1]=rr.z_params[1]; - z_size=rr.z_size; - } else { - access=iso->dirent->permissions() & ~S_IFMT; - adate=cdate=time=isodate_915(idr->date,0); - user=iso->dirent->user(); - group=iso->dirent->group(); - if (idr->flags[0] & 2) access |= S_IFDIR; else access |= S_IFREG; - if (!special) { - if (iso->joliet) { - for (i=0;i<(isonum_711(idr->name_len)-1);i+=2) { - TQChar ch( be2me_16(*((ushort*)&(idr->name[i]))) ); - if (ch==';') break; - path+=ch; - } - } else { - for (i=0;i<isonum_711(idr->name_len);i++) { - if (idr->name[i]==';') break; - if (idr->name[i]) path+=(idr->name[i]); - } - } - if (path.endsWith(".")) path.setLength(path.length()-1); - } - } - if (iso->showrr) FreeRR(&rr); - if (idr->flags[0] & 2) { - entry = new KIsoDirectory( iso, path, access | S_IFDIR, time, adate, cdate, - user, group, symlink ); - } else { - entry = new KIsoFile( iso, path, access, time, adate, cdate, - user, group, symlink, isonum_733(idr->extent)<<11,isonum_733(idr->size) ); - if (z_size) (static_cast <KIsoFile*> (entry))->setZF(z_algo,z_params,z_size); - - } - iso->dirent->addEntry(entry); - } - if ( (idr->flags[0] & 2) && (iso->level==0 || !special) ) { - if (iso->level) { - oldentry=iso->dirent; - iso->dirent=static_cast<KIsoDirectory*> (entry); - } - iso->level++; - ProcessDir(&readf,isonum_733(idr->extent),isonum_733(idr->size),&mycallb,udata); - iso->level--; - if (iso->level) iso->dirent=static_cast<KIsoDirectory*> (oldentry); - } - return 0; -} - -void KIso::addBoot(struct el_torito_boot_descriptor* bootdesc) { - - int i; - long long size; - boot_head boot; - boot_entry *be; - TQString path; - KIsoFile *entry; - - entry=new KIsoFile( this, "Catalog", dirent->permissions() & ~S_IFDIR, - dirent->date(), dirent->adate(), dirent->cdate(), - dirent->user(), dirent->group(), TQString::null, - isonum_731(bootdesc->boot_catalog)<<11, 2048 ); - dirent->addEntry(entry); - if (!ReadBootTable(&readf,isonum_731(bootdesc->boot_catalog),&boot,this)) { - i=1; - be=boot.defentry; - while (be) { - size=BootImageSize( isonum_711((reinterpret_cast<struct default_entry*>(be->data))->media), - isonum_721((reinterpret_cast<struct default_entry*>(be->data))->seccount)); - path="Default Image"; - if (i>1) path += " (" + TQString::number(i) + ")"; - entry=new KIsoFile( this, path, dirent->permissions() & ~S_IFDIR, - dirent->date(), dirent->adate(), dirent->cdate(), - dirent->user(), dirent->group(), TQString::null, - isonum_731((reinterpret_cast<struct default_entry*>(be->data))->start)<<11, size<<9 ); - dirent->addEntry(entry); - be=be->next; - i++; - } - - FreeBootTable(&boot); - } -} - -void KIso::readParams() -{ - TDEConfig *config; - - config = new TDEConfig("kio_isorc"); - - showhidden=config->readBoolEntry("showhidden",false); - showrr=config->readBoolEntry("showrr",true); - delete config; -} - -bool KIso::openArchive( int mode ) -{ - iso_vol_desc *desc; - TQString path,tmp,uid,gid; - struct stat buf; - int tracks[2*100],trackno=0,i,access,c_b,c_i,c_j; - KArchiveDirectory *root; - struct iso_directory_record* idr; - struct el_torito_boot_descriptor* bootdesc; - - if ( mode == IO_WriteOnly ) - return false; - - readParams(); - d->dirList.clear(); - - tracks[0]=0; - if (m_startsec>0) tracks[0]=m_startsec; - kdDebug() << " m_startsec: " << m_startsec << endl; - /* We'll use the permission and user/group of the 'host' file except - * in Rock Ridge, where the permissions are stored on the file system - */ - if (::stat( m_filename.local8Bit(), &buf )<0) { - /* defaults, if stat fails */ - memset(&buf,0,sizeof(struct stat)); - buf.st_mode=0777; - } else { - /* If it's a block device, try to query the track layout (for multisession) */ - if (m_startsec == -1 && S_ISBLK(buf.st_mode)) - trackno=getTracks(m_filename.latin1(),(int*) &tracks); - } - uid.setNum(buf.st_uid); - gid.setNum(buf.st_gid); - access = buf.st_mode & ~S_IFMT; - - kdDebug() << "KIso::openArchive number of tracks: " << trackno << endl; - - if (trackno==0) trackno=1; - for (i=0;i<trackno;i++) { - - c_b=1;c_i=1;c_j=1; - root=rootDir(); - if (trackno>1) { - path=TQString::null; - TQTextOStream(&path) << "Track " << tracks[(i<<1)+1]; - root = new KIsoDirectory( this, path, access | S_IFDIR, - buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, TQString::null ); - rootDir()->addEntry(root); - } - - desc=ReadISO9660(&readf,tracks[i<<1],this); - if (!desc) { - kdDebug() << "KIso::openArchive no volume descriptors" << endl; - continue; - } - - while (desc) { - switch (isonum_711(desc->data.type)) { - case ISO_VD_BOOT: - - bootdesc=(struct el_torito_boot_descriptor*) &(desc->data); - if ( !memcmp(EL_TORITO_ID,bootdesc->system_id,ISODCL(8,39)) ) { - path="El Torito Boot"; - if (c_b>1) path += " (" + TQString::number(c_b) + ")"; - - dirent = new KIsoDirectory( this, path, access | S_IFDIR, - buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, TQString::null ); - root->addEntry(dirent); - - addBoot(bootdesc); - c_b++; - } - break; - - case ISO_VD_PRIMARY: - case ISO_VD_SUPPLEMENTARY: - idr=(struct iso_directory_record*) &( ((struct iso_primary_descriptor*) &desc->data)->root_directory_record); - joliet = JolietLevel(&desc->data); - if (joliet) { - TQTextOStream(&path) << "Joliet level " << joliet; - if (c_j>1) path += " (" + TQString::number(c_j) + ")"; - } else { - path = "ISO9660"; - if (c_i>1) path += " (" + TQString::number(c_i) + ")"; - } - dirent = new KIsoDirectory( this, path, access | S_IFDIR, - buf.st_mtime, buf.st_atime, buf.st_ctime, uid, gid, TQString::null ); - root->addEntry(dirent); - level=0; - mycallb(idr, this ); - if (joliet) c_j++; else c_i++; - break; - } - desc=desc->next; - } - free(desc); - } - device()->close(); - return true; -} - -bool KIso::closeArchive() -{ - d->dirList.clear(); - return true; -} - -bool KIso::writeDir( const TQString&, const TQString&, const TQString& ) -{ - return false; -} - -bool KIso::prepareWriting( const TQString&, const TQString&, const TQString&, uint) -{ - return false; -} - -bool KIso::doneWriting( uint ) -{ - return false; -} - -void KIso::virtual_hook( int id, void* data ) -{ KArchive::virtual_hook( id, data ); } - |