platform.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /*
  2. * unix/platform.h: Unix-specific inter-module stuff.
  3. */
  4. #ifndef PUTTY_UNIX_PLATFORM_H
  5. #define PUTTY_UNIX_PLATFORM_H
  6. #include <stdio.h> /* for FILENAME_MAX */
  7. #include <stdint.h> /* C99 int types */
  8. #ifndef NO_LIBDL
  9. #include <dlfcn.h> /* Dynamic library loading */
  10. #endif /* NO_LIBDL */
  11. #include "charset.h"
  12. #include <sys/types.h> /* for mode_t */
  13. #ifdef OSX_GTK
  14. /*
  15. * Assorted tweaks to various parts of the GTK front end which all
  16. * need to be enabled when compiling on OS X. Because I might need the
  17. * same tweaks on other systems in future, I don't want to
  18. * conditionalise all of them on OSX_GTK directly, so instead, each
  19. * one has its own name and we enable them all centrally here if
  20. * OSX_GTK is defined at configure time.
  21. */
  22. #define NOT_X_WINDOWS /* of course, all the X11 stuff should be disabled */
  23. #define NO_PTY_PRE_INIT /* OS X gets very huffy if we try to set[ug]id */
  24. #define SET_NONBLOCK_VIA_OPENPT /* work around missing fcntl functionality */
  25. #define OSX_META_KEY_CONFIG /* two possible Meta keys to choose from */
  26. /* this potential one of the Meta keys needs manual handling */
  27. #define META_MANUAL_MASK (GDK_MOD1_MASK)
  28. #define JUST_USE_GTK_CLIPBOARD_UTF8 /* low-level gdk_selection_* fails */
  29. #define BUILDINFO_PLATFORM_GTK "OS X (GTK)"
  30. #define BUILDINFO_GTK
  31. #elif defined NOT_X_WINDOWS
  32. #define BUILDINFO_PLATFORM_GTK "Unix (pure GTK)"
  33. #define BUILDINFO_GTK
  34. #else
  35. #define BUILDINFO_PLATFORM_GTK "Unix (GTK + X11)"
  36. #define BUILDINFO_GTK
  37. #endif
  38. /* BUILDINFO_PLATFORM varies its expansion between the GTK and
  39. * pure-CLI utilities, so that Unix Plink, PSFTP etc don't announce
  40. * themselves incongruously as having something to do with GTK. */
  41. #define BUILDINFO_PLATFORM_CLI "Unix"
  42. extern const bool buildinfo_gtk_relevant;
  43. #define BUILDINFO_PLATFORM (buildinfo_gtk_relevant ? \
  44. BUILDINFO_PLATFORM_GTK : BUILDINFO_PLATFORM_CLI)
  45. char *buildinfo_gtk_version(void);
  46. struct Filename {
  47. char *path;
  48. };
  49. FILE *f_open(const struct Filename *, char const *, bool);
  50. #ifndef SUPERSEDE_FONTSPEC_FOR_TESTING
  51. struct FontSpec {
  52. char *name; /* may be "" to indicate no selected font at all */
  53. };
  54. struct FontSpec *fontspec_new(const char *name);
  55. #endif
  56. extern const struct BackendVtable pty_backend;
  57. #define BROKEN_PIPE_ERROR_CODE EPIPE /* used in ssh/sharing.c */
  58. /*
  59. * Under GTK, we send MA_CLICK _and_ MA_2CLK, or MA_CLICK _and_
  60. * MA_3CLK, when a button is pressed for the second or third time.
  61. */
  62. #define MULTICLICK_ONLY_EVENT 0
  63. /*
  64. * Under GTK, there is no context help available.
  65. */
  66. typedef void *HelpCtx;
  67. #define NULL_HELPCTX ((HelpCtx)NULL)
  68. #define HELPCTX(x) NULL
  69. typedef const char *FILESELECT_FILTER_TYPE;
  70. #define FILTER_KEY_FILES NULL /* FIXME */
  71. #define FILTER_DYNLIB_FILES NULL /* FIXME */
  72. /*
  73. * Under X, selection data must not be NUL-terminated.
  74. */
  75. #define SELECTION_NUL_TERMINATED 0
  76. /*
  77. * Under X, copying to the clipboard terminates lines with just LF.
  78. */
  79. #define SEL_NL { 10 }
  80. /* Simple wraparound timer function */
  81. unsigned long getticks(void);
  82. #define GETTICKCOUNT getticks
  83. #define TICKSPERSEC 1000 /* we choose to use milliseconds */
  84. #define CURSORBLINK 450 /* no standard way to set this */
  85. #define WCHAR wchar_t
  86. #define BYTE unsigned char
  87. #define PLATFORM_CLIPBOARDS(X) \
  88. X(CLIP_PRIMARY, "X11 primary selection") \
  89. X(CLIP_CLIPBOARD, "XDG clipboard") \
  90. X(CLIP_CUSTOM_1, "<custom#1>") \
  91. X(CLIP_CUSTOM_2, "<custom#2>") \
  92. X(CLIP_CUSTOM_3, "<custom#3>") \
  93. /* end of list */
  94. #ifdef OSX_GTK
  95. /* OS X has no PRIMARY selection */
  96. #define MOUSE_SELECT_CLIPBOARD CLIP_NULL
  97. #define MOUSE_PASTE_CLIPBOARD CLIP_LOCAL
  98. #define CLIPNAME_IMPLICIT "Last selected text"
  99. #define CLIPNAME_EXPLICIT "System clipboard"
  100. #define CLIPNAME_EXPLICIT_OBJECT "system clipboard"
  101. /* These defaults are the ones that more or less comply with the OS X
  102. * Human Interface Guidelines, i.e. copy/paste to the system clipboard
  103. * is _not_ implicit but requires a specific UI action. This is at
  104. * odds with all other PuTTY front ends' defaults, but on OS X there
  105. * is no multi-decade precedent for PuTTY working the other way. */
  106. #define CLIPUI_DEFAULT_AUTOCOPY false
  107. #define CLIPUI_DEFAULT_MOUSE CLIPUI_IMPLICIT
  108. #define CLIPUI_DEFAULT_INS CLIPUI_EXPLICIT
  109. #define MENU_CLIPBOARD CLIP_CLIPBOARD
  110. #define COPYALL_CLIPBOARDS CLIP_CLIPBOARD
  111. #else
  112. #define MOUSE_SELECT_CLIPBOARD CLIP_PRIMARY
  113. #define MOUSE_PASTE_CLIPBOARD CLIP_PRIMARY
  114. #define CLIPNAME_IMPLICIT "PRIMARY"
  115. #define CLIPNAME_EXPLICIT "CLIPBOARD"
  116. #define CLIPNAME_EXPLICIT_OBJECT "CLIPBOARD"
  117. /* These defaults are the ones Unix PuTTY has historically had since
  118. * it was first thought of in 2002 */
  119. #define CLIPUI_DEFAULT_AUTOCOPY false
  120. #define CLIPUI_DEFAULT_MOUSE CLIPUI_IMPLICIT
  121. #define CLIPUI_DEFAULT_INS CLIPUI_IMPLICIT
  122. #define MENU_CLIPBOARD CLIP_CLIPBOARD
  123. #define COPYALL_CLIPBOARDS CLIP_PRIMARY, CLIP_CLIPBOARD
  124. /* X11 supports arbitrary named clipboards */
  125. #define NAMED_CLIPBOARDS
  126. #endif
  127. /* The per-session frontend structure managed by window.c */
  128. typedef struct GtkFrontend GtkFrontend;
  129. /* Callback when a dialog box finishes, and a no-op implementation of it */
  130. typedef void (*post_dialog_fn_t)(void *ctx, int result);
  131. void trivial_post_dialog_fn(void *vctx, int result);
  132. /* Start up a session window, with or without a preliminary config box */
  133. void initial_config_box(Conf *conf, post_dialog_fn_t after, void *afterctx);
  134. void new_session_window(Conf *conf, const char *geometry_string);
  135. /* Defined in main-gtk-*.c */
  136. void launch_duplicate_session(Conf *conf);
  137. void launch_new_session(void);
  138. void launch_saved_session(const char *str);
  139. void session_window_closed(void);
  140. void window_setup_error(const char *errmsg);
  141. #ifdef MAY_REFER_TO_GTK_IN_HEADERS
  142. GtkWidget *make_gtk_toplevel_window(GtkFrontend *frontend);
  143. #endif
  144. const struct BackendVtable *select_backend(Conf *conf);
  145. /* Defined in gtk-common.c */
  146. void gtkcomm_setup(void);
  147. /* Used to pass application-menu operations from
  148. * main-gtk-application.c to window.c */
  149. enum MenuAction {
  150. MA_COPY, MA_PASTE, MA_COPY_ALL, MA_DUPLICATE_SESSION,
  151. MA_RESTART_SESSION, MA_CHANGE_SETTINGS, MA_CLEAR_SCROLLBACK,
  152. MA_RESET_TERMINAL, MA_EVENT_LOG
  153. };
  154. void app_menu_action(GtkFrontend *frontend, enum MenuAction);
  155. /* Arrays of pixmap data used for GTK window icons. (main_icon is for
  156. * the process's main window; cfg_icon is the modified icon used for
  157. * its config box.) */
  158. extern const char *const *const main_icon[];
  159. extern const char *const *const cfg_icon[];
  160. extern const int n_main_icon, n_cfg_icon;
  161. /* Things dialog.c needs from window.c */
  162. #ifdef MAY_REFER_TO_GTK_IN_HEADERS
  163. enum DialogSlot {
  164. DIALOG_SLOT_RECONFIGURE,
  165. DIALOG_SLOT_NETWORK_PROMPT,
  166. DIALOG_SLOT_LOGFILE_PROMPT,
  167. DIALOG_SLOT_WARN_ON_CLOSE,
  168. DIALOG_SLOT_CONNECTION_FATAL,
  169. DIALOG_SLOT_LIMIT /* must remain last */
  170. };
  171. GtkWidget *gtk_seat_get_window(Seat *seat);
  172. void register_dialog(Seat *seat, enum DialogSlot slot, GtkWidget *dialog);
  173. void unregister_dialog(Seat *seat, enum DialogSlot slot);
  174. void set_window_icon(GtkWidget *window, const char *const *const *icon,
  175. int n_icon);
  176. extern GdkAtom compound_text_atom;
  177. #endif
  178. /* Things window.c needs from dialog.c */
  179. #ifdef MAY_REFER_TO_GTK_IN_HEADERS
  180. GtkWidget *create_config_box(const char *title, Conf *conf,
  181. bool midsession, int protcfginfo,
  182. post_dialog_fn_t after, void *afterctx);
  183. #endif
  184. void nonfatal_message_box(void *window, const char *msg);
  185. void about_box(void *window);
  186. typedef struct eventlog_stuff eventlog_stuff;
  187. eventlog_stuff *eventlogstuff_new(void);
  188. void eventlogstuff_free(eventlog_stuff *);
  189. void showeventlog(eventlog_stuff *estuff, void *parentwin);
  190. void logevent_dlg(eventlog_stuff *estuff, const char *string);
  191. int gtkdlg_askappend(Seat *seat, Filename *filename,
  192. void (*callback)(void *ctx, int result), void *ctx);
  193. SeatPromptResult gtk_seat_confirm_ssh_host_key(
  194. Seat *seat, const char *host, int port, const char *keytype,
  195. char *keystr, SeatDialogText *text, HelpCtx helpctx,
  196. void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
  197. SeatPromptResult gtk_seat_confirm_weak_crypto_primitive(
  198. Seat *seat, SeatDialogText *text,
  199. void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
  200. SeatPromptResult gtk_seat_confirm_weak_cached_hostkey(
  201. Seat *seat, SeatDialogText *text,
  202. void (*callback)(void *ctx, SeatPromptResult result), void *ctx);
  203. const SeatDialogPromptDescriptions *gtk_seat_prompt_descriptions(Seat *seat);
  204. #ifdef MAY_REFER_TO_GTK_IN_HEADERS
  205. struct message_box_button {
  206. const char *title;
  207. char shortcut;
  208. int type; /* more negative means more appropriate to be the Esc action */
  209. int value; /* message box's return value if this is pressed */
  210. };
  211. struct message_box_buttons {
  212. const struct message_box_button *buttons;
  213. int nbuttons;
  214. };
  215. extern const struct message_box_buttons buttons_yn, buttons_ok;
  216. GtkWidget *create_message_box(
  217. GtkWidget *parentwin, const char *title, const char *msg, int minwid,
  218. bool selectable, const struct message_box_buttons *buttons,
  219. post_dialog_fn_t after, void *afterctx);
  220. #endif
  221. void show_ca_config_box_synchronously(void);
  222. /* window.c needs this special function in utils */
  223. int keysym_to_unicode(int keysym);
  224. /* Things storage.c needs from window.c */
  225. char *x_get_default(const char *key);
  226. /* Things storage.c provides to window.c */
  227. void provide_xrm_string(const char *string, const char *progname);
  228. /* Function that main-gtk-*.c needs from {pterm,putty}.c. Does
  229. * early process setup that varies between applications (e.g.
  230. * pty_pre_init or sk_init), and is passed a boolean by the caller
  231. * indicating whether this is an OS X style multi-session monolithic
  232. * process or an ordinary Unix one-shot. */
  233. void setup(bool single_session_in_this_process);
  234. /*
  235. * Per-application constants that affect behaviour of shared modules.
  236. */
  237. /* Do we need an Event Log menu item? (yes for PuTTY, no for pterm) */
  238. extern const bool use_event_log;
  239. /* Do we need a New Session menu item? (yes for PuTTY, no for pterm) */
  240. extern const bool new_session;
  241. /* Do we need a Saved Sessions menu item? (yes for PuTTY, no for pterm) */
  242. extern const bool saved_sessions;
  243. /* When we Duplicate Session, do we need to double-check that the Conf
  244. * is in a launchable state? (no for pterm, because conf_launchable
  245. * returns an irrelevant answer, since we'll force use of the pty
  246. * backend which ignores all the relevant settings) */
  247. extern const bool dup_check_launchable;
  248. /* In the Duplicate Session serialised data, do we send/receive an
  249. * argv array after the main Conf? (yes for pterm, no for PuTTY) */
  250. extern const bool use_pty_argv;
  251. /*
  252. * OS X environment munging: this is the prefix we expect to find on
  253. * environment variable names that were changed by osxlaunch.
  254. * Extracted from the command line of the OS X pterm main binary, and
  255. * used in pty.c to restore the original environment before
  256. * launching its subprocess.
  257. */
  258. extern char *pty_osx_envrestore_prefix;
  259. /* Things provided by console.c */
  260. struct termios;
  261. void stderr_tty_init(void); /* call at startup if stderr might be a tty */
  262. void premsg(struct termios *);
  263. void postmsg(struct termios *);
  264. /* The interface used by uxsel.c */
  265. typedef struct uxsel_id uxsel_id;
  266. void uxsel_init(void);
  267. typedef void (*uxsel_callback_fn)(int fd, int event);
  268. void uxsel_set(int fd, int rwx, uxsel_callback_fn callback);
  269. void uxsel_del(int fd);
  270. enum { SELECT_R = 1, SELECT_W = 2, SELECT_X = 4 };
  271. void select_result(int fd, int event);
  272. int first_fd(int *state, int *rwx);
  273. int next_fd(int *state, int *rwx);
  274. /* The following are expected to be provided _to_ uxsel.c by the frontend */
  275. uxsel_id *uxsel_input_add(int fd, int rwx); /* returns an id */
  276. void uxsel_input_remove(uxsel_id *id);
  277. /* config-unix.c */
  278. struct controlbox;
  279. void unix_setup_config_box(
  280. struct controlbox *b, bool midsession, int protocol);
  281. /* config-gtk.c */
  282. void gtk_setup_config_box(
  283. struct controlbox *b, bool midsession, void *window);
  284. /*
  285. * In the Unix Unicode layer, DEFAULT_CODEPAGE is a special value
  286. * which causes mb_to_wc and wc_to_mb to call _libc_ rather than
  287. * libcharset. That way, we can interface the various charsets
  288. * supported by libcharset with the one supported by mbstowcs and
  289. * wcstombs (which will be the character set in which stuff read
  290. * from the command line or config files is assumed to be encoded).
  291. */
  292. #define DEFAULT_CODEPAGE 0xFFFF
  293. #define CP_UTF8 CS_UTF8 /* from libcharset */
  294. #define CP_437 CS_CP437 /* used for test suites */
  295. #define CP_ISO8859_1 CS_ISO8859_1 /* used for test suites */
  296. #define strnicmp strncasecmp
  297. #define stricmp strcasecmp
  298. /* BSD-semantics version of signal(), and another helpful function */
  299. void (*putty_signal(int sig, void (*func)(int)))(int);
  300. void block_signal(int sig, bool block_it);
  301. /* utils */
  302. void cloexec(int);
  303. void noncloexec(int);
  304. bool nonblock(int);
  305. bool no_nonblock(int);
  306. char *make_dir_and_check_ours(const char *dirname);
  307. char *make_dir_path(const char *path, mode_t mode);
  308. /*
  309. * Exports from unicode.c.
  310. */
  311. bool init_ucs(struct unicode_data *ucsdata, char *line_codepage,
  312. bool utf8_override, int font_charset, int vtmode);
  313. /*
  314. * Spare functions exported directly from network.c.
  315. */
  316. void *sk_getxdmdata(Socket *sock, int *lenp);
  317. int sk_net_get_fd(Socket *sock);
  318. SockAddr *unix_sock_addr(const char *path);
  319. Socket *new_unix_listener(SockAddr *listenaddr, Plug *plug);
  320. /*
  321. * General helpful Unix stuff: more helpful version of the FD_SET
  322. * macro, which also handles maxfd.
  323. */
  324. #define FD_SET_MAX(fd, max, set) do { \
  325. FD_SET(fd, &set); \
  326. if (max < fd + 1) max = fd + 1; \
  327. } while (0)
  328. /*
  329. * Exports from serial.c.
  330. */
  331. extern const struct BackendVtable serial_backend;
  332. /*
  333. * peerinfo.c, wrapping getsockopt(SO_PEERCRED).
  334. */
  335. bool so_peercred(int fd, int *pid, int *uid, int *gid);
  336. /*
  337. * fd-socket.c.
  338. */
  339. Socket *make_fd_socket(int infd, int outfd, int inerrfd,
  340. SockAddr *addr, int port, Plug *plug);
  341. Socket *make_deferred_fd_socket(DeferredSocketOpener *opener,
  342. SockAddr *addr, int port, Plug *plug);
  343. void setup_fd_socket(Socket *s, int infd, int outfd, int inerrfd);
  344. void fd_socket_set_psb_prefix(Socket *s, const char *prefix);
  345. /*
  346. * Default font setting, which can vary depending on NOT_X_WINDOWS.
  347. */
  348. #ifdef NOT_X_WINDOWS
  349. #define DEFAULT_GTK_FONT "client:Monospace 12"
  350. #else
  351. #define DEFAULT_GTK_FONT "server:fixed"
  352. #endif
  353. /*
  354. * pty.c.
  355. */
  356. void pty_pre_init(void); /* pty+utmp setup before dropping privilege */
  357. /* Pass in the argv[] for an instance of the pty backend created by
  358. * the standard vtable constructor. Only called from (non-OSX) pterm,
  359. * which will construct exactly one such instance, and initialises
  360. * this from the command line. */
  361. extern char **pty_argv;
  362. /*
  363. * askpass.c.
  364. */
  365. char *gtk_askpass_main(const char *display, const char *wintitle,
  366. const char *prompt, bool *success);
  367. /*
  368. * procnet.c.
  369. */
  370. bool socket_peer_is_same_user(int fd);
  371. static inline bool sk_peer_trusted(Socket *sock)
  372. {
  373. int fd = sk_net_get_fd(sock);
  374. return fd >= 0 && socket_peer_is_same_user(fd);
  375. }
  376. /*
  377. * sftpserver.c.
  378. */
  379. extern const SftpServerVtable unix_live_sftpserver_vt;
  380. /*
  381. * utils/pollwrap.c.
  382. */
  383. typedef struct pollwrapper pollwrapper;
  384. pollwrapper *pollwrap_new(void);
  385. void pollwrap_free(pollwrapper *pw);
  386. void pollwrap_clear(pollwrapper *pw);
  387. void pollwrap_add_fd_events(pollwrapper *pw, int fd, int events);
  388. void pollwrap_add_fd_rwx(pollwrapper *pw, int fd, int rwx);
  389. int pollwrap_poll_instant(pollwrapper *pw);
  390. int pollwrap_poll_endless(pollwrapper *pw);
  391. int pollwrap_poll_timeout(pollwrapper *pw, int milliseconds);
  392. int pollwrap_get_fd_events(pollwrapper *pw, int fd);
  393. int pollwrap_get_fd_rwx(pollwrapper *pw, int fd);
  394. static inline bool pollwrap_check_fd_rwx(pollwrapper *pw, int fd, int rwx)
  395. {
  396. return (pollwrap_get_fd_rwx(pw, fd) & rwx) != 0;
  397. }
  398. /*
  399. * cliloop.c.
  400. */
  401. typedef bool (*cliloop_pw_setup_t)(void *ctx, pollwrapper *pw);
  402. typedef void (*cliloop_pw_check_t)(void *ctx, pollwrapper *pw);
  403. typedef bool (*cliloop_continue_t)(void *ctx, bool found_any_fd,
  404. bool ran_any_callback);
  405. void cli_main_loop(cliloop_pw_setup_t pw_setup,
  406. cliloop_pw_check_t pw_check,
  407. cliloop_continue_t cont, void *ctx);
  408. bool cliloop_no_pw_setup(void *ctx, pollwrapper *pw);
  409. void cliloop_no_pw_check(void *ctx, pollwrapper *pw);
  410. bool cliloop_always_continue(void *ctx, bool, bool);
  411. /* network.c: network error reporting helper taking an OS error code */
  412. void plug_closing_errno(Plug *plug, int error);
  413. SeatPromptResult make_spr_sw_abort_errno(const char *prefix, int errno_value);
  414. #endif /* PUTTY_UNIX_PLATFORM_H */