mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-06-30 19:12:48 -05:00
Whitespace rationalisation of entire code base.
The number of people has been steadily increasing who read our source code with an editor that thinks tab stops are 4 spaces apart, as opposed to the traditional tty-derived 8 that the PuTTY code expects. So I've been wondering for ages about just fixing it, and switching to a spaces-only policy throughout the code. And I recently found out about 'git blame -w', which should make this change not too disruptive for the purposes of source-control archaeology; so perhaps now is the time. While I'm at it, I've also taken the opportunity to remove all the trailing spaces from source lines (on the basis that git dislikes them, and is the only thing that seems to have a strong opinion one way or the other). Apologies to anyone downstream of this code who has complicated patch sets to rebase past this change. I don't intend it to be needed again.
This commit is contained in:
@ -11,10 +11,10 @@
|
||||
#include "storage.h"
|
||||
|
||||
static void about_handler(union control *ctrl, dlgparam *dlg,
|
||||
void *data, int event)
|
||||
void *data, int event)
|
||||
{
|
||||
if (event == EVENT_ACTION) {
|
||||
about_box(ctrl->generic.context.p);
|
||||
about_box(ctrl->generic.context.p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,13 +25,13 @@ void gtk_setup_config_box(struct controlbox *b, bool midsession, void *win)
|
||||
int i;
|
||||
|
||||
if (!midsession) {
|
||||
/*
|
||||
* Add the About button to the standard panel.
|
||||
*/
|
||||
s = ctrl_getset(b, "", "", "");
|
||||
c = ctrl_pushbutton(s, "About", 'a', HELPCTX(no_help),
|
||||
about_handler, P(win));
|
||||
c->generic.column = 0;
|
||||
/*
|
||||
* Add the About button to the standard panel.
|
||||
*/
|
||||
s = ctrl_getset(b, "", "", "");
|
||||
c = ctrl_pushbutton(s, "About", 'a', HELPCTX(no_help),
|
||||
about_handler, P(win));
|
||||
c->generic.column = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -39,10 +39,10 @@ void gtk_setup_config_box(struct controlbox *b, bool midsession, void *win)
|
||||
* than Windows does!
|
||||
*/
|
||||
s = ctrl_getset(b, "Window", "scrollback",
|
||||
"Control the scrollback in the window");
|
||||
"Control the scrollback in the window");
|
||||
ctrl_checkbox(s, "Scrollbar on left", 'l',
|
||||
HELPCTX(no_help),
|
||||
conf_checkbox_handler,
|
||||
HELPCTX(no_help),
|
||||
conf_checkbox_handler,
|
||||
I(CONF_scrollbar_on_left));
|
||||
/*
|
||||
* Really this wants to go just after `Display scrollbar'. See
|
||||
@ -89,29 +89,29 @@ void gtk_setup_config_box(struct controlbox *b, bool midsession, void *win)
|
||||
s = ctrl_getset(b, "Window/Fonts", "font",
|
||||
"Fonts for displaying non-bold text");
|
||||
ctrl_fontsel(s, "Font used for ordinary text", 'f',
|
||||
HELPCTX(no_help),
|
||||
conf_fontsel_handler, I(CONF_font));
|
||||
HELPCTX(no_help),
|
||||
conf_fontsel_handler, I(CONF_font));
|
||||
ctrl_fontsel(s, "Font used for wide (CJK) text", 'w',
|
||||
HELPCTX(no_help),
|
||||
conf_fontsel_handler, I(CONF_widefont));
|
||||
HELPCTX(no_help),
|
||||
conf_fontsel_handler, I(CONF_widefont));
|
||||
s = ctrl_getset(b, "Window/Fonts", "fontbold",
|
||||
"Fonts for displaying bolded text");
|
||||
ctrl_fontsel(s, "Font used for bolded text", 'b',
|
||||
HELPCTX(no_help),
|
||||
conf_fontsel_handler, I(CONF_boldfont));
|
||||
HELPCTX(no_help),
|
||||
conf_fontsel_handler, I(CONF_boldfont));
|
||||
ctrl_fontsel(s, "Font used for bold wide text", 'i',
|
||||
HELPCTX(no_help),
|
||||
conf_fontsel_handler, I(CONF_wideboldfont));
|
||||
HELPCTX(no_help),
|
||||
conf_fontsel_handler, I(CONF_wideboldfont));
|
||||
ctrl_checkbox(s, "Use shadow bold instead of bold fonts", 'u',
|
||||
HELPCTX(no_help),
|
||||
conf_checkbox_handler,
|
||||
I(CONF_shadowbold));
|
||||
HELPCTX(no_help),
|
||||
conf_checkbox_handler,
|
||||
I(CONF_shadowbold));
|
||||
ctrl_text(s, "(Note that bold fonts or shadow bolding are only"
|
||||
" used if you have not requested bolding to be done by"
|
||||
" changing the text colour.)",
|
||||
" used if you have not requested bolding to be done by"
|
||||
" changing the text colour.)",
|
||||
HELPCTX(no_help));
|
||||
ctrl_editbox(s, "Horizontal offset for shadow bold:", 'z', 20,
|
||||
HELPCTX(no_help), conf_editbox_handler,
|
||||
HELPCTX(no_help), conf_editbox_handler,
|
||||
I(CONF_shadowboldoffset), I(-1));
|
||||
|
||||
/*
|
||||
@ -123,11 +123,11 @@ void gtk_setup_config_box(struct controlbox *b, bool midsession, void *win)
|
||||
* here's an override option in the Translation panel.
|
||||
*/
|
||||
s = ctrl_getset(b, "Window/Translation", "trans",
|
||||
"Character set translation on received data");
|
||||
"Character set translation on received data");
|
||||
ctrl_checkbox(s, "Override with UTF-8 if locale says so", 'l',
|
||||
HELPCTX(translation_utf8_override),
|
||||
conf_checkbox_handler,
|
||||
I(CONF_utf8_override));
|
||||
HELPCTX(translation_utf8_override),
|
||||
conf_checkbox_handler,
|
||||
I(CONF_utf8_override));
|
||||
|
||||
#ifdef OSX_META_KEY_CONFIG
|
||||
/*
|
||||
@ -136,13 +136,13 @@ void gtk_setup_config_box(struct controlbox *b, bool midsession, void *win)
|
||||
* key, or whether they should have their normal OS functions.
|
||||
*/
|
||||
s = ctrl_getset(b, "Terminal/Keyboard", "meta",
|
||||
"Choose the Meta key:");
|
||||
"Choose the Meta key:");
|
||||
ctrl_checkbox(s, "Option key acts as Meta", 'p',
|
||||
HELPCTX(no_help),
|
||||
conf_checkbox_handler, I(CONF_osx_option_meta));
|
||||
HELPCTX(no_help),
|
||||
conf_checkbox_handler, I(CONF_osx_option_meta));
|
||||
ctrl_checkbox(s, "Command key acts as Meta", 'm',
|
||||
HELPCTX(no_help),
|
||||
conf_checkbox_handler, I(CONF_osx_command_meta));
|
||||
HELPCTX(no_help),
|
||||
conf_checkbox_handler, I(CONF_osx_command_meta));
|
||||
#endif
|
||||
|
||||
if (!midsession) {
|
||||
|
216
unix/gtkcols.c
216
unix/gtkcols.c
@ -88,18 +88,18 @@ GType columns_get_type(void)
|
||||
if (!columns_type) {
|
||||
static const GTypeInfo columns_info = {
|
||||
sizeof(ColumnsClass),
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) columns_class_init,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
sizeof(Columns),
|
||||
0,
|
||||
0,
|
||||
(GInstanceInitFunc)columns_init,
|
||||
};
|
||||
|
||||
columns_type = g_type_register_static(GTK_TYPE_CONTAINER, "Columns",
|
||||
&columns_info, 0);
|
||||
&columns_info, 0);
|
||||
}
|
||||
|
||||
return columns_type;
|
||||
@ -107,7 +107,7 @@ GType columns_get_type(void)
|
||||
#endif
|
||||
|
||||
static gint (*columns_inherited_focus)(FOCUS_METHOD_SUPERCLASS *container,
|
||||
GtkDirectionType direction);
|
||||
GtkDirectionType direction);
|
||||
|
||||
static void columns_class_init(ColumnsClass *klass)
|
||||
{
|
||||
@ -153,7 +153,7 @@ static void columns_class_init(ColumnsClass *klass)
|
||||
|
||||
/* Save the previous value of this method. */
|
||||
if (!columns_inherited_focus)
|
||||
columns_inherited_focus = FOCUS_METHOD_LOCATION->focus;
|
||||
columns_inherited_focus = FOCUS_METHOD_LOCATION->focus;
|
||||
FOCUS_METHOD_LOCATION->focus = columns_focus;
|
||||
}
|
||||
|
||||
@ -230,7 +230,7 @@ static void columns_map(GtkWidget *widget)
|
||||
children && (child = children->data);
|
||||
children = children->next) {
|
||||
if (child->widget &&
|
||||
gtk_widget_get_visible(child->widget) &&
|
||||
gtk_widget_get_visible(child->widget) &&
|
||||
!gtk_widget_get_mapped(child->widget))
|
||||
gtk_widget_map(child->widget);
|
||||
}
|
||||
@ -251,7 +251,7 @@ static void columns_unmap(GtkWidget *widget)
|
||||
children && (child = children->data);
|
||||
children = children->next) {
|
||||
if (child->widget &&
|
||||
gtk_widget_get_visible(child->widget) &&
|
||||
gtk_widget_get_visible(child->widget) &&
|
||||
gtk_widget_get_mapped(child->widget))
|
||||
gtk_widget_unmap(child->widget);
|
||||
}
|
||||
@ -274,7 +274,7 @@ static void columns_draw(GtkWidget *widget, GdkRectangle *area)
|
||||
children && (child = children->data);
|
||||
children = children->next) {
|
||||
if (child->widget &&
|
||||
GTK_WIDGET_DRAWABLE(child->widget) &&
|
||||
GTK_WIDGET_DRAWABLE(child->widget) &&
|
||||
gtk_widget_intersect(child->widget, area, &child_area))
|
||||
gtk_widget_draw(child->widget, &child_area);
|
||||
}
|
||||
@ -299,7 +299,7 @@ static gint columns_expose(GtkWidget *widget, GdkEventExpose *event)
|
||||
children && (child = children->data);
|
||||
children = children->next) {
|
||||
if (child->widget &&
|
||||
GTK_WIDGET_DRAWABLE(child->widget) &&
|
||||
GTK_WIDGET_DRAWABLE(child->widget) &&
|
||||
GTK_WIDGET_NO_WINDOW(child->widget) &&
|
||||
gtk_widget_intersect(child->widget, &event->area,
|
||||
&child_event.area))
|
||||
@ -401,8 +401,8 @@ static void columns_forall(GtkContainer *container, gboolean include_internals,
|
||||
* callback.
|
||||
*/
|
||||
next = children->next;
|
||||
if (child->widget)
|
||||
callback(child->widget, callback_data);
|
||||
if (child->widget)
|
||||
callback(child->widget, callback_data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -550,7 +550,7 @@ void columns_taborder_last(Columns *cols, GtkWidget *widget)
|
||||
|
||||
cols->taborder = g_list_remove_link(cols->taborder, children);
|
||||
g_list_free(children);
|
||||
cols->taborder = g_list_append(cols->taborder, widget);
|
||||
cols->taborder = g_list_append(cols->taborder, widget);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -571,52 +571,52 @@ static gint columns_focus(FOCUS_METHOD_SUPERCLASS *super, GtkDirectionType dir)
|
||||
cols = COLUMNS(super);
|
||||
|
||||
if (!gtk_widget_is_drawable(GTK_WIDGET(cols)) ||
|
||||
!gtk_widget_is_sensitive(GTK_WIDGET(cols)))
|
||||
return false;
|
||||
!gtk_widget_is_sensitive(GTK_WIDGET(cols)))
|
||||
return false;
|
||||
|
||||
if (!gtk_widget_get_can_focus(GTK_WIDGET(cols)) &&
|
||||
(dir == GTK_DIR_TAB_FORWARD || dir == GTK_DIR_TAB_BACKWARD)) {
|
||||
(dir == GTK_DIR_TAB_FORWARD || dir == GTK_DIR_TAB_BACKWARD)) {
|
||||
|
||||
focuschild = gtk_container_get_focus_child(GTK_CONTAINER(cols));
|
||||
gtk_container_set_focus_child(GTK_CONTAINER(cols), NULL);
|
||||
focuschild = gtk_container_get_focus_child(GTK_CONTAINER(cols));
|
||||
gtk_container_set_focus_child(GTK_CONTAINER(cols), NULL);
|
||||
|
||||
if (dir == GTK_DIR_TAB_FORWARD)
|
||||
pos = cols->taborder;
|
||||
else
|
||||
pos = g_list_last(cols->taborder);
|
||||
if (dir == GTK_DIR_TAB_FORWARD)
|
||||
pos = cols->taborder;
|
||||
else
|
||||
pos = g_list_last(cols->taborder);
|
||||
|
||||
while (pos) {
|
||||
GtkWidget *child = pos->data;
|
||||
while (pos) {
|
||||
GtkWidget *child = pos->data;
|
||||
|
||||
if (focuschild) {
|
||||
if (focuschild == child) {
|
||||
focuschild = NULL; /* now we can start looking in here */
|
||||
if (gtk_widget_is_drawable(child) &&
|
||||
GTK_IS_CONTAINER(child) &&
|
||||
!gtk_widget_has_focus(child)) {
|
||||
if (CHILD_FOCUS(child, dir))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (gtk_widget_is_drawable(child)) {
|
||||
if (GTK_IS_CONTAINER(child)) {
|
||||
if (CHILD_FOCUS(child, dir))
|
||||
return true;
|
||||
} else if (gtk_widget_get_can_focus(child)) {
|
||||
gtk_widget_grab_focus(child);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (focuschild) {
|
||||
if (focuschild == child) {
|
||||
focuschild = NULL; /* now we can start looking in here */
|
||||
if (gtk_widget_is_drawable(child) &&
|
||||
GTK_IS_CONTAINER(child) &&
|
||||
!gtk_widget_has_focus(child)) {
|
||||
if (CHILD_FOCUS(child, dir))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (gtk_widget_is_drawable(child)) {
|
||||
if (GTK_IS_CONTAINER(child)) {
|
||||
if (CHILD_FOCUS(child, dir))
|
||||
return true;
|
||||
} else if (gtk_widget_get_can_focus(child)) {
|
||||
gtk_widget_grab_focus(child);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dir == GTK_DIR_TAB_FORWARD)
|
||||
pos = pos->next;
|
||||
else
|
||||
pos = pos->prev;
|
||||
}
|
||||
if (dir == GTK_DIR_TAB_FORWARD)
|
||||
pos = pos->next;
|
||||
else
|
||||
pos = pos->prev;
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
} else
|
||||
return columns_inherited_focus(super, dir);
|
||||
return columns_inherited_focus(super, dir);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -650,19 +650,19 @@ static gint columns_compute_width(Columns *cols, widget_dim_fn_t get_width)
|
||||
children && (child = children->data);
|
||||
children = children->next) {
|
||||
|
||||
if (!child->widget) {
|
||||
/* Column reconfiguration. */
|
||||
ncols = child->ncols;
|
||||
percentages = child->percentages;
|
||||
continue;
|
||||
}
|
||||
if (!child->widget) {
|
||||
/* Column reconfiguration. */
|
||||
ncols = child->ncols;
|
||||
percentages = child->percentages;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only take visible widgets into account. */
|
||||
if (!gtk_widget_get_visible(child->widget))
|
||||
continue;
|
||||
|
||||
childwidth = get_width(child);
|
||||
colspan = child->colspan ? child->colspan : ncols-child->colstart;
|
||||
colspan = child->colspan ? child->colspan : ncols-child->colstart;
|
||||
assert(colspan > 0);
|
||||
|
||||
#ifdef COLUMNS_WIDTH_DIAGNOSTICS
|
||||
@ -753,41 +753,41 @@ static void columns_alloc_horiz(Columns *cols, gint ourwidth,
|
||||
children && (child = children->data);
|
||||
children = children->next) {
|
||||
|
||||
if (!child->widget) {
|
||||
gint percent;
|
||||
if (!child->widget) {
|
||||
gint percent;
|
||||
|
||||
/* Column reconfiguration. */
|
||||
ncols = child->ncols;
|
||||
colxpos = g_renew(gint, colxpos, ncols + 1);
|
||||
colxpos[0] = 0;
|
||||
percent = 0;
|
||||
for (i = 0; i < ncols; i++) {
|
||||
percent += child->percentages[i];
|
||||
colxpos[i+1] = (((ourwidth - 2*border) + cols->spacing)
|
||||
* percent / 100);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* Column reconfiguration. */
|
||||
ncols = child->ncols;
|
||||
colxpos = g_renew(gint, colxpos, ncols + 1);
|
||||
colxpos[0] = 0;
|
||||
percent = 0;
|
||||
for (i = 0; i < ncols; i++) {
|
||||
percent += child->percentages[i];
|
||||
colxpos[i+1] = (((ourwidth - 2*border) + cols->spacing)
|
||||
* percent / 100);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only take visible widgets into account. */
|
||||
if (!gtk_widget_get_visible(child->widget))
|
||||
continue;
|
||||
|
||||
childwidth = get_width(child);
|
||||
colspan = child->colspan ? child->colspan : ncols-child->colstart;
|
||||
colspan = child->colspan ? child->colspan : ncols-child->colstart;
|
||||
|
||||
/*
|
||||
* Starting x position is cols[colstart].
|
||||
* Ending x position is cols[colstart+colspan] - spacing.
|
||||
*
|
||||
* Unless we're forcing left, in which case the width is
|
||||
* exactly the requisition width.
|
||||
*
|
||||
* Unless we're forcing left, in which case the width is
|
||||
* exactly the requisition width.
|
||||
*/
|
||||
child->x = colxpos[child->colstart];
|
||||
if (child->force_left)
|
||||
child->w = childwidth;
|
||||
else
|
||||
child->w = (colxpos[child->colstart+colspan] -
|
||||
if (child->force_left)
|
||||
child->w = childwidth;
|
||||
else
|
||||
child->w = (colxpos[child->colstart+colspan] -
|
||||
colxpos[child->colstart] - cols->spacing);
|
||||
}
|
||||
|
||||
@ -810,18 +810,18 @@ static gint columns_compute_height(Columns *cols, widget_dim_fn_t get_height)
|
||||
children && (child = children->data);
|
||||
children = children->next) {
|
||||
|
||||
if (!child->widget) {
|
||||
/* Column reconfiguration. */
|
||||
for (i = 1; i < ncols; i++) {
|
||||
if (colypos[0] < colypos[i])
|
||||
colypos[0] = colypos[i];
|
||||
}
|
||||
ncols = child->ncols;
|
||||
colypos = g_renew(gint, colypos, ncols);
|
||||
for (i = 1; i < ncols; i++)
|
||||
colypos[i] = colypos[0];
|
||||
continue;
|
||||
}
|
||||
if (!child->widget) {
|
||||
/* Column reconfiguration. */
|
||||
for (i = 1; i < ncols; i++) {
|
||||
if (colypos[0] < colypos[i])
|
||||
colypos[0] = colypos[i];
|
||||
}
|
||||
ncols = child->ncols;
|
||||
colypos = g_renew(gint, colypos, ncols);
|
||||
for (i = 1; i < ncols; i++)
|
||||
colypos[i] = colypos[0];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only take visible widgets into account. */
|
||||
if (!gtk_widget_get_visible(child->widget))
|
||||
@ -833,7 +833,7 @@ static gint columns_compute_height(Columns *cols, widget_dim_fn_t get_height)
|
||||
if (childheight < childheight2)
|
||||
childheight = childheight2;
|
||||
}
|
||||
colspan = child->colspan ? child->colspan : ncols-child->colstart;
|
||||
colspan = child->colspan ? child->colspan : ncols-child->colstart;
|
||||
|
||||
/*
|
||||
* To compute height: the widget's top will be positioned at
|
||||
@ -883,18 +883,18 @@ static void columns_alloc_vert(Columns *cols, gint ourheight,
|
||||
for (children = cols->children;
|
||||
children && (child = children->data);
|
||||
children = children->next) {
|
||||
if (!child->widget) {
|
||||
/* Column reconfiguration. */
|
||||
for (i = 1; i < ncols; i++) {
|
||||
if (colypos[0] < colypos[i])
|
||||
colypos[0] = colypos[i];
|
||||
}
|
||||
ncols = child->ncols;
|
||||
colypos = g_renew(gint, colypos, ncols);
|
||||
for (i = 1; i < ncols; i++)
|
||||
colypos[i] = colypos[0];
|
||||
continue;
|
||||
}
|
||||
if (!child->widget) {
|
||||
/* Column reconfiguration. */
|
||||
for (i = 1; i < ncols; i++) {
|
||||
if (colypos[0] < colypos[i])
|
||||
colypos[0] = colypos[i];
|
||||
}
|
||||
ncols = child->ncols;
|
||||
colypos = g_renew(gint, colypos, ncols);
|
||||
for (i = 1; i < ncols; i++)
|
||||
colypos[i] = colypos[0];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only take visible widgets into account. */
|
||||
if (!gtk_widget_get_visible(child->widget))
|
||||
@ -906,7 +906,7 @@ static void columns_alloc_vert(Columns *cols, gint ourheight,
|
||||
if (fakeheight < childheight2)
|
||||
fakeheight = childheight2;
|
||||
}
|
||||
colspan = child->colspan ? child->colspan : ncols-child->colstart;
|
||||
colspan = child->colspan ? child->colspan : ncols-child->colstart;
|
||||
|
||||
/*
|
||||
* To compute height: the widget's top will be positioned
|
||||
@ -932,7 +932,7 @@ static void columns_alloc_vert(Columns *cols, gint ourheight,
|
||||
}
|
||||
}
|
||||
|
||||
g_free(colypos);
|
||||
g_free(colypos);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -28,8 +28,8 @@ typedef struct ColumnsChild_tag ColumnsChild;
|
||||
struct Columns_tag {
|
||||
GtkContainer container;
|
||||
/* private after here */
|
||||
GList *children; /* this holds ColumnsChild structures */
|
||||
GList *taborder; /* this just holds GtkWidgets */
|
||||
GList *children; /* this holds ColumnsChild structures */
|
||||
GList *taborder; /* this just holds GtkWidgets */
|
||||
gint spacing;
|
||||
};
|
||||
|
||||
|
@ -152,7 +152,7 @@ static gint timer_trigger(gpointer data)
|
||||
* Destroy the timer we got here on.
|
||||
*/
|
||||
if (timer_id) {
|
||||
g_source_remove(timer_id);
|
||||
g_source_remove(timer_id);
|
||||
timer_id = 0;
|
||||
}
|
||||
|
||||
@ -163,13 +163,13 @@ static gint timer_trigger(gpointer data)
|
||||
* still needs to be done, we do it ourselves.
|
||||
*/
|
||||
if (run_timers(now, &next) && !timer_id) {
|
||||
then = now;
|
||||
now = GETTICKCOUNT();
|
||||
if (now - then > next - then)
|
||||
ticks = 0;
|
||||
else
|
||||
ticks = next - now;
|
||||
timer_id = g_timeout_add(ticks, timer_trigger, LONG_TO_GPOINTER(next));
|
||||
then = now;
|
||||
now = GETTICKCOUNT();
|
||||
if (now - then > next - then)
|
||||
ticks = 0;
|
||||
else
|
||||
ticks = next - now;
|
||||
timer_id = g_timeout_add(ticks, timer_trigger, LONG_TO_GPOINTER(next));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -185,11 +185,11 @@ void timer_change_notify(unsigned long next)
|
||||
long ticks;
|
||||
|
||||
if (timer_id)
|
||||
g_source_remove(timer_id);
|
||||
g_source_remove(timer_id);
|
||||
|
||||
ticks = next - GETTICKCOUNT();
|
||||
if (ticks <= 0)
|
||||
ticks = 1; /* just in case */
|
||||
ticks = 1; /* just in case */
|
||||
|
||||
timer_id = g_timeout_add(ticks, timer_trigger, LONG_TO_GPOINTER(next));
|
||||
}
|
||||
|
2068
unix/gtkdlg.c
2068
unix/gtkdlg.c
File diff suppressed because it is too large
Load Diff
1644
unix/gtkfont.c
1644
unix/gtkfont.c
File diff suppressed because it is too large
Load Diff
@ -49,7 +49,7 @@
|
||||
/*
|
||||
* Exports from gtkfont.c.
|
||||
*/
|
||||
struct UnifontVtable; /* contents internal to gtkfont.c */
|
||||
struct UnifontVtable; /* contents internal to gtkfont.c */
|
||||
typedef struct unifont {
|
||||
const struct UnifontVtable *vt;
|
||||
/*
|
||||
@ -134,8 +134,8 @@ typedef struct unifont_drawctx {
|
||||
} unifont_drawctx;
|
||||
|
||||
unifont *unifont_create(GtkWidget *widget, const char *name,
|
||||
bool wide, bool bold,
|
||||
int shadowoffset, bool shadowalways);
|
||||
bool wide, bool bold,
|
||||
int shadowoffset, bool shadowalways);
|
||||
void unifont_destroy(unifont *font);
|
||||
void unifont_draw_text(unifont_drawctx *ctx, unifont *font,
|
||||
int x, int y, const wchar_t *string, int len,
|
||||
@ -166,13 +166,13 @@ unifont *multifont_create(GtkWidget *widget, const char *name,
|
||||
* Unified font selector dialog. I can't be bothered to do a
|
||||
* proper GTK subclassing today, so this will just be an ordinary
|
||||
* data structure with some useful members.
|
||||
*
|
||||
*
|
||||
* (Of course, these aren't the only members; this structure is
|
||||
* contained within a bigger one which holds data visible only to
|
||||
* the implementation.)
|
||||
*/
|
||||
typedef struct unifontsel {
|
||||
void *user_data; /* settable by the user */
|
||||
void *user_data; /* settable by the user */
|
||||
GtkWindow *window;
|
||||
GtkWidget *ok_button, *cancel_button;
|
||||
} unifontsel;
|
||||
|
366
unix/gtkmain.c
366
unix/gtkmain.c
@ -67,7 +67,7 @@ void fork_and_exec_self(int fd_to_close, ...)
|
||||
* Re-execing ourself is not an exact science under Unix. I do
|
||||
* the best I can by using /proc/self/exe if available and by
|
||||
* assuming argv[0] can be found on $PATH if not.
|
||||
*
|
||||
*
|
||||
* Note that we also have to reconstruct the elements of the
|
||||
* original argv which gtk swallowed, since the user wants the
|
||||
* new session to appear on the same X display as the old one.
|
||||
@ -81,17 +81,17 @@ void fork_and_exec_self(int fd_to_close, ...)
|
||||
* Collect the arguments with which to re-exec ourself.
|
||||
*/
|
||||
va_start(ap, fd_to_close);
|
||||
n = 2; /* progname and terminating NULL */
|
||||
n = 2; /* progname and terminating NULL */
|
||||
n += ngtkargs;
|
||||
while (va_arg(ap, char *) != NULL)
|
||||
n++;
|
||||
n++;
|
||||
va_end(ap);
|
||||
|
||||
args = snewn(n, char *);
|
||||
args[0] = progname;
|
||||
args[n-1] = NULL;
|
||||
for (i = 0; i < ngtkargs; i++)
|
||||
args[i+1] = gtkargvstart[i];
|
||||
args[i+1] = gtkargvstart[i];
|
||||
|
||||
i++;
|
||||
va_start(ap, fd_to_close);
|
||||
@ -105,43 +105,43 @@ void fork_and_exec_self(int fd_to_close, ...)
|
||||
*/
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("fork");
|
||||
perror("fork");
|
||||
sfree(args);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
int pid2 = fork();
|
||||
if (pid2 < 0) {
|
||||
perror("fork");
|
||||
_exit(1);
|
||||
} else if (pid2 > 0) {
|
||||
/*
|
||||
* First child has successfully forked second child. My
|
||||
* Work Here Is Done. Note the use of _exit rather than
|
||||
* exit: the latter appears to cause destroy messages
|
||||
* to be sent to the X server. I suspect gtk uses
|
||||
* atexit.
|
||||
*/
|
||||
_exit(0);
|
||||
}
|
||||
int pid2 = fork();
|
||||
if (pid2 < 0) {
|
||||
perror("fork");
|
||||
_exit(1);
|
||||
} else if (pid2 > 0) {
|
||||
/*
|
||||
* First child has successfully forked second child. My
|
||||
* Work Here Is Done. Note the use of _exit rather than
|
||||
* exit: the latter appears to cause destroy messages
|
||||
* to be sent to the X server. I suspect gtk uses
|
||||
* atexit.
|
||||
*/
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we reach here, we are the second child, so we now
|
||||
* actually perform the exec.
|
||||
*/
|
||||
if (fd_to_close >= 0)
|
||||
close(fd_to_close);
|
||||
/*
|
||||
* If we reach here, we are the second child, so we now
|
||||
* actually perform the exec.
|
||||
*/
|
||||
if (fd_to_close >= 0)
|
||||
close(fd_to_close);
|
||||
|
||||
execv("/proc/self/exe", args);
|
||||
execvp(progname, args);
|
||||
perror("exec");
|
||||
_exit(127);
|
||||
execv("/proc/self/exe", args);
|
||||
execvp(progname, args);
|
||||
perror("exec");
|
||||
_exit(127);
|
||||
|
||||
} else {
|
||||
int status;
|
||||
int status;
|
||||
sfree(args);
|
||||
waitpid(pid, &status, 0);
|
||||
waitpid(pid, &status, 0);
|
||||
}
|
||||
|
||||
}
|
||||
@ -159,15 +159,15 @@ void launch_duplicate_session(Conf *conf)
|
||||
int pipefd[2];
|
||||
|
||||
if (pipe(pipefd) < 0) {
|
||||
perror("pipe");
|
||||
return;
|
||||
perror("pipe");
|
||||
return;
|
||||
}
|
||||
|
||||
serialised = strbuf_new();
|
||||
|
||||
conf_serialise(BinarySink_UPCAST(serialised), conf);
|
||||
if (use_pty_argv && pty_argv)
|
||||
for (i = 0; pty_argv[i]; i++)
|
||||
for (i = 0; pty_argv[i]; i++)
|
||||
put_asciz(serialised, pty_argv[i]);
|
||||
|
||||
sprintf(option, "---[%d,%zu]", pipefd[0], serialised->len);
|
||||
@ -179,9 +179,9 @@ void launch_duplicate_session(Conf *conf)
|
||||
while (i < serialised->len &&
|
||||
(ret = write(pipefd[1], serialised->s + i,
|
||||
serialised->len - i)) > 0)
|
||||
i += ret;
|
||||
i += ret;
|
||||
if (ret < 0)
|
||||
perror("write to pipe");
|
||||
perror("write to pipe");
|
||||
close(pipefd[1]);
|
||||
strbuf_free(serialised);
|
||||
}
|
||||
@ -203,21 +203,21 @@ int read_dupsession_data(Conf *conf, char *arg)
|
||||
BinarySource src[1];
|
||||
|
||||
if (sscanf(arg, "---[%d,%d]", &fd, &size) != 2) {
|
||||
fprintf(stderr, "%s: malformed magic argument `%s'\n", appname, arg);
|
||||
exit(1);
|
||||
fprintf(stderr, "%s: malformed magic argument `%s'\n", appname, arg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
data = snewn(size, char);
|
||||
i = ret = 0;
|
||||
while (i < size && (ret = read(fd, data + i, size - i)) > 0)
|
||||
i += ret;
|
||||
i += ret;
|
||||
if (ret < 0) {
|
||||
perror("read from pipe");
|
||||
exit(1);
|
||||
perror("read from pipe");
|
||||
exit(1);
|
||||
} else if (i < size) {
|
||||
fprintf(stderr, "%s: unexpected EOF in Duplicate Session data\n",
|
||||
appname);
|
||||
exit(1);
|
||||
fprintf(stderr, "%s: unexpected EOF in Duplicate Session data\n",
|
||||
appname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
BinarySource_BARE_INIT(src, data, size);
|
||||
@ -226,7 +226,7 @@ int read_dupsession_data(Conf *conf, char *arg)
|
||||
exit(1);
|
||||
}
|
||||
if (use_pty_argv) {
|
||||
int pty_argc = 0;
|
||||
int pty_argc = 0;
|
||||
size_t argv_startpos = src->pos;
|
||||
|
||||
while (get_asciz(src), !get_err(src))
|
||||
@ -274,9 +274,9 @@ static void help(FILE *fp) {
|
||||
" -nethack Map numeric keypad to hjklyubn direction keys\n"
|
||||
" -xrm RESOURCE-STRING Set an X resource\n"
|
||||
" -e COMMAND [ARGS...] Execute command (consumes all remaining args)\n"
|
||||
) < 0 || fflush(fp) < 0) {
|
||||
perror("output error");
|
||||
exit(1);
|
||||
) < 0 || fflush(fp) < 0) {
|
||||
perror("output error");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,8 +284,8 @@ static void version(FILE *fp) {
|
||||
char *buildinfo_text = buildinfo("\n");
|
||||
if(fprintf(fp, "%s: %s\n%s\n", appname, ver, buildinfo_text) < 0 ||
|
||||
fflush(fp) < 0) {
|
||||
perror("output error");
|
||||
exit(1);
|
||||
perror("output error");
|
||||
exit(1);
|
||||
}
|
||||
sfree(buildinfo_text);
|
||||
}
|
||||
@ -324,92 +324,92 @@ bool do_cmdline(int argc, char **argv, bool do_everything, Conf *conf)
|
||||
*/
|
||||
#define EXPECTS_ARG { \
|
||||
if (--argc <= 0) { \
|
||||
err = true; \
|
||||
fprintf(stderr, "%s: %s expects an argument\n", appname, p); \
|
||||
err = true; \
|
||||
fprintf(stderr, "%s: %s expects an argument\n", appname, p); \
|
||||
continue; \
|
||||
} else \
|
||||
val = *++argv; \
|
||||
val = *++argv; \
|
||||
}
|
||||
#define SECOND_PASS_ONLY do { if (!do_everything) continue; } while (0)
|
||||
|
||||
while (--argc > 0) {
|
||||
const char *p = *++argv;
|
||||
const char *p = *++argv;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Shameless cheating. Debian requires all X terminal
|
||||
* emulators to support `-T title'; but
|
||||
* cmdline_process_param will eat -T (it means no-pty) and
|
||||
* complain that pterm doesn't support it. So, in pterm
|
||||
* only, we convert -T into -title.
|
||||
*/
|
||||
if ((cmdline_tooltype & TOOLTYPE_NONNETWORK) &&
|
||||
!strcmp(p, "-T"))
|
||||
p = "-title";
|
||||
/*
|
||||
* Shameless cheating. Debian requires all X terminal
|
||||
* emulators to support `-T title'; but
|
||||
* cmdline_process_param will eat -T (it means no-pty) and
|
||||
* complain that pterm doesn't support it. So, in pterm
|
||||
* only, we convert -T into -title.
|
||||
*/
|
||||
if ((cmdline_tooltype & TOOLTYPE_NONNETWORK) &&
|
||||
!strcmp(p, "-T"))
|
||||
p = "-title";
|
||||
|
||||
ret = cmdline_process_param(p, (argc > 1 ? argv[1] : NULL),
|
||||
do_everything ? 1 : -1, conf);
|
||||
|
||||
if (ret == -2) {
|
||||
cmdline_error("option \"%s\" requires an argument", p);
|
||||
} else if (ret == 2) {
|
||||
--argc, ++argv; /* skip next argument */
|
||||
if (ret == -2) {
|
||||
cmdline_error("option \"%s\" requires an argument", p);
|
||||
} else if (ret == 2) {
|
||||
--argc, ++argv; /* skip next argument */
|
||||
continue;
|
||||
} else if (ret == 1) {
|
||||
} else if (ret == 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcmp(p, "-fn") || !strcmp(p, "-font")) {
|
||||
FontSpec *fs;
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
if (!strcmp(p, "-fn") || !strcmp(p, "-font")) {
|
||||
FontSpec *fs;
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
fs = fontspec_new(val);
|
||||
conf_set_fontspec(conf, CONF_font, fs);
|
||||
conf_set_fontspec(conf, CONF_font, fs);
|
||||
fontspec_free(fs);
|
||||
|
||||
} else if (!strcmp(p, "-fb")) {
|
||||
FontSpec *fs;
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
} else if (!strcmp(p, "-fb")) {
|
||||
FontSpec *fs;
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
fs = fontspec_new(val);
|
||||
conf_set_fontspec(conf, CONF_boldfont, fs);
|
||||
conf_set_fontspec(conf, CONF_boldfont, fs);
|
||||
fontspec_free(fs);
|
||||
|
||||
} else if (!strcmp(p, "-fw")) {
|
||||
FontSpec *fs;
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
} else if (!strcmp(p, "-fw")) {
|
||||
FontSpec *fs;
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
fs = fontspec_new(val);
|
||||
conf_set_fontspec(conf, CONF_widefont, fs);
|
||||
conf_set_fontspec(conf, CONF_widefont, fs);
|
||||
fontspec_free(fs);
|
||||
|
||||
} else if (!strcmp(p, "-fwb")) {
|
||||
FontSpec *fs;
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
} else if (!strcmp(p, "-fwb")) {
|
||||
FontSpec *fs;
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
fs = fontspec_new(val);
|
||||
conf_set_fontspec(conf, CONF_wideboldfont, fs);
|
||||
conf_set_fontspec(conf, CONF_wideboldfont, fs);
|
||||
fontspec_free(fs);
|
||||
|
||||
} else if (!strcmp(p, "-cs")) {
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_str(conf, CONF_line_codepage, val);
|
||||
} else if (!strcmp(p, "-cs")) {
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_str(conf, CONF_line_codepage, val);
|
||||
|
||||
} else if (!strcmp(p, "-geometry")) {
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
} else if (!strcmp(p, "-geometry")) {
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
geometry_string = val;
|
||||
} else if (!strcmp(p, "-sl")) {
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_int(conf, CONF_savelines, atoi(val));
|
||||
} else if (!strcmp(p, "-sl")) {
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_int(conf, CONF_savelines, atoi(val));
|
||||
|
||||
} else if (!strcmp(p, "-fg") || !strcmp(p, "-bg") ||
|
||||
!strcmp(p, "-bfg") || !strcmp(p, "-bbg") ||
|
||||
!strcmp(p, "-cfg") || !strcmp(p, "-cbg")) {
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
} else if (!strcmp(p, "-fg") || !strcmp(p, "-bg") ||
|
||||
!strcmp(p, "-bfg") || !strcmp(p, "-bbg") ||
|
||||
!strcmp(p, "-cfg") || !strcmp(p, "-cbg")) {
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
|
||||
{
|
||||
#if GTK_CHECK_VERSION(3,0,0)
|
||||
@ -450,86 +450,86 @@ bool do_cmdline(int argc, char **argv, bool do_everything, Conf *conf)
|
||||
}
|
||||
}
|
||||
|
||||
} else if (use_pty_argv && !strcmp(p, "-e")) {
|
||||
/* This option swallows all further arguments. */
|
||||
if (!do_everything)
|
||||
break;
|
||||
} else if (use_pty_argv && !strcmp(p, "-e")) {
|
||||
/* This option swallows all further arguments. */
|
||||
if (!do_everything)
|
||||
break;
|
||||
|
||||
if (--argc > 0) {
|
||||
int i;
|
||||
pty_argv = snewn(argc+1, char *);
|
||||
++argv;
|
||||
for (i = 0; i < argc; i++)
|
||||
pty_argv[i] = argv[i];
|
||||
pty_argv[argc] = NULL;
|
||||
break; /* finished command-line processing */
|
||||
} else
|
||||
err = true, fprintf(stderr, "%s: -e expects an argument\n",
|
||||
if (--argc > 0) {
|
||||
int i;
|
||||
pty_argv = snewn(argc+1, char *);
|
||||
++argv;
|
||||
for (i = 0; i < argc; i++)
|
||||
pty_argv[i] = argv[i];
|
||||
pty_argv[argc] = NULL;
|
||||
break; /* finished command-line processing */
|
||||
} else
|
||||
err = true, fprintf(stderr, "%s: -e expects an argument\n",
|
||||
appname);
|
||||
|
||||
} else if (!strcmp(p, "-title")) {
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_str(conf, CONF_wintitle, val);
|
||||
} else if (!strcmp(p, "-title")) {
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_str(conf, CONF_wintitle, val);
|
||||
|
||||
} else if (!strcmp(p, "-log")) {
|
||||
Filename *fn;
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
} else if (!strcmp(p, "-log")) {
|
||||
Filename *fn;
|
||||
EXPECTS_ARG;
|
||||
SECOND_PASS_ONLY;
|
||||
fn = filename_from_str(val);
|
||||
conf_set_filename(conf, CONF_logfilename, fn);
|
||||
conf_set_int(conf, CONF_logtype, LGTYP_DEBUG);
|
||||
conf_set_filename(conf, CONF_logfilename, fn);
|
||||
conf_set_int(conf, CONF_logtype, LGTYP_DEBUG);
|
||||
filename_free(fn);
|
||||
|
||||
} else if (!strcmp(p, "-ut-") || !strcmp(p, "+ut")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_stamp_utmp, false);
|
||||
} else if (!strcmp(p, "-ut-") || !strcmp(p, "+ut")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_stamp_utmp, false);
|
||||
|
||||
} else if (!strcmp(p, "-ut")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_stamp_utmp, true);
|
||||
} else if (!strcmp(p, "-ut")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_stamp_utmp, true);
|
||||
|
||||
} else if (!strcmp(p, "-ls-") || !strcmp(p, "+ls")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_login_shell, false);
|
||||
} else if (!strcmp(p, "-ls-") || !strcmp(p, "+ls")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_login_shell, false);
|
||||
|
||||
} else if (!strcmp(p, "-ls")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_login_shell, true);
|
||||
} else if (!strcmp(p, "-ls")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_login_shell, true);
|
||||
|
||||
} else if (!strcmp(p, "-nethack")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_nethack_keypad, true);
|
||||
} else if (!strcmp(p, "-nethack")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_nethack_keypad, true);
|
||||
|
||||
} else if (!strcmp(p, "-sb-") || !strcmp(p, "+sb")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_scrollbar, false);
|
||||
} else if (!strcmp(p, "-sb-") || !strcmp(p, "+sb")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_scrollbar, false);
|
||||
|
||||
} else if (!strcmp(p, "-sb")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_scrollbar, true);
|
||||
} else if (!strcmp(p, "-sb")) {
|
||||
SECOND_PASS_ONLY;
|
||||
conf_set_bool(conf, CONF_scrollbar, true);
|
||||
|
||||
} else if (!strcmp(p, "-name")) {
|
||||
EXPECTS_ARG;
|
||||
app_name = val;
|
||||
} else if (!strcmp(p, "-name")) {
|
||||
EXPECTS_ARG;
|
||||
app_name = val;
|
||||
|
||||
} else if (!strcmp(p, "-xrm")) {
|
||||
EXPECTS_ARG;
|
||||
provide_xrm_string(val, appname);
|
||||
} else if (!strcmp(p, "-xrm")) {
|
||||
EXPECTS_ARG;
|
||||
provide_xrm_string(val, appname);
|
||||
|
||||
} else if(!strcmp(p, "-help") || !strcmp(p, "--help")) {
|
||||
help(stdout);
|
||||
exit(0);
|
||||
} else if(!strcmp(p, "-help") || !strcmp(p, "--help")) {
|
||||
help(stdout);
|
||||
exit(0);
|
||||
|
||||
} else if(!strcmp(p, "-version") || !strcmp(p, "--version")) {
|
||||
version(stdout);
|
||||
exit(0);
|
||||
} else if(!strcmp(p, "-version") || !strcmp(p, "--version")) {
|
||||
version(stdout);
|
||||
exit(0);
|
||||
|
||||
} else if (!strcmp(p, "-pgpfp")) {
|
||||
pgp_fingerprints();
|
||||
exit(1);
|
||||
|
||||
} else if (p[0] != '-') {
|
||||
} else if (p[0] != '-') {
|
||||
/* Non-option arguments not handled by cmdline.c are errors. */
|
||||
if (do_everything) {
|
||||
err = true;
|
||||
@ -537,10 +537,10 @@ bool do_cmdline(int argc, char **argv, bool do_everything, Conf *conf)
|
||||
appname, p);
|
||||
}
|
||||
|
||||
} else {
|
||||
err = true;
|
||||
fprintf(stderr, "%s: unrecognized option '%s'\n", appname, p);
|
||||
}
|
||||
} else {
|
||||
err = true;
|
||||
fprintf(stderr, "%s: unrecognized option '%s'\n", appname, p);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
@ -598,13 +598,13 @@ int main(int argc, char **argv)
|
||||
* it. It will be required later.
|
||||
*/
|
||||
{
|
||||
int i, oldargc;
|
||||
int i, oldargc;
|
||||
gtkargvstart = snewn(argc-1, char *);
|
||||
for (i = 1; i < argc; i++)
|
||||
gtkargvstart[i-1] = dupstr(argv[i]);
|
||||
oldargc = argc;
|
||||
gtk_init(&argc, &argv);
|
||||
ngtkargs = oldargc - argc;
|
||||
for (i = 1; i < argc; i++)
|
||||
gtkargvstart[i-1] = dupstr(argv[i]);
|
||||
oldargc = argc;
|
||||
gtk_init(&argc, &argv);
|
||||
ngtkargs = oldargc - argc;
|
||||
}
|
||||
|
||||
conf = conf_new();
|
||||
@ -620,20 +620,20 @@ int main(int argc, char **argv)
|
||||
block_signal(SIGPIPE, true);
|
||||
|
||||
if (argc > 1 && !strncmp(argv[1], "---", 3)) {
|
||||
read_dupsession_data(conf, argv[1]);
|
||||
/* Splatter this argument so it doesn't clutter a ps listing */
|
||||
smemclr(argv[1], strlen(argv[1]));
|
||||
read_dupsession_data(conf, argv[1]);
|
||||
/* Splatter this argument so it doesn't clutter a ps listing */
|
||||
smemclr(argv[1], strlen(argv[1]));
|
||||
|
||||
assert(!dup_check_launchable || conf_launchable(conf));
|
||||
need_config_box = false;
|
||||
} else {
|
||||
if (do_cmdline(argc, argv, false, conf))
|
||||
exit(1); /* pre-defaults pass to get -class */
|
||||
do_defaults(NULL, conf);
|
||||
if (do_cmdline(argc, argv, true, conf))
|
||||
exit(1); /* post-defaults, do everything */
|
||||
if (do_cmdline(argc, argv, false, conf))
|
||||
exit(1); /* pre-defaults pass to get -class */
|
||||
do_defaults(NULL, conf);
|
||||
if (do_cmdline(argc, argv, true, conf))
|
||||
exit(1); /* post-defaults, do everything */
|
||||
|
||||
cmdline_run_saved(conf);
|
||||
cmdline_run_saved(conf);
|
||||
|
||||
if (cmdline_tooltype & TOOLTYPE_HOST_ARG)
|
||||
need_config_box = !cmdline_host_ok(conf);
|
||||
|
1630
unix/gtkwin.c
1630
unix/gtkwin.c
File diff suppressed because it is too large
Load Diff
@ -2,29 +2,29 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>Pterm.icns</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Pterm</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Pterm</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Pterm</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>Unidentified build</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>Unidentified build</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.tartarus.projects.putty.macpterm</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>© 1997-2015 Simon Tatham. All rights reserved.</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>Pterm.icns</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Pterm</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Pterm</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>Pterm</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>Unidentified build</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>Unidentified build</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.tartarus.projects.putty.macpterm</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>© 1997-2015 Simon Tatham. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
@ -2,29 +2,29 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>PuTTY.icns</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>PuTTY</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>PuTTY</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>PuTTY</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>Unidentified build</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>Unidentified build</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.tartarus.projects.putty.macputty</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>© 1997-2015 Simon Tatham. All rights reserved.</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>PuTTY.icns</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>PuTTY</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>PuTTY</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>PuTTY</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>Unidentified build</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>Unidentified build</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.tartarus.projects.putty.macputty</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>© 1997-2015 Simon Tatham. All rights reserved.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
12
unix/unix.h
12
unix/unix.h
@ -5,10 +5,10 @@
|
||||
# include "uxconfig.h" /* Space to hide it from mkfiles.pl */
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* for FILENAME_MAX */
|
||||
#include <stdint.h> /* C99 int types */
|
||||
#include <stdio.h> /* for FILENAME_MAX */
|
||||
#include <stdint.h> /* C99 int types */
|
||||
#ifndef NO_LIBDL
|
||||
#include <dlfcn.h> /* Dynamic library loading */
|
||||
#include <dlfcn.h> /* Dynamic library loading */
|
||||
#endif /* NO_LIBDL */
|
||||
#include "charset.h"
|
||||
#include <sys/types.h> /* for mode_t */
|
||||
@ -95,8 +95,8 @@ extern const struct BackendVtable pty_backend;
|
||||
/* Simple wraparound timer function */
|
||||
unsigned long getticks(void);
|
||||
#define GETTICKCOUNT getticks
|
||||
#define TICKSPERSEC 1000 /* we choose to use milliseconds */
|
||||
#define CURSORBLINK 450 /* no standard way to set this */
|
||||
#define TICKSPERSEC 1000 /* we choose to use milliseconds */
|
||||
#define CURSORBLINK 450 /* no standard way to set this */
|
||||
|
||||
#define WCHAR wchar_t
|
||||
#define BYTE unsigned char
|
||||
@ -341,7 +341,7 @@ void gtk_setup_config_box(
|
||||
* from the command line or config files is assumed to be encoded).
|
||||
*/
|
||||
#define DEFAULT_CODEPAGE 0xFFFF
|
||||
#define CP_UTF8 CS_UTF8 /* from libcharset */
|
||||
#define CP_UTF8 CS_UTF8 /* from libcharset */
|
||||
|
||||
#define strnicmp strncasecmp
|
||||
#define stricmp strcasecmp
|
||||
|
@ -25,17 +25,17 @@ void platform_get_x11_auth(struct X11Display *disp, Conf *conf)
|
||||
needs_free = false;
|
||||
xauthfile = getenv("XAUTHORITY");
|
||||
if (!xauthfile) {
|
||||
xauthfile = getenv("HOME");
|
||||
if (xauthfile) {
|
||||
xauthfile = dupcat(xauthfile, "/.Xauthority", NULL);
|
||||
needs_free = true;
|
||||
}
|
||||
xauthfile = getenv("HOME");
|
||||
if (xauthfile) {
|
||||
xauthfile = dupcat(xauthfile, "/.Xauthority", NULL);
|
||||
needs_free = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (xauthfile) {
|
||||
x11_get_auth_from_authfile(disp, xauthfile);
|
||||
if (needs_free)
|
||||
sfree(xauthfile);
|
||||
x11_get_auth_from_authfile(disp, xauthfile);
|
||||
if (needs_free)
|
||||
sfree(xauthfile);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ bool agent_exists(void)
|
||||
{
|
||||
const char *p = getenv("SSH_AUTH_SOCK");
|
||||
if (p && *p)
|
||||
return true;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -37,9 +37,9 @@ static int agent_conncmp(void *av, void *bv)
|
||||
agent_pending_query *a = (agent_pending_query *) av;
|
||||
agent_pending_query *b = (agent_pending_query *) bv;
|
||||
if (a->fd < b->fd)
|
||||
return -1;
|
||||
return -1;
|
||||
if (a->fd > b->fd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
static int agent_connfind(void *av, void *bv)
|
||||
@ -47,9 +47,9 @@ static int agent_connfind(void *av, void *bv)
|
||||
int afd = *(int *) av;
|
||||
agent_pending_query *b = (agent_pending_query *) bv;
|
||||
if (afd < b->fd)
|
||||
return -1;
|
||||
return -1;
|
||||
if (afd > b->fd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -66,26 +66,26 @@ static bool agent_try_read(agent_pending_query *conn)
|
||||
ret = read(conn->fd, conn->retbuf+conn->retlen,
|
||||
conn->retsize-conn->retlen);
|
||||
if (ret <= 0) {
|
||||
if (conn->retbuf != conn->sizebuf) sfree(conn->retbuf);
|
||||
conn->retbuf = NULL;
|
||||
conn->retlen = 0;
|
||||
if (conn->retbuf != conn->sizebuf) sfree(conn->retbuf);
|
||||
conn->retbuf = NULL;
|
||||
conn->retlen = 0;
|
||||
return true;
|
||||
}
|
||||
conn->retlen += ret;
|
||||
if (conn->retsize == 4 && conn->retlen == 4) {
|
||||
conn->retsize = toint(GET_32BIT_MSB_FIRST(conn->retbuf) + 4);
|
||||
if (conn->retsize <= 0) {
|
||||
conn->retbuf = NULL;
|
||||
conn->retlen = 0;
|
||||
conn->retsize = toint(GET_32BIT_MSB_FIRST(conn->retbuf) + 4);
|
||||
if (conn->retsize <= 0) {
|
||||
conn->retbuf = NULL;
|
||||
conn->retlen = 0;
|
||||
return true; /* way too large */
|
||||
}
|
||||
assert(conn->retbuf == conn->sizebuf);
|
||||
conn->retbuf = snewn(conn->retsize, char);
|
||||
memcpy(conn->retbuf, conn->sizebuf, 4);
|
||||
}
|
||||
assert(conn->retbuf == conn->sizebuf);
|
||||
conn->retbuf = snewn(conn->retsize, char);
|
||||
memcpy(conn->retbuf, conn->sizebuf, 4);
|
||||
}
|
||||
|
||||
if (conn->retlen < conn->retsize)
|
||||
return false; /* more data to come */
|
||||
return false; /* more data to come */
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -108,12 +108,12 @@ static void agent_select_result(int fd, int event)
|
||||
|
||||
conn = find234(agent_pending_queries, &fd, agent_connfind);
|
||||
if (!conn) {
|
||||
uxsel_del(fd);
|
||||
return;
|
||||
uxsel_del(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!agent_try_read(conn))
|
||||
return; /* more data to come */
|
||||
return; /* more data to come */
|
||||
|
||||
/*
|
||||
* We have now completed the agent query. Do the callback.
|
||||
@ -137,12 +137,12 @@ agent_pending_query *agent_query(
|
||||
|
||||
name = getenv("SSH_AUTH_SOCK");
|
||||
if (!name || strlen(name) >= sizeof(addr.sun_path))
|
||||
goto failure;
|
||||
goto failure;
|
||||
|
||||
sock = socket(PF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
perror("socket(PF_UNIX)");
|
||||
exit(1);
|
||||
perror("socket(PF_UNIX)");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cloexec(sock);
|
||||
@ -150,20 +150,20 @@ agent_pending_query *agent_query(
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy(addr.sun_path, name);
|
||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||
close(sock);
|
||||
goto failure;
|
||||
close(sock);
|
||||
goto failure;
|
||||
}
|
||||
|
||||
strbuf_finalise_agent_query(query);
|
||||
|
||||
for (done = 0; done < query->len ;) {
|
||||
int ret = write(sock, query->s + done,
|
||||
int ret = write(sock, query->s + done,
|
||||
query->len - done);
|
||||
if (ret <= 0) {
|
||||
close(sock);
|
||||
goto failure;
|
||||
}
|
||||
done += ret;
|
||||
if (ret <= 0) {
|
||||
close(sock);
|
||||
goto failure;
|
||||
}
|
||||
done += ret;
|
||||
}
|
||||
|
||||
conn = snew(agent_pending_query);
|
||||
@ -200,7 +200,7 @@ agent_pending_query *agent_query(
|
||||
* select_result comes back to us.
|
||||
*/
|
||||
if (!agent_pending_queries)
|
||||
agent_pending_queries = newtree234(agent_conncmp);
|
||||
agent_pending_queries = newtree234(agent_conncmp);
|
||||
add234(agent_pending_queries, conn);
|
||||
|
||||
uxsel_set(sock, SELECT_R, agent_select_result);
|
||||
|
56
unix/uxcfg.c
56
unix/uxcfg.c
@ -36,36 +36,36 @@ void unix_setup_config_box(struct controlbox *b, bool midsession, int protocol)
|
||||
* adjust the text on the `Telnet command' control.
|
||||
*/
|
||||
if (!midsession) {
|
||||
int i;
|
||||
int i;
|
||||
s = ctrl_getset(b, "Connection/Proxy", "basics", NULL);
|
||||
for (i = 0; i < s->ncontrols; i++) {
|
||||
c = s->ctrls[i];
|
||||
if (c->generic.type == CTRL_RADIO &&
|
||||
c->generic.context.i == CONF_proxy_type) {
|
||||
assert(c->generic.handler == conf_radiobutton_handler);
|
||||
c->radio.nbuttons++;
|
||||
c->radio.buttons =
|
||||
sresize(c->radio.buttons, c->radio.nbuttons, char *);
|
||||
c->radio.buttons[c->radio.nbuttons-1] =
|
||||
dupstr("Local");
|
||||
c->radio.buttondata =
|
||||
sresize(c->radio.buttondata, c->radio.nbuttons, intorptr);
|
||||
c->radio.buttondata[c->radio.nbuttons-1] = I(PROXY_CMD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < s->ncontrols; i++) {
|
||||
c = s->ctrls[i];
|
||||
if (c->generic.type == CTRL_RADIO &&
|
||||
c->generic.context.i == CONF_proxy_type) {
|
||||
assert(c->generic.handler == conf_radiobutton_handler);
|
||||
c->radio.nbuttons++;
|
||||
c->radio.buttons =
|
||||
sresize(c->radio.buttons, c->radio.nbuttons, char *);
|
||||
c->radio.buttons[c->radio.nbuttons-1] =
|
||||
dupstr("Local");
|
||||
c->radio.buttondata =
|
||||
sresize(c->radio.buttondata, c->radio.nbuttons, intorptr);
|
||||
c->radio.buttondata[c->radio.nbuttons-1] = I(PROXY_CMD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < s->ncontrols; i++) {
|
||||
c = s->ctrls[i];
|
||||
if (c->generic.type == CTRL_EDITBOX &&
|
||||
c->generic.context.i == CONF_proxy_telnet_command) {
|
||||
assert(c->generic.handler == conf_editbox_handler);
|
||||
sfree(c->generic.label);
|
||||
c->generic.label = dupstr("Telnet command, or local"
|
||||
" proxy command");
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < s->ncontrols; i++) {
|
||||
c = s->ctrls[i];
|
||||
if (c->generic.type == CTRL_EDITBOX &&
|
||||
c->generic.context.i == CONF_proxy_telnet_command) {
|
||||
assert(c->generic.handler == conf_editbox_handler);
|
||||
sfree(c->generic.label);
|
||||
c->generic.label = dupstr("Telnet command, or local"
|
||||
" proxy command");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
356
unix/uxcons.c
356
unix/uxcons.c
@ -27,22 +27,22 @@ void stderr_tty_init()
|
||||
{
|
||||
/* Ensure that if stderr is a tty, we can get it back to a sane state. */
|
||||
if ((flags & FLAG_STDERR_TTY) && isatty(STDERR_FILENO)) {
|
||||
stderr_is_a_tty = true;
|
||||
tcgetattr(STDERR_FILENO, &orig_termios_stderr);
|
||||
stderr_is_a_tty = true;
|
||||
tcgetattr(STDERR_FILENO, &orig_termios_stderr);
|
||||
}
|
||||
}
|
||||
|
||||
void premsg(struct termios *cf)
|
||||
{
|
||||
if (stderr_is_a_tty) {
|
||||
tcgetattr(STDERR_FILENO, cf);
|
||||
tcsetattr(STDERR_FILENO, TCSADRAIN, &orig_termios_stderr);
|
||||
tcgetattr(STDERR_FILENO, cf);
|
||||
tcsetattr(STDERR_FILENO, TCSADRAIN, &orig_termios_stderr);
|
||||
}
|
||||
}
|
||||
void postmsg(struct termios *cf)
|
||||
{
|
||||
if (stderr_is_a_tty)
|
||||
tcsetattr(STDERR_FILENO, TCSADRAIN, cf);
|
||||
tcsetattr(STDERR_FILENO, TCSADRAIN, cf);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -161,49 +161,49 @@ int console_verify_ssh_host_key(
|
||||
int ret;
|
||||
|
||||
static const char absentmsg_batch[] =
|
||||
"The server's host key is not cached. You have no guarantee\n"
|
||||
"that the server is the computer you think it is.\n"
|
||||
"The server's %s key fingerprint is:\n"
|
||||
"%s\n"
|
||||
"Connection abandoned.\n";
|
||||
"The server's host key is not cached. You have no guarantee\n"
|
||||
"that the server is the computer you think it is.\n"
|
||||
"The server's %s key fingerprint is:\n"
|
||||
"%s\n"
|
||||
"Connection abandoned.\n";
|
||||
static const char absentmsg[] =
|
||||
"The server's host key is not cached. You have no guarantee\n"
|
||||
"that the server is the computer you think it is.\n"
|
||||
"The server's %s key fingerprint is:\n"
|
||||
"%s\n"
|
||||
"If you trust this host, enter \"y\" to add the key to\n"
|
||||
"PuTTY's cache and carry on connecting.\n"
|
||||
"If you want to carry on connecting just once, without\n"
|
||||
"adding the key to the cache, enter \"n\".\n"
|
||||
"If you do not trust this host, press Return to abandon the\n"
|
||||
"connection.\n"
|
||||
"Store key in cache? (y/n) ";
|
||||
"The server's host key is not cached. You have no guarantee\n"
|
||||
"that the server is the computer you think it is.\n"
|
||||
"The server's %s key fingerprint is:\n"
|
||||
"%s\n"
|
||||
"If you trust this host, enter \"y\" to add the key to\n"
|
||||
"PuTTY's cache and carry on connecting.\n"
|
||||
"If you want to carry on connecting just once, without\n"
|
||||
"adding the key to the cache, enter \"n\".\n"
|
||||
"If you do not trust this host, press Return to abandon the\n"
|
||||
"connection.\n"
|
||||
"Store key in cache? (y/n) ";
|
||||
|
||||
static const char wrongmsg_batch[] =
|
||||
"WARNING - POTENTIAL SECURITY BREACH!\n"
|
||||
"The server's host key does not match the one PuTTY has\n"
|
||||
"cached. This means that either the server administrator\n"
|
||||
"has changed the host key, or you have actually connected\n"
|
||||
"to another computer pretending to be the server.\n"
|
||||
"The new %s key fingerprint is:\n"
|
||||
"%s\n"
|
||||
"Connection abandoned.\n";
|
||||
"WARNING - POTENTIAL SECURITY BREACH!\n"
|
||||
"The server's host key does not match the one PuTTY has\n"
|
||||
"cached. This means that either the server administrator\n"
|
||||
"has changed the host key, or you have actually connected\n"
|
||||
"to another computer pretending to be the server.\n"
|
||||
"The new %s key fingerprint is:\n"
|
||||
"%s\n"
|
||||
"Connection abandoned.\n";
|
||||
static const char wrongmsg[] =
|
||||
"WARNING - POTENTIAL SECURITY BREACH!\n"
|
||||
"The server's host key does not match the one PuTTY has\n"
|
||||
"cached. This means that either the server administrator\n"
|
||||
"has changed the host key, or you have actually connected\n"
|
||||
"to another computer pretending to be the server.\n"
|
||||
"The new %s key fingerprint is:\n"
|
||||
"%s\n"
|
||||
"If you were expecting this change and trust the new key,\n"
|
||||
"enter \"y\" to update PuTTY's cache and continue connecting.\n"
|
||||
"If you want to carry on connecting but without updating\n"
|
||||
"the cache, enter \"n\".\n"
|
||||
"If you want to abandon the connection completely, press\n"
|
||||
"Return to cancel. Pressing Return is the ONLY guaranteed\n"
|
||||
"safe choice.\n"
|
||||
"Update cached key? (y/n, Return cancels connection) ";
|
||||
"WARNING - POTENTIAL SECURITY BREACH!\n"
|
||||
"The server's host key does not match the one PuTTY has\n"
|
||||
"cached. This means that either the server administrator\n"
|
||||
"has changed the host key, or you have actually connected\n"
|
||||
"to another computer pretending to be the server.\n"
|
||||
"The new %s key fingerprint is:\n"
|
||||
"%s\n"
|
||||
"If you were expecting this change and trust the new key,\n"
|
||||
"enter \"y\" to update PuTTY's cache and continue connecting.\n"
|
||||
"If you want to carry on connecting but without updating\n"
|
||||
"the cache, enter \"n\".\n"
|
||||
"If you want to abandon the connection completely, press\n"
|
||||
"Return to cancel. Pressing Return is the ONLY guaranteed\n"
|
||||
"safe choice.\n"
|
||||
"Update cached key? (y/n, Return cancels connection) ";
|
||||
|
||||
static const char abandoned[] = "Connection abandoned.\n";
|
||||
|
||||
@ -215,47 +215,47 @@ int console_verify_ssh_host_key(
|
||||
*/
|
||||
ret = verify_host_key(host, port, keytype, keystr);
|
||||
|
||||
if (ret == 0) /* success - key matched OK */
|
||||
return 1;
|
||||
if (ret == 0) /* success - key matched OK */
|
||||
return 1;
|
||||
|
||||
premsg(&cf);
|
||||
if (ret == 2) { /* key was different */
|
||||
if (console_batch_mode) {
|
||||
fprintf(stderr, wrongmsg_batch, keytype, fingerprint);
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, wrongmsg, keytype, fingerprint);
|
||||
fflush(stderr);
|
||||
if (ret == 2) { /* key was different */
|
||||
if (console_batch_mode) {
|
||||
fprintf(stderr, wrongmsg_batch, keytype, fingerprint);
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, wrongmsg, keytype, fingerprint);
|
||||
fflush(stderr);
|
||||
}
|
||||
if (ret == 1) { /* key was absent */
|
||||
if (console_batch_mode) {
|
||||
fprintf(stderr, absentmsg_batch, keytype, fingerprint);
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, absentmsg, keytype, fingerprint);
|
||||
fflush(stderr);
|
||||
if (ret == 1) { /* key was absent */
|
||||
if (console_batch_mode) {
|
||||
fprintf(stderr, absentmsg_batch, keytype, fingerprint);
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, absentmsg, keytype, fingerprint);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
{
|
||||
struct termios oldmode, newmode;
|
||||
tcgetattr(0, &oldmode);
|
||||
newmode = oldmode;
|
||||
newmode.c_lflag |= ECHO | ISIG | ICANON;
|
||||
tcsetattr(0, TCSANOW, &newmode);
|
||||
line[0] = '\0';
|
||||
if (block_and_read(0, line, sizeof(line) - 1) <= 0)
|
||||
/* handled below */;
|
||||
tcsetattr(0, TCSANOW, &oldmode);
|
||||
struct termios oldmode, newmode;
|
||||
tcgetattr(0, &oldmode);
|
||||
newmode = oldmode;
|
||||
newmode.c_lflag |= ECHO | ISIG | ICANON;
|
||||
tcsetattr(0, TCSANOW, &newmode);
|
||||
line[0] = '\0';
|
||||
if (block_and_read(0, line, sizeof(line) - 1) <= 0)
|
||||
/* handled below */;
|
||||
tcsetattr(0, TCSANOW, &oldmode);
|
||||
}
|
||||
|
||||
if (line[0] != '\0' && line[0] != '\r' && line[0] != '\n') {
|
||||
if (line[0] == 'y' || line[0] == 'Y')
|
||||
store_host_key(host, port, keytype, keystr);
|
||||
postmsg(&cf);
|
||||
if (line[0] == 'y' || line[0] == 'Y')
|
||||
store_host_key(host, port, keytype, keystr);
|
||||
postmsg(&cf);
|
||||
return 1;
|
||||
} else {
|
||||
fprintf(stderr, abandoned);
|
||||
postmsg(&cf);
|
||||
fprintf(stderr, abandoned);
|
||||
postmsg(&cf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -265,13 +265,13 @@ int console_confirm_weak_crypto_primitive(
|
||||
void (*callback)(void *ctx, int result), void *ctx)
|
||||
{
|
||||
static const char msg[] =
|
||||
"The first %s supported by the server is\n"
|
||||
"%s, which is below the configured warning threshold.\n"
|
||||
"Continue with connection? (y/n) ";
|
||||
"The first %s supported by the server is\n"
|
||||
"%s, which is below the configured warning threshold.\n"
|
||||
"Continue with connection? (y/n) ";
|
||||
static const char msg_batch[] =
|
||||
"The first %s supported by the server is\n"
|
||||
"%s, which is below the configured warning threshold.\n"
|
||||
"Connection abandoned.\n";
|
||||
"The first %s supported by the server is\n"
|
||||
"%s, which is below the configured warning threshold.\n"
|
||||
"Connection abandoned.\n";
|
||||
static const char abandoned[] = "Connection abandoned.\n";
|
||||
|
||||
char line[32];
|
||||
@ -279,32 +279,32 @@ int console_confirm_weak_crypto_primitive(
|
||||
|
||||
premsg(&cf);
|
||||
if (console_batch_mode) {
|
||||
fprintf(stderr, msg_batch, algtype, algname);
|
||||
return 0;
|
||||
fprintf(stderr, msg_batch, algtype, algname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, msg, algtype, algname);
|
||||
fflush(stderr);
|
||||
|
||||
{
|
||||
struct termios oldmode, newmode;
|
||||
tcgetattr(0, &oldmode);
|
||||
newmode = oldmode;
|
||||
newmode.c_lflag |= ECHO | ISIG | ICANON;
|
||||
tcsetattr(0, TCSANOW, &newmode);
|
||||
line[0] = '\0';
|
||||
if (block_and_read(0, line, sizeof(line) - 1) <= 0)
|
||||
/* handled below */;
|
||||
tcsetattr(0, TCSANOW, &oldmode);
|
||||
struct termios oldmode, newmode;
|
||||
tcgetattr(0, &oldmode);
|
||||
newmode = oldmode;
|
||||
newmode.c_lflag |= ECHO | ISIG | ICANON;
|
||||
tcsetattr(0, TCSANOW, &newmode);
|
||||
line[0] = '\0';
|
||||
if (block_and_read(0, line, sizeof(line) - 1) <= 0)
|
||||
/* handled below */;
|
||||
tcsetattr(0, TCSANOW, &oldmode);
|
||||
}
|
||||
|
||||
if (line[0] == 'y' || line[0] == 'Y') {
|
||||
postmsg(&cf);
|
||||
return 1;
|
||||
postmsg(&cf);
|
||||
return 1;
|
||||
} else {
|
||||
fprintf(stderr, abandoned);
|
||||
postmsg(&cf);
|
||||
return 0;
|
||||
fprintf(stderr, abandoned);
|
||||
postmsg(&cf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,19 +313,19 @@ int console_confirm_weak_cached_hostkey(
|
||||
void (*callback)(void *ctx, int result), void *ctx)
|
||||
{
|
||||
static const char msg[] =
|
||||
"The first host key type we have stored for this server\n"
|
||||
"is %s, which is below the configured warning threshold.\n"
|
||||
"The server also provides the following types of host key\n"
|
||||
"The first host key type we have stored for this server\n"
|
||||
"is %s, which is below the configured warning threshold.\n"
|
||||
"The server also provides the following types of host key\n"
|
||||
"above the threshold, which we do not have stored:\n"
|
||||
"%s\n"
|
||||
"Continue with connection? (y/n) ";
|
||||
"Continue with connection? (y/n) ";
|
||||
static const char msg_batch[] =
|
||||
"The first host key type we have stored for this server\n"
|
||||
"is %s, which is below the configured warning threshold.\n"
|
||||
"The server also provides the following types of host key\n"
|
||||
"The first host key type we have stored for this server\n"
|
||||
"is %s, which is below the configured warning threshold.\n"
|
||||
"The server also provides the following types of host key\n"
|
||||
"above the threshold, which we do not have stored:\n"
|
||||
"%s\n"
|
||||
"Connection abandoned.\n";
|
||||
"Connection abandoned.\n";
|
||||
static const char abandoned[] = "Connection abandoned.\n";
|
||||
|
||||
char line[32];
|
||||
@ -333,32 +333,32 @@ int console_confirm_weak_cached_hostkey(
|
||||
|
||||
premsg(&cf);
|
||||
if (console_batch_mode) {
|
||||
fprintf(stderr, msg_batch, algname, betteralgs);
|
||||
return 0;
|
||||
fprintf(stderr, msg_batch, algname, betteralgs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, msg, algname, betteralgs);
|
||||
fflush(stderr);
|
||||
|
||||
{
|
||||
struct termios oldmode, newmode;
|
||||
tcgetattr(0, &oldmode);
|
||||
newmode = oldmode;
|
||||
newmode.c_lflag |= ECHO | ISIG | ICANON;
|
||||
tcsetattr(0, TCSANOW, &newmode);
|
||||
line[0] = '\0';
|
||||
if (block_and_read(0, line, sizeof(line) - 1) <= 0)
|
||||
/* handled below */;
|
||||
tcsetattr(0, TCSANOW, &oldmode);
|
||||
struct termios oldmode, newmode;
|
||||
tcgetattr(0, &oldmode);
|
||||
newmode = oldmode;
|
||||
newmode.c_lflag |= ECHO | ISIG | ICANON;
|
||||
tcsetattr(0, TCSANOW, &newmode);
|
||||
line[0] = '\0';
|
||||
if (block_and_read(0, line, sizeof(line) - 1) <= 0)
|
||||
/* handled below */;
|
||||
tcsetattr(0, TCSANOW, &oldmode);
|
||||
}
|
||||
|
||||
if (line[0] == 'y' || line[0] == 'Y') {
|
||||
postmsg(&cf);
|
||||
return 1;
|
||||
postmsg(&cf);
|
||||
return 1;
|
||||
} else {
|
||||
fprintf(stderr, abandoned);
|
||||
postmsg(&cf);
|
||||
return 0;
|
||||
fprintf(stderr, abandoned);
|
||||
postmsg(&cf);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,49 +371,49 @@ static int console_askappend(LogPolicy *lp, Filename *filename,
|
||||
void *ctx)
|
||||
{
|
||||
static const char msgtemplate[] =
|
||||
"The session log file \"%.*s\" already exists.\n"
|
||||
"You can overwrite it with a new session log,\n"
|
||||
"append your session log to the end of it,\n"
|
||||
"or disable session logging for this session.\n"
|
||||
"Enter \"y\" to wipe the file, \"n\" to append to it,\n"
|
||||
"or just press Return to disable logging.\n"
|
||||
"Wipe the log file? (y/n, Return cancels logging) ";
|
||||
"The session log file \"%.*s\" already exists.\n"
|
||||
"You can overwrite it with a new session log,\n"
|
||||
"append your session log to the end of it,\n"
|
||||
"or disable session logging for this session.\n"
|
||||
"Enter \"y\" to wipe the file, \"n\" to append to it,\n"
|
||||
"or just press Return to disable logging.\n"
|
||||
"Wipe the log file? (y/n, Return cancels logging) ";
|
||||
|
||||
static const char msgtemplate_batch[] =
|
||||
"The session log file \"%.*s\" already exists.\n"
|
||||
"Logging will not be enabled.\n";
|
||||
"The session log file \"%.*s\" already exists.\n"
|
||||
"Logging will not be enabled.\n";
|
||||
|
||||
char line[32];
|
||||
struct termios cf;
|
||||
|
||||
premsg(&cf);
|
||||
if (console_batch_mode) {
|
||||
fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename->path);
|
||||
fflush(stderr);
|
||||
return 0;
|
||||
fprintf(stderr, msgtemplate_batch, FILENAME_MAX, filename->path);
|
||||
fflush(stderr);
|
||||
return 0;
|
||||
}
|
||||
fprintf(stderr, msgtemplate, FILENAME_MAX, filename->path);
|
||||
fflush(stderr);
|
||||
|
||||
{
|
||||
struct termios oldmode, newmode;
|
||||
tcgetattr(0, &oldmode);
|
||||
newmode = oldmode;
|
||||
newmode.c_lflag |= ECHO | ISIG | ICANON;
|
||||
tcsetattr(0, TCSANOW, &newmode);
|
||||
line[0] = '\0';
|
||||
if (block_and_read(0, line, sizeof(line) - 1) <= 0)
|
||||
/* handled below */;
|
||||
tcsetattr(0, TCSANOW, &oldmode);
|
||||
struct termios oldmode, newmode;
|
||||
tcgetattr(0, &oldmode);
|
||||
newmode = oldmode;
|
||||
newmode.c_lflag |= ECHO | ISIG | ICANON;
|
||||
tcsetattr(0, TCSANOW, &newmode);
|
||||
line[0] = '\0';
|
||||
if (block_and_read(0, line, sizeof(line) - 1) <= 0)
|
||||
/* handled below */;
|
||||
tcsetattr(0, TCSANOW, &oldmode);
|
||||
}
|
||||
|
||||
postmsg(&cf);
|
||||
if (line[0] == 'y' || line[0] == 'Y')
|
||||
return 2;
|
||||
return 2;
|
||||
else if (line[0] == 'n' || line[0] == 'N')
|
||||
return 1;
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool console_antispoof_prompt = true;
|
||||
@ -441,7 +441,7 @@ bool console_set_trust_status(Seat *seat, bool trusted)
|
||||
|
||||
/*
|
||||
* Warn about the obsolescent key file format.
|
||||
*
|
||||
*
|
||||
* Uniquely among these functions, this one does _not_ expect a
|
||||
* frontend handle. This means that if PuTTY is ported to a
|
||||
* platform which requires frontend handles, this function will be
|
||||
@ -452,15 +452,15 @@ bool console_set_trust_status(Seat *seat, bool trusted)
|
||||
void old_keyfile_warning(void)
|
||||
{
|
||||
static const char message[] =
|
||||
"You are loading an SSH-2 private key which has an\n"
|
||||
"old version of the file format. This means your key\n"
|
||||
"file is not fully tamperproof. Future versions of\n"
|
||||
"PuTTY may stop supporting this private key format,\n"
|
||||
"so we recommend you convert your key to the new\n"
|
||||
"format.\n"
|
||||
"\n"
|
||||
"Once the key is loaded into PuTTYgen, you can perform\n"
|
||||
"this conversion simply by saving it again.\n";
|
||||
"You are loading an SSH-2 private key which has an\n"
|
||||
"old version of the file format. This means your key\n"
|
||||
"file is not fully tamperproof. Future versions of\n"
|
||||
"PuTTY may stop supporting this private key format,\n"
|
||||
"so we recommend you convert your key to the new\n"
|
||||
"format.\n"
|
||||
"\n"
|
||||
"Once the key is loaded into PuTTYgen, you can perform\n"
|
||||
"this conversion simply by saving it again.\n";
|
||||
|
||||
struct termios cf;
|
||||
premsg(&cf);
|
||||
@ -535,13 +535,13 @@ int console_get_userpass_input(prompts_t *p)
|
||||
* Zero all the results, in case we abort half-way through.
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < p->n_prompts; i++)
|
||||
int i;
|
||||
for (i = 0; i < p->n_prompts; i++)
|
||||
prompt_set_result(p->prompts[i], "");
|
||||
}
|
||||
|
||||
if (p->n_prompts && console_batch_mode)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
console_open(&outfp, &infd);
|
||||
|
||||
@ -550,35 +550,35 @@ int console_get_userpass_input(prompts_t *p)
|
||||
*/
|
||||
/* We only print the `name' caption if we have to... */
|
||||
if (p->name_reqd && p->name) {
|
||||
ptrlen plname = ptrlen_from_asciz(p->name);
|
||||
console_write(outfp, plname);
|
||||
ptrlen plname = ptrlen_from_asciz(p->name);
|
||||
console_write(outfp, plname);
|
||||
if (!ptrlen_endswith(plname, PTRLEN_LITERAL("\n"), NULL))
|
||||
console_write(outfp, PTRLEN_LITERAL("\n"));
|
||||
console_write(outfp, PTRLEN_LITERAL("\n"));
|
||||
}
|
||||
/* ...but we always print any `instruction'. */
|
||||
if (p->instruction) {
|
||||
ptrlen plinst = ptrlen_from_asciz(p->instruction);
|
||||
console_write(outfp, plinst);
|
||||
ptrlen plinst = ptrlen_from_asciz(p->instruction);
|
||||
console_write(outfp, plinst);
|
||||
if (!ptrlen_endswith(plinst, PTRLEN_LITERAL("\n"), NULL))
|
||||
console_write(outfp, PTRLEN_LITERAL("\n"));
|
||||
console_write(outfp, PTRLEN_LITERAL("\n"));
|
||||
}
|
||||
|
||||
for (curr_prompt = 0; curr_prompt < p->n_prompts; curr_prompt++) {
|
||||
|
||||
struct termios oldmode, newmode;
|
||||
int len;
|
||||
prompt_t *pr = p->prompts[curr_prompt];
|
||||
struct termios oldmode, newmode;
|
||||
int len;
|
||||
prompt_t *pr = p->prompts[curr_prompt];
|
||||
|
||||
tcgetattr(infd, &oldmode);
|
||||
newmode = oldmode;
|
||||
newmode.c_lflag |= ISIG | ICANON;
|
||||
if (!pr->echo)
|
||||
newmode.c_lflag &= ~ECHO;
|
||||
else
|
||||
newmode.c_lflag |= ECHO;
|
||||
tcsetattr(infd, TCSANOW, &newmode);
|
||||
tcgetattr(infd, &oldmode);
|
||||
newmode = oldmode;
|
||||
newmode.c_lflag |= ISIG | ICANON;
|
||||
if (!pr->echo)
|
||||
newmode.c_lflag &= ~ECHO;
|
||||
else
|
||||
newmode.c_lflag |= ECHO;
|
||||
tcsetattr(infd, TCSANOW, &newmode);
|
||||
|
||||
console_write(outfp, ptrlen_from_asciz(pr->prompt));
|
||||
console_write(outfp, ptrlen_from_asciz(pr->prompt));
|
||||
|
||||
len = 0;
|
||||
while (1) {
|
||||
@ -597,9 +597,9 @@ int console_get_userpass_input(prompts_t *p)
|
||||
}
|
||||
}
|
||||
|
||||
tcsetattr(infd, TCSANOW, &oldmode);
|
||||
tcsetattr(infd, TCSANOW, &oldmode);
|
||||
|
||||
if (!pr->echo)
|
||||
if (!pr->echo)
|
||||
console_write(outfp, PTRLEN_LITERAL("\n"));
|
||||
|
||||
if (len < 0) {
|
||||
@ -607,7 +607,7 @@ int console_get_userpass_input(prompts_t *p)
|
||||
return 0; /* failure due to read error */
|
||||
}
|
||||
|
||||
pr->result[len] = '\0';
|
||||
pr->result[len] = '\0';
|
||||
}
|
||||
|
||||
console_close(outfp, infd);
|
||||
|
@ -44,9 +44,9 @@ static int fdsocket_infd_cmp(void *av, void *bv)
|
||||
FdSocket *a = (FdSocket *)av;
|
||||
FdSocket *b = (FdSocket *)bv;
|
||||
if (a->infd < b->infd)
|
||||
return -1;
|
||||
return -1;
|
||||
if (a->infd > b->infd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
static int fdsocket_infd_find(void *av, void *bv)
|
||||
@ -54,9 +54,9 @@ static int fdsocket_infd_find(void *av, void *bv)
|
||||
int a = *(int *)av;
|
||||
FdSocket *b = (FdSocket *)bv;
|
||||
if (a < b->infd)
|
||||
return -1;
|
||||
return -1;
|
||||
if (a > b->infd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
static int fdsocket_inerrfd_cmp(void *av, void *bv)
|
||||
@ -64,9 +64,9 @@ static int fdsocket_inerrfd_cmp(void *av, void *bv)
|
||||
FdSocket *a = (FdSocket *)av;
|
||||
FdSocket *b = (FdSocket *)bv;
|
||||
if (a->inerrfd < b->inerrfd)
|
||||
return -1;
|
||||
return -1;
|
||||
if (a->inerrfd > b->inerrfd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
static int fdsocket_inerrfd_find(void *av, void *bv)
|
||||
@ -74,9 +74,9 @@ static int fdsocket_inerrfd_find(void *av, void *bv)
|
||||
int a = *(int *)av;
|
||||
FdSocket *b = (FdSocket *)bv;
|
||||
if (a < b->inerrfd)
|
||||
return -1;
|
||||
return -1;
|
||||
if (a > b->inerrfd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
static int fdsocket_outfd_cmp(void *av, void *bv)
|
||||
@ -84,9 +84,9 @@ static int fdsocket_outfd_cmp(void *av, void *bv)
|
||||
FdSocket *a = (FdSocket *)av;
|
||||
FdSocket *b = (FdSocket *)bv;
|
||||
if (a->outfd < b->outfd)
|
||||
return -1;
|
||||
return -1;
|
||||
if (a->outfd > b->outfd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
static int fdsocket_outfd_find(void *av, void *bv)
|
||||
@ -94,9 +94,9 @@ static int fdsocket_outfd_find(void *av, void *bv)
|
||||
int a = *(int *)av;
|
||||
FdSocket *b = (FdSocket *)bv;
|
||||
if (a < b->outfd)
|
||||
return -1;
|
||||
return -1;
|
||||
if (a > b->outfd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ static Plug *fdsocket_plug(Socket *s, Plug *p)
|
||||
FdSocket *fds = container_of(s, FdSocket, sock);
|
||||
Plug *ret = fds->plug;
|
||||
if (p)
|
||||
fds->plug = p;
|
||||
fds->plug = p;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -164,21 +164,21 @@ static int fdsocket_try_send(FdSocket *fds)
|
||||
while (bufchain_size(&fds->pending_output_data) > 0) {
|
||||
ssize_t ret;
|
||||
|
||||
ptrlen data = bufchain_prefix(&fds->pending_output_data);
|
||||
ret = write(fds->outfd, data.ptr, data.len);
|
||||
ptrlen data = bufchain_prefix(&fds->pending_output_data);
|
||||
ret = write(fds->outfd, data.ptr, data.len);
|
||||
noise_ultralight(NOISE_SOURCE_IOID, ret);
|
||||
if (ret < 0 && errno != EWOULDBLOCK) {
|
||||
if (ret < 0 && errno != EWOULDBLOCK) {
|
||||
if (!fds->pending_error) {
|
||||
fds->pending_error = errno;
|
||||
queue_toplevel_callback(fdsocket_error_callback, fds);
|
||||
}
|
||||
return 0;
|
||||
} else if (ret <= 0) {
|
||||
break;
|
||||
} else {
|
||||
bufchain_consume(&fds->pending_output_data, ret);
|
||||
sent += ret;
|
||||
}
|
||||
} else if (ret <= 0) {
|
||||
break;
|
||||
} else {
|
||||
bufchain_consume(&fds->pending_output_data, ret);
|
||||
sent += ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (fds->outgoingeof == EOF_PENDING) {
|
||||
@ -190,9 +190,9 @@ static int fdsocket_try_send(FdSocket *fds)
|
||||
}
|
||||
|
||||
if (bufchain_size(&fds->pending_output_data) == 0)
|
||||
uxsel_del(fds->outfd);
|
||||
uxsel_del(fds->outfd);
|
||||
else
|
||||
uxsel_set(fds->outfd, SELECT_W, fdsocket_select_result_output);
|
||||
uxsel_set(fds->outfd, SELECT_W, fdsocket_select_result_output);
|
||||
|
||||
return sent;
|
||||
}
|
||||
@ -237,9 +237,9 @@ static void fdsocket_set_frozen(Socket *s, bool is_frozen)
|
||||
return;
|
||||
|
||||
if (is_frozen)
|
||||
uxsel_del(fds->infd);
|
||||
uxsel_del(fds->infd);
|
||||
else
|
||||
uxsel_set(fds->infd, SELECT_R, fdsocket_select_result_input);
|
||||
uxsel_set(fds->infd, SELECT_R, fdsocket_select_result_input);
|
||||
}
|
||||
|
||||
static const char *fdsocket_socket_error(Socket *s)
|
||||
|
18
unix/uxgen.c
18
unix/uxgen.c
@ -39,23 +39,23 @@ char *get_random_data(int len, const char *device)
|
||||
|
||||
fd = open(device, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
sfree(buf);
|
||||
fprintf(stderr, "puttygen: %s: open: %s\n",
|
||||
sfree(buf);
|
||||
fprintf(stderr, "puttygen: %s: open: %s\n",
|
||||
device, strerror(errno));
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ngot = 0;
|
||||
while (ngot < len) {
|
||||
ret = read(fd, buf+ngot, len-ngot);
|
||||
if (ret < 0) {
|
||||
close(fd);
|
||||
ret = read(fd, buf+ngot, len-ngot);
|
||||
if (ret < 0) {
|
||||
close(fd);
|
||||
sfree(buf);
|
||||
fprintf(stderr, "puttygen: %s: read: %s\n",
|
||||
device, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
ngot += ret;
|
||||
return NULL;
|
||||
}
|
||||
ngot += ret;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
32
unix/uxgss.c
32
unix/uxgss.c
@ -29,7 +29,7 @@ const struct keyvalwhere gsslibkeywords[] = {
|
||||
*/
|
||||
|
||||
static void gss_init(struct ssh_gss_library *lib, void *dlhandle,
|
||||
int id, const char *msg)
|
||||
int id, const char *msg)
|
||||
{
|
||||
lib->id = id;
|
||||
lib->gsslogmsg = msg;
|
||||
@ -67,25 +67,25 @@ struct ssh_gss_liblist *ssh_gss_setup(Conf *conf)
|
||||
|
||||
/* Heimdal's GSSAPI Library */
|
||||
if ((gsslib = dlopen("libgssapi.so.2", RTLD_LAZY)) != NULL)
|
||||
gss_init(&list->libraries[list->nlibraries++], gsslib,
|
||||
0, "Using GSSAPI from libgssapi.so.2");
|
||||
gss_init(&list->libraries[list->nlibraries++], gsslib,
|
||||
0, "Using GSSAPI from libgssapi.so.2");
|
||||
|
||||
/* MIT Kerberos's GSSAPI Library */
|
||||
if ((gsslib = dlopen("libgssapi_krb5.so.2", RTLD_LAZY)) != NULL)
|
||||
gss_init(&list->libraries[list->nlibraries++], gsslib,
|
||||
1, "Using GSSAPI from libgssapi_krb5.so.2");
|
||||
gss_init(&list->libraries[list->nlibraries++], gsslib,
|
||||
1, "Using GSSAPI from libgssapi_krb5.so.2");
|
||||
|
||||
/* Sun's GSSAPI Library */
|
||||
if ((gsslib = dlopen("libgss.so.1", RTLD_LAZY)) != NULL)
|
||||
gss_init(&list->libraries[list->nlibraries++], gsslib,
|
||||
2, "Using GSSAPI from libgss.so.1");
|
||||
gss_init(&list->libraries[list->nlibraries++], gsslib,
|
||||
2, "Using GSSAPI from libgss.so.1");
|
||||
|
||||
/* User-specified GSSAPI library */
|
||||
gsspath = conf_get_filename(conf, CONF_ssh_gss_custom)->path;
|
||||
if (*gsspath && (gsslib = dlopen(gsspath, RTLD_LAZY)) != NULL)
|
||||
gss_init(&list->libraries[list->nlibraries++], gsslib,
|
||||
3, dupprintf("Using GSSAPI from user-specified"
|
||||
" library '%s'", gsspath));
|
||||
gss_init(&list->libraries[list->nlibraries++], gsslib,
|
||||
3, dupprintf("Using GSSAPI from user-specified"
|
||||
" library '%s'", gsspath));
|
||||
|
||||
return list;
|
||||
}
|
||||
@ -103,12 +103,12 @@ void ssh_gss_cleanup(struct ssh_gss_liblist *list)
|
||||
* using it.
|
||||
*/
|
||||
for (i = 0; i < list->nlibraries; i++) {
|
||||
dlclose(list->libraries[i].handle);
|
||||
if (list->libraries[i].id == 3) {
|
||||
/* The 'custom' id involves a dynamically allocated message.
|
||||
* Note that we must cast away the 'const' to free it. */
|
||||
sfree((char *)list->libraries[i].gsslogmsg);
|
||||
}
|
||||
dlclose(list->libraries[i].handle);
|
||||
if (list->libraries[i].id == 3) {
|
||||
/* The 'custom' id involves a dynamically allocated message.
|
||||
* Note that we must cast away the 'const' to free it. */
|
||||
sfree((char *)list->libraries[i].gsslogmsg);
|
||||
}
|
||||
}
|
||||
sfree(list->libraries);
|
||||
sfree(list);
|
||||
|
@ -96,7 +96,7 @@ static FILE *debug_fp = NULL;
|
||||
void dputs(const char *buf)
|
||||
{
|
||||
if (!debug_fp) {
|
||||
debug_fp = fopen("debug.log", "w");
|
||||
debug_fp = fopen("debug.log", "w");
|
||||
}
|
||||
|
||||
if (write(1, buf, strlen(buf)) < 0) {} /* 'error check' to placate gcc */
|
||||
@ -123,25 +123,25 @@ char *get_username(void)
|
||||
setpwent();
|
||||
#endif
|
||||
if (user)
|
||||
p = getpwnam(user);
|
||||
p = getpwnam(user);
|
||||
else
|
||||
p = NULL;
|
||||
p = NULL;
|
||||
if (p && p->pw_uid == uid) {
|
||||
/*
|
||||
* The result of getlogin() really does correspond to
|
||||
* our uid. Fine.
|
||||
*/
|
||||
ret = user;
|
||||
/*
|
||||
* The result of getlogin() really does correspond to
|
||||
* our uid. Fine.
|
||||
*/
|
||||
ret = user;
|
||||
} else {
|
||||
/*
|
||||
* If that didn't work, for whatever reason, we'll do
|
||||
* the simpler version: look up our uid in the password
|
||||
* file and map it straight to a name.
|
||||
*/
|
||||
p = getpwuid(uid);
|
||||
if (!p)
|
||||
return NULL;
|
||||
ret = p->pw_name;
|
||||
/*
|
||||
* If that didn't work, for whatever reason, we'll do
|
||||
* the simpler version: look up our uid in the password
|
||||
* file and map it straight to a name.
|
||||
*/
|
||||
p = getpwuid(uid);
|
||||
if (!p)
|
||||
return NULL;
|
||||
ret = p->pw_name;
|
||||
}
|
||||
#if HAVE_ENDPWENT
|
||||
endpwent();
|
||||
@ -158,16 +158,16 @@ char *get_username(void)
|
||||
void pgp_fingerprints(void)
|
||||
{
|
||||
fputs("These are the fingerprints of the PuTTY PGP Master Keys. They can\n"
|
||||
"be used to establish a trust path from this executable to another\n"
|
||||
"one. See the manual for more information.\n"
|
||||
"(Note: these fingerprints have nothing to do with SSH!)\n"
|
||||
"\n"
|
||||
"PuTTY Master Key as of " PGP_MASTER_KEY_YEAR
|
||||
"be used to establish a trust path from this executable to another\n"
|
||||
"one. See the manual for more information.\n"
|
||||
"(Note: these fingerprints have nothing to do with SSH!)\n"
|
||||
"\n"
|
||||
"PuTTY Master Key as of " PGP_MASTER_KEY_YEAR
|
||||
" (" PGP_MASTER_KEY_DETAILS "):\n"
|
||||
" " PGP_MASTER_KEY_FP "\n\n"
|
||||
"Previous Master Key (" PGP_PREV_MASTER_KEY_YEAR
|
||||
" " PGP_MASTER_KEY_FP "\n\n"
|
||||
"Previous Master Key (" PGP_PREV_MASTER_KEY_YEAR
|
||||
", " PGP_PREV_MASTER_KEY_DETAILS "):\n"
|
||||
" " PGP_PREV_MASTER_KEY_FP "\n", stdout);
|
||||
" " PGP_PREV_MASTER_KEY_FP "\n", stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -240,15 +240,15 @@ bool no_nonblock(int fd) {
|
||||
FILE *f_open(const Filename *filename, char const *mode, bool is_private)
|
||||
{
|
||||
if (!is_private) {
|
||||
return fopen(filename->path, mode);
|
||||
return fopen(filename->path, mode);
|
||||
} else {
|
||||
int fd;
|
||||
assert(mode[0] == 'w'); /* is_private is meaningless for read,
|
||||
and tricky for append */
|
||||
fd = open(filename->path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
return fdopen(fd, mode);
|
||||
int fd;
|
||||
assert(mode[0] == 'w'); /* is_private is meaningless for read,
|
||||
and tricky for append */
|
||||
fd = open(filename->path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
return fdopen(fd, mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
790
unix/uxnet.c
790
unix/uxnet.c
File diff suppressed because it is too large
Load Diff
@ -23,16 +23,16 @@ static bool read_dev_urandom(char *buf, int len)
|
||||
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd < 0)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
ngot = 0;
|
||||
while (ngot < len) {
|
||||
ret = read(fd, buf+ngot, len-ngot);
|
||||
if (ret < 0) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
ngot += ret;
|
||||
ret = read(fd, buf+ngot, len-ngot);
|
||||
if (ret < 0) {
|
||||
close(fd);
|
||||
return false;
|
||||
}
|
||||
ngot += ret;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
@ -55,30 +55,30 @@ void noise_get_heavy(void (*func) (void *, int))
|
||||
bool got_dev_urandom = false;
|
||||
|
||||
if (read_dev_urandom(buf, 32)) {
|
||||
got_dev_urandom = true;
|
||||
func(buf, 32);
|
||||
got_dev_urandom = true;
|
||||
func(buf, 32);
|
||||
}
|
||||
|
||||
fp = popen("ps -axu 2>/dev/null", "r");
|
||||
if (fp) {
|
||||
while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
|
||||
func(buf, ret);
|
||||
pclose(fp);
|
||||
while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
|
||||
func(buf, ret);
|
||||
pclose(fp);
|
||||
} else if (!got_dev_urandom) {
|
||||
fprintf(stderr, "popen: %s\n"
|
||||
"Unable to access fallback entropy source\n", strerror(errno));
|
||||
exit(1);
|
||||
fprintf(stderr, "popen: %s\n"
|
||||
"Unable to access fallback entropy source\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fp = popen("ls -al /tmp 2>/dev/null", "r");
|
||||
if (fp) {
|
||||
while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
|
||||
func(buf, ret);
|
||||
pclose(fp);
|
||||
while ( (ret = fread(buf, 1, sizeof(buf), fp)) > 0)
|
||||
func(buf, ret);
|
||||
pclose(fp);
|
||||
} else if (!got_dev_urandom) {
|
||||
fprintf(stderr, "popen: %s\n"
|
||||
"Unable to access fallback entropy source\n", strerror(errno));
|
||||
exit(1);
|
||||
fprintf(stderr, "popen: %s\n"
|
||||
"Unable to access fallback entropy source\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
read_random_seed(func);
|
||||
@ -96,14 +96,14 @@ void noise_regular(void)
|
||||
struct rusage rusage;
|
||||
|
||||
if ((fd = open("/proc/meminfo", O_RDONLY)) >= 0) {
|
||||
while ( (ret = read(fd, buf, sizeof(buf))) > 0)
|
||||
random_add_noise(NOISE_SOURCE_MEMINFO, buf, ret);
|
||||
close(fd);
|
||||
while ( (ret = read(fd, buf, sizeof(buf))) > 0)
|
||||
random_add_noise(NOISE_SOURCE_MEMINFO, buf, ret);
|
||||
close(fd);
|
||||
}
|
||||
if ((fd = open("/proc/stat", O_RDONLY)) >= 0) {
|
||||
while ( (ret = read(fd, buf, sizeof(buf))) > 0)
|
||||
random_add_noise(NOISE_SOURCE_STAT, buf, ret);
|
||||
close(fd);
|
||||
while ( (ret = read(fd, buf, sizeof(buf))) > 0)
|
||||
random_add_noise(NOISE_SOURCE_STAT, buf, ret);
|
||||
close(fd);
|
||||
}
|
||||
getrusage(RUSAGE_SELF, &rusage);
|
||||
random_add_noise(NOISE_SOURCE_RUSAGE, &rusage, sizeof(rusage));
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define PUTTY_DO_GLOBALS /* actually _define_ globals */
|
||||
#define PUTTY_DO_GLOBALS /* actually _define_ globals */
|
||||
#include "putty.h"
|
||||
#include "ssh.h"
|
||||
#include "misc.h"
|
||||
@ -153,11 +153,11 @@ void chan_no_request_response(Channel *chan, bool success) {}
|
||||
* it's time to terminate.
|
||||
*/
|
||||
static void x11_log(Plug *p, int type, SockAddr *addr, int port,
|
||||
const char *error_msg, int error_code) {}
|
||||
const char *error_msg, int error_code) {}
|
||||
static void x11_receive(Plug *plug, int urgent, const char *data, size_t len) {}
|
||||
static void x11_sent(Plug *plug, size_t bufsize) {}
|
||||
static void x11_closing(Plug *plug, const char *error_msg, int error_code,
|
||||
bool calling_back)
|
||||
bool calling_back)
|
||||
{
|
||||
time_to_die = true;
|
||||
}
|
||||
@ -864,8 +864,8 @@ void run_agent(void)
|
||||
pollwrapper *pw = pollwrap_new();
|
||||
|
||||
while (!time_to_die) {
|
||||
int rwx;
|
||||
int ret;
|
||||
int rwx;
|
||||
int ret;
|
||||
unsigned long next;
|
||||
|
||||
pollwrap_clear(pw);
|
||||
@ -874,24 +874,24 @@ void run_agent(void)
|
||||
pollwrap_add_fd_rwx(pw, signalpipe[0], SELECT_R);
|
||||
}
|
||||
|
||||
/* Count the currently active fds. */
|
||||
i = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) i++;
|
||||
/* Count the currently active fds. */
|
||||
i = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) i++;
|
||||
|
||||
/* Expand the fdlist buffer if necessary. */
|
||||
/* Expand the fdlist buffer if necessary. */
|
||||
sgrowarray(fdlist, fdsize, i);
|
||||
|
||||
/*
|
||||
* Add all currently open fds to pw, and store them in fdlist
|
||||
* as well.
|
||||
*/
|
||||
int fdcount = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) {
|
||||
fdlist[fdcount++] = fd;
|
||||
/*
|
||||
* Add all currently open fds to pw, and store them in fdlist
|
||||
* as well.
|
||||
*/
|
||||
int fdcount = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) {
|
||||
fdlist[fdcount++] = fd;
|
||||
pollwrap_add_fd_rwx(pw, fd, rwx);
|
||||
}
|
||||
}
|
||||
|
||||
if (toplevel_callback_pending()) {
|
||||
ret = pollwrap_poll_instant(pw);
|
||||
@ -924,10 +924,10 @@ void run_agent(void)
|
||||
if (ret < 0 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (ret < 0) {
|
||||
perror("poll");
|
||||
exit(1);
|
||||
}
|
||||
if (ret < 0) {
|
||||
perror("poll");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (life == LIFE_TTY) {
|
||||
/*
|
||||
@ -943,21 +943,21 @@ void run_agent(void)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < fdcount; i++) {
|
||||
fd = fdlist[i];
|
||||
for (i = 0; i < fdcount; i++) {
|
||||
fd = fdlist[i];
|
||||
int rwx = pollwrap_get_fd_rwx(pw, fd);
|
||||
/*
|
||||
* We must process exceptional notifications before
|
||||
* ordinary readability ones, or we may go straight
|
||||
* past the urgent marker.
|
||||
*/
|
||||
if (rwx & SELECT_X)
|
||||
select_result(fd, SELECT_X);
|
||||
if (rwx & SELECT_R)
|
||||
select_result(fd, SELECT_R);
|
||||
if (rwx & SELECT_W)
|
||||
select_result(fd, SELECT_W);
|
||||
}
|
||||
if (rwx & SELECT_X)
|
||||
select_result(fd, SELECT_X);
|
||||
if (rwx & SELECT_R)
|
||||
select_result(fd, SELECT_R);
|
||||
if (rwx & SELECT_W)
|
||||
select_result(fd, SELECT_W);
|
||||
}
|
||||
|
||||
if (signalpipe[0] >= 0 &&
|
||||
pollwrap_check_fd_rwx(pw, signalpipe[0], SELECT_R)) {
|
||||
@ -1002,11 +1002,11 @@ int main(int argc, char **argv)
|
||||
* Process the command line.
|
||||
*/
|
||||
while (--argc > 0) {
|
||||
char *p = *++argv;
|
||||
if (*p == '-' && doing_opts) {
|
||||
char *p = *++argv;
|
||||
if (*p == '-' && doing_opts) {
|
||||
if (!strcmp(p, "-V") || !strcmp(p, "--version")) {
|
||||
version();
|
||||
} else if (!strcmp(p, "--help")) {
|
||||
} else if (!strcmp(p, "--help")) {
|
||||
usage();
|
||||
exit(0);
|
||||
} else if (!strcmp(p, "-v")) {
|
||||
|
414
unix/uxplink.c
414
unix/uxplink.c
@ -15,7 +15,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define PUTTY_DO_GLOBALS /* actually _define_ globals */
|
||||
#define PUTTY_DO_GLOBALS /* actually _define_ globals */
|
||||
#include "putty.h"
|
||||
#include "storage.h"
|
||||
#include "tree234.h"
|
||||
@ -46,9 +46,9 @@ Conf *conf;
|
||||
char *platform_default_s(const char *name)
|
||||
{
|
||||
if (!strcmp(name, "TermType"))
|
||||
return dupstr(getenv("TERM"));
|
||||
return dupstr(getenv("TERM"));
|
||||
if (!strcmp(name, "SerialLine"))
|
||||
return dupstr("/dev/ttyS0");
|
||||
return dupstr("/dev/ttyS0");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -70,14 +70,14 @@ FontSpec *platform_default_fontspec(const char *name)
|
||||
Filename *platform_default_filename(const char *name)
|
||||
{
|
||||
if (!strcmp(name, "LogFileName"))
|
||||
return filename_from_str("putty.log");
|
||||
return filename_from_str("putty.log");
|
||||
else
|
||||
return filename_from_str("");
|
||||
return filename_from_str("");
|
||||
}
|
||||
|
||||
char *x_get_default(const char *key)
|
||||
{
|
||||
return NULL; /* this is a stub */
|
||||
return NULL; /* this is a stub */
|
||||
}
|
||||
static void plink_echoedit_update(Seat *seat, bool echo, bool edit)
|
||||
{
|
||||
@ -89,29 +89,29 @@ static void plink_echoedit_update(Seat *seat, bool echo, bool edit)
|
||||
mode = orig_termios;
|
||||
|
||||
if (echo)
|
||||
mode.c_lflag |= ECHO;
|
||||
mode.c_lflag |= ECHO;
|
||||
else
|
||||
mode.c_lflag &= ~ECHO;
|
||||
mode.c_lflag &= ~ECHO;
|
||||
|
||||
if (edit) {
|
||||
mode.c_iflag |= ICRNL;
|
||||
mode.c_lflag |= ISIG | ICANON;
|
||||
mode.c_oflag |= OPOST;
|
||||
mode.c_iflag |= ICRNL;
|
||||
mode.c_lflag |= ISIG | ICANON;
|
||||
mode.c_oflag |= OPOST;
|
||||
} else {
|
||||
mode.c_iflag &= ~ICRNL;
|
||||
mode.c_lflag &= ~(ISIG | ICANON);
|
||||
mode.c_oflag &= ~OPOST;
|
||||
/* Solaris sets these to unhelpful values */
|
||||
mode.c_cc[VMIN] = 1;
|
||||
mode.c_cc[VTIME] = 0;
|
||||
/* FIXME: perhaps what we do with IXON/IXOFF should be an
|
||||
* argument to the echoedit_update() method, to allow
|
||||
* implementation of SSH-2 "xon-xoff" and Rlogin's
|
||||
* equivalent? */
|
||||
mode.c_iflag &= ~IXON;
|
||||
mode.c_iflag &= ~IXOFF;
|
||||
mode.c_iflag &= ~ICRNL;
|
||||
mode.c_lflag &= ~(ISIG | ICANON);
|
||||
mode.c_oflag &= ~OPOST;
|
||||
/* Solaris sets these to unhelpful values */
|
||||
mode.c_cc[VMIN] = 1;
|
||||
mode.c_cc[VTIME] = 0;
|
||||
/* FIXME: perhaps what we do with IXON/IXOFF should be an
|
||||
* argument to the echoedit_update() method, to allow
|
||||
* implementation of SSH-2 "xon-xoff" and Rlogin's
|
||||
* equivalent? */
|
||||
mode.c_iflag &= ~IXON;
|
||||
mode.c_iflag &= ~IXOFF;
|
||||
}
|
||||
/*
|
||||
/*
|
||||
* Mark parity errors and (more important) BREAK on input. This
|
||||
* is more complex than it need be because POSIX-2001 suggests
|
||||
* that escaping of valid 0xff in the input stream is dependent on
|
||||
@ -132,7 +132,7 @@ static char *get_ttychar(struct termios *t, int index)
|
||||
cc_t c = t->c_cc[index];
|
||||
#if defined(_POSIX_VDISABLE)
|
||||
if (c == _POSIX_VDISABLE)
|
||||
return dupstr("");
|
||||
return dupstr("");
|
||||
#endif
|
||||
return dupprintf("^<%d>", c);
|
||||
}
|
||||
@ -147,16 +147,16 @@ static char *plink_get_ttymode(Seat *seat, const char *mode)
|
||||
|
||||
#define GET_CHAR(ourname, uxname) \
|
||||
do { \
|
||||
if (strcmp(mode, ourname) == 0) \
|
||||
return get_ttychar(&orig_termios, uxname); \
|
||||
if (strcmp(mode, ourname) == 0) \
|
||||
return get_ttychar(&orig_termios, uxname); \
|
||||
} while(0)
|
||||
#define GET_BOOL(ourname, uxname, uxmemb, transform) \
|
||||
do { \
|
||||
if (strcmp(mode, ourname) == 0) { \
|
||||
bool b = (orig_termios.uxmemb & uxname) != 0; \
|
||||
transform; \
|
||||
return dupprintf("%d", b); \
|
||||
} \
|
||||
if (strcmp(mode, ourname) == 0) { \
|
||||
bool b = (orig_termios.uxmemb & uxname) != 0; \
|
||||
transform; \
|
||||
return dupprintf("%d", b); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
@ -312,7 +312,7 @@ static char *plink_get_ttymode(Seat *seat, const char *mode)
|
||||
void cleanup_termios(void)
|
||||
{
|
||||
if (local_tty)
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &orig_termios);
|
||||
}
|
||||
|
||||
bufchain stdout_data, stderr_data;
|
||||
@ -375,7 +375,7 @@ static int plink_get_userpass_input(Seat *seat, prompts_t *p, bufchain *input)
|
||||
int ret;
|
||||
ret = cmdline_get_passwd_input(p);
|
||||
if (ret == -1)
|
||||
ret = console_get_userpass_input(p);
|
||||
ret = console_get_userpass_input(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -411,59 +411,59 @@ static void from_tty(void *vbuf, unsigned len)
|
||||
|
||||
p = buf; end = buf + len;
|
||||
while (p < end) {
|
||||
switch (state) {
|
||||
case NORMAL:
|
||||
if (*p == '\xff') {
|
||||
p++;
|
||||
state = FF;
|
||||
} else {
|
||||
q = memchr(p, '\xff', end - p);
|
||||
if (q == NULL) q = end;
|
||||
switch (state) {
|
||||
case NORMAL:
|
||||
if (*p == '\xff') {
|
||||
p++;
|
||||
state = FF;
|
||||
} else {
|
||||
q = memchr(p, '\xff', end - p);
|
||||
if (q == NULL) q = end;
|
||||
backend_send(backend, p, q - p);
|
||||
p = q;
|
||||
}
|
||||
break;
|
||||
case FF:
|
||||
if (*p == '\xff') {
|
||||
p = q;
|
||||
}
|
||||
break;
|
||||
case FF:
|
||||
if (*p == '\xff') {
|
||||
backend_send(backend, p, 1);
|
||||
p++;
|
||||
state = NORMAL;
|
||||
} else if (*p == '\0') {
|
||||
p++;
|
||||
state = FF00;
|
||||
} else abort();
|
||||
break;
|
||||
case FF00:
|
||||
if (*p == '\0') {
|
||||
p++;
|
||||
state = NORMAL;
|
||||
} else if (*p == '\0') {
|
||||
p++;
|
||||
state = FF00;
|
||||
} else abort();
|
||||
break;
|
||||
case FF00:
|
||||
if (*p == '\0') {
|
||||
backend_special(backend, SS_BRK, 0);
|
||||
} else {
|
||||
/*
|
||||
* Pretend that PARMRK wasn't set. This involves
|
||||
* faking what INPCK and IGNPAR would have done if
|
||||
* we hadn't overridden them. Unfortunately, we
|
||||
* can't do this entirely correctly because INPCK
|
||||
* distinguishes between framing and parity
|
||||
* errors, but PARMRK format represents both in
|
||||
* the same way. We assume that parity errors are
|
||||
* more common than framing errors, and hence
|
||||
* treat all input errors as being subject to
|
||||
* INPCK.
|
||||
*/
|
||||
if (orig_termios.c_iflag & INPCK) {
|
||||
/* If IGNPAR is set, we throw away the character. */
|
||||
if (!(orig_termios.c_iflag & IGNPAR)) {
|
||||
/* PE/FE get passed on as NUL. */
|
||||
*p = 0;
|
||||
} else {
|
||||
/*
|
||||
* Pretend that PARMRK wasn't set. This involves
|
||||
* faking what INPCK and IGNPAR would have done if
|
||||
* we hadn't overridden them. Unfortunately, we
|
||||
* can't do this entirely correctly because INPCK
|
||||
* distinguishes between framing and parity
|
||||
* errors, but PARMRK format represents both in
|
||||
* the same way. We assume that parity errors are
|
||||
* more common than framing errors, and hence
|
||||
* treat all input errors as being subject to
|
||||
* INPCK.
|
||||
*/
|
||||
if (orig_termios.c_iflag & INPCK) {
|
||||
/* If IGNPAR is set, we throw away the character. */
|
||||
if (!(orig_termios.c_iflag & IGNPAR)) {
|
||||
/* PE/FE get passed on as NUL. */
|
||||
*p = 0;
|
||||
backend_send(backend, p, 1);
|
||||
}
|
||||
} else {
|
||||
/* INPCK not set. Assume we got a parity error. */
|
||||
}
|
||||
} else {
|
||||
/* INPCK not set. Assume we got a parity error. */
|
||||
backend_send(backend, p, 1);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
state = NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
p++;
|
||||
state = NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -472,7 +472,7 @@ int signalpipe[2];
|
||||
void sigwinch(int signum)
|
||||
{
|
||||
if (write(signalpipe[1], "x", 1) <= 0)
|
||||
/* not much we can do about it */;
|
||||
/* not much we can do about it */;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -611,22 +611,22 @@ int main(int argc, char **argv)
|
||||
default_port = conf_get_int(conf, CONF_port);
|
||||
errors = false;
|
||||
{
|
||||
/*
|
||||
* Override the default protocol if PLINK_PROTOCOL is set.
|
||||
*/
|
||||
char *p = getenv("PLINK_PROTOCOL");
|
||||
if (p) {
|
||||
/*
|
||||
* Override the default protocol if PLINK_PROTOCOL is set.
|
||||
*/
|
||||
char *p = getenv("PLINK_PROTOCOL");
|
||||
if (p) {
|
||||
const struct BackendVtable *vt = backend_vt_from_name(p);
|
||||
if (vt) {
|
||||
default_protocol = vt->protocol;
|
||||
default_port = vt->default_port;
|
||||
conf_set_int(conf, CONF_protocol, default_protocol);
|
||||
conf_set_int(conf, CONF_port, default_port);
|
||||
}
|
||||
}
|
||||
conf_set_int(conf, CONF_protocol, default_protocol);
|
||||
conf_set_int(conf, CONF_port, default_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (--argc) {
|
||||
char *p = *++argv;
|
||||
char *p = *++argv;
|
||||
int ret = cmdline_process_param(p, (argc > 1 ? argv[1] : NULL),
|
||||
1, conf);
|
||||
if (ret == -2) {
|
||||
@ -682,7 +682,7 @@ int main(int argc, char **argv)
|
||||
sanitise_stderr = FORCE_OFF;
|
||||
} else if (!strcmp(p, "-no-antispoof")) {
|
||||
console_antispoof_prompt = false;
|
||||
} else if (*p != '-') {
|
||||
} else if (*p != '-') {
|
||||
strbuf *cmdbuf = strbuf_new();
|
||||
|
||||
while (argc > 0) {
|
||||
@ -698,18 +698,18 @@ int main(int argc, char **argv)
|
||||
conf_set_bool(conf, CONF_nopty, true); /* command => no tty */
|
||||
|
||||
strbuf_free(cmdbuf);
|
||||
break; /* done with cmdline */
|
||||
break; /* done with cmdline */
|
||||
} else {
|
||||
fprintf(stderr, "plink: unknown option \"%s\"\n", p);
|
||||
errors = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (errors)
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
if (!cmdline_host_ok(conf)) {
|
||||
usage();
|
||||
usage();
|
||||
}
|
||||
|
||||
prepare_session(conf);
|
||||
@ -724,11 +724,11 @@ int main(int argc, char **argv)
|
||||
* one, as 'ssh' does.
|
||||
*/
|
||||
if (conf_get_str(conf, CONF_username)[0] == '\0') {
|
||||
char *user = get_username();
|
||||
if (user) {
|
||||
conf_set_str(conf, CONF_username, user);
|
||||
sfree(user);
|
||||
}
|
||||
char *user = get_username();
|
||||
if (user) {
|
||||
conf_set_str(conf, CONF_username, user);
|
||||
sfree(user);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -738,9 +738,9 @@ int main(int argc, char **argv)
|
||||
conf_set_bool(conf, CONF_ssh_subsys, true);
|
||||
|
||||
if (!*conf_get_str(conf, CONF_remote_cmd) &&
|
||||
!*conf_get_str(conf, CONF_remote_cmd2) &&
|
||||
!*conf_get_str(conf, CONF_ssh_nc_host))
|
||||
flags |= FLAG_INTERACTIVE;
|
||||
!*conf_get_str(conf, CONF_remote_cmd2) &&
|
||||
!*conf_get_str(conf, CONF_ssh_nc_host))
|
||||
flags |= FLAG_INTERACTIVE;
|
||||
|
||||
/*
|
||||
* Select protocol. This is farmed out into a table in a
|
||||
@ -748,9 +748,9 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
backvt = backend_vt_from_proto(conf_get_int(conf, CONF_protocol));
|
||||
if (!backvt) {
|
||||
fprintf(stderr,
|
||||
"Internal fault: Unsupported protocol found\n");
|
||||
return 1;
|
||||
fprintf(stderr,
|
||||
"Internal fault: Unsupported protocol found\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -763,8 +763,8 @@ int main(int argc, char **argv)
|
||||
* Set up the pipe we'll use to tell us about SIGWINCH.
|
||||
*/
|
||||
if (pipe(signalpipe) < 0) {
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
/* We don't want the signal handler to block if the pipe's full. */
|
||||
nonblock(signalpipe[0]);
|
||||
@ -778,8 +778,8 @@ int main(int argc, char **argv)
|
||||
* out the initial terminal size.
|
||||
*/
|
||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &size) >= 0) {
|
||||
conf_set_int(conf, CONF_width, size.ws_col);
|
||||
conf_set_int(conf, CONF_height, size.ws_row);
|
||||
conf_set_int(conf, CONF_width, size.ws_col);
|
||||
conf_set_int(conf, CONF_height, size.ws_row);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -818,10 +818,10 @@ int main(int argc, char **argv)
|
||||
* the "simple" flag.
|
||||
*/
|
||||
if (conf_get_int(conf, CONF_protocol) == PROT_SSH &&
|
||||
!conf_get_bool(conf, CONF_x11_forward) &&
|
||||
!conf_get_bool(conf, CONF_agentfwd) &&
|
||||
!conf_get_str_nthstrkey(conf, CONF_portfwd, 0))
|
||||
conf_set_bool(conf, CONF_ssh_simple, true);
|
||||
!conf_get_bool(conf, CONF_x11_forward) &&
|
||||
!conf_get_bool(conf, CONF_agentfwd) &&
|
||||
!conf_get_str_nthstrkey(conf, CONF_portfwd, 0))
|
||||
conf_set_bool(conf, CONF_ssh_simple, true);
|
||||
|
||||
if (just_test_share_exists) {
|
||||
if (!backvt->test_for_upstream) {
|
||||
@ -841,14 +841,14 @@ int main(int argc, char **argv)
|
||||
*/
|
||||
logctx = log_init(default_logpolicy, conf);
|
||||
{
|
||||
const char *error;
|
||||
char *realhost;
|
||||
/* nodelay is only useful if stdin is a terminal device */
|
||||
bool nodelay = conf_get_bool(conf, CONF_tcp_nodelay) && isatty(0);
|
||||
const char *error;
|
||||
char *realhost;
|
||||
/* nodelay is only useful if stdin is a terminal device */
|
||||
bool nodelay = conf_get_bool(conf, CONF_tcp_nodelay) && isatty(0);
|
||||
|
||||
/* This is a good place for a fuzzer to fork us. */
|
||||
/* This is a good place for a fuzzer to fork us. */
|
||||
#ifdef __AFL_HAVE_MANUAL_CONTROL
|
||||
__AFL_INIT();
|
||||
__AFL_INIT();
|
||||
#endif
|
||||
|
||||
error = backend_init(backvt, plink_seat, &backend, logctx, conf,
|
||||
@ -856,12 +856,12 @@ int main(int argc, char **argv)
|
||||
conf_get_int(conf, CONF_port),
|
||||
&realhost, nodelay,
|
||||
conf_get_bool(conf, CONF_tcp_keepalives));
|
||||
if (error) {
|
||||
fprintf(stderr, "Unable to open connection:\n%s\n", error);
|
||||
return 1;
|
||||
}
|
||||
if (error) {
|
||||
fprintf(stderr, "Unable to open connection:\n%s\n", error);
|
||||
return 1;
|
||||
}
|
||||
ldisc_create(conf, NULL, backend, plink_seat);
|
||||
sfree(realhost);
|
||||
sfree(realhost);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -878,50 +878,50 @@ int main(int argc, char **argv)
|
||||
pollwrapper *pw = pollwrap_new();
|
||||
|
||||
while (1) {
|
||||
int rwx;
|
||||
int ret;
|
||||
int rwx;
|
||||
int ret;
|
||||
unsigned long next;
|
||||
|
||||
pollwrap_clear(pw);
|
||||
|
||||
pollwrap_add_fd_rwx(pw, signalpipe[0], SELECT_R);
|
||||
pollwrap_add_fd_rwx(pw, signalpipe[0], SELECT_R);
|
||||
|
||||
if (!sending &&
|
||||
if (!sending &&
|
||||
backend_connected(backend) &&
|
||||
backend_sendok(backend) &&
|
||||
backend_sendbuffer(backend) < MAX_STDIN_BACKLOG) {
|
||||
/* If we're OK to send, then try to read from stdin. */
|
||||
/* If we're OK to send, then try to read from stdin. */
|
||||
pollwrap_add_fd_rwx(pw, STDIN_FILENO, SELECT_R);
|
||||
}
|
||||
}
|
||||
|
||||
if (bufchain_size(&stdout_data) > 0) {
|
||||
/* If we have data for stdout, try to write to stdout. */
|
||||
if (bufchain_size(&stdout_data) > 0) {
|
||||
/* If we have data for stdout, try to write to stdout. */
|
||||
pollwrap_add_fd_rwx(pw, STDOUT_FILENO, SELECT_W);
|
||||
}
|
||||
}
|
||||
|
||||
if (bufchain_size(&stderr_data) > 0) {
|
||||
/* If we have data for stderr, try to write to stderr. */
|
||||
if (bufchain_size(&stderr_data) > 0) {
|
||||
/* If we have data for stderr, try to write to stderr. */
|
||||
pollwrap_add_fd_rwx(pw, STDERR_FILENO, SELECT_W);
|
||||
}
|
||||
}
|
||||
|
||||
/* Count the currently active fds. */
|
||||
i = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) i++;
|
||||
/* Count the currently active fds. */
|
||||
i = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) i++;
|
||||
|
||||
/* Expand the fdlist buffer if necessary. */
|
||||
/* Expand the fdlist buffer if necessary. */
|
||||
sgrowarray(fdlist, fdsize, i);
|
||||
|
||||
/*
|
||||
* Add all currently open fds to pw, and store them in fdlist
|
||||
* as well.
|
||||
*/
|
||||
int fdcount = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) {
|
||||
fdlist[fdcount++] = fd;
|
||||
/*
|
||||
* Add all currently open fds to pw, and store them in fdlist
|
||||
* as well.
|
||||
*/
|
||||
int fdcount = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) {
|
||||
fdlist[fdcount++] = fd;
|
||||
pollwrap_add_fd_rwx(pw, fd, rwx);
|
||||
}
|
||||
}
|
||||
|
||||
if (toplevel_callback_pending()) {
|
||||
ret = pollwrap_poll_instant(pw);
|
||||
@ -930,12 +930,12 @@ int main(int argc, char **argv)
|
||||
unsigned long then;
|
||||
long ticks;
|
||||
|
||||
then = now;
|
||||
now = GETTICKCOUNT();
|
||||
if (now - then > next - then)
|
||||
ticks = 0;
|
||||
else
|
||||
ticks = next - now;
|
||||
then = now;
|
||||
now = GETTICKCOUNT();
|
||||
if (now - then > next - then)
|
||||
ticks = 0;
|
||||
else
|
||||
ticks = next - now;
|
||||
|
||||
bool overflow = false;
|
||||
if (ticks > INT_MAX) {
|
||||
@ -956,79 +956,79 @@ int main(int argc, char **argv)
|
||||
if (ret < 0 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (ret < 0) {
|
||||
perror("poll");
|
||||
exit(1);
|
||||
}
|
||||
if (ret < 0) {
|
||||
perror("poll");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < fdcount; i++) {
|
||||
fd = fdlist[i];
|
||||
for (i = 0; i < fdcount; i++) {
|
||||
fd = fdlist[i];
|
||||
int rwx = pollwrap_get_fd_rwx(pw, fd);
|
||||
/*
|
||||
* We must process exceptional notifications before
|
||||
* ordinary readability ones, or we may go straight
|
||||
* past the urgent marker.
|
||||
*/
|
||||
if (rwx & SELECT_X)
|
||||
select_result(fd, SELECT_X);
|
||||
if (rwx & SELECT_R)
|
||||
select_result(fd, SELECT_R);
|
||||
if (rwx & SELECT_W)
|
||||
select_result(fd, SELECT_W);
|
||||
}
|
||||
if (rwx & SELECT_X)
|
||||
select_result(fd, SELECT_X);
|
||||
if (rwx & SELECT_R)
|
||||
select_result(fd, SELECT_R);
|
||||
if (rwx & SELECT_W)
|
||||
select_result(fd, SELECT_W);
|
||||
}
|
||||
|
||||
if (pollwrap_check_fd_rwx(pw, signalpipe[0], SELECT_R)) {
|
||||
char c[1];
|
||||
struct winsize size;
|
||||
if (read(signalpipe[0], c, 1) <= 0)
|
||||
/* ignore error */;
|
||||
/* ignore its value; it'll be `x' */
|
||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, (void *)&size) >= 0)
|
||||
if (pollwrap_check_fd_rwx(pw, signalpipe[0], SELECT_R)) {
|
||||
char c[1];
|
||||
struct winsize size;
|
||||
if (read(signalpipe[0], c, 1) <= 0)
|
||||
/* ignore error */;
|
||||
/* ignore its value; it'll be `x' */
|
||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, (void *)&size) >= 0)
|
||||
backend_size(backend, size.ws_col, size.ws_row);
|
||||
}
|
||||
}
|
||||
|
||||
if (pollwrap_check_fd_rwx(pw, STDIN_FILENO, SELECT_R)) {
|
||||
char buf[4096];
|
||||
int ret;
|
||||
if (pollwrap_check_fd_rwx(pw, STDIN_FILENO, SELECT_R)) {
|
||||
char buf[4096];
|
||||
int ret;
|
||||
|
||||
if (backend_connected(backend)) {
|
||||
ret = read(STDIN_FILENO, buf, sizeof(buf));
|
||||
ret = read(STDIN_FILENO, buf, sizeof(buf));
|
||||
noise_ultralight(NOISE_SOURCE_IOLEN, ret);
|
||||
if (ret < 0) {
|
||||
perror("stdin: read");
|
||||
exit(1);
|
||||
} else if (ret == 0) {
|
||||
if (ret < 0) {
|
||||
perror("stdin: read");
|
||||
exit(1);
|
||||
} else if (ret == 0) {
|
||||
backend_special(backend, SS_EOF, 0);
|
||||
sending = false; /* send nothing further after this */
|
||||
} else {
|
||||
if (local_tty)
|
||||
from_tty(buf, ret);
|
||||
else
|
||||
sending = false; /* send nothing further after this */
|
||||
} else {
|
||||
if (local_tty)
|
||||
from_tty(buf, ret);
|
||||
else
|
||||
backend_send(backend, buf, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pollwrap_check_fd_rwx(pw, STDOUT_FILENO, SELECT_W)) {
|
||||
if (pollwrap_check_fd_rwx(pw, STDOUT_FILENO, SELECT_W)) {
|
||||
backend_unthrottle(backend, try_output(false));
|
||||
}
|
||||
}
|
||||
|
||||
if (pollwrap_check_fd_rwx(pw, STDERR_FILENO, SELECT_W)) {
|
||||
if (pollwrap_check_fd_rwx(pw, STDERR_FILENO, SELECT_W)) {
|
||||
backend_unthrottle(backend, try_output(true));
|
||||
}
|
||||
}
|
||||
|
||||
run_toplevel_callbacks();
|
||||
|
||||
if (!backend_connected(backend) &&
|
||||
bufchain_size(&stdout_data) == 0 &&
|
||||
bufchain_size(&stderr_data) == 0)
|
||||
break; /* we closed the connection */
|
||||
bufchain_size(&stdout_data) == 0 &&
|
||||
bufchain_size(&stderr_data) == 0)
|
||||
break; /* we closed the connection */
|
||||
}
|
||||
exitcode = backend_exitcode(backend);
|
||||
if (exitcode < 0) {
|
||||
fprintf(stderr, "Remote process exit code unavailable\n");
|
||||
exitcode = 1; /* this is an error condition */
|
||||
fprintf(stderr, "Remote process exit code unavailable\n");
|
||||
exitcode = 1; /* this is an error condition */
|
||||
}
|
||||
cleanup_exit(exitcode);
|
||||
return exitcode; /* shouldn't happen, but placates gcc */
|
||||
return exitcode; /* shouldn't happen, but placates gcc */
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ printer_job *printer_start_job(char *printer)
|
||||
*/
|
||||
ret->fp = popen(printer, "w");
|
||||
if (!ret->fp) {
|
||||
sfree(ret);
|
||||
ret = NULL;
|
||||
sfree(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -28,16 +28,16 @@ printer_job *printer_start_job(char *printer)
|
||||
void printer_job_data(printer_job *pj, const void *data, size_t len)
|
||||
{
|
||||
if (!pj)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (fwrite(data, 1, len, pj->fp) < len)
|
||||
/* ignore */;
|
||||
/* ignore */;
|
||||
}
|
||||
|
||||
void printer_finish_job(printer_job *pj)
|
||||
{
|
||||
if (!pj)
|
||||
return;
|
||||
return;
|
||||
|
||||
pclose(pj->fp);
|
||||
sfree(pj);
|
||||
|
@ -26,10 +26,10 @@ Socket *platform_new_connection(SockAddr *addr, const char *hostname,
|
||||
|
||||
proxytype = conf_get_int(conf, CONF_proxy_type);
|
||||
if (proxytype != PROXY_CMD && proxytype != PROXY_FUZZ)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
if (proxytype == PROXY_CMD) {
|
||||
cmd = format_telnet_command(addr, port, conf);
|
||||
cmd = format_telnet_command(addr, port, conf);
|
||||
|
||||
{
|
||||
char *logmsg = dupprintf("Starting local proxy command: %s", cmd);
|
||||
@ -37,65 +37,65 @@ Socket *platform_new_connection(SockAddr *addr, const char *hostname,
|
||||
sfree(logmsg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the pipes to the proxy command, and spawn the proxy
|
||||
* command process.
|
||||
*/
|
||||
if (pipe(to_cmd_pipe) < 0 ||
|
||||
pipe(from_cmd_pipe) < 0 ||
|
||||
/*
|
||||
* Create the pipes to the proxy command, and spawn the proxy
|
||||
* command process.
|
||||
*/
|
||||
if (pipe(to_cmd_pipe) < 0 ||
|
||||
pipe(from_cmd_pipe) < 0 ||
|
||||
pipe(cmd_err_pipe) < 0) {
|
||||
sfree(cmd);
|
||||
sfree(cmd);
|
||||
return new_error_socket_fmt(plug, "pipe: %s", strerror(errno));
|
||||
}
|
||||
cloexec(to_cmd_pipe[1]);
|
||||
cloexec(from_cmd_pipe[0]);
|
||||
}
|
||||
cloexec(to_cmd_pipe[1]);
|
||||
cloexec(from_cmd_pipe[0]);
|
||||
cloexec(cmd_err_pipe[0]);
|
||||
|
||||
pid = fork();
|
||||
pid = fork();
|
||||
if (pid == 0) {
|
||||
close(0);
|
||||
close(1);
|
||||
dup2(to_cmd_pipe[0], 0);
|
||||
dup2(from_cmd_pipe[1], 1);
|
||||
close(to_cmd_pipe[0]);
|
||||
close(from_cmd_pipe[1]);
|
||||
close(0);
|
||||
close(1);
|
||||
dup2(to_cmd_pipe[0], 0);
|
||||
dup2(from_cmd_pipe[1], 1);
|
||||
close(to_cmd_pipe[0]);
|
||||
close(from_cmd_pipe[1]);
|
||||
dup2(cmd_err_pipe[1], 2);
|
||||
noncloexec(0);
|
||||
noncloexec(1);
|
||||
execl("/bin/sh", "sh", "-c", cmd, (void *)NULL);
|
||||
_exit(255);
|
||||
}
|
||||
noncloexec(0);
|
||||
noncloexec(1);
|
||||
execl("/bin/sh", "sh", "-c", cmd, (void *)NULL);
|
||||
_exit(255);
|
||||
}
|
||||
|
||||
sfree(cmd);
|
||||
sfree(cmd);
|
||||
|
||||
if (pid < 0)
|
||||
if (pid < 0)
|
||||
return new_error_socket_fmt(plug, "fork: %s", strerror(errno));
|
||||
|
||||
close(to_cmd_pipe[0]);
|
||||
close(from_cmd_pipe[1]);
|
||||
close(to_cmd_pipe[0]);
|
||||
close(from_cmd_pipe[1]);
|
||||
close(cmd_err_pipe[1]);
|
||||
|
||||
outfd = to_cmd_pipe[1];
|
||||
infd = from_cmd_pipe[0];
|
||||
inerrfd = cmd_err_pipe[0];
|
||||
outfd = to_cmd_pipe[1];
|
||||
infd = from_cmd_pipe[0];
|
||||
inerrfd = cmd_err_pipe[0];
|
||||
} else {
|
||||
cmd = format_telnet_command(addr, port, conf);
|
||||
outfd = open("/dev/null", O_WRONLY);
|
||||
if (outfd == -1) {
|
||||
sfree(cmd);
|
||||
return new_error_socket_fmt(
|
||||
cmd = format_telnet_command(addr, port, conf);
|
||||
outfd = open("/dev/null", O_WRONLY);
|
||||
if (outfd == -1) {
|
||||
sfree(cmd);
|
||||
return new_error_socket_fmt(
|
||||
plug, "/dev/null: %s", strerror(errno));
|
||||
}
|
||||
infd = open(cmd, O_RDONLY);
|
||||
if (infd == -1) {
|
||||
}
|
||||
infd = open(cmd, O_RDONLY);
|
||||
if (infd == -1) {
|
||||
Socket *toret = new_error_socket_fmt(
|
||||
plug, "%s: %s", cmd, strerror(errno));
|
||||
sfree(cmd);
|
||||
sfree(cmd);
|
||||
close(outfd);
|
||||
return toret;
|
||||
}
|
||||
sfree(cmd);
|
||||
inerrfd = -1;
|
||||
return toret;
|
||||
}
|
||||
sfree(cmd);
|
||||
inerrfd = -1;
|
||||
}
|
||||
|
||||
/* We are responsible for this and don't need it any more */
|
||||
|
418
unix/uxpty.c
418
unix/uxpty.c
@ -106,9 +106,9 @@ static int ptyfd_compare(void *av, void *bv)
|
||||
PtyFd *b = (PtyFd *)bv;
|
||||
|
||||
if (a->fd < b->fd)
|
||||
return -1;
|
||||
return -1;
|
||||
else if (a->fd > b->fd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -118,9 +118,9 @@ static int ptyfd_find(void *av, void *bv)
|
||||
PtyFd *b = (PtyFd *)bv;
|
||||
|
||||
if (a < b->fd)
|
||||
return -1;
|
||||
return -1;
|
||||
else if (a > b->fd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -138,9 +138,9 @@ static int pty_compare_by_pid(void *av, void *bv)
|
||||
Pty *b = (Pty *)bv;
|
||||
|
||||
if (a->child_pid < b->child_pid)
|
||||
return -1;
|
||||
return -1;
|
||||
else if (a->child_pid > b->child_pid)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -150,9 +150,9 @@ static int pty_find_by_pid(void *av, void *bv)
|
||||
Pty *b = (Pty *)bv;
|
||||
|
||||
if (a < b->child_pid)
|
||||
return -1;
|
||||
return -1;
|
||||
else if (a > b->child_pid)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -163,12 +163,12 @@ static tree234 *ptys_by_pid = NULL;
|
||||
* allocated a pty structure, which we must then return from
|
||||
* pty_init() rather than allocating a new one. Here we store that
|
||||
* structure between allocation and use.
|
||||
*
|
||||
*
|
||||
* Note that although most of this module is entirely capable of
|
||||
* handling multiple ptys in a single process, pty_pre_init() is
|
||||
* fundamentally _dependent_ on there being at most one pty per
|
||||
* process, so the normal static-data constraints don't apply.
|
||||
*
|
||||
*
|
||||
* Likewise, since utmp is only used via pty_pre_init, it too must
|
||||
* be single-instance, so we can declare utmp-related variables
|
||||
* here.
|
||||
@ -240,9 +240,9 @@ static void setup_utmp(char *ttyname, char *location)
|
||||
strncpy(lastlog_entry.ll_host, location, lenof(lastlog_entry.ll_host));
|
||||
time(&lastlog_entry.ll_time);
|
||||
if ((lastlog = fopen(LASTLOG_FILE, "r+")) != NULL) {
|
||||
fseek(lastlog, sizeof(lastlog_entry) * getuid(), SEEK_SET);
|
||||
fwrite(&lastlog_entry, 1, sizeof(lastlog_entry), lastlog);
|
||||
fclose(lastlog);
|
||||
fseek(lastlog, sizeof(lastlog_entry) * getuid(), SEEK_SET);
|
||||
fwrite(&lastlog_entry, 1, sizeof(lastlog_entry), lastlog);
|
||||
fclose(lastlog);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -255,7 +255,7 @@ static void cleanup_utmp(void)
|
||||
struct timeval tv;
|
||||
|
||||
if (!pty_stamped_utmp)
|
||||
return;
|
||||
return;
|
||||
|
||||
utmp_entry.ut_type = DEAD_PROCESS;
|
||||
memset(utmp_entry.ut_user, 0, lenof(utmp_entry.ut_user));
|
||||
@ -280,7 +280,7 @@ static void cleanup_utmp(void)
|
||||
static void sigchld_handler(int signum)
|
||||
{
|
||||
if (write(pty_signal_pipe[1], "x", 1) <= 0)
|
||||
/* not much we can do about it */;
|
||||
/* not much we can do about it */;
|
||||
}
|
||||
|
||||
static void pty_setup_sigchld_handler(void)
|
||||
@ -304,7 +304,7 @@ static void fatal_sig_handler(int signum)
|
||||
static int pty_open_slave(Pty *pty)
|
||||
{
|
||||
if (pty->slave_fd < 0) {
|
||||
pty->slave_fd = open(pty->name, O_RDWR);
|
||||
pty->slave_fd = open(pty->name, O_RDWR);
|
||||
cloexec(pty->slave_fd);
|
||||
}
|
||||
|
||||
@ -321,34 +321,34 @@ static void pty_open_master(Pty *pty)
|
||||
struct group *gp;
|
||||
|
||||
for (p1 = chars1; *p1; p1++)
|
||||
for (p2 = chars2; *p2; p2++) {
|
||||
sprintf(master_name, "/dev/pty%c%c", *p1, *p2);
|
||||
pty->master_fd = open(master_name, O_RDWR);
|
||||
if (pty->master_fd >= 0) {
|
||||
if (geteuid() == 0 ||
|
||||
access(master_name, R_OK | W_OK) == 0) {
|
||||
/*
|
||||
* We must also check at this point that we are
|
||||
* able to open the slave side of the pty. We
|
||||
* wouldn't want to allocate the wrong master,
|
||||
* get all the way down to forking, and _then_
|
||||
* find we're unable to open the slave.
|
||||
*/
|
||||
strcpy(pty->name, master_name);
|
||||
pty->name[5] = 't'; /* /dev/ptyXX -> /dev/ttyXX */
|
||||
for (p2 = chars2; *p2; p2++) {
|
||||
sprintf(master_name, "/dev/pty%c%c", *p1, *p2);
|
||||
pty->master_fd = open(master_name, O_RDWR);
|
||||
if (pty->master_fd >= 0) {
|
||||
if (geteuid() == 0 ||
|
||||
access(master_name, R_OK | W_OK) == 0) {
|
||||
/*
|
||||
* We must also check at this point that we are
|
||||
* able to open the slave side of the pty. We
|
||||
* wouldn't want to allocate the wrong master,
|
||||
* get all the way down to forking, and _then_
|
||||
* find we're unable to open the slave.
|
||||
*/
|
||||
strcpy(pty->name, master_name);
|
||||
pty->name[5] = 't'; /* /dev/ptyXX -> /dev/ttyXX */
|
||||
|
||||
cloexec(pty->master_fd);
|
||||
|
||||
if (pty_open_slave(pty) >= 0 &&
|
||||
access(pty->name, R_OK | W_OK) == 0)
|
||||
goto got_one;
|
||||
if (pty->slave_fd > 0)
|
||||
close(pty->slave_fd);
|
||||
pty->slave_fd = -1;
|
||||
}
|
||||
close(pty->master_fd);
|
||||
}
|
||||
}
|
||||
if (pty_open_slave(pty) >= 0 &&
|
||||
access(pty->name, R_OK | W_OK) == 0)
|
||||
goto got_one;
|
||||
if (pty->slave_fd > 0)
|
||||
close(pty->slave_fd);
|
||||
pty->slave_fd = -1;
|
||||
}
|
||||
close(pty->master_fd);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we get here, we couldn't get a tty at all. */
|
||||
fprintf(stderr, "pterm: unable to open a pseudo-terminal device\n");
|
||||
@ -383,26 +383,26 @@ static void pty_open_master(Pty *pty)
|
||||
#endif
|
||||
|
||||
if (pty->master_fd < 0) {
|
||||
perror("posix_openpt");
|
||||
exit(1);
|
||||
perror("posix_openpt");
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
pty->master_fd = open("/dev/ptmx", flags);
|
||||
|
||||
if (pty->master_fd < 0) {
|
||||
perror("/dev/ptmx: open");
|
||||
exit(1);
|
||||
perror("/dev/ptmx: open");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (grantpt(pty->master_fd) < 0) {
|
||||
perror("grantpt");
|
||||
exit(1);
|
||||
perror("grantpt");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if (unlockpt(pty->master_fd) < 0) {
|
||||
perror("unlockpt");
|
||||
exit(1);
|
||||
perror("unlockpt");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
cloexec(pty->master_fd);
|
||||
@ -460,7 +460,7 @@ void pty_pre_init(void)
|
||||
#endif
|
||||
|
||||
if (geteuid() != getuid() || getegid() != getgid()) {
|
||||
pty_open_master(pty);
|
||||
pty_open_master(pty);
|
||||
|
||||
#ifndef OMIT_UTMP
|
||||
/*
|
||||
@ -489,7 +489,7 @@ void pty_pre_init(void)
|
||||
|
||||
dlen = 0;
|
||||
while (1) {
|
||||
|
||||
|
||||
ret = read(pipefd[0], buffer, lenof(buffer));
|
||||
if (ret <= 0) {
|
||||
cleanup_utmp();
|
||||
@ -565,23 +565,23 @@ void pty_pre_init(void)
|
||||
/* Drop privs. */
|
||||
{
|
||||
#ifndef HAVE_NO_SETRESUID
|
||||
int gid = getgid(), uid = getuid();
|
||||
int setresgid(gid_t, gid_t, gid_t);
|
||||
int setresuid(uid_t, uid_t, uid_t);
|
||||
if (setresgid(gid, gid, gid) < 0) {
|
||||
int gid = getgid(), uid = getuid();
|
||||
int setresgid(gid_t, gid_t, gid_t);
|
||||
int setresuid(uid_t, uid_t, uid_t);
|
||||
if (setresgid(gid, gid, gid) < 0) {
|
||||
perror("setresgid");
|
||||
exit(1);
|
||||
}
|
||||
if (setresuid(uid, uid, uid) < 0) {
|
||||
if (setresuid(uid, uid, uid) < 0) {
|
||||
perror("setresuid");
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
if (setgid(getgid()) < 0) {
|
||||
if (setgid(getgid()) < 0) {
|
||||
perror("setgid");
|
||||
exit(1);
|
||||
}
|
||||
if (setuid(getuid()) < 0) {
|
||||
if (setuid(getuid()) < 0) {
|
||||
perror("setuid");
|
||||
exit(1);
|
||||
}
|
||||
@ -601,13 +601,13 @@ static void pty_real_select_result(Pty *pty, int fd, int event, int status)
|
||||
bool finished = false;
|
||||
|
||||
if (event < 0) {
|
||||
/*
|
||||
* We've been called because our child process did
|
||||
* something. `status' tells us what.
|
||||
*/
|
||||
if ((WIFEXITED(status) || WIFSIGNALED(status))) {
|
||||
/*
|
||||
* The primary child process died.
|
||||
/*
|
||||
* We've been called because our child process did
|
||||
* something. `status' tells us what.
|
||||
*/
|
||||
if ((WIFEXITED(status) || WIFSIGNALED(status))) {
|
||||
/*
|
||||
* The primary child process died.
|
||||
*/
|
||||
pty->child_dead = true;
|
||||
del234(ptys_by_pid, pty);
|
||||
@ -615,24 +615,24 @@ static void pty_real_select_result(Pty *pty, int fd, int event, int status)
|
||||
|
||||
/*
|
||||
* If this is an ordinary pty session, this is also the
|
||||
* moment to terminate the whole backend.
|
||||
* moment to terminate the whole backend.
|
||||
*
|
||||
* We _could_ instead keep the terminal open for remaining
|
||||
* subprocesses to output to, but conventional wisdom
|
||||
* seems to feel that that's the Wrong Thing for an
|
||||
* xterm-alike, so we bail out now (though we don't
|
||||
* necessarily _close_ the window, depending on the state
|
||||
* of Close On Exit). This would be easy enough to change
|
||||
* or make configurable if necessary.
|
||||
*/
|
||||
* subprocesses to output to, but conventional wisdom
|
||||
* seems to feel that that's the Wrong Thing for an
|
||||
* xterm-alike, so we bail out now (though we don't
|
||||
* necessarily _close_ the window, depending on the state
|
||||
* of Close On Exit). This would be easy enough to change
|
||||
* or make configurable if necessary.
|
||||
*/
|
||||
if (pty->master_fd >= 0)
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (event == SELECT_R) {
|
||||
if (event == SELECT_R) {
|
||||
bool is_stdout = (fd == pty->master_o);
|
||||
|
||||
ret = read(fd, buf, sizeof(buf));
|
||||
ret = read(fd, buf, sizeof(buf));
|
||||
|
||||
/*
|
||||
* Treat EIO on a pty master as equivalent to EOF (because
|
||||
@ -643,7 +643,7 @@ static void pty_real_select_result(Pty *pty, int fd, int event, int status)
|
||||
if (fd == pty->master_fd && ret < 0 && errno == EIO)
|
||||
ret = 0;
|
||||
|
||||
if (ret == 0) {
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* EOF on this input fd, so to begin with, we may as
|
||||
* well close it, and remove all references to it in
|
||||
@ -673,13 +673,13 @@ static void pty_real_select_result(Pty *pty, int fd, int event, int status)
|
||||
if (!pty->child_dead)
|
||||
pty->exit_code = 0;
|
||||
}
|
||||
} else if (ret < 0) {
|
||||
perror("read pty master");
|
||||
exit(1);
|
||||
} else if (ret > 0) {
|
||||
seat_output(pty->seat, !is_stdout, buf, ret);
|
||||
}
|
||||
} else if (event == SELECT_W) {
|
||||
} else if (ret < 0) {
|
||||
perror("read pty master");
|
||||
exit(1);
|
||||
} else if (ret > 0) {
|
||||
seat_output(pty->seat, !is_stdout, buf, ret);
|
||||
}
|
||||
} else if (event == SELECT_W) {
|
||||
/*
|
||||
* Attempt to send data down the pty.
|
||||
*/
|
||||
@ -688,7 +688,7 @@ static void pty_real_select_result(Pty *pty, int fd, int event, int status)
|
||||
}
|
||||
|
||||
if (finished && !pty->finished) {
|
||||
int close_on_exit;
|
||||
int close_on_exit;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
@ -697,29 +697,29 @@ static void pty_real_select_result(Pty *pty, int fd, int event, int status)
|
||||
|
||||
pty_close(pty);
|
||||
|
||||
pty->finished = true;
|
||||
pty->finished = true;
|
||||
|
||||
/*
|
||||
* This is a slight layering-violation sort of hack: only
|
||||
* if we're not closing on exit (COE is set to Never, or to
|
||||
* Only On Clean and it wasn't a clean exit) do we output a
|
||||
* `terminated' message.
|
||||
*/
|
||||
close_on_exit = conf_get_int(pty->conf, CONF_close_on_exit);
|
||||
if (close_on_exit == FORCE_OFF ||
|
||||
(close_on_exit == AUTO && pty->exit_code != 0)) {
|
||||
char *message;
|
||||
/*
|
||||
* This is a slight layering-violation sort of hack: only
|
||||
* if we're not closing on exit (COE is set to Never, or to
|
||||
* Only On Clean and it wasn't a clean exit) do we output a
|
||||
* `terminated' message.
|
||||
*/
|
||||
close_on_exit = conf_get_int(pty->conf, CONF_close_on_exit);
|
||||
if (close_on_exit == FORCE_OFF ||
|
||||
(close_on_exit == AUTO && pty->exit_code != 0)) {
|
||||
char *message;
|
||||
if (WIFEXITED(pty->exit_code)) {
|
||||
message = dupprintf(
|
||||
message = dupprintf(
|
||||
"\r\n[pterm: process terminated with exit code %d]\r\n",
|
||||
WEXITSTATUS(pty->exit_code));
|
||||
} else if (WIFSIGNALED(pty->exit_code)) {
|
||||
#ifdef HAVE_NO_STRSIGNAL
|
||||
message = dupprintf(
|
||||
message = dupprintf(
|
||||
"\r\n[pterm: process terminated on signal %d]\r\n",
|
||||
WTERMSIG(pty->exit_code));
|
||||
#else
|
||||
message = dupprintf(
|
||||
message = dupprintf(
|
||||
"\r\n[pterm: process terminated on signal %d (%s)]\r\n",
|
||||
WTERMSIG(pty->exit_code),
|
||||
strsignal(WTERMSIG(pty->exit_code)));
|
||||
@ -729,12 +729,12 @@ static void pty_real_select_result(Pty *pty, int fd, int event, int status)
|
||||
* is better than no message at all */
|
||||
message = dupprintf("\r\n[pterm: process terminated]\r\n");
|
||||
}
|
||||
seat_stdout_pl(pty->seat, ptrlen_from_asciz(message));
|
||||
seat_stdout_pl(pty->seat, ptrlen_from_asciz(message));
|
||||
sfree(message);
|
||||
}
|
||||
}
|
||||
|
||||
seat_eof(pty->seat);
|
||||
seat_notify_remote_exit(pty->seat);
|
||||
seat_notify_remote_exit(pty->seat);
|
||||
}
|
||||
}
|
||||
|
||||
@ -757,18 +757,18 @@ static void pty_try_wait(void)
|
||||
void pty_select_result(int fd, int event)
|
||||
{
|
||||
if (fd == pty_signal_pipe[0]) {
|
||||
char c[1];
|
||||
char c[1];
|
||||
|
||||
if (read(pty_signal_pipe[0], c, 1) <= 0)
|
||||
/* ignore error */;
|
||||
/* ignore its value; it'll be `x' */
|
||||
if (read(pty_signal_pipe[0], c, 1) <= 0)
|
||||
/* ignore error */;
|
||||
/* ignore its value; it'll be `x' */
|
||||
|
||||
pty_try_wait();
|
||||
} else {
|
||||
PtyFd *ptyfd = find234(ptyfds, &fd, ptyfd_find);
|
||||
|
||||
if (ptyfd)
|
||||
pty_real_select_result(ptyfd->pty, fd, event, 0);
|
||||
if (ptyfd)
|
||||
pty_real_select_result(ptyfd->pty, fd, event, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -862,7 +862,7 @@ Backend *pty_backend_create(
|
||||
{
|
||||
int slavefd;
|
||||
pid_t pid, pgrp;
|
||||
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
||||
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
||||
bool got_windowid;
|
||||
long windowid;
|
||||
#endif
|
||||
@ -873,13 +873,13 @@ Backend *pty_backend_create(
|
||||
seat_set_trust_status(seat, false);
|
||||
|
||||
if (single_pty) {
|
||||
pty = single_pty;
|
||||
pty = single_pty;
|
||||
assert(pty->conf == NULL);
|
||||
} else {
|
||||
pty = new_pty_struct();
|
||||
pty->master_fd = pty->slave_fd = -1;
|
||||
pty = new_pty_struct();
|
||||
pty->master_fd = pty->slave_fd = -1;
|
||||
#ifndef OMIT_UTMP
|
||||
pty_stamped_utmp = false;
|
||||
pty_stamped_utmp = false;
|
||||
#endif
|
||||
}
|
||||
for (i = 0; i < 6; i++)
|
||||
@ -968,7 +968,7 @@ Backend *pty_backend_create(
|
||||
add234(ptyfds, &pty->fds[0]);
|
||||
}
|
||||
|
||||
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
||||
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
||||
got_windowid = seat_get_windowid(pty->seat, &windowid);
|
||||
#endif
|
||||
|
||||
@ -983,16 +983,16 @@ Backend *pty_backend_create(
|
||||
*/
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
struct termios attrs;
|
||||
|
||||
/*
|
||||
* We are the child.
|
||||
*/
|
||||
/*
|
||||
* We are the child.
|
||||
*/
|
||||
|
||||
if (pty_osx_envrestore_prefix) {
|
||||
int plen = strlen(pty_osx_envrestore_prefix);
|
||||
@ -1082,34 +1082,34 @@ Backend *pty_backend_create(
|
||||
}
|
||||
}
|
||||
|
||||
setpgid(pgrp, pgrp);
|
||||
setpgid(pgrp, pgrp);
|
||||
if (!pipes_instead) {
|
||||
int ptyfd = open(pty->name, O_WRONLY, 0);
|
||||
if (ptyfd >= 0)
|
||||
close(ptyfd);
|
||||
}
|
||||
setpgid(pgrp, pgrp);
|
||||
setpgid(pgrp, pgrp);
|
||||
|
||||
if (env_vars_to_unset)
|
||||
for (const char *const *p = env_vars_to_unset; *p; p++)
|
||||
unsetenv(*p);
|
||||
|
||||
if (!pipes_instead) {
|
||||
char *term_env_var = dupprintf("TERM=%s",
|
||||
conf_get_str(conf, CONF_termtype));
|
||||
putenv(term_env_var);
|
||||
/* We mustn't free term_env_var, as putenv links it into the
|
||||
* environment in place.
|
||||
*/
|
||||
}
|
||||
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
||||
if (got_windowid) {
|
||||
char *windowid_env_var = dupprintf("WINDOWID=%ld", windowid);
|
||||
putenv(windowid_env_var);
|
||||
/* We mustn't free windowid_env_var, as putenv links it into the
|
||||
* environment in place.
|
||||
*/
|
||||
}
|
||||
if (!pipes_instead) {
|
||||
char *term_env_var = dupprintf("TERM=%s",
|
||||
conf_get_str(conf, CONF_termtype));
|
||||
putenv(term_env_var);
|
||||
/* We mustn't free term_env_var, as putenv links it into the
|
||||
* environment in place.
|
||||
*/
|
||||
}
|
||||
#ifndef NOT_X_WINDOWS /* for Mac OS X native compilation */
|
||||
if (got_windowid) {
|
||||
char *windowid_env_var = dupprintf("WINDOWID=%ld", windowid);
|
||||
putenv(windowid_env_var);
|
||||
/* We mustn't free windowid_env_var, as putenv links it into the
|
||||
* environment in place.
|
||||
*/
|
||||
}
|
||||
{
|
||||
/*
|
||||
* In case we were invoked with a --display argument that
|
||||
@ -1128,22 +1128,22 @@ Backend *pty_backend_create(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
{
|
||||
char *key, *val;
|
||||
{
|
||||
char *key, *val;
|
||||
|
||||
for (val = conf_get_str_strs(conf, CONF_environmt, NULL, &key);
|
||||
val != NULL;
|
||||
val = conf_get_str_strs(conf, CONF_environmt, key, &key)) {
|
||||
char *varval = dupcat(key, "=", val, NULL);
|
||||
putenv(varval);
|
||||
/*
|
||||
* We must not free varval, since putenv links it
|
||||
* into the environment _in place_. Weird, but
|
||||
* there we go. Memory usage will be rationalised
|
||||
* as soon as we exec anyway.
|
||||
*/
|
||||
}
|
||||
}
|
||||
for (val = conf_get_str_strs(conf, CONF_environmt, NULL, &key);
|
||||
val != NULL;
|
||||
val = conf_get_str_strs(conf, CONF_environmt, key, &key)) {
|
||||
char *varval = dupcat(key, "=", val, NULL);
|
||||
putenv(varval);
|
||||
/*
|
||||
* We must not free varval, since putenv links it
|
||||
* into the environment _in place_. Weird, but
|
||||
* there we go. Memory usage will be rationalised
|
||||
* as soon as we exec anyway.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (dir) {
|
||||
if (chdir(dir) < 0) {
|
||||
@ -1152,18 +1152,18 @@ Backend *pty_backend_create(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SIGINT, SIGQUIT and SIGPIPE may have been set to ignored by
|
||||
* our parent, particularly by things like sh -c 'pterm &' and
|
||||
* some window or session managers. SIGPIPE was also
|
||||
* (potentially) blocked by us during startup. Reverse all
|
||||
* this for our child process.
|
||||
*/
|
||||
putty_signal(SIGINT, SIG_DFL);
|
||||
putty_signal(SIGQUIT, SIG_DFL);
|
||||
putty_signal(SIGPIPE, SIG_DFL);
|
||||
block_signal(SIGPIPE, false);
|
||||
if (argv || cmd) {
|
||||
/*
|
||||
* SIGINT, SIGQUIT and SIGPIPE may have been set to ignored by
|
||||
* our parent, particularly by things like sh -c 'pterm &' and
|
||||
* some window or session managers. SIGPIPE was also
|
||||
* (potentially) blocked by us during startup. Reverse all
|
||||
* this for our child process.
|
||||
*/
|
||||
putty_signal(SIGINT, SIG_DFL);
|
||||
putty_signal(SIGQUIT, SIG_DFL);
|
||||
putty_signal(SIGPIPE, SIG_DFL);
|
||||
block_signal(SIGPIPE, false);
|
||||
if (argv || cmd) {
|
||||
/*
|
||||
* If we were given a separated argument list, try to exec
|
||||
* it.
|
||||
@ -1207,31 +1207,31 @@ Backend *pty_backend_create(
|
||||
execl(shell, shell, "-c", cmd, (void *)NULL);
|
||||
}
|
||||
} else {
|
||||
char *shell = getenv("SHELL");
|
||||
char *shellname;
|
||||
if (conf_get_bool(conf, CONF_login_shell)) {
|
||||
char *p = strrchr(shell, '/');
|
||||
shellname = snewn(2+strlen(shell), char);
|
||||
p = p ? p+1 : shell;
|
||||
sprintf(shellname, "-%s", p);
|
||||
} else
|
||||
shellname = shell;
|
||||
execl(getenv("SHELL"), shellname, (void *)NULL);
|
||||
}
|
||||
char *shell = getenv("SHELL");
|
||||
char *shellname;
|
||||
if (conf_get_bool(conf, CONF_login_shell)) {
|
||||
char *p = strrchr(shell, '/');
|
||||
shellname = snewn(2+strlen(shell), char);
|
||||
p = p ? p+1 : shell;
|
||||
sprintf(shellname, "-%s", p);
|
||||
} else
|
||||
shellname = shell;
|
||||
execl(getenv("SHELL"), shellname, (void *)NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we're here, exec has gone badly foom.
|
||||
*/
|
||||
perror("exec");
|
||||
_exit(127);
|
||||
/*
|
||||
* If we're here, exec has gone badly foom.
|
||||
*/
|
||||
perror("exec");
|
||||
_exit(127);
|
||||
} else {
|
||||
pty->child_pid = pid;
|
||||
pty->child_dead = false;
|
||||
pty->finished = false;
|
||||
if (pty->slave_fd > 0)
|
||||
close(pty->slave_fd);
|
||||
if (!ptys_by_pid)
|
||||
ptys_by_pid = newtree234(pty_compare_by_pid);
|
||||
pty->child_pid = pid;
|
||||
pty->child_dead = false;
|
||||
pty->finished = false;
|
||||
if (pty->slave_fd > 0)
|
||||
close(pty->slave_fd);
|
||||
if (!ptys_by_pid)
|
||||
ptys_by_pid = newtree234(pty_compare_by_pid);
|
||||
if (pty->pipefds[0] >= 0) {
|
||||
close(pty->pipefds[0]);
|
||||
pty->pipefds[0] = -1;
|
||||
@ -1244,16 +1244,16 @@ Backend *pty_backend_create(
|
||||
close(pty->pipefds[5]);
|
||||
pty->pipefds[5] = -1;
|
||||
}
|
||||
add234(ptys_by_pid, pty);
|
||||
add234(ptys_by_pid, pty);
|
||||
}
|
||||
|
||||
if (pty_signal_pipe[0] < 0) {
|
||||
if (pipe(pty_signal_pipe) < 0) {
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
cloexec(pty_signal_pipe[0]);
|
||||
cloexec(pty_signal_pipe[1]);
|
||||
if (pipe(pty_signal_pipe) < 0) {
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
cloexec(pty_signal_pipe[0]);
|
||||
cloexec(pty_signal_pipe[1]);
|
||||
}
|
||||
pty_uxsel_setup(pty);
|
||||
|
||||
@ -1336,7 +1336,7 @@ static void pty_try_write(Pty *pty)
|
||||
|
||||
while (bufchain_size(&pty->output_data) > 0) {
|
||||
ptrlen data = bufchain_prefix(&pty->output_data);
|
||||
ret = write(pty->master_i, data.ptr, data.len);
|
||||
ret = write(pty->master_i, data.ptr, data.len);
|
||||
|
||||
if (ret < 0 && (errno == EWOULDBLOCK)) {
|
||||
/*
|
||||
@ -1344,11 +1344,11 @@ static void pty_try_write(Pty *pty)
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (ret < 0) {
|
||||
perror("write pty master");
|
||||
exit(1);
|
||||
}
|
||||
bufchain_consume(&pty->output_data, ret);
|
||||
if (ret < 0) {
|
||||
perror("write pty master");
|
||||
exit(1);
|
||||
}
|
||||
bufchain_consume(&pty->output_data, ret);
|
||||
}
|
||||
|
||||
if (pty->pending_eof && bufchain_size(&pty->output_data) == 0) {
|
||||
@ -1373,7 +1373,7 @@ static size_t pty_send(Backend *be, const char *buf, size_t len)
|
||||
Pty *pty = container_of(be, Pty, backend);
|
||||
|
||||
if (pty->master_i < 0 || pty->pending_eof)
|
||||
return 0; /* ignore all writes if fd closed */
|
||||
return 0; /* ignore all writes if fd closed */
|
||||
|
||||
bufchain_add(&pty->output_data, buf, len);
|
||||
pty_try_write(pty);
|
||||
@ -1393,8 +1393,8 @@ static void pty_close(Pty *pty)
|
||||
uxsel_del(pty->master_i);
|
||||
|
||||
if (pty->master_fd >= 0) {
|
||||
close(pty->master_fd);
|
||||
pty->master_fd = -1;
|
||||
close(pty->master_fd);
|
||||
pty->master_fd = -1;
|
||||
}
|
||||
for (i = 0; i < 6; i++) {
|
||||
if (pty->pipefds[i] >= 0)
|
||||
@ -1404,8 +1404,8 @@ static void pty_close(Pty *pty)
|
||||
pty->master_i = pty->master_o = pty->master_e = -1;
|
||||
#ifndef OMIT_UTMP
|
||||
if (pty_utmp_helper_pipe >= 0) {
|
||||
close(pty_utmp_helper_pipe); /* this causes utmp to be cleaned up */
|
||||
pty_utmp_helper_pipe = -1;
|
||||
close(pty_utmp_helper_pipe); /* this causes utmp to be cleaned up */
|
||||
pty_utmp_helper_pipe = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -1536,7 +1536,7 @@ static int pty_exitcode(Backend *be)
|
||||
{
|
||||
Pty *pty = container_of(be, Pty, backend);
|
||||
if (!pty->finished)
|
||||
return -1; /* not dead yet */
|
||||
return -1; /* not dead yet */
|
||||
else if (WIFSIGNALED(pty->exit_code))
|
||||
return 128 + WTERMSIG(pty->exit_code);
|
||||
else
|
||||
@ -1548,7 +1548,7 @@ int pty_backend_exit_signum(Backend *be)
|
||||
Pty *pty = container_of(be, Pty, backend);
|
||||
|
||||
if (!pty->finished || !WIFSIGNALED(pty->exit_code))
|
||||
return -1;
|
||||
return -1;
|
||||
|
||||
return WTERMSIG(pty->exit_code);
|
||||
}
|
||||
@ -1559,7 +1559,7 @@ ptrlen pty_backend_exit_signame(Backend *be, char **aux_msg)
|
||||
|
||||
int sig = pty_backend_exit_signum(be);
|
||||
if (sig < 0)
|
||||
return PTRLEN_LITERAL("");
|
||||
return PTRLEN_LITERAL("");
|
||||
|
||||
#define TRANSLATE_SIGNAL(s) do \
|
||||
{ \
|
||||
|
@ -21,7 +21,7 @@
|
||||
* Stubs to avoid uxpty.c needing to be linked in.
|
||||
*/
|
||||
const bool use_pty_argv = false;
|
||||
char **pty_argv; /* never used */
|
||||
char **pty_argv; /* never used */
|
||||
char *pty_osx_envrestore_prefix;
|
||||
|
||||
/*
|
||||
@ -68,8 +68,8 @@ 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");
|
||||
/* fall back to traditional method */
|
||||
display = getenv("DISPLAY");
|
||||
return dupstr(display);
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ void setup(bool single)
|
||||
{
|
||||
const struct BackendVtable *vt =
|
||||
backend_vt_from_proto(default_protocol);
|
||||
default_port = 0; /* illegal */
|
||||
default_port = 0; /* illegal */
|
||||
if (vt)
|
||||
default_port = vt->default_port;
|
||||
}
|
||||
|
38
unix/uxsel.c
38
unix/uxsel.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* uxsel.c
|
||||
*
|
||||
*
|
||||
* This module is a sort of all-purpose interchange for file
|
||||
* descriptors. At one end it talks to uxnet.c and pty.c and
|
||||
* anything else which might have one or more fds that need
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
struct fd {
|
||||
int fd;
|
||||
int rwx; /* 4=except 2=write 1=read */
|
||||
int rwx; /* 4=except 2=write 1=read */
|
||||
uxsel_callback_fn callback;
|
||||
uxsel_id *id; /* for uxsel_input_remove */
|
||||
};
|
||||
@ -29,9 +29,9 @@ static int uxsel_fd_cmp(void *av, void *bv)
|
||||
struct fd *a = (struct fd *)av;
|
||||
struct fd *b = (struct fd *)bv;
|
||||
if (a->fd < b->fd)
|
||||
return -1;
|
||||
return -1;
|
||||
if (a->fd > b->fd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
static int uxsel_fd_findcmp(void *av, void *bv)
|
||||
@ -39,9 +39,9 @@ static int uxsel_fd_findcmp(void *av, void *bv)
|
||||
int *a = (int *)av;
|
||||
struct fd *b = (struct fd *)bv;
|
||||
if (*a < b->fd)
|
||||
return -1;
|
||||
return -1;
|
||||
if (*a > b->fd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -69,12 +69,12 @@ void uxsel_set(int fd, int rwx, uxsel_callback_fn callback)
|
||||
uxsel_del(fd);
|
||||
|
||||
if (rwx) {
|
||||
newfd = snew(struct fd);
|
||||
newfd->fd = fd;
|
||||
newfd->rwx = rwx;
|
||||
newfd->callback = callback;
|
||||
newfd->id = uxsel_input_add(fd, rwx);
|
||||
add234(fds, newfd);
|
||||
newfd = snew(struct fd);
|
||||
newfd->fd = fd;
|
||||
newfd->rwx = rwx;
|
||||
newfd->callback = callback;
|
||||
newfd->id = uxsel_input_add(fd, rwx);
|
||||
add234(fds, newfd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,16 +82,16 @@ void uxsel_del(int fd)
|
||||
{
|
||||
struct fd *oldfd = find234(fds, &fd, uxsel_fd_findcmp);
|
||||
if (oldfd) {
|
||||
if (oldfd->id)
|
||||
if (oldfd->id)
|
||||
uxsel_input_remove(oldfd->id);
|
||||
del234(fds, oldfd);
|
||||
sfree(oldfd);
|
||||
del234(fds, oldfd);
|
||||
sfree(oldfd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* And here is the interface to select-functionality-supplying
|
||||
* modules.
|
||||
* modules.
|
||||
*/
|
||||
|
||||
int next_fd(int *state, int *rwx)
|
||||
@ -99,10 +99,10 @@ int next_fd(int *state, int *rwx)
|
||||
struct fd *fd;
|
||||
fd = index234(fds, (*state)++);
|
||||
if (fd) {
|
||||
*rwx = fd->rwx;
|
||||
return fd->fd;
|
||||
*rwx = fd->rwx;
|
||||
return fd->fd;
|
||||
} else
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int first_fd(int *state, int *rwx)
|
||||
|
148
unix/uxser.c
148
unix/uxser.c
@ -39,9 +39,9 @@ static int serial_compare_by_fd(void *av, void *bv)
|
||||
Serial *b = (Serial *)bv;
|
||||
|
||||
if (a->fd < b->fd)
|
||||
return -1;
|
||||
return -1;
|
||||
else if (a->fd > b->fd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -51,9 +51,9 @@ static int serial_find_by_fd(void *av, void *bv)
|
||||
Serial *b = (Serial *)bv;
|
||||
|
||||
if (a < b->fd)
|
||||
return -1;
|
||||
return -1;
|
||||
else if (a > b->fd)
|
||||
return +1;
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ static const char *serial_configure(Serial *serial, Conf *conf)
|
||||
const char *str;
|
||||
|
||||
if (serial->fd < 0)
|
||||
return "Unable to reconfigure already-closed serial connection";
|
||||
return "Unable to reconfigure already-closed serial connection";
|
||||
|
||||
tcgetattr(serial->fd, &options);
|
||||
|
||||
@ -195,9 +195,9 @@ static const char *serial_configure(Serial *serial, Conf *conf)
|
||||
conf_get_int(conf, CONF_serdatabits));
|
||||
|
||||
if (conf_get_int(conf, CONF_serstopbits) >= 4) {
|
||||
options.c_cflag |= CSTOPB;
|
||||
options.c_cflag |= CSTOPB;
|
||||
} else {
|
||||
options.c_cflag &= ~CSTOPB;
|
||||
options.c_cflag &= ~CSTOPB;
|
||||
}
|
||||
logeventf(serial->logctx, "Configuring %d stop bits",
|
||||
(options.c_cflag & CSTOPB ? 2 : 1));
|
||||
@ -211,33 +211,33 @@ static const char *serial_configure(Serial *serial, Conf *conf)
|
||||
#endif
|
||||
flow = conf_get_int(conf, CONF_serflow);
|
||||
if (flow == SER_FLOW_XONXOFF) {
|
||||
options.c_iflag |= IXON | IXOFF;
|
||||
str = "XON/XOFF";
|
||||
options.c_iflag |= IXON | IXOFF;
|
||||
str = "XON/XOFF";
|
||||
} else if (flow == SER_FLOW_RTSCTS) {
|
||||
#ifdef CRTSCTS
|
||||
options.c_cflag |= CRTSCTS;
|
||||
options.c_cflag |= CRTSCTS;
|
||||
#endif
|
||||
#ifdef CNEW_RTSCTS
|
||||
options.c_cflag |= CNEW_RTSCTS;
|
||||
options.c_cflag |= CNEW_RTSCTS;
|
||||
#endif
|
||||
str = "RTS/CTS";
|
||||
str = "RTS/CTS";
|
||||
} else
|
||||
str = "no";
|
||||
str = "no";
|
||||
logeventf(serial->logctx, "Configuring %s flow control", str);
|
||||
|
||||
/* Parity */
|
||||
parity = conf_get_int(conf, CONF_serparity);
|
||||
if (parity == SER_PAR_ODD) {
|
||||
options.c_cflag |= PARENB;
|
||||
options.c_cflag |= PARODD;
|
||||
str = "odd";
|
||||
options.c_cflag |= PARENB;
|
||||
options.c_cflag |= PARODD;
|
||||
str = "odd";
|
||||
} else if (parity == SER_PAR_EVEN) {
|
||||
options.c_cflag |= PARENB;
|
||||
options.c_cflag &= ~PARODD;
|
||||
str = "even";
|
||||
options.c_cflag |= PARENB;
|
||||
options.c_cflag &= ~PARODD;
|
||||
str = "even";
|
||||
} else {
|
||||
options.c_cflag &= ~PARENB;
|
||||
str = "no";
|
||||
options.c_cflag &= ~PARENB;
|
||||
str = "no";
|
||||
}
|
||||
logeventf(serial->logctx, "Configuring %s parity", str);
|
||||
|
||||
@ -245,35 +245,35 @@ static const char *serial_configure(Serial *serial, Conf *conf)
|
||||
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
|
||||
options.c_iflag &= ~(ISTRIP | IGNCR | INLCR | ICRNL
|
||||
#ifdef IUCLC
|
||||
| IUCLC
|
||||
| IUCLC
|
||||
#endif
|
||||
);
|
||||
);
|
||||
options.c_oflag &= ~(OPOST
|
||||
#ifdef ONLCR
|
||||
| ONLCR
|
||||
| ONLCR
|
||||
#endif
|
||||
#ifdef OCRNL
|
||||
| OCRNL
|
||||
| OCRNL
|
||||
#endif
|
||||
#ifdef ONOCR
|
||||
| ONOCR
|
||||
| ONOCR
|
||||
#endif
|
||||
#ifdef ONLRET
|
||||
| ONLRET
|
||||
| ONLRET
|
||||
#endif
|
||||
);
|
||||
);
|
||||
options.c_cc[VMIN] = 1;
|
||||
options.c_cc[VTIME] = 0;
|
||||
|
||||
if (tcsetattr(serial->fd, TCSANOW, &options) < 0)
|
||||
return "Unable to configure serial port";
|
||||
return "Unable to configure serial port";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to set up the serial connection.
|
||||
*
|
||||
*
|
||||
* Returns an error message, or NULL on success.
|
||||
*
|
||||
* Also places the canonical host name into `realhost'. It must be
|
||||
@ -281,7 +281,7 @@ static const char *serial_configure(Serial *serial, Conf *conf)
|
||||
*/
|
||||
static const char *serial_init(Seat *seat, Backend **backend_handle,
|
||||
LogContext *logctx, Conf *conf,
|
||||
const char *host, int port, char **realhost,
|
||||
const char *host, int port, char **realhost,
|
||||
bool nodelay, bool keepalive)
|
||||
{
|
||||
Serial *serial;
|
||||
@ -306,18 +306,18 @@ static const char *serial_init(Seat *seat, Backend **backend_handle,
|
||||
|
||||
serial->fd = open(line, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
|
||||
if (serial->fd < 0)
|
||||
return "Unable to open serial port";
|
||||
return "Unable to open serial port";
|
||||
|
||||
cloexec(serial->fd);
|
||||
|
||||
err = serial_configure(serial, conf);
|
||||
if (err)
|
||||
return err;
|
||||
return err;
|
||||
|
||||
*realhost = dupstr(line);
|
||||
|
||||
if (!serial_by_fd)
|
||||
serial_by_fd = newtree234(serial_compare_by_fd);
|
||||
serial_by_fd = newtree234(serial_compare_by_fd);
|
||||
add234(serial_by_fd, serial);
|
||||
|
||||
serial_uxsel_setup(serial);
|
||||
@ -333,8 +333,8 @@ static const char *serial_init(Seat *seat, Backend **backend_handle,
|
||||
static void serial_close(Serial *serial)
|
||||
{
|
||||
if (serial->fd >= 0) {
|
||||
close(serial->fd);
|
||||
serial->fd = -1;
|
||||
close(serial->fd);
|
||||
serial->fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,46 +369,46 @@ static void serial_select_result(int fd, int event)
|
||||
serial = find234(serial_by_fd, &fd, serial_find_by_fd);
|
||||
|
||||
if (!serial)
|
||||
return; /* spurious event; keep going */
|
||||
return; /* spurious event; keep going */
|
||||
|
||||
if (event == 1) {
|
||||
ret = read(serial->fd, buf, sizeof(buf));
|
||||
ret = read(serial->fd, buf, sizeof(buf));
|
||||
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* Shouldn't happen on a real serial port, but I'm open
|
||||
* to the idea that there might be two-way devices we
|
||||
* can treat _like_ serial ports which can return EOF.
|
||||
*/
|
||||
finished = true;
|
||||
} else if (ret < 0) {
|
||||
if (ret == 0) {
|
||||
/*
|
||||
* Shouldn't happen on a real serial port, but I'm open
|
||||
* to the idea that there might be two-way devices we
|
||||
* can treat _like_ serial ports which can return EOF.
|
||||
*/
|
||||
finished = true;
|
||||
} else if (ret < 0) {
|
||||
#ifdef EAGAIN
|
||||
if (errno == EAGAIN)
|
||||
return; /* spurious */
|
||||
if (errno == EAGAIN)
|
||||
return; /* spurious */
|
||||
#endif
|
||||
#ifdef EWOULDBLOCK
|
||||
if (errno == EWOULDBLOCK)
|
||||
return; /* spurious */
|
||||
if (errno == EWOULDBLOCK)
|
||||
return; /* spurious */
|
||||
#endif
|
||||
perror("read serial port");
|
||||
exit(1);
|
||||
} else if (ret > 0) {
|
||||
serial->inbufsize = seat_stdout(serial->seat, buf, ret);
|
||||
serial_uxsel_setup(serial); /* might acquire backlog and freeze */
|
||||
}
|
||||
perror("read serial port");
|
||||
exit(1);
|
||||
} else if (ret > 0) {
|
||||
serial->inbufsize = seat_stdout(serial->seat, buf, ret);
|
||||
serial_uxsel_setup(serial); /* might acquire backlog and freeze */
|
||||
}
|
||||
} else if (event == 2) {
|
||||
/*
|
||||
* Attempt to send data down the pty.
|
||||
*/
|
||||
serial_try_write(serial);
|
||||
/*
|
||||
* Attempt to send data down the pty.
|
||||
*/
|
||||
serial_try_write(serial);
|
||||
}
|
||||
|
||||
if (finished) {
|
||||
serial_close(serial);
|
||||
serial_close(serial);
|
||||
|
||||
serial->finished = true;
|
||||
serial->finished = true;
|
||||
|
||||
seat_notify_remote_exit(serial->seat);
|
||||
seat_notify_remote_exit(serial->seat);
|
||||
}
|
||||
}
|
||||
|
||||
@ -417,7 +417,7 @@ static void serial_uxsel_setup(Serial *serial)
|
||||
int rwx = 0;
|
||||
|
||||
if (serial->inbufsize <= SERIAL_MAX_BACKLOG)
|
||||
rwx |= SELECT_R;
|
||||
rwx |= SELECT_R;
|
||||
if (bufchain_size(&serial->output_data))
|
||||
rwx |= SELECT_W; /* might also want to write to it */
|
||||
uxsel_set(serial->fd, rwx, serial_select_result);
|
||||
@ -431,7 +431,7 @@ static void serial_try_write(Serial *serial)
|
||||
|
||||
while (bufchain_size(&serial->output_data) > 0) {
|
||||
ptrlen data = bufchain_prefix(&serial->output_data);
|
||||
ret = write(serial->fd, data.ptr, data.len);
|
||||
ret = write(serial->fd, data.ptr, data.len);
|
||||
|
||||
if (ret < 0 && (errno == EWOULDBLOCK)) {
|
||||
/*
|
||||
@ -439,11 +439,11 @@ static void serial_try_write(Serial *serial)
|
||||
*/
|
||||
break;
|
||||
}
|
||||
if (ret < 0) {
|
||||
perror("write serial port");
|
||||
exit(1);
|
||||
}
|
||||
bufchain_consume(&serial->output_data, ret);
|
||||
if (ret < 0) {
|
||||
perror("write serial port");
|
||||
exit(1);
|
||||
}
|
||||
bufchain_consume(&serial->output_data, ret);
|
||||
}
|
||||
|
||||
serial_uxsel_setup(serial);
|
||||
@ -457,7 +457,7 @@ static size_t serial_send(Backend *be, const char *buf, size_t len)
|
||||
Serial *serial = container_of(be, Serial, backend);
|
||||
|
||||
if (serial->fd < 0)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
bufchain_add(&serial->output_data, buf, len);
|
||||
serial_try_write(serial);
|
||||
@ -491,7 +491,7 @@ static void serial_special(Backend *be, SessionSpecialCode code, int arg)
|
||||
Serial *serial = container_of(be, Serial, backend);
|
||||
|
||||
if (serial->fd >= 0 && code == SS_BRK) {
|
||||
tcsendbreak(serial->fd, 0);
|
||||
tcsendbreak(serial->fd, 0);
|
||||
logevent(serial->logctx, "Sending serial break at user request");
|
||||
}
|
||||
|
||||
@ -505,8 +505,8 @@ static void serial_special(Backend *be, SessionSpecialCode code, int arg)
|
||||
static const SessionSpecial *serial_get_specials(Backend *be)
|
||||
{
|
||||
static const struct SessionSpecial specials[] = {
|
||||
{"Break", SS_BRK},
|
||||
{NULL, SS_EXITMENU}
|
||||
{"Break", SS_BRK},
|
||||
{NULL, SS_EXITMENU}
|
||||
};
|
||||
return specials;
|
||||
}
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define PUTTY_DO_GLOBALS /* actually _define_ globals */
|
||||
#define PUTTY_DO_GLOBALS /* actually _define_ globals */
|
||||
#include "putty.h"
|
||||
#include "mpint.h"
|
||||
#include "ssh.h"
|
||||
@ -93,7 +93,7 @@ Filename *platform_default_filename(const char *name)
|
||||
|
||||
char *x_get_default(const char *key)
|
||||
{
|
||||
return NULL; /* this is a stub */
|
||||
return NULL; /* this is a stub */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -486,7 +486,7 @@ static int server_accepting(Plug *p, accept_fn_t constructor, accept_ctx_t ctx)
|
||||
Plug *plug = server_conn_plug(cfg, &inst);
|
||||
s = constructor(ctx, plug);
|
||||
if ((err = sk_socket_error(s)) != NULL)
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
SocketPeerInfo *pi = sk_peer_info(s);
|
||||
|
||||
@ -837,30 +837,30 @@ int main(int argc, char **argv)
|
||||
|
||||
pollwrapper *pw = pollwrap_new();
|
||||
while (!finished) {
|
||||
int rwx;
|
||||
int ret;
|
||||
int rwx;
|
||||
int ret;
|
||||
unsigned long next;
|
||||
|
||||
pollwrap_clear(pw);
|
||||
|
||||
/* Count the currently active fds. */
|
||||
i = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) i++;
|
||||
/* Count the currently active fds. */
|
||||
i = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) i++;
|
||||
|
||||
/* Expand the fdlist buffer if necessary. */
|
||||
/* Expand the fdlist buffer if necessary. */
|
||||
sgrowarray(fdlist, fdsize, i);
|
||||
|
||||
/*
|
||||
* Add all currently open fds to the select sets, and store
|
||||
* them in fdlist as well.
|
||||
*/
|
||||
int fdcount = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) {
|
||||
fdlist[fdcount++] = fd;
|
||||
/*
|
||||
* Add all currently open fds to the select sets, and store
|
||||
* them in fdlist as well.
|
||||
*/
|
||||
int fdcount = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) {
|
||||
fdlist[fdcount++] = fd;
|
||||
pollwrap_add_fd_rwx(pw, fd, rwx);
|
||||
}
|
||||
}
|
||||
|
||||
if (toplevel_callback_pending()) {
|
||||
ret = pollwrap_poll_instant(pw);
|
||||
@ -869,12 +869,12 @@ int main(int argc, char **argv)
|
||||
unsigned long then;
|
||||
long ticks;
|
||||
|
||||
then = now;
|
||||
now = GETTICKCOUNT();
|
||||
if (now - then > next - then)
|
||||
ticks = 0;
|
||||
else
|
||||
ticks = next - now;
|
||||
then = now;
|
||||
now = GETTICKCOUNT();
|
||||
if (now - then > next - then)
|
||||
ticks = 0;
|
||||
else
|
||||
ticks = next - now;
|
||||
|
||||
bool overflow = false;
|
||||
if (ticks > INT_MAX) {
|
||||
@ -895,26 +895,26 @@ int main(int argc, char **argv)
|
||||
if (ret < 0 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
if (ret < 0) {
|
||||
perror("poll");
|
||||
exit(1);
|
||||
}
|
||||
if (ret < 0) {
|
||||
perror("poll");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < fdcount; i++) {
|
||||
fd = fdlist[i];
|
||||
for (i = 0; i < fdcount; i++) {
|
||||
fd = fdlist[i];
|
||||
int rwx = pollwrap_get_fd_rwx(pw, fd);
|
||||
/*
|
||||
* We must process exceptional notifications before
|
||||
* ordinary readability ones, or we may go straight
|
||||
* past the urgent marker.
|
||||
*/
|
||||
if (rwx & SELECT_X)
|
||||
select_result(fd, SELECT_X);
|
||||
if (rwx & SELECT_R)
|
||||
select_result(fd, SELECT_R);
|
||||
if (rwx & SELECT_W)
|
||||
select_result(fd, SELECT_W);
|
||||
}
|
||||
if (rwx & SELECT_X)
|
||||
select_result(fd, SELECT_X);
|
||||
if (rwx & SELECT_R)
|
||||
select_result(fd, SELECT_R);
|
||||
if (rwx & SELECT_W)
|
||||
select_result(fd, SELECT_W);
|
||||
}
|
||||
|
||||
run_toplevel_callbacks();
|
||||
}
|
||||
|
294
unix/uxsftp.c
294
unix/uxsftp.c
@ -30,7 +30,7 @@ void uxsel_input_remove(uxsel_id *id) { }
|
||||
|
||||
char *x_get_default(const char *key)
|
||||
{
|
||||
return NULL; /* this is a stub */
|
||||
return NULL; /* this is a stub */
|
||||
}
|
||||
|
||||
void platform_get_x11_auth(struct X11Display *display, Conf *conf)
|
||||
@ -65,9 +65,9 @@ FontSpec *platform_default_fontspec(const char *name)
|
||||
Filename *platform_default_filename(const char *name)
|
||||
{
|
||||
if (!strcmp(name, "LogFileName"))
|
||||
return filename_from_str("putty.log");
|
||||
return filename_from_str("putty.log");
|
||||
else
|
||||
return filename_from_str("");
|
||||
return filename_from_str("");
|
||||
}
|
||||
|
||||
int filexfer_get_userpass_input(Seat *seat, prompts_t *p, bufchain *input)
|
||||
@ -75,7 +75,7 @@ int filexfer_get_userpass_input(Seat *seat, prompts_t *p, bufchain *input)
|
||||
int ret;
|
||||
ret = cmdline_get_passwd_input(p);
|
||||
if (ret == -1)
|
||||
ret = console_get_userpass_input(p);
|
||||
ret = console_get_userpass_input(p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -86,9 +86,9 @@ int filexfer_get_userpass_input(Seat *seat, prompts_t *p, bufchain *input)
|
||||
char *psftp_lcd(char *dir)
|
||||
{
|
||||
if (chdir(dir) < 0)
|
||||
return dupprintf("%s: chdir: %s", dir, strerror(errno));
|
||||
return dupprintf("%s: chdir: %s", dir, strerror(errno));
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -102,17 +102,17 @@ char *psftp_getcwd(void)
|
||||
|
||||
buffer = snewn(size, char);
|
||||
while (1) {
|
||||
ret = getcwd(buffer, size);
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
if (errno != ERANGE) {
|
||||
sfree(buffer);
|
||||
return dupprintf("[cwd unavailable: %s]", strerror(errno));
|
||||
}
|
||||
/*
|
||||
* Otherwise, ERANGE was returned, meaning the buffer
|
||||
* wasn't big enough.
|
||||
*/
|
||||
ret = getcwd(buffer, size);
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
if (errno != ERANGE) {
|
||||
sfree(buffer);
|
||||
return dupprintf("[cwd unavailable: %s]", strerror(errno));
|
||||
}
|
||||
/*
|
||||
* Otherwise, ERANGE was returned, meaning the buffer
|
||||
* wasn't big enough.
|
||||
*/
|
||||
sgrowarray(buffer, size, size);
|
||||
}
|
||||
}
|
||||
@ -122,7 +122,7 @@ struct RFile {
|
||||
};
|
||||
|
||||
RFile *open_existing_file(const char *name, uint64_t *size,
|
||||
unsigned long *mtime, unsigned long *atime,
|
||||
unsigned long *mtime, unsigned long *atime,
|
||||
long *perms)
|
||||
{
|
||||
int fd;
|
||||
@ -130,29 +130,29 @@ RFile *open_existing_file(const char *name, uint64_t *size,
|
||||
|
||||
fd = open(name, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
ret = snew(RFile);
|
||||
ret->fd = fd;
|
||||
|
||||
if (size || mtime || atime || perms) {
|
||||
struct stat statbuf;
|
||||
if (fstat(fd, &statbuf) < 0) {
|
||||
fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));
|
||||
memset(&statbuf, 0, sizeof(statbuf));
|
||||
}
|
||||
struct stat statbuf;
|
||||
if (fstat(fd, &statbuf) < 0) {
|
||||
fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));
|
||||
memset(&statbuf, 0, sizeof(statbuf));
|
||||
}
|
||||
|
||||
if (size)
|
||||
*size = statbuf.st_size;
|
||||
|
||||
if (mtime)
|
||||
*mtime = statbuf.st_mtime;
|
||||
if (size)
|
||||
*size = statbuf.st_size;
|
||||
|
||||
if (atime)
|
||||
*atime = statbuf.st_atime;
|
||||
if (mtime)
|
||||
*mtime = statbuf.st_mtime;
|
||||
|
||||
if (perms)
|
||||
*perms = statbuf.st_mode;
|
||||
if (atime)
|
||||
*atime = statbuf.st_atime;
|
||||
|
||||
if (perms)
|
||||
*perms = statbuf.st_mode;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -182,7 +182,7 @@ WFile *open_new_file(const char *name, long perms)
|
||||
fd = open(name, O_CREAT | O_TRUNC | O_WRONLY,
|
||||
(mode_t)(perms ? perms : 0666));
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
ret = snew(WFile);
|
||||
ret->fd = fd;
|
||||
@ -199,20 +199,20 @@ WFile *open_existing_wfile(const char *name, uint64_t *size)
|
||||
|
||||
fd = open(name, O_APPEND | O_WRONLY);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
ret = snew(WFile);
|
||||
ret->fd = fd;
|
||||
ret->name = dupstr(name);
|
||||
|
||||
if (size) {
|
||||
struct stat statbuf;
|
||||
if (fstat(fd, &statbuf) < 0) {
|
||||
fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));
|
||||
memset(&statbuf, 0, sizeof(statbuf));
|
||||
}
|
||||
struct stat statbuf;
|
||||
if (fstat(fd, &statbuf) < 0) {
|
||||
fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));
|
||||
memset(&statbuf, 0, sizeof(statbuf));
|
||||
}
|
||||
|
||||
*size = statbuf.st_size;
|
||||
*size = statbuf.st_size;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -225,17 +225,17 @@ int write_to_file(WFile *f, void *buffer, int length)
|
||||
|
||||
/* Keep trying until we've really written as much as we can. */
|
||||
while (length > 0) {
|
||||
int ret = write(f->fd, p, length);
|
||||
int ret = write(f->fd, p, length);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ret == 0)
|
||||
break;
|
||||
if (ret == 0)
|
||||
break;
|
||||
|
||||
p += ret;
|
||||
length -= ret;
|
||||
so_far += ret;
|
||||
p += ret;
|
||||
length -= ret;
|
||||
so_far += ret;
|
||||
}
|
||||
|
||||
return so_far;
|
||||
@ -264,19 +264,19 @@ void close_wfile(WFile *f)
|
||||
int seek_file(WFile *f, uint64_t offset, int whence)
|
||||
{
|
||||
int lseek_whence;
|
||||
|
||||
|
||||
switch (whence) {
|
||||
case FROM_START:
|
||||
lseek_whence = SEEK_SET;
|
||||
break;
|
||||
lseek_whence = SEEK_SET;
|
||||
break;
|
||||
case FROM_CURRENT:
|
||||
lseek_whence = SEEK_CUR;
|
||||
break;
|
||||
lseek_whence = SEEK_CUR;
|
||||
break;
|
||||
case FROM_END:
|
||||
lseek_whence = SEEK_END;
|
||||
break;
|
||||
lseek_whence = SEEK_END;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lseek(f->fd, offset, lseek_whence) >= 0 ? 0 : -1;
|
||||
@ -292,16 +292,16 @@ int file_type(const char *name)
|
||||
struct stat statbuf;
|
||||
|
||||
if (stat(name, &statbuf) < 0) {
|
||||
if (errno != ENOENT)
|
||||
fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));
|
||||
return FILE_TYPE_NONEXISTENT;
|
||||
if (errno != ENOENT)
|
||||
fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));
|
||||
return FILE_TYPE_NONEXISTENT;
|
||||
}
|
||||
|
||||
if (S_ISREG(statbuf.st_mode))
|
||||
return FILE_TYPE_FILE;
|
||||
return FILE_TYPE_FILE;
|
||||
|
||||
if (S_ISDIR(statbuf.st_mode))
|
||||
return FILE_TYPE_DIRECTORY;
|
||||
return FILE_TYPE_DIRECTORY;
|
||||
|
||||
return FILE_TYPE_WEIRD;
|
||||
}
|
||||
@ -318,7 +318,7 @@ DirHandle *open_directory(const char *name, const char **errmsg)
|
||||
dir = opendir(name);
|
||||
if (!dir) {
|
||||
*errmsg = strerror(errno);
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = snew(DirHandle);
|
||||
@ -331,12 +331,12 @@ char *read_filename(DirHandle *dir)
|
||||
struct dirent *de;
|
||||
|
||||
do {
|
||||
de = readdir(dir->dir);
|
||||
if (de == NULL)
|
||||
return NULL;
|
||||
de = readdir(dir->dir);
|
||||
if (de == NULL)
|
||||
return NULL;
|
||||
} while ((de->d_name[0] == '.' &&
|
||||
(de->d_name[1] == '\0' ||
|
||||
(de->d_name[1] == '.' && de->d_name[2] == '\0'))));
|
||||
(de->d_name[1] == '\0' ||
|
||||
(de->d_name[1] == '.' && de->d_name[2] == '\0'))));
|
||||
|
||||
return dupstr(de->d_name);
|
||||
}
|
||||
@ -352,26 +352,26 @@ int test_wildcard(const char *name, bool cmdline)
|
||||
struct stat statbuf;
|
||||
|
||||
if (stat(name, &statbuf) == 0) {
|
||||
return WCTYPE_FILENAME;
|
||||
return WCTYPE_FILENAME;
|
||||
} else if (cmdline) {
|
||||
/*
|
||||
* On Unix, we never need to parse wildcards coming from
|
||||
* the command line, because the shell will have expanded
|
||||
* them into a filename list already.
|
||||
*/
|
||||
return WCTYPE_NONEXISTENT;
|
||||
/*
|
||||
* On Unix, we never need to parse wildcards coming from
|
||||
* the command line, because the shell will have expanded
|
||||
* them into a filename list already.
|
||||
*/
|
||||
return WCTYPE_NONEXISTENT;
|
||||
} else {
|
||||
#if HAVE_GLOB_H
|
||||
glob_t globbed;
|
||||
int ret = WCTYPE_NONEXISTENT;
|
||||
glob_t globbed;
|
||||
int ret = WCTYPE_NONEXISTENT;
|
||||
|
||||
if (glob(name, GLOB_ERR, NULL, &globbed) == 0) {
|
||||
if (globbed.gl_pathc > 0)
|
||||
ret = WCTYPE_WILDCARD;
|
||||
globfree(&globbed);
|
||||
}
|
||||
if (glob(name, GLOB_ERR, NULL, &globbed) == 0) {
|
||||
if (globbed.gl_pathc > 0)
|
||||
ret = WCTYPE_WILDCARD;
|
||||
globfree(&globbed);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
#else
|
||||
/* On a system without glob.h, we just have to return a
|
||||
* failure code */
|
||||
@ -392,8 +392,8 @@ WildcardMatcher *begin_wildcard_matching(const char *name) {
|
||||
WildcardMatcher *ret = snew(WildcardMatcher);
|
||||
|
||||
if (glob(name, 0, NULL, &ret->globbed) < 0) {
|
||||
sfree(ret);
|
||||
return NULL;
|
||||
sfree(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret->i = 0;
|
||||
@ -402,9 +402,9 @@ WildcardMatcher *begin_wildcard_matching(const char *name) {
|
||||
}
|
||||
char *wildcard_get_filename(WildcardMatcher *dir) {
|
||||
if (dir->i < dir->globbed.gl_pathc) {
|
||||
return dupstr(dir->globbed.gl_pathv[dir->i++]);
|
||||
return dupstr(dir->globbed.gl_pathv[dir->i++]);
|
||||
} else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
void finish_wildcard_matching(WildcardMatcher *dir) {
|
||||
globfree(&dir->globbed);
|
||||
@ -442,10 +442,10 @@ char *stripslashes(const char *str, bool local)
|
||||
bool vet_filename(const char *name)
|
||||
{
|
||||
if (strchr(name, '/'))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
if (name[0] == '.' && (!name[1] || (name[1] == '.' && !name[2])))
|
||||
return false;
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -483,34 +483,34 @@ static int ssh_sftp_do_select(bool include_stdin, bool no_fds_ok)
|
||||
|
||||
do {
|
||||
|
||||
/* Count the currently active fds. */
|
||||
i = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) i++;
|
||||
/* Count the currently active fds. */
|
||||
i = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) i++;
|
||||
|
||||
if (i < 1 && !no_fds_ok && !toplevel_callback_pending()) {
|
||||
if (i < 1 && !no_fds_ok && !toplevel_callback_pending()) {
|
||||
pollwrap_free(pw);
|
||||
return -1; /* doom */
|
||||
return -1; /* doom */
|
||||
}
|
||||
|
||||
/* Expand the fdlist buffer if necessary. */
|
||||
/* Expand the fdlist buffer if necessary. */
|
||||
sgrowarray(fdlist, fdsize, i);
|
||||
|
||||
pollwrap_clear(pw);
|
||||
|
||||
/*
|
||||
* Add all currently open fds to the select sets, and store
|
||||
* them in fdlist as well.
|
||||
*/
|
||||
fdcount = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) {
|
||||
fdlist[fdcount++] = fd;
|
||||
/*
|
||||
* Add all currently open fds to the select sets, and store
|
||||
* them in fdlist as well.
|
||||
*/
|
||||
fdcount = 0;
|
||||
for (fd = first_fd(&fdstate, &rwx); fd >= 0;
|
||||
fd = next_fd(&fdstate, &rwx)) {
|
||||
fdlist[fdcount++] = fd;
|
||||
pollwrap_add_fd_rwx(pw, fd, rwx);
|
||||
}
|
||||
}
|
||||
|
||||
if (include_stdin)
|
||||
pollwrap_add_fd_rwx(pw, 0, SELECT_R);
|
||||
if (include_stdin)
|
||||
pollwrap_add_fd_rwx(pw, 0, SELECT_R);
|
||||
|
||||
if (toplevel_callback_pending()) {
|
||||
ret = pollwrap_poll_instant(pw);
|
||||
@ -521,12 +521,12 @@ static int ssh_sftp_do_select(bool include_stdin, bool no_fds_ok)
|
||||
unsigned long then;
|
||||
long ticks;
|
||||
|
||||
then = now;
|
||||
now = GETTICKCOUNT();
|
||||
if (now - then > next - then)
|
||||
ticks = 0;
|
||||
else
|
||||
ticks = next - now;
|
||||
then = now;
|
||||
now = GETTICKCOUNT();
|
||||
if (now - then > next - then)
|
||||
ticks = 0;
|
||||
else
|
||||
ticks = next - now;
|
||||
|
||||
bool overflow = false;
|
||||
if (ticks > INT_MAX) {
|
||||
@ -548,24 +548,24 @@ static int ssh_sftp_do_select(bool include_stdin, bool no_fds_ok)
|
||||
} while (ret == 0 && !done_something);
|
||||
|
||||
if (ret < 0) {
|
||||
perror("poll");
|
||||
exit(1);
|
||||
perror("poll");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < fdcount; i++) {
|
||||
fd = fdlist[i];
|
||||
fd = fdlist[i];
|
||||
int rwx = pollwrap_get_fd_rwx(pw, fd);
|
||||
/*
|
||||
* We must process exceptional notifications before
|
||||
* ordinary readability ones, or we may go straight
|
||||
* past the urgent marker.
|
||||
*/
|
||||
if (rwx & SELECT_X)
|
||||
select_result(fd, SELECT_X);
|
||||
if (rwx & SELECT_R)
|
||||
select_result(fd, SELECT_R);
|
||||
if (rwx & SELECT_W)
|
||||
select_result(fd, SELECT_W);
|
||||
/*
|
||||
* We must process exceptional notifications before
|
||||
* ordinary readability ones, or we may go straight
|
||||
* past the urgent marker.
|
||||
*/
|
||||
if (rwx & SELECT_X)
|
||||
select_result(fd, SELECT_X);
|
||||
if (rwx & SELECT_R)
|
||||
select_result(fd, SELECT_R);
|
||||
if (rwx & SELECT_W)
|
||||
select_result(fd, SELECT_W);
|
||||
}
|
||||
|
||||
sfree(fdlist);
|
||||
@ -601,31 +601,31 @@ char *ssh_sftp_get_cmdline(const char *prompt, bool no_fds_ok)
|
||||
buflen = bufsize = 0;
|
||||
|
||||
while (1) {
|
||||
ret = ssh_sftp_do_select(true, no_fds_ok);
|
||||
if (ret < 0) {
|
||||
printf("connection died\n");
|
||||
ret = ssh_sftp_do_select(true, no_fds_ok);
|
||||
if (ret < 0) {
|
||||
printf("connection died\n");
|
||||
sfree(buf);
|
||||
return NULL; /* woop woop */
|
||||
}
|
||||
if (ret > 0) {
|
||||
return NULL; /* woop woop */
|
||||
}
|
||||
if (ret > 0) {
|
||||
sgrowarray(buf, bufsize, buflen);
|
||||
ret = read(0, buf+buflen, 1);
|
||||
if (ret < 0) {
|
||||
perror("read");
|
||||
ret = read(0, buf+buflen, 1);
|
||||
if (ret < 0) {
|
||||
perror("read");
|
||||
sfree(buf);
|
||||
return NULL;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* eof on stdin; no error, but no answer either */
|
||||
return NULL;
|
||||
}
|
||||
if (ret == 0) {
|
||||
/* eof on stdin; no error, but no answer either */
|
||||
sfree(buf);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (buf[buflen++] == '\n') {
|
||||
/* we have a full line */
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
if (buf[buflen++] == '\n') {
|
||||
/* we have a full line */
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,13 +17,13 @@
|
||||
void (*putty_signal(int sig, void (*func)(int)))(int) {
|
||||
struct sigaction sa;
|
||||
struct sigaction old;
|
||||
|
||||
|
||||
sa.sa_handler = func;
|
||||
if(sigemptyset(&sa.sa_mask) < 0)
|
||||
return SIG_ERR;
|
||||
return SIG_ERR;
|
||||
sa.sa_flags = SA_RESTART;
|
||||
if(sigaction(sig, &sa, &old) < 0)
|
||||
return SIG_ERR;
|
||||
return SIG_ERR;
|
||||
return old.sa_handler;
|
||||
}
|
||||
|
||||
@ -34,8 +34,8 @@ void block_signal(int sig, bool block_it)
|
||||
sigemptyset(&ss);
|
||||
sigaddset(&ss, sig);
|
||||
if(sigprocmask(block_it ? SIG_BLOCK : SIG_UNBLOCK, &ss, 0) < 0) {
|
||||
perror("sigprocmask");
|
||||
exit(1);
|
||||
perror("sigprocmask");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
282
unix/uxstore.c
282
unix/uxstore.c
@ -46,35 +46,35 @@ static void make_session_filename(const char *in, strbuf *out)
|
||||
* opt-in for safe characters rather than opt-out for
|
||||
* specific unsafe ones...
|
||||
*/
|
||||
if (*in!='+' && *in!='-' && *in!='.' && *in!='@' && *in!='_' &&
|
||||
if (*in!='+' && *in!='-' && *in!='.' && *in!='@' && *in!='_' &&
|
||||
!(*in >= '0' && *in <= '9') &&
|
||||
!(*in >= 'A' && *in <= 'Z') &&
|
||||
!(*in >= 'a' && *in <= 'z')) {
|
||||
put_byte(out, '%');
|
||||
put_byte(out, hex[((unsigned char) *in) >> 4]);
|
||||
put_byte(out, hex[((unsigned char) *in) & 15]);
|
||||
} else
|
||||
put_byte(out, *in);
|
||||
in++;
|
||||
put_byte(out, '%');
|
||||
put_byte(out, hex[((unsigned char) *in) >> 4]);
|
||||
put_byte(out, hex[((unsigned char) *in) & 15]);
|
||||
} else
|
||||
put_byte(out, *in);
|
||||
in++;
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_session_filename(const char *in, strbuf *out)
|
||||
{
|
||||
while (*in) {
|
||||
if (*in == '%' && in[1] && in[2]) {
|
||||
int i, j;
|
||||
if (*in == '%' && in[1] && in[2]) {
|
||||
int i, j;
|
||||
|
||||
i = in[1] - '0';
|
||||
i -= (i > 9 ? 7 : 0);
|
||||
j = in[2] - '0';
|
||||
j -= (j > 9 ? 7 : 0);
|
||||
i = in[1] - '0';
|
||||
i -= (i > 9 ? 7 : 0);
|
||||
j = in[2] - '0';
|
||||
j -= (j > 9 ? 7 : 0);
|
||||
|
||||
put_byte(out, (i << 4) + j);
|
||||
in += 3;
|
||||
} else {
|
||||
put_byte(out, *in++);
|
||||
}
|
||||
put_byte(out, (i << 4) + j);
|
||||
in += 3;
|
||||
} else {
|
||||
put_byte(out, *in++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,15 +87,15 @@ static char *make_filename(int index, const char *subname)
|
||||
* specific subparts of it, by means of environment variables.
|
||||
*/
|
||||
if (index == INDEX_DIR) {
|
||||
struct passwd *pwd;
|
||||
struct passwd *pwd;
|
||||
char *xdg_dir, *old_dir, *old_dir2, *old_dir3, *home, *pwd_home;
|
||||
|
||||
env = getenv("PUTTYDIR");
|
||||
if (env)
|
||||
return dupstr(env);
|
||||
env = getenv("PUTTYDIR");
|
||||
if (env)
|
||||
return dupstr(env);
|
||||
|
||||
home = getenv("HOME");
|
||||
pwd = getpwuid(getuid());
|
||||
pwd = getpwuid(getuid());
|
||||
if (pwd && pwd->pw_dir) {
|
||||
pwd_home = pwd->pw_dir;
|
||||
} else {
|
||||
@ -162,45 +162,45 @@ static char *make_filename(int index, const char *subname)
|
||||
return ret;
|
||||
}
|
||||
if (index == INDEX_SESSIONDIR) {
|
||||
env = getenv("PUTTYSESSIONS");
|
||||
if (env)
|
||||
return dupstr(env);
|
||||
tmp = make_filename(INDEX_DIR, NULL);
|
||||
ret = dupprintf("%s/sessions", tmp);
|
||||
sfree(tmp);
|
||||
return ret;
|
||||
env = getenv("PUTTYSESSIONS");
|
||||
if (env)
|
||||
return dupstr(env);
|
||||
tmp = make_filename(INDEX_DIR, NULL);
|
||||
ret = dupprintf("%s/sessions", tmp);
|
||||
sfree(tmp);
|
||||
return ret;
|
||||
}
|
||||
if (index == INDEX_SESSION) {
|
||||
strbuf *sb = strbuf_new();
|
||||
tmp = make_filename(INDEX_SESSIONDIR, NULL);
|
||||
strbuf_catf(sb, "%s/", tmp);
|
||||
sfree(tmp);
|
||||
tmp = make_filename(INDEX_SESSIONDIR, NULL);
|
||||
strbuf_catf(sb, "%s/", tmp);
|
||||
sfree(tmp);
|
||||
make_session_filename(subname, sb);
|
||||
return strbuf_to_str(sb);
|
||||
}
|
||||
if (index == INDEX_HOSTKEYS) {
|
||||
env = getenv("PUTTYSSHHOSTKEYS");
|
||||
if (env)
|
||||
return dupstr(env);
|
||||
tmp = make_filename(INDEX_DIR, NULL);
|
||||
ret = dupprintf("%s/sshhostkeys", tmp);
|
||||
sfree(tmp);
|
||||
return ret;
|
||||
env = getenv("PUTTYSSHHOSTKEYS");
|
||||
if (env)
|
||||
return dupstr(env);
|
||||
tmp = make_filename(INDEX_DIR, NULL);
|
||||
ret = dupprintf("%s/sshhostkeys", tmp);
|
||||
sfree(tmp);
|
||||
return ret;
|
||||
}
|
||||
if (index == INDEX_HOSTKEYS_TMP) {
|
||||
tmp = make_filename(INDEX_HOSTKEYS, NULL);
|
||||
ret = dupprintf("%s.tmp", tmp);
|
||||
sfree(tmp);
|
||||
return ret;
|
||||
tmp = make_filename(INDEX_HOSTKEYS, NULL);
|
||||
ret = dupprintf("%s.tmp", tmp);
|
||||
sfree(tmp);
|
||||
return ret;
|
||||
}
|
||||
if (index == INDEX_RANDSEED) {
|
||||
env = getenv("PUTTYRANDOMSEED");
|
||||
if (env)
|
||||
return dupstr(env);
|
||||
tmp = make_filename(INDEX_DIR, NULL);
|
||||
ret = dupprintf("%s/randomseed", tmp);
|
||||
sfree(tmp);
|
||||
return ret;
|
||||
env = getenv("PUTTYRANDOMSEED");
|
||||
if (env)
|
||||
return dupstr(env);
|
||||
tmp = make_filename(INDEX_DIR, NULL);
|
||||
ret = dupprintf("%s/randomseed", tmp);
|
||||
sfree(tmp);
|
||||
return ret;
|
||||
}
|
||||
tmp = make_filename(INDEX_DIR, NULL);
|
||||
ret = dupprintf("%s/ERROR", tmp);
|
||||
@ -246,8 +246,8 @@ settings_w *open_settings_w(const char *sessionname, char **errmsg)
|
||||
if (!fp) {
|
||||
*errmsg = dupprintf("Unable to save session: open(\"%s\") "
|
||||
"returned '%s'", filename, strerror(errno));
|
||||
sfree(filename);
|
||||
return NULL; /* can't open */
|
||||
sfree(filename);
|
||||
return NULL; /* can't open */
|
||||
}
|
||||
sfree(filename);
|
||||
|
||||
@ -309,30 +309,30 @@ void provide_xrm_string(const char *string, const char *progname)
|
||||
|
||||
p = q = strchr(string, ':');
|
||||
if (!q) {
|
||||
fprintf(stderr, "%s: expected a colon in resource string"
|
||||
" \"%s\"\n", progname, string);
|
||||
return;
|
||||
fprintf(stderr, "%s: expected a colon in resource string"
|
||||
" \"%s\"\n", progname, string);
|
||||
return;
|
||||
}
|
||||
q++;
|
||||
while (p > string && p[-1] != '.' && p[-1] != '*')
|
||||
p--;
|
||||
p--;
|
||||
xrms = snew(struct skeyval);
|
||||
key = snewn(q-p, char);
|
||||
memcpy(key, p, q-p);
|
||||
key[q-p-1] = '\0';
|
||||
xrms->key = key;
|
||||
while (*q && isspace((unsigned char)*q))
|
||||
q++;
|
||||
q++;
|
||||
xrms->value = dupstr(q);
|
||||
|
||||
if (!xrmtree)
|
||||
xrmtree = newtree234(keycmp);
|
||||
xrmtree = newtree234(keycmp);
|
||||
|
||||
ret = add234(xrmtree, xrms);
|
||||
if (ret) {
|
||||
/* Override an existing string. */
|
||||
del234(xrmtree, ret);
|
||||
add234(xrmtree, xrms);
|
||||
/* Override an existing string. */
|
||||
del234(xrmtree, ret);
|
||||
add234(xrmtree, xrms);
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,9 +341,9 @@ static const char *get_setting(const char *key)
|
||||
struct skeyval tmp, *ret;
|
||||
tmp.key = key;
|
||||
if (xrmtree) {
|
||||
ret = find234(xrmtree, &tmp, NULL);
|
||||
if (ret)
|
||||
return ret->value;
|
||||
ret = find234(xrmtree, &tmp, NULL);
|
||||
if (ret)
|
||||
return ret->value;
|
||||
}
|
||||
return x_get_default(key);
|
||||
}
|
||||
@ -368,7 +368,7 @@ settings_r *open_settings_r(const char *sessionname)
|
||||
fp = fopen(filename, "r");
|
||||
sfree(filename);
|
||||
if (!fp)
|
||||
return NULL; /* can't open */
|
||||
return NULL; /* can't open */
|
||||
|
||||
toret = snew(settings_r);
|
||||
toret->t = newtree234(keycmp);
|
||||
@ -411,9 +411,9 @@ char *read_setting_s(settings_r *handle, const char *key)
|
||||
val = get_setting(key);
|
||||
|
||||
if (!val)
|
||||
return NULL;
|
||||
return NULL;
|
||||
else
|
||||
return dupstr(val);
|
||||
return dupstr(val);
|
||||
}
|
||||
|
||||
int read_setting_i(settings_r *handle, const char *key, int defvalue)
|
||||
@ -430,9 +430,9 @@ int read_setting_i(settings_r *handle, const char *key, int defvalue)
|
||||
val = get_setting(key);
|
||||
|
||||
if (!val)
|
||||
return defvalue;
|
||||
return defvalue;
|
||||
else
|
||||
return atoi(val);
|
||||
return atoi(val);
|
||||
}
|
||||
|
||||
FontSpec *read_setting_fontspec(settings_r *handle, const char *name)
|
||||
@ -441,7 +441,7 @@ FontSpec *read_setting_fontspec(settings_r *handle, const char *name)
|
||||
* In GTK1-only PuTTY, we used to store font names simply as a
|
||||
* valid X font description string (logical or alias), under a
|
||||
* bare key such as "Font".
|
||||
*
|
||||
*
|
||||
* In GTK2 PuTTY, we have a prefix system where "client:"
|
||||
* indicates a Pango font and "server:" an X one; existing
|
||||
* configuration needs to be reinterpreted as having the
|
||||
@ -454,9 +454,9 @@ FontSpec *read_setting_fontspec(settings_r *handle, const char *name)
|
||||
|
||||
if ((tmp = read_setting_s(handle, suffname)) != NULL) {
|
||||
FontSpec *fs = fontspec_new(tmp);
|
||||
sfree(suffname);
|
||||
sfree(tmp);
|
||||
return fs; /* got new-style name */
|
||||
sfree(suffname);
|
||||
sfree(tmp);
|
||||
return fs; /* got new-style name */
|
||||
}
|
||||
sfree(suffname);
|
||||
|
||||
@ -465,12 +465,12 @@ FontSpec *read_setting_fontspec(settings_r *handle, const char *name)
|
||||
if (tmp && *tmp) {
|
||||
char *tmp2 = dupcat("server:", tmp, NULL);
|
||||
FontSpec *fs = fontspec_new(tmp2);
|
||||
sfree(tmp2);
|
||||
sfree(tmp);
|
||||
return fs;
|
||||
sfree(tmp2);
|
||||
sfree(tmp);
|
||||
return fs;
|
||||
} else {
|
||||
sfree(tmp);
|
||||
return NULL;
|
||||
sfree(tmp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Filename *read_setting_filename(settings_r *handle, const char *name)
|
||||
@ -478,10 +478,10 @@ Filename *read_setting_filename(settings_r *handle, const char *name)
|
||||
char *tmp = read_setting_s(handle, name);
|
||||
if (tmp) {
|
||||
Filename *ret = filename_from_str(tmp);
|
||||
sfree(tmp);
|
||||
return ret;
|
||||
sfree(tmp);
|
||||
return ret;
|
||||
} else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void write_setting_fontspec(settings_w *handle, const char *name, FontSpec *fs)
|
||||
@ -565,13 +565,13 @@ bool enum_settings_next(settings_e *handle, strbuf *out)
|
||||
|
||||
while ( (de = readdir(handle->dp)) != NULL ) {
|
||||
fullpath->len = baselen;
|
||||
put_datapl(fullpath, ptrlen_from_asciz(de->d_name));
|
||||
put_datapl(fullpath, ptrlen_from_asciz(de->d_name));
|
||||
|
||||
if (stat(fullpath->s, &st) < 0 || !S_ISREG(st.st_mode))
|
||||
continue; /* try another one */
|
||||
|
||||
decode_session_filename(de->d_name, out);
|
||||
strbuf_free(fullpath);
|
||||
strbuf_free(fullpath);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -588,15 +588,15 @@ void enum_settings_finish(settings_e *handle)
|
||||
|
||||
/*
|
||||
* Lines in the host keys file are of the form
|
||||
*
|
||||
*
|
||||
* type@port:hostname keydata
|
||||
*
|
||||
*
|
||||
* e.g.
|
||||
*
|
||||
*
|
||||
* rsa@22:foovax.example.org 0x23,0x293487364395345345....2343
|
||||
*/
|
||||
int verify_host_key(const char *hostname, int port,
|
||||
const char *keytype, const char *key)
|
||||
const char *keytype, const char *key)
|
||||
{
|
||||
FILE *fp;
|
||||
char *filename;
|
||||
@ -607,57 +607,57 @@ int verify_host_key(const char *hostname, int port,
|
||||
fp = fopen(filename, "r");
|
||||
sfree(filename);
|
||||
if (!fp)
|
||||
return 1; /* key does not exist */
|
||||
return 1; /* key does not exist */
|
||||
|
||||
ret = 1;
|
||||
while ( (line = fgetline(fp)) ) {
|
||||
int i;
|
||||
char *p = line;
|
||||
char porttext[20];
|
||||
int i;
|
||||
char *p = line;
|
||||
char porttext[20];
|
||||
|
||||
line[strcspn(line, "\n")] = '\0'; /* strip trailing newline */
|
||||
line[strcspn(line, "\n")] = '\0'; /* strip trailing newline */
|
||||
|
||||
i = strlen(keytype);
|
||||
if (strncmp(p, keytype, i))
|
||||
goto done;
|
||||
p += i;
|
||||
i = strlen(keytype);
|
||||
if (strncmp(p, keytype, i))
|
||||
goto done;
|
||||
p += i;
|
||||
|
||||
if (*p != '@')
|
||||
goto done;
|
||||
p++;
|
||||
if (*p != '@')
|
||||
goto done;
|
||||
p++;
|
||||
|
||||
sprintf(porttext, "%d", port);
|
||||
i = strlen(porttext);
|
||||
if (strncmp(p, porttext, i))
|
||||
goto done;
|
||||
p += i;
|
||||
sprintf(porttext, "%d", port);
|
||||
i = strlen(porttext);
|
||||
if (strncmp(p, porttext, i))
|
||||
goto done;
|
||||
p += i;
|
||||
|
||||
if (*p != ':')
|
||||
goto done;
|
||||
p++;
|
||||
if (*p != ':')
|
||||
goto done;
|
||||
p++;
|
||||
|
||||
i = strlen(hostname);
|
||||
if (strncmp(p, hostname, i))
|
||||
goto done;
|
||||
p += i;
|
||||
i = strlen(hostname);
|
||||
if (strncmp(p, hostname, i))
|
||||
goto done;
|
||||
p += i;
|
||||
|
||||
if (*p != ' ')
|
||||
goto done;
|
||||
p++;
|
||||
if (*p != ' ')
|
||||
goto done;
|
||||
p++;
|
||||
|
||||
/*
|
||||
* Found the key. Now just work out whether it's the right
|
||||
* one or not.
|
||||
*/
|
||||
if (!strcmp(p, key))
|
||||
ret = 0; /* key matched OK */
|
||||
else
|
||||
ret = 2; /* key mismatch */
|
||||
/*
|
||||
* Found the key. Now just work out whether it's the right
|
||||
* one or not.
|
||||
*/
|
||||
if (!strcmp(p, key))
|
||||
ret = 0; /* key matched OK */
|
||||
else
|
||||
ret = 2; /* key mismatch */
|
||||
|
||||
done:
|
||||
sfree(line);
|
||||
if (ret != 1)
|
||||
break;
|
||||
done:
|
||||
sfree(line);
|
||||
if (ret != 1)
|
||||
break;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
@ -675,7 +675,7 @@ bool have_ssh_host_key(const char *hostname, int port,
|
||||
}
|
||||
|
||||
void store_host_key(const char *hostname, int port,
|
||||
const char *keytype, const char *key)
|
||||
const char *keytype, const char *key)
|
||||
{
|
||||
FILE *rfp, *wfp;
|
||||
char *newtext, *line;
|
||||
@ -698,7 +698,7 @@ void store_host_key(const char *hostname, int port,
|
||||
sfree(tmpfilename);
|
||||
return;
|
||||
}
|
||||
sfree(dir);
|
||||
sfree(dir);
|
||||
|
||||
wfp = fopen(tmpfilename, "w");
|
||||
}
|
||||
@ -754,11 +754,11 @@ void read_random_seed(noise_consumer_t consumer)
|
||||
fd = open(fname, O_RDONLY);
|
||||
sfree(fname);
|
||||
if (fd >= 0) {
|
||||
char buf[512];
|
||||
int ret;
|
||||
while ( (ret = read(fd, buf, sizeof(buf))) > 0)
|
||||
consumer(buf, ret);
|
||||
close(fd);
|
||||
char buf[512];
|
||||
int ret;
|
||||
while ( (ret = read(fd, buf, sizeof(buf))) > 0)
|
||||
consumer(buf, ret);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -783,7 +783,7 @@ void write_random_seed(void *data, int len)
|
||||
}
|
||||
char *dir, *errmsg;
|
||||
|
||||
dir = make_filename(INDEX_DIR, NULL);
|
||||
dir = make_filename(INDEX_DIR, NULL);
|
||||
if ((errmsg = make_dir_path(dir, 0700)) != NULL) {
|
||||
nonfatal("Unable to write random seed: %s", errmsg);
|
||||
sfree(errmsg);
|
||||
@ -791,9 +791,9 @@ void write_random_seed(void *data, int len)
|
||||
sfree(dir);
|
||||
return;
|
||||
}
|
||||
sfree(dir);
|
||||
sfree(dir);
|
||||
|
||||
fd = open(fname, O_CREAT | O_WRONLY, 0600);
|
||||
fd = open(fname, O_CREAT | O_WRONLY, 0600);
|
||||
if (fd < 0) {
|
||||
nonfatal("Unable to write random seed: open(\"%s\") "
|
||||
"returned '%s'", fname, strerror(errno));
|
||||
@ -803,14 +803,14 @@ void write_random_seed(void *data, int len)
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
int ret = write(fd, data, len);
|
||||
if (ret < 0) {
|
||||
int ret = write(fd, data, len);
|
||||
if (ret < 0) {
|
||||
nonfatal("Unable to write random seed: write "
|
||||
"returned '%s'", strerror(errno));
|
||||
break;
|
||||
}
|
||||
len -= ret;
|
||||
data = (char *)data + len;
|
||||
len -= ret;
|
||||
data = (char *)data + len;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
224
unix/uxucs.c
224
unix/uxucs.c
@ -22,76 +22,76 @@ bool is_dbcs_leadbyte(int codepage, char byte)
|
||||
}
|
||||
|
||||
int mb_to_wc(int codepage, int flags, const char *mbstr, int mblen,
|
||||
wchar_t *wcstr, int wclen)
|
||||
wchar_t *wcstr, int wclen)
|
||||
{
|
||||
if (codepage == DEFAULT_CODEPAGE) {
|
||||
int n = 0;
|
||||
mbstate_t state;
|
||||
int n = 0;
|
||||
mbstate_t state;
|
||||
|
||||
memset(&state, 0, sizeof state);
|
||||
memset(&state, 0, sizeof state);
|
||||
|
||||
while (mblen > 0) {
|
||||
size_t i = mbrtowc(wcstr+n, mbstr, (size_t)mblen, &state);
|
||||
if (i == (size_t)-1 || i == (size_t)-2)
|
||||
break;
|
||||
n++;
|
||||
mbstr += i;
|
||||
mblen -= i;
|
||||
}
|
||||
while (mblen > 0) {
|
||||
size_t i = mbrtowc(wcstr+n, mbstr, (size_t)mblen, &state);
|
||||
if (i == (size_t)-1 || i == (size_t)-2)
|
||||
break;
|
||||
n++;
|
||||
mbstr += i;
|
||||
mblen -= i;
|
||||
}
|
||||
|
||||
return n;
|
||||
return n;
|
||||
} else if (codepage == CS_NONE) {
|
||||
int n = 0;
|
||||
int n = 0;
|
||||
|
||||
while (mblen > 0) {
|
||||
wcstr[n] = 0xD800 | (mbstr[0] & 0xFF);
|
||||
n++;
|
||||
mbstr++;
|
||||
mblen--;
|
||||
}
|
||||
while (mblen > 0) {
|
||||
wcstr[n] = 0xD800 | (mbstr[0] & 0xFF);
|
||||
n++;
|
||||
mbstr++;
|
||||
mblen--;
|
||||
}
|
||||
|
||||
return n;
|
||||
return n;
|
||||
} else
|
||||
return charset_to_unicode(&mbstr, &mblen, wcstr, wclen, codepage,
|
||||
NULL, NULL, 0);
|
||||
return charset_to_unicode(&mbstr, &mblen, wcstr, wclen, codepage,
|
||||
NULL, NULL, 0);
|
||||
}
|
||||
|
||||
int wc_to_mb(int codepage, int flags, const wchar_t *wcstr, int wclen,
|
||||
char *mbstr, int mblen, const char *defchr,
|
||||
struct unicode_data *ucsdata)
|
||||
char *mbstr, int mblen, const char *defchr,
|
||||
struct unicode_data *ucsdata)
|
||||
{
|
||||
if (codepage == DEFAULT_CODEPAGE) {
|
||||
char output[MB_LEN_MAX];
|
||||
mbstate_t state;
|
||||
int n = 0;
|
||||
char output[MB_LEN_MAX];
|
||||
mbstate_t state;
|
||||
int n = 0;
|
||||
|
||||
memset(&state, 0, sizeof state);
|
||||
memset(&state, 0, sizeof state);
|
||||
|
||||
while (wclen > 0) {
|
||||
int i = wcrtomb(output, wcstr[0], &state);
|
||||
if (i == (size_t)-1 || i > n - mblen)
|
||||
break;
|
||||
memcpy(mbstr+n, output, i);
|
||||
n += i;
|
||||
wcstr++;
|
||||
wclen--;
|
||||
}
|
||||
while (wclen > 0) {
|
||||
int i = wcrtomb(output, wcstr[0], &state);
|
||||
if (i == (size_t)-1 || i > n - mblen)
|
||||
break;
|
||||
memcpy(mbstr+n, output, i);
|
||||
n += i;
|
||||
wcstr++;
|
||||
wclen--;
|
||||
}
|
||||
|
||||
return n;
|
||||
return n;
|
||||
} else if (codepage == CS_NONE) {
|
||||
int n = 0;
|
||||
while (wclen > 0 && n < mblen) {
|
||||
if (*wcstr >= 0xD800 && *wcstr < 0xD900)
|
||||
mbstr[n++] = (*wcstr & 0xFF);
|
||||
else if (defchr)
|
||||
mbstr[n++] = *defchr;
|
||||
wcstr++;
|
||||
wclen--;
|
||||
}
|
||||
return n;
|
||||
int n = 0;
|
||||
while (wclen > 0 && n < mblen) {
|
||||
if (*wcstr >= 0xD800 && *wcstr < 0xD900)
|
||||
mbstr[n++] = (*wcstr & 0xFF);
|
||||
else if (defchr)
|
||||
mbstr[n++] = *defchr;
|
||||
wcstr++;
|
||||
wclen--;
|
||||
}
|
||||
return n;
|
||||
} else {
|
||||
return charset_from_unicode(&wcstr, &wclen, mbstr, mblen, codepage,
|
||||
NULL, defchr?defchr:NULL, defchr?1:0);
|
||||
return charset_from_unicode(&wcstr, &wclen, mbstr, mblen, codepage,
|
||||
NULL, defchr?defchr:NULL, defchr?1:0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,13 +119,13 @@ bool init_ucs(struct unicode_data *ucsdata, char *linecharset,
|
||||
*/
|
||||
ucsdata->line_codepage = CS_NONE;
|
||||
if (utf8_override) {
|
||||
const char *s;
|
||||
if (((s = getenv("LC_ALL")) && *s) ||
|
||||
((s = getenv("LC_CTYPE")) && *s) ||
|
||||
((s = getenv("LANG")) && *s)) {
|
||||
if (strstr(s, "UTF-8"))
|
||||
ucsdata->line_codepage = CS_UTF8;
|
||||
}
|
||||
const char *s;
|
||||
if (((s = getenv("LC_ALL")) && *s) ||
|
||||
((s = getenv("LC_CTYPE")) && *s) ||
|
||||
((s = getenv("LANG")) && *s)) {
|
||||
if (strstr(s, "UTF-8"))
|
||||
ucsdata->line_codepage = CS_UTF8;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -133,7 +133,7 @@ bool init_ucs(struct unicode_data *ucsdata, char *linecharset,
|
||||
* specification in conf.
|
||||
*/
|
||||
if (ucsdata->line_codepage == CS_NONE)
|
||||
ucsdata->line_codepage = decode_codepage(linecharset);
|
||||
ucsdata->line_codepage = decode_codepage(linecharset);
|
||||
|
||||
/*
|
||||
* If line_codepage is _still_ CS_NONE, we assume we're using
|
||||
@ -143,64 +143,64 @@ bool init_ucs(struct unicode_data *ucsdata, char *linecharset,
|
||||
* fall back to using the D800 page.
|
||||
*/
|
||||
if (ucsdata->line_codepage == CS_NONE)
|
||||
ucsdata->line_codepage = font_charset;
|
||||
ucsdata->line_codepage = font_charset;
|
||||
|
||||
if (ucsdata->line_codepage == CS_NONE)
|
||||
ret = true;
|
||||
ret = true;
|
||||
|
||||
/*
|
||||
* Set up unitab_line, by translating each individual character
|
||||
* in the line codepage into Unicode.
|
||||
*/
|
||||
for (i = 0; i < 256; i++) {
|
||||
char c[1];
|
||||
char c[1];
|
||||
const char *p;
|
||||
wchar_t wc[1];
|
||||
int len;
|
||||
c[0] = i;
|
||||
p = c;
|
||||
len = 1;
|
||||
if (ucsdata->line_codepage == CS_NONE)
|
||||
ucsdata->unitab_line[i] = 0xD800 | i;
|
||||
else if (1 == charset_to_unicode(&p, &len, wc, 1,
|
||||
ucsdata->line_codepage,
|
||||
NULL, L"", 0))
|
||||
ucsdata->unitab_line[i] = wc[0];
|
||||
else
|
||||
ucsdata->unitab_line[i] = 0xFFFD;
|
||||
wchar_t wc[1];
|
||||
int len;
|
||||
c[0] = i;
|
||||
p = c;
|
||||
len = 1;
|
||||
if (ucsdata->line_codepage == CS_NONE)
|
||||
ucsdata->unitab_line[i] = 0xD800 | i;
|
||||
else if (1 == charset_to_unicode(&p, &len, wc, 1,
|
||||
ucsdata->line_codepage,
|
||||
NULL, L"", 0))
|
||||
ucsdata->unitab_line[i] = wc[0];
|
||||
else
|
||||
ucsdata->unitab_line[i] = 0xFFFD;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up unitab_xterm. This is the same as unitab_line except
|
||||
* in the line-drawing regions, where it follows the Unicode
|
||||
* encoding.
|
||||
*
|
||||
*
|
||||
* (Note that the strange X encoding of line-drawing characters
|
||||
* in the bottom 32 glyphs of ISO8859-1 fonts is taken care of
|
||||
* by the font encoding, which will spot such a font and act as
|
||||
* if it were in a variant encoding of ISO8859-1.)
|
||||
*/
|
||||
for (i = 0; i < 256; i++) {
|
||||
static const wchar_t unitab_xterm_std[32] = {
|
||||
0x2666, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
|
||||
0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
|
||||
0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
|
||||
0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x0020
|
||||
};
|
||||
static const wchar_t unitab_xterm_poorman[32] =
|
||||
L"*#****o~**+++++-----++++|****L. ";
|
||||
static const wchar_t unitab_xterm_std[32] = {
|
||||
0x2666, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
|
||||
0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
|
||||
0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
|
||||
0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x0020
|
||||
};
|
||||
static const wchar_t unitab_xterm_poorman[32] =
|
||||
L"*#****o~**+++++-----++++|****L. ";
|
||||
|
||||
const wchar_t *ptr;
|
||||
const wchar_t *ptr;
|
||||
|
||||
if (vtmode == VT_POORMAN)
|
||||
ptr = unitab_xterm_poorman;
|
||||
else
|
||||
ptr = unitab_xterm_std;
|
||||
if (vtmode == VT_POORMAN)
|
||||
ptr = unitab_xterm_poorman;
|
||||
else
|
||||
ptr = unitab_xterm_std;
|
||||
|
||||
if (i >= 0x5F && i < 0x7F)
|
||||
ucsdata->unitab_xterm[i] = ptr[i & 0x1F];
|
||||
else
|
||||
ucsdata->unitab_xterm[i] = ucsdata->unitab_line[i];
|
||||
if (i >= 0x5F && i < 0x7F)
|
||||
ucsdata->unitab_xterm[i] = ptr[i & 0x1F];
|
||||
else
|
||||
ucsdata->unitab_xterm[i] = ucsdata->unitab_line[i];
|
||||
}
|
||||
|
||||
/*
|
||||
@ -208,17 +208,17 @@ bool init_ucs(struct unicode_data *ucsdata, char *linecharset,
|
||||
* simply CP437.
|
||||
*/
|
||||
for (i = 0; i < 256; i++) {
|
||||
char c[1];
|
||||
char c[1];
|
||||
const char *p;
|
||||
wchar_t wc[1];
|
||||
int len;
|
||||
c[0] = i;
|
||||
p = c;
|
||||
len = 1;
|
||||
if (1 == charset_to_unicode(&p, &len, wc, 1, CS_CP437, NULL, L"", 0))
|
||||
ucsdata->unitab_scoacs[i] = wc[0];
|
||||
else
|
||||
ucsdata->unitab_scoacs[i] = 0xFFFD;
|
||||
wchar_t wc[1];
|
||||
int len;
|
||||
c[0] = i;
|
||||
p = c;
|
||||
len = 1;
|
||||
if (1 == charset_to_unicode(&p, &len, wc, 1, CS_CP437, NULL, L"", 0))
|
||||
ucsdata->unitab_scoacs[i] = wc[0];
|
||||
else
|
||||
ucsdata->unitab_scoacs[i] = 0xFFFD;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -229,12 +229,12 @@ bool init_ucs(struct unicode_data *ucsdata, char *linecharset,
|
||||
* used in this way will be IBM or MS code pages anyway.)
|
||||
*/
|
||||
for (i = 0; i < 256; i++) {
|
||||
int lineval = ucsdata->unitab_line[i];
|
||||
if (lineval < ' ' || (lineval >= 0x7F && lineval < 0xA0) ||
|
||||
(lineval >= 0xD800 && lineval < 0xD820) || (lineval == 0xD87F))
|
||||
ucsdata->unitab_ctrl[i] = i;
|
||||
else
|
||||
ucsdata->unitab_ctrl[i] = 0xFF;
|
||||
int lineval = ucsdata->unitab_line[i];
|
||||
if (lineval < ' ' || (lineval >= 0x7F && lineval < 0xA0) ||
|
||||
(lineval >= 0xD800 && lineval < 0xD820) || (lineval == 0xD87F))
|
||||
ucsdata->unitab_ctrl[i] = i;
|
||||
else
|
||||
ucsdata->unitab_ctrl[i] = 0xFF;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -243,7 +243,7 @@ bool init_ucs(struct unicode_data *ucsdata, char *linecharset,
|
||||
const char *cp_name(int codepage)
|
||||
{
|
||||
if (codepage == CS_NONE)
|
||||
return "Use font encoding";
|
||||
return "Use font encoding";
|
||||
return charset_to_localenc(codepage);
|
||||
}
|
||||
|
||||
@ -255,7 +255,7 @@ const char *cp_enumerate(int index)
|
||||
/* "Use font encoding" comes after all the named charsets */
|
||||
if (charset_localenc_nth(index-1) != CS_NONE)
|
||||
return "Use font encoding";
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
return charset_to_localenc(charset);
|
||||
}
|
||||
@ -263,6 +263,6 @@ const char *cp_enumerate(int index)
|
||||
int decode_codepage(char *cp_name)
|
||||
{
|
||||
if (!cp_name || !*cp_name)
|
||||
return CS_UTF8;
|
||||
return CS_UTF8;
|
||||
return charset_from_localenc(cp_name);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* xkeysym.c: mapping from X keysyms to Unicode values
|
||||
*
|
||||
*
|
||||
* The basic idea of this is shamelessly cribbed from xterm. The
|
||||
* actual character data is generated from Markus Kuhn's proposed
|
||||
* redraft of the X11 keysym mapping table, using the following
|
||||
@ -999,13 +999,13 @@ int keysym_to_unicode(int keysym)
|
||||
j = lenof(keysyms);
|
||||
|
||||
while (j - i >= 2) {
|
||||
k = (j + i) / 2;
|
||||
if (keysyms[k].keysym == keysym)
|
||||
return keysyms[k].unicode;
|
||||
else if (keysyms[k].keysym < keysym)
|
||||
i = k;
|
||||
else
|
||||
j = k;
|
||||
k = (j + i) / 2;
|
||||
if (keysyms[k].keysym == keysym)
|
||||
return keysyms[k].unicode;
|
||||
else if (keysyms[k].keysym < keysym)
|
||||
i = k;
|
||||
else
|
||||
j = k;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
Reference in New Issue
Block a user