1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2 
3 /* Note that protocols except ssh aren't supported if USE_LIBSSH2 is defined. */
4 #ifdef USE_LIBSSH2
5 
6 #include <stdio.h>
7 #include <pobl/bl_str.h>
8 #include <pobl/bl_mem.h>
9 
10 #include "../ui_connect_dialog.h"
11 #include "../ui_screen.h"
12 #ifdef USE_WAYLAND
13 #include "ui_display.h"
14 #define ui_display_receive_next_event(disp) ui_display_receive_next_event_singly(disp)
15 #endif
16 
17 /* --- static variables --- */
18 
19 static int end_input;
20 static char *password;
21 static size_t password_len;
22 
23 /* --- static functions --- */
24 
key_pressed(ui_window_t * win,XKeyEvent * event)25 static void key_pressed(ui_window_t *win, XKeyEvent *event) {
26   u_char seq[1];
27   KeySym ksym;
28   ef_parser_t *parser;
29 
30   if (ui_window_get_str(win, seq, 1, &parser, &ksym, event) == 0) {
31     return;
32   }
33 
34   if (ksym == XK_Return) {
35     if (!password) {
36       password = strdup("");
37     }
38 
39     end_input = 1;
40   } else {
41     if (ksym == XK_BackSpace) {
42       if (password_len > 0) {
43         password[--password_len] = '\0';
44       }
45     } else if (0x20 <= seq[0] && seq[0] <= 0x7e) {
46       void *p;
47 
48       if ((p = realloc(password, password_len + 2))) {
49         password = p;
50         password[password_len++] = seq[0];
51         password[password_len] = '\0';
52       }
53     }
54   }
55 }
56 
57 
58 /* --- global functions --- */
59 
ui_connect_dialog(char ** uri,char ** pass,char ** exec_cmd,char ** privkey,int * x11_fwd,char * display_name,Window parent_window,char * def_server)60 int ui_connect_dialog(char **uri,      /* Should be free'ed by those who call this. */
61                       char **pass,     /* Same as uri. If pass is not input, "" is set. */
62                       char **exec_cmd, /* Same as uri. If exec_cmd is not input, NULL is set. */
63                       char **privkey,  /* in/out */
64                       int *x11_fwd,    /* in/out */
65                       char *display_name, Window parent_window,
66                       char *def_server /* (<user>@)(<proto>:)<server address>(:<encoding>). */
67                       ) {
68   ui_screen_t *screen;
69   char *prompt;
70   size_t prompt_len;
71   void (*orig_key_pressed)();
72 
73   prompt_len = 12 + strlen(def_server) + 11;
74   if (!(prompt = alloca(prompt_len + 1))) {
75     return 0;
76   }
77 
78   sprintf(prompt, " Connect to %s. Password:", def_server);
79 
80   if (!(*uri = strdup(def_server))) {
81     return 0;
82   }
83 
84   screen = (ui_screen_t *)parent_window;
85 
86   orig_key_pressed = screen->window.key_pressed;
87   screen->window.key_pressed = key_pressed;
88 
89   ui_window_clear_all(&screen->window);
90 
91 #ifndef USE_CONSOLE
92   ui_window_draw_image_string(&screen->window, ui_get_usascii_font(screen->font_man),
93                               ui_get_xcolor(screen->color_man, VT_FG_COLOR),
94                               ui_get_xcolor(screen->color_man, VT_BG_COLOR), 0,
95                               ui_line_ascent(screen), prompt, prompt_len);
96 #endif
97 
98   do {
99 #ifdef USE_CONSOLE
100     /*
101      * prompt is redrawn every time because ui_display_receive_next_event() receives
102      * "\x1b[8;%d;%d;4;%d;%dt" in startup.
103      */
104     ui_window_console_draw_string(&screen->window, ui_get_usascii_font(screen->font_man),
105                                   ui_get_xcolor(screen->color_man, VT_FG_COLOR),
106                                   ui_get_xcolor(screen->color_man, VT_BG_COLOR), 0,
107                                   ui_line_ascent(screen), prompt, prompt_len, 0);
108 #endif
109 #ifdef USE_SDL2
110     {
111       u_int num;
112       ui_get_opened_displays(&num);
113     }
114 #else
115     ui_display_receive_next_event(screen->window.disp);
116 #endif
117   } while (!end_input);
118 
119   end_input = 0;
120   screen->window.key_pressed = orig_key_pressed;
121 
122   if (!password) {
123     free(*uri);
124 
125     return 0;
126   }
127 
128   *pass = password;
129   password = NULL;
130   password_len = 0;
131 
132   *exec_cmd = NULL;
133 
134 #if 0
135   ui_window_update_all(&screen->window);
136 #endif
137 
138   return 1;
139 }
140 
141 #endif
142