]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - unix/uxputty.c
Now that we have `appname', make much wider use of it. In
[PuTTY.git] / unix / uxputty.c
1 /*
2  * Unix PuTTY main program.
3  */
4
5 #include <stdio.h>
6 #include <ctype.h>
7 #include <stdlib.h>
8 #include <assert.h>
9 #include <unistd.h>
10
11 #include "putty.h"
12 #include "storage.h"
13
14 /*
15  * TODO:
16  * 
17  *  - Remainder of the context menu:
18  * 
19  *     - Event Log (this means we must implement the Event Log; not
20  *       in pterm)
21  * 
22  *     - New Session and Duplicate Session (perhaps in pterm, in fact?!)
23  *        + Duplicate Session will be fun, since we must work out
24  *          how to pass the config data through.
25  *        + In fact this should be easier on Unix, since fork() is
26  *          available so we need not even exec (this also saves us
27  *          the trouble of scrabbling around trying to find our own
28  *          binary). Possible scenario: respond to Duplicate
29  *          Session by forking. Parent continues as before; child
30  *          unceremoniously frees all extant resources (backend,
31  *          terminal, ldisc, frontend etc) and then _longjmps_ (I
32  *          kid you not) back to a point in pt_main() which causes
33  *          it to go back round to the point of opening a new
34  *          terminal window and a new backend.
35  *        + A tricky bit here is how to free everything without
36  *          also _destroying_ things - calling GTK to free up
37  *          existing widgets is liable to send destroy messages to
38  *          the X server, which won't go down too well with the
39  *          parent process. exec() is a much cleaner solution to
40  *          this bit, but requires us to invent some ghastly IPC as
41  *          we did in Windows PuTTY.
42  *        + Arrgh! Also, this won't work in pterm since we'll
43  *          already have dropped privileges by this point, so we
44  *          can't get another pty. Sigh. Looks like exec has to be
45  *          the way forward then :-/
46  * 
47  *     - Saved Sessions submenu (not in pterm of course)
48  * 
49  *     - Change Settings
50  *        + we must also implement mid-session reconfig in pterm.c.
51  *        + note this also requires config.c and uxcfg.c to be able
52  *          to get hold of the application name.
53  * 
54  *     - Copy All to Clipboard (for what that's worth)
55  */
56
57 /*
58  * Clean up and exit.
59  */
60 void cleanup_exit(int code)
61 {
62     /*
63      * Clean up.
64      */
65     sk_cleanup();
66     random_save_seed();
67     exit(code);
68 }
69
70 Backend *select_backend(Config *cfg)
71 {
72     int i;
73     Backend *back = NULL;
74     for (i = 0; backends[i].backend != NULL; i++)
75         if (backends[i].protocol == cfg->protocol) {
76             back = backends[i].backend;
77             break;
78         }
79     assert(back != NULL);
80     return back;
81 }
82
83 int cfgbox(Config *cfg)
84 {
85     extern int do_config_box(const char *title, Config *cfg);
86     return do_config_box("PuTTY Configuration", cfg);
87 }
88
89 static int got_host = 0;
90
91 int process_nonoption_arg(char *arg, Config *cfg)
92 {
93     char *p, *q = arg;
94
95     if (got_host) {
96         /*
97          * If we already have a host name, treat this argument as a
98          * port number. NB we have to treat this as a saved -P
99          * argument, so that it will be deferred until it's a good
100          * moment to run it.
101          */
102         int ret = cmdline_process_param("-P", arg, 1, cfg);
103         assert(ret == 2);
104     } else if (!strncmp(q, "telnet:", 7)) {
105         /*
106          * If the hostname starts with "telnet:",
107          * set the protocol to Telnet and process
108          * the string as a Telnet URL.
109          */
110         char c;
111
112         q += 7;
113         if (q[0] == '/' && q[1] == '/')
114             q += 2;
115         cfg->protocol = PROT_TELNET;
116         p = q;
117         while (*p && *p != ':' && *p != '/')
118             p++;
119         c = *p;
120         if (*p)
121             *p++ = '\0';
122         if (c == ':')
123             cfg->port = atoi(p);
124         else
125             cfg->port = -1;
126         strncpy(cfg->host, q, sizeof(cfg->host) - 1);
127         cfg->host[sizeof(cfg->host) - 1] = '\0';
128         got_host = 1;
129     } else {
130         /*
131          * Otherwise, treat this argument as a host name.
132          */
133         p = arg;
134         while (*p && !isspace((unsigned char)*p))
135             p++;
136         if (*p)
137             *p++ = '\0';
138         strncpy(cfg->host, q, sizeof(cfg->host) - 1);
139         cfg->host[sizeof(cfg->host) - 1] = '\0';
140         got_host = 1;
141     }
142     return 1;
143 }
144
145 char *make_default_wintitle(char *hostname)
146 {
147     return dupcat(hostname, " - PuTTY", NULL);
148 }
149
150 int main(int argc, char **argv)
151 {
152     extern int pt_main(int argc, char **argv);
153     sk_init();
154     flags = FLAG_VERBOSE | FLAG_INTERACTIVE;
155     default_protocol = be_default_protocol;
156     /* Find the appropriate default port. */
157     {
158         int i;
159         default_port = 0; /* illegal */
160         for (i = 0; backends[i].backend != NULL; i++)
161             if (backends[i].protocol == default_protocol) {
162                 default_port = backends[i].backend->default_port;
163                 break;
164             }
165     }
166     return pt_main(argc, argv);
167 }