aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvovanec <vovanec@90c681e8-e032-0410-971d-27865f9a5e38>2007-09-27 21:24:44 +0000
committervovanec <vovanec@90c681e8-e032-0410-971d-27865f9a5e38>2007-09-27 21:24:44 +0000
commit381f4fed30fe4e5408cddf7e540ce2deca1b3baf (patch)
treec830e6dc158db0f6e4fb70c45435b91122108823 /src
parent0521ee9675e9434c240094a6c9e5ee15eaa9ee43 (diff)
downloadqmmp-381f4fed30fe4e5408cddf7e540ce2deca1b3baf.tar.gz
qmmp-381f4fed30fe4e5408cddf7e540ce2deca1b3baf.tar.bz2
qmmp-381f4fed30fe4e5408cddf7e540ce2deca1b3baf.zip
redesigned command line interface
git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@162 90c681e8-e032-0410-971d-27865f9a5e38
Diffstat (limited to 'src')
-rw-r--r--src/guard.cpp125
-rw-r--r--src/guard.h36
-rw-r--r--src/mainwindow.cpp15
-rw-r--r--src/qmmpstarter.cpp100
-rw-r--r--src/qmmpstarter.h16
-rw-r--r--src/src.pro10
-rw-r--r--src/tcpserver.cpp69
-rw-r--r--src/tcpserver.h51
-rw-r--r--src/unixdomainsocket.cpp67
-rw-r--r--src/unixdomainsocket.h46
-rw-r--r--src/version.h7
11 files changed, 188 insertions, 354 deletions
diff --git a/src/guard.cpp b/src/guard.cpp
deleted file mode 100644
index d9c701951..000000000
--- a/src/guard.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2006 by Ilya Kotov *
- * forkotov02@hotmail.ru *
- * *
- * 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 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#include "guard.h"
-
-//#define USE_SEMAPHORE
-
-#ifdef USE_SEMAPHORE
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <errno.h>
- #include <sys/sem.h>
-#else
- #include <QSettings>
-#endif
-
-#include <QDir>
-
-bool Guard::create(const QString& filepath)
-{
-#ifdef USE_SEMAPHORE
- key_t key;
- int sem_num = 1;
- if( (key = ftok(filepath.toAscii().data(),'A')) < 0)
- {
- qWarning("Warning: Unable get access to key...");
- return false;
- }
-
- if(semget(key,sem_num,IPC_CREAT | IPC_EXCL ) < 0)
- {
- if(errno == EEXIST)
- {
- qWarning("Warning: Semaphore with %d key already exists...",key);
- }
- return false;
- }
-
- return true;
-#else
- Q_UNUSED(filepath)
- QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat);
- settings.beginGroup("Application");
- settings.setValue("IS_RUNNING",TRUE);
- settings.endGroup();
- return true;
-#endif
-}
-
-bool Guard::exists(const QString& filepath)
-{
-#ifdef USE_SEMAPHORE
- key_t key;
- int sem_num = 1;
- int sem_id;
-
- if( (key = ftok(filepath.toAscii().data(),'A')) < 0)
- {
- qWarning("Warning: Unable get access to key");
- return false;
- }
-
- if( (sem_id = semget(key,sem_num,0)) < 0 )
- return false;
- return true;
-#else
- Q_UNUSED(filepath)
- QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat);
- settings.beginGroup("Application");
- bool res = settings.value("IS_RUNNING",FALSE).toBool();
- settings.endGroup();
- return res;
-#endif
-}
-
-bool Guard::destroy(const QString& filepath)
-{
-#ifdef USE_SEMAPHORE
- key_t key;
- int sem_num = 1;
- int sem_id;
-
- if( (key = ftok(filepath.toAscii().data(),'A')) < 0)
- {
- qWarning("Warning: Unable get access to key");
- return false;
- }
- if( (sem_id = semget(key,sem_num,0)) < 0 )
- {
- qWarning("Unable get semaphore with key %d",key);
- return false;
- }
-
- if(semctl(sem_id,1,IPC_RMID) < 0)
- {
- qWarning("Unable remove semaphore with key %d",key);
- return false;
- }
- return true;
-#else
- Q_UNUSED(filepath)
- QSettings settings(QDir::homePath()+"/.qmmp/qmmprc", QSettings::IniFormat);
- settings.beginGroup("Application");
- settings.setValue("IS_RUNNING",FALSE);
- settings.endGroup();
- return true;
-#endif
-}
diff --git a/src/guard.h b/src/guard.h
deleted file mode 100644
index 2ae05be4a..000000000
--- a/src/guard.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2006 by Ilya Kotov *
- * forkotov02@hotmail.ru *
- * *
- * 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 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifndef _GUARD_H
-#define _GUARD_H
-
-#include <QString>
-
-/**
- @author Vladimir Kuznetsov <vovanec@gmail.com>
- */
-struct Guard
-{
- static bool create(const QString& filepath);
- static bool exists(const QString& filepath);
- static bool destroy(const QString& filepath);
-};
-#endif
-
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 36d672175..1e8280875 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -39,7 +39,6 @@
#include "eqwidget.h"
#include "mainvisual.h"
#include "playlistformat.h"
-#include "tcpserver.h"
#include "jumptotrackdialog.h"
#include "aboutdialog.h"
#include <addurldialog.h>
@@ -138,10 +137,6 @@ MainWindow::MainWindow(const QStringList& args, QWidget *parent)
updateEQ();
updateSkin();
- // Starting the TcpServer
-
- new TcpServer(this);
-
FileDialog::registerBuiltinFactories();
FileDialog::registerExternalFactories();
@@ -764,9 +759,17 @@ bool MainWindow::processCommandArgs(const QStringList &slist,const QString& cwd)
else if (str == "--pause")
pause();
else if (str == "--next")
+ {
next();
+ if(!m_core->isInitialized())
+ play();
+ }
else if (str == "--previous")
+ {
previous();
+ if(!m_core->isInitialized())
+ play();
+ }
else if (str == "--play-pause")
playPause();
else
@@ -781,8 +784,6 @@ bool MainWindow::processCommandArgs(const QStringList &slist,const QString& cwd)
full_path_list << s;
else
full_path_list << cwd + "/" + s;
- //qWarning("Current working dir: %s",qPrintable(workingDir));
- //qWarning("Full path to play: %s",qPrintable(workingDir + "/" + s));
}
setFileList(full_path_list);
}
diff --git a/src/qmmpstarter.cpp b/src/qmmpstarter.cpp
index 4aab25da6..0ebf766fc 100644
--- a/src/qmmpstarter.cpp
+++ b/src/qmmpstarter.cpp
@@ -19,16 +19,17 @@
***************************************************************************/
#include <QApplication>
-#include <QTcpSocket>
+#include "unixdomainsocket.h"
#include <unistd.h>
#include "mainwindow.h"
#include "version.h"
#include "qmmpstarter.h"
-#include "guard.h"
-QMMPStarter::QMMPStarter(int argc,char ** argv,QObject* parent) : QObject(parent),mw(0)
+#define MAXCOMMANDSIZE 64
+
+QMMPStarter::QMMPStarter(int argc,char ** argv,QObject* parent) : QObject(parent),mw(NULL)
{
QStringList tmp;
for(int i = 1;i < argc;i++)
@@ -59,52 +60,40 @@ QMMPStarter::QMMPStarter(int argc,char ** argv,QObject* parent) : QObject(parent
qFatal("QMMP: Unknown command...");
exit(1);
}
-
- if(Guard::exists(QApplication::applicationFilePath()))
- {
- m_tcpSocket = new QTcpSocket(this);
- connect(m_tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
- this, SLOT(displayError(QAbstractSocket::SocketError)));
- connect(m_tcpSocket, SIGNAL(connected()),this, SLOT(writeCommand()));
-
- m_tcpSocket->connectToHost("127.0.0.1",TCPSERVER_PORT_NUMBER + getuid());
-
- }
- else
- {
- Guard::create(QApplication::applicationFilePath());
- QStringList arg_l = argString.split("\n", QString::SkipEmptyParts);
- mw = new MainWindow(arg_l,0);
- }
+
+ m_sock = new UnixDomainSocket(this);
+ if(m_sock->bind(UDS_PATH))
+ {
+ startMainWindow();
+ }
+ else if(!m_sock->alive(UDS_PATH)){
+ // Socket is present but not connectable - application was terminated previously???
+ unlink(UDS_PATH);
+ if(m_sock->bind(UDS_PATH))
+ {
+ startMainWindow();
+ }
+ else
+ {
+ qDebug("Fatal socket error, exiting");
+ exit(1);
+ }
+ }
+ else // socket is alive, qmmp application is already running. passing command to it!
+ writeCommand();
}
-void QMMPStarter::displayError(QAbstractSocket::SocketError socketError)
+QMMPStarter::~ QMMPStarter()
{
- switch (socketError)
- {
- case QAbstractSocket::RemoteHostClosedError:
- break;
- case QAbstractSocket::HostNotFoundError:
- qWarning("The host was not found");
- break;
- case QAbstractSocket::ConnectionRefusedError:
- qWarning("The connection was refused by the peer. ");
- break;
- default:
- qWarning("The following error: %s:",qPrintable(m_tcpSocket->errorString()));
- }
-
- Guard::create(QApplication::applicationFilePath());
- mw = new MainWindow(argString.split("\n", QString::SkipEmptyParts),0);
+ qWarning("QMMPStarter::~ QMMPStarter()");
+ if(mw) delete mw;
}
-QMMPStarter::~ QMMPStarter()
+void QMMPStarter::startMainWindow()
{
- if(mw)
- {
- Guard::destroy(QApplication::applicationFilePath());
- delete mw;
- }
+ connect(m_sock, SIGNAL(readyRead()),this, SLOT(readCommand()));
+ QStringList arg_l = argString.split("\n", QString::SkipEmptyParts);
+ mw = new MainWindow(arg_l,0);
}
void QMMPStarter::writeCommand()
@@ -117,18 +106,29 @@ void QMMPStarter::writeCommand()
QByteArray barray;
barray.append(workingDir);
barray.append(argString);
-
- m_tcpSocket->write(barray);
- m_tcpSocket->flush();
+ m_sock->writeDatagram ( barray.data(),UDS_PATH);
}
else
{
- qWarning("It seems that another version of application is already running ...\n");
printUsage();
}
- m_tcpSocket->close();
- QApplication::quit();
+ exit(0);
+}
+
+void QMMPStarter::readCommand()
+{
+ QByteArray inputArray;
+ inputArray.resize(MAXCOMMANDSIZE);
+ bzero(inputArray.data(),inputArray.size());
+ m_sock->readDatagram(inputArray.data(), inputArray.size());
+ QStringList slist = QString(inputArray).split("\n",QString::SkipEmptyParts);
+ QString cwd = slist.takeAt(0);
+ if(mw)
+ {
+ mw->processCommandArgs(slist,cwd);
+ }
+
}
void QMMPStarter::printUsage()
@@ -154,3 +154,5 @@ void QMMPStarter::printVersion()
qWarning("QMMP version: %s",QMMP_STR_VERSION);
}
+
+
diff --git a/src/qmmpstarter.h b/src/qmmpstarter.h
index b3094eb69..c859496cf 100644
--- a/src/qmmpstarter.h
+++ b/src/qmmpstarter.h
@@ -25,14 +25,14 @@
#include <QAbstractSocket>
#include <QStringList>
-class QTcpSocket;
+class UnixDomainSocket;
class MainWindow;
/*!
* QMMPStarter represents wrapper object that is responsible
* for proper QMMP initialization(only one instance of running
- * MainWindow) and passing command line args to the TcpServer.
+ * MainWindow) and passing command line args to application.
* @author Vladimir Kuznetsov <vovanec@gmail.com>
*/
class QMMPStarter : public QObject
@@ -42,15 +42,13 @@ public:
QMMPStarter(int argc,char ** argv,QObject* parent = 0);
~QMMPStarter();
protected slots:
- /*!
- * Displays error message.
- */
- void displayError(QAbstractSocket::SocketError socketError);
/*!
- * Passes command args to the running TCP server
+ * Passes command args to the running application
*/
void writeCommand();
+
+ void readCommand();
private:
/*!
* Prints usage
@@ -61,9 +59,11 @@ private:
* Prints version of program
*/
void printVersion();
+
+ void startMainWindow();
private:
MainWindow* mw;
- QTcpSocket* m_tcpSocket;
+ UnixDomainSocket* m_sock;
QString argString;
};
diff --git a/src/src.pro b/src/src.pro
index a7d321a73..9355db692 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -47,16 +47,15 @@ HEADERS += mainwindow.h \
playlistformat.h \
playlistcontrol.h \
version.h \
- tcpserver.h \
qmmpstarter.h \
- guard.h \
eqpreset.h \
preseteditor.h \
jumptotrackdialog.h \
aboutdialog.h \
timeindicator.h \
keyboardmanager.h \
- filedialog.h
+ filedialog.h \
+ unixdomainsocket.h
SOURCES += mainwindow.cpp \
@@ -96,15 +95,14 @@ SOURCES += mainwindow.cpp \
playlistformat.cpp \
playlistcontrol.cpp \
qmmpstarter.cpp \
- tcpserver.cpp \
- guard.cpp \
eqpreset.cpp \
preseteditor.cpp \
jumptotrackdialog.cpp \
aboutdialog.cpp \
timeindicator.cpp \
keyboardmanager.cpp \
- filedialog.cpp
+ filedialog.cpp \
+ unixdomainsocket.cpp
diff --git a/src/tcpserver.cpp b/src/tcpserver.cpp
deleted file mode 100644
index 735df2716..000000000
--- a/src/tcpserver.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2006 by Ilya Kotov *
- * forkotov02@hotmail.ru *
- * *
- * 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 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#include <QStringList>
-#include <QApplication>
-#include <QTcpSocket>
-#include <QRegExp>
-#include <QTimer>
-
-#include <unistd.h>
-
-#include "mainwindow.h"
-#include "tcpserver.h"
-#include "version.h"
-
-TcpServer::TcpServer(MainWindow* parent) : QTcpServer(parent) , m_mainWindow(parent)
-{
- if (!listen(QHostAddress::LocalHost,TCPSERVER_PORT_NUMBER + getuid()))
- {
- qFatal("Unable to start the server: %s ",qPrintable(errorString()));
- QApplication::exit(1);
- }
-
- connect(this, SIGNAL(newConnection()), this, SLOT(handleNewConnection()));
- qDebug("TcpServer running at localost port %d",TCPSERVER_PORT_NUMBER + getuid());
-}
-
-void TcpServer::handleNewConnection()
-{
- clientConnection = nextPendingConnection();
- connect(clientConnection, SIGNAL(readyRead()),this, SLOT(readCommand()));
-}
-
-
-void TcpServer::readCommand()
-{
- QByteArray inputArray(clientConnection->readAll());
- QStringList slist = QString(inputArray).split("\n",QString::SkipEmptyParts);
- QString cwd = slist.takeAt(0);
- m_mainWindow->processCommandArgs(slist,cwd);
-
- if(clientConnection)
- {
- clientConnection->disconnectFromHost();
- if(clientConnection)
- delete clientConnection;
- }
-}
-
-
-
-
diff --git a/src/tcpserver.h b/src/tcpserver.h
deleted file mode 100644
index 4438f712c..000000000
--- a/src/tcpserver.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2006 by Ilya Kotov *
- * forkotov02@hotmail.ru *
- * *
- * 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 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., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
- ***************************************************************************/
-
-#ifndef _TCPSERVER_H
-#define _TCPSERVER_H
-
-#include <QTcpServer>
-#include <QPointer>
-
-class TcpSocket;
-class MainWindow;
-
-/*!
- * Class TcpServer represents server for frocessing external command line args.
- @author Vladimir Kuznetsov <vovanec@gmail.com>
- */
-
-class TcpServer : public QTcpServer
-{
-Q_OBJECT
-public:
- TcpServer(MainWindow* parent = 0);
-protected slots:
- void handleNewConnection();
- /*!
- * Reads external commands and dispatches it to the MainWindow
- */
- void readCommand();
-private:
- MainWindow* m_mainWindow;
- QPointer <QTcpSocket>clientConnection;
-};
-
-#endif
diff --git a/src/unixdomainsocket.cpp b/src/unixdomainsocket.cpp
new file mode 100644
index 000000000..ecf8aa6f0
--- /dev/null
+++ b/src/unixdomainsocket.cpp
@@ -0,0 +1,67 @@
+#include <unistd.h>
+#include <strings.h>
+#include <string.h>
+#include <errno.h>
+
+#include "unixdomainsocket.h"
+
+
+UnixDomainSocket::UnixDomainSocket(QObject * parent ) : QUdpSocket(parent){
+ _binded = false;
+ _s = socket(AF_UNIX, SOCK_DGRAM, 0);
+ this->setSocketDescriptor(_s);
+}
+
+UnixDomainSocket::~UnixDomainSocket(){
+
+ if(_binded){
+ ::unlink(_local.sun_path);
+ }
+}
+
+bool UnixDomainSocket::bind(const QString& path){
+
+ int len;
+ bzero(&_local,sizeof(_local));
+ _local.sun_family = AF_UNIX;
+ strcpy(_local.sun_path,path.toLocal8Bit().data());
+ len = strlen(_local.sun_path) + sizeof(_local.sun_family);
+ bool res = !(::bind(_s, (struct sockaddr *)&_local, len));
+ if(res)
+ _binded = true;
+ return res;
+}
+
+
+bool UnixDomainSocket::alive(const QString& path)
+{
+ socklen_t len;
+ struct sockaddr_un server;
+ bzero(&server,sizeof(server));
+ server.sun_family = AF_UNIX;
+ strcpy(server.sun_path,path.toLocal8Bit().data());
+ len = strlen(server.sun_path) + sizeof(server.sun_family);
+
+ if (::connect(_s, (struct sockaddr *)&server, len) == -1)
+ {
+ perror("connect");
+ return false;
+ }
+ return true;
+}
+
+void UnixDomainSocket::writeDatagram(const char* command,const QString& path)
+{
+ socklen_t len;
+ struct sockaddr_un server;
+ bzero(&server,sizeof(server));
+ server.sun_family = AF_UNIX;
+ strcpy(server.sun_path,path.toLocal8Bit().data());
+
+ len = strlen(server.sun_path) + sizeof(server.sun_family);
+
+ sendto(_s,command,strlen(command),0,(struct sockaddr*)&server,len);
+}
+
+
+
diff --git a/src/unixdomainsocket.h b/src/unixdomainsocket.h
new file mode 100644
index 000000000..7538e685a
--- /dev/null
+++ b/src/unixdomainsocket.h
@@ -0,0 +1,46 @@
+#ifndef UNIXDOMAINSOCKET_H
+#define UNIXDOMAINSOCKET_H
+
+#include <QUdpSocket>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <linux/un.h>
+
+
+/*!
+ * UnixDomainSocket class is a wrapper around the unix domain sockets implementation.
+ * Used for QMMP interprocess communications.
+ * @author Vladimir Kuznetsov <vovanec@gmail.com>
+ */
+class UnixDomainSocket : public QUdpSocket
+{
+Q_OBJECT
+public:
+ UnixDomainSocket(QObject * parent = 0 );
+
+ /*!
+ * Try to bind socket to \b path. Returns \b true on success, otherwise \b false
+ */
+ bool bind(const QString& file);
+
+ /*!
+ * Checks if socket at \b path path is alive( i.e. connectable).
+ */
+ bool alive(const QString& path);
+ ~UnixDomainSocket();
+
+public slots:
+ /*!
+ * Sends the datagram \b command to the socket at \b path path.
+ */
+ void writeDatagram(const char* command,const QString& path);
+private:
+ unsigned int _s;
+ struct sockaddr_un _local;
+ bool _binded;
+};
+
+
+#endif
+
diff --git a/src/version.h b/src/version.h
index 0d621bacf..61fbc902e 100644
--- a/src/version.h
+++ b/src/version.h
@@ -1,10 +1,11 @@
#ifndef _QMMP_VERSION_H
#define _QMMP_VERSION_H
-#define QMMP_VERSION 0.2.0
+#define QMMP_VERSION 0.1.4
-#define QMMP_STR_VERSION "0.2.0"
+#define QMMP_STR_VERSION "0.1.4"
-#define TCPSERVER_PORT_NUMBER 33000
+#define LISTEN_PORT_BASE 33000
+#define UDS_PATH "/tmp/qmmp.sock"
#endif