diff --git a/cmdline.c b/cmdline.c index 4a84fa1c..5e507af6 100644 --- a/cmdline.c +++ b/cmdline.c @@ -563,20 +563,23 @@ int cmdline_process_param(CmdlineArg *arg, CmdlineArg *nextarg, sfree(host); } if (!strcmp(p, "-m")) { - const char *filename; + Filename *filename; FILE *fp; RETURN(2); UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK); SAVEABLE(0); - filename = value; + filename = cmdline_arg_to_filename(nextarg); - fp = fopen(filename, "r"); + fp = f_open(filename, "r", false); if (!fp) { - cmdline_error("unable to open command file \"%s\"", filename); + cmdline_error("unable to open command file \"%s\"", + filename_to_str(filename)); + filename_free(filename); return ret; } + filename_free(filename); strbuf *command = strbuf_new(); char readbuf[4096]; while (1) { @@ -628,7 +631,7 @@ int cmdline_process_param(CmdlineArg *arg, CmdlineArg *nextarg, cmdline_error("the -pwfile option can only be used with the " "SSH protocol"); else { - Filename *fn = filename_from_str(value); + Filename *fn = cmdline_arg_to_filename(nextarg); FILE *fp = f_open(fn, "r", false); if (!fp) { cmdline_error("unable to open password file '%s'", value); @@ -750,21 +753,19 @@ int cmdline_process_param(CmdlineArg *arg, CmdlineArg *nextarg, } if (!strcmp(p, "-i")) { - Filename *fn; RETURN(2); UNAVAILABLE_IN(TOOLTYPE_NONNETWORK); SAVEABLE(0); - fn = filename_from_str(value); + Filename *fn = cmdline_arg_to_filename(nextarg); conf_set_filename(conf, CONF_keyfile, fn); filename_free(fn); } if (!strcmp(p, "-cert")) { - Filename *fn; RETURN(2); UNAVAILABLE_IN(TOOLTYPE_NONNETWORK); SAVEABLE(0); - fn = filename_from_str(value); + Filename *fn = cmdline_arg_to_filename(nextarg); conf_set_filename(conf, CONF_detached_cert, fn); filename_free(fn); } @@ -868,12 +869,11 @@ int cmdline_process_param(CmdlineArg *arg, CmdlineArg *nextarg, } if (!strcmp(p, "-sessionlog")) { - Filename *fn; RETURN(2); UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER); /* but available even in TOOLTYPE_NONNETWORK, cf pterm "-log" */ SAVEABLE(0); - fn = filename_from_str(value); + Filename *fn = cmdline_arg_to_filename(nextarg); conf_set_filename(conf, CONF_logfilename, fn); conf_set_int(conf, CONF_logtype, LGTYP_DEBUG); filename_free(fn); @@ -881,11 +881,10 @@ int cmdline_process_param(CmdlineArg *arg, CmdlineArg *nextarg, if (!strcmp(p, "-sshlog") || !strcmp(p, "-sshrawlog")) { - Filename *fn; RETURN(2); UNAVAILABLE_IN(TOOLTYPE_NONNETWORK); SAVEABLE(0); - fn = filename_from_str(value); + Filename *fn = cmdline_arg_to_filename(nextarg); conf_set_filename(conf, CONF_logfilename, fn); conf_set_int(conf, CONF_logtype, !strcmp(p, "-sshlog") ? LGTYP_PACKETS : diff --git a/putty.h b/putty.h index 97ecb60f..df843c47 100644 --- a/putty.h +++ b/putty.h @@ -2436,6 +2436,7 @@ struct CmdlineArg { }; const char *cmdline_arg_to_utf8(CmdlineArg *arg); /* may fail */ const char *cmdline_arg_to_str(CmdlineArg *arg); /* must not fail */ +Filename *cmdline_arg_to_filename(CmdlineArg *arg); /* caller must free */ void cmdline_arg_wipe(CmdlineArg *arg); CmdlineArg *cmdline_arg_from_str(CmdlineArgList *list, const char *string); /* Platforms provide their own constructors for CmdlineArgList */ diff --git a/unix/main-gtk-simple.c b/unix/main-gtk-simple.c index 4ffd9ecf..76487772 100644 --- a/unix/main-gtk-simple.c +++ b/unix/main-gtk-simple.c @@ -476,10 +476,9 @@ bool do_cmdline(int argc, char **argv, bool do_everything, Conf *conf) conf_set_str(conf, CONF_wintitle, val); } else if (!strcmp(p, "-log")) { - Filename *fn; EXPECTS_ARG; SECOND_PASS_ONLY; - fn = filename_from_str(val); + Filename *fn = cmdline_arg_to_filename(nextarg); conf_set_filename(conf, CONF_logfilename, fn); conf_set_int(conf, CONF_logtype, LGTYP_DEBUG); filename_free(fn); diff --git a/unix/utils/cmdline_arg.c b/unix/utils/cmdline_arg.c index a33df45e..e8a7a654 100644 --- a/unix/utils/cmdline_arg.c +++ b/unix/utils/cmdline_arg.c @@ -124,6 +124,15 @@ const char *cmdline_arg_to_utf8(CmdlineArg *argp) return NULL; } +Filename *cmdline_arg_to_filename(CmdlineArg *argp) +{ + if (!argp) + return NULL; + + CmdlineArgUnix *arg = container_of(argp, CmdlineArgUnix, argp); + return filename_from_str(arg->value); +} + void cmdline_arg_wipe(CmdlineArg *argp) { if (!argp) diff --git a/windows/dialog.c b/windows/dialog.c index e7faf6df..96dab3ab 100644 --- a/windows/dialog.c +++ b/windows/dialog.c @@ -459,7 +459,7 @@ static HTREEITEM treeview_insert(struct treeview_faff *faff, return newitem; } -const char *dialog_box_demo_screenshot_filename = NULL; +Filename *dialog_box_demo_screenshot_filename = NULL; /* ctrltrees indices for the main dialog box */ enum { diff --git a/windows/pageant.c b/windows/pageant.c index 1f71bd6d..f30d9cdc 100644 --- a/windows/pageant.c +++ b/windows/pageant.c @@ -1537,7 +1537,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) const char *command = NULL; const char *unixsocket = NULL; bool show_keylist_on_startup = false; - const char *openssh_config_file = NULL; + Filename *openssh_config_file = NULL; typedef struct CommandLineKey { Filename *fn; @@ -1612,7 +1612,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) */ sgrowarray(clkeys, clkeysize, nclkeys); CommandLineKey *clkey = &clkeys[nclkeys++]; - clkey->fn = filename_from_str(cmdline_arg_to_str(valarg)); + clkey->fn = cmdline_arg_to_filename(valarg); clkey->add_encrypted = add_keys_encrypted; } else if (match_opt("-pgpfp")) { pgp_fingerprints_msgbox(NULL); @@ -1628,8 +1628,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) } else if (match_opt("-keylist")) { show_keylist_on_startup = true; } else if (match_optval("-openssh-config", "-openssh_config")) { - openssh_config_file = cmdline_arg_to_str(valarg); + openssh_config_file = cmdline_arg_to_filename(valarg); } else if (match_optval("-unix")) { + /* UNICODE: should this be a Unicode filename? Is there a + * Unicode version of connect() that lets you give a + * Unicode pathname when making an AF_UNIX socket? */ unixsocket = cmdline_arg_to_str(valarg); } else if (match_opt("-c")) { /* @@ -1735,10 +1738,11 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) * pointing at the named pipe, do so. */ if (openssh_config_file) { - FILE *fp = fopen(openssh_config_file, "w"); + FILE *fp = f_open(openssh_config_file, "w", true); if (!fp) { - char *err = dupprintf("Unable to write OpenSSH config " - "file to %s", openssh_config_file); + char *err = dupprintf( + "Unable to write OpenSSH config file to %s", + filename_to_str(openssh_config_file)); MessageBox(NULL, err, "Pageant Error", MB_ICONERROR | MB_OK); return 1; @@ -1960,7 +1964,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) * Leave this file around, but empty it, so that it doesn't * refer to a pipe we aren't listening on any more. */ - FILE *fp = fopen(openssh_config_file, "w"); + FILE *fp = f_open(openssh_config_file, "w", true); if (fp) fclose(fp); } diff --git a/windows/platform.h b/windows/platform.h index 034b3c28..7e2227b7 100644 --- a/windows/platform.h +++ b/windows/platform.h @@ -859,7 +859,7 @@ bool aux_match_opt(AuxMatchOpt *amo, CmdlineArg **val, const char *optname, ...); bool aux_match_done(AuxMatchOpt *amo); -char *save_screenshot(HWND hwnd, const char *outfile); +char *save_screenshot(HWND hwnd, Filename *outfile); void gui_terminal_ready(HWND hwnd, Seat *seat, Backend *backend); void setup_gui_timing(void); diff --git a/windows/putty.c b/windows/putty.c index 299a381f..eb1386e8 100644 --- a/windows/putty.c +++ b/windows/putty.c @@ -2,9 +2,9 @@ #include "storage.h" extern bool sesslist_demo_mode; -extern const char *dialog_box_demo_screenshot_filename; +extern Filename *dialog_box_demo_screenshot_filename; static strbuf *demo_terminal_data = NULL; -static const char *terminal_demo_screenshot_filename; +static Filename *terminal_demo_screenshot_filename; const unsigned cmdline_tooltype = TOOLTYPE_HOST_ARG | @@ -99,7 +99,7 @@ void gui_term_process_cmdline(Conf *conf, char *cmdline) } else { demo_config_box = true; dialog_box_demo_screenshot_filename = - cmdline_arg_to_str(arglist->args[arglistpos++]); + cmdline_arg_to_filename(arglist->args[arglistpos++]); } } else if (!strcmp(p, "-demo-terminal")) { if (!arglist->args[arglistpos] || @@ -109,7 +109,7 @@ void gui_term_process_cmdline(Conf *conf, char *cmdline) const char *infile = cmdline_arg_to_str(arglist->args[arglistpos++]); terminal_demo_screenshot_filename = - cmdline_arg_to_str(arglist->args[arglistpos++]); + cmdline_arg_to_filename(arglist->args[arglistpos++]); FILE *fp = fopen(infile, "rb"); if (!fp) cmdline_error("can't open input file '%s'", infile); diff --git a/windows/puttygen.c b/windows/puttygen.c index 51574139..643e1113 100644 --- a/windows/puttygen.c +++ b/windows/puttygen.c @@ -26,9 +26,9 @@ #define DEFAULT_ECCURVE_INDEX 0 #define DEFAULT_EDCURVE_INDEX 0 -static const char *cmdline_keyfile = NULL; +static Filename *cmdline_keyfile = NULL; static ptrlen cmdline_demo_keystr; -static const char *demo_screenshot_filename = NULL; +static Filename *demo_screenshot_filename = NULL; /* * Print a modal (Really Bad) message box and perform a fatal exit. @@ -1737,9 +1737,7 @@ static INT_PTR CALLBACK MainDlgProc(HWND hwnd, UINT msg, * Load a key file if one was provided on the command line. */ if (cmdline_keyfile) { - Filename *fn = filename_from_str(cmdline_keyfile); - load_key_file(hwnd, state, fn, false); - filename_free(fn); + load_key_file(hwnd, state, cmdline_keyfile, false); } else if (cmdline_demo_keystr.ptr) { BinarySource src[1]; BinarySource_BARE_INIT_PL(src, cmdline_demo_keystr); @@ -2430,7 +2428,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) * Assume the first argument to be a private key file, and * attempt to load it. */ - cmdline_keyfile = cmdline_arg_to_str(valarg); + cmdline_keyfile = cmdline_arg_to_filename(valarg); continue; } else { opt_error("unexpected extra argument '%s'\n", @@ -2550,7 +2548,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) } sfree(val); } else if (match_optval("-demo-screenshot")) { - demo_screenshot_filename = cmdline_arg_to_str(valarg); + demo_screenshot_filename = cmdline_arg_to_filename(valarg); cmdline_demo_keystr = PTRLEN_LITERAL( "PuTTY-User-Key-File-3: ssh-ed25519\n" "Encryption: none\n" diff --git a/windows/test/test_screenshot.c b/windows/test/test_screenshot.c index 3d558bc8..01643f4e 100644 --- a/windows/test/test_screenshot.c +++ b/windows/test/test_screenshot.c @@ -15,7 +15,7 @@ void out_of_memory(void) { fatal_error("out of memory"); } int main(int argc, char **argv) { - const char *outfile = NULL; + Filename *outfile = NULL; AuxMatchOpt amo = aux_match_opt_init(fatal_error); while (!aux_match_done(&amo)) { @@ -28,7 +28,7 @@ int main(int argc, char **argv) if (aux_match_arg(&amo, &val)) { fatal_error("unexpected argument '%s'", cmdline_arg_to_str(val)); } else if (match_optval("-o", "--output")) { - outfile = cmdline_arg_to_str(val); + outfile = cmdline_arg_to_filename(val); } else { fatal_error("unrecognised option '%s'\n", cmdline_arg_to_str(amo.arglist->args[amo.index])); @@ -41,6 +41,7 @@ int main(int argc, char **argv) char *err = save_screenshot(NULL, outfile); if (err) fatal_error("%s", err); + filename_free(outfile); return 0; } diff --git a/windows/utils/cmdline_arg.c b/windows/utils/cmdline_arg.c index 55c105f1..cb232361 100644 --- a/windows/utils/cmdline_arg.c +++ b/windows/utils/cmdline_arg.c @@ -162,6 +162,15 @@ const char *cmdline_arg_to_utf8(CmdlineArg *argp) return arg->utf8; } +Filename *cmdline_arg_to_filename(CmdlineArg *argp) +{ + if (!argp) + return NULL; + + CmdlineArgWin *arg = container_of(argp, CmdlineArgWin, argp); + return filename_from_wstr(arg->wide); +} + void cmdline_arg_wipe(CmdlineArg *argp) { if (!argp) diff --git a/windows/utils/screenshot.c b/windows/utils/screenshot.c index 777520fd..6b53cd70 100644 --- a/windows/utils/screenshot.c +++ b/windows/utils/screenshot.c @@ -4,7 +4,7 @@ #include -char *save_screenshot(HWND hwnd, const char *outfile) +char *save_screenshot(HWND hwnd, Filename *outfile) { HDC dcWindow = NULL, dcSave = NULL; HBITMAP bmSave = NULL; @@ -89,9 +89,9 @@ char *save_screenshot(HWND hwnd, const char *outfile) err = dupprintf("GetDIBits (get data): %s", win_strerror(GetLastError())); - FILE *fp = fopen(outfile, "wb"); + FILE *fp = f_open(outfile, "wb", false); if (!fp) { - err = dupprintf("'%s': unable to open file", outfile); + err = dupprintf("'%s': unable to open file", filename_to_str(outfile)); goto out; } @@ -118,7 +118,7 @@ char *save_screenshot(HWND hwnd, const char *outfile) #else /* HAVE_DWMAPI_H */ /* Without we can't get the right window rectangle */ -char *save_screenshot(HWND hwnd, const char *outfile) +char *save_screenshot(HWND hwnd, Filename *outfile) { return dupstr("Demo screenshots not compiled in to this build"); }