int pr_env_unset(pool *p, const char *key) { #if defined(HAVE_UNSETENV) char *res; #endif /* !HAVE_UNSETENV */ if (p == NULL || key == NULL) { errno = EINVAL; return -1; } #if defined(HAVE_UNSETENV) /* The same key may appear multiple times in the environ, so make certain * that all such occurrences are removed. */ res = pr_env_get(p, key); while (res) { pr_signals_handle(); unsetenv(key); res = pr_env_get(p, key); } return 0; #else errno = ENOSYS; return -1; #endif /* !HAVE_UNSETENV */ }
static char *get_config_word(pool *p, char *word) { size_t wordlen; /* Should this word be replaced with a value from the environment? * If so, tmp will contain the expanded value, otherwise tmp will * contain a string duped from the given pool. */ wordlen = strlen(word); if (wordlen > 7) { char *ptr = NULL; /* Does the given word use the environment syntax? We handle this in a * while loop in order to handle a) multiple different variables, and b) * cases where the substituted value is itself a variable. Hopefully no * one is so clever as to want to actually _use_ the latter approach. */ ptr = strstr(word, "%{env:"); while (ptr != NULL) { char *env, *key, *ptr2, *var; unsigned int keylen; pr_signals_handle(); ptr2 = strchr(ptr + 6, '}'); if (ptr2 == NULL) { /* No terminating marker; continue on to the next potential * variable in the word. */ ptr2 = ptr + 6; ptr = strstr(ptr2, "%{env:"); continue; } keylen = (ptr2 - ptr - 6); var = pstrndup(p, ptr, (ptr2 - ptr) + 1); key = pstrndup(p, ptr + 6, keylen); env = pr_env_get(p, key); if (env == NULL) { /* No value in the environment; continue on to the next potential * variable in the word. */ ptr = strstr(ptr2, "%{env:"); continue; } word = (char *) sreplace(p, word, var, env, NULL); ptr = strstr(word, "%{env:"); } } return pstrdup(p, word); }
void pr_getopt_reset(void) { #if defined(FREEBSD4) || defined(FREEBSD5) || defined(FREEBSD6) || \ defined(FREEBSD7) || defined(FREEBSD8) || defined(FREEBSD9) || \ defined(FREEBSD10) || \ defined(DARWIN7) || defined(DARWIN8) || defined(DARWIN9) || \ defined(DARWIN10) || defined(DARWIN11) || defined(DARWIN12) optreset = 1; opterr = 1; optind = 1; #elif defined(SOLARIS2) || defined(HPUX11) opterr = 0; optind = 1; #else opterr = 0; optind = 0; #endif /* !FreeBSD, !Mac OSX and !Solaris2 */ if (pr_env_get(permanent_pool, "POSIXLY_CORRECT") == NULL) { pr_env_set(permanent_pool, "POSIXLY_CORRECT", "1"); } }
static char *get_config_word(pool *p, char *word) { size_t wordlen; /* Should this word be replaced with a value from the environment? * If so, tmp will contain the expanded value, otherwise tmp will * contain a string duped from the given pool. */ wordlen = strlen(word); if (wordlen > 7) { char *ptr = NULL; /* Does the given word use the environment syntax? * * In the simple (and most common) case, the entire word is the variable * syntax. But we also need to check for cases where the environment * variable syntax is embedded within the word string. */ if (strncmp(word, "%{env:", 6) == 0 && word[wordlen-1] == '}') { char *env; word[wordlen-1] = '\0'; env = pr_env_get(p, word + 6); return env ? pstrdup(p, env) : ""; } /* This is in a while loop in order to handle a) multiple different * variables, and b) cases where the substituted value is itself a * variable. (Hopefully no one is so clever as to want to actually * _use_ the latter approach.) */ ptr = strstr(word, "%{env:"); while (ptr != NULL) { char *env, *key, *ptr2, *var; unsigned int keylen; pr_signals_handle(); ptr2 = strchr(ptr + 6, '}'); if (ptr2 == NULL) { /* No terminating marker; continue on to the next potential * variable in the word. */ ptr2 = ptr + 6; ptr = strstr(ptr2, "%{env:"); continue; } keylen = (ptr2 - ptr - 6); var = pstrndup(p, ptr, (ptr2 - ptr) + 1); key = pstrndup(p, ptr + 6, keylen); env = pr_env_get(p, key); if (env == NULL) { /* No value in the environment; continue on to the next potential * variable in the word. */ ptr = strstr(ptr2, "%{env:"); continue; } word = (char *) sreplace(p, word, var, env, NULL); ptr = strstr(word, "%{env:"); } } return pstrdup(p, word); }
const char *sftp_display_fh_get_msg(pool *p, pr_fh_t *fh) { struct stat st; char buf[PR_TUNABLE_BUFFER_SIZE], *msg = ""; int len, res; unsigned int *current_clients = NULL; unsigned int *max_clients = NULL; off_t fs_size = 0; void *v; const char *serverfqdn = main_server->ServerFQDN; char *outs, mg_size[12] = {'\0'}, mg_size_units[12] = {'\0'}, mg_max[12] = "unlimited"; char mg_class_limit[12] = {'\0'}, mg_cur[12] = {'\0'}, mg_cur_class[12] = {'\0'}; const char *mg_time; char *rfc1413_ident = NULL, *user = NULL; /* Stat the opened file to determine the optimal buffer size for IO. */ memset(&st, 0, sizeof(st)); if (pr_fsio_fstat(fh, &st) == 0) { fh->fh_iosz = st.st_blksize; } res = pr_fs_fgetsize(fh->fh_fd, &fs_size); if (res < 0 && errno != ENOSYS) { (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION, "error getting filesystem size for '%s': %s", fh->fh_path, strerror(errno)); fs_size = 0; } snprintf(mg_size, sizeof(mg_size), "%" PR_LU, (pr_off_t) fs_size); format_size_str(mg_size_units, sizeof(mg_size_units), fs_size); mg_time = pr_strtime(time(NULL)); max_clients = get_param_ptr(main_server->conf, "MaxClients", FALSE); v = pr_table_get(session.notes, "client-count", NULL); if (v) { current_clients = v; } snprintf(mg_cur, sizeof(mg_cur), "%u", current_clients ? *current_clients: 1); if (session.conn_class != NULL && session.conn_class->cls_name) { unsigned int *class_clients = NULL; config_rec *maxc = NULL; unsigned int maxclients = 0; v = pr_table_get(session.notes, "class-client-count", NULL); if (v) { class_clients = v; } snprintf(mg_cur_class, sizeof(mg_cur_class), "%u", class_clients ? *class_clients : 0); /* For the %z variable, first we scan through the MaxClientsPerClass, * and use the first applicable one. If none are found, look for * any MaxClients set. */ maxc = find_config(main_server->conf, CONF_PARAM, "MaxClientsPerClass", FALSE); while (maxc) { pr_signals_handle(); if (strcmp(maxc->argv[0], session.conn_class->cls_name) != 0) { maxc = find_config_next(maxc, maxc->next, CONF_PARAM, "MaxClientsPerClass", FALSE); continue; } maxclients = *((unsigned int *) maxc->argv[1]); break; } if (maxclients == 0) { maxc = find_config(main_server->conf, CONF_PARAM, "MaxClients", FALSE); if (maxc) maxclients = *((unsigned int *) maxc->argv[0]); } snprintf(mg_class_limit, sizeof(mg_class_limit), "%u", maxclients); } else { snprintf(mg_class_limit, sizeof(mg_class_limit), "%u", max_clients ? *max_clients : 0); snprintf(mg_cur_class, sizeof(mg_cur_class), "%u", 0); } snprintf(mg_max, sizeof(mg_max), "%u", max_clients ? *max_clients : 0); user = pr_table_get(session.notes, "mod_auth.orig-user", NULL); if (user == NULL) user = ""; rfc1413_ident = pr_table_get(session.notes, "mod_ident.rfc1413-ident", NULL); if (rfc1413_ident == NULL) { rfc1413_ident = "UNKNOWN"; } memset(buf, '\0', sizeof(buf)); while (pr_fsio_gets(buf, sizeof(buf), fh) != NULL) { char *tmp; pr_signals_handle(); buf[sizeof(buf)-1] = '\0'; len = strlen(buf); while (len > 0 && (buf[len-1] == '\r' || buf[len-1] == '\n')) { pr_signals_handle(); buf[len-1] = '\0'; len--; } /* Check for any Variable-type strings. */ tmp = strstr(buf, "%{"); while (tmp) { char *key, *tmp2; const char *val; pr_signals_handle(); tmp2 = strchr(tmp, '}'); if (tmp2 == NULL) { /* No closing '}' found in this string, so no need to look for any * aother '%{' opening sequence. Just move on. */ tmp = NULL; break; } key = pstrndup(p, tmp, tmp2 - tmp + 1); /* There are a couple of special-case keys to watch for: * * env:$var * time:$fmt * * The Var API does not easily support returning values for keys * where part of the value depends on part of the key. That's why * these keys are handled here, instead of in pr_var_get(). */ if (strncmp(key, "%{time:", 7) == 0) { char time_str[128], *fmt; time_t now; struct tm *time_info; fmt = pstrndup(p, key + 7, strlen(key) - 8); now = time(NULL); time_info = pr_localtime(NULL, &now); memset(time_str, 0, sizeof(time_str)); strftime(time_str, sizeof(time_str), fmt, time_info); val = pstrdup(p, time_str); } else if (strncmp(key, "%{env:", 6) == 0) { char *env_var; env_var = pstrndup(p, key + 6, strlen(key) - 7); val = pr_env_get(p, env_var); if (val == NULL) { pr_trace_msg("var", 4, "no value set for environment variable '%s', using \"(none)\"", env_var); val = "(none)"; } } else { val = pr_var_get(key); if (val == NULL) { pr_trace_msg("var", 4, "no value set for name '%s', using \"(none)\"", key); val = "(none)"; } } outs = sreplace(p, buf, key, val, NULL); sstrncpy(buf, outs, sizeof(buf)); tmp = strstr(outs, "%{"); } outs = sreplace(p, buf, "%C", (session.cwd[0] ? session.cwd : "(none)"), "%E", main_server->ServerAdmin, "%F", mg_size, "%f", mg_size_units, "%i", "0", "%K", "0", "%k", "0B", "%L", serverfqdn, "%M", mg_max, "%N", mg_cur, "%o", "0", "%R", (session.c && session.c->remote_name ? session.c->remote_name : "(unknown)"), "%T", mg_time, "%t", "0", "%U", user, "%u", rfc1413_ident, "%V", main_server->ServerName, "%x", session.conn_class ? session.conn_class->cls_name : "(unknown)", "%y", mg_cur_class, "%z", mg_class_limit, NULL); /* Always make sure that the lines we send are CRLF-terminated. */ msg = pstrcat(p, msg, outs, "\r\n", NULL); /* Clear the buffer for the next read. */ memset(buf, '\0', sizeof(buf)); } return msg; }