Oops, Ben is quite right about the rather appalling design of
[u/mdw/putty] / scp.c
diff --git a/scp.c b/scp.c
index 25f29b4..40d05df 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -99,6 +99,10 @@ static int gui_mode = 0;
 static char *gui_hwnd = NULL;
 static int using_sftp = 0;
 
+static Backend *back;
+static void *backhandle;
+static Config cfg;
+
 static void source(char *src);
 static void rsource(char *src);
 static void sink(char *targ, char *src);
@@ -117,7 +121,7 @@ static void gui_update_stats(char *name, unsigned long size,
  */
 #define MAX_SCP_BUFSIZE 16384
 
-void ldisc_send(char *buf, int len, int interactive)
+void ldisc_send(void *handle, char *buf, int len, int interactive)
 {
     /*
      * This is only here because of the calls to ldisc_send(NULL,
@@ -157,13 +161,15 @@ static void tell_str(FILE * stream, char *str)
 
 static void tell_user(FILE * stream, char *fmt, ...)
 {
-    char str[0x100];                  /* Make the size big enough */
+    char *str, *str2;
     va_list ap;
     va_start(ap, fmt);
-    vsprintf(str, fmt, ap);
+    str = dupvprintf(fmt, ap);
     va_end(ap);
-    strcat(str, "\n");
-    tell_str(stream, str);
+    str2 = dupcat(str, "\n", NULL);
+    sfree(str);
+    tell_str(stream, str2);
+    sfree(str2);
 }
 
 static void gui_update_stats(char *name, unsigned long size,
@@ -213,14 +219,15 @@ static void gui_update_stats(char *name, unsigned long size,
  */
 void fatalbox(char *fmt, ...)
 {
-    char str[0x100];                  /* Make the size big enough */
+    char *str, *str2;
     va_list ap;
     va_start(ap, fmt);
-    strcpy(str, "Fatal: ");
-    vsprintf(str + strlen(str), fmt, ap);
+    str = dupvprintf(fmt, ap);
+    str2 = dupcat("Fatal: ", str, "\n", NULL);
+    sfree(str);
     va_end(ap);
-    strcat(str, "\n");
-    tell_str(stderr, str);
+    tell_str(stderr, str2);
+    sfree(str2);
     errs++;
 
     if (gui_mode) {
@@ -236,14 +243,15 @@ void fatalbox(char *fmt, ...)
 }
 void modalfatalbox(char *fmt, ...)
 {
-    char str[0x100];                  /* Make the size big enough */
+    char *str, *str2;
     va_list ap;
     va_start(ap, fmt);
-    strcpy(str, "Fatal: ");
-    vsprintf(str + strlen(str), fmt, ap);
+    str = dupvprintf(fmt, ap);
+    str2 = dupcat("Fatal: ", str, "\n", NULL);
+    sfree(str);
     va_end(ap);
-    strcat(str, "\n");
-    tell_str(stderr, str);
+    tell_str(stderr, str2);
+    sfree(str2);
     errs++;
 
     if (gui_mode) {
@@ -257,16 +265,17 @@ void modalfatalbox(char *fmt, ...)
 
     cleanup_exit(1);
 }
-void connection_fatal(char *fmt, ...)
+void connection_fatal(void *frontend, char *fmt, ...)
 {
-    char str[0x100];                  /* Make the size big enough */
+    char *str, *str2;
     va_list ap;
     va_start(ap, fmt);
-    strcpy(str, "Fatal: ");
-    vsprintf(str + strlen(str), fmt, ap);
+    str = dupvprintf(fmt, ap);
+    str2 = dupcat("Fatal: ", str, "\n", NULL);
+    sfree(str);
     va_end(ap);
-    strcat(str, "\n");
-    tell_str(stderr, str);
+    tell_str(stderr, str2);
+    sfree(str2);
     errs++;
 
     if (gui_mode) {
@@ -308,7 +317,7 @@ static unsigned char *outptr;              /* where to put the data */
 static unsigned outlen;                       /* how much data required */
 static unsigned char *pending = NULL;  /* any spare data */
 static unsigned pendlen = 0, pendsize = 0;     /* length and phys. size of buffer */
-int from_backend(void *frontend, int is_stderr, char *data, int datalen)
+int from_backend(void *frontend, int is_stderr, const char *data, int datalen)
 {
     unsigned char *p = (unsigned char *) data;
     unsigned len = (unsigned) datalen;
@@ -424,14 +433,15 @@ static void ssh_scp_init(void)
  */
 static void bump(char *fmt, ...)
 {
-    char str[0x100];                  /* Make the size big enough */
+    char *str, *str2;
     va_list ap;
     va_start(ap, fmt);
-    strcpy(str, "Fatal: ");
-    vsprintf(str + strlen(str), fmt, ap);
+    str = dupvprintf(fmt, ap);
     va_end(ap);
-    strcat(str, "\n");
-    tell_str(stderr, str);
+    str2 = dupcat(str, "\n", NULL);
+    sfree(str);
+    tell_str(stderr, str2);
+    sfree(str2);
     errs++;
 
     if (back != NULL && back->socket(backhandle) != NULL) {
@@ -484,7 +494,7 @@ static void do_cmd(char *host, char *user, char *cmd)
     /*
      * Enact command-line overrides.
      */
-    cmdline_run_saved();
+    cmdline_run_saved(&cfg);
 
     /*
      * Trim leading whitespace off the hostname if it's there.
@@ -565,9 +575,12 @@ static void do_cmd(char *host, char *user, char *cmd)
 
     back = &ssh_backend;
 
-    err = back->init(NULL, &backhandle, cfg.host, cfg.port, &realhost, 0);
+    err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost,0);
     if (err != NULL)
        bump("ssh_init: %s", err);
+    logctx = log_init(NULL, &cfg);
+    back->provide_logctx(backhandle, logctx);
+    console_provide_logctx(logctx);
     ssh_scp_init();
     if (verbose && realhost != NULL)
        tell_user(stderr, "Connected to %s\n", realhost);
@@ -1498,16 +1511,17 @@ int scp_finish_filerecv(void)
  */
 static void run_err(const char *fmt, ...)
 {
-    char str[2048];
+    char *str, *str2;
     va_list ap;
     va_start(ap, fmt);
     errs++;
-    strcpy(str, "scp: ");
-    vsprintf(str + strlen(str), fmt, ap);
-    strcat(str, "\n");
-    scp_send_errmsg(str);
-    tell_user(stderr, "%s", str);
+    str = dupvprintf(fmt, ap);
+    str2 = dupcat("scp: ", str, "\n", NULL);
+    sfree(str);
+    scp_send_errmsg(str2);
+    tell_user(stderr, "%s", str2);
     va_end(ap);
+    sfree(str2);
 }
 
 /*
@@ -1916,12 +1930,11 @@ static void toremote(int argc, char *argv[])
        FindClose(fh);
     }
 
-    cmd = smalloc(strlen(targ) + 100);
-    sprintf(cmd, "scp%s%s%s%s -t %s",
-           verbose ? " -v" : "",
-           recursive ? " -r" : "",
-           preserve ? " -p" : "",
-           targetshouldbedirectory ? " -d" : "", targ);
+    cmd = dupprintf("scp%s%s%s%s -t %s",
+                   verbose ? " -v" : "",
+                   recursive ? " -r" : "",
+                   preserve ? " -p" : "",
+                   targetshouldbedirectory ? " -d" : "", targ);
     do_cmd(host, user, cmd);
     sfree(cmd);
 
@@ -2020,12 +2033,11 @@ static void tolocal(int argc, char *argv[])
            user = NULL;
     }
 
-    cmd = smalloc(strlen(src) + 100);
-    sprintf(cmd, "scp%s%s%s%s -f %s",
-           verbose ? " -v" : "",
-           recursive ? " -r" : "",
-           preserve ? " -p" : "",
-           targetshouldbedirectory ? " -d" : "", src);
+    cmd = dupprintf("scp%s%s%s%s -f %s",
+                   verbose ? " -v" : "",
+                   recursive ? " -r" : "",
+                   preserve ? " -p" : "",
+                   targetshouldbedirectory ? " -d" : "", src);
     do_cmd(host, user, cmd);
     sfree(cmd);
 
@@ -2156,7 +2168,7 @@ void cmdline_error(char *p, ...)
     va_start(ap, p);
     vfprintf(stderr, p, ap);
     va_end(ap);
-    fputc('\n', stderr);
+    fprintf(stderr, "\n      try typing just \"pscp\" for help\n");
     exit(1);
 }
 
@@ -2179,7 +2191,7 @@ int main(int argc, char *argv[])
        int ret;
        if (argv[i][0] != '-')
            break;
-       ret = cmdline_process_param(argv[i], i+1<argc?argv[i+1]:NULL, 1);
+       ret = cmdline_process_param(argv[i], i+1<argc?argv[i+1]:NULL, 1, &cfg);
        if (ret == -2) {
            cmdline_error("option \"%s\" requires an argument", argv[i]);
        } else if (ret == 2) {
@@ -2209,8 +2221,9 @@ int main(int argc, char *argv[])
        } else if (strcmp(argv[i], "--") == 0) {
            i++;
            break;
-       } else
-           usage();
+       } else {
+           cmdline_error("unknown option \"%s\"", argv[i]);
+       }
     }
     argc -= i;
     argv += i;