#include "ftpd.h" STRING *string_new(void) { STRING *ns = mallocwrapper(sizeof(STRING) + MINLEN + 1); STRLENGTH(ns) = 0; STRTOCHARN(ns, 0) = 0; return(ns); } void string_cat(STRING **s, char *catstr, int len) { if (len == -1) len = strlen(catstr); if (len + STRLENGTH(*s) >= MINLEN) reallocwrapper(len + STRCURSIZE(*s), (void *)s); memcpy(STRTOCHAR(*s) + STRLENGTH(*s), catstr, len); STRLENGTH(*s) += len; STRTOCHARN(*s, (*s)->strlen) = 0; } void string_clear(STRING **s) { if (STRLENGTH(*s) > MINLEN) reallocwrapper(sizeof(STRING) + MINLEN + 1, (void *)s); STRLENGTH(*s) = 0; STRTOCHARN(*s, 0) = 0; } void string_dropfront(STRING **s, int nchars) { int oldlen = STRLENGTH(*s); if ((*s)->strlen < nchars) nchars = (*s)->strlen; memmove(STRTOCHAR(*s), STRTOCHAR(*s) + nchars, STRLENGTH(*s) - nchars); STRLENGTH(*s) -= nchars; STRTOCHARN(*s, STRLENGTH(*s)) = 0; if (oldlen >= MINLEN) { if (STRLENGTH(*s) >= MINLEN) reallocwrapper(sizeof(STRING) + STRLENGTH(*s) + 1, (void *)s); else reallocwrapper(sizeof(STRING) + MINLEN + 1, (void *)s); } } void string_catvprintf(STRING **s, int len, char *format, va_list ap) { if (STRLENGTH(*s) + len >= MINLEN) reallocwrapper(len + STRCURSIZE(*s), (void *)s); vsnprintf(STRTOCHAR(*s) + STRLENGTH(*s), len+1, format, ap); STRLENGTH(*s) += len; } void string_catprintf(STRING **s, char *format, ...) { va_list printfargs; int len; va_start(printfargs, format); len = vsnprintf(NULL, 0, format, printfargs); va_end(printfargs); va_start(printfargs, format); string_catvprintf(s, len, format, printfargs); va_end(printfargs); } /* this is for input to ftp. Make very strict. (No tabs or nofing, only /r/n) */ void string_filterbadchars_telnet(STRING **s, int start) { int count, slen; unsigned char *pos1, *pos2; if (start > STRLENGTH(*s)) return; pos1 = pos2 = STRTOCHAR(*s) + start; slen = STRLENGTH(*s); count = start; while(count < slen) { /* be very aggressive. Only printable charaters! */ if ((*pos1 >= 32) && (*pos1 <= 126)) { *pos2 = *pos1; pos2++; } else { switch(*pos1) { case '\r': /* allow specific case of \r\n only. */ if (count != (slen - 1)) { if (*(pos1 + 1) == '\n') { // forward 2 chars *pos2 = *pos1; *(pos2 + 1) = *(pos1 + 1); pos1++; pos2 += 2; count++; } else STRLENGTH(*s) -= 1; } else STRLENGTH(*s) -= 1; break; default: STRLENGTH(*s) -= 1; break; } } pos1++; count++; } *pos2 = 0; } /* this is for input files. Be quite relaxed, but still remove annoying chars */ void string_filterbadchars_unix(STRING **s, int start) { int count, slen; unsigned char *pos1, *pos2; if (start > STRLENGTH(*s)) return; pos1 = pos2 = STRTOCHAR(*s) + start; slen = STRLENGTH(*s); count = start; while(count < slen) { /* be very aggressive. Only printable charaters! */ if (*pos1 >= 32) { *pos2 = *pos1; pos2++; } else { switch(*pos1) { case '\n': case '\t': *pos2 = *pos1; pos2++; break; default: STRLENGTH(*s) -= 1; break; } } pos1++; count++; } *pos2 = 0; }