--- minicom-2.2/src/updown.c.staticbuf 2007-03-09 13:10:38.000000000 +0100 +++ minicom-2.2/src/updown.c 2007-03-09 13:10:38.000000000 +0100 @@ -87,40 +87,83 @@ * Translate %b to the current bps rate, and * %l to the current tty port. * %f to the serial port file descriptor + * + * Caller must free the returned string */ static char *translate(char *s) { - static char buf[128]; - char str_portfd[8]; /* kino */ - int i; + char * ptr; + char * translation; + size_t translation_length; + char str_portfd[8]; /* kino */ + + /* determine how many bytes we'll need for the translated version */ + translation_length = 0; + for (ptr = s; *ptr != '\0'; ptr++) { + if (*ptr != '%') { + translation_length++; + } + else { + switch(*++ptr) { + + case 'l': /* tty port */ + translation_length += strlen(dial_tty); + break; + + case 'b': /* baud rate (bbp) */ + translation_length += strlen(P_BAUDRATE); + break; + + case 'f': /* serial port file descriptor */ + sprintf(str_portfd, "%d", portfd); + translation_length += strlen(str_portfd); + break; + + default: /* treat all other escape sequences literally */ + translation_length += 2; + break; + } + } + } + + translation = malloc(translation_length + 1); + if (translation == NULL) { + do_log("out of memory"); + return NULL; + } - for (i = 0; *s && i < 127; i++, s++) { + /* now copy and translate s into the allocated buffer */ + for (ptr = translation; *s != '\0'; s++) { if (*s != '%') { - buf[i] = *s; + *ptr++ = *s; continue; } - switch (*++s) { - case 'l': - strncpy(buf + i, dial_tty, sizeof(buf)-i); - i += strlen(dial_tty) - 1; + switch(*++s) { + case 'l': /* tty port */ + strcpy(ptr, dial_tty); + ptr += strlen(dial_tty); break; - case 'b': - strncpy(buf + i, P_BAUDRATE, sizeof(buf)-i); - i += strlen(P_BAUDRATE) - 1; + + case 'b': /* baud rate (bbp) */ + strcpy(ptr, P_BAUDRATE); + ptr += strlen(P_BAUDRATE); break; - case 'f': + + case 'f': /* serial port file descriptor */ sprintf(str_portfd, "%d", portfd); - strncpy(buf + i, str_portfd, sizeof(buf)-i); - i += strlen(str_portfd) - 1; + strcpy(ptr, str_portfd); + ptr += strlen(str_portfd); break; - default: - buf[i++] = '%'; - buf[i] = *s; + + default: /* treat all other escape sequences literally */ + *ptr++ = '%'; + *ptr++ = *s; break; } } - buf[i] = 0; - return buf; + *ptr = '\0'; + + return translation; } /* @@ -181,7 +224,8 @@ const char *s =""; int pipefd[2]; int n, status; - char cmdline[128]; + char * cmdline = NULL; + char * translated_cmdline = NULL; WIN *win = (WIN *)NULL; if (mcd(what == 'U' ? P_UPDIR : P_DOWNDIR) < 0) @@ -213,6 +257,7 @@ #if 1 { int multiple; /* 0:only directory, 1:one file, -1:any number */ + size_t cmdline_length; if (P_MUL(g)=='Y') /* need file(s), or just a directory? */ @@ -232,7 +277,13 @@ } /* discard directory if "multiple" == 0 */ - snprintf(cmdline, sizeof(cmdline), "%s %s", P_PPROG(g), multiple == 0? "" : s); + cmdline_length = strlen(P_PPROG(g)) + strlen((char*) (multiple == 0 ? "" : s)) + 1; /* + 1 for ' ' */ + cmdline = malloc(cmdline_length + 1); /* + 1 for NUL */ + if (cmdline == NULL) { + werror(_("Out of memory: could allocate buffer for command line")); + return; + } + snprintf(cmdline, cmdline_length + 1, "%s %s", P_PPROG(g), multiple == 0 ? "" : s); } #endif @@ -258,6 +309,8 @@ } else wreturn(); mcd(""); + if(cmdline) + free(cmdline); return; case 0: /* Child */ if (P_PIORED(g) == 'Y') { @@ -276,11 +329,21 @@ set_privs(); setgid((gid_t)real_gid); setuid((uid_t)real_uid); - fastexec(translate(cmdline)); + translated_cmdline = translate(cmdline); + if (translated_cmdline != NULL) { + fastexec(translated_cmdline); + free(translated_cmdline); + } + if(cmdline) + free(cmdline); exit(1); default: /* Parent */ break; } + + if(cmdline) + free(cmdline); + if (win) { setcbreak(1); /* Cbreak, no echo. */ enab_sig(1, 0); /* But enable SIGINT */ @@ -384,6 +447,7 @@ char buf[81]; int fd; #endif + char * translated_cmdline; /* Clear screen, set keyboard modes etc. */ wleave(); @@ -404,7 +468,11 @@ for (n = 0; n < _NSIG; n++) signal(n, SIG_DFL); - fastexec(translate(P_KERMIT)); + translated_cmdline = translate(P_KERMIT); + if (translated_cmdline != NULL) { + fastexec(translated_cmdline); + free(translated_cmdline); + } exit(1); default: /* Parent */ break; @@ -518,6 +586,7 @@ char buf[81]; char scr_lines[5]; char cmdline[128]; + char *translated_cmdline; char *ptr; WIN *w; int done = 0; @@ -623,7 +692,12 @@ mc_setenv("LOGIN", scr_user); mc_setenv("PASS", scr_passwd); mc_setenv("TERMLIN", scr_lines); /* jl 13.09.97 */ - fastexec(translate(cmdline)); + translated_cmdline = translate(cmdline); + + if (translated_cmdline != NULL) { + fastexec(translated_cmdline); + free(translated_cmdline); + } exit(1); default: /* Parent */ break;