]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - unix/uxputty.c
Fixed the printing and charset combo boxes in Unix PuTTY. (The
[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 const char *const appname = "PuTTY";
71
72 Backend *select_backend(Config *cfg)
73 {
74     int i;
75     Backend *back = NULL;
76     for (i = 0; backends[i].backend != NULL; i++)
77         if (backends[i].protocol == cfg->protocol) {
78             back = backends[i].backend;
79             break;
80         }
81     assert(back != NULL);
82     return back;
83 }
84
85 int cfgbox(Config *cfg)
86 {
87     extern int do_config_box(const char *title, Config *cfg);
88     return do_config_box("PuTTY Configuration", cfg);
89 }
90
91 static int got_host = 0;
92
93 int process_nonoption_arg(char *arg, Config *cfg)
94 {
95     char *p, *q = arg;
96
97     if (got_host) {
98         /*
99          * If we already have a host name, treat this argument as a
100          * port number. NB we have to treat this as a saved -P
101          * argument, so that it will be deferred until it's a good
102          * moment to run it.
103          */
104         int ret = cmdline_process_param("-P", arg, 1, cfg);
105         assert(ret == 2);
106     } else if (!strncmp(q, "telnet:", 7)) {
107         /*
108          * If the hostname starts with "telnet:",
109          * set the protocol to Telnet and process
110          * the string as a Telnet URL.
111          */
112         char c;
113
114         q += 7;
115         if (q[0] == '/' && q[1] == '/')
116             q += 2;
117         cfg->protocol = PROT_TELNET;
118         p = q;
119         while (*p && *p != ':' && *p != '/')
120             p++;
121         c = *p;
122         if (*p)
123             *p++ = '\0';
124         if (c == ':')
125             cfg->port = atoi(p);
126         else
127             cfg->port = -1;
128         strncpy(cfg->host, q, sizeof(cfg->host) - 1);
129         cfg->host[sizeof(cfg->host) - 1] = '\0';
130         got_host = 1;
131     } else {
132         /*
133          * Otherwise, treat this argument as a host name.
134          */
135         p = arg;
136         while (*p && !isspace((unsigned char)*p))
137             p++;
138         if (*p)
139             *p++ = '\0';
140         strncpy(cfg->host, q, sizeof(cfg->host) - 1);
141         cfg->host[sizeof(cfg->host) - 1] = '\0';
142         got_host = 1;
143     }
144     return 1;
145 }
146
147 char *make_default_wintitle(char *hostname)
148 {
149     return dupcat(hostname, " - PuTTY", NULL);
150 }
151
152 int main(int argc, char **argv)
153 {
154     extern int pt_main(int argc, char **argv);
155     sk_init();
156     flags = FLAG_VERBOSE | FLAG_INTERACTIVE;
157     default_protocol = be_default_protocol;
158     /* Find the appropriate default port. */
159     {
160         int i;
161         default_port = 0; /* illegal */
162         for (i = 0; backends[i].backend != NULL; i++)
163             if (backends[i].protocol == default_protocol) {
164                 default_port = backends[i].backend->default_port;
165                 break;
166             }
167     }
168     return pt_main(argc, argv);
169 }