diff --git a/sr_config.c b/sr_config.c index ec657d1..10cc087 100644 --- a/sr_config.c +++ b/sr_config.c @@ -873,6 +873,11 @@ int sr_config_parse_option(struct sr_config_s *sr_cfg, char *option, char *arg, if (sr_cfg->post_baseDir) free(sr_cfg->post_baseDir); sr_cfg->post_baseDir = argument; + if (sr_cfg->realpath_post_baseDir) { + free(sr_cfg->realpath_post_baseDir); + sr_cfg->realpath_post_baseDir = NULL; + } + sr_cfg->realpath_post_baseDir = realpath(sr_cfg->post_baseDir, sr_cfg->realpath_post_baseDir); argument = NULL; } else if (!strcmp(option, "post_base_dir") || !strcmp(option, "pbd") @@ -880,6 +885,11 @@ int sr_config_parse_option(struct sr_config_s *sr_cfg, char *option, char *arg, if (sr_cfg->post_baseDir) free(sr_cfg->post_baseDir); sr_cfg->post_baseDir = argument; + if (sr_cfg->realpath_post_baseDir) { + free(sr_cfg->realpath_post_baseDir); + sr_cfg->realpath_post_baseDir = NULL; + } + sr_cfg->realpath_post_baseDir = realpath(sr_cfg->post_baseDir, sr_cfg->realpath_post_baseDir); argument = NULL; retval = 2; @@ -1292,6 +1302,9 @@ void sr_config_free(struct sr_config_s *sr_cfg) if (sr_cfg->post_baseDir) free(sr_cfg->post_baseDir); sr_cfg->post_baseDir = NULL; + if (sr_cfg->realpath_post_baseDir) + free(sr_cfg->realpath_post_baseDir); + sr_cfg->realpath_post_baseDir = NULL; if (sr_cfg->exchange) free(sr_cfg->exchange); sr_cfg->exchange = NULL; @@ -1418,6 +1431,7 @@ void sr_config_init(struct sr_config_s *sr_cfg, const char *progname) sr_cfg->delete = 0; sr_cfg->directory = NULL; sr_cfg->post_baseDir = NULL; + sr_cfg->realpath_post_baseDir = NULL; sr_cfg->durable = 1; sr_cfg->events = (SR_EVENT_CREATE | SR_EVENT_MODIFY | SR_EVENT_DELETE | SR_EVENT_LINK | SR_EVENT_MKDIR | @@ -1931,25 +1945,35 @@ int sr_config_finalize(struct sr_config_s *sr_cfg, const int is_consumer) sr_cfg->to = strdup(sr_cfg->post_broker->hostname); } if (!(sr_cfg->post_baseDir)) { - if (sr_cfg->post_baseUrl) { - if (!strncmp(sr_cfg->post_baseUrl, "file:", 5)) { - sr_cfg->post_baseDir = strdup(sr_cfg->post_baseUrl + 5); - } else if (!strncmp(sr_cfg->post_baseUrl, "sftp:", 5)) { - char *slash; - char *at; - slash = index(sr_cfg->post_baseUrl+7,'/'); - at = index(sr_cfg->post_baseUrl+7,'@'); - if (slash) { - while (at > slash) { // there is a slash in a password... - slash = index(slash,'/'); - } - if (slash) { - while (*(slash+1) == '/') slash++; - sr_cfg->post_baseDir = strdup(slash); - } - } - } - } + if (sr_cfg->post_baseUrl) { + if (!strncmp(sr_cfg->post_baseUrl, "file:", 5)) { + sr_cfg->post_baseDir = strdup(sr_cfg->post_baseUrl + 5); + if (sr_cfg->realpath_post_baseDir) { + free(sr_cfg->realpath_post_baseDir); + sr_cfg->realpath_post_baseDir = NULL; + } + sr_cfg->realpath_post_baseDir = realpath(sr_cfg->post_baseDir, sr_cfg->realpath_post_baseDir); + } else if (!strncmp(sr_cfg->post_baseUrl, "sftp:", 5)) { + char *slash; + char *at; + slash = index(sr_cfg->post_baseUrl+7,'/'); + at = index(sr_cfg->post_baseUrl+7,'@'); + if (slash) { + while (at > slash) { // there is a slash in a password... + slash = index(slash,'/'); + } + if (slash) { + while (*(slash+1) == '/') slash++; + sr_cfg->post_baseDir = strdup(slash); + if (sr_cfg->realpath_post_baseDir) { + free(sr_cfg->realpath_post_baseDir); + sr_cfg->realpath_post_baseDir = NULL; + } + sr_cfg->realpath_post_baseDir = realpath(sr_cfg->post_baseDir, sr_cfg->realpath_post_baseDir); + } + } + } + } } } if (strcmp(sr_cfg->action, "sanity")) { @@ -1958,8 +1982,8 @@ int sr_config_finalize(struct sr_config_s *sr_cfg, const int is_consumer) sr_cfg->message_ttl, sr_cfg->post_exchange, sr_cfg->post_exchangeSplit, sr_cfg->post_exchangeSuffix); sr_log_msg(sr_cfg->logctx, ll, - "\tsource=%s, to=%s, post_baseUrl=%s, post_baseDir=%s\n", - sr_cfg->source, sr_cfg->to, sr_cfg->post_baseUrl, sr_cfg->post_baseDir ); + "\tsource=%s, to=%s, post_baseUrl=%s, post_baseDir=%s, realpath_post_baseDir=%s\n", + sr_cfg->source, sr_cfg->to, sr_cfg->post_baseUrl, sr_cfg->post_baseDir, sr_cfg->realpath_post_baseDir); sr_log_msg(sr_cfg->logctx, ll,"\ttopicPrefix=%s, post_topicPrefix=%s, pid=%d\n", sr_cfg->topicPrefix, sr_cfg->post_topicPrefix, sr_cfg->pid); sr_log_msg(sr_cfg->logctx, ll, "man sr3_cpost(1) for more information\n"); diff --git a/sr_config.h b/sr_config.h index d548cf8..2b22eed 100644 --- a/sr_config.h +++ b/sr_config.h @@ -207,6 +207,7 @@ struct sr_config_s { /**< the list of configurations or files given on the command line.*/ int pipe; /**< pipe mode, read file names from standard input*/ char *post_baseDir; /**< the local directory at the root of the url tree.*/ + char *realpath_post_baseDir; /**< the local directory at the root of the url tree (set from realpath of post_baseDir).*/ char *post_baseUrl; /**< the url that corresponds to the base directory.*/ struct sr_broker_s *post_broker; /**< the broker to post to.*/ diff --git a/sr_post.c b/sr_post.c index 9763fcf..63cbd97 100644 --- a/sr_post.c +++ b/sr_post.c @@ -652,6 +652,7 @@ int sr_file2message_start(struct sr_context *sr_c, const char *pathspec, char *c, *d; int lasti; int linklen; + int pbdlen = 0; char linkstr[PATH_MAXNUL]; char tmprk[PATH_MAXNUL + 100]; @@ -722,19 +723,30 @@ int sr_file2message_start(struct sr_context *sr_c, const char *pathspec, } *c = '\0'; + // build relPath that gets posted by removing (realpath_)post_baseDir from fn if (sr_c->cfg->post_baseDir && (strlen(sr_c->cfg->post_baseDir) > 1 ) ) { + // first try post_baseDir // the +1 is to because baseDir is always absolute, and relPath is always relative drfound = strstr(fn, (sr_c->cfg->post_baseDir)+1); - - // replace only if at the beginning of the string. + // replace post_baseDir only if at the beginning of the string. if (drfound==fn+1) { - drfound += strlen(sr_c->cfg->post_baseDir); + pbdlen = strlen(sr_c->cfg->post_baseDir); + drfound += (sr_c->cfg->post_baseDir[pbdlen-1] == '/') ? pbdlen - 1 : pbdlen; //adjust for trailing / strcpy(m->relPath, drfound); - } else if (absolute_path) { - sr_log_msg(sr_c->cfg->logctx,LOG_ERROR, "%s posting outside of post_baseDir (%s) invalid path: %s\n", - sr_c->cfg->progname, sr_c->cfg->post_baseDir, fn ); - return(0); - } + + // if post_baseDir didn't match, try realpath_post_baseDir + } else { + drfound = strstr(fn, (sr_c->cfg->realpath_post_baseDir)+1); + if (drfound==fn+1) { + pbdlen = strlen(sr_c->cfg->realpath_post_baseDir); + drfound += (sr_c->cfg->realpath_post_baseDir[pbdlen-1] == '/') ? pbdlen - 1 : pbdlen; //adjust for trailing / + strcpy(m->relPath, drfound); + } else if (absolute_path) { + sr_log_msg(sr_c->cfg->logctx,LOG_ERROR, "%s invalid path: %s is outside of post_baseDir (%s)\n", + sr_c->cfg->progname, fn, sr_c->cfg->post_baseDir); + return(0); + } + } } // Strip option: remove prefix from path according to / #