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