mirror of
https://github.com/autc04/Retro68.git
synced 2024-06-09 11:29:38 +00:00
LaunchAPPL --make-executable: add a #!/.../LaunchCFMApp to a mac app
This commit is contained in:
parent
bd38a209ba
commit
507ba9debf
|
@ -20,6 +20,7 @@ add_definitions(-DRETRO68_PREFIX="${CMAKE_INSTALL_PREFIX}")
|
||||||
|
|
||||||
add_executable(LaunchAPPL
|
add_executable(LaunchAPPL
|
||||||
LaunchAPPL.cc
|
LaunchAPPL.cc
|
||||||
|
MakeExecutable.cc
|
||||||
|
|
||||||
LaunchMethod.h LaunchMethod.cc
|
LaunchMethod.h LaunchMethod.cc
|
||||||
Launcher.h Launcher.cc
|
Launcher.h Launcher.cc
|
||||||
|
|
|
@ -93,7 +93,7 @@ static void usage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MakeExecutable(string filepath);
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -102,6 +102,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "show this help message")
|
("help,h", "show this help message")
|
||||||
|
("make-executable,x", po::value<std::string>(), "make a MacBinary file executable")
|
||||||
;
|
;
|
||||||
po::options_description configdesc;
|
po::options_description configdesc;
|
||||||
configdesc.add_options()
|
configdesc.add_options()
|
||||||
|
@ -158,12 +159,28 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
po::notify(options);
|
po::notify(options);
|
||||||
|
|
||||||
if(options.count("help") || !options.count("application") || !options.count("emulator"))
|
if(options.count("help") || (!options.count("application") && !options.count("make-executable")))
|
||||||
{
|
{
|
||||||
usage();
|
usage();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(options.count("make-executable"))
|
||||||
|
{
|
||||||
|
string fn = options["make-executable"].as<std::string>();
|
||||||
|
MakeExecutable(fn);
|
||||||
|
|
||||||
|
if(!options.count("application"))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!options.count("emulator"))
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: emulator/environment not specified.\n";
|
||||||
|
usage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
LaunchMethod *method = NULL;
|
LaunchMethod *method = NULL;
|
||||||
for(LaunchMethod *lm : launchMethods)
|
for(LaunchMethod *lm : launchMethods)
|
||||||
{
|
{
|
||||||
|
@ -181,7 +198,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if(!method->CheckOptions(options))
|
if(!method->CheckOptions(options))
|
||||||
{
|
{
|
||||||
std::cerr << "Missing configuration.\n";
|
std::cerr << "Need more configuration.\n";
|
||||||
usage();
|
usage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
52
LaunchAPPL/MakeExecutable.cc
Normal file
52
LaunchAPPL/MakeExecutable.cc
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "ResourceFile.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
|
void MakeExecutable(string fn)
|
||||||
|
{
|
||||||
|
ResourceFile rsrcFile(fn);
|
||||||
|
if(!rsrcFile.read())
|
||||||
|
{
|
||||||
|
std::cerr << "Cannot read application file: " << fn << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if(!rsrcFile.hasPlainDataFork())
|
||||||
|
{
|
||||||
|
std::cerr << "--make-executable can not be used with this data format.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
string headerString = "#!" RETRO68_PREFIX "/bin/LaunchAPPL\n";
|
||||||
|
|
||||||
|
bool hadShebang = false;
|
||||||
|
if(rsrcFile.data.size())
|
||||||
|
{
|
||||||
|
if(headerString.substr(2) == "#!")
|
||||||
|
{
|
||||||
|
string::size_type eol = headerString.find('\n');
|
||||||
|
if(eol != string::npos && eol >= 13 && eol < 4096)
|
||||||
|
{
|
||||||
|
if(headerString.substr(eol-11,11) == "/LaunchAPPL")
|
||||||
|
hadShebang = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!hadShebang)
|
||||||
|
{
|
||||||
|
std::cerr << "Unfortunately, the application already has a data fork.\n";
|
||||||
|
std::cerr << "LaunchAPPL --make-executable does not currently work for PowerPC apps.\n";
|
||||||
|
// TODO: if it's a PEF container, move it back a little and update cfrg
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::fstream(fn, std::ios::in | std::ios::out | std::ios::binary) << headerString;
|
||||||
|
|
||||||
|
fs::permissions(fs::path(fn), fs::owner_exe | fs::group_exe | fs::others_exe | fs::add_perms);
|
||||||
|
}
|
|
@ -523,3 +523,24 @@ bool ResourceFile::write()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ResourceFile::hasPlainDataFork(ResourceFile::Format f)
|
||||||
|
{
|
||||||
|
switch(f)
|
||||||
|
{
|
||||||
|
#ifdef __APPLE__
|
||||||
|
case Format::real:
|
||||||
|
#endif
|
||||||
|
case Format::basilisk:
|
||||||
|
case Format::underscore_appledouble:
|
||||||
|
case Format::percent_appledouble:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResourceFile::hasPlainDataFork()
|
||||||
|
{
|
||||||
|
return hasPlainDataFork(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,9 @@ public:
|
||||||
bool read();
|
bool read();
|
||||||
bool write();
|
bool write();
|
||||||
|
|
||||||
|
static bool hasPlainDataFork(Format f);
|
||||||
|
bool hasPlainDataFork();
|
||||||
|
|
||||||
std::string pathstring;
|
std::string pathstring;
|
||||||
Format format;
|
Format format;
|
||||||
ResType type;
|
ResType type;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user