summaryrefslogtreecommitdiffstats
path: root/src/kvilib/ext/kvi_mediatype.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 02:13:59 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 02:13:59 +0000
commita6d58bb6052ac8cb01805a48c4ad2f129126116f (patch)
treedd867a099fcbb263a8009a9fb22695b87855dad6 /src/kvilib/ext/kvi_mediatype.cpp
downloadkvirc-a6d58bb6052ac8cb01805a48c4ad2f129126116f.tar.gz
kvirc-a6d58bb6052ac8cb01805a48c4ad2f129126116f.zip
Added KDE3 version of kvirc
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kvirc@1095341 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/kvilib/ext/kvi_mediatype.cpp')
-rw-r--r--src/kvilib/ext/kvi_mediatype.cpp541
1 files changed, 541 insertions, 0 deletions
diff --git a/src/kvilib/ext/kvi_mediatype.cpp b/src/kvilib/ext/kvi_mediatype.cpp
new file mode 100644
index 00000000..87c7926d
--- /dev/null
+++ b/src/kvilib/ext/kvi_mediatype.cpp
@@ -0,0 +1,541 @@
+//
+// File : kvi_mediatype.cpp
+// Creation date : Mon Aug 21 2000 17:51:56 CEST by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000-2001 Szymon Stefanek (pragma at kvirc dot 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 opinion) any later version.
+//
+// This program is distributed in the HOPE that it will be USEFUL,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#define __KVILIB__
+
+
+//#define _KVI_DEBUG_CHECK_RANGE_
+
+
+
+#include "kvi_debug.h"
+#include "kvi_mediatype.h"
+#include "kvi_config.h"
+#include "kvi_fileutils.h"
+#include "kvi_locale.h"
+#include "kvi_file.h"
+
+#include "kvi_settings.h"
+
+#include <qregexp.h>
+#include <qdir.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+
+#ifndef COMPILE_ON_WINDOWS
+ #include <unistd.h>
+ #include "kvi_malloc.h"
+#endif
+
+
+
+#ifndef S_ISDIR
+#define S_ISDIR(__f) (__f & _S_IFDIR)
+#endif
+
+#ifndef S_ISFIFO
+#define S_ISFIFO(__f) (__f & _S_IFIFO)
+#endif
+
+#ifndef S_ISREG
+#define S_ISREG(__f) (__f & _S_IFREG)
+#endif
+
+#ifndef S_ISCHR
+#define S_ISCHR(__f) (__f & _S_IFCHR)
+#endif
+
+#ifndef COMPILE_ON_WINDOWS
+ #include <dirent.h>
+#else
+ #include "kvi_malloc.h"
+#endif
+
+
+
+
+KviMediaManager::KviMediaManager()
+: KviMutex()
+{
+ m_pMediaTypeList = new KviPointerList<KviMediaType>;
+ m_pMediaTypeList->setAutoDelete(true);
+}
+
+KviMediaManager::~KviMediaManager()
+{
+ delete m_pMediaTypeList;
+}
+
+KviMediaType * KviMediaManager::findMediaTypeByIanaType(const char * ianaType)
+{
+ __range_valid(locked());
+ for(KviMediaType * mt = m_pMediaTypeList->first();mt;mt = m_pMediaTypeList->next())
+ {
+ if(kvi_strEqualCI(mt->szIanaType.ptr(),ianaType))return mt;
+ }
+
+ return 0;
+}
+
+KviMediaType * KviMediaManager::findMediaTypeByFileMask(const char * filemask)
+{
+ __range_valid(locked());
+ for(KviMediaType * mt = m_pMediaTypeList->first();mt;mt = m_pMediaTypeList->next())
+ {
+// FIXME: #warning "Should this be case sensitive ?"
+ if(kvi_strEqualCI(mt->szFileMask.ptr(),filemask))return mt;
+ }
+
+ return 0;
+}
+
+void KviMediaManager::copyMediaType(KviMediaType * dst,KviMediaType * src)
+{
+ dst->szFileMask = src->szFileMask;
+ dst->szMagicBytes = src->szMagicBytes;
+ dst->szIanaType = src->szIanaType;
+ dst->szDescription = src->szDescription;
+ dst->szSavePath = src->szSavePath;
+ dst->szCommandline = src->szCommandline;
+ dst->szRemoteExecCommandline = src->szRemoteExecCommandline;
+ dst->szIcon = src->szIcon;
+}
+
+
+void KviMediaManager::insertMediaType(KviMediaType * m)
+{
+ __range_valid(locked());
+ int iWildCount = m->szFileMask.occurences('*');
+ int iNonWildCount = m->szFileMask.len() - iWildCount;
+
+ // The masks with no wildcards go first in the list
+ // then we insert the ones with more non-wild chars
+
+ int index = 0;
+ for(KviMediaType * mt = m_pMediaTypeList->first();mt;mt = m_pMediaTypeList->next())
+ {
+ if(iWildCount)
+ {
+ // the new mask has wildcards... if the current one has none, skip it
+ int iWildCountExisting = mt->szFileMask.occurences('*');
+ if(iWildCountExisting)
+ {
+ // the one in the list has wildcards too...
+ // the ones with more non-wild chars go first...
+ int iNonWildCountExisting = mt->szFileMask.len() - iWildCountExisting;
+ if(iNonWildCountExisting < iNonWildCount)
+ {
+ // ok...the new one has more non-wildcards , insert
+ m_pMediaTypeList->insert(index,m);
+ return;
+ } else {
+ if(iNonWildCount == iNonWildCountExisting)
+ {
+ // the same number of non-wildcards
+ // let the number of wildcards decide (it will be eventually equal)
+ if(iWildCount < iWildCountExisting)
+ {
+ // the new one has less wildcards... goes first
+ m_pMediaTypeList->insert(index,m);
+ return;
+ } // else the same number of wildcards and non-wildcards...skip
+ } // else the existing one has more non-wildcards...skip
+ }
+ } // else the current has no wildcards...skip
+ } else {
+ // the new mask has no wildcards....
+ if(mt->szFileMask.contains('*'))
+ {
+ // current one has wildcards...insert
+ m_pMediaTypeList->insert(index,m);
+ return;
+ }
+ // the current one has no wildcards...
+ // the longer masks go first....
+ if(mt->szFileMask.len() < m->szFileMask.len())
+ {
+ // the current one is shorter than the new one...insert
+ m_pMediaTypeList->insert(index,m);
+ return;
+ } // else current one is longer...skip
+ }
+ index++;
+ }
+ m_pMediaTypeList->append(m);
+
+/*
+ // the masks with no wildcards go first
+ // longer masks go first
+
+ bool bHasWildcards = m->szFileMask.contains('*');
+ int index = 0;
+ for(KviMediaType * mt = m_pMediaTypeList->first();mt;mt = m_pMediaTypeList->next())
+ {
+ if(bHasWildcards)
+ {
+ if(mt->szFileMask.len() < m->szFileMask.len())
+ {
+ m_pMediaTypeList->insert(index,m);
+ return;
+ } else if(mt->szFileMask.len() == m->szFileMask.len())
+ {
+ if(mt->szMagicBytes.len() < m->szMagicBytes.len())
+ {
+ m_pMediaTypeList->insert(index,m);
+ return;
+ }
+ }
+ } else {
+ if(mt->szFileMask.contains('*'))
+ {
+ m_pMediaTypeList->insert(index,m);
+ return;
+ } else {
+ if(mt->szFileMask.len() < m->szFileMask.len())
+ {
+ m_pMediaTypeList->insert(index,m);
+ return;
+ } else if(mt->szFileMask.len() == m->szFileMask.len())
+ {
+ if(mt->szMagicBytes.len() < m->szMagicBytes.len())
+ {
+ m_pMediaTypeList->insert(index,m);
+ return;
+ }
+ }
+ }
+ }
+ index++;
+ }
+ m_pMediaTypeList->append(m);
+*/
+}
+
+
+KviMediaType * KviMediaManager::findMediaType(const char * filename,bool bCheckMagic)
+{
+ // FIXME: This should be ported at least to QString....
+ __range_valid(locked());
+
+ KviStr szFullPath = filename;
+ if(!kvi_isAbsolutePath(szFullPath.ptr()))
+ {
+#ifdef COMPILE_USE_QT4
+ KviStr tmp = QDir::currentPath();
+#else
+ KviStr tmp = QDir::currentDirPath();
+#endif
+ tmp.ensureLastCharIs('/');
+ szFullPath.prepend(tmp);
+ }
+
+ KviStr szFile = filename;
+ szFile.cutToLast('/',true);
+
+
+ // first of all , lstat() the file
+#ifdef COMPILE_ON_WINDOWS
+ struct _stat st;
+ if(_stat(szFullPath.ptr(),&st) != 0)
+#else
+ struct stat st;
+ if(lstat(szFullPath.ptr(),&st) != 0)
+#endif
+ {
+ //debug("Problems while stating file %s",szFullPath.ptr());
+ // We do just the pattern matching
+ // it's better to avoid magic checks
+ // if the file is a device , we would be blocked while attempting to read data
+ return findMediaTypeForRegularFile(szFullPath.ptr(),szFile.ptr(),false);
+ } else {
+ // If it is a link , stat() the link target
+#ifndef COMPILE_ON_WINDOWS
+ if(S_ISLNK(st.st_mode))
+ {
+ if(stat(szFullPath.ptr(),&st) != 0)
+ {
+ debug("Problems while stating() target for link %s",szFullPath.ptr());
+ // Same as above
+ return findMediaTypeForRegularFile(szFullPath.ptr(),szFile.ptr(),false);
+ }
+ }
+#endif
+ }
+
+
+ if(S_ISDIR(st.st_mode))
+ {
+ // Directory : return default media type
+ KviMediaType * mtd = findMediaTypeByIanaType("inode/directory");
+ if(!mtd)
+ {
+ // Add it
+ mtd = new KviMediaType;
+ mtd->szIanaType = "inode/directory";
+ mtd->szDescription = __tr("Directory");
+ mtd->szCommandline = "dirbrowser.open -m $0";
+ mtd->szIcon = "kvi_dbfolder.png"; // hardcoded ?
+ insertMediaType(mtd);
+ }
+ return mtd;
+ }
+
+
+#ifndef COMPILE_ON_WINDOWS
+ if(S_ISSOCK(st.st_mode))
+ {
+ // Socket : return default media type
+ KviMediaType * mtd = findMediaTypeByIanaType("inode/socket");
+ if(!mtd)
+ {
+ // Add it
+ mtd = new KviMediaType;
+ mtd->szIanaType = "inode/socket";
+ mtd->szDescription = __tr("Socket");
+ mtd->szIcon = "kvi_dbsocket.png"; // hardcoded ?
+ insertMediaType(mtd);
+ }
+ return mtd;
+ }
+#endif
+
+ if(S_ISFIFO(st.st_mode))
+ {
+ // Fifo: return default media type
+ KviMediaType * mtd = findMediaTypeByIanaType("inode/fifo");
+ if(!mtd)
+ {
+ // Add it
+ mtd = new KviMediaType;
+ mtd->szIanaType = "inode/fifo";
+ mtd->szDescription = __tr("Fifo");
+ mtd->szIcon = "kvi_dbfifo.png"; // hardcoded ?
+ insertMediaType(mtd);
+ }
+ return mtd;
+ }
+
+#ifndef COMPILE_ON_WINDOWS
+ if(S_ISBLK(st.st_mode))
+ {
+ // Block device: return default media type
+ KviMediaType * mtd = findMediaTypeByIanaType("inode/blockdevice");
+ if(!mtd)
+ {
+ // Add it
+ mtd = new KviMediaType;
+ mtd->szIanaType = "inode/blockdevice";
+ mtd->szDescription = __tr("Block device");
+ mtd->szIcon = "kvi_dbblockdevice.png"; // hardcoded ?
+ insertMediaType(mtd);
+ }
+ return mtd;
+ }
+#endif
+
+ if(S_ISCHR(st.st_mode))
+ {
+ // Char device: return default media type
+ KviMediaType * mtd = findMediaTypeByIanaType("inode/chardevice");
+ if(!mtd)
+ {
+ // Add it
+ mtd = new KviMediaType;
+ mtd->szIanaType = "inode/chardevice";
+ mtd->szDescription = __tr("Char device");
+ mtd->szIcon = "kvi_dbchardevice.png"; // hardcoded ?
+ insertMediaType(mtd);
+ }
+ return mtd;
+ }
+
+
+ // this is a regular file (or at least it looks like one)
+ return findMediaTypeForRegularFile(szFullPath.ptr(),szFile.ptr(),bCheckMagic);
+}
+
+KviMediaType * KviMediaManager::findMediaTypeForRegularFile(const char * szFullPath,const char * szFileName,bool bCheckMagic)
+{
+ char buffer[17];
+ int len = 0;
+
+ if(bCheckMagic)
+ {
+ QString szTmp=QString::fromUtf8(szFullPath);
+ KviFile f(szTmp);
+ if(f.openForReading())
+ {
+ len = f.readBlock(buffer,16);
+ if(len > 0)
+ {
+ buffer[len] = '\0';
+ if(buffer[0] == 0)len = 0; // no way to match it
+ }
+ f.close();
+ }
+ }
+
+ for(KviMediaType * m = m_pMediaTypeList->first();m;m = m_pMediaTypeList->next())
+ {
+// FIXME: #warning "Should this be case sensitive ?"
+ if(kvi_matchWildExpr(m->szFileMask.ptr(),szFileName))
+ {
+ if(len && m->szMagicBytes.hasData())
+ {
+ QRegExp re(m->szMagicBytes.ptr());
+ // It looks like they can't decide the name for this function :D
+ // ... well, maybe the latest choice is the best one.
+#ifdef COMPILE_USE_QT4
+ if(re.indexIn(buffer) > -1)return m; // matched!
+#else
+ #if QT_VERSION >= 300
+ if(re.search(buffer) > -1)return m; // matched!
+ #else
+ if(re.find(buffer,0) > -1)return m; // matched!
+ #endif
+#endif
+ // else magic failed...not a match
+ } else return m; // matched! (no magic check)
+ }
+ }
+
+ KviMediaType * mtd = findMediaTypeByIanaType("application/octet-stream");
+ if(!mtd)
+ {
+ // Add it
+ mtd = new KviMediaType;
+ mtd->szIanaType = "application/octet-stream";
+ mtd->szDescription = __tr("Octet stream (unknown)");
+ mtd->szCommandline = "editor.open $0";
+ mtd->szIcon = "kvi_dbunknown.png"; // hardcoded ?
+ insertMediaType(mtd);
+ }
+
+ return mtd;
+}
+
+typedef struct _KviDefaultMediaType
+{
+ const char * filemask;
+ const char * magicbytes;
+ const char * ianatype;
+ const char * description;
+ const char * commandline;
+} KviDefaultMediaType;
+
+
+// FIXME : default handlers for windows ?
+
+static KviDefaultMediaType g_defMediaTypes[]=
+{
+ { "*.jpg","^\\0330\\0377","image/jpeg","JPEG image","run kview $0" },
+ { "*.jpeg","^\\0330\\0377","image/jpeg","JPEG image","run kview $0" },
+ { "*.png","","image/png","PNG image","run kview $0" },
+ { "*.mp3","","audio/mpeg","MPEG audio","run xmms -e $0" },
+ { "*.gif","","image/gif","GIF image","run kvirc $0" },
+ { "*.mpeg","","video/mpeg","MPEG video","run xanim $0" },
+ { "*.exe","","application/x-executable-file","Executable file","run $0" },
+ { "*.zip","^PK\\0003\\0004","application/zip","ZIP archive","run ark $0" },
+ { "*.tar.gz","","application/x-gzip","GZipped tarball","run ark $0" },
+ { "*.tar.bz2","","applicatoin/x-bzip2","BZipped tarball","run ark $0" },
+ { "*.tgz","","application/x-gzip","GZipped tarball","run ark $0" },
+ { "*.wav","","audio/wav","Wave audio","run play $0" },
+ { 0,0,0,0,0 }
+};
+
+void KviMediaManager::load(const char * filename)
+{
+ __range_valid(locked());
+
+ KviConfig cfg(filename,KviConfig::Read);
+ cfg.setGroup("MediaTypes");
+ unsigned int nEntries = cfg.readUIntEntry("NEntries",0);
+ for(unsigned int i = 0; i < nEntries;i++)
+ {
+ KviMediaType * m = new KviMediaType;
+ KviStr tmp(KviStr::Format,"%dFileMask",i);
+ m->szFileMask = cfg.readEntry(tmp.ptr(),"");
+ tmp.sprintf("%dMagicBytes",i);
+ m->szMagicBytes = cfg.readEntry(tmp.ptr(),"");
+ tmp.sprintf("%dIanaType",i);
+ m->szIanaType = cfg.readEntry(tmp.ptr(),"application/unknown");
+ tmp.sprintf("%dDescription",i);
+ m->szDescription = cfg.readEntry(tmp.ptr(),"");
+ tmp.sprintf("%dSavePath",i);
+ m->szSavePath = cfg.readEntry(tmp.ptr(),"");
+ tmp.sprintf("%dCommandline",i);
+ m->szCommandline = cfg.readEntry(tmp.ptr(),"");
+ tmp.sprintf("%dRemoteExecCommandline",i);
+ m->szRemoteExecCommandline = cfg.readEntry(tmp.ptr(),"");
+ tmp.sprintf("%dIcon",i);
+ m->szIcon = cfg.readEntry(tmp.ptr(),"");
+ insertMediaType(m);
+ }
+
+ for(int u = 0;g_defMediaTypes[u].filemask;u++)
+ {
+ if(!findMediaTypeByFileMask(g_defMediaTypes[u].filemask))
+ {
+ KviMediaType * m = new KviMediaType;
+ m->szFileMask = g_defMediaTypes[u].filemask;
+ m->szMagicBytes = g_defMediaTypes[u].magicbytes;
+ m->szIanaType = g_defMediaTypes[u].ianatype;
+ m->szDescription = g_defMediaTypes[u].description;
+ m->szCommandline = g_defMediaTypes[u].commandline;
+ insertMediaType(m);
+ }
+ }
+
+}
+
+void KviMediaManager::save(const char * filename)
+{
+ __range_valid(locked());
+ KviConfig cfg(filename,KviConfig::Write);
+
+ cfg.clear();
+ cfg.setGroup("MediaTypes");
+ cfg.writeEntry("NEntries",m_pMediaTypeList->count());
+ int index = 0;
+ for(KviMediaType * m= m_pMediaTypeList->first();m;m = m_pMediaTypeList->next())
+ {
+ KviStr tmp(KviStr::Format,"%dFileMask",index);
+ cfg.writeEntry(tmp.ptr(),m->szFileMask.ptr());
+ tmp.sprintf("%dMagicBytes",index);
+ cfg.writeEntry(tmp.ptr(),m->szMagicBytes.ptr());
+ tmp.sprintf("%dIanaType",index);
+ cfg.writeEntry(tmp.ptr(),m->szIanaType.ptr());
+ tmp.sprintf("%dDescription",index);
+ cfg.writeEntry(tmp.ptr(),m->szDescription.ptr());
+ tmp.sprintf("%dSavePath",index);
+ cfg.writeEntry(tmp.ptr(),m->szSavePath.ptr());
+ tmp.sprintf("%dCommandline",index);
+ cfg.writeEntry(tmp.ptr(),m->szCommandline.ptr());
+ tmp.sprintf("%dRemoteExecCommandline",index);
+ cfg.writeEntry(tmp.ptr(),m->szRemoteExecCommandline.ptr());
+ tmp.sprintf("%dIcon",index);
+ cfg.writeEntry(tmp.ptr(),m->szIcon.ptr());
+ ++index;
+ }
+}