📄 config.c
字号:
dlg_beep(dlg);
} else if (ctrl == td->rembutton) {
char *p = cfg->ttymodes;
int i = 0, len = lenof(cfg->ttymodes);
while (*p) {
int multisel = dlg_listbox_index(td->listbox, dlg) < 0;
if (dlg_listbox_issel(td->listbox, dlg, i)) {
if (!multisel) {
/* Populate controls with entry we're about to
* delete, for ease of editing.
* (If multiple entries were selected, don't
* touch the controls.) */
char *val = strchr(p, '\t');
if (val) {
int ind = 0;
val++;
while (ttymodes[ind]) {
if (strlen(ttymodes[ind]) == val-p-1 &&
!strncmp(ttymodes[ind], p, val-p-1))
break;
ind++;
}
dlg_listbox_select(td->modelist, dlg, ind);
dlg_radiobutton_set(td->valradio, dlg,
(*val == 'V'));
dlg_editbox_set(td->valbox, dlg, val+1);
}
}
memmove(p, p+strlen(p)+1, len - (strlen(p)+1));
i++;
continue;
}
len -= strlen(p) + 1;
p += strlen(p) + 1;
i++;
}
memset(p, 0, lenof(cfg->ttymodes) - len);
dlg_refresh(td->listbox, dlg);
}
}
}
struct environ_data {
union control *varbox, *valbox, *addbutton, *rembutton, *listbox;
};
static void environ_handler(union control *ctrl, void *dlg,
void *data, int event)
{
Config *cfg = (Config *)data;
struct environ_data *ed =
(struct environ_data *)ctrl->generic.context.p;
if (event == EVENT_REFRESH) {
if (ctrl == ed->listbox) {
char *p = cfg->environmt;
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
while (*p) {
dlg_listbox_add(ctrl, dlg, p);
p += strlen(p) + 1;
}
dlg_update_done(ctrl, dlg);
}
} else if (event == EVENT_ACTION) {
if (ctrl == ed->addbutton) {
char str[sizeof(cfg->environmt)];
char *p;
dlg_editbox_get(ed->varbox, dlg, str, sizeof(str)-1);
if (!*str) {
dlg_beep(dlg);
return;
}
p = str + strlen(str);
*p++ = '\t';
dlg_editbox_get(ed->valbox, dlg, p, sizeof(str)-1 - (p - str));
if (!*p) {
dlg_beep(dlg);
return;
}
p = cfg->environmt;
while (*p) {
while (*p)
p++;
p++;
}
if ((p - cfg->environmt) + strlen(str) + 2 <
sizeof(cfg->environmt)) {
strcpy(p, str);
p[strlen(str) + 1] = '\0';
dlg_listbox_add(ed->listbox, dlg, str);
dlg_editbox_set(ed->varbox, dlg, "");
dlg_editbox_set(ed->valbox, dlg, "");
} else {
dlg_error_msg(dlg, "Environment too big");
}
} else if (ctrl == ed->rembutton) {
int i = dlg_listbox_index(ed->listbox, dlg);
if (i < 0) {
dlg_beep(dlg);
} else {
char *p, *q, *str;
dlg_listbox_del(ed->listbox, dlg, i);
p = cfg->environmt;
while (i > 0) {
if (!*p)
goto disaster;
while (*p)
p++;
p++;
i--;
}
q = p;
if (!*p)
goto disaster;
/* Populate controls with the entry we're about to delete
* for ease of editing */
str = p;
p = strchr(p, '\t');
if (!p)
goto disaster;
*p = '\0';
dlg_editbox_set(ed->varbox, dlg, str);
p++;
str = p;
dlg_editbox_set(ed->valbox, dlg, str);
p = strchr(p, '\0');
if (!p)
goto disaster;
p++;
while (*p) {
while (*p)
*q++ = *p++;
*q++ = *p++;
}
*q = '\0';
disaster:;
}
}
}
}
struct portfwd_data {
union control *addbutton, *rembutton, *listbox;
union control *sourcebox, *destbox, *direction;
#ifndef NO_IPV6
union control *addressfamily;
#endif
};
static void portfwd_handler(union control *ctrl, void *dlg,
void *data, int event)
{
Config *cfg = (Config *)data;
struct portfwd_data *pfd =
(struct portfwd_data *)ctrl->generic.context.p;
if (event == EVENT_REFRESH) {
if (ctrl == pfd->listbox) {
char *p = cfg->portfwd;
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
while (*p) {
dlg_listbox_add(ctrl, dlg, p);
p += strlen(p) + 1;
}
dlg_update_done(ctrl, dlg);
} else if (ctrl == pfd->direction) {
/*
* Default is Local.
*/
dlg_radiobutton_set(ctrl, dlg, 0);
#ifndef NO_IPV6
} else if (ctrl == pfd->addressfamily) {
dlg_radiobutton_set(ctrl, dlg, 0);
#endif
}
} else if (event == EVENT_ACTION) {
if (ctrl == pfd->addbutton) {
char str[sizeof(cfg->portfwd)];
char *p;
int i, type;
int whichbutton;
i = 0;
#ifndef NO_IPV6
whichbutton = dlg_radiobutton_get(pfd->addressfamily, dlg);
if (whichbutton == 1)
str[i++] = '4';
else if (whichbutton == 2)
str[i++] = '6';
#endif
whichbutton = dlg_radiobutton_get(pfd->direction, dlg);
if (whichbutton == 0)
type = 'L';
else if (whichbutton == 1)
type = 'R';
else
type = 'D';
str[i++] = type;
dlg_editbox_get(pfd->sourcebox, dlg, str+i, sizeof(str) - i);
if (!str[i]) {
dlg_error_msg(dlg, "You need to specify a source port number");
return;
}
p = str + strlen(str);
if (type != 'D') {
*p++ = '\t';
dlg_editbox_get(pfd->destbox, dlg, p,
sizeof(str) - (p - str));
if (!*p || !strchr(p, ':')) {
dlg_error_msg(dlg,
"You need to specify a destination address\n"
"in the form \"host.name:port\"");
return;
}
} else
*p = '\0';
p = cfg->portfwd;
while (*p) {
while (*p)
p++;
p++;
}
if ((p - cfg->portfwd) + strlen(str) + 2 <=
sizeof(cfg->portfwd)) {
strcpy(p, str);
p[strlen(str) + 1] = '\0';
dlg_listbox_add(pfd->listbox, dlg, str);
dlg_editbox_set(pfd->sourcebox, dlg, "");
dlg_editbox_set(pfd->destbox, dlg, "");
} else {
dlg_error_msg(dlg, "Too many forwardings");
}
} else if (ctrl == pfd->rembutton) {
int i = dlg_listbox_index(pfd->listbox, dlg);
if (i < 0)
dlg_beep(dlg);
else {
char *p, *q, *src, *dst;
char dir;
dlg_listbox_del(pfd->listbox, dlg, i);
p = cfg->portfwd;
while (i > 0) {
if (!*p)
goto disaster2;
while (*p)
p++;
p++;
i--;
}
q = p;
if (!*p)
goto disaster2;
/* Populate the controls with the entry we're about to
* delete, for ease of editing. */
{
static const char *const afs = "A46";
char *afp = strchr(afs, *p);
int idx = afp ? afp-afs : 0;
if (afp)
p++;
#ifndef NO_IPV6
dlg_radiobutton_set(pfd->addressfamily, dlg, idx);
#endif
}
{
static const char *const dirs = "LRD";
dir = *p;
dlg_radiobutton_set(pfd->direction, dlg,
strchr(dirs, dir) - dirs);
}
p++;
if (dir != 'D') {
src = p;
p = strchr(p, '\t');
if (!p)
goto disaster2;
*p = '\0';
p++;
dst = p;
} else {
src = p;
dst = "";
}
p = strchr(p, '\0');
if (!p)
goto disaster2;
dlg_editbox_set(pfd->sourcebox, dlg, src);
dlg_editbox_set(pfd->destbox, dlg, dst);
p++;
while (*p) {
while (*p)
*q++ = *p++;
*q++ = *p++;
}
*q = '\0';
disaster2:;
}
}
}
}
void setup_config_box(struct controlbox *b, int midsession,
int protocol, int protcfginfo)
{
struct controlset *s;
struct sessionsaver_data *ssd;
struct charclass_data *ccd;
struct colour_data *cd;
struct ttymodes_data *td;
struct environ_data *ed;
struct portfwd_data *pfd;
union control *c;
char *str;
ssd = (struct sessionsaver_data *)
ctrl_alloc(b, sizeof(struct sessionsaver_data));
memset(ssd, 0, sizeof(*ssd));
ssd->midsession = midsession;
/*
* The standard panel that appears at the bottom of all panels:
* Open, Cancel, Apply etc.
*/
s = ctrl_getset(b, "", "", "");
ctrl_columns(s, 5, 20, 20, 20, 20, 20);
ssd->okbutton = ctrl_pushbutton(s,
(midsession ? "Apply" : "Open"),
(char)(midsession ? 'a' : 'o'),
HELPCTX(no_help),
sessionsaver_handler, P(ssd));
ssd->okbutton->button.isdefault = TRUE;
ssd->okbutton->generic.column = 3;
ssd->cancelbutton = ctrl_pushbutton(s, "Cancel", 'c', HELPCTX(no_help),
sessionsaver_handler, P(ssd));
ssd->cancelbutton->button.iscancel = TRUE;
ssd->cancelbutton->generic.column = 4;
/* We carefully don't close the 5-column part, so that platform-
* specific add-ons can put extra buttons alongside Open and Cancel. */
/*
* The Session panel.
*/
str = dupprintf("Basic options for your %s session", appname);
ctrl_settitle(b, "Session", str);
sfree(str);
if (!midsession) {
struct hostport *hp = (struct hostport *)
ctrl_alloc(b, sizeof(struct hostport));
s = ctrl_getset(b, "Session", "hostport",
"Specify the destination you want to connect to");
ctrl_columns(s, 2, 75, 25);
c = ctrl_editbox(s, HOST_BOX_TITLE, 'n', 100,
HELPCTX(session_hostname),
config_host_handler, I(0), I(0));
c->generic.column = 0;
hp->host = c;
c = ctrl_editbox(s, PORT_BOX_TITLE, 'p', 100,
HELPCTX(session_hostname),
config_port_handler, I(0), I(0));
c->generic.column = 1;
hp->port = c;
ctrl_columns(s, 1, 100);
if (!have_backend(PROT_SSH)) {
ctrl_radiobuttons(s, "Connection type:", NO_SHORTCUT, 3,
HELPCTX(session_hostname),
config_protocolbuttons_handler, P(hp),
"Raw", 'r', I(PROT_RAW),
"Telnet", 't', I(PROT_TELNET),
"Rlogin", 'i', I(PROT_RLOGIN),
NULL);
} else {
ctrl_radiobuttons(s, "Connection type:", NO_SHORTCUT, 4,
HELPCTX(session_hostname),
config_protocolbuttons_handler, P(hp),
"Raw", 'r', I(PROT_RAW),
"Telnet", 't', I(PROT_TELNET),
"Rlogin", 'i', I(PROT_RLOGIN),
"SSH", 's', I(PROT_SSH),
NULL);
}
}
/*
* The Load/Save panel is available even in mid-session.
*/
s = ctrl_getset(b, "Session", "savedsessions",
midsession ? "Save the current session settings" :
"Load, save or delete a stored session");
ctrl_columns(s, 2, 75, 25);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -