char *pr_str_strip(pool *p, char *str) { char c, *dupstr, *start, *finish; if (!p || !str) { errno = EINVAL; return NULL; } /* First, find the non-whitespace start of the given string */ for (start = str; PR_ISSPACE(*start); start++); /* Now, find the non-whitespace end of the given string */ for (finish = &str[strlen(str)-1]; PR_ISSPACE(*finish); finish--); /* finish is now pointing to a non-whitespace character. So advance one * character forward, and set that to NUL. */ c = *++finish; *finish = '\0'; /* The space-stripped string is, then, everything from start to finish. */ dupstr = pstrdup(p, start); /* Restore the given string buffer contents. */ *finish = c; return dupstr; }
/* safe_token tokenizes a string, and increments the pointer to * the next non-white space character. It's "safe" because it * never returns NULL, only an empty string if no token remains * in the source string. */ char *safe_token(char **s) { char *res = ""; if (s == NULL || !*s) { return res; } while (PR_ISSPACE(**s) && **s) { (*s)++; } if (**s) { res = *s; while (!PR_ISSPACE(**s) && **s) { (*s)++; } if (**s) { *(*s)++ = '\0'; } while (PR_ISSPACE(**s) && **s) { (*s)++; } } return res; }
/* safe_token tokenizes a string, and increments the pointer to * the next non-white space character. It's "safe" because it * never returns NULL, only an empty string if no token remains * in the source string. */ char *safe_token(char **s) { char *res = ""; if (!s || !*s) return res; while (PR_ISSPACE(**s) && **s) (*s)++; if (**s) { res = *s; while (!PR_ISSPACE(**s) && **s) (*s)++; if (**s) *(*s)++ = '\0'; while (PR_ISSPACE(**s) && **s) (*s)++; } return res; }
int pr_auth_banned_by_ftpusers(xaset_t *ctx, const char *user) { int res = FALSE; unsigned char *use_ftp_users; use_ftp_users = get_param_ptr(ctx, "UseFtpUsers", FALSE); if (use_ftp_users == NULL || *use_ftp_users == TRUE) { FILE *fh = NULL; char buf[256]; PRIVS_ROOT fh = fopen(PR_FTPUSERS_PATH, "r"); PRIVS_RELINQUISH if (fh == NULL) return res; memset(buf, '\0', sizeof(buf)); while (fgets(buf, sizeof(buf)-1, fh)) { char *ptr; pr_signals_handle(); buf[sizeof(buf)-1] = '\0'; CHOP(buf); ptr = buf; while (PR_ISSPACE(*ptr) && *ptr) { ptr++; } if (!*ptr || *ptr == '#') { continue; } if (strcmp(ptr, user) == 0 ) { res = TRUE; break; } memset(buf, '\0', sizeof(buf)); } fclose(fh); }
int xferlog_write(long xfertime, const char *remhost, off_t fsize, char *fname, char xfertype, char direction, char access_mode, char *user, char abort_flag, const char *action_flags) { const char *xfer_proto; char buf[LOGBUFFER_SIZE] = {'\0'}, fbuf[LOGBUFFER_SIZE] = {'\0'}; int have_ident = FALSE, len; char *rfc1413_ident = NULL; register unsigned int i = 0; if (xferlogfd == -1 || remhost == NULL || user == NULL || fname == NULL) { return 0; } for (i = 0; (i + 1 < sizeof(fbuf)) && fname[i] != '\0'; i++) { fbuf[i] = (PR_ISSPACE(fname[i]) || PR_ISCNTRL(fname[i])) ? '_' : fname[i]; } fbuf[i] = '\0'; rfc1413_ident = pr_table_get(session.notes, "mod_ident.rfc1413-ident", NULL); if (rfc1413_ident) { have_ident = TRUE; /* If the retrieved identity is "UNKNOWN", then change the string to be * "*", since "*" is to be logged in the xferlog, as per the doc, when * the authenticated user ID is not available. */ if (strncmp(rfc1413_ident, "UNKNOWN", 8) == 0) rfc1413_ident = "*"; } else { /* If an authenticated user ID is not available, log "*", as per the * xferlog man page/spec. */ rfc1413_ident = "*"; } xfer_proto = pr_session_get_protocol(0); len = snprintf(buf, sizeof(buf), "%s %ld %s %" PR_LU " %s %c %s %c %c %s %s %c %s %c\n", pr_strtime(time(NULL)), xfertime, remhost, (pr_off_t) fsize, fbuf, xfertype, action_flags, direction, access_mode, user, xfer_proto, have_ident ? '1' : '0', rfc1413_ident, abort_flag); buf[sizeof(buf)-1] = '\0'; pr_log_event_generate(PR_LOG_TYPE_XFERLOG, xferlogfd, -1, buf, len); return write(xferlogfd, buf, len); }
/* This functions returns the next line from the configuration stream, * skipping commented-out lines and trimming trailing and leading whitespace, * returning, in effect, the next line of configuration data on which to * act. This function has the advantage that it can be called by functions * that don't have access to configuration file handle, such as the * <IfDefine> and <IfModule> configuration handlers. */ char *pr_parser_read_line(char *buf, size_t bufsz) { struct config_src *cs; /* Always use the config stream at the top of the stack. */ cs = parser_sources; if (buf == NULL || cs == NULL) { errno = EINVAL; return NULL; } if (cs->cs_fh == NULL) { errno = EPERM; return NULL; } parser_curr_lineno = cs->cs_lineno; /* Check for error conditions. */ while ((pr_fsio_getline(buf, bufsz, cs->cs_fh, &(cs->cs_lineno))) != NULL) { int have_eol = FALSE; char *bufp = NULL; size_t buflen; pr_signals_handle(); buflen = strlen(buf); parser_curr_lineno = cs->cs_lineno; /* Trim off the trailing newline, if present. */ if (buflen && buf[buflen - 1] == '\n') { have_eol = TRUE; buf[buflen-1] = '\0'; buflen--; } if (buflen && buf[buflen - 1] == '\r') { buf[buflen-1] = '\0'; buflen--; } if (have_eol == FALSE) { pr_log_pri(PR_LOG_WARNING, "warning: handling possibly truncated configuration data at " "line %u of '%s'", cs->cs_lineno, cs->cs_fh->fh_path); } /* Advance past any leading whitespace. */ for (bufp = buf; *bufp && PR_ISSPACE(*bufp); bufp++); /* Check for commented or blank lines at this point, and just continue on * to the next configuration line if found. If not, return the * configuration line. */ if (*bufp == '#' || !*bufp) { continue; } else { /* Copy the value of bufp back into the pointer passed in * and return it. */ buf = bufp; return buf; } } return NULL; }
int pr_str_get_nbytes(const char *str, const char *units, off_t *nbytes) { off_t sz; char *ptr = NULL; float factor = 0.0; if (str == NULL) { errno = EINVAL; return -1; } /* No negative numbers. */ if (*str == '-') { errno = EINVAL; return -1; } if (units == NULL || *units == '\0') { factor = 1.0; } else if (strncasecmp(units, "KB", 3) == 0) { factor = 1024.0; } else if (strncasecmp(units, "MB", 3) == 0) { factor = 1024.0 * 1024.0; } else if (strncasecmp(units, "GB", 3) == 0) { factor = 1024.0 * 1024.0 * 1024.0; } else if (strncasecmp(units, "TB", 3) == 0) { factor = 1024.0 * 1024.0 * 1024.0 * 1024.0; } else if (strncasecmp(units, "B", 2) == 0) { factor = 1.0; } else { errno = EINVAL; return -1; } errno = 0; #ifdef HAVE_STRTOULL sz = strtoull(str, &ptr, 10); #else sz = strtoul(str, &ptr, 10); #endif /* !HAVE_STRTOULL */ if (errno == ERANGE) { return -1; } if (ptr != NULL && *ptr) { /* Error parsing the given string */ errno = EINVAL; return -1; } /* Don't bother applying the factor if the result will overflow the result. */ #ifdef ULLONG_MAX if (sz > (ULLONG_MAX / factor)) { #else if (sz > (ULONG_MAX / factor)) { #endif /* !ULLONG_MAX */ errno = ERANGE; return -1; } if (nbytes != NULL) { *nbytes = (off_t) (sz * factor); } return 0; } char *pr_str_get_word(char **cp, int flags) { char *res, *dst; char quote_mode = 0; if (cp == NULL || !*cp || !**cp) { errno = EINVAL; return NULL; } if (!(flags & PR_STR_FL_PRESERVE_WHITESPACE)) { while (**cp && PR_ISSPACE(**cp)) { pr_signals_handle(); (*cp)++; } } if (!**cp) { return NULL; } res = dst = *cp; if (!(flags & PR_STR_FL_PRESERVE_COMMENTS)) { /* Stop processing at start of an inline comment. */ if (**cp == '#') { return NULL; } } if (**cp == '\"') { quote_mode++; (*cp)++; } while (**cp && (quote_mode ? (**cp != '\"') : !PR_ISSPACE(**cp))) { pr_signals_handle(); if (**cp == '\\' && quote_mode) { /* Escaped char */ if (*((*cp)+1)) { *dst = *(++(*cp)); } } *dst++ = **cp; ++(*cp); } if (**cp) { (*cp)++; } *dst = '\0'; return res; }
char *util_scan_config(const char *config_path, const char *directive) { FILE *fp = NULL; char buf[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; char *cp, *value = NULL; if (!config_path || !directive) { errno = EINVAL; return NULL; } fp = fopen(config_path, "r"); if (fp == NULL) return NULL; while (!value && fgets(buf, sizeof(buf) - 1, fp)) { size_t len = strlen(buf); if (len && buf[len-1] == '\n') buf[len-1] = '\0'; for (cp = buf; *cp && PR_ISSPACE(*cp); cp++); if (*cp == '#' || !*cp) continue; len = strlen(directive); if (strncasecmp(cp, directive, len) != 0) continue; /* Found it! */ cp += len; /* strip whitespace */ while (*cp && PR_ISSPACE(*cp)) { cp++; } value = cp; /* If the value is quoted, dequote. */ if (*cp == '"') { char *src = cp; cp++; value++; while (*++src) { switch (*src) { case '\\': if (*++src) *cp++ = *src; break; case '"': src++; break; default: *cp++ = *src; } } *cp = '\0'; } } fclose(fp); return value ? strdup(value) : NULL; }