apprunner.cpp
1 //------------------------------------------------------------------------------
2 // apprunner.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 USA
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2010 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "apprunner.h"
24 
25 #include "gui/standardserverconsole.h"
26 #include "log.h"
27 #include "serverapi/message.h"
28 #include "strings.hpp"
29 #include <QProcess>
30 
32 {
33  return !executable.filePath().isEmpty();
34 }
35 
36 void AppRunner::cleanArguments(QStringList &args)
37 {
38  QStringList::iterator it;
39  for (it = args.begin(); it != args.end(); ++it)
40  {
41  if (it->contains(" "))
42  Strings::trim(*it, "\"");
43  }
44 }
45 
46 #ifdef Q_OS_DARWIN
47 QString AppRunner::findBundleBinary(const QFileInfo &file)
48 {
49  // Scan the plist file for where the real binary is in a bundle. We have
50  // to do this because some bundles (ZDaemon) don't like the --args method
51  // and I heard that only works on Mac OS X 10.6 anywyas.
52  QFile pLists(file.canonicalFilePath() + "/Contents/Info.plist");
53  if (!pLists.open(QIODevice::ReadOnly | QIODevice::Text))
54  {
55  gLog << tr("Could not read bundle plist. (%1)").arg(file.canonicalFilePath() + "/Contents/Info.plist");
56  return QString();
57  }
58 
59  char line[128];
60  bool keyFound = false;
61  while (pLists.readLine(line, 128) != -1)
62  {
63  if (!keyFound)
64  {
65  if (QString(line).trimmed() == "<key>CFBundleExecutable</key>")
66  keyFound = true;
67  }
68  else
69  {
70  QString binaryLine(line);
71  binaryLine = binaryLine.trimmed();
72  if (binaryLine.startsWith("<string>") && binaryLine.endsWith("</string>"))
73  return QString("/Contents/MacOS/") + binaryLine.mid(8, binaryLine.indexOf("</string>") - 8);
74  keyFound = false;
75  }
76  }
77  return QString();
78 }
79 #endif
80 
81 Message AppRunner::runExecutable(const CommandLineInfo &cmdInfo)
82 {
83  gLog << tr("Starting (working dir %1): %2").arg(cmdInfo.applicationDir.absolutePath()).arg(cmdInfo.executable.absoluteFilePath());
84  QStringList args = cmdInfo.args;
85  cleanArguments(args);
86 
87  int result;
88 
89  #ifdef Q_OS_DARWIN
90  if ( cmdInfo.executable.isBundle())
91  result = QProcess::startDetached(cmdInfo.executable.absoluteFilePath() + AppRunner::findBundleBinary(cmdInfo.executable), args, cmdInfo.applicationDir.absolutePath());
92  else
93  #endif
94  {
95  result = QProcess::startDetached(cmdInfo.executable.absoluteFilePath(), args, cmdInfo.applicationDir.absolutePath());
96  }
97 
98  Message message;
99 
100  if (!result)
101  {
102  QString error = tr("File: %1\ncannot be run").arg(cmdInfo.executable.absoluteFilePath());
103  gLog << error;
104  message = Message::customError(error);
105  return message;
106  }
107 
108  return message;
109 }
110 
112  const QIcon &icon, const CommandLineInfo &cli)
113 {
114  gLog << tr("Starting (working dir %1): %2").arg(cli.applicationDir.absolutePath())
115  .arg(cli.executable.absoluteFilePath());
116  QStringList args = cli.args;
117  cleanArguments(args);
118  new StandardServerConsole(icon, cli.executable.absoluteFilePath(), args);
119 }