diff --git a/doc/scripts/CMakeLists.txt b/doc/scripts/CMakeLists.txt index 3523806f4f..d01360f503 100644 --- a/doc/scripts/CMakeLists.txt +++ b/doc/scripts/CMakeLists.txt @@ -94,7 +94,7 @@ macro(REST_TARGET srcDir broInput) set(group "") endif () - if (${group} STREQUAL "default" OR ${group} STREQUAL "bifs") + if ("${group}" STREQUAL "default" OR "${group}" STREQUAL "bifs") set(BRO_ARGS --doc-scripts --exec '') else () set(BRO_ARGS --doc-scripts ${broInput}) @@ -127,117 +127,127 @@ macro(REST_TARGET srcDir broInput) endmacro(REST_TARGET) # Schedule Bro scripts for which to generate documentation. -# Note: the script may be located in a subdirectory off of one of the main -# directories in BROPATH. In that case, just list the script as 'foo/bar.bro' -rest_target(${CMAKE_CURRENT_SOURCE_DIR} example.bro internal) +# +# Note: any path prefix of the script (2nd argument of rest_target macro) +# will be used to derive what path under policy/ the generated documentation +# will be placed. -rest_target(${POLICY_SRC_DIR} conn.bro user) -rest_target(${POLICY_SRC_DIR} conn/base.bro user) -rest_target(${POLICY_SRC_DIR} conn/contents.bro user) +rest_target(${CMAKE_CURRENT_SOURCE_DIR} example.bro) -rest_target(${POLICY_SRC_DIR} dns.bro policy/dns-index) -rest_target(${POLICY_SRC_DIR} dns/auth-addl.bro policy/dns-index) -rest_target(${POLICY_SRC_DIR} dns/base.bro policy/dns-index) -rest_target(${POLICY_SRC_DIR} dns/consts.bro policy/dns-index) -rest_target(${POLICY_SRC_DIR} dns/detect.bro policy/dns-index) -rest_target(${POLICY_SRC_DIR} dns/passive-replication.bro policy/dns-index) +rest_target(${CMAKE_BINARY_DIR}/src bro.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/src const.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/src event.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/src logging.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/src strings.bif.bro) +rest_target(${CMAKE_BINARY_DIR}/src types.bif.bro) -# TODO: these don't currently work due to something that looks like a -# circular dependency. They'll also change to the 'default' group once -# loaded from bro.init. -#rest_target(${POLICY_SRC_DIR} dpd.bro policy/dpd-index) -#rest_target(${POLICY_SRC_DIR} dpd/base.bro policy/dpd-index) -#rest_target(${POLICY_SRC_DIR} dpd/dyn-disable.bro policy/dpd-index) -#rest_target(${POLICY_SRC_DIR} dpd/packet-segment-logging.bro policy/dpd-index) +set(psd ${POLICY_SRC_DIR}) -rest_target(${POLICY_SRC_DIR} ftp.bro policy/ftp-index) -rest_target(${POLICY_SRC_DIR} ftp/base.bro policy/ftp-index) -rest_target(${POLICY_SRC_DIR} ftp/detect.bro policy/ftp-index) -rest_target(${POLICY_SRC_DIR} ftp/file-extract.bro policy/ftp-index) -rest_target(${POLICY_SRC_DIR} ftp/software.bro policy/ftp-index) -rest_target(${POLICY_SRC_DIR} ftp/utils-commands.bro policy/ftp-index) +rest_target(${psd} bro.init) +rest_target(${psd} site.bro) -rest_target(${POLICY_SRC_DIR} functions.bro user) +rest_target(${psd} detectors/http-MHR.bro) -# TODO: hot.conn.bro currently won't load because hot.bro doesn't exist -#rest_target(${POLICY_SRC_DIR} hot.conn.bro user) +rest_target(${psd} frameworks/communication/base.bro) +rest_target(${psd} frameworks/communication/listen-clear.bro) +rest_target(${psd} frameworks/communication/listen-ssl.bro) -rest_target(${POLICY_SRC_DIR} http.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/base-extended.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/base.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/detect-intel.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/detect-sqli.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/detect-webapps.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/file-extract.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/file-hash.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/file-ident.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/headers.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/software.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/utils.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/var-extraction-cookies.bro policy/http-index) -rest_target(${POLICY_SRC_DIR} http/var-extraction-uri.bro policy/http-index) +rest_target(${psd} frameworks/dpd/base.bro) +rest_target(${psd} frameworks/dpd/dyn-disable.bro) +rest_target(${psd} frameworks/dpd/packet-segment-logging.bro) -rest_target(${POLICY_SRC_DIR} irc.bro policy/irc-index) -rest_target(${POLICY_SRC_DIR} irc/base.bro policy/irc-index) -rest_target(${POLICY_SRC_DIR} irc/dcc-send.bro policy/irc-index) +rest_target(${psd} frameworks/intel/base.bro) -rest_target(${POLICY_SRC_DIR} known-services.bro user) -rest_target(${POLICY_SRC_DIR} known-hosts.bro user) +rest_target(${psd} frameworks/logging/base.bro) +rest_target(${psd} frameworks/logging/plugins/ascii.bro) -rest_target(${POLICY_SRC_DIR} metrics.bro policy/metrics-index) -rest_target(${POLICY_SRC_DIR} metrics/base.bro policy/metrics-index) -rest_target(${POLICY_SRC_DIR} metrics/conn-example.bro policy/metrics-index) -rest_target(${POLICY_SRC_DIR} metrics/http-example.bro policy/metrics-index) +rest_target(${psd} frameworks/metrics/base.bro) +rest_target(${psd} frameworks/metrics/conn-example.bro) +rest_target(${psd} frameworks/metrics/http-example.bro) -rest_target(${POLICY_SRC_DIR} mime.bro policy/mime-index) -rest_target(${POLICY_SRC_DIR} mime/base.bro policy/mime-index) -rest_target(${POLICY_SRC_DIR} mime/file-extract.bro policy/mime-index) -rest_target(${POLICY_SRC_DIR} mime/file-hash.bro policy/mime-index) -rest_target(${POLICY_SRC_DIR} mime/file-ident.bro policy/mime-index) +rest_target(${psd} frameworks/notice/action-filters.bro) +rest_target(${psd} frameworks/notice/base.bro) +rest_target(${psd} frameworks/notice/weird.bro) -rest_target(${POLICY_SRC_DIR} notice-action-filters.bro user) -rest_target(${POLICY_SRC_DIR} notice.bro user) -rest_target(${POLICY_SRC_DIR} site.bro user) +rest_target(${psd} frameworks/packet-filter/base.bro) +rest_target(${psd} frameworks/packet-filter/netstats.bro) -rest_target(${POLICY_SRC_DIR} signatures.bro policy/sig-index) -rest_target(${POLICY_SRC_DIR} signatures/base.bro policy/sig-index) +rest_target(${psd} frameworks/signatures/base.bro) -rest_target(${POLICY_SRC_DIR} smtp.bro policy/smtp-index) -rest_target(${POLICY_SRC_DIR} smtp/base-extended.bro policy/smtp-index) -rest_target(${POLICY_SRC_DIR} smtp/base.bro policy/smtp-index) -rest_target(${POLICY_SRC_DIR} smtp/detect.bro policy/smtp-index) -rest_target(${POLICY_SRC_DIR} smtp/software.bro policy/smtp-index) -rest_target(${POLICY_SRC_DIR} smtp/utils.bro policy/smtp-index) -rest_target(${POLICY_SRC_DIR} smtp/webmail-ident.bro policy/smtp-index) +rest_target(${psd} frameworks/software/base.bro) +rest_target(${psd} frameworks/software/vulnerable.bro) -rest_target(${POLICY_SRC_DIR} software.bro policy/software-index) -rest_target(${POLICY_SRC_DIR} software/base.bro policy/software-index) -rest_target(${POLICY_SRC_DIR} software/vulnerable.bro policy/software-index) +rest_target(${psd} integration/barnyard2/base.bro) +rest_target(${psd} integration/barnyard2/event.bro) +rest_target(${psd} integration/barnyard2/types.bro) -rest_target(${POLICY_SRC_DIR} ssh.bro policy/ssh-index) -rest_target(${POLICY_SRC_DIR} ssh/base.bro policy/ssh-index) -rest_target(${POLICY_SRC_DIR} ssh/software.bro policy/ssh-index) +rest_target(${psd} protocols/conn/base.bro) +rest_target(${psd} protocols/conn/contents.bro) +rest_target(${psd} protocols/conn/inactivity.bro) +rest_target(${psd} protocols/conn/known-hosts.bro) +rest_target(${psd} protocols/conn/known-services.bro) -rest_target(${POLICY_SRC_DIR} ssl-ciphers.bro policy/ssl-index) -rest_target(${POLICY_SRC_DIR} ssl-errors.bro policy/ssl-index) -rest_target(${POLICY_SRC_DIR} ssl.bro policy/ssl-index) +rest_target(${psd} protocols/dns/auth-addl.bro) +rest_target(${psd} protocols/dns/base.bro) +rest_target(${psd} protocols/dns/consts.bro) +rest_target(${psd} protocols/dns/detect.bro) -rest_target(${POLICY_SRC_DIR} utils/pattern.bro user) -rest_target(${POLICY_SRC_DIR} weird.bro user) +rest_target(${psd} protocols/ftp/base.bro) +rest_target(${psd} protocols/ftp/detect.bro) +rest_target(${psd} protocols/ftp/file-extract.bro) +rest_target(${psd} protocols/ftp/software.bro) +rest_target(${psd} protocols/ftp/utils-commands.bro) -# Finding out what scripts bro will generate documentation for by default -# can be done like: `bro --doc-scripts --exec ""` -rest_target(${POLICY_SRC_DIR} bro.init default) -rest_target(${POLICY_SRC_DIR} logging-ascii.bro default) -rest_target(${POLICY_SRC_DIR} logging.bro default) -rest_target(${POLICY_SRC_DIR} pcap.bro default) -rest_target(${POLICY_SRC_DIR} server-ports.bro default) -rest_target(${CMAKE_BINARY_DIR}/src bro.bif.bro bifs) -rest_target(${CMAKE_BINARY_DIR}/src const.bif.bro bifs) -rest_target(${CMAKE_BINARY_DIR}/src event.bif.bro bifs) -rest_target(${CMAKE_BINARY_DIR}/src logging.bif.bro bifs) -rest_target(${CMAKE_BINARY_DIR}/src strings.bif.bro bifs) -rest_target(${CMAKE_BINARY_DIR}/src types.bif.bro bifs) +rest_target(${psd} protocols/http/base.bro) +rest_target(${psd} protocols/http/detect-intel.bro) +rest_target(${psd} protocols/http/detect-sqli.bro) +rest_target(${psd} protocols/http/detect-webapps.bro) +rest_target(${psd} protocols/http/file-extract.bro) +rest_target(${psd} protocols/http/file-hash.bro) +rest_target(${psd} protocols/http/file-ident.bro) +rest_target(${psd} protocols/http/headers.bro) +rest_target(${psd} protocols/http/software.bro) +rest_target(${psd} protocols/http/utils.bro) +rest_target(${psd} protocols/http/var-extraction-cookies.bro) +rest_target(${psd} protocols/http/var-extraction-uri.bro) + +rest_target(${psd} protocols/irc/base.bro) +rest_target(${psd} protocols/irc/dcc-send.bro) + +rest_target(${psd} protocols/mime/base.bro) +rest_target(${psd} protocols/mime/file-extract.bro) +rest_target(${psd} protocols/mime/file-hash.bro) +rest_target(${psd} protocols/mime/file-ident.bro) + +rest_target(${psd} protocols/smtp/base.bro) +rest_target(${psd} protocols/smtp/detect.bro) +rest_target(${psd} protocols/smtp/software.bro) + +rest_target(${psd} protocols/ssh/base.bro) +rest_target(${psd} protocols/ssh/software.bro) + +#rest_target(${psd} protocols/ssl/base.bro) +#rest_target(${psd} protocols/ssl/ssl-ciphers.bro) +#rest_target(${psd} protocols/ssl/ssl-errors.bro) +#rest_target(${psd} protocols/ssl/ssl.bro) +#rest_target(${psd} protocols/ssl/validate.bro) + +rest_target(${psd} protocols/syslog/base.bro) +rest_target(${psd} protocols/syslog/consts.bro) + +rest_target(${psd} tuning/defaults/packet-fragments.bro) +rest_target(${psd} tuning/defaults/remove-high-volume-notices.bro) +rest_target(${psd} tuning/track-all-assets.bro) + +rest_target(${psd} utils/addrs.bro) +rest_target(${psd} utils/conn_ids.bro) +rest_target(${psd} utils/directions-and-hosts.bro) +rest_target(${psd} utils/files.bro) +rest_target(${psd} utils/numbers.bro) +rest_target(${psd} utils/paths.bro) +rest_target(${psd} utils/pattern.bro) +rest_target(${psd} utils/strings.bro) +rest_target(${psd} utils/thresholds.bro) # create temporary list of all docs to include in the master policy/index file file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/tmp_policy_index diff --git a/doc/scripts/source/index.rst b/doc/scripts/source/index.rst index 91864f1881..049b548896 100644 --- a/doc/scripts/source/index.rst +++ b/doc/scripts/source/index.rst @@ -13,7 +13,6 @@ Contents: builtins default bifs - user policy/dns-index policy/ftp-index policy/http-index diff --git a/doc/scripts/source/user.rst b/doc/scripts/source/user.rst deleted file mode 100644 index 3d5804b7df..0000000000 --- a/doc/scripts/source/user.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. This is a stub doc to which the build process can append. - -Other User-Facing Policy Scripts -================================ - diff --git a/src/BroDoc.cc b/src/BroDoc.cc index 621209391a..e71026a250 100644 --- a/src/BroDoc.cc +++ b/src/BroDoc.cc @@ -3,9 +3,11 @@ #include #include #include +#include #include "BroDoc.h" #include "BroDocObj.h" +#include "util.h" BroDoc::BroDoc(const std::string& rel, const std::string& abs) { @@ -15,25 +17,19 @@ BroDoc::BroDoc(const std::string& rel, const std::string& abs) else source_filename = abs.substr(f_pos + 1); - if ( rel == abs ) + if ( rel[0] == '/' || rel[0] == '.' ) { - // The Bro script must have been loaded from an explicit path, - // so just use the basename as the document title + // The Bro script must not be on a subpath of the policy/ dir of + // BROPATH, so just use the basename as the document title doc_title = source_filename; } else { - // Must have relied on BROPATH to load the script, keep the relative - // directory as part of the source file name - size_t ext_pos = rel.find_last_of('.'); - std::string rel_ext = rel.substr(ext_pos + 1); - ext_pos = abs.find_last_of('.'); - std::string abs_ext = abs.substr(ext_pos + 1); - - if ( rel_ext == abs_ext || std::string::npos == ext_pos ) - doc_title = rel; + // keep the relative directory as part of the document title + if ( rel.size() == 0 || rel[rel.size() - 1] == '/' ) + doc_title = rel + source_filename; else - doc_title = rel + "." + abs_ext; + doc_title = rel + "/" + source_filename; } reST_filename = doc_title; @@ -46,24 +42,6 @@ BroDoc::BroDoc(const std::string& rel, const std::string& abs) reST_filename = doc_title.substr(0, ext_pos); reST_filename += ".rst"; -/* - // if the bro source file is being loaded from a relative path, - // re-create that directory tree to store the output - size_t f_pos = reST_filename.find_last_of('/'); - if ( std::string::npos != f_pos ) - { - std::string outdir = reST_filename.substr(0, f_pos); - std::string subdir; - while ( ! outdir.empty() ) - { - size_t pos = outdir.find_first_of('/'); - if ( pos != std::string::npos ) pos++; - subdir += outdir.substr(0, pos); - outdir.erase(0, pos); - ensure_dir(subdir.c_str()); - } - } -*/ // Instead of re-creating the directory hierarchy based on related // loads, just replace the directory separatories such that the reST // output will all be placed in a flat directory (the working dir). @@ -76,7 +54,7 @@ BroDoc::BroDoc(const std::string& rel, const std::string& abs) #ifdef DEBUG fprintf(stdout, "Documenting absolute source: %s\n", abs.c_str()); - fprintf(stdout, "\trelative load: %s\n", rel.c_str()); + fprintf(stdout, "\trelative dir: %s\n", rel.c_str()); fprintf(stdout, "\tdoc title: %s\n", doc_title.c_str()); fprintf(stdout, "\tbro file: %s\n", source_filename.c_str()); fprintf(stdout, "\trst file: %s\n", reST_filename.c_str()); @@ -93,12 +71,60 @@ BroDoc::~BroDoc() void BroDoc::AddImport(const std::string& s) { - size_t ext_pos = s.find_last_of('.'); + std::string lname(s); + // first strip any .bro extension + size_t ext_pos = lname.find(".bro"); + if ( ext_pos != std::string::npos ) + lname = lname.substr(0, ext_pos); - if ( ext_pos == std::string::npos ) - imports.push_back(s); + const char* full_filename = ""; + const char* subpath = ""; + FILE* f = search_for_file(lname.c_str(), "bro", &full_filename, true, + &subpath); + + if ( f ) + { + fclose(f); + + char* tmp = copy_string(full_filename); + char* filename = basename(tmp); + extern char* PACKAGE_LOADER; + + if ( streq(filename, PACKAGE_LOADER) ) + { + // link to the package's index + // TODO: check that this works + string pkg(subpath); + pkg += "/index"; + imports.push_back(pkg); + } + else + { + if ( subpath[0] == '/' || subpath[0] == '.' ) + { + // it's not a subpath of policy/, so just add the name of it + // as it's given in the @load directive + imports.push_back(lname); + } + else + { + // combine the base file name of script in the @load directive + // with the subpath of BROPATH's policy/ directory + string fname(subpath); + char* othertmp = copy_string(lname.c_str()); + fname.append("/").append(basename(othertmp)); + imports.push_back(fname); + delete [] othertmp; + } + } + + delete [] tmp; + delete [] full_filename; + delete [] subpath; + } else - imports.push_back(s.substr(0, ext_pos)); + fprintf(stderr, "Failed to document '@load %s' in file: %s\n", + s.c_str(), reST_filename.c_str()); } void BroDoc::SetPacketFilter(const std::string& s) diff --git a/src/BroDoc.h b/src/BroDoc.h index 5c9b175958..e98b511478 100644 --- a/src/BroDoc.h +++ b/src/BroDoc.h @@ -24,9 +24,11 @@ public: * If the filename doesn't end in ".bro", then ".rst" is just appended. * Any '/' characters in the reST file name that result from choice of * the 'rel' parameter are replaced with '^'. - * @param rel A string representing the path relative to BROPATH off of - * which the source file is loaded or generally any filesystem - * path to a Bro script. May or may not have .bro file extension. + * @param subpath A string representing a subpath of BROPATH's policy/ + * directory in which the source file is located. It can + * also be full path to the file or a full path that's in BROPATH, + * but in either of those cases, the parameter is essentially + * ignored and the document title is just derived from file name * @param abs The absolute path to the Bro script for which to generate * documentation. */ diff --git a/src/Debug.cc b/src/Debug.cc index 272d6739ae..6a0bbfdbb7 100644 --- a/src/Debug.cc +++ b/src/Debug.cc @@ -343,7 +343,7 @@ vector parse_location_string(const string& s) plr.type = plrUnknown; FILE* throwaway = search_for_file(filename.c_str(), "bro", - &full_filename, true); + &full_filename, true, 0); if ( ! throwaway ) { debug_msg("No such policy file: %s.\n", filename.c_str()); diff --git a/src/OSFinger.cc b/src/OSFinger.cc index f7b4903700..56f55f1225 100644 --- a/src/OSFinger.cc +++ b/src/OSFinger.cc @@ -295,7 +295,7 @@ void OSFingerprint::load_config(const char* file) uint32 ln=0; char buf[MAXLINE]; char* p; - FILE* c = search_for_file( file, "osf", 0, false); + FILE* c = search_for_file( file, "osf", 0, false, 0); if (!c) { diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index 4bc28b4c32..5cf6059249 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -197,7 +197,7 @@ bool RuleMatcher::ReadFiles(const name_list& files) for ( int i = 0; i < files.length(); ++i ) { - rules_in = search_for_file( files[i], "sig", 0, false); + rules_in = search_for_file( files[i], "sig", 0, false, 0); if ( ! rules_in ) { error("Can't open signature file", files[i]); diff --git a/src/scan.l b/src/scan.l index 8b599939db..553260a479 100644 --- a/src/scan.l +++ b/src/scan.l @@ -348,7 +348,7 @@ when return TOK_WHEN; // All we have to do is pretend we've already scanned it. const char* full_filename; - FILE* f = search_for_file(new_file, "bro", &full_filename, true); + FILE* f = search_for_file(new_file, "bro", &full_filename, true, 0); if ( f ) { @@ -537,6 +537,7 @@ static int load_files_with_prefix(const char* orig_file) const char* prefix = prefixes[i]; const char* full_filename = ""; + const char* bropath_subpath = ""; FILE* f; if ( streq(orig_file, "-") ) @@ -561,7 +562,7 @@ static int load_files_with_prefix(const char* orig_file) else strcpy(new_filename, orig_file); - f = search_for_file(new_filename, "bro", &full_filename, true); + f = search_for_file(new_filename, "bro", &full_filename, true, &bropath_subpath); delete [] new_filename; } @@ -576,6 +577,7 @@ static int load_files_with_prefix(const char* orig_file) { fclose(f); delete [] full_filename; + delete [] bropath_subpath; return 0; } } @@ -621,10 +623,12 @@ static int load_files_with_prefix(const char* orig_file) if ( generate_documentation ) { - current_reST_doc = new BroDoc(orig_file, full_filename); + current_reST_doc = new BroDoc(bropath_subpath, full_filename); docs_generated.push_back(current_reST_doc); } + delete [] bropath_subpath; + // "orig_file", could be an alias for yytext, which is ephemeral // and will be zapped after the yy_switch_to_buffer() below. yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); diff --git a/src/util.cc b/src/util.cc index 6c3f39bf72..4b4e833ef2 100644 --- a/src/util.cc +++ b/src/util.cc @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef HAVE_MALLINFO # include @@ -881,7 +882,7 @@ const char* bro_prefixes() return p; } -static const char* PACKAGE_LOADER = "__load__.bro"; +const char* PACKAGE_LOADER = "__load__.bro"; // If filename is pointing to a directory that contains a file called // PACKAGE_LOADER, returns the files path. Otherwise returns filename itself. @@ -915,11 +916,73 @@ FILE* open_file(const char* filename, const char** full_filename, bool load_pkgs return f; } +// Returns the subpath of BROPATH's policy/ directory in which the loaded +// file in located. If it's not under a subpath of policy/ then the full +// path is returned, else the subpath of policy/ concatentated with any +// directory prefix of the file is returned. +void get_policy_subpath(const char* dir, const char* file, const char** subpath) + { + // first figure out if this is a subpath of policy/ + const char* ploc = strstr(dir, "policy"); + if ( ploc ) + if ( ploc[6] == '\0' ) + *subpath = copy_string(ploc + 6); + else if ( ploc[6] == '/' ) + *subpath = copy_string(ploc + 7); + else + *subpath = copy_string(dir); + else + *subpath = copy_string(dir); + + // and now add any directory parts of the filename + char full_filename_buf[1024]; + safe_snprintf(full_filename_buf, sizeof(full_filename_buf), + "%s/%s", dir, file); + char* tmp = copy_string(file); + const char* fdir = 0; + + if ( is_dir(full_filename_buf) ) + fdir = file; + + if ( ! fdir ) + fdir = dirname(tmp); + + if ( ! streq(fdir, ".") ) + { + size_t full_subpath_len = strlen(*subpath) + strlen(fdir) + 1; + bool needslash = false; + if ( strlen(*subpath) != 0 && (*subpath)[strlen(*subpath) - 1] != '/' ) + { + ++full_subpath_len; + needslash = true; + } + + char* full_subpath = new char[full_subpath_len]; + strcpy(full_subpath, *subpath); + if ( needslash ) + strcat(full_subpath, "/"); + strcat(full_subpath, fdir); + delete [] *subpath; + *subpath = full_subpath; + } + + delete [] tmp; + } + FILE* search_for_file(const char* filename, const char* ext, - const char** full_filename, bool load_pkgs) + const char** full_filename, bool load_pkgs, + const char** bropath_subpath) { if ( filename[0] == '/' || filename[0] == '.' ) + { + if ( bropath_subpath ) + { + char* tmp = copy_string(filename); + *bropath_subpath = copy_string(dirname(tmp)); + delete [] tmp; + } return open_file(filename, full_filename, load_pkgs); + } char path[1024], full_filename_buf[1024]; safe_strncpy(path, bro_path(), sizeof(path)); @@ -942,18 +1005,32 @@ FILE* search_for_file(const char* filename, const char* ext, "%s/%s.%s", dir_beginning, filename, ext); if ( access(full_filename_buf, R_OK) == 0 && ! is_dir(full_filename_buf) ) + { + if ( bropath_subpath ) + get_policy_subpath(dir_beginning, filename, bropath_subpath); return open_file(full_filename_buf, full_filename, load_pkgs); + } safe_snprintf(full_filename_buf, sizeof(full_filename_buf), "%s/%s", dir_beginning, filename); if ( access(full_filename_buf, R_OK) == 0 ) + { + if ( bropath_subpath ) + get_policy_subpath(dir_beginning, filename, bropath_subpath); return open_file(full_filename_buf, full_filename, load_pkgs); + } dir_beginning = ++dir_ending; } if ( full_filename ) *full_filename = copy_string(filename); + if ( bropath_subpath ) + { + char* tmp = copy_string(filename); + *bropath_subpath = copy_string(dirname(tmp)); + delete [] tmp; + } return 0; } diff --git a/src/util.h b/src/util.h index 6aad1271af..e3929fa850 100644 --- a/src/util.h +++ b/src/util.h @@ -189,8 +189,9 @@ extern int int_list_cmp(const void* v1, const void* v2); extern const char* bro_path(); extern const char* bro_prefixes(); +void get_policy_subpath(const char* dir, const char* file, const char** subpath); extern FILE* search_for_file(const char* filename, const char* ext, - const char** full_filename, bool load_pkgs); + const char** full_filename, bool load_pkgs, const char** bropath_subpath); // Renames the given file to a new temporary name, and opens a new file with // the original name. Returns new file or NULL on error. Inits rotate_info if diff --git a/testing/btest/Baseline/doc.autogen-reST-example/example.rst b/testing/btest/Baseline/doc.autogen-reST-example/example.rst index a7ef21d907..d9a6fd0adf 100644 --- a/testing/btest/Baseline/doc.autogen-reST-example/example.rst +++ b/testing/btest/Baseline/doc.autogen-reST-example/example.rst @@ -29,7 +29,7 @@ each of "columns", "event", "filter" depending on exactly what it's doing. :Author: Jon Siwek -:Imports: :doc:`notice ` +:Imports: :doc:`frameworks/notice/index ` Summary ~~~~~~~