1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 18:07:59 +00:00
putty-source/unix/uxputty.c
Simon Tatham 7d705ed1bd New program 'osxlaunch', to use as an OS X bundle launcher.
The big problem with making an OS X application out of a GTK program
is that it won't start unless DYLD_LIBRARY_PATH and several other
environment variables point at all the GTK machinery. So your app
bundle has to contain two programs: a launcher to set up that
environment, and then the real main program that the launcher execs
once it's done so.

But in our case, we also need pterm to start subprocesses _without_
all that stuff in the environment - so our launcher has to be more
complicated than the usual one, because it's also got to save every
detail of how the environment was when it started up. So this is the
launcher program I'm going to use. Comments in the header explain in
more detail how it'll work.

Also in this commit, I add the other end of the same machinery to
gtkapp.c and uxpty.c: the former catches an extra command-line
argument that the launcher used to indicate how it had munged the
environment, and stores it in a global variable where the latter can
pick it up after fork() and use to actually undo the munging.
2016-03-23 22:22:48 +00:00

149 lines
3.3 KiB
C

/*
* Unix PuTTY main program.
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "putty.h"
#include "storage.h"
#include "gtkcompat.h"
/*
* Stubs to avoid uxpty.c needing to be linked in.
*/
const int use_pty_argv = FALSE;
char **pty_argv; /* never used */
char *pty_osx_envrestore_prefix;
/*
* Clean up and exit.
*/
void cleanup_exit(int code)
{
/*
* Clean up.
*/
sk_cleanup();
random_save_seed();
exit(code);
}
Backend *select_backend(Conf *conf)
{
Backend *back = backend_from_proto(conf_get_int(conf, CONF_protocol));
assert(back != NULL);
return back;
}
int cfgbox(Conf *conf)
{
char *title = dupcat(appname, " Configuration", NULL);
int ret = do_config_box(title, conf, 0, 0);
sfree(title);
return ret;
}
static int got_host = 0;
const int use_event_log = 1, new_session = 1, saved_sessions = 1;
int process_nonoption_arg(const char *arg, Conf *conf, int *allow_launch)
{
char *argdup, *p, *q;
argdup = dupstr(arg);
q = argdup;
if (got_host) {
/*
* If we already have a host name, treat this argument as a
* port number. NB we have to treat this as a saved -P
* argument, so that it will be deferred until it's a good
* moment to run it.
*/
int ret = cmdline_process_param("-P", argdup, 1, conf);
assert(ret == 2);
} else if (!strncmp(q, "telnet:", 7)) {
/*
* If the hostname starts with "telnet:",
* set the protocol to Telnet and process
* the string as a Telnet URL.
*/
char c;
q += 7;
if (q[0] == '/' && q[1] == '/')
q += 2;
conf_set_int(conf, CONF_protocol, PROT_TELNET);
p = q;
p += host_strcspn(p, ":/");
c = *p;
if (*p)
*p++ = '\0';
if (c == ':')
conf_set_int(conf, CONF_port, atoi(p));
else
conf_set_int(conf, CONF_port, -1);
conf_set_str(conf, CONF_host, q);
got_host = 1;
} else {
/*
* Otherwise, treat this argument as a host name.
*/
p = argdup;
while (*p && !isspace((unsigned char)*p))
p++;
if (*p)
*p++ = '\0';
conf_set_str(conf, CONF_host, q);
got_host = 1;
}
if (got_host)
*allow_launch = TRUE;
sfree(argdup);
return 1;
}
char *make_default_wintitle(char *hostname)
{
return dupcat(hostname, " - ", appname, NULL);
}
/*
* X11-forwarding-related things suitable for Gtk app.
*/
char *platform_get_x_display(void) {
const char *display;
/* Try to take account of --display and what have you. */
if (!(display = gdk_get_display()))
/* fall back to traditional method */
display = getenv("DISPLAY");
return dupstr(display);
}
const int share_can_be_downstream = TRUE;
const int share_can_be_upstream = TRUE;
void setup(int single)
{
sk_init();
flags = FLAG_VERBOSE | FLAG_INTERACTIVE;
default_protocol = be_default_protocol;
/* Find the appropriate default port. */
{
Backend *b = backend_from_proto(default_protocol);
default_port = 0; /* illegal */
if (b)
default_port = b->default_port;
}
}